diff --git a/conf/distro/iot2050-debian.conf b/conf/distro/iot2050-debian.conf index 78eb5ec32..584fe88ae 100644 --- a/conf/distro/iot2050-debian.conf +++ b/conf/distro/iot2050-debian.conf @@ -16,8 +16,8 @@ DISTRO_NAME = "IOT2050 Debian System" HOSTNAME ??= "iot2050-debian" -PREFERRED_VERSION_linux-iot2050 ?= "5.10.%" -PREFERRED_VERSION_linux-iot2050-rt ?= "5.10.%" +PREFERRED_VERSION_linux-iot2050 ?= "6.1.%" +PREFERRED_VERSION_linux-iot2050-rt ?= "6.1.%" KERNEL_NAME ?= "cip" diff --git a/recipes-kernel/linux/files/patches-5.10/0001-dmaengine-ti-k3-udma-glue-Add-function-to-get-device.patch b/recipes-kernel/linux/files/patches-5.10/0001-dmaengine-ti-k3-udma-glue-Add-function-to-get-device.patch deleted file mode 100644 index 24bbf260e..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0001-dmaengine-ti-k3-udma-glue-Add-function-to-get-device.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Tue, 8 Dec 2020 11:04:24 +0200 -Subject: [PATCH] dmaengine: ti: k3-udma-glue: Add function to get device - pointer for DMA API - -Glue layer users should use the device of the DMA for DMA mapping and -allocations as it is the DMA which accesses to descriptors and buffers, -not the clients - -Signed-off-by: Peter Ujfalusi -Reviewed-by: Grygorii Strashko -Link: https://lore.kernel.org/r/20201208090440.31792-5-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul ---- - drivers/dma/ti/k3-udma-glue.c | 14 ++++++++++++++ - drivers/dma/ti/k3-udma-private.c | 6 ++++++ - drivers/dma/ti/k3-udma.h | 1 + - include/linux/dma/k3-udma-glue.h | 4 ++++ - 4 files changed, 25 insertions(+) - -diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c -index a367584f0d7b..a53bc4707ae8 100644 ---- a/drivers/dma/ti/k3-udma-glue.c -+++ b/drivers/dma/ti/k3-udma-glue.c -@@ -487,6 +487,13 @@ int k3_udma_glue_tx_get_irq(struct k3_udma_glue_tx_channel *tx_chn) - } - EXPORT_SYMBOL_GPL(k3_udma_glue_tx_get_irq); - -+struct device * -+ k3_udma_glue_tx_get_dma_device(struct k3_udma_glue_tx_channel *tx_chn) -+{ -+ return xudma_get_device(tx_chn->common.udmax); -+} -+EXPORT_SYMBOL_GPL(k3_udma_glue_tx_get_dma_device); -+ - static int k3_udma_glue_cfg_rx_chn(struct k3_udma_glue_rx_channel *rx_chn) - { - const struct udma_tisci_rm *tisci_rm = rx_chn->common.tisci_rm; -@@ -1189,3 +1196,10 @@ int k3_udma_glue_rx_get_irq(struct k3_udma_glue_rx_channel *rx_chn, - return flow->virq; - } - EXPORT_SYMBOL_GPL(k3_udma_glue_rx_get_irq); -+ -+struct device * -+ k3_udma_glue_rx_get_dma_device(struct k3_udma_glue_rx_channel *rx_chn) -+{ -+ return xudma_get_device(rx_chn->common.udmax); -+} -+EXPORT_SYMBOL_GPL(k3_udma_glue_rx_get_dma_device); -diff --git a/drivers/dma/ti/k3-udma-private.c b/drivers/dma/ti/k3-udma-private.c -index dadab2feca08..bae6150b1d8d 100644 ---- a/drivers/dma/ti/k3-udma-private.c -+++ b/drivers/dma/ti/k3-udma-private.c -@@ -50,6 +50,12 @@ struct udma_dev *of_xudma_dev_get(struct device_node *np, const char *property) - } - EXPORT_SYMBOL(of_xudma_dev_get); - -+struct device *xudma_get_device(struct udma_dev *ud) -+{ -+ return ud->dev; -+} -+EXPORT_SYMBOL(xudma_get_device); -+ - u32 xudma_dev_get_psil_base(struct udma_dev *ud) - { - return ud->psil_base; -diff --git a/drivers/dma/ti/k3-udma.h b/drivers/dma/ti/k3-udma.h -index 09c4529e013d..d1cace0cb43b 100644 ---- a/drivers/dma/ti/k3-udma.h -+++ b/drivers/dma/ti/k3-udma.h -@@ -112,6 +112,7 @@ int xudma_navss_psil_unpair(struct udma_dev *ud, u32 src_thread, - u32 dst_thread); - - struct udma_dev *of_xudma_dev_get(struct device_node *np, const char *property); -+struct device *xudma_get_device(struct udma_dev *ud); - void xudma_dev_put(struct udma_dev *ud); - u32 xudma_dev_get_psil_base(struct udma_dev *ud); - struct udma_tisci_rm *xudma_dev_get_tisci_rm(struct udma_dev *ud); -diff --git a/include/linux/dma/k3-udma-glue.h b/include/linux/dma/k3-udma-glue.h -index 5eb34ad973a7..d7c12f31377c 100644 ---- a/include/linux/dma/k3-udma-glue.h -+++ b/include/linux/dma/k3-udma-glue.h -@@ -41,6 +41,8 @@ void k3_udma_glue_reset_tx_chn(struct k3_udma_glue_tx_channel *tx_chn, - u32 k3_udma_glue_tx_get_hdesc_size(struct k3_udma_glue_tx_channel *tx_chn); - u32 k3_udma_glue_tx_get_txcq_id(struct k3_udma_glue_tx_channel *tx_chn); - int k3_udma_glue_tx_get_irq(struct k3_udma_glue_tx_channel *tx_chn); -+struct device * -+ k3_udma_glue_tx_get_dma_device(struct k3_udma_glue_tx_channel *tx_chn); - - enum { - K3_UDMA_GLUE_SRC_TAG_LO_KEEP = 0, -@@ -130,5 +132,7 @@ int k3_udma_glue_rx_flow_enable(struct k3_udma_glue_rx_channel *rx_chn, - u32 flow_idx); - int k3_udma_glue_rx_flow_disable(struct k3_udma_glue_rx_channel *rx_chn, - u32 flow_idx); -+struct device * -+ k3_udma_glue_rx_get_dma_device(struct k3_udma_glue_rx_channel *rx_chn); - - #endif /* K3_UDMA_GLUE_H_ */ diff --git a/recipes-kernel/linux/files/patches-5.10/0002-arm64-dts-ti-k3-am65-ringacc-drop-ti-dma-ring-reset-.patch b/recipes-kernel/linux/files/patches-5.10/0002-arm64-dts-ti-k3-am65-ringacc-drop-ti-dma-ring-reset-.patch deleted file mode 100644 index 6bc973d30..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0002-arm64-dts-ti-k3-am65-ringacc-drop-ti-dma-ring-reset-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Sat, 29 Aug 2020 21:41:39 +0300 -Subject: [PATCH] arm64: dts: ti: k3-am65: ringacc: drop ti, - dma-ring-reset-quirk - -Remove obsolete "ti,dma-ring-reset-quirk" Ringacc DT property. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Nishanth Menon -Link: https://lore.kernel.org/r/20200829184139.15547-4-grygorii.strashko@ti.com ---- - arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 1 - - arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi | 1 - - 2 files changed, 2 deletions(-) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index 4265f627ca16..8b797a0a05cd 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -614,7 +614,6 @@ ringacc: ringacc@3c000000 { - reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target"; - ti,num-rings = <818>; - ti,sci-rm-range-gp-rings = <0x1>; /* GP ring range */ -- ti,dma-ring-reset-quirk; - ti,sci = <&dmsc>; - ti,sci-dev-id = <187>; - msi-parent = <&inta_main_udmass>; -diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi -index 29aaf8dca6f6..044042b166d9 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi -@@ -135,7 +135,6 @@ mcu_ringacc: ringacc@2b800000 { - reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target"; - ti,num-rings = <286>; - ti,sci-rm-range-gp-rings = <0x1>; /* GP ring range */ -- ti,dma-ring-reset-quirk; - ti,sci = <&dmsc>; - ti,sci-dev-id = <195>; - msi-parent = <&inta_main_udmass>; diff --git a/recipes-kernel/linux/files/patches-5.10/0003-arm64-dts-ti-k3-am65-mcu-Add-MCU-domain-R5F-cluster-.patch b/recipes-kernel/linux/files/patches-5.10/0003-arm64-dts-ti-k3-am65-mcu-Add-MCU-domain-R5F-cluster-.patch deleted file mode 100644 index 8233a5ef3..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0003-arm64-dts-ti-k3-am65-mcu-Add-MCU-domain-R5F-cluster-.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Wed, 28 Oct 2020 22:37:55 -0500 -Subject: [PATCH] arm64: dts: ti: k3-am65-mcu: Add MCU domain R5F cluster node - -The AM65x SoCs have a single dual-core Arm Cortex-R5F processor (R5FSS) -subsystem/cluster. This R5F cluster (MCU_R5FSS0) is present within the -MCU domain, and can be configured at boot time to be either run in a -LockStep mode or in an Asymmetric Multi Processing (AMP) fashion in -Split-mode. This subsystem has 64 KB each Tightly-Coupled Memory (TCM) -internal memories for each core split between two banks - TCMA and TCMB -(further interleaved into two banks). There are some IP integration -differences from standard Arm R5F clusters such as the absence of an ACP -port, presence of an additional TI-specific Region Address Translater -(RAT) module for translating 32-bit CPU addresses into larger system -bus addresses etc. - -Add the DT node for this R5F cluster/subsystem, the two R5F cores are -added as child nodes to the main cluster node. The cluster is configured -to run in LockStep mode by default, with the ATCMs enabled to allow the -R5 cores to execute code from DDR with boot-strapping code from ATCM. -The inter-processor communication between the main A53 cores and these -processors is achieved through shared memory and Mailboxes. - -The following firmware names are used by default for these cores, and -can be overridden in a board dts file if needed: - am65x-mcu-r5f0_0-fw (LockStep mode and for Core0 in Split mode) - am65x-mcu-r5f0_1-fw (Core1 in Split mode) - -Signed-off-by: Suman Anna -Signed-off-by: Nishanth Menon -Reviewed-by: Lokesh Vutla -Link: https://lore.kernel.org/r/20201029033802.15366-2-s-anna@ti.com ---- - arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi | 42 ++++++++++++++++++++++++- - 1 file changed, 41 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi -index 044042b166d9..7454c8cec0cc 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi -@@ -2,7 +2,7 @@ - /* - * Device Tree Source for AM6 SoC Family MCU Domain peripherals - * -- * Copyright (C) 2016-2018 Texas Instruments Incorporated - https://www.ti.com/ -+ * Copyright (C) 2016-2020 Texas Instruments Incorporated - https://www.ti.com/ - */ - - &cbass_mcu { -@@ -268,4 +268,44 @@ mcu_cpsw_cpts_mux: refclk-mux { - }; - }; - }; -+ -+ mcu_r5fss0: r5fss@41000000 { -+ compatible = "ti,am654-r5fss"; -+ ti,cluster-mode = <1>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x41000000 0x00 0x41000000 0x20000>, -+ <0x41400000 0x00 0x41400000 0x20000>; -+ power-domains = <&k3_pds 129 TI_SCI_PD_EXCLUSIVE>; -+ -+ mcu_r5fss0_core0: r5f@41000000 { -+ compatible = "ti,am654-r5f"; -+ reg = <0x41000000 0x00008000>, -+ <0x41010000 0x00008000>; -+ reg-names = "atcm", "btcm"; -+ ti,sci = <&dmsc>; -+ ti,sci-dev-id = <159>; -+ ti,sci-proc-ids = <0x01 0xff>; -+ resets = <&k3_reset 159 1>; -+ firmware-name = "am65x-mcu-r5f0_0-fw"; -+ ti,atcm-enable = <1>; -+ ti,btcm-enable = <1>; -+ ti,loczrama = <1>; -+ }; -+ -+ mcu_r5fss0_core1: r5f@41400000 { -+ compatible = "ti,am654-r5f"; -+ reg = <0x41400000 0x00008000>, -+ <0x41410000 0x00008000>; -+ reg-names = "atcm", "btcm"; -+ ti,sci = <&dmsc>; -+ ti,sci-dev-id = <245>; -+ ti,sci-proc-ids = <0x02 0xff>; -+ resets = <&k3_reset 245 1>; -+ firmware-name = "am65x-mcu-r5f0_1-fw"; -+ ti,atcm-enable = <1>; -+ ti,btcm-enable = <1>; -+ ti,loczrama = <1>; -+ }; -+ }; - }; diff --git a/recipes-kernel/linux/files/patches-5.10/0004-arm64-dts-ti-k3-am65-Cleanup-disabled-nodes-at-SoC-d.patch b/recipes-kernel/linux/files/patches-5.10/0004-arm64-dts-ti-k3-am65-Cleanup-disabled-nodes-at-SoC-d.patch deleted file mode 100644 index 8bcc289b7..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0004-arm64-dts-ti-k3-am65-Cleanup-disabled-nodes-at-SoC-d.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Fri, 13 Nov 2020 15:18:22 -0600 -Subject: [PATCH] arm64: dts: ti: k3-am65*: Cleanup disabled nodes at SoC dtsi - level - -The device tree standard states that when the status property is -not present under a node, the okay value is assumed. There are many -reasons for doing the same, the number of strings in the device -tree, default power management functionality, etc. are a few of the -reasons. - -In general, after a few rounds of discussions [1] there are few -options one could take when dealing with SoC dtsi and board dts - -a. SoC dtsi provide nodes as a super-set default (aka enabled) state and - to prevent messy board files, when more boards are added per SoC, we - optimize and disable commonly un-used nodes in board-common.dtsi -b. SoC dtsi disables all hardware dependent nodes by default and board - dts files enable nodes based on a need basis. -c. Subjectively pick and choose which nodes we will disable by default - in SoC dtsi and over the years we can optimize things and change - default state depending on the need. - -While there are pros and cons on each of these approaches, the right -thing to do will be to stick with device tree default standards and -work within those established rules. So, we choose to go with option -(a). - -Lets cleanup defaults of am654 SoC dtsi before this gets more harder -to cleanup later on and new SoCs are added. - -The dtb generated is identical with the patch and it is just cleanup to -ensure we have a clean usage model - -NOTE: There is a known risk of omission that new board dts developers -might miss reviewing both the board schematics in addition to all the -DT nodes of the SoC when setting appropriate nodes status to disable -or reserved in the board dts. This can expose issues in drivers that -may not anticipate an incomplete node (example: missing appropriate -board properties) being in an "okay" state. These cases are considered -bugs and need to be fixed in the drivers as and when identified. - -[1] https://lore.kernel.org/linux-arm-kernel/20201027130701.GE5639@atomide.com/ - -Signed-off-by: Nishanth Menon -Reviewed-by: Tomi Valkeinen -Reviewed-by: Tony Lindgren -Cc: Jyri Sarha -Cc: Tomi Valkeinen -Cc: Peter Ujfalusi -Cc: Tony Lindgren -Link: https://lore.kernel.org/r/20201113211826.13087-2-nm@ti.com ---- - arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 8 -------- - arch/arm64/boot/dts/ti/k3-am654-base-board.dts | 16 ++++++++++++++++ - 2 files changed, 16 insertions(+), 8 deletions(-) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index 8b797a0a05cd..8d081ee03320 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -771,8 +771,6 @@ mcasp0: mcasp@2b00000 { - clocks = <&k3_clks 104 0>; - clock-names = "fck"; - power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>; -- -- status = "disabled"; - }; - - mcasp1: mcasp@2b10000 { -@@ -790,8 +788,6 @@ mcasp1: mcasp@2b10000 { - clocks = <&k3_clks 105 0>; - clock-names = "fck"; - power-domains = <&k3_pds 105 TI_SCI_PD_EXCLUSIVE>; -- -- status = "disabled"; - }; - - mcasp2: mcasp@2b20000 { -@@ -809,8 +805,6 @@ mcasp2: mcasp@2b20000 { - clocks = <&k3_clks 106 0>; - clock-names = "fck"; - power-domains = <&k3_pds 106 TI_SCI_PD_EXCLUSIVE>; -- -- status = "disabled"; - }; - - cal: cal@6f03000 { -@@ -866,8 +860,6 @@ dss: dss@4a00000 { - - interrupts = ; - -- status = "disabled"; -- - dma-coherent; - - dss_ports: ports { -diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts -index 937dd7280c7a..8c082af489f5 100644 ---- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts -+++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts -@@ -486,3 +486,19 @@ &cpsw_port1 { - phy-mode = "rgmii-rxid"; - phy-handle = <&phy0>; - }; -+ -+&mcasp0 { -+ status = "disabled"; -+}; -+ -+&mcasp1 { -+ status = "disabled"; -+}; -+ -+&mcasp2 { -+ status = "disabled"; -+}; -+ -+&dss { -+ status = "disabled"; -+}; diff --git a/recipes-kernel/linux/files/patches-5.10/0005-arm64-dts-ti-am65-j721e-Fix-up-un-necessary-status-s.patch b/recipes-kernel/linux/files/patches-5.10/0005-arm64-dts-ti-am65-j721e-Fix-up-un-necessary-status-s.patch deleted file mode 100644 index 26add5c4c..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0005-arm64-dts-ti-am65-j721e-Fix-up-un-necessary-status-s.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Fri, 13 Nov 2020 15:18:24 -0600 -Subject: [PATCH] arm64: dts: ti: am65/j721e: Fix up un-necessary status set to - "okay" for crypto - -The default state of a device tree node is "okay". There is no specific -use of explicitly adding status = "okay" in the SoC dtsi. - -Signed-off-by: Nishanth Menon -Reviewed-by: Tony Lindgren -Reviewed-by: Keerthy -Acked-by: Tero Kristo -Cc: Keerthy -Link: https://lore.kernel.org/r/20201113211826.13087-4-nm@ti.com ---- - arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 1 - - arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 2 -- - 2 files changed, 3 deletions(-) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index 8d081ee03320..4ad46fddc12c 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -122,7 +122,6 @@ crypto: crypto@4e00000 { - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x04e00000 0x00 0x04e00000 0x0 0x30000>; -- status = "okay"; - - dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>, - <&main_udmap 0x4001>; -diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -index 691d73f0f1e0..afb8fd7df629 100644 ---- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -@@ -362,8 +362,6 @@ main_crypto: crypto@4e00000 { - #size-cells = <2>; - ranges = <0x0 0x04e00000 0x00 0x04e00000 0x0 0x30000>; - -- status = "okay"; -- - dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>, - <&main_udmap 0x4001>; - dma-names = "tx", "rx1", "rx2"; diff --git a/recipes-kernel/linux/files/patches-5.10/0006-arm64-dts-ti-k3-mmc-fix-dtbs_check-warnings.patch b/recipes-kernel/linux/files/patches-5.10/0006-arm64-dts-ti-k3-mmc-fix-dtbs_check-warnings.patch deleted file mode 100644 index 0a1d58ec2..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0006-arm64-dts-ti-k3-mmc-fix-dtbs_check-warnings.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Fri, 15 Jan 2021 21:30:16 +0200 -Subject: [PATCH] arm64: dts: ti: k3: mmc: fix dtbs_check warnings - -Now the dtbs_check produces below warnings - sdhci@4f80000: clock-names:0: 'clk_ahb' was expected - sdhci@4f80000: clock-names:1: 'clk_xin' was expected - $nodename:0: 'sdhci@4f80000' does not match '^mmc(@.*)?$' - -Fix above warnings by updating mmc DT definitions to follow -sdhci-am654.yaml bindings: - - rename sdhci dt nodes to 'mmc@' - - swap clk_xin/clk_ahb clocks, the clk_ahb clock expected to be defined -first - -Signed-off-by: Grygorii Strashko -Signed-off-by: Nishanth Menon -Reviewed-by: Suman Anna -Reviewed-by: Aswath Govindraju -Link: https://lore.kernel.org/r/20210115193016.5581-1-grygorii.strashko@ti.com ---- - arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 4 ++-- - arch/arm64/boot/dts/ti/k3-j7200-main.dtsi | 8 ++++---- - arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 18 +++++++++--------- - 3 files changed, 15 insertions(+), 15 deletions(-) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index 4ad46fddc12c..5be027228e88 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -258,7 +258,7 @@ main_spi4: spi@2140000 { - #size-cells = <0>; - }; - -- sdhci0: sdhci@4f80000 { -+ sdhci0: mmc@4f80000 { - compatible = "ti,am654-sdhci-5.1"; - reg = <0x0 0x4f80000 0x0 0x260>, <0x0 0x4f90000 0x0 0x134>; - power-domains = <&k3_pds 47 TI_SCI_PD_EXCLUSIVE>; -@@ -282,7 +282,7 @@ sdhci0: sdhci@4f80000 { - dma-coherent; - }; - -- sdhci1: sdhci@4fa0000 { -+ sdhci1: mmc@4fa0000 { - compatible = "ti,am654-sdhci-5.1"; - reg = <0x0 0x4fa0000 0x0 0x260>, <0x0 0x4fb0000 0x0 0x134>; - power-domains = <&k3_pds 48 TI_SCI_PD_EXCLUSIVE>; -diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi -index bef47f96376d..cb22e65d61ab 100644 ---- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi -@@ -390,8 +390,8 @@ main_sdhci0: mmc@4f80000 { - reg = <0x00 0x04f80000 0x00 0x260>, <0x00 0x4f88000 0x00 0x134>; - interrupts = ; - power-domains = <&k3_pds 91 TI_SCI_PD_EXCLUSIVE>; -- clock-names = "clk_xin", "clk_ahb"; -- clocks = <&k3_clks 91 3>, <&k3_clks 91 0>; -+ clock-names = "clk_ahb", "clk_xin"; -+ clocks = <&k3_clks 91 0>, <&k3_clks 91 3>; - ti,otap-del-sel-legacy = <0x0>; - ti,otap-del-sel-mmc-hs = <0x0>; - ti,otap-del-sel-ddr52 = <0x6>; -@@ -409,8 +409,8 @@ main_sdhci1: mmc@4fb0000 { - reg = <0x00 0x04fb0000 0x00 0x260>, <0x00 0x4fb8000 0x00 0x134>; - interrupts = ; - power-domains = <&k3_pds 92 TI_SCI_PD_EXCLUSIVE>; -- clock-names = "clk_xin", "clk_ahb"; -- clocks = <&k3_clks 92 2>, <&k3_clks 92 1>; -+ clock-names = "clk_ahb", "clk_xin"; -+ clocks = <&k3_clks 92 1>, <&k3_clks 92 2>; - ti,otap-del-sel-legacy = <0x0>; - ti,otap-del-sel-sd-hs = <0x0>; - ti,otap-del-sel-sdr12 = <0xf>; -diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -index afb8fd7df629..7c0a8f1fca85 100644 ---- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -@@ -1071,13 +1071,13 @@ main_gpio7: gpio@631000 { - clock-names = "gpio"; - }; - -- main_sdhci0: sdhci@4f80000 { -+ main_sdhci0: mmc@4f80000 { - compatible = "ti,j721e-sdhci-8bit"; - reg = <0x0 0x4f80000 0x0 0x1000>, <0x0 0x4f88000 0x0 0x400>; - interrupts = ; - power-domains = <&k3_pds 91 TI_SCI_PD_EXCLUSIVE>; -- clock-names = "clk_xin", "clk_ahb"; -- clocks = <&k3_clks 91 1>, <&k3_clks 91 0>; -+ clock-names = "clk_ahb", "clk_xin"; -+ clocks = <&k3_clks 91 0>, <&k3_clks 91 1>; - assigned-clocks = <&k3_clks 91 1>; - assigned-clock-parents = <&k3_clks 91 2>; - bus-width = <8>; -@@ -1089,13 +1089,13 @@ main_sdhci0: sdhci@4f80000 { - dma-coherent; - }; - -- main_sdhci1: sdhci@4fb0000 { -+ main_sdhci1: mmc@4fb0000 { - compatible = "ti,j721e-sdhci-4bit"; - reg = <0x0 0x04fb0000 0x0 0x1000>, <0x0 0x4fb8000 0x0 0x400>; - interrupts = ; - power-domains = <&k3_pds 92 TI_SCI_PD_EXCLUSIVE>; -- clock-names = "clk_xin", "clk_ahb"; -- clocks = <&k3_clks 92 0>, <&k3_clks 92 5>; -+ clock-names = "clk_ahb", "clk_xin"; -+ clocks = <&k3_clks 92 5>, <&k3_clks 92 0>; - assigned-clocks = <&k3_clks 92 0>; - assigned-clock-parents = <&k3_clks 92 1>; - ti,otap-del-sel = <0x2>; -@@ -1105,13 +1105,13 @@ main_sdhci1: sdhci@4fb0000 { - no-1-8-v; - }; - -- main_sdhci2: sdhci@4f98000 { -+ main_sdhci2: mmc@4f98000 { - compatible = "ti,j721e-sdhci-4bit"; - reg = <0x0 0x4f98000 0x0 0x1000>, <0x0 0x4f90000 0x0 0x400>; - interrupts = ; - power-domains = <&k3_pds 93 TI_SCI_PD_EXCLUSIVE>; -- clock-names = "clk_xin", "clk_ahb"; -- clocks = <&k3_clks 93 0>, <&k3_clks 93 5>; -+ clock-names = "clk_ahb", "clk_xin"; -+ clocks = <&k3_clks 93 5>, <&k3_clks 93 0>; - assigned-clocks = <&k3_clks 93 0>; - assigned-clock-parents = <&k3_clks 93 1>; - ti,otap-del-sel = <0x2>; diff --git a/recipes-kernel/linux/files/patches-5.10/0007-arm64-dts-ti-k3-am65-main-Add-device_type-to-pcie-_r.patch b/recipes-kernel/linux/files/patches-5.10/0007-arm64-dts-ti-k3-am65-main-Add-device_type-to-pcie-_r.patch deleted file mode 100644 index 2a20c56af..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0007-arm64-dts-ti-k3-am65-main-Add-device_type-to-pcie-_r.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Thu, 11 Feb 2021 20:32:56 +0100 -Subject: [PATCH] arm64: dts: ti: k3-am65-main: Add device_type to pcie*_rc - nodes - -This is demanded by the parent binding of ti,am654-pcie-rc, see -Documentation/devicetree/bindings/pci/designware-pcie.txt. - -Signed-off-by: Jan Kiszka -Signed-off-by: Nishanth Menon -Reviewed-by: Kishon Vijay Abraham I -Link: https://lore.kernel.org/r/881dfd6c75423efce1d10261909939cd5ef19937.1613071976.git.jan.kiszka@siemens.com ---- - arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index 5be027228e88..57d1088f8f61 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -708,6 +708,7 @@ pcie0_rc: pcie@5500000 { - dma-coherent; - interrupts = ; - msi-map = <0x0 &gic_its 0x0 0x10000>; -+ device_type = "pci"; - }; - - pcie0_ep: pcie-ep@5500000 { -@@ -740,6 +741,7 @@ pcie1_rc: pcie@5600000 { - dma-coherent; - interrupts = ; - msi-map = <0x0 &gic_its 0x10000 0x10000>; -+ device_type = "pci"; - }; - - pcie1_ep: pcie-ep@5600000 { diff --git a/recipes-kernel/linux/files/patches-5.10/0008-arm64-dts-ti-k3-am65-main-Add-ICSSG-nodes.patch b/recipes-kernel/linux/files/patches-5.10/0008-arm64-dts-ti-k3-am65-main-Add-ICSSG-nodes.patch deleted file mode 100644 index 034ce2b83..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0008-arm64-dts-ti-k3-am65-main-Add-ICSSG-nodes.patch +++ /dev/null @@ -1,476 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Thu, 4 Mar 2021 10:07:11 -0600 -Subject: [PATCH] arm64: dts: ti: k3-am65-main: Add ICSSG nodes - -Add the DT nodes for the ICSSG0, ICSSG1 and ICSSG2 processor subsystems -that are present on the K3 AM65x SoCs. The three ICSSGs are identical -to each other for the most part, with the ICSSG2 supporting slightly -enhanced features for supporting SGMII PRU Ethernet. Each ICSSG instance -is represented by a PRUSS subsystem node. These nodes are enabled by -default. - -The ICSSGs on K3 AM65x SoCs are super-sets of the PRUSS on the AM57xx/ -6AK2G SoCs except for larger Shared Data RAM and the lack of a PRU-ICSS -crossbar. They include two auxiliary PRU cores called RTUs and few other -additional sub-modules. The interrupt integration is also different on -the K3 AM65x SoCs and are propagated through various SoC-level Interrupt -Router and Interrupt Aggregator blocks. The AM65x SR2.0 SoCs have a -revised ICSSG IP that is based off the subsequent IP used on J721E SoCs, -and has two new auxiliary PRU cores called Tx_PRUs. The Tx_PRUs have 6 KB -of IRAMs and leverage the same host interrupts as the regular PRU cores. -The Broadside (BS) RAM within each core is also sized differently w.r.t -SR1.0. - -The ICSSG subsystem node contains the entire address space. The various -sub-modules of the ICSSG are represented as individual child nodes (so -platform devices themselves) of the PRUSS subsystem node. These include -the various PRU cores and the interrupt controller. All the Data RAMs -are represented within a child node of its own named 'memories' without -any compatible. The Real Time Media Independent Interface controllers -(MII_RT and MII_G_RT), and the CFG sub-module are represented as syscon -nodes. The ICSSG CFG module has clock muxes for IEP clock and CORE clock, -these clk nodes are added under the CFG child node 'clocks'. The default -parents for these mux clocks are also assigned. - -The DT nodes use all standard properties. The regs property in the -PRU/RTU/Tx_PRU nodes define the addresses for the Instruction RAM, the -Debug and Control sub-modules for that PRU core. The firmware for each -PRU/RTU/Tx_PRU core is defined through a 'firmware-name' property. - -The default names for the firmware images for each PRU, RTU and Tx_PRU -cores are defined as follows (these can be adjusted either in derivative -board dts files or through sysfs at runtime if required): - ICSSG0 PRU0 Core : am65x-pru0_0-fw ; PRU1 Core : am65x-pru0_1-fw - ICSSG0 RTU0 Core : am65x-rtu0_0-fw ; RTU1 Core : am65x-rtu0_1-fw - ICSSG0 Tx_PRU0 Core : am65x-txpru0_0-fw ; Tx_PRU1 Core : am65x-txpru0_1-fw - ICSSG1 PRU0 Core : am65x-pru1_0-fw ; PRU1 Core : am65x-pru1_1-fw - ICSSG1 RTU0 Core : am65x-rtu1_0-fw ; RTU1 Core : am65x-rtu1_1-fw - ICSSG1 Tx_PRU0 Core : am65x-txpru1_0-fw ; Tx_PRU1 Core : am65x-txpru1_1-fw - ICSSG2 PRU0 Core : am65x-pru2_0-fw ; PRU1 Core : am65x-pru2_1-fw - ICSSG2 RTU0 Core : am65x-rtu2_0-fw ; RTU1 Core : am65x-rtu2_1-fw - ICSSG2 Tx_PRU0 Core : am65x-txpru2_0-fw ; Tx_PRU1 Core : am65x-txpru2_1-fw - -Note: -1. The ICSSG nodes are all added as per the SR2.0 device. Any sub-module IP - differences need to be handled within the driver using SoC device match - logic or separate dts/overlay files (if needs to be supported) with the - Tx_PRU nodes expected to be disabled at the minimum. -2. The ICSSG INTC on AM65x SoCs share 5, 6, 7 host interrupts with other - processors, so use the 'ti,irqs-reserved' property in derivative board - dts files _if_ any of them should not be handled by the host OS. -3. There are few more sub-modules like the Industrial Ethernet Peripherals - (IEPs), MDIO, PWM, UART that do not have bindings and so will be added - in the future. - -Signed-off-by: Suman Anna -Signed-off-by: Roger Quadros -Signed-off-by: Nishanth Menon -Reviewed-by: Vignesh Raghavendra -Link: https://lore.kernel.org/r/20210304160712.8452-2-s-anna@ti.com ---- - arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 393 +++++++++++++++++++++++ - 1 file changed, 393 insertions(+) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index 57d1088f8f61..8bf4fefd83fd 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -922,4 +922,397 @@ ehrpwm5: pwm@3050000 { - clocks = <&ehrpwm_tbclk 5>, <&k3_clks 45 0>; - clock-names = "tbclk", "fck"; - }; -+ -+ icssg0: icssg@b000000 { -+ compatible = "ti,am654-icssg"; -+ reg = <0x00 0xb000000 0x00 0x80000>; -+ power-domains = <&k3_pds 62 TI_SCI_PD_EXCLUSIVE>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x0 0x00 0xb000000 0x80000>; -+ -+ icssg0_mem: memories@0 { -+ reg = <0x0 0x2000>, -+ <0x2000 0x2000>, -+ <0x10000 0x10000>; -+ reg-names = "dram0", "dram1", -+ "shrdram2"; -+ }; -+ -+ icssg0_cfg: cfg@26000 { -+ compatible = "ti,pruss-cfg", "syscon"; -+ reg = <0x26000 0x200>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x0 0x26000 0x2000>; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ icssg0_coreclk_mux: coreclk-mux@3c { -+ reg = <0x3c>; -+ #clock-cells = <0>; -+ clocks = <&k3_clks 62 19>, /* icssg0_core_clk */ -+ <&k3_clks 62 3>; /* icssg0_iclk */ -+ assigned-clocks = <&icssg0_coreclk_mux>; -+ assigned-clock-parents = <&k3_clks 62 3>; -+ }; -+ -+ icssg0_iepclk_mux: iepclk-mux@30 { -+ reg = <0x30>; -+ #clock-cells = <0>; -+ clocks = <&k3_clks 62 10>, /* icssg0_iep_clk */ -+ <&icssg0_coreclk_mux>; /* core_clk */ -+ assigned-clocks = <&icssg0_iepclk_mux>; -+ assigned-clock-parents = <&icssg0_coreclk_mux>; -+ }; -+ }; -+ }; -+ -+ icssg0_mii_rt: mii-rt@32000 { -+ compatible = "ti,pruss-mii", "syscon"; -+ reg = <0x32000 0x100>; -+ }; -+ -+ icssg0_mii_g_rt: mii-g-rt@33000 { -+ compatible = "ti,pruss-mii-g", "syscon"; -+ reg = <0x33000 0x1000>; -+ }; -+ -+ icssg0_intc: interrupt-controller@20000 { -+ compatible = "ti,icssg-intc"; -+ reg = <0x20000 0x2000>; -+ interrupt-controller; -+ #interrupt-cells = <3>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ interrupt-names = "host_intr0", "host_intr1", -+ "host_intr2", "host_intr3", -+ "host_intr4", "host_intr5", -+ "host_intr6", "host_intr7"; -+ }; -+ -+ pru0_0: pru@34000 { -+ compatible = "ti,am654-pru"; -+ reg = <0x34000 0x4000>, -+ <0x22000 0x100>, -+ <0x22400 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-pru0_0-fw"; -+ }; -+ -+ rtu0_0: rtu@4000 { -+ compatible = "ti,am654-rtu"; -+ reg = <0x4000 0x2000>, -+ <0x23000 0x100>, -+ <0x23400 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-rtu0_0-fw"; -+ }; -+ -+ tx_pru0_0: txpru@a000 { -+ compatible = "ti,am654-tx-pru"; -+ reg = <0xa000 0x1800>, -+ <0x25000 0x100>, -+ <0x25400 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-txpru0_0-fw"; -+ }; -+ -+ pru0_1: pru@38000 { -+ compatible = "ti,am654-pru"; -+ reg = <0x38000 0x4000>, -+ <0x24000 0x100>, -+ <0x24400 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-pru0_1-fw"; -+ }; -+ -+ rtu0_1: rtu@6000 { -+ compatible = "ti,am654-rtu"; -+ reg = <0x6000 0x2000>, -+ <0x23800 0x100>, -+ <0x23c00 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-rtu0_1-fw"; -+ }; -+ -+ tx_pru0_1: txpru@c000 { -+ compatible = "ti,am654-tx-pru"; -+ reg = <0xc000 0x1800>, -+ <0x25800 0x100>, -+ <0x25c00 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-txpru0_1-fw"; -+ }; -+ }; -+ -+ icssg1: icssg@b100000 { -+ compatible = "ti,am654-icssg"; -+ reg = <0x00 0xb100000 0x00 0x80000>; -+ power-domains = <&k3_pds 63 TI_SCI_PD_EXCLUSIVE>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x0 0x00 0xb100000 0x80000>; -+ -+ icssg1_mem: memories@0 { -+ reg = <0x0 0x2000>, -+ <0x2000 0x2000>, -+ <0x10000 0x10000>; -+ reg-names = "dram0", "dram1", -+ "shrdram2"; -+ }; -+ -+ icssg1_cfg: cfg@26000 { -+ compatible = "ti,pruss-cfg", "syscon"; -+ reg = <0x26000 0x200>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x0 0x26000 0x2000>; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ icssg1_coreclk_mux: coreclk-mux@3c { -+ reg = <0x3c>; -+ #clock-cells = <0>; -+ clocks = <&k3_clks 63 19>, /* icssg1_core_clk */ -+ <&k3_clks 63 3>; /* icssg1_iclk */ -+ assigned-clocks = <&icssg1_coreclk_mux>; -+ assigned-clock-parents = <&k3_clks 63 3>; -+ }; -+ -+ icssg1_iepclk_mux: iepclk-mux@30 { -+ reg = <0x30>; -+ #clock-cells = <0>; -+ clocks = <&k3_clks 63 10>, /* icssg1_iep_clk */ -+ <&icssg1_coreclk_mux>; /* core_clk */ -+ assigned-clocks = <&icssg1_iepclk_mux>; -+ assigned-clock-parents = <&icssg1_coreclk_mux>; -+ }; -+ }; -+ }; -+ -+ icssg1_mii_rt: mii-rt@32000 { -+ compatible = "ti,pruss-mii", "syscon"; -+ reg = <0x32000 0x100>; -+ }; -+ -+ icssg1_mii_g_rt: mii-g-rt@33000 { -+ compatible = "ti,pruss-mii-g", "syscon"; -+ reg = <0x33000 0x1000>; -+ }; -+ -+ icssg1_intc: interrupt-controller@20000 { -+ compatible = "ti,icssg-intc"; -+ reg = <0x20000 0x2000>; -+ interrupt-controller; -+ #interrupt-cells = <3>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ interrupt-names = "host_intr0", "host_intr1", -+ "host_intr2", "host_intr3", -+ "host_intr4", "host_intr5", -+ "host_intr6", "host_intr7"; -+ }; -+ -+ pru1_0: pru@34000 { -+ compatible = "ti,am654-pru"; -+ reg = <0x34000 0x4000>, -+ <0x22000 0x100>, -+ <0x22400 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-pru1_0-fw"; -+ }; -+ -+ rtu1_0: rtu@4000 { -+ compatible = "ti,am654-rtu"; -+ reg = <0x4000 0x2000>, -+ <0x23000 0x100>, -+ <0x23400 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-rtu1_0-fw"; -+ }; -+ -+ tx_pru1_0: txpru@a000 { -+ compatible = "ti,am654-tx-pru"; -+ reg = <0xa000 0x1800>, -+ <0x25000 0x100>, -+ <0x25400 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-txpru1_0-fw"; -+ }; -+ -+ pru1_1: pru@38000 { -+ compatible = "ti,am654-pru"; -+ reg = <0x38000 0x4000>, -+ <0x24000 0x100>, -+ <0x24400 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-pru1_1-fw"; -+ }; -+ -+ rtu1_1: rtu@6000 { -+ compatible = "ti,am654-rtu"; -+ reg = <0x6000 0x2000>, -+ <0x23800 0x100>, -+ <0x23c00 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-rtu1_1-fw"; -+ }; -+ -+ tx_pru1_1: txpru@c000 { -+ compatible = "ti,am654-tx-pru"; -+ reg = <0xc000 0x1800>, -+ <0x25800 0x100>, -+ <0x25c00 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-txpru1_1-fw"; -+ }; -+ }; -+ -+ icssg2: icssg@b200000 { -+ compatible = "ti,am654-icssg"; -+ reg = <0x00 0xb200000 0x00 0x80000>; -+ power-domains = <&k3_pds 64 TI_SCI_PD_EXCLUSIVE>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x0 0x00 0xb200000 0x80000>; -+ -+ icssg2_mem: memories@0 { -+ reg = <0x0 0x2000>, -+ <0x2000 0x2000>, -+ <0x10000 0x10000>; -+ reg-names = "dram0", "dram1", -+ "shrdram2"; -+ }; -+ -+ icssg2_cfg: cfg@26000 { -+ compatible = "ti,pruss-cfg", "syscon"; -+ reg = <0x26000 0x200>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x0 0x26000 0x2000>; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ icssg2_coreclk_mux: coreclk-mux@3c { -+ reg = <0x3c>; -+ #clock-cells = <0>; -+ clocks = <&k3_clks 64 19>, /* icssg1_core_clk */ -+ <&k3_clks 64 3>; /* icssg1_iclk */ -+ assigned-clocks = <&icssg2_coreclk_mux>; -+ assigned-clock-parents = <&k3_clks 64 3>; -+ }; -+ -+ icssg2_iepclk_mux: iepclk-mux@30 { -+ reg = <0x30>; -+ #clock-cells = <0>; -+ clocks = <&k3_clks 64 10>, /* icssg1_iep_clk */ -+ <&icssg2_coreclk_mux>; /* core_clk */ -+ assigned-clocks = <&icssg2_iepclk_mux>; -+ assigned-clock-parents = <&icssg2_coreclk_mux>; -+ }; -+ }; -+ }; -+ -+ icssg2_mii_rt: mii-rt@32000 { -+ compatible = "ti,pruss-mii", "syscon"; -+ reg = <0x32000 0x100>; -+ }; -+ -+ icssg2_mii_g_rt: mii-g-rt@33000 { -+ compatible = "ti,pruss-mii-g", "syscon"; -+ reg = <0x33000 0x1000>; -+ }; -+ -+ icssg2_intc: interrupt-controller@20000 { -+ compatible = "ti,icssg-intc"; -+ reg = <0x20000 0x2000>; -+ interrupt-controller; -+ #interrupt-cells = <3>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ interrupt-names = "host_intr0", "host_intr1", -+ "host_intr2", "host_intr3", -+ "host_intr4", "host_intr5", -+ "host_intr6", "host_intr7"; -+ }; -+ -+ pru2_0: pru@34000 { -+ compatible = "ti,am654-pru"; -+ reg = <0x34000 0x4000>, -+ <0x22000 0x100>, -+ <0x22400 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-pru2_0-fw"; -+ }; -+ -+ rtu2_0: rtu@4000 { -+ compatible = "ti,am654-rtu"; -+ reg = <0x4000 0x2000>, -+ <0x23000 0x100>, -+ <0x23400 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-rtu2_0-fw"; -+ }; -+ -+ tx_pru2_0: txpru@a000 { -+ compatible = "ti,am654-tx-pru"; -+ reg = <0xa000 0x1800>, -+ <0x25000 0x100>, -+ <0x25400 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-txpru2_0-fw"; -+ }; -+ -+ pru2_1: pru@38000 { -+ compatible = "ti,am654-pru"; -+ reg = <0x38000 0x4000>, -+ <0x24000 0x100>, -+ <0x24400 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-pru2_1-fw"; -+ }; -+ -+ rtu2_1: rtu@6000 { -+ compatible = "ti,am654-rtu"; -+ reg = <0x6000 0x2000>, -+ <0x23800 0x100>, -+ <0x23c00 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-rtu2_1-fw"; -+ }; -+ -+ tx_pru2_1: txpru@c000 { -+ compatible = "ti,am654-tx-pru"; -+ reg = <0xc000 0x1800>, -+ <0x25800 0x100>, -+ <0x25c00 0x100>; -+ reg-names = "iram", "control", "debug"; -+ firmware-name = "am65x-txpru2_1-fw"; -+ }; -+ }; - }; diff --git a/recipes-kernel/linux/files/patches-5.10/0009-arm64-dts-ti-k3-am65-mcu-Add-RTI-watchdog-entry.patch b/recipes-kernel/linux/files/patches-5.10/0009-arm64-dts-ti-k3-am65-mcu-Add-RTI-watchdog-entry.patch deleted file mode 100644 index e08faecf1..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0009-arm64-dts-ti-k3-am65-mcu-Add-RTI-watchdog-entry.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Sat, 20 Feb 2021 13:49:51 +0100 -Subject: [PATCH] arm64: dts: ti: k3-am65-mcu: Add RTI watchdog entry - -Add the DT entry for a watchdog based on RTI1. - -On SR1.0 silicon, it requires additional firmware on the MCU R5F cores -to handle the expiry, e.g. https://github.com/siemens/k3-rti-wdt. As -this firmware will also lock the power domain to protect it against -premature shutdown, mark it shared. - -Signed-off-by: Jan Kiszka -Signed-off-by: Nishanth Menon -Acked-by: Praneeth Bajjuri -Link: https://lore.kernel.org/r/279c20fa-6e5e-4f88-9cd1-f76297a28a19@web.de ---- - arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi -index 7454c8cec0cc..0388c02c2203 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi -@@ -308,4 +308,13 @@ mcu_r5fss0_core1: r5f@41400000 { - ti,loczrama = <1>; - }; - }; -+ -+ mcu_rti1: watchdog@40610000 { -+ compatible = "ti,j7-rti-wdt"; -+ reg = <0x0 0x40610000 0x0 0x100>; -+ clocks = <&k3_clks 135 0>; -+ power-domains = <&k3_pds 135 TI_SCI_PD_SHARED>; -+ assigned-clocks = <&k3_clks 135 0>; -+ assigned-clock-parents = <&k3_clks 135 4>; -+ }; - }; diff --git a/recipes-kernel/linux/files/patches-5.10/0010-arm64-dts-ti-Add-support-for-Siemens-IOT2050-boards.patch b/recipes-kernel/linux/files/patches-5.10/0010-arm64-dts-ti-Add-support-for-Siemens-IOT2050-boards.patch deleted file mode 100644 index 392508a4b..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0010-arm64-dts-ti-Add-support-for-Siemens-IOT2050-boards.patch +++ /dev/null @@ -1,836 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Thu, 11 Mar 2021 15:33:43 +0100 -Subject: [PATCH] arm64: dts: ti: Add support for Siemens IOT2050 boards - -Add support for two Siemens SIMATIC IOT2050 variants, Basic and -Advanced. They are based on the TI AM6528 GP and AM6548 SOCs HS, thus -differ in their number of cores and availability of security features. -Furthermore the Advanced version comes with more RAM, an eMMC and a few -internal differences. - -Based on original version by Le Jin. - -Signed-off-by: Jan Kiszka -Signed-off-by: Nishanth Menon -Reviewed-by: Vignesh Raghavendra -Link: https://new.siemens.com/global/en/products/automation/pc-based/iot-gateways/simatic-iot2050.html -Link: https://github.com/siemens/meta-iot2050 -Link: https://lore.kernel.org/r/4fb05969102d14d230e03ca4312ef9706efa61e6.1615473223.git.jan.kiszka@siemens.com ---- - arch/arm64/boot/dts/ti/Makefile | 2 + - .../boot/dts/ti/k3-am65-iot2050-common.dtsi | 655 ++++++++++++++++++ - .../boot/dts/ti/k3-am6528-iot2050-basic.dts | 61 ++ - .../dts/ti/k3-am6548-iot2050-advanced.dts | 60 ++ - 4 files changed, 778 insertions(+) - create mode 100644 arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi - create mode 100644 arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts - create mode 100644 arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts - -diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile -index 65506f21ba30..22108491f16e 100644 ---- a/arch/arm64/boot/dts/ti/Makefile -+++ b/arch/arm64/boot/dts/ti/Makefile -@@ -7,6 +7,8 @@ - # - - dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board.dtb -+dtb-$(CONFIG_ARCH_K3) += k3-am6528-iot2050-basic.dtb -+dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced.dtb - - dtb-$(CONFIG_ARCH_K3) += k3-j721e-common-proc-board.dtb - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -new file mode 100644 -index 000000000000..de763ca9251c ---- /dev/null -+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -@@ -0,0 +1,655 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) Siemens AG, 2018-2021 -+ * -+ * Authors: -+ * Le Jin -+ * Jan Kiszka -+ * -+ * Common bits of the IOT2050 Basic and Advanced variants -+ */ -+ -+/dts-v1/; -+ -+#include "k3-am654.dtsi" -+#include -+ -+/ { -+ aliases { -+ spi0 = &mcu_spi0; -+ }; -+ -+ chosen { -+ stdout-path = "serial3:115200n8"; -+ bootargs = "earlycon=ns16550a,mmio32,0x02810000"; -+ }; -+ -+ reserved-memory { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ secure_ddr: secure-ddr@9e800000 { -+ reg = <0 0x9e800000 0 0x01800000>; /* for OP-TEE */ -+ alignment = <0x1000>; -+ no-map; -+ }; -+ -+ mcu_r5fss0_core0_dma_memory_region: r5f-dma-memory@a0000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0 0xa0000000 0 0x100000>; -+ no-map; -+ }; -+ -+ mcu_r5fss0_core0_memory_region: r5f-memory@a0100000 { -+ compatible = "shared-dma-pool"; -+ reg = <0 0xa0100000 0 0xf00000>; -+ no-map; -+ }; -+ -+ mcu_r5fss0_core1_dma_memory_region: r5f-dma-memory@a1000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0 0xa1000000 0 0x100000>; -+ no-map; -+ }; -+ -+ mcu_r5fss0_core1_memory_region: r5f-memory@a1100000 { -+ compatible = "shared-dma-pool"; -+ reg = <0 0xa1100000 0 0xf00000>; -+ no-map; -+ }; -+ -+ rtos_ipc_memory_region: ipc-memories@a2000000 { -+ reg = <0x00 0xa2000000 0x00 0x00200000>; -+ alignment = <0x1000>; -+ no-map; -+ }; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&leds_pins_default>; -+ -+ status-led-red { -+ gpios = <&wkup_gpio0 32 GPIO_ACTIVE_HIGH>; -+ panic-indicator; -+ }; -+ -+ status-led-green { -+ gpios = <&wkup_gpio0 24 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ user-led1-red { -+ gpios = <&pcal9535_3 14 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ user-led1-green { -+ gpios = <&pcal9535_2 15 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ user-led2-red { -+ gpios = <&wkup_gpio0 17 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ user-led2-green { -+ gpios = <&wkup_gpio0 22 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ -+ dp_refclk: clock { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <19200000>; -+ }; -+}; -+ -+&wkup_pmx0 { -+ wkup_i2c0_pins_default: wkup-i2c0-pins-default { -+ pinctrl-single,pins = < -+ /* (AC7) WKUP_I2C0_SCL */ -+ AM65X_WKUP_IOPAD(0x00e0, PIN_INPUT, 0) -+ /* (AD6) WKUP_I2C0_SDA */ -+ AM65X_WKUP_IOPAD(0x00e4, PIN_INPUT, 0) -+ >; -+ }; -+ -+ mcu_i2c0_pins_default: mcu-i2c0-pins-default { -+ pinctrl-single,pins = < -+ /* (AD8) MCU_I2C0_SCL */ -+ AM65X_WKUP_IOPAD(0x00e8, PIN_INPUT, 0) -+ /* (AD7) MCU_I2C0_SDA */ -+ AM65X_WKUP_IOPAD(0x00ec, PIN_INPUT, 0) -+ >; -+ }; -+ -+ arduino_i2c_aio_switch_pins_default: arduino-i2c-aio-switch-pins-default { -+ pinctrl-single,pins = < -+ /* (R2) WKUP_GPIO0_21 */ -+ AM65X_WKUP_IOPAD(0x0024, PIN_OUTPUT, 7) -+ >; -+ }; -+ -+ push_button_pins_default: push-button-pins-default { -+ pinctrl-single,pins = < -+ /* (T1) MCU_OSPI1_CLK.WKUP_GPIO0_25 */ -+ AM65X_WKUP_IOPAD(0x0034, PIN_INPUT, 7) -+ >; -+ }; -+ -+ arduino_uart_pins_default: arduino-uart-pins-default { -+ pinctrl-single,pins = < -+ /* (P4) MCU_UART0_RXD */ -+ AM65X_WKUP_IOPAD(0x0044, PIN_INPUT, 4) -+ /* (P5) MCU_UART0_TXD */ -+ AM65X_WKUP_IOPAD(0x0048, PIN_OUTPUT, 4) -+ >; -+ }; -+ -+ arduino_io_d2_to_d3_pins_default: arduino-io-d2-to-d3-pins-default { -+ pinctrl-single,pins = < -+ /* (P1) WKUP_GPIO0_31 */ -+ AM65X_WKUP_IOPAD(0x004C, PIN_OUTPUT, 7) -+ /* (N3) WKUP_GPIO0_33 */ -+ AM65X_WKUP_IOPAD(0x0054, PIN_OUTPUT, 7) -+ >; -+ }; -+ -+ arduino_io_oe_pins_default: arduino-io-oe-pins-default { -+ pinctrl-single,pins = < -+ /* (N4) WKUP_GPIO0_34 */ -+ AM65X_WKUP_IOPAD(0x0058, PIN_OUTPUT, 7) -+ /* (M2) WKUP_GPIO0_36 */ -+ AM65X_WKUP_IOPAD(0x0060, PIN_OUTPUT, 7) -+ /* (M3) WKUP_GPIO0_37 */ -+ AM65X_WKUP_IOPAD(0x0064, PIN_OUTPUT, 7) -+ /* (M4) WKUP_GPIO0_38 */ -+ AM65X_WKUP_IOPAD(0x0068, PIN_OUTPUT, 7) -+ /* (M1) WKUP_GPIO0_41 */ -+ AM65X_WKUP_IOPAD(0x0074, PIN_OUTPUT, 7) -+ >; -+ }; -+ -+ mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins-default { -+ pinctrl-single,pins = < -+ /* (V1) MCU_OSPI0_CLK */ -+ AM65X_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) -+ /* (U2) MCU_OSPI0_DQS */ -+ AM65X_WKUP_IOPAD(0x0008, PIN_INPUT, 0) -+ /* (U4) MCU_OSPI0_D0 */ -+ AM65X_WKUP_IOPAD(0x000c, PIN_INPUT, 0) -+ /* (U5) MCU_OSPI0_D1 */ -+ AM65X_WKUP_IOPAD(0x0010, PIN_INPUT, 0) -+ /* (R4) MCU_OSPI0_CSn0 */ -+ AM65X_WKUP_IOPAD(0x002c, PIN_OUTPUT, 0) -+ >; -+ }; -+ -+ db9_com_mode_pins_default: db9-com-mode-pins-default { -+ pinctrl-single,pins = < -+ /* (AD3) WKUP_GPIO0_5, used as uart0 mode 0 */ -+ AM65X_WKUP_IOPAD(0x00c4, PIN_OUTPUT, 7) -+ /* (AC3) WKUP_GPIO0_4, used as uart0 mode 1 */ -+ AM65X_WKUP_IOPAD(0x00c0, PIN_OUTPUT, 7) -+ /* (AC1) WKUP_GPIO0_7, used as uart0 term */ -+ AM65X_WKUP_IOPAD(0x00cc, PIN_OUTPUT, 7) -+ /* (AC2) WKUP_GPIO0_6, used as uart0 en */ -+ AM65X_WKUP_IOPAD(0x00c8, PIN_OUTPUT, 7) -+ >; -+ }; -+ -+ leds_pins_default: leds-pins-default { -+ pinctrl-single,pins = < -+ /* (T2) WKUP_GPIO0_17, used as user led1 red */ -+ AM65X_WKUP_IOPAD(0x0014, PIN_OUTPUT, 7) -+ /* (R3) WKUP_GPIO0_22, used as user led1 green */ -+ AM65X_WKUP_IOPAD(0x0028, PIN_OUTPUT, 7) -+ /* (R5) WKUP_GPIO0_24, used as status led red */ -+ AM65X_WKUP_IOPAD(0x0030, PIN_OUTPUT, 7) -+ /* (N2) WKUP_GPIO0_32, used as status led green */ -+ AM65X_WKUP_IOPAD(0x0050, PIN_OUTPUT, 7) -+ >; -+ }; -+ -+ mcu_spi0_pins_default: mcu-spi0-pins-default { -+ pinctrl-single,pins = < -+ /* (Y1) MCU_SPI0_CLK */ -+ AM65X_WKUP_IOPAD(0x0090, PIN_INPUT, 0) -+ /* (Y3) MCU_SPI0_D0 */ -+ AM65X_WKUP_IOPAD(0x0094, PIN_INPUT, 0) -+ /* (Y2) MCU_SPI0_D1 */ -+ AM65X_WKUP_IOPAD(0x0098, PIN_INPUT, 0) -+ /* (Y4) MCU_SPI0_CS0 */ -+ AM65X_WKUP_IOPAD(0x009c, PIN_OUTPUT, 0) -+ >; -+ }; -+ -+ minipcie_pins_default: minipcie-pins-default { -+ pinctrl-single,pins = < -+ /* (P2) MCU_OSPI1_DQS.WKUP_GPIO0_27 */ -+ AM65X_WKUP_IOPAD(0x003C, PIN_OUTPUT, 7) -+ >; -+ }; -+}; -+ -+&main_pmx0 { -+ main_uart1_pins_default: main-uart1-pins-default { -+ pinctrl-single,pins = < -+ AM65X_IOPAD(0x0174, PIN_INPUT, 6) /* (AE23) UART1_RXD */ -+ AM65X_IOPAD(0x014c, PIN_OUTPUT, 6) /* (AD23) UART1_TXD */ -+ AM65X_IOPAD(0x0178, PIN_INPUT, 6) /* (AD22) UART1_CTSn */ -+ AM65X_IOPAD(0x017c, PIN_OUTPUT, 6) /* (AC21) UART1_RTSn */ -+ >; -+ }; -+ -+ main_i2c3_pins_default: main-i2c3-pins-default { -+ pinctrl-single,pins = < -+ AM65X_IOPAD(0x01c0, PIN_INPUT, 2) /* (AF13) I2C3_SCL */ -+ AM65X_IOPAD(0x01d4, PIN_INPUT, 2) /* (AG12) I2C3_SDA */ -+ >; -+ }; -+ -+ main_mmc1_pins_default: main-mmc1-pins-default { -+ pinctrl-single,pins = < -+ AM65X_IOPAD(0x02d4, PIN_INPUT_PULLDOWN, 0) /* (C27) MMC1_CLK */ -+ AM65X_IOPAD(0x02d8, PIN_INPUT_PULLUP, 0) /* (C28) MMC1_CMD */ -+ AM65X_IOPAD(0x02d0, PIN_INPUT_PULLUP, 0) /* (D28) MMC1_DAT0 */ -+ AM65X_IOPAD(0x02cc, PIN_INPUT_PULLUP, 0) /* (E27) MMC1_DAT1 */ -+ AM65X_IOPAD(0x02c8, PIN_INPUT_PULLUP, 0) /* (D26) MMC1_DAT2 */ -+ AM65X_IOPAD(0x02c4, PIN_INPUT_PULLUP, 0) /* (D27) MMC1_DAT3 */ -+ AM65X_IOPAD(0x02dc, PIN_INPUT_PULLUP, 0) /* (B24) MMC1_SDCD */ -+ AM65X_IOPAD(0x02e0, PIN_INPUT_PULLUP, 0) /* (C24) MMC1_SDWP */ -+ >; -+ }; -+ -+ usb0_pins_default: usb0-pins-default { -+ pinctrl-single,pins = < -+ AM65X_IOPAD(0x02bc, PIN_OUTPUT, 0) /* (AD9) USB0_DRVVBUS */ -+ >; -+ }; -+ -+ usb1_pins_default: usb1-pins-default { -+ pinctrl-single,pins = < -+ AM65X_IOPAD(0x02c0, PIN_OUTPUT, 0) /* (AC8) USB1_DRVVBUS */ -+ >; -+ }; -+ -+ arduino_io_d4_to_d9_pins_default: arduino-io-d4-to-d9-pins-default { -+ pinctrl-single,pins = < -+ AM65X_IOPAD(0x0084, PIN_OUTPUT, 7) /* (AG18) GPIO0_33 */ -+ AM65X_IOPAD(0x008C, PIN_OUTPUT, 7) /* (AF17) GPIO0_35 */ -+ AM65X_IOPAD(0x0098, PIN_OUTPUT, 7) /* (AH16) GPIO0_38 */ -+ AM65X_IOPAD(0x00AC, PIN_OUTPUT, 7) /* (AH15) GPIO0_43 */ -+ AM65X_IOPAD(0x00C0, PIN_OUTPUT, 7) /* (AG15) GPIO0_48 */ -+ AM65X_IOPAD(0x00CC, PIN_OUTPUT, 7) /* (AD15) GPIO0_51 */ -+ >; -+ }; -+ -+ dss_vout1_pins_default: dss-vout1-pins-default { -+ pinctrl-single,pins = < -+ AM65X_IOPAD(0x0000, PIN_OUTPUT, 1) /* VOUT1_DATA0 */ -+ AM65X_IOPAD(0x0004, PIN_OUTPUT, 1) /* VOUT1_DATA1 */ -+ AM65X_IOPAD(0x0008, PIN_OUTPUT, 1) /* VOUT1_DATA2 */ -+ AM65X_IOPAD(0x000c, PIN_OUTPUT, 1) /* VOUT1_DATA3 */ -+ AM65X_IOPAD(0x0010, PIN_OUTPUT, 1) /* VOUT1_DATA4 */ -+ AM65X_IOPAD(0x0014, PIN_OUTPUT, 1) /* VOUT1_DATA5 */ -+ AM65X_IOPAD(0x0018, PIN_OUTPUT, 1) /* VOUT1_DATA6 */ -+ AM65X_IOPAD(0x001c, PIN_OUTPUT, 1) /* VOUT1_DATA7 */ -+ AM65X_IOPAD(0x0020, PIN_OUTPUT, 1) /* VOUT1_DATA8 */ -+ AM65X_IOPAD(0x0024, PIN_OUTPUT, 1) /* VOUT1_DATA9 */ -+ AM65X_IOPAD(0x0028, PIN_OUTPUT, 1) /* VOUT1_DATA10 */ -+ AM65X_IOPAD(0x002c, PIN_OUTPUT, 1) /* VOUT1_DATA11 */ -+ AM65X_IOPAD(0x0030, PIN_OUTPUT, 1) /* VOUT1_DATA12 */ -+ AM65X_IOPAD(0x0034, PIN_OUTPUT, 1) /* VOUT1_DATA13 */ -+ AM65X_IOPAD(0x0038, PIN_OUTPUT, 1) /* VOUT1_DATA14 */ -+ AM65X_IOPAD(0x003c, PIN_OUTPUT, 1) /* VOUT1_DATA15 */ -+ AM65X_IOPAD(0x0040, PIN_OUTPUT, 1) /* VOUT1_DATA16 */ -+ AM65X_IOPAD(0x0044, PIN_OUTPUT, 1) /* VOUT1_DATA17 */ -+ AM65X_IOPAD(0x0048, PIN_OUTPUT, 1) /* VOUT1_DATA18 */ -+ AM65X_IOPAD(0x004c, PIN_OUTPUT, 1) /* VOUT1_DATA19 */ -+ AM65X_IOPAD(0x0050, PIN_OUTPUT, 1) /* VOUT1_DATA20 */ -+ AM65X_IOPAD(0x0054, PIN_OUTPUT, 1) /* VOUT1_DATA21 */ -+ AM65X_IOPAD(0x0058, PIN_OUTPUT, 1) /* VOUT1_DATA22 */ -+ AM65X_IOPAD(0x005c, PIN_OUTPUT, 1) /* VOUT1_DATA23 */ -+ AM65X_IOPAD(0x0060, PIN_OUTPUT, 1) /* VOUT1_VSYNC */ -+ AM65X_IOPAD(0x0064, PIN_OUTPUT, 1) /* VOUT1_HSYNC */ -+ AM65X_IOPAD(0x0068, PIN_OUTPUT, 1) /* VOUT1_PCLK */ -+ AM65X_IOPAD(0x006c, PIN_OUTPUT, 1) /* VOUT1_DE */ -+ >; -+ }; -+ -+ dp_pins_default: dp-pins-default { -+ pinctrl-single,pins = < -+ AM65X_IOPAD(0x0078, PIN_OUTPUT, 7) /* (AF18) DP rst_n */ -+ >; -+ }; -+ -+ main_i2c2_pins_default: main-i2c2-pins-default { -+ pinctrl-single,pins = < -+ AM65X_IOPAD(0x0074, PIN_INPUT, 5) /* (T27) I2C2_SCL */ -+ AM65X_IOPAD(0x0070, PIN_INPUT, 5) /* (R25) I2C2_SDA */ -+ >; -+ }; -+}; -+ -+&main_pmx1 { -+ main_i2c0_pins_default: main-i2c0-pins-default { -+ pinctrl-single,pins = < -+ AM65X_IOPAD(0x0000, PIN_INPUT, 0) /* (D20) I2C0_SCL */ -+ AM65X_IOPAD(0x0004, PIN_INPUT, 0) /* (C21) I2C0_SDA */ -+ >; -+ }; -+ -+ main_i2c1_pins_default: main-i2c1-pins-default { -+ pinctrl-single,pins = < -+ AM65X_IOPAD(0x0008, PIN_INPUT, 0) /* (B21) I2C1_SCL */ -+ AM65X_IOPAD(0x000c, PIN_INPUT, 0) /* (E21) I2C1_SDA */ -+ >; -+ }; -+ -+ ecap0_pins_default: ecap0-pins-default { -+ pinctrl-single,pins = < -+ AM65X_IOPAD(0x0010, PIN_INPUT, 0) /* (D21) ECAP0_IN_APWM_OUT */ -+ >; -+ }; -+}; -+ -+&wkup_uart0 { -+ /* Wakeup UART is used by System firmware */ -+ status = "reserved"; -+}; -+ -+&main_uart1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&main_uart1_pins_default>; -+}; -+ -+&main_uart2 { -+ status = "disabled"; -+}; -+ -+&mcu_uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&arduino_uart_pins_default>; -+}; -+ -+&main_gpio0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&arduino_io_d4_to_d9_pins_default>; -+ gpio-line-names = -+ "main_gpio0-base", "", "", "", "", "", "", "", "", "", -+ "", "", "", "", "", "", "", "", "", "", -+ "", "", "", "", "", "", "", "", "", "", -+ "", "", "", "IO4", "", "IO5", "", "", "IO6", "", -+ "", "", "", "IO7", "", "", "", "", "IO8", "", -+ "", "IO9"; -+}; -+ -+&wkup_gpio0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = < -+ &arduino_io_d2_to_d3_pins_default -+ &arduino_i2c_aio_switch_pins_default -+ &arduino_io_oe_pins_default -+ &push_button_pins_default -+ &db9_com_mode_pins_default -+ >; -+ gpio-line-names = -+ /* 0..9 */ -+ "wkup_gpio0-base", "", "", "", "UART0-mode1", "UART0-mode0", -+ "UART0-enable", "UART0-terminate", "", "WIFI-disable", -+ /* 10..19 */ -+ "", "", "", "", "", "", "", "", "", "", -+ /* 20..29 */ -+ "", "A4A5-I2C-mux", "", "", "", "USER-button", "", "", "","IO0", -+ /* 30..39 */ -+ "IO1", "IO2", "", "IO3", "IO17-direction", "A5", -+ "IO16-direction", "IO15-direction", "IO14-direction", "A3", -+ /* 40..49 */ -+ "", "IO18-direction", "A4", "A2", "A1", "A0", "", "", "IO13", -+ "IO11", -+ /* 50..51 */ -+ "IO12", "IO10"; -+}; -+ -+&wkup_i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wkup_i2c0_pins_default>; -+ clock-frequency = <400000>; -+}; -+ -+&mcu_i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcu_i2c0_pins_default>; -+ clock-frequency = <400000>; -+ -+ psu: regulator@60 { -+ compatible = "ti,tps62363"; -+ reg = <0x60>; -+ regulator-name = "tps62363-vout"; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <1500000>; -+ regulator-boot-on; -+ ti,vsel0-state-high; -+ ti,vsel1-state-high; -+ ti,enable-vout-discharge; -+ }; -+ -+ /* D4200 */ -+ pcal9535_1: gpio@20 { -+ compatible = "nxp,pcal9535"; -+ reg = <0x20>; -+ #gpio-cells = <2>; -+ gpio-controller; -+ gpio-line-names = -+ "A0-pull", "A1-pull", "A2-pull", "A3-pull", "A4-pull", -+ "A5-pull", "", "", -+ "IO14-enable", "IO15-enable", "IO16-enable", -+ "IO17-enable", "IO18-enable", "IO19-enable"; -+ }; -+ -+ /* D4201 */ -+ pcal9535_2: gpio@21 { -+ compatible = "nxp,pcal9535"; -+ reg = <0x21>; -+ #gpio-cells = <2>; -+ gpio-controller; -+ gpio-line-names = -+ "IO0-direction", "IO1-direction", "IO2-direction", -+ "IO3-direction", "IO4-direction", "IO5-direction", -+ "IO6-direction", "IO7-direction", -+ "IO8-direction", "IO9-direction", "IO10-direction", -+ "IO11-direction", "IO12-direction", "IO13-direction", -+ "IO19-direction"; -+ }; -+ -+ /* D4202 */ -+ pcal9535_3: gpio@25 { -+ compatible = "nxp,pcal9535"; -+ reg = <0x25>; -+ #gpio-cells = <2>; -+ gpio-controller; -+ gpio-line-names = -+ "IO0-pull", "IO1-pull", "IO2-pull", "IO3-pull", -+ "IO4-pull", "IO5-pull", "IO6-pull", "IO7-pull", -+ "IO8-pull", "IO9-pull", "IO10-pull", "IO11-pull", -+ "IO12-pull", "IO13-pull"; -+ }; -+}; -+ -+&main_i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&main_i2c0_pins_default>; -+ clock-frequency = <400000>; -+ -+ rtc: rtc8564@51 { -+ compatible = "nxp,pcf8563"; -+ reg = <0x51>; -+ }; -+ -+ eeprom: eeprom@54 { -+ compatible = "atmel,24c08"; -+ reg = <0x54>; -+ pagesize = <16>; -+ }; -+}; -+ -+&main_i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&main_i2c1_pins_default>; -+ clock-frequency = <400000>; -+}; -+ -+&main_i2c2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&main_i2c2_pins_default>; -+ clock-frequency = <400000>; -+}; -+ -+&main_i2c3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&main_i2c3_pins_default>; -+ clock-frequency = <400000>; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ edp-bridge@f { -+ compatible = "toshiba,tc358767"; -+ reg = <0x0f>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&dp_pins_default>; -+ reset-gpios = <&main_gpio0 30 GPIO_ACTIVE_HIGH>; -+ -+ clock-names = "ref"; -+ clocks = <&dp_refclk>; -+ -+ toshiba,hpd-pin = <0>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@1 { -+ reg = <1>; -+ -+ bridge_in: endpoint { -+ remote-endpoint = <&dpi_out>; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&mcu_cpsw { -+ status = "disabled"; -+}; -+ -+&ecap0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ecap0_pins_default>; -+}; -+ -+&sdhci1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&main_mmc1_pins_default>; -+ ti,driver-strength-ohm = <50>; -+ disable-wp; -+}; -+ -+&usb0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb0_pins_default>; -+ dr_mode = "host"; -+}; -+ -+&usb1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb1_pins_default>; -+ dr_mode = "host"; -+}; -+ -+&mcu_spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcu_spi0_pins_default>; -+ -+ #address-cells = <1>; -+ #size-cells= <0>; -+ ti,pindir-d0-out-d1-in = <1>; -+}; -+ -+&tscadc0 { -+ status = "disabled"; -+}; -+ -+&tscadc1 { -+ adc { -+ ti,adc-channels = <0 1 2 3 4 5>; -+ }; -+}; -+ -+&ospi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcu_fss0_ospi0_pins_default>; -+ -+ flash@0 { -+ compatible = "jedec,spi-nor"; -+ reg = <0x0>; -+ spi-tx-bus-width = <1>; -+ spi-rx-bus-width = <1>; -+ spi-max-frequency = <50000000>; -+ cdns,tshsl-ns = <60>; -+ cdns,tsd2d-ns = <60>; -+ cdns,tchsh-ns = <60>; -+ cdns,tslch-ns = <60>; -+ cdns,read-delay = <2>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ }; -+}; -+ -+&dss { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&dss_vout1_pins_default>; -+ -+ assigned-clocks = <&k3_clks 67 2>; -+ assigned-clock-parents = <&k3_clks 67 5>; -+}; -+ -+&dss_ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ port@1 { -+ reg = <1>; -+ -+ dpi_out: endpoint { -+ remote-endpoint = <&bridge_in>; -+ }; -+ }; -+}; -+ -+&serdes0 { -+ status = "disabled"; -+}; -+ -+&pcie0_rc { -+ status = "disabled"; -+}; -+ -+&pcie0_ep { -+ status = "disabled"; -+}; -+ -+&pcie1_rc { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&minipcie_pins_default>; -+ -+ num-lanes = <1>; -+ phys = <&serdes1 PHY_TYPE_PCIE 0>; -+ phy-names = "pcie-phy0"; -+ reset-gpios = <&wkup_gpio0 27 GPIO_ACTIVE_HIGH>; -+}; -+ -+&pcie1_ep { -+ status = "disabled"; -+}; -diff --git a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts -new file mode 100644 -index 000000000000..4f7e3f2a6265 ---- /dev/null -+++ b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts -@@ -0,0 +1,61 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) Siemens AG, 2018-2021 -+ * -+ * Authors: -+ * Le Jin -+ * Jan Kiszka -+ * -+ * AM6528-based (dual-core) IOT2050 Basic variant -+ * 1 GB RAM, no eMMC, main_uart0 on connector X30 -+ */ -+ -+/dts-v1/; -+ -+#include "k3-am65-iot2050-common.dtsi" -+ -+/ { -+ compatible = "siemens,iot2050-basic", "ti,am654"; -+ model = "SIMATIC IOT2050 Basic"; -+ -+ memory@80000000 { -+ device_type = "memory"; -+ /* 1G RAM */ -+ reg = <0x00000000 0x80000000 0x00000000 0x40000000>; -+ }; -+ -+ cpus { -+ cpu-map { -+ /delete-node/ cluster1; -+ }; -+ /delete-node/ cpu@100; -+ /delete-node/ cpu@101; -+ }; -+ -+ /delete-node/ l2-cache1; -+}; -+ -+/* eMMC */ -+&sdhci0 { -+ status = "disabled"; -+}; -+ -+&main_pmx0 { -+ main_uart0_pins_default: main-uart0-pins-default { -+ pinctrl-single,pins = < -+ AM65X_IOPAD(0x01e4, PIN_INPUT, 0) /* (AF11) UART0_RXD */ -+ AM65X_IOPAD(0x01e8, PIN_OUTPUT, 0) /* (AE11) UART0_TXD */ -+ AM65X_IOPAD(0x01ec, PIN_INPUT, 0) /* (AG11) UART0_CTSn */ -+ AM65X_IOPAD(0x01f0, PIN_OUTPUT, 0) /* (AD11) UART0_RTSn */ -+ AM65X_IOPAD(0x0188, PIN_INPUT, 1) /* (D25) UART0_DCDn */ -+ AM65X_IOPAD(0x018c, PIN_INPUT, 1) /* (B26) UART0_DSRn */ -+ AM65X_IOPAD(0x0190, PIN_OUTPUT, 1) /* (A24) UART0_DTRn */ -+ AM65X_IOPAD(0x0194, PIN_INPUT, 1) /* (E24) UART0_RIN */ -+ >; -+ }; -+}; -+ -+&main_uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&main_uart0_pins_default>; -+}; -diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts -new file mode 100644 -index 000000000000..ec9617c13cdb ---- /dev/null -+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts -@@ -0,0 +1,60 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) Siemens AG, 2018-2021 -+ * -+ * Authors: -+ * Le Jin -+ * Jan Kiszka -+ * -+ * AM6548-based (quad-core) IOT2050 Advanced variant -+ * 2 GB RAM, 16 GB eMMC, USB-serial converter on connector X30 -+ */ -+ -+/dts-v1/; -+ -+#include "k3-am65-iot2050-common.dtsi" -+ -+/ { -+ compatible = "siemens,iot2050-advanced", "ti,am654"; -+ model = "SIMATIC IOT2050 Advanced"; -+ -+ memory@80000000 { -+ device_type = "memory"; -+ /* 2G RAM */ -+ reg = <0x00000000 0x80000000 0x00000000 0x80000000>; -+ }; -+}; -+ -+&main_pmx0 { -+ main_mmc0_pins_default: main-mmc0-pins-default { -+ pinctrl-single,pins = < -+ AM65X_IOPAD(0x01a8, PIN_INPUT_PULLDOWN, 0) /* (B25) MMC0_CLK */ -+ AM65X_IOPAD(0x01ac, PIN_INPUT_PULLUP, 0) /* (B27) MMC0_CMD */ -+ AM65X_IOPAD(0x01a4, PIN_INPUT_PULLUP, 0) /* (A26) MMC0_DAT0 */ -+ AM65X_IOPAD(0x01a0, PIN_INPUT_PULLUP, 0) /* (E25) MMC0_DAT1 */ -+ AM65X_IOPAD(0x019c, PIN_INPUT_PULLUP, 0) /* (C26) MMC0_DAT2 */ -+ AM65X_IOPAD(0x0198, PIN_INPUT_PULLUP, 0) /* (A25) MMC0_DAT3 */ -+ AM65X_IOPAD(0x0194, PIN_INPUT_PULLUP, 0) /* (E24) MMC0_DAT4 */ -+ AM65X_IOPAD(0x0190, PIN_INPUT_PULLUP, 0) /* (A24) MMC0_DAT5 */ -+ AM65X_IOPAD(0x018c, PIN_INPUT_PULLUP, 0) /* (B26) MMC0_DAT6 */ -+ AM65X_IOPAD(0x0188, PIN_INPUT_PULLUP, 0) /* (D25) MMC0_DAT7 */ -+ AM65X_IOPAD(0x01b8, PIN_OUTPUT_PULLUP, 7) /* (B23) MMC0_SDWP */ -+ AM65X_IOPAD(0x01b4, PIN_INPUT_PULLUP, 0) /* (A23) MMC0_SDCD */ -+ AM65X_IOPAD(0x01b0, PIN_INPUT, 0) /* (C25) MMC0_DS */ -+ >; -+ }; -+}; -+ -+/* eMMC */ -+&sdhci0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&main_mmc0_pins_default>; -+ bus-width = <8>; -+ non-removable; -+ ti,driver-strength-ohm = <50>; -+ disable-wp; -+}; -+ -+&main_uart0 { -+ status = "disabled"; -+}; diff --git a/recipes-kernel/linux/files/patches-5.10/0011-arm64-dts-ti-k3-am65-j721e-am64-Map-the-dma-navigato.patch b/recipes-kernel/linux/files/patches-5.10/0011-arm64-dts-ti-k3-am65-j721e-am64-Map-the-dma-navigato.patch deleted file mode 100644 index a86fac958..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0011-arm64-dts-ti-k3-am65-j721e-am64-Map-the-dma-navigato.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Mon, 10 May 2021 09:54:29 -0500 -Subject: [PATCH] arm64: dts: ti: k3-am65|j721e|am64: Map the dma / navigator - subsystem via explicit ranges - -Instead of using empty ranges property, lets map explicitly the address -range that is mapped onto the dma / navigator subsystems (navss/dmss). - -This is also exposed via the dtbs_check with dt-schema newer than -2021.03 version by throwing out following: -arch/arm64/boot/dts/ti/k3-am654-base-board.dt.yaml: bus@100000: main-navss: -{'type': 'object'} is not allowed for -{'compatible': ['simple-mfd'], '#address-cells': [[2]], ..... - -This has already been correctly done for J7200, however was missed for -other k3 SoCs. Fix that oversight. - -Signed-off-by: Nishanth Menon -Reviewed-by: Tero Kristo -Acked-by: Vignesh Raghavendra -Link: https://lore.kernel.org/r/20210510145429.8752-1-nm@ti.com -[Jan: drop am64 bits] -Signed-off-by: Jan Kiszka ---- - arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 4 ++-- - arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi | 4 ++-- - arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 4 ++-- - arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi | 4 ++-- - 4 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index 8bf4fefd83fd..dcd1d8fe6c9f 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -446,11 +446,11 @@ intr_main_gpio: interrupt-controller0 { - ti,interrupt-ranges = <0 392 32>; - }; - -- main-navss { -+ main_navss: bus@30800000 { - compatible = "simple-mfd"; - #address-cells = <2>; - #size-cells = <2>; -- ranges; -+ ranges = <0x0 0x30800000 0x0 0x30800000 0x0 0xbc00000>; - dma-coherent; - dma-ranges; - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi -index 0388c02c2203..f5b8ef2f5f77 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi -@@ -116,11 +116,11 @@ adc { - }; - }; - -- mcu-navss { -+ mcu_navss: bus@28380000 { - compatible = "simple-mfd"; - #address-cells = <2>; - #size-cells = <2>; -- ranges; -+ ranges = <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>; - dma-coherent; - dma-ranges; - -diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -index 7c0a8f1fca85..4c3ee45bdcf9 100644 ---- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -@@ -136,11 +136,11 @@ main_gpio_intr: interrupt-controller0 { - ti,interrupt-ranges = <8 392 56>; - }; - -- main-navss { -+ main_navss: bus@30000000 { - compatible = "simple-mfd"; - #address-cells = <2>; - #size-cells = <2>; -- ranges; -+ ranges = <0x00 0x30000000 0x00 0x30000000 0x00 0x0c400000>; - dma-coherent; - dma-ranges; - -diff --git a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi -index e581cb1d87ee..d766c7fe02af 100644 ---- a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi -@@ -249,11 +249,11 @@ adc { - }; - }; - -- mcu-navss { -+ mcu_navss: bus@28380000 { - compatible = "simple-mfd"; - #address-cells = <2>; - #size-cells = <2>; -- ranges; -+ ranges = <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>; - dma-coherent; - dma-ranges; - diff --git a/recipes-kernel/linux/files/patches-5.10/0012-arm64-dts-ti-k3-Introduce-reg-definition-for-interru.patch b/recipes-kernel/linux/files/patches-5.10/0012-arm64-dts-ti-k3-Introduce-reg-definition-for-interru.patch deleted file mode 100644 index a408a6315..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0012-arm64-dts-ti-k3-Introduce-reg-definition-for-interru.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Tue, 11 May 2021 14:48:21 -0500 -Subject: [PATCH] arm64: dts: ti: k3*: Introduce reg definition for interrupt - routers - -Interrupt routers are memory mapped peripherals, that are organized -in our dts bus hierarchy to closely represents the actual hardware -behavior. - -However, without explicitly calling out the reg property, using -2021.03+ dt-schema package, this exposes the following problem with -dtbs_check: - -/arch/arm64/boot/dts/ti/k3-am654-base-board.dt.yaml: bus@100000: -interrupt-controller0: {'type': 'object'} is not allowed for -{'compatible': ['ti,sci-intr'], ..... - -Even though we don't use interrupt router directly via memory mapped -registers and have to use it via the system controller, the hardware -block is memory mapped, so describe the base address in device tree. - -This is a valid, comprehensive description of hardware and permitted -by the existing ti,sci-intr schema. - -Reviewed-by: Tero Kristo -Reviewed-by: Lokesh Vutla -Signed-off-by: Nishanth Menon -Link: https://lore.kernel.org/r/20210511194821.13919-1-nm@ti.com -[Jan: drop am64 bits] -Signed-off-by: Jan Kiszka ---- - arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 6 ++++-- - arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi | 3 ++- - arch/arm64/boot/dts/ti/k3-j7200-main.dtsi | 6 ++++-- - arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi | 3 ++- - arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 6 ++++-- - arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi | 3 ++- - 6 files changed, 18 insertions(+), 9 deletions(-) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index dcd1d8fe6c9f..2814acfc07b5 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -435,8 +435,9 @@ usb1_phy: phy@4110000 { - #phy-cells = <0>; - }; - -- intr_main_gpio: interrupt-controller0 { -+ intr_main_gpio: interrupt-controller@a00000 { - compatible = "ti,sci-intr"; -+ reg = <0x0 0x00a00000 0x0 0x400>; - ti,intr-trigger-type = <1>; - interrupt-controller; - interrupt-parent = <&gic500>; -@@ -456,8 +457,9 @@ main_navss: bus@30800000 { - - ti,sci-dev-id = <118>; - -- intr_main_navss: interrupt-controller1 { -+ intr_main_navss: interrupt-controller@310e0000 { - compatible = "ti,sci-intr"; -+ reg = <0x0 0x310e0000 0x0 0x2000>; - ti,intr-trigger-type = <4>; - interrupt-controller; - interrupt-parent = <&gic500>; -diff --git a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi -index ed42f13e7663..62a18b110c52 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi -@@ -69,8 +69,9 @@ wkup_i2c0: i2c@42120000 { - power-domains = <&k3_pds 115 TI_SCI_PD_EXCLUSIVE>; - }; - -- intr_wkup_gpio: interrupt-controller2 { -+ intr_wkup_gpio: interrupt-controller@42200000 { - compatible = "ti,sci-intr"; -+ reg = <0x42200000 0x200>; - ti,intr-trigger-type = <1>; - interrupt-controller; - interrupt-parent = <&gic500>; -diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi -index cb22e65d61ab..a0365890571e 100644 ---- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi -@@ -64,8 +64,9 @@ gic_its: msi-controller@1820000 { - }; - }; - -- main_gpio_intr: interrupt-controller0 { -+ main_gpio_intr: interrupt-controller@a00000 { - compatible = "ti,sci-intr"; -+ reg = <0x00 0x00a00000 0x00 0x800>; - ti,intr-trigger-type = <1>; - interrupt-controller; - interrupt-parent = <&gic500>; -@@ -84,8 +85,9 @@ main_navss: bus@30000000 { - dma-coherent; - dma-ranges; - -- main_navss_intr: interrupt-controller1 { -+ main_navss_intr: interrupt-controller@310e0000 { - compatible = "ti,sci-intr"; -+ reg = <0x00 0x310e0000 0x00 0x4000>; - ti,intr-trigger-type = <4>; - interrupt-controller; - interrupt-parent = <&gic500>; -diff --git a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi -index 7f252cc6eb37..7988b9660f65 100644 ---- a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi -@@ -123,8 +123,9 @@ mcu_uart0: serial@40a00000 { - clock-names = "fclk"; - }; - -- wkup_gpio_intr: interrupt-controller2 { -+ wkup_gpio_intr: interrupt-controller@42200000 { - compatible = "ti,sci-intr"; -+ reg = <0x00 0x42200000 0x00 0x400>; - ti,intr-trigger-type = <1>; - interrupt-controller; - interrupt-parent = <&gic500>; -diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -index 4c3ee45bdcf9..b14fe61782d3 100644 ---- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi -@@ -125,8 +125,9 @@ gic_its: msi-controller@1820000 { - }; - }; - -- main_gpio_intr: interrupt-controller0 { -+ main_gpio_intr: interrupt-controller@a00000 { - compatible = "ti,sci-intr"; -+ reg = <0x00 0x00a00000 0x00 0x800>; - ti,intr-trigger-type = <1>; - interrupt-controller; - interrupt-parent = <&gic500>; -@@ -146,8 +147,9 @@ main_navss: bus@30000000 { - - ti,sci-dev-id = <199>; - -- main_navss_intr: interrupt-controller1 { -+ main_navss_intr: interrupt-controller@310e0000 { - compatible = "ti,sci-intr"; -+ reg = <0x0 0x310e0000 0x0 0x4000>; - ti,intr-trigger-type = <4>; - interrupt-controller; - interrupt-parent = <&gic500>; -diff --git a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi -index d766c7fe02af..282bbdc359ac 100644 ---- a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi -@@ -96,8 +96,9 @@ mcu_uart0: serial@40a00000 { - clock-names = "fclk"; - }; - -- wkup_gpio_intr: interrupt-controller2 { -+ wkup_gpio_intr: interrupt-controller@42200000 { - compatible = "ti,sci-intr"; -+ reg = <0x00 0x42200000 0x00 0x400>; - ti,intr-trigger-type = <1>; - interrupt-controller; - interrupt-parent = <&gic500>; diff --git a/recipes-kernel/linux/files/patches-5.10/0013-mmc-sdhci_am654-Use-pm_runtime_resume_and_get-to-rep.patch b/recipes-kernel/linux/files/patches-5.10/0013-mmc-sdhci_am654-Use-pm_runtime_resume_and_get-to-rep.patch deleted file mode 100644 index 55115ef5e..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0013-mmc-sdhci_am654-Use-pm_runtime_resume_and_get-to-rep.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tian Tao -Date: Fri, 21 May 2021 08:59:35 +0800 -Subject: [PATCH] mmc: sdhci_am654: Use pm_runtime_resume_and_get() to replace - open coding - -use pm_runtime_resume_and_get() to replace pm_runtime_get_sync and -pm_runtime_put_noidle. this change is just to simplify the code, no -actual functional changes. - -Signed-off-by: Tian Tao -Link: https://lore.kernel.org/r/1621558775-31185-1-git-send-email-tiantao6@hisilicon.com -Signed-off-by: Ulf Hansson ---- - drivers/mmc/host/sdhci_am654.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c -index 8e52905458f9..c72e10f36c1c 100644 ---- a/drivers/mmc/host/sdhci_am654.c -+++ b/drivers/mmc/host/sdhci_am654.c -@@ -801,11 +801,9 @@ static int sdhci_am654_probe(struct platform_device *pdev) - - /* Clocks are enabled using pm_runtime */ - pm_runtime_enable(dev); -- ret = pm_runtime_get_sync(dev); -- if (ret < 0) { -- pm_runtime_put_noidle(dev); -+ ret = pm_runtime_resume_and_get(dev); -+ if (ret) - goto pm_runtime_disable; -- } - - base = devm_platform_ioremap_resource(pdev, 1); - if (IS_ERR(base)) { diff --git a/recipes-kernel/linux/files/patches-5.10/0014-arm64-dts-ti-k3-am65-iot2050-common-Disable-mailbox-.patch b/recipes-kernel/linux/files/patches-5.10/0014-arm64-dts-ti-k3-am65-iot2050-common-Disable-mailbox-.patch deleted file mode 100644 index f3dda68f9..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0014-arm64-dts-ti-k3-am65-iot2050-common-Disable-mailbox-.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Fri, 14 May 2021 16:20:16 -0500 -Subject: [PATCH] arm64: dts: ti: k3-am65-iot2050-common: Disable mailbox nodes - -There are no sub-mailbox devices defined currently for both the -IOT2050 boards. These are usually dictated by the firmwares running -on the R5F remote processors and the applications they provide. -Defining the actual sub-mailboxes will also dictate the interrupts -the clusters will use for interrupts on the Cortex-A53 cores. - -Disable all of the Mailbox clusters until the sub-mailboxes are -defined and used. This fixes the warnings around the missing -interrupts with the upcoming conversion of the OMAP Mailbox binding -to YAML format. - -Signed-off-by: Suman Anna -Acked-by: Jan Kiszka -Signed-off-by: Nishanth Menon -Link: https://lore.kernel.org/r/20210514212016.3153-1-s-anna@ti.com ---- - .../boot/dts/ti/k3-am65-iot2050-common.dtsi | 48 +++++++++++++++++++ - 1 file changed, 48 insertions(+) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index de763ca9251c..f4ec9ed52939 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -@@ -653,3 +653,51 @@ &pcie1_rc { - &pcie1_ep { - status = "disabled"; - }; -+ -+&mailbox0_cluster0 { -+ status = "disabled"; -+}; -+ -+&mailbox0_cluster1 { -+ status = "disabled"; -+}; -+ -+&mailbox0_cluster2 { -+ status = "disabled"; -+}; -+ -+&mailbox0_cluster3 { -+ status = "disabled"; -+}; -+ -+&mailbox0_cluster4 { -+ status = "disabled"; -+}; -+ -+&mailbox0_cluster5 { -+ status = "disabled"; -+}; -+ -+&mailbox0_cluster6 { -+ status = "disabled"; -+}; -+ -+&mailbox0_cluster7 { -+ status = "disabled"; -+}; -+ -+&mailbox0_cluster8 { -+ status = "disabled"; -+}; -+ -+&mailbox0_cluster9 { -+ status = "disabled"; -+}; -+ -+&mailbox0_cluster10 { -+ status = "disabled"; -+}; -+ -+&mailbox0_cluster11 { -+ status = "disabled"; -+}; diff --git a/recipes-kernel/linux/files/patches-5.10/0015-arm64-dts-ti-k3-am65-Add-support-for-UHS-I-modes-in-.patch b/recipes-kernel/linux/files/patches-5.10/0015-arm64-dts-ti-k3-am65-Add-support-for-UHS-I-modes-in-.patch deleted file mode 100644 index 8e192dd11..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0015-arm64-dts-ti-k3-am65-Add-support-for-UHS-I-modes-in-.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aswath Govindraju -Date: Sat, 29 May 2021 09:07:49 +0530 -Subject: [PATCH] arm64: dts: ti: k3-am65: Add support for UHS-I modes in - MMCSD1 subsystem - -UHS-I speed modes are supported in AM65 S.R. 2.0 SoC[1]. - -Add support by removing the no-1-8-v tag and including the voltage -regulator device tree nodes for power cycling. - -However, the 4 bit interface of AM65 SR 1.0 cannot be supported at 3.3 V or -1.8 V because of erratas i2025 and i2026 [2]. As the SD card is the primary -boot mode for development usecases, continue to enable SD card and disable -UHS-I modes in it to minimize any ageing issues happening because of -erratas. - -k3-am6528-iot2050-basic and k3-am6548-iot2050-advanced boards use S.R. 1.0 -version of AM65 SoC. Therefore, add no-1-8-v in sdhci1 device tree node of -the common iot2050 device tree file. - -[1] - https://www.ti.com/lit/ug/spruid7e/spruid7e.pdf, section 12.3.6.1.1 -[2] - https://www.ti.com/lit/er/sprz452e/sprz452e.pdf - -Signed-off-by: Aswath Govindraju -Acked-by: Jan Kiszka -Signed-off-by: Nishanth Menon -Link: https://lore.kernel.org/r/20210529033749.6250-1-a-govindraju@ti.com ---- - .../boot/dts/ti/k3-am65-iot2050-common.dtsi | 1 + - arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 1 - - .../arm64/boot/dts/ti/k3-am654-base-board.dts | 33 +++++++++++++++++++ - 3 files changed, 34 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index f4ec9ed52939..d90abda1de84 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -@@ -555,6 +555,7 @@ &sdhci1 { - pinctrl-0 = <&main_mmc1_pins_default>; - ti,driver-strength-ohm = <50>; - disable-wp; -+ no-1-8-v; - }; - - &usb0 { -diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index 2814acfc07b5..11982ae5593c 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -303,7 +303,6 @@ sdhci1: mmc@4fa0000 { - ti,otap-del-sel = <0x2>; - ti,trm-icp = <0x8>; - dma-coherent; -- no-1-8-v; - }; - - scm_conf: scm-conf@100000 { -diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts -index 8c082af489f5..fea6a8243d75 100644 ---- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts -+++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts -@@ -60,6 +60,38 @@ clk_ov5640_fixed: clock { - #clock-cells = <0>; - clock-frequency = <24000000>; - }; -+ -+ evm_12v0: fixedregulator-evm12v0 { -+ /* main supply */ -+ compatible = "regulator-fixed"; -+ regulator-name = "evm_12v0"; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ vcc3v3_io: fixedregulator-vcc3v3io { -+ /* Output of TPS54334 */ -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc3v3_io"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ regulator-boot-on; -+ vin-supply = <&evm_12v0>; -+ }; -+ -+ vdd_mmc1_sd: fixedregulator-sd { -+ compatible = "regulator-fixed"; -+ regulator-name = "vdd_mmc1_sd"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ enable-active-high; -+ vin-supply = <&vcc3v3_io>; -+ gpio = <&pca9554 4 GPIO_ACTIVE_HIGH>; -+ }; - }; - - &wkup_pmx0 { -@@ -319,6 +351,7 @@ &sdhci0 { - * disable sdhci1 - */ - &sdhci1 { -+ vmmc-supply = <&vdd_mmc1_sd>; - pinctrl-names = "default"; - pinctrl-0 = <&main_mmc1_pins_default>; - ti,driver-strength-ohm = <50>; diff --git a/recipes-kernel/linux/files/patches-5.10/0016-arm64-dts-ti-k3-am65-main-Add-ICSSG-MDIO-nodes.patch b/recipes-kernel/linux/files/patches-5.10/0016-arm64-dts-ti-k3-am65-main-Add-ICSSG-MDIO-nodes.patch deleted file mode 100644 index fa24d1c0f..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0016-arm64-dts-ti-k3-am65-main-Add-ICSSG-MDIO-nodes.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Roger Quadros -Date: Tue, 1 Jun 2021 10:00:31 -0500 -Subject: [PATCH] arm64: dts: ti: k3-am65-main: Add ICSSG MDIO nodes - -The ICSSGs on K3 AM65x SoCs contain an MDIO controller that can -be used to control external PHYs associated with the Industrial -Ethernet peripherals within each ICSSG instance. The MDIO module -used within the ICSSG is similar to the MDIO Controller used -in TI Davinci SoCs. A bus frequency of 1 MHz is chosen for the -MDIO operations. - -The nodes are added and enabled in the common k3-am65-main.dtsi -file by default, and disabled in the existing AM65 board dts -files. These nodes need pinctrl lines, and so should be enabled -only on boards where they are actually wired and pinned out for -ICSSG Ethernet. Any new board dts file should disable these if -they are not sure. - -Signed-off-by: Roger Quadros -[s-anna@ti.com: move the disabled status to board dts files] -Signed-off-by: Suman Anna -Reviewed-by: Grygorii Strashko -Acked-by: Jan Kiszka -Signed-off-by: Nishanth Menon -Link: https://lore.kernel.org/r/20210601150032.11432-2-s-anna@ti.com ---- - .../boot/dts/ti/k3-am65-iot2050-common.dtsi | 12 ++++++++ - arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 30 +++++++++++++++++++ - .../arm64/boot/dts/ti/k3-am654-base-board.dts | 12 ++++++++ - 3 files changed, 54 insertions(+) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index d90abda1de84..8c6b538c53f3 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -@@ -702,3 +702,15 @@ &mailbox0_cluster10 { - &mailbox0_cluster11 { - status = "disabled"; - }; -+ -+&icssg0_mdio { -+ status = "disabled"; -+}; -+ -+&icssg1_mdio { -+ status = "disabled"; -+}; -+ -+&icssg2_mdio { -+ status = "disabled"; -+}; -diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index 11982ae5593c..fb94d61eae0e 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -1053,6 +1053,16 @@ tx_pru0_1: txpru@c000 { - reg-names = "iram", "control", "debug"; - firmware-name = "am65x-txpru0_1-fw"; - }; -+ -+ icssg0_mdio: mdio@32400 { -+ compatible = "ti,davinci_mdio"; -+ reg = <0x32400 0x100>; -+ clocks = <&k3_clks 62 3>; -+ clock-names = "fck"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ bus_freq = <1000000>; -+ }; - }; - - icssg1: icssg@b100000 { -@@ -1184,6 +1194,16 @@ tx_pru1_1: txpru@c000 { - reg-names = "iram", "control", "debug"; - firmware-name = "am65x-txpru1_1-fw"; - }; -+ -+ icssg1_mdio: mdio@32400 { -+ compatible = "ti,davinci_mdio"; -+ reg = <0x32400 0x100>; -+ clocks = <&k3_clks 63 3>; -+ clock-names = "fck"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ bus_freq = <1000000>; -+ }; - }; - - icssg2: icssg@b200000 { -@@ -1315,5 +1335,15 @@ tx_pru2_1: txpru@c000 { - reg-names = "iram", "control", "debug"; - firmware-name = "am65x-txpru2_1-fw"; - }; -+ -+ icssg2_mdio: mdio@32400 { -+ compatible = "ti,davinci_mdio"; -+ reg = <0x32400 0x100>; -+ clocks = <&k3_clks 64 3>; -+ clock-names = "fck"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ bus_freq = <1000000>; -+ }; - }; - }; -diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts -index fea6a8243d75..b47fc2a1e59d 100644 ---- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts -+++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts -@@ -535,3 +535,15 @@ &mcasp2 { - &dss { - status = "disabled"; - }; -+ -+&icssg0_mdio { -+ status = "disabled"; -+}; -+ -+&icssg1_mdio { -+ status = "disabled"; -+}; -+ -+&icssg2_mdio { -+ status = "disabled"; -+}; diff --git a/recipes-kernel/linux/files/patches-5.10/0017-arm64-dts-ti-iot2050-Configure-r5f-cluster-on-basic-.patch b/recipes-kernel/linux/files/patches-5.10/0017-arm64-dts-ti-iot2050-Configure-r5f-cluster-on-basic-.patch deleted file mode 100644 index cca2f9784..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0017-arm64-dts-ti-iot2050-Configure-r5f-cluster-on-basic-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Wed, 2 Jun 2021 08:56:15 +0200 -Subject: [PATCH] arm64: dts: ti: iot2050: Configure r5f cluster on basic - variant in split mode - -Lockstep mode is not supported here. So turn it off to avoid warnings -during startup. - -Signed-off-by: Jan Kiszka -Signed-off-by: Nishanth Menon -Link: https://lore.kernel.org/r/3a241e50-80a3-992a-2445-345c629d7895@siemens.com ---- - arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts -index 4f7e3f2a6265..94bb5dd39122 100644 ---- a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts -+++ b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts -@@ -59,3 +59,8 @@ &main_uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&main_uart0_pins_default>; - }; -+ -+&mcu_r5fss0 { -+ /* lock-step mode not supported on this board */ -+ ti,cluster-mode = <0>; -+}; diff --git a/recipes-kernel/linux/files/patches-5.10/0018-arm64-dts-ti-am65-align-ti-pindir-d0-out-d1-in-prope.patch b/recipes-kernel/linux/files/patches-5.10/0018-arm64-dts-ti-am65-align-ti-pindir-d0-out-d1-in-prope.patch deleted file mode 100644 index 027e75a5a..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0018-arm64-dts-ti-am65-align-ti-pindir-d0-out-d1-in-prope.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aswath Govindraju -Date: Tue, 8 Jun 2021 10:44:13 +0530 -Subject: [PATCH] arm64: dts: ti: am65: align ti,pindir-d0-out-d1-in property - with dt-shema - -ti,pindir-d0-out-d1-in property is expected to be of type boolean. -Therefore, fix the property accordingly. - -Fixes: e180f76d0641 ("arm64: dts: ti: Add support for Siemens IOT2050 boards") -Fixes: 5da94b50475a ("arm64: dts: ti: k3-am654: Enable main domain McSPI0") -Signed-off-by: Aswath Govindraju -Acked-by: Jan Kiszka -Reviewed-by: Vignesh Raghavendra -Signed-off-by: Nishanth Menon -Link: https://lore.kernel.org/r/20210608051414.14873-2-a-govindraju@ti.com ---- - arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi | 2 +- - arch/arm64/boot/dts/ti/k3-am654-base-board.dts | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index 8c6b538c53f3..1008e9162ba2 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -@@ -576,7 +576,7 @@ &mcu_spi0 { - - #address-cells = <1>; - #size-cells= <0>; -- ti,pindir-d0-out-d1-in = <1>; -+ ti,pindir-d0-out-d1-in; - }; - - &tscadc0 { -diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts -index b47fc2a1e59d..56dc855a5f13 100644 ---- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts -+++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts -@@ -323,7 +323,7 @@ &main_spi0 { - pinctrl-0 = <&main_spi0_pins_default>; - #address-cells = <1>; - #size-cells= <0>; -- ti,pindir-d0-out-d1-in = <1>; -+ ti,pindir-d0-out-d1-in; - - flash@0{ - compatible = "jedec,spi-nor"; diff --git a/recipes-kernel/linux/files/patches-5.10/0019-firmware-ti_sci-rm-Add-support-for-tx_tdtype-paramet.patch b/recipes-kernel/linux/files/patches-5.10/0019-firmware-ti_sci-rm-Add-support-for-tx_tdtype-paramet.patch deleted file mode 100644 index 40171f4e9..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0019-firmware-ti_sci-rm-Add-support-for-tx_tdtype-paramet.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Sun, 25 Oct 2020 12:10:02 -0700 -Subject: [PATCH] firmware: ti_sci: rm: Add support for tx_tdtype parameter for - tx channel - -The system controller's resource manager have support for configuring the -TDTYPE of TCHAN_CFG register on j721e. -With this parameter the teardown completion can be controlled: -TDTYPE == 0: Return without waiting for peer to complete the teardown -TDTYPE == 1: Wait for peer to complete the teardown - -Signed-off-by: Peter Ujfalusi -Reviewed-by: Tero Kristo -Tested-by: Keerthy -Reviewed-by: Grygorii Strashko -Signed-off-by: Santosh Shilimkar ---- - drivers/firmware/ti_sci.c | 1 + - drivers/firmware/ti_sci.h | 7 +++++++ - include/linux/soc/ti/ti_sci_protocol.h | 2 ++ - 3 files changed, 10 insertions(+) - -diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c -index 896f53ec7857..65a8c2e82093 100644 ---- a/drivers/firmware/ti_sci.c -+++ b/drivers/firmware/ti_sci.c -@@ -2362,6 +2362,7 @@ static int ti_sci_cmd_rm_udmap_tx_ch_cfg(const struct ti_sci_handle *handle, - req->fdepth = params->fdepth; - req->tx_sched_priority = params->tx_sched_priority; - req->tx_burst_size = params->tx_burst_size; -+ req->tx_tdtype = params->tx_tdtype; - - ret = ti_sci_do_xfer(info, xfer); - if (ret) { -diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h -index 57cd04062994..dca19ca5fc49 100644 ---- a/drivers/firmware/ti_sci.h -+++ b/drivers/firmware/ti_sci.h -@@ -910,6 +910,7 @@ struct rm_ti_sci_msg_udmap_rx_flow_opt_cfg { - * 12 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_credit_count - * 13 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::fdepth - * 14 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_burst_size -+ * 15 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_tdtype - * - * @nav_id: SoC device ID of Navigator Subsystem where tx channel is located - * -@@ -973,6 +974,11 @@ struct rm_ti_sci_msg_udmap_rx_flow_opt_cfg { - * - * @tx_burst_size: UDMAP transmit channel burst size configuration to be - * programmed into the tx_burst_size field of the TCHAN_TCFG register. -+ * -+ * @tx_tdtype: UDMAP transmit channel teardown type configuration to be -+ * programmed into the tdtype field of the TCHAN_TCFG register: -+ * 0 - Return immediately -+ * 1 - Wait for completion message from remote peer - */ - struct ti_sci_msg_rm_udmap_tx_ch_cfg_req { - struct ti_sci_msg_hdr hdr; -@@ -994,6 +1000,7 @@ struct ti_sci_msg_rm_udmap_tx_ch_cfg_req { - u16 fdepth; - u8 tx_sched_priority; - u8 tx_burst_size; -+ u8 tx_tdtype; - } __packed; - - /** -diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h -index b1af87330f86..fece890e1635 100644 ---- a/include/linux/soc/ti/ti_sci_protocol.h -+++ b/include/linux/soc/ti/ti_sci_protocol.h -@@ -345,6 +345,7 @@ struct ti_sci_msg_rm_udmap_tx_ch_cfg { - #define TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_SUPR_TDPKT_VALID BIT(11) - #define TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_CREDIT_COUNT_VALID BIT(12) - #define TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_FDEPTH_VALID BIT(13) -+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_TDTYPE_VALID BIT(15) - u16 nav_id; - u16 index; - u8 tx_pause_on_err; -@@ -362,6 +363,7 @@ struct ti_sci_msg_rm_udmap_tx_ch_cfg { - u16 fdepth; - u8 tx_sched_priority; - u8 tx_burst_size; -+ u8 tx_tdtype; - }; - - /** diff --git a/recipes-kernel/linux/files/patches-5.10/0020-firmware-ti_sci-Use-struct-ti_sci_resource_desc-in-g.patch b/recipes-kernel/linux/files/patches-5.10/0020-firmware-ti_sci-Use-struct-ti_sci_resource_desc-in-g.patch deleted file mode 100644 index f5e230757..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0020-firmware-ti_sci-Use-struct-ti_sci_resource_desc-in-g.patch +++ /dev/null @@ -1,178 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Sun, 25 Oct 2020 12:10:03 -0700 -Subject: [PATCH] firmware: ti_sci: Use struct ti_sci_resource_desc in - get_range ops - -Use the ti_sci_resource_desc directly and update it's start and num members -directly instead of requiring individual parameters for them. - -This will allow easy extension of the RM parameters without changing API. - -Signed-off-by: Peter Ujfalusi -Signed-off-by: Santosh Shilimkar ---- - drivers/firmware/ti_sci.c | 32 ++++++++++++-------------- - include/linux/soc/ti/ti_sci_protocol.h | 32 +++++++++++++------------- - 2 files changed, 31 insertions(+), 33 deletions(-) - -diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c -index 65a8c2e82093..7a777e91ce3e 100644 ---- a/drivers/firmware/ti_sci.c -+++ b/drivers/firmware/ti_sci.c -@@ -1703,14 +1703,14 @@ static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle) - * @subtype: Resource assignment subtype that is being requested - * from the given device. - * @s_host: Host processor ID to which the resources are allocated -- * @range_start: Start index of the resource range -- * @range_num: Number of resources in the range -+ * @desc: Pointer to ti_sci_resource_desc to be updated with the -+ * resource range start index and number of resources - * - * Return: 0 if all went fine, else return appropriate error. - */ - static int ti_sci_get_resource_range(const struct ti_sci_handle *handle, - u32 dev_id, u8 subtype, u8 s_host, -- u16 *range_start, u16 *range_num) -+ struct ti_sci_resource_desc *desc) - { - struct ti_sci_msg_resp_get_resource_range *resp; - struct ti_sci_msg_req_get_resource_range *req; -@@ -1721,7 +1721,7 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle, - - if (IS_ERR(handle)) - return PTR_ERR(handle); -- if (!handle) -+ if (!handle || !desc) - return -EINVAL; - - info = handle_to_ti_sci_info(handle); -@@ -1754,8 +1754,8 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle, - } else if (!resp->range_start && !resp->range_num) { - ret = -ENODEV; - } else { -- *range_start = resp->range_start; -- *range_num = resp->range_num; -+ desc->start = resp->range_start; -+ desc->num = resp->range_num; - }; - - fail: -@@ -1771,18 +1771,18 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle, - * @dev_id: TISCI device ID. - * @subtype: Resource assignment subtype that is being requested - * from the given device. -- * @range_start: Start index of the resource range -- * @range_num: Number of resources in the range -+ * @desc: Pointer to ti_sci_resource_desc to be updated with the -+ * resource range start index and number of resources - * - * Return: 0 if all went fine, else return appropriate error. - */ - static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle, - u32 dev_id, u8 subtype, -- u16 *range_start, u16 *range_num) -+ struct ti_sci_resource_desc *desc) - { - return ti_sci_get_resource_range(handle, dev_id, subtype, - TI_SCI_IRQ_SECONDARY_HOST_INVALID, -- range_start, range_num); -+ desc); - } - - /** -@@ -1793,18 +1793,17 @@ static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle, - * @subtype: Resource assignment subtype that is being requested - * from the given device. - * @s_host: Host processor ID to which the resources are allocated -- * @range_start: Start index of the resource range -- * @range_num: Number of resources in the range -+ * @desc: Pointer to ti_sci_resource_desc to be updated with the -+ * resource range start index and number of resources - * - * Return: 0 if all went fine, else return appropriate error. - */ - static - int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle, - u32 dev_id, u8 subtype, u8 s_host, -- u16 *range_start, u16 *range_num) -+ struct ti_sci_resource_desc *desc) - { -- return ti_sci_get_resource_range(handle, dev_id, subtype, s_host, -- range_start, range_num); -+ return ti_sci_get_resource_range(handle, dev_id, subtype, s_host, desc); - } - - /** -@@ -3243,8 +3242,7 @@ devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle, - for (i = 0; i < res->sets; i++) { - ret = handle->ops.rm_core_ops.get_range(handle, dev_id, - sub_types[i], -- &res->desc[i].start, -- &res->desc[i].num); -+ &res->desc[i]); - if (ret) { - dev_dbg(dev, "dev = %d subtype %d not allocated for this host\n", - dev_id, sub_types[i]); -diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h -index fece890e1635..19b90545edd8 100644 ---- a/include/linux/soc/ti/ti_sci_protocol.h -+++ b/include/linux/soc/ti/ti_sci_protocol.h -@@ -195,6 +195,18 @@ struct ti_sci_clk_ops { - u64 *current_freq); - }; - -+/** -+ * struct ti_sci_resource_desc - Description of TI SCI resource instance range. -+ * @start: Start index of the resource. -+ * @num: Number of resources. -+ * @res_map: Bitmap to manage the allocation of these resources. -+ */ -+struct ti_sci_resource_desc { -+ u16 start; -+ u16 num; -+ unsigned long *res_map; -+}; -+ - /** - * struct ti_sci_rm_core_ops - Resource management core operations - * @get_range: Get a range of resources belonging to ti sci host. -@@ -209,15 +221,15 @@ struct ti_sci_clk_ops { - * - dev_id: TISCI device ID. - * - subtype: Resource assignment subtype that is being requested - * from the given device. -- * - range_start: Start index of the resource range -- * - range_end: Number of resources in the range -+ * - desc: Pointer to ti_sci_resource_desc to be updated with the resource -+ * range start index and number of resources - */ - struct ti_sci_rm_core_ops { - int (*get_range)(const struct ti_sci_handle *handle, u32 dev_id, -- u8 subtype, u16 *range_start, u16 *range_num); -+ u8 subtype, struct ti_sci_resource_desc *desc); - int (*get_range_from_shost)(const struct ti_sci_handle *handle, - u32 dev_id, u8 subtype, u8 s_host, -- u16 *range_start, u16 *range_num); -+ struct ti_sci_resource_desc *desc); - }; - - #define TI_SCI_RESASG_SUBTYPE_IR_OUTPUT 0 -@@ -522,18 +534,6 @@ struct ti_sci_handle { - - #define TI_SCI_RESOURCE_NULL 0xffff - --/** -- * struct ti_sci_resource_desc - Description of TI SCI resource instance range. -- * @start: Start index of the resource. -- * @num: Number of resources. -- * @res_map: Bitmap to manage the allocation of these resources. -- */ --struct ti_sci_resource_desc { -- u16 start; -- u16 num; -- unsigned long *res_map; --}; -- - /** - * struct ti_sci_resource - Structure representing a resource assigned - * to a device. diff --git a/recipes-kernel/linux/files/patches-5.10/0021-firmware-ti_sci-rm-Add-support-for-second-resource-r.patch b/recipes-kernel/linux/files/patches-5.10/0021-firmware-ti_sci-rm-Add-support-for-second-resource-r.patch deleted file mode 100644 index efcc863c6..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0021-firmware-ti_sci-rm-Add-support-for-second-resource-r.patch +++ /dev/null @@ -1,174 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Sun, 25 Oct 2020 12:10:03 -0700 -Subject: [PATCH] firmware: ti_sci: rm: Add support for second resource range - -Sysfw added support for a second range in the resource range API to be able -to describe complex allocations mainly for DMA channels. - -Update the ti_sci part to consider the second range as well. - -Signed-off-by: Peter Ujfalusi -Signed-off-by: Santosh Shilimkar ---- - drivers/firmware/ti_sci.c | 48 +++++++++++++++++--------- - drivers/firmware/ti_sci.h | 8 +++-- - include/linux/soc/ti/ti_sci_protocol.h | 8 +++-- - 3 files changed, 43 insertions(+), 21 deletions(-) - -diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c -index 7a777e91ce3e..2793bb923881 100644 ---- a/drivers/firmware/ti_sci.c -+++ b/drivers/firmware/ti_sci.c -@@ -1751,11 +1751,14 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle, - - if (!ti_sci_is_response_ack(resp)) { - ret = -ENODEV; -- } else if (!resp->range_start && !resp->range_num) { -+ } else if (!resp->range_num && !resp->range_num_sec) { -+ /* Neither of the two resource range is valid */ - ret = -ENODEV; - } else { - desc->start = resp->range_start; - desc->num = resp->range_num; -+ desc->start_sec = resp->range_start_sec; -+ desc->num_sec = resp->range_num_sec; - }; - - fail: -@@ -3157,12 +3160,18 @@ u16 ti_sci_get_free_resource(struct ti_sci_resource *res) - - raw_spin_lock_irqsave(&res->lock, flags); - for (set = 0; set < res->sets; set++) { -- free_bit = find_first_zero_bit(res->desc[set].res_map, -- res->desc[set].num); -- if (free_bit != res->desc[set].num) { -- set_bit(free_bit, res->desc[set].res_map); -+ struct ti_sci_resource_desc *desc = &res->desc[set]; -+ int res_count = desc->num + desc->num_sec; -+ -+ free_bit = find_first_zero_bit(desc->res_map, res_count); -+ if (free_bit != res_count) { -+ set_bit(free_bit, desc->res_map); - raw_spin_unlock_irqrestore(&res->lock, flags); -- return res->desc[set].start + free_bit; -+ -+ if (desc->num && free_bit < desc->num) -+ return desc->start + free_bit; -+ else -+ return desc->start_sec + free_bit; - } - } - raw_spin_unlock_irqrestore(&res->lock, flags); -@@ -3183,10 +3192,14 @@ void ti_sci_release_resource(struct ti_sci_resource *res, u16 id) - - raw_spin_lock_irqsave(&res->lock, flags); - for (set = 0; set < res->sets; set++) { -- if (res->desc[set].start <= id && -- (res->desc[set].num + res->desc[set].start) > id) -- clear_bit(id - res->desc[set].start, -- res->desc[set].res_map); -+ struct ti_sci_resource_desc *desc = &res->desc[set]; -+ -+ if (desc->num && desc->start <= id && -+ (desc->start + desc->num) > id) -+ clear_bit(id - desc->start, desc->res_map); -+ else if (desc->num_sec && desc->start_sec <= id && -+ (desc->start_sec + desc->num_sec) > id) -+ clear_bit(id - desc->start_sec, desc->res_map); - } - raw_spin_unlock_irqrestore(&res->lock, flags); - } -@@ -3203,7 +3216,7 @@ u32 ti_sci_get_num_resources(struct ti_sci_resource *res) - u32 set, count = 0; - - for (set = 0; set < res->sets; set++) -- count += res->desc[set].num; -+ count += res->desc[set].num + res->desc[set].num_sec; - - return count; - } -@@ -3227,7 +3240,7 @@ devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle, - { - struct ti_sci_resource *res; - bool valid_set = false; -- int i, ret; -+ int i, ret, res_count; - - res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL); - if (!res) -@@ -3246,18 +3259,19 @@ devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle, - if (ret) { - dev_dbg(dev, "dev = %d subtype %d not allocated for this host\n", - dev_id, sub_types[i]); -- res->desc[i].start = 0; -- res->desc[i].num = 0; -+ memset(&res->desc[i], 0, sizeof(res->desc[i])); - continue; - } - -- dev_dbg(dev, "dev = %d, subtype = %d, start = %d, num = %d\n", -+ dev_dbg(dev, "dev/sub_type: %d/%d, start/num: %d/%d | %d/%d\n", - dev_id, sub_types[i], res->desc[i].start, -- res->desc[i].num); -+ res->desc[i].num, res->desc[i].start_sec, -+ res->desc[i].num_sec); - - valid_set = true; -+ res_count = res->desc[i].num + res->desc[i].num_sec; - res->desc[i].res_map = -- devm_kzalloc(dev, BITS_TO_LONGS(res->desc[i].num) * -+ devm_kzalloc(dev, BITS_TO_LONGS(res_count) * - sizeof(*res->desc[i].res_map), GFP_KERNEL); - if (!res->desc[i].res_map) - return ERR_PTR(-ENOMEM); -diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h -index dca19ca5fc49..4d980eb592c4 100644 ---- a/drivers/firmware/ti_sci.h -+++ b/drivers/firmware/ti_sci.h -@@ -574,8 +574,10 @@ struct ti_sci_msg_req_get_resource_range { - /** - * struct ti_sci_msg_resp_get_resource_range - Response to resource get range. - * @hdr: Generic Header -- * @range_start: Start index of the resource range. -- * @range_num: Number of resources in the range. -+ * @range_start: Start index of the first resource range. -+ * @range_num: Number of resources in the first range. -+ * @range_start_sec: Start index of the second resource range. -+ * @range_num_sec: Number of resources in the second range. - * - * Response to request TI_SCI_MSG_GET_RESOURCE_RANGE. - */ -@@ -583,6 +585,8 @@ struct ti_sci_msg_resp_get_resource_range { - struct ti_sci_msg_hdr hdr; - u16 range_start; - u16 range_num; -+ u16 range_start_sec; -+ u16 range_num_sec; - } __packed; - - /** -diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h -index 19b90545edd8..2cd563c7328c 100644 ---- a/include/linux/soc/ti/ti_sci_protocol.h -+++ b/include/linux/soc/ti/ti_sci_protocol.h -@@ -197,13 +197,17 @@ struct ti_sci_clk_ops { - - /** - * struct ti_sci_resource_desc - Description of TI SCI resource instance range. -- * @start: Start index of the resource. -- * @num: Number of resources. -+ * @start: Start index of the first resource range. -+ * @num: Number of resources in the first range. -+ * @start_sec: Start index of the second resource range. -+ * @num_sec: Number of resources in the second range. - * @res_map: Bitmap to manage the allocation of these resources. - */ - struct ti_sci_resource_desc { - u16 start; - u16 num; -+ u16 start_sec; -+ u16 num_sec; - unsigned long *res_map; - }; - diff --git a/recipes-kernel/linux/files/patches-5.10/0022-soc-ti-ti_sci_inta_msi-Add-support-for-second-range-.patch b/recipes-kernel/linux/files/patches-5.10/0022-soc-ti-ti_sci_inta_msi-Add-support-for-second-range-.patch deleted file mode 100644 index deeac86ef..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0022-soc-ti-ti_sci_inta_msi-Add-support-for-second-range-.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Sun, 25 Oct 2020 12:10:04 -0700 -Subject: [PATCH] soc: ti: ti_sci_inta_msi: Add support for second range in - resource ranges - -Allocate MSI entries for both first and second range if they are valid - -Signed-off-by: Peter Ujfalusi -Signed-off-by: Santosh Shilimkar ---- - drivers/soc/ti/ti_sci_inta_msi.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/drivers/soc/ti/ti_sci_inta_msi.c b/drivers/soc/ti/ti_sci_inta_msi.c -index 0eb9462f609e..a1d9c027022a 100644 ---- a/drivers/soc/ti/ti_sci_inta_msi.c -+++ b/drivers/soc/ti/ti_sci_inta_msi.c -@@ -89,6 +89,18 @@ static int ti_sci_inta_msi_alloc_descs(struct device *dev, - list_add_tail(&msi_desc->list, dev_to_msi_list(dev)); - count++; - } -+ for (i = 0; i < res->desc[set].num_sec; i++) { -+ msi_desc = alloc_msi_entry(dev, 1, NULL); -+ if (!msi_desc) { -+ ti_sci_inta_msi_free_descs(dev); -+ return -ENOMEM; -+ } -+ -+ msi_desc->inta.dev_index = res->desc[set].start_sec + i; -+ INIT_LIST_HEAD(&msi_desc->list); -+ list_add_tail(&msi_desc->list, dev_to_msi_list(dev)); -+ count++; -+ } - } - - return count; diff --git a/recipes-kernel/linux/files/patches-5.10/0023-firmware-ti_sci-rm-Add-support-for-extended_ch_type-.patch b/recipes-kernel/linux/files/patches-5.10/0023-firmware-ti_sci-rm-Add-support-for-extended_ch_type-.patch deleted file mode 100644 index 68ed89fc2..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0023-firmware-ti_sci-rm-Add-support-for-extended_ch_type-.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Sun, 25 Oct 2020 12:10:05 -0700 -Subject: [PATCH] firmware: ti_sci: rm: Add support for extended_ch_type for tx - channel - -Sysfw added 'extended_ch_type' to the tx_ch_cfg_req message which should be -used when BCDMA block copy channels are configured: -extended_ch_type = 0 : the channel is split tx channel (tchan) -extended_ch_type = 1 : the channel is block copy channel (bchan) - -Signed-off-by: Peter Ujfalusi -Signed-off-by: Santosh Shilimkar ---- - drivers/firmware/ti_sci.c | 1 + - drivers/firmware/ti_sci.h | 6 ++++++ - include/linux/soc/ti/ti_sci_protocol.h | 5 +++++ - 3 files changed, 12 insertions(+) - -diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c -index 2793bb923881..0dd3fbb4f964 100644 ---- a/drivers/firmware/ti_sci.c -+++ b/drivers/firmware/ti_sci.c -@@ -2365,6 +2365,7 @@ static int ti_sci_cmd_rm_udmap_tx_ch_cfg(const struct ti_sci_handle *handle, - req->tx_sched_priority = params->tx_sched_priority; - req->tx_burst_size = params->tx_burst_size; - req->tx_tdtype = params->tx_tdtype; -+ req->extended_ch_type = params->extended_ch_type; - - ret = ti_sci_do_xfer(info, xfer); - if (ret) { -diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h -index 4d980eb592c4..ca15d8f1f8de 100644 ---- a/drivers/firmware/ti_sci.h -+++ b/drivers/firmware/ti_sci.h -@@ -915,6 +915,7 @@ struct rm_ti_sci_msg_udmap_rx_flow_opt_cfg { - * 13 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::fdepth - * 14 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_burst_size - * 15 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_tdtype -+ * 16 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::extended_ch_type - * - * @nav_id: SoC device ID of Navigator Subsystem where tx channel is located - * -@@ -983,6 +984,10 @@ struct rm_ti_sci_msg_udmap_rx_flow_opt_cfg { - * programmed into the tdtype field of the TCHAN_TCFG register: - * 0 - Return immediately - * 1 - Wait for completion message from remote peer -+ * -+ * @extended_ch_type: Valid for BCDMA. -+ * 0 - the channel is split tx channel (tchan) -+ * 1 - the channel is block copy channel (bchan) - */ - struct ti_sci_msg_rm_udmap_tx_ch_cfg_req { - struct ti_sci_msg_hdr hdr; -@@ -1005,6 +1010,7 @@ struct ti_sci_msg_rm_udmap_tx_ch_cfg_req { - u8 tx_sched_priority; - u8 tx_burst_size; - u8 tx_tdtype; -+ u8 extended_ch_type; - } __packed; - - /** -diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h -index 2cd563c7328c..a090b72a3362 100644 ---- a/include/linux/soc/ti/ti_sci_protocol.h -+++ b/include/linux/soc/ti/ti_sci_protocol.h -@@ -336,6 +336,9 @@ struct ti_sci_rm_psil_ops { - #define TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_128_BYTES 2 - #define TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_256_BYTES 3 - -+#define TI_SCI_RM_BCDMA_EXTENDED_CH_TYPE_TCHAN 0 -+#define TI_SCI_RM_BCDMA_EXTENDED_CH_TYPE_BCHAN 1 -+ - /* UDMAP TX/RX channel valid_params common declarations */ - #define TI_SCI_MSG_VALUE_RM_UDMAP_CH_PAUSE_ON_ERR_VALID BIT(0) - #define TI_SCI_MSG_VALUE_RM_UDMAP_CH_ATYPE_VALID BIT(1) -@@ -362,6 +365,7 @@ struct ti_sci_msg_rm_udmap_tx_ch_cfg { - #define TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_CREDIT_COUNT_VALID BIT(12) - #define TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_FDEPTH_VALID BIT(13) - #define TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_TDTYPE_VALID BIT(15) -+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_EXTENDED_CH_TYPE_VALID BIT(16) - u16 nav_id; - u16 index; - u8 tx_pause_on_err; -@@ -380,6 +384,7 @@ struct ti_sci_msg_rm_udmap_tx_ch_cfg { - u8 tx_sched_priority; - u8 tx_burst_size; - u8 tx_tdtype; -+ u8 extended_ch_type; - }; - - /** diff --git a/recipes-kernel/linux/files/patches-5.10/0024-firmware-ti_sci-rm-Remove-ring_get_config-support.patch b/recipes-kernel/linux/files/patches-5.10/0024-firmware-ti_sci-rm-Remove-ring_get_config-support.patch deleted file mode 100644 index 5ece9718e..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0024-firmware-ti_sci-rm-Remove-ring_get_config-support.patch +++ /dev/null @@ -1,201 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Sun, 25 Oct 2020 12:10:05 -0700 -Subject: [PATCH] firmware: ti_sci: rm: Remove ring_get_config support - -The ring_get_cfg (0x1111 message) is not used and it is not supported by -sysfw for a long time. - -Signed-off-by: Peter Ujfalusi -Reviewed-by: Grygorii Strashko -Signed-off-by: Santosh Shilimkar ---- - drivers/firmware/ti_sci.c | 80 -------------------------- - drivers/firmware/ti_sci.h | 44 -------------- - include/linux/soc/ti/ti_sci_protocol.h | 6 -- - 3 files changed, 130 deletions(-) - -diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c -index 0dd3fbb4f964..0b801e67e672 100644 ---- a/drivers/firmware/ti_sci.c -+++ b/drivers/firmware/ti_sci.c -@@ -2119,85 +2119,6 @@ static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle, - return ret; - } - --/** -- * ti_sci_cmd_ring_get_config() - get RA ring configuration -- * @handle: Pointer to TI SCI handle. -- * @nav_id: Device ID of Navigator Subsystem from which the ring is -- * allocated -- * @index: Ring index -- * @addr_lo: Returns ring's base address lo 32 bits -- * @addr_hi: Returns ring's base address hi 32 bits -- * @count: Returns number of ring elements -- * @mode: Returns mode of the ring -- * @size: Returns ring element size -- * @order_id: Returns ring's bus order ID -- * -- * Return: 0 if all went well, else returns appropriate error value. -- * -- * See @ti_sci_msg_rm_ring_get_cfg_req for more info. -- */ --static int ti_sci_cmd_ring_get_config(const struct ti_sci_handle *handle, -- u32 nav_id, u32 index, u8 *mode, -- u32 *addr_lo, u32 *addr_hi, -- u32 *count, u8 *size, u8 *order_id) --{ -- struct ti_sci_msg_rm_ring_get_cfg_resp *resp; -- struct ti_sci_msg_rm_ring_get_cfg_req *req; -- struct ti_sci_xfer *xfer; -- struct ti_sci_info *info; -- struct device *dev; -- int ret = 0; -- -- if (IS_ERR_OR_NULL(handle)) -- return -EINVAL; -- -- info = handle_to_ti_sci_info(handle); -- dev = info->dev; -- -- xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_RING_GET_CFG, -- TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, -- sizeof(*req), sizeof(*resp)); -- if (IS_ERR(xfer)) { -- ret = PTR_ERR(xfer); -- dev_err(dev, -- "RM_RA:Message get config failed(%d)\n", ret); -- return ret; -- } -- req = (struct ti_sci_msg_rm_ring_get_cfg_req *)xfer->xfer_buf; -- req->nav_id = nav_id; -- req->index = index; -- -- ret = ti_sci_do_xfer(info, xfer); -- if (ret) { -- dev_err(dev, "RM_RA:Mbox get config send fail %d\n", ret); -- goto fail; -- } -- -- resp = (struct ti_sci_msg_rm_ring_get_cfg_resp *)xfer->xfer_buf; -- -- if (!ti_sci_is_response_ack(resp)) { -- ret = -ENODEV; -- } else { -- if (mode) -- *mode = resp->mode; -- if (addr_lo) -- *addr_lo = resp->addr_lo; -- if (addr_hi) -- *addr_hi = resp->addr_hi; -- if (count) -- *count = resp->count; -- if (size) -- *size = resp->size; -- if (order_id) -- *order_id = resp->order_id; -- }; -- --fail: -- ti_sci_put_one_xfer(&info->minfo, xfer); -- dev_dbg(dev, "RM_RA:get config ring %u ret:%d\n", index, ret); -- return ret; --} -- - /** - * ti_sci_cmd_rm_psil_pair() - Pair PSI-L source to destination thread - * @handle: Pointer to TI SCI handle. -@@ -2926,7 +2847,6 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) - iops->free_event_map = ti_sci_cmd_free_event_map; - - rops->config = ti_sci_cmd_ring_config; -- rops->get_config = ti_sci_cmd_ring_get_config; - - psilops->pair = ti_sci_cmd_rm_psil_pair; - psilops->unpair = ti_sci_cmd_rm_psil_unpair; -diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h -index ca15d8f1f8de..1cdf918be861 100644 ---- a/drivers/firmware/ti_sci.h -+++ b/drivers/firmware/ti_sci.h -@@ -49,7 +49,6 @@ - #define TI_SCI_MSG_RM_RING_RECONFIG 0x1102 - #define TI_SCI_MSG_RM_RING_RESET 0x1103 - #define TI_SCI_MSG_RM_RING_CFG 0x1110 --#define TI_SCI_MSG_RM_RING_GET_CFG 0x1111 - - /* PSI-L requests */ - #define TI_SCI_MSG_RM_PSIL_PAIR 0x1280 -@@ -687,49 +686,6 @@ struct ti_sci_msg_rm_ring_cfg_req { - u8 order_id; - } __packed; - --/** -- * struct ti_sci_msg_rm_ring_get_cfg_req - Get RA ring's configuration -- * -- * Gets the configuration of the non-real-time register fields of a ring. The -- * host, or a supervisor of the host, who owns the ring must be the requesting -- * host. The values of the non-real-time registers are returned in -- * @ti_sci_msg_rm_ring_get_cfg_resp. -- * -- * @hdr: Generic Header -- * @nav_id: Device ID of Navigator Subsystem from which the ring is allocated -- * @index: ring index. -- */ --struct ti_sci_msg_rm_ring_get_cfg_req { -- struct ti_sci_msg_hdr hdr; -- u16 nav_id; -- u16 index; --} __packed; -- --/** -- * struct ti_sci_msg_rm_ring_get_cfg_resp - Ring get configuration response -- * -- * Response received by host processor after RM has handled -- * @ti_sci_msg_rm_ring_get_cfg_req. The response contains the ring's -- * non-real-time register values. -- * -- * @hdr: Generic Header -- * @addr_lo: Ring 32 LSBs of base address -- * @addr_hi: Ring 16 MSBs of base address. -- * @count: Ring number of elements. -- * @mode: Ring mode. -- * @size: encoded Ring element size -- * @order_id: ing order ID. -- */ --struct ti_sci_msg_rm_ring_get_cfg_resp { -- struct ti_sci_msg_hdr hdr; -- u32 addr_lo; -- u32 addr_hi; -- u32 count; -- u8 mode; -- u8 size; -- u8 order_id; --} __packed; -- - /** - * struct ti_sci_msg_psil_pair - Pairs a PSI-L source thread to a destination - * thread -diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h -index a090b72a3362..7727ec954f62 100644 ---- a/include/linux/soc/ti/ti_sci_protocol.h -+++ b/include/linux/soc/ti/ti_sci_protocol.h -@@ -286,8 +286,6 @@ struct ti_sci_rm_irq_ops { - /** - * struct ti_sci_rm_ringacc_ops - Ring Accelerator Management operations - * @config: configure the SoC Navigator Subsystem Ring Accelerator ring -- * @get_config: get the SoC Navigator Subsystem Ring Accelerator ring -- * configuration - */ - struct ti_sci_rm_ringacc_ops { - int (*config)(const struct ti_sci_handle *handle, -@@ -295,10 +293,6 @@ struct ti_sci_rm_ringacc_ops { - u32 addr_lo, u32 addr_hi, u32 count, u8 mode, - u8 size, u8 order_id - ); -- int (*get_config)(const struct ti_sci_handle *handle, -- u32 nav_id, u32 index, u8 *mode, -- u32 *addr_lo, u32 *addr_hi, u32 *count, -- u8 *size, u8 *order_id); - }; - - /** diff --git a/recipes-kernel/linux/files/patches-5.10/0025-firmware-ti_sci-rm-Add-new-ops-for-ring-configuratio.patch b/recipes-kernel/linux/files/patches-5.10/0025-firmware-ti_sci-rm-Add-new-ops-for-ring-configuratio.patch deleted file mode 100644 index 7c5a14448..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0025-firmware-ti_sci-rm-Add-new-ops-for-ring-configuratio.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Sun, 25 Oct 2020 12:10:06 -0700 -Subject: [PATCH] firmware: ti_sci: rm: Add new ops for ring configuration - -The sysfw ring configuration message has been extended to include virtid -and asel value for the ring. -Add the ASEL_VALID to TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER as it is required -for DMA rings. - -Instead of extending the current .config() ops - which would need same -patch change in the ringacc driver - add ti_sci_msg_rm_ring_cfg struct and -a new ops using it to configure the ring. - -This will allow easy update path in case new members are added for the ring -configuration. - -Signed-off-by: Peter Ujfalusi -Reviewed-by: Grygorii Strashko -Signed-off-by: Santosh Shilimkar ---- - drivers/firmware/ti_sci.c | 63 ++++++++++++++++++++++++++ - drivers/firmware/ti_sci.h | 7 +++ - include/linux/soc/ti/ti_sci_protocol.h | 31 ++++++++++++- - 3 files changed, 100 insertions(+), 1 deletion(-) - -diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c -index 0b801e67e672..a4d2b318795c 100644 ---- a/drivers/firmware/ti_sci.c -+++ b/drivers/firmware/ti_sci.c -@@ -2119,6 +2119,68 @@ static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle, - return ret; - } - -+/** -+ * ti_sci_cmd_rm_ring_cfg() - Configure a NAVSS ring -+ * @handle: Pointer to TI SCI handle. -+ * @params: Pointer to ti_sci_msg_rm_ring_cfg ring config structure -+ * -+ * Return: 0 if all went well, else returns appropriate error value. -+ * -+ * See @ti_sci_msg_rm_ring_cfg and @ti_sci_msg_rm_ring_cfg_req for -+ * more info. -+ */ -+static int ti_sci_cmd_rm_ring_cfg(const struct ti_sci_handle *handle, -+ const struct ti_sci_msg_rm_ring_cfg *params) -+{ -+ struct ti_sci_msg_rm_ring_cfg_req *req; -+ struct ti_sci_msg_hdr *resp; -+ struct ti_sci_xfer *xfer; -+ struct ti_sci_info *info; -+ struct device *dev; -+ int ret = 0; -+ -+ if (IS_ERR_OR_NULL(handle)) -+ return -EINVAL; -+ -+ info = handle_to_ti_sci_info(handle); -+ dev = info->dev; -+ -+ xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_RING_CFG, -+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, -+ sizeof(*req), sizeof(*resp)); -+ if (IS_ERR(xfer)) { -+ ret = PTR_ERR(xfer); -+ dev_err(dev, "RM_RA:Message config failed(%d)\n", ret); -+ return ret; -+ } -+ req = (struct ti_sci_msg_rm_ring_cfg_req *)xfer->xfer_buf; -+ req->valid_params = params->valid_params; -+ req->nav_id = params->nav_id; -+ req->index = params->index; -+ req->addr_lo = params->addr_lo; -+ req->addr_hi = params->addr_hi; -+ req->count = params->count; -+ req->mode = params->mode; -+ req->size = params->size; -+ req->order_id = params->order_id; -+ req->virtid = params->virtid; -+ req->asel = params->asel; -+ -+ ret = ti_sci_do_xfer(info, xfer); -+ if (ret) { -+ dev_err(dev, "RM_RA:Mbox config send fail %d\n", ret); -+ goto fail; -+ } -+ -+ resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; -+ ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL; -+ -+fail: -+ ti_sci_put_one_xfer(&info->minfo, xfer); -+ dev_dbg(dev, "RM_RA:config ring %u ret:%d\n", params->index, ret); -+ return ret; -+} -+ - /** - * ti_sci_cmd_rm_psil_pair() - Pair PSI-L source to destination thread - * @handle: Pointer to TI SCI handle. -@@ -2847,6 +2909,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) - iops->free_event_map = ti_sci_cmd_free_event_map; - - rops->config = ti_sci_cmd_ring_config; -+ rops->set_cfg = ti_sci_cmd_rm_ring_cfg; - - psilops->pair = ti_sci_cmd_rm_psil_pair; - psilops->unpair = ti_sci_cmd_rm_psil_unpair; -diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h -index 1cdf918be861..ef3a8214d002 100644 ---- a/drivers/firmware/ti_sci.h -+++ b/drivers/firmware/ti_sci.h -@@ -659,6 +659,8 @@ struct ti_sci_msg_req_manage_irq { - * 3 - Valid bit for @tisci_msg_rm_ring_cfg_req mode - * 4 - Valid bit for @tisci_msg_rm_ring_cfg_req size - * 5 - Valid bit for @tisci_msg_rm_ring_cfg_req order_id -+ * 6 - Valid bit for @tisci_msg_rm_ring_cfg_req virtid -+ * 7 - Valid bit for @tisci_msg_rm_ring_cfg_req ASEL - * @nav_id: Device ID of Navigator Subsystem from which the ring is allocated - * @index: ring index to be configured. - * @addr_lo: 32 LSBs of ring base address to be programmed into the ring's -@@ -672,6 +674,9 @@ struct ti_sci_msg_req_manage_irq { - * the formula (log2(size_bytes) - 2), where size_bytes cannot be - * greater than 256. - * @order_id: Specifies the ring's bus order ID. -+ * @virtid: Ring virt ID value -+ * @asel: Ring ASEL (address select) value to be set into the ASEL field of the -+ * ring's RING_BA_HI register. - */ - struct ti_sci_msg_rm_ring_cfg_req { - struct ti_sci_msg_hdr hdr; -@@ -684,6 +689,8 @@ struct ti_sci_msg_rm_ring_cfg_req { - u8 mode; - u8 size; - u8 order_id; -+ u16 virtid; -+ u8 asel; - } __packed; - - /** -diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h -index 7727ec954f62..d7f0dcf98861 100644 ---- a/include/linux/soc/ti/ti_sci_protocol.h -+++ b/include/linux/soc/ti/ti_sci_protocol.h -@@ -275,17 +275,44 @@ struct ti_sci_rm_irq_ops { - #define TI_SCI_MSG_VALUE_RM_RING_SIZE_VALID BIT(4) - /* RA config.order_id parameter is valid for RM ring configure TISCI message */ - #define TI_SCI_MSG_VALUE_RM_RING_ORDER_ID_VALID BIT(5) -+/* RA config.virtid parameter is valid for RM ring configure TISCI message */ -+#define TI_SCI_MSG_VALUE_RM_RING_VIRTID_VALID BIT(6) -+/* RA config.asel parameter is valid for RM ring configure TISCI message */ -+#define TI_SCI_MSG_VALUE_RM_RING_ASEL_VALID BIT(7) - - #define TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER \ - (TI_SCI_MSG_VALUE_RM_RING_ADDR_LO_VALID | \ - TI_SCI_MSG_VALUE_RM_RING_ADDR_HI_VALID | \ - TI_SCI_MSG_VALUE_RM_RING_COUNT_VALID | \ - TI_SCI_MSG_VALUE_RM_RING_MODE_VALID | \ -- TI_SCI_MSG_VALUE_RM_RING_SIZE_VALID) -+ TI_SCI_MSG_VALUE_RM_RING_SIZE_VALID | \ -+ TI_SCI_MSG_VALUE_RM_RING_ASEL_VALID) -+ -+/** -+ * struct ti_sci_msg_rm_ring_cfg - Ring configuration -+ * -+ * Parameters for Navigator Subsystem ring configuration -+ * See @ti_sci_msg_rm_ring_cfg_req -+ */ -+struct ti_sci_msg_rm_ring_cfg { -+ u32 valid_params; -+ u16 nav_id; -+ u16 index; -+ u32 addr_lo; -+ u32 addr_hi; -+ u32 count; -+ u8 mode; -+ u8 size; -+ u8 order_id; -+ u16 virtid; -+ u8 asel; -+}; - - /** - * struct ti_sci_rm_ringacc_ops - Ring Accelerator Management operations - * @config: configure the SoC Navigator Subsystem Ring Accelerator ring -+ * Deprecated -+ * @set_cfg: configure the SoC Navigator Subsystem Ring Accelerator ring - */ - struct ti_sci_rm_ringacc_ops { - int (*config)(const struct ti_sci_handle *handle, -@@ -293,6 +320,8 @@ struct ti_sci_rm_ringacc_ops { - u32 addr_lo, u32 addr_hi, u32 count, u8 mode, - u8 size, u8 order_id - ); -+ int (*set_cfg)(const struct ti_sci_handle *handle, -+ const struct ti_sci_msg_rm_ring_cfg *params); - }; - - /** diff --git a/recipes-kernel/linux/files/patches-5.10/0026-soc-ti-k3-ringacc-Use-the-ti_sci-set_cfg-callback-fo.patch b/recipes-kernel/linux/files/patches-5.10/0026-soc-ti-k3-ringacc-Use-the-ti_sci-set_cfg-callback-fo.patch deleted file mode 100644 index cee6da51c..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0026-soc-ti-k3-ringacc-Use-the-ti_sci-set_cfg-callback-fo.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Sun, 25 Oct 2020 12:10:07 -0700 -Subject: [PATCH] soc: ti: k3-ringacc: Use the ti_sci set_cfg callback for ring - configuration - -Switch to the new set_cfg to configure the ring. - -Signed-off-by: Peter Ujfalusi -Reviewed-by: Grygorii Strashko -Signed-off-by: Santosh Shilimkar ---- - drivers/soc/ti/k3-ringacc.c | 79 +++++++++++++++---------------------- - 1 file changed, 32 insertions(+), 47 deletions(-) - -diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c -index 1147dc4c1d59..9ddd77113c5a 100644 ---- a/drivers/soc/ti/k3-ringacc.c -+++ b/drivers/soc/ti/k3-ringacc.c -@@ -365,20 +365,16 @@ EXPORT_SYMBOL_GPL(k3_ringacc_request_rings_pair); - - static void k3_ringacc_ring_reset_sci(struct k3_ring *ring) - { -+ struct ti_sci_msg_rm_ring_cfg ring_cfg = { 0 }; - struct k3_ringacc *ringacc = ring->parent; - int ret; - -- ret = ringacc->tisci_ring_ops->config( -- ringacc->tisci, -- TI_SCI_MSG_VALUE_RM_RING_COUNT_VALID, -- ringacc->tisci_dev_id, -- ring->ring_id, -- 0, -- 0, -- ring->size, -- 0, -- 0, -- 0); -+ ring_cfg.nav_id = ringacc->tisci_dev_id; -+ ring_cfg.index = ring->ring_id; -+ ring_cfg.valid_params = TI_SCI_MSG_VALUE_RM_RING_COUNT_VALID; -+ ring_cfg.count = ring->size; -+ -+ ret = ringacc->tisci_ring_ops->set_cfg(ringacc->tisci, &ring_cfg); - if (ret) - dev_err(ringacc->dev, "TISCI reset ring fail (%d) ring_idx %d\n", - ret, ring->ring_id); -@@ -398,20 +394,16 @@ EXPORT_SYMBOL_GPL(k3_ringacc_ring_reset); - static void k3_ringacc_ring_reconfig_qmode_sci(struct k3_ring *ring, - enum k3_ring_mode mode) - { -+ struct ti_sci_msg_rm_ring_cfg ring_cfg = { 0 }; - struct k3_ringacc *ringacc = ring->parent; - int ret; - -- ret = ringacc->tisci_ring_ops->config( -- ringacc->tisci, -- TI_SCI_MSG_VALUE_RM_RING_MODE_VALID, -- ringacc->tisci_dev_id, -- ring->ring_id, -- 0, -- 0, -- 0, -- mode, -- 0, -- 0); -+ ring_cfg.nav_id = ringacc->tisci_dev_id; -+ ring_cfg.index = ring->ring_id; -+ ring_cfg.valid_params = TI_SCI_MSG_VALUE_RM_RING_MODE_VALID; -+ ring_cfg.mode = mode; -+ -+ ret = ringacc->tisci_ring_ops->set_cfg(ringacc->tisci, &ring_cfg); - if (ret) - dev_err(ringacc->dev, "TISCI reconf qmode fail (%d) ring_idx %d\n", - ret, ring->ring_id); -@@ -478,20 +470,15 @@ EXPORT_SYMBOL_GPL(k3_ringacc_ring_reset_dma); - - static void k3_ringacc_ring_free_sci(struct k3_ring *ring) - { -+ struct ti_sci_msg_rm_ring_cfg ring_cfg = { 0 }; - struct k3_ringacc *ringacc = ring->parent; - int ret; - -- ret = ringacc->tisci_ring_ops->config( -- ringacc->tisci, -- TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER, -- ringacc->tisci_dev_id, -- ring->ring_id, -- 0, -- 0, -- 0, -- 0, -- 0, -- 0); -+ ring_cfg.nav_id = ringacc->tisci_dev_id; -+ ring_cfg.index = ring->ring_id; -+ ring_cfg.valid_params = TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER; -+ -+ ret = ringacc->tisci_ring_ops->set_cfg(ringacc->tisci, &ring_cfg); - if (ret) - dev_err(ringacc->dev, "TISCI ring free fail (%d) ring_idx %d\n", - ret, ring->ring_id); -@@ -575,28 +562,26 @@ EXPORT_SYMBOL_GPL(k3_ringacc_get_ring_irq_num); - - static int k3_ringacc_ring_cfg_sci(struct k3_ring *ring) - { -+ struct ti_sci_msg_rm_ring_cfg ring_cfg = { 0 }; - struct k3_ringacc *ringacc = ring->parent; -- u32 ring_idx; - int ret; - - if (!ringacc->tisci) - return -EINVAL; - -- ring_idx = ring->ring_id; -- ret = ringacc->tisci_ring_ops->config( -- ringacc->tisci, -- TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER, -- ringacc->tisci_dev_id, -- ring_idx, -- lower_32_bits(ring->ring_mem_dma), -- upper_32_bits(ring->ring_mem_dma), -- ring->size, -- ring->mode, -- ring->elm_size, -- 0); -+ ring_cfg.nav_id = ringacc->tisci_dev_id; -+ ring_cfg.index = ring->ring_id; -+ ring_cfg.valid_params = TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER; -+ ring_cfg.addr_lo = lower_32_bits(ring->ring_mem_dma); -+ ring_cfg.addr_hi = upper_32_bits(ring->ring_mem_dma); -+ ring_cfg.count = ring->size; -+ ring_cfg.mode = ring->mode; -+ ring_cfg.size = ring->elm_size; -+ -+ ret = ringacc->tisci_ring_ops->set_cfg(ringacc->tisci, &ring_cfg); - if (ret) - dev_err(ringacc->dev, "TISCI config ring fail (%d) ring_idx %d\n", -- ret, ring_idx); -+ ret, ring->ring_id); - - return ret; - } diff --git a/recipes-kernel/linux/files/patches-5.10/0027-firmware-ti_sci-rm-Remove-unused-config-from-ti_sci_.patch b/recipes-kernel/linux/files/patches-5.10/0027-firmware-ti_sci-rm-Remove-unused-config-from-ti_sci_.patch deleted file mode 100644 index 4c50df439..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0027-firmware-ti_sci-rm-Remove-unused-config-from-ti_sci_.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Sun, 25 Oct 2020 12:10:07 -0700 -Subject: [PATCH] firmware: ti_sci: rm: Remove unused config() from - ti_sci_rm_ringacc_ops - -The ringacc driver has been converted to use the new set_cfg function to -configure the ring, the old config ops can be removed. - -Signed-off-by: Peter Ujfalusi -Reviewed-by: Grygorii Strashko -Signed-off-by: Santosh Shilimkar ---- - drivers/firmware/ti_sci.c | 72 -------------------------- - include/linux/soc/ti/ti_sci_protocol.h | 7 --- - 2 files changed, 79 deletions(-) - -diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c -index a4d2b318795c..235c7e7869aa 100644 ---- a/drivers/firmware/ti_sci.c -+++ b/drivers/firmware/ti_sci.c -@@ -2048,77 +2048,6 @@ static int ti_sci_cmd_free_event_map(const struct ti_sci_handle *handle, - ia_id, vint, global_event, vint_status_bit, 0); - } - --/** -- * ti_sci_cmd_ring_config() - configure RA ring -- * @handle: Pointer to TI SCI handle. -- * @valid_params: Bitfield defining validity of ring configuration -- * parameters -- * @nav_id: Device ID of Navigator Subsystem from which the ring is -- * allocated -- * @index: Ring index -- * @addr_lo: The ring base address lo 32 bits -- * @addr_hi: The ring base address hi 32 bits -- * @count: Number of ring elements -- * @mode: The mode of the ring -- * @size: The ring element size. -- * @order_id: Specifies the ring's bus order ID -- * -- * Return: 0 if all went well, else returns appropriate error value. -- * -- * See @ti_sci_msg_rm_ring_cfg_req for more info. -- */ --static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle, -- u32 valid_params, u16 nav_id, u16 index, -- u32 addr_lo, u32 addr_hi, u32 count, -- u8 mode, u8 size, u8 order_id) --{ -- struct ti_sci_msg_rm_ring_cfg_req *req; -- struct ti_sci_msg_hdr *resp; -- struct ti_sci_xfer *xfer; -- struct ti_sci_info *info; -- struct device *dev; -- int ret = 0; -- -- if (IS_ERR_OR_NULL(handle)) -- return -EINVAL; -- -- info = handle_to_ti_sci_info(handle); -- dev = info->dev; -- -- xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_RING_CFG, -- TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, -- sizeof(*req), sizeof(*resp)); -- if (IS_ERR(xfer)) { -- ret = PTR_ERR(xfer); -- dev_err(dev, "RM_RA:Message config failed(%d)\n", ret); -- return ret; -- } -- req = (struct ti_sci_msg_rm_ring_cfg_req *)xfer->xfer_buf; -- req->valid_params = valid_params; -- req->nav_id = nav_id; -- req->index = index; -- req->addr_lo = addr_lo; -- req->addr_hi = addr_hi; -- req->count = count; -- req->mode = mode; -- req->size = size; -- req->order_id = order_id; -- -- ret = ti_sci_do_xfer(info, xfer); -- if (ret) { -- dev_err(dev, "RM_RA:Mbox config send fail %d\n", ret); -- goto fail; -- } -- -- resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; -- ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; -- --fail: -- ti_sci_put_one_xfer(&info->minfo, xfer); -- dev_dbg(dev, "RM_RA:config ring %u ret:%d\n", index, ret); -- return ret; --} -- - /** - * ti_sci_cmd_rm_ring_cfg() - Configure a NAVSS ring - * @handle: Pointer to TI SCI handle. -@@ -2908,7 +2837,6 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) - iops->free_irq = ti_sci_cmd_free_irq; - iops->free_event_map = ti_sci_cmd_free_event_map; - -- rops->config = ti_sci_cmd_ring_config; - rops->set_cfg = ti_sci_cmd_rm_ring_cfg; - - psilops->pair = ti_sci_cmd_rm_psil_pair; -diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h -index d7f0dcf98861..bd0d11af76c5 100644 ---- a/include/linux/soc/ti/ti_sci_protocol.h -+++ b/include/linux/soc/ti/ti_sci_protocol.h -@@ -310,16 +310,9 @@ struct ti_sci_msg_rm_ring_cfg { - - /** - * struct ti_sci_rm_ringacc_ops - Ring Accelerator Management operations -- * @config: configure the SoC Navigator Subsystem Ring Accelerator ring -- * Deprecated - * @set_cfg: configure the SoC Navigator Subsystem Ring Accelerator ring - */ - struct ti_sci_rm_ringacc_ops { -- int (*config)(const struct ti_sci_handle *handle, -- u32 valid_params, u16 nav_id, u16 index, -- u32 addr_lo, u32 addr_hi, u32 count, u8 mode, -- u8 size, u8 order_id -- ); - int (*set_cfg)(const struct ti_sci_handle *handle, - const struct ti_sci_msg_rm_ring_cfg *params); - }; diff --git a/recipes-kernel/linux/files/patches-5.10/0028-soc-ti-k3-ringacc-Use-correct-device-for-allocation-.patch b/recipes-kernel/linux/files/patches-5.10/0028-soc-ti-k3-ringacc-Use-correct-device-for-allocation-.patch deleted file mode 100644 index 40086b75b..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0028-soc-ti-k3-ringacc-Use-correct-device-for-allocation-.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Sun, 25 Oct 2020 12:10:22 -0700 -Subject: [PATCH] soc: ti: k3-ringacc: Use correct device for allocation in - RING mode - -In RING mode the ringacc does not access the ring memory. In this access -mode the ringacc coherency does not have meaning. - -If the ring is configured in RING mode, then the ringacc itself will not -access to the ring memory. Only the requester (user) of the ring is going -to read/write to the memory. -Extend the ring configuration parameters with a device pointer to be used -for DMA API when the ring is configured in RING mode. - -Extending the ring configuration struct will allow per ring selection of -device to be used for allocation, thus allowing per ring coherency. - -To avoid regression, fall back to use the ringacc dev in case the alloc_dev -is not provided. - -Signed-off-by: Peter Ujfalusi -Reviewed-by: Grygorii Strashko -Signed-off-by: Santosh Shilimkar ---- - drivers/soc/ti/k3-ringacc.c | 18 +++++++++++++----- - include/linux/soc/ti/k3-ringacc.h | 5 +++++ - 2 files changed, 18 insertions(+), 5 deletions(-) - -diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c -index 9ddd77113c5a..7fdb688452f7 100644 ---- a/drivers/soc/ti/k3-ringacc.c -+++ b/drivers/soc/ti/k3-ringacc.c -@@ -141,6 +141,7 @@ struct k3_ring_state { - * @parent: Pointer on struct @k3_ringacc - * @use_count: Use count for shared rings - * @proxy_id: RA Ring Proxy Id (only if @K3_RINGACC_RING_USE_PROXY) -+ * @dma_dev: device to be used for DMA API (allocation, mapping) - */ - struct k3_ring { - struct k3_ring_rt_regs __iomem *rt; -@@ -160,6 +161,7 @@ struct k3_ring { - struct k3_ringacc *parent; - u32 use_count; - int proxy_id; -+ struct device *dma_dev; - }; - - struct k3_ringacc_ops { -@@ -508,11 +510,12 @@ int k3_ringacc_ring_free(struct k3_ring *ring) - - k3_ringacc_ring_free_sci(ring); - -- dma_free_coherent(ringacc->dev, -+ dma_free_coherent(ring->dma_dev, - ring->size * (4 << ring->elm_size), - ring->ring_mem_virt, ring->ring_mem_dma); - ring->flags = 0; - ring->ops = NULL; -+ ring->dma_dev = NULL; - if (ring->proxy_id != K3_RINGACC_PROXY_NOT_USED) { - clear_bit(ring->proxy_id, ringacc->proxy_inuse); - ring->proxy = NULL; -@@ -633,8 +636,12 @@ int k3_ringacc_ring_cfg(struct k3_ring *ring, struct k3_ring_cfg *cfg) - switch (ring->mode) { - case K3_RINGACC_RING_MODE_RING: - ring->ops = &k3_ring_mode_ring_ops; -+ ring->dma_dev = cfg->dma_dev; -+ if (!ring->dma_dev) -+ ring->dma_dev = ringacc->dev; - break; - case K3_RINGACC_RING_MODE_MESSAGE: -+ ring->dma_dev = ringacc->dev; - if (ring->proxy) - ring->ops = &k3_ring_mode_proxy_ops; - else -@@ -646,9 +653,9 @@ int k3_ringacc_ring_cfg(struct k3_ring *ring, struct k3_ring_cfg *cfg) - goto err_free_proxy; - } - -- ring->ring_mem_virt = dma_alloc_coherent(ringacc->dev, -- ring->size * (4 << ring->elm_size), -- &ring->ring_mem_dma, GFP_KERNEL); -+ ring->ring_mem_virt = dma_alloc_coherent(ring->dma_dev, -+ ring->size * (4 << ring->elm_size), -+ &ring->ring_mem_dma, GFP_KERNEL); - if (!ring->ring_mem_virt) { - dev_err(ringacc->dev, "Failed to alloc ring mem\n"); - ret = -ENOMEM; -@@ -669,12 +676,13 @@ int k3_ringacc_ring_cfg(struct k3_ring *ring, struct k3_ring_cfg *cfg) - return 0; - - err_free_mem: -- dma_free_coherent(ringacc->dev, -+ dma_free_coherent(ring->dma_dev, - ring->size * (4 << ring->elm_size), - ring->ring_mem_virt, - ring->ring_mem_dma); - err_free_ops: - ring->ops = NULL; -+ ring->dma_dev = NULL; - err_free_proxy: - ring->proxy = NULL; - return ret; -diff --git a/include/linux/soc/ti/k3-ringacc.h b/include/linux/soc/ti/k3-ringacc.h -index 5a472eca5ee4..658dc71d2901 100644 ---- a/include/linux/soc/ti/k3-ringacc.h -+++ b/include/linux/soc/ti/k3-ringacc.h -@@ -67,6 +67,9 @@ struct k3_ring; - * few times. It's usable when the same ring is used as Free Host PD ring - * for different flows, for example. - * Note: Locking should be done by consumer if required -+ * @dma_dev: Master device which is using and accessing to the ring -+ * memory when the mode is K3_RINGACC_RING_MODE_RING. Memory allocations -+ * should be done using this device. - */ - struct k3_ring_cfg { - u32 size; -@@ -74,6 +77,8 @@ struct k3_ring_cfg { - enum k3_ring_mode mode; - #define K3_RINGACC_RING_SHARED BIT(1) - u32 flags; -+ -+ struct device *dma_dev; - }; - - #define K3_RINGACC_RING_ID_ANY (-1) diff --git a/recipes-kernel/linux/files/patches-5.10/0029-soc-ti-pruss-Remove-wrong-check-against-get_match_da.patch b/recipes-kernel/linux/files/patches-5.10/0029-soc-ti-pruss-Remove-wrong-check-against-get_match_da.patch deleted file mode 100644 index 7d5f80ad7..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0029-soc-ti-pruss-Remove-wrong-check-against-get_match_da.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grzegorz Jaszczyk -Date: Sat, 21 Nov 2020 19:22:25 -0800 -Subject: [PATCH] soc: ti: pruss: Remove wrong check against *get_match_data - return value - -Since the of_device_get_match_data() doesn't return error code, remove -wrong IS_ERR test. Proper check against NULL pointer is already done -later before usage: if (data && data->...). - -Additionally, proceeding with empty device data is valid (e.g. in case -of "ti,am3356-pruss"). - -Reported-by: Wei Yongjun -Signed-off-by: Grzegorz Jaszczyk -Signed-off-by: Santosh Shilimkar ---- - drivers/soc/ti/pruss.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c -index 30695172a508..aa3aba80dbc6 100644 ---- a/drivers/soc/ti/pruss.c -+++ b/drivers/soc/ti/pruss.c -@@ -126,8 +126,6 @@ static int pruss_clk_init(struct pruss *pruss, struct device_node *cfg_node) - int ret = 0; - - data = of_device_get_match_data(dev); -- if (IS_ERR(data)) -- return -ENODEV; - - clks_np = of_get_child_by_name(cfg_node, "clocks"); - if (!clks_np) { -@@ -175,10 +173,6 @@ static int pruss_probe(struct platform_device *pdev) - const char *mem_names[PRUSS_MEM_MAX] = { "dram0", "dram1", "shrdram2" }; - - data = of_device_get_match_data(&pdev->dev); -- if (IS_ERR(data)) { -- dev_err(dev, "missing private data\n"); -- return -ENODEV; -- } - - ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); - if (ret) { diff --git a/recipes-kernel/linux/files/patches-5.10/0030-soc-ti-pruss-Correct-the-pruss_clk_init-error-trace-.patch b/recipes-kernel/linux/files/patches-5.10/0030-soc-ti-pruss-Correct-the-pruss_clk_init-error-trace-.patch deleted file mode 100644 index be60b7ae9..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0030-soc-ti-pruss-Correct-the-pruss_clk_init-error-trace-.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Sun, 24 Jan 2021 20:51:37 -0800 -Subject: [PATCH] soc: ti: pruss: Correct the pruss_clk_init error trace text - -The pruss_clk_init() function can register more than one clock. -Correct the existing misleading error trace upon a failure within -this function. - -Signed-off-by: Suman Anna -Signed-off-by: Santosh Shilimkar ---- - drivers/soc/ti/pruss.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c -index aa3aba80dbc6..dc94335fc351 100644 ---- a/drivers/soc/ti/pruss.c -+++ b/drivers/soc/ti/pruss.c -@@ -273,7 +273,7 @@ static int pruss_probe(struct platform_device *pdev) - - ret = pruss_clk_init(pruss, child); - if (ret) { -- dev_err(dev, "failed to setup coreclk-mux\n"); -+ dev_err(dev, "pruss_clk_init failed, ret = %d\n", ret); - goto node_put; - } - diff --git a/recipes-kernel/linux/files/patches-5.10/0031-soc-ti-pruss-Refactor-the-CFG-sub-module-init.patch b/recipes-kernel/linux/files/patches-5.10/0031-soc-ti-pruss-Refactor-the-CFG-sub-module-init.patch deleted file mode 100644 index 48137a564..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0031-soc-ti-pruss-Refactor-the-CFG-sub-module-init.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Sun, 31 Jan 2021 20:53:43 -0800 -Subject: [PATCH] soc: ti: pruss: Refactor the CFG sub-module init - -The CFG sub-module is not present on some earlier SoCs like the -DA850/OMAPL-138 in the TI Davinci family. Refactor out the CFG -sub-module parse and initialization logic into a separate function -to make it easier to add logic for the PRUSS IP on the above legacy -SoC families. - -Signed-off-by: Suman Anna -Signed-off-by: Santosh Shilimkar ---- - drivers/soc/ti/pruss.c | 91 +++++++++++++++++++++++------------------- - 1 file changed, 50 insertions(+), 41 deletions(-) - -diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c -index dc94335fc351..afc8aae68035 100644 ---- a/drivers/soc/ti/pruss.c -+++ b/drivers/soc/ti/pruss.c -@@ -161,6 +161,53 @@ static struct regmap_config regmap_conf = { - .reg_stride = 4, - }; - -+static int pruss_cfg_of_init(struct device *dev, struct pruss *pruss) -+{ -+ struct device_node *np = dev_of_node(dev); -+ struct device_node *child; -+ struct resource res; -+ int ret; -+ -+ child = of_get_child_by_name(np, "cfg"); -+ if (!child) { -+ dev_err(dev, "%pOF is missing its 'cfg' node\n", child); -+ return -ENODEV; -+ } -+ -+ if (of_address_to_resource(child, 0, &res)) { -+ ret = -ENOMEM; -+ goto node_put; -+ } -+ -+ pruss->cfg_base = devm_ioremap(dev, res.start, resource_size(&res)); -+ if (!pruss->cfg_base) { -+ ret = -ENOMEM; -+ goto node_put; -+ } -+ -+ regmap_conf.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", child, -+ (u64)res.start); -+ regmap_conf.max_register = resource_size(&res) - 4; -+ -+ pruss->cfg_regmap = devm_regmap_init_mmio(dev, pruss->cfg_base, -+ ®map_conf); -+ kfree(regmap_conf.name); -+ if (IS_ERR(pruss->cfg_regmap)) { -+ dev_err(dev, "regmap_init_mmio failed for cfg, ret = %ld\n", -+ PTR_ERR(pruss->cfg_regmap)); -+ ret = PTR_ERR(pruss->cfg_regmap); -+ goto node_put; -+ } -+ -+ ret = pruss_clk_init(pruss, child); -+ if (ret) -+ dev_err(dev, "pruss_clk_init failed, ret = %d\n", ret); -+ -+node_put: -+ of_node_put(child); -+ return ret; -+} -+ - static int pruss_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -239,56 +286,18 @@ static int pruss_probe(struct platform_device *pdev) - goto rpm_disable; - } - -- child = of_get_child_by_name(np, "cfg"); -- if (!child) { -- dev_err(dev, "%pOF is missing its 'cfg' node\n", child); -- ret = -ENODEV; -+ ret = pruss_cfg_of_init(dev, pruss); -+ if (ret < 0) - goto rpm_put; -- } -- -- if (of_address_to_resource(child, 0, &res)) { -- ret = -ENOMEM; -- goto node_put; -- } -- -- pruss->cfg_base = devm_ioremap(dev, res.start, resource_size(&res)); -- if (!pruss->cfg_base) { -- ret = -ENOMEM; -- goto node_put; -- } -- -- regmap_conf.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", child, -- (u64)res.start); -- regmap_conf.max_register = resource_size(&res) - 4; -- -- pruss->cfg_regmap = devm_regmap_init_mmio(dev, pruss->cfg_base, -- ®map_conf); -- kfree(regmap_conf.name); -- if (IS_ERR(pruss->cfg_regmap)) { -- dev_err(dev, "regmap_init_mmio failed for cfg, ret = %ld\n", -- PTR_ERR(pruss->cfg_regmap)); -- ret = PTR_ERR(pruss->cfg_regmap); -- goto node_put; -- } -- -- ret = pruss_clk_init(pruss, child); -- if (ret) { -- dev_err(dev, "pruss_clk_init failed, ret = %d\n", ret); -- goto node_put; -- } - - ret = devm_of_platform_populate(dev); - if (ret) { - dev_err(dev, "failed to register child devices\n"); -- goto node_put; -+ goto rpm_put; - } - -- of_node_put(child); -- - return 0; - --node_put: -- of_node_put(child); - rpm_put: - pm_runtime_put_sync(dev); - rpm_disable: diff --git a/recipes-kernel/linux/files/patches-5.10/0032-soc-ti-k3-ringacc-Use-of_device_get_match_data.patch b/recipes-kernel/linux/files/patches-5.10/0032-soc-ti-k3-ringacc-Use-of_device_get_match_data.patch deleted file mode 100644 index 1dc105e9c..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0032-soc-ti-k3-ringacc-Use-of_device_get_match_data.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Sun, 31 Jan 2021 20:58:49 -0800 -Subject: [PATCH] soc: ti: k3-ringacc: Use of_device_get_match_data() - -Simplify the retrieval of getting the match data in the probe -function by directly using of_device_get_match_data() instead -of using of_match_node() and getting data. - -Signed-off-by: Suman Anna -Signed-off-by: Santosh Shilimkar ---- - drivers/soc/ti/k3-ringacc.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c -index 7fdb688452f7..db3f705da7a0 100644 ---- a/drivers/soc/ti/k3-ringacc.c -+++ b/drivers/soc/ti/k3-ringacc.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1205,15 +1206,13 @@ static const struct of_device_id k3_ringacc_of_match[] = { - static int k3_ringacc_probe(struct platform_device *pdev) - { - const struct ringacc_match_data *match_data; -- const struct of_device_id *match; - struct device *dev = &pdev->dev; - struct k3_ringacc *ringacc; - int ret; - -- match = of_match_node(k3_ringacc_of_match, dev->of_node); -- if (!match) -+ match_data = of_device_get_match_data(&pdev->dev); -+ if (!match_data) - return -ENODEV; -- match_data = match->data; - - ringacc = devm_kzalloc(dev, sizeof(*ringacc), GFP_KERNEL); - if (!ringacc) diff --git a/recipes-kernel/linux/files/patches-5.10/0033-remoteproc-ti_k3-fix-Wcast-function-type-warning.patch b/recipes-kernel/linux/files/patches-5.10/0033-remoteproc-ti_k3-fix-Wcast-function-type-warning.patch deleted file mode 100644 index 4efdcbc7b..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0033-remoteproc-ti_k3-fix-Wcast-function-type-warning.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -Date: Mon, 26 Oct 2020 17:05:23 +0100 -Subject: [PATCH] remoteproc: ti_k3: fix -Wcast-function-type warning - -The function cast causes a warning with "make W=1" - -drivers/remoteproc/ti_k3_r5_remoteproc.c: In function 'k3_r5_probe': -drivers/remoteproc/ti_k3_r5_remoteproc.c:1368:12: warning: cast between incompatible function types from 'int (*)(struct platform_device *)' to 'void (*)(void *)' [-Wcast-function-type] - -Rewrite the code to avoid the cast, and fix the incorrect return -type of the callback. - -Fixes: 6dedbd1d5443 ("remoteproc: k3-r5: Add a remoteproc driver for R5F subsystem") -Signed-off-by: Arnd Bergmann -Link: https://lore.kernel.org/r/20201026160533.3705998-1-arnd@kernel.org -Signed-off-by: Bjorn Andersson ---- - drivers/remoteproc/ti_k3_r5_remoteproc.c | 18 ++++++------------ - 1 file changed, 6 insertions(+), 12 deletions(-) - -diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c b/drivers/remoteproc/ti_k3_r5_remoteproc.c -index f92a18c06d80..e5346251db0f 100644 ---- a/drivers/remoteproc/ti_k3_r5_remoteproc.c -+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c -@@ -940,9 +940,9 @@ static int k3_r5_cluster_rproc_init(struct platform_device *pdev) - return ret; - } - --static int k3_r5_cluster_rproc_exit(struct platform_device *pdev) -+static void k3_r5_cluster_rproc_exit(void *data) - { -- struct k3_r5_cluster *cluster = platform_get_drvdata(pdev); -+ struct k3_r5_cluster *cluster = platform_get_drvdata(data); - struct k3_r5_rproc *kproc; - struct k3_r5_core *core; - struct rproc *rproc; -@@ -967,8 +967,6 @@ static int k3_r5_cluster_rproc_exit(struct platform_device *pdev) - rproc_free(rproc); - core->rproc = NULL; - } -- -- return 0; - } - - static int k3_r5_core_of_get_internal_memories(struct platform_device *pdev, -@@ -1255,9 +1253,9 @@ static void k3_r5_core_of_exit(struct platform_device *pdev) - devres_release_group(dev, k3_r5_core_of_init); - } - --static void k3_r5_cluster_of_exit(struct platform_device *pdev) -+static void k3_r5_cluster_of_exit(void *data) - { -- struct k3_r5_cluster *cluster = platform_get_drvdata(pdev); -+ struct k3_r5_cluster *cluster = platform_get_drvdata(data); - struct platform_device *cpdev; - struct k3_r5_core *core, *temp; - -@@ -1353,9 +1351,7 @@ static int k3_r5_probe(struct platform_device *pdev) - return ret; - } - -- ret = devm_add_action_or_reset(dev, -- (void(*)(void *))k3_r5_cluster_of_exit, -- pdev); -+ ret = devm_add_action_or_reset(dev, k3_r5_cluster_of_exit, pdev); - if (ret) - return ret; - -@@ -1366,9 +1362,7 @@ static int k3_r5_probe(struct platform_device *pdev) - return ret; - } - -- ret = devm_add_action_or_reset(dev, -- (void(*)(void *))k3_r5_cluster_rproc_exit, -- pdev); -+ ret = devm_add_action_or_reset(dev, k3_r5_cluster_rproc_exit, pdev); - if (ret) - return ret; - diff --git a/recipes-kernel/linux/files/patches-5.10/0034-remoteproc-Add-a-rproc_set_firmware-API.patch b/recipes-kernel/linux/files/patches-5.10/0034-remoteproc-Add-a-rproc_set_firmware-API.patch deleted file mode 100644 index b6548bf83..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0034-remoteproc-Add-a-rproc_set_firmware-API.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Fri, 20 Nov 2020 21:20:42 -0600 -Subject: [PATCH] remoteproc: Add a rproc_set_firmware() API - -A new API, rproc_set_firmware() is added to allow the remoteproc platform -drivers and remoteproc client drivers to be able to configure a custom -firmware name that is different from the default name used during -remoteproc registration. This function is being introduced to provide -a kernel-level equivalent of the current sysfs interface to remoteproc -client drivers, and can only change firmwares when the remoteproc is -offline. This allows some remoteproc drivers to choose different firmwares -at runtime based on the functionality the remote processor is providing. -The TI PRU Ethernet driver will be an example of such usage as it -requires to use different firmwares for different supported protocols. - -Also, update the firmware_store() function used by the sysfs interface -to reuse this function to avoid code duplication. - -Reviewed-by: Rishabh Bhatnagar -Signed-off-by: Suman Anna -Link: https://lore.kernel.org/r/20201121032042.6195-1-s-anna@ti.com -Signed-off-by: Bjorn Andersson ---- - drivers/remoteproc/remoteproc_core.c | 63 +++++++++++++++++++++++++++ - drivers/remoteproc/remoteproc_sysfs.c | 33 +------------- - include/linux/remoteproc.h | 1 + - 3 files changed, 66 insertions(+), 31 deletions(-) - -diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c -index cc55ff0128cf..742da1079010 100644 ---- a/drivers/remoteproc/remoteproc_core.c -+++ b/drivers/remoteproc/remoteproc_core.c -@@ -1943,6 +1943,69 @@ struct rproc *rproc_get_by_phandle(phandle phandle) - #endif - EXPORT_SYMBOL(rproc_get_by_phandle); - -+/** -+ * rproc_set_firmware() - assign a new firmware -+ * @rproc: rproc handle to which the new firmware is being assigned -+ * @fw_name: new firmware name to be assigned -+ * -+ * This function allows remoteproc drivers or clients to configure a custom -+ * firmware name that is different from the default name used during remoteproc -+ * registration. The function does not trigger a remote processor boot, -+ * only sets the firmware name used for a subsequent boot. This function -+ * should also be called only when the remote processor is offline. -+ * -+ * This allows either the userspace to configure a different name through -+ * sysfs or a kernel-level remoteproc or a remoteproc client driver to set -+ * a specific firmware when it is controlling the boot and shutdown of the -+ * remote processor. -+ * -+ * Return: 0 on success or a negative value upon failure -+ */ -+int rproc_set_firmware(struct rproc *rproc, const char *fw_name) -+{ -+ struct device *dev; -+ int ret, len; -+ char *p; -+ -+ if (!rproc || !fw_name) -+ return -EINVAL; -+ -+ dev = rproc->dev.parent; -+ -+ ret = mutex_lock_interruptible(&rproc->lock); -+ if (ret) { -+ dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret); -+ return -EINVAL; -+ } -+ -+ if (rproc->state != RPROC_OFFLINE) { -+ dev_err(dev, "can't change firmware while running\n"); -+ ret = -EBUSY; -+ goto out; -+ } -+ -+ len = strcspn(fw_name, "\n"); -+ if (!len) { -+ dev_err(dev, "can't provide empty string for firmware name\n"); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ p = kstrndup(fw_name, len, GFP_KERNEL); -+ if (!p) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ kfree(rproc->firmware); -+ rproc->firmware = p; -+ -+out: -+ mutex_unlock(&rproc->lock); -+ return ret; -+} -+EXPORT_SYMBOL(rproc_set_firmware); -+ - static int rproc_validate(struct rproc *rproc) - { - switch (rproc->state) { -diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c -index d1cf7bf277c4..1dbef895e65e 100644 ---- a/drivers/remoteproc/remoteproc_sysfs.c -+++ b/drivers/remoteproc/remoteproc_sysfs.c -@@ -154,38 +154,9 @@ static ssize_t firmware_store(struct device *dev, - const char *buf, size_t count) - { - struct rproc *rproc = to_rproc(dev); -- char *p; -- int err, len = count; -+ int err; - -- err = mutex_lock_interruptible(&rproc->lock); -- if (err) { -- dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, err); -- return -EINVAL; -- } -- -- if (rproc->state != RPROC_OFFLINE) { -- dev_err(dev, "can't change firmware while running\n"); -- err = -EBUSY; -- goto out; -- } -- -- len = strcspn(buf, "\n"); -- if (!len) { -- dev_err(dev, "can't provide a NULL firmware\n"); -- err = -EINVAL; -- goto out; -- } -- -- p = kstrndup(buf, len, GFP_KERNEL); -- if (!p) { -- err = -ENOMEM; -- goto out; -- } -- -- kfree(rproc->firmware); -- rproc->firmware = p; --out: -- mutex_unlock(&rproc->lock); -+ err = rproc_set_firmware(rproc, buf); - - return err ? err : count; - } -diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h -index 3fa3ba6498e8..e8ac041c64d9 100644 ---- a/include/linux/remoteproc.h -+++ b/include/linux/remoteproc.h -@@ -653,6 +653,7 @@ rproc_of_resm_mem_entry_init(struct device *dev, u32 of_resm_idx, size_t len, - - int rproc_boot(struct rproc *rproc); - void rproc_shutdown(struct rproc *rproc); -+int rproc_set_firmware(struct rproc *rproc, const char *fw_name); - void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type); - int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size); - int rproc_coredump_add_custom_segment(struct rproc *rproc, diff --git a/recipes-kernel/linux/files/patches-5.10/0035-remoteproc-pru-Add-a-PRU-remoteproc-driver.patch b/recipes-kernel/linux/files/patches-5.10/0035-remoteproc-pru-Add-a-PRU-remoteproc-driver.patch deleted file mode 100644 index 820425def..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0035-remoteproc-pru-Add-a-PRU-remoteproc-driver.patch +++ /dev/null @@ -1,525 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Tue, 8 Dec 2020 15:09:58 +0100 -Subject: [PATCH] remoteproc: pru: Add a PRU remoteproc driver - -The Programmable Real-Time Unit Subsystem (PRUSS) consists of -dual 32-bit RISC cores (Programmable Real-Time Units, or PRUs) -for program execution. This patch adds a remoteproc platform -driver for managing the individual PRU RISC cores life cycle. - -The PRUs do not have a unified address space (have an Instruction -RAM and a primary Data RAM at both 0x0). The PRU remoteproc driver -therefore uses a custom remoteproc core ELF loader ops. The added -.da_to_va ops is only used to provide translations for the PRU -Data RAMs. This remoteproc driver does not have support for error -recovery and system suspend/resume features. Different compatibles -are used to allow providing scalability for instance-specific device -data if needed. The driver uses a default firmware-name retrieved -from device-tree for each PRU core, and the firmwares are expected -to be present in the standard Linux firmware search paths. They can -also be adjusted by userspace if required through the sysfs interface -provided by the remoteproc core. - -The PRU remoteproc driver uses a client-driven boot methodology: it -does _not_ support auto-boot so that the PRU load and boot is dictated -by the corresponding client drivers for achieving various usecases. -This allows flexibility for the client drivers or applications to set -a firmware name (if needed) based on their desired functionality and -boot the PRU. The sysfs bind and unbind attributes have also been -suppressed so that the PRU devices cannot be unbound and thereby -shutdown a PRU from underneath a PRU client driver. - -The driver currently supports the AM335x, AM437x, AM57xx and 66AK2G -SoCs, and support for other TI SoCs will be added in subsequent -patches. - -Co-developed-by: Andrew F. Davis -Signed-off-by: Andrew F. Davis -Signed-off-by: Suman Anna -Co-developed-by: Grzegorz Jaszczyk -Signed-off-by: Grzegorz Jaszczyk -Reviewed-by: Mathieu Poirier -Link: https://lore.kernel.org/r/20201208141002.17777-3-grzegorz.jaszczyk@linaro.org -Signed-off-by: Bjorn Andersson ---- - drivers/remoteproc/Kconfig | 12 + - drivers/remoteproc/Makefile | 1 + - drivers/remoteproc/pru_rproc.c | 433 +++++++++++++++++++++++++++++++++ - 3 files changed, 446 insertions(+) - create mode 100644 drivers/remoteproc/pru_rproc.c - -diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig -index d99548fb5dde..3e3865a7cd78 100644 ---- a/drivers/remoteproc/Kconfig -+++ b/drivers/remoteproc/Kconfig -@@ -125,6 +125,18 @@ config KEYSTONE_REMOTEPROC - It's safe to say N here if you're not interested in the Keystone - DSPs or just want to use a bare minimum kernel. - -+config PRU_REMOTEPROC -+ tristate "TI PRU remoteproc support" -+ depends on TI_PRUSS -+ default TI_PRUSS -+ help -+ Support for TI PRU remote processors present within a PRU-ICSS -+ subsystem via the remote processor framework. -+ -+ Say Y or M here to support the Programmable Realtime Unit (PRU) -+ processors on various TI SoCs. It's safe to say N here if you're -+ not interested in the PRU or if you are unsure. -+ - config QCOM_PIL_INFO - tristate - -diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile -index da2ace4ec86c..bb26c9e4ef9c 100644 ---- a/drivers/remoteproc/Makefile -+++ b/drivers/remoteproc/Makefile -@@ -18,6 +18,7 @@ obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o - obj-$(CONFIG_WKUP_M3_RPROC) += wkup_m3_rproc.o - obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o - obj-$(CONFIG_KEYSTONE_REMOTEPROC) += keystone_remoteproc.o -+obj-$(CONFIG_PRU_REMOTEPROC) += pru_rproc.o - obj-$(CONFIG_QCOM_PIL_INFO) += qcom_pil_info.o - obj-$(CONFIG_QCOM_RPROC_COMMON) += qcom_common.o - obj-$(CONFIG_QCOM_Q6V5_COMMON) += qcom_q6v5.o -diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c -new file mode 100644 -index 000000000000..d33392bbd8af ---- /dev/null -+++ b/drivers/remoteproc/pru_rproc.c -@@ -0,0 +1,433 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * PRU-ICSS remoteproc driver for various TI SoCs -+ * -+ * Copyright (C) 2014-2020 Texas Instruments Incorporated - https://www.ti.com/ -+ * -+ * Author(s): -+ * Suman Anna -+ * Andrew F. Davis -+ * Grzegorz Jaszczyk for Texas Instruments -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "remoteproc_internal.h" -+#include "remoteproc_elf_helpers.h" -+ -+/* PRU_ICSS_PRU_CTRL registers */ -+#define PRU_CTRL_CTRL 0x0000 -+#define PRU_CTRL_STS 0x0004 -+ -+/* CTRL register bit-fields */ -+#define CTRL_CTRL_SOFT_RST_N BIT(0) -+#define CTRL_CTRL_EN BIT(1) -+#define CTRL_CTRL_SLEEPING BIT(2) -+#define CTRL_CTRL_CTR_EN BIT(3) -+#define CTRL_CTRL_SINGLE_STEP BIT(8) -+#define CTRL_CTRL_RUNSTATE BIT(15) -+ -+/* PRU Core IRAM address masks */ -+#define PRU_IRAM_ADDR_MASK 0x3ffff -+#define PRU0_IRAM_ADDR_MASK 0x34000 -+#define PRU1_IRAM_ADDR_MASK 0x38000 -+ -+/* PRU device addresses for various type of PRU RAMs */ -+#define PRU_IRAM_DA 0 /* Instruction RAM */ -+#define PRU_PDRAM_DA 0 /* Primary Data RAM */ -+#define PRU_SDRAM_DA 0x2000 /* Secondary Data RAM */ -+#define PRU_SHRDRAM_DA 0x10000 /* Shared Data RAM */ -+ -+/** -+ * enum pru_iomem - PRU core memory/register range identifiers -+ * -+ * @PRU_IOMEM_IRAM: PRU Instruction RAM range -+ * @PRU_IOMEM_CTRL: PRU Control register range -+ * @PRU_IOMEM_DEBUG: PRU Debug register range -+ * @PRU_IOMEM_MAX: just keep this one at the end -+ */ -+enum pru_iomem { -+ PRU_IOMEM_IRAM = 0, -+ PRU_IOMEM_CTRL, -+ PRU_IOMEM_DEBUG, -+ PRU_IOMEM_MAX, -+}; -+ -+/** -+ * struct pru_rproc - PRU remoteproc structure -+ * @id: id of the PRU core within the PRUSS -+ * @dev: PRU core device pointer -+ * @pruss: back-reference to parent PRUSS structure -+ * @rproc: remoteproc pointer for this PRU core -+ * @mem_regions: data for each of the PRU memory regions -+ * @fw_name: name of firmware image used during loading -+ */ -+struct pru_rproc { -+ int id; -+ struct device *dev; -+ struct pruss *pruss; -+ struct rproc *rproc; -+ struct pruss_mem_region mem_regions[PRU_IOMEM_MAX]; -+ const char *fw_name; -+}; -+ -+static inline u32 pru_control_read_reg(struct pru_rproc *pru, unsigned int reg) -+{ -+ return readl_relaxed(pru->mem_regions[PRU_IOMEM_CTRL].va + reg); -+} -+ -+static inline -+void pru_control_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val) -+{ -+ writel_relaxed(val, pru->mem_regions[PRU_IOMEM_CTRL].va + reg); -+} -+ -+static int pru_rproc_start(struct rproc *rproc) -+{ -+ struct device *dev = &rproc->dev; -+ struct pru_rproc *pru = rproc->priv; -+ u32 val; -+ -+ dev_dbg(dev, "starting PRU%d: entry-point = 0x%llx\n", -+ pru->id, (rproc->bootaddr >> 2)); -+ -+ val = CTRL_CTRL_EN | ((rproc->bootaddr >> 2) << 16); -+ pru_control_write_reg(pru, PRU_CTRL_CTRL, val); -+ -+ return 0; -+} -+ -+static int pru_rproc_stop(struct rproc *rproc) -+{ -+ struct device *dev = &rproc->dev; -+ struct pru_rproc *pru = rproc->priv; -+ u32 val; -+ -+ dev_dbg(dev, "stopping PRU%d\n", pru->id); -+ -+ val = pru_control_read_reg(pru, PRU_CTRL_CTRL); -+ val &= ~CTRL_CTRL_EN; -+ pru_control_write_reg(pru, PRU_CTRL_CTRL, val); -+ -+ return 0; -+} -+ -+/* -+ * Convert PRU device address (data spaces only) to kernel virtual address. -+ * -+ * Each PRU has access to all data memories within the PRUSS, accessible at -+ * different ranges. So, look through both its primary and secondary Data -+ * RAMs as well as any shared Data RAM to convert a PRU device address to -+ * kernel virtual address. Data RAM0 is primary Data RAM for PRU0 and Data -+ * RAM1 is primary Data RAM for PRU1. -+ */ -+static void *pru_d_da_to_va(struct pru_rproc *pru, u32 da, size_t len) -+{ -+ struct pruss_mem_region dram0, dram1, shrd_ram; -+ struct pruss *pruss = pru->pruss; -+ u32 offset; -+ void *va = NULL; -+ -+ if (len == 0) -+ return NULL; -+ -+ dram0 = pruss->mem_regions[PRUSS_MEM_DRAM0]; -+ dram1 = pruss->mem_regions[PRUSS_MEM_DRAM1]; -+ /* PRU1 has its local RAM addresses reversed */ -+ if (pru->id == 1) -+ swap(dram0, dram1); -+ shrd_ram = pruss->mem_regions[PRUSS_MEM_SHRD_RAM2]; -+ -+ if (da >= PRU_PDRAM_DA && da + len <= PRU_PDRAM_DA + dram0.size) { -+ offset = da - PRU_PDRAM_DA; -+ va = (__force void *)(dram0.va + offset); -+ } else if (da >= PRU_SDRAM_DA && -+ da + len <= PRU_SDRAM_DA + dram1.size) { -+ offset = da - PRU_SDRAM_DA; -+ va = (__force void *)(dram1.va + offset); -+ } else if (da >= PRU_SHRDRAM_DA && -+ da + len <= PRU_SHRDRAM_DA + shrd_ram.size) { -+ offset = da - PRU_SHRDRAM_DA; -+ va = (__force void *)(shrd_ram.va + offset); -+ } -+ -+ return va; -+} -+ -+/* -+ * Convert PRU device address (instruction space) to kernel virtual address. -+ * -+ * A PRU does not have an unified address space. Each PRU has its very own -+ * private Instruction RAM, and its device address is identical to that of -+ * its primary Data RAM device address. -+ */ -+static void *pru_i_da_to_va(struct pru_rproc *pru, u32 da, size_t len) -+{ -+ u32 offset; -+ void *va = NULL; -+ -+ if (len == 0) -+ return NULL; -+ -+ if (da >= PRU_IRAM_DA && -+ da + len <= PRU_IRAM_DA + pru->mem_regions[PRU_IOMEM_IRAM].size) { -+ offset = da - PRU_IRAM_DA; -+ va = (__force void *)(pru->mem_regions[PRU_IOMEM_IRAM].va + -+ offset); -+ } -+ -+ return va; -+} -+ -+/* -+ * Provide address translations for only PRU Data RAMs through the remoteproc -+ * core for any PRU client drivers. The PRU Instruction RAM access is restricted -+ * only to the PRU loader code. -+ */ -+static void *pru_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len) -+{ -+ struct pru_rproc *pru = rproc->priv; -+ -+ return pru_d_da_to_va(pru, da, len); -+} -+ -+/* PRU-specific address translator used by PRU loader. */ -+static void *pru_da_to_va(struct rproc *rproc, u64 da, size_t len, bool is_iram) -+{ -+ struct pru_rproc *pru = rproc->priv; -+ void *va; -+ -+ if (is_iram) -+ va = pru_i_da_to_va(pru, da, len); -+ else -+ va = pru_d_da_to_va(pru, da, len); -+ -+ return va; -+} -+ -+static struct rproc_ops pru_rproc_ops = { -+ .start = pru_rproc_start, -+ .stop = pru_rproc_stop, -+ .da_to_va = pru_rproc_da_to_va, -+}; -+ -+static int -+pru_rproc_load_elf_segments(struct rproc *rproc, const struct firmware *fw) -+{ -+ struct device *dev = &rproc->dev; -+ struct elf32_hdr *ehdr; -+ struct elf32_phdr *phdr; -+ int i, ret = 0; -+ const u8 *elf_data = fw->data; -+ -+ ehdr = (struct elf32_hdr *)elf_data; -+ phdr = (struct elf32_phdr *)(elf_data + ehdr->e_phoff); -+ -+ /* go through the available ELF segments */ -+ for (i = 0; i < ehdr->e_phnum; i++, phdr++) { -+ u32 da = phdr->p_paddr; -+ u32 memsz = phdr->p_memsz; -+ u32 filesz = phdr->p_filesz; -+ u32 offset = phdr->p_offset; -+ bool is_iram; -+ void *ptr; -+ -+ if (phdr->p_type != PT_LOAD || !filesz) -+ continue; -+ -+ dev_dbg(dev, "phdr: type %d da 0x%x memsz 0x%x filesz 0x%x\n", -+ phdr->p_type, da, memsz, filesz); -+ -+ if (filesz > memsz) { -+ dev_err(dev, "bad phdr filesz 0x%x memsz 0x%x\n", -+ filesz, memsz); -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (offset + filesz > fw->size) { -+ dev_err(dev, "truncated fw: need 0x%x avail 0x%zx\n", -+ offset + filesz, fw->size); -+ ret = -EINVAL; -+ break; -+ } -+ -+ /* grab the kernel address for this device address */ -+ is_iram = phdr->p_flags & PF_X; -+ ptr = pru_da_to_va(rproc, da, memsz, is_iram); -+ if (!ptr) { -+ dev_err(dev, "bad phdr da 0x%x mem 0x%x\n", da, memsz); -+ ret = -EINVAL; -+ break; -+ } -+ -+ memcpy(ptr, elf_data + phdr->p_offset, filesz); -+ -+ /* skip the memzero logic performed by remoteproc ELF loader */ -+ } -+ -+ return ret; -+} -+ -+/* -+ * Use a custom parse_fw callback function for dealing with PRU firmware -+ * specific sections. -+ */ -+static int pru_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw) -+{ -+ int ret; -+ -+ /* load optional rsc table */ -+ ret = rproc_elf_load_rsc_table(rproc, fw); -+ if (ret == -EINVAL) -+ dev_dbg(&rproc->dev, "no resource table found for this fw\n"); -+ else if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+/* -+ * Compute PRU id based on the IRAM addresses. The PRU IRAMs are -+ * always at a particular offset within the PRUSS address space. -+ */ -+static int pru_rproc_set_id(struct pru_rproc *pru) -+{ -+ int ret = 0; -+ -+ switch (pru->mem_regions[PRU_IOMEM_IRAM].pa & PRU_IRAM_ADDR_MASK) { -+ case PRU0_IRAM_ADDR_MASK: -+ pru->id = 0; -+ break; -+ case PRU1_IRAM_ADDR_MASK: -+ pru->id = 1; -+ break; -+ default: -+ ret = -EINVAL; -+ } -+ -+ return ret; -+} -+ -+static int pru_rproc_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct platform_device *ppdev = to_platform_device(dev->parent); -+ struct pru_rproc *pru; -+ const char *fw_name; -+ struct rproc *rproc = NULL; -+ struct resource *res; -+ int i, ret; -+ const char *mem_names[PRU_IOMEM_MAX] = { "iram", "control", "debug" }; -+ -+ ret = of_property_read_string(np, "firmware-name", &fw_name); -+ if (ret) { -+ dev_err(dev, "unable to retrieve firmware-name %d\n", ret); -+ return ret; -+ } -+ -+ rproc = devm_rproc_alloc(dev, pdev->name, &pru_rproc_ops, fw_name, -+ sizeof(*pru)); -+ if (!rproc) { -+ dev_err(dev, "rproc_alloc failed\n"); -+ return -ENOMEM; -+ } -+ /* use a custom load function to deal with PRU-specific quirks */ -+ rproc->ops->load = pru_rproc_load_elf_segments; -+ -+ /* use a custom parse function to deal with PRU-specific resources */ -+ rproc->ops->parse_fw = pru_rproc_parse_fw; -+ -+ /* error recovery is not supported for PRUs */ -+ rproc->recovery_disabled = true; -+ -+ /* -+ * rproc_add will auto-boot the processor normally, but this is not -+ * desired with PRU client driven boot-flow methodology. A PRU -+ * application/client driver will boot the corresponding PRU -+ * remote-processor as part of its state machine either through the -+ * remoteproc sysfs interface or through the equivalent kernel API. -+ */ -+ rproc->auto_boot = false; -+ -+ pru = rproc->priv; -+ pru->dev = dev; -+ pru->pruss = platform_get_drvdata(ppdev); -+ pru->rproc = rproc; -+ pru->fw_name = fw_name; -+ -+ for (i = 0; i < ARRAY_SIZE(mem_names); i++) { -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, -+ mem_names[i]); -+ pru->mem_regions[i].va = devm_ioremap_resource(dev, res); -+ if (IS_ERR(pru->mem_regions[i].va)) { -+ dev_err(dev, "failed to parse and map memory resource %d %s\n", -+ i, mem_names[i]); -+ ret = PTR_ERR(pru->mem_regions[i].va); -+ return ret; -+ } -+ pru->mem_regions[i].pa = res->start; -+ pru->mem_regions[i].size = resource_size(res); -+ -+ dev_dbg(dev, "memory %8s: pa %pa size 0x%zx va %pK\n", -+ mem_names[i], &pru->mem_regions[i].pa, -+ pru->mem_regions[i].size, pru->mem_regions[i].va); -+ } -+ -+ ret = pru_rproc_set_id(pru); -+ if (ret < 0) -+ return ret; -+ -+ platform_set_drvdata(pdev, rproc); -+ -+ ret = devm_rproc_add(dev, pru->rproc); -+ if (ret) { -+ dev_err(dev, "rproc_add failed: %d\n", ret); -+ return ret; -+ } -+ -+ dev_dbg(dev, "PRU rproc node %pOF probed successfully\n", np); -+ -+ return 0; -+} -+ -+static int pru_rproc_remove(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct rproc *rproc = platform_get_drvdata(pdev); -+ -+ dev_dbg(dev, "%s: removing rproc %s\n", __func__, rproc->name); -+ -+ return 0; -+} -+ -+static const struct of_device_id pru_rproc_match[] = { -+ { .compatible = "ti,am3356-pru", }, -+ { .compatible = "ti,am4376-pru", }, -+ { .compatible = "ti,am5728-pru", }, -+ { .compatible = "ti,k2g-pru", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, pru_rproc_match); -+ -+static struct platform_driver pru_rproc_driver = { -+ .driver = { -+ .name = "pru-rproc", -+ .of_match_table = pru_rproc_match, -+ .suppress_bind_attrs = true, -+ }, -+ .probe = pru_rproc_probe, -+ .remove = pru_rproc_remove, -+}; -+module_platform_driver(pru_rproc_driver); -+ -+MODULE_AUTHOR("Suman Anna "); -+MODULE_AUTHOR("Andrew F. Davis "); -+MODULE_AUTHOR("Grzegorz Jaszczyk "); -+MODULE_DESCRIPTION("PRU-ICSS Remote Processor Driver"); -+MODULE_LICENSE("GPL v2"); diff --git a/recipes-kernel/linux/files/patches-5.10/0036-remoteproc-pru-Add-support-for-PRU-specific-interrup.patch b/recipes-kernel/linux/files/patches-5.10/0036-remoteproc-pru-Add-support-for-PRU-specific-interrup.patch deleted file mode 100644 index 64cbfcc93..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0036-remoteproc-pru-Add-support-for-PRU-specific-interrup.patch +++ /dev/null @@ -1,353 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grzegorz Jaszczyk -Date: Tue, 8 Dec 2020 15:09:59 +0100 -Subject: [PATCH] remoteproc: pru: Add support for PRU specific interrupt - configuration - -The firmware blob can contain optional ELF sections: .resource_table -section and .pru_irq_map one. The second one contains the PRUSS -interrupt mapping description, which needs to be setup before powering -on the PRU core. To avoid RAM wastage this ELF section is not mapped to -any ELF segment (by the firmware linker) and therefore is not loaded to -PRU memory. - -The PRU interrupt configuration is handled within the PRUSS INTC irqchip -driver and leverages the system events to interrupt channels and host -interrupts mapping configuration. Relevant irq routing information is -passed through a special .pru_irq_map ELF section (for interrupts routed -to and used by PRU cores) or via the PRU application's device tree node -(for interrupts routed to and used by the main CPU). The mappings are -currently programmed during the booting/shutdown of the PRU. - -The interrupt configuration passed through .pru_irq_map ELF section is -optional. It varies on specific firmware functionality and therefore -have to be unwinded during PRU stop and performed again during -PRU start. - -Reviewed-by: Mathieu Poirier -Co-developed-by: Suman Anna -Signed-off-by: Suman Anna -Signed-off-by: Grzegorz Jaszczyk -Link: https://lore.kernel.org/r/20201208141002.17777-4-grzegorz.jaszczyk@linaro.org -Signed-off-by: Bjorn Andersson ---- - drivers/remoteproc/pru_rproc.c | 181 +++++++++++++++++++++++++++++++++ - drivers/remoteproc/pru_rproc.h | 46 +++++++++ - 2 files changed, 227 insertions(+) - create mode 100644 drivers/remoteproc/pru_rproc.h - -diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c -index d33392bbd8af..72e64d15f0dc 100644 ---- a/drivers/remoteproc/pru_rproc.c -+++ b/drivers/remoteproc/pru_rproc.c -@@ -11,13 +11,16 @@ - */ - - #include -+#include - #include - #include -+#include - #include - #include - - #include "remoteproc_internal.h" - #include "remoteproc_elf_helpers.h" -+#include "pru_rproc.h" - - /* PRU_ICSS_PRU_CTRL registers */ - #define PRU_CTRL_CTRL 0x0000 -@@ -42,6 +45,8 @@ - #define PRU_SDRAM_DA 0x2000 /* Secondary Data RAM */ - #define PRU_SHRDRAM_DA 0x10000 /* Shared Data RAM */ - -+#define MAX_PRU_SYS_EVENTS 160 -+ - /** - * enum pru_iomem - PRU core memory/register range identifiers - * -@@ -65,6 +70,10 @@ enum pru_iomem { - * @rproc: remoteproc pointer for this PRU core - * @mem_regions: data for each of the PRU memory regions - * @fw_name: name of firmware image used during loading -+ * @mapped_irq: virtual interrupt numbers of created fw specific mapping -+ * @pru_interrupt_map: pointer to interrupt mapping description (firmware) -+ * @pru_interrupt_map_sz: pru_interrupt_map size -+ * @evt_count: number of mapped events - */ - struct pru_rproc { - int id; -@@ -73,6 +82,10 @@ struct pru_rproc { - struct rproc *rproc; - struct pruss_mem_region mem_regions[PRU_IOMEM_MAX]; - const char *fw_name; -+ unsigned int *mapped_irq; -+ struct pru_irq_rsc *pru_interrupt_map; -+ size_t pru_interrupt_map_sz; -+ u8 evt_count; - }; - - static inline u32 pru_control_read_reg(struct pru_rproc *pru, unsigned int reg) -@@ -86,15 +99,108 @@ void pru_control_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val) - writel_relaxed(val, pru->mem_regions[PRU_IOMEM_CTRL].va + reg); - } - -+static void pru_dispose_irq_mapping(struct pru_rproc *pru) -+{ -+ while (pru->evt_count--) { -+ if (pru->mapped_irq[pru->evt_count] > 0) -+ irq_dispose_mapping(pru->mapped_irq[pru->evt_count]); -+ } -+ -+ kfree(pru->mapped_irq); -+} -+ -+/* -+ * Parse the custom PRU interrupt map resource and configure the INTC -+ * appropriately. -+ */ -+static int pru_handle_intrmap(struct rproc *rproc) -+{ -+ struct device *dev = rproc->dev.parent; -+ struct pru_rproc *pru = rproc->priv; -+ struct pru_irq_rsc *rsc = pru->pru_interrupt_map; -+ struct irq_fwspec fwspec; -+ struct device_node *irq_parent; -+ int i, ret = 0; -+ -+ /* not having pru_interrupt_map is not an error */ -+ if (!rsc) -+ return 0; -+ -+ /* currently supporting only type 0 */ -+ if (rsc->type != 0) { -+ dev_err(dev, "unsupported rsc type: %d\n", rsc->type); -+ return -EINVAL; -+ } -+ -+ if (rsc->num_evts > MAX_PRU_SYS_EVENTS) -+ return -EINVAL; -+ -+ if (sizeof(*rsc) + rsc->num_evts * sizeof(struct pruss_int_map) != -+ pru->pru_interrupt_map_sz) -+ return -EINVAL; -+ -+ pru->evt_count = rsc->num_evts; -+ pru->mapped_irq = kcalloc(pru->evt_count, sizeof(unsigned int), -+ GFP_KERNEL); -+ if (!pru->mapped_irq) -+ return -ENOMEM; -+ -+ /* -+ * parse and fill in system event to interrupt channel and -+ * channel-to-host mapping -+ */ -+ irq_parent = of_irq_find_parent(pru->dev->of_node); -+ if (!irq_parent) { -+ kfree(pru->mapped_irq); -+ return -ENODEV; -+ } -+ -+ fwspec.fwnode = of_node_to_fwnode(irq_parent); -+ fwspec.param_count = 3; -+ for (i = 0; i < pru->evt_count; i++) { -+ fwspec.param[0] = rsc->pru_intc_map[i].event; -+ fwspec.param[1] = rsc->pru_intc_map[i].chnl; -+ fwspec.param[2] = rsc->pru_intc_map[i].host; -+ -+ dev_dbg(dev, "mapping%d: event %d, chnl %d, host %d\n", -+ i, fwspec.param[0], fwspec.param[1], fwspec.param[2]); -+ -+ pru->mapped_irq[i] = irq_create_fwspec_mapping(&fwspec); -+ if (!pru->mapped_irq[i]) { -+ dev_err(dev, "failed to get virq\n"); -+ ret = pru->mapped_irq[i]; -+ goto map_fail; -+ } -+ } -+ -+ return ret; -+ -+map_fail: -+ pru_dispose_irq_mapping(pru); -+ -+ return ret; -+} -+ - static int pru_rproc_start(struct rproc *rproc) - { - struct device *dev = &rproc->dev; - struct pru_rproc *pru = rproc->priv; - u32 val; -+ int ret; - - dev_dbg(dev, "starting PRU%d: entry-point = 0x%llx\n", - pru->id, (rproc->bootaddr >> 2)); - -+ ret = pru_handle_intrmap(rproc); -+ /* -+ * reset references to pru interrupt map - they will stop being valid -+ * after rproc_start returns -+ */ -+ pru->pru_interrupt_map = NULL; -+ pru->pru_interrupt_map_sz = 0; -+ if (ret) -+ return ret; -+ - val = CTRL_CTRL_EN | ((rproc->bootaddr >> 2) << 16); - pru_control_write_reg(pru, PRU_CTRL_CTRL, val); - -@@ -113,6 +219,10 @@ static int pru_rproc_stop(struct rproc *rproc) - val &= ~CTRL_CTRL_EN; - pru_control_write_reg(pru, PRU_CTRL_CTRL, val); - -+ /* dispose irq mapping - new firmware can provide new mapping */ -+ if (pru->mapped_irq) -+ pru_dispose_irq_mapping(pru); -+ - return 0; - } - -@@ -273,12 +383,70 @@ pru_rproc_load_elf_segments(struct rproc *rproc, const struct firmware *fw) - return ret; - } - -+static const void * -+pru_rproc_find_interrupt_map(struct device *dev, const struct firmware *fw) -+{ -+ struct elf32_shdr *shdr, *name_table_shdr; -+ const char *name_table; -+ const u8 *elf_data = fw->data; -+ struct elf32_hdr *ehdr = (struct elf32_hdr *)elf_data; -+ u16 shnum = ehdr->e_shnum; -+ u16 shstrndx = ehdr->e_shstrndx; -+ int i; -+ -+ /* first, get the section header */ -+ shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff); -+ /* compute name table section header entry in shdr array */ -+ name_table_shdr = shdr + shstrndx; -+ /* finally, compute the name table section address in elf */ -+ name_table = elf_data + name_table_shdr->sh_offset; -+ -+ for (i = 0; i < shnum; i++, shdr++) { -+ u32 size = shdr->sh_size; -+ u32 offset = shdr->sh_offset; -+ u32 name = shdr->sh_name; -+ -+ if (strcmp(name_table + name, ".pru_irq_map")) -+ continue; -+ -+ /* make sure we have the entire irq map */ -+ if (offset + size > fw->size || offset + size < size) { -+ dev_err(dev, ".pru_irq_map section truncated\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ /* make sure irq map has at least the header */ -+ if (sizeof(struct pru_irq_rsc) > size) { -+ dev_err(dev, "header-less .pru_irq_map section\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ return shdr; -+ } -+ -+ dev_dbg(dev, "no .pru_irq_map section found for this fw\n"); -+ -+ return NULL; -+} -+ - /* - * Use a custom parse_fw callback function for dealing with PRU firmware - * specific sections. -+ * -+ * The firmware blob can contain optional ELF sections: .resource_table section -+ * and .pru_irq_map one. The second one contains the PRUSS interrupt mapping -+ * description, which needs to be setup before powering on the PRU core. To -+ * avoid RAM wastage this ELF section is not mapped to any ELF segment (by the -+ * firmware linker) and therefore is not loaded to PRU memory. - */ - static int pru_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw) - { -+ struct device *dev = &rproc->dev; -+ struct pru_rproc *pru = rproc->priv; -+ const u8 *elf_data = fw->data; -+ const void *shdr; -+ u8 class = fw_elf_get_class(fw); -+ u64 sh_offset; - int ret; - - /* load optional rsc table */ -@@ -288,6 +456,19 @@ static int pru_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw) - else if (ret) - return ret; - -+ /* find .pru_interrupt_map section, not having it is not an error */ -+ shdr = pru_rproc_find_interrupt_map(dev, fw); -+ if (IS_ERR(shdr)) -+ return PTR_ERR(shdr); -+ -+ if (!shdr) -+ return 0; -+ -+ /* preserve pointer to PRU interrupt map together with it size */ -+ sh_offset = elf_shdr_get_sh_offset(class, shdr); -+ pru->pru_interrupt_map = (struct pru_irq_rsc *)(elf_data + sh_offset); -+ pru->pru_interrupt_map_sz = elf_shdr_get_sh_size(class, shdr); -+ - return 0; - } - -diff --git a/drivers/remoteproc/pru_rproc.h b/drivers/remoteproc/pru_rproc.h -new file mode 100644 -index 000000000000..8ee9c3171610 ---- /dev/null -+++ b/drivers/remoteproc/pru_rproc.h -@@ -0,0 +1,46 @@ -+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ -+/* -+ * PRUSS Remote Processor specific types -+ * -+ * Copyright (C) 2014-2020 Texas Instruments Incorporated - https://www.ti.com/ -+ * Suman Anna -+ */ -+ -+#ifndef _PRU_RPROC_H_ -+#define _PRU_RPROC_H_ -+ -+/** -+ * struct pruss_int_map - PRU system events _to_ channel and host mapping -+ * @event: number of the system event -+ * @chnl: channel number assigned to a given @event -+ * @host: host number assigned to a given @chnl -+ * -+ * PRU system events are mapped to channels, and these channels are mapped -+ * to host interrupts. Events can be mapped to channels in a one-to-one or -+ * many-to-one ratio (multiple events per channel), and channels can be -+ * mapped to host interrupts in a one-to-one or many-to-one ratio (multiple -+ * channels per interrupt). -+ */ -+struct pruss_int_map { -+ u8 event; -+ u8 chnl; -+ u8 host; -+}; -+ -+/** -+ * struct pru_irq_rsc - PRU firmware section header for IRQ data -+ * @type: resource type -+ * @num_evts: number of described events -+ * @pru_intc_map: PRU interrupt routing description -+ * -+ * The PRU firmware blob can contain optional .pru_irq_map ELF section, which -+ * provides the PRUSS interrupt mapping description. The pru_irq_rsc struct -+ * describes resource entry format. -+ */ -+struct pru_irq_rsc { -+ u8 type; -+ u8 num_evts; -+ struct pruss_int_map pru_intc_map[]; -+} __packed; -+ -+#endif /* _PRU_RPROC_H_ */ diff --git a/recipes-kernel/linux/files/patches-5.10/0037-remoteproc-pru-Add-pru-specific-debugfs-support.patch b/recipes-kernel/linux/files/patches-5.10/0037-remoteproc-pru-Add-pru-specific-debugfs-support.patch deleted file mode 100644 index dbfa8c175..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0037-remoteproc-pru-Add-pru-specific-debugfs-support.patch +++ /dev/null @@ -1,224 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Tue, 8 Dec 2020 15:10:00 +0100 -Subject: [PATCH] remoteproc: pru: Add pru-specific debugfs support - -The remoteproc core creates certain standard debugfs entries, -that does not give a whole lot of useful information for the -PRUs. The PRU remoteproc driver is enhanced to add additional -debugfs entries for PRU. These will be auto-cleaned up when -the parent rproc debug directory is removed. - -The enhanced debugfs support adds two new entries: 'regs' and -'single_step'. The 'regs' dumps out the useful CTRL sub-module -registers as well as each of the 32 GPREGs and CT_REGs registers. -The GPREGs and CT_REGs though are printed only when the PRU is -halted and accessible as per the IP design. - -The 'single_step' utilizes the single-step execution of the PRU -cores. Writing a non-zero value performs a single step, and a -zero value restores the PRU to execute in the same mode as the -mode before the first single step. (note: if the PRU is halted -because of a halt instruction, then no change occurs). - -Logic for setting the PC and jumping over a halt instruction shall -be added in the future. - -Signed-off-by: Suman Anna -Signed-off-by: Grzegorz Jaszczyk -Reviewed-by: Mathieu Poirier -Link: https://lore.kernel.org/r/20201208141002.17777-5-grzegorz.jaszczyk@linaro.org -Signed-off-by: Bjorn Andersson ---- - drivers/remoteproc/pru_rproc.c | 136 +++++++++++++++++++++++++++++++++ - 1 file changed, 136 insertions(+) - -diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c -index 72e64d15f0dc..59240fd82f56 100644 ---- a/drivers/remoteproc/pru_rproc.c -+++ b/drivers/remoteproc/pru_rproc.c -@@ -11,6 +11,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -25,6 +26,13 @@ - /* PRU_ICSS_PRU_CTRL registers */ - #define PRU_CTRL_CTRL 0x0000 - #define PRU_CTRL_STS 0x0004 -+#define PRU_CTRL_WAKEUP_EN 0x0008 -+#define PRU_CTRL_CYCLE 0x000C -+#define PRU_CTRL_STALL 0x0010 -+#define PRU_CTRL_CTBIR0 0x0020 -+#define PRU_CTRL_CTBIR1 0x0024 -+#define PRU_CTRL_CTPPR0 0x0028 -+#define PRU_CTRL_CTPPR1 0x002C - - /* CTRL register bit-fields */ - #define CTRL_CTRL_SOFT_RST_N BIT(0) -@@ -34,6 +42,10 @@ - #define CTRL_CTRL_SINGLE_STEP BIT(8) - #define CTRL_CTRL_RUNSTATE BIT(15) - -+/* PRU_ICSS_PRU_DEBUG registers */ -+#define PRU_DEBUG_GPREG(x) (0x0000 + (x) * 4) -+#define PRU_DEBUG_CT_REG(x) (0x0080 + (x) * 4) -+ - /* PRU Core IRAM address masks */ - #define PRU_IRAM_ADDR_MASK 0x3ffff - #define PRU0_IRAM_ADDR_MASK 0x34000 -@@ -73,6 +85,8 @@ enum pru_iomem { - * @mapped_irq: virtual interrupt numbers of created fw specific mapping - * @pru_interrupt_map: pointer to interrupt mapping description (firmware) - * @pru_interrupt_map_sz: pru_interrupt_map size -+ * @dbg_single_step: debug state variable to set PRU into single step mode -+ * @dbg_continuous: debug state variable to restore PRU execution mode - * @evt_count: number of mapped events - */ - struct pru_rproc { -@@ -85,6 +99,8 @@ struct pru_rproc { - unsigned int *mapped_irq; - struct pru_irq_rsc *pru_interrupt_map; - size_t pru_interrupt_map_sz; -+ u32 dbg_single_step; -+ u32 dbg_continuous; - u8 evt_count; - }; - -@@ -99,6 +115,124 @@ void pru_control_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val) - writel_relaxed(val, pru->mem_regions[PRU_IOMEM_CTRL].va + reg); - } - -+static inline u32 pru_debug_read_reg(struct pru_rproc *pru, unsigned int reg) -+{ -+ return readl_relaxed(pru->mem_regions[PRU_IOMEM_DEBUG].va + reg); -+} -+ -+static int regs_show(struct seq_file *s, void *data) -+{ -+ struct rproc *rproc = s->private; -+ struct pru_rproc *pru = rproc->priv; -+ int i, nregs = 32; -+ u32 pru_sts; -+ int pru_is_running; -+ -+ seq_puts(s, "============== Control Registers ==============\n"); -+ seq_printf(s, "CTRL := 0x%08x\n", -+ pru_control_read_reg(pru, PRU_CTRL_CTRL)); -+ pru_sts = pru_control_read_reg(pru, PRU_CTRL_STS); -+ seq_printf(s, "STS (PC) := 0x%08x (0x%08x)\n", pru_sts, pru_sts << 2); -+ seq_printf(s, "WAKEUP_EN := 0x%08x\n", -+ pru_control_read_reg(pru, PRU_CTRL_WAKEUP_EN)); -+ seq_printf(s, "CYCLE := 0x%08x\n", -+ pru_control_read_reg(pru, PRU_CTRL_CYCLE)); -+ seq_printf(s, "STALL := 0x%08x\n", -+ pru_control_read_reg(pru, PRU_CTRL_STALL)); -+ seq_printf(s, "CTBIR0 := 0x%08x\n", -+ pru_control_read_reg(pru, PRU_CTRL_CTBIR0)); -+ seq_printf(s, "CTBIR1 := 0x%08x\n", -+ pru_control_read_reg(pru, PRU_CTRL_CTBIR1)); -+ seq_printf(s, "CTPPR0 := 0x%08x\n", -+ pru_control_read_reg(pru, PRU_CTRL_CTPPR0)); -+ seq_printf(s, "CTPPR1 := 0x%08x\n", -+ pru_control_read_reg(pru, PRU_CTRL_CTPPR1)); -+ -+ seq_puts(s, "=============== Debug Registers ===============\n"); -+ pru_is_running = pru_control_read_reg(pru, PRU_CTRL_CTRL) & -+ CTRL_CTRL_RUNSTATE; -+ if (pru_is_running) { -+ seq_puts(s, "PRU is executing, cannot print/access debug registers.\n"); -+ return 0; -+ } -+ -+ for (i = 0; i < nregs; i++) { -+ seq_printf(s, "GPREG%-2d := 0x%08x\tCT_REG%-2d := 0x%08x\n", -+ i, pru_debug_read_reg(pru, PRU_DEBUG_GPREG(i)), -+ i, pru_debug_read_reg(pru, PRU_DEBUG_CT_REG(i))); -+ } -+ -+ return 0; -+} -+DEFINE_SHOW_ATTRIBUTE(regs); -+ -+/* -+ * Control PRU single-step mode -+ * -+ * This is a debug helper function used for controlling the single-step -+ * mode of the PRU. The PRU Debug registers are not accessible when the -+ * PRU is in RUNNING state. -+ * -+ * Writing a non-zero value sets the PRU into single-step mode irrespective -+ * of its previous state. The PRU mode is saved only on the first set into -+ * a single-step mode. Writing a zero value will restore the PRU into its -+ * original mode. -+ */ -+static int pru_rproc_debug_ss_set(void *data, u64 val) -+{ -+ struct rproc *rproc = data; -+ struct pru_rproc *pru = rproc->priv; -+ u32 reg_val; -+ -+ val = val ? 1 : 0; -+ if (!val && !pru->dbg_single_step) -+ return 0; -+ -+ reg_val = pru_control_read_reg(pru, PRU_CTRL_CTRL); -+ -+ if (val && !pru->dbg_single_step) -+ pru->dbg_continuous = reg_val; -+ -+ if (val) -+ reg_val |= CTRL_CTRL_SINGLE_STEP | CTRL_CTRL_EN; -+ else -+ reg_val = pru->dbg_continuous; -+ -+ pru->dbg_single_step = val; -+ pru_control_write_reg(pru, PRU_CTRL_CTRL, reg_val); -+ -+ return 0; -+} -+ -+static int pru_rproc_debug_ss_get(void *data, u64 *val) -+{ -+ struct rproc *rproc = data; -+ struct pru_rproc *pru = rproc->priv; -+ -+ *val = pru->dbg_single_step; -+ -+ return 0; -+} -+DEFINE_SIMPLE_ATTRIBUTE(pru_rproc_debug_ss_fops, pru_rproc_debug_ss_get, -+ pru_rproc_debug_ss_set, "%llu\n"); -+ -+/* -+ * Create PRU-specific debugfs entries -+ * -+ * The entries are created only if the parent remoteproc debugfs directory -+ * exists, and will be cleaned up by the remoteproc core. -+ */ -+static void pru_rproc_create_debug_entries(struct rproc *rproc) -+{ -+ if (!rproc->dbg_dir) -+ return; -+ -+ debugfs_create_file("regs", 0400, rproc->dbg_dir, -+ rproc, ®s_fops); -+ debugfs_create_file("single_step", 0600, rproc->dbg_dir, -+ rproc, &pru_rproc_debug_ss_fops); -+} -+ - static void pru_dispose_irq_mapping(struct pru_rproc *pru) - { - while (pru->evt_count--) { -@@ -572,6 +706,8 @@ static int pru_rproc_probe(struct platform_device *pdev) - return ret; - } - -+ pru_rproc_create_debug_entries(rproc); -+ - dev_dbg(dev, "PRU rproc node %pOF probed successfully\n", np); - - return 0; diff --git a/recipes-kernel/linux/files/patches-5.10/0038-remoteproc-pru-Add-support-for-various-PRU-cores-on-.patch b/recipes-kernel/linux/files/patches-5.10/0038-remoteproc-pru-Add-support-for-various-PRU-cores-on-.patch deleted file mode 100644 index 14a70e012..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0038-remoteproc-pru-Add-support-for-various-PRU-cores-on-.patch +++ /dev/null @@ -1,295 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Tue, 8 Dec 2020 15:10:01 +0100 -Subject: [PATCH] remoteproc: pru: Add support for various PRU cores on K3 - AM65x SoCs - -The K3 AM65x family of SoCs have the next generation of the PRU-ICSS -processor subsystem, commonly referred to as ICSSG. Each ICSSG processor -subsystem on AM65x SR1.0 contains two primary PRU cores and two new -auxiliary PRU cores called RTUs. The AM65x SR2.0 SoCs have a revised -ICSSG IP that is based off the subsequent IP revision used on J721E -SoCs. This IP instance has two new custom auxiliary PRU cores called -Transmit PRUs (Tx_PRUs) in addition to the existing PRUs and RTUs. - -Each RTU and Tx_PRU cores have their own dedicated IRAM (smaller than -a PRU), Control and debug feature sets, but is different in terms of -sub-modules integrated around it and does not have the full capabilities -associated with a PRU core. The RTU core is typically used to aid a -PRU core in accelerating data transfers, while the Tx_PRU cores is -normally used to control the TX L2 FIFO if enabled in Ethernet -applications. Both can also be used to run independent applications. -The RTU and Tx_PRU cores though share the same Data RAMs as the PRU -cores, so the memories have to be partitioned carefully between different -applications. The new cores also support a new sub-module called Task -Manager to support two different context thread executions. - -Enhance the existing PRU remoteproc driver to support these new PRU, RTU -and Tx PRU cores by using specific compatibles. The initial names for the -firmware images for each PRU core are retrieved from DT nodes, and can -be adjusted through sysfs if required. - -The PRU remoteproc driver has to be specifically modified to use a -custom memcpy function within its ELF loader implementation for these -new cores in order to overcome a limitation with copying data into each -of the core's IRAM memories. These memory ports support only 4-byte -writes, and any sub-word order byte writes clear out the remaining -bytes other than the bytes being written within the containing word. -The default ARM64 memcpy also cannot be used as it throws an exception -when the preferred 8-byte copy operation is attempted. This choice is -made by using a state flag that is set only on K3 SoCs. - -Signed-off-by: Suman Anna -Co-developed-by: Grzegorz Jaszczyk -Signed-off-by: Grzegorz Jaszczyk -Reviewed-by: Mathieu Poirier -Link: https://lore.kernel.org/r/20201208141002.17777-6-grzegorz.jaszczyk@linaro.org -Signed-off-by: Bjorn Andersson ---- - drivers/remoteproc/pru_rproc.c | 140 ++++++++++++++++++++++++++++++--- - 1 file changed, 131 insertions(+), 9 deletions(-) - -diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c -index 59240fd82f56..421ebbc1c02d 100644 ---- a/drivers/remoteproc/pru_rproc.c -+++ b/drivers/remoteproc/pru_rproc.c -@@ -46,10 +46,14 @@ - #define PRU_DEBUG_GPREG(x) (0x0000 + (x) * 4) - #define PRU_DEBUG_CT_REG(x) (0x0080 + (x) * 4) - --/* PRU Core IRAM address masks */ -+/* PRU/RTU/Tx_PRU Core IRAM address masks */ - #define PRU_IRAM_ADDR_MASK 0x3ffff - #define PRU0_IRAM_ADDR_MASK 0x34000 - #define PRU1_IRAM_ADDR_MASK 0x38000 -+#define RTU0_IRAM_ADDR_MASK 0x4000 -+#define RTU1_IRAM_ADDR_MASK 0x6000 -+#define TX_PRU0_IRAM_ADDR_MASK 0xa000 -+#define TX_PRU1_IRAM_ADDR_MASK 0xc000 - - /* PRU device addresses for various type of PRU RAMs */ - #define PRU_IRAM_DA 0 /* Instruction RAM */ -@@ -74,12 +78,38 @@ enum pru_iomem { - PRU_IOMEM_MAX, - }; - -+/** -+ * enum pru_type - PRU core type identifier -+ * -+ * @PRU_TYPE_PRU: Programmable Real-time Unit -+ * @PRU_TYPE_RTU: Auxiliary Programmable Real-Time Unit -+ * @PRU_TYPE_TX_PRU: Transmit Programmable Real-Time Unit -+ * @PRU_TYPE_MAX: just keep this one at the end -+ */ -+enum pru_type { -+ PRU_TYPE_PRU = 0, -+ PRU_TYPE_RTU, -+ PRU_TYPE_TX_PRU, -+ PRU_TYPE_MAX, -+}; -+ -+/** -+ * struct pru_private_data - device data for a PRU core -+ * @type: type of the PRU core (PRU, RTU, Tx_PRU) -+ * @is_k3: flag used to identify the need for special load handling -+ */ -+struct pru_private_data { -+ enum pru_type type; -+ unsigned int is_k3 : 1; -+}; -+ - /** - * struct pru_rproc - PRU remoteproc structure - * @id: id of the PRU core within the PRUSS - * @dev: PRU core device pointer - * @pruss: back-reference to parent PRUSS structure - * @rproc: remoteproc pointer for this PRU core -+ * @data: PRU core specific data - * @mem_regions: data for each of the PRU memory regions - * @fw_name: name of firmware image used during loading - * @mapped_irq: virtual interrupt numbers of created fw specific mapping -@@ -94,6 +124,7 @@ struct pru_rproc { - struct device *dev; - struct pruss *pruss; - struct rproc *rproc; -+ const struct pru_private_data *data; - struct pruss_mem_region mem_regions[PRU_IOMEM_MAX]; - const char *fw_name; - unsigned int *mapped_irq; -@@ -319,11 +350,12 @@ static int pru_rproc_start(struct rproc *rproc) - { - struct device *dev = &rproc->dev; - struct pru_rproc *pru = rproc->priv; -+ const char *names[PRU_TYPE_MAX] = { "PRU", "RTU", "Tx_PRU" }; - u32 val; - int ret; - -- dev_dbg(dev, "starting PRU%d: entry-point = 0x%llx\n", -- pru->id, (rproc->bootaddr >> 2)); -+ dev_dbg(dev, "starting %s%d: entry-point = 0x%llx\n", -+ names[pru->data->type], pru->id, (rproc->bootaddr >> 2)); - - ret = pru_handle_intrmap(rproc); - /* -@@ -345,9 +377,10 @@ static int pru_rproc_stop(struct rproc *rproc) - { - struct device *dev = &rproc->dev; - struct pru_rproc *pru = rproc->priv; -+ const char *names[PRU_TYPE_MAX] = { "PRU", "RTU", "Tx_PRU" }; - u32 val; - -- dev_dbg(dev, "stopping PRU%d\n", pru->id); -+ dev_dbg(dev, "stopping %s%d\n", names[pru->data->type], pru->id); - - val = pru_control_read_reg(pru, PRU_CTRL_CTRL); - val &= ~CTRL_CTRL_EN; -@@ -459,9 +492,52 @@ static struct rproc_ops pru_rproc_ops = { - .da_to_va = pru_rproc_da_to_va, - }; - -+/* -+ * Custom memory copy implementation for ICSSG PRU/RTU/Tx_PRU Cores -+ * -+ * The ICSSG PRU/RTU/Tx_PRU cores have a memory copying issue with IRAM -+ * memories, that is not seen on previous generation SoCs. The data is reflected -+ * properly in the IRAM memories only for integer (4-byte) copies. Any unaligned -+ * copies result in all the other pre-existing bytes zeroed out within that -+ * 4-byte boundary, thereby resulting in wrong text/code in the IRAMs. Also, the -+ * IRAM memory port interface does not allow any 8-byte copies (as commonly used -+ * by ARM64 memcpy implementation) and throws an exception. The DRAM memory -+ * ports do not show this behavior. -+ */ -+static int pru_rproc_memcpy(void *dest, const void *src, size_t count) -+{ -+ const u32 *s = src; -+ u32 *d = dest; -+ size_t size = count / 4; -+ u32 *tmp_src = NULL; -+ -+ /* -+ * TODO: relax limitation of 4-byte aligned dest addresses and copy -+ * sizes -+ */ -+ if ((long)dest % 4 || count % 4) -+ return -EINVAL; -+ -+ /* src offsets in ELF firmware image can be non-aligned */ -+ if ((long)src % 4) { -+ tmp_src = kmemdup(src, count, GFP_KERNEL); -+ if (!tmp_src) -+ return -ENOMEM; -+ s = tmp_src; -+ } -+ -+ while (size--) -+ *d++ = *s++; -+ -+ kfree(tmp_src); -+ -+ return 0; -+} -+ - static int - pru_rproc_load_elf_segments(struct rproc *rproc, const struct firmware *fw) - { -+ struct pru_rproc *pru = rproc->priv; - struct device *dev = &rproc->dev; - struct elf32_hdr *ehdr; - struct elf32_phdr *phdr; -@@ -509,7 +585,17 @@ pru_rproc_load_elf_segments(struct rproc *rproc, const struct firmware *fw) - break; - } - -- memcpy(ptr, elf_data + phdr->p_offset, filesz); -+ if (pru->data->is_k3 && is_iram) { -+ ret = pru_rproc_memcpy(ptr, elf_data + phdr->p_offset, -+ filesz); -+ if (ret) { -+ dev_err(dev, "PRU memory copy failed for da 0x%x memsz 0x%x\n", -+ da, memsz); -+ break; -+ } -+ } else { -+ memcpy(ptr, elf_data + phdr->p_offset, filesz); -+ } - - /* skip the memzero logic performed by remoteproc ELF loader */ - } -@@ -615,9 +701,17 @@ static int pru_rproc_set_id(struct pru_rproc *pru) - int ret = 0; - - switch (pru->mem_regions[PRU_IOMEM_IRAM].pa & PRU_IRAM_ADDR_MASK) { -+ case TX_PRU0_IRAM_ADDR_MASK: -+ fallthrough; -+ case RTU0_IRAM_ADDR_MASK: -+ fallthrough; - case PRU0_IRAM_ADDR_MASK: - pru->id = 0; - break; -+ case TX_PRU1_IRAM_ADDR_MASK: -+ fallthrough; -+ case RTU1_IRAM_ADDR_MASK: -+ fallthrough; - case PRU1_IRAM_ADDR_MASK: - pru->id = 1; - break; -@@ -638,8 +732,13 @@ static int pru_rproc_probe(struct platform_device *pdev) - struct rproc *rproc = NULL; - struct resource *res; - int i, ret; -+ const struct pru_private_data *data; - const char *mem_names[PRU_IOMEM_MAX] = { "iram", "control", "debug" }; - -+ data = of_device_get_match_data(&pdev->dev); -+ if (!data) -+ return -ENODEV; -+ - ret = of_property_read_string(np, "firmware-name", &fw_name); - if (ret) { - dev_err(dev, "unable to retrieve firmware-name %d\n", ret); -@@ -672,6 +771,7 @@ static int pru_rproc_probe(struct platform_device *pdev) - - pru = rproc->priv; - pru->dev = dev; -+ pru->data = data; - pru->pruss = platform_get_drvdata(ppdev); - pru->rproc = rproc; - pru->fw_name = fw_name; -@@ -723,11 +823,33 @@ static int pru_rproc_remove(struct platform_device *pdev) - return 0; - } - -+static const struct pru_private_data pru_data = { -+ .type = PRU_TYPE_PRU, -+}; -+ -+static const struct pru_private_data k3_pru_data = { -+ .type = PRU_TYPE_PRU, -+ .is_k3 = 1, -+}; -+ -+static const struct pru_private_data k3_rtu_data = { -+ .type = PRU_TYPE_RTU, -+ .is_k3 = 1, -+}; -+ -+static const struct pru_private_data k3_tx_pru_data = { -+ .type = PRU_TYPE_TX_PRU, -+ .is_k3 = 1, -+}; -+ - static const struct of_device_id pru_rproc_match[] = { -- { .compatible = "ti,am3356-pru", }, -- { .compatible = "ti,am4376-pru", }, -- { .compatible = "ti,am5728-pru", }, -- { .compatible = "ti,k2g-pru", }, -+ { .compatible = "ti,am3356-pru", .data = &pru_data }, -+ { .compatible = "ti,am4376-pru", .data = &pru_data }, -+ { .compatible = "ti,am5728-pru", .data = &pru_data }, -+ { .compatible = "ti,k2g-pru", .data = &pru_data }, -+ { .compatible = "ti,am654-pru", .data = &k3_pru_data }, -+ { .compatible = "ti,am654-rtu", .data = &k3_rtu_data }, -+ { .compatible = "ti,am654-tx-pru", .data = &k3_tx_pru_data }, - {}, - }; - MODULE_DEVICE_TABLE(of, pru_rproc_match); diff --git a/recipes-kernel/linux/files/patches-5.10/0039-remoteproc-pru-Fix-loading-of-GNU-Binutils-ELF.patch b/recipes-kernel/linux/files/patches-5.10/0039-remoteproc-pru-Fix-loading-of-GNU-Binutils-ELF.patch deleted file mode 100644 index 3bcfa215f..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0039-remoteproc-pru-Fix-loading-of-GNU-Binutils-ELF.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dimitar Dimitrov -Date: Wed, 30 Dec 2020 12:50:05 +0200 -Subject: [PATCH] remoteproc: pru: Fix loading of GNU Binutils ELF - -PRU port of GNU Binutils lacks support for separate address spaces. -PRU IRAM addresses are marked with artificial offset to differentiate -them from DRAM addresses. Hence remoteproc must mask IRAM addresses -coming from GNU ELF in order to get the true hardware address. - -PRU firmware used for testing was the example in: - https://github.com/dinuxbg/pru-gcc-examples/tree/master/blinking-led/pru - -Signed-off-by: Dimitar Dimitrov -Link: https://lore.kernel.org/r/20201230105005.30492-1-dimitar@dinux.eu -Signed-off-by: Bjorn Andersson ---- - drivers/remoteproc/pru_rproc.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c -index 421ebbc1c02d..a113e150d5d5 100644 ---- a/drivers/remoteproc/pru_rproc.c -+++ b/drivers/remoteproc/pru_rproc.c -@@ -450,6 +450,24 @@ static void *pru_i_da_to_va(struct pru_rproc *pru, u32 da, size_t len) - if (len == 0) - return NULL; - -+ /* -+ * GNU binutils do not support multiple address spaces. The GNU -+ * linker's default linker script places IRAM at an arbitrary high -+ * offset, in order to differentiate it from DRAM. Hence we need to -+ * strip the artificial offset in the IRAM addresses coming from the -+ * ELF file. -+ * -+ * The TI proprietary linker would never set those higher IRAM address -+ * bits anyway. PRU architecture limits the program counter to 16-bit -+ * word-address range. This in turn corresponds to 18-bit IRAM -+ * byte-address range for ELF. -+ * -+ * Two more bits are added just in case to make the final 20-bit mask. -+ * Idea is to have a safeguard in case TI decides to add banking -+ * in future SoCs. -+ */ -+ da &= 0xfffff; -+ - if (da >= PRU_IRAM_DA && - da + len <= PRU_IRAM_DA + pru->mem_regions[PRU_IOMEM_IRAM].size) { - offset = da - PRU_IRAM_DA; diff --git a/recipes-kernel/linux/files/patches-5.10/0040-remoteproc-pru-Fix-firmware-loading-crashes-on-K3-So.patch b/recipes-kernel/linux/files/patches-5.10/0040-remoteproc-pru-Fix-firmware-loading-crashes-on-K3-So.patch deleted file mode 100644 index 0805b264e..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0040-remoteproc-pru-Fix-firmware-loading-crashes-on-K3-So.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Mon, 15 Mar 2021 15:58:59 -0500 -Subject: [PATCH] remoteproc: pru: Fix firmware loading crashes on K3 SoCs - -The K3 PRUs are 32-bit processors and in general have some limitations -in using the standard ARMv8 memcpy function for loading firmware segments, -so the driver already uses a custom memcpy implementation. This added -logic however is limited to only IRAMs at the moment, but the loading -into Data RAMs is not completely ok either and does generate a kernel -crash for unaligned accesses. - -Fix these crashes by removing the existing IRAM logic limitation and -extending the custom memcpy usage to Data RAMs as well for all K3 SoCs. - -Fixes: 1d39f4d19921 ("remoteproc: pru: Add support for various PRU cores on K3 AM65x SoCs") -Signed-off-by: Suman Anna -Link: https://lore.kernel.org/r/20210315205859.19590-1-s-anna@ti.com -Signed-off-by: Bjorn Andersson ---- - drivers/remoteproc/pru_rproc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c -index a113e150d5d5..21105592a83d 100644 ---- a/drivers/remoteproc/pru_rproc.c -+++ b/drivers/remoteproc/pru_rproc.c -@@ -603,7 +603,7 @@ pru_rproc_load_elf_segments(struct rproc *rproc, const struct firmware *fw) - break; - } - -- if (pru->data->is_k3 && is_iram) { -+ if (pru->data->is_k3) { - ret = pru_rproc_memcpy(ptr, elf_data + phdr->p_offset, - filesz); - if (ret) { diff --git a/recipes-kernel/linux/files/patches-5.10/0041-remoteproc-pru-Fixup-interrupt-parent-logic-for-fw-e.patch b/recipes-kernel/linux/files/patches-5.10/0041-remoteproc-pru-Fixup-interrupt-parent-logic-for-fw-e.patch deleted file mode 100644 index b7ee8139d..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0041-remoteproc-pru-Fixup-interrupt-parent-logic-for-fw-e.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Wed, 7 Apr 2021 10:56:39 -0500 -Subject: [PATCH] remoteproc: pru: Fixup interrupt-parent logic for fw events - -The PRU firmware interrupt mapping logic in pru_handle_intrmap() uses -of_irq_find_parent() with PRU device node to get a handle to the PRUSS -Interrupt Controller at present. This logic however requires that the -PRU nodes always define a interrupt-parent property. This property is -neither a required/defined property as per the PRU remoteproc binding, -nor is relevant from a DT node point of view without any associated -interrupts. The current logic finds a wrong interrupt controller and -fails to perform proper mapping without any interrupt-parent property -in the PRU nodes. - -Fix this logic to always find and use the sibling interrupt controller. -Also, while at this, fix the acquired interrupt controller device node -reference properly. - -Fixes: c75c9fdac66e ("remoteproc: pru: Add support for PRU specific interrupt configuration") -Signed-off-by: Suman Anna -Reviewed-by: Mathieu Poirier -Link: https://lore.kernel.org/r/20210407155641.5501-2-s-anna@ti.com -Signed-off-by: Bjorn Andersson ---- - drivers/remoteproc/pru_rproc.c | 15 ++++++++++++--- - 1 file changed, 12 insertions(+), 3 deletions(-) - -diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c -index 21105592a83d..773c09d01958 100644 ---- a/drivers/remoteproc/pru_rproc.c -+++ b/drivers/remoteproc/pru_rproc.c -@@ -284,7 +284,7 @@ static int pru_handle_intrmap(struct rproc *rproc) - struct pru_rproc *pru = rproc->priv; - struct pru_irq_rsc *rsc = pru->pru_interrupt_map; - struct irq_fwspec fwspec; -- struct device_node *irq_parent; -+ struct device_node *parent, *irq_parent; - int i, ret = 0; - - /* not having pru_interrupt_map is not an error */ -@@ -312,9 +312,16 @@ static int pru_handle_intrmap(struct rproc *rproc) - - /* - * parse and fill in system event to interrupt channel and -- * channel-to-host mapping -+ * channel-to-host mapping. The interrupt controller to be used -+ * for these mappings for a given PRU remoteproc is always its -+ * corresponding sibling PRUSS INTC node. - */ -- irq_parent = of_irq_find_parent(pru->dev->of_node); -+ parent = of_get_parent(dev_of_node(pru->dev)); -+ if (!parent) -+ return -ENODEV; -+ -+ irq_parent = of_get_child_by_name(parent, "interrupt-controller"); -+ of_node_put(parent); - if (!irq_parent) { - kfree(pru->mapped_irq); - return -ENODEV; -@@ -337,11 +344,13 @@ static int pru_handle_intrmap(struct rproc *rproc) - goto map_fail; - } - } -+ of_node_put(irq_parent); - - return ret; - - map_fail: - pru_dispose_irq_mapping(pru); -+ of_node_put(irq_parent); - - return ret; - } diff --git a/recipes-kernel/linux/files/patches-5.10/0042-remoteproc-pru-Fix-wrong-success-return-value-for-fw.patch b/recipes-kernel/linux/files/patches-5.10/0042-remoteproc-pru-Fix-wrong-success-return-value-for-fw.patch deleted file mode 100644 index b80620173..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0042-remoteproc-pru-Fix-wrong-success-return-value-for-fw.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Wed, 7 Apr 2021 10:56:40 -0500 -Subject: [PATCH] remoteproc: pru: Fix wrong success return value for fw events - -The irq_create_fwspec_mapping() returns a proper virq value on success -and 0 upon any failure. The pru_handle_intrmap() treats this as an error -and disposes all firmware event mappings correctly, but is returning -this incorrect value as is, letting the pru_rproc_start() interpret it -as a success and boot the PRU. - -Fix this by returning an error value back upon any such failure. While -at this, revise the error trace to print some meaningful info about the -failed event. - -Fixes: c75c9fdac66e ("remoteproc: pru: Add support for PRU specific interrupt configuration") -Signed-off-by: Suman Anna -Reviewed-by: Mathieu Poirier -Link: https://lore.kernel.org/r/20210407155641.5501-3-s-anna@ti.com -Signed-off-by: Bjorn Andersson ---- - drivers/remoteproc/pru_rproc.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c -index 773c09d01958..e0c5fce8bccd 100644 ---- a/drivers/remoteproc/pru_rproc.c -+++ b/drivers/remoteproc/pru_rproc.c -@@ -339,8 +339,10 @@ static int pru_handle_intrmap(struct rproc *rproc) - - pru->mapped_irq[i] = irq_create_fwspec_mapping(&fwspec); - if (!pru->mapped_irq[i]) { -- dev_err(dev, "failed to get virq\n"); -- ret = pru->mapped_irq[i]; -+ dev_err(dev, "failed to get virq for fw mapping %d: event %d chnl %d host %d\n", -+ i, fwspec.param[0], fwspec.param[1], -+ fwspec.param[2]); -+ ret = -EINVAL; - goto map_fail; - } - } diff --git a/recipes-kernel/linux/files/patches-5.10/0043-remoteproc-pru-Fix-and-cleanup-firmware-interrupt-ma.patch b/recipes-kernel/linux/files/patches-5.10/0043-remoteproc-pru-Fix-and-cleanup-firmware-interrupt-ma.patch deleted file mode 100644 index ba0f76b48..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0043-remoteproc-pru-Fix-and-cleanup-firmware-interrupt-ma.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Wed, 7 Apr 2021 10:56:41 -0500 -Subject: [PATCH] remoteproc: pru: Fix and cleanup firmware interrupt mapping - logic - -The PRU firmware interrupt mappings are configured and unconfigured in -.start() and .stop() callbacks respectively using the variables 'evt_count' -and a 'mapped_irq' pointer. These variables are modified only during these -callbacks but are not re-initialized/reset properly during unwind or -failure paths. These stale values caused a kernel crash while stopping a -PRU remoteproc running a different firmware with no events on a subsequent -run after a previous run that was running a firmware with events. - -Fix this crash by ensuring that the evt_count is 0 and the mapped_irq -pointer is set to NULL in pru_dispose_irq_mapping(). Also, reset these -variables properly during any failures in the .start() callback. While -at this, the pru_dispose_irq_mapping() callsites are all made to look -the same, moving any conditional logic to inside the function. - -Reviewed-by: Mathieu Poirier -Fixes: c75c9fdac66e ("remoteproc: pru: Add support for PRU specific interrupt configuration") -Reported-by: Vignesh Raghavendra -Signed-off-by: Suman Anna -Link: https://lore.kernel.org/r/20210407155641.5501-4-s-anna@ti.com -Signed-off-by: Bjorn Andersson ---- - drivers/remoteproc/pru_rproc.c | 22 +++++++++++++++++----- - 1 file changed, 17 insertions(+), 5 deletions(-) - -diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c -index e0c5fce8bccd..d8597027a93e 100644 ---- a/drivers/remoteproc/pru_rproc.c -+++ b/drivers/remoteproc/pru_rproc.c -@@ -266,12 +266,17 @@ static void pru_rproc_create_debug_entries(struct rproc *rproc) - - static void pru_dispose_irq_mapping(struct pru_rproc *pru) - { -- while (pru->evt_count--) { -+ if (!pru->mapped_irq) -+ return; -+ -+ while (pru->evt_count) { -+ pru->evt_count--; - if (pru->mapped_irq[pru->evt_count] > 0) - irq_dispose_mapping(pru->mapped_irq[pru->evt_count]); - } - - kfree(pru->mapped_irq); -+ pru->mapped_irq = NULL; - } - - /* -@@ -307,8 +312,10 @@ static int pru_handle_intrmap(struct rproc *rproc) - pru->evt_count = rsc->num_evts; - pru->mapped_irq = kcalloc(pru->evt_count, sizeof(unsigned int), - GFP_KERNEL); -- if (!pru->mapped_irq) -+ if (!pru->mapped_irq) { -+ pru->evt_count = 0; - return -ENOMEM; -+ } - - /* - * parse and fill in system event to interrupt channel and -@@ -317,13 +324,19 @@ static int pru_handle_intrmap(struct rproc *rproc) - * corresponding sibling PRUSS INTC node. - */ - parent = of_get_parent(dev_of_node(pru->dev)); -- if (!parent) -+ if (!parent) { -+ kfree(pru->mapped_irq); -+ pru->mapped_irq = NULL; -+ pru->evt_count = 0; - return -ENODEV; -+ } - - irq_parent = of_get_child_by_name(parent, "interrupt-controller"); - of_node_put(parent); - if (!irq_parent) { - kfree(pru->mapped_irq); -+ pru->mapped_irq = NULL; -+ pru->evt_count = 0; - return -ENODEV; - } - -@@ -398,8 +411,7 @@ static int pru_rproc_stop(struct rproc *rproc) - pru_control_write_reg(pru, PRU_CTRL_CTRL, val); - - /* dispose irq mapping - new firmware can provide new mapping */ -- if (pru->mapped_irq) -- pru_dispose_irq_mapping(pru); -+ pru_dispose_irq_mapping(pru); - - return 0; - } diff --git a/recipes-kernel/linux/files/patches-5.10/0044-watchdog-rti_wdt-Fix-calculation-and-evaluation-of-p.patch b/recipes-kernel/linux/files/patches-5.10/0044-watchdog-rti_wdt-Fix-calculation-and-evaluation-of-p.patch deleted file mode 100644 index c86554a55..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0044-watchdog-rti_wdt-Fix-calculation-and-evaluation-of-p.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Mon, 21 Feb 2022 17:22:38 +0100 -Subject: [PATCH] watchdog: rti_wdt: Fix calculation and evaluation of preset - heartbeat - -This ensures that the same value is read back as was eventually -programmed when using seconds as accuracy. Even then, comparing the more -precise heartbeat_ms against heartbeat in seconds will almost never -provide a match and will needlessly raise a warning. Fix by comparing -apples to apples. - -Tested in combination with U-Boot as watchdog starter. - -Signed-off-by: Jan Kiszka -Reviewed-by: Guenter Roeck -Link: https://lore.kernel.org/r/6a4b54ac-9588-e172-c4c7-b91d524a851e@siemens.com -Signed-off-by: Guenter Roeck -Signed-off-by: Wim Van Sebroeck ---- - drivers/watchdog/rti_wdt.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c -index 46c2a4bd9ebe..06f9d0ee1340 100644 ---- a/drivers/watchdog/rti_wdt.c -+++ b/drivers/watchdog/rti_wdt.c -@@ -255,6 +255,7 @@ static int rti_wdt_probe(struct platform_device *pdev) - } - - if (readl(wdt->base + RTIDWDCTRL) == WDENABLE_KEY) { -+ int preset_heartbeat; - u32 time_left_ms; - u64 heartbeat_ms; - u32 wsize; -@@ -265,11 +266,12 @@ static int rti_wdt_probe(struct platform_device *pdev) - heartbeat_ms <<= WDT_PRELOAD_SHIFT; - heartbeat_ms *= 1000; - do_div(heartbeat_ms, wdt->freq); -- if (heartbeat_ms != heartbeat * 1000) -+ preset_heartbeat = heartbeat_ms + 500; -+ preset_heartbeat /= 1000; -+ if (preset_heartbeat != heartbeat) - dev_warn(dev, "watchdog already running, ignoring heartbeat config!\n"); - -- heartbeat = heartbeat_ms; -- heartbeat /= 1000; -+ heartbeat = preset_heartbeat; - - wsize = readl(wdt->base + RTIWWDSIZECTRL); - ret = rti_wdt_setup_hw_hb(wdd, wsize); diff --git a/recipes-kernel/linux/files/patches-5.10/0045-arm64-dts-ti-iot2050-Flip-mmc-device-ordering-on-Adv.patch b/recipes-kernel/linux/files/patches-5.10/0045-arm64-dts-ti-iot2050-Flip-mmc-device-ordering-on-Adv.patch deleted file mode 100644 index 39ada1800..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0045-arm64-dts-ti-iot2050-Flip-mmc-device-ordering-on-Adv.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Sun, 26 Sep 2021 14:05:12 +0200 -Subject: [PATCH] arm64: dts: ti: iot2050: Flip mmc device ordering on Advanced - devices - -This ensures that the SD card will remain mmc0 across Basic and Advanced -devices, also avoiding surprises for users coming from the downstream -kernels. - -Signed-off-by: Jan Kiszka -Acked-by: Aswath Govindraju -Signed-off-by: Nishanth Menon -Link: https://lore.kernel.org/r/fe20d6346f119a28e47d129b616682001299cf0e.1632657917.git.jan.kiszka@web.de ---- - arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index 1008e9162ba2..6261ca8ee2d8 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -@@ -17,6 +17,8 @@ - / { - aliases { - spi0 = &mcu_spi0; -+ mmc0 = &sdhci1; -+ mmc1 = &sdhci0; - }; - - chosen { diff --git a/recipes-kernel/linux/files/patches-5.10/0046-arm64-dts-ti-iot2050-Disable-SR2.0-only-PRUs.patch b/recipes-kernel/linux/files/patches-5.10/0046-arm64-dts-ti-iot2050-Disable-SR2.0-only-PRUs.patch deleted file mode 100644 index d84f75c4d..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0046-arm64-dts-ti-iot2050-Disable-SR2.0-only-PRUs.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Sun, 26 Sep 2021 14:05:13 +0200 -Subject: [PATCH] arm64: dts: ti: iot2050: Disable SR2.0-only PRUs - -The IOT2050 devices described so far are using SR1.0 silicon, thus do -not have the additional PRUs of the ICSSG of the SR2.0. Disable them. - -Signed-off-by: Jan Kiszka -Acked-by: Aswath Govindraju -Acked-by: Suman Anna -Signed-off-by: Nishanth Menon -Link: https://lore.kernel.org/r/189a91866fb1af02e4fd2345dc56774aa069d5ba.1632657917.git.jan.kiszka@web.de ---- - .../boot/dts/ti/k3-am65-iot2050-common.dtsi | 24 +++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index 6261ca8ee2d8..58c8e64d5885 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -@@ -716,3 +716,27 @@ &icssg1_mdio { - &icssg2_mdio { - status = "disabled"; - }; -+ -+&tx_pru0_0 { -+ status = "disabled"; -+}; -+ -+&tx_pru0_1 { -+ status = "disabled"; -+}; -+ -+&tx_pru1_0 { -+ status = "disabled"; -+}; -+ -+&tx_pru1_1 { -+ status = "disabled"; -+}; -+ -+&tx_pru2_0 { -+ status = "disabled"; -+}; -+ -+&tx_pru2_1 { -+ status = "disabled"; -+}; diff --git a/recipes-kernel/linux/files/patches-5.10/0047-arm64-dts-ti-iot2050-Add-enabled-mailboxes-and-carve.patch b/recipes-kernel/linux/files/patches-5.10/0047-arm64-dts-ti-iot2050-Add-enabled-mailboxes-and-carve.patch deleted file mode 100644 index 8c100b6b5..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0047-arm64-dts-ti-iot2050-Add-enabled-mailboxes-and-carve.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Sun, 26 Sep 2021 14:05:14 +0200 -Subject: [PATCH] arm64: dts: ti: iot2050: Add/enabled mailboxes and carve-outs - for R5F cores - -Analogously to the am654-base-board, configure the mailboxes for the two -R5F cores, add them and the already existing memory carve-outs to the -related MCU nodes. Allows to load applications under Linux onto the -cores, e.g. the RTI watchdog firmware. - -Signed-off-by: Jan Kiszka -Reviewed-by: Suman Anna -Signed-off-by: Nishanth Menon -Link: https://lore.kernel.org/r/1776f8be19b39a938d9248fcfc5332b753783c3e.1632657917.git.jan.kiszka@web.de ---- - .../boot/dts/ti/k3-am65-iot2050-common.dtsi | 26 +++++++++++++++++-- - 1 file changed, 24 insertions(+), 2 deletions(-) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index 58c8e64d5885..b29537088289 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -@@ -658,11 +658,21 @@ &pcie1_ep { - }; - - &mailbox0_cluster0 { -- status = "disabled"; -+ interrupts = <436>; -+ -+ mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 { -+ ti,mbox-tx = <1 0 0>; -+ ti,mbox-rx = <0 0 0>; -+ }; - }; - - &mailbox0_cluster1 { -- status = "disabled"; -+ interrupts = <432>; -+ -+ mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 { -+ ti,mbox-tx = <1 0 0>; -+ ti,mbox-rx = <0 0 0>; -+ }; - }; - - &mailbox0_cluster2 { -@@ -705,6 +715,18 @@ &mailbox0_cluster11 { - status = "disabled"; - }; - -+&mcu_r5fss0_core0 { -+ memory-region = <&mcu_r5fss0_core0_dma_memory_region>, -+ <&mcu_r5fss0_core0_memory_region>; -+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core0>; -+}; -+ -+&mcu_r5fss0_core1 { -+ memory-region = <&mcu_r5fss0_core1_dma_memory_region>, -+ <&mcu_r5fss0_core1_memory_region>; -+ mboxes = <&mailbox0_cluster1 &mbox_mcu_r5fss0_core1>; -+}; -+ - &icssg0_mdio { - status = "disabled"; - }; diff --git a/recipes-kernel/linux/files/patches-5.10/0048-arm64-dts-ti-iot2050-Prepare-for-adding-2nd-generati.patch b/recipes-kernel/linux/files/patches-5.10/0048-arm64-dts-ti-iot2050-Prepare-for-adding-2nd-generati.patch deleted file mode 100644 index aa61012de..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0048-arm64-dts-ti-iot2050-Prepare-for-adding-2nd-generati.patch +++ /dev/null @@ -1,360 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Sun, 26 Sep 2021 14:05:16 +0200 -Subject: [PATCH] arm64: dts: ti: iot2050: Prepare for adding 2nd-generation - boards - -The current IOT2050 devices are Product Generation 1 (PG1), using SR1.0 -AM65x silicon. Upcoming PG2 devices will use SR2.x SoCs and will -therefore need separate device trees. Prepare for that by factoring out -common bits that will be shared across both generations. - -At this chance, drop a link to the product homepage to in the top-level -dts files. Also fix a typo in my email address in some headers. - -Signed-off-by: Jan Kiszka -Signed-off-by: Nishanth Menon -Link: https://lore.kernel.org/r/31fece05f9728a852c0632985c4fa537cced4ece.1632657917.git.jan.kiszka@web.de ---- - .../dts/ti/k3-am65-iot2050-common-pg1.dtsi | 46 +++++++++++++++ - .../boot/dts/ti/k3-am65-iot2050-common.dtsi | 35 +----------- - ...ts => k3-am6528-iot2050-basic-common.dtsi} | 12 +--- - .../boot/dts/ti/k3-am6528-iot2050-basic.dts | 56 +++---------------- - ...=> k3-am6548-iot2050-advanced-common.dtsi} | 8 +-- - .../dts/ti/k3-am6548-iot2050-advanced.dts | 50 +++-------------- - 6 files changed, 67 insertions(+), 140 deletions(-) - create mode 100644 arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi - copy arch/arm64/boot/dts/ti/{k3-am6528-iot2050-basic.dts => k3-am6528-iot2050-basic-common.dtsi} (80%) - copy arch/arm64/boot/dts/ti/{k3-am6548-iot2050-advanced.dts => k3-am6548-iot2050-advanced-common.dtsi} (85%) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi -new file mode 100644 -index 000000000000..51f902fa35a7 ---- /dev/null -+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi -@@ -0,0 +1,46 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) Siemens AG, 2021 -+ * -+ * Authors: -+ * Jan Kiszka -+ * -+ * Common bits of the IOT2050 Basic and Advanced variants, PG1 -+ */ -+ -+&dss { -+ assigned-clocks = <&k3_clks 67 2>; -+ assigned-clock-parents = <&k3_clks 67 5>; -+}; -+ -+&serdes0 { -+ status = "disabled"; -+}; -+ -+&sdhci1 { -+ no-1-8-v; -+}; -+ -+&tx_pru0_0 { -+ status = "disabled"; -+}; -+ -+&tx_pru0_1 { -+ status = "disabled"; -+}; -+ -+&tx_pru1_0 { -+ status = "disabled"; -+}; -+ -+&tx_pru1_1 { -+ status = "disabled"; -+}; -+ -+&tx_pru2_0 { -+ status = "disabled"; -+}; -+ -+&tx_pru2_1 { -+ status = "disabled"; -+}; -diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index b29537088289..65da226847f4 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -@@ -4,13 +4,11 @@ - * - * Authors: - * Le Jin -- * Jan Kiszka -+ * Jan Kiszka - * -- * Common bits of the IOT2050 Basic and Advanced variants -+ * Common bits of the IOT2050 Basic and Advanced variants, PG1 and PG2 - */ - --/dts-v1/; -- - #include "k3-am654.dtsi" - #include - -@@ -557,7 +555,6 @@ &sdhci1 { - pinctrl-0 = <&main_mmc1_pins_default>; - ti,driver-strength-ohm = <50>; - disable-wp; -- no-1-8-v; - }; - - &usb0 { -@@ -631,10 +628,6 @@ dpi_out: endpoint { - }; - }; - --&serdes0 { -- status = "disabled"; --}; -- - &pcie0_rc { - status = "disabled"; - }; -@@ -738,27 +731,3 @@ &icssg1_mdio { - &icssg2_mdio { - status = "disabled"; - }; -- --&tx_pru0_0 { -- status = "disabled"; --}; -- --&tx_pru0_1 { -- status = "disabled"; --}; -- --&tx_pru1_0 { -- status = "disabled"; --}; -- --&tx_pru1_1 { -- status = "disabled"; --}; -- --&tx_pru2_0 { -- status = "disabled"; --}; -- --&tx_pru2_1 { -- status = "disabled"; --}; -diff --git a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi -similarity index 80% -copy from arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts -copy to arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi -index 94bb5dd39122..4a9bf7d7c07d 100644 ---- a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts -+++ b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi -@@ -4,20 +4,14 @@ - * - * Authors: - * Le Jin -- * Jan Kiszka -+ * Jan Kiszka - * -- * AM6528-based (dual-core) IOT2050 Basic variant -- * 1 GB RAM, no eMMC, main_uart0 on connector X30 -+ * Common bits of the IOT2050 Basic variant, PG1 and PG2 - */ - --/dts-v1/; -- - #include "k3-am65-iot2050-common.dtsi" - - / { -- compatible = "siemens,iot2050-basic", "ti,am654"; -- model = "SIMATIC IOT2050 Basic"; -- - memory@80000000 { - device_type = "memory"; - /* 1G RAM */ -@@ -61,6 +55,6 @@ &main_uart0 { - }; - - &mcu_r5fss0 { -- /* lock-step mode not supported on this board */ -+ /* lock-step mode not supported on Basic boards */ - ti,cluster-mode = <0>; - }; -diff --git a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts -index 94bb5dd39122..87928ff28214 100644 ---- a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts -+++ b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts -@@ -4,63 +4,21 @@ - * - * Authors: - * Le Jin -- * Jan Kiszka -+ * Jan Kiszka - * -- * AM6528-based (dual-core) IOT2050 Basic variant -+ * AM6528-based (dual-core) IOT2050 Basic variant, Product Generation 1 - * 1 GB RAM, no eMMC, main_uart0 on connector X30 -+ * -+ * Product homepage: -+ * https://new.siemens.com/global/en/products/automation/pc-based/iot-gateways/simatic-iot2050.html - */ - - /dts-v1/; - --#include "k3-am65-iot2050-common.dtsi" -+#include "k3-am6528-iot2050-basic-common.dtsi" -+#include "k3-am65-iot2050-common-pg1.dtsi" - - / { - compatible = "siemens,iot2050-basic", "ti,am654"; - model = "SIMATIC IOT2050 Basic"; -- -- memory@80000000 { -- device_type = "memory"; -- /* 1G RAM */ -- reg = <0x00000000 0x80000000 0x00000000 0x40000000>; -- }; -- -- cpus { -- cpu-map { -- /delete-node/ cluster1; -- }; -- /delete-node/ cpu@100; -- /delete-node/ cpu@101; -- }; -- -- /delete-node/ l2-cache1; --}; -- --/* eMMC */ --&sdhci0 { -- status = "disabled"; --}; -- --&main_pmx0 { -- main_uart0_pins_default: main-uart0-pins-default { -- pinctrl-single,pins = < -- AM65X_IOPAD(0x01e4, PIN_INPUT, 0) /* (AF11) UART0_RXD */ -- AM65X_IOPAD(0x01e8, PIN_OUTPUT, 0) /* (AE11) UART0_TXD */ -- AM65X_IOPAD(0x01ec, PIN_INPUT, 0) /* (AG11) UART0_CTSn */ -- AM65X_IOPAD(0x01f0, PIN_OUTPUT, 0) /* (AD11) UART0_RTSn */ -- AM65X_IOPAD(0x0188, PIN_INPUT, 1) /* (D25) UART0_DCDn */ -- AM65X_IOPAD(0x018c, PIN_INPUT, 1) /* (B26) UART0_DSRn */ -- AM65X_IOPAD(0x0190, PIN_OUTPUT, 1) /* (A24) UART0_DTRn */ -- AM65X_IOPAD(0x0194, PIN_INPUT, 1) /* (E24) UART0_RIN */ -- >; -- }; --}; -- --&main_uart0 { -- pinctrl-names = "default"; -- pinctrl-0 = <&main_uart0_pins_default>; --}; -- --&mcu_r5fss0 { -- /* lock-step mode not supported on this board */ -- ti,cluster-mode = <0>; - }; -diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi -similarity index 85% -copy from arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts -copy to arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi -index ec9617c13cdb..d25e8b26187f 100644 ---- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts -+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi -@@ -4,10 +4,9 @@ - * - * Authors: - * Le Jin -- * Jan Kiszka -+ * Jan Kiszka - * -- * AM6548-based (quad-core) IOT2050 Advanced variant -- * 2 GB RAM, 16 GB eMMC, USB-serial converter on connector X30 -+ * Common bits of the IOT2050 Advanced variant, PG1 and PG2 - */ - - /dts-v1/; -@@ -15,9 +14,6 @@ - #include "k3-am65-iot2050-common.dtsi" - - / { -- compatible = "siemens,iot2050-advanced", "ti,am654"; -- model = "SIMATIC IOT2050 Advanced"; -- - memory@80000000 { - device_type = "memory"; - /* 2G RAM */ -diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts -index ec9617c13cdb..077f165bdc68 100644 ---- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts -+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts -@@ -4,57 +4,21 @@ - * - * Authors: - * Le Jin -- * Jan Kiszka -+ * Jan Kiszka - * -- * AM6548-based (quad-core) IOT2050 Advanced variant -+ * AM6548-based (quad-core) IOT2050 Advanced variant, Product Generation 1 - * 2 GB RAM, 16 GB eMMC, USB-serial converter on connector X30 -+ * -+ * Product homepage: -+ * https://new.siemens.com/global/en/products/automation/pc-based/iot-gateways/simatic-iot2050.html - */ - - /dts-v1/; - --#include "k3-am65-iot2050-common.dtsi" -+#include "k3-am6548-iot2050-advanced-common.dtsi" -+#include "k3-am65-iot2050-common-pg1.dtsi" - - / { - compatible = "siemens,iot2050-advanced", "ti,am654"; - model = "SIMATIC IOT2050 Advanced"; -- -- memory@80000000 { -- device_type = "memory"; -- /* 2G RAM */ -- reg = <0x00000000 0x80000000 0x00000000 0x80000000>; -- }; --}; -- --&main_pmx0 { -- main_mmc0_pins_default: main-mmc0-pins-default { -- pinctrl-single,pins = < -- AM65X_IOPAD(0x01a8, PIN_INPUT_PULLDOWN, 0) /* (B25) MMC0_CLK */ -- AM65X_IOPAD(0x01ac, PIN_INPUT_PULLUP, 0) /* (B27) MMC0_CMD */ -- AM65X_IOPAD(0x01a4, PIN_INPUT_PULLUP, 0) /* (A26) MMC0_DAT0 */ -- AM65X_IOPAD(0x01a0, PIN_INPUT_PULLUP, 0) /* (E25) MMC0_DAT1 */ -- AM65X_IOPAD(0x019c, PIN_INPUT_PULLUP, 0) /* (C26) MMC0_DAT2 */ -- AM65X_IOPAD(0x0198, PIN_INPUT_PULLUP, 0) /* (A25) MMC0_DAT3 */ -- AM65X_IOPAD(0x0194, PIN_INPUT_PULLUP, 0) /* (E24) MMC0_DAT4 */ -- AM65X_IOPAD(0x0190, PIN_INPUT_PULLUP, 0) /* (A24) MMC0_DAT5 */ -- AM65X_IOPAD(0x018c, PIN_INPUT_PULLUP, 0) /* (B26) MMC0_DAT6 */ -- AM65X_IOPAD(0x0188, PIN_INPUT_PULLUP, 0) /* (D25) MMC0_DAT7 */ -- AM65X_IOPAD(0x01b8, PIN_OUTPUT_PULLUP, 7) /* (B23) MMC0_SDWP */ -- AM65X_IOPAD(0x01b4, PIN_INPUT_PULLUP, 0) /* (A23) MMC0_SDCD */ -- AM65X_IOPAD(0x01b0, PIN_INPUT, 0) /* (C25) MMC0_DS */ -- >; -- }; --}; -- --/* eMMC */ --&sdhci0 { -- pinctrl-names = "default"; -- pinctrl-0 = <&main_mmc0_pins_default>; -- bus-width = <8>; -- non-removable; -- ti,driver-strength-ohm = <50>; -- disable-wp; --}; -- --&main_uart0 { -- status = "disabled"; - }; diff --git a/recipes-kernel/linux/files/patches-5.10/0049-arm64-dts-ti-iot2050-Add-support-for-product-generat.patch b/recipes-kernel/linux/files/patches-5.10/0049-arm64-dts-ti-iot2050-Add-support-for-product-generat.patch deleted file mode 100644 index 407e02cd5..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0049-arm64-dts-ti-iot2050-Add-support-for-product-generat.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Sun, 26 Sep 2021 14:05:17 +0200 -Subject: [PATCH] arm64: dts: ti: iot2050: Add support for product generation 2 - boards - -This adds the devices trees for IOT2050 Product Generation 2 (PG2) -boards. We have Basic and an Advanced variants again, differing in -number of cores, RAM size, availability of eMMC and further details. -The major difference to PG1 is the used silicon revision (SR2.x on -PG2). - -Signed-off-by: Jan Kiszka -Signed-off-by: Nishanth Menon -Link: https://lore.kernel.org/r/cc868da8264324bde2c87d0c01d4763e3678c706.1632657917.git.jan.kiszka@web.de ---- - arch/arm64/boot/dts/ti/Makefile | 2 + - .../dts/ti/k3-am65-iot2050-common-pg2.dtsi | 51 +++++++++++++++++++ - .../dts/ti/k3-am6528-iot2050-basic-pg2.dts | 24 +++++++++ - .../dts/ti/k3-am6548-iot2050-advanced-pg2.dts | 29 +++++++++++ - 4 files changed, 106 insertions(+) - create mode 100644 arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi - create mode 100644 arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts - create mode 100644 arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts - -diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile -index 22108491f16e..e8a07d411627 100644 ---- a/arch/arm64/boot/dts/ti/Makefile -+++ b/arch/arm64/boot/dts/ti/Makefile -@@ -8,7 +8,9 @@ - - dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board.dtb - dtb-$(CONFIG_ARCH_K3) += k3-am6528-iot2050-basic.dtb -+dtb-$(CONFIG_ARCH_K3) += k3-am6528-iot2050-basic-pg2.dtb - dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced.dtb -+dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced-pg2.dtb - - dtb-$(CONFIG_ARCH_K3) += k3-j721e-common-proc-board.dtb - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi -new file mode 100644 -index 000000000000..e73458ca6900 ---- /dev/null -+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi -@@ -0,0 +1,51 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) Siemens AG, 2021 -+ * -+ * Authors: -+ * Chao Zeng -+ * Jan Kiszka -+ * -+ * Common bits of the IOT2050 Basic and Advanced variants, PG2 -+ */ -+ -+&main_pmx0 { -+ cp2102n_reset_pin_default: cp2102n-reset-pin-default { -+ pinctrl-single,pins = < -+ /* (AF12) GPIO1_24, used as cp2102 reset */ -+ AM65X_IOPAD(0x01e0, PIN_OUTPUT, 7) -+ >; -+ }; -+}; -+ -+&main_gpio1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&cp2102n_reset_pin_default>; -+ gpio-line-names = -+ "", "", "", "", "", "", "", "", "", "", -+ "", "", "", "", "", "", "", "", "", "", -+ "", "", "", "", "CP2102N-RESET"; -+}; -+ -+&dss { -+ /* Workaround needed to get DP clock of 154Mhz */ -+ assigned-clocks = <&k3_clks 67 0>; -+}; -+ -+&serdes0 { -+ assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>; -+ assigned-clock-parents = <&k3_clks 153 7>, <&k3_clks 153 4>; -+}; -+ -+&dwc3_0 { -+ assigned-clock-parents = <&k3_clks 151 4>, /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */ -+ <&k3_clks 151 8>; /* set PIPE3_TXB_CLK to WIZ8B2M4VSB */ -+ phys = <&serdes0 PHY_TYPE_USB3 0>; -+ phy-names = "usb3-phy"; -+}; -+ -+&usb0 { -+ maximum-speed = "super-speed"; -+ snps,dis-u1-entry-quirk; -+ snps,dis-u2-entry-quirk; -+}; -diff --git a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts -new file mode 100644 -index 000000000000..c62549a4b436 ---- /dev/null -+++ b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts -@@ -0,0 +1,24 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) Siemens AG, 2018-2021 -+ * -+ * Authors: -+ * Le Jin -+ * Jan Kiszka -+ * -+ * AM6528-based (dual-core) IOT2050 Basic variant, Product Generation 2 -+ * 1 GB RAM, no eMMC, main_uart0 on connector X30 -+ * -+ * Product homepage: -+ * https://new.siemens.com/global/en/products/automation/pc-based/iot-gateways/simatic-iot2050.html -+ */ -+ -+/dts-v1/; -+ -+#include "k3-am6528-iot2050-basic-common.dtsi" -+#include "k3-am65-iot2050-common-pg2.dtsi" -+ -+/ { -+ compatible = "siemens,iot2050-basic-pg2", "ti,am654"; -+ model = "SIMATIC IOT2050 Basic PG2"; -+}; -diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts -new file mode 100644 -index 000000000000..f00dc86d01b9 ---- /dev/null -+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts -@@ -0,0 +1,29 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) Siemens AG, 2018-2021 -+ * -+ * Authors: -+ * Le Jin -+ * Jan Kiszka -+ * -+ * AM6548-based (quad-core) IOT2050 Advanced variant, Product Generation 2 -+ * 2 GB RAM, 16 GB eMMC, USB-serial converter on connector X30 -+ * -+ * Product homepage: -+ * https://new.siemens.com/global/en/products/automation/pc-based/iot-gateways/simatic-iot2050.html -+ */ -+ -+/dts-v1/; -+ -+#include "k3-am6548-iot2050-advanced-common.dtsi" -+#include "k3-am65-iot2050-common-pg2.dtsi" -+ -+/ { -+ compatible = "siemens,iot2050-advanced-pg2", "ti,am654"; -+ model = "SIMATIC IOT2050 Advanced PG2"; -+}; -+ -+&mcu_r5fss0 { -+ /* lock-step mode not supported on this board */ -+ ti,cluster-mode = <0>; -+}; diff --git a/recipes-kernel/linux/files/patches-5.10/0052-irqdomain-Export-of_phandle_args_to_fwspec.patch b/recipes-kernel/linux/files/patches-5.10/0052-irqdomain-Export-of_phandle_args_to_fwspec.patch deleted file mode 100644 index 5f1aae26a..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0052-irqdomain-Export-of_phandle_args_to_fwspec.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Kishon Vijay Abraham I -Date: Tue, 30 Mar 2021 17:24:46 +0530 -Subject: [PATCH] irqdomain: Export of_phandle_args_to_fwspec() - -Export of_phandle_args_to_fwspec() to be used by drivers. -of_phandle_args_to_fwspec() can be used by drivers to get irq specifier -from device node useful while creating hierarchy domain. This was -suggested by Marc Zyngier [1]. - -[1] -> http://lore.kernel.org/r/20190223121143.14c1f150@why.wild-wind.fr.eu.org/ - -Signed-off-by: Kishon Vijay Abraham I -Signed-off-by: Vignesh Raghavendra ---- - include/linux/irqdomain.h | 2 ++ - kernel/irq/irqdomain.c | 6 +++--- - 2 files changed, 5 insertions(+), 3 deletions(-) - -diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h -index 9b9743f7538c..a1a143007fa9 100644 ---- a/include/linux/irqdomain.h -+++ b/include/linux/irqdomain.h -@@ -387,6 +387,8 @@ extern void irq_domain_disassociate(struct irq_domain *domain, - extern unsigned int irq_create_mapping_affinity(struct irq_domain *host, - irq_hw_number_t hwirq, - const struct irq_affinity_desc *affinity); -+void of_phandle_args_to_fwspec(struct device_node *np, const u32 *args, unsigned int count, -+ struct irq_fwspec *fwspec); - extern unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec); - extern void irq_dispose_mapping(unsigned int virq); - -diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c -index fd3f7c16c299..5d4aeb6c8678 100644 ---- a/kernel/irq/irqdomain.c -+++ b/kernel/irq/irqdomain.c -@@ -784,9 +784,8 @@ static int irq_domain_translate(struct irq_domain *d, - return 0; - } - --static void of_phandle_args_to_fwspec(struct device_node *np, const u32 *args, -- unsigned int count, -- struct irq_fwspec *fwspec) -+void of_phandle_args_to_fwspec(struct device_node *np, const u32 *args, unsigned int count, -+ struct irq_fwspec *fwspec) - { - int i; - -@@ -796,6 +795,7 @@ static void of_phandle_args_to_fwspec(struct device_node *np, const u32 *args, - for (i = 0; i < count; i++) - fwspec->param[i] = args[i]; - } -+EXPORT_SYMBOL_GPL(of_phandle_args_to_fwspec); - - unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) - { diff --git a/recipes-kernel/linux/files/patches-5.10/0057-remoteproc-Fix-unbalanced-boot-with-sysfs-for-no-aut.patch b/recipes-kernel/linux/files/patches-5.10/0057-remoteproc-Fix-unbalanced-boot-with-sysfs-for-no-aut.patch deleted file mode 100644 index 41daa0c8e..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0057-remoteproc-Fix-unbalanced-boot-with-sysfs-for-no-aut.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Fri, 20 Nov 2020 21:01:54 -0600 -Subject: [PATCH] remoteproc: Fix unbalanced boot with sysfs for no auto-boot - rprocs - -The remoteproc core performs automatic boot and shutdown of a remote -processor during rproc_add() and rproc_del() for remote processors -supporting 'auto-boot'. The remoteproc devices not using 'auto-boot' -require either a remoteproc client driver or a userspace client to -use the sysfs 'state' variable to perform the boot and shutdown. The -in-kernel client drivers hold the corresponding remoteproc driver -module's reference count when they acquire a rproc handle through -the rproc_get_by_phandle() API, but there is no such support for -userspace applications performing the boot through sysfs interface. - -The shutdown of a remoteproc upon removing a remoteproc platform -driver is automatic only with 'auto-boot' and this can cause a -remoteproc with no auto-boot to stay powered on and never freed -up if booted using the sysfs interface without a matching stop, -and when the remoteproc driver module is removed or unbound from -the device. This will result in a memory leak as well as the -corresponding remoteproc ida being never deallocated. Fix this -by holding a module reference count for the remoteproc's driver -during a sysfs 'start' and releasing it during the sysfs 'stop' -operation. - -Signed-off-by: Suman Anna -Acked-by: Arnaud Pouliquen ---- - drivers/remoteproc/remoteproc_sysfs.c | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - -diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c -index 1dbef895e65e..3b05230641c8 100644 ---- a/drivers/remoteproc/remoteproc_sysfs.c -+++ b/drivers/remoteproc/remoteproc_sysfs.c -@@ -3,6 +3,7 @@ - * Remote Processor Framework - */ - -+#include - #include - #include - -@@ -199,14 +200,27 @@ static ssize_t state_store(struct device *dev, - if (rproc->state == RPROC_RUNNING) - return -EBUSY; - -+ /* -+ * prevent underlying implementation from being removed -+ * when remoteproc does not support auto-boot -+ */ -+ if (!rproc->auto_boot && -+ !try_module_get(dev->parent->driver->owner)) -+ return -EINVAL; -+ - ret = rproc_boot(rproc); -- if (ret) -+ if (ret) { - dev_err(&rproc->dev, "Boot failed: %d\n", ret); -+ if (!rproc->auto_boot) -+ module_put(dev->parent->driver->owner); -+ } - } else if (sysfs_streq(buf, "stop")) { - if (rproc->state != RPROC_RUNNING) - return -EINVAL; - - rproc_shutdown(rproc); -+ if (!rproc->auto_boot) -+ module_put(dev->parent->driver->owner); - } else { - dev_err(&rproc->dev, "Unrecognised option: %s\n", buf); - ret = -EINVAL; diff --git a/recipes-kernel/linux/files/patches-5.10/0058-remoteproc-Introduce-deny_sysfs_ops-flag.patch b/recipes-kernel/linux/files/patches-5.10/0058-remoteproc-Introduce-deny_sysfs_ops-flag.patch deleted file mode 100644 index 310b34afa..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0058-remoteproc-Introduce-deny_sysfs_ops-flag.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Fri, 26 Mar 2021 13:05:28 -0500 -Subject: [PATCH] remoteproc: Introduce deny_sysfs_ops flag - -The remoteproc framework provides sysfs interfaces for changing the -firmware name and for starting/stopping a remote processor through -the sysfs files 'state' and 'firmware'. The 'recovery' and 'coredump' -sysfs files can also be used similarly to control the error recovery -state machine and coredump of a remoteproc. These interfaces are -currently allowed irrespective of how the remoteprocs were booted -(like remoteproc self auto-boot, remoteproc client-driven boot etc). -These interfaces can adversely affect a remoteproc and its clients -especially when a remoteproc is being controlled by a remoteproc -client driver(s). Also, not all remoteproc drivers may want to -support the sysfs interfaces by default. - -Add support to deny the sysfs state/firmware/recovery/coredump change -by introducing a state flag 'deny_sysfs_ops' that the individual -remoteproc drivers can set based on their usage needs. The default -behavior is to allow the sysfs operations as before. - -Signed-off-by: Suman Anna ---- - drivers/remoteproc/remoteproc_sysfs.c | 16 ++++++++++++++++ - include/linux/remoteproc.h | 2 ++ - 2 files changed, 18 insertions(+) - -diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c -index 3b05230641c8..16f4a3ea0b25 100644 ---- a/drivers/remoteproc/remoteproc_sysfs.c -+++ b/drivers/remoteproc/remoteproc_sysfs.c -@@ -49,6 +49,10 @@ static ssize_t recovery_store(struct device *dev, - { - struct rproc *rproc = to_rproc(dev); - -+ /* restrict sysfs operations if not allowed by remoteproc drivers */ -+ if (rproc->deny_sysfs_ops) -+ return -EPERM; -+ - if (sysfs_streq(buf, "enabled")) { - /* change the flag and begin the recovery process if needed */ - rproc->recovery_disabled = false; -@@ -108,6 +112,10 @@ static ssize_t coredump_store(struct device *dev, - { - struct rproc *rproc = to_rproc(dev); - -+ /* restrict sysfs operations if not allowed by remoteproc drivers */ -+ if (rproc->deny_sysfs_ops) -+ return -EPERM; -+ - if (rproc->state == RPROC_CRASHED) { - dev_err(&rproc->dev, "can't change coredump configuration\n"); - return -EBUSY; -@@ -157,6 +165,10 @@ static ssize_t firmware_store(struct device *dev, - struct rproc *rproc = to_rproc(dev); - int err; - -+ /* restrict sysfs operations if not allowed by remoteproc drivers */ -+ if (rproc->deny_sysfs_ops) -+ return -EPERM; -+ - err = rproc_set_firmware(rproc, buf); - - return err ? err : count; -@@ -196,6 +208,10 @@ static ssize_t state_store(struct device *dev, - struct rproc *rproc = to_rproc(dev); - int ret = 0; - -+ /* restrict sysfs operations if not allowed by remoteproc drivers */ -+ if (rproc->deny_sysfs_ops) -+ return -EPERM; -+ - if (sysfs_streq(buf, "start")) { - if (rproc->state == RPROC_RUNNING) - return -EBUSY; -diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h -index e8ac041c64d9..02425aac6100 100644 ---- a/include/linux/remoteproc.h -+++ b/include/linux/remoteproc.h -@@ -508,6 +508,7 @@ struct rproc_dump_segment { - * @has_iommu: flag to indicate if remote processor is behind an MMU - * @auto_boot: flag to indicate if remote processor should be auto-started - * @autonomous: true if an external entity has booted the remote processor -+ * @deny_sysfs_ops: flag to not permit sysfs store operations - * @dump_segments: list of segments in the firmware - * @nb_vdev: number of vdev currently handled by rproc - * @char_dev: character device of the rproc -@@ -545,6 +546,7 @@ struct rproc { - bool has_iommu; - bool auto_boot; - bool autonomous; -+ bool deny_sysfs_ops; - struct list_head dump_segments; - int nb_vdev; - u8 elf_class; diff --git a/recipes-kernel/linux/files/patches-5.10/0065-soc-ti-pruss-Add-pruss_cfg_read-update-API.patch b/recipes-kernel/linux/files/patches-5.10/0065-soc-ti-pruss-Add-pruss_cfg_read-update-API.patch deleted file mode 100644 index 95fcea181..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0065-soc-ti-pruss-Add-pruss_cfg_read-update-API.patch +++ /dev/null @@ -1,210 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Fri, 26 Mar 2021 16:27:34 -0500 -Subject: [PATCH] soc: ti: pruss: Add pruss_cfg_read()/update() API - -Add two new generic API pruss_cfg_read() and pruss_cfg_update() to -the PRUSS platform driver to allow other drivers to read and program -respectively a register within the PRUSS CFG sub-module represented -by a syscon driver. This interface provides a simple way for client -drivers without having them to include and parse the CFG syscon node -within their respective device nodes. Various useful registers and -macros for certain register bit-fields and their values have also -been added. - -It is the responsibility of the client drivers to reconfigure or -reset a particular register upon any failures. - -Signed-off-by: Suman Anna -Co-developed-by: Grzegorz Jaszczyk -Signed-off-by: Grzegorz Jaszczyk ---- - drivers/soc/ti/pruss.c | 41 +++++++++++++++++ - include/linux/pruss.h | 102 +++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 143 insertions(+) - -diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c -index dc1470fa33d0..8841d85a0a0d 100644 ---- a/drivers/soc/ti/pruss.c -+++ b/drivers/soc/ti/pruss.c -@@ -165,6 +165,47 @@ int pruss_release_mem_region(struct pruss *pruss, - } - EXPORT_SYMBOL_GPL(pruss_release_mem_region); - -+/** -+ * pruss_cfg_read() - read a PRUSS CFG sub-module register -+ * @pruss: the pruss instance handle -+ * @reg: register offset within the CFG sub-module -+ * @val: pointer to return the value in -+ * -+ * Reads a given register within the PRUSS CFG sub-module and -+ * returns it through the passed-in @val pointer -+ * -+ * Return: 0 on success, or an error code otherwise -+ */ -+int pruss_cfg_read(struct pruss *pruss, unsigned int reg, unsigned int *val) -+{ -+ if (IS_ERR_OR_NULL(pruss)) -+ return -EINVAL; -+ -+ return regmap_read(pruss->cfg_regmap, reg, val); -+} -+EXPORT_SYMBOL_GPL(pruss_cfg_read); -+ -+/** -+ * pruss_cfg_update() - configure a PRUSS CFG sub-module register -+ * @pruss: the pruss instance handle -+ * @reg: register offset within the CFG sub-module -+ * @mask: bit mask to use for programming the @val -+ * @val: value to write -+ * -+ * Programs a given register within the PRUSS CFG sub-module -+ * -+ * Return: 0 on success, or an error code otherwise -+ */ -+int pruss_cfg_update(struct pruss *pruss, unsigned int reg, -+ unsigned int mask, unsigned int val) -+{ -+ if (IS_ERR_OR_NULL(pruss)) -+ return -EINVAL; -+ -+ return regmap_update_bits(pruss->cfg_regmap, reg, mask, val); -+} -+EXPORT_SYMBOL_GPL(pruss_cfg_update); -+ - static void pruss_of_free_clk_provider(void *data) - { - struct device_node *clk_mux_np = data; -diff --git a/include/linux/pruss.h b/include/linux/pruss.h -index 40de553d4446..a4f59a46c331 100644 ---- a/include/linux/pruss.h -+++ b/include/linux/pruss.h -@@ -10,12 +10,99 @@ - #ifndef __LINUX_PRUSS_H - #define __LINUX_PRUSS_H - -+#include - #include - #include - #include - - #define PRU_RPROC_DRVNAME "pru-rproc" - -+/* -+ * PRU_ICSS_CFG registers -+ * SYSCFG, ISRP, ISP, IESP, IECP, SCRP applicable on AMxxxx devices only -+ */ -+#define PRUSS_CFG_REVID 0x00 -+#define PRUSS_CFG_SYSCFG 0x04 -+#define PRUSS_CFG_GPCFG(x) (0x08 + (x) * 4) -+#define PRUSS_CFG_CGR 0x10 -+#define PRUSS_CFG_ISRP 0x14 -+#define PRUSS_CFG_ISP 0x18 -+#define PRUSS_CFG_IESP 0x1C -+#define PRUSS_CFG_IECP 0x20 -+#define PRUSS_CFG_SCRP 0x24 -+#define PRUSS_CFG_PMAO 0x28 -+#define PRUSS_CFG_MII_RT 0x2C -+#define PRUSS_CFG_IEPCLK 0x30 -+#define PRUSS_CFG_SPP 0x34 -+#define PRUSS_CFG_PIN_MX 0x40 -+ -+/* PRUSS_GPCFG register bits */ -+#define PRUSS_GPCFG_PRU_GPO_SH_SEL BIT(25) -+ -+#define PRUSS_GPCFG_PRU_DIV1_SHIFT 20 -+#define PRUSS_GPCFG_PRU_DIV1_MASK GENMASK(24, 20) -+ -+#define PRUSS_GPCFG_PRU_DIV0_SHIFT 15 -+#define PRUSS_GPCFG_PRU_DIV0_MASK GENMASK(15, 19) -+ -+#define PRUSS_GPCFG_PRU_GPO_MODE BIT(14) -+#define PRUSS_GPCFG_PRU_GPO_MODE_DIRECT 0 -+#define PRUSS_GPCFG_PRU_GPO_MODE_SERIAL BIT(14) -+ -+#define PRUSS_GPCFG_PRU_GPI_SB BIT(13) -+ -+#define PRUSS_GPCFG_PRU_GPI_DIV1_SHIFT 8 -+#define PRUSS_GPCFG_PRU_GPI_DIV1_MASK GENMASK(12, 8) -+ -+#define PRUSS_GPCFG_PRU_GPI_DIV0_SHIFT 3 -+#define PRUSS_GPCFG_PRU_GPI_DIV0_MASK GENMASK(7, 3) -+ -+#define PRUSS_GPCFG_PRU_GPI_CLK_MODE_POSITIVE 0 -+#define PRUSS_GPCFG_PRU_GPI_CLK_MODE_NEGATIVE BIT(2) -+#define PRUSS_GPCFG_PRU_GPI_CLK_MODE BIT(2) -+ -+#define PRUSS_GPCFG_PRU_GPI_MODE_MASK GENMASK(1, 0) -+#define PRUSS_GPCFG_PRU_GPI_MODE_SHIFT 0 -+ -+#define PRUSS_GPCFG_PRU_MUX_SEL_SHIFT 26 -+#define PRUSS_GPCFG_PRU_MUX_SEL_MASK GENMASK(29, 26) -+ -+/* PRUSS_MII_RT register bits */ -+#define PRUSS_MII_RT_EVENT_EN BIT(0) -+ -+/* PRUSS_SPP register bits */ -+#define PRUSS_SPP_XFER_SHIFT_EN BIT(1) -+#define PRUSS_SPP_PRU1_PAD_HP_EN BIT(0) -+ -+/* -+ * enum pruss_gp_mux_sel - PRUSS GPI/O Mux modes for the -+ * PRUSS_GPCFG0/1 registers -+ * -+ * NOTE: The below defines are the most common values, but there -+ * are some exceptions like on 66AK2G, where the RESERVED and MII2 -+ * values are interchanged. Also, this bit-field does not exist on -+ * AM335x SoCs -+ */ -+enum pruss_gp_mux_sel { -+ PRUSS_GP_MUX_SEL_GP = 0, -+ PRUSS_GP_MUX_SEL_ENDAT, -+ PRUSS_GP_MUX_SEL_RESERVED, -+ PRUSS_GP_MUX_SEL_SD, -+ PRUSS_GP_MUX_SEL_MII2, -+ PRUSS_GP_MUX_SEL_MAX, -+}; -+ -+/* -+ * enum pruss_gpi_mode - PRUSS GPI configuration modes, used -+ * to program the PRUSS_GPCFG0/1 registers -+ */ -+enum pruss_gpi_mode { -+ PRUSS_GPI_MODE_DIRECT = 0, -+ PRUSS_GPI_MODE_PARALLEL, -+ PRUSS_GPI_MODE_28BIT_SHIFT, -+ PRUSS_GPI_MODE_MII, -+}; -+ - /* - * enum pruss_pru_id - PRU core identifiers - */ -@@ -73,6 +160,9 @@ int pruss_request_mem_region(struct pruss *pruss, enum pruss_mem mem_id, - struct pruss_mem_region *region); - int pruss_release_mem_region(struct pruss *pruss, - struct pruss_mem_region *region); -+int pruss_cfg_read(struct pruss *pruss, unsigned int reg, unsigned int *val); -+int pruss_cfg_update(struct pruss *pruss, unsigned int reg, -+ unsigned int mask, unsigned int val); - - #else - -@@ -96,6 +186,18 @@ static inline int pruss_release_mem_region(struct pruss *pruss, - return -EOPNOTSUPP; - } - -+static inline int pruss_cfg_read(struct pruss *pruss, unsigned int reg, -+ unsigned int *val) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int pruss_cfg_update(struct pruss *pruss, unsigned int reg, -+ unsigned int mask, unsigned int val) -+{ -+ return -EOPNOTSUPP; -+} -+ - #endif /* CONFIG_TI_PRUSS */ - - #if IS_ENABLED(CONFIG_PRU_REMOTEPROC) diff --git a/recipes-kernel/linux/files/patches-5.10/0066-soc-ti-pruss-Add-helper-functions-to-set-GPI-mode-MI.patch b/recipes-kernel/linux/files/patches-5.10/0066-soc-ti-pruss-Add-helper-functions-to-set-GPI-mode-MI.patch deleted file mode 100644 index 35d209706..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0066-soc-ti-pruss-Add-helper-functions-to-set-GPI-mode-MI.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Fri, 11 Dec 2020 19:48:09 +0100 -Subject: [PATCH] soc: ti: pruss: Add helper functions to set GPI mode, - MII_RT_event and XFR - -The PRUSS CFG module is represented as a syscon node and is currently -managed by the PRUSS platform driver. Add easy accessor functions to set -GPI mode, MII_RT event enable/disable and XFR (XIN XOUT) enable/disable -to enable the PRUSS Ethernet usecase. These functions reuse the generic -pruss_cfg_update() API function. - -Signed-off-by: Suman Anna -Co-developed-by: Grzegorz Jaszczyk -Signed-off-by: Grzegorz Jaszczyk ---- - include/linux/pruss.h | 55 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 55 insertions(+) - -diff --git a/include/linux/pruss.h b/include/linux/pruss.h -index a4f59a46c331..ba5b728d5015 100644 ---- a/include/linux/pruss.h -+++ b/include/linux/pruss.h -@@ -235,4 +235,59 @@ static inline bool is_pru_rproc(struct device *dev) - return true; - } - -+/** -+ * pruss_cfg_gpimode() - set the GPI mode of the PRU -+ * @pruss: the pruss instance handle -+ * @pru_id: id of the PRU core within the PRUSS -+ * @mode: GPI mode to set -+ * -+ * Sets the GPI mode for a given PRU by programming the -+ * corresponding PRUSS_CFG_GPCFGx register -+ * -+ * Return: 0 on success, or an error code otherwise -+ */ -+static inline int pruss_cfg_gpimode(struct pruss *pruss, -+ enum pruss_pru_id pru_id, -+ enum pruss_gpi_mode mode) -+{ -+ if (pru_id < 0 || pru_id >= PRUSS_NUM_PRUS) -+ return -EINVAL; -+ -+ return pruss_cfg_update(pruss, PRUSS_CFG_GPCFG(pru_id), -+ PRUSS_GPCFG_PRU_GPI_MODE_MASK, -+ mode << PRUSS_GPCFG_PRU_GPI_MODE_SHIFT); -+} -+ -+/** -+ * pruss_cfg_miirt_enable() - Enable/disable MII RT Events -+ * @pruss: the pruss instance -+ * @enable: enable/disable -+ * -+ * Enable/disable the MII RT Events for the PRUSS. -+ * -+ * Return: 0 on success, or an error code otherwise -+ */ -+static inline int pruss_cfg_miirt_enable(struct pruss *pruss, bool enable) -+{ -+ u32 set = enable ? PRUSS_MII_RT_EVENT_EN : 0; -+ -+ return pruss_cfg_update(pruss, PRUSS_CFG_MII_RT, -+ PRUSS_MII_RT_EVENT_EN, set); -+} -+ -+/** -+ * pruss_cfg_xfr_enable() - Enable/disable XIN XOUT shift functionality -+ * @pruss: the pruss instance -+ * @enable: enable/disable -+ * -+ * Return: 0 on success, or an error code otherwise -+ */ -+static inline int pruss_cfg_xfr_enable(struct pruss *pruss, bool enable) -+{ -+ u32 set = enable ? PRUSS_SPP_XFER_SHIFT_EN : 0; -+ -+ return pruss_cfg_update(pruss, PRUSS_CFG_SPP, -+ PRUSS_SPP_XFER_SHIFT_EN, set); -+} -+ - #endif /* __LINUX_PRUSS_H */ diff --git a/recipes-kernel/linux/files/patches-5.10/0067-soc-ti-pruss-Add-helper-function-to-enable-OCP-maste.patch b/recipes-kernel/linux/files/patches-5.10/0067-soc-ti-pruss-Add-helper-function-to-enable-OCP-maste.patch deleted file mode 100644 index 2f310044c..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0067-soc-ti-pruss-Add-helper-function-to-enable-OCP-maste.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Fri, 26 Mar 2021 16:38:11 -0500 -Subject: [PATCH] soc: ti: pruss: Add helper function to enable OCP master - ports - -The PRU-ICSS subsystem on OMAP-architecture based SoCS (AM33xx, AM437x -and AM57xx SoCs) has a control bit STANDBY_INIT in the PRUSS_CFG register -to initiate a Standby sequence (when set) and trigger a MStandby request -to the SoC's PRCM module. This same bit is also used to enable the OCP -master ports (when cleared). The clearing of the STANDBY_INIT bit requires -an acknowledgment from PRCM and is done through the monitoring of the -PRUSS_SYSCFG.SUB_MWAIT bit. - -Add a helper function pruss_cfg_ocp_master_ports() to allow the PRU -client drivers to control this bit and enable or disable the firmware -running on PRU cores access to any peripherals or memory to achieve -desired functionality. The access is disabled by default on power-up -and on any suspend (context is not maintained). - -Signed-off-by: Suman Anna -Co-developed-by: Grzegorz Jaszczyk -Signed-off-by: Grzegorz Jaszczyk ---- - drivers/soc/ti/pruss.c | 81 ++++++++++++++++++++++++++++++++++++++++-- - include/linux/pruss.h | 6 ++++ - 2 files changed, 85 insertions(+), 2 deletions(-) - -diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c -index 8841d85a0a0d..1254495b7c45 100644 ---- a/drivers/soc/ti/pruss.c -+++ b/drivers/soc/ti/pruss.c -@@ -22,14 +22,19 @@ - #include - #include - -+#define SYSCFG_STANDBY_INIT BIT(4) -+#define SYSCFG_SUB_MWAIT_READY BIT(5) -+ - /** - * struct pruss_private_data - PRUSS driver private data - * @has_no_sharedram: flag to indicate the absence of PRUSS Shared Data RAM - * @has_core_mux_clock: flag to indicate the presence of PRUSS core clock -+ * @has_ocp_syscfg: flag to indicate if OCP SYSCFG is present - */ - struct pruss_private_data { - bool has_no_sharedram; - bool has_core_mux_clock; -+ bool has_ocp_syscfg; - }; - - /** -@@ -206,6 +211,72 @@ int pruss_cfg_update(struct pruss *pruss, unsigned int reg, - } - EXPORT_SYMBOL_GPL(pruss_cfg_update); - -+/** -+ * pruss_cfg_ocp_master_ports() - configure PRUSS OCP master ports -+ * @pruss: the pruss instance handle -+ * @enable: set to true for enabling or false for disabling the OCP master ports -+ * -+ * This function programs the PRUSS_SYSCFG.STANDBY_INIT bit either to enable or -+ * disable the OCP master ports (applicable only on SoCs using OCP interconnect -+ * like the OMAP family). Clearing the bit achieves dual functionalities - one -+ * is to deassert the MStandby signal to the device PRCM, and the other is to -+ * enable OCP master ports to allow accesses outside of the PRU-ICSS. The -+ * function has to wait for the PRCM to acknowledge through the monitoring of -+ * the PRUSS_SYSCFG.SUB_MWAIT bit when enabling master ports. Setting the bit -+ * disables the master access, and also signals the PRCM that the PRUSS is ready -+ * for Standby. -+ * -+ * Return: 0 on success, or an error code otherwise. ETIMEDOUT is returned -+ * when the ready-state fails. -+ */ -+int pruss_cfg_ocp_master_ports(struct pruss *pruss, bool enable) -+{ -+ int ret; -+ u32 syscfg_val, i; -+ const struct pruss_private_data *data; -+ -+ if (IS_ERR_OR_NULL(pruss)) -+ return -EINVAL; -+ -+ data = of_device_get_match_data(pruss->dev); -+ -+ /* nothing to do on non OMAP-SoCs */ -+ if (!data || !data->has_ocp_syscfg) -+ return 0; -+ -+ /* assert the MStandby signal during disable path */ -+ if (!enable) -+ return pruss_cfg_update(pruss, PRUSS_CFG_SYSCFG, -+ SYSCFG_STANDBY_INIT, -+ SYSCFG_STANDBY_INIT); -+ -+ /* enable the OCP master ports and disable MStandby */ -+ ret = pruss_cfg_update(pruss, PRUSS_CFG_SYSCFG, SYSCFG_STANDBY_INIT, 0); -+ if (ret) -+ return ret; -+ -+ /* wait till we are ready for transactions - delay is arbitrary */ -+ for (i = 0; i < 10; i++) { -+ ret = pruss_cfg_read(pruss, PRUSS_CFG_SYSCFG, &syscfg_val); -+ if (ret) -+ goto disable; -+ -+ if (!(syscfg_val & SYSCFG_SUB_MWAIT_READY)) -+ return 0; -+ -+ udelay(5); -+ } -+ -+ dev_err(pruss->dev, "timeout waiting for SUB_MWAIT_READY\n"); -+ ret = -ETIMEDOUT; -+ -+disable: -+ pruss_cfg_update(pruss, PRUSS_CFG_SYSCFG, SYSCFG_STANDBY_INIT, -+ SYSCFG_STANDBY_INIT); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(pruss_cfg_ocp_master_ports); -+ - static void pruss_of_free_clk_provider(void *data) - { - struct device_node *clk_mux_np = data; -@@ -497,10 +568,16 @@ static int pruss_remove(struct platform_device *pdev) - /* instance-specific driver private data */ - static const struct pruss_private_data am437x_pruss1_data = { - .has_no_sharedram = false, -+ .has_ocp_syscfg = true, - }; - - static const struct pruss_private_data am437x_pruss0_data = { - .has_no_sharedram = true, -+ .has_ocp_syscfg = false, -+}; -+ -+static const struct pruss_private_data am33xx_am57xx_data = { -+ .has_ocp_syscfg = true, - }; - - static const struct pruss_private_data am65x_j721e_pruss_data = { -@@ -508,10 +585,10 @@ static const struct pruss_private_data am65x_j721e_pruss_data = { - }; - - static const struct of_device_id pruss_of_match[] = { -- { .compatible = "ti,am3356-pruss" }, -+ { .compatible = "ti,am3356-pruss", .data = &am33xx_am57xx_data }, - { .compatible = "ti,am4376-pruss0", .data = &am437x_pruss0_data, }, - { .compatible = "ti,am4376-pruss1", .data = &am437x_pruss1_data, }, -- { .compatible = "ti,am5728-pruss" }, -+ { .compatible = "ti,am5728-pruss", .data = &am33xx_am57xx_data }, - { .compatible = "ti,k2g-pruss" }, - { .compatible = "ti,am654-icssg", .data = &am65x_j721e_pruss_data, }, - { .compatible = "ti,j721e-icssg", .data = &am65x_j721e_pruss_data, }, -diff --git a/include/linux/pruss.h b/include/linux/pruss.h -index ba5b728d5015..5fdd6f03446d 100644 ---- a/include/linux/pruss.h -+++ b/include/linux/pruss.h -@@ -163,6 +163,7 @@ int pruss_release_mem_region(struct pruss *pruss, - int pruss_cfg_read(struct pruss *pruss, unsigned int reg, unsigned int *val); - int pruss_cfg_update(struct pruss *pruss, unsigned int reg, - unsigned int mask, unsigned int val); -+int pruss_cfg_ocp_master_ports(struct pruss *pruss, bool enable); - - #else - -@@ -198,6 +199,11 @@ static inline int pruss_cfg_update(struct pruss *pruss, unsigned int reg, - return -EOPNOTSUPP; - } - -+static inline int pruss_cfg_ocp_master_ports(struct pruss *pruss, bool enable) -+{ -+ return -EOPNOTSUPP; -+} -+ - #endif /* CONFIG_TI_PRUSS */ - - #if IS_ENABLED(CONFIG_PRU_REMOTEPROC) diff --git a/recipes-kernel/linux/files/patches-5.10/0068-soc-ti-pruss-Add-helper-functions-to-get-set-PRUSS_C.patch b/recipes-kernel/linux/files/patches-5.10/0068-soc-ti-pruss-Add-helper-functions-to-get-set-PRUSS_C.patch deleted file mode 100644 index 53617ef17..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0068-soc-ti-pruss-Add-helper-functions-to-get-set-PRUSS_C.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tero Kristo -Date: Sat, 27 Mar 2021 09:24:51 -0500 -Subject: [PATCH] soc: ti: pruss: Add helper functions to get/set - PRUSS_CFG_GPMUX - -Add two new helper functions pruss_cfg_get_gpmux() & pruss_cfg_set_gpmux() -to get and set the GP MUX mode for programming the PRUSS internal wrapper -mux functionality as needed by usecases. - -Co-developed-by: Suman Anna -Signed-off-by: Suman Anna -Signed-off-by: Tero Kristo -Co-developed-by: Grzegorz Jaszczyk -Signed-off-by: Grzegorz Jaszczyk ---- - include/linux/pruss_driver.h | 44 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 44 insertions(+) - -diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h -index f1d1197fd91a..d6abfdd17631 100644 ---- a/include/linux/pruss_driver.h -+++ b/include/linux/pruss_driver.h -@@ -35,4 +35,48 @@ struct pruss { - struct clk *iep_clk_mux; - }; - -+/** -+ * pruss_cfg_get_gpmux() - get the current GPMUX value for a PRU device -+ * @pruss: pruss instance -+ * @pru_id: PRU identifier (0-1) -+ * @mux: pointer to store the current mux value into -+ * -+ * Return: 0 on success, or an error code otherwise -+ */ -+static inline int pruss_cfg_get_gpmux(struct pruss *pruss, -+ enum pruss_pru_id pru_id, u8 *mux) -+{ -+ int ret = 0; -+ u32 val; -+ -+ if (pru_id < 0 || pru_id >= PRUSS_NUM_PRUS) -+ return -EINVAL; -+ -+ ret = pruss_cfg_read(pruss, PRUSS_CFG_GPCFG(pru_id), &val); -+ if (!ret) -+ *mux = (u8)((val & PRUSS_GPCFG_PRU_MUX_SEL_MASK) >> -+ PRUSS_GPCFG_PRU_MUX_SEL_SHIFT); -+ return ret; -+} -+ -+/** -+ * pruss_cfg_set_gpmux() - set the GPMUX value for a PRU device -+ * @pruss: pruss instance -+ * @pru_id: PRU identifier (0-1) -+ * @mux: new mux value for PRU -+ * -+ * Return: 0 on success, or an error code otherwise -+ */ -+static inline int pruss_cfg_set_gpmux(struct pruss *pruss, -+ enum pruss_pru_id pru_id, u8 mux) -+{ -+ if (mux >= PRUSS_GP_MUX_SEL_MAX || -+ pru_id < 0 || pru_id >= PRUSS_NUM_PRUS) -+ return -EINVAL; -+ -+ return pruss_cfg_update(pruss, PRUSS_CFG_GPCFG(pru_id), -+ PRUSS_GPCFG_PRU_MUX_SEL_MASK, -+ (u32)mux << PRUSS_GPCFG_PRU_MUX_SEL_SHIFT); -+} -+ - #endif /* _PRUSS_DRIVER_H_ */ diff --git a/recipes-kernel/linux/files/patches-5.10/0071-HACK-net-ethernet-ti-icss-iep-Fix-sync0-generation-o.patch b/recipes-kernel/linux/files/patches-5.10/0071-HACK-net-ethernet-ti-icss-iep-Fix-sync0-generation-o.patch deleted file mode 100644 index 86b1462b2..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0071-HACK-net-ethernet-ti-icss-iep-Fix-sync0-generation-o.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Lokesh Vutla -Date: Tue, 20 Apr 2021 13:17:31 +0530 -Subject: [PATCH] HACK: net: ethernet: ti: icss-iep: Fix sync0 generation on a - compare event - -commit 41e5c46849b5 ("net: ethernet: ti: icss-iep: Add support for generating -perout/PPS signal for am57xx variant") introduced support for generating -PPS signal using the following method: -- Configure sync0 in single shot mode with 100ms as pulse length. - - This allows to generate a pulse on first compare event after - sync0 is enabled. -- Adjust CMP[1] register to next second boundary on every compare event. - -With this setup only one pulse is created after enabling the pps as -sync0 is configured in single shot mode. In order to create a pulse on -every compare event, sync0 has to be disabled and enabled after the -pulse is completed. There are 2 ways to do it: -- Create a hrtimer task which gets scheduled after completed the pulse. With - this there is a possibility that pulse can be missed, but in current - situation there is not other better way. $patch is implementing this. -- Trigger an interrupt on falling edge of the pulse. But hardware does - not support for this interrupt. - -There are other ways on how sync0 can be configured. Below gives details -on why other approaches are not taken: -- Cyclic generation: Where cycle time & pulse length is configured upfront. - Configuring cycle time upfront is a problem, as - cycle time is in IEP clock cycles and cmp event is - based on the IEP counter with compensation. This - way cmp event and sync0 signal goes out of sync. -- Single shot mode: This is the current implementation. -- Cyclic with Ack mode: Where cycle time is configured upfront. Pulse - width is based on the Ack from software. In case - if this is used, ack should happen in cmp - interrupt handler. In this case, the interrupt - handling and ack is fast enough that most of the - times the pulse is not observed on the scope. -- Single shot with Ack mode: Where cycle length and pulse length is not - fixed. Pulse gets started with first compare - event. Pulse gets low with the ack from - software. This will have the same problem - as single shot mode and cyclic with ack - mode. - -After these experiments, the possible approach is to use Single shot -mode and re-enable sync after every pulse. This patch is using a hrtimer -task for re-enabling sync and that is why it is marked as HACK. - -TODO: Explore if the task can be offloaded to firmware and then revert -this HACK - -Signed-off-by: Lokesh Vutla -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 22 +++++++++++++++++++++- - 1 file changed, 21 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index 234972a034a9..22034d41c988 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -126,6 +126,7 @@ struct icss_iep { - int cap_cmp_irq; - struct ptp_clock_time period; - u32 latch_enable; -+ struct hrtimer sync_timer; - }; - - /** -@@ -539,6 +540,10 @@ static irqreturn_t icss_iep_cap_cmp_handler(int irq, void *dev_id) - pevent.index = index; - ptp_clock_event(iep->ptp_clock, &pevent); - dev_dbg(iep->dev, "IEP:pps ts: %llu\n", ns); -+ -+ hrtimer_start(&iep->sync_timer, ms_to_ktime(110), /* 100ms + buffer */ -+ HRTIMER_MODE_REL); -+ - ret = IRQ_HANDLED; - } - -@@ -664,6 +669,17 @@ static struct ptp_clock_info icss_iep_ptp_info = { - .enable = icss_iep_ptp_enable, - }; - -+static enum hrtimer_restart icss_iep_sync0_work(struct hrtimer *timer) -+{ -+ struct icss_iep *iep = container_of(timer, struct icss_iep, sync_timer); -+ -+ regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0); -+ regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, -+ IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN); -+ -+ return HRTIMER_NORESTART; -+} -+ - struct icss_iep *icss_iep_get(struct device_node *np) - { - struct platform_device *pdev; -@@ -707,6 +723,8 @@ struct icss_iep *icss_iep_get(struct device_node *np) - dev_err(iep->dev, "Request irq failed for cap_cmp %d\n", ret); - goto put_iep_device; - } -+ hrtimer_init(&iep->sync_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ iep->sync_timer.function = icss_iep_sync0_work; - } - - iep->ptp_info = icss_iep_ptp_info; -@@ -734,8 +752,10 @@ void icss_iep_put(struct icss_iep *iep) - iep->client_np = NULL; - device_unlock(iep->dev); - put_device(iep->dev); -- if (iep->cap_cmp_irq) -+ if (iep->cap_cmp_irq) { - free_irq(iep->cap_cmp_irq, iep); -+ hrtimer_cancel(&iep->sync_timer); -+ } - } - EXPORT_SYMBOL_GPL(icss_iep_put); - diff --git a/recipes-kernel/linux/files/patches-5.10/0072-net-ethernet-ti-icss_iep-drop-ICSS_IEP_CAPx_FALL_REG.patch b/recipes-kernel/linux/files/patches-5.10/0072-net-ethernet-ti-icss_iep-drop-ICSS_IEP_CAPx_FALL_REG.patch deleted file mode 100644 index dd1a811c2..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0072-net-ethernet-ti-icss_iep-drop-ICSS_IEP_CAPx_FALL_REG.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Thu, 29 Apr 2021 18:13:28 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: drop ICSS_IEP_CAPx_FALL_REGy - -ICSS_IEP_CAPx_FALL_REGy are not used, but cause indexation issues in -icss_iep_cap_cmp_handler(). -So, drop them for now - can be properly added later if needed. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 15 --------------- - 1 file changed, 15 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index 22034d41c988..60a284c6c0c9 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -65,13 +65,9 @@ enum { - - ICSS_IEP_CAP6_RISE_REG0, - ICSS_IEP_CAP6_RISE_REG1, -- ICSS_IEP_CAP6_FALL_REG0, -- ICSS_IEP_CAP6_FALL_REG1, - - ICSS_IEP_CAP7_RISE_REG0, - ICSS_IEP_CAP7_RISE_REG1, -- ICSS_IEP_CAP7_FALL_REG0, -- ICSS_IEP_CAP7_FALL_REG1, - - ICSS_IEP_CMP_CFG_REG, - ICSS_IEP_CMP_STAT_REG, -@@ -912,13 +908,9 @@ static const struct icss_iep_plat_data am654_icss_iep_plat_data = { - - [ICSS_IEP_CAP6_RISE_REG0] = 0x50, - [ICSS_IEP_CAP6_RISE_REG1] = 0x54, -- [ICSS_IEP_CAP6_FALL_REG0] = 0x58, -- [ICSS_IEP_CAP6_FALL_REG1] = 0x5c, - - [ICSS_IEP_CAP7_RISE_REG0] = 0x60, - [ICSS_IEP_CAP7_RISE_REG1] = 0x64, -- [ICSS_IEP_CAP7_FALL_REG0] = 0x68, -- [ICSS_IEP_CAP7_FALL_REG1] = 0x6c, - - [ICSS_IEP_CMP_CFG_REG] = 0x70, - [ICSS_IEP_CMP_STAT_REG] = 0x74, -@@ -954,13 +946,9 @@ static const struct icss_iep_plat_data am57xx_icss_iep_plat_data = { - - [ICSS_IEP_CAP6_RISE_REG0] = 0x50, - [ICSS_IEP_CAP6_RISE_REG1] = 0x54, -- [ICSS_IEP_CAP6_FALL_REG0] = 0x58, -- [ICSS_IEP_CAP6_FALL_REG1] = 0x5c, - - [ICSS_IEP_CAP7_RISE_REG0] = 0x60, - [ICSS_IEP_CAP7_RISE_REG1] = 0x64, -- [ICSS_IEP_CAP7_FALL_REG0] = 0x68, -- [ICSS_IEP_CAP7_FALL_REG1] = 0x6c, - - [ICSS_IEP_CMP_CFG_REG] = 0x70, - [ICSS_IEP_CMP_STAT_REG] = 0x74, -@@ -987,7 +975,6 @@ static bool am335x_icss_iep_valid_reg(struct device *dev, unsigned int reg) - switch (reg) { - case ICSS_IEP_GLOBAL_CFG_REG ... ICSS_IEP_CAPTURE_STAT_REG: - case ICSS_IEP_CAP6_RISE_REG0: -- case ICSS_IEP_CAP6_FALL_REG0: - case ICSS_IEP_CMP_CFG_REG ... ICSS_IEP_CMP0_REG0: - case ICSS_IEP_CMP8_REG0 ... ICSS_IEP_SYNC_START_REG: - return true; -@@ -1017,10 +1004,8 @@ static const struct icss_iep_plat_data am335x_icss_iep_plat_data = { - [ICSS_IEP_CAPTURE_STAT_REG] = 0x14, - - [ICSS_IEP_CAP6_RISE_REG0] = 0x30, -- [ICSS_IEP_CAP6_FALL_REG0] = 0x34, - - [ICSS_IEP_CAP7_RISE_REG0] = 0x38, -- [ICSS_IEP_CAP7_FALL_REG0] = 0x3C, - - [ICSS_IEP_CMP_CFG_REG] = 0x40, - [ICSS_IEP_CMP_STAT_REG] = 0x44, diff --git a/recipes-kernel/linux/files/patches-5.10/0073-net-ethernet-ti-icss_iep-fix-access-to-x_REG1-in-non.patch b/recipes-kernel/linux/files/patches-5.10/0073-net-ethernet-ti-icss_iep-fix-access-to-x_REG1-in-non.patch deleted file mode 100644 index fd4571b3a..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0073-net-ethernet-ti-icss_iep-fix-access-to-x_REG1-in-non.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Thu, 29 Apr 2021 18:13:29 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: fix access to x_REG1 in non - 64bit mode - -Do not access x_REG1 registers in non 64bit mode. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 27 ++++++++++++++++++--------- - 1 file changed, 18 insertions(+), 9 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index 60a284c6c0c9..73c0a31e8245 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -265,7 +265,8 @@ static void icss_iep_enable_shadow_mode(struct icss_iep *iep, u32 cycle_time_ns) - - /* set CMP0 value to cycle time */ - regmap_write(iep->map, ICSS_IEP_CMP0_REG0, cycle_time); -- regmap_write(iep->map, ICSS_IEP_CMP0_REG1, cycle_time); -+ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) -+ regmap_write(iep->map, ICSS_IEP_CMP0_REG1, cycle_time); - - icss_iep_enable(iep); - } -@@ -427,7 +428,8 @@ static void icss_iep_update_to_next_boundary(struct icss_iep *iep) - ns += p_ns; - - regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(ns)); -- regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(ns)); -+ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) -+ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(ns)); - } - - static int icss_iep_perout_enable_hw(struct icss_iep *iep, -@@ -444,7 +446,8 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep, - if (on) { - /* Configure CMP */ - regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(cmp)); -- regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(cmp)); -+ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) -+ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(cmp)); - /* Configure SYNC */ - regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG, 1000000); /* 1ms pulse width */ - regmap_write(iep->map, ICSS_IEP_SYNC0_PERIOD_REG, 0); -@@ -460,7 +463,8 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep, - - /* clear regs */ - regmap_write(iep->map, ICSS_IEP_CMP1_REG0, 0); -- regmap_write(iep->map, ICSS_IEP_CMP1_REG1, 0); -+ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) -+ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, 0); - } - } else { - if (on) { -@@ -479,7 +483,8 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep, - - /* clear CMP regs */ - regmap_write(iep->map, ICSS_IEP_CMP1_REG0, 0); -- regmap_write(iep->map, ICSS_IEP_CMP1_REG1, 0); -+ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) -+ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, 0); - - /* Disable sync */ - regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0); -@@ -527,8 +532,10 @@ static irqreturn_t icss_iep_cap_cmp_handler(int irq, void *dev_id) - regmap_write(iep->map, ICSS_IEP_CMP_STAT_REG, BIT(CMP_INDEX(index))); - regmap_read(iep->map, ICSS_IEP_CMP1_REG0, &val); - ns = val; -- regmap_read(iep->map, ICSS_IEP_CMP1_REG1, &val); -- ns |= (u64)val << 32; -+ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) { -+ regmap_read(iep->map, ICSS_IEP_CMP1_REG1, &val); -+ ns |= (u64)val << 32; -+ } - icss_iep_update_to_next_boundary(iep); - - pevent.pps_times.ts_real = ns_to_timespec64(ns); -@@ -551,8 +558,10 @@ static irqreturn_t icss_iep_cap_cmp_handler(int irq, void *dev_id) - if (sts & IEP_CAP_CFG_CAPNR_1ST_EVENT_EN(i * 2)) { - regmap_read(iep->map, ICSS_IEP_CAP6_RISE_REG0 + (i * 2), &val); - ns = val; -- regmap_read(iep->map, ICSS_IEP_CAP6_RISE_REG0 + (i * 2) + 1, &val); -- ns |= (u64)val << 32; -+ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) { -+ regmap_read(iep->map, ICSS_IEP_CAP6_RISE_REG0 + (i * 2) + 1, &val); -+ ns |= (u64)val << 32; -+ } - pevent.timestamp = ns; - pevent.type = PTP_CLOCK_EXTTS; - pevent.index = i; diff --git a/recipes-kernel/linux/files/patches-5.10/0074-net-ethernet-ti-icss_iep-disable-extts-and-pps-if-no.patch b/recipes-kernel/linux/files/patches-5.10/0074-net-ethernet-ti-icss_iep-disable-extts-and-pps-if-no.patch deleted file mode 100644 index 5e66ce37e..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0074-net-ethernet-ti-icss_iep-disable-extts-and-pps-if-no.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Thu, 29 Apr 2021 18:13:30 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: disable extts and pps if no slow - compensation or non 64bit mode - -Disable extts and pps if no slow compensation support or non 64bit mode. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index 73c0a31e8245..c0bcb1d1180a 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -734,6 +734,11 @@ struct icss_iep *icss_iep_get(struct device_node *np) - - iep->ptp_info = icss_iep_ptp_info; - -+ -+ if (!(iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) || -+ !(iep->plat_data->flags & ICSS_IEP_SLOW_COMPEN_REG_SUPPORT)) -+ goto exit; -+ - if (iep->cap_cmp_irq || (iep->ops && iep->ops->perout_enable)) { - iep->ptp_info.n_per_out = 1; - iep->ptp_info.pps = 1; -@@ -742,6 +747,7 @@ struct icss_iep *icss_iep_get(struct device_node *np) - if (iep->cap_cmp_irq || (iep->ops && iep->ops->extts_enable)) - iep->ptp_info.n_ext_ts = 2; - -+exit: - return iep; - - put_iep_device: diff --git a/recipes-kernel/linux/files/patches-5.10/0075-net-ethernet-ti-icss_iep-fix-pps-irq-race-vs-pps-dis.patch b/recipes-kernel/linux/files/patches-5.10/0075-net-ethernet-ti-icss_iep-fix-pps-irq-race-vs-pps-dis.patch deleted file mode 100644 index d3f73b84f..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0075-net-ethernet-ti-icss_iep-fix-pps-irq-race-vs-pps-dis.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Thu, 29 Apr 2021 18:13:31 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: fix pps irq race vs pps disable - -When PPS is disabled the PPS IRQ can be running and PPS timer started which -could left IEP HW in undefined, partially configured state. - -Add spin_lock to protect PPS disabling vs PPS IRQ and ensure PPS timer -canceled. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 23 ++++++++++++++++++++++- - 1 file changed, 22 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index c0bcb1d1180a..ead1e7c94021 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -111,6 +111,7 @@ struct icss_iep { - struct ptp_clock_info ptp_info; - struct ptp_clock *ptp_clock; - struct mutex ptp_clk_mutex; /* PHC access serializer */ -+ spinlock_t irq_lock; /* CMP IRQ vs icss_iep_ptp_enable access */ - u32 def_inc; - s16 slow_cmp_inc; - u32 slow_cmp_count; -@@ -497,6 +498,7 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep, - static int icss_iep_perout_enable(struct icss_iep *iep, - struct ptp_perout_request *req, int on) - { -+ unsigned long flags; - int ret = 0; - - mutex_lock(&iep->ptp_clk_mutex); -@@ -509,9 +511,12 @@ static int icss_iep_perout_enable(struct icss_iep *iep, - if (iep->perout_enabled == !!on) - goto exit; - -+ spin_lock_irqsave(&iep->irq_lock, flags); -+ hrtimer_cancel(&iep->sync_timer); - ret = icss_iep_perout_enable_hw(iep, req, on); - if (!ret) - iep->perout_enabled = !!on; -+ spin_unlock_irqrestore(&iep->irq_lock, flags); - - exit: - mutex_unlock(&iep->ptp_clk_mutex); -@@ -525,11 +530,18 @@ static irqreturn_t icss_iep_cap_cmp_handler(int irq, void *dev_id) - unsigned int val, index = 0, i, sts; - struct ptp_clock_event pevent; - irqreturn_t ret = IRQ_NONE; -+ unsigned long flags; - u64 ns; - -+ spin_lock_irqsave(&iep->irq_lock, flags); -+ - regmap_read(iep->map, ICSS_IEP_CMP_STAT_REG, &val); - if (val & BIT(CMP_INDEX(index))) { - regmap_write(iep->map, ICSS_IEP_CMP_STAT_REG, BIT(CMP_INDEX(index))); -+ -+ if (!iep->pps_enabled && !iep->perout_enabled) -+ goto do_latch; -+ - regmap_read(iep->map, ICSS_IEP_CMP1_REG0, &val); - ns = val; - if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) { -@@ -550,9 +562,10 @@ static irqreturn_t icss_iep_cap_cmp_handler(int irq, void *dev_id) - ret = IRQ_HANDLED; - } - -+do_latch: - regmap_read(iep->map, ICSS_IEP_CAPTURE_STAT_REG, &sts); - if (!sts) -- return ret; -+ goto cap_cmp_exit; - - for (i = 0; i < iep->ptp_info.n_ext_ts; i++) { - if (sts & IEP_CAP_CFG_CAPNR_1ST_EVENT_EN(i * 2)) { -@@ -571,6 +584,8 @@ static irqreturn_t icss_iep_cap_cmp_handler(int irq, void *dev_id) - } - } - -+cap_cmp_exit: -+ spin_unlock_irqrestore(&iep->irq_lock, flags); - return ret; - } - -@@ -579,6 +594,7 @@ static int icss_iep_pps_enable(struct icss_iep *iep, int on) - int ret = 0; - struct timespec64 ts; - struct ptp_clock_request rq; -+ unsigned long flags; - u64 ns; - - mutex_lock(&iep->ptp_clk_mutex); -@@ -591,6 +607,8 @@ static int icss_iep_pps_enable(struct icss_iep *iep, int on) - if (iep->pps_enabled == !!on) - goto exit; - -+ spin_lock_irqsave(&iep->irq_lock, flags); -+ - rq.perout.index = 0; - if (on) { - ns = icss_iep_gettime(iep); -@@ -601,12 +619,15 @@ static int icss_iep_pps_enable(struct icss_iep *iep, int on) - rq.perout.start.nsec = 0; - ret = icss_iep_perout_enable_hw(iep, &rq.perout, on); - } else { -+ hrtimer_cancel(&iep->sync_timer); - ret = icss_iep_perout_enable_hw(iep, &rq.perout, on); - } - - if (!ret) - iep->pps_enabled = !!on; - -+ spin_unlock_irqrestore(&iep->irq_lock, flags); -+ - exit: - mutex_unlock(&iep->ptp_clk_mutex); - diff --git a/recipes-kernel/linux/files/patches-5.10/0076-net-ethernet-ti-icss_iep-improve-icss_iep_gettime.patch b/recipes-kernel/linux/files/patches-5.10/0076-net-ethernet-ti-icss_iep-improve-icss_iep_gettime.patch deleted file mode 100644 index 0c65b3f5d..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0076-net-ethernet-ti-icss_iep-improve-icss_iep_gettime.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Thu, 29 Apr 2021 18:13:32 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: improve icss_iep_gettime - -There are few issues with icss_iep_gettime(): -- it has to be very fast, but it's not protected from interruption -- it uses regmap which is very slow for time critial code - -hence, improve it: -- protect it by local_irq_save/restore to avoid interruption and work for -both RT/non-RT kernels -- replace regmap with readl() - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 27 ++++++++++++++++++--------- - 1 file changed, 18 insertions(+), 9 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index ead1e7c94021..cbec01328a71 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -126,6 +126,11 @@ struct icss_iep { - struct hrtimer sync_timer; - }; - -+static u32 icss_iep_readl(struct icss_iep *iep, int reg) -+{ -+ return readl(iep->base + iep->plat_data->reg_offs[reg]); -+} -+ - /** - * icss_iep_get_count_hi() - Get the upper 32 bit IEP counter - * @iep: Pointer to structure representing IEP. -@@ -193,20 +198,24 @@ static void icss_iep_settime(struct icss_iep *iep, u64 ns) - - static u64 icss_iep_gettime(struct icss_iep *iep) - { -- u64 val; -- u32 tmp; -+ u32 ts_hi = 0, ts_lo; -+ unsigned long flags; - - if (iep->ops && iep->ops->gettime) - return iep->ops->gettime(iep->clockops_data); - -- regmap_read(iep->map, ICSS_IEP_COUNT_REG0, &tmp); -- val = tmp; -- if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) { -- regmap_read(iep->map, ICSS_IEP_COUNT_REG1, &tmp); -- val |= (u64)tmp << 32; -- } -+ /* use local_irq_x() to make it work for both RT/non-RT */ -+ local_irq_save(flags); - -- return val; -+ /* no need to play with hi-lo, hi is latched when lo is read */ -+ ts_lo = icss_iep_readl(iep, ICSS_IEP_COUNT_REG0); -+ -+ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) -+ ts_hi = icss_iep_readl(iep, ICSS_IEP_COUNT_REG1); -+ -+ local_irq_restore(flags); -+ -+ return (u64)ts_lo | (u64)ts_hi << 32; - } - - static void icss_iep_enable(struct icss_iep *iep) diff --git a/recipes-kernel/linux/files/patches-5.10/0077-net-ethernet-ti-icss_iep-simplify-peroutput-processi.patch b/recipes-kernel/linux/files/patches-5.10/0077-net-ethernet-ti-icss_iep-simplify-peroutput-processi.patch deleted file mode 100644 index 898856e62..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0077-net-ethernet-ti-icss_iep-simplify-peroutput-processi.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Thu, 29 Apr 2021 18:13:33 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: simplify peroutput processing - -simplify peroutput processing - -- There is no need to perform any kind of calculations during CMP -IRQ processing as there is slow compensation in place which handles -frequency adjustment, so just shift next CMP value. -- The periodic output enabling should take into account start time -requested by caller -- The period of periodic output can be saved in 'ns'. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 40 +++++++++++++++++++----------- - 1 file changed, 26 insertions(+), 14 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index cbec01328a71..b39d4c08c6c9 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -121,7 +121,7 @@ struct icss_iep { - u32 perout_enabled; - bool pps_enabled; - int cap_cmp_irq; -- struct ptp_clock_time period; -+ u64 period; - u32 latch_enable; - struct hrtimer sync_timer; - }; -@@ -422,24 +422,26 @@ static int icss_iep_ptp_settime(struct ptp_clock_info *ptp, - return 0; - } - --static void icss_iep_update_to_next_boundary(struct icss_iep *iep) -+static void icss_iep_update_to_next_boundary(struct icss_iep *iep, u64 start_ns) - { - u64 ns, p_ns; - u32 offset; - - ns = icss_iep_gettime(iep); -- p_ns = ((u64)iep->period.sec * NSEC_PER_SEC) + iep->period.nsec; -+ if (start_ns < ns) -+ start_ns = ns; -+ p_ns = iep->period; - /* Round up to next period boundary */ -- ns += p_ns - 1; -- offset = do_div(ns, p_ns); -- ns = ns * p_ns; -+ start_ns += p_ns - 1; -+ offset = do_div(start_ns, p_ns); -+ start_ns = start_ns * p_ns; - /* If it is too close to update, shift to next boundary */ - if (p_ns - offset < 10) -- ns += p_ns; -+ start_ns += p_ns; - -- regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(ns)); -+ regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(start_ns)); - if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) -- regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(ns)); -+ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(start_ns)); - } - - static int icss_iep_perout_enable_hw(struct icss_iep *iep, -@@ -478,8 +480,14 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep, - } - } else { - if (on) { -- iep->period = req->period; -- icss_iep_update_to_next_boundary(iep); -+ u64 start_ns; -+ -+ iep->period = ((u64)req->period.sec * NSEC_PER_SEC) + -+ req->period.nsec; -+ start_ns = ((u64)req->period.sec * NSEC_PER_SEC) -+ + req->period.nsec; -+ icss_iep_update_to_next_boundary(iep, start_ns); -+ - /* Enable Sync in single shot mode */ - regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, - IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN); -@@ -540,7 +548,7 @@ static irqreturn_t icss_iep_cap_cmp_handler(int irq, void *dev_id) - struct ptp_clock_event pevent; - irqreturn_t ret = IRQ_NONE; - unsigned long flags; -- u64 ns; -+ u64 ns, ns_next; - - spin_lock_irqsave(&iep->irq_lock, flags); - -@@ -557,13 +565,17 @@ static irqreturn_t icss_iep_cap_cmp_handler(int irq, void *dev_id) - regmap_read(iep->map, ICSS_IEP_CMP1_REG1, &val); - ns |= (u64)val << 32; - } -- icss_iep_update_to_next_boundary(iep); -+ /* set next event */ -+ ns_next = ns + iep->period; -+ regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(ns_next)); -+ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) -+ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(ns_next)); - - pevent.pps_times.ts_real = ns_to_timespec64(ns); - pevent.type = PTP_CLOCK_PPSUSR; - pevent.index = index; - ptp_clock_event(iep->ptp_clock, &pevent); -- dev_dbg(iep->dev, "IEP:pps ts: %llu\n", ns); -+ dev_dbg(iep->dev, "IEP:pps ts: %llu next:%llu:\n", ns, ns_next); - - hrtimer_start(&iep->sync_timer, ms_to_ktime(110), /* 100ms + buffer */ - HRTIMER_MODE_REL); diff --git a/recipes-kernel/linux/files/patches-5.10/0078-net-ethernet-ti-icss_iep-use-readl-writel-in-cap_cmp.patch b/recipes-kernel/linux/files/patches-5.10/0078-net-ethernet-ti-icss_iep-use-readl-writel-in-cap_cmp.patch deleted file mode 100644 index c6269ecc0..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0078-net-ethernet-ti-icss_iep-use-readl-writel-in-cap_cmp.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Thu, 29 Apr 2021 18:13:34 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: use readl/writel in - cap_cmp_handler - -Use readl/writel in cap_cmp_handler and timer handler instead of regmap -which is too slow. - -Also, clean up SYNC ststus in timer handler. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 37 +++++++++++++++++++----------- - 1 file changed, 23 insertions(+), 14 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index b39d4c08c6c9..e2663dd5cf38 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -131,6 +131,11 @@ static u32 icss_iep_readl(struct icss_iep *iep, int reg) - return readl(iep->base + iep->plat_data->reg_offs[reg]); - } - -+static void icss_iep_writel(struct icss_iep *iep, int reg, u32 val) -+{ -+ return writel(val, iep->base + iep->plat_data->reg_offs[reg]); -+} -+ - /** - * icss_iep_get_count_hi() - Get the upper 32 bit IEP counter - * @iep: Pointer to structure representing IEP. -@@ -552,24 +557,26 @@ static irqreturn_t icss_iep_cap_cmp_handler(int irq, void *dev_id) - - spin_lock_irqsave(&iep->irq_lock, flags); - -- regmap_read(iep->map, ICSS_IEP_CMP_STAT_REG, &val); -+ val = icss_iep_readl(iep, ICSS_IEP_CMP_STAT_REG); - if (val & BIT(CMP_INDEX(index))) { -- regmap_write(iep->map, ICSS_IEP_CMP_STAT_REG, BIT(CMP_INDEX(index))); -+ icss_iep_writel(iep, ICSS_IEP_CMP_STAT_REG, -+ BIT(CMP_INDEX(index))); - - if (!iep->pps_enabled && !iep->perout_enabled) - goto do_latch; - -- regmap_read(iep->map, ICSS_IEP_CMP1_REG0, &val); -- ns = val; -+ ns = icss_iep_readl(iep, ICSS_IEP_CMP1_REG0); - if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) { -- regmap_read(iep->map, ICSS_IEP_CMP1_REG1, &val); -+ val = icss_iep_readl(iep, ICSS_IEP_CMP1_REG1); - ns |= (u64)val << 32; - } - /* set next event */ - ns_next = ns + iep->period; -- regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(ns_next)); -+ icss_iep_writel(iep, ICSS_IEP_CMP1_REG0, -+ lower_32_bits(ns_next)); - if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) -- regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(ns_next)); -+ icss_iep_writel(iep, ICSS_IEP_CMP1_REG1, -+ upper_32_bits(ns_next)); - - pevent.pps_times.ts_real = ns_to_timespec64(ns); - pevent.type = PTP_CLOCK_PPSUSR; -@@ -584,16 +591,17 @@ static irqreturn_t icss_iep_cap_cmp_handler(int irq, void *dev_id) - } - - do_latch: -- regmap_read(iep->map, ICSS_IEP_CAPTURE_STAT_REG, &sts); -+ sts = icss_iep_readl(iep, ICSS_IEP_CAPTURE_STAT_REG); - if (!sts) - goto cap_cmp_exit; - - for (i = 0; i < iep->ptp_info.n_ext_ts; i++) { - if (sts & IEP_CAP_CFG_CAPNR_1ST_EVENT_EN(i * 2)) { -- regmap_read(iep->map, ICSS_IEP_CAP6_RISE_REG0 + (i * 2), &val); -- ns = val; -+ ns = icss_iep_readl(iep, -+ ICSS_IEP_CAP6_RISE_REG0 + (i * 2)); - if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) { -- regmap_read(iep->map, ICSS_IEP_CAP6_RISE_REG0 + (i * 2) + 1, &val); -+ val = icss_iep_readl(iep, -+ ICSS_IEP_CAP6_RISE_REG0 + (i * 2) + 1); - ns |= (u64)val << 32; - } - pevent.timestamp = ns; -@@ -720,9 +728,10 @@ static enum hrtimer_restart icss_iep_sync0_work(struct hrtimer *timer) - { - struct icss_iep *iep = container_of(timer, struct icss_iep, sync_timer); - -- regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0); -- regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, -- IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN); -+ icss_iep_writel(iep, ICSS_IEP_SYNC_CTRL_REG, 0); -+ icss_iep_writel(iep, ICSS_IEP_SYNC_CTRL_REG, -+ IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN); -+ icss_iep_writel(iep, ICSS_IEP_SYNC0_STAT_REG, 1); - - return HRTIMER_NORESTART; - } diff --git a/recipes-kernel/linux/files/patches-5.10/0079-net-ethernet-ti-icss_iep-switch-to-.gettimex64.patch b/recipes-kernel/linux/files/patches-5.10/0079-net-ethernet-ti-icss_iep-switch-to-.gettimex64.patch deleted file mode 100644 index 86475bd1f..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0079-net-ethernet-ti-icss_iep-switch-to-.gettimex64.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Thu, 29 Apr 2021 18:13:35 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: switch to .gettimex64() - -The .gettime64() is deprecated by commit 916444df305e ("ptp: deprecate -gettime64() in favor of gettimex64()"). - -Hence switch IEP driver to use .gettimex64(). - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 21 ++++++++++++--------- - 1 file changed, 12 insertions(+), 9 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index e2663dd5cf38..c0497b448d68 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -201,7 +201,8 @@ static void icss_iep_settime(struct icss_iep *iep, u64 ns) - icss_iep_set_counter(iep, ns); - } - --static u64 icss_iep_gettime(struct icss_iep *iep) -+static u64 icss_iep_gettime(struct icss_iep *iep, -+ struct ptp_system_timestamp *sts) - { - u32 ts_hi = 0, ts_lo; - unsigned long flags; -@@ -213,8 +214,9 @@ static u64 icss_iep_gettime(struct icss_iep *iep) - local_irq_save(flags); - - /* no need to play with hi-lo, hi is latched when lo is read */ -+ ptp_read_system_prets(sts); - ts_lo = icss_iep_readl(iep, ICSS_IEP_COUNT_REG0); -- -+ ptp_read_system_postts(sts); - if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) - ts_hi = icss_iep_readl(iep, ICSS_IEP_COUNT_REG1); - -@@ -390,7 +392,7 @@ static int icss_iep_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) - if (iep->ops && iep->ops->adjtime) { - iep->ops->adjtime(iep->clockops_data, delta); - } else { -- ns = icss_iep_gettime(iep); -+ ns = icss_iep_gettime(iep, NULL); - ns += delta; - icss_iep_settime(iep, ns); - } -@@ -399,14 +401,15 @@ static int icss_iep_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) - return 0; - } - --static int icss_iep_ptp_gettime(struct ptp_clock_info *ptp, -- struct timespec64 *ts) -+static int icss_iep_ptp_gettimeex(struct ptp_clock_info *ptp, -+ struct timespec64 *ts, -+ struct ptp_system_timestamp *sts) - { - struct icss_iep *iep = container_of(ptp, struct icss_iep, ptp_info); - u64 ns; - - mutex_lock(&iep->ptp_clk_mutex); -- ns = icss_iep_gettime(iep); -+ ns = icss_iep_gettime(iep, sts); - *ts = ns_to_timespec64(ns); - mutex_unlock(&iep->ptp_clk_mutex); - -@@ -432,7 +435,7 @@ static void icss_iep_update_to_next_boundary(struct icss_iep *iep, u64 start_ns) - u64 ns, p_ns; - u32 offset; - -- ns = icss_iep_gettime(iep); -+ ns = icss_iep_gettime(iep, NULL); - if (start_ns < ns) - start_ns = ns; - p_ns = iep->period; -@@ -640,7 +643,7 @@ static int icss_iep_pps_enable(struct icss_iep *iep, int on) - - rq.perout.index = 0; - if (on) { -- ns = icss_iep_gettime(iep); -+ ns = icss_iep_gettime(iep, NULL); - ts = ns_to_timespec64(ns); - rq.perout.period.sec = 1; - rq.perout.period.nsec = 0; -@@ -719,7 +722,7 @@ static struct ptp_clock_info icss_iep_ptp_info = { - .max_adj = 10000000, - .adjfreq = icss_iep_ptp_adjfreq, - .adjtime = icss_iep_ptp_adjtime, -- .gettime64 = icss_iep_ptp_gettime, -+ .gettimex64 = icss_iep_ptp_gettimeex, - .settime64 = icss_iep_ptp_settime, - .enable = icss_iep_ptp_enable, - }; diff --git a/recipes-kernel/linux/files/patches-5.10/0080-net-ethernet-ti-icss_iep-Update-compare-registers-af.patch b/recipes-kernel/linux/files/patches-5.10/0080-net-ethernet-ti-icss_iep-Update-compare-registers-af.patch deleted file mode 100644 index 6b64301b2..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0080-net-ethernet-ti-icss_iep-Update-compare-registers-af.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Lokesh Vutla -Date: Thu, 29 Apr 2021 18:13:36 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: Update compare registers after - changing ptp clock time - -Consider the scenario where PPS is enabled, then iep set_time or adjust_time is -called with time deviation that is > PPS period. In this scenario there -is a possibility that PPS stopped as IEP compare registers are not -updated but the counter registers are updated and counter value can -never be matched with compare value. - -To avoid this scenario, update the compare registers when set/adjust -time is called. - -Signed-off-by: Lokesh Vutla -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 19 +++++++++++++++++-- - 1 file changed, 17 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index c0497b448d68..8bad9c86775a 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -187,18 +187,33 @@ EXPORT_SYMBOL_GPL(icss_iep_get_ptp_clock_idx); - static void icss_iep_set_counter(struct icss_iep *iep, u64 ns) - { - if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) -- regmap_write(iep->map, ICSS_IEP_COUNT_REG1, upper_32_bits(ns)); -- regmap_write(iep->map, ICSS_IEP_COUNT_REG0, lower_32_bits(ns)); -+ icss_iep_writel(iep, ICSS_IEP_COUNT_REG1, upper_32_bits(ns)); -+ icss_iep_writel(iep, ICSS_IEP_COUNT_REG0, lower_32_bits(ns)); - } - -+static void icss_iep_update_to_next_boundary(struct icss_iep *iep, u64 start_ns); -+ - static void icss_iep_settime(struct icss_iep *iep, u64 ns) - { -+ unsigned long flags; -+ - if (iep->ops && iep->ops->settime) { - iep->ops->settime(iep->clockops_data, ns); - return; - } - -+ spin_lock_irqsave(&iep->irq_lock, flags); -+ if (iep->pps_enabled || iep->perout_enabled) -+ icss_iep_writel(iep, ICSS_IEP_SYNC_CTRL_REG, 0); -+ - icss_iep_set_counter(iep, ns); -+ -+ if (iep->pps_enabled || iep->perout_enabled) { -+ icss_iep_update_to_next_boundary(iep, ns); -+ icss_iep_writel(iep, ICSS_IEP_SYNC_CTRL_REG, -+ IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN); -+ } -+ spin_unlock_irqrestore(&iep->irq_lock, flags); - } - - static u64 icss_iep_gettime(struct icss_iep *iep, diff --git a/recipes-kernel/linux/files/patches-5.10/0081-net-ethernet-ti-icss_iep-request-cmp_cap-irq-from-pr.patch b/recipes-kernel/linux/files/patches-5.10/0081-net-ethernet-ti-icss_iep-request-cmp_cap-irq-from-pr.patch deleted file mode 100644 index 1e634dd6f..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0081-net-ethernet-ti-icss_iep-request-cmp_cap-irq-from-pr.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Thu, 29 Apr 2021 18:13:37 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: request cmp_cap irq from probe - -The current INTC design allows to define IEP cmp_cap IRQ explicitly for IEP -device, so it can be requested from probe and do not have dependencies from -FW any more. - -So move IEP cmp_cap IRQ request in probe. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 42 ++++++++++++++---------------- - 1 file changed, 19 insertions(+), 23 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index 8bad9c86775a..df74b5fd17e9 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -759,7 +759,6 @@ struct icss_iep *icss_iep_get(struct device_node *np) - struct platform_device *pdev; - struct device_node *iep_np; - struct icss_iep *iep; -- int ret; - - iep_np = of_parse_phandle(np, "iep", 0); - if (!iep_np || !of_device_is_available(iep_np)) -@@ -787,20 +786,6 @@ struct icss_iep *icss_iep_get(struct device_node *np) - device_unlock(iep->dev); - get_device(iep->dev); - -- iep->cap_cmp_irq = of_irq_get_byname(np, "iep_cap_cmp"); -- if (iep->cap_cmp_irq < 0) { -- iep->cap_cmp_irq = 0; -- } else { -- ret = request_irq(iep->cap_cmp_irq, icss_iep_cap_cmp_handler, IRQF_TRIGGER_HIGH, -- "iep_cap_cmp", iep); -- if (ret) { -- dev_err(iep->dev, "Request irq failed for cap_cmp %d\n", ret); -- goto put_iep_device; -- } -- hrtimer_init(&iep->sync_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -- iep->sync_timer.function = icss_iep_sync0_work; -- } -- - iep->ptp_info = icss_iep_ptp_info; - - -@@ -818,11 +803,6 @@ struct icss_iep *icss_iep_get(struct device_node *np) - - exit: - return iep; -- --put_iep_device: -- put_device(iep->dev); -- -- return ERR_PTR(ret); - } - EXPORT_SYMBOL_GPL(icss_iep_get); - -@@ -832,10 +812,8 @@ void icss_iep_put(struct icss_iep *iep) - iep->client_np = NULL; - device_unlock(iep->dev); - put_device(iep->dev); -- if (iep->cap_cmp_irq) { -- free_irq(iep->cap_cmp_irq, iep); -+ if (iep->cap_cmp_irq) - hrtimer_cancel(&iep->sync_timer); -- } - } - EXPORT_SYMBOL_GPL(icss_iep_put); - -@@ -901,6 +879,7 @@ static int icss_iep_probe(struct platform_device *pdev) - struct icss_iep *iep; - struct resource *res; - struct clk *iep_clk; -+ int ret; - - iep = devm_kzalloc(dev, sizeof(*iep), GFP_KERNEL); - if (!iep) -@@ -912,6 +891,23 @@ static int icss_iep_probe(struct platform_device *pdev) - if (IS_ERR(iep->base)) - return -ENODEV; - -+ iep->cap_cmp_irq = platform_get_irq_byname_optional(pdev, "iep_cap_cmp"); -+ if (iep->cap_cmp_irq < 0) { -+ if (iep->cap_cmp_irq == -EPROBE_DEFER) -+ return iep->cap_cmp_irq; -+ iep->cap_cmp_irq = 0; -+ } else { -+ ret = devm_request_irq(dev, iep->cap_cmp_irq, -+ icss_iep_cap_cmp_handler, IRQF_TRIGGER_HIGH, -+ "iep_cap_cmp", iep); -+ if (ret) { -+ dev_err(iep->dev, "Request irq failed for cap_cmp %d\n", ret); -+ return ret; -+ } -+ hrtimer_init(&iep->sync_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ iep->sync_timer.function = icss_iep_sync0_work; -+ } -+ - iep_clk = devm_clk_get(dev, NULL); - if (IS_ERR(iep_clk)) - return PTR_ERR(iep_clk); diff --git a/recipes-kernel/linux/files/patches-5.10/0082-net-ethernet-ti-icss_iep-set-phc-time-to-system-time.patch b/recipes-kernel/linux/files/patches-5.10/0082-net-ethernet-ti-icss_iep-set-phc-time-to-system-time.patch deleted file mode 100644 index 2cd4aae01..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0082-net-ethernet-ti-icss_iep-set-phc-time-to-system-time.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Thu, 29 Apr 2021 18:13:38 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: set phc time to system time on - init - -Following customer feedback IEP PHC time has to be set to system time on -init to avoid clock jumps between local PHC clocks in case they are -synchronized to each other. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index df74b5fd17e9..08b456f0bc12 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -844,7 +844,7 @@ int icss_iep_init(struct icss_iep *iep, const struct icss_iep_clockops *clkops, - icss_iep_enable(iep); - - iep->cycle_time_ns = cycle_time_ns; -- icss_iep_set_counter(iep, 0); -+ icss_iep_set_counter(iep, ktime_get_real_ns()); - - iep->clk_tick_time = def_inc; - diff --git a/recipes-kernel/linux/files/patches-5.10/0083-net-ethernet-ti-icss_iep-use-devm_platform_ioremap_r.patch b/recipes-kernel/linux/files/patches-5.10/0083-net-ethernet-ti-icss_iep-use-devm_platform_ioremap_r.patch deleted file mode 100644 index dca5a4e9e..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0083-net-ethernet-ti-icss_iep-use-devm_platform_ioremap_r.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Thu, 29 Apr 2021 18:13:39 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: use - devm_platform_ioremap_resource - -Use devm_platform_ioremap_resource() in probe to simplify code. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index 08b456f0bc12..640f483854d0 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -877,7 +877,6 @@ static int icss_iep_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; - struct icss_iep *iep; -- struct resource *res; - struct clk *iep_clk; - int ret; - -@@ -886,8 +885,7 @@ static int icss_iep_probe(struct platform_device *pdev) - return -ENOMEM; - - iep->dev = dev; -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- iep->base = devm_ioremap_resource(dev, res); -+ iep->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(iep->base)) - return -ENODEV; - diff --git a/recipes-kernel/linux/files/patches-5.10/0085-dt-bindings-net-Add-binding-for-ti-icssg-prueth-devi.patch b/recipes-kernel/linux/files/patches-5.10/0085-dt-bindings-net-Add-binding-for-ti-icssg-prueth-devi.patch deleted file mode 100644 index 140dfe16f..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0085-dt-bindings-net-Add-binding-for-ti-icssg-prueth-devi.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Roger Quadros -Date: Tue, 18 May 2021 23:37:22 +0300 -Subject: [PATCH] dt-bindings: net: Add binding for ti,icssg-prueth device - -This is the DT binding document for the ICSSG Dual-EMAC Ethernet -device. - -SR2.0 support: -We need to specify PRU handle and firmware for TX_PRU, configure -ICSS gp-mux in Linux and provide TX timestamp IRQ. -IEP is now optional for the emac nodes. -Also update the example to reflect SR2.0 case. - -Signed-off-by: Roger Quadros -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - .../bindings/net/ti,icssg-prueth.txt | 121 ++++++++++++++++++ - 1 file changed, 121 insertions(+) - create mode 100644 Documentation/devicetree/bindings/net/ti,icssg-prueth.txt - -diff --git a/Documentation/devicetree/bindings/net/ti,icssg-prueth.txt b/Documentation/devicetree/bindings/net/ti,icssg-prueth.txt -new file mode 100644 -index 000000000000..67609e26afa5 ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/ti,icssg-prueth.txt -@@ -0,0 +1,121 @@ -+Texas Instruments ICSSG PRUSS Ethernet -+====================================== -+ -+Required properties: -+- compatible : Should be "ti,am654-icssg-prueth" for AM65x Family SoCs -+ "ti,am654-icssg-prueth-sr1" for SR1.0 -+- ti,prus : list of pHandles to the PRU, RTU and TX_PRU nodes -+- firmware-name : should contain the name of the firmware image -+ file located in the firmware search path -+- sram : phandle to MSMC SRAM node -+- dmas : list of phandles and specifiers to UDMA as specified in -+ bindings/dma/ti/k3-udma.txt. -+- dma-names : Names for the DMA channels. -+ Should be "tx0-0", "tx0-1", "tx0-2", "0-3", -+ "tx1-0", "tx1-1", "tx1-2", "tx1-3", -+ "rx0", "rx1", "rxmgm0", "rxmgm1" -+- mii-g-rt : phandle to MII_G_RT module's syscon regmap. -+- mii-rt : phandle to MII_RT module's syscon regmap. -+- ti,pruss-gp-mux-sel : GP-MUX value required for both ports. -+- iep : list of pHandles to the to IEP modules -+- interrupts : (SR2.0 only) Interrupt specifiers to TX timestamp IRQ. -+- interrupt-names : "tx_ts0", "tx_ts1" -+ -+Must contain children, one for each of the MAC ports. -+Children must be named ethernet-mii0 and ethernet-mii1. -+Either one or both children can be present. If only one -+child is present driver operates in single EMAC mode. -+ -+For single mode operation with the 2nd SLICE, you still need -+to provide both PRUs and RTUs and firmware-names but the firmware-name -+for the first PRU & RTU can be NULL. -+ -+Required properties for children: -+- phy-handle : See ethernet.txt file in the same directory. -+- phy-mode : See ethernet.txt file in the same directory. -+- syscon-rgmii-delay : phandle to system controller node and register offset -+ to ICSSG control register for RGMII transmit delay. -+ -+Optional properties for children: -+- local-mac-address : mac address for the port. -+ -+Example (k3-am654 base board SR2.0, dual-emac): -+============================================== -+ -+ /* Dual Ethernet application node on PRU-ICSSG2 */ -+ pruss2_eth: pruss2_eth { -+ compatible = "ti,am654-icssg-prueth"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&icssg2_rgmii_pins_default>; -+ sram = <&msmc_ram>; -+ -+ prus = <&pru2_0>, <&rtu2_0>, <&tx_pru2_0>, <&pru2_1>, <&rtu2_1>, <&tx_pru2_1>; -+ firmware-name = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf", -+ "ti-pruss/am65x-sr2-rtu0-prueth-fw.elf", -+ "ti-pruss/am65x-sr2-txpru0-prueth-fw.elf", -+ "ti-pruss/am65x-sr2-pru1-prueth-fw.elf", -+ "ti-pruss/am65x-sr2-rtu1-prueth-fw.elf", -+ "ti-pruss/am65x-sr2-txpru1-prueth-fw.elf"; -+ ti,pruss-gp-mux-sel = <2>, /* MII mode */ -+ <2>, -+ <2>, -+ <2>, /* MII mode */ -+ <2>, -+ <2>; -+ mii-g-rt = <&icssg2_mii_g_rt>; -+ dma-coherent; -+ dmas = <&main_udmap 0xc300>, /* egress slice 0 */ -+ <&main_udmap 0xc301>, /* egress slice 0 */ -+ <&main_udmap 0xc302>, /* egress slice 0 */ -+ <&main_udmap 0xc303>, /* egress slice 0 */ -+ <&main_udmap 0xc304>, /* egress slice 1 */ -+ <&main_udmap 0xc305>, /* egress slice 1 */ -+ <&main_udmap 0xc306>, /* egress slice 1 */ -+ <&main_udmap 0xc307>, /* egress slice 1 */ -+ -+ <&main_udmap 0x4300>, /* ingress slice 0 */ -+ <&main_udmap 0x4301>, /* ingress slice 1 */ -+ <&main_udmap 0x4302>, /* mgmnt rsp slice 0 */ -+ <&main_udmap 0x4303>; /* mgmnt rsp slice 1 */ -+ dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3", -+ "tx1-0", "tx1-1", "tx1-2", "tx1-3", -+ "rx0", "rx1", -+ "rxmgm0", "rxmgm1"; -+ -+ pruss2_emac0: ethernet-mii0 { -+ phy-handle = <&pruss2_eth0_phy>; -+ phy-mode = "rgmii-rxid"; -+ interrupts-extended = <&icssg2_intc 24>; -+ syscon-rgmii-delay = <&scm_conf 0x4120>; -+ iep = <&icssg2_iep0>; -+ /* Filled in by bootloader */ -+ local-mac-address = [00 00 00 00 00 00]; -+ }; -+ -+ pruss2_emac1: ethernet-mii1 { -+ phy-handle = <&pruss2_eth1_phy>; -+ phy-mode = "rgmii-rxid"; -+ interrupts-extended = <&icssg2_intc 25>; -+ syscon-rgmii-delay = <&scm_conf 0x4124>; -+ /* Filled in by bootloader */ -+ local-mac-address = [00 00 00 00 00 00]; -+ }; -+ }; -+ -+ &icssg2_mdio { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&icssg2_mdio_pins_default>; -+ -+ pruss2_eth0_phy: ethernet-phy@0 { -+ reg = <0>; -+ ti,rx-internal-delay = ; -+ ti,fifo-depth = ; -+ }; -+ -+ pruss2_eth1_phy: ethernet-phy@3 { -+ reg = <3>; -+ ti,rx-internal-delay = ; -+ ti,fifo-depth = ; -+ }; -+ }; diff --git a/recipes-kernel/linux/files/patches-5.10/0086-net-ti-icssg-prueth-Add-ICSSG-ethernet-driver.patch b/recipes-kernel/linux/files/patches-5.10/0086-net-ti-icssg-prueth-Add-ICSSG-ethernet-driver.patch deleted file mode 100644 index e0a6f3a58..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0086-net-ti-icssg-prueth-Add-ICSSG-ethernet-driver.patch +++ /dev/null @@ -1,4498 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Roger Quadros -Date: Tue, 18 May 2021 23:37:23 +0300 -Subject: [PATCH] net: ti: icssg-prueth: Add ICSSG ethernet driver - -This is the Ethernet driver for TI SoCs with the -ICSSG PRU Sub-system running dual-EMAC firmware. - -Changes in SR2.0 firmware: -- TX_PRU core added -- Config mechanism has changed. ICSSG Hardware queue module -- DMEM registers are used to provide initial configuration. -- ICSSG Hardwre queue module is used to send commands to firmware -and obtain the TX timestamp. Configuration over management channel -is not required. -- IEP made optional as now only 1 port can use IEP. -- IEP operation has changed. 32-bit shadow mode is used instead -of 64-bit mode. DMEM registers needs to be used to calculate -ns timestamp along with IEP count register. - -For SR1.0 the only change is that IEP node is now optional for each port. -This patch addresses those while maintaining compatibility with SR1.0 -firmware. - -SR2.0 firmware doesn't use FT1 for multicast filtering. Add separate -ndo_set_rx_mode for SR2.0. Firmware must be told if all multicast packets -are to be allowed using commands. Add those. - -MultiQ support: -In the Tx/Egress direction, ICSSG firmware has 8 internal strict -priority queues that are used to queue the frames received from the -Host. However there are only 4 PSI threads/channels from host to ICSSG -which are equivalent to hw queue definition of Linux. So implement 4 -hw queues in the Egress direction using netdev multiq framework for -SR2 of ICSSG. -SR1 ICSSG firmware support 3 Egress data channels and 1 management -channel. So extend the multiq support for SR1 and implement 3 -hwqueues at the Egress. Management channel number used is highest -data channel number + 1. Ethtool -l command will show maximum -of 3 hwqueues for Egress that can be configured by user. - -Add MAC address to FT1 slot 0: -This is required by firmware to deal with Source Address Violation -for zero address for example if one of the ports has MAC address -set to 0 (e.g. when only one port was brought up). -Without this f/w drops packets containing zero address even if -promiscuous mode is enabled. - -Enable XFR mode for PRU and RTU: -This is required by firmware for proper operation. - -This includes the following commits from ti-5.4 - net: ethernet: ti: icssg_prueth: Fix PHY supported/advertised modes - net: ethernet: ti: icssg_prueth: fix irqs type - net: ethernet: ti: icssg_prueth: Support SR2.0 - net: ethernet: ti: icssg_prueth: use lkml dma desc pool api - net: ethernet: ti: icssg_prueth: update swich_map.h - net: ethernet: ti: icssg_prueth: use ERR_PTR check for mac address - net: ethernet: ti: icssg_prueth: TIMESYNC registers in SHRDRAM2 - net: ethernet: ti: icssg_prueth: move R30 management to DRAM interface - net: ethernet: ti: icssg_prueth: remove 60 byte padding workaround - net: ethernet: ti: icssg_prueth: fix rx_mgm_chn cleanup on SR1 - net: ethernet: ti: icssg_prueth: remove unused lock variable in chan struct - net: ethernet: ti: icssg_prueth: add multiq support for SR2 - net: ethernet: ti: icssg_prueth: re-arrange functions to avoid declaration - net: ethernet: ti: icssg_prueth: extend multiq support for SR1 - net: ethernet: ti: icssg_prueth: add ethtool support to change num hwqueues - net: ethernet: ti: icssg_prueth: do phy_start() at the end - net: ethernet: ti: icssg_prueth: IRQ related cleanup - net: ethernet: ti: icssg_prueth: Re-use RX channel prepare code - net: ethernet: ti: icssg_prueth: cleanup TX/RX channels on error - net: ethernet: ti: icssg_prueth: Add MAC address to FT1 slot 0 - net: ethernet: ti: icssg_prueth: Fix promiscuous/allmulti for SR2.0 - net: ethernet: ti: icssg_prueth: enable XFR mode for PRU and RTU - net: ethernet: ti: icssg_prueth: Fix warnings when built with W=1 C=1 - -Signed-off-by: Roger Quadros -Co-developed-by: Murali Karicheri -Signed-off-by: Murali Karicheri -Co-developed-by: Grygorii Strashko -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra -[Jan: rebased over upstream, included icss_mii_rt.h] -Signed-off-by: Jan Kiszka ---- - drivers/net/ethernet/ti/Kconfig | 12 + - drivers/net/ethernet/ti/Makefile | 3 + - drivers/net/ethernet/ti/icss_mii_rt.h | 194 ++ - drivers/net/ethernet/ti/icssg_classifier.c | 463 ++++ - drivers/net/ethernet/ti/icssg_config.c | 412 ++++ - drivers/net/ethernet/ti/icssg_config.h | 192 ++ - drivers/net/ethernet/ti/icssg_ethtool.c | 335 +++ - drivers/net/ethernet/ti/icssg_prueth.c | 2226 ++++++++++++++++++++ - drivers/net/ethernet/ti/icssg_prueth.h | 253 +++ - drivers/net/ethernet/ti/icssg_queues.c | 50 + - drivers/net/ethernet/ti/icssg_switch_map.h | 163 ++ - include/linux/pruss.h | 4 +- - 12 files changed, 4306 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/ethernet/ti/icss_mii_rt.h - create mode 100644 drivers/net/ethernet/ti/icssg_classifier.c - create mode 100644 drivers/net/ethernet/ti/icssg_config.c - create mode 100644 drivers/net/ethernet/ti/icssg_config.h - create mode 100644 drivers/net/ethernet/ti/icssg_ethtool.c - create mode 100644 drivers/net/ethernet/ti/icssg_prueth.c - create mode 100644 drivers/net/ethernet/ti/icssg_prueth.h - create mode 100644 drivers/net/ethernet/ti/icssg_queues.c - create mode 100644 drivers/net/ethernet/ti/icssg_switch_map.h - -diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig -index bf497da88814..f17df3b25dd0 100644 ---- a/drivers/net/ethernet/ti/Kconfig -+++ b/drivers/net/ethernet/ti/Kconfig -@@ -179,4 +179,16 @@ config TI_ICSS_IEP - This enables support for the PRU-ICSS Industrial Ethernet Peripheral - within a PRU-ICSS subsystem present on various TI SoCs. - -+config TI_ICSSG_PRUETH -+ tristate "TI Gigabit PRU Ethernet driver" -+ select TI_DAVINCI_MDIO -+ select NET_PTP_CLASSIFY -+ select TI_ICSS_IEP -+ imply PTP_1588_CLOCK -+ depends on PRU_REMOTEPROC -+ depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER -+ help -+ Support dual Gigabit Ethernet ports over the ICSSG PRU Subsystem -+ This subsystem is available starting with the AM65 platform. -+ - endif # NET_VENDOR_TI -diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile -index ec94422a572f..5f99e7b48103 100644 ---- a/drivers/net/ethernet/ti/Makefile -+++ b/drivers/net/ethernet/ti/Makefile -@@ -29,3 +29,6 @@ ti-am65-cpsw-nuss-y := am65-cpsw-nuss.o cpsw_sl.o am65-cpsw-ethtool.o cpsw_ale.o - obj-$(CONFIG_TI_K3_AM65_CPTS) += am65-cpts.o - - obj-$(CONFIG_TI_ICSS_IEP) += icss_iep.o -+ -+obj-$(CONFIG_TI_ICSSG_PRUETH) += icssg-prueth.o -+icssg-prueth-y := icssg_prueth.o icssg_classifier.o icssg_ethtool.o icssg_queues.o icssg_config.o k3-cppi-desc-pool.o -diff --git a/drivers/net/ethernet/ti/icss_mii_rt.h b/drivers/net/ethernet/ti/icss_mii_rt.h -new file mode 100644 -index 000000000000..a7643bb46b9d ---- /dev/null -+++ b/drivers/net/ethernet/ti/icss_mii_rt.h -@@ -0,0 +1,194 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+/* PRU-ICSS MII_RT register definitions -+ * -+ * Copyright (C) 2015-2021 Texas Instruments Incorporated - https://www.ti.com -+ */ -+ -+#ifndef __NET_PRUSS_MII_RT_H__ -+#define __NET_PRUSS_MII_RT_H__ -+ -+/* PRUSS_MII_RT Registers */ -+#define PRUSS_MII_RT_RXCFG0 0x0 -+#define PRUSS_MII_RT_RXCFG1 0x4 -+#define PRUSS_MII_RT_TXCFG0 0x10 -+#define PRUSS_MII_RT_TXCFG1 0x14 -+#define PRUSS_MII_RT_TX_CRC0 0x20 -+#define PRUSS_MII_RT_TX_CRC1 0x24 -+#define PRUSS_MII_RT_TX_IPG0 0x30 -+#define PRUSS_MII_RT_TX_IPG1 0x34 -+#define PRUSS_MII_RT_PRS0 0x38 -+#define PRUSS_MII_RT_PRS1 0x3c -+#define PRUSS_MII_RT_RX_FRMS0 0x40 -+#define PRUSS_MII_RT_RX_FRMS1 0x44 -+#define PRUSS_MII_RT_RX_PCNT0 0x48 -+#define PRUSS_MII_RT_RX_PCNT1 0x4c -+#define PRUSS_MII_RT_RX_ERR0 0x50 -+#define PRUSS_MII_RT_RX_ERR1 0x54 -+ -+/* PRUSS_MII_RT_RXCFG0/1 bits */ -+#define PRUSS_MII_RT_RXCFG_RX_ENABLE BIT(0) -+#define PRUSS_MII_RT_RXCFG_RX_DATA_RDY_MODE_DIS BIT(1) -+#define PRUSS_MII_RT_RXCFG_RX_CUT_PREAMBLE BIT(2) -+#define PRUSS_MII_RT_RXCFG_RX_MUX_SEL BIT(3) -+#define PRUSS_MII_RT_RXCFG_RX_L2_EN BIT(4) -+#define PRUSS_MII_RT_RXCFG_RX_BYTE_SWAP BIT(5) -+#define PRUSS_MII_RT_RXCFG_RX_AUTO_FWD_PRE BIT(6) -+#define PRUSS_MII_RT_RXCFG_RX_L2_EOF_SCLR_DIS BIT(9) -+ -+/* PRUSS_MII_RT_TXCFG0/1 bits */ -+#define PRUSS_MII_RT_TXCFG_TX_ENABLE BIT(0) -+#define PRUSS_MII_RT_TXCFG_TX_AUTO_PREAMBLE BIT(1) -+#define PRUSS_MII_RT_TXCFG_TX_EN_MODE BIT(2) -+#define PRUSS_MII_RT_TXCFG_TX_BYTE_SWAP BIT(3) -+#define PRUSS_MII_RT_TXCFG_TX_MUX_SEL BIT(8) -+#define PRUSS_MII_RT_TXCFG_PRE_TX_AUTO_SEQUENCE BIT(9) -+#define PRUSS_MII_RT_TXCFG_PRE_TX_AUTO_ESC_ERR BIT(10) -+#define PRUSS_MII_RT_TXCFG_TX_32_MODE_EN BIT(11) -+#define PRUSS_MII_RT_TXCFG_TX_IPG_WIRE_CLK_EN BIT(12) /* SR2.0 onwards */ -+ -+#define PRUSS_MII_RT_TXCFG_TX_START_DELAY_SHIFT 16 -+#define PRUSS_MII_RT_TXCFG_TX_START_DELAY_MASK GENMASK(25, 16) -+ -+#define PRUSS_MII_RT_TXCFG_TX_CLK_DELAY_SHIFT 28 -+#define PRUSS_MII_RT_TXCFG_TX_CLK_DELAY_MASK GENMASK(30, 28) -+ -+/* PRUSS_MII_RT_TX_IPG0/1 bits */ -+#define PRUSS_MII_RT_TX_IPG_IPG_SHIFT 0 -+#define PRUSS_MII_RT_TX_IPG_IPG_MASK GENMASK(9, 0) -+ -+/* PRUSS_MII_RT_PRS0/1 bits */ -+#define PRUSS_MII_RT_PRS_COL BIT(0) -+#define PRUSS_MII_RT_PRS_CRS BIT(1) -+ -+/* PRUSS_MII_RT_RX_FRMS0/1 bits */ -+#define PRUSS_MII_RT_RX_FRMS_MIN_FRM_SHIFT 0 -+#define PRUSS_MII_RT_RX_FRMS_MIN_FRM_MASK GENMASK(15, 0) -+ -+#define PRUSS_MII_RT_RX_FRMS_MAX_FRM_SHIFT 16 -+#define PRUSS_MII_RT_RX_FRMS_MAX_FRM_MASK GENMASK(31, 16) -+ -+/* PRUSS_MII_RT_RX_PCNT0/1 bits */ -+#define PRUSS_MII_RT_RX_PCNT_MIN_PCNT_SHIFT 0 -+#define PRUSS_MII_RT_RX_PCNT_MIN_PCNT_MASK GENMASK(3, 0) -+ -+#define PRUSS_MII_RT_RX_PCNT_MAX_PCNT_SHIFT 4 -+#define PRUSS_MII_RT_RX_PCNT_MAX_PCNT_MASK GENMASK(7, 4) -+ -+/* PRUSS_MII_RT_RX_ERR0/1 bits */ -+#define PRUSS_MII_RT_RX_ERR_MIN_PCNT_ERR BIT(0) -+#define PRUSS_MII_RT_RX_ERR_MAX_PCNT_ERR BIT(1) -+#define PRUSS_MII_RT_RX_ERR_MIN_FRM_ERR BIT(2) -+#define PRUSS_MII_RT_RX_ERR_MAX_FRM_ERR BIT(3) -+ -+#define ICSSG_CFG_OFFSET 0 -+#define RGMII_CFG_OFFSET 4 -+ -+/* Constant to choose between MII0 and MII1 */ -+#define ICSS_MII0 0 -+#define ICSS_MII1 1 -+ -+/* ICSSG_CFG Register bits */ -+#define ICSSG_CFG_SGMII_MODE BIT(16) -+#define ICSSG_CFG_TX_PRU_EN BIT(11) -+#define ICSSG_CFG_RX_SFD_TX_SOF_EN BIT(10) -+#define ICSSG_CFG_RTU_PRU_PSI_SHARE_EN BIT(9) -+#define ICSSG_CFG_IEP1_TX_EN BIT(8) -+#define ICSSG_CFG_MII1_MODE GENMASK(6, 5) -+#define ICSSG_CFG_MII1_MODE_SHIFT 5 -+#define ICSSG_CFG_MII0_MODE GENMASK(4, 3) -+#define ICSSG_CFG_MII0_MODE_SHIFT 3 -+#define ICSSG_CFG_RX_L2_G_EN BIT(2) -+#define ICSSG_CFG_TX_L2_EN BIT(1) -+#define ICSSG_CFG_TX_L1_EN BIT(0) -+ -+enum mii_mode { MII_MODE_MII = 0, MII_MODE_RGMII, MII_MODE_SGMII }; -+ -+/* RGMII CFG Register bits */ -+#define RGMII_CFG_GIG_EN_MII0 BIT(17) -+#define RGMII_CFG_GIG_EN_MII1 BIT(21) -+#define RGMII_CFG_FULL_DUPLEX_MII0 BIT(18) -+#define RGMII_CFG_FULL_DUPLEX_MII1 BIT(22) -+#define RGMII_CFG_SPEED_MII0 GENMASK(2, 1) -+#define RGMII_CFG_SPEED_MII1 GENMASK(6, 5) -+#define RGMII_CFG_SPEED_MII0_SHIFT 1 -+#define RGMII_CFG_SPEED_MII1_SHIFT 5 -+#define RGMII_CFG_FULLDUPLEX_MII0 BIT(3) -+#define RGMII_CFG_FULLDUPLEX_MII1 BIT(7) -+#define RGMII_CFG_FULLDUPLEX_MII0_SHIFT 3 -+#define RGMII_CFG_FULLDUPLEX_MII1_SHIFT 7 -+#define RGMII_CFG_SPEED_10M 0 -+#define RGMII_CFG_SPEED_100M 1 -+#define RGMII_CFG_SPEED_1G 2 -+ -+static inline void icssg_mii_update_ipg(struct regmap *mii_rt, int mii, u32 ipg) -+{ -+ u32 val; -+ -+ if (mii == ICSS_MII0) { -+ regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG0, ipg); -+ } else { -+ /* Errata workaround: IEP1 is not read by h/w unless IEP0 is written */ -+ regmap_read(mii_rt, PRUSS_MII_RT_TX_IPG0, &val); -+ regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG1, ipg); -+ regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG0, val); -+ } -+} -+ -+static inline void icssg_update_rgmii_cfg(struct regmap *miig_rt, bool gig_en, -+ bool full_duplex, int mii) -+{ -+ u32 gig_en_mask, gig_val = 0, full_duplex_mask, full_duplex_val = 0; -+ -+ gig_en_mask = (mii == ICSS_MII0) ? RGMII_CFG_GIG_EN_MII0 : -+ RGMII_CFG_GIG_EN_MII1; -+ if (gig_en) -+ gig_val = gig_en_mask; -+ regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, gig_en_mask, gig_val); -+ -+ full_duplex_mask = (mii == ICSS_MII0) ? RGMII_CFG_FULL_DUPLEX_MII0 : -+ RGMII_CFG_FULL_DUPLEX_MII1; -+ if (full_duplex) -+ full_duplex_val = full_duplex_mask; -+ regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, full_duplex_mask, -+ full_duplex_val); -+} -+ -+static inline u32 icssg_rgmii_cfg_get_bitfield(struct regmap *miig_rt, -+ u32 mask, u32 shift) -+{ -+ u32 val; -+ -+ regmap_read(miig_rt, RGMII_CFG_OFFSET, &val); -+ val &= mask; -+ val >>= shift; -+ -+ return val; -+} -+ -+static inline u32 icssg_rgmii_get_speed(struct regmap *miig_rt, int mii) -+{ -+ u32 shift = RGMII_CFG_SPEED_MII0_SHIFT, mask = RGMII_CFG_SPEED_MII0; -+ -+ if (mii == ICSS_MII1) { -+ shift = RGMII_CFG_SPEED_MII1_SHIFT; -+ mask = RGMII_CFG_SPEED_MII1; -+ } -+ -+ return icssg_rgmii_cfg_get_bitfield(miig_rt, mask, shift); -+} -+ -+static inline u32 icssg_rgmii_get_fullduplex(struct regmap *miig_rt, int mii) -+{ -+ u32 shift = RGMII_CFG_FULLDUPLEX_MII0_SHIFT; -+ u32 mask = RGMII_CFG_FULLDUPLEX_MII0; -+ -+ if (mii == ICSS_MII1) { -+ shift = RGMII_CFG_FULLDUPLEX_MII1_SHIFT; -+ mask = RGMII_CFG_FULLDUPLEX_MII1; -+ } -+ -+ return icssg_rgmii_cfg_get_bitfield(miig_rt, mask, shift); -+} -+ -+#endif /* __NET_PRUSS_MII_RT_H__ */ -diff --git a/drivers/net/ethernet/ti/icssg_classifier.c b/drivers/net/ethernet/ti/icssg_classifier.c -new file mode 100644 -index 000000000000..ea9a1c7bb0fe ---- /dev/null -+++ b/drivers/net/ethernet/ti/icssg_classifier.c -@@ -0,0 +1,463 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* Texas Instruments ICSSG Ethernet Driver -+ * -+ * Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/ -+ * -+ */ -+ -+#include -+#include -+#include -+ -+#include "icssg_prueth.h" -+ -+#define ICSSG_NUM_CLASSIFIERS 16 -+#define ICSSG_NUM_FT1_SLOTS 8 -+#define ICSSG_NUM_FT3_SLOTS 16 -+ -+#define ICSSG_NUM_CLASSIFIERS_IN_USE 5 -+ -+/* Filter 1 - FT1 */ -+#define FT1_NUM_SLOTS 8 -+#define FT1_SLOT_SIZE 0x10 /* bytes */ -+ -+/* offsets from FT1 slot base i.e. slot 1 start */ -+#define FT1_DA0 0x0 -+#define FT1_DA1 0x4 -+#define FT1_DA0_MASK 0x8 -+#define FT1_DA1_MASK 0xc -+ -+#define FT1_N_REG(slize, n, reg) (offs[slice].ft1_slot_base + FT1_SLOT_SIZE * (n) + (reg)) -+ -+#define FT1_LEN_MASK GENMASK(19, 16) -+#define FT1_LEN_SHIFT 16 -+#define FT1_LEN(len) (((len) << FT1_LEN_SHIFT) & FT1_LEN_MASK) -+ -+#define FT1_START_MASK GENMASK(14, 0) -+#define FT1_START(start) ((start) & FT1_START_MASK) -+ -+#define FT1_MATCH_SLOT(n) (GENMASK(23, 16) & (BIT(n) << 16)) -+ -+enum ft1_cfg_type { -+ FT1_CFG_TYPE_DISABLED = 0, -+ FT1_CFG_TYPE_EQ, -+ FT1_CFG_TYPE_GT, -+ FT1_CFG_TYPE_LT, -+}; -+ -+#define FT1_CFG_SHIFT(n) (2 * (n)) -+#define FT1_CFG_MASK(n) (0x3 << FT1_CFG_SHIFT((n))) -+ -+/* Filter 3 - FT3 */ -+#define FT3_NUM_SLOTS 16 -+#define FT3_SLOT_SIZE 0x20 /* bytes */ -+ -+/* offsets from FT3 slot n's base */ -+#define FT3_START 0 -+#define FT3_START_AUTO 0x4 -+#define FT3_START_OFFSET 0x8 -+#define FT3_JUMP_OFFSET 0xc -+#define FT3_LEN 0x10 -+#define FT3_CFG 0x14 -+#define FT3_T 0x18 -+#define FT3_T_MASK 0x1c -+ -+#define FT3_N_REG(slize, n, reg) (offs[slice].ft3_slot_base + FT3_SLOT_SIZE * (n) + (reg)) -+ -+/* offsets from rx_class n's base */ -+#define RX_CLASS_AND_EN 0 -+#define RX_CLASS_OR_EN 0x4 -+ -+#define RX_CLASS_NUM_SLOTS 16 -+#define RX_CLASS_EN_SIZE 0x8 /* bytes */ -+ -+#define RX_CLASS_N_REG(slice, n, reg) (offs[slice].rx_class_base + RX_CLASS_EN_SIZE * (n) + (reg)) -+ -+/* RX Class Gates */ -+#define RX_CLASS_GATES_SIZE 0x4 /* bytes */ -+ -+#define RX_CLASS_GATES_N_REG(slice, n) \ -+ (offs[slice].rx_class_gates_base + RX_CLASS_GATES_SIZE * (n)) -+ -+#define RX_CLASS_GATES_ALLOW_MASK BIT(6) -+#define RX_CLASS_GATES_RAW_MASK BIT(5) -+#define RX_CLASS_GATES_PHASE_MASK BIT(4) -+ -+/* RX Class traffic data matching bits */ -+#define RX_CLASS_FT_UC BIT(31) -+#define RX_CLASS_FT_MC BIT(30) -+#define RX_CLASS_FT_BC BIT(29) -+#define RX_CLASS_FT_FW BIT(28) -+#define RX_CLASS_FT_RCV BIT(27) -+#define RX_CLASS_FT_VLAN BIT(26) -+#define RX_CLASS_FT_DA_P BIT(25) -+#define RX_CLASS_FT_DA_I BIT(24) -+#define RX_CLASS_FT_FT1_MATCH_MASK GENMASK(23, 16) -+#define RX_CLASS_FT_FT1_MATCH_SHIFT 16 -+#define RX_CLASS_FT_FT3_MATCH_MASK GENMASK(15, 0) -+#define RX_CLASS_FT_FT3_MATCH_SHIFT 0 -+ -+#define RX_CLASS_FT_FT1_MATCH(slot) \ -+ ((BIT(slot) << RX_CLASS_FT_FT1_MATCH_SHIFT) & RX_CLASS_FT_FT1_MATCH_MASK) -+ -+enum rx_class_sel_type { -+ RX_CLASS_SEL_TYPE_OR = 0, -+ RX_CLASS_SEL_TYPE_AND = 1, -+ RX_CLASS_SEL_TYPE_OR_AND_AND = 2, -+ RX_CLASS_SEL_TYPE_OR_OR_AND = 3, -+}; -+ -+#define FT1_CFG_SHIFT(n) (2 * (n)) -+#define FT1_CFG_MASK(n) (0x3 << FT1_CFG_SHIFT((n))) -+ -+#define RX_CLASS_SEL_SHIFT(n) (2 * (n)) -+#define RX_CLASS_SEL_MASK(n) (0x3 << RX_CLASS_SEL_SHIFT((n))) -+ -+#define ICSSG_CFG_OFFSET 0 -+ -+#define ICSSG_CFG_RX_L2_G_EN BIT(2) -+ -+/* these are register offsets per PRU */ -+struct miig_rt_offsets { -+ u32 mac0; -+ u32 mac1; -+ u32 ft1_start_len; -+ u32 ft1_cfg; -+ u32 ft1_slot_base; -+ u32 ft3_slot_base; -+ u32 ft3_p_base; -+ u32 ft_rx_ptr; -+ u32 rx_class_base; -+ u32 rx_class_cfg1; -+ u32 rx_class_cfg2; -+ u32 rx_class_gates_base; -+ u32 rx_green; -+ u32 rx_rate_cfg_base; -+ u32 rx_rate_src_sel0; -+ u32 rx_rate_src_sel1; -+ u32 tx_rate_cfg_base; -+ u32 stat_base; -+ u32 tx_hsr_tag; -+ u32 tx_hsr_seq; -+ u32 tx_vlan_type; -+ u32 tx_vlan_ins; -+}; -+ -+static struct miig_rt_offsets offs[] = { -+ /* PRU0 */ -+ { -+ 0x8, -+ 0xc, -+ 0x80, -+ 0x84, -+ 0x88, -+ 0x108, -+ 0x308, -+ 0x408, -+ 0x40c, -+ 0x48c, -+ 0x490, -+ 0x494, -+ 0x4d4, -+ 0x4e4, -+ 0x504, -+ 0x508, -+ 0x50c, -+ 0x54c, -+ 0x63c, -+ 0x640, -+ 0x644, -+ 0x648, -+ }, -+ /* PRU1 */ -+ { -+ 0x10, -+ 0x14, -+ 0x64c, -+ 0x650, -+ 0x654, -+ 0x6d4, -+ 0x8d4, -+ 0x9d4, -+ 0x9d8, -+ 0xa58, -+ 0xa5c, -+ 0xa60, -+ 0xaa0, -+ 0xab0, -+ 0xad0, -+ 0xad4, -+ 0xad8, -+ 0xb18, -+ 0xc08, -+ 0xc0c, -+ 0xc10, -+ 0xc14, -+ }, -+}; -+ -+static inline u32 addr_to_da0(const u8 *addr) -+{ -+ return (u32)(addr[0] | addr[1] << 8 | -+ addr[2] << 16 | addr[3] << 24); -+}; -+ -+static inline u32 addr_to_da1(const u8 *addr) -+{ -+ return (u32)(addr[4] | addr[5] << 8); -+}; -+ -+static void rx_class_ft1_set_start_len(struct regmap *miig_rt, int slice, -+ u16 start, u8 len) -+{ -+ u32 offset, val; -+ -+ offset = offs[slice].ft1_start_len; -+ val = FT1_LEN(len) | FT1_START(start); -+ regmap_write(miig_rt, offset, val); -+} -+ -+static void rx_class_ft1_set_da(struct regmap *miig_rt, int slice, -+ int n, const u8 *addr) -+{ -+ u32 offset; -+ -+ offset = FT1_N_REG(slice, n, FT1_DA0); -+ regmap_write(miig_rt, offset, addr_to_da0(addr)); -+ offset = FT1_N_REG(slice, n, FT1_DA1); -+ regmap_write(miig_rt, offset, addr_to_da1(addr)); -+} -+ -+static void rx_class_ft1_set_da_mask(struct regmap *miig_rt, int slice, -+ int n, const u8 *addr) -+{ -+ u32 offset; -+ -+ offset = FT1_N_REG(slice, n, FT1_DA0_MASK); -+ regmap_write(miig_rt, offset, addr_to_da0(addr)); -+ offset = FT1_N_REG(slice, n, FT1_DA1_MASK); -+ regmap_write(miig_rt, offset, addr_to_da1(addr)); -+} -+ -+static void rx_class_ft1_cfg_set_type(struct regmap *miig_rt, int slice, int n, -+ enum ft1_cfg_type type) -+{ -+ u32 offset; -+ -+ offset = offs[slice].ft1_cfg; -+ regmap_update_bits(miig_rt, offset, FT1_CFG_MASK(n), -+ type << FT1_CFG_SHIFT(n)); -+} -+ -+static void rx_class_sel_set_type(struct regmap *miig_rt, int slice, int n, -+ enum rx_class_sel_type type) -+{ -+ u32 offset; -+ -+ offset = offs[slice].rx_class_cfg1; -+ regmap_update_bits(miig_rt, offset, RX_CLASS_SEL_MASK(n), -+ type << RX_CLASS_SEL_SHIFT(n)); -+} -+ -+static void rx_class_set_and(struct regmap *miig_rt, int slice, int n, -+ u32 data) -+{ -+ u32 offset; -+ -+ offset = RX_CLASS_N_REG(slice, n, RX_CLASS_AND_EN); -+ regmap_write(miig_rt, offset, data); -+} -+ -+static void rx_class_set_or(struct regmap *miig_rt, int slice, int n, -+ u32 data) -+{ -+ u32 offset; -+ -+ offset = RX_CLASS_N_REG(slice, n, RX_CLASS_OR_EN); -+ regmap_write(miig_rt, offset, data); -+} -+ -+static u32 rx_class_get_or(struct regmap *miig_rt, int slice, int n) -+{ -+ u32 offset, val; -+ -+ offset = RX_CLASS_N_REG(slice, n, RX_CLASS_OR_EN); -+ regmap_read(miig_rt, offset, &val); -+ -+ return val; -+} -+ -+void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac) -+{ -+ regmap_write(miig_rt, offs[slice].mac0, addr_to_da0(mac)); -+ regmap_write(miig_rt, offs[slice].mac1, addr_to_da1(mac)); -+} -+ -+static void icssg_class_ft1_add_mcast(struct regmap *miig_rt, int slice, -+ int slot, const u8 *addr, const u8 *mask) -+{ -+ int i; -+ u32 val; -+ -+ WARN(slot >= FT1_NUM_SLOTS, "invalid slot: %d\n", slot); -+ -+ rx_class_ft1_set_da(miig_rt, slice, slot, addr); -+ rx_class_ft1_set_da_mask(miig_rt, slice, slot, mask); -+ rx_class_ft1_cfg_set_type(miig_rt, slice, slot, FT1_CFG_TYPE_EQ); -+ -+ /* Enable the FT1 slot in OR enable for all classifiers */ -+ for (i = 0; i < ICSSG_NUM_CLASSIFIERS_IN_USE; i++) { -+ val = rx_class_get_or(miig_rt, slice, i); -+ val |= RX_CLASS_FT_FT1_MATCH(slot); -+ rx_class_set_or(miig_rt, slice, i, val); -+ } -+} -+ -+/* disable all RX traffic */ -+void icssg_class_disable(struct regmap *miig_rt, int slice) -+{ -+ u32 data, offset; -+ int n; -+ -+ /* Enable RX_L2_G */ -+ regmap_update_bits(miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_RX_L2_G_EN, -+ ICSSG_CFG_RX_L2_G_EN); -+ -+ for (n = 0; n < ICSSG_NUM_CLASSIFIERS; n++) { -+ /* AND_EN = 0 */ -+ rx_class_set_and(miig_rt, slice, n, 0); -+ /* OR_EN = 0 */ -+ rx_class_set_or(miig_rt, slice, n, 0); -+ -+ /* set CFG1 to OR */ -+ rx_class_sel_set_type(miig_rt, slice, n, RX_CLASS_SEL_TYPE_OR); -+ -+ /* configure gate */ -+ offset = RX_CLASS_GATES_N_REG(slice, n); -+ regmap_read(miig_rt, offset, &data); -+ /* clear class_raw so we go through filters */ -+ data &= ~RX_CLASS_GATES_RAW_MASK; -+ /* set allow and phase mask */ -+ data |= RX_CLASS_GATES_ALLOW_MASK | RX_CLASS_GATES_PHASE_MASK; -+ regmap_write(miig_rt, offset, data); -+ } -+ -+ /* FT1 Disabled */ -+ for (n = 0; n < ICSSG_NUM_FT1_SLOTS; n++) { -+ u8 addr[] = { 0, 0, 0, 0, 0, 0, }; -+ -+ rx_class_ft1_cfg_set_type(miig_rt, slice, n, -+ FT1_CFG_TYPE_DISABLED); -+ rx_class_ft1_set_da(miig_rt, slice, n, addr); -+ rx_class_ft1_set_da_mask(miig_rt, slice, n, addr); -+ } -+ -+ /* clear CFG2 */ -+ regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0); -+} -+ -+void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti, -+ bool is_sr1) -+{ -+ u32 data; -+ int n; -+ int classifiers_in_use = ICSSG_NUM_CLASSIFIERS_IN_USE; -+ -+ if (!is_sr1) -+ classifiers_in_use = 1; -+ -+ /* defaults */ -+ icssg_class_disable(miig_rt, slice); -+ -+ /* Setup Classifier */ -+ for (n = 0; n < classifiers_in_use; n++) { -+ /* match on Broadcast or MAC_PRU address */ -+ data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P; -+ -+ /* multicast? */ -+ if (allmulti) -+ data |= RX_CLASS_FT_MC; -+ -+ rx_class_set_or(miig_rt, slice, n, data); -+ -+ /* set CFG1 for OR_OR_AND for classifier */ -+ rx_class_sel_set_type(miig_rt, slice, n, -+ RX_CLASS_SEL_TYPE_OR_OR_AND); -+ } -+ -+ /* clear CFG2 */ -+ regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0); -+} -+ -+void icssg_class_promiscuous_sr1(struct regmap *miig_rt, int slice) -+{ -+ u32 data; -+ u32 offset; -+ int n; -+ -+ /* defaults */ -+ icssg_class_disable(miig_rt, slice); -+ -+ /* Setup Classifier */ -+ for (n = 0; n < ICSSG_NUM_CLASSIFIERS_IN_USE; n++) { -+ /* set RAW_MASK to bypass filters */ -+ offset = RX_CLASS_GATES_N_REG(slice, n); -+ regmap_read(miig_rt, offset, &data); -+ data |= RX_CLASS_GATES_RAW_MASK; -+ regmap_write(miig_rt, offset, data); -+ } -+} -+ -+void icssg_class_add_mcast_sr1(struct regmap *miig_rt, int slice, -+ struct net_device *ndev) -+{ -+ int slot; -+ struct netdev_hw_addr *ha; -+ u8 sr_addr[] = { 0x01, 0x80, 0xC2, 0, 0, 0, }; -+ u8 cb_addr[] = { 0x01, 0x00, 0x5e, 0, 0, 0, }; -+ u8 mask_addr[] = { 0, 0, 0, 0, 0, 0, }; -+ -+ rx_class_ft1_set_start_len(miig_rt, slice, 0, 6); -+ /* reserve first 2 slots for -+ * 1) 01-80-C2-00-00-XX Known Service Ethernet Multicast addresses -+ * 2) 01-00-5e-00-00-XX Local Network Control Block -+ * (224.0.0.0 - 224.0.0.255 (224.0.0/24)) -+ */ -+ mask_addr[5] = 0xff; -+ icssg_class_ft1_add_mcast(miig_rt, slice, 0, sr_addr, mask_addr); -+ icssg_class_ft1_add_mcast(miig_rt, slice, 1, cb_addr, mask_addr); -+ mask_addr[5] = 0; -+ slot = 2; -+ netdev_for_each_mc_addr(ha, ndev) { -+ /* skip addresses matching reserved slots */ -+ if (!memcmp(sr_addr, ha->addr, 5) || -+ !memcmp(cb_addr, ha->addr, 5)) { -+ netdev_dbg(ndev, "mcast skip %pM\n", ha->addr); -+ continue; -+ } -+ -+ if (slot >= FT1_NUM_SLOTS) { -+ netdev_dbg(ndev, -+ "can't add more than %d MC addresses, enabling allmulti\n", -+ FT1_NUM_SLOTS); -+ icssg_class_default(miig_rt, slice, 1, 1); -+ break; -+ } -+ -+ netdev_dbg(ndev, "mcast add %pM\n", ha->addr); -+ icssg_class_ft1_add_mcast(miig_rt, slice, slot, -+ ha->addr, mask_addr); -+ slot++; -+ } -+} -+ -+/* required for SR2 for SAV check */ -+void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr) -+{ -+ u8 mask_addr[] = { 0, 0, 0, 0, 0, 0, }; -+ -+ rx_class_ft1_set_start_len(miig_rt, slice, 0, 6); -+ rx_class_ft1_set_da(miig_rt, slice, 0, mac_addr); -+ rx_class_ft1_set_da_mask(miig_rt, slice, 0, mask_addr); -+ rx_class_ft1_cfg_set_type(miig_rt, slice, 0, FT1_CFG_TYPE_EQ); -+} -diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c -new file mode 100644 -index 000000000000..3f0ab061e0e6 ---- /dev/null -+++ b/drivers/net/ethernet/ti/icssg_config.c -@@ -0,0 +1,412 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* ICSSG Ethernet driver -+ * -+ * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com -+ */ -+ -+#include -+#include "icssg_config.h" -+#include "icssg_prueth.h" -+#include "icssg_switch_map.h" -+#include "icss_mii_rt.h" -+ -+/* TX IPG Values to be set for 100M and 1G link speeds. These values are -+ * in ocp_clk cycles. So need change if ocp_clk is changed for a specific -+ * h/w design. -+ */ -+ -+/* SR1.0 IPG is in core_clk cycles */ -+#define MII_RT_TX_IPG_100M_SR1 0x166 -+#define MII_RT_TX_IPG_1G_SR1 0x18 -+ -+/* SR2.0 IPG is in rgmii_clk (125MHz) clock cycles + 1 */ -+#define MII_RT_TX_IPG_100M 0xb2 /* FIXME: cross check */ -+#define MII_RT_TX_IPG_1G 0xb -+ -+#define ICSSG_QUEUES_MAX 64 -+#define ICSSG_QUEUE_OFFSET 0xd00 -+#define ICSSG_QUEUE_PEEK_OFFSET 0xe00 -+#define ICSSG_QUEUE_CNT_OFFSET 0xe40 -+#define ICSSG_QUEUE_RESET_OFFSET 0xf40 -+ -+#define ICSSG_NUM_TX_QUEUES 8 -+ -+#define RECYCLE_Q_SLICE0 16 -+#define RECYCLE_Q_SLICE1 17 -+ -+#define ICSSG_NUM_OTHER_QUEUES 5 /* port, host and special queues */ -+ -+#define PORT_HI_Q_SLICE0 32 -+#define PORT_LO_Q_SLICE0 33 -+#define HOST_HI_Q_SLICE0 34 -+#define HOST_LO_Q_SLICE0 35 -+#define HOST_SPL_Q_SLICE0 40 /* Special Queue */ -+ -+#define PORT_HI_Q_SLICE1 36 -+#define PORT_LO_Q_SLICE1 37 -+#define HOST_HI_Q_SLICE1 38 -+#define HOST_LO_Q_SLICE1 39 -+#define HOST_SPL_Q_SLICE1 41 /* Special Queue */ -+ -+#define MII_RXCFG_DEFAULT (PRUSS_MII_RT_RXCFG_RX_ENABLE | \ -+ PRUSS_MII_RT_RXCFG_RX_DATA_RDY_MODE_DIS | \ -+ PRUSS_MII_RT_RXCFG_RX_L2_EN | \ -+ PRUSS_MII_RT_RXCFG_RX_L2_EOF_SCLR_DIS) -+ -+#define MII_TXCFG_DEFAULT (PRUSS_MII_RT_TXCFG_TX_ENABLE | \ -+ PRUSS_MII_RT_TXCFG_TX_AUTO_PREAMBLE | \ -+ PRUSS_MII_RT_TXCFG_TX_32_MODE_EN | \ -+ PRUSS_MII_RT_TXCFG_TX_IPG_WIRE_CLK_EN) -+ -+#define ICSSG_CFG_DEFAULT (ICSSG_CFG_TX_L1_EN | \ -+ ICSSG_CFG_TX_L2_EN | ICSSG_CFG_RX_L2_G_EN | \ -+ ICSSG_CFG_TX_PRU_EN | /* SR2.0 only */ \ -+ ICSSG_CFG_SGMII_MODE) -+ -+struct map { -+ int queue; -+ u32 pd_addr_start; -+ u32 flags; -+ bool special; -+}; -+ -+struct map hwq_map[2][ICSSG_NUM_OTHER_QUEUES] = { -+ { -+ { PORT_HI_Q_SLICE0, PORT_DESC0_HI, 0x200000, 0 }, -+ { PORT_LO_Q_SLICE0, PORT_DESC0_LO, 0, 0 }, -+ { HOST_HI_Q_SLICE0, HOST_DESC0_HI, 0x200000, 0 }, -+ { HOST_LO_Q_SLICE0, HOST_DESC0_LO, 0, 0 }, -+ { HOST_SPL_Q_SLICE0, HOST_SPPD0, 0x400000, 1 }, -+ }, -+ { -+ { PORT_HI_Q_SLICE1, PORT_DESC1_HI, 0xa00000, 0 }, -+ { PORT_LO_Q_SLICE1, PORT_DESC1_LO, 0x800000, 0 }, -+ { HOST_HI_Q_SLICE1, HOST_DESC1_HI, 0xa00000, 0 }, -+ { HOST_LO_Q_SLICE1, HOST_DESC1_LO, 0x800000, 0 }, -+ { HOST_SPL_Q_SLICE1, HOST_SPPD1, 0xc00000, 1 }, -+ }, -+}; -+ -+static void icssg_config_mii_init(struct prueth *prueth, int mii) -+{ -+ struct regmap *mii_rt = prueth->mii_rt; -+ u32 rxcfg_reg, txcfg_reg, pcnt_reg; -+ u32 rxcfg, txcfg; -+ -+ rxcfg_reg = (mii == ICSS_MII0) ? PRUSS_MII_RT_RXCFG0 : -+ PRUSS_MII_RT_RXCFG1; -+ txcfg_reg = (mii == ICSS_MII0) ? PRUSS_MII_RT_TXCFG0 : -+ PRUSS_MII_RT_TXCFG1; -+ pcnt_reg = (mii == ICSS_MII0) ? PRUSS_MII_RT_RX_PCNT0 : -+ PRUSS_MII_RT_RX_PCNT1; -+ -+ icssg_config_ipg(prueth, SPEED_1000, mii); -+ -+ rxcfg = MII_RXCFG_DEFAULT; -+ txcfg = MII_TXCFG_DEFAULT; -+ -+ if (mii == ICSS_MII1) { -+ rxcfg |= PRUSS_MII_RT_RXCFG_RX_MUX_SEL; -+ txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL; -+ } -+ -+ regmap_write(mii_rt, rxcfg_reg, rxcfg); -+ regmap_write(mii_rt, txcfg_reg, txcfg); -+ regmap_write(mii_rt, pcnt_reg, 0x1); -+} -+ -+static void icssg_config_rgmii_init(struct prueth *prueth, int slice) -+{ -+ void __iomem *smem = prueth->shram.va; -+ struct regmap *miig_rt = prueth->miig_rt; -+ int queue = 0, i, j; -+ u8 pd[ICSSG_SPECIAL_PD_SIZE]; -+ u32 *pdword; -+ u32 mii_mode; -+ -+ mii_mode = MII_MODE_RGMII << ICSSG_CFG_MII0_MODE_SHIFT; -+ mii_mode |= MII_MODE_RGMII << ICSSG_CFG_MII1_MODE_SHIFT; -+ regmap_write(miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_DEFAULT | mii_mode); -+ -+ icssg_update_rgmii_cfg(miig_rt, true, true, slice); -+ /* reset hwqueues */ -+ if (slice) -+ queue = ICSSG_NUM_TX_QUEUES; -+ -+ for (i = 0; i < ICSSG_NUM_TX_QUEUES; i++) { -+ regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue); -+ queue++; -+ } -+ -+ queue = slice ? RECYCLE_Q_SLICE1 : RECYCLE_Q_SLICE0; -+ regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue); -+ -+ for (i = 0; i < ICSSG_NUM_OTHER_QUEUES; i++) { -+ regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, -+ hwq_map[slice][i].queue); -+ } -+ -+ /* initialize packet descriptors in SMEM */ -+ /* push pakcet descriptors to hwqueues */ -+ -+ pdword = (u32 *)pd; -+ for (j = 0; j < ICSSG_NUM_OTHER_QUEUES; j++) { -+ struct map *mp; -+ int pd_size, num_pds; -+ u32 pdaddr; -+ -+ mp = &hwq_map[slice][j]; -+ if (mp->special) { -+ pd_size = ICSSG_SPECIAL_PD_SIZE; -+ num_pds = ICSSG_NUM_SPECIAL_PDS; -+ } else { -+ pd_size = ICSSG_NORMAL_PD_SIZE; -+ num_pds = ICSSG_NUM_NORMAL_PDS; -+ } -+ -+ for (i = 0; i < num_pds; i++) { -+ memset(pd, 0, pd_size); -+ -+ pdword[0] &= cpu_to_le32(ICSSG_FLAG_MASK); -+ pdword[0] |= cpu_to_le32(mp->flags); -+ pdaddr = mp->pd_addr_start + i * pd_size; -+ -+ memcpy_toio(smem + pdaddr, pd, pd_size); -+ queue = mp->queue; -+ regmap_write(miig_rt, ICSSG_QUEUE_OFFSET + 4 * queue, -+ pdaddr); -+ } -+ } -+} -+ -+void icssg_config_ipg(struct prueth *prueth, int speed, int mii) -+{ -+ switch (speed) { -+ case SPEED_1000: -+ icssg_mii_update_ipg(prueth->mii_rt, mii, prueth->is_sr1 ? -+ MII_RT_TX_IPG_1G_SR1 : MII_RT_TX_IPG_1G); -+ break; -+ case SPEED_100: -+ icssg_mii_update_ipg(prueth->mii_rt, mii, prueth->is_sr1 ? -+ MII_RT_TX_IPG_100M_SR1 : MII_RT_TX_IPG_100M); -+ break; -+ default: -+ /* Other links speeds not supported */ -+ pr_err("Unsupported link speed\n"); -+ return; -+ } -+} -+ -+/* SR1: Set buffer sizes for the pools. There are 8 internal queues -+ * implemented in firmware, but only 4 tx channels/threads in the Egress -+ * direction to firmware. Need a high priority queue for management -+ * messages since they shouldn't be blocked even during high traffic -+ * situation. So use Q0-Q2 as data queues and Q3 as management queue -+ * in the max case. However for ease of configuration, use the max -+ * data queue + 1 for management message if we are not using max -+ * case. -+ * -+ * Allocate 4 MTU buffers per data queue. Firmware requires -+ * pool sizes to be set for internal queues. Set the upper 5 queue -+ * pool size to min size of 128 bytes since there are only 3 tx -+ * data channels and management queue requires only minimum buffer. -+ * i.e lower queues are used by driver and highest priority queue -+ * from that is used for management message. -+ */ -+ -+static int emac_egress_buf_pool_size[] = { -+ PRUETH_EMAC_BUF_POOL_SIZE_SR1, PRUETH_EMAC_BUF_POOL_SIZE_SR1, -+ PRUETH_EMAC_BUF_POOL_SIZE_SR1, PRUETH_EMAC_BUF_POOL_MIN_SIZE_SR1, -+ PRUETH_EMAC_BUF_POOL_MIN_SIZE_SR1, PRUETH_EMAC_BUF_POOL_MIN_SIZE_SR1, -+ PRUETH_EMAC_BUF_POOL_MIN_SIZE_SR1, PRUETH_EMAC_BUF_POOL_MIN_SIZE_SR1}; -+ -+void icssg_config_sr1(struct prueth *prueth, struct prueth_emac *emac, -+ int slice) -+{ -+ void __iomem *va; -+ struct icssg_config_sr1 *config; -+ int i, index; -+ -+ va = prueth->shram.va + slice * ICSSG_CONFIG_OFFSET_SLICE1; -+ config = &prueth->config[slice]; -+ memset(config, 0, sizeof(*config)); -+ config->addr_lo = cpu_to_le32(lower_32_bits(prueth->msmcram.pa)); -+ config->addr_hi = cpu_to_le32(upper_32_bits(prueth->msmcram.pa)); -+ config->num_tx_threads = 0; -+ config->rx_flow_id = emac->rx_flow_id_base; /* flow id for host port */ -+ config->rx_mgr_flow_id = emac->rx_mgm_flow_id_base; /* for mgm ch */ -+ -+ for (i = PRUETH_EMAC_BUF_POOL_START_SR1; i < PRUETH_NUM_BUF_POOLS_SR1; -+ i++) { -+ index = i - PRUETH_EMAC_BUF_POOL_START_SR1; -+ config->tx_buf_sz[i] = -+ cpu_to_le32(emac_egress_buf_pool_size[index]); -+ } -+ -+ memcpy_toio(va, &prueth->config[slice], sizeof(prueth->config[slice])); -+} -+ -+static void emac_r30_cmd_init(struct prueth_emac *emac) -+{ -+ int i; -+ struct icssg_r30_cmd *p; -+ -+ p = emac->dram.va + MGR_R30_CMD_OFFSET; -+ -+ for (i = 0; i < 4; i++) -+ writel(EMAC_NONE, &p->cmd[i]); -+} -+ -+static int emac_r30_is_done(struct prueth_emac *emac) -+{ -+ const struct icssg_r30_cmd *p; -+ int i; -+ u32 cmd; -+ -+ p = emac->dram.va + MGR_R30_CMD_OFFSET; -+ -+ for (i = 0; i < 4; i++) { -+ cmd = readl(&p->cmd[i]); -+ if (cmd != EMAC_NONE) -+ return 0; -+ } -+ -+ return 1; -+} -+ -+int icssg_config_sr2(struct prueth *prueth, struct prueth_emac *emac, int slice) -+{ -+ void *config = emac->dram.va + ICSSG_CONFIG_OFFSET; -+ u8 *cfg_byte_ptr = config; -+ struct icssg_flow_cfg *flow_cfg; -+ struct icssg_buffer_pool_cfg *bpool_cfg; -+ struct icssg_rxq_ctx *rxq_ctx; -+ int i; -+ u32 addr, mask; -+ -+ rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET; -+ memset_io(config, 0, TAS_GATE_MASK_LIST0); -+ icssg_config_rgmii_init(prueth, slice); -+ icssg_config_mii_init(prueth, slice); -+ -+ /* set GPI mode */ -+ pruss_cfg_gpimode(prueth->pruss, prueth->pru_id[slice], -+ PRUSS_GPI_MODE_MII); -+ -+ /* enable XFR shift for PRU and RTU */ -+ mask = PRUSS_SPP_XFER_SHIFT_EN | PRUSS_SPP_RTU_XFR_SHIFT_EN; -+ pruss_cfg_update(prueth->pruss, PRUSS_CFG_SPP, mask, mask); -+ -+ /* set C28 to 0x100 */ -+ pru_rproc_set_ctable(prueth->pru[slice], PRU_C28, 0x100 << 8); -+ pru_rproc_set_ctable(prueth->rtu[slice], PRU_C28, 0x100 << 8); -+ pru_rproc_set_ctable(prueth->txpru[slice], PRU_C28, 0x100 << 8); -+ -+ bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET; -+ -+ flow_cfg = config + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET; -+ flow_cfg->rx_base_flow = cpu_to_le32(emac->rx_flow_id_base); -+ flow_cfg->mgm_base_flow = 0; -+ *(cfg_byte_ptr + SPL_PKT_DEFAULT_PRIORITY) = 0; -+ *(cfg_byte_ptr + QUEUE_NUM_UNTAGGED) = 0x0; -+ -+ /* Layout to have 64KB aligned buffer pool -+ * |BPOOL0|BPOOL1|RX_CTX0|RX_CTX1| -+ */ -+ -+ addr = lower_32_bits(prueth->msmcram.pa); -+ if (slice) -+ addr += PRUETH_NUM_BUF_POOLS_SR2 * PRUETH_EMAC_BUF_POOL_SIZE_SR2; -+ -+ if (addr % SZ_64K) { -+ dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n"); -+ return -EINVAL; -+ } -+ -+ /* workaround for f/w bug. bpool 0 needs to be initilalized */ -+ bpool_cfg[0].addr = cpu_to_le32(addr); -+ bpool_cfg[0].len = 0; -+ -+ for (i = PRUETH_EMAC_BUF_POOL_START_SR2; -+ i < (PRUETH_EMAC_BUF_POOL_START_SR2 + PRUETH_NUM_BUF_POOLS_SR2); -+ i++) { -+ bpool_cfg[i].addr = cpu_to_le32(addr); -+ bpool_cfg[i].len = cpu_to_le32(PRUETH_EMAC_BUF_POOL_SIZE_SR2); -+ addr += PRUETH_EMAC_BUF_POOL_SIZE_SR2; -+ } -+ -+ addr += PRUETH_NUM_BUF_POOLS_SR2 * PRUETH_EMAC_BUF_POOL_SIZE_SR2; -+ if (slice) -+ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; -+ -+ for (i = 0; i < 3; i++) -+ rxq_ctx->start[i] = cpu_to_le32(addr); -+ -+ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; -+ rxq_ctx->end = cpu_to_le32(addr); -+ -+ emac_r30_cmd_init(emac); -+ return 0; -+} -+ -+/* commands to program ICSSG R30 registers */ -+/* FIXME: fix hex magic numbers with macros */ -+static struct icssg_r30_cmd emac_r32_bitmask[] = { -+ {{0xffff0004, 0xffff0100, 0xffff0100, EMAC_NONE}}, /* EMAC_PORT_DISABLE */ -+ {{0xfffb0040, 0xfeff0200, 0xfeff0200, EMAC_NONE}}, /* EMAC_PORT_BLOCK */ -+ {{0xffbb0000, 0xfcff0000, 0xdcff0000, EMAC_NONE}}, /* EMAC_PORT_FORWARD */ -+ {{0xffbb0000, 0xfcff0000, 0xfcff2000, EMAC_NONE}}, /* EMAC_PORT_FORWARD_WO_LEARNING */ -+ {{0xffff0001, EMAC_NONE, EMAC_NONE, EMAC_NONE}}, /* ACCEPT ALL */ -+ {{0xfffe0002, EMAC_NONE, EMAC_NONE, EMAC_NONE}}, /* ACCEPT TAGGED */ -+ {{0xfffc0000, EMAC_NONE, EMAC_NONE, EMAC_NONE}}, /* ACCEPT UNTAGGED and PRIO */ -+ {{EMAC_NONE, 0xffff0020, EMAC_NONE, EMAC_NONE}}, /* TAS Trigger List change */ -+ {{EMAC_NONE, 0xdfff1000, EMAC_NONE, EMAC_NONE}}, /* TAS set state ENABLE*/ -+ {{EMAC_NONE, 0xefff2000, EMAC_NONE, EMAC_NONE}}, /* TAS set state RESET*/ -+ {{EMAC_NONE, 0xcfff0000, EMAC_NONE, EMAC_NONE}}, /* TAS set state DISABLE*/ -+ {{EMAC_NONE, EMAC_NONE, 0xffff0400, EMAC_NONE}}, /* UC flooding ENABLE*/ -+ {{EMAC_NONE, EMAC_NONE, 0xfbff0000, EMAC_NONE}}, /* UC flooding DISABLE*/ -+ {{EMAC_NONE, EMAC_NONE, 0xffff0800, EMAC_NONE}}, /* MC flooding ENABLE*/ -+ {{EMAC_NONE, EMAC_NONE, 0xf7ff0000, EMAC_NONE}}, /* MC flooding DISABLE*/ -+ {{EMAC_NONE, 0xffff4000, EMAC_NONE, EMAC_NONE}}, /* Preemption on Tx ENABLE*/ -+ {{EMAC_NONE, 0xbfff0000, EMAC_NONE, EMAC_NONE}} /* Preemption on Tx DISABLE*/ -+}; -+ -+int emac_set_port_state(struct prueth_emac *emac, -+ enum icssg_port_state_cmd cmd) -+{ -+ struct icssg_r30_cmd *p; -+ int ret = -ETIMEDOUT; -+ int timeout = 10; -+ int i; -+ -+ p = emac->dram.va + MGR_R30_CMD_OFFSET; -+ -+ if (cmd >= ICSSG_EMAC_PORT_MAX_COMMANDS) { -+ netdev_err(emac->ndev, "invalid port command\n"); -+ return -EINVAL; -+ } -+ -+ /* only one command at a time allowed to firmware */ -+ mutex_lock(&emac->cmd_lock); -+ -+ for (i = 0; i < 4; i++) -+ writel(emac_r32_bitmask[cmd].cmd[i], &p->cmd[i]); -+ -+ /* wait for done */ -+ while (timeout) { -+ if (emac_r30_is_done(emac)) { -+ ret = 0; -+ break; -+ } -+ -+ usleep_range(1000, 2000); -+ timeout--; -+ } -+ -+ if (ret == -ETIMEDOUT) -+ netdev_err(emac->ndev, "timeout waiting for command done\n"); -+ -+ mutex_unlock(&emac->cmd_lock); -+ -+ return ret; -+} -diff --git a/drivers/net/ethernet/ti/icssg_config.h b/drivers/net/ethernet/ti/icssg_config.h -new file mode 100644 -index 000000000000..e8f02208fe4f ---- /dev/null -+++ b/drivers/net/ethernet/ti/icssg_config.h -@@ -0,0 +1,192 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* Texas Instruments ICSSG Ethernet driver -+ * -+ * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/ -+ * -+ */ -+ -+#ifndef __NET_TI_ICSSG_CONFIG_H -+#define __NET_TI_ICSSG_CONFIG_H -+ -+struct icssg_buffer_pool_cfg { -+ __le32 addr; -+ __le32 len; -+} __packed; -+ -+struct icssg_flow_cfg { -+ __le16 rx_base_flow; -+ __le16 mgm_base_flow; -+} __packed; -+ -+/*------------------------ SR1.0 related --------------------------*/ -+ -+/* Port queue size in MSMC from firmware -+ * PORTQSZ_HP .set (0x1800) -+ * PORTQSZ_HP2 .set (PORTQSZ_HP+128) ;include barrier area -+ * 0x1880 x 8 bytes per slice (port) -+ */ -+ -+#define MSMC_RAM_SIZE_SR1 (SZ_64K + SZ_32K + SZ_2K) /* 0x1880 x 8 x 2 */ -+ -+#define PRUETH_MAX_RX_MGM_DESC 8 -+#define PRUETH_MAX_RX_FLOWS_SR1 4 /* excluding default flow */ -+#define PRUETH_RX_FLOW_DATA_SR1 3 /* highest priority flow */ -+#define PRUETH_MAX_RX_MGM_FLOWS 2 /* excluding default flow */ -+#define PRUETH_RX_MGM_FLOW_RESPONSE 0 -+#define PRUETH_RX_MGM_FLOW_TIMESTAMP 1 -+#define PRUETH_RX_MGM_FLOW_OTHER 2 -+ -+#define PRUETH_NUM_BUF_POOLS_SR1 16 -+#define PRUETH_EMAC_BUF_POOL_START_SR1 8 -+#define PRUETH_EMAC_BUF_POOL_MIN_SIZE_SR1 128 -+#define PRUETH_EMAC_BUF_SIZE_SR1 1536 -+#define PRUETH_EMAC_NUM_BUF_SR1 4 -+#define PRUETH_EMAC_BUF_POOL_SIZE_SR1 (PRUETH_EMAC_NUM_BUF_SR1 * \ -+ PRUETH_EMAC_BUF_SIZE_SR1) -+/* Config area lies in shared RAM */ -+#define ICSSG_CONFIG_OFFSET_SLICE0 0 -+#define ICSSG_CONFIG_OFFSET_SLICE1 0x8000 -+ -+struct icssg_config_sr1 { -+ __le32 status; /* Firmware status */ -+ __le32 addr_lo; /* MSMC Buffer pool base address low. */ -+ __le32 addr_hi; /* MSMC Buffer pool base address high. Must be 0 */ -+ __le32 tx_buf_sz[16]; /* Array of buffer pool sizes */ -+ __le32 num_tx_threads; /* Number of active egress threads, 1 to 4 */ -+ __le32 tx_rate_lim_en; /* Bitmask: Egress rate limit en per thread */ -+ __le32 rx_flow_id; /* RX flow id for first rx ring */ -+ __le32 rx_mgr_flow_id; /* RX flow id for the first management ring */ -+ __le32 flags; /* TBD */ -+ __le32 n_burst; /* for debug */ -+ __le32 rtu_status; /* RTU status */ -+ __le32 info; /* reserved */ -+} __packed; -+ -+/* Shutdown command to stop processing at firmware. -+ * Command format : 0x8101ss00. ss - sequence number. Currently not used -+ * by driver. -+ */ -+#define ICSSG_SHUTDOWN_CMD 0x81010000 -+ -+/* pstate speed/duplex command to set speed and duplex settings -+ * in firmware. -+ * Command format : 0x8102ssPN. ss - sequence number: currently not -+ * used by driver, P - port number: For switch, N - Speed/Duplex state -+ * - Possible values of N: -+ * 0x0 - 10Mbps/Half duplex ; -+ * 0x8 - 10Mbps/Full duplex ; -+ * 0x2 - 100Mbps/Half duplex; -+ * 0xa - 100Mbps/Full duplex; -+ * 0xc - 1Gbps/Full duplex; -+ * NOTE: The above are same as bits [3..1](slice 0) or bits [8..6](slice 1) of -+ * RGMII CFG register. So suggested to read the register to populate the command -+ * bits. -+ */ -+#define ICSSG_PSTATE_SPEED_DUPLEX_CMD 0x81020000 -+ -+/*------------------------ SR2.0 related --------------------------*/ -+ -+#define PRUETH_PKT_TYPE_CMD 0x10 -+#define PRUETH_NAV_PS_DATA_SIZE 16 /* Protocol specific data size */ -+#define PRUETH_NAV_SW_DATA_SIZE 16 /* SW related data size */ -+#define PRUETH_MAX_TX_DESC 512 -+#define PRUETH_MAX_RX_DESC 512 -+#define PRUETH_MAX_RX_FLOWS_SR2 1 /* excluding default flow */ -+#define PRUETH_RX_FLOW_DATA_SR2 0 /* FIXME: f/w bug to change to highest priority flow */ -+ -+#define PRUETH_EMAC_BUF_POOL_SIZE_SR2 SZ_8K -+#define PRUETH_EMAC_POOLS_PER_SLICE 24 -+#define PRUETH_EMAC_BUF_POOL_START_SR2 8 -+#define PRUETH_NUM_BUF_POOLS_SR2 8 -+#define PRUETH_EMAC_RX_CTX_BUF_SIZE SZ_16K /* per slice */ -+#define MSMC_RAM_SIZE_SR2 \ -+ (2 * (PRUETH_EMAC_BUF_POOL_SIZE_SR2 * PRUETH_NUM_BUF_POOLS_SR2 + \ -+ PRUETH_EMAC_RX_CTX_BUF_SIZE)) -+ -+struct icssg_rxq_ctx { -+ __le32 start[3]; -+ __le32 end; -+} __packed; -+ -+/* Load time Fiwmware Configuration */ -+ -+#define ICSSG_FW_MGMT_CMD_HEADER 0x81 -+#define ICSSG_FW_MGMT_FDB_CMD_TYPE 0x03 -+#define ICSSG_FW_MGMT_CMD_TYPE 0x04 -+#define ICSSG_FW_MGMT_PKT 0x80000000 -+ -+struct icssg_r30_cmd { -+ u32 cmd[4]; -+} __packed; -+ -+enum icssg_port_state_cmd { -+ ICSSG_EMAC_PORT_DISABLE = 0, -+ ICSSG_EMAC_PORT_BLOCK, -+ ICSSG_EMAC_PORT_FORWARD, -+ ICSSG_EMAC_PORT_FORWARD_WO_LEARNING, -+ ICSSG_EMAC_PORT_ACCEPT_ALL, -+ ICSSG_EMAC_PORT_ACCEPT_TAGGED, -+ ICSSG_EMAC_PORT_ACCEPT_UNTAGGED_N_PRIO, -+ ICSSG_EMAC_PORT_TAS_TRIGGER, -+ ICSSG_EMAC_PORT_TAS_ENABLE, -+ ICSSG_EMAC_PORT_TAS_RESET, -+ ICSSG_EMAC_PORT_TAS_DISABLE, -+ ICSSG_EMAC_PORT_UC_FLOODING_ENABLE, -+ ICSSG_EMAC_PORT_UC_FLOODING_DISABLE, -+ ICSSG_EMAC_PORT_MC_FLOODING_ENABLE, -+ ICSSG_EMAC_PORT_MC_FLOODING_DISABLE, -+ ICSSG_EMAC_PORT_PREMPT_TX_ENABLE, -+ ICSSG_EMAC_PORT_PREMPT_TX_DISABLE, -+ ICSSG_EMAC_PORT_MAX_COMMANDS -+}; -+ -+#define EMAC_NONE 0xffff0000 -+#define EMAC_PRU0_P_DI 0xffff0004 -+#define EMAC_PRU1_P_DI 0xffff0040 -+#define EMAC_TX_P_DI 0xffff0100 -+ -+#define EMAC_PRU0_P_EN 0xfffb0000 -+#define EMAC_PRU1_P_EN 0xffbf0000 -+#define EMAC_TX_P_EN 0xfeff0000 -+ -+#define EMAC_P_BLOCK 0xffff0040 -+#define EMAC_TX_P_BLOCK 0xffff0200 -+#define EMAC_P_UNBLOCK 0xffbf0000 -+#define EMAC_TX_P_UNBLOCK 0xfdff0000 -+#define EMAC_LEAN_EN 0xfff70000 -+#define EMAC_LEAN_DI 0xffff0008 -+ -+#define EMAC_ACCEPT_ALL 0xffff0001 -+#define EMAC_ACCEPT_TAG 0xfffe0002 -+#define EMAC_ACCEPT_PRIOR 0xfffc0000 -+ -+/* Config area lies in DRAM */ -+#define ICSSG_CONFIG_OFFSET 0x0 -+ -+#define ICSSG_NUM_NORMAL_PDS 64 -+#define ICSSG_NUM_SPECIAL_PDS 16 -+ -+#define ICSSG_NORMAL_PD_SIZE 8 -+#define ICSSG_SPECIAL_PD_SIZE 20 -+ -+#define ICSSG_FLAG_MASK 0xff00ffff -+ -+#define ICSSG_CMD_POP_SLICE0 56 -+#define ICSSG_CMD_POP_SLICE1 60 -+ -+#define ICSSG_CMD_PUSH_SLICE0 57 -+#define ICSSG_CMD_PUSH_SLICE1 61 -+ -+#define ICSSG_RSP_POP_SLICE0 58 -+#define ICSSG_RSP_POP_SLICE1 62 -+ -+#define ICSSG_RSP_PUSH_SLICE0 56 -+#define ICSSG_RSP_PUSH_SLICE1 60 -+ -+#define ICSSG_TS_POP_SLICE0 59 -+#define ICSSG_TS_POP_SLICE1 63 -+ -+#define ICSSG_TS_PUSH_SLICE0 40 -+#define ICSSG_TS_PUSH_SLICE1 41 -+ -+#endif /* __NET_TI_ICSSG_CONFIG_H */ -diff --git a/drivers/net/ethernet/ti/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg_ethtool.c -new file mode 100644 -index 000000000000..b43fb0e6109a ---- /dev/null -+++ b/drivers/net/ethernet/ti/icssg_ethtool.c -@@ -0,0 +1,335 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* Texas Instruments ICSSG Ethernet driver -+ * -+ * Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/ -+ * -+ */ -+ -+#include "icssg_prueth.h" -+#include -+ -+static u32 stats_base[] = { 0x54c, /* Slice 0 stats start */ -+ 0xb18, /* Slice 1 stats start */ -+}; -+ -+struct miig_stats_regs { -+ /* Rx */ -+ u32 rx_good_frames; -+ u32 rx_broadcast_frames; -+ u32 rx_multicast_frames; -+ u32 rx_crc_error_frames; -+ u32 rx_mii_error_frames; -+ u32 rx_odd_nibble_frames; -+ u32 rx_frame_max_size; -+ u32 rx_max_size_error_frames; -+ u32 rx_frame_min_size; -+ u32 rx_min_size_error_frames; -+ u32 rx_overrun_frames; -+ u32 rx_class0_hits; -+ u32 rx_class1_hits; -+ u32 rx_class2_hits; -+ u32 rx_class3_hits; -+ u32 rx_class4_hits; -+ u32 rx_class5_hits; -+ u32 rx_class6_hits; -+ u32 rx_class7_hits; -+ u32 rx_class8_hits; -+ u32 rx_class9_hits; -+ u32 rx_class10_hits; -+ u32 rx_class11_hits; -+ u32 rx_class12_hits; -+ u32 rx_class13_hits; -+ u32 rx_class14_hits; -+ u32 rx_class15_hits; -+ u32 rx_smd_frags; -+ u32 rx_bucket1_size; -+ u32 rx_bucket2_size; -+ u32 rx_bucket3_size; -+ u32 rx_bucket4_size; -+ u32 rx_64B_frames; -+ u32 rx_bucket1_frames; -+ u32 rx_bucket2_frames; -+ u32 rx_bucket3_frames; -+ u32 rx_bucket4_frames; -+ u32 rx_bucket5_frames; -+ u32 rx_total_bytes; -+ u32 rx_tx_total_bytes; -+ /* Tx */ -+ u32 tx_good_frames; -+ u32 tx_broadcast_frames; -+ u32 tx_multicast_frames; -+ u32 tx_odd_nibble_frames; -+ u32 tx_underflow_errors; -+ u32 tx_frame_max_size; -+ u32 tx_max_size_error_frames; -+ u32 tx_frame_min_size; -+ u32 tx_min_size_error_frames; -+ u32 tx_bucket1_size; -+ u32 tx_bucket2_size; -+ u32 tx_bucket3_size; -+ u32 tx_bucket4_size; -+ u32 tx_64B_frames; -+ u32 tx_bucket1_frames; -+ u32 tx_bucket2_frames; -+ u32 tx_bucket3_frames; -+ u32 tx_bucket4_frames; -+ u32 tx_bucket5_frames; -+ u32 tx_total_bytes; -+}; -+ -+#define ICSSG_STATS(field) \ -+{ \ -+ #field, \ -+ offsetof(struct miig_stats_regs, field), \ -+} -+ -+struct icssg_stats { -+ char name[ETH_GSTRING_LEN]; -+ u32 offset; -+}; -+ -+static const struct icssg_stats icssg_ethtool_stats[] = { -+ /* Rx */ -+ ICSSG_STATS(rx_good_frames), -+ ICSSG_STATS(rx_broadcast_frames), -+ ICSSG_STATS(rx_multicast_frames), -+ ICSSG_STATS(rx_crc_error_frames), -+ ICSSG_STATS(rx_mii_error_frames), -+ ICSSG_STATS(rx_odd_nibble_frames), -+ ICSSG_STATS(rx_frame_max_size), -+ ICSSG_STATS(rx_max_size_error_frames), -+ ICSSG_STATS(rx_frame_min_size), -+ ICSSG_STATS(rx_min_size_error_frames), -+ ICSSG_STATS(rx_overrun_frames), -+ ICSSG_STATS(rx_class0_hits), -+ ICSSG_STATS(rx_class1_hits), -+ ICSSG_STATS(rx_class2_hits), -+ ICSSG_STATS(rx_class3_hits), -+ ICSSG_STATS(rx_class4_hits), -+ ICSSG_STATS(rx_class5_hits), -+ ICSSG_STATS(rx_class6_hits), -+ ICSSG_STATS(rx_class7_hits), -+ ICSSG_STATS(rx_class8_hits), -+ ICSSG_STATS(rx_class9_hits), -+ ICSSG_STATS(rx_class10_hits), -+ ICSSG_STATS(rx_class11_hits), -+ ICSSG_STATS(rx_class12_hits), -+ ICSSG_STATS(rx_class13_hits), -+ ICSSG_STATS(rx_class14_hits), -+ ICSSG_STATS(rx_class15_hits), -+ ICSSG_STATS(rx_smd_frags), -+ ICSSG_STATS(rx_bucket1_size), -+ ICSSG_STATS(rx_bucket2_size), -+ ICSSG_STATS(rx_bucket3_size), -+ ICSSG_STATS(rx_bucket4_size), -+ ICSSG_STATS(rx_64B_frames), -+ ICSSG_STATS(rx_bucket1_frames), -+ ICSSG_STATS(rx_bucket2_frames), -+ ICSSG_STATS(rx_bucket3_frames), -+ ICSSG_STATS(rx_bucket4_frames), -+ ICSSG_STATS(rx_bucket5_frames), -+ ICSSG_STATS(rx_total_bytes), -+ ICSSG_STATS(rx_tx_total_bytes), -+ /* Tx */ -+ ICSSG_STATS(tx_good_frames), -+ ICSSG_STATS(tx_broadcast_frames), -+ ICSSG_STATS(tx_multicast_frames), -+ ICSSG_STATS(tx_odd_nibble_frames), -+ ICSSG_STATS(tx_underflow_errors), -+ ICSSG_STATS(tx_frame_max_size), -+ ICSSG_STATS(tx_max_size_error_frames), -+ ICSSG_STATS(tx_frame_min_size), -+ ICSSG_STATS(tx_min_size_error_frames), -+ ICSSG_STATS(tx_bucket1_size), -+ ICSSG_STATS(tx_bucket2_size), -+ ICSSG_STATS(tx_bucket3_size), -+ ICSSG_STATS(tx_bucket4_size), -+ ICSSG_STATS(tx_64B_frames), -+ ICSSG_STATS(tx_bucket1_frames), -+ ICSSG_STATS(tx_bucket2_frames), -+ ICSSG_STATS(tx_bucket3_frames), -+ ICSSG_STATS(tx_bucket4_frames), -+ ICSSG_STATS(tx_bucket5_frames), -+ ICSSG_STATS(tx_total_bytes), -+}; -+ -+static void emac_get_drvinfo(struct net_device *ndev, -+ struct ethtool_drvinfo *info) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth *prueth = emac->prueth; -+ -+ strlcpy(info->driver, dev_driver_string(prueth->dev), -+ sizeof(info->driver)); -+ /* TODO: info->fw_version */ -+ strlcpy(info->bus_info, dev_name(prueth->dev), sizeof(info->bus_info)); -+} -+ -+static u32 emac_get_msglevel(struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ return emac->msg_enable; -+} -+ -+static void emac_set_msglevel(struct net_device *ndev, u32 value) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ emac->msg_enable = value; -+} -+ -+static int emac_get_link_ksettings(struct net_device *ndev, -+ struct ethtool_link_ksettings *ecmd) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ if (!emac->phydev) -+ return -EOPNOTSUPP; -+ -+ phy_ethtool_ksettings_get(emac->phydev, ecmd); -+ return 0; -+} -+ -+static int emac_set_link_ksettings(struct net_device *ndev, -+ const struct ethtool_link_ksettings *ecmd) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ if (!emac->phydev || phy_is_pseudo_fixed_link(emac->phydev)) -+ return -EOPNOTSUPP; -+ -+ return phy_ethtool_ksettings_set(emac->phydev, ecmd); -+} -+ -+static int emac_get_eee(struct net_device *ndev, struct ethtool_eee *edata) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ if (!emac->phydev || phy_is_pseudo_fixed_link(emac->phydev)) -+ return -EOPNOTSUPP; -+ -+ return phy_ethtool_get_eee(emac->phydev, edata); -+} -+ -+static int emac_set_eee(struct net_device *ndev, struct ethtool_eee *edata) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ if (!emac->phydev || phy_is_pseudo_fixed_link(emac->phydev)) -+ return -EOPNOTSUPP; -+ -+ return phy_ethtool_set_eee(emac->phydev, edata); -+} -+ -+static int emac_nway_reset(struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ if (!emac->phydev || phy_is_pseudo_fixed_link(emac->phydev)) -+ return -EOPNOTSUPP; -+ -+ return genphy_restart_aneg(emac->phydev); -+} -+ -+static int emac_get_sset_count(struct net_device *ndev, int stringset) -+{ -+ switch (stringset) { -+ case ETH_SS_STATS: -+ return ARRAY_SIZE(icssg_ethtool_stats); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static void emac_get_strings(struct net_device *ndev, u32 stringset, u8 *data) -+{ -+ u8 *p = data; -+ int i; -+ -+ switch (stringset) { -+ case ETH_SS_STATS: -+ for (i = 0; i < ARRAY_SIZE(icssg_ethtool_stats); i++) { -+ memcpy(p, icssg_ethtool_stats[i].name, -+ ETH_GSTRING_LEN); -+ p += ETH_GSTRING_LEN; -+ } -+ break; -+ default: -+ break; -+ } -+} -+ -+static void emac_get_ethtool_stats(struct net_device *ndev, -+ struct ethtool_stats *stats, u64 *data) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth *prueth = emac->prueth; -+ int i; -+ int slice = prueth_emac_slice(emac); -+ u32 base = stats_base[slice]; -+ u32 val; -+ -+ for (i = 0; i < ARRAY_SIZE(icssg_ethtool_stats); i++) { -+ regmap_read(prueth->miig_rt, -+ base + icssg_ethtool_stats[i].offset, -+ &val); -+ data[i] = val; -+ } -+} -+ -+static void emac_get_channels(struct net_device *ndev, -+ struct ethtool_channels *ch) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ ch->max_rx = 1; -+ /* SR1 use high priority channel for management messages */ -+ ch->max_tx = emac->is_sr1 ? PRUETH_MAX_TX_QUEUES - 1 : -+ PRUETH_MAX_TX_QUEUES; -+ ch->rx_count = 1; -+ ch->tx_count = emac->is_sr1 ? emac->tx_ch_num - 1 : -+ emac->tx_ch_num; -+} -+ -+static int emac_set_channels(struct net_device *ndev, -+ struct ethtool_channels *ch) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ /* verify we have at least one channel in each direction */ -+ /* TODO: remove below check before sending to LKML */ -+ if (!ch->rx_count || !ch->tx_count) -+ return -EINVAL; -+ -+ /* Check if interface is up. Can change the num queues when -+ * the interface is down. -+ */ -+ if (netif_running(emac->ndev)) -+ return -EBUSY; -+ -+ emac->tx_ch_num = ch->tx_count; -+ /* highest channel number for management messaging on SR1 */ -+ if (emac->is_sr1) -+ emac->tx_ch_num++; -+ -+ return 0; -+} -+ -+const struct ethtool_ops icssg_ethtool_ops = { -+ .get_drvinfo = emac_get_drvinfo, -+ .get_msglevel = emac_get_msglevel, -+ .set_msglevel = emac_set_msglevel, -+ .get_sset_count = emac_get_sset_count, -+ .get_strings = emac_get_strings, -+ .get_ethtool_stats = emac_get_ethtool_stats, -+ -+ .get_channels = emac_get_channels, -+ .set_channels = emac_set_channels, -+ .get_link_ksettings = emac_get_link_ksettings, -+ .set_link_ksettings = emac_set_link_ksettings, -+ .get_link = ethtool_op_get_link, -+ .get_eee = emac_get_eee, -+ .set_eee = emac_set_eee, -+ .nway_reset = emac_nway_reset, -+}; -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -new file mode 100644 -index 000000000000..5a9b8aa41bb8 ---- /dev/null -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -0,0 +1,2226 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+/* Texas Instruments ICSSG Ethernet Driver -+ * -+ * Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/ -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "icssg_prueth.h" -+#include "icss_mii_rt.h" -+#include "k3-cppi-desc-pool.h" -+ -+#define PRUETH_MODULE_VERSION "0.1" -+#define PRUETH_MODULE_DESCRIPTION "PRUSS ICSSG Ethernet driver" -+ -+#define PRUETH_MIN_PKT_SIZE (VLAN_ETH_ZLEN) -+#define PRUETH_MAX_PKT_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) -+ -+/* Netif debug messages possible */ -+#define PRUETH_EMAC_DEBUG (NETIF_MSG_DRV | \ -+ NETIF_MSG_PROBE | \ -+ NETIF_MSG_LINK | \ -+ NETIF_MSG_TIMER | \ -+ NETIF_MSG_IFDOWN | \ -+ NETIF_MSG_IFUP | \ -+ NETIF_MSG_RX_ERR | \ -+ NETIF_MSG_TX_ERR | \ -+ NETIF_MSG_TX_QUEUED | \ -+ NETIF_MSG_INTR | \ -+ NETIF_MSG_TX_DONE | \ -+ NETIF_MSG_RX_STATUS | \ -+ NETIF_MSG_PKTDATA | \ -+ NETIF_MSG_HW | \ -+ NETIF_MSG_WOL) -+ -+#define prueth_napi_to_emac(napi) container_of(napi, struct prueth_emac, napi) -+ -+/* CTRLMMR_ICSSG_RGMII_CTRL register bits */ -+#define ICSSG_CTRL_RGMII_ID_MODE BIT(24) -+ -+static int debug_level = -1; -+module_param(debug_level, int, 0644); -+MODULE_PARM_DESC(debug_level, "PRUETH debug level (NETIF_MSG bits)"); -+ -+static void prueth_cleanup_rx_chns(struct prueth_emac *emac, -+ struct prueth_rx_chn *rx_chn, -+ int max_rflows) -+{ -+ if (rx_chn->rx_chn) -+ k3_udma_glue_release_rx_chn(rx_chn->rx_chn); -+ -+ if (rx_chn->desc_pool) -+ k3_cppi_desc_pool_destroy(rx_chn->desc_pool); -+} -+ -+static void prueth_cleanup_tx_chns(struct prueth_emac *emac) -+{ -+ int i; -+ -+ for (i = 0; i < emac->tx_ch_num; i++) { -+ struct prueth_tx_chn *tx_chn = &emac->tx_chns[i]; -+ -+ if (tx_chn->tx_chn) -+ k3_udma_glue_release_tx_chn(tx_chn->tx_chn); -+ -+ if (tx_chn->desc_pool) -+ k3_cppi_desc_pool_destroy(tx_chn->desc_pool); -+ -+ /* Assume prueth_cleanup_tx_chns() is called at the -+ * end after all channel resources are freed -+ */ -+ memset(tx_chn, 0, sizeof(*tx_chn)); -+ } -+} -+ -+static void prueth_ndev_del_tx_napi(struct prueth_emac *emac, int num) -+{ -+ int i; -+ -+ for (i = 0; i < num; i++) { -+ struct prueth_tx_chn *tx_chn = &emac->tx_chns[i]; -+ -+ if (tx_chn->irq) -+ free_irq(tx_chn->irq, tx_chn); -+ netif_napi_del(&tx_chn->napi_tx); -+ } -+} -+ -+static void prueth_xmit_free(struct prueth_tx_chn *tx_chn, -+ struct device *dev, -+ struct cppi5_host_desc_t *desc) -+{ -+ struct cppi5_host_desc_t *first_desc, *next_desc; -+ dma_addr_t buf_dma, next_desc_dma; -+ u32 buf_dma_len; -+ -+ first_desc = desc; -+ next_desc = first_desc; -+ -+ cppi5_hdesc_get_obuf(first_desc, &buf_dma, &buf_dma_len); -+ -+ dma_unmap_single(dev, buf_dma, buf_dma_len, -+ DMA_TO_DEVICE); -+ -+ next_desc_dma = cppi5_hdesc_get_next_hbdesc(first_desc); -+ while (next_desc_dma) { -+ next_desc = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, -+ next_desc_dma); -+ cppi5_hdesc_get_obuf(next_desc, &buf_dma, &buf_dma_len); -+ -+ dma_unmap_page(dev, buf_dma, buf_dma_len, -+ DMA_TO_DEVICE); -+ -+ next_desc_dma = cppi5_hdesc_get_next_hbdesc(next_desc); -+ -+ k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc); -+ } -+ -+ k3_cppi_desc_pool_free(tx_chn->desc_pool, first_desc); -+} -+ -+static int emac_tx_complete_packets(struct prueth_emac *emac, int chn, -+ int budget) -+{ -+ struct net_device *ndev = emac->ndev; -+ struct cppi5_host_desc_t *desc_tx; -+ struct device *dev = emac->prueth->dev; -+ struct netdev_queue *netif_txq; -+ struct prueth_tx_chn *tx_chn; -+ unsigned int total_bytes = 0; -+ struct sk_buff *skb; -+ dma_addr_t desc_dma; -+ int res, num_tx = 0; -+ void **swdata; -+ -+ tx_chn = &emac->tx_chns[chn]; -+ -+ while (budget--) { -+ res = k3_udma_glue_pop_tx_chn(tx_chn->tx_chn, &desc_dma); -+ if (res == -ENODATA) -+ break; -+ -+ /* teardown completion */ -+ if (cppi5_desc_is_tdcm(desc_dma)) { -+ if (atomic_dec_and_test(&emac->tdown_cnt)) -+ complete(&emac->tdown_complete); -+ break; -+ } -+ -+ desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, -+ desc_dma); -+ swdata = cppi5_hdesc_get_swdata(desc_tx); -+ -+ /* was this command's TX complete? */ -+ if (emac->is_sr1 && *(swdata) == emac->cmd_data) { -+ prueth_xmit_free(tx_chn, dev, desc_tx); -+ budget++; /* not a data packet */ -+ continue; -+ } -+ -+ skb = *(swdata); -+ prueth_xmit_free(tx_chn, dev, desc_tx); -+ -+ ndev = skb->dev; -+ ndev->stats.tx_packets++; -+ ndev->stats.tx_bytes += skb->len; -+ total_bytes += skb->len; -+ napi_consume_skb(skb, budget); -+ num_tx++; -+ } -+ -+ if (!num_tx) -+ return 0; -+ -+ netif_txq = netdev_get_tx_queue(ndev, chn); -+ netdev_tx_completed_queue(netif_txq, num_tx, total_bytes); -+ -+ if (netif_tx_queue_stopped(netif_txq)) { -+ /* If the TX queue was stopped, wake it now -+ * if we have enough room. -+ */ -+ __netif_tx_lock(netif_txq, smp_processor_id()); -+ if (netif_running(ndev) && -+ (k3_cppi_desc_pool_avail(tx_chn->desc_pool) >= -+ MAX_SKB_FRAGS)) -+ netif_tx_wake_queue(netif_txq); -+ __netif_tx_unlock(netif_txq); -+ } -+ -+ return num_tx; -+} -+ -+static int emac_napi_tx_poll(struct napi_struct *napi_tx, int budget) -+{ -+ struct prueth_tx_chn *tx_chn = prueth_napi_to_tx_chn(napi_tx); -+ struct prueth_emac *emac = tx_chn->emac; -+ int num_tx_packets; -+ -+ num_tx_packets = emac_tx_complete_packets(emac, tx_chn->id, budget); -+ -+ if (num_tx_packets < budget) { -+ napi_complete(napi_tx); -+ enable_irq(tx_chn->irq); -+ } -+ -+ return num_tx_packets; -+} -+ -+static irqreturn_t prueth_tx_irq(int irq, void *dev_id) -+{ -+ struct prueth_tx_chn *tx_chn = dev_id; -+ -+ disable_irq_nosync(irq); -+ napi_schedule(&tx_chn->napi_tx); -+ -+ return IRQ_HANDLED; -+} -+ -+static int prueth_ndev_add_tx_napi(struct prueth_emac *emac) -+{ -+ struct prueth *prueth = emac->prueth; -+ int i, ret; -+ -+ for (i = 0; i < emac->tx_ch_num; i++) { -+ struct prueth_tx_chn *tx_chn = &emac->tx_chns[i]; -+ -+ netif_tx_napi_add(emac->ndev, &tx_chn->napi_tx, -+ emac_napi_tx_poll, NAPI_POLL_WEIGHT); -+ ret = request_irq(tx_chn->irq, prueth_tx_irq, -+ IRQF_TRIGGER_HIGH, tx_chn->name, -+ tx_chn); -+ if (ret) { -+ netif_napi_del(&tx_chn->napi_tx); -+ dev_err(prueth->dev, "unable to request TX IRQ %d\n", -+ tx_chn->irq); -+ goto fail; -+ } -+ } -+ -+ return 0; -+fail: -+ prueth_ndev_del_tx_napi(emac, i); -+ return ret; -+} -+ -+static int prueth_init_tx_chns(struct prueth_emac *emac) -+{ -+ struct net_device *ndev = emac->ndev; -+ struct device *dev = emac->prueth->dev; -+ struct k3_udma_glue_tx_channel_cfg tx_cfg; -+ static const struct k3_ring_cfg ring_cfg = { -+ .elm_size = K3_RINGACC_RING_ELSIZE_8, -+ .mode = K3_RINGACC_RING_MODE_RING, -+ .flags = 0, -+ .size = PRUETH_MAX_TX_DESC, -+ }; -+ int ret, slice, i; -+ u32 hdesc_size; -+ -+ slice = prueth_emac_slice(emac); -+ if (slice < 0) -+ return slice; -+ -+ init_completion(&emac->tdown_complete); -+ -+ hdesc_size = cppi5_hdesc_calc_size(true, PRUETH_NAV_PS_DATA_SIZE, -+ PRUETH_NAV_SW_DATA_SIZE); -+ memset(&tx_cfg, 0, sizeof(tx_cfg)); -+ tx_cfg.swdata_size = PRUETH_NAV_SW_DATA_SIZE; -+ tx_cfg.tx_cfg = ring_cfg; -+ tx_cfg.txcq_cfg = ring_cfg; -+ -+ for (i = 0; i < emac->tx_ch_num; i++) { -+ struct prueth_tx_chn *tx_chn = &emac->tx_chns[i]; -+ -+ /* To differentiate channels for SLICE0 vs SLICE1 */ -+ snprintf(tx_chn->name, sizeof(tx_chn->name), -+ "tx%d-%d", slice, i); -+ -+ tx_chn->emac = emac; -+ tx_chn->id = i; -+ tx_chn->descs_num = PRUETH_MAX_TX_DESC; -+ tx_chn->desc_pool = -+ k3_cppi_desc_pool_create_name(dev, -+ tx_chn->descs_num, -+ hdesc_size, -+ tx_chn->name); -+ if (IS_ERR(tx_chn->desc_pool)) { -+ ret = PTR_ERR(tx_chn->desc_pool); -+ tx_chn->desc_pool = NULL; -+ netdev_err(ndev, "Failed to create tx pool: %d\n", ret); -+ goto fail; -+ } -+ -+ tx_chn->tx_chn = -+ k3_udma_glue_request_tx_chn(dev, tx_chn->name, -+ &tx_cfg); -+ if (IS_ERR(tx_chn->tx_chn)) { -+ ret = PTR_ERR(tx_chn->tx_chn); -+ tx_chn->tx_chn = NULL; -+ netdev_err(ndev, -+ "Failed to request tx dma ch: %d\n", ret); -+ goto fail; -+ } -+ -+ tx_chn->irq = k3_udma_glue_tx_get_irq(tx_chn->tx_chn); -+ if (tx_chn->irq <= 0) { -+ ret = -EINVAL; -+ netdev_err(ndev, "failed to get tx irq\n"); -+ goto fail; -+ } -+ -+ snprintf(tx_chn->name, sizeof(tx_chn->name), "%s-tx%d", -+ dev_name(dev), tx_chn->id); -+ } -+ -+ return 0; -+ -+fail: -+ prueth_cleanup_tx_chns(emac); -+ return ret; -+} -+ -+static int prueth_init_rx_chns(struct prueth_emac *emac, -+ struct prueth_rx_chn *rx_chn, -+ char *name, u32 max_rflows, -+ u32 max_desc_num) -+{ -+ struct net_device *ndev = emac->ndev; -+ struct device *dev = emac->prueth->dev; -+ struct k3_udma_glue_rx_channel_cfg rx_cfg; -+ u32 fdqring_id; -+ u32 hdesc_size; -+ int i, ret = 0, slice; -+ -+ slice = prueth_emac_slice(emac); -+ if (slice < 0) -+ return slice; -+ -+ /* To differentiate channels for SLICE0 vs SLICE1 */ -+ snprintf(rx_chn->name, sizeof(rx_chn->name), "%s%d", name, slice); -+ -+ hdesc_size = cppi5_hdesc_calc_size(true, PRUETH_NAV_PS_DATA_SIZE, -+ PRUETH_NAV_SW_DATA_SIZE); -+ memset(&rx_cfg, 0, sizeof(rx_cfg)); -+ rx_cfg.swdata_size = PRUETH_NAV_SW_DATA_SIZE; -+ rx_cfg.flow_id_num = max_rflows; -+ rx_cfg.flow_id_base = -1; /* udmax will auto select flow id base */ -+ -+ /* init all flows */ -+ rx_chn->dev = dev; -+ rx_chn->descs_num = max_desc_num; -+ rx_chn->desc_pool = k3_cppi_desc_pool_create_name(dev, -+ rx_chn->descs_num, -+ hdesc_size, -+ rx_chn->name); -+ if (IS_ERR(rx_chn->desc_pool)) { -+ ret = PTR_ERR(rx_chn->desc_pool); -+ rx_chn->desc_pool = NULL; -+ netdev_err(ndev, "Failed to create rx pool: %d\n", ret); -+ goto fail; -+ } -+ -+ rx_chn->rx_chn = k3_udma_glue_request_rx_chn(dev, rx_chn->name, -+ &rx_cfg); -+ if (IS_ERR(rx_chn->rx_chn)) { -+ ret = PTR_ERR(rx_chn->rx_chn); -+ rx_chn->rx_chn = NULL; -+ netdev_err(ndev, "Failed to request rx dma ch: %d\n", ret); -+ goto fail; -+ } -+ -+ if (!strncmp(name, "rxmgm", 5)) { -+ emac->rx_mgm_flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn); -+ netdev_dbg(ndev, "mgm flow id base = %d\n", -+ emac->rx_mgm_flow_id_base); -+ } else { -+ emac->rx_flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn); -+ netdev_dbg(ndev, "flow id base = %d\n", -+ emac->rx_flow_id_base); -+ } -+ -+ fdqring_id = K3_RINGACC_RING_ID_ANY; -+ for (i = 0; i < rx_cfg.flow_id_num; i++) { -+ struct k3_ring_cfg rxring_cfg = { -+ .elm_size = K3_RINGACC_RING_ELSIZE_8, -+ .mode = K3_RINGACC_RING_MODE_MESSAGE, -+ .flags = 0, -+ }; -+ struct k3_ring_cfg fdqring_cfg = { -+ .elm_size = K3_RINGACC_RING_ELSIZE_8, -+ .mode = K3_RINGACC_RING_MODE_MESSAGE, -+ .flags = K3_RINGACC_RING_SHARED, -+ }; -+ struct k3_udma_glue_rx_flow_cfg rx_flow_cfg = { -+ .rx_cfg = rxring_cfg, -+ .rxfdq_cfg = fdqring_cfg, -+ .ring_rxq_id = K3_RINGACC_RING_ID_ANY, -+ .src_tag_lo_sel = -+ K3_UDMA_GLUE_SRC_TAG_LO_USE_REMOTE_SRC_TAG, -+ }; -+ -+ rx_flow_cfg.ring_rxfdq0_id = fdqring_id; -+ rx_flow_cfg.rx_cfg.size = max_desc_num; -+ rx_flow_cfg.rxfdq_cfg.size = max_desc_num; -+ -+ ret = k3_udma_glue_rx_flow_init(rx_chn->rx_chn, -+ i, &rx_flow_cfg); -+ if (ret) { -+ netdev_err(ndev, "Failed to init rx flow%d %d\n", -+ i, ret); -+ goto fail; -+ } -+ if (!i) -+ fdqring_id = k3_udma_glue_rx_flow_get_fdq_id(rx_chn->rx_chn, -+ i); -+ rx_chn->irq[i] = k3_udma_glue_rx_get_irq(rx_chn->rx_chn, i); -+ if (rx_chn->irq[i] <= 0) { -+ netdev_err(ndev, "Failed to get rx dma irq"); -+ goto fail; -+ } -+ } -+ -+ return 0; -+ -+fail: -+ prueth_cleanup_rx_chns(emac, rx_chn, max_rflows); -+ return ret; -+} -+ -+static int prueth_dma_rx_push(struct prueth_emac *emac, -+ struct sk_buff *skb, -+ struct prueth_rx_chn *rx_chn) -+{ -+ struct cppi5_host_desc_t *desc_rx; -+ struct device *dev = emac->prueth->dev; -+ struct net_device *ndev = emac->ndev; -+ dma_addr_t desc_dma; -+ dma_addr_t buf_dma; -+ u32 pkt_len = skb_tailroom(skb); -+ void **swdata; -+ -+ desc_rx = k3_cppi_desc_pool_alloc(rx_chn->desc_pool); -+ if (!desc_rx) { -+ netdev_err(ndev, "rx push: failed to allocate descriptor\n"); -+ return -ENOMEM; -+ } -+ desc_dma = k3_cppi_desc_pool_virt2dma(rx_chn->desc_pool, desc_rx); -+ -+ buf_dma = dma_map_single(dev, skb->data, pkt_len, DMA_FROM_DEVICE); -+ if (unlikely(dma_mapping_error(dev, buf_dma))) { -+ k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); -+ netdev_err(ndev, "rx push: failed to map rx pkt buffer\n"); -+ return -EINVAL; -+ } -+ -+ cppi5_hdesc_init(desc_rx, CPPI5_INFO0_HDESC_EPIB_PRESENT, -+ PRUETH_NAV_PS_DATA_SIZE); -+ cppi5_hdesc_attach_buf(desc_rx, 0, 0, buf_dma, skb_tailroom(skb)); -+ -+ swdata = cppi5_hdesc_get_swdata(desc_rx); -+ *swdata = skb; -+ -+ return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, 0, -+ desc_rx, desc_dma); -+} -+ -+static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) -+{ -+ struct prueth_rx_chn *rx_chn = &emac->rx_chns; -+ struct device *dev = emac->prueth->dev; -+ struct net_device *ndev = emac->ndev; -+ struct cppi5_host_desc_t *desc_rx; -+ dma_addr_t desc_dma, buf_dma; -+ u32 buf_dma_len, pkt_len, port_id = 0; -+ int ret; -+ void **swdata; -+ struct sk_buff *skb, *new_skb; -+ u32 *psdata; -+ -+ ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma); -+ if (ret) { -+ if (ret != -ENODATA) -+ netdev_err(ndev, "rx pop: failed: %d\n", ret); -+ return ret; -+ } -+ -+ if (cppi5_desc_is_tdcm(desc_dma)) /* Teardown ? */ -+ return 0; -+ -+ desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma); -+ -+ swdata = cppi5_hdesc_get_swdata(desc_rx); -+ skb = *swdata; -+ -+ psdata = cppi5_hdesc_get_psdata(desc_rx); -+ -+ cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); -+ pkt_len = cppi5_hdesc_get_pktlen(desc_rx); -+ /* firmware adds 4 CRC bytes, strip them */ -+ pkt_len -= 4; -+ cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL); -+ -+ dma_unmap_single(dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE); -+ k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); -+ -+ skb->dev = ndev; -+ if (!netif_running(skb->dev)) { -+ dev_kfree_skb_any(skb); -+ return 0; -+ } -+ -+ new_skb = netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE); -+ /* if allocation fails we drop the packet but push the -+ * descriptor back to the ring with old skb to prevent a stall -+ */ -+ if (!new_skb) { -+ ndev->stats.rx_dropped++; -+ new_skb = skb; -+ } else { -+ /* send the filled skb up the n/w stack */ -+ skb_put(skb, pkt_len); -+ skb->protocol = eth_type_trans(skb, ndev); -+ netif_receive_skb(skb); -+ ndev->stats.rx_bytes += pkt_len; -+ ndev->stats.rx_packets++; -+ } -+ -+ /* queue another RX DMA */ -+ ret = prueth_dma_rx_push(emac, new_skb, &emac->rx_chns); -+ if (WARN_ON(ret < 0)) { -+ dev_kfree_skb_any(new_skb); -+ ndev->stats.rx_errors++; -+ ndev->stats.rx_dropped++; -+ } -+ -+ return ret; -+} -+ -+static void prueth_rx_cleanup(void *data, dma_addr_t desc_dma) -+{ -+ struct prueth_rx_chn *rx_chn = data; -+ struct cppi5_host_desc_t *desc_rx; -+ struct sk_buff *skb; -+ dma_addr_t buf_dma; -+ u32 buf_dma_len; -+ void **swdata; -+ -+ desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma); -+ swdata = cppi5_hdesc_get_swdata(desc_rx); -+ skb = *swdata; -+ cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); -+ -+ dma_unmap_single(rx_chn->dev, buf_dma, buf_dma_len, -+ DMA_FROM_DEVICE); -+ k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); -+ -+ dev_kfree_skb_any(skb); -+} -+ -+/* TODO: Convert this to use worker/workqueue mechanism to serialize the -+ * request to firmware -+ */ -+static int emac_send_command_sr1(struct prueth_emac *emac, u32 cmd) -+{ -+ struct device *dev = emac->prueth->dev; -+ dma_addr_t desc_dma, buf_dma; -+ struct prueth_tx_chn *tx_chn; -+ struct cppi5_host_desc_t *first_desc; -+ int ret = 0; -+ u32 *epib; -+ u32 *data = emac->cmd_data; -+ u32 pkt_len = sizeof(emac->cmd_data); -+ void **swdata; -+ -+ netdev_dbg(emac->ndev, "Sending cmd %x\n", cmd); -+ -+ /* only one command at a time allowed to firmware */ -+ mutex_lock(&emac->cmd_lock); -+ data[0] = cpu_to_le32(cmd); -+ -+ /* Map the linear buffer */ -+ buf_dma = dma_map_single(dev, data, pkt_len, DMA_TO_DEVICE); -+ if (dma_mapping_error(dev, buf_dma)) { -+ netdev_err(emac->ndev, "cmd %x: failed to map cmd buffer\n", cmd); -+ ret = -EINVAL; -+ goto err_unlock; -+ } -+ -+ /* highest priority channel for management messages */ -+ tx_chn = &emac->tx_chns[emac->tx_ch_num - 1]; -+ -+ first_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool); -+ if (!first_desc) { -+ netdev_err(emac->ndev, "cmd %x: failed to allocate descriptor\n", cmd); -+ dma_unmap_single(dev, buf_dma, pkt_len, DMA_TO_DEVICE); -+ ret = -ENOMEM; -+ goto err_unlock; -+ } -+ -+ cppi5_hdesc_init(first_desc, CPPI5_INFO0_HDESC_EPIB_PRESENT, -+ PRUETH_NAV_PS_DATA_SIZE); -+ cppi5_hdesc_set_pkttype(first_desc, PRUETH_PKT_TYPE_CMD); -+ epib = first_desc->epib; -+ epib[0] = 0; -+ epib[1] = 0; -+ -+ cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len); -+ swdata = cppi5_hdesc_get_swdata(first_desc); -+ *swdata = data; -+ -+ cppi5_hdesc_set_pktlen(first_desc, pkt_len); -+ desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, first_desc); -+ -+ /* send command */ -+ reinit_completion(&emac->cmd_complete); -+ ret = k3_udma_glue_push_tx_chn(tx_chn->tx_chn, first_desc, desc_dma); -+ if (ret) { -+ netdev_err(emac->ndev, "cmd %x: push failed: %d\n", cmd, ret); -+ goto free_desc; -+ } -+ ret = wait_for_completion_timeout(&emac->cmd_complete, msecs_to_jiffies(100)); -+ if (!ret) -+ netdev_err(emac->ndev, "cmd %x: completion timeout\n", cmd); -+ -+ mutex_unlock(&emac->cmd_lock); -+ -+ return ret; -+free_desc: -+ prueth_xmit_free(tx_chn, dev, first_desc); -+err_unlock: -+ mutex_unlock(&emac->cmd_lock); -+ -+ return ret; -+} -+ -+static void emac_change_port_speed_duplex(struct prueth_emac *emac, -+ bool full_duplex, int speed) -+{ -+ u32 cmd = ICSSG_PSTATE_SPEED_DUPLEX_CMD, val; -+ struct prueth *prueth = emac->prueth; -+ int slice = prueth_emac_slice(emac); -+ -+ /* only 100M and 1G and full duplex supported for now */ -+ if (!(full_duplex && (speed == SPEED_1000 || speed == SPEED_100))) -+ return; -+ -+ /* FIXME for SR2.0 */ -+ if (!emac->is_sr1) -+ return; -+ -+ val = icssg_rgmii_get_speed(prueth->miig_rt, slice); -+ /* firmware expects full duplex settings in bit 2-1 */ -+ val <<= 1; -+ cmd |= val; -+ -+ val = icssg_rgmii_get_fullduplex(prueth->miig_rt, slice); -+ /* firmware expects full duplex settings in bit 3 */ -+ val <<= 3; -+ cmd |= val; -+ -+ emac_send_command_sr1(emac, cmd); -+} -+ -+static int emac_shutdown(struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ /* FIXME for SR2.0 */ -+ if (!emac->is_sr1) -+ return 0; -+ -+ return emac_send_command_sr1(emac, ICSSG_SHUTDOWN_CMD); -+} -+ -+/** -+ * emac_ndo_start_xmit - EMAC Transmit function -+ * @skb: SKB pointer -+ * @ndev: EMAC network adapter -+ * -+ * Called by the system to transmit a packet - we queue the packet in -+ * EMAC hardware transmit queue -+ * Doesn't wait for completion we'll check for TX completion in -+ * emac_tx_complete_packets(). -+ * -+ * Returns success(NETDEV_TX_OK) or error code (typically out of descs) -+ */ -+static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct device *dev = emac->prueth->dev; -+ struct cppi5_host_desc_t *first_desc, *next_desc, *cur_desc; -+ struct netdev_queue *netif_txq; -+ struct prueth_tx_chn *tx_chn; -+ dma_addr_t desc_dma, buf_dma; -+ int i, ret = 0, q_idx; -+ void **swdata; -+ u32 pkt_len; -+ u32 *epib; -+ -+ pkt_len = skb_headlen(skb); -+ q_idx = skb_get_queue_mapping(skb); -+ -+ tx_chn = &emac->tx_chns[q_idx]; -+ netif_txq = netdev_get_tx_queue(ndev, q_idx); -+ -+ /* Map the linear buffer */ -+ buf_dma = dma_map_single(dev, skb->data, pkt_len, DMA_TO_DEVICE); -+ if (dma_mapping_error(dev, buf_dma)) { -+ netdev_err(ndev, "tx: failed to map skb buffer\n"); -+ ret = -EINVAL; -+ goto drop_stop_q; -+ } -+ -+ first_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool); -+ if (!first_desc) { -+ netdev_dbg(ndev, "tx: failed to allocate descriptor\n"); -+ dma_unmap_single(dev, buf_dma, pkt_len, DMA_TO_DEVICE); -+ ret = -ENOMEM; -+ goto drop_stop_q_busy; -+ } -+ -+ cppi5_hdesc_init(first_desc, CPPI5_INFO0_HDESC_EPIB_PRESENT, -+ PRUETH_NAV_PS_DATA_SIZE); -+ cppi5_hdesc_set_pkttype(first_desc, 0); -+ epib = first_desc->epib; -+ epib[0] = 0; -+ epib[1] = 0; -+ -+ /* set dst tag to indicate internal qid at the firmware which is at -+ * bit8..bit15 -+ */ -+ cppi5_desc_set_tags_ids(&first_desc->hdr, 0, (q_idx << 8)); -+ cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len); -+ swdata = cppi5_hdesc_get_swdata(first_desc); -+ *swdata = skb; -+ -+ if (!skb_is_nonlinear(skb)) -+ goto tx_push; -+ -+ /* Handle the case where skb is fragmented in pages */ -+ cur_desc = first_desc; -+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { -+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; -+ u32 frag_size = skb_frag_size(frag); -+ -+ next_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool); -+ if (!next_desc) { -+ netdev_err(ndev, -+ "tx: failed to allocate frag. descriptor\n"); -+ ret = -ENOMEM; -+ goto drop_free_descs; -+ } -+ -+ buf_dma = skb_frag_dma_map(dev, frag, 0, frag_size, -+ DMA_TO_DEVICE); -+ if (dma_mapping_error(dev, buf_dma)) { -+ netdev_err(ndev, "tx: Failed to map skb page\n"); -+ k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc); -+ ret = -EINVAL; -+ goto drop_free_descs; -+ } -+ -+ cppi5_hdesc_reset_hbdesc(next_desc); -+ cppi5_hdesc_attach_buf(next_desc, -+ buf_dma, frag_size, buf_dma, frag_size); -+ -+ desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, -+ next_desc); -+ cppi5_hdesc_link_hbdesc(cur_desc, desc_dma); -+ -+ pkt_len += frag_size; -+ cur_desc = next_desc; -+ } -+ WARN_ON(pkt_len != skb->len); -+ -+tx_push: -+ /* report bql before sending packet */ -+ netdev_tx_sent_queue(netif_txq, pkt_len); -+ -+ cppi5_hdesc_set_pktlen(first_desc, pkt_len); -+ desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, first_desc); -+ /* cppi5_desc_dump(first_desc, 64); */ -+ -+ skb_tx_timestamp(skb); /* SW timestamp if SKBTX_IN_PROGRESS not set */ -+ ret = k3_udma_glue_push_tx_chn(tx_chn->tx_chn, first_desc, desc_dma); -+ if (ret) { -+ netdev_err(ndev, "tx: push failed: %d\n", ret); -+ goto drop_free_descs; -+ } -+ -+ if (k3_cppi_desc_pool_avail(tx_chn->desc_pool) < MAX_SKB_FRAGS) { -+ netif_tx_stop_queue(netif_txq); -+ /* Barrier, so that stop_queue visible to other cpus */ -+ smp_mb__after_atomic(); -+ -+ if (k3_cppi_desc_pool_avail(tx_chn->desc_pool) >= -+ MAX_SKB_FRAGS) -+ netif_tx_wake_queue(netif_txq); -+ } -+ -+ return NETDEV_TX_OK; -+ -+drop_free_descs: -+ prueth_xmit_free(tx_chn, dev, first_desc); -+drop_stop_q: -+ netif_tx_stop_queue(netif_txq); -+ dev_kfree_skb_any(skb); -+ -+ /* error */ -+ ndev->stats.tx_dropped++; -+ netdev_err(ndev, "tx: error: %d\n", ret); -+ -+ return ret; -+ -+drop_stop_q_busy: -+ netif_tx_stop_queue(netif_txq); -+ return NETDEV_TX_BUSY; -+} -+ -+static void prueth_tx_cleanup(void *data, dma_addr_t desc_dma) -+{ -+ struct prueth_tx_chn *tx_chn = data; -+ struct prueth_emac *emac = tx_chn->emac; -+ struct cppi5_host_desc_t *desc_tx; -+ struct sk_buff *skb; -+ void **swdata; -+ -+ desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma); -+ swdata = cppi5_hdesc_get_swdata(desc_tx); -+ skb = *(swdata); -+ prueth_xmit_free(tx_chn, emac->prueth->dev, desc_tx); -+ -+ dev_kfree_skb_any(skb); -+} -+ -+/* get one packet from requested flow_id -+ * -+ * Returns skb pointer if packet found else NULL -+ * Caller must free the returned skb. -+ */ -+static struct sk_buff *prueth_process_rx_mgm(struct prueth_emac *emac, -+ u32 flow_id) -+{ -+ struct prueth_rx_chn *rx_chn = &emac->rx_mgm_chn; -+ struct device *dev = emac->prueth->dev; -+ struct net_device *ndev = emac->ndev; -+ struct cppi5_host_desc_t *desc_rx; -+ dma_addr_t desc_dma, buf_dma; -+ u32 buf_dma_len, pkt_len; -+ int ret; -+ void **swdata; -+ struct sk_buff *skb, *new_skb; -+ -+ ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma); -+ if (ret) { -+ if (ret != -ENODATA) -+ netdev_err(ndev, "rx mgm pop: failed: %d\n", ret); -+ return NULL; -+ } -+ -+ if (cppi5_desc_is_tdcm(desc_dma)) /* Teardown */ -+ return NULL; -+ -+ desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma); -+ -+ /* Fix FW bug about incorrect PSDATA size */ -+ if (cppi5_hdesc_get_psdata_size(desc_rx) != PRUETH_NAV_PS_DATA_SIZE) { -+ cppi5_hdesc_update_psdata_size(desc_rx, -+ PRUETH_NAV_PS_DATA_SIZE); -+ } -+ -+ swdata = cppi5_hdesc_get_swdata(desc_rx); -+ skb = *swdata; -+ cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); -+ pkt_len = cppi5_hdesc_get_pktlen(desc_rx); -+ -+ dma_unmap_single(dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE); -+ k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); -+ -+ new_skb = netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE); -+ /* if allocation fails we drop the packet but push the -+ * descriptor back to the ring with old skb to prevent a stall -+ */ -+ if (!new_skb) { -+ netdev_err(ndev, -+ "skb alloc failed, dropped mgm pkt from flow %d\n", -+ flow_id); -+ new_skb = skb; -+ skb = NULL; /* return NULL */ -+ } else { -+ /* return the filled skb */ -+ skb_put(skb, pkt_len); -+ } -+ -+ /* queue another DMA */ -+ ret = prueth_dma_rx_push(emac, new_skb, &emac->rx_mgm_chn); -+ if (WARN_ON(ret < 0)) -+ dev_kfree_skb_any(new_skb); -+ -+ return skb; -+} -+ -+static irqreturn_t prueth_rx_mgm_ts_thread(int irq, void *dev_id) -+{ -+ struct prueth_emac *emac = dev_id; -+ struct sk_buff *skb; -+ -+ skb = prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_TIMESTAMP); -+ if (!skb) -+ return IRQ_NONE; -+ -+ dev_kfree_skb_any(skb); -+ -+ return IRQ_HANDLED; -+} -+ -+static irqreturn_t prueth_rx_mgm_rsp_thread(int irq, void *dev_id) -+{ -+ struct prueth_emac *emac = dev_id; -+ struct sk_buff *skb; -+ u32 rsp; -+ -+ skb = prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_RESPONSE); -+ if (!skb) -+ return IRQ_NONE; -+ -+ /* Process command response */ -+ rsp = le32_to_cpu(*(u32 *)skb->data); -+ if ((rsp & 0xffff0000) == ICSSG_SHUTDOWN_CMD) { -+ netdev_dbg(emac->ndev, -+ "f/w Shutdown cmd resp %x\n", rsp); -+ complete(&emac->cmd_complete); -+ } else if ((rsp & 0xffff0000) == -+ ICSSG_PSTATE_SPEED_DUPLEX_CMD) { -+ netdev_dbg(emac->ndev, -+ "f/w Speed/Duplex cmd rsp %x\n", -+ rsp); -+ complete(&emac->cmd_complete); -+ } -+ -+ dev_kfree_skb_any(skb); -+ -+ return IRQ_HANDLED; -+} -+ -+static irqreturn_t prueth_rx_irq(int irq, void *dev_id) -+{ -+ struct prueth_emac *emac = dev_id; -+ -+ disable_irq_nosync(irq); -+ napi_schedule(&emac->napi_rx); -+ -+ return IRQ_HANDLED; -+} -+ -+static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac) -+{ -+ struct device *dev = prueth->dev; -+ int slice, ret; -+ -+ slice = prueth_emac_slice(emac); -+ if (slice < 0) { -+ netdev_err(emac->ndev, "invalid port\n"); -+ return -EINVAL; -+ } -+ -+ /* Set Load time configuration */ -+ if (emac->is_sr1) { -+ icssg_config_sr1(prueth, emac, slice); -+ } else { -+ ret = icssg_config_sr2(prueth, emac, slice); -+ if (ret) -+ return ret; -+ } -+ -+ ret = rproc_boot(prueth->pru[slice]); -+ if (ret) { -+ dev_err(dev, "failed to boot PRU%d: %d\n", slice, ret); -+ return -EINVAL; -+ } -+ -+ ret = rproc_boot(prueth->rtu[slice]); -+ if (ret) { -+ dev_err(dev, "failed to boot RTU%d: %d\n", slice, ret); -+ goto halt_pru; -+ } -+ -+ if (emac->is_sr1) -+ goto done; -+ -+ ret = rproc_boot(prueth->txpru[slice]); -+ if (ret) { -+ dev_err(dev, "failed to boot TX_PRU%d: %d\n", slice, ret); -+ goto halt_rtu; -+ } -+ -+done: -+ emac->fw_running = 1; -+ return 0; -+ -+halt_rtu: -+ rproc_shutdown(prueth->rtu[slice]); -+ -+halt_pru: -+ rproc_shutdown(prueth->pru[slice]); -+ -+ return ret; -+} -+ -+static void prueth_emac_stop(struct prueth_emac *emac) -+{ -+ struct prueth *prueth = emac->prueth; -+ int slice; -+ -+ switch (emac->port_id) { -+ case PRUETH_PORT_MII0: -+ slice = ICSS_SLICE0; -+ break; -+ case PRUETH_PORT_MII1: -+ slice = ICSS_SLICE1; -+ break; -+ default: -+ netdev_err(emac->ndev, "invalid port\n"); -+ return; -+ } -+ -+ emac->fw_running = 0; -+ if (!emac->is_sr1) -+ rproc_shutdown(prueth->txpru[slice]); -+ rproc_shutdown(prueth->rtu[slice]); -+ rproc_shutdown(prueth->pru[slice]); -+} -+ -+/* called back by PHY layer if there is change in link state of hw port*/ -+static void emac_adjust_link(struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct phy_device *phydev = emac->phydev; -+ bool gig_en = false, full_duplex = false; -+ struct prueth *prueth = emac->prueth; -+ int slice = prueth_emac_slice(emac); -+ bool new_state = false; -+ unsigned long flags; -+ -+ if (phydev->link) { -+ /* check the mode of operation - full/half duplex */ -+ if (phydev->duplex != emac->duplex) { -+ new_state = true; -+ emac->duplex = phydev->duplex; -+ } -+ if (phydev->speed != emac->speed) { -+ new_state = true; -+ emac->speed = phydev->speed; -+ } -+ if (!emac->link) { -+ new_state = true; -+ emac->link = 1; -+ } -+ } else if (emac->link) { -+ new_state = true; -+ emac->link = 0; -+ /* defaults for no link */ -+ -+ /* f/w should support 100 & 1000 */ -+ emac->speed = SPEED_1000; -+ -+ /* half duplex may not be supported by f/w */ -+ emac->duplex = DUPLEX_FULL; -+ } -+ -+ if (new_state) { -+ phy_print_status(phydev); -+ -+ /* update RGMII and MII configuration based on PHY negotiated -+ * values -+ */ -+ spin_lock_irqsave(&emac->lock, flags); -+ if (emac->link) { -+ if (phydev->speed == SPEED_1000) -+ gig_en = true; -+ -+ if (phydev->duplex == DUPLEX_FULL) -+ full_duplex = true; -+ /* Set the RGMII cfg for gig en and full duplex */ -+ icssg_update_rgmii_cfg(prueth->miig_rt, gig_en, -+ full_duplex, slice); -+ -+ /* update the Tx IPG based on 100M/1G speed */ -+ icssg_config_ipg(prueth, emac->speed, slice); -+ } -+ spin_unlock_irqrestore(&emac->lock, flags); -+ -+ /* send command to firmware to change speed and duplex -+ * setting when link is up. -+ */ -+ if (emac->link) -+ emac_change_port_speed_duplex(emac, full_duplex, -+ emac->speed); -+ } -+ -+ if (emac->link) { -+ /* link ON */ -+ netif_carrier_on(ndev); -+ /* reactivate the transmit queue */ -+ netif_tx_wake_all_queues(ndev); -+ } else { -+ /* link OFF */ -+ netif_carrier_off(ndev); -+ netif_tx_stop_all_queues(ndev); -+ } -+} -+ -+static int emac_napi_rx_poll(struct napi_struct *napi_rx, int budget) -+{ -+ struct prueth_emac *emac = prueth_napi_to_emac(napi_rx); -+ int num_rx = 0; -+ int flow = emac->is_sr1 ? -+ PRUETH_MAX_RX_FLOWS_SR1 : PRUETH_MAX_RX_FLOWS_SR2; -+ int rx_flow = emac->is_sr1 ? -+ PRUETH_RX_FLOW_DATA_SR1 : PRUETH_RX_FLOW_DATA_SR2; -+ int cur_budget; -+ int ret; -+ -+ while (flow--) { -+ cur_budget = budget - num_rx; -+ -+ while (cur_budget--) { -+ ret = emac_rx_packet(emac, flow); -+ if (ret) -+ break; -+ num_rx++; -+ } -+ -+ if (num_rx >= budget) -+ break; -+ } -+ -+ if (num_rx < budget) { -+ napi_complete(napi_rx); -+ enable_irq(emac->rx_chns.irq[rx_flow]); -+ } -+ -+ return num_rx; -+} -+ -+static int prueth_prepare_rx_chan(struct prueth_emac *emac, -+ struct prueth_rx_chn *chn, -+ int buf_size) -+{ -+ struct sk_buff *skb; -+ int i, ret; -+ -+ for (i = 0; i < chn->descs_num; i++) { -+ skb = __netdev_alloc_skb_ip_align(NULL, buf_size, GFP_KERNEL); -+ if (!skb) -+ return -ENOMEM; -+ -+ ret = prueth_dma_rx_push(emac, skb, chn); -+ if (ret < 0) { -+ netdev_err(emac->ndev, -+ "cannot submit skb for rx chan %s ret %d\n", -+ chn->name, ret); -+ kfree_skb(skb); -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+static void prueth_reset_tx_chan(struct prueth_emac *emac, int ch_num, -+ bool free_skb) -+{ -+ int i; -+ -+ for (i = 0; i < ch_num; i++) { -+ if (free_skb) -+ k3_udma_glue_reset_tx_chn(emac->tx_chns[i].tx_chn, -+ &emac->tx_chns[i], -+ prueth_tx_cleanup); -+ k3_udma_glue_disable_tx_chn(emac->tx_chns[i].tx_chn); -+ } -+} -+ -+static void prueth_reset_rx_chan(struct prueth_rx_chn *chn, -+ int num_flows, bool disable) -+{ -+ int i; -+ -+ for (i = 0; i < num_flows; i++) -+ k3_udma_glue_reset_rx_chn(chn->rx_chn, i, chn, -+ prueth_rx_cleanup, !!i); -+ if (disable) -+ k3_udma_glue_disable_rx_chn(chn->rx_chn); -+} -+ -+/** -+ * emac_ndo_open - EMAC device open -+ * @ndev: network adapter device -+ * -+ * Called when system wants to start the interface. -+ * -+ * Returns 0 for a successful open, or appropriate error code -+ */ -+static int emac_ndo_open(struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ int ret, i, num_data_chn = emac->tx_ch_num; -+ struct prueth *prueth = emac->prueth; -+ int slice = prueth_emac_slice(emac); -+ struct device *dev = prueth->dev; -+ int max_rx_flows; -+ int rx_flow; -+ -+ /* clear SMEM of this slice */ -+ if (emac->is_sr1) { -+ memset_io(prueth->shram.va + slice * ICSSG_CONFIG_OFFSET_SLICE1, -+ 0, ICSSG_CONFIG_OFFSET_SLICE1); -+ /* For SR1, high priority channel is used exclusively for -+ * management messages. Do reduce number of data channels. -+ */ -+ num_data_chn--; -+ } -+ -+ /* set h/w MAC as user might have re-configured */ -+ ether_addr_copy(emac->mac_addr, ndev->dev_addr); -+ -+ icssg_class_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); -+ if (!emac->is_sr1) -+ icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); -+ -+ icssg_class_default(prueth->miig_rt, slice, 0, emac->is_sr1); -+ -+ netif_carrier_off(ndev); -+ -+ /* Notify the stack of the actual queue counts. */ -+ ret = netif_set_real_num_tx_queues(ndev, num_data_chn); -+ if (ret) { -+ dev_err(dev, "cannot set real number of tx queues\n"); -+ return ret; -+ } -+ -+ init_completion(&emac->cmd_complete); -+ ret = prueth_init_tx_chns(emac); -+ if (ret) { -+ dev_err(dev, "failed to init tx channel: %d\n", ret); -+ return ret; -+ } -+ -+ max_rx_flows = emac->is_sr1 ? -+ PRUETH_MAX_RX_FLOWS_SR1 : PRUETH_MAX_RX_FLOWS_SR2; -+ ret = prueth_init_rx_chns(emac, &emac->rx_chns, "rx", -+ max_rx_flows, PRUETH_MAX_RX_DESC); -+ if (ret) { -+ dev_err(dev, "failed to init rx channel: %d\n", ret); -+ goto cleanup_tx; -+ } -+ -+ if (emac->is_sr1) { -+ ret = prueth_init_rx_chns(emac, &emac->rx_mgm_chn, "rxmgm", -+ PRUETH_MAX_RX_MGM_FLOWS, -+ PRUETH_MAX_RX_MGM_DESC); -+ if (ret) { -+ dev_err(dev, "failed to init rx mgmt channel: %d\n", -+ ret); -+ goto cleanup_rx; -+ } -+ } -+ -+ ret = prueth_ndev_add_tx_napi(emac); -+ if (ret) -+ goto cleanup_rx_mgm; -+ -+ /* we use only the highest priority flow for now i.e. @irq[3] */ -+ rx_flow = emac->is_sr1 ? -+ PRUETH_RX_FLOW_DATA_SR1 : PRUETH_RX_FLOW_DATA_SR2; -+ ret = request_irq(emac->rx_chns.irq[rx_flow], prueth_rx_irq, -+ IRQF_TRIGGER_HIGH, dev_name(dev), emac); -+ if (ret) { -+ dev_err(dev, "unable to request RX IRQ\n"); -+ goto cleanup_napi; -+ } -+ -+ if (!emac->is_sr1) -+ goto skip_mgm_irq; -+ -+ ret = request_threaded_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_RESPONSE], -+ NULL, prueth_rx_mgm_rsp_thread, -+ IRQF_ONESHOT | IRQF_TRIGGER_HIGH, -+ dev_name(dev), emac); -+ if (ret) { -+ dev_err(dev, "unable to request RX Management RSP IRQ\n"); -+ goto free_rx_irq; -+ } -+ -+ ret = request_threaded_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_TIMESTAMP], -+ NULL, prueth_rx_mgm_ts_thread, -+ IRQF_ONESHOT | IRQF_TRIGGER_HIGH, -+ dev_name(dev), emac); -+ if (ret) { -+ dev_err(dev, "unable to request RX Management TS IRQ\n"); -+ goto free_rx_mgm_rsp_irq; -+ } -+ -+skip_mgm_irq: -+ /* reset and start PRU firmware */ -+ ret = prueth_emac_start(prueth, emac); -+ if (ret) -+ goto free_rx_mgmt_ts_irq; -+ -+ /* Prepare RX */ -+ ret = prueth_prepare_rx_chan(emac, &emac->rx_chns, PRUETH_MAX_PKT_SIZE); -+ if (ret) -+ goto stop; -+ -+ if (emac->is_sr1) { -+ ret = prueth_prepare_rx_chan(emac, &emac->rx_mgm_chn, 64); -+ if (ret) -+ goto reset_rx_chn; -+ -+ ret = k3_udma_glue_enable_rx_chn(emac->rx_mgm_chn.rx_chn); -+ if (ret) -+ goto reset_rx_chn; -+ } -+ -+ ret = k3_udma_glue_enable_rx_chn(emac->rx_chns.rx_chn); -+ if (ret) -+ goto reset_rx_mgm_chn; -+ -+ for (i = 0; i < emac->tx_ch_num; i++) { -+ ret = k3_udma_glue_enable_tx_chn(emac->tx_chns[i].tx_chn); -+ if (ret) -+ goto reset_tx_chan; -+ } -+ -+ /* Enable NAPI in Tx and Rx direction */ -+ for (i = 0; i < emac->tx_ch_num; i++) -+ napi_enable(&emac->tx_chns[i].napi_tx); -+ napi_enable(&emac->napi_rx); -+ -+ /* Get attached phy details */ -+ phy_attached_info(emac->phydev); -+ -+ /* start PHY */ -+ phy_start(emac->phydev); -+ -+ if (netif_msg_drv(emac)) -+ dev_notice(&ndev->dev, "started\n"); -+ -+ if (!emac->is_sr1) -+ emac_set_port_state(emac, ICSSG_EMAC_PORT_FORWARD); -+ -+ return 0; -+ -+reset_tx_chan: -+ /* Since interface is not yet up, there is wouldn't be -+ * any SKB for completion. So set false to free_skb -+ */ -+ prueth_reset_tx_chan(emac, i, false); -+reset_rx_mgm_chn: -+ if (emac->is_sr1) -+ prueth_reset_rx_chan(&emac->rx_mgm_chn, -+ PRUETH_MAX_RX_MGM_FLOWS, true); -+reset_rx_chn: -+ prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, false); -+stop: -+ prueth_emac_stop(emac); -+free_rx_mgmt_ts_irq: -+ if (emac->is_sr1) -+ free_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_TIMESTAMP], -+ emac); -+free_rx_mgm_rsp_irq: -+ if (emac->is_sr1) -+ free_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_RESPONSE], -+ emac); -+free_rx_irq: -+ free_irq(emac->rx_chns.irq[rx_flow], emac); -+cleanup_napi: -+ prueth_ndev_del_tx_napi(emac, emac->tx_ch_num); -+cleanup_rx_mgm: -+ if (emac->is_sr1) -+ prueth_cleanup_rx_chns(emac, &emac->rx_mgm_chn, -+ PRUETH_MAX_RX_MGM_FLOWS); -+cleanup_rx: -+ prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows); -+cleanup_tx: -+ prueth_cleanup_tx_chns(emac); -+ -+ return ret; -+} -+ -+/** -+ * emac_ndo_stop - EMAC device stop -+ * @ndev: network adapter device -+ * -+ * Called when system wants to stop or down the interface. -+ */ -+static int emac_ndo_stop(struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth *prueth = emac->prueth; -+ int ret, i; -+ int max_rx_flows; -+ int rx_flow = emac->is_sr1 ? -+ PRUETH_RX_FLOW_DATA_SR1 : PRUETH_RX_FLOW_DATA_SR2; -+ -+ /* inform the upper layers. */ -+ netif_tx_stop_all_queues(ndev); -+ -+ /* block packets from wire */ -+ phy_stop(emac->phydev); -+ icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac)); -+ -+ /* send shutdown command */ -+ emac_shutdown(ndev); -+ -+ atomic_set(&emac->tdown_cnt, emac->tx_ch_num); -+ /* ensure new tdown_cnt value is visible */ -+ smp_mb__after_atomic(); -+ /* tear down and disable UDMA channels */ -+ reinit_completion(&emac->tdown_complete); -+ for (i = 0; i < emac->tx_ch_num; i++) -+ k3_udma_glue_tdown_tx_chn(emac->tx_chns[i].tx_chn, false); -+ -+ ret = wait_for_completion_timeout(&emac->tdown_complete, -+ msecs_to_jiffies(1000)); -+ if (!ret) -+ netdev_err(ndev, "tx teardown timeout\n"); -+ -+ prueth_reset_tx_chan(emac, emac->tx_ch_num, true); -+ for (i = 0; i < emac->tx_ch_num; i++) -+ napi_disable(&emac->tx_chns[i].napi_tx); -+ -+ max_rx_flows = emac->is_sr1 ? -+ PRUETH_MAX_RX_FLOWS_SR1 : PRUETH_MAX_RX_FLOWS_SR2; -+ k3_udma_glue_tdown_rx_chn(emac->rx_chns.rx_chn, true); -+ -+ prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, true); -+ if (emac->is_sr1) { -+ /* Teardown RX MGM channel */ -+ k3_udma_glue_tdown_rx_chn(emac->rx_mgm_chn.rx_chn, true); -+ prueth_reset_rx_chan(&emac->rx_mgm_chn, -+ PRUETH_MAX_RX_MGM_FLOWS, true); -+ } -+ -+ napi_disable(&emac->napi_rx); -+ -+ /* stop PRUs */ -+ prueth_emac_stop(emac); -+ -+ if (emac->is_sr1) { -+ free_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_TIMESTAMP], -+ emac); -+ free_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_RESPONSE], -+ emac); -+ } -+ free_irq(emac->rx_chns.irq[rx_flow], emac); -+ prueth_ndev_del_tx_napi(emac, emac->tx_ch_num); -+ prueth_cleanup_tx_chns(emac); -+ -+ if (emac->is_sr1) -+ prueth_cleanup_rx_chns(emac, &emac->rx_mgm_chn, -+ PRUETH_MAX_RX_MGM_FLOWS); -+ prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows); -+ prueth_cleanup_tx_chns(emac); -+ -+ if (netif_msg_drv(emac)) -+ dev_notice(&ndev->dev, "stopped\n"); -+ -+ return 0; -+} -+ -+static void emac_ndo_tx_timeout(struct net_device *ndev, unsigned int txqueue) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ if (netif_msg_tx_err(emac)) -+ netdev_err(ndev, "xmit timeout"); -+ -+ ndev->stats.tx_errors++; -+ -+ /* TODO: can we recover or need to reboot firmware? */ -+} -+ -+static void emac_ndo_set_rx_mode_sr1(struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth *prueth = emac->prueth; -+ int slice = prueth_emac_slice(emac); -+ bool promisc = ndev->flags & IFF_PROMISC; -+ bool allmulti = ndev->flags & IFF_ALLMULTI; -+ -+ if (promisc) { -+ icssg_class_promiscuous_sr1(prueth->miig_rt, slice); -+ return; -+ } -+ -+ if (allmulti) { -+ icssg_class_default(prueth->miig_rt, slice, 1, emac->is_sr1); -+ return; -+ } -+ -+ icssg_class_default(prueth->miig_rt, slice, 0, emac->is_sr1); -+ if (!netdev_mc_empty(ndev)) { -+ /* program multicast address list into Classifier */ -+ icssg_class_add_mcast_sr1(prueth->miig_rt, slice, ndev); -+ return; -+ } -+} -+ -+/** -+ * emac_ndo_set_rx_mode - EMAC set receive mode function -+ * @ndev: The EMAC network adapter -+ * -+ * Called when system wants to set the receive mode of the device. -+ * -+ */ -+static void emac_ndo_set_rx_mode(struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth *prueth = emac->prueth; -+ bool promisc = ndev->flags & IFF_PROMISC; -+ bool allmulti = ndev->flags & IFF_ALLMULTI; -+ -+ if (prueth->is_sr1) { -+ emac_ndo_set_rx_mode_sr1(ndev); -+ return; -+ } -+ -+ emac_set_port_state(emac, ICSSG_EMAC_PORT_UC_FLOODING_DISABLE); -+ emac_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_DISABLE); -+ -+ if (promisc) { -+ emac_set_port_state(emac, ICSSG_EMAC_PORT_UC_FLOODING_ENABLE); -+ emac_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_ENABLE); -+ return; -+ } -+ -+ if (allmulti) { -+ emac_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_ENABLE); -+ return; -+ } -+ -+ if (!netdev_mc_empty(ndev)) { -+ /* TODO: Add FDB entries for multicast. till then enable allmulti */ -+ emac_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_ENABLE); -+ return; -+ } -+} -+ -+static int emac_ndo_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ return phy_mii_ioctl(emac->phydev, ifr, cmd); -+} -+ -+static int emac_ndo_get_phys_port_name(struct net_device *ndev, char *name, size_t len) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ int err; -+ -+ err = snprintf(name, len, "p%d", emac->port_id); -+ -+ if (err >= len) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static const struct net_device_ops emac_netdev_ops = { -+ .ndo_open = emac_ndo_open, -+ .ndo_stop = emac_ndo_stop, -+ .ndo_start_xmit = emac_ndo_start_xmit, -+ .ndo_set_mac_address = eth_mac_addr, -+ .ndo_validate_addr = eth_validate_addr, -+ .ndo_tx_timeout = emac_ndo_tx_timeout, -+ .ndo_set_rx_mode = emac_ndo_set_rx_mode, -+ .ndo_do_ioctl = emac_ndo_ioctl, -+ .ndo_get_phys_port_name = emac_ndo_get_phys_port_name, -+}; -+ -+/* get emac_port corresponding to eth_node name */ -+static int prueth_node_port(struct device_node *eth_node) -+{ -+ if (!strcmp(eth_node->name, "ethernet-mii0")) -+ return PRUETH_PORT_MII0; -+ else if (!strcmp(eth_node->name, "ethernet-mii1")) -+ return PRUETH_PORT_MII1; -+ else -+ return -EINVAL; -+} -+ -+/* get MAC instance corresponding to eth_node name */ -+static int prueth_node_mac(struct device_node *eth_node) -+{ -+ if (!strcmp(eth_node->name, "ethernet-mii0")) -+ return PRUETH_MAC0; -+ else if (!strcmp(eth_node->name, "ethernet-mii1")) -+ return PRUETH_MAC1; -+ else -+ return -EINVAL; -+} -+ -+extern const struct ethtool_ops icssg_ethtool_ops; -+ -+static int prueth_netdev_init(struct prueth *prueth, -+ struct device_node *eth_node) -+{ -+ int ret, num_tx_chn = PRUETH_MAX_TX_QUEUES; -+ struct prueth_emac *emac; -+ struct net_device *ndev; -+ enum prueth_port port; -+ enum prueth_mac mac; -+ const u8 *mac_addr; -+ -+ port = prueth_node_port(eth_node); -+ if (port < 0) -+ return -EINVAL; -+ -+ mac = prueth_node_mac(eth_node); -+ if (mac < 0) -+ return -EINVAL; -+ -+ /* Use 1 channel for management messages on SR1 */ -+ if (prueth->is_sr1) -+ num_tx_chn--; -+ -+ ndev = alloc_etherdev_mq(sizeof(*emac), num_tx_chn); -+ if (!ndev) -+ return -ENOMEM; -+ -+ emac = netdev_priv(ndev); -+ prueth->emac[mac] = emac; -+ emac->prueth = prueth; -+ emac->ndev = ndev; -+ emac->port_id = port; -+ -+ ret = pruss_request_mem_region(prueth->pruss, -+ port == PRUETH_PORT_MII0 ? -+ PRUSS_MEM_DRAM0 : PRUSS_MEM_DRAM1, -+ &emac->dram); -+ if (ret) { -+ dev_err(prueth->dev, "unable to get DRAM: %d\n", ret); -+ return -ENOMEM; -+ } -+ -+ emac->is_sr1 = prueth->is_sr1; -+ emac->tx_ch_num = 1; -+ if (emac->is_sr1) { -+ /* use a dedicated high priority channel for management -+ * messages which is +1 of highest priority data channel. -+ */ -+ emac->tx_ch_num++; -+ } -+ -+ SET_NETDEV_DEV(ndev, prueth->dev); -+ emac->msg_enable = netif_msg_init(debug_level, PRUETH_EMAC_DEBUG); -+ spin_lock_init(&emac->lock); -+ mutex_init(&emac->cmd_lock); -+ -+ emac->phy_node = of_parse_phandle(eth_node, "phy-handle", 0); -+ if (!emac->phy_node) { -+ dev_err(prueth->dev, "couldn't find phy-handle\n"); -+ ret = -ENODEV; -+ goto free; -+ } -+ -+ if (of_phy_is_fixed_link(emac->phy_node)) { -+ ret = of_phy_register_fixed_link(emac->phy_node); -+ if (ret) { -+ if (ret != -EPROBE_DEFER) { -+ dev_err(prueth->dev, -+ "failed to register fixed-link phy: %d\n", -+ ret); -+ } -+ -+ goto free; -+ } -+ } -+ -+ ret = of_get_phy_mode(eth_node, &emac->phy_if); -+ if (ret) { -+ dev_err(prueth->dev, "could not get phy-mode property\n"); -+ goto free; -+ } -+ -+ /* connect PHY */ -+ emac->phydev = of_phy_connect(ndev, emac->phy_node, -+ &emac_adjust_link, 0, emac->phy_if); -+ if (!emac->phydev) { -+ dev_dbg(prueth->dev, "couldn't connect to phy %s\n", -+ emac->phy_node->full_name); -+ ret = -EPROBE_DEFER; -+ goto free; -+ } -+ -+ /* remove unsupported modes */ -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT); -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Pause_BIT); -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT); -+ -+ /* get mac address from DT and set private and netdev addr */ -+ mac_addr = of_get_mac_address(eth_node); -+ if (!IS_ERR(mac_addr)) -+ ether_addr_copy(ndev->dev_addr, mac_addr); -+ if (!is_valid_ether_addr(ndev->dev_addr)) { -+ eth_hw_addr_random(ndev); -+ dev_warn(prueth->dev, "port %d: using random MAC addr: %pM\n", -+ port, ndev->dev_addr); -+ } -+ ether_addr_copy(emac->mac_addr, ndev->dev_addr); -+ -+ ndev->netdev_ops = &emac_netdev_ops; -+ ndev->ethtool_ops = &icssg_ethtool_ops; -+ -+ netif_napi_add(ndev, &emac->napi_rx, -+ emac_napi_rx_poll, NAPI_POLL_WEIGHT); -+ -+ return 0; -+ -+free: -+ pruss_release_mem_region(prueth->pruss, &emac->dram); -+ free_netdev(ndev); -+ prueth->emac[mac] = NULL; -+ -+ return ret; -+} -+ -+static void prueth_netdev_exit(struct prueth *prueth, -+ struct device_node *eth_node) -+{ -+ struct prueth_emac *emac; -+ enum prueth_mac mac; -+ -+ mac = prueth_node_mac(eth_node); -+ if (mac < 0) -+ return; -+ -+ emac = prueth->emac[mac]; -+ if (!emac) -+ return; -+ -+ phy_disconnect(emac->phydev); -+ -+ if (of_phy_is_fixed_link(emac->phy_node)) -+ of_phy_deregister_fixed_link(emac->phy_node); -+ -+ netif_napi_del(&emac->napi_rx); -+ -+ pruss_release_mem_region(prueth->pruss, &emac->dram); -+ free_netdev(emac->ndev); -+ prueth->emac[mac] = NULL; -+} -+ -+static int prueth_get_cores(struct prueth *prueth, int slice) -+{ -+ enum pruss_pru_id pruss_id; -+ struct device *dev = prueth->dev; -+ struct device_node *np = dev->of_node; -+ int pru, rtu, txpru = -1, ret; -+ -+ switch (slice) { -+ case ICSS_SLICE0: -+ pru = 0; -+ rtu = 1; -+ if (!prueth->is_sr1) -+ txpru = 2; -+ break; -+ case ICSS_SLICE1: -+ if (prueth->is_sr1) { -+ pru = 2; -+ rtu = 3; -+ } else { -+ pru = 3; -+ rtu = 4; -+ txpru = 5; -+ } -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ prueth->pru[slice] = pru_rproc_get(np, pru, &pruss_id); -+ if (IS_ERR(prueth->pru[slice])) { -+ ret = PTR_ERR(prueth->pru[slice]); -+ prueth->pru[slice] = NULL; -+ if (ret != -EPROBE_DEFER) -+ dev_err(dev, "unable to get PRU%d: %d\n", slice, ret); -+ return ret; -+ } -+ prueth->pru_id[slice] = pruss_id; -+ -+ prueth->rtu[slice] = pru_rproc_get(np, rtu, NULL); -+ if (IS_ERR(prueth->rtu[slice])) { -+ ret = PTR_ERR(prueth->rtu[slice]); -+ prueth->rtu[slice] = NULL; -+ if (ret != -EPROBE_DEFER) -+ dev_err(dev, "unable to get RTU%d: %d\n", slice, ret); -+ return ret; -+ } -+ -+ if (prueth->is_sr1) -+ return 0; -+ -+ prueth->txpru[slice] = pru_rproc_get(np, txpru, NULL); -+ if (IS_ERR(prueth->txpru[slice])) { -+ ret = PTR_ERR(prueth->txpru[slice]); -+ prueth->txpru[slice] = NULL; -+ if (ret != -EPROBE_DEFER) -+ dev_err(dev, "unable to get TX_PRU%d: %d\n", -+ slice, ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void prueth_put_cores(struct prueth *prueth, int slice) -+{ -+ if (prueth->txpru[slice]) -+ pru_rproc_put(prueth->txpru[slice]); -+ -+ if (prueth->rtu[slice]) -+ pru_rproc_put(prueth->rtu[slice]); -+ -+ if (prueth->pru[slice]) -+ pru_rproc_put(prueth->pru[slice]); -+} -+ -+static int prueth_config_rgmiidelay(struct prueth *prueth, -+ struct device_node *eth_np) -+{ -+ struct device *dev = prueth->dev; -+ struct regmap *ctrl_mmr; -+ u32 icssgctrl; -+ struct device_node *np = dev->of_node; -+ -+ if (!of_device_is_compatible(np, "ti,am654-icssg-prueth")) -+ return 0; -+ -+ ctrl_mmr = syscon_regmap_lookup_by_phandle(eth_np, "syscon-rgmii-delay"); -+ if (IS_ERR(ctrl_mmr)) { -+ dev_err(dev, "couldn't get syscon-rgmii-delay\n"); -+ return -ENODEV; -+ } -+ -+ if (of_property_read_u32_index(eth_np, "syscon-rgmii-delay", 1, -+ &icssgctrl)) { -+ dev_err(dev, "couldn't get rgmii-delay reg. offset\n"); -+ return -ENODEV; -+ } -+ -+ regmap_update_bits(ctrl_mmr, icssgctrl, ICSSG_CTRL_RGMII_ID_MODE, 0); -+ -+ return 0; -+} -+ -+static const struct of_device_id prueth_dt_match[]; -+ -+static int prueth_probe(struct platform_device *pdev) -+{ -+ struct prueth *prueth; -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct device_node *eth0_node, *eth1_node; -+ const struct of_device_id *match; -+ struct pruss *pruss; -+ int i, ret; -+ u32 msmc_ram_size; -+ struct genpool_data_align gp_data = { -+ .align = SZ_64K, -+ }; -+ -+ match = of_match_device(prueth_dt_match, dev); -+ if (!match) -+ return -ENODEV; -+ -+ prueth = devm_kzalloc(dev, sizeof(*prueth), GFP_KERNEL); -+ if (!prueth) -+ return -ENOMEM; -+ -+ dev_set_drvdata(dev, prueth); -+ prueth->pdev = pdev; -+ -+ if (of_device_is_compatible(np, "ti,am654-icssg-prueth-sr1")) -+ prueth->is_sr1 = true; -+ -+ prueth->dev = dev; -+ eth0_node = of_get_child_by_name(np, "ethernet-mii0"); -+ if (!of_device_is_available(eth0_node)) { -+ of_node_put(eth0_node); -+ eth0_node = NULL; -+ } -+ -+ eth1_node = of_get_child_by_name(np, "ethernet-mii1"); -+ if (!of_device_is_available(eth1_node)) { -+ of_node_put(eth1_node); -+ eth1_node = NULL; -+ } -+ -+ /* At least one node must be present and available else we fail */ -+ if (!eth0_node && !eth1_node) { -+ dev_err(dev, "neither ethernet-mii0 nor ethernet-mii1 node available\n"); -+ return -ENODEV; -+ } -+ -+ prueth->eth_node[PRUETH_MAC0] = eth0_node; -+ prueth->eth_node[PRUETH_MAC1] = eth1_node; -+ -+ prueth->miig_rt = syscon_regmap_lookup_by_phandle(np, "mii-g-rt"); -+ if (IS_ERR(prueth->miig_rt)) { -+ dev_err(dev, "couldn't get mii-g-rt syscon regmap\n"); -+ return -ENODEV; -+ } -+ -+ prueth->mii_rt = syscon_regmap_lookup_by_phandle(np, "mii-rt"); -+ if (IS_ERR(prueth->mii_rt)) { -+ dev_err(dev, "couldn't get mii-rt syscon regmap\n"); -+ return -ENODEV; -+ } -+ -+ if (eth0_node) { -+ ret = prueth_config_rgmiidelay(prueth, eth0_node); -+ if (ret) -+ goto put_cores; -+ -+ ret = prueth_get_cores(prueth, ICSS_SLICE0); -+ if (ret) -+ goto put_cores; -+ } -+ -+ if (eth1_node) { -+ ret = prueth_config_rgmiidelay(prueth, eth1_node); -+ if (ret) -+ goto put_cores; -+ -+ ret = prueth_get_cores(prueth, ICSS_SLICE1); -+ if (ret) -+ goto put_cores; -+ } -+ -+ pruss = pruss_get(eth0_node ? -+ prueth->pru[ICSS_SLICE0] : prueth->pru[ICSS_SLICE1]); -+ if (IS_ERR(pruss)) { -+ ret = PTR_ERR(pruss); -+ dev_err(dev, "unable to get pruss handle\n"); -+ goto put_cores; -+ } -+ -+ prueth->pruss = pruss; -+ -+ ret = pruss_request_mem_region(pruss, PRUSS_MEM_SHRD_RAM2, -+ &prueth->shram); -+ if (ret) { -+ dev_err(dev, "unable to get PRUSS SHRD RAM2: %d\n", ret); -+ goto put_mem; -+ } -+ -+ prueth->sram_pool = of_gen_pool_get(np, "sram", 0); -+ if (!prueth->sram_pool) { -+ dev_err(dev, "unable to get SRAM pool\n"); -+ ret = -ENODEV; -+ -+ goto put_mem; -+ } -+ -+ msmc_ram_size = prueth->is_sr1 ? MSMC_RAM_SIZE_SR1 : MSMC_RAM_SIZE_SR2; -+ if (prueth->is_sr1) { -+ prueth->msmcram.va = -+ (void __iomem *)gen_pool_alloc(prueth->sram_pool, -+ msmc_ram_size); -+ } else { -+ /* TEMP: FW bug needs buffer base to be 64KB aligned */ -+ prueth->msmcram.va = -+ (void __iomem *)gen_pool_alloc_algo(prueth->sram_pool, -+ msmc_ram_size, -+ gen_pool_first_fit_align, -+ &gp_data); -+ } -+ -+ if (!prueth->msmcram.va) { -+ ret = -ENOMEM; -+ dev_err(dev, "unable to allocate MSMC resource\n"); -+ goto put_mem; -+ } -+ prueth->msmcram.pa = gen_pool_virt_to_phys(prueth->sram_pool, -+ (unsigned long)prueth->msmcram.va); -+ prueth->msmcram.size = msmc_ram_size; -+ memset(prueth->msmcram.va, 0, msmc_ram_size); -+ dev_dbg(dev, "sram: pa %llx va %p size %zx\n", prueth->msmcram.pa, -+ prueth->msmcram.va, prueth->msmcram.size); -+ -+ /* setup netdev interfaces */ -+ if (eth0_node) { -+ ret = prueth_netdev_init(prueth, eth0_node); -+ if (ret) { -+ if (ret != -EPROBE_DEFER) { -+ dev_err(dev, "netdev init %s failed: %d\n", -+ eth0_node->name, ret); -+ } -+ goto free_pool; -+ } -+ } -+ -+ if (eth1_node) { -+ ret = prueth_netdev_init(prueth, eth1_node); -+ if (ret) { -+ if (ret != -EPROBE_DEFER) { -+ dev_err(dev, "netdev init %s failed: %d\n", -+ eth1_node->name, ret); -+ } -+ goto netdev_exit; -+ } -+ } -+ -+ /* register the network devices */ -+ if (eth0_node) { -+ ret = register_netdev(prueth->emac[PRUETH_MAC0]->ndev); -+ if (ret) { -+ dev_err(dev, "can't register netdev for port MII0"); -+ goto netdev_exit; -+ } -+ -+ prueth->registered_netdevs[PRUETH_MAC0] = prueth->emac[PRUETH_MAC0]->ndev; -+ } -+ -+ if (eth1_node) { -+ ret = register_netdev(prueth->emac[PRUETH_MAC1]->ndev); -+ if (ret) { -+ dev_err(dev, "can't register netdev for port MII1"); -+ goto netdev_unregister; -+ } -+ -+ prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev; -+ } -+ -+ dev_info(dev, "TI PRU ethernet driver initialized: %s EMAC mode\n", -+ (!eth0_node || !eth1_node) ? "single" : "dual"); -+ -+ if (eth1_node) -+ of_node_put(eth1_node); -+ if (eth0_node) -+ of_node_put(eth0_node); -+ -+ return 0; -+ -+netdev_unregister: -+ for (i = 0; i < PRUETH_NUM_MACS; i++) { -+ if (!prueth->registered_netdevs[i]) -+ continue; -+ unregister_netdev(prueth->registered_netdevs[i]); -+ } -+ -+netdev_exit: -+ for (i = 0; i < PRUETH_NUM_MACS; i++) { -+ struct device_node *eth_node; -+ -+ eth_node = prueth->eth_node[i]; -+ if (!eth_node) -+ continue; -+ -+ prueth_netdev_exit(prueth, eth_node); -+ } -+ -+free_pool: -+ gen_pool_free(prueth->sram_pool, -+ (unsigned long)prueth->msmcram.va, msmc_ram_size); -+ -+put_mem: -+ pruss_release_mem_region(prueth->pruss, &prueth->shram); -+ pruss_put(prueth->pruss); -+ -+put_cores: -+ if (eth1_node) { -+ prueth_put_cores(prueth, ICSS_SLICE1); -+ of_node_put(eth1_node); -+ } -+ -+ if (eth0_node) { -+ prueth_put_cores(prueth, ICSS_SLICE0); -+ of_node_put(eth0_node); -+ } -+ -+ return ret; -+} -+ -+static int prueth_remove(struct platform_device *pdev) -+{ -+ struct device_node *eth_node; -+ struct prueth *prueth = platform_get_drvdata(pdev); -+ int i; -+ -+ for (i = 0; i < PRUETH_NUM_MACS; i++) { -+ if (!prueth->registered_netdevs[i]) -+ continue; -+ unregister_netdev(prueth->registered_netdevs[i]); -+ } -+ -+ for (i = 0; i < PRUETH_NUM_MACS; i++) { -+ eth_node = prueth->eth_node[i]; -+ if (!eth_node) -+ continue; -+ -+ prueth_netdev_exit(prueth, eth_node); -+ } -+ -+ gen_pool_free(prueth->sram_pool, -+ (unsigned long)prueth->msmcram.va, -+ prueth->is_sr1 ? MSMC_RAM_SIZE_SR1 : MSMC_RAM_SIZE_SR2); -+ -+ pruss_release_mem_region(prueth->pruss, &prueth->shram); -+ -+ pruss_put(prueth->pruss); -+ -+ if (prueth->eth_node[PRUETH_MAC1]) -+ prueth_put_cores(prueth, ICSS_SLICE1); -+ -+ if (prueth->eth_node[PRUETH_MAC0]) -+ prueth_put_cores(prueth, ICSS_SLICE0); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM_SLEEP -+static int prueth_suspend(struct device *dev) -+{ -+ struct prueth *prueth = dev_get_drvdata(dev); -+ struct net_device *ndev; -+ int i, ret; -+ -+ for (i = 0; i < PRUETH_NUM_MACS; i++) { -+ ndev = prueth->registered_netdevs[i]; -+ -+ if (!ndev) -+ continue; -+ -+ if (netif_running(ndev)) { -+ netif_device_detach(ndev); -+ ret = emac_ndo_stop(ndev); -+ if (ret < 0) { -+ netdev_err(ndev, "failed to stop: %d", ret); -+ return ret; -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static int prueth_resume(struct device *dev) -+{ -+ struct prueth *prueth = dev_get_drvdata(dev); -+ struct net_device *ndev; -+ int i, ret; -+ -+ for (i = 0; i < PRUETH_NUM_MACS; i++) { -+ ndev = prueth->registered_netdevs[i]; -+ -+ if (!ndev) -+ continue; -+ -+ if (netif_running(ndev)) { -+ ret = emac_ndo_open(ndev); -+ if (ret < 0) { -+ netdev_err(ndev, "failed to start: %d", ret); -+ return ret; -+ } -+ netif_device_attach(ndev); -+ } -+ } -+ -+ return 0; -+} -+#endif /* CONFIG_PM_SLEEP */ -+ -+static const struct dev_pm_ops prueth_dev_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(prueth_suspend, prueth_resume) -+}; -+ -+static const struct of_device_id prueth_dt_match[] = { -+ { .compatible = "ti,am654-icssg-prueth-sr1", }, -+ { .compatible = "ti,am654-icssg-prueth", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, prueth_dt_match); -+ -+static struct platform_driver prueth_driver = { -+ .probe = prueth_probe, -+ .remove = prueth_remove, -+ .driver = { -+ .name = "icssg-prueth", -+ .of_match_table = prueth_dt_match, -+ .pm = &prueth_dev_pm_ops, -+ }, -+}; -+module_platform_driver(prueth_driver); -+ -+MODULE_AUTHOR("Roger Quadros "); -+MODULE_DESCRIPTION("PRUSS ICSSG Ethernet Driver"); -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -new file mode 100644 -index 000000000000..1c2908eb2d57 ---- /dev/null -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -0,0 +1,253 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* Texas Instruments ICSSG Ethernet driver -+ * -+ * Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/ -+ * -+ */ -+ -+#ifndef __NET_TI_ICSSG_PRUETH_H -+#define __NET_TI_ICSSG_PRUETH_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "icssg_config.h" -+#include "icssg_switch_map.h" -+ -+#define ICSS_SLICE0 0 -+#define ICSS_SLICE1 1 -+ -+#define ICSS_FW_PRU 0 -+#define ICSS_FW_RTU 1 -+ -+#define ICSSG_MAX_RFLOWS 8 /* per slice */ -+ -+/* Firmware status codes */ -+#define ICSS_HS_FW_READY 0x55555555 -+#define ICSS_HS_FW_DEAD 0xDEAD0000 /* lower 16 bits contain error code */ -+ -+/* Firmware command codes */ -+#define ICSS_HS_CMD_BUSY 0x40000000 -+#define ICSS_HS_CMD_DONE 0x80000000 -+#define ICSS_HS_CMD_CANCEL 0x10000000 -+ -+/* Firmware commands */ -+#define ICSS_CMD_SPAD 0x20 -+#define ICSS_CMD_RXTX 0x10 -+#define ICSS_CMD_ADD_FDB 0x1 -+#define ICSS_CMD_SET_RUN 0x4 -+#define ICSS_CMD_ENABLE_VLAN 0x5 -+#define ICSS_CMD_DISABLE_VLAN 0x6 -+#define ICSS_CMD_ADD_FILTER 0x7 -+#define ICSS_CMD_ADD_MAC 0x8 -+ -+/* Firmware flags */ -+#define ICSS_SET_RUN_FLAG_VLAN_ENABLE BIT(0) /* switch only */ -+#define ICSS_SET_RUN_FLAG_FLOOD_UNICAST BIT(1) /* switch only */ -+#define ICSS_SET_RUN_FLAG_PROMISC BIT(2) /* MAC only */ -+#define ICSS_SET_RUN_FLAG_MULTICAST_PROMISC BIT(3) /* MAC only */ -+ -+/* In switch mode there are 3 real ports i.e. 3 mac addrs. -+ * however Linux sees only the host side port. The other 2 ports -+ * are the switch ports. -+ * In emac mode there are 2 real ports i.e. 2 mac addrs. -+ * Linux sees both the ports. -+ */ -+enum prueth_port { -+ PRUETH_PORT_HOST = 0, /* host side port */ -+ PRUETH_PORT_MII0, /* physical port RG/SG MII 0 */ -+ PRUETH_PORT_MII1, /* physical port RG/SG MII 1 */ -+}; -+ -+enum prueth_mac { -+ PRUETH_MAC0 = 0, -+ PRUETH_MAC1, -+ PRUETH_NUM_MACS, -+}; -+ -+struct prueth_tx_chn { -+ struct napi_struct napi_tx; -+ struct k3_cppi_desc_pool *desc_pool; -+ struct k3_udma_glue_tx_channel *tx_chn; -+ struct prueth_emac *emac; -+ u32 id; -+ u32 descs_num; -+ unsigned int irq; -+ char name[32]; -+}; -+ -+struct prueth_rx_chn { -+ struct device *dev; -+ struct k3_cppi_desc_pool *desc_pool; -+ struct k3_udma_glue_rx_channel *rx_chn; -+ u32 descs_num; -+ unsigned int irq[ICSSG_MAX_RFLOWS]; /* separate irq per flow */ -+ char name[32]; -+}; -+ -+/* There are 4 Tx DMA channels, but the highest priority is CH3 (thread 3) -+ * and lower three are lower priority channels or threads. -+ */ -+#define PRUETH_MAX_TX_QUEUES 4 -+ -+/* data for each emac port */ -+struct prueth_emac { -+ bool is_sr1; -+ bool fw_running; -+ struct prueth *prueth; -+ struct net_device *ndev; -+ u8 mac_addr[6]; -+ struct napi_struct napi_rx; -+ u32 msg_enable; -+ -+ int link; -+ int speed; -+ int duplex; -+ -+ const char *phy_id; -+ struct device_node *phy_node; -+ phy_interface_t phy_if; -+ struct phy_device *phydev; -+ enum prueth_port port_id; -+ -+ /* DMA related */ -+ struct prueth_tx_chn tx_chns[PRUETH_MAX_TX_QUEUES]; -+ struct completion tdown_complete; -+ atomic_t tdown_cnt; -+ struct prueth_rx_chn rx_chns; -+ int rx_flow_id_base; -+ int tx_ch_num; -+ -+ /* SR1.0 Management channel */ -+ struct prueth_rx_chn rx_mgm_chn; -+ int rx_mgm_flow_id_base; -+ -+ spinlock_t lock; /* serialize access */ -+ -+ u8 cmd_seq; -+ /* shutdown related */ -+ u32 cmd_data[4]; -+ struct completion cmd_complete; -+ /* Mutex to serialize access to firmware command interface */ -+ struct mutex cmd_lock; -+ -+ struct pruss_mem_region dram; -+}; -+ -+/** -+ * struct prueth - PRUeth structure -+ * @is_sr1: device is pg1.0 (pg1.0 will be deprecated upstream) -+ * @dev: device -+ * @pruss: pruss handle -+ * @pru: rproc instances of PRUs -+ * @rtu: rproc instances of RTUs -+ * @rtu: rproc instances of TX_PRUs -+ * @shram: PRUSS shared RAM region -+ * @sram_pool: MSMC RAM pool for buffers -+ * @msmcram: MSMC RAM region -+ * @eth_node: DT node for the port -+ * @emac: private EMAC data structure -+ * @registered_netdevs: list of registered netdevs -+ * @fw_data: firmware names to be used with PRU remoteprocs -+ * @config: firmware load time configuration per slice -+ * @miig_rt: regmap to mii_g_rt block -+ * @pa_stats: regmap to pa_stats block -+ */ -+struct prueth { -+ bool is_sr1; -+ struct device *dev; -+ struct pruss *pruss; -+ struct rproc *pru[PRUSS_NUM_PRUS]; -+ struct rproc *rtu[PRUSS_NUM_PRUS]; -+ struct rproc *txpru[PRUSS_NUM_PRUS]; -+ struct pruss_mem_region shram; -+ struct gen_pool *sram_pool; -+ struct pruss_mem_region msmcram; -+ -+ struct device_node *eth_node[PRUETH_NUM_MACS]; -+ struct prueth_emac *emac[PRUETH_NUM_MACS]; -+ struct net_device *registered_netdevs[PRUETH_NUM_MACS]; -+ const struct prueth_private_data *fw_data; -+ struct icssg_config_sr1 config[PRUSS_NUM_PRUS]; -+ struct regmap *miig_rt; -+ struct regmap *mii_rt; -+ struct regmap *pa_stats; -+ -+ enum pruss_pru_id pru_id[PRUSS_NUM_PRUS]; -+ struct platform_device *pdev; -+}; -+ -+struct emac_tx_ts_response_sr1 { -+ u32 lo_ts; -+ u32 hi_ts; -+ u32 reserved; -+ u32 cookie; -+}; -+ -+struct emac_tx_ts_response { -+ u32 reserved[2]; -+ u32 cookie; -+ u32 lo_ts; -+ u32 hi_ts; -+}; -+ -+/* Classifier helpers */ -+void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac); -+void icssg_class_disable(struct regmap *miig_rt, int slice); -+void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti, -+ bool is_sr1); -+void icssg_class_promiscuous_sr1(struct regmap *miig_rt, int slice); -+void icssg_class_add_mcast_sr1(struct regmap *miig_rt, int slice, -+ struct net_device *ndev); -+void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr); -+ -+/* Buffer queue helpers */ -+int icssg_queue_pop(struct prueth *prueth, u8 queue); -+void icssg_queue_push(struct prueth *prueth, int queue, u16 addr); -+u32 icssg_queue_level(struct prueth *prueth, int queue); -+ -+/* get PRUSS SLICE number from prueth_emac */ -+static inline int prueth_emac_slice(struct prueth_emac *emac) -+{ -+ switch (emac->port_id) { -+ case PRUETH_PORT_MII0: -+ return ICSS_SLICE0; -+ case PRUETH_PORT_MII1: -+ return ICSS_SLICE1; -+ default: -+ return -EINVAL; -+ } -+} -+ -+/* config helpers */ -+void icssg_config_ipg(struct prueth *prueth, int speed, int mii); -+void icssg_config_sr1(struct prueth *prueth, struct prueth_emac *emac, -+ int slice); -+int icssg_config_sr2(struct prueth *prueth, struct prueth_emac *emac, -+ int slice); -+int emac_set_port_state(struct prueth_emac *emac, -+ enum icssg_port_state_cmd state); -+#define prueth_napi_to_tx_chn(pnapi) \ -+ container_of(pnapi, struct prueth_tx_chn, napi_tx) -+ -+#endif /* __NET_TI_ICSSG_PRUETH_H */ -diff --git a/drivers/net/ethernet/ti/icssg_queues.c b/drivers/net/ethernet/ti/icssg_queues.c -new file mode 100644 -index 000000000000..3c34f61ad40b ---- /dev/null -+++ b/drivers/net/ethernet/ti/icssg_queues.c -@@ -0,0 +1,50 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* ICSSG Buffer queue helpers -+ * -+ * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com -+ */ -+ -+#include -+#include "icssg_prueth.h" -+ -+#define ICSSG_QUEUES_MAX 64 -+#define ICSSG_QUEUE_OFFSET 0xd00 -+#define ICSSG_QUEUE_PEEK_OFFSET 0xe00 -+#define ICSSG_QUEUE_CNT_OFFSET 0xe40 -+#define ICSSG_QUEUE_RESET_OFFSET 0xf40 -+ -+int icssg_queue_pop(struct prueth *prueth, u8 queue) -+{ -+ u32 val, cnt; -+ -+ if (queue >= ICSSG_QUEUES_MAX) -+ return -EINVAL; -+ -+ regmap_read(prueth->miig_rt, ICSSG_QUEUE_CNT_OFFSET + 4 * queue, &cnt); -+ if (!cnt) -+ return -EINVAL; -+ -+ regmap_read(prueth->miig_rt, ICSSG_QUEUE_OFFSET + 4 * queue, &val); -+ -+ return val; -+} -+ -+void icssg_queue_push(struct prueth *prueth, int queue, u16 addr) -+{ -+ if (queue >= ICSSG_QUEUES_MAX) -+ return; -+ -+ regmap_write(prueth->miig_rt, ICSSG_QUEUE_OFFSET + 4 * queue, addr); -+} -+ -+u32 icssg_queue_level(struct prueth *prueth, int queue) -+{ -+ u32 reg; -+ -+ if (queue >= ICSSG_QUEUES_MAX) -+ return 0; -+ -+ regmap_read(prueth->miig_rt, ICSSG_QUEUE_CNT_OFFSET + 4 * queue, ®); -+ -+ return reg; -+} -diff --git a/drivers/net/ethernet/ti/icssg_switch_map.h b/drivers/net/ethernet/ti/icssg_switch_map.h -new file mode 100644 -index 000000000000..bf52d350bdd0 ---- /dev/null -+++ b/drivers/net/ethernet/ti/icssg_switch_map.h -@@ -0,0 +1,163 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* Texas Instruments ICSSG Ethernet driver -+ * -+ * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/ -+ * -+ * -+ */ -+ -+#ifndef __NET_TI_ICSSG_SWITCH_MAP_H -+#define __NET_TI_ICSSG_SWITCH_MAP_H -+ -+/* Memory Usage of : SHARED_MEMORY -+ * -+ */ -+ -+/*Time after which FDB entries are checked for aged out values. Value in nanoseconds*/ -+#define FDB_AGEING_TIMEOUT_OFFSET 0x0014 -+/*default VLAN tag for Host Port*/ -+#define HOST_PORT_DF_VLAN_OFFSET 0x001C -+/*Same as HOST_PORT_DF_VLAN_OFFSET*/ -+#define EMAC_ICSSG_SWITCH_PORT0_DEFAULT_VLAN_OFFSET HOST_PORT_DF_VLAN_OFFSET -+/*default VLAN tag for P1 Port*/ -+#define P1_PORT_DF_VLAN_OFFSET 0x0020 -+/*Same as P1_PORT_DF_VLAN_OFFSET*/ -+#define EMAC_ICSSG_SWITCH_PORT1_DEFAULT_VLAN_OFFSET P1_PORT_DF_VLAN_OFFSET -+/*default VLAN tag for P2 Port*/ -+#define P2_PORT_DF_VLAN_OFFSET 0x0024 -+/*Same as P2_PORT_DF_VLAN_OFFSET*/ -+#define EMAC_ICSSG_SWITCH_PORT2_DEFAULT_VLAN_OFFSET P2_PORT_DF_VLAN_OFFSET -+/*VLAN-FID Table offset. 4096 VIDs. 2B per VID = 8KB = 0x2000*/ -+#define VLAN_STATIC_REG_TABLE_OFFSET 0x0100 -+/*VLAN-FID Table offset for EMAC*/ -+#define EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET VLAN_STATIC_REG_TABLE_OFFSET -+/*packet descriptor Q reserved memory*/ -+#define PORT_DESC0_HI 0x2104 -+/*packet descriptor Q reserved memory*/ -+#define PORT_DESC0_LO 0x2F6C -+/*packet descriptor Q reserved memory*/ -+#define PORT_DESC1_HI 0x3DD4 -+/*packet descriptor Q reserved memory*/ -+#define PORT_DESC1_LO 0x4C3C -+/*packet descriptor Q reserved memory*/ -+#define HOST_DESC0_HI 0x5AA4 -+/*packet descriptor Q reserved memory*/ -+#define HOST_DESC0_LO 0x5F0C -+/*packet descriptor Q reserved memory*/ -+#define HOST_DESC1_HI 0x6374 -+/*packet descriptor Q reserved memory*/ -+#define HOST_DESC1_LO 0x67DC -+/*special packet descriptor Q reserved memory*/ -+#define HOST_SPPD0 0x7AAC -+/*special packet descriptor Q reserved memory*/ -+#define HOST_SPPD1 0x7EAC -+/*_Small_Description_*/ -+#define TIMESYNC_FW_WC_CYCLECOUNT_OFFSET 0x83EC -+/*IEP count hi roll over count*/ -+#define TIMESYNC_FW_WC_HI_ROLLOVER_COUNT_OFFSET 0x83F4 -+/*_Small_Description_*/ -+#define TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET 0x83F8 -+/*Set clock descriptor*/ -+#define TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET 0x83FC -+/*_Small_Description_*/ -+#define TIMESYNC_FW_WC_SYNCOUT_REDUCTION_FACTOR_OFFSET 0x843C -+/*_Small_Description_*/ -+#define TIMESYNC_FW_WC_SYNCOUT_REDUCTION_COUNT_OFFSET 0x8440 -+/*_Small_Description_*/ -+#define TIMESYNC_FW_WC_SYNCOUT_START_TIME_CYCLECOUNT_OFFSET 0x8444 -+/*Control variable to generate SYNC1*/ -+#define TIMESYNC_FW_WC_ISOM_PIN_SIGNAL_EN_OFFSET 0x844C -+/*SystemTime Sync0 periodicity*/ -+#define TIMESYNC_FW_ST_SYNCOUT_PERIOD_OFFSET 0x8450 -+/*pktTxDelay for P1 = link speed dependent p1 mac delay + p1 phy delay*/ -+#define TIMESYNC_FW_WC_PKTTXDELAY_P1_OFFSET 0x8454 -+/*pktTxDelay for P2 = link speed dependent p2 mac delay + p2 phy delay*/ -+#define TIMESYNC_FW_WC_PKTTXDELAY_P2_OFFSET 0x8458 -+/*Set clock operation done signal for next task*/ -+#define TIMESYNC_FW_SIG_PNFW_OFFSET 0x845C -+/*Set clock operation done signal for next task*/ -+#define TIMESYNC_FW_SIG_TIMESYNCFW_OFFSET 0x8460 -+ -+/* Memory Usage of : MSMC -+ * -+ */ -+ -+/* Memory Usage of : DMEM0 -+ * -+ */ -+ -+/*New list is copied at this time*/ -+#define TAS_CONFIG_CHANGE_TIME 0x000C -+/*config change error counter*/ -+#define TAS_CONFIG_CHANGE_ERROR_COUNTER 0x0014 -+/*TAS List update pending flag*/ -+#define TAS_CONFIG_PENDING 0x0018 -+/*TAS list update trigger flag*/ -+#define TAS_CONFIG_CHANGE 0x0019 -+/*List length for new TAS schedule*/ -+#define TAS_ADMIN_LIST_LENGTH 0x001A -+/*Currently active TAS list index*/ -+#define TAS_ACTIVE_LIST_INDEX 0x001B -+/*Cycle time for the new TAS schedule*/ -+#define TAS_ADMIN_CYCLE_TIME 0x001C -+/*Cycle counts remaining till the TAS list update*/ -+#define TAS_CONFIG_CHANGE_CYCLE_COUNT 0x0020 -+/*Base Flow ID for sending packets to Host for Slice0*/ -+#define PSI_L_REGULAR_FLOW_ID_BASE_OFFSET 0x0024 -+/*Same as PSI_L_REGULAR_FLOW_ID_BASE_OFFSET*/ -+#define EMAC_ICSSG_SWITCH_PSI_L_REGULAR_FLOW_ID_BASE_OFFSET PSI_L_REGULAR_FLOW_ID_BASE_OFFSET -+/*Base Flow ID for sending mgmt and Tx TS to Host for Slice0*/ -+#define PSI_L_MGMT_FLOW_ID_OFFSET 0x0026 -+/*Same as PSI_L_MGMT_FLOW_ID_OFFSET*/ -+#define EMAC_ICSSG_SWITCH_PSI_L_MGMT_FLOW_ID_BASE_OFFSET PSI_L_MGMT_FLOW_ID_OFFSET -+/*Queue number for Special packets written here*/ -+#define SPL_PKT_DEFAULT_PRIORITY 0x0028 -+/*Express Preemptible Queue Mask*/ -+#define EXPRESS_PRE_EMPTIVE_Q_MASK 0x0029 -+/*Port1/Port2 Default Queue number for untagged packets, only 1B is used*/ -+#define QUEUE_NUM_UNTAGGED 0x002A -+/*Stores the table used for priority regeneration. 1B per PCP/Queue*/ -+#define PORT_Q_PRIORITY_REGEN_OFFSET 0x002C -+/*For marking packet as priority/express (this feature is disabled) or cut-through/S&F.*/ -+#define EXPRESS_PRE_EMPTIVE_Q_MAP 0x0034 -+/*Stores the table used for priority mapping. 1B per PCP/Queue*/ -+#define PORT_Q_PRIORITY_MAPPING_OFFSET 0x003C -+/*TAS gate mask for windows list0*/ -+#define TAS_GATE_MASK_LIST0 0x0100 -+/*TAS gate mask for windows list1*/ -+#define TAS_GATE_MASK_LIST1 0x0350 -+/*Memory to Enable/Disable Preemption on TX side*/ -+#define PRE_EMPTION_ENABLE_TX 0x05A0 -+/*Active State of Preemption on TX side*/ -+#define PRE_EMPTION_ACTIVE_TX 0x05A1 -+/*Memory to Enable/Disable Verify State Machine Preemption*/ -+#define PRE_EMPTION_ENABLE_VERIFY 0x05A2 -+/*Verify Status of State Machine*/ -+#define PRE_EMPTION_VERIFY_STATUS 0x05A3 -+/*Non Final Fragment Size supported by Link Partner*/ -+#define PRE_EMPTION_ADD_FRAG_SIZE_REMOTE 0x05A4 -+/*Non Final Fragment Size supported by Firmware*/ -+#define PRE_EMPTION_ADD_FRAG_SIZE_LOCAL 0x05A6 -+/*Time in ms the State machine waits for respond packet*/ -+#define PRE_EMPTION_VERIFY_TIME 0x05A8 -+/*Memory used for R30 related management commands*/ -+#define MGR_R30_CMD_OFFSET 0x05AC -+/*HW Buffer Pool0 base address*/ -+#define BUFFER_POOL_0_ADDR_OFFSET 0x05BC -+/*16B for Host Egress MSMC Q (Pre-emptible) context*/ -+#define HOST_RX_Q_PRE_CONTEXT_OFFSET 0x0684 -+/*Buffer for 8 FDB entries to be added by 'Add Multiple FDB entries IOCTL*/ -+#define FDB_CMD_BUFFER 0x0894 -+ -+/* Memory Usage of : DMEM1 -+ * -+ */ -+ -+/* Memory Usage of : PA_STAT -+ * -+ */ -+ -+/*Start of 32 bits PA_STAT counters*/ -+#define PA_STAT_32b_START_OFFSET 0x0080 -+ -+#endif /* __NET_TI_ICSSG_SWITCH_MAP_H */ -diff --git a/include/linux/pruss.h b/include/linux/pruss.h -index 5fdd6f03446d..2a034c08b4c2 100644 ---- a/include/linux/pruss.h -+++ b/include/linux/pruss.h -@@ -71,8 +71,10 @@ - #define PRUSS_MII_RT_EVENT_EN BIT(0) - - /* PRUSS_SPP register bits */ --#define PRUSS_SPP_XFER_SHIFT_EN BIT(1) - #define PRUSS_SPP_PRU1_PAD_HP_EN BIT(0) -+#define PRUSS_SPP_XFER_SHIFT_EN BIT(1) -+#define PRUSS_SPP_XFR_BYTE_SHIFT_EN BIT(2) -+#define PRUSS_SPP_RTU_XFR_SHIFT_EN BIT(3) - - /* - * enum pruss_gp_mux_sel - PRUSS GPI/O Mux modes for the diff --git a/recipes-kernel/linux/files/patches-5.10/0087-net-ethernet-ti-icssg_prueth-add-10M-full-duplex-sup.patch b/recipes-kernel/linux/files/patches-5.10/0087-net-ethernet-ti-icssg_prueth-add-10M-full-duplex-sup.patch deleted file mode 100644 index 933c4c310..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0087-net-ethernet-ti-icssg_prueth-add-10M-full-duplex-sup.patch +++ /dev/null @@ -1,250 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Tue, 18 May 2021 23:37:24 +0300 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: add 10M full duplex support - -For 10M support RGMII need to be configured in inband mode and FW has to be -notified about current link speed in PORT_LINK_SPEED MMR. - -There is an issue which causes ICSSG FW to stuck if link down happens while -there is TX traffic and only ICSSG reset helps to recovery. -Hence, enable 10M FD only for SR1.0 as it has FW fix for above issue. - -Signed-off-by: Vignesh Raghavendra -Signed-off-by: Grygorii Strashko ---- - drivers/net/ethernet/ti/icss_mii_rt.h | 17 +++++++--- - drivers/net/ethernet/ti/icssg_config.c | 39 ++++++++++++++++++---- - drivers/net/ethernet/ti/icssg_prueth.c | 26 ++++++--------- - drivers/net/ethernet/ti/icssg_prueth.h | 1 + - drivers/net/ethernet/ti/icssg_switch_map.h | 6 ++++ - 5 files changed, 63 insertions(+), 26 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_mii_rt.h b/drivers/net/ethernet/ti/icss_mii_rt.h -index a7643bb46b9d..836060ffdd4a 100644 ---- a/drivers/net/ethernet/ti/icss_mii_rt.h -+++ b/drivers/net/ethernet/ti/icss_mii_rt.h -@@ -105,7 +105,9 @@ - enum mii_mode { MII_MODE_MII = 0, MII_MODE_RGMII, MII_MODE_SGMII }; - - /* RGMII CFG Register bits */ -+#define RGMII_CFG_INBAND_EN_MII0 BIT(16) - #define RGMII_CFG_GIG_EN_MII0 BIT(17) -+#define RGMII_CFG_INBAND_EN_MII1 BIT(20) - #define RGMII_CFG_GIG_EN_MII1 BIT(21) - #define RGMII_CFG_FULL_DUPLEX_MII0 BIT(18) - #define RGMII_CFG_FULL_DUPLEX_MII1 BIT(22) -@@ -135,20 +137,27 @@ static inline void icssg_mii_update_ipg(struct regmap *mii_rt, int mii, u32 ipg) - } - } - --static inline void icssg_update_rgmii_cfg(struct regmap *miig_rt, bool gig_en, -- bool full_duplex, int mii) -+static inline void icssg_update_rgmii_cfg(struct regmap *miig_rt, int speed, -+ int duplex, int mii) - { - u32 gig_en_mask, gig_val = 0, full_duplex_mask, full_duplex_val = 0; -+ u32 inband_en_mask, inband_val = 0; - - gig_en_mask = (mii == ICSS_MII0) ? RGMII_CFG_GIG_EN_MII0 : - RGMII_CFG_GIG_EN_MII1; -- if (gig_en) -+ if (speed == SPEED_1000) - gig_val = gig_en_mask; - regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, gig_en_mask, gig_val); - -+ inband_en_mask = (mii == ICSS_MII0) ? RGMII_CFG_INBAND_EN_MII0 : -+ RGMII_CFG_INBAND_EN_MII1; -+ if (speed == SPEED_10) -+ inband_val = inband_en_mask; -+ regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, inband_en_mask, inband_val); -+ - full_duplex_mask = (mii == ICSS_MII0) ? RGMII_CFG_FULL_DUPLEX_MII0 : - RGMII_CFG_FULL_DUPLEX_MII1; -- if (full_duplex) -+ if (duplex == DUPLEX_FULL) - full_duplex_val = full_duplex_mask; - regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, full_duplex_mask, - full_duplex_val); -diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c -index 3f0ab061e0e6..b5cef264cdf9 100644 ---- a/drivers/net/ethernet/ti/icssg_config.c -+++ b/drivers/net/ethernet/ti/icssg_config.c -@@ -15,12 +15,10 @@ - * h/w design. - */ - --/* SR1.0 IPG is in core_clk cycles */ -+/* IPG is in core_clk cycles */ - #define MII_RT_TX_IPG_100M_SR1 0x166 --#define MII_RT_TX_IPG_1G_SR1 0x18 -- --/* SR2.0 IPG is in rgmii_clk (125MHz) clock cycles + 1 */ --#define MII_RT_TX_IPG_100M 0xb2 /* FIXME: cross check */ -+#define MII_RT_TX_IPG_1G_SR1 0x1a -+#define MII_RT_TX_IPG_100M 0x17 - #define MII_RT_TX_IPG_1G 0xb - - #define ICSSG_QUEUES_MAX 64 -@@ -128,7 +126,7 @@ static void icssg_config_rgmii_init(struct prueth *prueth, int slice) - mii_mode |= MII_MODE_RGMII << ICSSG_CFG_MII1_MODE_SHIFT; - regmap_write(miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_DEFAULT | mii_mode); - -- icssg_update_rgmii_cfg(miig_rt, true, true, slice); -+ icssg_update_rgmii_cfg(miig_rt, SPEED_1000, DUPLEX_FULL, slice); - /* reset hwqueues */ - if (slice) - queue = ICSSG_NUM_TX_QUEUES; -@@ -190,6 +188,12 @@ void icssg_config_ipg(struct prueth *prueth, int speed, int mii) - icssg_mii_update_ipg(prueth->mii_rt, mii, prueth->is_sr1 ? - MII_RT_TX_IPG_100M_SR1 : MII_RT_TX_IPG_100M); - break; -+ case SPEED_10: -+ /* Firmware hardcodes IPG for PG1. PG2 same as 100M */ -+ if (!prueth->is_sr1) -+ icssg_mii_update_ipg(prueth->mii_rt, mii, -+ MII_RT_TX_IPG_100M); -+ break; - default: - /* Other links speeds not supported */ - pr_err("Unsupported link speed\n"); -@@ -410,3 +414,26 @@ int emac_set_port_state(struct prueth_emac *emac, - - return ret; - } -+ -+void icssg_config_set_speed(struct prueth_emac *emac) -+{ -+ u8 fw_speed; -+ -+ switch (emac->speed) { -+ case SPEED_1000: -+ fw_speed = FW_LINK_SPEED_1G; -+ break; -+ case SPEED_100: -+ fw_speed = FW_LINK_SPEED_100M; -+ break; -+ case SPEED_10: -+ fw_speed = FW_LINK_SPEED_10M; -+ break; -+ default: -+ /* Other links speeds not supported */ -+ pr_err("Unsupported link speed\n"); -+ return; -+ } -+ -+ writeb(fw_speed, emac->dram.va + PORT_LINK_SPEED_OFFSET); -+} -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 5a9b8aa41bb8..730f08471738 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -655,18 +655,16 @@ static int emac_send_command_sr1(struct prueth_emac *emac, u32 cmd) - return ret; - } - --static void emac_change_port_speed_duplex(struct prueth_emac *emac, -- bool full_duplex, int speed) -+static void emac_change_port_speed_duplex(struct prueth_emac *emac) - { - u32 cmd = ICSSG_PSTATE_SPEED_DUPLEX_CMD, val; - struct prueth *prueth = emac->prueth; - int slice = prueth_emac_slice(emac); - -- /* only 100M and 1G and full duplex supported for now */ -- if (!(full_duplex && (speed == SPEED_1000 || speed == SPEED_100))) -+ /* only full duplex supported for now */ -+ if (emac->duplex != DUPLEX_FULL) - return; - -- /* FIXME for SR2.0 */ - if (!emac->is_sr1) - return; - -@@ -1058,7 +1056,6 @@ static void emac_adjust_link(struct net_device *ndev) - { - struct prueth_emac *emac = netdev_priv(ndev); - struct phy_device *phydev = emac->phydev; -- bool gig_en = false, full_duplex = false; - struct prueth *prueth = emac->prueth; - int slice = prueth_emac_slice(emac); - bool new_state = false; -@@ -1098,17 +1095,13 @@ static void emac_adjust_link(struct net_device *ndev) - */ - spin_lock_irqsave(&emac->lock, flags); - if (emac->link) { -- if (phydev->speed == SPEED_1000) -- gig_en = true; -- -- if (phydev->duplex == DUPLEX_FULL) -- full_duplex = true; - /* Set the RGMII cfg for gig en and full duplex */ -- icssg_update_rgmii_cfg(prueth->miig_rt, gig_en, -- full_duplex, slice); -+ icssg_update_rgmii_cfg(prueth->miig_rt, emac->speed, -+ emac->duplex, slice); - - /* update the Tx IPG based on 100M/1G speed */ - icssg_config_ipg(prueth, emac->speed, slice); -+ icssg_config_set_speed(emac); - } - spin_unlock_irqrestore(&emac->lock, flags); - -@@ -1116,8 +1109,7 @@ static void emac_adjust_link(struct net_device *ndev) - * setting when link is up. - */ - if (emac->link) -- emac_change_port_speed_duplex(emac, full_duplex, -- emac->speed); -+ emac_change_port_speed_duplex(emac); - } - - if (emac->link) { -@@ -1718,8 +1710,10 @@ static int prueth_netdev_init(struct prueth *prueth, - } - - /* remove unsupported modes */ -+ /* 10M FD fixed in FW for SR1.0 */ -+ if (!emac->is_sr1) -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT); - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); -- phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT); - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Pause_BIT); -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 1c2908eb2d57..69c558eb004d 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -247,6 +247,7 @@ int icssg_config_sr2(struct prueth *prueth, struct prueth_emac *emac, - int slice); - int emac_set_port_state(struct prueth_emac *emac, - enum icssg_port_state_cmd state); -+void icssg_config_set_speed(struct prueth_emac *emac); - #define prueth_napi_to_tx_chn(pnapi) \ - container_of(pnapi, struct prueth_tx_chn, napi_tx) - -diff --git a/drivers/net/ethernet/ti/icssg_switch_map.h b/drivers/net/ethernet/ti/icssg_switch_map.h -index bf52d350bdd0..644a22b53424 100644 ---- a/drivers/net/ethernet/ti/icssg_switch_map.h -+++ b/drivers/net/ethernet/ti/icssg_switch_map.h -@@ -13,6 +13,10 @@ - * - */ - -+#define FW_LINK_SPEED_1G (0x00) -+#define FW_LINK_SPEED_100M (0x01) -+#define FW_LINK_SPEED_10M (0x02) -+ - /*Time after which FDB entries are checked for aged out values. Value in nanoseconds*/ - #define FDB_AGEING_TIMEOUT_OFFSET 0x0014 - /*default VLAN tag for Host Port*/ -@@ -122,6 +126,8 @@ - #define EXPRESS_PRE_EMPTIVE_Q_MAP 0x0034 - /*Stores the table used for priority mapping. 1B per PCP/Queue*/ - #define PORT_Q_PRIORITY_MAPPING_OFFSET 0x003C -+/*Used to notify the FW of the current link speed*/ -+#define PORT_LINK_SPEED_OFFSET 0x00A8 - /*TAS gate mask for windows list0*/ - #define TAS_GATE_MASK_LIST0 0x0100 - /*TAS gate mask for windows list1*/ diff --git a/recipes-kernel/linux/files/patches-5.10/0088-net-ethernet-ti-icssg_prueth-Use-DMA-device-for-DMA-.patch b/recipes-kernel/linux/files/patches-5.10/0088-net-ethernet-ti-icssg_prueth-Use-DMA-device-for-DMA-.patch deleted file mode 100644 index 4bcca0e8e..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0088-net-ethernet-ti-icssg_prueth-Use-DMA-device-for-DMA-.patch +++ /dev/null @@ -1,342 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Tue, 18 May 2021 23:37:25 +0300 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: Use DMA device for DMA API - -For DMA API the DMA device should be used as cpsw does not accesses to -descriptors or data buffers in any ways. The DMA does. - -Also, drop dma_coerce_mask_and_coherent() setting on ICSSG device, as it -should be done by DMA driver which does data movement. - -This is required for adding AM64x ICSSG support where DMA coherency -supported per DMA channel. - -Signed-off-by: Vignesh Raghavendra -Signed-off-by: Grygorii Strashko ---- - drivers/net/ethernet/ti/icssg_prueth.c | 100 ++++++++++++------------- - drivers/net/ethernet/ti/icssg_prueth.h | 2 + - 2 files changed, 50 insertions(+), 52 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 730f08471738..90cb3418d72f 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -108,7 +108,6 @@ static void prueth_ndev_del_tx_napi(struct prueth_emac *emac, int num) - } - - static void prueth_xmit_free(struct prueth_tx_chn *tx_chn, -- struct device *dev, - struct cppi5_host_desc_t *desc) - { - struct cppi5_host_desc_t *first_desc, *next_desc; -@@ -120,7 +119,7 @@ static void prueth_xmit_free(struct prueth_tx_chn *tx_chn, - - cppi5_hdesc_get_obuf(first_desc, &buf_dma, &buf_dma_len); - -- dma_unmap_single(dev, buf_dma, buf_dma_len, -+ dma_unmap_single(tx_chn->dma_dev, buf_dma, buf_dma_len, - DMA_TO_DEVICE); - - next_desc_dma = cppi5_hdesc_get_next_hbdesc(first_desc); -@@ -129,7 +128,7 @@ static void prueth_xmit_free(struct prueth_tx_chn *tx_chn, - next_desc_dma); - cppi5_hdesc_get_obuf(next_desc, &buf_dma, &buf_dma_len); - -- dma_unmap_page(dev, buf_dma, buf_dma_len, -+ dma_unmap_page(tx_chn->dma_dev, buf_dma, buf_dma_len, - DMA_TO_DEVICE); - - next_desc_dma = cppi5_hdesc_get_next_hbdesc(next_desc); -@@ -145,7 +144,6 @@ static int emac_tx_complete_packets(struct prueth_emac *emac, int chn, - { - struct net_device *ndev = emac->ndev; - struct cppi5_host_desc_t *desc_tx; -- struct device *dev = emac->prueth->dev; - struct netdev_queue *netif_txq; - struct prueth_tx_chn *tx_chn; - unsigned int total_bytes = 0; -@@ -174,13 +172,13 @@ static int emac_tx_complete_packets(struct prueth_emac *emac, int chn, - - /* was this command's TX complete? */ - if (emac->is_sr1 && *(swdata) == emac->cmd_data) { -- prueth_xmit_free(tx_chn, dev, desc_tx); -+ prueth_xmit_free(tx_chn, desc_tx); - budget++; /* not a data packet */ - continue; - } - - skb = *(swdata); -- prueth_xmit_free(tx_chn, dev, desc_tx); -+ prueth_xmit_free(tx_chn, desc_tx); - - ndev = skb->dev; - ndev->stats.tx_packets++; -@@ -301,17 +299,6 @@ static int prueth_init_tx_chns(struct prueth_emac *emac) - tx_chn->emac = emac; - tx_chn->id = i; - tx_chn->descs_num = PRUETH_MAX_TX_DESC; -- tx_chn->desc_pool = -- k3_cppi_desc_pool_create_name(dev, -- tx_chn->descs_num, -- hdesc_size, -- tx_chn->name); -- if (IS_ERR(tx_chn->desc_pool)) { -- ret = PTR_ERR(tx_chn->desc_pool); -- tx_chn->desc_pool = NULL; -- netdev_err(ndev, "Failed to create tx pool: %d\n", ret); -- goto fail; -- } - - tx_chn->tx_chn = - k3_udma_glue_request_tx_chn(dev, tx_chn->name, -@@ -324,6 +311,19 @@ static int prueth_init_tx_chns(struct prueth_emac *emac) - goto fail; - } - -+ tx_chn->dma_dev = k3_udma_glue_tx_get_dma_device(tx_chn->tx_chn); -+ tx_chn->desc_pool = -+ k3_cppi_desc_pool_create_name(tx_chn->dma_dev, -+ tx_chn->descs_num, -+ hdesc_size, -+ tx_chn->name); -+ if (IS_ERR(tx_chn->desc_pool)) { -+ ret = PTR_ERR(tx_chn->desc_pool); -+ tx_chn->desc_pool = NULL; -+ netdev_err(ndev, "Failed to create tx pool: %d\n", ret); -+ goto fail; -+ } -+ - tx_chn->irq = k3_udma_glue_tx_get_irq(tx_chn->tx_chn); - if (tx_chn->irq <= 0) { - ret = -EINVAL; -@@ -371,16 +371,6 @@ static int prueth_init_rx_chns(struct prueth_emac *emac, - /* init all flows */ - rx_chn->dev = dev; - rx_chn->descs_num = max_desc_num; -- rx_chn->desc_pool = k3_cppi_desc_pool_create_name(dev, -- rx_chn->descs_num, -- hdesc_size, -- rx_chn->name); -- if (IS_ERR(rx_chn->desc_pool)) { -- ret = PTR_ERR(rx_chn->desc_pool); -- rx_chn->desc_pool = NULL; -- netdev_err(ndev, "Failed to create rx pool: %d\n", ret); -- goto fail; -- } - - rx_chn->rx_chn = k3_udma_glue_request_rx_chn(dev, rx_chn->name, - &rx_cfg); -@@ -391,6 +381,18 @@ static int prueth_init_rx_chns(struct prueth_emac *emac, - goto fail; - } - -+ rx_chn->dma_dev = k3_udma_glue_rx_get_dma_device(rx_chn->rx_chn); -+ rx_chn->desc_pool = k3_cppi_desc_pool_create_name(rx_chn->dma_dev, -+ rx_chn->descs_num, -+ hdesc_size, -+ rx_chn->name); -+ if (IS_ERR(rx_chn->desc_pool)) { -+ ret = PTR_ERR(rx_chn->desc_pool); -+ rx_chn->desc_pool = NULL; -+ netdev_err(ndev, "Failed to create rx pool: %d\n", ret); -+ goto fail; -+ } -+ - if (!strncmp(name, "rxmgm", 5)) { - emac->rx_mgm_flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn); - netdev_dbg(ndev, "mgm flow id base = %d\n", -@@ -454,7 +456,6 @@ static int prueth_dma_rx_push(struct prueth_emac *emac, - struct prueth_rx_chn *rx_chn) - { - struct cppi5_host_desc_t *desc_rx; -- struct device *dev = emac->prueth->dev; - struct net_device *ndev = emac->ndev; - dma_addr_t desc_dma; - dma_addr_t buf_dma; -@@ -468,8 +469,8 @@ static int prueth_dma_rx_push(struct prueth_emac *emac, - } - desc_dma = k3_cppi_desc_pool_virt2dma(rx_chn->desc_pool, desc_rx); - -- buf_dma = dma_map_single(dev, skb->data, pkt_len, DMA_FROM_DEVICE); -- if (unlikely(dma_mapping_error(dev, buf_dma))) { -+ buf_dma = dma_map_single(rx_chn->dma_dev, skb->data, pkt_len, DMA_FROM_DEVICE); -+ if (unlikely(dma_mapping_error(rx_chn->dma_dev, buf_dma))) { - k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); - netdev_err(ndev, "rx push: failed to map rx pkt buffer\n"); - return -EINVAL; -@@ -489,7 +490,6 @@ static int prueth_dma_rx_push(struct prueth_emac *emac, - static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) - { - struct prueth_rx_chn *rx_chn = &emac->rx_chns; -- struct device *dev = emac->prueth->dev; - struct net_device *ndev = emac->ndev; - struct cppi5_host_desc_t *desc_rx; - dma_addr_t desc_dma, buf_dma; -@@ -522,7 +522,7 @@ static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) - pkt_len -= 4; - cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL); - -- dma_unmap_single(dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE); -+ dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE); - k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); - - skb->dev = ndev; -@@ -572,7 +572,7 @@ static void prueth_rx_cleanup(void *data, dma_addr_t desc_dma) - skb = *swdata; - cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); - -- dma_unmap_single(rx_chn->dev, buf_dma, buf_dma_len, -+ dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, - DMA_FROM_DEVICE); - k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); - -@@ -584,7 +584,6 @@ static void prueth_rx_cleanup(void *data, dma_addr_t desc_dma) - */ - static int emac_send_command_sr1(struct prueth_emac *emac, u32 cmd) - { -- struct device *dev = emac->prueth->dev; - dma_addr_t desc_dma, buf_dma; - struct prueth_tx_chn *tx_chn; - struct cppi5_host_desc_t *first_desc; -@@ -600,21 +599,21 @@ static int emac_send_command_sr1(struct prueth_emac *emac, u32 cmd) - mutex_lock(&emac->cmd_lock); - data[0] = cpu_to_le32(cmd); - -+ /* highest priority channel for management messages */ -+ tx_chn = &emac->tx_chns[emac->tx_ch_num - 1]; -+ - /* Map the linear buffer */ -- buf_dma = dma_map_single(dev, data, pkt_len, DMA_TO_DEVICE); -- if (dma_mapping_error(dev, buf_dma)) { -+ buf_dma = dma_map_single(tx_chn->dma_dev, data, pkt_len, DMA_TO_DEVICE); -+ if (dma_mapping_error(tx_chn->dma_dev, buf_dma)) { - netdev_err(emac->ndev, "cmd %x: failed to map cmd buffer\n", cmd); - ret = -EINVAL; - goto err_unlock; - } - -- /* highest priority channel for management messages */ -- tx_chn = &emac->tx_chns[emac->tx_ch_num - 1]; -- - first_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool); - if (!first_desc) { - netdev_err(emac->ndev, "cmd %x: failed to allocate descriptor\n", cmd); -- dma_unmap_single(dev, buf_dma, pkt_len, DMA_TO_DEVICE); -+ dma_unmap_single(tx_chn->dma_dev, buf_dma, pkt_len, DMA_TO_DEVICE); - ret = -ENOMEM; - goto err_unlock; - } -@@ -648,7 +647,7 @@ static int emac_send_command_sr1(struct prueth_emac *emac, u32 cmd) - - return ret; - free_desc: -- prueth_xmit_free(tx_chn, dev, first_desc); -+ prueth_xmit_free(tx_chn, first_desc); - err_unlock: - mutex_unlock(&emac->cmd_lock); - -@@ -707,7 +706,6 @@ static int emac_shutdown(struct net_device *ndev) - static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - { - struct prueth_emac *emac = netdev_priv(ndev); -- struct device *dev = emac->prueth->dev; - struct cppi5_host_desc_t *first_desc, *next_desc, *cur_desc; - struct netdev_queue *netif_txq; - struct prueth_tx_chn *tx_chn; -@@ -724,8 +722,8 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - netif_txq = netdev_get_tx_queue(ndev, q_idx); - - /* Map the linear buffer */ -- buf_dma = dma_map_single(dev, skb->data, pkt_len, DMA_TO_DEVICE); -- if (dma_mapping_error(dev, buf_dma)) { -+ buf_dma = dma_map_single(tx_chn->dma_dev, skb->data, pkt_len, DMA_TO_DEVICE); -+ if (dma_mapping_error(tx_chn->dma_dev, buf_dma)) { - netdev_err(ndev, "tx: failed to map skb buffer\n"); - ret = -EINVAL; - goto drop_stop_q; -@@ -734,7 +732,7 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - first_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool); - if (!first_desc) { - netdev_dbg(ndev, "tx: failed to allocate descriptor\n"); -- dma_unmap_single(dev, buf_dma, pkt_len, DMA_TO_DEVICE); -+ dma_unmap_single(tx_chn->dma_dev, buf_dma, pkt_len, DMA_TO_DEVICE); - ret = -ENOMEM; - goto drop_stop_q_busy; - } -@@ -771,9 +769,9 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - goto drop_free_descs; - } - -- buf_dma = skb_frag_dma_map(dev, frag, 0, frag_size, -+ buf_dma = skb_frag_dma_map(tx_chn->dma_dev, frag, 0, frag_size, - DMA_TO_DEVICE); -- if (dma_mapping_error(dev, buf_dma)) { -+ if (dma_mapping_error(tx_chn->dma_dev, buf_dma)) { - netdev_err(ndev, "tx: Failed to map skb page\n"); - k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc); - ret = -EINVAL; -@@ -821,7 +819,7 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - return NETDEV_TX_OK; - - drop_free_descs: -- prueth_xmit_free(tx_chn, dev, first_desc); -+ prueth_xmit_free(tx_chn, first_desc); - drop_stop_q: - netif_tx_stop_queue(netif_txq); - dev_kfree_skb_any(skb); -@@ -840,7 +838,6 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - static void prueth_tx_cleanup(void *data, dma_addr_t desc_dma) - { - struct prueth_tx_chn *tx_chn = data; -- struct prueth_emac *emac = tx_chn->emac; - struct cppi5_host_desc_t *desc_tx; - struct sk_buff *skb; - void **swdata; -@@ -848,7 +845,7 @@ static void prueth_tx_cleanup(void *data, dma_addr_t desc_dma) - desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma); - swdata = cppi5_hdesc_get_swdata(desc_tx); - skb = *(swdata); -- prueth_xmit_free(tx_chn, emac->prueth->dev, desc_tx); -+ prueth_xmit_free(tx_chn, desc_tx); - - dev_kfree_skb_any(skb); - } -@@ -862,7 +859,6 @@ static struct sk_buff *prueth_process_rx_mgm(struct prueth_emac *emac, - u32 flow_id) - { - struct prueth_rx_chn *rx_chn = &emac->rx_mgm_chn; -- struct device *dev = emac->prueth->dev; - struct net_device *ndev = emac->ndev; - struct cppi5_host_desc_t *desc_rx; - dma_addr_t desc_dma, buf_dma; -@@ -894,7 +890,7 @@ static struct sk_buff *prueth_process_rx_mgm(struct prueth_emac *emac, - cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); - pkt_len = cppi5_hdesc_get_pktlen(desc_rx); - -- dma_unmap_single(dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE); -+ dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE); - k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); - - new_skb = netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE); -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 69c558eb004d..2e8d45c8c25d 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -86,6 +86,7 @@ enum prueth_mac { - }; - - struct prueth_tx_chn { -+ struct device *dma_dev; - struct napi_struct napi_tx; - struct k3_cppi_desc_pool *desc_pool; - struct k3_udma_glue_tx_channel *tx_chn; -@@ -98,6 +99,7 @@ struct prueth_tx_chn { - - struct prueth_rx_chn { - struct device *dev; -+ struct device *dma_dev; - struct k3_cppi_desc_pool *desc_pool; - struct k3_udma_glue_rx_channel *rx_chn; - u32 descs_num; diff --git a/recipes-kernel/linux/files/patches-5.10/0089-net-ethernet-ti-icss_iep-add-icss_iep_get_idx-api.patch b/recipes-kernel/linux/files/patches-5.10/0089-net-ethernet-ti-icss_iep-add-icss_iep_get_idx-api.patch deleted file mode 100644 index cf0317f6c..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0089-net-ethernet-ti-icss_iep-add-icss_iep_get_idx-api.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Tue, 18 May 2021 23:37:26 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: add icss_iep_get_idx() api - -Add icss_iep_get_idx() API to allow retrieve IEP from phandle list in DT. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 10 ++++++++-- - drivers/net/ethernet/ti/icss_iep.h | 1 + - 2 files changed, 9 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index 640f483854d0..51f8717fc446 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -754,13 +754,13 @@ static enum hrtimer_restart icss_iep_sync0_work(struct hrtimer *timer) - return HRTIMER_NORESTART; - } - --struct icss_iep *icss_iep_get(struct device_node *np) -+struct icss_iep *icss_iep_get_idx(struct device_node *np, int idx) - { - struct platform_device *pdev; - struct device_node *iep_np; - struct icss_iep *iep; - -- iep_np = of_parse_phandle(np, "iep", 0); -+ iep_np = of_parse_phandle(np, "iep", idx); - if (!iep_np || !of_device_is_available(iep_np)) - return ERR_PTR(-ENODEV); - -@@ -804,6 +804,12 @@ struct icss_iep *icss_iep_get(struct device_node *np) - exit: - return iep; - } -+EXPORT_SYMBOL_GPL(icss_iep_get_idx); -+ -+struct icss_iep *icss_iep_get(struct device_node *np) -+{ -+ return icss_iep_get_idx(np, 0); -+} - EXPORT_SYMBOL_GPL(icss_iep_get); - - void icss_iep_put(struct icss_iep *iep) -diff --git a/drivers/net/ethernet/ti/icss_iep.h b/drivers/net/ethernet/ti/icss_iep.h -index a41e18df666e..eefc8c8bd8cc 100644 ---- a/drivers/net/ethernet/ti/icss_iep.h -+++ b/drivers/net/ethernet/ti/icss_iep.h -@@ -26,6 +26,7 @@ struct icss_iep_clockops { - }; - - struct icss_iep *icss_iep_get(struct device_node *np); -+struct icss_iep *icss_iep_get_idx(struct device_node *np, int idx); - void icss_iep_put(struct icss_iep *iep); - int icss_iep_init(struct icss_iep *iep, const struct icss_iep_clockops *clkops, - void *clockops_data, u32 cycle_time_ns); diff --git a/recipes-kernel/linux/files/patches-5.10/0090-net-ethernet-ti-icss_iep-use-readl-in-icss_iep_get_c.patch b/recipes-kernel/linux/files/patches-5.10/0090-net-ethernet-ti-icss_iep-use-readl-in-icss_iep_get_c.patch deleted file mode 100644 index 3f6a77c47..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0090-net-ethernet-ti-icss_iep-use-readl-in-icss_iep_get_c.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Tue, 18 May 2021 23:37:27 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: use readl() in - icss_iep_get_count_low/hi() - -Use readl() in icss_iep_get_count_low/hi() to speed up hot path. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index 51f8717fc446..23e72e0ffe46 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -147,7 +147,7 @@ int icss_iep_get_count_hi(struct icss_iep *iep) - u32 val = 0; - - if (iep && (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)) -- regmap_read(iep->map, ICSS_IEP_COUNT_REG1, &val); -+ val = icss_iep_readl(iep, ICSS_IEP_COUNT_REG1); - - return val; - } -@@ -164,7 +164,7 @@ int icss_iep_get_count_low(struct icss_iep *iep) - u32 val = 0; - - if (iep) -- regmap_read(iep->map, ICSS_IEP_COUNT_REG0, &val); -+ val = icss_iep_readl(iep, ICSS_IEP_COUNT_REG0); - - return val; - } diff --git a/recipes-kernel/linux/files/patches-5.10/0091-net-ethernet-ti-icss_iep-fix-init-for-sr2.0.patch b/recipes-kernel/linux/files/patches-5.10/0091-net-ethernet-ti-icss_iep-fix-init-for-sr2.0.patch deleted file mode 100644 index 57e03049c..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0091-net-ethernet-ti-icss_iep-fix-init-for-sr2.0.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Tue, 18 May 2021 23:37:28 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: fix init for sr2.0 - -There are two issues with IEP initialization for ICSSG SR2.0 where only one -IEP0 is used in shadow mode: -- IEP counter set to the current system time by writing into registers -directly, but instead counter need to be reset to 0 and special FW command -used to set time. -- PPS/PEROUT and EXTTS are not enabled for SR2.0 as corresponding checks -performed in icss_iep_get() when icss_iep_clockops are not set yet. - -Hence, fix above two issue by reworking IEP initialization. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 64 +++++++++++++++--------------- - 1 file changed, 31 insertions(+), 33 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index 23e72e0ffe46..eec7e9fb1f61 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -254,13 +254,13 @@ static void icss_iep_disable(struct icss_iep *iep) - 0); - } - --static void icss_iep_enable_shadow_mode(struct icss_iep *iep, u32 cycle_time_ns) -+static void icss_iep_enable_shadow_mode(struct icss_iep *iep) - { - u32 cycle_time; - int cmp; - - /* FIXME: check why we need to decrement by def_inc */ -- cycle_time = cycle_time_ns - iep->def_inc; -+ cycle_time = iep->cycle_time_ns - iep->def_inc; - - icss_iep_disable(iep); - -@@ -300,6 +300,7 @@ static void icss_iep_enable_shadow_mode(struct icss_iep *iep, u32 cycle_time_ns) - if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) - regmap_write(iep->map, ICSS_IEP_CMP0_REG1, cycle_time); - -+ icss_iep_set_counter(iep, 0); - icss_iep_enable(iep); - } - -@@ -786,22 +787,6 @@ struct icss_iep *icss_iep_get_idx(struct device_node *np, int idx) - device_unlock(iep->dev); - get_device(iep->dev); - -- iep->ptp_info = icss_iep_ptp_info; -- -- -- if (!(iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) || -- !(iep->plat_data->flags & ICSS_IEP_SLOW_COMPEN_REG_SUPPORT)) -- goto exit; -- -- if (iep->cap_cmp_irq || (iep->ops && iep->ops->perout_enable)) { -- iep->ptp_info.n_per_out = 1; -- iep->ptp_info.pps = 1; -- } -- -- if (iep->cap_cmp_irq || (iep->ops && iep->ops->extts_enable)) -- iep->ptp_info.n_ext_ts = 2; -- --exit: - return iep; - } - EXPORT_SYMBOL_GPL(icss_iep_get_idx); -@@ -826,33 +811,38 @@ EXPORT_SYMBOL_GPL(icss_iep_put); - int icss_iep_init(struct icss_iep *iep, const struct icss_iep_clockops *clkops, - void *clockops_data, u32 cycle_time_ns) - { -- u32 def_inc; - int ret = 0; - -- def_inc = NSEC_PER_SEC / iep->refclk_freq; /* ns per clock tick */ -- if (def_inc > IEP_MAX_DEF_INC) -- /* iep_core_clk too slow to be supported */ -- return -EINVAL; -- -- iep->def_inc = def_inc; -+ iep->cycle_time_ns = cycle_time_ns; -+ iep->clk_tick_time = iep->def_inc; - iep->ops = clkops; - iep->clockops_data = clockops_data; -- icss_iep_set_default_inc(iep, def_inc); -- icss_iep_set_compensation_inc(iep, def_inc); -+ icss_iep_set_default_inc(iep, iep->def_inc); -+ icss_iep_set_compensation_inc(iep, iep->def_inc); - icss_iep_set_compensation_count(iep, 0); - regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG, iep->refclk_freq / 10); /* 100 ms pulse */ - regmap_write(iep->map, ICSS_IEP_SYNC0_PERIOD_REG, 0); - if (iep->plat_data->flags & ICSS_IEP_SLOW_COMPEN_REG_SUPPORT) - icss_iep_set_slow_compensation_count(iep, 0); -+ -+ if (!(iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) || -+ !(iep->plat_data->flags & ICSS_IEP_SLOW_COMPEN_REG_SUPPORT)) -+ goto skip_perout; -+ -+ if (iep->cap_cmp_irq || (iep->ops && iep->ops->perout_enable)) { -+ iep->ptp_info.n_per_out = 1; -+ iep->ptp_info.pps = 1; -+ } -+ -+ if (iep->cap_cmp_irq || (iep->ops && iep->ops->extts_enable)) -+ iep->ptp_info.n_ext_ts = 2; -+ -+skip_perout: - if (cycle_time_ns) -- icss_iep_enable_shadow_mode(iep, cycle_time_ns); -+ icss_iep_enable_shadow_mode(iep); - else - icss_iep_enable(iep); -- -- iep->cycle_time_ns = cycle_time_ns; -- icss_iep_set_counter(iep, ktime_get_real_ns()); -- -- iep->clk_tick_time = def_inc; -+ icss_iep_settime(iep, ktime_get_real_ns()); - - iep->ptp_clock = ptp_clock_register(&iep->ptp_info, iep->dev); - if (IS_ERR(iep->ptp_clock)) { -@@ -918,6 +908,13 @@ static int icss_iep_probe(struct platform_device *pdev) - - iep->refclk_freq = clk_get_rate(iep_clk); - -+ iep->def_inc = NSEC_PER_SEC / iep->refclk_freq; /* ns per clock tick */ -+ if (iep->def_inc > IEP_MAX_DEF_INC) { -+ dev_err(dev, "Failed to set def_inc %d. IEP_clock is too slow to be supported\n", -+ iep->def_inc); -+ return -EINVAL; -+ } -+ - iep->plat_data = of_device_get_match_data(dev); - if (!iep->plat_data) - return -EINVAL; -@@ -929,6 +926,7 @@ static int icss_iep_probe(struct platform_device *pdev) - return PTR_ERR(iep->map); - } - -+ iep->ptp_info = icss_iep_ptp_info; - mutex_init(&iep->ptp_clk_mutex); - dev_set_drvdata(dev, iep); - icss_iep_disable(iep); diff --git a/recipes-kernel/linux/files/patches-5.10/0092-net-ethernet-ti-icss_iep-sr2.0-fix-NULL-pointer-exce.patch b/recipes-kernel/linux/files/patches-5.10/0092-net-ethernet-ti-icss_iep-sr2.0-fix-NULL-pointer-exce.patch deleted file mode 100644 index d33803966..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0092-net-ethernet-ti-icss_iep-sr2.0-fix-NULL-pointer-exce.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Tue, 18 May 2021 23:37:29 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: sr2.0 fix NULL pointer exception - on pps stop - -The NULL pointer exception is observed on pps stop - fix it as timer is not -used for SR2.0. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index eec7e9fb1f61..0ed54c8251e2 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -553,7 +553,8 @@ static int icss_iep_perout_enable(struct icss_iep *iep, - goto exit; - - spin_lock_irqsave(&iep->irq_lock, flags); -- hrtimer_cancel(&iep->sync_timer); -+ if (iep->cap_cmp_irq) -+ hrtimer_cancel(&iep->sync_timer); - ret = icss_iep_perout_enable_hw(iep, req, on); - if (!ret) - iep->perout_enabled = !!on; -@@ -667,7 +668,8 @@ static int icss_iep_pps_enable(struct icss_iep *iep, int on) - rq.perout.start.nsec = 0; - ret = icss_iep_perout_enable_hw(iep, &rq.perout, on); - } else { -- hrtimer_cancel(&iep->sync_timer); -+ if (iep->cap_cmp_irq) -+ hrtimer_cancel(&iep->sync_timer); - ret = icss_iep_perout_enable_hw(iep, &rq.perout, on); - } - diff --git a/recipes-kernel/linux/files/patches-5.10/0094-net-ethernet-ti-icssg_prueth-add-am64x-icssg-support.patch b/recipes-kernel/linux/files/patches-5.10/0094-net-ethernet-ti-icssg_prueth-add-am64x-icssg-support.patch deleted file mode 100644 index eba9ea86f..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0094-net-ethernet-ti-icssg_prueth-add-am64x-icssg-support.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Tue, 18 May 2021 23:37:33 +0300 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: add am64x icssg support - -Add AM64x ICSSG support which is similar to am65x SR2.0, but required: -- all ring configured in exposed ring mode -- always fill both original and buffer fields in cppi5 desc - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - .../bindings/net/ti,icssg-prueth.txt | 1 + - drivers/net/ethernet/ti/icssg_prueth.c | 20 ++++++++++++++----- - drivers/net/ethernet/ti/icssg_prueth.h | 9 +++++++++ - 3 files changed, 25 insertions(+), 5 deletions(-) - -diff --git a/Documentation/devicetree/bindings/net/ti,icssg-prueth.txt b/Documentation/devicetree/bindings/net/ti,icssg-prueth.txt -index 67609e26afa5..125a204ef2d2 100644 ---- a/Documentation/devicetree/bindings/net/ti,icssg-prueth.txt -+++ b/Documentation/devicetree/bindings/net/ti,icssg-prueth.txt -@@ -4,6 +4,7 @@ Texas Instruments ICSSG PRUSS Ethernet - Required properties: - - compatible : Should be "ti,am654-icssg-prueth" for AM65x Family SoCs - "ti,am654-icssg-prueth-sr1" for SR1.0 -+ "ti,am642-icssg-prueth" for AM64x - - ti,prus : list of pHandles to the PRU, RTU and TX_PRU nodes - - firmware-name : should contain the name of the firmware image - file located in the firmware search path -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index f18af03964b1..c8cd1bb2c7be 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -409,12 +409,11 @@ static int prueth_init_rx_chns(struct prueth_emac *emac, - for (i = 0; i < rx_cfg.flow_id_num; i++) { - struct k3_ring_cfg rxring_cfg = { - .elm_size = K3_RINGACC_RING_ELSIZE_8, -- .mode = K3_RINGACC_RING_MODE_MESSAGE, -+ .mode = K3_RINGACC_RING_MODE_RING, - .flags = 0, - }; - struct k3_ring_cfg fdqring_cfg = { - .elm_size = K3_RINGACC_RING_ELSIZE_8, -- .mode = K3_RINGACC_RING_MODE_MESSAGE, - .flags = K3_RINGACC_RING_SHARED, - }; - struct k3_udma_glue_rx_flow_cfg rx_flow_cfg = { -@@ -428,6 +427,7 @@ static int prueth_init_rx_chns(struct prueth_emac *emac, - rx_flow_cfg.ring_rxfdq0_id = fdqring_id; - rx_flow_cfg.rx_cfg.size = max_desc_num; - rx_flow_cfg.rxfdq_cfg.size = max_desc_num; -+ rx_flow_cfg.rxfdq_cfg.mode = emac->prueth->pdata.fdqring_mode; - - ret = k3_udma_glue_rx_flow_init(rx_chn->rx_chn, - i, &rx_flow_cfg); -@@ -480,7 +480,7 @@ static int prueth_dma_rx_push(struct prueth_emac *emac, - - cppi5_hdesc_init(desc_rx, CPPI5_INFO0_HDESC_EPIB_PRESENT, - PRUETH_NAV_PS_DATA_SIZE); -- cppi5_hdesc_attach_buf(desc_rx, 0, 0, buf_dma, skb_tailroom(skb)); -+ cppi5_hdesc_attach_buf(desc_rx, buf_dma, skb_tailroom(skb), buf_dma, skb_tailroom(skb)); - - swdata = cppi5_hdesc_get_swdata(desc_rx); - *swdata = skb; -@@ -2318,6 +2318,7 @@ static int prueth_probe(struct platform_device *pdev) - - dev_set_drvdata(dev, prueth); - prueth->pdev = pdev; -+ prueth->pdata = *(const struct prueth_pdata *)match->data; - - if (of_device_is_compatible(np, "ti,am654-icssg-prueth-sr1")) - prueth->is_sr1 = true; -@@ -2668,9 +2669,18 @@ static const struct dev_pm_ops prueth_dev_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(prueth_suspend, prueth_resume) - }; - -+static const struct prueth_pdata am654_icssg_pdata = { -+ .fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE, -+}; -+ -+static const struct prueth_pdata am64x_icssg_pdata = { -+ .fdqring_mode = K3_RINGACC_RING_MODE_RING, -+}; -+ - static const struct of_device_id prueth_dt_match[] = { -- { .compatible = "ti,am654-icssg-prueth-sr1", }, -- { .compatible = "ti,am654-icssg-prueth", }, -+ { .compatible = "ti,am654-icssg-prueth-sr1", .data = &am654_icssg_pdata }, -+ { .compatible = "ti,am654-icssg-prueth", .data = &am654_icssg_pdata }, -+ { .compatible = "ti,am642-icssg-prueth", .data = &am64x_icssg_pdata }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, prueth_dt_match); -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 156716bf0a76..b536ac5ec0bf 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -170,6 +170,14 @@ struct prueth_emac { - struct pruss_mem_region dram; - }; - -+/** -+ * struct prueth - PRUeth platform data -+ * @fdqring_mode: Free desc queue mode -+ */ -+struct prueth_pdata { -+ enum k3_ring_mode fdqring_mode; -+}; -+ - /** - * struct prueth - PRUeth structure - * @is_sr1: device is pg1.0 (pg1.0 will be deprecated upstream) -@@ -214,6 +222,7 @@ struct prueth { - struct icss_iep *iep0; - struct icss_iep *iep1; - int iep_initialized; -+ struct prueth_pdata pdata; - }; - - struct emac_tx_ts_response_sr1 { diff --git a/recipes-kernel/linux/files/patches-5.10/0095-net-ethernet-ti-icssg_prueth-am65x-SR2.0-add-10M-ful.patch b/recipes-kernel/linux/files/patches-5.10/0095-net-ethernet-ti-icssg_prueth-am65x-SR2.0-add-10M-ful.patch deleted file mode 100644 index 456465779..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0095-net-ethernet-ti-icssg_prueth-am65x-SR2.0-add-10M-ful.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Wed, 19 May 2021 19:31:36 +0300 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: am65x SR2.0 add 10M full - duplex support - -For for AM65x SR2.0 it's required to enable IEP1 in raw 64bit mode which is -used by PRU FW to monitor the link and apply w/a for 10M link issue. -Note. No public errata available yet. - -Without this w/a the PRU FW will stuck if link state changes under TX -traffic pressure. - -Hence, add support for 10M full duplex for AM65x SR2.0: - - add new IEP API to enable IEP, but without PTP support - - add pdata quirk_10m_link_issue to enable 10M link issue w/a. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 26 ++++++++++++++++++++++++++ - drivers/net/ethernet/ti/icss_iep.h | 2 ++ - drivers/net/ethernet/ti/icssg_prueth.c | 19 +++++++++++++++---- - drivers/net/ethernet/ti/icssg_prueth.h | 3 +++ - 4 files changed, 46 insertions(+), 4 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index 0ed54c8251e2..d3aa3dca729c 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -810,6 +810,32 @@ void icss_iep_put(struct icss_iep *iep) - } - EXPORT_SYMBOL_GPL(icss_iep_put); - -+void icss_iep_init_fw(struct icss_iep *iep) -+{ -+ /* start IEP for FW use in raw 64bit mode, no PTP support */ -+ iep->clk_tick_time = iep->def_inc; -+ iep->cycle_time_ns = 0; -+ iep->ops = NULL; -+ iep->clockops_data = NULL; -+ icss_iep_set_default_inc(iep, iep->def_inc); -+ icss_iep_set_compensation_inc(iep, iep->def_inc); -+ icss_iep_set_compensation_count(iep, 0); -+ regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG, iep->refclk_freq / 10); /* 100 ms pulse */ -+ regmap_write(iep->map, ICSS_IEP_SYNC0_PERIOD_REG, 0); -+ if (iep->plat_data->flags & ICSS_IEP_SLOW_COMPEN_REG_SUPPORT) -+ icss_iep_set_slow_compensation_count(iep, 0); -+ -+ icss_iep_enable(iep); -+ icss_iep_settime(iep, 0); -+} -+EXPORT_SYMBOL_GPL(icss_iep_init_fw); -+ -+void icss_iep_exit_fw(struct icss_iep *iep) -+{ -+ icss_iep_disable(iep); -+} -+EXPORT_SYMBOL_GPL(icss_iep_exit_fw); -+ - int icss_iep_init(struct icss_iep *iep, const struct icss_iep_clockops *clkops, - void *clockops_data, u32 cycle_time_ns) - { -diff --git a/drivers/net/ethernet/ti/icss_iep.h b/drivers/net/ethernet/ti/icss_iep.h -index eefc8c8bd8cc..1c8f74ae659a 100644 ---- a/drivers/net/ethernet/ti/icss_iep.h -+++ b/drivers/net/ethernet/ti/icss_iep.h -@@ -34,5 +34,7 @@ int icss_iep_exit(struct icss_iep *iep); - int icss_iep_get_count_low(struct icss_iep *iep); - int icss_iep_get_count_hi(struct icss_iep *iep); - int icss_iep_get_ptp_clock_idx(struct icss_iep *iep); -+void icss_iep_init_fw(struct icss_iep *iep); -+void icss_iep_exit_fw(struct icss_iep *iep); - - #endif /* __NET_TI_ICSS_IEP_H */ -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index c8cd1bb2c7be..ef7392a2b9da 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -2127,9 +2127,6 @@ static int prueth_netdev_init(struct prueth *prueth, - } - - /* remove unsupported modes */ -- /* 10M FD fixed in FW for SR1.0 */ -- if (!emac->is_sr1) -- phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT); - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); -@@ -2457,6 +2454,11 @@ static int prueth_probe(struct platform_device *pdev) - icss_iep_exit(prueth->iep1); - goto free_iep; - } -+ } else if (prueth->pdata.quirk_10m_link_issue) { -+ /* Enable IEP1 for FW in 64bit mode as W/A for 10M FD link detect issue under TX -+ * traffic. -+ */ -+ icss_iep_init_fw(prueth->iep1); - } - - /* setup netdev interfaces */ -@@ -2540,6 +2542,8 @@ static int prueth_probe(struct platform_device *pdev) - if (prueth->is_sr1) { - icss_iep_exit(prueth->iep1); - icss_iep_exit(prueth->iep0); -+ } else if (prueth->pdata.quirk_10m_link_issue) { -+ icss_iep_exit_fw(prueth->iep1); - } - - free_iep: -@@ -2591,6 +2595,8 @@ static int prueth_remove(struct platform_device *pdev) - if (prueth->is_sr1) { - icss_iep_exit(prueth->iep1); - icss_iep_exit(prueth->iep0); -+ } else if (prueth->pdata.quirk_10m_link_issue) { -+ icss_iep_exit_fw(prueth->iep1); - } - - icss_iep_put(prueth->iep1); -@@ -2669,8 +2675,13 @@ static const struct dev_pm_ops prueth_dev_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(prueth_suspend, prueth_resume) - }; - -+static const struct prueth_pdata am654_icssg_pdata_sr1 = { -+ .fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE, -+}; -+ - static const struct prueth_pdata am654_icssg_pdata = { - .fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE, -+ .quirk_10m_link_issue = 1, - }; - - static const struct prueth_pdata am64x_icssg_pdata = { -@@ -2678,7 +2689,7 @@ static const struct prueth_pdata am64x_icssg_pdata = { - }; - - static const struct of_device_id prueth_dt_match[] = { -- { .compatible = "ti,am654-icssg-prueth-sr1", .data = &am654_icssg_pdata }, -+ { .compatible = "ti,am654-icssg-prueth-sr1", .data = &am654_icssg_pdata_sr1 }, - { .compatible = "ti,am654-icssg-prueth", .data = &am654_icssg_pdata }, - { .compatible = "ti,am642-icssg-prueth", .data = &am64x_icssg_pdata }, - { /* sentinel */ } -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index b536ac5ec0bf..7cc81c67bf72 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -173,9 +173,12 @@ struct prueth_emac { - /** - * struct prueth - PRUeth platform data - * @fdqring_mode: Free desc queue mode -+ * @quirk_10m_link_issue: 10M link detect errata - */ - struct prueth_pdata { - enum k3_ring_mode fdqring_mode; -+ -+ u32 quirk_10m_link_issue:1; - }; - - /** diff --git a/recipes-kernel/linux/files/patches-5.10/0096-net-ti-icssg_prueth-Free-desc-pool-before-DMA-channe.patch b/recipes-kernel/linux/files/patches-5.10/0096-net-ti-icssg_prueth-Free-desc-pool-before-DMA-channe.patch deleted file mode 100644 index 5cf71db74..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0096-net-ti-icssg_prueth-Free-desc-pool-before-DMA-channe.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Mon, 21 Jun 2021 15:47:49 +0530 -Subject: [PATCH] net: ti: icssg_prueth: Free desc pool before DMA channel - release - -Release DMA desc pool associated with channel before releasing the -channel itself as the pool is associated with channel's struct device - -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index ef7392a2b9da..38d151dca81c 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -69,11 +69,11 @@ static void prueth_cleanup_rx_chns(struct prueth_emac *emac, - struct prueth_rx_chn *rx_chn, - int max_rflows) - { -- if (rx_chn->rx_chn) -- k3_udma_glue_release_rx_chn(rx_chn->rx_chn); -- - if (rx_chn->desc_pool) - k3_cppi_desc_pool_destroy(rx_chn->desc_pool); -+ -+ if (rx_chn->rx_chn) -+ k3_udma_glue_release_rx_chn(rx_chn->rx_chn); - } - - static void prueth_cleanup_tx_chns(struct prueth_emac *emac) -@@ -83,12 +83,12 @@ static void prueth_cleanup_tx_chns(struct prueth_emac *emac) - for (i = 0; i < emac->tx_ch_num; i++) { - struct prueth_tx_chn *tx_chn = &emac->tx_chns[i]; - -- if (tx_chn->tx_chn) -- k3_udma_glue_release_tx_chn(tx_chn->tx_chn); -- - if (tx_chn->desc_pool) - k3_cppi_desc_pool_destroy(tx_chn->desc_pool); - -+ if (tx_chn->tx_chn) -+ k3_udma_glue_release_tx_chn(tx_chn->tx_chn); -+ - /* Assume prueth_cleanup_tx_chns() is called at the - * end after all channel resources are freed - */ diff --git a/recipes-kernel/linux/files/patches-5.10/0097-net-ethernet-icssg-prueth-fix-rgmii-tx-delay-configu.patch b/recipes-kernel/linux/files/patches-5.10/0097-net-ethernet-icssg-prueth-fix-rgmii-tx-delay-configu.patch deleted file mode 100644 index 165d04524..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0097-net-ethernet-icssg-prueth-fix-rgmii-tx-delay-configu.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Fri, 18 Jun 2021 20:51:47 +0300 -Subject: [PATCH] net: ethernet: icssg-prueth: fix rgmii tx delay configuration - -The driver enables RGMII TX delay without checking specified -phy-connection-type value, which may break TX data path. - -Hence, fix it by checking phy-connection-type and enable RGMII TX delay for -"rgmii" and "rgmii-rxid" modes only. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 70 +++++++++++++------------- - 1 file changed, 34 insertions(+), 36 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 38d151dca81c..d19a05fd8b06 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -2021,6 +2021,36 @@ static int prueth_node_mac(struct device_node *eth_node) - return -EINVAL; - } - -+static int prueth_config_rgmiidelay(struct prueth *prueth, -+ struct device_node *eth_np, -+ phy_interface_t phy_if) -+{ -+ struct device *dev = prueth->dev; -+ struct regmap *ctrl_mmr; -+ u32 rgmii_tx_id = 0; -+ u32 icssgctrl_reg; -+ -+ ctrl_mmr = syscon_regmap_lookup_by_phandle(eth_np, "syscon-rgmii-delay"); -+ if (IS_ERR(ctrl_mmr)) { -+ dev_err(dev, "couldn't get syscon-rgmii-delay\n"); -+ return -ENODEV; -+ } -+ -+ if (of_property_read_u32_index(eth_np, "syscon-rgmii-delay", 1, -+ &icssgctrl_reg)) { -+ dev_err(dev, "couldn't get rgmii-delay reg. offset\n"); -+ return -ENODEV; -+ } -+ -+ if (phy_if == PHY_INTERFACE_MODE_RGMII_ID || -+ phy_if == PHY_INTERFACE_MODE_RGMII_TXID) -+ rgmii_tx_id |= ICSSG_CTRL_RGMII_ID_MODE; -+ -+ regmap_update_bits(ctrl_mmr, icssgctrl_reg, ICSSG_CTRL_RGMII_ID_MODE, rgmii_tx_id); -+ -+ return 0; -+} -+ - extern const struct ethtool_ops icssg_ethtool_ops; - - static int prueth_netdev_init(struct prueth *prueth, -@@ -2116,6 +2146,10 @@ static int prueth_netdev_init(struct prueth *prueth, - goto free; - } - -+ ret = prueth_config_rgmiidelay(prueth, eth_node, emac->phy_if); -+ if (ret) -+ goto free; -+ - /* connect PHY */ - emac->phydev = of_phy_connect(ndev, emac->phy_node, - &emac_adjust_link, 0, emac->phy_if); -@@ -2261,34 +2295,6 @@ static void prueth_put_cores(struct prueth *prueth, int slice) - pru_rproc_put(prueth->pru[slice]); - } - --static int prueth_config_rgmiidelay(struct prueth *prueth, -- struct device_node *eth_np) --{ -- struct device *dev = prueth->dev; -- struct regmap *ctrl_mmr; -- u32 icssgctrl; -- struct device_node *np = dev->of_node; -- -- if (!of_device_is_compatible(np, "ti,am654-icssg-prueth")) -- return 0; -- -- ctrl_mmr = syscon_regmap_lookup_by_phandle(eth_np, "syscon-rgmii-delay"); -- if (IS_ERR(ctrl_mmr)) { -- dev_err(dev, "couldn't get syscon-rgmii-delay\n"); -- return -ENODEV; -- } -- -- if (of_property_read_u32_index(eth_np, "syscon-rgmii-delay", 1, -- &icssgctrl)) { -- dev_err(dev, "couldn't get rgmii-delay reg. offset\n"); -- return -ENODEV; -- } -- -- regmap_update_bits(ctrl_mmr, icssgctrl, ICSSG_CTRL_RGMII_ID_MODE, 0); -- -- return 0; --} -- - static const struct of_device_id prueth_dt_match[]; - - static int prueth_probe(struct platform_device *pdev) -@@ -2355,20 +2361,12 @@ static int prueth_probe(struct platform_device *pdev) - } - - if (eth0_node) { -- ret = prueth_config_rgmiidelay(prueth, eth0_node); -- if (ret) -- goto put_cores; -- - ret = prueth_get_cores(prueth, ICSS_SLICE0); - if (ret) - goto put_cores; - } - - if (eth1_node) { -- ret = prueth_config_rgmiidelay(prueth, eth1_node); -- if (ret) -- goto put_cores; -- - ret = prueth_get_cores(prueth, ICSS_SLICE1); - if (ret) - goto put_cores; diff --git a/recipes-kernel/linux/files/patches-5.10/0098-net-ethernet-icssg-prueth-enable-fixed-link-connecti.patch b/recipes-kernel/linux/files/patches-5.10/0098-net-ethernet-icssg-prueth-enable-fixed-link-connecti.patch deleted file mode 100644 index 69bc6bde2..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0098-net-ethernet-icssg-prueth-enable-fixed-link-connecti.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Fri, 18 Jun 2021 20:51:48 +0300 -Subject: [PATCH] net: ethernet: icssg-prueth: enable "fixed-link" connection - -The ICSSG has incomplete and incorrect "fixed-link" connection type -implementation. The "fixed-link" is property of the Ethernet port and not -provided in "phy-handle" property. - -So fix it by first checking for real PHY (phy-handle) and then for child -"fixed-link" property. After this patch the below DT definition should -allow to use fixed-link connection: - - icssg2_emac1: ethernet-mii1 { - phy-mode = "rgmii-rxid"; - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 20 ++++++++------------ - 1 file changed, 8 insertions(+), 12 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index d19a05fd8b06..3b1769a5e2b3 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -2121,23 +2121,19 @@ static int prueth_netdev_init(struct prueth *prueth, - mutex_init(&emac->cmd_lock); - - emac->phy_node = of_parse_phandle(eth_node, "phy-handle", 0); -- if (!emac->phy_node) { -+ if (!emac->phy_node && !of_phy_is_fixed_link(eth_node)) { - dev_err(prueth->dev, "couldn't find phy-handle\n"); - ret = -ENODEV; - goto free; -- } -- -- if (of_phy_is_fixed_link(emac->phy_node)) { -- ret = of_phy_register_fixed_link(emac->phy_node); -+ } else if (of_phy_is_fixed_link(eth_node)) { -+ ret = of_phy_register_fixed_link(eth_node); - if (ret) { -- if (ret != -EPROBE_DEFER) { -- dev_err(prueth->dev, -- "failed to register fixed-link phy: %d\n", -- ret); -- } -- -+ ret = dev_err_probe(prueth->dev, ret, -+ "failed to register fixed-link phy\n"); - goto free; - } -+ -+ emac->phy_node = eth_node; - } - - ret = of_get_phy_mode(eth_node, &emac->phy_if); -@@ -2154,7 +2150,7 @@ static int prueth_netdev_init(struct prueth *prueth, - emac->phydev = of_phy_connect(ndev, emac->phy_node, - &emac_adjust_link, 0, emac->phy_if); - if (!emac->phydev) { -- dev_dbg(prueth->dev, "couldn't connect to phy %s\n", -+ dev_err(prueth->dev, "couldn't connect to phy %s\n", - emac->phy_node->full_name); - ret = -EPROBE_DEFER; - goto free; diff --git a/recipes-kernel/linux/files/patches-5.10/0099-net-ethernet-icssg-prueth-fix-bug-scheduling-while-a.patch b/recipes-kernel/linux/files/patches-5.10/0099-net-ethernet-icssg-prueth-fix-bug-scheduling-while-a.patch deleted file mode 100644 index acbf99d37..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0099-net-ethernet-icssg-prueth-fix-bug-scheduling-while-a.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Wed, 7 Jul 2021 14:43:12 +0300 -Subject: [PATCH] net: ethernet: icssg-prueth: fix bug 'scheduling while - atomic' from emac_ndo_set_rx_mode() - -The .ndo_set_rx_mode() is called with BH disabled and should be atomic, but -current ICSSG SR2.0 driver calls non-atomic emac_set_port_state() from -emac_ndo_set_rx_mode() which causes "BUG: scheduling while atomic: -ifconfig/1739/0x00000202". - -Fix it by adding workqueue and scheduling work in emac_ndo_set_rx_mode() to -reconfigure port instead of calling emac_set_port_state() directly. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 50 ++++++++++++++++++-------- - drivers/net/ethernet/ti/icssg_prueth.h | 2 ++ - 2 files changed, 37 insertions(+), 15 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 3b1769a5e2b3..f212e5904afc 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1790,6 +1790,7 @@ static int emac_ndo_stop(struct net_device *ndev) - - prueth->iep_initialized--; - -+ cancel_work_sync(&emac->rx_mode_work); - /* stop PRUs */ - prueth_emac_stop(emac); - -@@ -1856,25 +1857,17 @@ static void emac_ndo_set_rx_mode_sr1(struct net_device *ndev) - } - } - --/** -- * emac_ndo_set_rx_mode - EMAC set receive mode function -- * @ndev: The EMAC network adapter -- * -- * Called when system wants to set the receive mode of the device. -- * -- */ --static void emac_ndo_set_rx_mode(struct net_device *ndev) -+static void emac_ndo_set_rx_mode_work(struct work_struct *work) - { -- struct prueth_emac *emac = netdev_priv(ndev); -- struct prueth *prueth = emac->prueth; -- bool promisc = ndev->flags & IFF_PROMISC; -- bool allmulti = ndev->flags & IFF_ALLMULTI; -+ struct prueth_emac *emac = container_of(work, struct prueth_emac, rx_mode_work); -+ struct net_device *ndev = emac->ndev; -+ bool promisc, allmulti; - -- if (prueth->is_sr1) { -- emac_ndo_set_rx_mode_sr1(ndev); -+ if (!(ndev->flags & IFF_UP)) - return; -- } - -+ promisc = ndev->flags & IFF_PROMISC; -+ allmulti = ndev->flags & IFF_ALLMULTI; - emac_set_port_state(emac, ICSSG_EMAC_PORT_UC_FLOODING_DISABLE); - emac_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_DISABLE); - -@@ -1896,6 +1889,26 @@ static void emac_ndo_set_rx_mode(struct net_device *ndev) - } - } - -+/** -+ * emac_ndo_set_rx_mode - EMAC set receive mode function -+ * @ndev: The EMAC network adapter -+ * -+ * Called when system wants to set the receive mode of the device. -+ * -+ */ -+static void emac_ndo_set_rx_mode(struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth *prueth = emac->prueth; -+ -+ if (prueth->is_sr1) { -+ emac_ndo_set_rx_mode_sr1(ndev); -+ return; -+ } -+ -+ queue_work(emac->cmd_wq, &emac->rx_mode_work); -+} -+ - static int emac_set_ts_config(struct net_device *ndev, struct ifreq *ifr) - { - struct prueth_emac *emac = netdev_priv(ndev); -@@ -2085,6 +2098,10 @@ static int prueth_netdev_init(struct prueth *prueth, - emac->prueth = prueth; - emac->ndev = ndev; - emac->port_id = port; -+ emac->cmd_wq = create_singlethread_workqueue("icssg_cmd_wq"); -+ if (!emac->cmd_wq) -+ goto free_ndev; -+ INIT_WORK(&emac->rx_mode_work, emac_ndo_set_rx_mode_work); - - ret = pruss_request_mem_region(prueth->pruss, - port == PRUETH_PORT_MII0 ? -@@ -2184,6 +2201,8 @@ static int prueth_netdev_init(struct prueth *prueth, - - free: - pruss_release_mem_region(prueth->pruss, &emac->dram); -+ destroy_workqueue(emac->cmd_wq); -+free_ndev: - free_netdev(ndev); - prueth->emac[mac] = NULL; - -@@ -2212,6 +2231,7 @@ static void prueth_netdev_exit(struct prueth *prueth, - netif_napi_del(&emac->napi_rx); - - pruss_release_mem_region(prueth->pruss, &emac->dram); -+ destroy_workqueue(emac->cmd_wq); - free_netdev(emac->ndev); - prueth->emac[mac] = NULL; - } -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 7cc81c67bf72..59dec45a3c86 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -166,6 +166,8 @@ struct prueth_emac { - struct completion cmd_complete; - /* Mutex to serialize access to firmware command interface */ - struct mutex cmd_lock; -+ struct work_struct rx_mode_work; -+ struct workqueue_struct *cmd_wq; - - struct pruss_mem_region dram; - }; diff --git a/recipes-kernel/linux/files/patches-5.10/0100-net-ethernet-icssg-prueth-fix-enabling-disabling-por.patch b/recipes-kernel/linux/files/patches-5.10/0100-net-ethernet-icssg-prueth-fix-enabling-disabling-por.patch deleted file mode 100644 index 74ad6f74a..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0100-net-ethernet-icssg-prueth-fix-enabling-disabling-por.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Wed, 7 Jul 2021 14:43:13 +0300 -Subject: [PATCH] net: ethernet: icssg-prueth: fix enabling/disabling port in - emac_adjust_link() - -The port state is set to FORWARD in emac_ndo_open() and never changed, but -the correct behavior is to enable port (FORWARD) on link up and disable -(DISABLE) on link down events. - -Hence fix emac_adjust_link() to set correct port state depending on link -status. Also, reduce spinlock section to only icssg_config_ipg() which is -the only one need protection between interfaces. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index f212e5904afc..abd062bedebb 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1274,17 +1274,23 @@ static void emac_adjust_link(struct net_device *ndev) - /* update RGMII and MII configuration based on PHY negotiated - * values - */ -- spin_lock_irqsave(&emac->lock, flags); - if (emac->link) { - /* Set the RGMII cfg for gig en and full duplex */ - icssg_update_rgmii_cfg(prueth->miig_rt, emac->speed, - emac->duplex, slice); - - /* update the Tx IPG based on 100M/1G speed */ -+ spin_lock_irqsave(&emac->lock, flags); - icssg_config_ipg(prueth, emac->speed, slice); -+ spin_unlock_irqrestore(&emac->lock, flags); - icssg_config_set_speed(emac); -+ if (!emac->is_sr1) -+ emac_set_port_state(emac, ICSSG_EMAC_PORT_FORWARD); -+ -+ } else { -+ if (!emac->is_sr1) -+ emac_set_port_state(emac, ICSSG_EMAC_PORT_DISABLE); - } -- spin_unlock_irqrestore(&emac->lock, flags); - - /* send command to firmware to change speed and duplex - * setting when link is up. -@@ -1684,9 +1690,6 @@ static int emac_ndo_open(struct net_device *ndev) - if (netif_msg_drv(emac)) - dev_notice(&ndev->dev, "started\n"); - -- if (!emac->is_sr1) -- emac_set_port_state(emac, ICSSG_EMAC_PORT_FORWARD); -- - return 0; - - reset_tx_chan: diff --git a/recipes-kernel/linux/files/patches-5.10/0103-WIP-feat-extend-led-panic-indicator-on-and-off.patch b/recipes-kernel/linux/files/patches-5.10/0103-WIP-feat-extend-led-panic-indicator-on-and-off.patch deleted file mode 100644 index d38372eef..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0103-WIP-feat-extend-led-panic-indicator-on-and-off.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Su Baocheng -Date: Tue, 22 Dec 2020 15:05:56 +0800 -Subject: [PATCH] WIP: feat:extend led panic-indicator on and off - -WIP because upstream strategy is still under discussion. - -Signed-off-by: Gao Nian -[Jan: ported and fixed non-panic cases] -Signed-off-by: Jan Kiszka ---- - drivers/leds/led-triggers.c | 10 ++++++++-- - drivers/leds/leds-gpio.c | 12 ++++++++++-- - drivers/leds/trigger/ledtrig-panic.c | 5 ++++- - include/linux/leds.h | 8 +++++++- - 4 files changed, 29 insertions(+), 6 deletions(-) - -diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c -index 4e7b78a84149..30527da8db97 100644 ---- a/drivers/leds/led-triggers.c -+++ b/drivers/leds/led-triggers.c -@@ -384,8 +384,14 @@ void led_trigger_event(struct led_trigger *trig, - return; - - read_lock_irqsave(&trig->leddev_list_lock, flags); -- list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) -- led_set_brightness(led_cdev, brightness); -+ list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) { -+ if (led_cdev->flags & LED_PANIC_INDICATOR_OFF) -+ led_set_brightness(led_cdev, LED_OFF); -+ else if (led_cdev->flags & LED_PANIC_INDICATOR_ON) -+ led_set_brightness(led_cdev, LED_FULL); -+ else -+ led_set_brightness(led_cdev, brightness); -+ } - read_unlock_irqrestore(&trig->leddev_list_lock, flags); - } - EXPORT_SYMBOL_GPL(led_trigger_event); -diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c -index 93f5b1b60fde..8ad1b5dddc71 100644 ---- a/drivers/leds/leds-gpio.c -+++ b/drivers/leds/leds-gpio.c -@@ -99,8 +99,12 @@ static int create_gpio_led(const struct gpio_led *template, - led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; - if (!template->retain_state_suspended) - led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; -- if (template->panic_indicator) -+ if (template->panic_indicator == LEDS_PANICINDICATOR_BLINK) - led_dat->cdev.flags |= LED_PANIC_INDICATOR; -+ else if (template->panic_indicator == LEDS_PANICINDICATOR_OFF) -+ led_dat->cdev.flags |= LED_PANIC_INDICATOR_OFF; -+ else if (template->panic_indicator == LEDS_PANICINDICATOR_ON) -+ led_dat->cdev.flags |= LED_PANIC_INDICATOR_ON; - if (template->retain_state_shutdown) - led_dat->cdev.flags |= LED_RETAIN_AT_SHUTDOWN; - -@@ -175,7 +179,11 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev) - if (fwnode_property_present(child, "retain-state-shutdown")) - led.retain_state_shutdown = 1; - if (fwnode_property_present(child, "panic-indicator")) -- led.panic_indicator = 1; -+ led.panic_indicator = LEDS_PANICINDICATOR_BLINK; -+ else if (fwnode_property_present(child, "panic-indicator-off")) -+ led.panic_indicator = LEDS_PANICINDICATOR_OFF; -+ else if (fwnode_property_present(child, "panic-indicator-on")) -+ led.panic_indicator = LEDS_PANICINDICATOR_ON; - - ret = create_gpio_led(&led, led_dat, dev, child, NULL); - if (ret < 0) { -diff --git a/drivers/leds/trigger/ledtrig-panic.c b/drivers/leds/trigger/ledtrig-panic.c -index 5751cd032f9d..12b332ecd86e 100644 ---- a/drivers/leds/trigger/ledtrig-panic.c -+++ b/drivers/leds/trigger/ledtrig-panic.c -@@ -32,6 +32,7 @@ static void led_trigger_set_panic(struct led_classdev *led_cdev) - /* Avoid the delayed blink path */ - led_cdev->blink_delay_on = 0; - led_cdev->blink_delay_off = 0; -+ led_cdev->work_flags = 0; - - led_cdev->trigger = trig; - if (trig->activate) -@@ -46,7 +47,9 @@ static int led_trigger_panic_notifier(struct notifier_block *nb, - struct led_classdev *led_cdev; - - list_for_each_entry(led_cdev, &leds_list, node) -- if (led_cdev->flags & LED_PANIC_INDICATOR) -+ if (led_cdev->flags & (LED_PANIC_INDICATOR | -+ LED_PANIC_INDICATOR_OFF | -+ LED_PANIC_INDICATOR_ON)) - led_trigger_set_panic(led_cdev); - return NOTIFY_DONE; - } -diff --git a/include/linux/leds.h b/include/linux/leds.h -index 6a8d6409c993..d84423d42f89 100644 ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -79,6 +79,8 @@ struct led_classdev { - #define LED_BRIGHT_HW_CHANGED BIT(21) - #define LED_RETAIN_AT_SHUTDOWN BIT(22) - #define LED_INIT_DEFAULT_TRIGGER BIT(23) -+#define LED_PANIC_INDICATOR_OFF BIT(24) -+#define LED_PANIC_INDICATOR_ON BIT(25) - - /* set_brightness_work / blink_timer flags, atomic, private. */ - unsigned long work_flags; -@@ -516,7 +518,7 @@ struct gpio_led { - unsigned gpio; - unsigned active_low : 1; - unsigned retain_state_suspended : 1; -- unsigned panic_indicator : 1; -+ unsigned panic_indicator : 2; - unsigned default_state : 2; - unsigned retain_state_shutdown : 1; - /* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */ -@@ -526,6 +528,10 @@ struct gpio_led { - #define LEDS_GPIO_DEFSTATE_ON 1 - #define LEDS_GPIO_DEFSTATE_KEEP 2 - -+#define LEDS_PANICINDICATOR_BLINK 1 -+#define LEDS_PANICINDICATOR_OFF 2 -+#define LEDS_PANICINDICATOR_ON 3 -+ - struct gpio_led_platform_data { - int num_leds; - const struct gpio_led *leds; diff --git a/recipes-kernel/linux/files/patches-5.10/0105-dt-bindings-net-ti-icssg-prueth-Add-documentation-fo.patch b/recipes-kernel/linux/files/patches-5.10/0105-dt-bindings-net-ti-icssg-prueth-Add-documentation-fo.patch deleted file mode 100644 index f7555d805..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0105-dt-bindings-net-ti-icssg-prueth-Add-documentation-fo.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Murali Karicheri -Date: Tue, 12 Oct 2021 13:54:41 +0300 -Subject: [PATCH] dt-bindings: net: ti, icssg-prueth: Add documentation for - half duplex - -In order to support half-duplex operation at 10M and 100M link speeds, the -PHY collision detection signal (GPIO output pin) should be routed to ICSSG, -GPIO pin so that firmware can detect collision signal and apply the csma/cd -algorithm applicable for half duplex operation. A DT property, half-duplex -is introduced for this purpose. If board has the required modification -done, this DT property can be added to eth node of ICSSG, MII port to -support half duplex operation at that port. - -On AM654x-IDK only ICSSG0 MII port 1 can be used. - -Signed-off-by: Murali Karicheri -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - Documentation/devicetree/bindings/net/ti,icssg-prueth.txt | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/Documentation/devicetree/bindings/net/ti,icssg-prueth.txt b/Documentation/devicetree/bindings/net/ti,icssg-prueth.txt -index 125a204ef2d2..41cba6907fc9 100644 ---- a/Documentation/devicetree/bindings/net/ti,icssg-prueth.txt -+++ b/Documentation/devicetree/bindings/net/ti,icssg-prueth.txt -@@ -39,6 +39,10 @@ Required properties for children: - - Optional properties for children: - - local-mac-address : mac address for the port. -+- ti,half-duplex-capable : Enable half duplex operation on ICSSG MII port. -+ This requires board modification to route PHY -+ output pin (COL) to ICSSG GPIO pin -+ (PRG0_PRU1_GPIO10) as input. - - Example (k3-am654 base board SR2.0, dual-emac): - ============================================== diff --git a/recipes-kernel/linux/files/patches-5.10/0106-net-ethernet-icssg-prueth-sr1.0-add-support-for-half.patch b/recipes-kernel/linux/files/patches-5.10/0106-net-ethernet-icssg-prueth-sr1.0-add-support-for-half.patch deleted file mode 100644 index 76ba20e45..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0106-net-ethernet-icssg-prueth-sr1.0-add-support-for-half.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Tue, 12 Oct 2021 13:54:42 +0300 -Subject: [PATCH] net: ethernet: icssg-prueth: sr1.0: add support for half - duplex operation - -This patch adds support for half duplex operation at 10M and 100M link -speeds. Driver needs to configure rand_seed, a random number, in the config -struct passed to firmware. This is used as a seed value at firmware for -random number generation logic required to implement csma/cd logic timer. -Also don't clear the half duplex bits in the supported modes of phydev for -10M and 100M as they now become supported. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_config.c | 1 + - drivers/net/ethernet/ti/icssg_config.h | 2 ++ - drivers/net/ethernet/ti/icssg_prueth.c | 19 +++++++++++++++++-- - drivers/net/ethernet/ti/icssg_prueth.h | 1 + - 4 files changed, 21 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c -index b5cef264cdf9..905c743e8e11 100644 ---- a/drivers/net/ethernet/ti/icssg_config.c -+++ b/drivers/net/ethernet/ti/icssg_config.c -@@ -239,6 +239,7 @@ void icssg_config_sr1(struct prueth *prueth, struct prueth_emac *emac, - config->num_tx_threads = 0; - config->rx_flow_id = emac->rx_flow_id_base; /* flow id for host port */ - config->rx_mgr_flow_id = emac->rx_mgm_flow_id_base; /* for mgm ch */ -+ config->rand_seed = get_random_int(); - - for (i = PRUETH_EMAC_BUF_POOL_START_SR1; i < PRUETH_NUM_BUF_POOLS_SR1; - i++) { -diff --git a/drivers/net/ethernet/ti/icssg_config.h b/drivers/net/ethernet/ti/icssg_config.h -index 82930383204b..b9fe3f3cc940 100644 ---- a/drivers/net/ethernet/ti/icssg_config.h -+++ b/drivers/net/ethernet/ti/icssg_config.h -@@ -60,6 +60,8 @@ struct icssg_config_sr1 { - __le32 n_burst; /* for debug */ - __le32 rtu_status; /* RTU status */ - __le32 info; /* reserved */ -+ __le32 reserve; -+ __le32 rand_seed; /* Used for the random number generation at fw */ - } __packed; - - /* Shutdown command to stop processing at firmware. -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index abd062bedebb..635eec1fd6ee 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1232,6 +1232,15 @@ static void prueth_emac_stop(struct prueth_emac *emac) - rproc_shutdown(prueth->pru[slice]); - } - -+static void icssg_config_half_duplex(struct prueth *prueth, int slice) -+{ -+ void __iomem *va = prueth->shram.va + slice * ICSSG_CONFIG_OFFSET_SLICE1; -+ struct icssg_config_sr1 *config = (struct icssg_config_sr1 *)va; -+ u32 val = get_random_int(); -+ -+ writel(val, &config->rand_seed); -+} -+ - /* called back by PHY layer if there is change in link state of hw port*/ - static void emac_adjust_link(struct net_device *ndev) - { -@@ -1275,6 +1284,8 @@ static void emac_adjust_link(struct net_device *ndev) - * values - */ - if (emac->link) { -+ if (emac->duplex == DUPLEX_HALF) -+ icssg_config_half_duplex(prueth, prueth_emac_slice(emac)); - /* Set the RGMII cfg for gig en and full duplex */ - icssg_update_rgmii_cfg(prueth->miig_rt, emac->speed, - emac->duplex, slice); -@@ -2176,9 +2187,13 @@ static int prueth_netdev_init(struct prueth *prueth, - goto free; - } - -+ emac->half_duplex = of_property_read_bool(eth_node, "ti,half-duplex-capable"); -+ - /* remove unsupported modes */ -- phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); -- phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); -+ if (!emac->half_duplex) { -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); -+ } - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Pause_BIT); - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT); -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 59dec45a3c86..917c6f9a2514 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -139,6 +139,7 @@ struct prueth_emac { - struct icss_iep *iep; - unsigned int rx_ts_enabled : 1; - unsigned int tx_ts_enabled : 1; -+ unsigned int half_duplex : 1; - - /* DMA related */ - struct prueth_tx_chn tx_chns[PRUETH_MAX_TX_QUEUES]; diff --git a/recipes-kernel/linux/files/patches-5.10/0107-net-ethernet-icssg-prueth-sr2.0-add-support-for-half.patch b/recipes-kernel/linux/files/patches-5.10/0107-net-ethernet-icssg-prueth-sr2.0-add-support-for-half.patch deleted file mode 100644 index ad6b8c66f..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0107-net-ethernet-icssg-prueth-sr2.0-add-support-for-half.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Tue, 12 Oct 2021 13:54:43 +0300 -Subject: [PATCH] net: ethernet: icssg-prueth: sr2.0: add support for half - duplex operation - -This patch adds support for half duplex operation at 10M and 100M link -speeds for AM654x ICSS-G SR2.0 devices. -- Driver configures rand_seed, a random number, in DMEM HD_RAND_SEED_OFFSET -field, which will be used by firmware for Back off time calculation. -- Driver informs FW about half duplex link operation in DMEM -PORT_LINK_SPEED_OFFSET field by setting bit 7 for 10/100M HD. - -Hence, the half duplex operation depends on board design the -"ti,half-duplex-capable" property has to be enabled for ICSS-G ports if HW -is capable to perform half duplex. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_config.c | 30 ++++++++++++++++++++++ - drivers/net/ethernet/ti/icssg_prueth.c | 11 +------- - drivers/net/ethernet/ti/icssg_prueth.h | 2 ++ - drivers/net/ethernet/ti/icssg_switch_map.h | 3 +++ - 4 files changed, 36 insertions(+), 10 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c -index 905c743e8e11..50acf4e31008 100644 ---- a/drivers/net/ethernet/ti/icssg_config.c -+++ b/drivers/net/ethernet/ti/icssg_config.c -@@ -420,6 +420,9 @@ void icssg_config_set_speed(struct prueth_emac *emac) - { - u8 fw_speed; - -+ if (emac->is_sr1) -+ return; -+ - switch (emac->speed) { - case SPEED_1000: - fw_speed = FW_LINK_SPEED_1G; -@@ -436,5 +439,32 @@ void icssg_config_set_speed(struct prueth_emac *emac) - return; - } - -+ if (emac->duplex == DUPLEX_HALF) -+ fw_speed |= FW_LINK_SPEED_HD; -+ - writeb(fw_speed, emac->dram.va + PORT_LINK_SPEED_OFFSET); - } -+ -+static void icssg_config_half_duplex_sr1(struct prueth_emac *emac) -+{ -+ int slice = prueth_emac_slice(emac); -+ struct icssg_config_sr1 *config; -+ u32 val = get_random_int(); -+ void __iomem *va; -+ -+ va = emac->prueth->shram.va + slice * ICSSG_CONFIG_OFFSET_SLICE1; -+ config = (struct icssg_config_sr1 *)va; -+ -+ writel(val, &config->rand_seed); -+} -+ -+void icssg_config_half_duplex(struct prueth_emac *emac) -+{ -+ u32 val; -+ -+ if (emac->is_sr1) -+ icssg_config_half_duplex_sr1(emac); -+ -+ val = get_random_int(); -+ writel(val, emac->dram.va + HD_RAND_SEED_OFFSET); -+} -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 635eec1fd6ee..e33aafc9e029 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1232,15 +1232,6 @@ static void prueth_emac_stop(struct prueth_emac *emac) - rproc_shutdown(prueth->pru[slice]); - } - --static void icssg_config_half_duplex(struct prueth *prueth, int slice) --{ -- void __iomem *va = prueth->shram.va + slice * ICSSG_CONFIG_OFFSET_SLICE1; -- struct icssg_config_sr1 *config = (struct icssg_config_sr1 *)va; -- u32 val = get_random_int(); -- -- writel(val, &config->rand_seed); --} -- - /* called back by PHY layer if there is change in link state of hw port*/ - static void emac_adjust_link(struct net_device *ndev) - { -@@ -1285,7 +1276,7 @@ static void emac_adjust_link(struct net_device *ndev) - */ - if (emac->link) { - if (emac->duplex == DUPLEX_HALF) -- icssg_config_half_duplex(prueth, prueth_emac_slice(emac)); -+ icssg_config_half_duplex(emac); - /* Set the RGMII cfg for gig en and full duplex */ - icssg_update_rgmii_cfg(prueth->miig_rt, emac->speed, - emac->duplex, slice); -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 917c6f9a2514..0ff9e9680b57 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -282,6 +282,8 @@ int icssg_config_sr2(struct prueth *prueth, struct prueth_emac *emac, - int emac_set_port_state(struct prueth_emac *emac, - enum icssg_port_state_cmd state); - void icssg_config_set_speed(struct prueth_emac *emac); -+void icssg_config_half_duplex(struct prueth_emac *emac); -+ - #define prueth_napi_to_tx_chn(pnapi) \ - container_of(pnapi, struct prueth_tx_chn, napi_tx) - -diff --git a/drivers/net/ethernet/ti/icssg_switch_map.h b/drivers/net/ethernet/ti/icssg_switch_map.h -index 644a22b53424..99225d0f1582 100644 ---- a/drivers/net/ethernet/ti/icssg_switch_map.h -+++ b/drivers/net/ethernet/ti/icssg_switch_map.h -@@ -16,6 +16,7 @@ - #define FW_LINK_SPEED_1G (0x00) - #define FW_LINK_SPEED_100M (0x01) - #define FW_LINK_SPEED_10M (0x02) -+#define FW_LINK_SPEED_HD (0x80) - - /*Time after which FDB entries are checked for aged out values. Value in nanoseconds*/ - #define FDB_AGEING_TIMEOUT_OFFSET 0x0014 -@@ -154,6 +155,8 @@ - #define HOST_RX_Q_PRE_CONTEXT_OFFSET 0x0684 - /*Buffer for 8 FDB entries to be added by 'Add Multiple FDB entries IOCTL*/ - #define FDB_CMD_BUFFER 0x0894 -+/*Used by FW to generate random number with the SEED value*/ -+#define HD_RAND_SEED_OFFSET 0x0934 - - /* Memory Usage of : DMEM1 - * diff --git a/recipes-kernel/linux/files/patches-5.10/0108-arm64-dts-ti-add-the-support-for-the-half-duplex.patch b/recipes-kernel/linux/files/patches-5.10/0108-arm64-dts-ti-add-the-support-for-the-half-duplex.patch deleted file mode 100644 index 3dad6c909..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0108-arm64-dts-ti-add-the-support-for-the-half-duplex.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: chao zeng -Date: Fri, 22 Oct 2021 13:37:22 +0800 -Subject: [PATCH] arm64: dts: ti: add the support for the half-duplex - -origin from TI and add the dts property to support the half-duplex for ethernet port - -Signed-off-by: chao zeng ---- - arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index fcf877d3d504..ea8ff74c681c 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -@@ -159,6 +159,7 @@ icssg0_emac0: ethernet-mii0 { - phy-handle = <&icssg0_eth0_phy>; - phy-mode = "rgmii-rxid"; - syscon-rgmii-delay = <&scm_conf 0x4100>; -+ ti,half-duplex-capable; - /* Filled in by bootloader */ - local-mac-address = [00 00 00 00 00 00]; - }; -@@ -167,6 +168,7 @@ icssg0_emac1: ethernet-mii1 { - phy-handle = <&icssg0_eth1_phy>; - phy-mode = "rgmii-rxid"; - syscon-rgmii-delay = <&scm_conf 0x4104>; -+ ti,half-duplex-capable; - /* Filled in by bootloader */ - local-mac-address = [00 00 00 00 00 00]; - }; diff --git a/recipes-kernel/linux/files/patches-5.10/0109-USB-serial-cp210x-return-early-on-unchanged-termios.patch b/recipes-kernel/linux/files/patches-5.10/0109-USB-serial-cp210x-return-early-on-unchanged-termios.patch deleted file mode 100644 index d2647aaeb..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0109-USB-serial-cp210x-return-early-on-unchanged-termios.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Johan Hovold -Date: Mon, 16 Nov 2020 17:18:21 +0100 -Subject: [PATCH] USB: serial: cp210x: return early on unchanged termios - -Return early from set_termios() in case no relevant terminal settings -have changed. - -This avoids testing each parameter in turn and specifically allows the -line-control handling to be cleaned up further. - -Signed-off-by: Johan Hovold ---- - drivers/usb/serial/cp210x.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c -index 045e24174e1a..3de3109ac2e2 100644 ---- a/drivers/usb/serial/cp210x.c -+++ b/drivers/usb/serial/cp210x.c -@@ -1379,6 +1379,15 @@ static void cp210x_disable_event_mode(struct usb_serial_port *port) - port_priv->event_mode = false; - } - -+static bool cp210x_termios_change(const struct ktermios *a, const struct ktermios *b) -+{ -+ bool iflag_change; -+ -+ iflag_change = ((a->c_iflag ^ b->c_iflag) & INPCK); -+ -+ return tty_termios_hw_change(a, b) || iflag_change; -+} -+ - static void cp210x_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) - { -@@ -1386,6 +1395,9 @@ static void cp210x_set_termios(struct tty_struct *tty, - unsigned int cflag, old_cflag; - u16 bits; - -+ if (!cp210x_termios_change(&tty->termios, old_termios)) -+ return; -+ - cflag = tty->termios.c_cflag; - old_cflag = old_termios->c_cflag; - diff --git a/recipes-kernel/linux/files/patches-5.10/0110-USB-serial-cp210x-clean-up-line-control-handling.patch b/recipes-kernel/linux/files/patches-5.10/0110-USB-serial-cp210x-clean-up-line-control-handling.patch deleted file mode 100644 index 9477248b3..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0110-USB-serial-cp210x-clean-up-line-control-handling.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Johan Hovold -Date: Mon, 16 Nov 2020 17:18:22 +0100 -Subject: [PATCH] USB: serial: cp210x: clean up line-control handling - -Update the line-control settings in one request unconditionally instead -of setting the word-length, parity and stop-bit settings separately. - -This avoids multiple requests when several settings are changed even if -this scheme could potentially also be used to detect unsupported device -settings. Since all device types but CP2101 appears to support all -settings, let's handle that one specifically and also report back the -unsupported settings properly through termios by clearing the -corresponding bits. - -Also drop the related unnecessary debug printks. - -Signed-off-by: Johan Hovold ---- - drivers/usb/serial/cp210x.c | 101 +++++++++++++++--------------------- - 1 file changed, 41 insertions(+), 60 deletions(-) - -diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c -index 3de3109ac2e2..8bfc3c06f5e6 100644 ---- a/drivers/usb/serial/cp210x.c -+++ b/drivers/usb/serial/cp210x.c -@@ -1391,9 +1391,11 @@ static bool cp210x_termios_change(const struct ktermios *a, const struct ktermio - static void cp210x_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) - { -+ struct cp210x_serial_private *priv = usb_get_serial_data(port->serial); - struct device *dev = &port->dev; - unsigned int cflag, old_cflag; - u16 bits; -+ int ret; - - if (!cp210x_termios_change(&tty->termios, old_termios)) - return; -@@ -1404,74 +1406,53 @@ static void cp210x_set_termios(struct tty_struct *tty, - if (tty->termios.c_ospeed != old_termios->c_ospeed) - cp210x_change_speed(tty, port, old_termios); - -- /* If the number of data bits is to be updated */ -- if ((cflag & CSIZE) != (old_cflag & CSIZE)) { -- cp210x_get_line_ctl(port, &bits); -- bits &= ~BITS_DATA_MASK; -- switch (cflag & CSIZE) { -- case CS5: -- bits |= BITS_DATA_5; -- dev_dbg(dev, "%s - data bits = 5\n", __func__); -- break; -- case CS6: -- bits |= BITS_DATA_6; -- dev_dbg(dev, "%s - data bits = 6\n", __func__); -- break; -- case CS7: -- bits |= BITS_DATA_7; -- dev_dbg(dev, "%s - data bits = 7\n", __func__); -- break; -- case CS8: -- default: -- bits |= BITS_DATA_8; -- dev_dbg(dev, "%s - data bits = 8\n", __func__); -- break; -- } -- if (cp210x_write_u16_reg(port, CP210X_SET_LINE_CTL, bits)) -- dev_dbg(dev, "Number of data bits requested not supported by device\n"); -+ /* CP2101 only supports CS8, 1 stop bit and non-stick parity. */ -+ if (priv->partnum == CP210X_PARTNUM_CP2101) { -+ tty->termios.c_cflag &= ~(CSIZE | CSTOPB | CMSPAR); -+ tty->termios.c_cflag |= CS8; - } - -- if ((cflag & (PARENB|PARODD|CMSPAR)) != -- (old_cflag & (PARENB|PARODD|CMSPAR))) { -- cp210x_get_line_ctl(port, &bits); -- bits &= ~BITS_PARITY_MASK; -- if (cflag & PARENB) { -- if (cflag & CMSPAR) { -- if (cflag & PARODD) { -- bits |= BITS_PARITY_MARK; -- dev_dbg(dev, "%s - parity = MARK\n", __func__); -- } else { -- bits |= BITS_PARITY_SPACE; -- dev_dbg(dev, "%s - parity = SPACE\n", __func__); -- } -- } else { -- if (cflag & PARODD) { -- bits |= BITS_PARITY_ODD; -- dev_dbg(dev, "%s - parity = ODD\n", __func__); -- } else { -- bits |= BITS_PARITY_EVEN; -- dev_dbg(dev, "%s - parity = EVEN\n", __func__); -- } -- } -- } -- if (cp210x_write_u16_reg(port, CP210X_SET_LINE_CTL, bits)) -- dev_dbg(dev, "Parity mode not supported by device\n"); -+ bits = 0; -+ -+ switch (C_CSIZE(tty)) { -+ case CS5: -+ bits |= BITS_DATA_5; -+ break; -+ case CS6: -+ bits |= BITS_DATA_6; -+ break; -+ case CS7: -+ bits |= BITS_DATA_7; -+ break; -+ case CS8: -+ default: -+ bits |= BITS_DATA_8; -+ break; - } - -- if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { -- cp210x_get_line_ctl(port, &bits); -- bits &= ~BITS_STOP_MASK; -- if (cflag & CSTOPB) { -- bits |= BITS_STOP_2; -- dev_dbg(dev, "%s - stop bits = 2\n", __func__); -+ if (C_PARENB(tty)) { -+ if (C_CMSPAR(tty)) { -+ if (C_PARODD(tty)) -+ bits |= BITS_PARITY_MARK; -+ else -+ bits |= BITS_PARITY_SPACE; - } else { -- bits |= BITS_STOP_1; -- dev_dbg(dev, "%s - stop bits = 1\n", __func__); -+ if (C_PARODD(tty)) -+ bits |= BITS_PARITY_ODD; -+ else -+ bits |= BITS_PARITY_EVEN; - } -- if (cp210x_write_u16_reg(port, CP210X_SET_LINE_CTL, bits)) -- dev_dbg(dev, "Number of stop bits requested not supported by device\n"); - } - -+ if (C_CSTOPB(tty)) -+ bits |= BITS_STOP_2; -+ else -+ bits |= BITS_STOP_1; -+ -+ ret = cp210x_write_u16_reg(port, CP210X_SET_LINE_CTL, bits); -+ if (ret) -+ dev_err(&port->dev, "failed to set line control: %d\n", ret); -+ - if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { - struct cp210x_flow_ctl flow_ctl; - u32 ctl_hs; diff --git a/recipes-kernel/linux/files/patches-5.10/0111-USB-serial-cp210x-set-terminal-settings-on-open.patch b/recipes-kernel/linux/files/patches-5.10/0111-USB-serial-cp210x-set-terminal-settings-on-open.patch deleted file mode 100644 index 712a474f0..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0111-USB-serial-cp210x-set-terminal-settings-on-open.patch +++ /dev/null @@ -1,399 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Johan Hovold -Date: Mon, 16 Nov 2020 17:18:23 +0100 -Subject: [PATCH] USB: serial: cp210x: set terminal settings on open - -Unlike other drivers cp210x have been retrieving the current terminal -settings from the device on open and reflecting those in termios. - -Due to how set_termios() used to be implemented, this saved a few -control requests on open but has instead caused problems like broken -flow control and has required adding workarounds for swapped -line-control in cp2108 and line-speed initialisation on cp2104. - -This unusual implementation also complicates adding new features for no -good reason. - -Rip out the corresponding code and the above mentioned workarounds and -instead initialise the terminal settings unconditionally on open. - -Signed-off-by: Johan Hovold ---- - drivers/usb/serial/cp210x.c | 289 +----------------------------------- - 1 file changed, 6 insertions(+), 283 deletions(-) - -diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c -index 8bfc3c06f5e6..325a2fb0f8bf 100644 ---- a/drivers/usb/serial/cp210x.c -+++ b/drivers/usb/serial/cp210x.c -@@ -31,9 +31,6 @@ - */ - static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *); - static void cp210x_close(struct usb_serial_port *); --static void cp210x_get_termios(struct tty_struct *, struct usb_serial_port *); --static void cp210x_get_termios_port(struct usb_serial_port *port, -- tcflag_t *cflagp, unsigned int *baudp); - static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *, - struct ktermios *); - static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *, -@@ -284,7 +281,6 @@ enum cp210x_event_state { - - struct cp210x_port_private { - u8 bInterfaceNumber; -- bool has_swapped_line_ctl; - bool event_mode; - enum cp210x_event_state event_state; - u8 lsr; -@@ -616,46 +612,6 @@ static int cp210x_read_reg_block(struct usb_serial_port *port, u8 req, - return result; - } - --/* -- * Reads any 32-bit CP210X_ register identified by req. -- */ --static int cp210x_read_u32_reg(struct usb_serial_port *port, u8 req, u32 *val) --{ -- __le32 le32_val; -- int err; -- -- err = cp210x_read_reg_block(port, req, &le32_val, sizeof(le32_val)); -- if (err) { -- /* -- * FIXME Some callers don't bother to check for error, -- * at least give them consistent junk until they are fixed -- */ -- *val = 0; -- return err; -- } -- -- *val = le32_to_cpu(le32_val); -- -- return 0; --} -- --/* -- * Reads any 16-bit CP210X_ register identified by req. -- */ --static int cp210x_read_u16_reg(struct usb_serial_port *port, u8 req, u16 *val) --{ -- __le16 le16_val; -- int err; -- -- err = cp210x_read_reg_block(port, req, &le16_val, sizeof(le16_val)); -- if (err) -- return err; -- -- *val = le16_to_cpu(le16_val); -- -- return 0; --} -- - /* - * Reads any 8-bit CP210X_ register identified by req. - */ -@@ -803,59 +759,6 @@ static int cp210x_write_vendor_block(struct usb_serial *serial, u8 type, - } - #endif - --/* -- * Detect CP2108 GET_LINE_CTL bug and activate workaround. -- * Write a known good value 0x800, read it back. -- * If it comes back swapped the bug is detected. -- * Preserve the original register value. -- */ --static int cp210x_detect_swapped_line_ctl(struct usb_serial_port *port) --{ -- struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); -- u16 line_ctl_save; -- u16 line_ctl_test; -- int err; -- -- err = cp210x_read_u16_reg(port, CP210X_GET_LINE_CTL, &line_ctl_save); -- if (err) -- return err; -- -- err = cp210x_write_u16_reg(port, CP210X_SET_LINE_CTL, 0x800); -- if (err) -- return err; -- -- err = cp210x_read_u16_reg(port, CP210X_GET_LINE_CTL, &line_ctl_test); -- if (err) -- return err; -- -- if (line_ctl_test == 8) { -- port_priv->has_swapped_line_ctl = true; -- line_ctl_save = swab16(line_ctl_save); -- } -- -- return cp210x_write_u16_reg(port, CP210X_SET_LINE_CTL, line_ctl_save); --} -- --/* -- * Must always be called instead of cp210x_read_u16_reg(CP210X_GET_LINE_CTL) -- * to workaround cp2108 bug and get correct value. -- */ --static int cp210x_get_line_ctl(struct usb_serial_port *port, u16 *ctl) --{ -- struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); -- int err; -- -- err = cp210x_read_u16_reg(port, CP210X_GET_LINE_CTL, ctl); -- if (err) -- return err; -- -- /* Workaround swapped bytes in 16-bit value from CP210X_GET_LINE_CTL */ -- if (port_priv->has_swapped_line_ctl) -- *ctl = swab16(*ctl); -- -- return 0; --} -- - static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) - { - struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); -@@ -867,16 +770,8 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) - return result; - } - -- /* Configure the termios structure */ -- cp210x_get_termios(tty, port); -- -- if (tty) { -- /* The baud rate must be initialised on cp2104 */ -- cp210x_change_speed(tty, port, NULL); -- -- if (I_INPCK(tty)) -- cp210x_enable_event_mode(port); -- } -+ if (tty) -+ cp210x_set_termios(tty, port, NULL); - - result = usb_serial_generic_open(tty, port); - if (result) -@@ -1055,167 +950,6 @@ static bool cp210x_tx_empty(struct usb_serial_port *port) - return !count; - } - --/* -- * cp210x_get_termios -- * Reads the baud rate, data bits, parity, stop bits and flow control mode -- * from the device, corrects any unsupported values, and configures the -- * termios structure to reflect the state of the device -- */ --static void cp210x_get_termios(struct tty_struct *tty, -- struct usb_serial_port *port) --{ -- unsigned int baud; -- -- if (tty) { -- cp210x_get_termios_port(tty->driver_data, -- &tty->termios.c_cflag, &baud); -- tty_encode_baud_rate(tty, baud, baud); -- } else { -- tcflag_t cflag; -- cflag = 0; -- cp210x_get_termios_port(port, &cflag, &baud); -- } --} -- --/* -- * cp210x_get_termios_port -- * This is the heart of cp210x_get_termios which always uses a &usb_serial_port. -- */ --static void cp210x_get_termios_port(struct usb_serial_port *port, -- tcflag_t *cflagp, unsigned int *baudp) --{ -- struct device *dev = &port->dev; -- tcflag_t cflag; -- struct cp210x_flow_ctl flow_ctl; -- u32 baud; -- u16 bits; -- u32 ctl_hs; -- u32 flow_repl; -- -- cp210x_read_u32_reg(port, CP210X_GET_BAUDRATE, &baud); -- -- dev_dbg(dev, "%s - baud rate = %d\n", __func__, baud); -- *baudp = baud; -- -- cflag = *cflagp; -- -- cp210x_get_line_ctl(port, &bits); -- cflag &= ~CSIZE; -- switch (bits & BITS_DATA_MASK) { -- case BITS_DATA_5: -- dev_dbg(dev, "%s - data bits = 5\n", __func__); -- cflag |= CS5; -- break; -- case BITS_DATA_6: -- dev_dbg(dev, "%s - data bits = 6\n", __func__); -- cflag |= CS6; -- break; -- case BITS_DATA_7: -- dev_dbg(dev, "%s - data bits = 7\n", __func__); -- cflag |= CS7; -- break; -- case BITS_DATA_8: -- dev_dbg(dev, "%s - data bits = 8\n", __func__); -- cflag |= CS8; -- break; -- case BITS_DATA_9: -- dev_dbg(dev, "%s - data bits = 9 (not supported, using 8 data bits)\n", __func__); -- cflag |= CS8; -- bits &= ~BITS_DATA_MASK; -- bits |= BITS_DATA_8; -- cp210x_write_u16_reg(port, CP210X_SET_LINE_CTL, bits); -- break; -- default: -- dev_dbg(dev, "%s - Unknown number of data bits, using 8\n", __func__); -- cflag |= CS8; -- bits &= ~BITS_DATA_MASK; -- bits |= BITS_DATA_8; -- cp210x_write_u16_reg(port, CP210X_SET_LINE_CTL, bits); -- break; -- } -- -- switch (bits & BITS_PARITY_MASK) { -- case BITS_PARITY_NONE: -- dev_dbg(dev, "%s - parity = NONE\n", __func__); -- cflag &= ~PARENB; -- break; -- case BITS_PARITY_ODD: -- dev_dbg(dev, "%s - parity = ODD\n", __func__); -- cflag |= (PARENB|PARODD); -- break; -- case BITS_PARITY_EVEN: -- dev_dbg(dev, "%s - parity = EVEN\n", __func__); -- cflag &= ~PARODD; -- cflag |= PARENB; -- break; -- case BITS_PARITY_MARK: -- dev_dbg(dev, "%s - parity = MARK\n", __func__); -- cflag |= (PARENB|PARODD|CMSPAR); -- break; -- case BITS_PARITY_SPACE: -- dev_dbg(dev, "%s - parity = SPACE\n", __func__); -- cflag &= ~PARODD; -- cflag |= (PARENB|CMSPAR); -- break; -- default: -- dev_dbg(dev, "%s - Unknown parity mode, disabling parity\n", __func__); -- cflag &= ~PARENB; -- bits &= ~BITS_PARITY_MASK; -- cp210x_write_u16_reg(port, CP210X_SET_LINE_CTL, bits); -- break; -- } -- -- cflag &= ~CSTOPB; -- switch (bits & BITS_STOP_MASK) { -- case BITS_STOP_1: -- dev_dbg(dev, "%s - stop bits = 1\n", __func__); -- break; -- case BITS_STOP_1_5: -- dev_dbg(dev, "%s - stop bits = 1.5 (not supported, using 1 stop bit)\n", __func__); -- bits &= ~BITS_STOP_MASK; -- cp210x_write_u16_reg(port, CP210X_SET_LINE_CTL, bits); -- break; -- case BITS_STOP_2: -- dev_dbg(dev, "%s - stop bits = 2\n", __func__); -- cflag |= CSTOPB; -- break; -- default: -- dev_dbg(dev, "%s - Unknown number of stop bits, using 1 stop bit\n", __func__); -- bits &= ~BITS_STOP_MASK; -- cp210x_write_u16_reg(port, CP210X_SET_LINE_CTL, bits); -- break; -- } -- -- cp210x_read_reg_block(port, CP210X_GET_FLOW, &flow_ctl, -- sizeof(flow_ctl)); -- ctl_hs = le32_to_cpu(flow_ctl.ulControlHandshake); -- if (ctl_hs & CP210X_SERIAL_CTS_HANDSHAKE) { -- dev_dbg(dev, "%s - flow control = CRTSCTS\n", __func__); -- /* -- * When the port is closed, the CP210x hardware disables -- * auto-RTS and RTS is deasserted but it leaves auto-CTS when -- * in hardware flow control mode. When re-opening the port, if -- * auto-CTS is enabled on the cp210x, then auto-RTS must be -- * re-enabled in the driver. -- */ -- flow_repl = le32_to_cpu(flow_ctl.ulFlowReplace); -- flow_repl &= ~CP210X_SERIAL_RTS_MASK; -- flow_repl |= CP210X_SERIAL_RTS_SHIFT(CP210X_SERIAL_RTS_FLOW_CTL); -- flow_ctl.ulFlowReplace = cpu_to_le32(flow_repl); -- cp210x_write_reg_block(port, -- CP210X_SET_FLOW, -- &flow_ctl, -- sizeof(flow_ctl)); -- -- cflag |= CRTSCTS; -- } else { -- dev_dbg(dev, "%s - flow control = NONE\n", __func__); -- cflag &= ~CRTSCTS; -- } -- -- *cflagp = cflag; --} -- - struct cp210x_rate { - speed_t rate; - speed_t high; -@@ -1393,17 +1127,13 @@ static void cp210x_set_termios(struct tty_struct *tty, - { - struct cp210x_serial_private *priv = usb_get_serial_data(port->serial); - struct device *dev = &port->dev; -- unsigned int cflag, old_cflag; - u16 bits; - int ret; - -- if (!cp210x_termios_change(&tty->termios, old_termios)) -+ if (old_termios && !cp210x_termios_change(&tty->termios, old_termios)) - return; - -- cflag = tty->termios.c_cflag; -- old_cflag = old_termios->c_cflag; -- -- if (tty->termios.c_ospeed != old_termios->c_ospeed) -+ if (!old_termios || tty->termios.c_ospeed != old_termios->c_ospeed) - cp210x_change_speed(tty, port, old_termios); - - /* CP2101 only supports CS8, 1 stop bit and non-stick parity. */ -@@ -1453,7 +1183,7 @@ static void cp210x_set_termios(struct tty_struct *tty, - if (ret) - dev_err(&port->dev, "failed to set line control: %d\n", ret); - -- if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { -+ if (!old_termios || C_CRTSCTS(tty) != (old_termios->c_cflag & CRTSCTS)) { - struct cp210x_flow_ctl flow_ctl; - u32 ctl_hs; - u32 flow_repl; -@@ -1470,7 +1200,7 @@ static void cp210x_set_termios(struct tty_struct *tty, - ctl_hs &= ~CP210X_SERIAL_DSR_SENSITIVITY; - ctl_hs &= ~CP210X_SERIAL_DTR_MASK; - ctl_hs |= CP210X_SERIAL_DTR_SHIFT(CP210X_SERIAL_DTR_ACTIVE); -- if (cflag & CRTSCTS) { -+ if (C_CRTSCTS(tty)) { - ctl_hs |= CP210X_SERIAL_CTS_HANDSHAKE; - - flow_repl &= ~CP210X_SERIAL_RTS_MASK; -@@ -2020,7 +1750,6 @@ static int cp210x_port_probe(struct usb_serial_port *port) - { - struct usb_serial *serial = port->serial; - struct cp210x_port_private *port_priv; -- int ret; - - port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); - if (!port_priv) -@@ -2030,12 +1759,6 @@ static int cp210x_port_probe(struct usb_serial_port *port) - - usb_set_serial_port_data(port, port_priv); - -- ret = cp210x_detect_swapped_line_ctl(port); -- if (ret) { -- kfree(port_priv); -- return ret; -- } -- - return 0; - } - diff --git a/recipes-kernel/linux/files/patches-5.10/0112-USB-serial-cp210x-drop-flow-control-debugging.patch b/recipes-kernel/linux/files/patches-5.10/0112-USB-serial-cp210x-drop-flow-control-debugging.patch deleted file mode 100644 index 181e7f31c..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0112-USB-serial-cp210x-drop-flow-control-debugging.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Johan Hovold -Date: Mon, 16 Nov 2020 17:18:24 +0100 -Subject: [PATCH] USB: serial: cp210x: drop flow-control debugging - -Drop some unnecessary flow-control debugging. - -Signed-off-by: Johan Hovold ---- - drivers/usb/serial/cp210x.c | 6 +----- - 1 file changed, 1 insertion(+), 5 deletions(-) - -diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c -index 325a2fb0f8bf..03f21186f72b 100644 ---- a/drivers/usb/serial/cp210x.c -+++ b/drivers/usb/serial/cp210x.c -@@ -1192,8 +1192,6 @@ static void cp210x_set_termios(struct tty_struct *tty, - sizeof(flow_ctl)); - ctl_hs = le32_to_cpu(flow_ctl.ulControlHandshake); - flow_repl = le32_to_cpu(flow_ctl.ulFlowReplace); -- dev_dbg(dev, "%s - read ulControlHandshake=0x%08x, ulFlowReplace=0x%08x\n", -- __func__, ctl_hs, flow_repl); - - ctl_hs &= ~CP210X_SERIAL_DSR_HANDSHAKE; - ctl_hs &= ~CP210X_SERIAL_DCD_HANDSHAKE; -@@ -1206,17 +1204,15 @@ static void cp210x_set_termios(struct tty_struct *tty, - flow_repl &= ~CP210X_SERIAL_RTS_MASK; - flow_repl |= CP210X_SERIAL_RTS_SHIFT( - CP210X_SERIAL_RTS_FLOW_CTL); -- dev_dbg(dev, "%s - flow control = CRTSCTS\n", __func__); - } else { - ctl_hs &= ~CP210X_SERIAL_CTS_HANDSHAKE; - - flow_repl &= ~CP210X_SERIAL_RTS_MASK; - flow_repl |= CP210X_SERIAL_RTS_SHIFT( - CP210X_SERIAL_RTS_ACTIVE); -- dev_dbg(dev, "%s - flow control = NONE\n", __func__); - } - -- dev_dbg(dev, "%s - write ulControlHandshake=0x%08x, ulFlowReplace=0x%08x\n", -+ dev_dbg(dev, "%s - ulControlHandshake=0x%08x, ulFlowReplace=0x%08x\n", - __func__, ctl_hs, flow_repl); - flow_ctl.ulControlHandshake = cpu_to_le32(ctl_hs); - flow_ctl.ulFlowReplace = cpu_to_le32(flow_repl); diff --git a/recipes-kernel/linux/files/patches-5.10/0113-USB-serial-cp210x-refactor-flow-control-handling.patch b/recipes-kernel/linux/files/patches-5.10/0113-USB-serial-cp210x-refactor-flow-control-handling.patch deleted file mode 100644 index d653f1cb5..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0113-USB-serial-cp210x-refactor-flow-control-handling.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Johan Hovold -Date: Mon, 16 Nov 2020 17:18:25 +0100 -Subject: [PATCH] USB: serial: cp210x: refactor flow-control handling - -Add a helper function to be used to configure flow control. - -The flow-control code was the last caller that relied on the -memset-on-failure behaviour of cp210x_read_reg_block(), which we can now -drop in favour of bailing out on errors when retrieving the flow-control -settings. - -This should also simplify adding support for software flow control. - -Signed-off-by: Johan Hovold ---- - drivers/usb/serial/cp210x.c | 97 ++++++++++++++++++------------------- - 1 file changed, 47 insertions(+), 50 deletions(-) - -diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c -index 03f21186f72b..4fdf2c2091f6 100644 ---- a/drivers/usb/serial/cp210x.c -+++ b/drivers/usb/serial/cp210x.c -@@ -578,14 +578,8 @@ static int cp210x_read_reg_block(struct usb_serial_port *port, u8 req, - int result; - - dmabuf = kmalloc(bufsize, GFP_KERNEL); -- if (!dmabuf) { -- /* -- * FIXME Some callers don't bother to check for error, -- * at least give them consistent junk until they are fixed -- */ -- memset(buf, 0, bufsize); -+ if (!dmabuf) - return -ENOMEM; -- } - - result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - req, REQTYPE_INTERFACE_TO_HOST, 0, -@@ -599,12 +593,6 @@ static int cp210x_read_reg_block(struct usb_serial_port *port, u8 req, - req, bufsize, result); - if (result >= 0) - result = -EIO; -- -- /* -- * FIXME Some callers don't bother to check for error, -- * at least give them consistent junk until they are fixed -- */ -- memset(buf, 0, bufsize); - } - - kfree(dmabuf); -@@ -1122,11 +1110,55 @@ static bool cp210x_termios_change(const struct ktermios *a, const struct ktermio - return tty_termios_hw_change(a, b) || iflag_change; - } - -+static void cp210x_set_flow_control(struct tty_struct *tty, -+ struct usb_serial_port *port, struct ktermios *old_termios) -+{ -+ struct cp210x_flow_ctl flow_ctl; -+ u32 flow_repl; -+ u32 ctl_hs; -+ int ret; -+ -+ if (old_termios && C_CRTSCTS(tty) == (old_termios->c_cflag & CRTSCTS)) -+ return; -+ -+ ret = cp210x_read_reg_block(port, CP210X_GET_FLOW, &flow_ctl, -+ sizeof(flow_ctl)); -+ if (ret) -+ return; -+ -+ ctl_hs = le32_to_cpu(flow_ctl.ulControlHandshake); -+ flow_repl = le32_to_cpu(flow_ctl.ulFlowReplace); -+ -+ ctl_hs &= ~CP210X_SERIAL_DSR_HANDSHAKE; -+ ctl_hs &= ~CP210X_SERIAL_DCD_HANDSHAKE; -+ ctl_hs &= ~CP210X_SERIAL_DSR_SENSITIVITY; -+ ctl_hs &= ~CP210X_SERIAL_DTR_MASK; -+ ctl_hs |= CP210X_SERIAL_DTR_SHIFT(CP210X_SERIAL_DTR_ACTIVE); -+ -+ if (C_CRTSCTS(tty)) { -+ ctl_hs |= CP210X_SERIAL_CTS_HANDSHAKE; -+ flow_repl &= ~CP210X_SERIAL_RTS_MASK; -+ flow_repl |= CP210X_SERIAL_RTS_SHIFT(CP210X_SERIAL_RTS_FLOW_CTL); -+ } else { -+ ctl_hs &= ~CP210X_SERIAL_CTS_HANDSHAKE; -+ flow_repl &= ~CP210X_SERIAL_RTS_MASK; -+ flow_repl |= CP210X_SERIAL_RTS_SHIFT(CP210X_SERIAL_RTS_ACTIVE); -+ } -+ -+ dev_dbg(&port->dev, "%s - ulControlHandshake=0x%08x, ulFlowReplace=0x%08x\n", -+ __func__, ctl_hs, flow_repl); -+ -+ flow_ctl.ulControlHandshake = cpu_to_le32(ctl_hs); -+ flow_ctl.ulFlowReplace = cpu_to_le32(flow_repl); -+ -+ cp210x_write_reg_block(port, CP210X_SET_FLOW, &flow_ctl, -+ sizeof(flow_ctl)); -+} -+ - static void cp210x_set_termios(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) - { - struct cp210x_serial_private *priv = usb_get_serial_data(port->serial); -- struct device *dev = &port->dev; - u16 bits; - int ret; - -@@ -1183,42 +1215,7 @@ static void cp210x_set_termios(struct tty_struct *tty, - if (ret) - dev_err(&port->dev, "failed to set line control: %d\n", ret); - -- if (!old_termios || C_CRTSCTS(tty) != (old_termios->c_cflag & CRTSCTS)) { -- struct cp210x_flow_ctl flow_ctl; -- u32 ctl_hs; -- u32 flow_repl; -- -- cp210x_read_reg_block(port, CP210X_GET_FLOW, &flow_ctl, -- sizeof(flow_ctl)); -- ctl_hs = le32_to_cpu(flow_ctl.ulControlHandshake); -- flow_repl = le32_to_cpu(flow_ctl.ulFlowReplace); -- -- ctl_hs &= ~CP210X_SERIAL_DSR_HANDSHAKE; -- ctl_hs &= ~CP210X_SERIAL_DCD_HANDSHAKE; -- ctl_hs &= ~CP210X_SERIAL_DSR_SENSITIVITY; -- ctl_hs &= ~CP210X_SERIAL_DTR_MASK; -- ctl_hs |= CP210X_SERIAL_DTR_SHIFT(CP210X_SERIAL_DTR_ACTIVE); -- if (C_CRTSCTS(tty)) { -- ctl_hs |= CP210X_SERIAL_CTS_HANDSHAKE; -- -- flow_repl &= ~CP210X_SERIAL_RTS_MASK; -- flow_repl |= CP210X_SERIAL_RTS_SHIFT( -- CP210X_SERIAL_RTS_FLOW_CTL); -- } else { -- ctl_hs &= ~CP210X_SERIAL_CTS_HANDSHAKE; -- -- flow_repl &= ~CP210X_SERIAL_RTS_MASK; -- flow_repl |= CP210X_SERIAL_RTS_SHIFT( -- CP210X_SERIAL_RTS_ACTIVE); -- } -- -- dev_dbg(dev, "%s - ulControlHandshake=0x%08x, ulFlowReplace=0x%08x\n", -- __func__, ctl_hs, flow_repl); -- flow_ctl.ulControlHandshake = cpu_to_le32(ctl_hs); -- flow_ctl.ulFlowReplace = cpu_to_le32(flow_repl); -- cp210x_write_reg_block(port, CP210X_SET_FLOW, &flow_ctl, -- sizeof(flow_ctl)); -- } -+ cp210x_set_flow_control(tty, port, old_termios); - - /* - * Enable event-insertion mode only if input parity checking is diff --git a/recipes-kernel/linux/files/patches-5.10/0114-USB-serial-cp210x-clean-up-dtr_rts.patch b/recipes-kernel/linux/files/patches-5.10/0114-USB-serial-cp210x-clean-up-dtr_rts.patch deleted file mode 100644 index 494e370f1..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0114-USB-serial-cp210x-clean-up-dtr_rts.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Johan Hovold -Date: Mon, 16 Nov 2020 17:18:26 +0100 -Subject: [PATCH] USB: serial: cp210x: clean up dtr_rts() - -Clean up dtr_rts() by renaming the port parameter and adding missing -whitespace. - -Signed-off-by: Johan Hovold ---- - drivers/usb/serial/cp210x.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c -index 4fdf2c2091f6..52d4be3ae73c 100644 ---- a/drivers/usb/serial/cp210x.c -+++ b/drivers/usb/serial/cp210x.c -@@ -46,7 +46,7 @@ static void cp210x_disconnect(struct usb_serial *); - static void cp210x_release(struct usb_serial *); - static int cp210x_port_probe(struct usb_serial_port *); - static int cp210x_port_remove(struct usb_serial_port *); --static void cp210x_dtr_rts(struct usb_serial_port *p, int on); -+static void cp210x_dtr_rts(struct usb_serial_port *port, int on); - static void cp210x_process_read_urb(struct urb *urb); - static void cp210x_enable_event_mode(struct usb_serial_port *port); - static void cp210x_disable_event_mode(struct usb_serial_port *port); -@@ -1261,12 +1261,12 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, - return cp210x_write_u16_reg(port, CP210X_SET_MHS, control); - } - --static void cp210x_dtr_rts(struct usb_serial_port *p, int on) -+static void cp210x_dtr_rts(struct usb_serial_port *port, int on) - { - if (on) -- cp210x_tiocmset_port(p, TIOCM_DTR|TIOCM_RTS, 0); -+ cp210x_tiocmset_port(port, TIOCM_DTR | TIOCM_RTS, 0); - else -- cp210x_tiocmset_port(p, 0, TIOCM_DTR|TIOCM_RTS); -+ cp210x_tiocmset_port(port, 0, TIOCM_DTR | TIOCM_RTS); - } - - static int cp210x_tiocmget(struct tty_struct *tty) diff --git a/recipes-kernel/linux/files/patches-5.10/0115-USB-serial-cp210x-add-support-for-software-flow-cont.patch b/recipes-kernel/linux/files/patches-5.10/0115-USB-serial-cp210x-add-support-for-software-flow-cont.patch deleted file mode 100644 index b69910448..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0115-USB-serial-cp210x-add-support-for-software-flow-cont.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Wang Sheng Long -Date: Mon, 18 Jan 2021 12:13:26 +0100 -Subject: [PATCH] USB: serial: cp210x: add support for software flow control - -When data is transmitted between two serial ports, the phenomenon of -data loss often occurs. The two kinds of flow control commonly used in -serial communication are hardware flow control and software flow -control. - -In serial communication, If you only use RX/TX/GND Pins, you can't do -hardware flow. So we often used software flow control and prevent data -loss. The user sets the software flow control through the application -program, and the application program sets the software flow control mode -for the serial port chip through the driver. - -For the cp210 serial port chip, its driver lacks the software flow -control setting code, so the user cannot set the software flow control -function through the application program. This adds the missing software -flow control. - -Signed-off-by: Wang Sheng Long -Link: https://lore.kernel.org/r/20210104094502.3942-1-china_shenglong@163.com -[ johan: rework properly on top of recent termios changes ] -Reviewed-by: Greg Kroah-Hartman -Signed-off-by: Johan Hovold ---- - drivers/usb/serial/cp210x.c | 67 +++++++++++++++++++++++++++++++++++-- - 1 file changed, 65 insertions(+), 2 deletions(-) - -diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c -index 52d4be3ae73c..0fc826bd42f0 100644 ---- a/drivers/usb/serial/cp210x.c -+++ b/drivers/usb/serial/cp210x.c -@@ -394,6 +394,16 @@ static struct usb_serial_driver * const serial_drivers[] = { - #define CONTROL_WRITE_DTR 0x0100 - #define CONTROL_WRITE_RTS 0x0200 - -+/* CP210X_(GET|SET)_CHARS */ -+struct cp210x_special_chars { -+ u8 bEofChar; -+ u8 bErrorChar; -+ u8 bBreakChar; -+ u8 bEventChar; -+ u8 bXonChar; -+ u8 bXoffChar; -+}; -+ - /* CP210X_VENDOR_SPECIFIC values */ - #define CP210X_READ_2NCONFIG 0x000E - #define CP210X_READ_LATCH 0x00C2 -@@ -1101,11 +1111,38 @@ static void cp210x_disable_event_mode(struct usb_serial_port *port) - port_priv->event_mode = false; - } - -+static int cp210x_set_chars(struct usb_serial_port *port, -+ struct cp210x_special_chars *chars) -+{ -+ struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); -+ struct usb_serial *serial = port->serial; -+ void *dmabuf; -+ int result; -+ -+ dmabuf = kmemdup(chars, sizeof(*chars), GFP_KERNEL); -+ if (!dmabuf) -+ return -ENOMEM; -+ -+ result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), -+ CP210X_SET_CHARS, REQTYPE_HOST_TO_INTERFACE, 0, -+ port_priv->bInterfaceNumber, -+ dmabuf, sizeof(*chars), USB_CTRL_SET_TIMEOUT); -+ -+ kfree(dmabuf); -+ -+ if (result < 0) { -+ dev_err(&port->dev, "failed to set special chars: %d\n", result); -+ return result; -+ } -+ -+ return 0; -+} -+ - static bool cp210x_termios_change(const struct ktermios *a, const struct ktermios *b) - { - bool iflag_change; - -- iflag_change = ((a->c_iflag ^ b->c_iflag) & INPCK); -+ iflag_change = ((a->c_iflag ^ b->c_iflag) & (INPCK | IXON | IXOFF)); - - return tty_termios_hw_change(a, b) || iflag_change; - } -@@ -1113,13 +1150,29 @@ static bool cp210x_termios_change(const struct ktermios *a, const struct ktermio - static void cp210x_set_flow_control(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) - { -+ struct cp210x_special_chars chars; - struct cp210x_flow_ctl flow_ctl; - u32 flow_repl; - u32 ctl_hs; - int ret; - -- if (old_termios && C_CRTSCTS(tty) == (old_termios->c_cflag & CRTSCTS)) -+ if (old_termios && -+ C_CRTSCTS(tty) == (old_termios->c_cflag & CRTSCTS) && -+ I_IXON(tty) == (old_termios->c_iflag & IXON) && -+ I_IXOFF(tty) == (old_termios->c_iflag & IXOFF)) { - return; -+ } -+ -+ if (I_IXON(tty) || I_IXOFF(tty)) { -+ memset(&chars, 0, sizeof(chars)); -+ -+ chars.bXonChar = START_CHAR(tty); -+ chars.bXoffChar = STOP_CHAR(tty); -+ -+ ret = cp210x_set_chars(port, &chars); -+ if (ret) -+ return; -+ } - - ret = cp210x_read_reg_block(port, CP210X_GET_FLOW, &flow_ctl, - sizeof(flow_ctl)); -@@ -1145,6 +1198,16 @@ static void cp210x_set_flow_control(struct tty_struct *tty, - flow_repl |= CP210X_SERIAL_RTS_SHIFT(CP210X_SERIAL_RTS_ACTIVE); - } - -+ if (I_IXOFF(tty)) -+ flow_repl |= CP210X_SERIAL_AUTO_RECEIVE; -+ else -+ flow_repl &= ~CP210X_SERIAL_AUTO_RECEIVE; -+ -+ if (I_IXON(tty)) -+ flow_repl |= CP210X_SERIAL_AUTO_TRANSMIT; -+ else -+ flow_repl &= ~CP210X_SERIAL_AUTO_TRANSMIT; -+ - dev_dbg(&port->dev, "%s - ulControlHandshake=0x%08x, ulFlowReplace=0x%08x\n", - __func__, ctl_hs, flow_repl); - diff --git a/recipes-kernel/linux/files/patches-5.10/0116-USB-serial-cp210x-fix-control-characters-error-handl.patch b/recipes-kernel/linux/files/patches-5.10/0116-USB-serial-cp210x-fix-control-characters-error-handl.patch deleted file mode 100644 index a61fa7ff1..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0116-USB-serial-cp210x-fix-control-characters-error-handl.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Johan Hovold -Date: Mon, 5 Jul 2021 10:20:10 +0200 -Subject: [PATCH] USB: serial: cp210x: fix control-characters error handling - -In the unlikely event that setting the software flow-control characters -fails the other flow-control settings should still be updated (just like -all other terminal settings). - -Move out the error message printed by the set_chars() helper to make it -more obvious that this is intentional. - -Fixes: 7748feffcd80 ("USB: serial: cp210x: add support for software flow control") -Cc: stable@vger.kernel.org # 5.11 -Reviewed-by: Greg Kroah-Hartman -Signed-off-by: Johan Hovold ---- - drivers/usb/serial/cp210x.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c -index 0fc826bd42f0..695a6d4f1fb5 100644 ---- a/drivers/usb/serial/cp210x.c -+++ b/drivers/usb/serial/cp210x.c -@@ -1130,10 +1130,8 @@ static int cp210x_set_chars(struct usb_serial_port *port, - - kfree(dmabuf); - -- if (result < 0) { -- dev_err(&port->dev, "failed to set special chars: %d\n", result); -+ if (result < 0) - return result; -- } - - return 0; - } -@@ -1170,8 +1168,10 @@ static void cp210x_set_flow_control(struct tty_struct *tty, - chars.bXoffChar = STOP_CHAR(tty); - - ret = cp210x_set_chars(port, &chars); -- if (ret) -- return; -+ if (ret) { -+ dev_err(&port->dev, "failed to set special chars: %d\n", -+ ret); -+ } - } - - ret = cp210x_read_reg_block(port, CP210X_GET_FLOW, &flow_ctl, diff --git a/recipes-kernel/linux/files/patches-5.10/0117-net-ethernet-icssg-prueth-Fix-release-of-iep0-on-pro.patch b/recipes-kernel/linux/files/patches-5.10/0117-net-ethernet-icssg-prueth-Fix-release-of-iep0-on-pro.patch deleted file mode 100644 index 04d1a8fa3..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0117-net-ethernet-icssg-prueth-Fix-release-of-iep0-on-pro.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Tue, 30 Nov 2021 10:53:42 +0100 -Subject: [PATCH] net: ethernet: icssg-prueth: Fix release of iep0 on probing - error - -A typo caused crashes in case icss_iep_get_idx succeeded for iep0 but -failed for iep1. - -Signed-off-by: Jan Kiszka ---- - drivers/net/ethernet/ti/icssg_prueth.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index e33aafc9e029..f996273b4ea3 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -2458,7 +2458,7 @@ static int prueth_probe(struct platform_device *pdev) - prueth->iep1 = icss_iep_get_idx(np, 1); - if (IS_ERR(prueth->iep1)) { - ret = dev_err_probe(dev, PTR_ERR(prueth->iep1), "iep1 get failed\n"); -- icss_iep_put(prueth->iep1); -+ icss_iep_put(prueth->iep0); - prueth->iep0 = NULL; - prueth->iep1 = NULL; - goto free_pool; diff --git a/recipes-kernel/linux/files/patches-5.10/0120-dmaengine-ti-k3-udma-glue-move-psi-l-pairing-in-chan.patch b/recipes-kernel/linux/files/patches-5.10/0120-dmaengine-ti-k3-udma-glue-move-psi-l-pairing-in-chan.patch deleted file mode 100644 index 8713437f2..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0120-dmaengine-ti-k3-udma-glue-move-psi-l-pairing-in-chan.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Fri, 30 Oct 2020 22:30:00 +0200 -Subject: [PATCH] dmaengine: ti: k3-udma-glue: move psi-l pairing in channel - en/dis functions - -commit 69973b4895b35a67409c8ce1c3d62090470ef47b upstream. - -The NAVSS UDMA will stuck if target IP module is disabled by PM while PSI-L -threads are paired UDMA<->IP and no further transfers is possible. This -could be the case for IPs J721E Main CPSW (cpsw9g). - -Hence, to avoid such situation do PSI-L threads pairing only when UDMA -channel is going to be enabled as at this time DMA consumer module expected -to be active already. - -Signed-off-by: Grygorii Strashko -Acked-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20201030203000.4281-1-grygorii.strashko@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit '69973b4895b3' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/k3-udma-glue.c | 64 +++++++++++++++++++++-------------- - 1 file changed, 38 insertions(+), 26 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c -index a53bc4707ae8..29d1524d1916 100644 ---- a/drivers/dma/ti/k3-udma-glue.c -+++ b/drivers/dma/ti/k3-udma-glue.c -@@ -303,19 +303,6 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev, - goto err; - } - -- ret = xudma_navss_psil_pair(tx_chn->common.udmax, -- tx_chn->common.src_thread, -- tx_chn->common.dst_thread); -- if (ret) { -- dev_err(dev, "PSI-L request err %d\n", ret); -- goto err; -- } -- -- tx_chn->psil_paired = true; -- -- /* reset TX RT registers */ -- k3_udma_glue_disable_tx_chn(tx_chn); -- - k3_udma_glue_dump_tx_chn(tx_chn); - - return tx_chn; -@@ -378,6 +365,18 @@ EXPORT_SYMBOL_GPL(k3_udma_glue_pop_tx_chn); - - int k3_udma_glue_enable_tx_chn(struct k3_udma_glue_tx_channel *tx_chn) - { -+ int ret; -+ -+ ret = xudma_navss_psil_pair(tx_chn->common.udmax, -+ tx_chn->common.src_thread, -+ tx_chn->common.dst_thread); -+ if (ret) { -+ dev_err(tx_chn->common.dev, "PSI-L request err %d\n", ret); -+ return ret; -+ } -+ -+ tx_chn->psil_paired = true; -+ - xudma_tchanrt_write(tx_chn->udma_tchanx, UDMA_CHAN_RT_PEER_RT_EN_REG, - UDMA_PEER_RT_EN_ENABLE); - -@@ -398,6 +397,13 @@ void k3_udma_glue_disable_tx_chn(struct k3_udma_glue_tx_channel *tx_chn) - xudma_tchanrt_write(tx_chn->udma_tchanx, - UDMA_CHAN_RT_PEER_RT_EN_REG, 0); - k3_udma_glue_dump_tx_rt_chn(tx_chn, "txchn dis2"); -+ -+ if (tx_chn->psil_paired) { -+ xudma_navss_psil_unpair(tx_chn->common.udmax, -+ tx_chn->common.src_thread, -+ tx_chn->common.dst_thread); -+ tx_chn->psil_paired = false; -+ } - } - EXPORT_SYMBOL_GPL(k3_udma_glue_disable_tx_chn); - -@@ -822,19 +828,6 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, const char *name, - goto err; - } - -- ret = xudma_navss_psil_pair(rx_chn->common.udmax, -- rx_chn->common.src_thread, -- rx_chn->common.dst_thread); -- if (ret) { -- dev_err(dev, "PSI-L request err %d\n", ret); -- goto err; -- } -- -- rx_chn->psil_paired = true; -- -- /* reset RX RT registers */ -- k3_udma_glue_disable_rx_chn(rx_chn); -- - k3_udma_glue_dump_rx_chn(rx_chn); - - return rx_chn; -@@ -1059,12 +1052,24 @@ EXPORT_SYMBOL_GPL(k3_udma_glue_rx_flow_disable); - - int k3_udma_glue_enable_rx_chn(struct k3_udma_glue_rx_channel *rx_chn) - { -+ int ret; -+ - if (rx_chn->remote) - return -EINVAL; - - if (rx_chn->flows_ready < rx_chn->flow_num) - return -EINVAL; - -+ ret = xudma_navss_psil_pair(rx_chn->common.udmax, -+ rx_chn->common.src_thread, -+ rx_chn->common.dst_thread); -+ if (ret) { -+ dev_err(rx_chn->common.dev, "PSI-L request err %d\n", ret); -+ return ret; -+ } -+ -+ rx_chn->psil_paired = true; -+ - xudma_rchanrt_write(rx_chn->udma_rchanx, UDMA_CHAN_RT_CTL_REG, - UDMA_CHAN_RT_CTL_EN); - -@@ -1085,6 +1090,13 @@ void k3_udma_glue_disable_rx_chn(struct k3_udma_glue_rx_channel *rx_chn) - xudma_rchanrt_write(rx_chn->udma_rchanx, UDMA_CHAN_RT_CTL_REG, 0); - - k3_udma_glue_dump_rx_rt_chn(rx_chn, "rxrt dis2"); -+ -+ if (rx_chn->psil_paired) { -+ xudma_navss_psil_unpair(rx_chn->common.udmax, -+ rx_chn->common.src_thread, -+ rx_chn->common.dst_thread); -+ rx_chn->psil_paired = false; -+ } - } - EXPORT_SYMBOL_GPL(k3_udma_glue_disable_rx_chn); - diff --git a/recipes-kernel/linux/files/patches-5.10/0121-dmaengine-ti-k3-udma-remove-redundant-irqsave-and-ir.patch b/recipes-kernel/linux/files/patches-5.10/0121-dmaengine-ti-k3-udma-remove-redundant-irqsave-and-ir.patch deleted file mode 100644 index 8e36addaf..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0121-dmaengine-ti-k3-udma-remove-redundant-irqsave-and-ir.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Barry Song -Date: Wed, 28 Oct 2020 10:52:44 +1300 -Subject: [PATCH] dmaengine: ti: k3-udma: remove redundant irqsave and - irqrestore in hardIRQ - -commit e991c06ed714c64d3d79696513370f894a4ab751 upstream. - -Running in hardIRQ, disabling IRQ is redundant since hardIRQ has disabled -IRQ. This patch removes the irqsave and irqstore to save some instruction -cycles. - -Signed-off-by: Barry Song -Acked-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20201027215252.25820-3-song.bao.hua@hisilicon.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit 'e991c06ed714' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/k3-udma.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index d3902784cae2..0e8426dd18a7 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -1020,13 +1020,12 @@ static irqreturn_t udma_ring_irq_handler(int irq, void *data) - { - struct udma_chan *uc = data; - struct udma_desc *d; -- unsigned long flags; - dma_addr_t paddr = 0; - - if (udma_pop_from_ring(uc, &paddr) || !paddr) - return IRQ_HANDLED; - -- spin_lock_irqsave(&uc->vc.lock, flags); -+ spin_lock(&uc->vc.lock); - - /* Teardown completion message */ - if (cppi5_desc_is_tdcm(paddr)) { -@@ -1077,7 +1076,7 @@ static irqreturn_t udma_ring_irq_handler(int irq, void *data) - } - } - out: -- spin_unlock_irqrestore(&uc->vc.lock, flags); -+ spin_unlock(&uc->vc.lock); - - return IRQ_HANDLED; - } -@@ -1086,9 +1085,8 @@ static irqreturn_t udma_udma_irq_handler(int irq, void *data) - { - struct udma_chan *uc = data; - struct udma_desc *d; -- unsigned long flags; - -- spin_lock_irqsave(&uc->vc.lock, flags); -+ spin_lock(&uc->vc.lock); - d = uc->desc; - if (d) { - d->tr_idx = (d->tr_idx + 1) % d->sglen; -@@ -1103,7 +1101,7 @@ static irqreturn_t udma_udma_irq_handler(int irq, void *data) - } - } - -- spin_unlock_irqrestore(&uc->vc.lock, flags); -+ spin_unlock(&uc->vc.lock); - - return IRQ_HANDLED; - } diff --git a/recipes-kernel/linux/files/patches-5.10/0122-dmaengine-ti-drop-of_match_ptr-and-mark-of_device_id.patch b/recipes-kernel/linux/files/patches-5.10/0122-dmaengine-ti-drop-of_match_ptr-and-mark-of_device_id.patch deleted file mode 100644 index 14825494a..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0122-dmaengine-ti-drop-of_match_ptr-and-mark-of_device_id.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Fri, 20 Nov 2020 17:23:03 +0100 -Subject: [PATCH] dmaengine: ti: drop of_match_ptr and mark of_device_id table - as maybe unused -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -commit 5d051f37f49d5bf04dca15fadea3a90a6a6f0f15 upstream. - -The driver can match only via the DT table so the main table should be -always used and the of_match_ptr does not have any sense (this also -allows ACPI matching via PRP0001, even though it is not relevant here). - -The secondary match of_device_id tables (passed to of_match_node) should -be marked as maybe unused to fix compile testing (!CONFIG_OF on x86_64) -warnings: - - drivers/dma/ti/dma-crossbar.c:125:34: warning: - ‘ti_am335x_master_match’ defined but not used [-Wunused-const-variable=] - drivers/dma/ti/dma-crossbar.c:22:34: warning: - ‘ti_dma_xbar_match’ defined but not used [-Wunused-const-variable=] - -Signed-off-by: Krzysztof Kozlowski -Link: https://lore.kernel.org/r/20201120162303.482126-6-krzk@kernel.org -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit '5d051f37f49d' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/dma-crossbar.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/dma/ti/dma-crossbar.c b/drivers/dma/ti/dma-crossbar.c -index 86ced7f2d771..f744ddbbbad7 100644 ---- a/drivers/dma/ti/dma-crossbar.c -+++ b/drivers/dma/ti/dma-crossbar.c -@@ -122,7 +122,7 @@ static void *ti_am335x_xbar_route_allocate(struct of_phandle_args *dma_spec, - return map; - } - --static const struct of_device_id ti_am335x_master_match[] = { -+static const struct of_device_id ti_am335x_master_match[] __maybe_unused = { - { .compatible = "ti,edma3-tpcc", }, - {}, - }; -@@ -297,7 +297,7 @@ static const u32 ti_dma_offset[] = { - [TI_XBAR_SDMA_OFFSET] = 1, - }; - --static const struct of_device_id ti_dra7_master_match[] = { -+static const struct of_device_id ti_dra7_master_match[] __maybe_unused = { - { - .compatible = "ti,omap4430-sdma", - .data = &ti_dma_offset[TI_XBAR_SDMA_OFFSET], -@@ -465,7 +465,7 @@ static int ti_dma_xbar_probe(struct platform_device *pdev) - static struct platform_driver ti_dma_xbar_driver = { - .driver = { - .name = "ti-dma-crossbar", -- .of_match_table = of_match_ptr(ti_dma_xbar_match), -+ .of_match_table = ti_dma_xbar_match, - }, - .probe = ti_dma_xbar_probe, - }; diff --git a/recipes-kernel/linux/files/patches-5.10/0123-dmaengine-ti-k3-udma-Wait-for-peer-teardown-completi.patch b/recipes-kernel/linux/files/patches-5.10/0123-dmaengine-ti-k3-udma-Wait-for-peer-teardown-completi.patch deleted file mode 100644 index 66491f35b..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0123-dmaengine-ti-k3-udma-Wait-for-peer-teardown-completi.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Tue, 8 Dec 2020 11:04:22 +0200 -Subject: [PATCH] dmaengine: ti: k3-udma: Wait for peer teardown completion if - supported - -commit 5e1cb1cb0f9fe670900d736822a7dbcd7c11dbba upstream. - -Set the TDTYPE if it is supported on the platform (j721e) which will cause -UDMAP to wait for the remote peer to finish the teardown before returning -the teardown completed message. - -Signed-off-by: Peter Ujfalusi -Tested-by: Keerthy -Reviewed-by: Grygorii Strashko -Link: https://lore.kernel.org/r/20201208090440.31792-3-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit '5e1cb1cb0f9f' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/k3-udma.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index 0e8426dd18a7..eee43757e774 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -86,6 +86,7 @@ struct udma_rchan { - - #define UDMA_FLAG_PDMA_ACC32 BIT(0) - #define UDMA_FLAG_PDMA_BURST BIT(1) -+#define UDMA_FLAG_TDTYPE BIT(2) - - struct udma_match_data { - u32 psil_base; -@@ -1589,6 +1590,13 @@ static int udma_tisci_tx_channel_config(struct udma_chan *uc) - req_tx.tx_fetch_size = fetch_size >> 2; - req_tx.txcq_qnum = tc_ring; - req_tx.tx_atype = uc->config.atype; -+ if (uc->config.ep_type == PSIL_EP_PDMA_XY && -+ ud->match_data->flags & UDMA_FLAG_TDTYPE) { -+ /* wait for peer to complete the teardown for PDMAs */ -+ req_tx.valid_params |= -+ TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_TDTYPE_VALID; -+ req_tx.tx_tdtype = 1; -+ } - - ret = tisci_ops->tx_ch_cfg(tisci_rm->tisci, &req_tx); - if (ret) -@@ -3105,14 +3113,14 @@ static struct udma_match_data am654_mcu_data = { - static struct udma_match_data j721e_main_data = { - .psil_base = 0x1000, - .enable_memcpy_support = true, -- .flags = UDMA_FLAG_PDMA_ACC32 | UDMA_FLAG_PDMA_BURST, -+ .flags = UDMA_FLAG_PDMA_ACC32 | UDMA_FLAG_PDMA_BURST | UDMA_FLAG_TDTYPE, - .statictr_z_mask = GENMASK(23, 0), - }; - - static struct udma_match_data j721e_mcu_data = { - .psil_base = 0x6000, - .enable_memcpy_support = false, /* MEM_TO_MEM is slow via MCU UDMA */ -- .flags = UDMA_FLAG_PDMA_ACC32 | UDMA_FLAG_PDMA_BURST, -+ .flags = UDMA_FLAG_PDMA_ACC32 | UDMA_FLAG_PDMA_BURST | UDMA_FLAG_TDTYPE, - .statictr_z_mask = GENMASK(23, 0), - }; - diff --git a/recipes-kernel/linux/files/patches-5.10/0124-dmaengine-ti-k3-udma-Add-support-for-second-resource.patch b/recipes-kernel/linux/files/patches-5.10/0124-dmaengine-ti-k3-udma-Add-support-for-second-resource.patch deleted file mode 100644 index a724f7880..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0124-dmaengine-ti-k3-udma-Add-support-for-second-resource.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Tue, 8 Dec 2020 11:04:23 +0200 -Subject: [PATCH] dmaengine: ti: k3-udma: Add support for second resource range - from sysfw - -commit 1609c15a20b8e0c1adc2a26ad81fd7e2b968f81a upstream. - -Resource allocation via sysfw can use up to two ranges per resource subtype -to support more complex resource assignment, mainly for DMA channels. - -Take the second range also into consideration when setting up the maps for -available resources. - -Signed-off-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20201208090440.31792-4-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit '1609c15a20b8' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/k3-udma.c | 55 ++++++++++++++++++++++------------------ - 1 file changed, 31 insertions(+), 24 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index eee43757e774..b89afa602532 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -3174,12 +3174,22 @@ static int udma_get_mmrs(struct platform_device *pdev, struct udma_dev *ud) - return 0; - } - -+static void udma_mark_resource_ranges(struct udma_dev *ud, unsigned long *map, -+ struct ti_sci_resource_desc *rm_desc, -+ char *name) -+{ -+ bitmap_clear(map, rm_desc->start, rm_desc->num); -+ bitmap_clear(map, rm_desc->start_sec, rm_desc->num_sec); -+ dev_dbg(ud->dev, "ti_sci resource range for %s: %d:%d | %d:%d\n", name, -+ rm_desc->start, rm_desc->num, rm_desc->start_sec, -+ rm_desc->num_sec); -+} -+ - static int udma_setup_resources(struct udma_dev *ud) - { - struct device *dev = ud->dev; - int ch_count, ret, i, j; - u32 cap2, cap3; -- struct ti_sci_resource_desc *rm_desc; - struct ti_sci_resource *rm_res, irq_res; - struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; - static const char * const range_names[] = { "ti,sci-rm-range-tchan", -@@ -3264,13 +3274,9 @@ static int udma_setup_resources(struct udma_dev *ud) - bitmap_zero(ud->tchan_map, ud->tchan_cnt); - } else { - bitmap_fill(ud->tchan_map, ud->tchan_cnt); -- for (i = 0; i < rm_res->sets; i++) { -- rm_desc = &rm_res->desc[i]; -- bitmap_clear(ud->tchan_map, rm_desc->start, -- rm_desc->num); -- dev_dbg(dev, "ti-sci-res: tchan: %d:%d\n", -- rm_desc->start, rm_desc->num); -- } -+ for (i = 0; i < rm_res->sets; i++) -+ udma_mark_resource_ranges(ud, ud->tchan_map, -+ &rm_res->desc[i], "tchan"); - } - irq_res.sets = rm_res->sets; - -@@ -3280,13 +3286,9 @@ static int udma_setup_resources(struct udma_dev *ud) - bitmap_zero(ud->rchan_map, ud->rchan_cnt); - } else { - bitmap_fill(ud->rchan_map, ud->rchan_cnt); -- for (i = 0; i < rm_res->sets; i++) { -- rm_desc = &rm_res->desc[i]; -- bitmap_clear(ud->rchan_map, rm_desc->start, -- rm_desc->num); -- dev_dbg(dev, "ti-sci-res: rchan: %d:%d\n", -- rm_desc->start, rm_desc->num); -- } -+ for (i = 0; i < rm_res->sets; i++) -+ udma_mark_resource_ranges(ud, ud->rchan_map, -+ &rm_res->desc[i], "rchan"); - } - - irq_res.sets += rm_res->sets; -@@ -3295,12 +3297,21 @@ static int udma_setup_resources(struct udma_dev *ud) - for (i = 0; i < rm_res->sets; i++) { - irq_res.desc[i].start = rm_res->desc[i].start; - irq_res.desc[i].num = rm_res->desc[i].num; -+ irq_res.desc[i].start_sec = rm_res->desc[i].start_sec; -+ irq_res.desc[i].num_sec = rm_res->desc[i].num_sec; - } - rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN]; - for (j = 0; j < rm_res->sets; j++, i++) { -- irq_res.desc[i].start = rm_res->desc[j].start + -+ if (rm_res->desc[j].num) { -+ irq_res.desc[i].start = rm_res->desc[j].start + - ud->soc_data->rchan_oes_offset; -- irq_res.desc[i].num = rm_res->desc[j].num; -+ irq_res.desc[i].num = rm_res->desc[j].num; -+ } -+ if (rm_res->desc[j].num_sec) { -+ irq_res.desc[i].start_sec = rm_res->desc[j].start_sec + -+ ud->soc_data->rchan_oes_offset; -+ irq_res.desc[i].num_sec = rm_res->desc[j].num_sec; -+ } - } - ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res); - kfree(irq_res.desc); -@@ -3316,13 +3327,9 @@ static int udma_setup_resources(struct udma_dev *ud) - bitmap_clear(ud->rflow_gp_map, ud->rchan_cnt, - ud->rflow_cnt - ud->rchan_cnt); - } else { -- for (i = 0; i < rm_res->sets; i++) { -- rm_desc = &rm_res->desc[i]; -- bitmap_clear(ud->rflow_gp_map, rm_desc->start, -- rm_desc->num); -- dev_dbg(dev, "ti-sci-res: rflow: %d:%d\n", -- rm_desc->start, rm_desc->num); -- } -+ for (i = 0; i < rm_res->sets; i++) -+ udma_mark_resource_ranges(ud, ud->rflow_gp_map, -+ &rm_res->desc[i], "gp-rflow"); - } - - ch_count -= bitmap_weight(ud->tchan_map, ud->tchan_cnt); diff --git a/recipes-kernel/linux/files/patches-5.10/0125-dmaengine-ti-k3-udma-glue-Get-the-ringacc-from-udma_.patch b/recipes-kernel/linux/files/patches-5.10/0125-dmaengine-ti-k3-udma-glue-Get-the-ringacc-from-udma_.patch deleted file mode 100644 index 691c7ad68..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0125-dmaengine-ti-k3-udma-glue-Get-the-ringacc-from-udma_.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Tue, 8 Dec 2020 11:04:25 +0200 -Subject: [PATCH] dmaengine: ti: k3-udma-glue: Get the ringacc from udma_dev - -commit aa8a4c4edad0bed7aaf3a7cfcae9fa555d847955 upstream. - -If of_xudma_dev_get() returns with the valid udma_dev then the driver -already got the ringacc, there is no need to execute -of_k3_ringacc_get_by_phandle() for each channel via the glue layer. - -Signed-off-by: Peter Ujfalusi -Reviewed-by: Grygorii Strashko -Link: https://lore.kernel.org/r/20201208090440.31792-6-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit 'aa8a4c4edad0' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/k3-udma-glue.c | 6 +----- - drivers/dma/ti/k3-udma-private.c | 6 ++++++ - drivers/dma/ti/k3-udma.h | 1 + - 3 files changed, 8 insertions(+), 5 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c -index 29d1524d1916..8a8988be4175 100644 ---- a/drivers/dma/ti/k3-udma-glue.c -+++ b/drivers/dma/ti/k3-udma-glue.c -@@ -86,15 +86,11 @@ struct k3_udma_glue_rx_channel { - static int of_k3_udma_glue_parse(struct device_node *udmax_np, - struct k3_udma_glue_common *common) - { -- common->ringacc = of_k3_ringacc_get_by_phandle(udmax_np, -- "ti,ringacc"); -- if (IS_ERR(common->ringacc)) -- return PTR_ERR(common->ringacc); -- - common->udmax = of_xudma_dev_get(udmax_np, NULL); - if (IS_ERR(common->udmax)) - return PTR_ERR(common->udmax); - -+ common->ringacc = xudma_get_ringacc(common->udmax); - common->tisci_rm = xudma_dev_get_tisci_rm(common->udmax); - - return 0; -diff --git a/drivers/dma/ti/k3-udma-private.c b/drivers/dma/ti/k3-udma-private.c -index bae6150b1d8d..10a3ee529710 100644 ---- a/drivers/dma/ti/k3-udma-private.c -+++ b/drivers/dma/ti/k3-udma-private.c -@@ -56,6 +56,12 @@ struct device *xudma_get_device(struct udma_dev *ud) - } - EXPORT_SYMBOL(xudma_get_device); - -+struct k3_ringacc *xudma_get_ringacc(struct udma_dev *ud) -+{ -+ return ud->ringacc; -+} -+EXPORT_SYMBOL(xudma_get_ringacc); -+ - u32 xudma_dev_get_psil_base(struct udma_dev *ud) - { - return ud->psil_base; -diff --git a/drivers/dma/ti/k3-udma.h b/drivers/dma/ti/k3-udma.h -index d1cace0cb43b..b4334b1b7b14 100644 ---- a/drivers/dma/ti/k3-udma.h -+++ b/drivers/dma/ti/k3-udma.h -@@ -113,6 +113,7 @@ int xudma_navss_psil_unpair(struct udma_dev *ud, u32 src_thread, - - struct udma_dev *of_xudma_dev_get(struct device_node *np, const char *property); - struct device *xudma_get_device(struct udma_dev *ud); -+struct k3_ringacc *xudma_get_ringacc(struct udma_dev *ud); - void xudma_dev_put(struct udma_dev *ud); - u32 xudma_dev_get_psil_base(struct udma_dev *ud); - struct udma_tisci_rm *xudma_dev_get_tisci_rm(struct udma_dev *ud); diff --git a/recipes-kernel/linux/files/patches-5.10/0126-dmaengine-ti-k3-udma-glue-Configure-the-dma_dev-for-.patch b/recipes-kernel/linux/files/patches-5.10/0126-dmaengine-ti-k3-udma-glue-Configure-the-dma_dev-for-.patch deleted file mode 100644 index 5ab0a1f5d..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0126-dmaengine-ti-k3-udma-glue-Configure-the-dma_dev-for-.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Tue, 8 Dec 2020 11:04:26 +0200 -Subject: [PATCH] dmaengine: ti: k3-udma-glue: Configure the dma_dev for rings - -commit d553e2ab0137ae489b41824b1e8283053c363ed1 upstream. - -Rings in RING mode should be using the DMA device for DMA API as in this -mode the ringacc will not access the ring memory in any ways, but the DMA -is. - -Fix up the ring configuration and set the dma_dev unconditionally and let -the ringacc driver to select the correct device to use for DMA API. - -Signed-off-by: Peter Ujfalusi -Reviewed-by: Grygorii Strashko -Link: https://lore.kernel.org/r/20201208090440.31792-7-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit 'd553e2ab0137' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/k3-udma-glue.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c -index 8a8988be4175..e6ebcd98c02a 100644 ---- a/drivers/dma/ti/k3-udma-glue.c -+++ b/drivers/dma/ti/k3-udma-glue.c -@@ -276,6 +276,10 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev, - goto err; - } - -+ /* Set the dma_dev for the rings to be configured */ -+ cfg->tx_cfg.dma_dev = k3_udma_glue_tx_get_dma_device(tx_chn); -+ cfg->txcq_cfg.dma_dev = cfg->tx_cfg.dma_dev; -+ - ret = k3_ringacc_ring_cfg(tx_chn->ringtx, &cfg->tx_cfg); - if (ret) { - dev_err(dev, "Failed to cfg ringtx %d\n", ret); -@@ -591,6 +595,10 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn, - goto err_rflow_put; - } - -+ /* Set the dma_dev for the rings to be configured */ -+ flow_cfg->rx_cfg.dma_dev = k3_udma_glue_rx_get_dma_device(rx_chn); -+ flow_cfg->rxfdq_cfg.dma_dev = flow_cfg->rx_cfg.dma_dev; -+ - ret = k3_ringacc_ring_cfg(flow->ringrx, &flow_cfg->rx_cfg); - if (ret) { - dev_err(dev, "Failed to cfg ringrx %d\n", ret); diff --git a/recipes-kernel/linux/files/patches-5.10/0127-dmaengine-of-dma-Add-support-for-optional-router-con.patch b/recipes-kernel/linux/files/patches-5.10/0127-dmaengine-of-dma-Add-support-for-optional-router-con.patch deleted file mode 100644 index 29383e127..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0127-dmaengine-of-dma-Add-support-for-optional-router-con.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Tue, 8 Dec 2020 11:04:27 +0200 -Subject: [PATCH] dmaengine: of-dma: Add support for optional router - configuration callback - -commit 4f910c035f38053ac8eb63a672c78862c535cd0f upstream. - -Additional configuration for the DMA event router might be needed for a -channel which can not be done during device_alloc_chan_resources callback -since the router information is not yet present for the drivers. - -If there is a need for additional configuration for the channel if DMA -router is in use, then the driver can implement the device_router_config -callback. - -Signed-off-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20201208090440.31792-8-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit '4f910c035f38' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/dma/of-dma.c | 10 ++++++++++ - include/linux/dmaengine.h | 2 ++ - 2 files changed, 12 insertions(+) - -diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c -index 4be433482053..ac61ecda2926 100644 ---- a/drivers/dma/of-dma.c -+++ b/drivers/dma/of-dma.c -@@ -79,8 +79,18 @@ static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec, - ofdma->dma_router->route_free(ofdma->dma_router->dev, - route_data); - } else { -+ int ret = 0; -+ - chan->router = ofdma->dma_router; - chan->route_data = route_data; -+ -+ if (chan->device->device_router_config) -+ ret = chan->device->device_router_config(chan); -+ -+ if (ret) { -+ dma_release_channel(chan); -+ chan = ERR_PTR(ret); -+ } - } - - err: -diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h -index 256592c0a365..86beb2b84bac 100644 ---- a/include/linux/dmaengine.h -+++ b/include/linux/dmaengine.h -@@ -801,6 +801,7 @@ struct dma_filter { - * by tx_status - * @device_alloc_chan_resources: allocate resources and return the - * number of allocated descriptors -+ * @device_router_config: optional callback for DMA router configuration - * @device_free_chan_resources: release DMA channel's resources - * @device_prep_dma_memcpy: prepares a memcpy operation - * @device_prep_dma_xor: prepares a xor operation -@@ -875,6 +876,7 @@ struct dma_device { - enum dma_residue_granularity residue_granularity; - - int (*device_alloc_chan_resources)(struct dma_chan *chan); -+ int (*device_router_config)(struct dma_chan *chan); - void (*device_free_chan_resources)(struct dma_chan *chan); - - struct dma_async_tx_descriptor *(*device_prep_dma_memcpy)( diff --git a/recipes-kernel/linux/files/patches-5.10/0128-dmaengine-Add-support-for-per-channel-coherency-hand.patch b/recipes-kernel/linux/files/patches-5.10/0128-dmaengine-Add-support-for-per-channel-coherency-hand.patch deleted file mode 100644 index 29d927dd7..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0128-dmaengine-Add-support-for-per-channel-coherency-hand.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Tue, 8 Dec 2020 11:04:28 +0200 -Subject: [PATCH] dmaengine: Add support for per channel coherency handling - -commit ab650ef6d548153862119e1bf3bf267510707f48 upstream. - -If the DMA device supports per channel coherency configuration (a channel -can be configured to have coherent or not coherent view) then a single -device (the DMA controller's device) can not be used for dma_api for all -channels as channels can have different coherency. - -Introduce custom_dma_mapping flag for the dma_chan and a new helper to get -the device pointer to be used for dma_api for the given channel. - -Client drivers should be updated to be able to support per channel -coherency by: - -- dma_map_single(chan->device->dev, ptr, size, DMA_TO_DEVICE); -+ struct device *dma_dev = dmaengine_get_dma_device(chan); -+ -+ dma_map_single(dma_dev, ptr, size, DMA_TO_DEVICE); - -Signed-off-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20201208090440.31792-9-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit 'ab650ef6d548' from v5.11] -Signed-off-by: Suman Anna ---- - include/linux/dmaengine.h | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h -index 86beb2b84bac..6ca71379dd5f 100644 ---- a/include/linux/dmaengine.h -+++ b/include/linux/dmaengine.h -@@ -357,11 +357,14 @@ struct dma_chan { - * @chan: driver channel device - * @device: sysfs device - * @dev_id: parent dma_device dev_id -+ * @chan_dma_dev: The channel is using custom/different dma-mapping -+ * compared to the parent dma_device - */ - struct dma_chan_dev { - struct dma_chan *chan; - struct device device; - int dev_id; -+ bool chan_dma_dev; - }; - - /** -@@ -1614,4 +1617,13 @@ dmaengine_get_direction_text(enum dma_transfer_direction dir) - return "invalid"; - } - } -+ -+static inline struct device *dmaengine_get_dma_device(struct dma_chan *chan) -+{ -+ if (chan->dev->chan_dma_dev) -+ return &chan->dev->device; -+ -+ return chan->device->dev; -+} -+ - #endif /* DMAENGINE_H */ diff --git a/recipes-kernel/linux/files/patches-5.10/0129-dmaengine-ti-k3-psil-Extend-psil_endpoint_config-for.patch b/recipes-kernel/linux/files/patches-5.10/0129-dmaengine-ti-k3-psil-Extend-psil_endpoint_config-for.patch deleted file mode 100644 index e5ff85358..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0129-dmaengine-ti-k3-psil-Extend-psil_endpoint_config-for.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Tue, 8 Dec 2020 11:04:33 +0200 -Subject: [PATCH] dmaengine: ti: k3-psil: Extend psil_endpoint_config for K3 - PKTDMA - -commit b9366e2577a38ca5322f326cff9752c2008597c6 upstream. - -Additional fields needed for K3 PKTDMA to be able to handle the mapped -channels (channels are locked to handle specific threads) and flow ranges -for these mapped threads. -PKTDMA also introduces tflow for tx channels which can not be found in -K3 UDMA architecture. - -Signed-off-by: Peter Ujfalusi -Reviewed-by: Grygorii Strashko -Link: https://lore.kernel.org/r/20201208090440.31792-14-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit 'b9366e2577a3' from v5.11] -Signed-off-by: Suman Anna ---- - include/linux/dma/k3-psil.h | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/include/linux/dma/k3-psil.h b/include/linux/dma/k3-psil.h -index 1962f75fa2d3..36e22c5a0f29 100644 ---- a/include/linux/dma/k3-psil.h -+++ b/include/linux/dma/k3-psil.h -@@ -50,6 +50,15 @@ enum psil_endpoint_type { - * @channel_tpl: Desired throughput level for the channel - * @pdma_acc32: ACC32 must be enabled on the PDMA side - * @pdma_burst: BURST must be enabled on the PDMA side -+ * @mapped_channel_id: PKTDMA thread to channel mapping for mapped channels. -+ * The thread must be serviced by the specified channel if -+ * mapped_channel_id is >= 0 in case of PKTDMA -+ * @flow_start: PKDMA flow range start of mapped channel. Unmapped -+ * channels use flow_id == chan_id -+ * @flow_num: PKDMA flow count of mapped channel. Unmapped channels -+ * use flow_id == chan_id -+ * @default_flow_id: PKDMA default (r)flow index of mapped channel. -+ * Must be within the flow range of the mapped channel. - */ - struct psil_endpoint_config { - enum psil_endpoint_type ep_type; -@@ -63,6 +72,13 @@ struct psil_endpoint_config { - /* PDMA properties, valid for PSIL_EP_PDMA_* */ - unsigned pdma_acc32:1; - unsigned pdma_burst:1; -+ -+ /* PKDMA mapped channel */ -+ int mapped_channel_id; -+ /* PKTDMA tflow and rflow ranges for mapped channel */ -+ u16 flow_start; -+ u16 flow_num; -+ u16 default_flow_id; - }; - - int psil_set_new_ep_config(struct device *dev, const char *name, diff --git a/recipes-kernel/linux/files/patches-5.10/0130-dmaengine-ti-Add-support-for-k3-event-routers.patch b/recipes-kernel/linux/files/patches-5.10/0130-dmaengine-ti-Add-support-for-k3-event-routers.patch deleted file mode 100644 index a8c40975b..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0130-dmaengine-ti-Add-support-for-k3-event-routers.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Tue, 8 Dec 2020 11:04:35 +0200 -Subject: [PATCH] dmaengine: ti: Add support for k3 event routers - -commit fc373e47d72605cc3f5012ddda49d2dca430d51f upstream. - -In k3 architecture a DMA channel (in TR momde) can be triggered by global -events, origination from different modules. - -The events for triggers can be sent from any module which is connected to -PSI-L fabric, but the event number to be sent is DMA channel specific, it -is only known after the channel itself is requested. - -The router operation needs to be split up: -- route_allocate: configure the dma_spec for the DMA and store the - configuration which is needed for the router's input -- set_event: callback used by the DMA driver to set the event number for - the channel and enable the routing - -Signed-off-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20201208090440.31792-16-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit 'fc373e47d726' from v5.11] -Signed-off-by: Suman Anna ---- - include/linux/dma/k3-event-router.h | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - create mode 100644 include/linux/dma/k3-event-router.h - -diff --git a/include/linux/dma/k3-event-router.h b/include/linux/dma/k3-event-router.h -new file mode 100644 -index 000000000000..e3f88b2f87be ---- /dev/null -+++ b/include/linux/dma/k3-event-router.h -@@ -0,0 +1,16 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com -+ */ -+ -+#ifndef K3_EVENT_ROUTER_ -+#define K3_EVENT_ROUTER_ -+ -+#include -+ -+struct k3_event_route_data { -+ void *priv; -+ int (*set_event)(void *priv, u32 event); -+}; -+ -+#endif /* K3_EVENT_ROUTER_ */ diff --git a/recipes-kernel/linux/files/patches-5.10/0131-soc-ti-k3-ringacc-add-AM64-DMA-rings-support.patch b/recipes-kernel/linux/files/patches-5.10/0131-soc-ti-k3-ringacc-add-AM64-DMA-rings-support.patch deleted file mode 100644 index 84ef53d5a..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0131-soc-ti-k3-ringacc-add-AM64-DMA-rings-support.patch +++ /dev/null @@ -1,600 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Tue, 8 Dec 2020 11:04:36 +0200 -Subject: [PATCH] soc: ti: k3-ringacc: add AM64 DMA rings support. - -commit d782298c6f6b854452965b56d91616dfb60490c5 upstream. - -The DMAs in AM64 have built in rings compared to AM654/J721e/J7200 where a -separate and generic ringacc is used. - -The ring SW interface is similar to ringacc with some major architectural -differences, like - -They are part of the DMA (BCDMA or PKTDMA). - -They are dual mode rings are modeled as pair of Rings objects which has -common configuration and memory buffer, but separate real-time control -register sets for each direction mem2dev (forward) and dev2mem (reverse). - -The ringacc driver must be initialized for DMA rings use with -k3_ringacc_dmarings_init() as it is not an independent device as ringacc -is. - -AM64 rings must be requested only using k3_ringacc_request_rings_pair(), -and forward ring must always be initialized/configured. After this any -other Ringacc APIs can be used without any callers changes. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20201208090440.31792-17-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit 'd782298c6f6b' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/soc/ti/k3-ringacc.c | 325 +++++++++++++++++++++++++++++- - include/linux/soc/ti/k3-ringacc.h | 17 ++ - 2 files changed, 335 insertions(+), 7 deletions(-) - -diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c -index db3f705da7a0..3a0002303379 100644 ---- a/drivers/soc/ti/k3-ringacc.c -+++ b/drivers/soc/ti/k3-ringacc.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -22,6 +23,7 @@ static LIST_HEAD(k3_ringacc_list); - static DEFINE_MUTEX(k3_ringacc_list_lock); - - #define K3_RINGACC_CFG_RING_SIZE_ELCNT_MASK GENMASK(19, 0) -+#define K3_DMARING_CFG_RING_SIZE_ELCNT_MASK GENMASK(15, 0) - - /** - * struct k3_ring_rt_regs - The RA realtime Control/Status Registers region -@@ -44,7 +46,13 @@ struct k3_ring_rt_regs { - u32 hwindx; - }; - --#define K3_RINGACC_RT_REGS_STEP 0x1000 -+#define K3_RINGACC_RT_REGS_STEP 0x1000 -+#define K3_DMARING_RT_REGS_STEP 0x2000 -+#define K3_DMARING_RT_REGS_REVERSE_OFS 0x1000 -+#define K3_RINGACC_RT_OCC_MASK GENMASK(20, 0) -+#define K3_DMARING_RT_OCC_TDOWN_COMPLETE BIT(31) -+#define K3_DMARING_RT_DB_ENTRY_MASK GENMASK(7, 0) -+#define K3_DMARING_RT_DB_TDOWN_ACK BIT(31) - - /** - * struct k3_ring_fifo_regs - The Ring Accelerator Queues Registers region -@@ -123,6 +131,7 @@ struct k3_ring_state { - u32 occ; - u32 windex; - u32 rindex; -+ u32 tdown_complete:1; - }; - - /** -@@ -143,6 +152,7 @@ struct k3_ring_state { - * @use_count: Use count for shared rings - * @proxy_id: RA Ring Proxy Id (only if @K3_RINGACC_RING_USE_PROXY) - * @dma_dev: device to be used for DMA API (allocation, mapping) -+ * @asel: Address Space Select value for physical addresses - */ - struct k3_ring { - struct k3_ring_rt_regs __iomem *rt; -@@ -157,12 +167,15 @@ struct k3_ring { - u32 flags; - #define K3_RING_FLAG_BUSY BIT(1) - #define K3_RING_FLAG_SHARED BIT(2) -+#define K3_RING_FLAG_REVERSE BIT(3) - struct k3_ring_state state; - u32 ring_id; - struct k3_ringacc *parent; - u32 use_count; - int proxy_id; - struct device *dma_dev; -+ u32 asel; -+#define K3_ADDRESS_ASEL_SHIFT 48 - }; - - struct k3_ringacc_ops { -@@ -188,6 +201,7 @@ struct k3_ringacc_ops { - * @tisci_ring_ops: ti-sci rings ops - * @tisci_dev_id: ti-sci device id - * @ops: SoC specific ringacc operation -+ * @dma_rings: indicate DMA ring (dual ring within BCDMA/PKTDMA) - */ - struct k3_ringacc { - struct device *dev; -@@ -210,6 +224,7 @@ struct k3_ringacc { - u32 tisci_dev_id; - - const struct k3_ringacc_ops *ops; -+ bool dma_rings; - }; - - /** -@@ -221,6 +236,21 @@ struct k3_ringacc_soc_data { - unsigned dma_ring_reset_quirk:1; - }; - -+static int k3_ringacc_ring_read_occ(struct k3_ring *ring) -+{ -+ return readl(&ring->rt->occ) & K3_RINGACC_RT_OCC_MASK; -+} -+ -+static void k3_ringacc_ring_update_occ(struct k3_ring *ring) -+{ -+ u32 val; -+ -+ val = readl(&ring->rt->occ); -+ -+ ring->state.occ = val & K3_RINGACC_RT_OCC_MASK; -+ ring->state.tdown_complete = !!(val & K3_DMARING_RT_OCC_TDOWN_COMPLETE); -+} -+ - static long k3_ringacc_ring_get_fifo_pos(struct k3_ring *ring) - { - return K3_RINGACC_FIFO_WINDOW_SIZE_BYTES - -@@ -234,12 +264,24 @@ static void *k3_ringacc_get_elm_addr(struct k3_ring *ring, u32 idx) - - static int k3_ringacc_ring_push_mem(struct k3_ring *ring, void *elem); - static int k3_ringacc_ring_pop_mem(struct k3_ring *ring, void *elem); -+static int k3_dmaring_fwd_pop(struct k3_ring *ring, void *elem); -+static int k3_dmaring_reverse_pop(struct k3_ring *ring, void *elem); - - static struct k3_ring_ops k3_ring_mode_ring_ops = { - .push_tail = k3_ringacc_ring_push_mem, - .pop_head = k3_ringacc_ring_pop_mem, - }; - -+static struct k3_ring_ops k3_dmaring_fwd_ops = { -+ .push_tail = k3_ringacc_ring_push_mem, -+ .pop_head = k3_dmaring_fwd_pop, -+}; -+ -+static struct k3_ring_ops k3_dmaring_reverse_ops = { -+ /* Reverse side of the DMA ring can only be popped by SW */ -+ .pop_head = k3_dmaring_reverse_pop, -+}; -+ - static int k3_ringacc_ring_push_io(struct k3_ring *ring, void *elem); - static int k3_ringacc_ring_pop_io(struct k3_ring *ring, void *elem); - static int k3_ringacc_ring_push_head_io(struct k3_ring *ring, void *elem); -@@ -342,6 +384,40 @@ struct k3_ring *k3_ringacc_request_ring(struct k3_ringacc *ringacc, - } - EXPORT_SYMBOL_GPL(k3_ringacc_request_ring); - -+static int k3_dmaring_request_dual_ring(struct k3_ringacc *ringacc, int fwd_id, -+ struct k3_ring **fwd_ring, -+ struct k3_ring **compl_ring) -+{ -+ int ret = 0; -+ -+ /* -+ * DMA rings must be requested by ID, completion ring is the reverse -+ * side of the forward ring -+ */ -+ if (fwd_id < 0) -+ return -EINVAL; -+ -+ mutex_lock(&ringacc->req_lock); -+ -+ if (test_bit(fwd_id, ringacc->rings_inuse)) { -+ ret = -EBUSY; -+ goto error; -+ } -+ -+ *fwd_ring = &ringacc->rings[fwd_id]; -+ *compl_ring = &ringacc->rings[fwd_id + ringacc->num_rings]; -+ set_bit(fwd_id, ringacc->rings_inuse); -+ ringacc->rings[fwd_id].use_count++; -+ dev_dbg(ringacc->dev, "Giving ring#%d\n", fwd_id); -+ -+ mutex_unlock(&ringacc->req_lock); -+ return 0; -+ -+error: -+ mutex_unlock(&ringacc->req_lock); -+ return ret; -+} -+ - int k3_ringacc_request_rings_pair(struct k3_ringacc *ringacc, - int fwd_id, int compl_id, - struct k3_ring **fwd_ring, -@@ -352,6 +428,10 @@ int k3_ringacc_request_rings_pair(struct k3_ringacc *ringacc, - if (!fwd_ring || !compl_ring) - return -EINVAL; - -+ if (ringacc->dma_rings) -+ return k3_dmaring_request_dual_ring(ringacc, fwd_id, -+ fwd_ring, compl_ring); -+ - *fwd_ring = k3_ringacc_request_ring(ringacc, fwd_id, 0); - if (!(*fwd_ring)) - return -ENODEV; -@@ -421,7 +501,7 @@ void k3_ringacc_ring_reset_dma(struct k3_ring *ring, u32 occ) - goto reset; - - if (!occ) -- occ = readl(&ring->rt->occ); -+ occ = k3_ringacc_ring_read_occ(ring); - - if (occ) { - u32 db_ring_cnt, db_ring_cnt_cur; -@@ -496,6 +576,13 @@ int k3_ringacc_ring_free(struct k3_ring *ring) - - ringacc = ring->parent; - -+ /* -+ * DMA rings: rings shared memory and configuration, only forward ring -+ * is configured and reverse ring considered as slave. -+ */ -+ if (ringacc->dma_rings && (ring->flags & K3_RING_FLAG_REVERSE)) -+ return 0; -+ - dev_dbg(ring->parent->dev, "flags: 0x%08x\n", ring->flags); - - if (!test_bit(ring->ring_id, ringacc->rings_inuse)) -@@ -517,6 +604,8 @@ int k3_ringacc_ring_free(struct k3_ring *ring) - ring->flags = 0; - ring->ops = NULL; - ring->dma_dev = NULL; -+ ring->asel = 0; -+ - if (ring->proxy_id != K3_RINGACC_PROXY_NOT_USED) { - clear_bit(ring->proxy_id, ringacc->proxy_inuse); - ring->proxy = NULL; -@@ -581,6 +670,7 @@ static int k3_ringacc_ring_cfg_sci(struct k3_ring *ring) - ring_cfg.count = ring->size; - ring_cfg.mode = ring->mode; - ring_cfg.size = ring->elm_size; -+ ring_cfg.asel = ring->asel; - - ret = ringacc->tisci_ring_ops->set_cfg(ringacc->tisci, &ring_cfg); - if (ret) -@@ -590,6 +680,90 @@ static int k3_ringacc_ring_cfg_sci(struct k3_ring *ring) - return ret; - } - -+static int k3_dmaring_cfg(struct k3_ring *ring, struct k3_ring_cfg *cfg) -+{ -+ struct k3_ringacc *ringacc; -+ struct k3_ring *reverse_ring; -+ int ret = 0; -+ -+ if (cfg->elm_size != K3_RINGACC_RING_ELSIZE_8 || -+ cfg->mode != K3_RINGACC_RING_MODE_RING || -+ cfg->size & ~K3_DMARING_CFG_RING_SIZE_ELCNT_MASK) -+ return -EINVAL; -+ -+ ringacc = ring->parent; -+ -+ /* -+ * DMA rings: rings shared memory and configuration, only forward ring -+ * is configured and reverse ring considered as slave. -+ */ -+ if (ringacc->dma_rings && (ring->flags & K3_RING_FLAG_REVERSE)) -+ return 0; -+ -+ if (!test_bit(ring->ring_id, ringacc->rings_inuse)) -+ return -EINVAL; -+ -+ ring->size = cfg->size; -+ ring->elm_size = cfg->elm_size; -+ ring->mode = cfg->mode; -+ ring->asel = cfg->asel; -+ ring->dma_dev = cfg->dma_dev; -+ if (!ring->dma_dev) { -+ dev_warn(ringacc->dev, "dma_dev is not provided for ring%d\n", -+ ring->ring_id); -+ ring->dma_dev = ringacc->dev; -+ } -+ -+ memset(&ring->state, 0, sizeof(ring->state)); -+ -+ ring->ops = &k3_dmaring_fwd_ops; -+ -+ ring->ring_mem_virt = dma_alloc_coherent(ring->dma_dev, -+ ring->size * (4 << ring->elm_size), -+ &ring->ring_mem_dma, GFP_KERNEL); -+ if (!ring->ring_mem_virt) { -+ dev_err(ringacc->dev, "Failed to alloc ring mem\n"); -+ ret = -ENOMEM; -+ goto err_free_ops; -+ } -+ -+ ret = k3_ringacc_ring_cfg_sci(ring); -+ if (ret) -+ goto err_free_mem; -+ -+ ring->flags |= K3_RING_FLAG_BUSY; -+ -+ k3_ringacc_ring_dump(ring); -+ -+ /* DMA rings: configure reverse ring */ -+ reverse_ring = &ringacc->rings[ring->ring_id + ringacc->num_rings]; -+ reverse_ring->size = cfg->size; -+ reverse_ring->elm_size = cfg->elm_size; -+ reverse_ring->mode = cfg->mode; -+ reverse_ring->asel = cfg->asel; -+ memset(&reverse_ring->state, 0, sizeof(reverse_ring->state)); -+ reverse_ring->ops = &k3_dmaring_reverse_ops; -+ -+ reverse_ring->ring_mem_virt = ring->ring_mem_virt; -+ reverse_ring->ring_mem_dma = ring->ring_mem_dma; -+ reverse_ring->flags |= K3_RING_FLAG_BUSY; -+ k3_ringacc_ring_dump(reverse_ring); -+ -+ return 0; -+ -+err_free_mem: -+ dma_free_coherent(ring->dma_dev, -+ ring->size * (4 << ring->elm_size), -+ ring->ring_mem_virt, -+ ring->ring_mem_dma); -+err_free_ops: -+ ring->ops = NULL; -+ ring->proxy = NULL; -+ ring->dma_dev = NULL; -+ ring->asel = 0; -+ return ret; -+} -+ - int k3_ringacc_ring_cfg(struct k3_ring *ring, struct k3_ring_cfg *cfg) - { - struct k3_ringacc *ringacc; -@@ -597,8 +771,12 @@ int k3_ringacc_ring_cfg(struct k3_ring *ring, struct k3_ring_cfg *cfg) - - if (!ring || !cfg) - return -EINVAL; -+ - ringacc = ring->parent; - -+ if (ringacc->dma_rings) -+ return k3_dmaring_cfg(ring, cfg); -+ - if (cfg->elm_size > K3_RINGACC_RING_ELSIZE_256 || - cfg->mode >= K3_RINGACC_RING_MODE_INVALID || - cfg->size & ~K3_RINGACC_CFG_RING_SIZE_ELCNT_MASK || -@@ -705,7 +883,7 @@ u32 k3_ringacc_ring_get_free(struct k3_ring *ring) - return -EINVAL; - - if (!ring->state.free) -- ring->state.free = ring->size - readl(&ring->rt->occ); -+ ring->state.free = ring->size - k3_ringacc_ring_read_occ(ring); - - return ring->state.free; - } -@@ -716,7 +894,7 @@ u32 k3_ringacc_ring_get_occ(struct k3_ring *ring) - if (!ring || !(ring->flags & K3_RING_FLAG_BUSY)) - return -EINVAL; - -- return readl(&ring->rt->occ); -+ return k3_ringacc_ring_read_occ(ring); - } - EXPORT_SYMBOL_GPL(k3_ringacc_ring_get_occ); - -@@ -892,6 +1070,72 @@ static int k3_ringacc_ring_pop_tail_io(struct k3_ring *ring, void *elem) - K3_RINGACC_ACCESS_MODE_POP_HEAD); - } - -+/* -+ * The element is 48 bits of address + ASEL bits in the ring. -+ * ASEL is used by the DMAs and should be removed for the kernel as it is not -+ * part of the physical memory address. -+ */ -+static void k3_dmaring_remove_asel_from_elem(u64 *elem) -+{ -+ *elem &= GENMASK_ULL(K3_ADDRESS_ASEL_SHIFT - 1, 0); -+} -+ -+static int k3_dmaring_fwd_pop(struct k3_ring *ring, void *elem) -+{ -+ void *elem_ptr; -+ u32 elem_idx; -+ -+ /* -+ * DMA rings: forward ring is always tied DMA channel and HW does not -+ * maintain any state data required for POP operation and its unknown -+ * how much elements were consumed by HW. So, to actually -+ * do POP, the read pointer has to be recalculated every time. -+ */ -+ ring->state.occ = k3_ringacc_ring_read_occ(ring); -+ if (ring->state.windex >= ring->state.occ) -+ elem_idx = ring->state.windex - ring->state.occ; -+ else -+ elem_idx = ring->size - (ring->state.occ - ring->state.windex); -+ -+ elem_ptr = k3_ringacc_get_elm_addr(ring, elem_idx); -+ memcpy(elem, elem_ptr, (4 << ring->elm_size)); -+ k3_dmaring_remove_asel_from_elem(elem); -+ -+ ring->state.occ--; -+ writel(-1, &ring->rt->db); -+ -+ dev_dbg(ring->parent->dev, "%s: occ%d Windex%d Rindex%d pos_ptr%px\n", -+ __func__, ring->state.occ, ring->state.windex, elem_idx, -+ elem_ptr); -+ return 0; -+} -+ -+static int k3_dmaring_reverse_pop(struct k3_ring *ring, void *elem) -+{ -+ void *elem_ptr; -+ -+ elem_ptr = k3_ringacc_get_elm_addr(ring, ring->state.rindex); -+ -+ if (ring->state.occ) { -+ memcpy(elem, elem_ptr, (4 << ring->elm_size)); -+ k3_dmaring_remove_asel_from_elem(elem); -+ -+ ring->state.rindex = (ring->state.rindex + 1) % ring->size; -+ ring->state.occ--; -+ writel(-1 & K3_DMARING_RT_DB_ENTRY_MASK, &ring->rt->db); -+ } else if (ring->state.tdown_complete) { -+ dma_addr_t *value = elem; -+ -+ *value = CPPI5_TDCM_MARKER; -+ writel(K3_DMARING_RT_DB_TDOWN_ACK, &ring->rt->db); -+ ring->state.tdown_complete = false; -+ } -+ -+ dev_dbg(ring->parent->dev, "%s: occ%d index%d pos_ptr%px\n", -+ __func__, ring->state.occ, ring->state.rindex, elem_ptr); -+ return 0; -+} -+ - static int k3_ringacc_ring_push_mem(struct k3_ring *ring, void *elem) - { - void *elem_ptr; -@@ -899,6 +1143,11 @@ static int k3_ringacc_ring_push_mem(struct k3_ring *ring, void *elem) - elem_ptr = k3_ringacc_get_elm_addr(ring, ring->state.windex); - - memcpy(elem_ptr, elem, (4 << ring->elm_size)); -+ if (ring->parent->dma_rings) { -+ u64 *addr = elem_ptr; -+ -+ *addr |= ((u64)ring->asel << K3_ADDRESS_ASEL_SHIFT); -+ } - - ring->state.windex = (ring->state.windex + 1) % ring->size; - ring->state.free--; -@@ -975,12 +1224,12 @@ int k3_ringacc_ring_pop(struct k3_ring *ring, void *elem) - return -EINVAL; - - if (!ring->state.occ) -- ring->state.occ = k3_ringacc_ring_get_occ(ring); -+ k3_ringacc_ring_update_occ(ring); - - dev_dbg(ring->parent->dev, "ring_pop: occ%d index%d\n", ring->state.occ, - ring->state.rindex); - -- if (!ring->state.occ) -+ if (!ring->state.occ && !ring->state.tdown_complete) - return -ENODATA; - - if (ring->ops && ring->ops->pop_head) -@@ -998,7 +1247,7 @@ int k3_ringacc_ring_pop_tail(struct k3_ring *ring, void *elem) - return -EINVAL; - - if (!ring->state.occ) -- ring->state.occ = k3_ringacc_ring_get_occ(ring); -+ k3_ringacc_ring_update_occ(ring); - - dev_dbg(ring->parent->dev, "ring_pop_tail: occ%d index%d\n", - ring->state.occ, ring->state.rindex); -@@ -1203,6 +1452,68 @@ static const struct of_device_id k3_ringacc_of_match[] = { - {}, - }; - -+struct k3_ringacc *k3_ringacc_dmarings_init(struct platform_device *pdev, -+ struct k3_ringacc_init_data *data) -+{ -+ struct device *dev = &pdev->dev; -+ struct k3_ringacc *ringacc; -+ void __iomem *base_rt; -+ struct resource *res; -+ int i; -+ -+ ringacc = devm_kzalloc(dev, sizeof(*ringacc), GFP_KERNEL); -+ if (!ringacc) -+ return ERR_PTR(-ENOMEM); -+ -+ ringacc->dev = dev; -+ ringacc->dma_rings = true; -+ ringacc->num_rings = data->num_rings; -+ ringacc->tisci = data->tisci; -+ ringacc->tisci_dev_id = data->tisci_dev_id; -+ -+ mutex_init(&ringacc->req_lock); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ringrt"); -+ base_rt = devm_ioremap_resource(dev, res); -+ if (IS_ERR(base_rt)) -+ return base_rt; -+ -+ ringacc->rings = devm_kzalloc(dev, -+ sizeof(*ringacc->rings) * -+ ringacc->num_rings * 2, -+ GFP_KERNEL); -+ ringacc->rings_inuse = devm_kcalloc(dev, -+ BITS_TO_LONGS(ringacc->num_rings), -+ sizeof(unsigned long), GFP_KERNEL); -+ -+ if (!ringacc->rings || !ringacc->rings_inuse) -+ return ERR_PTR(-ENOMEM); -+ -+ for (i = 0; i < ringacc->num_rings; i++) { -+ struct k3_ring *ring = &ringacc->rings[i]; -+ -+ ring->rt = base_rt + K3_DMARING_RT_REGS_STEP * i; -+ ring->parent = ringacc; -+ ring->ring_id = i; -+ ring->proxy_id = K3_RINGACC_PROXY_NOT_USED; -+ -+ ring = &ringacc->rings[ringacc->num_rings + i]; -+ ring->rt = base_rt + K3_DMARING_RT_REGS_STEP * i + -+ K3_DMARING_RT_REGS_REVERSE_OFS; -+ ring->parent = ringacc; -+ ring->ring_id = i; -+ ring->proxy_id = K3_RINGACC_PROXY_NOT_USED; -+ ring->flags = K3_RING_FLAG_REVERSE; -+ } -+ -+ ringacc->tisci_ring_ops = &ringacc->tisci->ops.rm_ring_ops; -+ -+ dev_info(dev, "Number of rings: %u\n", ringacc->num_rings); -+ -+ return ringacc; -+} -+EXPORT_SYMBOL_GPL(k3_ringacc_dmarings_init); -+ - static int k3_ringacc_probe(struct platform_device *pdev) - { - const struct ringacc_match_data *match_data; -diff --git a/include/linux/soc/ti/k3-ringacc.h b/include/linux/soc/ti/k3-ringacc.h -index 658dc71d2901..39b022b92598 100644 ---- a/include/linux/soc/ti/k3-ringacc.h -+++ b/include/linux/soc/ti/k3-ringacc.h -@@ -70,6 +70,7 @@ struct k3_ring; - * @dma_dev: Master device which is using and accessing to the ring - * memory when the mode is K3_RINGACC_RING_MODE_RING. Memory allocations - * should be done using this device. -+ * @asel: Address Space Select value for physical addresses - */ - struct k3_ring_cfg { - u32 size; -@@ -79,6 +80,7 @@ struct k3_ring_cfg { - u32 flags; - - struct device *dma_dev; -+ u32 asel; - }; - - #define K3_RINGACC_RING_ID_ANY (-1) -@@ -250,4 +252,19 @@ int k3_ringacc_ring_pop_tail(struct k3_ring *ring, void *elem); - - u32 k3_ringacc_get_tisci_dev_id(struct k3_ring *ring); - -+/* DMA ring support */ -+struct ti_sci_handle; -+ -+/** -+ * struct struct k3_ringacc_init_data - Initialization data for DMA rings -+ */ -+struct k3_ringacc_init_data { -+ const struct ti_sci_handle *tisci; -+ u32 tisci_dev_id; -+ u32 num_rings; -+}; -+ -+struct k3_ringacc *k3_ringacc_dmarings_init(struct platform_device *pdev, -+ struct k3_ringacc_init_data *data); -+ - #endif /* __SOC_TI_K3_RINGACC_API_H_ */ diff --git a/recipes-kernel/linux/files/patches-5.10/0132-dmaengine-ti-k3-udma-Initial-support-for-K3-BCDMA.patch b/recipes-kernel/linux/files/patches-5.10/0132-dmaengine-ti-k3-udma-Initial-support-for-K3-BCDMA.patch deleted file mode 100644 index 522fc6767..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0132-dmaengine-ti-k3-udma-Initial-support-for-K3-BCDMA.patch +++ /dev/null @@ -1,2054 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Tue, 8 Dec 2020 11:04:37 +0200 -Subject: [PATCH] dmaengine: ti: k3-udma: Initial support for K3 BCDMA - -commit 017794739702d444ca48115ff0fcdce19edb5559 upstream. - -One of the DMAs introduced with AM64 is the Block Copy DMA (BCDMA). -It serves similar purpose as K3 UDMAP channels in TR mode. - -The rings for the BCDMA is integrated within the DMA itself instead of -using rings from the general purpose ringacc. - -A BCDMA have two different type of channels: -- Block Copy Channels (bchan) -- Split Channels (tchan and rchan) - -tchan and rchan can be used to service PSI-L peripherals, similarly to -K3 UDMA channels. - -bchan can be only used for block copy operation (TR type15) like the -paired K3 UDMA tchan/rchan configured in block copy mode. -bchans can be also used to service peripherals directly if an external -trigger is selected for the channel. - -Most of the driver code can be reused for BCDMA bchan/tchan/rchan support -but new setup and allocation functions are needed to handle the -differences between the DMAs. - -Signed-off-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20201208090440.31792-18-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit '017794739702' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/k3-udma.c | 1384 ++++++++++++++++++++++++++++++++++---- - drivers/dma/ti/k3-udma.h | 12 +- - 2 files changed, 1245 insertions(+), 151 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index b89afa602532..f327d436f8ad 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - - #include "../virt-dma.h" -@@ -55,14 +56,25 @@ struct udma_static_tr { - - struct udma_chan; - -+enum k3_dma_type { -+ DMA_TYPE_UDMA = 0, -+ DMA_TYPE_BCDMA, -+}; -+ - enum udma_mmr { - MMR_GCFG = 0, -+ MMR_BCHANRT, - MMR_RCHANRT, - MMR_TCHANRT, - MMR_LAST, - }; - --static const char * const mmr_names[] = { "gcfg", "rchanrt", "tchanrt" }; -+static const char * const mmr_names[] = { -+ [MMR_GCFG] = "gcfg", -+ [MMR_BCHANRT] = "bchanrt", -+ [MMR_RCHANRT] = "rchanrt", -+ [MMR_TCHANRT] = "tchanrt", -+}; - - struct udma_tchan { - void __iomem *reg_rt; -@@ -72,6 +84,8 @@ struct udma_tchan { - struct k3_ring *tc_ring; /* Transmit Completion ring */ - }; - -+#define udma_bchan udma_tchan -+ - struct udma_rflow { - int id; - struct k3_ring *fd_ring; /* Free Descriptor ring */ -@@ -84,11 +98,25 @@ struct udma_rchan { - int id; - }; - -+struct udma_oes_offsets { -+ /* K3 UDMA Output Event Offset */ -+ u32 udma_rchan; -+ -+ /* BCDMA Output Event Offsets */ -+ u32 bcdma_bchan_data; -+ u32 bcdma_bchan_ring; -+ u32 bcdma_tchan_data; -+ u32 bcdma_tchan_ring; -+ u32 bcdma_rchan_data; -+ u32 bcdma_rchan_ring; -+}; -+ - #define UDMA_FLAG_PDMA_ACC32 BIT(0) - #define UDMA_FLAG_PDMA_BURST BIT(1) - #define UDMA_FLAG_TDTYPE BIT(2) - - struct udma_match_data { -+ enum k3_dma_type type; - u32 psil_base; - bool enable_memcpy_support; - u32 flags; -@@ -96,7 +124,8 @@ struct udma_match_data { - }; - - struct udma_soc_data { -- u32 rchan_oes_offset; -+ struct udma_oes_offsets oes; -+ u32 bcdma_trigger_event_offset; - }; - - struct udma_hwdesc { -@@ -139,16 +168,19 @@ struct udma_dev { - - struct udma_rx_flush rx_flush; - -+ int bchan_cnt; - int tchan_cnt; - int echan_cnt; - int rchan_cnt; - int rflow_cnt; -+ unsigned long *bchan_map; - unsigned long *tchan_map; - unsigned long *rchan_map; - unsigned long *rflow_gp_map; - unsigned long *rflow_gp_map_allocated; - unsigned long *rflow_in_use; - -+ struct udma_bchan *bchans; - struct udma_tchan *tchans; - struct udma_rchan *rchans; - struct udma_rflow *rflows; -@@ -156,6 +188,7 @@ struct udma_dev { - struct udma_chan *channels; - u32 psil_base; - u32 atype; -+ u32 asel; - }; - - struct udma_desc { -@@ -200,6 +233,7 @@ struct udma_chan_config { - bool notdpkt; /* Suppress sending TDC packet */ - int remote_thread_id; - u32 atype; -+ u32 asel; - u32 src_thread; - u32 dst_thread; - enum psil_endpoint_type ep_type; -@@ -207,6 +241,8 @@ struct udma_chan_config { - bool enable_burst; - enum udma_tp_level channel_tpl; /* Channel Throughput Level */ - -+ u32 tr_trigger_type; -+ - enum dma_transfer_direction dir; - }; - -@@ -214,11 +250,13 @@ struct udma_chan { - struct virt_dma_chan vc; - struct dma_slave_config cfg; - struct udma_dev *ud; -+ struct device *dma_dev; - struct udma_desc *desc; - struct udma_desc *terminated_desc; - struct udma_static_tr static_tr; - char *name; - -+ struct udma_bchan *bchan; - struct udma_tchan *tchan; - struct udma_rchan *rchan; - struct udma_rflow *rflow; -@@ -354,6 +392,30 @@ static int navss_psil_unpair(struct udma_dev *ud, u32 src_thread, - src_thread, dst_thread); - } - -+static void k3_configure_chan_coherency(struct dma_chan *chan, u32 asel) -+{ -+ struct device *chan_dev = &chan->dev->device; -+ -+ if (asel == 0) { -+ /* No special handling for the channel */ -+ chan->dev->chan_dma_dev = false; -+ -+ chan_dev->dma_coherent = false; -+ chan_dev->dma_parms = NULL; -+ } else if (asel == 14 || asel == 15) { -+ chan->dev->chan_dma_dev = true; -+ -+ chan_dev->dma_coherent = true; -+ dma_coerce_mask_and_coherent(chan_dev, DMA_BIT_MASK(48)); -+ chan_dev->dma_parms = chan_dev->parent->dma_parms; -+ } else { -+ dev_warn(chan->device->dev, "Invalid ASEL value: %u\n", asel); -+ -+ chan_dev->dma_coherent = false; -+ chan_dev->dma_parms = NULL; -+ } -+} -+ - static void udma_reset_uchan(struct udma_chan *uc) - { - memset(&uc->config, 0, sizeof(uc->config)); -@@ -440,9 +502,7 @@ static void udma_free_hwdesc(struct udma_chan *uc, struct udma_desc *d) - d->hwdesc[i].cppi5_desc_vaddr = NULL; - } - } else if (d->hwdesc[0].cppi5_desc_vaddr) { -- struct udma_dev *ud = uc->ud; -- -- dma_free_coherent(ud->dev, d->hwdesc[0].cppi5_desc_size, -+ dma_free_coherent(uc->dma_dev, d->hwdesc[0].cppi5_desc_size, - d->hwdesc[0].cppi5_desc_vaddr, - d->hwdesc[0].cppi5_desc_paddr); - -@@ -671,8 +731,10 @@ static void udma_reset_counters(struct udma_chan *uc) - val = udma_tchanrt_read(uc, UDMA_CHAN_RT_PCNT_REG); - udma_tchanrt_write(uc, UDMA_CHAN_RT_PCNT_REG, val); - -- val = udma_tchanrt_read(uc, UDMA_CHAN_RT_PEER_BCNT_REG); -- udma_tchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); -+ if (!uc->bchan) { -+ val = udma_tchanrt_read(uc, UDMA_CHAN_RT_PEER_BCNT_REG); -+ udma_tchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); -+ } - } - - if (uc->rchan) { -@@ -1233,6 +1295,42 @@ static struct udma_##res *__udma_reserve_##res(struct udma_dev *ud, \ - UDMA_RESERVE_RESOURCE(tchan); - UDMA_RESERVE_RESOURCE(rchan); - -+static struct udma_bchan *__bcdma_reserve_bchan(struct udma_dev *ud, int id) -+{ -+ if (id >= 0) { -+ if (test_bit(id, ud->bchan_map)) { -+ dev_err(ud->dev, "bchan%d is in use\n", id); -+ return ERR_PTR(-ENOENT); -+ } -+ } else { -+ id = find_next_zero_bit(ud->bchan_map, ud->bchan_cnt, 0); -+ if (id == ud->bchan_cnt) -+ return ERR_PTR(-ENOENT); -+ } -+ -+ set_bit(id, ud->bchan_map); -+ return &ud->bchans[id]; -+} -+ -+static int bcdma_get_bchan(struct udma_chan *uc) -+{ -+ struct udma_dev *ud = uc->ud; -+ -+ if (uc->bchan) { -+ dev_dbg(ud->dev, "chan%d: already have bchan%d allocated\n", -+ uc->id, uc->bchan->id); -+ return 0; -+ } -+ -+ uc->bchan = __bcdma_reserve_bchan(ud, -1); -+ if (IS_ERR(uc->bchan)) -+ return PTR_ERR(uc->bchan); -+ -+ uc->tchan = uc->bchan; -+ -+ return 0; -+} -+ - static int udma_get_tchan(struct udma_chan *uc) - { - struct udma_dev *ud = uc->ud; -@@ -1325,6 +1423,19 @@ static int udma_get_rflow(struct udma_chan *uc, int flow_id) - return PTR_ERR_OR_ZERO(uc->rflow); - } - -+static void bcdma_put_bchan(struct udma_chan *uc) -+{ -+ struct udma_dev *ud = uc->ud; -+ -+ if (uc->bchan) { -+ dev_dbg(ud->dev, "chan%d: put bchan%d\n", uc->id, -+ uc->bchan->id); -+ clear_bit(uc->bchan->id, ud->bchan_map); -+ uc->bchan = NULL; -+ uc->tchan = NULL; -+ } -+} -+ - static void udma_put_rchan(struct udma_chan *uc) - { - struct udma_dev *ud = uc->ud; -@@ -1361,6 +1472,65 @@ static void udma_put_rflow(struct udma_chan *uc) - } - } - -+static void bcdma_free_bchan_resources(struct udma_chan *uc) -+{ -+ if (!uc->bchan) -+ return; -+ -+ k3_ringacc_ring_free(uc->bchan->tc_ring); -+ k3_ringacc_ring_free(uc->bchan->t_ring); -+ uc->bchan->tc_ring = NULL; -+ uc->bchan->t_ring = NULL; -+ k3_configure_chan_coherency(&uc->vc.chan, 0); -+ -+ bcdma_put_bchan(uc); -+} -+ -+static int bcdma_alloc_bchan_resources(struct udma_chan *uc) -+{ -+ struct k3_ring_cfg ring_cfg; -+ struct udma_dev *ud = uc->ud; -+ int ret; -+ -+ ret = bcdma_get_bchan(uc); -+ if (ret) -+ return ret; -+ -+ ret = k3_ringacc_request_rings_pair(ud->ringacc, uc->bchan->id, -1, -+ &uc->bchan->t_ring, -+ &uc->bchan->tc_ring); -+ if (ret) { -+ ret = -EBUSY; -+ goto err_ring; -+ } -+ -+ memset(&ring_cfg, 0, sizeof(ring_cfg)); -+ ring_cfg.size = K3_UDMA_DEFAULT_RING_SIZE; -+ ring_cfg.elm_size = K3_RINGACC_RING_ELSIZE_8; -+ ring_cfg.mode = K3_RINGACC_RING_MODE_RING; -+ -+ k3_configure_chan_coherency(&uc->vc.chan, ud->asel); -+ ring_cfg.asel = ud->asel; -+ ring_cfg.dma_dev = dmaengine_get_dma_device(&uc->vc.chan); -+ -+ ret = k3_ringacc_ring_cfg(uc->bchan->t_ring, &ring_cfg); -+ if (ret) -+ goto err_ringcfg; -+ -+ return 0; -+ -+err_ringcfg: -+ k3_ringacc_ring_free(uc->bchan->tc_ring); -+ uc->bchan->tc_ring = NULL; -+ k3_ringacc_ring_free(uc->bchan->t_ring); -+ uc->bchan->t_ring = NULL; -+ k3_configure_chan_coherency(&uc->vc.chan, 0); -+err_ring: -+ bcdma_put_bchan(uc); -+ -+ return ret; -+} -+ - static void udma_free_tx_resources(struct udma_chan *uc) - { - if (!uc->tchan) -@@ -1378,15 +1548,19 @@ static int udma_alloc_tx_resources(struct udma_chan *uc) - { - struct k3_ring_cfg ring_cfg; - struct udma_dev *ud = uc->ud; -- int ret; -+ struct udma_tchan *tchan; -+ int ring_idx, ret; - - ret = udma_get_tchan(uc); - if (ret) - return ret; - -- ret = k3_ringacc_request_rings_pair(ud->ringacc, uc->tchan->id, -1, -- &uc->tchan->t_ring, -- &uc->tchan->tc_ring); -+ tchan = uc->tchan; -+ ring_idx = ud->bchan_cnt + tchan->id; -+ -+ ret = k3_ringacc_request_rings_pair(ud->ringacc, ring_idx, -1, -+ &tchan->t_ring, -+ &tchan->tc_ring); - if (ret) { - ret = -EBUSY; - goto err_ring; -@@ -1395,10 +1569,18 @@ static int udma_alloc_tx_resources(struct udma_chan *uc) - memset(&ring_cfg, 0, sizeof(ring_cfg)); - ring_cfg.size = K3_UDMA_DEFAULT_RING_SIZE; - ring_cfg.elm_size = K3_RINGACC_RING_ELSIZE_8; -- ring_cfg.mode = K3_RINGACC_RING_MODE_MESSAGE; -+ if (ud->match_data->type == DMA_TYPE_UDMA) { -+ ring_cfg.mode = K3_RINGACC_RING_MODE_MESSAGE; -+ } else { -+ ring_cfg.mode = K3_RINGACC_RING_MODE_RING; -+ -+ k3_configure_chan_coherency(&uc->vc.chan, uc->config.asel); -+ ring_cfg.asel = uc->config.asel; -+ ring_cfg.dma_dev = dmaengine_get_dma_device(&uc->vc.chan); -+ } - -- ret = k3_ringacc_ring_cfg(uc->tchan->t_ring, &ring_cfg); -- ret |= k3_ringacc_ring_cfg(uc->tchan->tc_ring, &ring_cfg); -+ ret = k3_ringacc_ring_cfg(tchan->t_ring, &ring_cfg); -+ ret |= k3_ringacc_ring_cfg(tchan->tc_ring, &ring_cfg); - - if (ret) - goto err_ringcfg; -@@ -1458,7 +1640,8 @@ static int udma_alloc_rx_resources(struct udma_chan *uc) - } - - rflow = uc->rflow; -- fd_ring_id = ud->tchan_cnt + ud->echan_cnt + uc->rchan->id; -+ fd_ring_id = ud->bchan_cnt + ud->tchan_cnt + ud->echan_cnt + -+ uc->rchan->id; - ret = k3_ringacc_request_rings_pair(ud->ringacc, fd_ring_id, -1, - &rflow->fd_ring, &rflow->r_ring); - if (ret) { -@@ -1468,15 +1651,25 @@ static int udma_alloc_rx_resources(struct udma_chan *uc) - - memset(&ring_cfg, 0, sizeof(ring_cfg)); - -- if (uc->config.pkt_mode) -- ring_cfg.size = SG_MAX_SEGMENTS; -- else -+ ring_cfg.elm_size = K3_RINGACC_RING_ELSIZE_8; -+ if (ud->match_data->type == DMA_TYPE_UDMA) { -+ if (uc->config.pkt_mode) -+ ring_cfg.size = SG_MAX_SEGMENTS; -+ else -+ ring_cfg.size = K3_UDMA_DEFAULT_RING_SIZE; -+ -+ ring_cfg.mode = K3_RINGACC_RING_MODE_MESSAGE; -+ } else { - ring_cfg.size = K3_UDMA_DEFAULT_RING_SIZE; -+ ring_cfg.mode = K3_RINGACC_RING_MODE_RING; - -- ring_cfg.elm_size = K3_RINGACC_RING_ELSIZE_8; -- ring_cfg.mode = K3_RINGACC_RING_MODE_MESSAGE; -+ k3_configure_chan_coherency(&uc->vc.chan, uc->config.asel); -+ ring_cfg.asel = uc->config.asel; -+ ring_cfg.dma_dev = dmaengine_get_dma_device(&uc->vc.chan); -+ } - - ret = k3_ringacc_ring_cfg(rflow->fd_ring, &ring_cfg); -+ - ring_cfg.size = K3_UDMA_DEFAULT_RING_SIZE; - ret |= k3_ringacc_ring_cfg(rflow->r_ring, &ring_cfg); - -@@ -1498,7 +1691,18 @@ static int udma_alloc_rx_resources(struct udma_chan *uc) - return ret; - } - --#define TISCI_TCHAN_VALID_PARAMS ( \ -+#define TISCI_BCDMA_BCHAN_VALID_PARAMS ( \ -+ TI_SCI_MSG_VALUE_RM_UDMAP_CH_PAUSE_ON_ERR_VALID | \ -+ TI_SCI_MSG_VALUE_RM_UDMAP_CH_EXTENDED_CH_TYPE_VALID) -+ -+#define TISCI_BCDMA_TCHAN_VALID_PARAMS ( \ -+ TI_SCI_MSG_VALUE_RM_UDMAP_CH_PAUSE_ON_ERR_VALID | \ -+ TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_SUPR_TDPKT_VALID) -+ -+#define TISCI_BCDMA_RCHAN_VALID_PARAMS ( \ -+ TI_SCI_MSG_VALUE_RM_UDMAP_CH_PAUSE_ON_ERR_VALID) -+ -+#define TISCI_UDMA_TCHAN_VALID_PARAMS ( \ - TI_SCI_MSG_VALUE_RM_UDMAP_CH_PAUSE_ON_ERR_VALID | \ - TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_FILT_EINFO_VALID | \ - TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_FILT_PSWORDS_VALID | \ -@@ -1508,7 +1712,7 @@ static int udma_alloc_rx_resources(struct udma_chan *uc) - TI_SCI_MSG_VALUE_RM_UDMAP_CH_CQ_QNUM_VALID | \ - TI_SCI_MSG_VALUE_RM_UDMAP_CH_ATYPE_VALID) - --#define TISCI_RCHAN_VALID_PARAMS ( \ -+#define TISCI_UDMA_RCHAN_VALID_PARAMS ( \ - TI_SCI_MSG_VALUE_RM_UDMAP_CH_PAUSE_ON_ERR_VALID | \ - TI_SCI_MSG_VALUE_RM_UDMAP_CH_FETCH_SIZE_VALID | \ - TI_SCI_MSG_VALUE_RM_UDMAP_CH_CQ_QNUM_VALID | \ -@@ -1533,7 +1737,7 @@ static int udma_tisci_m2m_channel_config(struct udma_chan *uc) - struct ti_sci_msg_rm_udmap_tx_ch_cfg req_tx = { 0 }; - struct ti_sci_msg_rm_udmap_rx_ch_cfg req_rx = { 0 }; - -- req_tx.valid_params = TISCI_TCHAN_VALID_PARAMS; -+ req_tx.valid_params = TISCI_UDMA_TCHAN_VALID_PARAMS; - req_tx.nav_id = tisci_rm->tisci_dev_id; - req_tx.index = tchan->id; - req_tx.tx_chan_type = TI_SCI_RM_UDMAP_CHAN_TYPE_3RDP_BCOPY_PBRR; -@@ -1547,7 +1751,7 @@ static int udma_tisci_m2m_channel_config(struct udma_chan *uc) - return ret; - } - -- req_rx.valid_params = TISCI_RCHAN_VALID_PARAMS; -+ req_rx.valid_params = TISCI_UDMA_RCHAN_VALID_PARAMS; - req_rx.nav_id = tisci_rm->tisci_dev_id; - req_rx.index = rchan->id; - req_rx.rx_fetch_size = sizeof(struct cppi5_desc_hdr_t) >> 2; -@@ -1562,6 +1766,27 @@ static int udma_tisci_m2m_channel_config(struct udma_chan *uc) - return ret; - } - -+static int bcdma_tisci_m2m_channel_config(struct udma_chan *uc) -+{ -+ struct udma_dev *ud = uc->ud; -+ struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; -+ const struct ti_sci_rm_udmap_ops *tisci_ops = tisci_rm->tisci_udmap_ops; -+ struct ti_sci_msg_rm_udmap_tx_ch_cfg req_tx = { 0 }; -+ struct udma_bchan *bchan = uc->bchan; -+ int ret = 0; -+ -+ req_tx.valid_params = TISCI_BCDMA_BCHAN_VALID_PARAMS; -+ req_tx.nav_id = tisci_rm->tisci_dev_id; -+ req_tx.extended_ch_type = TI_SCI_RM_BCDMA_EXTENDED_CH_TYPE_BCHAN; -+ req_tx.index = bchan->id; -+ -+ ret = tisci_ops->tx_ch_cfg(tisci_rm->tisci, &req_tx); -+ if (ret) -+ dev_err(ud->dev, "bchan%d cfg failed %d\n", bchan->id, ret); -+ -+ return ret; -+} -+ - static int udma_tisci_tx_channel_config(struct udma_chan *uc) - { - struct udma_dev *ud = uc->ud; -@@ -1582,7 +1807,7 @@ static int udma_tisci_tx_channel_config(struct udma_chan *uc) - fetch_size = sizeof(struct cppi5_desc_hdr_t); - } - -- req_tx.valid_params = TISCI_TCHAN_VALID_PARAMS; -+ req_tx.valid_params = TISCI_UDMA_TCHAN_VALID_PARAMS; - req_tx.nav_id = tisci_rm->tisci_dev_id; - req_tx.index = tchan->id; - req_tx.tx_chan_type = mode; -@@ -1605,6 +1830,33 @@ static int udma_tisci_tx_channel_config(struct udma_chan *uc) - return ret; - } - -+static int bcdma_tisci_tx_channel_config(struct udma_chan *uc) -+{ -+ struct udma_dev *ud = uc->ud; -+ struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; -+ const struct ti_sci_rm_udmap_ops *tisci_ops = tisci_rm->tisci_udmap_ops; -+ struct udma_tchan *tchan = uc->tchan; -+ struct ti_sci_msg_rm_udmap_tx_ch_cfg req_tx = { 0 }; -+ int ret = 0; -+ -+ req_tx.valid_params = TISCI_BCDMA_TCHAN_VALID_PARAMS; -+ req_tx.nav_id = tisci_rm->tisci_dev_id; -+ req_tx.index = tchan->id; -+ req_tx.tx_supr_tdpkt = uc->config.notdpkt; -+ if (ud->match_data->flags & UDMA_FLAG_TDTYPE) { -+ /* wait for peer to complete the teardown for PDMAs */ -+ req_tx.valid_params |= -+ TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_TDTYPE_VALID; -+ req_tx.tx_tdtype = 1; -+ } -+ -+ ret = tisci_ops->tx_ch_cfg(tisci_rm->tisci, &req_tx); -+ if (ret) -+ dev_err(ud->dev, "tchan%d cfg failed %d\n", tchan->id, ret); -+ -+ return ret; -+} -+ - static int udma_tisci_rx_channel_config(struct udma_chan *uc) - { - struct udma_dev *ud = uc->ud; -@@ -1627,7 +1879,7 @@ static int udma_tisci_rx_channel_config(struct udma_chan *uc) - fetch_size = sizeof(struct cppi5_desc_hdr_t); - } - -- req_rx.valid_params = TISCI_RCHAN_VALID_PARAMS; -+ req_rx.valid_params = TISCI_UDMA_RCHAN_VALID_PARAMS; - req_rx.nav_id = tisci_rm->tisci_dev_id; - req_rx.index = rchan->id; - req_rx.rx_fetch_size = fetch_size >> 2; -@@ -1686,6 +1938,26 @@ static int udma_tisci_rx_channel_config(struct udma_chan *uc) - return 0; - } - -+static int bcdma_tisci_rx_channel_config(struct udma_chan *uc) -+{ -+ struct udma_dev *ud = uc->ud; -+ struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; -+ const struct ti_sci_rm_udmap_ops *tisci_ops = tisci_rm->tisci_udmap_ops; -+ struct udma_rchan *rchan = uc->rchan; -+ struct ti_sci_msg_rm_udmap_rx_ch_cfg req_rx = { 0 }; -+ int ret = 0; -+ -+ req_rx.valid_params = TISCI_BCDMA_RCHAN_VALID_PARAMS; -+ req_rx.nav_id = tisci_rm->tisci_dev_id; -+ req_rx.index = rchan->id; -+ -+ ret = tisci_ops->rx_ch_cfg(tisci_rm->tisci, &req_rx); -+ if (ret) -+ dev_err(ud->dev, "rchan%d cfg failed %d\n", rchan->id, ret); -+ -+ return ret; -+} -+ - static int udma_alloc_chan_resources(struct dma_chan *chan) - { - struct udma_chan *uc = to_udma_chan(chan); -@@ -1695,6 +1967,8 @@ static int udma_alloc_chan_resources(struct dma_chan *chan) - u32 irq_udma_idx; - int ret; - -+ uc->dma_dev = ud->dev; -+ - if (uc->config.pkt_mode || uc->config.dir == DMA_MEM_TO_MEM) { - uc->use_dma_pool = true; - /* in case of MEM_TO_MEM we have maximum of two TRs */ -@@ -1790,7 +2064,7 @@ static int udma_alloc_chan_resources(struct dma_chan *chan) - K3_PSIL_DST_THREAD_ID_OFFSET; - - irq_ring = uc->rflow->r_ring; -- irq_udma_idx = soc_data->rchan_oes_offset + uc->rchan->id; -+ irq_udma_idx = soc_data->oes.udma_rchan + uc->rchan->id; - - ret = udma_tisci_rx_channel_config(uc); - break; -@@ -1890,81 +2164,293 @@ static int udma_alloc_chan_resources(struct dma_chan *chan) - return ret; - } - --static int udma_slave_config(struct dma_chan *chan, -- struct dma_slave_config *cfg) -+static int bcdma_alloc_chan_resources(struct dma_chan *chan) - { - struct udma_chan *uc = to_udma_chan(chan); -+ struct udma_dev *ud = to_udma_dev(chan->device); -+ const struct udma_oes_offsets *oes = &ud->soc_data->oes; -+ u32 irq_udma_idx, irq_ring_idx; -+ int ret; - -- memcpy(&uc->cfg, cfg, sizeof(uc->cfg)); -+ /* Only TR mode is supported */ -+ uc->config.pkt_mode = false; - -- return 0; --} -+ /* -+ * Make sure that the completion is in a known state: -+ * No teardown, the channel is idle -+ */ -+ reinit_completion(&uc->teardown_completed); -+ complete_all(&uc->teardown_completed); -+ uc->state = UDMA_CHAN_IS_IDLE; - --static struct udma_desc *udma_alloc_tr_desc(struct udma_chan *uc, -- size_t tr_size, int tr_count, -- enum dma_transfer_direction dir) --{ -- struct udma_hwdesc *hwdesc; -- struct cppi5_desc_hdr_t *tr_desc; -- struct udma_desc *d; -- u32 reload_count = 0; -- u32 ring_id; -+ switch (uc->config.dir) { -+ case DMA_MEM_TO_MEM: -+ /* Non synchronized - mem to mem type of transfer */ -+ dev_dbg(uc->ud->dev, "%s: chan%d as MEM-to-MEM\n", __func__, -+ uc->id); - -- switch (tr_size) { -- case 16: -- case 32: -- case 64: -- case 128: -- break; -- default: -- dev_err(uc->ud->dev, "Unsupported TR size of %zu\n", tr_size); -- return NULL; -- } -+ ret = bcdma_alloc_bchan_resources(uc); -+ if (ret) -+ return ret; - -- /* We have only one descriptor containing multiple TRs */ -- d = kzalloc(sizeof(*d) + sizeof(d->hwdesc[0]), GFP_NOWAIT); -- if (!d) -- return NULL; -+ irq_ring_idx = uc->bchan->id + oes->bcdma_bchan_ring; -+ irq_udma_idx = uc->bchan->id + oes->bcdma_bchan_data; - -- d->sglen = tr_count; -+ ret = bcdma_tisci_m2m_channel_config(uc); -+ break; -+ case DMA_MEM_TO_DEV: -+ /* Slave transfer synchronized - mem to dev (TX) trasnfer */ -+ dev_dbg(uc->ud->dev, "%s: chan%d as MEM-to-DEV\n", __func__, -+ uc->id); - -- d->hwdesc_count = 1; -- hwdesc = &d->hwdesc[0]; -+ ret = udma_alloc_tx_resources(uc); -+ if (ret) { -+ uc->config.remote_thread_id = -1; -+ return ret; -+ } - -- /* Allocate memory for DMA ring descriptor */ -- if (uc->use_dma_pool) { -- hwdesc->cppi5_desc_size = uc->config.hdesc_size; -- hwdesc->cppi5_desc_vaddr = dma_pool_zalloc(uc->hdesc_pool, -- GFP_NOWAIT, -- &hwdesc->cppi5_desc_paddr); -- } else { -- hwdesc->cppi5_desc_size = cppi5_trdesc_calc_size(tr_size, -- tr_count); -- hwdesc->cppi5_desc_size = ALIGN(hwdesc->cppi5_desc_size, -- uc->ud->desc_align); -- hwdesc->cppi5_desc_vaddr = dma_alloc_coherent(uc->ud->dev, -- hwdesc->cppi5_desc_size, -- &hwdesc->cppi5_desc_paddr, -- GFP_NOWAIT); -- } -+ uc->config.src_thread = ud->psil_base + uc->tchan->id; -+ uc->config.dst_thread = uc->config.remote_thread_id; -+ uc->config.dst_thread |= K3_PSIL_DST_THREAD_ID_OFFSET; - -- if (!hwdesc->cppi5_desc_vaddr) { -- kfree(d); -- return NULL; -- } -+ irq_ring_idx = uc->tchan->id + oes->bcdma_tchan_ring; -+ irq_udma_idx = uc->tchan->id + oes->bcdma_tchan_data; - -- /* Start of the TR req records */ -- hwdesc->tr_req_base = hwdesc->cppi5_desc_vaddr + tr_size; -- /* Start address of the TR response array */ -- hwdesc->tr_resp_base = hwdesc->tr_req_base + tr_size * tr_count; -+ ret = bcdma_tisci_tx_channel_config(uc); -+ break; -+ case DMA_DEV_TO_MEM: -+ /* Slave transfer synchronized - dev to mem (RX) trasnfer */ -+ dev_dbg(uc->ud->dev, "%s: chan%d as DEV-to-MEM\n", __func__, -+ uc->id); - -- tr_desc = hwdesc->cppi5_desc_vaddr; -+ ret = udma_alloc_rx_resources(uc); -+ if (ret) { -+ uc->config.remote_thread_id = -1; -+ return ret; -+ } - -- if (uc->cyclic) -- reload_count = CPPI5_INFO0_TRDESC_RLDCNT_INFINITE; -+ uc->config.src_thread = uc->config.remote_thread_id; -+ uc->config.dst_thread = (ud->psil_base + uc->rchan->id) | -+ K3_PSIL_DST_THREAD_ID_OFFSET; - -- if (dir == DMA_DEV_TO_MEM) -- ring_id = k3_ringacc_get_ring_id(uc->rflow->r_ring); -+ irq_ring_idx = uc->rchan->id + oes->bcdma_rchan_ring; -+ irq_udma_idx = uc->rchan->id + oes->bcdma_rchan_data; -+ -+ ret = bcdma_tisci_rx_channel_config(uc); -+ break; -+ default: -+ /* Can not happen */ -+ dev_err(uc->ud->dev, "%s: chan%d invalid direction (%u)\n", -+ __func__, uc->id, uc->config.dir); -+ return -EINVAL; -+ } -+ -+ /* check if the channel configuration was successful */ -+ if (ret) -+ goto err_res_free; -+ -+ if (udma_is_chan_running(uc)) { -+ dev_warn(ud->dev, "chan%d: is running!\n", uc->id); -+ udma_reset_chan(uc, false); -+ if (udma_is_chan_running(uc)) { -+ dev_err(ud->dev, "chan%d: won't stop!\n", uc->id); -+ ret = -EBUSY; -+ goto err_res_free; -+ } -+ } -+ -+ uc->dma_dev = dmaengine_get_dma_device(chan); -+ if (uc->config.dir == DMA_MEM_TO_MEM && !uc->config.tr_trigger_type) { -+ uc->config.hdesc_size = cppi5_trdesc_calc_size( -+ sizeof(struct cppi5_tr_type15_t), 2); -+ -+ uc->hdesc_pool = dma_pool_create(uc->name, ud->ddev.dev, -+ uc->config.hdesc_size, -+ ud->desc_align, -+ 0); -+ if (!uc->hdesc_pool) { -+ dev_err(ud->ddev.dev, -+ "Descriptor pool allocation failed\n"); -+ uc->use_dma_pool = false; -+ return -ENOMEM; -+ } -+ -+ uc->use_dma_pool = true; -+ } else if (uc->config.dir != DMA_MEM_TO_MEM) { -+ /* PSI-L pairing */ -+ ret = navss_psil_pair(ud, uc->config.src_thread, -+ uc->config.dst_thread); -+ if (ret) { -+ dev_err(ud->dev, -+ "PSI-L pairing failed: 0x%04x -> 0x%04x\n", -+ uc->config.src_thread, uc->config.dst_thread); -+ goto err_res_free; -+ } -+ -+ uc->psil_paired = true; -+ } -+ -+ uc->irq_num_ring = ti_sci_inta_msi_get_virq(ud->dev, irq_ring_idx); -+ if (uc->irq_num_ring <= 0) { -+ dev_err(ud->dev, "Failed to get ring irq (index: %u)\n", -+ irq_ring_idx); -+ ret = -EINVAL; -+ goto err_psi_free; -+ } -+ -+ ret = request_irq(uc->irq_num_ring, udma_ring_irq_handler, -+ IRQF_TRIGGER_HIGH, uc->name, uc); -+ if (ret) { -+ dev_err(ud->dev, "chan%d: ring irq request failed\n", uc->id); -+ goto err_irq_free; -+ } -+ -+ /* Event from BCDMA (TR events) only needed for slave channels */ -+ if (is_slave_direction(uc->config.dir)) { -+ uc->irq_num_udma = ti_sci_inta_msi_get_virq(ud->dev, -+ irq_udma_idx); -+ if (uc->irq_num_udma <= 0) { -+ dev_err(ud->dev, "Failed to get bcdma irq (index: %u)\n", -+ irq_udma_idx); -+ free_irq(uc->irq_num_ring, uc); -+ ret = -EINVAL; -+ goto err_irq_free; -+ } -+ -+ ret = request_irq(uc->irq_num_udma, udma_udma_irq_handler, 0, -+ uc->name, uc); -+ if (ret) { -+ dev_err(ud->dev, "chan%d: BCDMA irq request failed\n", -+ uc->id); -+ free_irq(uc->irq_num_ring, uc); -+ goto err_irq_free; -+ } -+ } else { -+ uc->irq_num_udma = 0; -+ } -+ -+ udma_reset_rings(uc); -+ -+ INIT_DELAYED_WORK_ONSTACK(&uc->tx_drain.work, -+ udma_check_tx_completion); -+ return 0; -+ -+err_irq_free: -+ uc->irq_num_ring = 0; -+ uc->irq_num_udma = 0; -+err_psi_free: -+ if (uc->psil_paired) -+ navss_psil_unpair(ud, uc->config.src_thread, -+ uc->config.dst_thread); -+ uc->psil_paired = false; -+err_res_free: -+ bcdma_free_bchan_resources(uc); -+ udma_free_tx_resources(uc); -+ udma_free_rx_resources(uc); -+ -+ udma_reset_uchan(uc); -+ -+ if (uc->use_dma_pool) { -+ dma_pool_destroy(uc->hdesc_pool); -+ uc->use_dma_pool = false; -+ } -+ -+ return ret; -+} -+ -+static int bcdma_router_config(struct dma_chan *chan) -+{ -+ struct k3_event_route_data *router_data = chan->route_data; -+ struct udma_chan *uc = to_udma_chan(chan); -+ u32 trigger_event; -+ -+ if (!uc->bchan) -+ return -EINVAL; -+ -+ if (uc->config.tr_trigger_type != 1 && uc->config.tr_trigger_type != 2) -+ return -EINVAL; -+ -+ trigger_event = uc->ud->soc_data->bcdma_trigger_event_offset; -+ trigger_event += (uc->bchan->id * 2) + uc->config.tr_trigger_type - 1; -+ -+ return router_data->set_event(router_data->priv, trigger_event); -+} -+ -+static int udma_slave_config(struct dma_chan *chan, -+ struct dma_slave_config *cfg) -+{ -+ struct udma_chan *uc = to_udma_chan(chan); -+ -+ memcpy(&uc->cfg, cfg, sizeof(uc->cfg)); -+ -+ return 0; -+} -+ -+static struct udma_desc *udma_alloc_tr_desc(struct udma_chan *uc, -+ size_t tr_size, int tr_count, -+ enum dma_transfer_direction dir) -+{ -+ struct udma_hwdesc *hwdesc; -+ struct cppi5_desc_hdr_t *tr_desc; -+ struct udma_desc *d; -+ u32 reload_count = 0; -+ u32 ring_id; -+ -+ switch (tr_size) { -+ case 16: -+ case 32: -+ case 64: -+ case 128: -+ break; -+ default: -+ dev_err(uc->ud->dev, "Unsupported TR size of %zu\n", tr_size); -+ return NULL; -+ } -+ -+ /* We have only one descriptor containing multiple TRs */ -+ d = kzalloc(sizeof(*d) + sizeof(d->hwdesc[0]), GFP_NOWAIT); -+ if (!d) -+ return NULL; -+ -+ d->sglen = tr_count; -+ -+ d->hwdesc_count = 1; -+ hwdesc = &d->hwdesc[0]; -+ -+ /* Allocate memory for DMA ring descriptor */ -+ if (uc->use_dma_pool) { -+ hwdesc->cppi5_desc_size = uc->config.hdesc_size; -+ hwdesc->cppi5_desc_vaddr = dma_pool_zalloc(uc->hdesc_pool, -+ GFP_NOWAIT, -+ &hwdesc->cppi5_desc_paddr); -+ } else { -+ hwdesc->cppi5_desc_size = cppi5_trdesc_calc_size(tr_size, -+ tr_count); -+ hwdesc->cppi5_desc_size = ALIGN(hwdesc->cppi5_desc_size, -+ uc->ud->desc_align); -+ hwdesc->cppi5_desc_vaddr = dma_alloc_coherent(uc->ud->dev, -+ hwdesc->cppi5_desc_size, -+ &hwdesc->cppi5_desc_paddr, -+ GFP_NOWAIT); -+ } -+ -+ if (!hwdesc->cppi5_desc_vaddr) { -+ kfree(d); -+ return NULL; -+ } -+ -+ /* Start of the TR req records */ -+ hwdesc->tr_req_base = hwdesc->cppi5_desc_vaddr + tr_size; -+ /* Start address of the TR response array */ -+ hwdesc->tr_resp_base = hwdesc->tr_req_base + tr_size * tr_count; -+ -+ tr_desc = hwdesc->cppi5_desc_vaddr; -+ -+ if (uc->cyclic) -+ reload_count = CPPI5_INFO0_TRDESC_RLDCNT_INFINITE; -+ -+ if (dir == DMA_DEV_TO_MEM) -+ ring_id = k3_ringacc_get_ring_id(uc->rflow->r_ring); - else - ring_id = k3_ringacc_get_ring_id(uc->tchan->tc_ring); - -@@ -2034,6 +2520,7 @@ udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl, - size_t tr_size; - int num_tr = 0; - int tr_idx = 0; -+ u64 asel; - - /* estimate the number of TRs we will need */ - for_each_sg(sgl, sgent, sglen, i) { -@@ -2051,6 +2538,11 @@ udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl, - - d->sglen = sglen; - -+ if (uc->ud->match_data->type == DMA_TYPE_UDMA) -+ asel = 0; -+ else -+ asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT; -+ - tr_req = d->hwdesc[0].tr_req_base; - for_each_sg(sgl, sgent, sglen, i) { - dma_addr_t sg_addr = sg_dma_address(sgent); -@@ -2069,6 +2561,7 @@ udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl, - false, CPPI5_TR_EVENT_SIZE_COMPLETION, 0); - cppi5_tr_csf_set(&tr_req[tr_idx].flags, CPPI5_TR_CSF_SUPR_EVT); - -+ sg_addr |= asel; - tr_req[tr_idx].addr = sg_addr; - tr_req[tr_idx].icnt0 = tr0_cnt0; - tr_req[tr_idx].icnt1 = tr0_cnt1; -@@ -2098,6 +2591,205 @@ udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl, - return d; - } - -+static struct udma_desc * -+udma_prep_slave_sg_triggered_tr(struct udma_chan *uc, struct scatterlist *sgl, -+ unsigned int sglen, -+ enum dma_transfer_direction dir, -+ unsigned long tx_flags, void *context) -+{ -+ struct scatterlist *sgent; -+ struct cppi5_tr_type15_t *tr_req = NULL; -+ enum dma_slave_buswidth dev_width; -+ u16 tr_cnt0, tr_cnt1; -+ dma_addr_t dev_addr; -+ struct udma_desc *d; -+ unsigned int i; -+ size_t tr_size, sg_len; -+ int num_tr = 0; -+ int tr_idx = 0; -+ u32 burst, trigger_size, port_window; -+ u64 asel; -+ -+ if (dir == DMA_DEV_TO_MEM) { -+ dev_addr = uc->cfg.src_addr; -+ dev_width = uc->cfg.src_addr_width; -+ burst = uc->cfg.src_maxburst; -+ port_window = uc->cfg.src_port_window_size; -+ } else if (dir == DMA_MEM_TO_DEV) { -+ dev_addr = uc->cfg.dst_addr; -+ dev_width = uc->cfg.dst_addr_width; -+ burst = uc->cfg.dst_maxburst; -+ port_window = uc->cfg.dst_port_window_size; -+ } else { -+ dev_err(uc->ud->dev, "%s: bad direction?\n", __func__); -+ return NULL; -+ } -+ -+ if (!burst) -+ burst = 1; -+ -+ if (port_window) { -+ if (port_window != burst) { -+ dev_err(uc->ud->dev, -+ "The burst must be equal to port_window\n"); -+ return NULL; -+ } -+ -+ tr_cnt0 = dev_width * port_window; -+ tr_cnt1 = 1; -+ } else { -+ tr_cnt0 = dev_width; -+ tr_cnt1 = burst; -+ } -+ trigger_size = tr_cnt0 * tr_cnt1; -+ -+ /* estimate the number of TRs we will need */ -+ for_each_sg(sgl, sgent, sglen, i) { -+ sg_len = sg_dma_len(sgent); -+ -+ if (sg_len % trigger_size) { -+ dev_err(uc->ud->dev, -+ "Not aligned SG entry (%zu for %u)\n", sg_len, -+ trigger_size); -+ return NULL; -+ } -+ -+ if (sg_len / trigger_size < SZ_64K) -+ num_tr++; -+ else -+ num_tr += 2; -+ } -+ -+ /* Now allocate and setup the descriptor. */ -+ tr_size = sizeof(struct cppi5_tr_type15_t); -+ d = udma_alloc_tr_desc(uc, tr_size, num_tr, dir); -+ if (!d) -+ return NULL; -+ -+ d->sglen = sglen; -+ -+ if (uc->ud->match_data->type == DMA_TYPE_UDMA) { -+ asel = 0; -+ } else { -+ asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT; -+ dev_addr |= asel; -+ } -+ -+ tr_req = d->hwdesc[0].tr_req_base; -+ for_each_sg(sgl, sgent, sglen, i) { -+ u16 tr0_cnt2, tr0_cnt3, tr1_cnt2; -+ dma_addr_t sg_addr = sg_dma_address(sgent); -+ -+ sg_len = sg_dma_len(sgent); -+ num_tr = udma_get_tr_counters(sg_len / trigger_size, 0, -+ &tr0_cnt2, &tr0_cnt3, &tr1_cnt2); -+ if (num_tr < 0) { -+ dev_err(uc->ud->dev, "size %zu is not supported\n", -+ sg_len); -+ udma_free_hwdesc(uc, d); -+ kfree(d); -+ return NULL; -+ } -+ -+ cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE15, false, -+ true, CPPI5_TR_EVENT_SIZE_COMPLETION, 0); -+ cppi5_tr_csf_set(&tr_req[tr_idx].flags, CPPI5_TR_CSF_SUPR_EVT); -+ cppi5_tr_set_trigger(&tr_req[tr_idx].flags, -+ uc->config.tr_trigger_type, -+ CPPI5_TR_TRIGGER_TYPE_ICNT2_DEC, 0, 0); -+ -+ sg_addr |= asel; -+ if (dir == DMA_DEV_TO_MEM) { -+ tr_req[tr_idx].addr = dev_addr; -+ tr_req[tr_idx].icnt0 = tr_cnt0; -+ tr_req[tr_idx].icnt1 = tr_cnt1; -+ tr_req[tr_idx].icnt2 = tr0_cnt2; -+ tr_req[tr_idx].icnt3 = tr0_cnt3; -+ tr_req[tr_idx].dim1 = (-1) * tr_cnt0; -+ -+ tr_req[tr_idx].daddr = sg_addr; -+ tr_req[tr_idx].dicnt0 = tr_cnt0; -+ tr_req[tr_idx].dicnt1 = tr_cnt1; -+ tr_req[tr_idx].dicnt2 = tr0_cnt2; -+ tr_req[tr_idx].dicnt3 = tr0_cnt3; -+ tr_req[tr_idx].ddim1 = tr_cnt0; -+ tr_req[tr_idx].ddim2 = trigger_size; -+ tr_req[tr_idx].ddim3 = trigger_size * tr0_cnt2; -+ } else { -+ tr_req[tr_idx].addr = sg_addr; -+ tr_req[tr_idx].icnt0 = tr_cnt0; -+ tr_req[tr_idx].icnt1 = tr_cnt1; -+ tr_req[tr_idx].icnt2 = tr0_cnt2; -+ tr_req[tr_idx].icnt3 = tr0_cnt3; -+ tr_req[tr_idx].dim1 = tr_cnt0; -+ tr_req[tr_idx].dim2 = trigger_size; -+ tr_req[tr_idx].dim3 = trigger_size * tr0_cnt2; -+ -+ tr_req[tr_idx].daddr = dev_addr; -+ tr_req[tr_idx].dicnt0 = tr_cnt0; -+ tr_req[tr_idx].dicnt1 = tr_cnt1; -+ tr_req[tr_idx].dicnt2 = tr0_cnt2; -+ tr_req[tr_idx].dicnt3 = tr0_cnt3; -+ tr_req[tr_idx].ddim1 = (-1) * tr_cnt0; -+ } -+ -+ tr_idx++; -+ -+ if (num_tr == 2) { -+ cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE15, -+ false, true, -+ CPPI5_TR_EVENT_SIZE_COMPLETION, 0); -+ cppi5_tr_csf_set(&tr_req[tr_idx].flags, -+ CPPI5_TR_CSF_SUPR_EVT); -+ cppi5_tr_set_trigger(&tr_req[tr_idx].flags, -+ uc->config.tr_trigger_type, -+ CPPI5_TR_TRIGGER_TYPE_ICNT2_DEC, -+ 0, 0); -+ -+ sg_addr += trigger_size * tr0_cnt2 * tr0_cnt3; -+ if (dir == DMA_DEV_TO_MEM) { -+ tr_req[tr_idx].addr = dev_addr; -+ tr_req[tr_idx].icnt0 = tr_cnt0; -+ tr_req[tr_idx].icnt1 = tr_cnt1; -+ tr_req[tr_idx].icnt2 = tr1_cnt2; -+ tr_req[tr_idx].icnt3 = 1; -+ tr_req[tr_idx].dim1 = (-1) * tr_cnt0; -+ -+ tr_req[tr_idx].daddr = sg_addr; -+ tr_req[tr_idx].dicnt0 = tr_cnt0; -+ tr_req[tr_idx].dicnt1 = tr_cnt1; -+ tr_req[tr_idx].dicnt2 = tr1_cnt2; -+ tr_req[tr_idx].dicnt3 = 1; -+ tr_req[tr_idx].ddim1 = tr_cnt0; -+ tr_req[tr_idx].ddim2 = trigger_size; -+ } else { -+ tr_req[tr_idx].addr = sg_addr; -+ tr_req[tr_idx].icnt0 = tr_cnt0; -+ tr_req[tr_idx].icnt1 = tr_cnt1; -+ tr_req[tr_idx].icnt2 = tr1_cnt2; -+ tr_req[tr_idx].icnt3 = 1; -+ tr_req[tr_idx].dim1 = tr_cnt0; -+ tr_req[tr_idx].dim2 = trigger_size; -+ -+ tr_req[tr_idx].daddr = dev_addr; -+ tr_req[tr_idx].dicnt0 = tr_cnt0; -+ tr_req[tr_idx].dicnt1 = tr_cnt1; -+ tr_req[tr_idx].dicnt2 = tr1_cnt2; -+ tr_req[tr_idx].dicnt3 = 1; -+ tr_req[tr_idx].ddim1 = (-1) * tr_cnt0; -+ } -+ tr_idx++; -+ } -+ -+ d->residue += sg_len; -+ } -+ -+ cppi5_tr_csf_set(&tr_req[tr_idx - 1].flags, -+ CPPI5_TR_CSF_SUPR_EVT | CPPI5_TR_CSF_EOP); -+ -+ return d; -+} -+ - static int udma_configure_statictr(struct udma_chan *uc, struct udma_desc *d, - enum dma_slave_buswidth dev_width, - u16 elcnt) -@@ -2339,7 +3031,8 @@ udma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, - struct udma_desc *d; - u32 burst; - -- if (dir != uc->config.dir) { -+ if (dir != uc->config.dir && -+ (uc->config.dir == DMA_MEM_TO_MEM && !uc->config.tr_trigger_type)) { - dev_err(chan->device->dev, - "%s: chan%d is for %s, not supporting %s\n", - __func__, uc->id, -@@ -2365,9 +3058,12 @@ udma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, - if (uc->config.pkt_mode) - d = udma_prep_slave_sg_pkt(uc, sgl, sglen, dir, tx_flags, - context); -- else -+ else if (is_slave_direction(uc->config.dir)) - d = udma_prep_slave_sg_tr(uc, sgl, sglen, dir, tx_flags, - context); -+ else -+ d = udma_prep_slave_sg_triggered_tr(uc, sgl, sglen, dir, -+ tx_flags, context); - - if (!d) - return NULL; -@@ -2421,7 +3117,12 @@ udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr, - return NULL; - - tr_req = d->hwdesc[0].tr_req_base; -- period_addr = buf_addr; -+ if (uc->ud->match_data->type == DMA_TYPE_UDMA) -+ period_addr = buf_addr; -+ else -+ period_addr = buf_addr | -+ ((u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT); -+ - for (i = 0; i < periods; i++) { - int tr_idx = i * num_tr; - -@@ -2627,6 +3328,11 @@ udma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, - d->tr_idx = 0; - d->residue = len; - -+ if (uc->ud->match_data->type != DMA_TYPE_UDMA) { -+ src |= (u64)uc->ud->asel << K3_ADDRESS_ASEL_SHIFT; -+ dest |= (u64)uc->ud->asel << K3_ADDRESS_ASEL_SHIFT; -+ } -+ - tr_req = d->hwdesc[0].tr_req_base; - - cppi5_tr_init(&tr_req[0].flags, CPPI5_TR_TYPE15, false, true, -@@ -2984,6 +3690,7 @@ static void udma_free_chan_resources(struct dma_chan *chan) - vchan_free_chan_resources(&uc->vc); - tasklet_kill(&uc->vc.task); - -+ bcdma_free_bchan_resources(uc); - udma_free_tx_resources(uc); - udma_free_rx_resources(uc); - udma_reset_uchan(uc); -@@ -2995,10 +3702,13 @@ static void udma_free_chan_resources(struct dma_chan *chan) - } - - static struct platform_driver udma_driver; -+static struct platform_driver bcdma_driver; - - struct udma_filter_param { - int remote_thread_id; - u32 atype; -+ u32 asel; -+ u32 tr_trigger_type; - }; - - static bool udma_dma_filter_fn(struct dma_chan *chan, void *param) -@@ -3009,7 +3719,8 @@ static bool udma_dma_filter_fn(struct dma_chan *chan, void *param) - struct udma_chan *uc; - struct udma_dev *ud; - -- if (chan->device->dev->driver != &udma_driver.driver) -+ if (chan->device->dev->driver != &udma_driver.driver && -+ chan->device->dev->driver != &bcdma_driver.driver) - return false; - - uc = to_udma_chan(chan); -@@ -3023,13 +3734,25 @@ static bool udma_dma_filter_fn(struct dma_chan *chan, void *param) - return false; - } - -+ if (filter_param->asel > 15) { -+ dev_err(ud->dev, "Invalid channel asel: %u\n", -+ filter_param->asel); -+ return false; -+ } -+ - ucc->remote_thread_id = filter_param->remote_thread_id; - ucc->atype = filter_param->atype; -+ ucc->asel = filter_param->asel; -+ ucc->tr_trigger_type = filter_param->tr_trigger_type; - -- if (ucc->remote_thread_id & K3_PSIL_DST_THREAD_ID_OFFSET) -+ if (ucc->tr_trigger_type) { -+ ucc->dir = DMA_MEM_TO_MEM; -+ goto triggered_bchan; -+ } else if (ucc->remote_thread_id & K3_PSIL_DST_THREAD_ID_OFFSET) { - ucc->dir = DMA_MEM_TO_DEV; -- else -+ } else { - ucc->dir = DMA_DEV_TO_MEM; -+ } - - ep_config = psil_get_ep_config(ucc->remote_thread_id); - if (IS_ERR(ep_config)) { -@@ -3038,6 +3761,19 @@ static bool udma_dma_filter_fn(struct dma_chan *chan, void *param) - ucc->dir = DMA_MEM_TO_MEM; - ucc->remote_thread_id = -1; - ucc->atype = 0; -+ ucc->asel = 0; -+ return false; -+ } -+ -+ if (ud->match_data->type == DMA_TYPE_BCDMA && -+ ep_config->pkt_mode) { -+ dev_err(ud->dev, -+ "Only TR mode is supported (psi-l thread 0x%04x)\n", -+ ucc->remote_thread_id); -+ ucc->dir = DMA_MEM_TO_MEM; -+ ucc->remote_thread_id = -1; -+ ucc->atype = 0; -+ ucc->asel = 0; - return false; - } - -@@ -3069,6 +3805,13 @@ static bool udma_dma_filter_fn(struct dma_chan *chan, void *param) - ucc->remote_thread_id, dmaengine_get_direction_text(ucc->dir)); - - return true; -+ -+triggered_bchan: -+ dev_dbg(ud->dev, "chan%d: triggered channel (type: %u)\n", uc->id, -+ ucc->tr_trigger_type); -+ -+ return true; -+ - } - - static struct dma_chan *udma_of_xlate(struct of_phandle_args *dma_spec, -@@ -3079,14 +3822,33 @@ static struct dma_chan *udma_of_xlate(struct of_phandle_args *dma_spec, - struct udma_filter_param filter_param; - struct dma_chan *chan; - -- if (dma_spec->args_count != 1 && dma_spec->args_count != 2) -- return NULL; -+ if (ud->match_data->type == DMA_TYPE_BCDMA) { -+ if (dma_spec->args_count != 3) -+ return NULL; - -- filter_param.remote_thread_id = dma_spec->args[0]; -- if (dma_spec->args_count == 2) -- filter_param.atype = dma_spec->args[1]; -- else -+ filter_param.tr_trigger_type = dma_spec->args[0]; -+ filter_param.remote_thread_id = dma_spec->args[1]; -+ filter_param.asel = dma_spec->args[2]; - filter_param.atype = 0; -+ } else { -+ if (dma_spec->args_count != 1 && dma_spec->args_count != 2) -+ return NULL; -+ -+ filter_param.remote_thread_id = dma_spec->args[0]; -+ filter_param.tr_trigger_type = 0; -+ if (dma_spec->args_count == 2) { -+ if (ud->match_data->type == DMA_TYPE_UDMA) { -+ filter_param.atype = dma_spec->args[1]; -+ filter_param.asel = 0; -+ } else { -+ filter_param.atype = 0; -+ filter_param.asel = dma_spec->args[1]; -+ } -+ } else { -+ filter_param.atype = 0; -+ filter_param.asel = 0; -+ } -+ } - - chan = __dma_request_channel(&mask, udma_dma_filter_fn, &filter_param, - ofdma->of_node); -@@ -3099,18 +3861,21 @@ static struct dma_chan *udma_of_xlate(struct of_phandle_args *dma_spec, - } - - static struct udma_match_data am654_main_data = { -+ .type = DMA_TYPE_UDMA, - .psil_base = 0x1000, - .enable_memcpy_support = true, - .statictr_z_mask = GENMASK(11, 0), - }; - - static struct udma_match_data am654_mcu_data = { -+ .type = DMA_TYPE_UDMA, - .psil_base = 0x6000, - .enable_memcpy_support = false, - .statictr_z_mask = GENMASK(11, 0), - }; - - static struct udma_match_data j721e_main_data = { -+ .type = DMA_TYPE_UDMA, - .psil_base = 0x1000, - .enable_memcpy_support = true, - .flags = UDMA_FLAG_PDMA_ACC32 | UDMA_FLAG_PDMA_BURST | UDMA_FLAG_TDTYPE, -@@ -3118,12 +3883,21 @@ static struct udma_match_data j721e_main_data = { - }; - - static struct udma_match_data j721e_mcu_data = { -+ .type = DMA_TYPE_UDMA, - .psil_base = 0x6000, - .enable_memcpy_support = false, /* MEM_TO_MEM is slow via MCU UDMA */ - .flags = UDMA_FLAG_PDMA_ACC32 | UDMA_FLAG_PDMA_BURST | UDMA_FLAG_TDTYPE, - .statictr_z_mask = GENMASK(23, 0), - }; - -+static struct udma_match_data am64_bcdma_data = { -+ .type = DMA_TYPE_BCDMA, -+ .psil_base = 0x2000, /* for tchan and rchan, not applicable to bchan */ -+ .enable_memcpy_support = true, /* Supported via bchan */ -+ .flags = UDMA_FLAG_PDMA_ACC32 | UDMA_FLAG_PDMA_BURST | UDMA_FLAG_TDTYPE, -+ .statictr_z_mask = GENMASK(23, 0), -+}; -+ - static const struct of_device_id udma_of_match[] = { - { - .compatible = "ti,am654-navss-main-udmap", -@@ -3142,30 +3916,88 @@ static const struct of_device_id udma_of_match[] = { - { /* Sentinel */ }, - }; - -+static const struct of_device_id bcdma_of_match[] = { -+ { -+ .compatible = "ti,am64-dmss-bcdma", -+ .data = &am64_bcdma_data, -+ }, -+ { /* Sentinel */ }, -+}; -+ - static struct udma_soc_data am654_soc_data = { -- .rchan_oes_offset = 0x200, -+ .oes = { -+ .udma_rchan = 0x200, -+ }, - }; - - static struct udma_soc_data j721e_soc_data = { -- .rchan_oes_offset = 0x400, -+ .oes = { -+ .udma_rchan = 0x400, -+ }, - }; - - static struct udma_soc_data j7200_soc_data = { -- .rchan_oes_offset = 0x80, -+ .oes = { -+ .udma_rchan = 0x80, -+ }, -+}; -+ -+static struct udma_soc_data am64_soc_data = { -+ .oes = { -+ .bcdma_bchan_data = 0x2200, -+ .bcdma_bchan_ring = 0x2400, -+ .bcdma_tchan_data = 0x2800, -+ .bcdma_tchan_ring = 0x2a00, -+ .bcdma_rchan_data = 0x2e00, -+ .bcdma_rchan_ring = 0x3000, -+ }, -+ .bcdma_trigger_event_offset = 0xc400, - }; - - static const struct soc_device_attribute k3_soc_devices[] = { - { .family = "AM65X", .data = &am654_soc_data }, - { .family = "J721E", .data = &j721e_soc_data }, - { .family = "J7200", .data = &j7200_soc_data }, -+ { .family = "AM64X", .data = &am64_soc_data }, - { /* sentinel */ } - }; - - static int udma_get_mmrs(struct platform_device *pdev, struct udma_dev *ud) - { -+ u32 cap2, cap3; - int i; - -- for (i = 0; i < MMR_LAST; i++) { -+ ud->mmrs[MMR_GCFG] = devm_platform_ioremap_resource_byname(pdev, mmr_names[MMR_GCFG]); -+ if (IS_ERR(ud->mmrs[MMR_GCFG])) -+ return PTR_ERR(ud->mmrs[MMR_GCFG]); -+ -+ cap2 = udma_read(ud->mmrs[MMR_GCFG], 0x28); -+ cap3 = udma_read(ud->mmrs[MMR_GCFG], 0x2c); -+ -+ switch (ud->match_data->type) { -+ case DMA_TYPE_UDMA: -+ ud->rflow_cnt = UDMA_CAP3_RFLOW_CNT(cap3); -+ ud->tchan_cnt = UDMA_CAP2_TCHAN_CNT(cap2); -+ ud->echan_cnt = UDMA_CAP2_ECHAN_CNT(cap2); -+ ud->rchan_cnt = UDMA_CAP2_RCHAN_CNT(cap2); -+ break; -+ case DMA_TYPE_BCDMA: -+ ud->bchan_cnt = BCDMA_CAP2_BCHAN_CNT(cap2); -+ ud->tchan_cnt = BCDMA_CAP2_TCHAN_CNT(cap2); -+ ud->rchan_cnt = BCDMA_CAP2_RCHAN_CNT(cap2); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ for (i = 1; i < MMR_LAST; i++) { -+ if (i == MMR_BCHANRT && ud->bchan_cnt == 0) -+ continue; -+ if (i == MMR_TCHANRT && ud->tchan_cnt == 0) -+ continue; -+ if (i == MMR_RCHANRT && ud->rchan_cnt == 0) -+ continue; -+ - ud->mmrs[i] = devm_platform_ioremap_resource_byname(pdev, mmr_names[i]); - if (IS_ERR(ud->mmrs[i])) - return PTR_ERR(ud->mmrs[i]); -@@ -3185,27 +4017,23 @@ static void udma_mark_resource_ranges(struct udma_dev *ud, unsigned long *map, - rm_desc->num_sec); - } - -+static const char * const range_names[] = { -+ [RM_RANGE_BCHAN] = "ti,sci-rm-range-bchan", -+ [RM_RANGE_TCHAN] = "ti,sci-rm-range-tchan", -+ [RM_RANGE_RCHAN] = "ti,sci-rm-range-rchan", -+ [RM_RANGE_RFLOW] = "ti,sci-rm-range-rflow" -+}; -+ - static int udma_setup_resources(struct udma_dev *ud) - { -+ int ret, i, j; - struct device *dev = ud->dev; -- int ch_count, ret, i, j; -- u32 cap2, cap3; - struct ti_sci_resource *rm_res, irq_res; - struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; -- static const char * const range_names[] = { "ti,sci-rm-range-tchan", -- "ti,sci-rm-range-rchan", -- "ti,sci-rm-range-rflow" }; -- -- cap2 = udma_read(ud->mmrs[MMR_GCFG], UDMA_CAP_REG(2)); -- cap3 = udma_read(ud->mmrs[MMR_GCFG], UDMA_CAP_REG(3)); -- -- ud->rflow_cnt = UDMA_CAP3_RFLOW_CNT(cap3); -- ud->tchan_cnt = UDMA_CAP2_TCHAN_CNT(cap2); -- ud->echan_cnt = UDMA_CAP2_ECHAN_CNT(cap2); -- ud->rchan_cnt = UDMA_CAP2_RCHAN_CNT(cap2); -- ch_count = ud->tchan_cnt + ud->rchan_cnt; -+ u32 cap3; - - /* Set up the throughput level start indexes */ -+ cap3 = udma_read(ud->mmrs[MMR_GCFG], 0x2c); - if (of_device_is_compatible(dev->of_node, - "ti,am654-navss-main-udmap")) { - ud->tpl_levels = 2; -@@ -3262,11 +4090,15 @@ static int udma_setup_resources(struct udma_dev *ud) - bitmap_set(ud->rflow_gp_map, 0, ud->rflow_cnt); - - /* Get resource ranges from tisci */ -- for (i = 0; i < RM_RANGE_LAST; i++) -+ for (i = 0; i < RM_RANGE_LAST; i++) { -+ if (i == RM_RANGE_BCHAN) -+ continue; -+ - tisci_rm->rm_ranges[i] = - devm_ti_sci_get_of_resource(tisci_rm->tisci, dev, - tisci_rm->tisci_dev_id, - (char *)range_names[i]); -+ } - - /* tchan ranges */ - rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN]; -@@ -3304,12 +4136,12 @@ static int udma_setup_resources(struct udma_dev *ud) - for (j = 0; j < rm_res->sets; j++, i++) { - if (rm_res->desc[j].num) { - irq_res.desc[i].start = rm_res->desc[j].start + -- ud->soc_data->rchan_oes_offset; -+ ud->soc_data->oes.udma_rchan; - irq_res.desc[i].num = rm_res->desc[j].num; - } - if (rm_res->desc[j].num_sec) { - irq_res.desc[i].start_sec = rm_res->desc[j].start_sec + -- ud->soc_data->rchan_oes_offset; -+ ud->soc_data->oes.udma_rchan; - irq_res.desc[i].num_sec = rm_res->desc[j].num_sec; - } - } -@@ -3332,6 +4164,174 @@ static int udma_setup_resources(struct udma_dev *ud) - &rm_res->desc[i], "gp-rflow"); - } - -+ return 0; -+} -+ -+static int bcdma_setup_resources(struct udma_dev *ud) -+{ -+ int ret, i, j; -+ struct device *dev = ud->dev; -+ struct ti_sci_resource *rm_res, irq_res; -+ struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; -+ const struct udma_oes_offsets *oes = &ud->soc_data->oes; -+ -+ ud->bchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->bchan_cnt), -+ sizeof(unsigned long), GFP_KERNEL); -+ ud->bchans = devm_kcalloc(dev, ud->bchan_cnt, sizeof(*ud->bchans), -+ GFP_KERNEL); -+ ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt), -+ sizeof(unsigned long), GFP_KERNEL); -+ ud->tchans = devm_kcalloc(dev, ud->tchan_cnt, sizeof(*ud->tchans), -+ GFP_KERNEL); -+ ud->rchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->rchan_cnt), -+ sizeof(unsigned long), GFP_KERNEL); -+ ud->rchans = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rchans), -+ GFP_KERNEL); -+ /* BCDMA do not really have flows, but the driver expect it */ -+ ud->rflow_in_use = devm_kcalloc(dev, BITS_TO_LONGS(ud->rchan_cnt), -+ sizeof(unsigned long), -+ GFP_KERNEL); -+ ud->rflows = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rflows), -+ GFP_KERNEL); -+ -+ if (!ud->bchan_map || !ud->tchan_map || !ud->rchan_map || -+ !ud->rflow_in_use || !ud->bchans || !ud->tchans || !ud->rchans || -+ !ud->rflows) -+ return -ENOMEM; -+ -+ /* TPL is not yet supported for BCDMA */ -+ ud->tpl_levels = 1; -+ -+ /* Get resource ranges from tisci */ -+ for (i = 0; i < RM_RANGE_LAST; i++) { -+ if (i == RM_RANGE_RFLOW) -+ continue; -+ if (i == RM_RANGE_BCHAN && ud->bchan_cnt == 0) -+ continue; -+ if (i == RM_RANGE_TCHAN && ud->tchan_cnt == 0) -+ continue; -+ if (i == RM_RANGE_RCHAN && ud->rchan_cnt == 0) -+ continue; -+ -+ tisci_rm->rm_ranges[i] = -+ devm_ti_sci_get_of_resource(tisci_rm->tisci, dev, -+ tisci_rm->tisci_dev_id, -+ (char *)range_names[i]); -+ } -+ -+ irq_res.sets = 0; -+ -+ /* bchan ranges */ -+ if (ud->bchan_cnt) { -+ rm_res = tisci_rm->rm_ranges[RM_RANGE_BCHAN]; -+ if (IS_ERR(rm_res)) { -+ bitmap_zero(ud->bchan_map, ud->bchan_cnt); -+ } else { -+ bitmap_fill(ud->bchan_map, ud->bchan_cnt); -+ for (i = 0; i < rm_res->sets; i++) -+ udma_mark_resource_ranges(ud, ud->bchan_map, -+ &rm_res->desc[i], -+ "bchan"); -+ } -+ irq_res.sets += rm_res->sets; -+ } -+ -+ /* tchan ranges */ -+ if (ud->tchan_cnt) { -+ rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN]; -+ if (IS_ERR(rm_res)) { -+ bitmap_zero(ud->tchan_map, ud->tchan_cnt); -+ } else { -+ bitmap_fill(ud->tchan_map, ud->tchan_cnt); -+ for (i = 0; i < rm_res->sets; i++) -+ udma_mark_resource_ranges(ud, ud->tchan_map, -+ &rm_res->desc[i], -+ "tchan"); -+ } -+ irq_res.sets += rm_res->sets * 2; -+ } -+ -+ /* rchan ranges */ -+ if (ud->rchan_cnt) { -+ rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN]; -+ if (IS_ERR(rm_res)) { -+ bitmap_zero(ud->rchan_map, ud->rchan_cnt); -+ } else { -+ bitmap_fill(ud->rchan_map, ud->rchan_cnt); -+ for (i = 0; i < rm_res->sets; i++) -+ udma_mark_resource_ranges(ud, ud->rchan_map, -+ &rm_res->desc[i], -+ "rchan"); -+ } -+ irq_res.sets += rm_res->sets * 2; -+ } -+ -+ irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL); -+ if (ud->bchan_cnt) { -+ rm_res = tisci_rm->rm_ranges[RM_RANGE_BCHAN]; -+ for (i = 0; i < rm_res->sets; i++) { -+ irq_res.desc[i].start = rm_res->desc[i].start + -+ oes->bcdma_bchan_ring; -+ irq_res.desc[i].num = rm_res->desc[i].num; -+ } -+ } -+ if (ud->tchan_cnt) { -+ rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN]; -+ for (j = 0; j < rm_res->sets; j++, i += 2) { -+ irq_res.desc[i].start = rm_res->desc[j].start + -+ oes->bcdma_tchan_data; -+ irq_res.desc[i].num = rm_res->desc[j].num; -+ -+ irq_res.desc[i + 1].start = rm_res->desc[j].start + -+ oes->bcdma_tchan_ring; -+ irq_res.desc[i + 1].num = rm_res->desc[j].num; -+ } -+ } -+ if (ud->rchan_cnt) { -+ rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN]; -+ for (j = 0; j < rm_res->sets; j++, i += 2) { -+ irq_res.desc[i].start = rm_res->desc[j].start + -+ oes->bcdma_rchan_data; -+ irq_res.desc[i].num = rm_res->desc[j].num; -+ -+ irq_res.desc[i + 1].start = rm_res->desc[j].start + -+ oes->bcdma_rchan_ring; -+ irq_res.desc[i + 1].num = rm_res->desc[j].num; -+ } -+ } -+ -+ ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res); -+ kfree(irq_res.desc); -+ if (ret) { -+ dev_err(ud->dev, "Failed to allocate MSI interrupts\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int setup_resources(struct udma_dev *ud) -+{ -+ struct device *dev = ud->dev; -+ int ch_count, ret; -+ -+ switch (ud->match_data->type) { -+ case DMA_TYPE_UDMA: -+ ret = udma_setup_resources(ud); -+ break; -+ case DMA_TYPE_BCDMA: -+ ret = bcdma_setup_resources(ud); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (ret) -+ return ret; -+ -+ ch_count = ud->bchan_cnt + ud->tchan_cnt + ud->rchan_cnt; -+ if (ud->bchan_cnt) -+ ch_count -= bitmap_weight(ud->bchan_map, ud->bchan_cnt); - ch_count -= bitmap_weight(ud->tchan_map, ud->tchan_cnt); - ch_count -= bitmap_weight(ud->rchan_map, ud->rchan_cnt); - if (!ch_count) -@@ -3342,12 +4342,32 @@ static int udma_setup_resources(struct udma_dev *ud) - if (!ud->channels) - return -ENOMEM; - -- dev_info(dev, "Channels: %d (tchan: %u, rchan: %u, gp-rflow: %u)\n", -- ch_count, -- ud->tchan_cnt - bitmap_weight(ud->tchan_map, ud->tchan_cnt), -- ud->rchan_cnt - bitmap_weight(ud->rchan_map, ud->rchan_cnt), -- ud->rflow_cnt - bitmap_weight(ud->rflow_gp_map, -- ud->rflow_cnt)); -+ switch (ud->match_data->type) { -+ case DMA_TYPE_UDMA: -+ dev_info(dev, -+ "Channels: %d (tchan: %u, rchan: %u, gp-rflow: %u)\n", -+ ch_count, -+ ud->tchan_cnt - bitmap_weight(ud->tchan_map, -+ ud->tchan_cnt), -+ ud->rchan_cnt - bitmap_weight(ud->rchan_map, -+ ud->rchan_cnt), -+ ud->rflow_cnt - bitmap_weight(ud->rflow_gp_map, -+ ud->rflow_cnt)); -+ break; -+ case DMA_TYPE_BCDMA: -+ dev_info(dev, -+ "Channels: %d (bchan: %u, tchan: %u, rchan: %u)\n", -+ ch_count, -+ ud->bchan_cnt - bitmap_weight(ud->bchan_map, -+ ud->bchan_cnt), -+ ud->tchan_cnt - bitmap_weight(ud->tchan_map, -+ ud->tchan_cnt), -+ ud->rchan_cnt - bitmap_weight(ud->rchan_map, -+ ud->rchan_cnt)); -+ break; -+ default: -+ break; -+ } - - return ch_count; - } -@@ -3456,10 +4476,19 @@ static void udma_dbg_summary_show_chan(struct seq_file *s, - - seq_printf(s, " %-13s| %s", dma_chan_name(chan), - chan->dbg_client_name ?: "in-use"); -- seq_printf(s, " (%s, ", dmaengine_get_direction_text(uc->config.dir)); -+ if (ucc->tr_trigger_type) -+ seq_puts(s, " (triggered, "); -+ else -+ seq_printf(s, " (%s, ", -+ dmaengine_get_direction_text(uc->config.dir)); - - switch (uc->config.dir) { - case DMA_MEM_TO_MEM: -+ if (uc->ud->match_data->type == DMA_TYPE_BCDMA) { -+ seq_printf(s, "bchan%d)\n", uc->bchan->id); -+ return; -+ } -+ - seq_printf(s, "chan%d pair [0x%04x -> 0x%04x], ", uc->tchan->id, - ucc->src_thread, ucc->dst_thread); - break; -@@ -3531,6 +4560,23 @@ static int udma_probe(struct platform_device *pdev) - if (!ud) - return -ENOMEM; - -+ match = of_match_node(udma_of_match, dev->of_node); -+ if (!match) { -+ match = of_match_node(bcdma_of_match, dev->of_node); -+ if (!match) { -+ dev_err(dev, "No compatible match found\n"); -+ return -ENODEV; -+ } -+ } -+ ud->match_data = match->data; -+ -+ soc = soc_device_match(k3_soc_devices); -+ if (!soc) { -+ dev_err(dev, "No compatible SoC found\n"); -+ return -ENODEV; -+ } -+ ud->soc_data = soc->data; -+ - ret = udma_get_mmrs(pdev, ud); - if (ret) - return ret; -@@ -3554,16 +4600,38 @@ static int udma_probe(struct platform_device *pdev) - return ret; - } - -- ret = of_property_read_u32(dev->of_node, "ti,udma-atype", &ud->atype); -- if (!ret && ud->atype > 2) { -- dev_err(dev, "Invalid atype: %u\n", ud->atype); -- return -EINVAL; -+ if (ud->match_data->type == DMA_TYPE_UDMA) { -+ ret = of_property_read_u32(dev->of_node, "ti,udma-atype", -+ &ud->atype); -+ if (!ret && ud->atype > 2) { -+ dev_err(dev, "Invalid atype: %u\n", ud->atype); -+ return -EINVAL; -+ } -+ } else { -+ ret = of_property_read_u32(dev->of_node, "ti,asel", -+ &ud->asel); -+ if (!ret && ud->asel > 15) { -+ dev_err(dev, "Invalid asel: %u\n", ud->asel); -+ return -EINVAL; -+ } - } - - ud->tisci_rm.tisci_udmap_ops = &ud->tisci_rm.tisci->ops.rm_udmap_ops; - ud->tisci_rm.tisci_psil_ops = &ud->tisci_rm.tisci->ops.rm_psil_ops; - -- ud->ringacc = of_k3_ringacc_get_by_phandle(dev->of_node, "ti,ringacc"); -+ if (ud->match_data->type == DMA_TYPE_UDMA) { -+ ud->ringacc = of_k3_ringacc_get_by_phandle(dev->of_node, "ti,ringacc"); -+ } else { -+ struct k3_ringacc_init_data ring_init_data; -+ -+ ring_init_data.tisci = ud->tisci_rm.tisci; -+ ring_init_data.tisci_dev_id = ud->tisci_rm.tisci_dev_id; -+ ring_init_data.num_rings = ud->bchan_cnt + ud->tchan_cnt + -+ ud->rchan_cnt; -+ -+ ud->ringacc = k3_ringacc_dmarings_init(pdev, &ring_init_data); -+ } -+ - if (IS_ERR(ud->ringacc)) - return PTR_ERR(ud->ringacc); - -@@ -3574,24 +4642,9 @@ static int udma_probe(struct platform_device *pdev) - return -EPROBE_DEFER; - } - -- match = of_match_node(udma_of_match, dev->of_node); -- if (!match) { -- dev_err(dev, "No compatible match found\n"); -- return -ENODEV; -- } -- ud->match_data = match->data; -- -- soc = soc_device_match(k3_soc_devices); -- if (!soc) { -- dev_err(dev, "No compatible SoC found\n"); -- return -ENODEV; -- } -- ud->soc_data = soc->data; -- - dma_cap_set(DMA_SLAVE, ud->ddev.cap_mask); - dma_cap_set(DMA_CYCLIC, ud->ddev.cap_mask); - -- ud->ddev.device_alloc_chan_resources = udma_alloc_chan_resources; - ud->ddev.device_config = udma_slave_config; - ud->ddev.device_prep_slave_sg = udma_prep_slave_sg; - ud->ddev.device_prep_dma_cyclic = udma_prep_dma_cyclic; -@@ -3605,7 +4658,21 @@ static int udma_probe(struct platform_device *pdev) - ud->ddev.dbg_summary_show = udma_dbg_summary_show; - #endif - -+ switch (ud->match_data->type) { -+ case DMA_TYPE_UDMA: -+ ud->ddev.device_alloc_chan_resources = -+ udma_alloc_chan_resources; -+ break; -+ case DMA_TYPE_BCDMA: -+ ud->ddev.device_alloc_chan_resources = -+ bcdma_alloc_chan_resources; -+ ud->ddev.device_router_config = bcdma_router_config; -+ break; -+ default: -+ return -EINVAL; -+ } - ud->ddev.device_free_chan_resources = udma_free_chan_resources; -+ - ud->ddev.src_addr_widths = TI_UDMAC_BUSWIDTHS; - ud->ddev.dst_addr_widths = TI_UDMAC_BUSWIDTHS; - ud->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); -@@ -3613,7 +4680,8 @@ static int udma_probe(struct platform_device *pdev) - ud->ddev.copy_align = DMAENGINE_ALIGN_8_BYTES; - ud->ddev.desc_metadata_modes = DESC_METADATA_CLIENT | - DESC_METADATA_ENGINE; -- if (ud->match_data->enable_memcpy_support) { -+ if (ud->match_data->enable_memcpy_support && -+ !(ud->match_data->type == DMA_TYPE_BCDMA && ud->bchan_cnt == 0)) { - dma_cap_set(DMA_MEMCPY, ud->ddev.cap_mask); - ud->ddev.device_prep_dma_memcpy = udma_prep_dma_memcpy; - ud->ddev.directions |= BIT(DMA_MEM_TO_MEM); -@@ -3626,7 +4694,7 @@ static int udma_probe(struct platform_device *pdev) - INIT_LIST_HEAD(&ud->ddev.channels); - INIT_LIST_HEAD(&ud->desc_to_purge); - -- ch_count = udma_setup_resources(ud); -+ ch_count = setup_resources(ud); - if (ch_count <= 0) - return ch_count; - -@@ -3641,6 +4709,13 @@ static int udma_probe(struct platform_device *pdev) - if (ret) - return ret; - -+ for (i = 0; i < ud->bchan_cnt; i++) { -+ struct udma_bchan *bchan = &ud->bchans[i]; -+ -+ bchan->id = i; -+ bchan->reg_rt = ud->mmrs[MMR_BCHANRT] + i * 0x1000; -+ } -+ - for (i = 0; i < ud->tchan_cnt; i++) { - struct udma_tchan *tchan = &ud->tchans[i]; - -@@ -3667,6 +4742,7 @@ static int udma_probe(struct platform_device *pdev) - uc->ud = ud; - uc->vc.desc_free = udma_desc_free; - uc->id = i; -+ uc->bchan = NULL; - uc->tchan = NULL; - uc->rchan = NULL; - uc->config.remote_thread_id = -1; -@@ -3708,5 +4784,15 @@ static struct platform_driver udma_driver = { - }; - builtin_platform_driver(udma_driver); - -+static struct platform_driver bcdma_driver = { -+ .driver = { -+ .name = "ti-bcdma", -+ .of_match_table = bcdma_of_match, -+ .suppress_bind_attrs = true, -+ }, -+ .probe = udma_probe, -+}; -+builtin_platform_driver(bcdma_driver); -+ - /* Private interfaces to UDMA */ - #include "k3-udma-private.c" -diff --git a/drivers/dma/ti/k3-udma.h b/drivers/dma/ti/k3-udma.h -index b4334b1b7b14..c97ed5271fd9 100644 ---- a/drivers/dma/ti/k3-udma.h -+++ b/drivers/dma/ti/k3-udma.h -@@ -18,7 +18,7 @@ - #define UDMA_RX_FLOW_ID_FW_OES_REG 0x80 - #define UDMA_RX_FLOW_ID_FW_STATUS_REG 0x88 - --/* TCHANRT/RCHANRT registers */ -+/* BCHANRT/TCHANRT/RCHANRT registers */ - #define UDMA_CHAN_RT_CTL_REG 0x0 - #define UDMA_CHAN_RT_SWTRIG_REG 0x8 - #define UDMA_CHAN_RT_STDATA_REG 0x80 -@@ -45,6 +45,10 @@ - #define UDMA_CAP3_HCHAN_CNT(val) (((val) >> 14) & 0x1ff) - #define UDMA_CAP3_UCHAN_CNT(val) (((val) >> 23) & 0x1ff) - -+#define BCDMA_CAP2_BCHAN_CNT(val) ((val) & 0x1ff) -+#define BCDMA_CAP2_TCHAN_CNT(val) (((val) >> 9) & 0x1ff) -+#define BCDMA_CAP2_RCHAN_CNT(val) (((val) >> 18) & 0x1ff) -+ - /* UDMA_CHAN_RT_CTL_REG */ - #define UDMA_CHAN_RT_CTL_EN BIT(31) - #define UDMA_CHAN_RT_CTL_TDOWN BIT(30) -@@ -82,13 +86,17 @@ - */ - #define PDMA_STATIC_TR_Z(x, mask) ((x) & (mask)) - -+/* Address Space Select */ -+#define K3_ADDRESS_ASEL_SHIFT 48 -+ - struct udma_dev; - struct udma_tchan; - struct udma_rchan; - struct udma_rflow; - - enum udma_rm_range { -- RM_RANGE_TCHAN = 0, -+ RM_RANGE_BCHAN = 0, -+ RM_RANGE_TCHAN, - RM_RANGE_RCHAN, - RM_RANGE_RFLOW, - RM_RANGE_LAST, diff --git a/recipes-kernel/linux/files/patches-5.10/0133-dmaengine-ti-k3-udma-Add-support-for-BCDMA-channel-T.patch b/recipes-kernel/linux/files/patches-5.10/0133-dmaengine-ti-k3-udma-Add-support-for-BCDMA-channel-T.patch deleted file mode 100644 index 8ecc3f8ea..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0133-dmaengine-ti-k3-udma-Add-support-for-BCDMA-channel-T.patch +++ /dev/null @@ -1,243 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Tue, 8 Dec 2020 11:04:38 +0200 -Subject: [PATCH] dmaengine: ti: k3-udma: Add support for BCDMA channel TPL - handling - -commit 8844898028d4127b0071ecb5a72e1894bd8b21d6 upstream. - -Unlike UDMAP the BCDMA defines the channel TPL levels per channel type. -In UDMAP the number of high and ultra-high channels applies to both tchan -and rchan. - -BCDMA defines the TPL per channel types: bchan, tchan and rchan can have -different number of high and ultra-high channels. - -In order to support BCDMA channel TPL we need to move the tpl information -as per channel type property for the DMAs. - -Signed-off-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20201208090440.31792-19-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit '8844898028d4' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/k3-udma.c | 117 ++++++++++++++++++++++++++------------- - drivers/dma/ti/k3-udma.h | 6 ++ - 2 files changed, 85 insertions(+), 38 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index f327d436f8ad..0dc3430fea40 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -146,6 +146,11 @@ struct udma_rx_flush { - dma_addr_t buffer_paddr; - }; - -+struct udma_tpl { -+ u8 levels; -+ u32 start_idx[3]; -+}; -+ - struct udma_dev { - struct dma_device ddev; - struct device *dev; -@@ -153,8 +158,9 @@ struct udma_dev { - const struct udma_match_data *match_data; - const struct udma_soc_data *soc_data; - -- u8 tpl_levels; -- u32 tpl_start_idx[3]; -+ struct udma_tpl bchan_tpl; -+ struct udma_tpl tchan_tpl; -+ struct udma_tpl rchan_tpl; - - size_t desc_align; /* alignment to use for descriptors */ - -@@ -1276,10 +1282,10 @@ static struct udma_##res *__udma_reserve_##res(struct udma_dev *ud, \ - } else { \ - int start; \ - \ -- if (tpl >= ud->tpl_levels) \ -- tpl = ud->tpl_levels - 1; \ -+ if (tpl >= ud->res##_tpl.levels) \ -+ tpl = ud->res##_tpl.levels - 1; \ - \ -- start = ud->tpl_start_idx[tpl]; \ -+ start = ud->res##_tpl.start_idx[tpl]; \ - \ - id = find_next_zero_bit(ud->res##_map, ud->res##_cnt, \ - start); \ -@@ -1292,29 +1298,14 @@ static struct udma_##res *__udma_reserve_##res(struct udma_dev *ud, \ - return &ud->res##s[id]; \ - } - -+UDMA_RESERVE_RESOURCE(bchan); - UDMA_RESERVE_RESOURCE(tchan); - UDMA_RESERVE_RESOURCE(rchan); - --static struct udma_bchan *__bcdma_reserve_bchan(struct udma_dev *ud, int id) --{ -- if (id >= 0) { -- if (test_bit(id, ud->bchan_map)) { -- dev_err(ud->dev, "bchan%d is in use\n", id); -- return ERR_PTR(-ENOENT); -- } -- } else { -- id = find_next_zero_bit(ud->bchan_map, ud->bchan_cnt, 0); -- if (id == ud->bchan_cnt) -- return ERR_PTR(-ENOENT); -- } -- -- set_bit(id, ud->bchan_map); -- return &ud->bchans[id]; --} -- - static int bcdma_get_bchan(struct udma_chan *uc) - { - struct udma_dev *ud = uc->ud; -+ enum udma_tp_level tpl; - - if (uc->bchan) { - dev_dbg(ud->dev, "chan%d: already have bchan%d allocated\n", -@@ -1322,7 +1313,16 @@ static int bcdma_get_bchan(struct udma_chan *uc) - return 0; - } - -- uc->bchan = __bcdma_reserve_bchan(ud, -1); -+ /* -+ * Use normal channels for peripherals, and highest TPL channel for -+ * mem2mem -+ */ -+ if (uc->config.tr_trigger_type) -+ tpl = 0; -+ else -+ tpl = ud->bchan_tpl.levels - 1; -+ -+ uc->bchan = __udma_reserve_bchan(ud, tpl, -1); - if (IS_ERR(uc->bchan)) - return PTR_ERR(uc->bchan); - -@@ -1384,8 +1384,11 @@ static int udma_get_chan_pair(struct udma_chan *uc) - - /* Can be optimized, but let's have it like this for now */ - end = min(ud->tchan_cnt, ud->rchan_cnt); -- /* Try to use the highest TPL channel pair for MEM_TO_MEM channels */ -- chan_id = ud->tpl_start_idx[ud->tpl_levels - 1]; -+ /* -+ * Try to use the highest TPL channel pair for MEM_TO_MEM channels -+ * Note: in UDMAP the channel TPL is symmetric between tchan and rchan -+ */ -+ chan_id = ud->tchan_tpl.start_idx[ud->tchan_tpl.levels - 1]; - for (; chan_id < end; chan_id++) { - if (!test_bit(chan_id, ud->tchan_map) && - !test_bit(chan_id, ud->rchan_map)) -@@ -4036,23 +4039,27 @@ static int udma_setup_resources(struct udma_dev *ud) - cap3 = udma_read(ud->mmrs[MMR_GCFG], 0x2c); - if (of_device_is_compatible(dev->of_node, - "ti,am654-navss-main-udmap")) { -- ud->tpl_levels = 2; -- ud->tpl_start_idx[0] = 8; -+ ud->tchan_tpl.levels = 2; -+ ud->tchan_tpl.start_idx[0] = 8; - } else if (of_device_is_compatible(dev->of_node, - "ti,am654-navss-mcu-udmap")) { -- ud->tpl_levels = 2; -- ud->tpl_start_idx[0] = 2; -+ ud->tchan_tpl.levels = 2; -+ ud->tchan_tpl.start_idx[0] = 2; - } else if (UDMA_CAP3_UCHAN_CNT(cap3)) { -- ud->tpl_levels = 3; -- ud->tpl_start_idx[1] = UDMA_CAP3_UCHAN_CNT(cap3); -- ud->tpl_start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3); -+ ud->tchan_tpl.levels = 3; -+ ud->tchan_tpl.start_idx[1] = UDMA_CAP3_UCHAN_CNT(cap3); -+ ud->tchan_tpl.start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3); - } else if (UDMA_CAP3_HCHAN_CNT(cap3)) { -- ud->tpl_levels = 2; -- ud->tpl_start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3); -+ ud->tchan_tpl.levels = 2; -+ ud->tchan_tpl.start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3); - } else { -- ud->tpl_levels = 1; -+ ud->tchan_tpl.levels = 1; - } - -+ ud->rchan_tpl.levels = ud->tchan_tpl.levels; -+ ud->rchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0]; -+ ud->rchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1]; -+ - ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt), - sizeof(unsigned long), GFP_KERNEL); - ud->tchans = devm_kcalloc(dev, ud->tchan_cnt, sizeof(*ud->tchans), -@@ -4174,6 +4181,43 @@ static int bcdma_setup_resources(struct udma_dev *ud) - struct ti_sci_resource *rm_res, irq_res; - struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; - const struct udma_oes_offsets *oes = &ud->soc_data->oes; -+ u32 cap; -+ -+ /* Set up the throughput level start indexes */ -+ cap = udma_read(ud->mmrs[MMR_GCFG], 0x2c); -+ if (BCDMA_CAP3_UBCHAN_CNT(cap)) { -+ ud->bchan_tpl.levels = 3; -+ ud->bchan_tpl.start_idx[1] = BCDMA_CAP3_UBCHAN_CNT(cap); -+ ud->bchan_tpl.start_idx[0] = BCDMA_CAP3_HBCHAN_CNT(cap); -+ } else if (BCDMA_CAP3_HBCHAN_CNT(cap)) { -+ ud->bchan_tpl.levels = 2; -+ ud->bchan_tpl.start_idx[0] = BCDMA_CAP3_HBCHAN_CNT(cap); -+ } else { -+ ud->bchan_tpl.levels = 1; -+ } -+ -+ cap = udma_read(ud->mmrs[MMR_GCFG], 0x30); -+ if (BCDMA_CAP4_URCHAN_CNT(cap)) { -+ ud->rchan_tpl.levels = 3; -+ ud->rchan_tpl.start_idx[1] = BCDMA_CAP4_URCHAN_CNT(cap); -+ ud->rchan_tpl.start_idx[0] = BCDMA_CAP4_HRCHAN_CNT(cap); -+ } else if (BCDMA_CAP4_HRCHAN_CNT(cap)) { -+ ud->rchan_tpl.levels = 2; -+ ud->rchan_tpl.start_idx[0] = BCDMA_CAP4_HRCHAN_CNT(cap); -+ } else { -+ ud->rchan_tpl.levels = 1; -+ } -+ -+ if (BCDMA_CAP4_UTCHAN_CNT(cap)) { -+ ud->tchan_tpl.levels = 3; -+ ud->tchan_tpl.start_idx[1] = BCDMA_CAP4_UTCHAN_CNT(cap); -+ ud->tchan_tpl.start_idx[0] = BCDMA_CAP4_HTCHAN_CNT(cap); -+ } else if (BCDMA_CAP4_HTCHAN_CNT(cap)) { -+ ud->tchan_tpl.levels = 2; -+ ud->tchan_tpl.start_idx[0] = BCDMA_CAP4_HTCHAN_CNT(cap); -+ } else { -+ ud->tchan_tpl.levels = 1; -+ } - - ud->bchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->bchan_cnt), - sizeof(unsigned long), GFP_KERNEL); -@@ -4199,9 +4243,6 @@ static int bcdma_setup_resources(struct udma_dev *ud) - !ud->rflows) - return -ENOMEM; - -- /* TPL is not yet supported for BCDMA */ -- ud->tpl_levels = 1; -- - /* Get resource ranges from tisci */ - for (i = 0; i < RM_RANGE_LAST; i++) { - if (i == RM_RANGE_RFLOW) -diff --git a/drivers/dma/ti/k3-udma.h b/drivers/dma/ti/k3-udma.h -index c97ed5271fd9..3ec38b383b76 100644 ---- a/drivers/dma/ti/k3-udma.h -+++ b/drivers/dma/ti/k3-udma.h -@@ -48,6 +48,12 @@ - #define BCDMA_CAP2_BCHAN_CNT(val) ((val) & 0x1ff) - #define BCDMA_CAP2_TCHAN_CNT(val) (((val) >> 9) & 0x1ff) - #define BCDMA_CAP2_RCHAN_CNT(val) (((val) >> 18) & 0x1ff) -+#define BCDMA_CAP3_HBCHAN_CNT(val) (((val) >> 14) & 0x1ff) -+#define BCDMA_CAP3_UBCHAN_CNT(val) (((val) >> 23) & 0x1ff) -+#define BCDMA_CAP4_HRCHAN_CNT(val) ((val) & 0xff) -+#define BCDMA_CAP4_URCHAN_CNT(val) (((val) >> 8) & 0xff) -+#define BCDMA_CAP4_HTCHAN_CNT(val) (((val) >> 16) & 0xff) -+#define BCDMA_CAP4_UTCHAN_CNT(val) (((val) >> 24) & 0xff) - - /* UDMA_CHAN_RT_CTL_REG */ - #define UDMA_CHAN_RT_CTL_EN BIT(31) diff --git a/recipes-kernel/linux/files/patches-5.10/0134-dmaengine-ti-k3-udma-Initial-support-for-K3-PKTDMA.patch b/recipes-kernel/linux/files/patches-5.10/0134-dmaengine-ti-k3-udma-Initial-support-for-K3-PKTDMA.patch deleted file mode 100644 index e2d5a780d..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0134-dmaengine-ti-k3-udma-Initial-support-for-K3-PKTDMA.patch +++ /dev/null @@ -1,958 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Tue, 8 Dec 2020 11:04:39 +0200 -Subject: [PATCH] dmaengine: ti: k3-udma: Initial support for K3 PKTDMA - -commit d2abc982333c02f9e1ff1c6b3782174f5b7662d7 upstream. - -One of the DMAs introduced with AM64 is the Packet DMA (PKTDMA). -It serves similar purpose as K3 UDMAP channels in packet mode, but with -notable differences, like tflow support and channels being allocated to -service specific peripherals. -The rings for the PKTDMA is integrated within the DMA itself instead of -using rings from the general purpose ringacc. - -PKTDMA can be used to service PSI-L peripherals, similarly to -K3 UDMA channels. - -Most of the driver code can be reused for PKTDMA tchan/rchan support but -new setup and allocation functions are needed to handle the differences -between the DMAs. - -Signed-off-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20201208090440.31792-20-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit 'd2abc982333c' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/k3-udma-private.c | 9 + - drivers/dma/ti/k3-udma.c | 545 +++++++++++++++++++++++++++++-- - drivers/dma/ti/k3-udma.h | 4 + - 3 files changed, 533 insertions(+), 25 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma-private.c b/drivers/dma/ti/k3-udma-private.c -index 10a3ee529710..3a08e68de349 100644 ---- a/drivers/dma/ti/k3-udma-private.c -+++ b/drivers/dma/ti/k3-udma-private.c -@@ -88,6 +88,9 @@ EXPORT_SYMBOL(xudma_free_gp_rflow_range); - - bool xudma_rflow_is_gp(struct udma_dev *ud, int id) - { -+ if (!ud->rflow_gp_map) -+ return false; -+ - return !test_bit(id, ud->rflow_gp_map); - } - EXPORT_SYMBOL(xudma_rflow_is_gp); -@@ -119,6 +122,12 @@ void xudma_rflow_put(struct udma_dev *ud, struct udma_rflow *p) - } - EXPORT_SYMBOL(xudma_rflow_put); - -+int xudma_get_rflow_ring_offset(struct udma_dev *ud) -+{ -+ return ud->tflow_cnt; -+} -+EXPORT_SYMBOL(xudma_get_rflow_ring_offset); -+ - #define XUDMA_GET_RESOURCE_ID(res) \ - int xudma_##res##_get_id(struct udma_##res *p) \ - { \ -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index 0dc3430fea40..87157cbae1b8 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -59,6 +59,7 @@ struct udma_chan; - enum k3_dma_type { - DMA_TYPE_UDMA = 0, - DMA_TYPE_BCDMA, -+ DMA_TYPE_PKTDMA, - }; - - enum udma_mmr { -@@ -82,6 +83,8 @@ struct udma_tchan { - int id; - struct k3_ring *t_ring; /* Transmit ring */ - struct k3_ring *tc_ring; /* Transmit Completion ring */ -+ int tflow_id; /* applicable only for PKTDMA */ -+ - }; - - #define udma_bchan udma_tchan -@@ -109,6 +112,10 @@ struct udma_oes_offsets { - u32 bcdma_tchan_ring; - u32 bcdma_rchan_data; - u32 bcdma_rchan_ring; -+ -+ /* PKTDMA Output Event Offsets */ -+ u32 pktdma_tchan_flow; -+ u32 pktdma_rchan_flow; - }; - - #define UDMA_FLAG_PDMA_ACC32 BIT(0) -@@ -179,12 +186,14 @@ struct udma_dev { - int echan_cnt; - int rchan_cnt; - int rflow_cnt; -+ int tflow_cnt; - unsigned long *bchan_map; - unsigned long *tchan_map; - unsigned long *rchan_map; - unsigned long *rflow_gp_map; - unsigned long *rflow_gp_map_allocated; - unsigned long *rflow_in_use; -+ unsigned long *tflow_map; - - struct udma_bchan *bchans; - struct udma_tchan *tchans; -@@ -249,6 +258,11 @@ struct udma_chan_config { - - u32 tr_trigger_type; - -+ /* PKDMA mapped channel */ -+ int mapped_channel_id; -+ /* PKTDMA default tflow or rflow for mapped channel */ -+ int default_flow_id; -+ - enum dma_transfer_direction dir; - }; - -@@ -426,6 +440,8 @@ static void udma_reset_uchan(struct udma_chan *uc) - { - memset(&uc->config, 0, sizeof(uc->config)); - uc->config.remote_thread_id = -1; -+ uc->config.mapped_channel_id = -1; -+ uc->config.default_flow_id = -1; - uc->state = UDMA_CHAN_IS_IDLE; - } - -@@ -815,10 +831,16 @@ static void udma_start_desc(struct udma_chan *uc) - { - struct udma_chan_config *ucc = &uc->config; - -- if (ucc->pkt_mode && (uc->cyclic || ucc->dir == DMA_DEV_TO_MEM)) { -+ if (uc->ud->match_data->type == DMA_TYPE_UDMA && ucc->pkt_mode && -+ (uc->cyclic || ucc->dir == DMA_DEV_TO_MEM)) { - int i; - -- /* Push all descriptors to ring for packet mode cyclic or RX */ -+ /* -+ * UDMA only: Push all descriptors to ring for packet mode -+ * cyclic or RX -+ * PKTDMA supports pre-linked descriptor and cyclic is not -+ * supported -+ */ - for (i = 0; i < uc->desc->sglen; i++) - udma_push_to_ring(uc, i); - } else { -@@ -1248,10 +1270,12 @@ static struct udma_rflow *__udma_get_rflow(struct udma_dev *ud, int id) - if (test_bit(id, ud->rflow_in_use)) - return ERR_PTR(-ENOENT); - -- /* GP rflow has to be allocated first */ -- if (!test_bit(id, ud->rflow_gp_map) && -- !test_bit(id, ud->rflow_gp_map_allocated)) -- return ERR_PTR(-EINVAL); -+ if (ud->rflow_gp_map) { -+ /* GP rflow has to be allocated first */ -+ if (!test_bit(id, ud->rflow_gp_map) && -+ !test_bit(id, ud->rflow_gp_map_allocated)) -+ return ERR_PTR(-EINVAL); -+ } - - dev_dbg(ud->dev, "get rflow%d\n", id); - set_bit(id, ud->rflow_in_use); -@@ -1341,9 +1365,39 @@ static int udma_get_tchan(struct udma_chan *uc) - return 0; - } - -- uc->tchan = __udma_reserve_tchan(ud, uc->config.channel_tpl, -1); -+ /* -+ * mapped_channel_id is -1 for UDMA, BCDMA and PKTDMA unmapped channels. -+ * For PKTDMA mapped channels it is configured to a channel which must -+ * be used to service the peripheral. -+ */ -+ uc->tchan = __udma_reserve_tchan(ud, uc->config.channel_tpl, -+ uc->config.mapped_channel_id); -+ if (IS_ERR(uc->tchan)) -+ return PTR_ERR(uc->tchan); -+ -+ if (ud->tflow_cnt) { -+ int tflow_id; -+ -+ /* Only PKTDMA have support for tx flows */ -+ if (uc->config.default_flow_id >= 0) -+ tflow_id = uc->config.default_flow_id; -+ else -+ tflow_id = uc->tchan->id; -+ -+ if (test_bit(tflow_id, ud->tflow_map)) { -+ dev_err(ud->dev, "tflow%d is in use\n", tflow_id); -+ clear_bit(uc->tchan->id, ud->tchan_map); -+ uc->tchan = NULL; -+ return -ENOENT; -+ } -+ -+ uc->tchan->tflow_id = tflow_id; -+ set_bit(tflow_id, ud->tflow_map); -+ } else { -+ uc->tchan->tflow_id = -1; -+ } - -- return PTR_ERR_OR_ZERO(uc->tchan); -+ return 0; - } - - static int udma_get_rchan(struct udma_chan *uc) -@@ -1356,7 +1410,13 @@ static int udma_get_rchan(struct udma_chan *uc) - return 0; - } - -- uc->rchan = __udma_reserve_rchan(ud, uc->config.channel_tpl, -1); -+ /* -+ * mapped_channel_id is -1 for UDMA, BCDMA and PKTDMA unmapped channels. -+ * For PKTDMA mapped channels it is configured to a channel which must -+ * be used to service the peripheral. -+ */ -+ uc->rchan = __udma_reserve_rchan(ud, uc->config.channel_tpl, -+ uc->config.mapped_channel_id); - - return PTR_ERR_OR_ZERO(uc->rchan); - } -@@ -1403,6 +1463,9 @@ static int udma_get_chan_pair(struct udma_chan *uc) - uc->tchan = &ud->tchans[chan_id]; - uc->rchan = &ud->rchans[chan_id]; - -+ /* UDMA does not use tx flows */ -+ uc->tchan->tflow_id = -1; -+ - return 0; - } - -@@ -1459,6 +1522,10 @@ static void udma_put_tchan(struct udma_chan *uc) - dev_dbg(ud->dev, "chan%d: put tchan%d\n", uc->id, - uc->tchan->id); - clear_bit(uc->tchan->id, ud->tchan_map); -+ -+ if (uc->tchan->tflow_id >= 0) -+ clear_bit(uc->tchan->tflow_id, ud->tflow_map); -+ - uc->tchan = NULL; - } - } -@@ -1559,7 +1626,10 @@ static int udma_alloc_tx_resources(struct udma_chan *uc) - return ret; - - tchan = uc->tchan; -- ring_idx = ud->bchan_cnt + tchan->id; -+ if (tchan->tflow_id >= 0) -+ ring_idx = tchan->tflow_id; -+ else -+ ring_idx = ud->bchan_cnt + tchan->id; - - ret = k3_ringacc_request_rings_pair(ud->ringacc, ring_idx, -1, - &tchan->t_ring, -@@ -1636,15 +1706,23 @@ static int udma_alloc_rx_resources(struct udma_chan *uc) - if (uc->config.dir == DMA_MEM_TO_MEM) - return 0; - -- ret = udma_get_rflow(uc, uc->rchan->id); -+ if (uc->config.default_flow_id >= 0) -+ ret = udma_get_rflow(uc, uc->config.default_flow_id); -+ else -+ ret = udma_get_rflow(uc, uc->rchan->id); -+ - if (ret) { - ret = -EBUSY; - goto err_rflow; - } - - rflow = uc->rflow; -- fd_ring_id = ud->bchan_cnt + ud->tchan_cnt + ud->echan_cnt + -- uc->rchan->id; -+ if (ud->tflow_cnt) -+ fd_ring_id = ud->tflow_cnt + rflow->id; -+ else -+ fd_ring_id = ud->bchan_cnt + ud->tchan_cnt + ud->echan_cnt + -+ uc->rchan->id; -+ - ret = k3_ringacc_request_rings_pair(ud->ringacc, fd_ring_id, -1, - &rflow->fd_ring, &rflow->r_ring); - if (ret) { -@@ -1860,6 +1938,8 @@ static int bcdma_tisci_tx_channel_config(struct udma_chan *uc) - return ret; - } - -+#define pktdma_tisci_tx_channel_config bcdma_tisci_tx_channel_config -+ - static int udma_tisci_rx_channel_config(struct udma_chan *uc) - { - struct udma_dev *ud = uc->ud; -@@ -1961,6 +2041,52 @@ static int bcdma_tisci_rx_channel_config(struct udma_chan *uc) - return ret; - } - -+static int pktdma_tisci_rx_channel_config(struct udma_chan *uc) -+{ -+ struct udma_dev *ud = uc->ud; -+ struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; -+ const struct ti_sci_rm_udmap_ops *tisci_ops = tisci_rm->tisci_udmap_ops; -+ struct ti_sci_msg_rm_udmap_rx_ch_cfg req_rx = { 0 }; -+ struct ti_sci_msg_rm_udmap_flow_cfg flow_req = { 0 }; -+ int ret = 0; -+ -+ req_rx.valid_params = TISCI_BCDMA_RCHAN_VALID_PARAMS; -+ req_rx.nav_id = tisci_rm->tisci_dev_id; -+ req_rx.index = uc->rchan->id; -+ -+ ret = tisci_ops->rx_ch_cfg(tisci_rm->tisci, &req_rx); -+ if (ret) { -+ dev_err(ud->dev, "rchan%d cfg failed %d\n", uc->rchan->id, ret); -+ return ret; -+ } -+ -+ flow_req.valid_params = -+ TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_EINFO_PRESENT_VALID | -+ TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_PSINFO_PRESENT_VALID | -+ TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_ERROR_HANDLING_VALID; -+ -+ flow_req.nav_id = tisci_rm->tisci_dev_id; -+ flow_req.flow_index = uc->rflow->id; -+ -+ if (uc->config.needs_epib) -+ flow_req.rx_einfo_present = 1; -+ else -+ flow_req.rx_einfo_present = 0; -+ if (uc->config.psd_size) -+ flow_req.rx_psinfo_present = 1; -+ else -+ flow_req.rx_psinfo_present = 0; -+ flow_req.rx_error_handling = 1; -+ -+ ret = tisci_ops->rx_flow_cfg(tisci_rm->tisci, &flow_req); -+ -+ if (ret) -+ dev_err(ud->dev, "flow%d config failed: %d\n", uc->rflow->id, -+ ret); -+ -+ return ret; -+} -+ - static int udma_alloc_chan_resources(struct dma_chan *chan) - { - struct udma_chan *uc = to_udma_chan(chan); -@@ -2379,6 +2505,157 @@ static int bcdma_router_config(struct dma_chan *chan) - return router_data->set_event(router_data->priv, trigger_event); - } - -+static int pktdma_alloc_chan_resources(struct dma_chan *chan) -+{ -+ struct udma_chan *uc = to_udma_chan(chan); -+ struct udma_dev *ud = to_udma_dev(chan->device); -+ const struct udma_oes_offsets *oes = &ud->soc_data->oes; -+ u32 irq_ring_idx; -+ int ret; -+ -+ /* -+ * Make sure that the completion is in a known state: -+ * No teardown, the channel is idle -+ */ -+ reinit_completion(&uc->teardown_completed); -+ complete_all(&uc->teardown_completed); -+ uc->state = UDMA_CHAN_IS_IDLE; -+ -+ switch (uc->config.dir) { -+ case DMA_MEM_TO_DEV: -+ /* Slave transfer synchronized - mem to dev (TX) trasnfer */ -+ dev_dbg(uc->ud->dev, "%s: chan%d as MEM-to-DEV\n", __func__, -+ uc->id); -+ -+ ret = udma_alloc_tx_resources(uc); -+ if (ret) { -+ uc->config.remote_thread_id = -1; -+ return ret; -+ } -+ -+ uc->config.src_thread = ud->psil_base + uc->tchan->id; -+ uc->config.dst_thread = uc->config.remote_thread_id; -+ uc->config.dst_thread |= K3_PSIL_DST_THREAD_ID_OFFSET; -+ -+ irq_ring_idx = uc->tchan->tflow_id + oes->pktdma_tchan_flow; -+ -+ ret = pktdma_tisci_tx_channel_config(uc); -+ break; -+ case DMA_DEV_TO_MEM: -+ /* Slave transfer synchronized - dev to mem (RX) trasnfer */ -+ dev_dbg(uc->ud->dev, "%s: chan%d as DEV-to-MEM\n", __func__, -+ uc->id); -+ -+ ret = udma_alloc_rx_resources(uc); -+ if (ret) { -+ uc->config.remote_thread_id = -1; -+ return ret; -+ } -+ -+ uc->config.src_thread = uc->config.remote_thread_id; -+ uc->config.dst_thread = (ud->psil_base + uc->rchan->id) | -+ K3_PSIL_DST_THREAD_ID_OFFSET; -+ -+ irq_ring_idx = uc->rflow->id + oes->pktdma_rchan_flow; -+ -+ ret = pktdma_tisci_rx_channel_config(uc); -+ break; -+ default: -+ /* Can not happen */ -+ dev_err(uc->ud->dev, "%s: chan%d invalid direction (%u)\n", -+ __func__, uc->id, uc->config.dir); -+ return -EINVAL; -+ } -+ -+ /* check if the channel configuration was successful */ -+ if (ret) -+ goto err_res_free; -+ -+ if (udma_is_chan_running(uc)) { -+ dev_warn(ud->dev, "chan%d: is running!\n", uc->id); -+ udma_reset_chan(uc, false); -+ if (udma_is_chan_running(uc)) { -+ dev_err(ud->dev, "chan%d: won't stop!\n", uc->id); -+ ret = -EBUSY; -+ goto err_res_free; -+ } -+ } -+ -+ uc->dma_dev = dmaengine_get_dma_device(chan); -+ uc->hdesc_pool = dma_pool_create(uc->name, uc->dma_dev, -+ uc->config.hdesc_size, ud->desc_align, -+ 0); -+ if (!uc->hdesc_pool) { -+ dev_err(ud->ddev.dev, -+ "Descriptor pool allocation failed\n"); -+ uc->use_dma_pool = false; -+ ret = -ENOMEM; -+ goto err_res_free; -+ } -+ -+ uc->use_dma_pool = true; -+ -+ /* PSI-L pairing */ -+ ret = navss_psil_pair(ud, uc->config.src_thread, uc->config.dst_thread); -+ if (ret) { -+ dev_err(ud->dev, "PSI-L pairing failed: 0x%04x -> 0x%04x\n", -+ uc->config.src_thread, uc->config.dst_thread); -+ goto err_res_free; -+ } -+ -+ uc->psil_paired = true; -+ -+ uc->irq_num_ring = ti_sci_inta_msi_get_virq(ud->dev, irq_ring_idx); -+ if (uc->irq_num_ring <= 0) { -+ dev_err(ud->dev, "Failed to get ring irq (index: %u)\n", -+ irq_ring_idx); -+ ret = -EINVAL; -+ goto err_psi_free; -+ } -+ -+ ret = request_irq(uc->irq_num_ring, udma_ring_irq_handler, -+ IRQF_TRIGGER_HIGH, uc->name, uc); -+ if (ret) { -+ dev_err(ud->dev, "chan%d: ring irq request failed\n", uc->id); -+ goto err_irq_free; -+ } -+ -+ uc->irq_num_udma = 0; -+ -+ udma_reset_rings(uc); -+ -+ INIT_DELAYED_WORK_ONSTACK(&uc->tx_drain.work, -+ udma_check_tx_completion); -+ -+ if (uc->tchan) -+ dev_dbg(ud->dev, -+ "chan%d: tchan%d, tflow%d, Remote thread: 0x%04x\n", -+ uc->id, uc->tchan->id, uc->tchan->tflow_id, -+ uc->config.remote_thread_id); -+ else if (uc->rchan) -+ dev_dbg(ud->dev, -+ "chan%d: rchan%d, rflow%d, Remote thread: 0x%04x\n", -+ uc->id, uc->rchan->id, uc->rflow->id, -+ uc->config.remote_thread_id); -+ return 0; -+ -+err_irq_free: -+ uc->irq_num_ring = 0; -+err_psi_free: -+ navss_psil_unpair(ud, uc->config.src_thread, uc->config.dst_thread); -+ uc->psil_paired = false; -+err_res_free: -+ udma_free_tx_resources(uc); -+ udma_free_rx_resources(uc); -+ -+ udma_reset_uchan(uc); -+ -+ dma_pool_destroy(uc->hdesc_pool); -+ uc->use_dma_pool = false; -+ -+ return ret; -+} -+ - static int udma_slave_config(struct dma_chan *chan, - struct dma_slave_config *cfg) - { -@@ -2857,6 +3134,7 @@ udma_prep_slave_sg_pkt(struct udma_chan *uc, struct scatterlist *sgl, - struct udma_desc *d; - u32 ring_id; - unsigned int i; -+ u64 asel; - - d = kzalloc(struct_size(d, hwdesc, sglen), GFP_NOWAIT); - if (!d) -@@ -2870,6 +3148,11 @@ udma_prep_slave_sg_pkt(struct udma_chan *uc, struct scatterlist *sgl, - else - ring_id = k3_ringacc_get_ring_id(uc->tchan->tc_ring); - -+ if (uc->ud->match_data->type == DMA_TYPE_UDMA) -+ asel = 0; -+ else -+ asel = (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT; -+ - for_each_sg(sgl, sgent, sglen, i) { - struct udma_hwdesc *hwdesc = &d->hwdesc[i]; - dma_addr_t sg_addr = sg_dma_address(sgent); -@@ -2904,14 +3187,16 @@ udma_prep_slave_sg_pkt(struct udma_chan *uc, struct scatterlist *sgl, - } - - /* attach the sg buffer to the descriptor */ -+ sg_addr |= asel; - cppi5_hdesc_attach_buf(desc, sg_addr, sg_len, sg_addr, sg_len); - - /* Attach link as host buffer descriptor */ - if (h_desc) - cppi5_hdesc_link_hbdesc(h_desc, -- hwdesc->cppi5_desc_paddr); -+ hwdesc->cppi5_desc_paddr | asel); - -- if (dir == DMA_MEM_TO_DEV) -+ if (uc->ud->match_data->type == DMA_TYPE_PKTDMA || -+ dir == DMA_MEM_TO_DEV) - h_desc = desc; - } - -@@ -3190,6 +3475,9 @@ udma_prep_dma_cyclic_pkt(struct udma_chan *uc, dma_addr_t buf_addr, - else - ring_id = k3_ringacc_get_ring_id(uc->tchan->tc_ring); - -+ if (uc->ud->match_data->type != DMA_TYPE_UDMA) -+ buf_addr |= (u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT; -+ - for (i = 0; i < periods; i++) { - struct udma_hwdesc *hwdesc = &d->hwdesc[i]; - dma_addr_t period_addr = buf_addr + (period_len * i); -@@ -3706,6 +3994,7 @@ static void udma_free_chan_resources(struct dma_chan *chan) - - static struct platform_driver udma_driver; - static struct platform_driver bcdma_driver; -+static struct platform_driver pktdma_driver; - - struct udma_filter_param { - int remote_thread_id; -@@ -3723,7 +4012,8 @@ static bool udma_dma_filter_fn(struct dma_chan *chan, void *param) - struct udma_dev *ud; - - if (chan->device->dev->driver != &udma_driver.driver && -- chan->device->dev->driver != &bcdma_driver.driver) -+ chan->device->dev->driver != &bcdma_driver.driver && -+ chan->device->dev->driver != &pktdma_driver.driver) - return false; - - uc = to_udma_chan(chan); -@@ -3785,6 +4075,15 @@ static bool udma_dma_filter_fn(struct dma_chan *chan, void *param) - ucc->notdpkt = ep_config->notdpkt; - ucc->ep_type = ep_config->ep_type; - -+ if (ud->match_data->type == DMA_TYPE_PKTDMA && -+ ep_config->mapped_channel_id >= 0) { -+ ucc->mapped_channel_id = ep_config->mapped_channel_id; -+ ucc->default_flow_id = ep_config->default_flow_id; -+ } else { -+ ucc->mapped_channel_id = -1; -+ ucc->default_flow_id = -1; -+ } -+ - if (ucc->ep_type != PSIL_EP_NATIVE) { - const struct udma_match_data *match_data = ud->match_data; - -@@ -3901,6 +4200,14 @@ static struct udma_match_data am64_bcdma_data = { - .statictr_z_mask = GENMASK(23, 0), - }; - -+static struct udma_match_data am64_pktdma_data = { -+ .type = DMA_TYPE_PKTDMA, -+ .psil_base = 0x1000, -+ .enable_memcpy_support = false, /* PKTDMA does not support MEM_TO_MEM */ -+ .flags = UDMA_FLAG_PDMA_ACC32 | UDMA_FLAG_PDMA_BURST | UDMA_FLAG_TDTYPE, -+ .statictr_z_mask = GENMASK(23, 0), -+}; -+ - static const struct of_device_id udma_of_match[] = { - { - .compatible = "ti,am654-navss-main-udmap", -@@ -3927,6 +4234,14 @@ static const struct of_device_id bcdma_of_match[] = { - { /* Sentinel */ }, - }; - -+static const struct of_device_id pktdma_of_match[] = { -+ { -+ .compatible = "ti,am64-dmss-pktdma", -+ .data = &am64_pktdma_data, -+ }, -+ { /* Sentinel */ }, -+}; -+ - static struct udma_soc_data am654_soc_data = { - .oes = { - .udma_rchan = 0x200, -@@ -3953,6 +4268,8 @@ static struct udma_soc_data am64_soc_data = { - .bcdma_tchan_ring = 0x2a00, - .bcdma_rchan_data = 0x2e00, - .bcdma_rchan_ring = 0x3000, -+ .pktdma_tchan_flow = 0x1200, -+ .pktdma_rchan_flow = 0x1600, - }, - .bcdma_trigger_event_offset = 0xc400, - }; -@@ -3967,7 +4284,7 @@ static const struct soc_device_attribute k3_soc_devices[] = { - - static int udma_get_mmrs(struct platform_device *pdev, struct udma_dev *ud) - { -- u32 cap2, cap3; -+ u32 cap2, cap3, cap4; - int i; - - ud->mmrs[MMR_GCFG] = devm_platform_ioremap_resource_byname(pdev, mmr_names[MMR_GCFG]); -@@ -3989,6 +4306,13 @@ static int udma_get_mmrs(struct platform_device *pdev, struct udma_dev *ud) - ud->tchan_cnt = BCDMA_CAP2_TCHAN_CNT(cap2); - ud->rchan_cnt = BCDMA_CAP2_RCHAN_CNT(cap2); - break; -+ case DMA_TYPE_PKTDMA: -+ cap4 = udma_read(ud->mmrs[MMR_GCFG], 0x30); -+ ud->tchan_cnt = UDMA_CAP2_TCHAN_CNT(cap2); -+ ud->rchan_cnt = UDMA_CAP2_RCHAN_CNT(cap2); -+ ud->rflow_cnt = UDMA_CAP3_RFLOW_CNT(cap3); -+ ud->tflow_cnt = PKTDMA_CAP4_TFLOW_CNT(cap4); -+ break; - default: - return -EINVAL; - } -@@ -4024,7 +4348,8 @@ static const char * const range_names[] = { - [RM_RANGE_BCHAN] = "ti,sci-rm-range-bchan", - [RM_RANGE_TCHAN] = "ti,sci-rm-range-tchan", - [RM_RANGE_RCHAN] = "ti,sci-rm-range-rchan", -- [RM_RANGE_RFLOW] = "ti,sci-rm-range-rflow" -+ [RM_RANGE_RFLOW] = "ti,sci-rm-range-rflow", -+ [RM_RANGE_TFLOW] = "ti,sci-rm-range-tflow", - }; - - static int udma_setup_resources(struct udma_dev *ud) -@@ -4098,7 +4423,7 @@ static int udma_setup_resources(struct udma_dev *ud) - - /* Get resource ranges from tisci */ - for (i = 0; i < RM_RANGE_LAST; i++) { -- if (i == RM_RANGE_BCHAN) -+ if (i == RM_RANGE_BCHAN || i == RM_RANGE_TFLOW) - continue; - - tisci_rm->rm_ranges[i] = -@@ -4245,7 +4570,7 @@ static int bcdma_setup_resources(struct udma_dev *ud) - - /* Get resource ranges from tisci */ - for (i = 0; i < RM_RANGE_LAST; i++) { -- if (i == RM_RANGE_RFLOW) -+ if (i == RM_RANGE_RFLOW || i == RM_RANGE_TFLOW) - continue; - if (i == RM_RANGE_BCHAN && ud->bchan_cnt == 0) - continue; -@@ -4351,6 +4676,134 @@ static int bcdma_setup_resources(struct udma_dev *ud) - return 0; - } - -+static int pktdma_setup_resources(struct udma_dev *ud) -+{ -+ int ret, i, j; -+ struct device *dev = ud->dev; -+ struct ti_sci_resource *rm_res, irq_res; -+ struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; -+ const struct udma_oes_offsets *oes = &ud->soc_data->oes; -+ u32 cap3; -+ -+ /* Set up the throughput level start indexes */ -+ cap3 = udma_read(ud->mmrs[MMR_GCFG], 0x2c); -+ if (UDMA_CAP3_UCHAN_CNT(cap3)) { -+ ud->tchan_tpl.levels = 3; -+ ud->tchan_tpl.start_idx[1] = UDMA_CAP3_UCHAN_CNT(cap3); -+ ud->tchan_tpl.start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3); -+ } else if (UDMA_CAP3_HCHAN_CNT(cap3)) { -+ ud->tchan_tpl.levels = 2; -+ ud->tchan_tpl.start_idx[0] = UDMA_CAP3_HCHAN_CNT(cap3); -+ } else { -+ ud->tchan_tpl.levels = 1; -+ } -+ -+ ud->tchan_tpl.levels = ud->tchan_tpl.levels; -+ ud->tchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0]; -+ ud->tchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1]; -+ -+ ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt), -+ sizeof(unsigned long), GFP_KERNEL); -+ ud->tchans = devm_kcalloc(dev, ud->tchan_cnt, sizeof(*ud->tchans), -+ GFP_KERNEL); -+ ud->rchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->rchan_cnt), -+ sizeof(unsigned long), GFP_KERNEL); -+ ud->rchans = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rchans), -+ GFP_KERNEL); -+ ud->rflow_in_use = devm_kcalloc(dev, BITS_TO_LONGS(ud->rflow_cnt), -+ sizeof(unsigned long), -+ GFP_KERNEL); -+ ud->rflows = devm_kcalloc(dev, ud->rflow_cnt, sizeof(*ud->rflows), -+ GFP_KERNEL); -+ ud->tflow_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tflow_cnt), -+ sizeof(unsigned long), GFP_KERNEL); -+ -+ if (!ud->tchan_map || !ud->rchan_map || !ud->tflow_map || !ud->tchans || -+ !ud->rchans || !ud->rflows || !ud->rflow_in_use) -+ return -ENOMEM; -+ -+ /* Get resource ranges from tisci */ -+ for (i = 0; i < RM_RANGE_LAST; i++) { -+ if (i == RM_RANGE_BCHAN) -+ continue; -+ -+ tisci_rm->rm_ranges[i] = -+ devm_ti_sci_get_of_resource(tisci_rm->tisci, dev, -+ tisci_rm->tisci_dev_id, -+ (char *)range_names[i]); -+ } -+ -+ /* tchan ranges */ -+ rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN]; -+ if (IS_ERR(rm_res)) { -+ bitmap_zero(ud->tchan_map, ud->tchan_cnt); -+ } else { -+ bitmap_fill(ud->tchan_map, ud->tchan_cnt); -+ for (i = 0; i < rm_res->sets; i++) -+ udma_mark_resource_ranges(ud, ud->tchan_map, -+ &rm_res->desc[i], "tchan"); -+ } -+ -+ /* rchan ranges */ -+ rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN]; -+ if (IS_ERR(rm_res)) { -+ bitmap_zero(ud->rchan_map, ud->rchan_cnt); -+ } else { -+ bitmap_fill(ud->rchan_map, ud->rchan_cnt); -+ for (i = 0; i < rm_res->sets; i++) -+ udma_mark_resource_ranges(ud, ud->rchan_map, -+ &rm_res->desc[i], "rchan"); -+ } -+ -+ /* rflow ranges */ -+ rm_res = tisci_rm->rm_ranges[RM_RANGE_RFLOW]; -+ if (IS_ERR(rm_res)) { -+ /* all rflows are assigned exclusively to Linux */ -+ bitmap_zero(ud->rflow_in_use, ud->rflow_cnt); -+ } else { -+ bitmap_fill(ud->rflow_in_use, ud->rflow_cnt); -+ for (i = 0; i < rm_res->sets; i++) -+ udma_mark_resource_ranges(ud, ud->rflow_in_use, -+ &rm_res->desc[i], "rflow"); -+ } -+ irq_res.sets = rm_res->sets; -+ -+ /* tflow ranges */ -+ rm_res = tisci_rm->rm_ranges[RM_RANGE_TFLOW]; -+ if (IS_ERR(rm_res)) { -+ /* all tflows are assigned exclusively to Linux */ -+ bitmap_zero(ud->tflow_map, ud->tflow_cnt); -+ } else { -+ bitmap_fill(ud->tflow_map, ud->tflow_cnt); -+ for (i = 0; i < rm_res->sets; i++) -+ udma_mark_resource_ranges(ud, ud->tflow_map, -+ &rm_res->desc[i], "tflow"); -+ } -+ irq_res.sets += rm_res->sets; -+ -+ irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL); -+ rm_res = tisci_rm->rm_ranges[RM_RANGE_TFLOW]; -+ for (i = 0; i < rm_res->sets; i++) { -+ irq_res.desc[i].start = rm_res->desc[i].start + -+ oes->pktdma_tchan_flow; -+ irq_res.desc[i].num = rm_res->desc[i].num; -+ } -+ rm_res = tisci_rm->rm_ranges[RM_RANGE_RFLOW]; -+ for (j = 0; j < rm_res->sets; j++, i++) { -+ irq_res.desc[i].start = rm_res->desc[j].start + -+ oes->pktdma_rchan_flow; -+ irq_res.desc[i].num = rm_res->desc[j].num; -+ } -+ ret = ti_sci_inta_msi_domain_alloc_irqs(ud->dev, &irq_res); -+ kfree(irq_res.desc); -+ if (ret) { -+ dev_err(ud->dev, "Failed to allocate MSI interrupts\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ - static int setup_resources(struct udma_dev *ud) - { - struct device *dev = ud->dev; -@@ -4363,6 +4816,9 @@ static int setup_resources(struct udma_dev *ud) - case DMA_TYPE_BCDMA: - ret = bcdma_setup_resources(ud); - break; -+ case DMA_TYPE_PKTDMA: -+ ret = pktdma_setup_resources(ud); -+ break; - default: - return -EINVAL; - } -@@ -4406,6 +4862,14 @@ static int setup_resources(struct udma_dev *ud) - ud->rchan_cnt - bitmap_weight(ud->rchan_map, - ud->rchan_cnt)); - break; -+ case DMA_TYPE_PKTDMA: -+ dev_info(dev, -+ "Channels: %d (tchan: %u, rchan: %u)\n", -+ ch_count, -+ ud->tchan_cnt - bitmap_weight(ud->tchan_map, -+ ud->tchan_cnt), -+ ud->rchan_cnt - bitmap_weight(ud->rchan_map, -+ ud->rchan_cnt)); - default: - break; - } -@@ -4536,10 +5000,14 @@ static void udma_dbg_summary_show_chan(struct seq_file *s, - case DMA_DEV_TO_MEM: - seq_printf(s, "rchan%d [0x%04x -> 0x%04x], ", uc->rchan->id, - ucc->src_thread, ucc->dst_thread); -+ if (uc->ud->match_data->type == DMA_TYPE_PKTDMA) -+ seq_printf(s, "rflow%d, ", uc->rflow->id); - break; - case DMA_MEM_TO_DEV: - seq_printf(s, "tchan%d [0x%04x -> 0x%04x], ", uc->tchan->id, - ucc->src_thread, ucc->dst_thread); -+ if (uc->ud->match_data->type == DMA_TYPE_PKTDMA) -+ seq_printf(s, "tflow%d, ", uc->tchan->tflow_id); - break; - default: - seq_printf(s, ")\n"); -@@ -4602,8 +5070,10 @@ static int udma_probe(struct platform_device *pdev) - return -ENOMEM; - - match = of_match_node(udma_of_match, dev->of_node); -- if (!match) { -+ if (!match) - match = of_match_node(bcdma_of_match, dev->of_node); -+ if (!match) { -+ match = of_match_node(pktdma_of_match, dev->of_node); - if (!match) { - dev_err(dev, "No compatible match found\n"); - return -ENODEV; -@@ -4667,8 +5137,14 @@ static int udma_probe(struct platform_device *pdev) - - ring_init_data.tisci = ud->tisci_rm.tisci; - ring_init_data.tisci_dev_id = ud->tisci_rm.tisci_dev_id; -- ring_init_data.num_rings = ud->bchan_cnt + ud->tchan_cnt + -- ud->rchan_cnt; -+ if (ud->match_data->type == DMA_TYPE_BCDMA) { -+ ring_init_data.num_rings = ud->bchan_cnt + -+ ud->tchan_cnt + -+ ud->rchan_cnt; -+ } else { -+ ring_init_data.num_rings = ud->rflow_cnt + -+ ud->tflow_cnt; -+ } - - ud->ringacc = k3_ringacc_dmarings_init(pdev, &ring_init_data); - } -@@ -4684,11 +5160,14 @@ static int udma_probe(struct platform_device *pdev) - } - - dma_cap_set(DMA_SLAVE, ud->ddev.cap_mask); -- dma_cap_set(DMA_CYCLIC, ud->ddev.cap_mask); -+ /* cyclic operation is not supported via PKTDMA */ -+ if (ud->match_data->type != DMA_TYPE_PKTDMA) { -+ dma_cap_set(DMA_CYCLIC, ud->ddev.cap_mask); -+ ud->ddev.device_prep_dma_cyclic = udma_prep_dma_cyclic; -+ } - - ud->ddev.device_config = udma_slave_config; - ud->ddev.device_prep_slave_sg = udma_prep_slave_sg; -- ud->ddev.device_prep_dma_cyclic = udma_prep_dma_cyclic; - ud->ddev.device_issue_pending = udma_issue_pending; - ud->ddev.device_tx_status = udma_tx_status; - ud->ddev.device_pause = udma_pause; -@@ -4709,6 +5188,10 @@ static int udma_probe(struct platform_device *pdev) - bcdma_alloc_chan_resources; - ud->ddev.device_router_config = bcdma_router_config; - break; -+ case DMA_TYPE_PKTDMA: -+ ud->ddev.device_alloc_chan_resources = -+ pktdma_alloc_chan_resources; -+ break; - default: - return -EINVAL; - } -@@ -4787,6 +5270,8 @@ static int udma_probe(struct platform_device *pdev) - uc->tchan = NULL; - uc->rchan = NULL; - uc->config.remote_thread_id = -1; -+ uc->config.mapped_channel_id = -1; -+ uc->config.default_flow_id = -1; - uc->config.dir = DMA_MEM_TO_MEM; - uc->name = devm_kasprintf(dev, GFP_KERNEL, "%s chan%d", - dev_name(dev), i); -@@ -4835,5 +5320,15 @@ static struct platform_driver bcdma_driver = { - }; - builtin_platform_driver(bcdma_driver); - -+static struct platform_driver pktdma_driver = { -+ .driver = { -+ .name = "ti-pktdma", -+ .of_match_table = pktdma_of_match, -+ .suppress_bind_attrs = true, -+ }, -+ .probe = udma_probe, -+}; -+builtin_platform_driver(pktdma_driver); -+ - /* Private interfaces to UDMA */ - #include "k3-udma-private.c" -diff --git a/drivers/dma/ti/k3-udma.h b/drivers/dma/ti/k3-udma.h -index 3ec38b383b76..ccb19f286daf 100644 ---- a/drivers/dma/ti/k3-udma.h -+++ b/drivers/dma/ti/k3-udma.h -@@ -55,6 +55,8 @@ - #define BCDMA_CAP4_HTCHAN_CNT(val) (((val) >> 16) & 0xff) - #define BCDMA_CAP4_UTCHAN_CNT(val) (((val) >> 24) & 0xff) - -+#define PKTDMA_CAP4_TFLOW_CNT(val) ((val) & 0x3fff) -+ - /* UDMA_CHAN_RT_CTL_REG */ - #define UDMA_CHAN_RT_CTL_EN BIT(31) - #define UDMA_CHAN_RT_CTL_TDOWN BIT(30) -@@ -105,6 +107,7 @@ enum udma_rm_range { - RM_RANGE_TCHAN, - RM_RANGE_RCHAN, - RM_RANGE_RFLOW, -+ RM_RANGE_TFLOW, - RM_RANGE_LAST, - }; - -@@ -152,5 +155,6 @@ void xudma_tchanrt_write(struct udma_tchan *tchan, int reg, u32 val); - u32 xudma_rchanrt_read(struct udma_rchan *rchan, int reg); - void xudma_rchanrt_write(struct udma_rchan *rchan, int reg, u32 val); - bool xudma_rflow_is_gp(struct udma_dev *ud, int id); -+int xudma_get_rflow_ring_offset(struct udma_dev *ud); - - #endif /* K3_UDMA_H_ */ diff --git a/recipes-kernel/linux/files/patches-5.10/0135-dmaengine-ti-k3-udma-glue-Add-support-for-K3-PKTDMA.patch b/recipes-kernel/linux/files/patches-5.10/0135-dmaengine-ti-k3-udma-glue-Add-support-for-K3-PKTDMA.patch deleted file mode 100644 index 76c8d59e1..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0135-dmaengine-ti-k3-udma-glue-Add-support-for-K3-PKTDMA.patch +++ /dev/null @@ -1,652 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Tue, 8 Dec 2020 11:04:40 +0200 -Subject: [PATCH] dmaengine: ti: k3-udma-glue: Add support for K3 PKTDMA - -commit 5b65781d06ea90ef2f8e51a13352c43c3daa8cdc upstream. - -This commit adds support for PKTDMA in k3-udma glue driver. Use new -psil_endpoint_config struct to get static data for a given channel or a -flow during setup. Make sure that the RX flows being mapped to a RX -channel is within the range of flows that is been allocated to that RX -channel. - -Signed-off-by: Vignesh Raghavendra -Signed-off-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20201208090440.31792-21-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit '5b65781d06ea' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/k3-udma-glue.c | 291 +++++++++++++++++++++++++++---- - drivers/dma/ti/k3-udma-private.c | 24 +++ - drivers/dma/ti/k3-udma.h | 4 + - include/linux/dma/k3-udma-glue.h | 8 + - 4 files changed, 289 insertions(+), 38 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c -index e6ebcd98c02a..4fdd9f06b723 100644 ---- a/drivers/dma/ti/k3-udma-glue.c -+++ b/drivers/dma/ti/k3-udma-glue.c -@@ -22,6 +22,7 @@ - - struct k3_udma_glue_common { - struct device *dev; -+ struct device chan_dev; - struct udma_dev *udmax; - const struct udma_tisci_rm *tisci_rm; - struct k3_ringacc *ringacc; -@@ -32,7 +33,8 @@ struct k3_udma_glue_common { - bool epib; - u32 psdata_size; - u32 swdata_size; -- u32 atype; -+ u32 atype_asel; -+ struct psil_endpoint_config *ep_config; - }; - - struct k3_udma_glue_tx_channel { -@@ -53,6 +55,8 @@ struct k3_udma_glue_tx_channel { - bool tx_filt_einfo; - bool tx_filt_pswords; - bool tx_supr_tdpkt; -+ -+ int udma_tflow_id; - }; - - struct k3_udma_glue_rx_flow { -@@ -81,6 +85,16 @@ struct k3_udma_glue_rx_channel { - u32 flows_ready; - }; - -+static void k3_udma_chan_dev_release(struct device *dev) -+{ -+ /* The struct containing the device is devm managed */ -+} -+ -+static struct class k3_udma_glue_devclass = { -+ .name = "k3_udma_glue_chan", -+ .dev_release = k3_udma_chan_dev_release, -+}; -+ - #define K3_UDMAX_TDOWN_TIMEOUT_US 1000 - - static int of_k3_udma_glue_parse(struct device_node *udmax_np, -@@ -100,7 +114,6 @@ static int of_k3_udma_glue_parse_chn(struct device_node *chn_np, - const char *name, struct k3_udma_glue_common *common, - bool tx_chn) - { -- struct psil_endpoint_config *ep_config; - struct of_phandle_args dma_spec; - u32 thread_id; - int ret = 0; -@@ -117,15 +130,26 @@ static int of_k3_udma_glue_parse_chn(struct device_node *chn_np, - &dma_spec)) - return -ENOENT; - -+ ret = of_k3_udma_glue_parse(dma_spec.np, common); -+ if (ret) -+ goto out_put_spec; -+ - thread_id = dma_spec.args[0]; - if (dma_spec.args_count == 2) { -- if (dma_spec.args[1] > 2) { -+ if (dma_spec.args[1] > 2 && !xudma_is_pktdma(common->udmax)) { - dev_err(common->dev, "Invalid channel atype: %u\n", - dma_spec.args[1]); - ret = -EINVAL; - goto out_put_spec; - } -- common->atype = dma_spec.args[1]; -+ if (dma_spec.args[1] > 15 && xudma_is_pktdma(common->udmax)) { -+ dev_err(common->dev, "Invalid channel asel: %u\n", -+ dma_spec.args[1]); -+ ret = -EINVAL; -+ goto out_put_spec; -+ } -+ -+ common->atype_asel = dma_spec.args[1]; - } - - if (tx_chn && !(thread_id & K3_PSIL_DST_THREAD_ID_OFFSET)) { -@@ -139,25 +163,23 @@ static int of_k3_udma_glue_parse_chn(struct device_node *chn_np, - } - - /* get psil endpoint config */ -- ep_config = psil_get_ep_config(thread_id); -- if (IS_ERR(ep_config)) { -+ common->ep_config = psil_get_ep_config(thread_id); -+ if (IS_ERR(common->ep_config)) { - dev_err(common->dev, - "No configuration for psi-l thread 0x%04x\n", - thread_id); -- ret = PTR_ERR(ep_config); -+ ret = PTR_ERR(common->ep_config); - goto out_put_spec; - } - -- common->epib = ep_config->needs_epib; -- common->psdata_size = ep_config->psd_size; -+ common->epib = common->ep_config->needs_epib; -+ common->psdata_size = common->ep_config->psd_size; - - if (tx_chn) - common->dst_thread = thread_id; - else - common->src_thread = thread_id; - -- ret = of_k3_udma_glue_parse(dma_spec.np, common); -- - out_put_spec: - of_node_put(dma_spec.np); - return ret; -@@ -223,7 +245,7 @@ static int k3_udma_glue_cfg_tx_chn(struct k3_udma_glue_tx_channel *tx_chn) - req.tx_supr_tdpkt = 1; - req.tx_fetch_size = tx_chn->common.hdesc_size >> 2; - req.txcq_qnum = k3_ringacc_get_ring_id(tx_chn->ringtxcq); -- req.tx_atype = tx_chn->common.atype; -+ req.tx_atype = tx_chn->common.atype_asel; - - return tisci_rm->tisci_udmap_ops->tx_ch_cfg(tisci_rm->tisci, &req); - } -@@ -255,8 +277,14 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev, - tx_chn->common.psdata_size, - tx_chn->common.swdata_size); - -+ if (xudma_is_pktdma(tx_chn->common.udmax)) -+ tx_chn->udma_tchan_id = tx_chn->common.ep_config->mapped_channel_id; -+ else -+ tx_chn->udma_tchan_id = -1; -+ - /* request and cfg UDMAP TX channel */ -- tx_chn->udma_tchanx = xudma_tchan_get(tx_chn->common.udmax, -1); -+ tx_chn->udma_tchanx = xudma_tchan_get(tx_chn->common.udmax, -+ tx_chn->udma_tchan_id); - if (IS_ERR(tx_chn->udma_tchanx)) { - ret = PTR_ERR(tx_chn->udma_tchanx); - dev_err(dev, "UDMAX tchanx get err %d\n", ret); -@@ -264,11 +292,34 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev, - } - tx_chn->udma_tchan_id = xudma_tchan_get_id(tx_chn->udma_tchanx); - -+ tx_chn->common.chan_dev.class = &k3_udma_glue_devclass; -+ tx_chn->common.chan_dev.parent = xudma_get_device(tx_chn->common.udmax); -+ dev_set_name(&tx_chn->common.chan_dev, "tchan%d-0x%04x", -+ tx_chn->udma_tchan_id, tx_chn->common.dst_thread); -+ ret = device_register(&tx_chn->common.chan_dev); -+ if (ret) { -+ dev_err(dev, "Channel Device registration failed %d\n", ret); -+ tx_chn->common.chan_dev.parent = NULL; -+ goto err; -+ } -+ -+ if (xudma_is_pktdma(tx_chn->common.udmax)) { -+ /* prepare the channel device as coherent */ -+ tx_chn->common.chan_dev.dma_coherent = true; -+ dma_coerce_mask_and_coherent(&tx_chn->common.chan_dev, -+ DMA_BIT_MASK(48)); -+ } -+ - atomic_set(&tx_chn->free_pkts, cfg->txcq_cfg.size); - -+ if (xudma_is_pktdma(tx_chn->common.udmax)) -+ tx_chn->udma_tflow_id = tx_chn->common.ep_config->default_flow_id; -+ else -+ tx_chn->udma_tflow_id = tx_chn->udma_tchan_id; -+ - /* request and cfg rings */ - ret = k3_ringacc_request_rings_pair(tx_chn->common.ringacc, -- tx_chn->udma_tchan_id, -1, -+ tx_chn->udma_tflow_id, -1, - &tx_chn->ringtx, - &tx_chn->ringtxcq); - if (ret) { -@@ -280,6 +331,12 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev, - cfg->tx_cfg.dma_dev = k3_udma_glue_tx_get_dma_device(tx_chn); - cfg->txcq_cfg.dma_dev = cfg->tx_cfg.dma_dev; - -+ /* Set the ASEL value for DMA rings of PKTDMA */ -+ if (xudma_is_pktdma(tx_chn->common.udmax)) { -+ cfg->tx_cfg.asel = tx_chn->common.atype_asel; -+ cfg->txcq_cfg.asel = tx_chn->common.atype_asel; -+ } -+ - ret = k3_ringacc_ring_cfg(tx_chn->ringtx, &cfg->tx_cfg); - if (ret) { - dev_err(dev, "Failed to cfg ringtx %d\n", ret); -@@ -331,6 +388,11 @@ void k3_udma_glue_release_tx_chn(struct k3_udma_glue_tx_channel *tx_chn) - - if (tx_chn->ringtx) - k3_ringacc_ring_free(tx_chn->ringtx); -+ -+ if (tx_chn->common.chan_dev.parent) { -+ device_unregister(&tx_chn->common.chan_dev); -+ tx_chn->common.chan_dev.parent = NULL; -+ } - } - EXPORT_SYMBOL_GPL(k3_udma_glue_release_tx_chn); - -@@ -443,13 +505,10 @@ void k3_udma_glue_reset_tx_chn(struct k3_udma_glue_tx_channel *tx_chn, - void *data, - void (*cleanup)(void *data, dma_addr_t desc_dma)) - { -+ struct device *dev = tx_chn->common.dev; - dma_addr_t desc_dma; - int occ_tx, i, ret; - -- /* reset TXCQ as it is not input for udma - expected to be empty */ -- if (tx_chn->ringtxcq) -- k3_ringacc_ring_reset(tx_chn->ringtxcq); -- - /* - * TXQ reset need to be special way as it is input for udma and its - * state cached by udma, so: -@@ -458,17 +517,20 @@ void k3_udma_glue_reset_tx_chn(struct k3_udma_glue_tx_channel *tx_chn, - * 3) reset TXQ in a special way - */ - occ_tx = k3_ringacc_ring_get_occ(tx_chn->ringtx); -- dev_dbg(tx_chn->common.dev, "TX reset occ_tx %u\n", occ_tx); -+ dev_dbg(dev, "TX reset occ_tx %u\n", occ_tx); - - for (i = 0; i < occ_tx; i++) { - ret = k3_ringacc_ring_pop(tx_chn->ringtx, &desc_dma); - if (ret) { -- dev_err(tx_chn->common.dev, "TX reset pop %d\n", ret); -+ if (ret != -ENODATA) -+ dev_err(dev, "TX reset pop %d\n", ret); - break; - } - cleanup(data, desc_dma); - } - -+ /* reset TXCQ as it is not input for udma - expected to be empty */ -+ k3_ringacc_ring_reset(tx_chn->ringtxcq); - k3_ringacc_ring_reset_dma(tx_chn->ringtx, occ_tx); - } - EXPORT_SYMBOL_GPL(k3_udma_glue_reset_tx_chn); -@@ -487,7 +549,12 @@ EXPORT_SYMBOL_GPL(k3_udma_glue_tx_get_txcq_id); - - int k3_udma_glue_tx_get_irq(struct k3_udma_glue_tx_channel *tx_chn) - { -- tx_chn->virq = k3_ringacc_get_ring_irq_num(tx_chn->ringtxcq); -+ if (xudma_is_pktdma(tx_chn->common.udmax)) { -+ tx_chn->virq = xudma_pktdma_tflow_get_irq(tx_chn->common.udmax, -+ tx_chn->udma_tflow_id); -+ } else { -+ tx_chn->virq = k3_ringacc_get_ring_irq_num(tx_chn->ringtxcq); -+ } - - return tx_chn->virq; - } -@@ -496,10 +563,36 @@ EXPORT_SYMBOL_GPL(k3_udma_glue_tx_get_irq); - struct device * - k3_udma_glue_tx_get_dma_device(struct k3_udma_glue_tx_channel *tx_chn) - { -+ if (xudma_is_pktdma(tx_chn->common.udmax) && -+ (tx_chn->common.atype_asel == 14 || tx_chn->common.atype_asel == 15)) -+ return &tx_chn->common.chan_dev; -+ - return xudma_get_device(tx_chn->common.udmax); - } - EXPORT_SYMBOL_GPL(k3_udma_glue_tx_get_dma_device); - -+void k3_udma_glue_tx_dma_to_cppi5_addr(struct k3_udma_glue_tx_channel *tx_chn, -+ dma_addr_t *addr) -+{ -+ if (!xudma_is_pktdma(tx_chn->common.udmax) || -+ !tx_chn->common.atype_asel) -+ return; -+ -+ *addr |= (u64)tx_chn->common.atype_asel << K3_ADDRESS_ASEL_SHIFT; -+} -+EXPORT_SYMBOL_GPL(k3_udma_glue_tx_dma_to_cppi5_addr); -+ -+void k3_udma_glue_tx_cppi5_to_dma_addr(struct k3_udma_glue_tx_channel *tx_chn, -+ dma_addr_t *addr) -+{ -+ if (!xudma_is_pktdma(tx_chn->common.udmax) || -+ !tx_chn->common.atype_asel) -+ return; -+ -+ *addr &= (u64)GENMASK(K3_ADDRESS_ASEL_SHIFT - 1, 0); -+} -+EXPORT_SYMBOL_GPL(k3_udma_glue_tx_cppi5_to_dma_addr); -+ - static int k3_udma_glue_cfg_rx_chn(struct k3_udma_glue_rx_channel *rx_chn) - { - const struct udma_tisci_rm *tisci_rm = rx_chn->common.tisci_rm; -@@ -511,8 +604,6 @@ static int k3_udma_glue_cfg_rx_chn(struct k3_udma_glue_rx_channel *rx_chn) - req.valid_params = TI_SCI_MSG_VALUE_RM_UDMAP_CH_FETCH_SIZE_VALID | - TI_SCI_MSG_VALUE_RM_UDMAP_CH_CQ_QNUM_VALID | - TI_SCI_MSG_VALUE_RM_UDMAP_CH_CHAN_TYPE_VALID | -- TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_START_VALID | -- TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_CNT_VALID | - TI_SCI_MSG_VALUE_RM_UDMAP_CH_ATYPE_VALID; - - req.nav_id = tisci_rm->tisci_dev_id; -@@ -524,13 +615,16 @@ static int k3_udma_glue_cfg_rx_chn(struct k3_udma_glue_rx_channel *rx_chn) - * req.rxcq_qnum = k3_ringacc_get_ring_id(rx_chn->flows[0].ringrx); - */ - req.rxcq_qnum = 0xFFFF; -- if (rx_chn->flow_num && rx_chn->flow_id_base != rx_chn->udma_rchan_id) { -+ if (!xudma_is_pktdma(rx_chn->common.udmax) && rx_chn->flow_num && -+ rx_chn->flow_id_base != rx_chn->udma_rchan_id) { - /* Default flow + extra ones */ -+ req.valid_params |= TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_START_VALID | -+ TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_CNT_VALID; - req.flowid_start = rx_chn->flow_id_base; - req.flowid_cnt = rx_chn->flow_num; - } - req.rx_chan_type = TI_SCI_RM_UDMAP_CHAN_TYPE_PKT_PBRR; -- req.rx_atype = rx_chn->common.atype; -+ req.rx_atype = rx_chn->common.atype_asel; - - ret = tisci_rm->tisci_udmap_ops->rx_ch_cfg(tisci_rm->tisci, &req); - if (ret) -@@ -584,10 +678,18 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn, - goto err_rflow_put; - } - -+ if (xudma_is_pktdma(rx_chn->common.udmax)) { -+ rx_ringfdq_id = flow->udma_rflow_id + -+ xudma_get_rflow_ring_offset(rx_chn->common.udmax); -+ rx_ring_id = 0; -+ } else { -+ rx_ring_id = flow_cfg->ring_rxq_id; -+ rx_ringfdq_id = flow_cfg->ring_rxfdq0_id; -+ } -+ - /* request and cfg rings */ - ret = k3_ringacc_request_rings_pair(rx_chn->common.ringacc, -- flow_cfg->ring_rxfdq0_id, -- flow_cfg->ring_rxq_id, -+ rx_ringfdq_id, rx_ring_id, - &flow->ringrxfdq, - &flow->ringrx); - if (ret) { -@@ -599,6 +701,12 @@ static int k3_udma_glue_cfg_rx_flow(struct k3_udma_glue_rx_channel *rx_chn, - flow_cfg->rx_cfg.dma_dev = k3_udma_glue_rx_get_dma_device(rx_chn); - flow_cfg->rxfdq_cfg.dma_dev = flow_cfg->rx_cfg.dma_dev; - -+ /* Set the ASEL value for DMA rings of PKTDMA */ -+ if (xudma_is_pktdma(rx_chn->common.udmax)) { -+ flow_cfg->rx_cfg.asel = rx_chn->common.atype_asel; -+ flow_cfg->rxfdq_cfg.asel = rx_chn->common.atype_asel; -+ } -+ - ret = k3_ringacc_ring_cfg(flow->ringrx, &flow_cfg->rx_cfg); - if (ret) { - dev_err(dev, "Failed to cfg ringrx %d\n", ret); -@@ -757,6 +865,7 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, const char *name, - struct k3_udma_glue_rx_channel_cfg *cfg) - { - struct k3_udma_glue_rx_channel *rx_chn; -+ struct psil_endpoint_config *ep_cfg; - int ret, i; - - if (cfg->flow_id_num <= 0) -@@ -784,8 +893,16 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, const char *name, - rx_chn->common.psdata_size, - rx_chn->common.swdata_size); - -+ ep_cfg = rx_chn->common.ep_config; -+ -+ if (xudma_is_pktdma(rx_chn->common.udmax)) -+ rx_chn->udma_rchan_id = ep_cfg->mapped_channel_id; -+ else -+ rx_chn->udma_rchan_id = -1; -+ - /* request and cfg UDMAP RX channel */ -- rx_chn->udma_rchanx = xudma_rchan_get(rx_chn->common.udmax, -1); -+ rx_chn->udma_rchanx = xudma_rchan_get(rx_chn->common.udmax, -+ rx_chn->udma_rchan_id); - if (IS_ERR(rx_chn->udma_rchanx)) { - ret = PTR_ERR(rx_chn->udma_rchanx); - dev_err(dev, "UDMAX rchanx get err %d\n", ret); -@@ -793,12 +910,48 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, const char *name, - } - rx_chn->udma_rchan_id = xudma_rchan_get_id(rx_chn->udma_rchanx); - -- rx_chn->flow_num = cfg->flow_id_num; -- rx_chn->flow_id_base = cfg->flow_id_base; -+ rx_chn->common.chan_dev.class = &k3_udma_glue_devclass; -+ rx_chn->common.chan_dev.parent = xudma_get_device(rx_chn->common.udmax); -+ dev_set_name(&rx_chn->common.chan_dev, "rchan%d-0x%04x", -+ rx_chn->udma_rchan_id, rx_chn->common.src_thread); -+ ret = device_register(&rx_chn->common.chan_dev); -+ if (ret) { -+ dev_err(dev, "Channel Device registration failed %d\n", ret); -+ rx_chn->common.chan_dev.parent = NULL; -+ goto err; -+ } - -- /* Use RX channel id as flow id: target dev can't generate flow_id */ -- if (cfg->flow_id_use_rxchan_id) -- rx_chn->flow_id_base = rx_chn->udma_rchan_id; -+ if (xudma_is_pktdma(rx_chn->common.udmax)) { -+ /* prepare the channel device as coherent */ -+ rx_chn->common.chan_dev.dma_coherent = true; -+ dma_coerce_mask_and_coherent(&rx_chn->common.chan_dev, -+ DMA_BIT_MASK(48)); -+ } -+ -+ if (xudma_is_pktdma(rx_chn->common.udmax)) { -+ int flow_start = cfg->flow_id_base; -+ int flow_end; -+ -+ if (flow_start == -1) -+ flow_start = ep_cfg->flow_start; -+ -+ flow_end = flow_start + cfg->flow_id_num - 1; -+ if (flow_start < ep_cfg->flow_start || -+ flow_end > (ep_cfg->flow_start + ep_cfg->flow_num - 1)) { -+ dev_err(dev, "Invalid flow range requested\n"); -+ ret = -EINVAL; -+ goto err; -+ } -+ rx_chn->flow_id_base = flow_start; -+ } else { -+ rx_chn->flow_id_base = cfg->flow_id_base; -+ -+ /* Use RX channel id as flow id: target dev can't generate flow_id */ -+ if (cfg->flow_id_use_rxchan_id) -+ rx_chn->flow_id_base = rx_chn->udma_rchan_id; -+ } -+ -+ rx_chn->flow_num = cfg->flow_id_num; - - rx_chn->flows = devm_kcalloc(dev, rx_chn->flow_num, - sizeof(*rx_chn->flows), GFP_KERNEL); -@@ -888,6 +1041,24 @@ k3_udma_glue_request_remote_rx_chn(struct device *dev, const char *name, - goto err; - } - -+ rx_chn->common.chan_dev.class = &k3_udma_glue_devclass; -+ rx_chn->common.chan_dev.parent = xudma_get_device(rx_chn->common.udmax); -+ dev_set_name(&rx_chn->common.chan_dev, "rchan_remote-0x%04x", -+ rx_chn->common.src_thread); -+ ret = device_register(&rx_chn->common.chan_dev); -+ if (ret) { -+ dev_err(dev, "Channel Device registration failed %d\n", ret); -+ rx_chn->common.chan_dev.parent = NULL; -+ goto err; -+ } -+ -+ if (xudma_is_pktdma(rx_chn->common.udmax)) { -+ /* prepare the channel device as coherent */ -+ rx_chn->common.chan_dev.dma_coherent = true; -+ dma_coerce_mask_and_coherent(&rx_chn->common.chan_dev, -+ DMA_BIT_MASK(48)); -+ } -+ - ret = k3_udma_glue_allocate_rx_flows(rx_chn, cfg); - if (ret) - goto err; -@@ -940,6 +1111,11 @@ void k3_udma_glue_release_rx_chn(struct k3_udma_glue_rx_channel *rx_chn) - if (!IS_ERR_OR_NULL(rx_chn->udma_rchanx)) - xudma_rchan_put(rx_chn->common.udmax, - rx_chn->udma_rchanx); -+ -+ if (rx_chn->common.chan_dev.parent) { -+ device_unregister(&rx_chn->common.chan_dev); -+ rx_chn->common.chan_dev.parent = NULL; -+ } - } - EXPORT_SYMBOL_GPL(k3_udma_glue_release_rx_chn); - -@@ -1151,12 +1327,10 @@ void k3_udma_glue_reset_rx_chn(struct k3_udma_glue_rx_channel *rx_chn, - /* reset RXCQ as it is not input for udma - expected to be empty */ - occ_rx = k3_ringacc_ring_get_occ(flow->ringrx); - dev_dbg(dev, "RX reset flow %u occ_rx %u\n", flow_num, occ_rx); -- if (flow->ringrx) -- k3_ringacc_ring_reset(flow->ringrx); - - /* Skip RX FDQ in case one FDQ is used for the set of flows */ - if (skip_fdq) -- return; -+ goto do_reset; - - /* - * RX FDQ reset need to be special way as it is input for udma and its -@@ -1171,13 +1345,17 @@ void k3_udma_glue_reset_rx_chn(struct k3_udma_glue_rx_channel *rx_chn, - for (i = 0; i < occ_rx; i++) { - ret = k3_ringacc_ring_pop(flow->ringrxfdq, &desc_dma); - if (ret) { -- dev_err(dev, "RX reset pop %d\n", ret); -+ if (ret != -ENODATA) -+ dev_err(dev, "RX reset pop %d\n", ret); - break; - } - cleanup(data, desc_dma); - } - - k3_ringacc_ring_reset_dma(flow->ringrxfdq, occ_rx); -+ -+do_reset: -+ k3_ringacc_ring_reset(flow->ringrx); - } - EXPORT_SYMBOL_GPL(k3_udma_glue_reset_rx_chn); - -@@ -1207,7 +1385,12 @@ int k3_udma_glue_rx_get_irq(struct k3_udma_glue_rx_channel *rx_chn, - - flow = &rx_chn->flows[flow_num]; - -- flow->virq = k3_ringacc_get_ring_irq_num(flow->ringrx); -+ if (xudma_is_pktdma(rx_chn->common.udmax)) { -+ flow->virq = xudma_pktdma_rflow_get_irq(rx_chn->common.udmax, -+ flow->udma_rflow_id); -+ } else { -+ flow->virq = k3_ringacc_get_ring_irq_num(flow->ringrx); -+ } - - return flow->virq; - } -@@ -1216,6 +1399,38 @@ EXPORT_SYMBOL_GPL(k3_udma_glue_rx_get_irq); - struct device * - k3_udma_glue_rx_get_dma_device(struct k3_udma_glue_rx_channel *rx_chn) - { -+ if (xudma_is_pktdma(rx_chn->common.udmax) && -+ (rx_chn->common.atype_asel == 14 || rx_chn->common.atype_asel == 15)) -+ return &rx_chn->common.chan_dev; -+ - return xudma_get_device(rx_chn->common.udmax); - } - EXPORT_SYMBOL_GPL(k3_udma_glue_rx_get_dma_device); -+ -+void k3_udma_glue_rx_dma_to_cppi5_addr(struct k3_udma_glue_rx_channel *rx_chn, -+ dma_addr_t *addr) -+{ -+ if (!xudma_is_pktdma(rx_chn->common.udmax) || -+ !rx_chn->common.atype_asel) -+ return; -+ -+ *addr |= (u64)rx_chn->common.atype_asel << K3_ADDRESS_ASEL_SHIFT; -+} -+EXPORT_SYMBOL_GPL(k3_udma_glue_rx_dma_to_cppi5_addr); -+ -+void k3_udma_glue_rx_cppi5_to_dma_addr(struct k3_udma_glue_rx_channel *rx_chn, -+ dma_addr_t *addr) -+{ -+ if (!xudma_is_pktdma(rx_chn->common.udmax) || -+ !rx_chn->common.atype_asel) -+ return; -+ -+ *addr &= (u64)GENMASK(K3_ADDRESS_ASEL_SHIFT - 1, 0); -+} -+EXPORT_SYMBOL_GPL(k3_udma_glue_rx_cppi5_to_dma_addr); -+ -+static int __init k3_udma_glue_class_init(void) -+{ -+ return class_register(&k3_udma_glue_devclass); -+} -+arch_initcall(k3_udma_glue_class_init); -diff --git a/drivers/dma/ti/k3-udma-private.c b/drivers/dma/ti/k3-udma-private.c -index 3a08e68de349..3257b2f5157c 100644 ---- a/drivers/dma/ti/k3-udma-private.c -+++ b/drivers/dma/ti/k3-udma-private.c -@@ -157,3 +157,27 @@ void xudma_##res##rt_write(struct udma_##res *p, int reg, u32 val) \ - EXPORT_SYMBOL(xudma_##res##rt_write) - XUDMA_RT_IO_FUNCTIONS(tchan); - XUDMA_RT_IO_FUNCTIONS(rchan); -+ -+int xudma_is_pktdma(struct udma_dev *ud) -+{ -+ return ud->match_data->type == DMA_TYPE_PKTDMA; -+} -+EXPORT_SYMBOL(xudma_is_pktdma); -+ -+int xudma_pktdma_tflow_get_irq(struct udma_dev *ud, int udma_tflow_id) -+{ -+ const struct udma_oes_offsets *oes = &ud->soc_data->oes; -+ -+ return ti_sci_inta_msi_get_virq(ud->dev, udma_tflow_id + -+ oes->pktdma_tchan_flow); -+} -+EXPORT_SYMBOL(xudma_pktdma_tflow_get_irq); -+ -+int xudma_pktdma_rflow_get_irq(struct udma_dev *ud, int udma_rflow_id) -+{ -+ const struct udma_oes_offsets *oes = &ud->soc_data->oes; -+ -+ return ti_sci_inta_msi_get_virq(ud->dev, udma_rflow_id + -+ oes->pktdma_rchan_flow); -+} -+EXPORT_SYMBOL(xudma_pktdma_rflow_get_irq); -diff --git a/drivers/dma/ti/k3-udma.h b/drivers/dma/ti/k3-udma.h -index ccb19f286daf..d349c6d482ae 100644 ---- a/drivers/dma/ti/k3-udma.h -+++ b/drivers/dma/ti/k3-udma.h -@@ -157,4 +157,8 @@ void xudma_rchanrt_write(struct udma_rchan *rchan, int reg, u32 val); - bool xudma_rflow_is_gp(struct udma_dev *ud, int id); - int xudma_get_rflow_ring_offset(struct udma_dev *ud); - -+int xudma_is_pktdma(struct udma_dev *ud); -+ -+int xudma_pktdma_tflow_get_irq(struct udma_dev *ud, int udma_tflow_id); -+int xudma_pktdma_rflow_get_irq(struct udma_dev *ud, int udma_rflow_id); - #endif /* K3_UDMA_H_ */ -diff --git a/include/linux/dma/k3-udma-glue.h b/include/linux/dma/k3-udma-glue.h -index d7c12f31377c..e443be4d3b4b 100644 ---- a/include/linux/dma/k3-udma-glue.h -+++ b/include/linux/dma/k3-udma-glue.h -@@ -43,6 +43,10 @@ u32 k3_udma_glue_tx_get_txcq_id(struct k3_udma_glue_tx_channel *tx_chn); - int k3_udma_glue_tx_get_irq(struct k3_udma_glue_tx_channel *tx_chn); - struct device * - k3_udma_glue_tx_get_dma_device(struct k3_udma_glue_tx_channel *tx_chn); -+void k3_udma_glue_tx_dma_to_cppi5_addr(struct k3_udma_glue_tx_channel *tx_chn, -+ dma_addr_t *addr); -+void k3_udma_glue_tx_cppi5_to_dma_addr(struct k3_udma_glue_tx_channel *tx_chn, -+ dma_addr_t *addr); - - enum { - K3_UDMA_GLUE_SRC_TAG_LO_KEEP = 0, -@@ -134,5 +138,9 @@ int k3_udma_glue_rx_flow_disable(struct k3_udma_glue_rx_channel *rx_chn, - u32 flow_idx); - struct device * - k3_udma_glue_rx_get_dma_device(struct k3_udma_glue_rx_channel *rx_chn); -+void k3_udma_glue_rx_dma_to_cppi5_addr(struct k3_udma_glue_rx_channel *rx_chn, -+ dma_addr_t *addr); -+void k3_udma_glue_rx_cppi5_to_dma_addr(struct k3_udma_glue_rx_channel *rx_chn, -+ dma_addr_t *addr); - - #endif /* K3_UDMA_GLUE_H_ */ diff --git a/recipes-kernel/linux/files/patches-5.10/0136-soc-ti-k3-ringacc-Use-correct-error-casting-in-k3_ri.patch b/recipes-kernel/linux/files/patches-5.10/0136-soc-ti-k3-ringacc-Use-correct-error-casting-in-k3_ri.patch deleted file mode 100644 index 76e63c3bb..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0136-soc-ti-k3-ringacc-Use-correct-error-casting-in-k3_ri.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Mon, 14 Dec 2020 08:54:21 +0200 -Subject: [PATCH] soc: ti: k3-ringacc: Use correct error casting in - k3_ringacc_dmarings_init - -commit 115ff12aecfd55376d704fa2c0a2d117e5827f9f upstream. - -Use ERR_CAST() when devm_ioremap_resource() fails. - -Reported-by: kernel test robot -Signed-off-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20201214065421.5138-1-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit '115ff12aecfd' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/soc/ti/k3-ringacc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c -index 3a0002303379..086d61a86b17 100644 ---- a/drivers/soc/ti/k3-ringacc.c -+++ b/drivers/soc/ti/k3-ringacc.c -@@ -1476,7 +1476,7 @@ struct k3_ringacc *k3_ringacc_dmarings_init(struct platform_device *pdev, - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ringrt"); - base_rt = devm_ioremap_resource(dev, res); - if (IS_ERR(base_rt)) -- return base_rt; -+ return ERR_CAST(base_rt); - - ringacc->rings = devm_kzalloc(dev, - sizeof(*ringacc->rings) * diff --git a/recipes-kernel/linux/files/patches-5.10/0137-dmaengine-ti-k3-udma-Fix-pktdma-rchan-TPL-level-setu.patch b/recipes-kernel/linux/files/patches-5.10/0137-dmaengine-ti-k3-udma-Fix-pktdma-rchan-TPL-level-setu.patch deleted file mode 100644 index ebe4f3b10..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0137-dmaengine-ti-k3-udma-Fix-pktdma-rchan-TPL-level-setu.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Wed, 16 Dec 2020 17:48:33 +0200 -Subject: [PATCH] dmaengine: ti: k3-udma: Fix pktdma rchan TPL level setup - -commit 26b614fa441048a9f8e4a814c3b01756816ce7a7 upstream. - -Instead of initializing the rchan_tpl the initial commit re-initialized -the tchan_tpl. - -Fixes: d2abc982333c0 ("dmaengine: ti: k3-udma: Initial support for K3 PKTDMA") -Signed-off-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20201216154833.20821-1-peter.ujfalusi@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick commit '26b614fa4410' from v5.11] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/k3-udma.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index 87157cbae1b8..298460438bb4 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -4698,9 +4698,9 @@ static int pktdma_setup_resources(struct udma_dev *ud) - ud->tchan_tpl.levels = 1; - } - -- ud->tchan_tpl.levels = ud->tchan_tpl.levels; -- ud->tchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0]; -- ud->tchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1]; -+ ud->rchan_tpl.levels = ud->tchan_tpl.levels; -+ ud->rchan_tpl.start_idx[0] = ud->tchan_tpl.start_idx[0]; -+ ud->rchan_tpl.start_idx[1] = ud->tchan_tpl.start_idx[1]; - - ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt), - sizeof(unsigned long), GFP_KERNEL); diff --git a/recipes-kernel/linux/files/patches-5.10/0138-dmaengine-ti-k3-udma-Set-rflow-count-for-BCDMA-split.patch b/recipes-kernel/linux/files/patches-5.10/0138-dmaengine-ti-k3-udma-Set-rflow-count-for-BCDMA-split.patch deleted file mode 100644 index 091d71d60..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0138-dmaengine-ti-k3-udma-Set-rflow-count-for-BCDMA-split.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Tue, 12 Jan 2021 19:44:03 +0530 -Subject: [PATCH] dmaengine: ti: k3-udma: Set rflow count for BCDMA split - channels - -commit aecf9d38361090857aa58708e500ee79bed1e273 upstream. - -BCDMA RX channels have one flow per channel, therefore set the rflow_cnt -to rchan_cnt. - -Without this patch, request for BCDMA RX channel allocation fails as -rflow_cnt is 0 thus fails to reserve a rflow for the channel. - -Fixes: 8844898028d4 ("dmaengine: ti: k3-udma: Add support for BCDMA channel TPL handling") -Signed-off-by: Vignesh Raghavendra -Acked-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20210112141403.30286-1-vigneshr@ti.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick linux-next commit 'aecf9d383610' for v5.12] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/k3-udma.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index 298460438bb4..a1af59d901be 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -4305,6 +4305,7 @@ static int udma_get_mmrs(struct platform_device *pdev, struct udma_dev *ud) - ud->bchan_cnt = BCDMA_CAP2_BCHAN_CNT(cap2); - ud->tchan_cnt = BCDMA_CAP2_TCHAN_CNT(cap2); - ud->rchan_cnt = BCDMA_CAP2_RCHAN_CNT(cap2); -+ ud->rflow_cnt = ud->rchan_cnt; - break; - case DMA_TYPE_PKTDMA: - cap4 = udma_read(ud->mmrs[MMR_GCFG], 0x30); diff --git a/recipes-kernel/linux/files/patches-5.10/0139-dmaengine-Extend-the-dmaengine_alignment-for-128-and.patch b/recipes-kernel/linux/files/patches-5.10/0139-dmaengine-Extend-the-dmaengine_alignment-for-128-and.patch deleted file mode 100644 index 584088e4b..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0139-dmaengine-Extend-the-dmaengine_alignment-for-128-and.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Wed, 13 Jan 2021 13:49:21 +0200 -Subject: [PATCH] dmaengine: Extend the dmaengine_alignment for 128 and 256 - bytes - -commit 660343d063f7b7151a8c679d91ebe13cf40ad866 upstream. - -Some DMA device can benefit with higher order of alignment than the maximum -of 64 bytes currently defined. - -Define 128 and 256 bytes alignment for these devices. - -Signed-off-by: Peter Ujfalusi -Signed-off-by: Peter Ujfalusi -Tested-by: Kishon Vijay Abraham I -Link: https://lore.kernel.org/r/20210113114923.9231-2-peter.ujfalusi@gmail.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick linux-next commit '660343d063f7' for v5.12] -Signed-off-by: Suman Anna ---- - include/linux/dmaengine.h | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h -index 6ca71379dd5f..1d755c0aeefc 100644 ---- a/include/linux/dmaengine.h -+++ b/include/linux/dmaengine.h -@@ -741,6 +741,8 @@ enum dmaengine_alignment { - DMAENGINE_ALIGN_16_BYTES = 4, - DMAENGINE_ALIGN_32_BYTES = 5, - DMAENGINE_ALIGN_64_BYTES = 6, -+ DMAENGINE_ALIGN_128_BYTES = 7, -+ DMAENGINE_ALIGN_256_BYTES = 8, - }; - - /** diff --git a/recipes-kernel/linux/files/patches-5.10/0140-dmaengine-ti-k3-udma-Add-support-for-burst_size-conf.patch b/recipes-kernel/linux/files/patches-5.10/0140-dmaengine-ti-k3-udma-Add-support-for-burst_size-conf.patch deleted file mode 100644 index 36c61571c..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0140-dmaengine-ti-k3-udma-Add-support-for-burst_size-conf.patch +++ /dev/null @@ -1,285 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Wed, 13 Jan 2021 13:49:22 +0200 -Subject: [PATCH] dmaengine: ti: k3-udma: Add support for burst_size - configuration for mem2mem - -commit 046d679b5b8194184efb9f0fe6e6e3f9e06d2c90 upstream. - -The UDMA and BCDMA can provide higher throughput if the burst_size of the -channel is changed from it's default (which is 64 bytes) for Ultra-high -and high capacity channels. - -This performance benefit is even more visible when the buffers are aligned -with the burst_size configuration. - -The am654 does not have a way to change the burst size, but it is using -64 bytes burst, so increasing the copy_align from 8 bytes to 64 (and -clients taking that into account) can increase the throughput as well. - -Numbers gathered on j721e: -echo 8000000 > /sys/module/dmatest/parameters/test_buf_size -echo 2000 > /sys/module/dmatest/parameters/timeout -echo 50 > /sys/module/dmatest/parameters/iterations -echo 1 > /sys/module/dmatest/parameters/max_channels - -Prior this patch: ~1.3 GB/s -After this patch: ~1.8 GB/s - with 1 byte alignment: ~1.7 GB/s - -Signed-off-by: Peter Ujfalusi -Signed-off-by: Peter Ujfalusi -Tested-by: Kishon Vijay Abraham I -Link: https://lore.kernel.org/r/20210113114923.9231-3-peter.ujfalusi@gmail.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick linux-next commit '046d679b5b81' for v5.12] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/k3-udma.c | 116 +++++++++++++++++++++++++++++++++++++-- - 1 file changed, 111 insertions(+), 5 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index a1af59d901be..1eefbfbbb604 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -121,6 +121,11 @@ struct udma_oes_offsets { - #define UDMA_FLAG_PDMA_ACC32 BIT(0) - #define UDMA_FLAG_PDMA_BURST BIT(1) - #define UDMA_FLAG_TDTYPE BIT(2) -+#define UDMA_FLAG_BURST_SIZE BIT(3) -+#define UDMA_FLAGS_J7_CLASS (UDMA_FLAG_PDMA_ACC32 | \ -+ UDMA_FLAG_PDMA_BURST | \ -+ UDMA_FLAG_TDTYPE | \ -+ UDMA_FLAG_BURST_SIZE) - - struct udma_match_data { - enum k3_dma_type type; -@@ -128,6 +133,7 @@ struct udma_match_data { - bool enable_memcpy_support; - u32 flags; - u32 statictr_z_mask; -+ u8 burst_size[3]; - }; - - struct udma_soc_data { -@@ -436,6 +442,18 @@ static void k3_configure_chan_coherency(struct dma_chan *chan, u32 asel) - } - } - -+static u8 udma_get_chan_tpl_index(struct udma_tpl *tpl_map, int chan_id) -+{ -+ int i; -+ -+ for (i = 0; i < tpl_map->levels; i++) { -+ if (chan_id >= tpl_map->start_idx[i]) -+ return i; -+ } -+ -+ return 0; -+} -+ - static void udma_reset_uchan(struct udma_chan *uc) - { - memset(&uc->config, 0, sizeof(uc->config)); -@@ -1811,13 +1829,21 @@ static int udma_tisci_m2m_channel_config(struct udma_chan *uc) - const struct ti_sci_rm_udmap_ops *tisci_ops = tisci_rm->tisci_udmap_ops; - struct udma_tchan *tchan = uc->tchan; - struct udma_rchan *rchan = uc->rchan; -+ u8 burst_size = 0; - int ret = 0; -+ u8 tpl; - - /* Non synchronized - mem to mem type of transfer */ - int tc_ring = k3_ringacc_get_ring_id(tchan->tc_ring); - struct ti_sci_msg_rm_udmap_tx_ch_cfg req_tx = { 0 }; - struct ti_sci_msg_rm_udmap_rx_ch_cfg req_rx = { 0 }; - -+ if (ud->match_data->flags & UDMA_FLAG_BURST_SIZE) { -+ tpl = udma_get_chan_tpl_index(&ud->tchan_tpl, tchan->id); -+ -+ burst_size = ud->match_data->burst_size[tpl]; -+ } -+ - req_tx.valid_params = TISCI_UDMA_TCHAN_VALID_PARAMS; - req_tx.nav_id = tisci_rm->tisci_dev_id; - req_tx.index = tchan->id; -@@ -1825,6 +1851,10 @@ static int udma_tisci_m2m_channel_config(struct udma_chan *uc) - req_tx.tx_fetch_size = sizeof(struct cppi5_desc_hdr_t) >> 2; - req_tx.txcq_qnum = tc_ring; - req_tx.tx_atype = ud->atype; -+ if (burst_size) { -+ req_tx.valid_params |= TI_SCI_MSG_VALUE_RM_UDMAP_CH_BURST_SIZE_VALID; -+ req_tx.tx_burst_size = burst_size; -+ } - - ret = tisci_ops->tx_ch_cfg(tisci_rm->tisci, &req_tx); - if (ret) { -@@ -1839,6 +1869,10 @@ static int udma_tisci_m2m_channel_config(struct udma_chan *uc) - req_rx.rxcq_qnum = tc_ring; - req_rx.rx_chan_type = TI_SCI_RM_UDMAP_CHAN_TYPE_3RDP_BCOPY_PBRR; - req_rx.rx_atype = ud->atype; -+ if (burst_size) { -+ req_rx.valid_params |= TI_SCI_MSG_VALUE_RM_UDMAP_CH_BURST_SIZE_VALID; -+ req_rx.rx_burst_size = burst_size; -+ } - - ret = tisci_ops->rx_ch_cfg(tisci_rm->tisci, &req_rx); - if (ret) -@@ -1854,12 +1888,24 @@ static int bcdma_tisci_m2m_channel_config(struct udma_chan *uc) - const struct ti_sci_rm_udmap_ops *tisci_ops = tisci_rm->tisci_udmap_ops; - struct ti_sci_msg_rm_udmap_tx_ch_cfg req_tx = { 0 }; - struct udma_bchan *bchan = uc->bchan; -+ u8 burst_size = 0; - int ret = 0; -+ u8 tpl; -+ -+ if (ud->match_data->flags & UDMA_FLAG_BURST_SIZE) { -+ tpl = udma_get_chan_tpl_index(&ud->bchan_tpl, bchan->id); -+ -+ burst_size = ud->match_data->burst_size[tpl]; -+ } - - req_tx.valid_params = TISCI_BCDMA_BCHAN_VALID_PARAMS; - req_tx.nav_id = tisci_rm->tisci_dev_id; - req_tx.extended_ch_type = TI_SCI_RM_BCDMA_EXTENDED_CH_TYPE_BCHAN; - req_tx.index = bchan->id; -+ if (burst_size) { -+ req_tx.valid_params |= TI_SCI_MSG_VALUE_RM_UDMAP_CH_BURST_SIZE_VALID; -+ req_tx.tx_burst_size = burst_size; -+ } - - ret = tisci_ops->tx_ch_cfg(tisci_rm->tisci, &req_tx); - if (ret) -@@ -4167,6 +4213,11 @@ static struct udma_match_data am654_main_data = { - .psil_base = 0x1000, - .enable_memcpy_support = true, - .statictr_z_mask = GENMASK(11, 0), -+ .burst_size = { -+ TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES, /* Normal Channels */ -+ TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES, /* H Channels */ -+ 0, /* No UH Channels */ -+ }, - }; - - static struct udma_match_data am654_mcu_data = { -@@ -4174,38 +4225,63 @@ static struct udma_match_data am654_mcu_data = { - .psil_base = 0x6000, - .enable_memcpy_support = false, - .statictr_z_mask = GENMASK(11, 0), -+ .burst_size = { -+ TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES, /* Normal Channels */ -+ TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES, /* H Channels */ -+ 0, /* No UH Channels */ -+ }, - }; - - static struct udma_match_data j721e_main_data = { - .type = DMA_TYPE_UDMA, - .psil_base = 0x1000, - .enable_memcpy_support = true, -- .flags = UDMA_FLAG_PDMA_ACC32 | UDMA_FLAG_PDMA_BURST | UDMA_FLAG_TDTYPE, -+ .flags = UDMA_FLAGS_J7_CLASS, - .statictr_z_mask = GENMASK(23, 0), -+ .burst_size = { -+ TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES, /* Normal Channels */ -+ TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_256_BYTES, /* H Channels */ -+ TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_256_BYTES, /* UH Channels */ -+ }, - }; - - static struct udma_match_data j721e_mcu_data = { - .type = DMA_TYPE_UDMA, - .psil_base = 0x6000, - .enable_memcpy_support = false, /* MEM_TO_MEM is slow via MCU UDMA */ -- .flags = UDMA_FLAG_PDMA_ACC32 | UDMA_FLAG_PDMA_BURST | UDMA_FLAG_TDTYPE, -+ .flags = UDMA_FLAGS_J7_CLASS, - .statictr_z_mask = GENMASK(23, 0), -+ .burst_size = { -+ TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES, /* Normal Channels */ -+ TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_128_BYTES, /* H Channels */ -+ 0, /* No UH Channels */ -+ }, - }; - - static struct udma_match_data am64_bcdma_data = { - .type = DMA_TYPE_BCDMA, - .psil_base = 0x2000, /* for tchan and rchan, not applicable to bchan */ - .enable_memcpy_support = true, /* Supported via bchan */ -- .flags = UDMA_FLAG_PDMA_ACC32 | UDMA_FLAG_PDMA_BURST | UDMA_FLAG_TDTYPE, -+ .flags = UDMA_FLAGS_J7_CLASS, - .statictr_z_mask = GENMASK(23, 0), -+ .burst_size = { -+ TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES, /* Normal Channels */ -+ 0, /* No H Channels */ -+ 0, /* No UH Channels */ -+ }, - }; - - static struct udma_match_data am64_pktdma_data = { - .type = DMA_TYPE_PKTDMA, - .psil_base = 0x1000, - .enable_memcpy_support = false, /* PKTDMA does not support MEM_TO_MEM */ -- .flags = UDMA_FLAG_PDMA_ACC32 | UDMA_FLAG_PDMA_BURST | UDMA_FLAG_TDTYPE, -+ .flags = UDMA_FLAGS_J7_CLASS, - .statictr_z_mask = GENMASK(23, 0), -+ .burst_size = { -+ TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES, /* Normal Channels */ -+ 0, /* No H Channels */ -+ 0, /* No UH Channels */ -+ }, - }; - - static const struct of_device_id udma_of_match[] = { -@@ -5046,6 +5122,34 @@ static void udma_dbg_summary_show(struct seq_file *s, - } - #endif /* CONFIG_DEBUG_FS */ - -+static enum dmaengine_alignment udma_get_copy_align(struct udma_dev *ud) -+{ -+ const struct udma_match_data *match_data = ud->match_data; -+ u8 tpl; -+ -+ if (!match_data->enable_memcpy_support) -+ return DMAENGINE_ALIGN_8_BYTES; -+ -+ /* Get the highest TPL level the device supports for memcpy */ -+ if (ud->bchan_cnt) -+ tpl = udma_get_chan_tpl_index(&ud->bchan_tpl, 0); -+ else if (ud->tchan_cnt) -+ tpl = udma_get_chan_tpl_index(&ud->tchan_tpl, 0); -+ else -+ return DMAENGINE_ALIGN_8_BYTES; -+ -+ switch (match_data->burst_size[tpl]) { -+ case TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_256_BYTES: -+ return DMAENGINE_ALIGN_256_BYTES; -+ case TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_128_BYTES: -+ return DMAENGINE_ALIGN_128_BYTES; -+ case TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES: -+ fallthrough; -+ default: -+ return DMAENGINE_ALIGN_64_BYTES; -+ } -+} -+ - #define TI_UDMAC_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ - BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ - BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \ -@@ -5202,7 +5306,6 @@ static int udma_probe(struct platform_device *pdev) - ud->ddev.dst_addr_widths = TI_UDMAC_BUSWIDTHS; - ud->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); - ud->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; -- ud->ddev.copy_align = DMAENGINE_ALIGN_8_BYTES; - ud->ddev.desc_metadata_modes = DESC_METADATA_CLIENT | - DESC_METADATA_ENGINE; - if (ud->match_data->enable_memcpy_support && -@@ -5284,6 +5387,9 @@ static int udma_probe(struct platform_device *pdev) - INIT_DELAYED_WORK(&uc->tx_drain.work, udma_check_tx_completion); - } - -+ /* Configure the copy_align to the maximum burst size the device supports */ -+ ud->ddev.copy_align = udma_get_copy_align(ud); -+ - ret = dma_async_device_register(&ud->ddev); - if (ret) { - dev_err(dev, "failed to register slave DMA engine: %d\n", ret); diff --git a/recipes-kernel/linux/files/patches-5.10/0141-dmaengine-ti-k3-udma-Do-not-initialize-ret-in-tisci-.patch b/recipes-kernel/linux/files/patches-5.10/0141-dmaengine-ti-k3-udma-Do-not-initialize-ret-in-tisci-.patch deleted file mode 100644 index 3cd0d482a..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0141-dmaengine-ti-k3-udma-Do-not-initialize-ret-in-tisci-.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Ujfalusi -Date: Wed, 13 Jan 2021 13:49:23 +0200 -Subject: [PATCH] dmaengine: ti: k3-udma: Do not initialize ret in tisci - channel config functions - -commit 747ee57bd33d5d64e127c09ea0d24026acc1a653 upstream. - -The ret does not need to be initialized to 0 in the tisci channel config -functions. - -Signed-off-by: Peter Ujfalusi -Link: https://lore.kernel.org/r/20210113114923.9231-4-peter.ujfalusi@gmail.com -Signed-off-by: Vinod Koul -[s-anna@ti.com: cherry-pick linux-next commit '747ee57bd33d' for v5.12] -Signed-off-by: Suman Anna ---- - drivers/dma/ti/k3-udma.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index 1eefbfbbb604..8e3fd1119a77 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -1830,7 +1830,7 @@ static int udma_tisci_m2m_channel_config(struct udma_chan *uc) - struct udma_tchan *tchan = uc->tchan; - struct udma_rchan *rchan = uc->rchan; - u8 burst_size = 0; -- int ret = 0; -+ int ret; - u8 tpl; - - /* Non synchronized - mem to mem type of transfer */ -@@ -1889,7 +1889,7 @@ static int bcdma_tisci_m2m_channel_config(struct udma_chan *uc) - struct ti_sci_msg_rm_udmap_tx_ch_cfg req_tx = { 0 }; - struct udma_bchan *bchan = uc->bchan; - u8 burst_size = 0; -- int ret = 0; -+ int ret; - u8 tpl; - - if (ud->match_data->flags & UDMA_FLAG_BURST_SIZE) { -@@ -1923,7 +1923,7 @@ static int udma_tisci_tx_channel_config(struct udma_chan *uc) - int tc_ring = k3_ringacc_get_ring_id(tchan->tc_ring); - struct ti_sci_msg_rm_udmap_tx_ch_cfg req_tx = { 0 }; - u32 mode, fetch_size; -- int ret = 0; -+ int ret; - - if (uc->config.pkt_mode) { - mode = TI_SCI_RM_UDMAP_CHAN_TYPE_PKT_PBRR; -@@ -1964,7 +1964,7 @@ static int bcdma_tisci_tx_channel_config(struct udma_chan *uc) - const struct ti_sci_rm_udmap_ops *tisci_ops = tisci_rm->tisci_udmap_ops; - struct udma_tchan *tchan = uc->tchan; - struct ti_sci_msg_rm_udmap_tx_ch_cfg req_tx = { 0 }; -- int ret = 0; -+ int ret; - - req_tx.valid_params = TISCI_BCDMA_TCHAN_VALID_PARAMS; - req_tx.nav_id = tisci_rm->tisci_dev_id; -@@ -1997,7 +1997,7 @@ static int udma_tisci_rx_channel_config(struct udma_chan *uc) - struct ti_sci_msg_rm_udmap_rx_ch_cfg req_rx = { 0 }; - struct ti_sci_msg_rm_udmap_flow_cfg flow_req = { 0 }; - u32 mode, fetch_size; -- int ret = 0; -+ int ret; - - if (uc->config.pkt_mode) { - mode = TI_SCI_RM_UDMAP_CHAN_TYPE_PKT_PBRR; -@@ -2074,7 +2074,7 @@ static int bcdma_tisci_rx_channel_config(struct udma_chan *uc) - const struct ti_sci_rm_udmap_ops *tisci_ops = tisci_rm->tisci_udmap_ops; - struct udma_rchan *rchan = uc->rchan; - struct ti_sci_msg_rm_udmap_rx_ch_cfg req_rx = { 0 }; -- int ret = 0; -+ int ret; - - req_rx.valid_params = TISCI_BCDMA_RCHAN_VALID_PARAMS; - req_rx.nav_id = tisci_rm->tisci_dev_id; -@@ -2094,7 +2094,7 @@ static int pktdma_tisci_rx_channel_config(struct udma_chan *uc) - const struct ti_sci_rm_udmap_ops *tisci_ops = tisci_rm->tisci_udmap_ops; - struct ti_sci_msg_rm_udmap_rx_ch_cfg req_rx = { 0 }; - struct ti_sci_msg_rm_udmap_flow_cfg flow_req = { 0 }; -- int ret = 0; -+ int ret; - - req_rx.valid_params = TISCI_BCDMA_RCHAN_VALID_PARAMS; - req_rx.nav_id = tisci_rm->tisci_dev_id; diff --git a/recipes-kernel/linux/files/patches-5.10/0142-firmware-ti_sci-Update-ti_sci_msg_req_reboot-to-incl.patch b/recipes-kernel/linux/files/patches-5.10/0142-firmware-ti_sci-Update-ti_sci_msg_req_reboot-to-incl.patch deleted file mode 100644 index 8ed8942f5..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0142-firmware-ti_sci-Update-ti_sci_msg_req_reboot-to-incl.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Fri, 23 Oct 2020 14:36:43 -0500 -Subject: [PATCH] firmware: ti_sci: Update ti_sci_msg_req_reboot to include - domain - -The ti_sci_msg_req_reboot message payload has been extended to include -a domain field, and this should be zero to reset the entire SoC with -System Firmwares newer than v2020.04. Add the domain field to the -ti_sci_msg_req_reboot message structure for completeness. Set it up -to zero to fix the reboot issues with newer firmwares. - -The ideal long-term fix should be to ensure that the transfer buffer -is zero-initialized. - -Signed-off-by: Suman Anna -Signed-off-by: Dave Gerlach ---- - drivers/firmware/ti_sci.c | 1 + - drivers/firmware/ti_sci.h | 2 ++ - 2 files changed, 3 insertions(+) - -diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c -index 235c7e7869aa..406b1643f38e 100644 ---- a/drivers/firmware/ti_sci.c -+++ b/drivers/firmware/ti_sci.c -@@ -1674,6 +1674,7 @@ static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle) - return ret; - } - req = (struct ti_sci_msg_req_reboot *)xfer->xfer_buf; -+ req->domain = 0; - - ret = ti_sci_do_xfer(info, xfer); - if (ret) { -diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h -index ef3a8214d002..c0766dfcd7a1 100644 ---- a/drivers/firmware/ti_sci.h -+++ b/drivers/firmware/ti_sci.h -@@ -124,12 +124,14 @@ struct ti_sci_msg_resp_version { - /** - * struct ti_sci_msg_req_reboot - Reboot the SoC - * @hdr: Generic Header -+ * @domain: Domain to be reset, 0 for full SoC reboot - * - * Request type is TI_SCI_MSG_SYS_RESET, responded with a generic - * ACK/NACK message. - */ - struct ti_sci_msg_req_reboot { - struct ti_sci_msg_hdr hdr; -+ u8 domain; - } __packed; - - /** diff --git a/recipes-kernel/linux/files/patches-5.10/0146-irqchip-irq-pruss-intc-Fix-build-warning.patch b/recipes-kernel/linux/files/patches-5.10/0146-irqchip-irq-pruss-intc-Fix-build-warning.patch deleted file mode 100644 index 0b3c57c31..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0146-irqchip-irq-pruss-intc-Fix-build-warning.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Fri, 9 Jul 2021 17:12:24 +0300 -Subject: [PATCH] irqchip/irq-pruss-intc: Fix build warning -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Fix build warning on v7 platforms: - - CC [M] drivers/irqchip/irq-pruss-intc.o -In file included from ../include/linux/bits.h:6, - from ../include/linux/bitops.h:5, - from ../include/linux/kernel.h:12, - from ../include/linux/interrupt.h:6, - from ../drivers/irqchip/irq-pruss-intc.c:15: -../include/vdso/bits.h:7:26: warning: left shift count >= width of type [-Wshift-count-overflow] - #define BIT(nr) (UL(1) << (nr)) - ^~ -../drivers/irqchip/irq-pruss-intc.c:668:32: note: in expansion of macro ‘BIT’ - .quirky_events = BIT_ULL(7) | BIT(56), /* IEP{0,1} capture/compare events */ - ^~~ -The quirky_events is u64 so BIT_ULL() has to be used. - -Fixes: bbe0ff82f922 ("HACK: irqchip/irq-pruss-intc: Fix processing of IEP interrupts") -Signed-off-by: Grygorii Strashko -Signed-off-by: Suman Anna ---- - drivers/irqchip/irq-pruss-intc.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c -index 74f7d51236f7..00dd8ee40b82 100644 ---- a/drivers/irqchip/irq-pruss-intc.c -+++ b/drivers/irqchip/irq-pruss-intc.c -@@ -310,7 +310,7 @@ static void pruss_intc_irq_ack(struct irq_data *data) - unsigned int hwirq = data->hwirq; - - if (hwirq < MAX_PRU_INT_EVENTS && -- intc->soc_config->quirky_events & BIT(hwirq)) -+ intc->soc_config->quirky_events & BIT_ULL(hwirq)) - return; - - pruss_intc_write_reg(intc, PRU_INTC_SICR, hwirq); -@@ -330,7 +330,7 @@ static void pruss_intc_irq_unmask(struct irq_data *data) - unsigned int hwirq = data->hwirq; - - if (hwirq < MAX_PRU_INT_EVENTS && -- intc->soc_config->quirky_events & BIT(hwirq)) -+ intc->soc_config->quirky_events & BIT_ULL(hwirq)) - pruss_intc_write_reg(intc, PRU_INTC_SICR, hwirq); - pruss_intc_write_reg(intc, PRU_INTC_EISR, hwirq); - } -@@ -659,13 +659,13 @@ static int pruss_intc_remove(struct platform_device *pdev) - static const struct pruss_intc_match_data pruss_intc_data = { - .num_system_events = 64, - .num_host_events = 10, -- .quirky_events = BIT(7), /* IEP capture/compare event */ -+ .quirky_events = BIT_ULL(7), /* IEP capture/compare event */ - }; - - static const struct pruss_intc_match_data icssg_intc_data = { - .num_system_events = 160, - .num_host_events = 20, -- .quirky_events = BIT(7) | BIT(56), /* IEP{0,1} capture/compare events */ -+ .quirky_events = BIT_ULL(7) | BIT_ULL(56), /* IEP{0,1} capture/compare events */ - }; - - static const struct of_device_id pruss_intc_of_match[] = { diff --git a/recipes-kernel/linux/files/patches-5.10/0148-net-ethernet-ti-icssg_prueth-move-miig_rt-api-in-sep.patch b/recipes-kernel/linux/files/patches-5.10/0148-net-ethernet-ti-icssg_prueth-move-miig_rt-api-in-sep.patch deleted file mode 100644 index e747bf725..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0148-net-ethernet-ti-icssg_prueth-move-miig_rt-api-in-sep.patch +++ /dev/null @@ -1,215 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Mon, 13 Sep 2021 18:19:53 +0300 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: move miig_rt api in separate - file - -No need to have those functions as inline and as preparation for adding -"mii" support. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/Makefile | 2 +- - drivers/net/ethernet/ti/icss_mii_rt.h | 82 ++--------------------- - drivers/net/ethernet/ti/icssg_mii_cfg.c | 89 +++++++++++++++++++++++++ - 3 files changed, 96 insertions(+), 77 deletions(-) - create mode 100644 drivers/net/ethernet/ti/icssg_mii_cfg.c - -diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile -index 5f99e7b48103..b40292eff9bf 100644 ---- a/drivers/net/ethernet/ti/Makefile -+++ b/drivers/net/ethernet/ti/Makefile -@@ -31,4 +31,4 @@ obj-$(CONFIG_TI_K3_AM65_CPTS) += am65-cpts.o - obj-$(CONFIG_TI_ICSS_IEP) += icss_iep.o - - obj-$(CONFIG_TI_ICSSG_PRUETH) += icssg-prueth.o --icssg-prueth-y := icssg_prueth.o icssg_classifier.o icssg_ethtool.o icssg_queues.o icssg_config.o k3-cppi-desc-pool.o -+icssg-prueth-y := icssg_prueth.o icssg_classifier.o icssg_ethtool.o icssg_queues.o icssg_config.o k3-cppi-desc-pool.o icssg_mii_cfg.o -diff --git a/drivers/net/ethernet/ti/icss_mii_rt.h b/drivers/net/ethernet/ti/icss_mii_rt.h -index 836060ffdd4a..88b3c9cf222f 100644 ---- a/drivers/net/ethernet/ti/icss_mii_rt.h -+++ b/drivers/net/ethernet/ti/icss_mii_rt.h -@@ -123,81 +123,11 @@ enum mii_mode { MII_MODE_MII = 0, MII_MODE_RGMII, MII_MODE_SGMII }; - #define RGMII_CFG_SPEED_100M 1 - #define RGMII_CFG_SPEED_1G 2 - --static inline void icssg_mii_update_ipg(struct regmap *mii_rt, int mii, u32 ipg) --{ -- u32 val; -- -- if (mii == ICSS_MII0) { -- regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG0, ipg); -- } else { -- /* Errata workaround: IEP1 is not read by h/w unless IEP0 is written */ -- regmap_read(mii_rt, PRUSS_MII_RT_TX_IPG0, &val); -- regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG1, ipg); -- regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG0, val); -- } --} -- --static inline void icssg_update_rgmii_cfg(struct regmap *miig_rt, int speed, -- int duplex, int mii) --{ -- u32 gig_en_mask, gig_val = 0, full_duplex_mask, full_duplex_val = 0; -- u32 inband_en_mask, inband_val = 0; -- -- gig_en_mask = (mii == ICSS_MII0) ? RGMII_CFG_GIG_EN_MII0 : -- RGMII_CFG_GIG_EN_MII1; -- if (speed == SPEED_1000) -- gig_val = gig_en_mask; -- regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, gig_en_mask, gig_val); -- -- inband_en_mask = (mii == ICSS_MII0) ? RGMII_CFG_INBAND_EN_MII0 : -- RGMII_CFG_INBAND_EN_MII1; -- if (speed == SPEED_10) -- inband_val = inband_en_mask; -- regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, inband_en_mask, inband_val); -- -- full_duplex_mask = (mii == ICSS_MII0) ? RGMII_CFG_FULL_DUPLEX_MII0 : -- RGMII_CFG_FULL_DUPLEX_MII1; -- if (duplex == DUPLEX_FULL) -- full_duplex_val = full_duplex_mask; -- regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, full_duplex_mask, -- full_duplex_val); --} -- --static inline u32 icssg_rgmii_cfg_get_bitfield(struct regmap *miig_rt, -- u32 mask, u32 shift) --{ -- u32 val; -- -- regmap_read(miig_rt, RGMII_CFG_OFFSET, &val); -- val &= mask; -- val >>= shift; -- -- return val; --} -- --static inline u32 icssg_rgmii_get_speed(struct regmap *miig_rt, int mii) --{ -- u32 shift = RGMII_CFG_SPEED_MII0_SHIFT, mask = RGMII_CFG_SPEED_MII0; -- -- if (mii == ICSS_MII1) { -- shift = RGMII_CFG_SPEED_MII1_SHIFT; -- mask = RGMII_CFG_SPEED_MII1; -- } -- -- return icssg_rgmii_cfg_get_bitfield(miig_rt, mask, shift); --} -- --static inline u32 icssg_rgmii_get_fullduplex(struct regmap *miig_rt, int mii) --{ -- u32 shift = RGMII_CFG_FULLDUPLEX_MII0_SHIFT; -- u32 mask = RGMII_CFG_FULLDUPLEX_MII0; -- -- if (mii == ICSS_MII1) { -- shift = RGMII_CFG_FULLDUPLEX_MII1_SHIFT; -- mask = RGMII_CFG_FULLDUPLEX_MII1; -- } -- -- return icssg_rgmii_cfg_get_bitfield(miig_rt, mask, shift); --} -+void icssg_mii_update_ipg(struct regmap *mii_rt, int mii, u32 ipg); -+void icssg_update_rgmii_cfg(struct regmap *miig_rt, int speed, -+ int duplex, int mii); -+u32 icssg_rgmii_cfg_get_bitfield(struct regmap *miig_rt, u32 mask, u32 shift); -+u32 icssg_rgmii_get_speed(struct regmap *miig_rt, int mii); -+u32 icssg_rgmii_get_fullduplex(struct regmap *miig_rt, int mii); - - #endif /* __NET_PRUSS_MII_RT_H__ */ -diff --git a/drivers/net/ethernet/ti/icssg_mii_cfg.c b/drivers/net/ethernet/ti/icssg_mii_cfg.c -new file mode 100644 -index 000000000000..eea04806ad28 ---- /dev/null -+++ b/drivers/net/ethernet/ti/icssg_mii_cfg.c -@@ -0,0 +1,89 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* Texas Instruments ICSSG Ethernet Driver -+ * -+ * Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/ -+ * -+ */ -+ -+#include -+#include -+#include -+ -+#include "icss_mii_rt.h" -+#include "icssg_prueth.h" -+ -+void icssg_mii_update_ipg(struct regmap *mii_rt, int mii, u32 ipg) -+{ -+ u32 val; -+ -+ if (mii == ICSS_MII0) { -+ regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG0, ipg); -+ } else { -+ /* Errata workaround: IEP1 is not read by h/w unless IEP0 is written */ -+ regmap_read(mii_rt, PRUSS_MII_RT_TX_IPG0, &val); -+ regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG1, ipg); -+ regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG0, val); -+ } -+} -+ -+void icssg_update_rgmii_cfg(struct regmap *miig_rt, int speed, -+ int duplex, int mii) -+{ -+ u32 gig_en_mask, gig_val = 0, full_duplex_mask, full_duplex_val = 0; -+ u32 inband_en_mask, inband_val = 0; -+ -+ gig_en_mask = (mii == ICSS_MII0) ? RGMII_CFG_GIG_EN_MII0 : -+ RGMII_CFG_GIG_EN_MII1; -+ if (speed == SPEED_1000) -+ gig_val = gig_en_mask; -+ regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, gig_en_mask, gig_val); -+ -+ inband_en_mask = (mii == ICSS_MII0) ? RGMII_CFG_INBAND_EN_MII0 : -+ RGMII_CFG_INBAND_EN_MII1; -+ if (speed == SPEED_10) -+ inband_val = inband_en_mask; -+ regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, inband_en_mask, inband_val); -+ -+ full_duplex_mask = (mii == ICSS_MII0) ? RGMII_CFG_FULL_DUPLEX_MII0 : -+ RGMII_CFG_FULL_DUPLEX_MII1; -+ if (duplex == DUPLEX_FULL) -+ full_duplex_val = full_duplex_mask; -+ regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, full_duplex_mask, -+ full_duplex_val); -+} -+ -+u32 icssg_rgmii_cfg_get_bitfield(struct regmap *miig_rt, u32 mask, u32 shift) -+{ -+ u32 val; -+ -+ regmap_read(miig_rt, RGMII_CFG_OFFSET, &val); -+ val &= mask; -+ val >>= shift; -+ -+ return val; -+} -+ -+u32 icssg_rgmii_get_speed(struct regmap *miig_rt, int mii) -+{ -+ u32 shift = RGMII_CFG_SPEED_MII0_SHIFT, mask = RGMII_CFG_SPEED_MII0; -+ -+ if (mii == ICSS_MII1) { -+ shift = RGMII_CFG_SPEED_MII1_SHIFT; -+ mask = RGMII_CFG_SPEED_MII1; -+ } -+ -+ return icssg_rgmii_cfg_get_bitfield(miig_rt, mask, shift); -+} -+ -+u32 icssg_rgmii_get_fullduplex(struct regmap *miig_rt, int mii) -+{ -+ u32 shift = RGMII_CFG_FULLDUPLEX_MII0_SHIFT; -+ u32 mask = RGMII_CFG_FULLDUPLEX_MII0; -+ -+ if (mii == ICSS_MII1) { -+ shift = RGMII_CFG_FULLDUPLEX_MII1_SHIFT; -+ mask = RGMII_CFG_FULLDUPLEX_MII1; -+ } -+ -+ return icssg_rgmii_cfg_get_bitfield(miig_rt, mask, shift); -+} diff --git a/recipes-kernel/linux/files/patches-5.10/0149-net-ethernet-ti-icssg_prueth-skip-rgmii-delay-if-not.patch b/recipes-kernel/linux/files/patches-5.10/0149-net-ethernet-ti-icssg_prueth-skip-rgmii-delay-if-not.patch deleted file mode 100644 index ca41a515b..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0149-net-ethernet-ti-icssg_prueth-skip-rgmii-delay-if-not.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Mon, 13 Sep 2021 18:19:54 +0300 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: skip rgmii delay if not - rgmii - -Do not configure RGMII delay if PHY interface mode is not RGMII. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index f996273b4ea3..b9e2b4c0da54 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -2048,6 +2048,9 @@ static int prueth_config_rgmiidelay(struct prueth *prueth, - u32 rgmii_tx_id = 0; - u32 icssgctrl_reg; - -+ if (!phy_interface_mode_is_rgmii(phy_if)) -+ return 0; -+ - ctrl_mmr = syscon_regmap_lookup_by_phandle(eth_np, "syscon-rgmii-delay"); - if (IS_ERR(ctrl_mmr)) { - dev_err(dev, "couldn't get syscon-rgmii-delay\n"); diff --git a/recipes-kernel/linux/files/patches-5.10/0150-net-ethernet-ti-icssg_prueth-simplify-icssg_config_i.patch b/recipes-kernel/linux/files/patches-5.10/0150-net-ethernet-ti-icssg_prueth-simplify-icssg_config_i.patch deleted file mode 100644 index a93deaa2d..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0150-net-ethernet-ti-icssg_prueth-simplify-icssg_config_i.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Mon, 13 Sep 2021 18:19:55 +0300 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: simplify icssg_config_ipg() - -Pass struct prueth_emac *emac as parameter instead of prueth/speed/slice as -it contains all needed info. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_config.c | 18 +++++++++++------- - drivers/net/ethernet/ti/icssg_prueth.c | 2 +- - drivers/net/ethernet/ti/icssg_prueth.h | 2 +- - 3 files changed, 13 insertions(+), 9 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c -index 50acf4e31008..7b0a39f6de54 100644 ---- a/drivers/net/ethernet/ti/icssg_config.c -+++ b/drivers/net/ethernet/ti/icssg_config.c -@@ -98,8 +98,6 @@ static void icssg_config_mii_init(struct prueth *prueth, int mii) - pcnt_reg = (mii == ICSS_MII0) ? PRUSS_MII_RT_RX_PCNT0 : - PRUSS_MII_RT_RX_PCNT1; - -- icssg_config_ipg(prueth, SPEED_1000, mii); -- - rxcfg = MII_RXCFG_DEFAULT; - txcfg = MII_TXCFG_DEFAULT; - -@@ -177,21 +175,24 @@ static void icssg_config_rgmii_init(struct prueth *prueth, int slice) - } - } - --void icssg_config_ipg(struct prueth *prueth, int speed, int mii) -+void icssg_config_ipg(struct prueth_emac *emac) - { -- switch (speed) { -+ struct prueth *prueth = emac->prueth; -+ int slice = prueth_emac_slice(emac); -+ -+ switch (emac->speed) { - case SPEED_1000: -- icssg_mii_update_ipg(prueth->mii_rt, mii, prueth->is_sr1 ? -+ icssg_mii_update_ipg(prueth->mii_rt, slice, prueth->is_sr1 ? - MII_RT_TX_IPG_1G_SR1 : MII_RT_TX_IPG_1G); - break; - case SPEED_100: -- icssg_mii_update_ipg(prueth->mii_rt, mii, prueth->is_sr1 ? -+ icssg_mii_update_ipg(prueth->mii_rt, slice, prueth->is_sr1 ? - MII_RT_TX_IPG_100M_SR1 : MII_RT_TX_IPG_100M); - break; - case SPEED_10: - /* Firmware hardcodes IPG for PG1. PG2 same as 100M */ - if (!prueth->is_sr1) -- icssg_mii_update_ipg(prueth->mii_rt, mii, -+ icssg_mii_update_ipg(prueth->mii_rt, slice, - MII_RT_TX_IPG_100M); - break; - default: -@@ -293,6 +294,9 @@ int icssg_config_sr2(struct prueth *prueth, struct prueth_emac *emac, int slice) - memset_io(config, 0, TAS_GATE_MASK_LIST0); - icssg_config_rgmii_init(prueth, slice); - icssg_config_mii_init(prueth, slice); -+ emac->speed = SPEED_1000; -+ emac->duplex = DUPLEX_FULL; -+ icssg_config_ipg(emac); - - /* set GPI mode */ - pruss_cfg_gpimode(prueth->pruss, prueth->pru_id[slice], -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index b9e2b4c0da54..d485930d11ac 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1283,7 +1283,7 @@ static void emac_adjust_link(struct net_device *ndev) - - /* update the Tx IPG based on 100M/1G speed */ - spin_lock_irqsave(&emac->lock, flags); -- icssg_config_ipg(prueth, emac->speed, slice); -+ icssg_config_ipg(emac); - spin_unlock_irqrestore(&emac->lock, flags); - icssg_config_set_speed(emac); - if (!emac->is_sr1) -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 0ff9e9680b57..7da6cb08a49d 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -274,7 +274,7 @@ static inline int prueth_emac_slice(struct prueth_emac *emac) - } - - /* config helpers */ --void icssg_config_ipg(struct prueth *prueth, int speed, int mii); -+void icssg_config_ipg(struct prueth_emac *emac); - void icssg_config_sr1(struct prueth *prueth, struct prueth_emac *emac, - int slice); - int icssg_config_sr2(struct prueth *prueth, struct prueth_emac *emac, diff --git a/recipes-kernel/linux/files/patches-5.10/0151-net-ethernet-ti-icssg_prueth-add-mii-phy-interface-m.patch b/recipes-kernel/linux/files/patches-5.10/0151-net-ethernet-ti-icssg_prueth-add-mii-phy-interface-m.patch deleted file mode 100644 index 8ed723f4f..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0151-net-ethernet-ti-icssg_prueth-add-mii-phy-interface-m.patch +++ /dev/null @@ -1,261 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Mon, 13 Sep 2021 18:19:56 +0300 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: add mii phy interface mode - support - -Add and use icssg_miig_set_interface_mode() API and rework mii/miig -initialization for MII PHY mode support. -Also change: -- default speed/duplex to 100M FD -- update icssg_update_rgmii_cfg() to not enable in-band mode for MII case -- limit PHY capabilities to 100M in case of MII - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_mii_rt.h | 15 +++++++-- - drivers/net/ethernet/ti/icssg_config.c | 44 +++++++++++++++---------- - drivers/net/ethernet/ti/icssg_mii_cfg.c | 32 +++++++++++++----- - drivers/net/ethernet/ti/icssg_prueth.c | 13 ++++++-- - 4 files changed, 73 insertions(+), 31 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_mii_rt.h b/drivers/net/ethernet/ti/icss_mii_rt.h -index 88b3c9cf222f..11c159cb8510 100644 ---- a/drivers/net/ethernet/ti/icss_mii_rt.h -+++ b/drivers/net/ethernet/ti/icss_mii_rt.h -@@ -8,6 +8,8 @@ - #ifndef __NET_PRUSS_MII_RT_H__ - #define __NET_PRUSS_MII_RT_H__ - -+#include -+ - /* PRUSS_MII_RT Registers */ - #define PRUSS_MII_RT_RXCFG0 0x0 - #define PRUSS_MII_RT_RXCFG1 0x4 -@@ -102,7 +104,11 @@ - #define ICSSG_CFG_TX_L2_EN BIT(1) - #define ICSSG_CFG_TX_L1_EN BIT(0) - --enum mii_mode { MII_MODE_MII = 0, MII_MODE_RGMII, MII_MODE_SGMII }; -+enum mii_mode { -+ MII_MODE_MII = 0, -+ MII_MODE_RGMII, -+ MII_MODE_SGMII -+}; - - /* RGMII CFG Register bits */ - #define RGMII_CFG_INBAND_EN_MII0 BIT(16) -@@ -123,11 +129,14 @@ enum mii_mode { MII_MODE_MII = 0, MII_MODE_RGMII, MII_MODE_SGMII }; - #define RGMII_CFG_SPEED_100M 1 - #define RGMII_CFG_SPEED_1G 2 - -+struct regmap; -+struct prueth_emac; -+ - void icssg_mii_update_ipg(struct regmap *mii_rt, int mii, u32 ipg); --void icssg_update_rgmii_cfg(struct regmap *miig_rt, int speed, -- int duplex, int mii); -+void icssg_update_rgmii_cfg(struct regmap *miig_rt, struct prueth_emac *emac); - u32 icssg_rgmii_cfg_get_bitfield(struct regmap *miig_rt, u32 mask, u32 shift); - u32 icssg_rgmii_get_speed(struct regmap *miig_rt, int mii); - u32 icssg_rgmii_get_fullduplex(struct regmap *miig_rt, int mii); -+void icssg_miig_set_interface_mode(struct regmap *miig_rt, int mii, phy_interface_t phy_if); - - #endif /* __NET_PRUSS_MII_RT_H__ */ -diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c -index 7b0a39f6de54..faa9855f03bf 100644 ---- a/drivers/net/ethernet/ti/icssg_config.c -+++ b/drivers/net/ethernet/ti/icssg_config.c -@@ -85,46 +85,48 @@ struct map hwq_map[2][ICSSG_NUM_OTHER_QUEUES] = { - }, - }; - --static void icssg_config_mii_init(struct prueth *prueth, int mii) -+static void icssg_config_mii_init(struct prueth_emac *emac) - { -+ struct prueth *prueth = emac->prueth; - struct regmap *mii_rt = prueth->mii_rt; -+ int slice = prueth_emac_slice(emac); - u32 rxcfg_reg, txcfg_reg, pcnt_reg; - u32 rxcfg, txcfg; - -- rxcfg_reg = (mii == ICSS_MII0) ? PRUSS_MII_RT_RXCFG0 : -+ rxcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RXCFG0 : - PRUSS_MII_RT_RXCFG1; -- txcfg_reg = (mii == ICSS_MII0) ? PRUSS_MII_RT_TXCFG0 : -+ txcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_TXCFG0 : - PRUSS_MII_RT_TXCFG1; -- pcnt_reg = (mii == ICSS_MII0) ? PRUSS_MII_RT_RX_PCNT0 : -+ pcnt_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RX_PCNT0 : - PRUSS_MII_RT_RX_PCNT1; - - rxcfg = MII_RXCFG_DEFAULT; - txcfg = MII_TXCFG_DEFAULT; - -- if (mii == ICSS_MII1) { -+ if (slice == ICSS_MII1) - rxcfg |= PRUSS_MII_RT_RXCFG_RX_MUX_SEL; -+ -+ /* In MII mode TX lines swapped inside ICSSG, so TX_MUX_SEL cfg need -+ * to be swapped also comparing to RGMII mode. TODO: errata? -+ */ -+ if (emac->phy_if == PHY_INTERFACE_MODE_MII && slice == ICSS_MII0) -+ txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL; -+ else if (emac->phy_if != PHY_INTERFACE_MODE_MII && slice == ICSS_MII1) - txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL; -- } - - regmap_write(mii_rt, rxcfg_reg, rxcfg); - regmap_write(mii_rt, txcfg_reg, txcfg); - regmap_write(mii_rt, pcnt_reg, 0x1); - } - --static void icssg_config_rgmii_init(struct prueth *prueth, int slice) -+static void icssg_miig_queues_init(struct prueth *prueth, int slice) - { -- void __iomem *smem = prueth->shram.va; - struct regmap *miig_rt = prueth->miig_rt; -- int queue = 0, i, j; -+ void __iomem *smem = prueth->shram.va; - u8 pd[ICSSG_SPECIAL_PD_SIZE]; -+ int queue = 0, i, j; - u32 *pdword; -- u32 mii_mode; - -- mii_mode = MII_MODE_RGMII << ICSSG_CFG_MII0_MODE_SHIFT; -- mii_mode |= MII_MODE_RGMII << ICSSG_CFG_MII1_MODE_SHIFT; -- regmap_write(miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_DEFAULT | mii_mode); -- -- icssg_update_rgmii_cfg(miig_rt, SPEED_1000, DUPLEX_FULL, slice); - /* reset hwqueues */ - if (slice) - queue = ICSSG_NUM_TX_QUEUES; -@@ -292,11 +294,19 @@ int icssg_config_sr2(struct prueth *prueth, struct prueth_emac *emac, int slice) - - rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET; - memset_io(config, 0, TAS_GATE_MASK_LIST0); -- icssg_config_rgmii_init(prueth, slice); -- icssg_config_mii_init(prueth, slice); -+ icssg_miig_queues_init(prueth, slice); -+ - emac->speed = SPEED_1000; - emac->duplex = DUPLEX_FULL; -+ if (!phy_interface_mode_is_rgmii(emac->phy_if)) { -+ emac->speed = SPEED_100; -+ emac->duplex = DUPLEX_FULL; -+ } -+ regmap_update_bits(prueth->miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_DEFAULT, ICSSG_CFG_DEFAULT); -+ icssg_miig_set_interface_mode(prueth->miig_rt, slice, emac->phy_if); -+ icssg_config_mii_init(emac); - icssg_config_ipg(emac); -+ icssg_update_rgmii_cfg(prueth->miig_rt, emac); - - /* set GPI mode */ - pruss_cfg_gpimode(prueth->pruss, prueth->pru_id[slice], -diff --git a/drivers/net/ethernet/ti/icssg_mii_cfg.c b/drivers/net/ethernet/ti/icssg_mii_cfg.c -index eea04806ad28..97c2e5b2957b 100644 ---- a/drivers/net/ethernet/ti/icssg_mii_cfg.c -+++ b/drivers/net/ethernet/ti/icssg_mii_cfg.c -@@ -26,32 +26,48 @@ void icssg_mii_update_ipg(struct regmap *mii_rt, int mii, u32 ipg) - } - } - --void icssg_update_rgmii_cfg(struct regmap *miig_rt, int speed, -- int duplex, int mii) -+void icssg_update_rgmii_cfg(struct regmap *miig_rt, struct prueth_emac *emac) - { - u32 gig_en_mask, gig_val = 0, full_duplex_mask, full_duplex_val = 0; -+ int slice = prueth_emac_slice(emac); - u32 inband_en_mask, inband_val = 0; - -- gig_en_mask = (mii == ICSS_MII0) ? RGMII_CFG_GIG_EN_MII0 : -+ gig_en_mask = (slice == ICSS_MII0) ? RGMII_CFG_GIG_EN_MII0 : - RGMII_CFG_GIG_EN_MII1; -- if (speed == SPEED_1000) -+ if (emac->speed == SPEED_1000) - gig_val = gig_en_mask; - regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, gig_en_mask, gig_val); - -- inband_en_mask = (mii == ICSS_MII0) ? RGMII_CFG_INBAND_EN_MII0 : -+ inband_en_mask = (slice == ICSS_MII0) ? RGMII_CFG_INBAND_EN_MII0 : - RGMII_CFG_INBAND_EN_MII1; -- if (speed == SPEED_10) -+ if (emac->speed == SPEED_10 && phy_interface_mode_is_rgmii(emac->phy_if)) - inband_val = inband_en_mask; - regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, inband_en_mask, inband_val); - -- full_duplex_mask = (mii == ICSS_MII0) ? RGMII_CFG_FULL_DUPLEX_MII0 : -+ full_duplex_mask = (slice == ICSS_MII0) ? RGMII_CFG_FULL_DUPLEX_MII0 : - RGMII_CFG_FULL_DUPLEX_MII1; -- if (duplex == DUPLEX_FULL) -+ if (emac->duplex == DUPLEX_FULL) - full_duplex_val = full_duplex_mask; - regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, full_duplex_mask, - full_duplex_val); - } - -+void icssg_miig_set_interface_mode(struct regmap *miig_rt, int mii, phy_interface_t phy_if) -+{ -+ u32 val, mask, shift; -+ -+ mask = mii == ICSS_MII0 ? ICSSG_CFG_MII0_MODE : ICSSG_CFG_MII1_MODE; -+ shift = mii == ICSS_MII0 ? ICSSG_CFG_MII0_MODE_SHIFT : ICSSG_CFG_MII1_MODE_SHIFT; -+ -+ val = MII_MODE_RGMII; -+ if (phy_if == PHY_INTERFACE_MODE_MII) -+ val = MII_MODE_MII; -+ -+ val <<= shift; -+ regmap_update_bits(miig_rt, ICSSG_CFG_OFFSET, mask, val); -+ regmap_read(miig_rt, ICSSG_CFG_OFFSET, &val); -+} -+ - u32 icssg_rgmii_cfg_get_bitfield(struct regmap *miig_rt, u32 mask, u32 shift) - { - u32 val; -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index d485930d11ac..70188d08a164 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1238,7 +1238,6 @@ static void emac_adjust_link(struct net_device *ndev) - struct prueth_emac *emac = netdev_priv(ndev); - struct phy_device *phydev = emac->phydev; - struct prueth *prueth = emac->prueth; -- int slice = prueth_emac_slice(emac); - bool new_state = false; - unsigned long flags; - -@@ -1278,8 +1277,7 @@ static void emac_adjust_link(struct net_device *ndev) - if (emac->duplex == DUPLEX_HALF) - icssg_config_half_duplex(emac); - /* Set the RGMII cfg for gig en and full duplex */ -- icssg_update_rgmii_cfg(prueth->miig_rt, emac->speed, -- emac->duplex, slice); -+ icssg_update_rgmii_cfg(prueth->miig_rt, emac); - - /* update the Tx IPG based on 100M/1G speed */ - spin_lock_irqsave(&emac->lock, flags); -@@ -2167,6 +2165,12 @@ static int prueth_netdev_init(struct prueth *prueth, - goto free; - } - -+ if (emac->phy_if != PHY_INTERFACE_MODE_MII && -+ !phy_interface_mode_is_rgmii(emac->phy_if)) { -+ dev_err(prueth->dev, "PHY mode unsupported %s\n", phy_modes(emac->phy_if)); -+ goto free; -+ } -+ - ret = prueth_config_rgmiidelay(prueth, eth_node, emac->phy_if); - if (ret) - goto free; -@@ -2192,6 +2196,9 @@ static int prueth_netdev_init(struct prueth *prueth, - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Pause_BIT); - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT); - -+ if (emac->phy_if == PHY_INTERFACE_MODE_MII) -+ phy_set_max_speed(emac->phydev, SPEED_100); -+ - /* get mac address from DT and set private and netdev addr */ - mac_addr = of_get_mac_address(eth_node); - if (!IS_ERR(mac_addr)) diff --git a/recipes-kernel/linux/files/patches-5.10/0152-net-ethernet-ti-icssg_prueth-fix-llvm-build-warn.patch b/recipes-kernel/linux/files/patches-5.10/0152-net-ethernet-ti-icssg_prueth-fix-llvm-build-warn.patch deleted file mode 100644 index 6bba1b9f7..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0152-net-ethernet-ti-icssg_prueth-fix-llvm-build-warn.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Fri, 17 Sep 2021 17:00:21 +0300 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: fix llvm build warn - -Fix: -drivers/net/ethernet/ti/icssg_prueth.c:2106:6: warning: variable 'ret' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized] - if (!emac->cmd_wq) - ^~~~~~~~~~~~~ -drivers/net/ethernet/ti/icssg_prueth.c:2222:9: note: uninitialized use occurs here - return ret; - ^~~ - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 70188d08a164..4470482062f9 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -2105,8 +2105,10 @@ static int prueth_netdev_init(struct prueth *prueth, - emac->ndev = ndev; - emac->port_id = port; - emac->cmd_wq = create_singlethread_workqueue("icssg_cmd_wq"); -- if (!emac->cmd_wq) -+ if (!emac->cmd_wq) { -+ ret = -ENOMEM; - goto free_ndev; -+ } - INIT_WORK(&emac->rx_mode_work, emac_ndo_set_rx_mode_work); - - ret = pruss_request_mem_region(prueth->pruss, diff --git a/recipes-kernel/linux/files/patches-5.10/0154-net-ethernet-ti-icss_iep-fix-phc2sys-sync.patch b/recipes-kernel/linux/files/patches-5.10/0154-net-ethernet-ti-icss_iep-fix-phc2sys-sync.patch deleted file mode 100644 index 050943b1f..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0154-net-ethernet-ti-icss_iep-fix-phc2sys-sync.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Fri, 24 Sep 2021 16:58:40 +0300 -Subject: [PATCH] net: ethernet: ti: icss_iep: fix phc2sys sync - -Now when phc2sys is running to sync sys-clock to PHC the sync doesn't -happen: - -phc2sys[2046.273]: CLOCK_REALTIME phc offset -1588667462018990140 s0 freq +100000000 delay 1048389136 -phc2sys[2047.273]: clockcheck: clock jumped backward or running slower than expected! -phc2sys[2047.273]: CLOCK_REALTIME phc offset -1588667463942743044 s0 freq +100000000 delay 0 -phc2sys[2048.273]: CLOCK_REALTIME phc offset -864962291571182424 s2 freq +100000000 delay 1447410346965662944 -phc2sys[2049.273]: clockcheck: clock jumped backward or running slower than expected! -phc2sys[2049.273]: CLOCK_REALTIME phc offset -1588667465352817468 s0 freq +100000000 delay 1048389136 - -cmd master: -phc2sys -a -rr -m -q -l5& -ptp4l -2 -i eth0 -l5 -m -q --priority1 127& - -cmd slave: -phc2sys -a -r -q -m -l6& -ptp4l -2 -s -i eth3 -m -q -l5& - -The issue is due PTP IEP PHC clock was converted to use .gettimex64() -callback and code path for AM65x SR1.0 IEP was updated properly to fill -struct ptp_system_timestamp *sts parameter, but the same is missing for -AM65x SR2.0 IEP code path where gettime() is implemented in icssg_prueth -driver through .gettime() callback. - -Hence fix AM65x SR2.0 IEP to pass struct ptp_system_timestamp to -icss_iep_clockops.gettime() callback and fill it properly. After this -change: - -phc2sys -a -r -q -m -l6 -phc2sys[177.659]: reconfiguring after port state change -phc2sys[177.659]: selecting CLOCK_REALTIME for synchronization -phc2sys[177.659]: selecting eth3 as the master clock -phc2sys[177.659]: CLOCK_REALTIME phc offset 43656345542569315 s0 freq +0 delay 330 -phc2sys[178.659]: CLOCK_REALTIME phc offset 43656345542534414 s1 freq -34897 delay 330 -phc2sys[179.659]: CLOCK_REALTIME phc offset -2 s2 freq -34899 delay 330 -phc2sys[180.660]: CLOCK_REALTIME phc offset -19 s2 freq -34917 delay 325 -phc2sys[181.660]: CLOCK_REALTIME phc offset -18 s2 freq -34921 delay 330 -phc2sys[182.660]: CLOCK_REALTIME phc offset -48 s2 freq -34957 delay 330 -phc2sys[183.660]: CLOCK_REALTIME phc offset -34 s2 freq -34957 delay 330 -phc2sys[184.660]: CLOCK_REALTIME phc offset -32 s2 freq -34965 delay 325 -phc2sys[185.660]: CLOCK_REALTIME phc offset -12 s2 freq -34955 delay 330 -phc2sys[186.660]: CLOCK_REALTIME phc offset 1 s2 freq -34946 delay 330 -phc2sys[187.660]: CLOCK_REALTIME phc offset 2 s2 freq -34944 delay 330 - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 2 +- - drivers/net/ethernet/ti/icss_iep.h | 2 +- - drivers/net/ethernet/ti/icssg_prueth.c | 7 ++++++- - 3 files changed, 8 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index d3aa3dca729c..481dc366a7c2 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -223,7 +223,7 @@ static u64 icss_iep_gettime(struct icss_iep *iep, - unsigned long flags; - - if (iep->ops && iep->ops->gettime) -- return iep->ops->gettime(iep->clockops_data); -+ return iep->ops->gettime(iep->clockops_data, sts); - - /* use local_irq_x() to make it work for both RT/non-RT */ - local_irq_save(flags); -diff --git a/drivers/net/ethernet/ti/icss_iep.h b/drivers/net/ethernet/ti/icss_iep.h -index 1c8f74ae659a..22bee0ad4565 100644 ---- a/drivers/net/ethernet/ti/icss_iep.h -+++ b/drivers/net/ethernet/ti/icss_iep.h -@@ -18,7 +18,7 @@ struct icss_iep; - struct icss_iep_clockops { - void (*settime)(void *clockops_data, u64 ns); - void (*adjtime)(void *clockops_data, s64 delta); -- u64 (*gettime)(void *clockops_data); -+ u64 (*gettime)(void *clockops_data, struct ptp_system_timestamp *sts); - int (*perout_enable)(void *clockops_data, - struct ptp_perout_request *req, int on, - u64 *cmp); -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 4470482062f9..e07b318d9422 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1395,7 +1395,7 @@ static void prueth_reset_rx_chan(struct prueth_rx_chn *chn, - k3_udma_glue_disable_rx_chn(chn->rx_chn); - } - --static u64 prueth_iep_gettime(void *clockops_data) -+static u64 prueth_iep_gettime(void *clockops_data, struct ptp_system_timestamp *sts) - { - u32 hi_rollover_count, hi_rollover_count_r; - struct prueth_emac *emac = clockops_data; -@@ -1403,23 +1403,28 @@ static u64 prueth_iep_gettime(void *clockops_data) - void __iomem *fw_hi_r_count_addr; - void __iomem *fw_count_hi_addr; - u32 iepcount_hi, iepcount_hi_r; -+ unsigned long flags; - u32 iepcount_lo; - u64 ts = 0; - - fw_count_hi_addr = prueth->shram.va + TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET; - fw_hi_r_count_addr = prueth->shram.va + TIMESYNC_FW_WC_HI_ROLLOVER_COUNT_OFFSET; - -+ local_irq_save(flags); - do { - iepcount_hi = icss_iep_get_count_hi(emac->iep); - iepcount_hi += readl(fw_count_hi_addr); - hi_rollover_count = readl(fw_hi_r_count_addr); -+ ptp_read_system_prets(sts); - iepcount_lo = icss_iep_get_count_low(emac->iep); -+ ptp_read_system_postts(sts); - - iepcount_hi_r = icss_iep_get_count_hi(emac->iep); - iepcount_hi_r += readl(fw_count_hi_addr); - hi_rollover_count_r = readl(fw_hi_r_count_addr); - } while ((iepcount_hi_r != iepcount_hi) || - (hi_rollover_count != hi_rollover_count_r)); -+ local_irq_restore(flags); - - ts = ((u64)hi_rollover_count) << 23 | iepcount_hi; - ts = ts * (u64)IEP_DEFAULT_CYCLE_TIME_NS + iepcount_lo; diff --git a/recipes-kernel/linux/files/patches-5.10/0155-net-ethernet-ti-icssg_prueth-declare-NETIF_F_SG-supp.patch b/recipes-kernel/linux/files/patches-5.10/0155-net-ethernet-ti-icssg_prueth-declare-NETIF_F_SG-supp.patch deleted file mode 100644 index 2886ff6ef..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0155-net-ethernet-ti-icssg_prueth-declare-NETIF_F_SG-supp.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Thu, 7 Oct 2021 20:27:03 +0300 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: declare NETIF_F_SG support - -The ICSSG driver can accept fragmented skbs, but it doesn't declare -NETIF_F_SG as result Net core will linear all skbs during xmit. It also -disables GSO which depends on SG. - -Hence declare NETIF_F_SG feature support. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index e07b318d9422..eed91038bde2 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -2219,6 +2219,8 @@ static int prueth_netdev_init(struct prueth *prueth, - - ndev->netdev_ops = &emac_netdev_ops; - ndev->ethtool_ops = &icssg_ethtool_ops; -+ ndev->hw_features = NETIF_F_SG; -+ ndev->features = ndev->hw_features; - - netif_napi_add(ndev, &emac->napi_rx, - emac_napi_rx_poll, NAPI_POLL_WEIGHT); diff --git a/recipes-kernel/linux/files/patches-5.10/0156-net-ethernet-ti-icssg_config-Refractor-Shared-memory.patch b/recipes-kernel/linux/files/patches-5.10/0156-net-ethernet-ti-icssg_config-Refractor-Shared-memory.patch deleted file mode 100644 index 707203538..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0156-net-ethernet-ti-icssg_config-Refractor-Shared-memory.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Thu, 14 Oct 2021 14:14:24 +0530 -Subject: [PATCH] net: ethernet: ti: icssg_config: Refractor Shared memory - buffer setup code - -Extract shared memory buffers setup code into a separate function so as -in preparation of introducing Switch support - -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_config.c | 96 +++++++++++++++----------- - 1 file changed, 55 insertions(+), 41 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c -index faa9855f03bf..bf7c7201b141 100644 ---- a/drivers/net/ethernet/ti/icssg_config.c -+++ b/drivers/net/ethernet/ti/icssg_config.c -@@ -282,17 +282,63 @@ static int emac_r30_is_done(struct prueth_emac *emac) - return 1; - } - --int icssg_config_sr2(struct prueth *prueth, struct prueth_emac *emac, int slice) -+static int prueth_emac_buffer_setup(struct prueth_emac *emac) - { -- void *config = emac->dram.va + ICSSG_CONFIG_OFFSET; -- u8 *cfg_byte_ptr = config; -- struct icssg_flow_cfg *flow_cfg; - struct icssg_buffer_pool_cfg *bpool_cfg; -+ struct prueth *prueth = emac->prueth; -+ int slice = prueth_emac_slice(emac); - struct icssg_rxq_ctx *rxq_ctx; -+ u32 addr; - int i; -- u32 addr, mask; -+ -+ /* Layout to have 64KB aligned buffer pool -+ * |BPOOL0|BPOOL1|RX_CTX0|RX_CTX1| -+ */ -+ -+ addr = lower_32_bits(prueth->msmcram.pa); -+ if (slice) -+ addr += PRUETH_NUM_BUF_POOLS_SR2 * PRUETH_EMAC_BUF_POOL_SIZE_SR2; -+ -+ if (addr % SZ_64K) { -+ dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n"); -+ return -EINVAL; -+ } -+ -+ bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET; -+ /* workaround for f/w bug. bpool 0 needs to be initilalized */ -+ bpool_cfg[0].addr = cpu_to_le32(addr); -+ bpool_cfg[0].len = 0; -+ -+ for (i = PRUETH_EMAC_BUF_POOL_START_SR2; -+ i < (PRUETH_EMAC_BUF_POOL_START_SR2 + PRUETH_NUM_BUF_POOLS_SR2); -+ i++) { -+ bpool_cfg[i].addr = cpu_to_le32(addr); -+ bpool_cfg[i].len = cpu_to_le32(PRUETH_EMAC_BUF_POOL_SIZE_SR2); -+ addr += PRUETH_EMAC_BUF_POOL_SIZE_SR2; -+ } -+ -+ addr += PRUETH_NUM_BUF_POOLS_SR2 * PRUETH_EMAC_BUF_POOL_SIZE_SR2; -+ if (slice) -+ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; - - rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET; -+ for (i = 0; i < 3; i++) -+ rxq_ctx->start[i] = cpu_to_le32(addr); -+ -+ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; -+ rxq_ctx->end = cpu_to_le32(addr); -+ -+ return 0; -+} -+ -+int icssg_config_sr2(struct prueth *prueth, struct prueth_emac *emac, int slice) -+{ -+ void *config = emac->dram.va + ICSSG_CONFIG_OFFSET; -+ u8 *cfg_byte_ptr = config; -+ struct icssg_flow_cfg *flow_cfg; -+ u32 mask; -+ int ret; -+ - memset_io(config, 0, TAS_GATE_MASK_LIST0); - icssg_miig_queues_init(prueth, slice); - -@@ -321,50 +367,18 @@ int icssg_config_sr2(struct prueth *prueth, struct prueth_emac *emac, int slice) - pru_rproc_set_ctable(prueth->rtu[slice], PRU_C28, 0x100 << 8); - pru_rproc_set_ctable(prueth->txpru[slice], PRU_C28, 0x100 << 8); - -- bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET; -- - flow_cfg = config + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET; - flow_cfg->rx_base_flow = cpu_to_le32(emac->rx_flow_id_base); - flow_cfg->mgm_base_flow = 0; - *(cfg_byte_ptr + SPL_PKT_DEFAULT_PRIORITY) = 0; - *(cfg_byte_ptr + QUEUE_NUM_UNTAGGED) = 0x0; - -- /* Layout to have 64KB aligned buffer pool -- * |BPOOL0|BPOOL1|RX_CTX0|RX_CTX1| -- */ -- -- addr = lower_32_bits(prueth->msmcram.pa); -- if (slice) -- addr += PRUETH_NUM_BUF_POOLS_SR2 * PRUETH_EMAC_BUF_POOL_SIZE_SR2; -- -- if (addr % SZ_64K) { -- dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n"); -- return -EINVAL; -- } -- -- /* workaround for f/w bug. bpool 0 needs to be initilalized */ -- bpool_cfg[0].addr = cpu_to_le32(addr); -- bpool_cfg[0].len = 0; -- -- for (i = PRUETH_EMAC_BUF_POOL_START_SR2; -- i < (PRUETH_EMAC_BUF_POOL_START_SR2 + PRUETH_NUM_BUF_POOLS_SR2); -- i++) { -- bpool_cfg[i].addr = cpu_to_le32(addr); -- bpool_cfg[i].len = cpu_to_le32(PRUETH_EMAC_BUF_POOL_SIZE_SR2); -- addr += PRUETH_EMAC_BUF_POOL_SIZE_SR2; -- } -- -- addr += PRUETH_NUM_BUF_POOLS_SR2 * PRUETH_EMAC_BUF_POOL_SIZE_SR2; -- if (slice) -- addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; -- -- for (i = 0; i < 3; i++) -- rxq_ctx->start[i] = cpu_to_le32(addr); -- -- addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; -- rxq_ctx->end = cpu_to_le32(addr); -+ ret = prueth_emac_buffer_setup(emac); -+ if (ret) -+ return ret; - - emac_r30_cmd_init(emac); -+ - return 0; - } - diff --git a/recipes-kernel/linux/files/patches-5.10/0157-net-ethernet-ti-icssg_prueth-Add-helper-functions-to.patch b/recipes-kernel/linux/files/patches-5.10/0157-net-ethernet-ti-icssg_prueth-Add-helper-functions-to.patch deleted file mode 100644 index 180d34f78..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0157-net-ethernet-ti-icssg_prueth-Add-helper-functions-to.patch +++ /dev/null @@ -1,399 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Thu, 14 Oct 2021 14:14:25 +0530 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: Add helper functions to - configure FDB - -Introduce helper functions to configure firmware FDB tables, VLAN tables -and Port VLAN ID settings to aid adding Switch mode support. - -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_config.c | 209 ++++++++++++++++++++- - drivers/net/ethernet/ti/icssg_config.h | 63 +++++++ - drivers/net/ethernet/ti/icssg_prueth.h | 14 ++ - drivers/net/ethernet/ti/icssg_switch_map.h | 7 + - 4 files changed, 292 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c -index bf7c7201b141..ec996b540ce8 100644 ---- a/drivers/net/ethernet/ti/icssg_config.c -+++ b/drivers/net/ethernet/ti/icssg_config.c -@@ -5,6 +5,7 @@ - */ - - #include -+#include - #include "icssg_config.h" - #include "icssg_prueth.h" - #include "icssg_switch_map.h" -@@ -61,6 +62,18 @@ - ICSSG_CFG_TX_PRU_EN | /* SR2.0 only */ \ - ICSSG_CFG_SGMII_MODE) - -+#define FDB_GEN_CFG1 0x60 -+#define SMEM_VLAN_OFFSET 8 -+#define SMEM_VLAN_OFFSET_MASK GENMASK(25, 8) -+ -+#define FDB_GEN_CFG2 0x64 -+#define FDB_VLAN_EN BIT(6) -+#define FDB_HOST_EN BIT(2) -+#define FDB_PRU1_EN BIT(1) -+#define FDB_PRU0_EN BIT(0) -+#define FDB_EN_ALL (FDB_PRU0_EN | FDB_PRU1_EN | \ -+ FDB_HOST_EN | FDB_VLAN_EN) -+ - struct map { - int queue; - u32 pd_addr_start; -@@ -401,7 +414,9 @@ static struct icssg_r30_cmd emac_r32_bitmask[] = { - {{EMAC_NONE, EMAC_NONE, 0xffff0800, EMAC_NONE}}, /* MC flooding ENABLE*/ - {{EMAC_NONE, EMAC_NONE, 0xf7ff0000, EMAC_NONE}}, /* MC flooding DISABLE*/ - {{EMAC_NONE, 0xffff4000, EMAC_NONE, EMAC_NONE}}, /* Preemption on Tx ENABLE*/ -- {{EMAC_NONE, 0xbfff0000, EMAC_NONE, EMAC_NONE}} /* Preemption on Tx DISABLE*/ -+ {{EMAC_NONE, 0xbfff0000, EMAC_NONE, EMAC_NONE}}, /* Preemption on Tx DISABLE*/ -+ {{0xffff0010, EMAC_NONE, 0xffff0010, EMAC_NONE}}, /* VLAN AWARE*/ -+ {{0xffef0000, EMAC_NONE, 0xffef0000, EMAC_NONE}} /* VLAN UNWARE*/ - }; - - int emac_set_port_state(struct prueth_emac *emac, -@@ -496,3 +511,195 @@ void icssg_config_half_duplex(struct prueth_emac *emac) - val = get_random_int(); - writel(val, emac->dram.va + HD_RAND_SEED_OFFSET); - } -+ -+int icssg_send_fdb_msg(struct prueth_emac *emac, struct mgmt_cmd *cmd, -+ struct mgmt_cmd_rsp *rsp) -+{ -+ struct prueth *prueth = emac->prueth; -+ int slice = prueth_emac_slice(emac); -+ int addr; -+ int i = 10000; -+ -+ addr = icssg_queue_pop(prueth, slice == 0 ? -+ ICSSG_CMD_POP_SLICE0 : ICSSG_CMD_POP_SLICE1); -+ if (addr < 0) -+ return addr; -+ -+ /* First 4 bytes have FW owned buffer linking info which should -+ * not be touched -+ */ -+ memcpy_toio(prueth->shram.va + addr + 4, cmd, sizeof(*cmd)); -+ icssg_queue_push(prueth, slice == 0 ? -+ ICSSG_CMD_PUSH_SLICE0 : ICSSG_CMD_PUSH_SLICE1, addr); -+ while (i--) { -+ addr = icssg_queue_pop(prueth, slice == 0 ? -+ ICSSG_RSP_POP_SLICE0 : ICSSG_RSP_POP_SLICE1); -+ if (addr < 0) { -+ usleep_range(1000, 2000); -+ continue; -+ } -+ -+ memcpy_fromio(rsp, prueth->shram.va + addr, sizeof(*rsp)); -+ /* Return buffer back for to pool */ -+ icssg_queue_push(prueth, slice == 0 ? -+ ICSSG_RSP_PUSH_SLICE0 : ICSSG_RSP_PUSH_SLICE1, addr); -+ break; -+ } -+ if (i <= 0) { -+ netdev_err(emac->ndev, "Timedout sending HWQ message\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+int icssg_fdb_add_del(struct prueth_emac *emac, const unsigned char *addr, -+ u8 vid, u8 fid_c2, bool add) -+{ -+ struct mgmt_cmd_rsp fdb_cmd_rsp = { 0 }; -+ struct mgmt_cmd fdb_cmd = { 0 }; -+ int slice = prueth_emac_slice(emac); -+ u8 mac_fid[ETH_ALEN + 2]; -+ u8 fid = vid; -+ int ret, i; -+ u16 fdb_slot; -+ -+ for (i = 0; i < ETH_ALEN; i++) -+ mac_fid[i] = addr[i]; -+ -+ /* 1-1 VID-FID mapping is already setup */ -+ mac_fid[ETH_ALEN] = fid; -+ mac_fid[ETH_ALEN + 1] = 0; -+ -+ fdb_slot = bitrev32(crc32_le(0, mac_fid, 8)) & PRUETH_SWITCH_FDB_MASK; -+ -+ fdb_cmd.header = ICSSG_FW_MGMT_CMD_HEADER; -+ fdb_cmd.type = ICSSG_FW_MGMT_FDB_CMD_TYPE; -+ fdb_cmd.seqnum = ++(emac->prueth->icssg_hwcmdseq); -+ if (add) -+ fdb_cmd.param = ICSS_CMD_ADD_FDB; -+ else -+ fdb_cmd.param = ICSS_CMD_DEL_FDB; -+ -+ fdb_cmd.param |= (slice << 4); -+ -+ fid_c2 |= ICSSG_FDB_ENTRY_VALID; -+ memcpy(&fdb_cmd.cmd_args[0], addr, 4); -+ memcpy(&fdb_cmd.cmd_args[1], &addr[4], 2); -+ fdb_cmd.cmd_args[1] |= ((fid << 16) | (fid_c2 << 24)); -+ fdb_cmd.cmd_args[2] = fdb_slot; -+ -+ netdev_dbg(emac->ndev, "MAC %pM slot %X vlan %X FID %X\n", -+ addr, fdb_slot, vid, fid); -+ -+ ret = icssg_send_fdb_msg(emac, &fdb_cmd, &fdb_cmd_rsp); -+ if (ret) -+ return ret; -+ -+ WARN_ON(fdb_cmd.seqnum != fdb_cmd_rsp.seqnum); -+ if (fdb_cmd_rsp.status == 1) -+ return 0; -+ -+ return -EINVAL; -+} -+ -+int icssg_fdb_lookup(struct prueth_emac *emac, const unsigned char *addr, -+ u8 vid) -+{ -+ struct mgmt_cmd_rsp fdb_cmd_rsp = { 0 }; -+ struct mgmt_cmd fdb_cmd = { 0 }; -+ int slice = prueth_emac_slice(emac); -+ struct prueth_fdb_slot *slot; -+ u8 mac_fid[ETH_ALEN + 2]; -+ u8 fid = vid; -+ int ret, i; -+ u16 fdb_slot; -+ -+ for (i = 0; i < ETH_ALEN; i++) -+ mac_fid[i] = addr[i]; -+ -+ /* 1-1 VID-FID mapping is already setup */ -+ mac_fid[ETH_ALEN] = fid; -+ mac_fid[ETH_ALEN + 1] = 0; -+ -+ fdb_slot = bitrev32(crc32_le(0, mac_fid, 8)) & PRUETH_SWITCH_FDB_MASK; -+ -+ fdb_cmd.header = ICSSG_FW_MGMT_CMD_HEADER; -+ fdb_cmd.type = ICSSG_FW_MGMT_FDB_CMD_TYPE; -+ fdb_cmd.seqnum = ++(emac->prueth->icssg_hwcmdseq); -+ fdb_cmd.param = ICSS_CMD_GET_FDB_SLOT; -+ -+ fdb_cmd.param |= (slice << 4); -+ -+ memcpy(&fdb_cmd.cmd_args[0], addr, 4); -+ memcpy(&fdb_cmd.cmd_args[1], &addr[4], 2); -+ fdb_cmd.cmd_args[1] |= fid << 16; -+ fdb_cmd.cmd_args[2] = fdb_slot; -+ -+ ret = icssg_send_fdb_msg(emac, &fdb_cmd, &fdb_cmd_rsp); -+ if (ret) -+ return ret; -+ -+ WARN_ON(fdb_cmd.seqnum != fdb_cmd_rsp.seqnum); -+ -+ slot = emac->dram.va + FDB_CMD_BUFFER; -+ for (i = 0; i < 4; i++) { -+ if (ether_addr_equal(addr, slot->mac) && vid == slot->fid) -+ return (slot->fid_c2 & ~ICSSG_FDB_ENTRY_VALID); -+ slot++; -+ } -+ -+ return 0; -+} -+ -+void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask, -+ u8 untag_mask, bool add) -+{ -+ struct prueth *prueth = emac->prueth; -+ struct prueth_vlan_tbl *tbl = prueth->vlan_tbl; -+ u8 fid_c1 = tbl[vid].fid_c1; -+ -+ /* FID_C1: bit0..2 port membership mask, -+ * bit3..5 tagging mask for each port -+ * bit6 Stream VID (not handled currently) -+ * bit7 MC flood (not handled currently) -+ */ -+ if (add) { -+ fid_c1 |= (port_mask | port_mask << 3); -+ fid_c1 &= ~(untag_mask << 3); -+ } else { -+ fid_c1 &= ~(port_mask | port_mask << 3); -+ } -+ -+ tbl[vid].fid_c1 = fid_c1; -+} -+ -+u16 icssg_get_pvid(struct prueth_emac *emac) -+{ -+ struct prueth *prueth = emac->prueth; -+ u32 pvid; -+ -+ if (emac->port_id == PRUETH_PORT_MII0) -+ pvid = readl(prueth->shram.va + EMAC_ICSSG_SWITCH_PORT1_DEFAULT_VLAN_OFFSET); -+ else -+ pvid = readl(prueth->shram.va + EMAC_ICSSG_SWITCH_PORT2_DEFAULT_VLAN_OFFSET); -+ -+ pvid = pvid >> 24; -+ -+ return pvid; -+} -+ -+void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port) -+{ -+ u32 pvid; -+ -+ /* only 256 VLANs are supported */ -+ pvid = cpu_to_be32((ETH_P_8021Q << 16) | (vid & 0xff)); -+ -+ if (port == PRUETH_PORT_MII0) -+ writel(pvid, prueth->shram.va + EMAC_ICSSG_SWITCH_PORT1_DEFAULT_VLAN_OFFSET); -+ else if (port == PRUETH_PORT_MII1) -+ writel(pvid, prueth->shram.va + EMAC_ICSSG_SWITCH_PORT2_DEFAULT_VLAN_OFFSET); -+ else -+ writel(pvid, prueth->shram.va + EMAC_ICSSG_SWITCH_PORT0_DEFAULT_VLAN_OFFSET); -+} -diff --git a/drivers/net/ethernet/ti/icssg_config.h b/drivers/net/ethernet/ti/icssg_config.h -index b9fe3f3cc940..887e85789f05 100644 ---- a/drivers/net/ethernet/ti/icssg_config.h -+++ b/drivers/net/ethernet/ti/icssg_config.h -@@ -105,6 +105,8 @@ struct icssg_config_sr1 { - (2 * (PRUETH_EMAC_BUF_POOL_SIZE_SR2 * PRUETH_NUM_BUF_POOLS_SR2 + \ - PRUETH_EMAC_RX_CTX_BUF_SIZE)) - -+#define PRUETH_SWITCH_FDB_MASK ((SIZE_OF_FDB / NUMBER_OF_FDB_BUCKET_ENTRIES) - 1) -+ - struct icssg_rxq_ctx { - __le32 start[3]; - __le32 end; -@@ -139,6 +141,8 @@ enum icssg_port_state_cmd { - ICSSG_EMAC_PORT_MC_FLOODING_DISABLE, - ICSSG_EMAC_PORT_PREMPT_TX_ENABLE, - ICSSG_EMAC_PORT_PREMPT_TX_DISABLE, -+ ICSSG_EMAC_PORT_VLAN_AWARE_ENABLE, -+ ICSSG_EMAC_PORT_VLAN_AWARE_DISABLE, - ICSSG_EMAC_PORT_MAX_COMMANDS - }; - -@@ -210,4 +214,63 @@ struct icssg_setclock_desc { - #define ICSSG_TS_PUSH_SLICE0 40 - #define ICSSG_TS_PUSH_SLICE1 41 - -+struct mgmt_cmd { -+ u8 param; -+ u8 seqnum; -+ u8 type; -+ u8 header; -+ u32 cmd_args[3]; -+} __packed; -+ -+struct mgmt_cmd_rsp { -+ u32 reserved; -+ u8 status; -+ u8 seqnum; -+ u8 type; -+ u8 header; -+ u32 cmd_args[3]; -+} __packed; -+ -+/* FDB FID_C2 flag definitions */ -+/* Indicates host port membership.*/ -+#define ICSSG_FDB_ENTRY_P0_MEMBERSHIP BIT(0) -+/* Indicates that MAC ID is connected to physical port 1 */ -+#define ICSSG_FDB_ENTRY_P1_MEMBERSHIP BIT(1) -+/* Indicates that MAC ID is connected to physical port 2 */ -+#define ICSSG_FDB_ENTRY_P2_MEMBERSHIP BIT(2) -+/* Ageable bit is set for learned entries and cleared for static entries */ -+#define ICSSG_FDB_ENTRY_AGEABLE BIT(3) -+/* If set for DA then packet is determined to be a special packet */ -+#define ICSSG_FDB_ENTRY_BLOCK BIT(4) -+/* If set for DA then the SA from the packet is not learned */ -+#define ICSSG_FDB_ENTRY_SECURE BIT(5) -+/* If set, it means packet has been seen recently with source address + FID -+ * matching MAC address/FID of entry -+ */ -+#define ICSSG_FDB_ENTRY_TOUCHED BIT(6) -+/* Set if entry is valid */ -+#define ICSSG_FDB_ENTRY_VALID BIT(7) -+ -+/** -+ * struct prueth_vlan_tbl - VLAN table entries struct in ICSSG SMEM -+ * @fid_c1: membership and forwarding rules flag to this table. See -+ * above to defines for bit definitions -+ * @fid: FDB index for this VID (there is 1-1 mapping b/w VID and FID) -+ */ -+struct prueth_vlan_tbl { -+ u8 fid_c1; -+ u8 fid; -+} __packed; -+ -+/** -+ * struct prueth_fdb_slot - Result of FDB slot lookup -+ * @mac: MAC address -+ * @fid: fid to be associated with MAC -+ * @fid_c2: FID_C2 entry for this MAC -+ */ -+struct prueth_fdb_slot { -+ u8 mac[ETH_ALEN]; -+ u8 fid; -+ u8 fid_c2; -+} __packed; - #endif /* __NET_TI_ICSSG_CONFIG_H */ -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 7da6cb08a49d..94490ecd920d 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -56,7 +56,9 @@ - #define ICSS_CMD_SPAD 0x20 - #define ICSS_CMD_RXTX 0x10 - #define ICSS_CMD_ADD_FDB 0x1 -+#define ICSS_CMD_DEL_FDB 0x2 - #define ICSS_CMD_SET_RUN 0x4 -+#define ICSS_CMD_GET_FDB_SLOT 0x5 - #define ICSS_CMD_ENABLE_VLAN 0x5 - #define ICSS_CMD_DISABLE_VLAN 0x6 - #define ICSS_CMD_ADD_FILTER 0x7 -@@ -229,6 +231,8 @@ struct prueth { - struct icss_iep *iep1; - int iep_initialized; - struct prueth_pdata pdata; -+ struct prueth_vlan_tbl *vlan_tbl; -+ u8 icssg_hwcmdseq; - }; - - struct emac_tx_ts_response_sr1 { -@@ -284,6 +288,16 @@ int emac_set_port_state(struct prueth_emac *emac, - void icssg_config_set_speed(struct prueth_emac *emac); - void icssg_config_half_duplex(struct prueth_emac *emac); - -+int icssg_send_fdb_msg(struct prueth_emac *emac, struct mgmt_cmd *cmd, -+ struct mgmt_cmd_rsp *rsp); -+int icssg_fdb_add_del(struct prueth_emac *emac, const unsigned char *addr, -+ u8 vid, u8 fid_c2, bool add); -+int icssg_fdb_lookup(struct prueth_emac *emac, const unsigned char *addr, -+ u8 vid); -+void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask, -+ u8 untag_mask, bool add); -+u16 icssg_get_pvid(struct prueth_emac *emac); -+void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port); - #define prueth_napi_to_tx_chn(pnapi) \ - container_of(pnapi, struct prueth_tx_chn, napi_tx) - -diff --git a/drivers/net/ethernet/ti/icssg_switch_map.h b/drivers/net/ethernet/ti/icssg_switch_map.h -index 99225d0f1582..0d16544aa096 100644 ---- a/drivers/net/ethernet/ti/icssg_switch_map.h -+++ b/drivers/net/ethernet/ti/icssg_switch_map.h -@@ -9,6 +9,13 @@ - #ifndef __NET_TI_ICSSG_SWITCH_MAP_H - #define __NET_TI_ICSSG_SWITCH_MAP_H - -+/************************* Ethernet Switch Constants *********************/ -+ -+/* if bucket size is changed in firmware then this too should be changed */ -+/* because it directly impacts FDB ageing calculation */ -+#define NUMBER_OF_FDB_BUCKET_ENTRIES (4) -+#define SIZE_OF_FDB (2048) /* This is fixed in ICSSG */ -+ - /* Memory Usage of : SHARED_MEMORY - * - */ diff --git a/recipes-kernel/linux/files/patches-5.10/0158-net-ethernet-ti-icssg_prueth-Zero-shared-buffers-bef.patch b/recipes-kernel/linux/files/patches-5.10/0158-net-ethernet-ti-icssg_prueth-Zero-shared-buffers-bef.patch deleted file mode 100644 index 78245de3f..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0158-net-ethernet-ti-icssg_prueth-Zero-shared-buffers-bef.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Thu, 14 Oct 2021 14:14:26 +0530 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: Zero shared buffers before - starting up - -Zero out shared MSMC buffers and PRU shared memories before starting up -interfaces. This is required for clean switch b/w Dual EMAC and Switch -mode. -Clear all buffers at once when first interface is starting up. This -requires to keep track of number of MAC ports initialized, hence -introduce prueth->emacs_initialized flag to keep track of this, drop -prueth->iep_initialized flag as its redundant. - -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 20 ++++++++++++-------- - drivers/net/ethernet/ti/icssg_prueth.h | 3 ++- - 2 files changed, 14 insertions(+), 9 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index eed91038bde2..715f9f7822d3 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1547,10 +1547,13 @@ static int emac_ndo_open(struct net_device *ndev) - int max_rx_flows; - int rx_flow; - -- /* clear SMEM of this slice */ -+ /* clear SMEM and MSMC settings for all slices */ -+ if (!prueth->emacs_initialized) { -+ memset_io(prueth->msmcram.va, 0, prueth->msmcram.size); -+ memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS); -+ } -+ - if (emac->is_sr1) { -- memset_io(prueth->shram.va + slice * ICSSG_CONFIG_OFFSET_SLICE1, -- 0, ICSSG_CONFIG_OFFSET_SLICE1); - /* For SR1, high priority channel is used exclusively for - * management messages. Do reduce number of data channels. - */ -@@ -1643,11 +1646,10 @@ static int emac_ndo_open(struct net_device *ndev) - if (ret) - goto free_rx_mgmt_ts_irq; - -- if (!emac->is_sr1 && !prueth->iep_initialized) { -+ if (!emac->is_sr1 && !prueth->emacs_initialized) { - ret = icss_iep_init(emac->iep, &prueth_iep_clockops, - emac, IEP_DEFAULT_CYCLE_TIME_NS); - } -- prueth->iep_initialized++; - - if (!emac->is_sr1) { - ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq, -@@ -1692,6 +1694,8 @@ static int emac_ndo_open(struct net_device *ndev) - /* start PHY */ - phy_start(emac->phydev); - -+ prueth->emacs_initialized++; -+ - if (netif_msg_drv(emac)) - dev_notice(&ndev->dev, "started\n"); - -@@ -1793,11 +1797,9 @@ static int emac_ndo_stop(struct net_device *ndev) - - napi_disable(&emac->napi_rx); - -- if (!emac->is_sr1 && prueth->iep_initialized == 1) -+ if (!emac->is_sr1 && prueth->emacs_initialized == 1) - icss_iep_exit(emac->iep); - -- prueth->iep_initialized--; -- - cancel_work_sync(&emac->rx_mode_work); - /* stop PRUs */ - prueth_emac_stop(emac); -@@ -1821,6 +1823,8 @@ static int emac_ndo_stop(struct net_device *ndev) - prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows); - prueth_cleanup_tx_chns(emac); - -+ prueth->emacs_initialized--; -+ - if (netif_msg_drv(emac)) - dev_notice(&ndev->dev, "stopped\n"); - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 94490ecd920d..12db0a91d4c5 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -229,10 +229,11 @@ struct prueth { - struct platform_device *pdev; - struct icss_iep *iep0; - struct icss_iep *iep1; -- int iep_initialized; - struct prueth_pdata pdata; - struct prueth_vlan_tbl *vlan_tbl; - u8 icssg_hwcmdseq; -+ -+ int emacs_initialized; - }; - - struct emac_tx_ts_response_sr1 { diff --git a/recipes-kernel/linux/files/patches-5.10/0159-net-ethernet-ti-icssg_switch-Add-switchdev-based-dri.patch b/recipes-kernel/linux/files/patches-5.10/0159-net-ethernet-ti-icssg_switch-Add-switchdev-based-dri.patch deleted file mode 100644 index d0a8683dc..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0159-net-ethernet-ti-icssg_switch-Add-switchdev-based-dri.patch +++ /dev/null @@ -1,649 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Thu, 14 Oct 2021 14:14:27 +0530 -Subject: [PATCH] net: ethernet: ti: icssg_switch: Add switchdev based driver - for ethernet switch support - -ICSSG can operating in switch mode with 2 ext port and 1 host port with -VLAN/FDB/MDB and STP offloading. Add switchdev based driver to -support the same. - -Driver itself will be integrated with icssg_prueth in future commits - -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 1 + - drivers/net/ethernet/ti/icssg_prueth.h | 46 ++ - drivers/net/ethernet/ti/icssg_switchdev.c | 494 ++++++++++++++++++++++ - drivers/net/ethernet/ti/icssg_switchdev.h | 13 + - 4 files changed, 554 insertions(+) - create mode 100644 drivers/net/ethernet/ti/icssg_switchdev.c - create mode 100644 drivers/net/ethernet/ti/icssg_switchdev.h - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 715f9f7822d3..d58588b5294c 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -28,6 +28,7 @@ - #include - - #include "icssg_prueth.h" -+#include "icssg_switchdev.h" - #include "icss_mii_rt.h" - #include "k3-cppi-desc-pool.h" - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 12db0a91d4c5..e5068223bdf8 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -31,6 +31,8 @@ - #include - #include - -+#include -+ - #include "icssg_config.h" - #include "icss_iep.h" - #include "icssg_switch_map.h" -@@ -114,6 +116,15 @@ enum prueth_state_flags { - __STATE_TX_TS_IN_PROGRESS, - }; - -+enum prueth_devlink_param_id { -+ PRUETH_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, -+ PRUETH_DL_PARAM_SWITCH_MODE, -+}; -+ -+struct prueth_devlink { -+ struct prueth *prueth; -+}; -+ - /* There are 4 Tx DMA channels, but the highest priority is CH3 (thread 3) - * and lower three are lower priority channels or threads. - */ -@@ -173,17 +184,23 @@ struct prueth_emac { - struct workqueue_struct *cmd_wq; - - struct pruss_mem_region dram; -+ -+ bool offload_fwd_mark; -+ struct devlink_port devlink_port; -+ int port_vlan; - }; - - /** - * struct prueth - PRUeth platform data - * @fdqring_mode: Free desc queue mode - * @quirk_10m_link_issue: 10M link detect errata -+ * @switch_mode: switch firmware support - */ - struct prueth_pdata { - enum k3_ring_mode fdqring_mode; - - u32 quirk_10m_link_issue:1; -+ u32 switch_mode:1; - }; - - /** -@@ -204,6 +221,24 @@ struct prueth_pdata { - * @config: firmware load time configuration per slice - * @miig_rt: regmap to mii_g_rt block - * @pa_stats: regmap to pa_stats block -+ * @pru_id: ID for each of the PRUs -+ * @pdev: pointer to ICSSG platform device -+ * @iep0: pointer to IEP0 device -+ * @iep1: pointer to IEP1 device -+ * @pdata: pointer to platform data for ICSSG driver -+ * @vlan_tbl: VLAN-FID table pointer -+ * @icssg_hwcmdseq: seq counter or HWQ messages -+ * @emacs_initialized: num of EMACs/ext ports that are up/running -+ * @hw_bridge_dev: pointer to HW bridge net device -+ * @br_members: bitmask of bridge member ports -+ * @prueth_netdevice_nb: netdevice notifier block -+ * @prueth_switchdevice_nb: switchdev notifier block -+ * @prueth_switchdev_bl_nb: switchdev blocking notifier block -+ * @is_switch_mode: flag to indicate if device is in Switch mode -+ * @is_switchmode_supported: indicates platform support for switch mode -+ * @switch_id: ID for mapping switch ports to bridge -+ * @default_vlan: Default VLAN for host -+ * @devlink: pointer to devlink - */ - struct prueth { - bool is_sr1; -@@ -234,6 +269,17 @@ struct prueth { - u8 icssg_hwcmdseq; - - int emacs_initialized; -+ -+ struct net_device *hw_bridge_dev; -+ u8 br_members; -+ struct notifier_block prueth_netdevice_nb; -+ struct notifier_block prueth_switchdev_nb; -+ struct notifier_block prueth_switchdev_bl_nb; -+ bool is_switch_mode; -+ bool is_switchmode_supported; -+ unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN]; -+ int default_vlan; -+ struct devlink *devlink; - }; - - struct emac_tx_ts_response_sr1 { -diff --git a/drivers/net/ethernet/ti/icssg_switchdev.c b/drivers/net/ethernet/ti/icssg_switchdev.c -new file mode 100644 -index 000000000000..e42ff73b60d3 ---- /dev/null -+++ b/drivers/net/ethernet/ti/icssg_switchdev.c -@@ -0,0 +1,494 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* Texas Instruments K3 ICSSG Ethernet Switchdev Driver -+ * -+ * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/ -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "icssg_prueth.h" -+#include "icssg_switchdev.h" -+#include "icss_mii_rt.h" -+ -+struct prueth_switchdev_event_work { -+ struct work_struct work; -+ struct switchdev_notifier_fdb_info fdb_info; -+ struct prueth_emac *emac; -+ unsigned long event; -+}; -+ -+static int prueth_switchdev_stp_state_set(struct prueth_emac *emac, -+ struct switchdev_trans *trans, -+ u8 state) -+{ -+ enum icssg_port_state_cmd emac_state; -+ int ret = 0; -+ -+ if (switchdev_trans_ph_prepare(trans)) -+ return 0; -+ -+ switch (state) { -+ case BR_STATE_FORWARDING: -+ emac_state = ICSSG_EMAC_PORT_FORWARD; -+ break; -+ case BR_STATE_DISABLED: -+ emac_state = ICSSG_EMAC_PORT_DISABLE; -+ break; -+ case BR_STATE_LEARNING: -+ case BR_STATE_LISTENING: -+ case BR_STATE_BLOCKING: -+ emac_state = ICSSG_EMAC_PORT_BLOCK; -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ emac_set_port_state(emac, emac_state); -+ netdev_dbg(emac->ndev, "STP state: %u\n", emac_state); -+ -+ return ret; -+} -+ -+static int prueth_switchdev_attr_br_flags_set(struct prueth_emac *emac, -+ struct switchdev_trans *trans, -+ struct net_device *orig_dev, -+ unsigned long brport_flags) -+{ -+ enum icssg_port_state_cmd emac_state; -+ -+ if (switchdev_trans_ph_prepare(trans)) -+ return 0; -+ -+ if (brport_flags & BR_MCAST_FLOOD) -+ emac_state = ICSSG_EMAC_PORT_MC_FLOODING_ENABLE; -+ else -+ emac_state = ICSSG_EMAC_PORT_MC_FLOODING_DISABLE; -+ -+ netdev_dbg(emac->ndev, "BR_MCAST_FLOOD: %d port %u\n", -+ emac_state, emac->port_id); -+ -+ emac_set_port_state(emac, emac_state); -+ -+ return 0; -+} -+ -+static int prueth_switchdev_attr_br_flags_pre_set(struct net_device *netdev, -+ struct switchdev_trans *trans, -+ unsigned long flags) -+{ -+ if (flags & ~(BR_LEARNING | BR_MCAST_FLOOD)) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int prueth_switchdev_attr_set(struct net_device *ndev, -+ const struct switchdev_attr *attr, -+ struct switchdev_trans *trans) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ int ret; -+ -+ netdev_dbg(ndev, "attr: id %u port: %u\n", attr->id, emac->port_id); -+ -+ switch (attr->id) { -+ case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS: -+ ret = prueth_switchdev_attr_br_flags_pre_set(ndev, trans, -+ attr->u.brport_flags); -+ break; -+ case SWITCHDEV_ATTR_ID_PORT_STP_STATE: -+ ret = prueth_switchdev_stp_state_set(emac, trans, -+ attr->u.stp_state); -+ netdev_dbg(ndev, "stp state: %u\n", attr->u.stp_state); -+ break; -+ case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS: -+ ret = prueth_switchdev_attr_br_flags_set(emac, trans, attr->orig_dev, -+ attr->u.brport_flags); -+ break; -+ default: -+ ret = -EOPNOTSUPP; -+ break; -+ } -+ -+ return ret; -+} -+ -+static void prueth_switchdev_fdb_offload_notify(struct net_device *ndev, -+ struct switchdev_notifier_fdb_info *rcv) -+{ -+ struct switchdev_notifier_fdb_info info; -+ -+ memset(&info, 0, sizeof(info)); -+ info.addr = rcv->addr; -+ info.vid = rcv->vid; -+ info.offloaded = true; -+ call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED, -+ ndev, &info.info, NULL); -+} -+ -+static void prueth_switchdev_event_work(struct work_struct *work) -+{ -+ struct prueth_switchdev_event_work *switchdev_work = -+ container_of(work, struct prueth_switchdev_event_work, work); -+ struct prueth_emac *emac = switchdev_work->emac; -+ struct switchdev_notifier_fdb_info *fdb; -+ int port_id = emac->port_id; -+ int ret; -+ -+ rtnl_lock(); -+ switch (switchdev_work->event) { -+ case SWITCHDEV_FDB_ADD_TO_DEVICE: -+ fdb = &switchdev_work->fdb_info; -+ -+ netdev_dbg(emac->ndev, "prueth_fdb_add: MACID = %pM vid = %u flags = %u %u -- port %d\n", -+ fdb->addr, fdb->vid, fdb->added_by_user, -+ fdb->offloaded, port_id); -+ -+ if (!fdb->added_by_user) -+ break; -+ if (memcmp(emac->mac_addr, (u8 *)fdb->addr, ETH_ALEN) == 0) -+ break; -+ -+ ret = icssg_fdb_add_del(emac, fdb->addr, fdb->vid, -+ BIT(port_id), true); -+ if (!ret) -+ prueth_switchdev_fdb_offload_notify(emac->ndev, fdb); -+ break; -+ case SWITCHDEV_FDB_DEL_TO_DEVICE: -+ fdb = &switchdev_work->fdb_info; -+ -+ netdev_dbg(emac->ndev, "prueth_fdb_del: MACID = %pM vid = %u flags = %u %u -- port %d\n", -+ fdb->addr, fdb->vid, fdb->added_by_user, -+ fdb->offloaded, port_id); -+ -+ if (!fdb->added_by_user) -+ break; -+ if (memcmp(emac->mac_addr, (u8 *)fdb->addr, ETH_ALEN) == 0) -+ break; -+ icssg_fdb_add_del(emac, fdb->addr, fdb->vid, -+ BIT(port_id), false); -+ break; -+ default: -+ break; -+ } -+ rtnl_unlock(); -+ -+ kfree(switchdev_work->fdb_info.addr); -+ kfree(switchdev_work); -+ dev_put(emac->ndev); -+} -+ -+static int prueth_switchdev_event(struct notifier_block *unused, -+ unsigned long event, void *ptr) -+{ -+ struct net_device *ndev = switchdev_notifier_info_to_dev(ptr); -+ struct prueth_switchdev_event_work *switchdev_work; -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct switchdev_notifier_fdb_info *fdb_info = ptr; -+ int err; -+ -+ if (!prueth_dev_check(ndev)) -+ return NOTIFY_DONE; -+ -+ if (event == SWITCHDEV_PORT_ATTR_SET) { -+ err = switchdev_handle_port_attr_set(ndev, ptr, -+ prueth_dev_check, -+ prueth_switchdev_attr_set); -+ return notifier_from_errno(err); -+ } -+ -+ switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); -+ if (WARN_ON(!switchdev_work)) -+ return NOTIFY_BAD; -+ -+ INIT_WORK(&switchdev_work->work, prueth_switchdev_event_work); -+ switchdev_work->emac = emac; -+ switchdev_work->event = event; -+ -+ switch (event) { -+ case SWITCHDEV_FDB_ADD_TO_DEVICE: -+ case SWITCHDEV_FDB_DEL_TO_DEVICE: -+ memcpy(&switchdev_work->fdb_info, ptr, -+ sizeof(switchdev_work->fdb_info)); -+ switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC); -+ if (!switchdev_work->fdb_info.addr) -+ goto err_addr_alloc; -+ ether_addr_copy((u8 *)switchdev_work->fdb_info.addr, -+ fdb_info->addr); -+ dev_hold(ndev); -+ break; -+ default: -+ kfree(switchdev_work); -+ return NOTIFY_DONE; -+ } -+ -+ queue_work(system_long_wq, &switchdev_work->work); -+ -+ return NOTIFY_DONE; -+ -+err_addr_alloc: -+ kfree(switchdev_work); -+ return NOTIFY_BAD; -+} -+ -+static int prueth_switchdev_vlan_add(struct prueth_emac *emac, bool untag, bool pvid, -+ u8 vid, struct net_device *orig_dev) -+{ -+ bool cpu_port = netif_is_bridge_master(orig_dev); -+ int untag_mask = 0; -+ int port_mask; -+ int ret = 0; -+ -+ if (cpu_port) -+ port_mask = BIT(PRUETH_PORT_HOST); -+ else -+ port_mask = BIT(emac->port_id); -+ -+ if (untag) -+ untag_mask = port_mask; -+ -+ icssg_vtbl_modify(emac, vid, port_mask, untag_mask, true); -+ -+ netdev_dbg(emac->ndev, "VID add vid:%u port_mask:%X untag_mask %X PVID %d\n", -+ vid, port_mask, untag_mask, pvid); -+ -+ if (!pvid) -+ return ret; -+ -+ icssg_set_pvid(emac->prueth, vid, emac->port_id); -+ -+ return ret; -+} -+ -+static int prueth_switchdev_vlan_del(struct prueth_emac *emac, u16 vid, -+ struct net_device *orig_dev) -+{ -+ bool cpu_port = netif_is_bridge_master(orig_dev); -+ int port_mask; -+ int ret = 0; -+ -+ if (cpu_port) -+ port_mask = BIT(PRUETH_PORT_HOST); -+ else -+ port_mask = BIT(emac->port_id); -+ -+ icssg_vtbl_modify(emac, vid, port_mask, 0, false); -+ -+ if (cpu_port) -+ icssg_fdb_add_del(emac, emac->mac_addr, vid, -+ BIT(PRUETH_PORT_HOST), false); -+ -+ if (vid == icssg_get_pvid(emac)) -+ icssg_set_pvid(emac->prueth, 0, emac->port_id); -+ -+ netdev_dbg(emac->ndev, "VID del vid:%u port_mask:%X\n", -+ vid, port_mask); -+ -+ return ret; -+} -+ -+static int prueth_switchdev_vlans_add(struct prueth_emac *emac, -+ const struct switchdev_obj_port_vlan *vlan, -+ struct switchdev_trans *trans) -+{ -+ bool untag = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; -+ struct net_device *orig_dev = vlan->obj.orig_dev; -+ bool cpu_port = netif_is_bridge_master(orig_dev); -+ bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; -+ -+ netdev_dbg(emac->ndev, "VID add vid:%u flags:%X\n", -+ vlan->vid_begin, vlan->flags); -+ -+ if (cpu_port && !(vlan->flags & BRIDGE_VLAN_INFO_BRENTRY)) -+ return 0; -+ -+ if (switchdev_trans_ph_prepare(trans)) -+ return 0; -+ -+ if (vlan->vid_begin > 0xff) -+ return 0; -+ -+ return prueth_switchdev_vlan_add(emac, untag, pvid, vlan->vid_begin, -+ orig_dev); -+} -+ -+static int prueth_switchdev_vlans_del(struct prueth_emac *emac, -+ const struct switchdev_obj_port_vlan *vlan) -+ -+{ -+ if (vlan->vid_begin > 0xff) -+ return 0; -+ -+ return prueth_switchdev_vlan_del(emac, vlan->vid_begin, -+ vlan->obj.orig_dev); -+} -+ -+static int prueth_switchdev_mdb_add(struct prueth_emac *emac, -+ struct switchdev_obj_port_mdb *mdb, -+ struct switchdev_trans *trans) -+ -+{ -+ struct net_device *orig_dev = mdb->obj.orig_dev; -+ bool cpu_port = netif_is_bridge_master(orig_dev); -+ u8 port_mask, fid_c2; -+ int err; -+ -+ if (switchdev_trans_ph_prepare(trans)) -+ return 0; -+ -+ if (cpu_port) -+ port_mask = BIT(PRUETH_PORT_HOST); -+ else -+ port_mask = BIT(emac->port_id); -+ -+ fid_c2 = icssg_fdb_lookup(emac, mdb->addr, mdb->vid); -+ -+ err = icssg_fdb_add_del(emac, mdb->addr, mdb->vid, fid_c2 | port_mask, true); -+ netdev_dbg(emac->ndev, "MDB add vid %u:%pM ports: %X\n", -+ mdb->vid, mdb->addr, port_mask); -+ -+ return err; -+} -+ -+static int prueth_switchdev_mdb_del(struct prueth_emac *emac, -+ struct switchdev_obj_port_mdb *mdb) -+ -+{ -+ struct net_device *orig_dev = mdb->obj.orig_dev; -+ bool cpu_port = netif_is_bridge_master(orig_dev); -+ int del_mask, ret, fid_c2; -+ -+ if (cpu_port) -+ del_mask = BIT(PRUETH_PORT_HOST); -+ else -+ del_mask = BIT(emac->port_id); -+ -+ fid_c2 = icssg_fdb_lookup(emac, mdb->addr, mdb->vid); -+ -+ if (fid_c2 & ~del_mask) -+ ret = icssg_fdb_add_del(emac, mdb->addr, mdb->vid, fid_c2 & ~del_mask, true); -+ else -+ ret = icssg_fdb_add_del(emac, mdb->addr, mdb->vid, 0, false); -+ -+ netdev_dbg(emac->ndev, "MDB del vid %u:%pM ports: %X\n", -+ mdb->vid, mdb->addr, del_mask); -+ -+ return ret; -+} -+ -+static int prueth_switchdev_obj_add(struct net_device *ndev, -+ const struct switchdev_obj *obj, -+ struct switchdev_trans *trans, -+ struct netlink_ext_ack *extack) -+{ -+ struct switchdev_obj_port_vlan *vlan = SWITCHDEV_OBJ_PORT_VLAN(obj); -+ struct switchdev_obj_port_mdb *mdb = SWITCHDEV_OBJ_PORT_MDB(obj); -+ struct prueth_emac *emac = netdev_priv(ndev); -+ int err = 0; -+ -+ netdev_dbg(ndev, "obj_add: id %u port: %u\n", obj->id, emac->port_id); -+ -+ switch (obj->id) { -+ case SWITCHDEV_OBJ_ID_PORT_VLAN: -+ err = prueth_switchdev_vlans_add(emac, vlan, trans); -+ break; -+ case SWITCHDEV_OBJ_ID_PORT_MDB: -+ case SWITCHDEV_OBJ_ID_HOST_MDB: -+ err = prueth_switchdev_mdb_add(emac, mdb, trans); -+ break; -+ default: -+ err = -EOPNOTSUPP; -+ break; -+ } -+ -+ return err; -+} -+ -+static int prueth_switchdev_obj_del(struct net_device *ndev, -+ const struct switchdev_obj *obj) -+{ -+ struct switchdev_obj_port_vlan *vlan = SWITCHDEV_OBJ_PORT_VLAN(obj); -+ struct switchdev_obj_port_mdb *mdb = SWITCHDEV_OBJ_PORT_MDB(obj); -+ struct prueth_emac *emac = netdev_priv(ndev); -+ int err = 0; -+ -+ netdev_dbg(ndev, "obj_del: id %u port: %u\n", obj->id, emac->port_id); -+ -+ switch (obj->id) { -+ case SWITCHDEV_OBJ_ID_PORT_VLAN: -+ err = prueth_switchdev_vlans_del(emac, vlan); -+ break; -+ case SWITCHDEV_OBJ_ID_PORT_MDB: -+ case SWITCHDEV_OBJ_ID_HOST_MDB: -+ err = prueth_switchdev_mdb_del(emac, mdb); -+ break; -+ default: -+ err = -EOPNOTSUPP; -+ break; -+ } -+ -+ return err; -+} -+ -+static int prueth_switchdev_blocking_event(struct notifier_block *unused, -+ unsigned long event, void *ptr) -+{ -+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr); -+ int err; -+ -+ switch (event) { -+ case SWITCHDEV_PORT_OBJ_ADD: -+ err = switchdev_handle_port_obj_add(dev, ptr, -+ prueth_dev_check, -+ prueth_switchdev_obj_add); -+ return notifier_from_errno(err); -+ case SWITCHDEV_PORT_OBJ_DEL: -+ err = switchdev_handle_port_obj_del(dev, ptr, -+ prueth_dev_check, -+ prueth_switchdev_obj_del); -+ return notifier_from_errno(err); -+ case SWITCHDEV_PORT_ATTR_SET: -+ err = switchdev_handle_port_attr_set(dev, ptr, -+ prueth_dev_check, -+ prueth_switchdev_attr_set); -+ return notifier_from_errno(err); -+ default: -+ break; -+ } -+ -+ return NOTIFY_DONE; -+} -+ -+int prueth_switchdev_register_notifiers(struct prueth *prueth) -+{ -+ int ret = 0; -+ -+ prueth->prueth_switchdev_nb.notifier_call = &prueth_switchdev_event; -+ ret = register_switchdev_notifier(&prueth->prueth_switchdev_nb); -+ if (ret) { -+ dev_err(prueth->dev, "register switchdev notifier fail ret:%d\n", -+ ret); -+ return ret; -+ } -+ -+ prueth->prueth_switchdev_bl_nb.notifier_call = &prueth_switchdev_blocking_event; -+ ret = register_switchdev_blocking_notifier(&prueth->prueth_switchdev_bl_nb); -+ if (ret) { -+ dev_err(prueth->dev, "register switchdev blocking notifier ret:%d\n", -+ ret); -+ unregister_switchdev_notifier(&prueth->prueth_switchdev_nb); -+ } -+ -+ return ret; -+} -+ -+void prueth_switchdev_unregister_notifiers(struct prueth *prueth) -+{ -+ unregister_switchdev_blocking_notifier(&prueth->prueth_switchdev_bl_nb); -+ unregister_switchdev_notifier(&prueth->prueth_switchdev_nb); -+} -diff --git a/drivers/net/ethernet/ti/icssg_switchdev.h b/drivers/net/ethernet/ti/icssg_switchdev.h -new file mode 100644 -index 000000000000..0e64e7760a00 ---- /dev/null -+++ b/drivers/net/ethernet/ti/icssg_switchdev.h -@@ -0,0 +1,13 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/ -+ */ -+#ifndef __NET_TI_ICSSG_SWITCHDEV_H -+#define __NET_TI_ICSSG_SWITCHDEV_H -+ -+#include "icssg_prueth.h" -+ -+int prueth_switchdev_register_notifiers(struct prueth *prueth); -+void prueth_switchdev_unregister_notifiers(struct prueth *prueth); -+bool prueth_dev_check(const struct net_device *ndev); -+ -+#endif /* __NET_TI_ICSSG_SWITCHDEV_H */ diff --git a/recipes-kernel/linux/files/patches-5.10/0160-net-ethernet-ti-icssg_prueth-Add-support-for-ICSSG-s.patch b/recipes-kernel/linux/files/patches-5.10/0160-net-ethernet-ti-icssg_prueth-Add-support-for-ICSSG-s.patch deleted file mode 100644 index 5bb314e99..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0160-net-ethernet-ti-icssg_prueth-Add-support-for-ICSSG-s.patch +++ /dev/null @@ -1,839 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Thu, 14 Oct 2021 14:14:28 +0530 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: Add support for ICSSG switch - firmware on AM654 PG2.0 - -Add support for ICSSG switch firmware using existing Dual EMAC driver -with switchdev and devlink framework. - -Limitations: -VLAN offloading is limited to 0-256 IDs. -MDB/FDB static entries are limited to 511 entries and different FDBs can -hash to same bucket and thus may not completely offloaded - -Switch mode requires loading of new firmware into ICSSG cores. This -means interfaces have to taken down and then reconfigured to switch mode -using devlink. - -Example assuming ETH1 and ETH2 as ICSSG2 interfaces: - -Switch to ICSSG Switch mode: - ip link set dev eth1 down - ip link set dev eth2 down - devlink dev param set platform/icssg2-eth name switch_mode value 1 cmode runtime - ip link add name br0 type bridge - ip link set dev eth1 master br0 - ip link set dev eth2 master br0 - ip link set dev br0 up - ip link set dev eth1 up - ip link set dev eth2 up - bridge vlan add dev br0 vid 1 pvid untagged self - -Going back to Dual EMAC mode: - - ip link set dev br0 down - ip link set dev eth1 nomaster - ip link set dev eth2 nomaster - ip link set dev eth1 down - ip link set dev eth2 down - devlink dev param set platform/icssg2-eth name switch_mode value 0 cmode runtime - ip link del name br0 type bridge - ip link set dev eth1 up - ip link set dev eth2 up - -By default, Dual EMAC firmware is loaded, and can be changed to switch -mode by above steps - -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/Kconfig | 1 + - drivers/net/ethernet/ti/Makefile | 2 +- - drivers/net/ethernet/ti/icssg_classifier.c | 8 + - drivers/net/ethernet/ti/icssg_config.c | 143 +++++++- - drivers/net/ethernet/ti/icssg_config.h | 6 + - drivers/net/ethernet/ti/icssg_prueth.c | 398 ++++++++++++++++++++- - drivers/net/ethernet/ti/icssg_prueth.h | 1 + - 7 files changed, 545 insertions(+), 14 deletions(-) - -diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig -index f17df3b25dd0..90ede5a5f108 100644 ---- a/drivers/net/ethernet/ti/Kconfig -+++ b/drivers/net/ethernet/ti/Kconfig -@@ -186,6 +186,7 @@ config TI_ICSSG_PRUETH - select TI_ICSS_IEP - imply PTP_1588_CLOCK - depends on PRU_REMOTEPROC -+ depends on NET_SWITCHDEV - depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER - help - Support dual Gigabit Ethernet ports over the ICSSG PRU Subsystem -diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile -index b40292eff9bf..5b4cc0a3e3f8 100644 ---- a/drivers/net/ethernet/ti/Makefile -+++ b/drivers/net/ethernet/ti/Makefile -@@ -31,4 +31,4 @@ obj-$(CONFIG_TI_K3_AM65_CPTS) += am65-cpts.o - obj-$(CONFIG_TI_ICSS_IEP) += icss_iep.o - - obj-$(CONFIG_TI_ICSSG_PRUETH) += icssg-prueth.o --icssg-prueth-y := icssg_prueth.o icssg_classifier.o icssg_ethtool.o icssg_queues.o icssg_config.o k3-cppi-desc-pool.o icssg_mii_cfg.o -+icssg-prueth-y := icssg_prueth.o icssg_classifier.o icssg_ethtool.o icssg_queues.o icssg_config.o k3-cppi-desc-pool.o icssg_mii_cfg.o icssg_switchdev.o -diff --git a/drivers/net/ethernet/ti/icssg_classifier.c b/drivers/net/ethernet/ti/icssg_classifier.c -index ea9a1c7bb0fe..47b13672d723 100644 ---- a/drivers/net/ethernet/ti/icssg_classifier.c -+++ b/drivers/net/ethernet/ti/icssg_classifier.c -@@ -114,6 +114,8 @@ enum rx_class_sel_type { - #define RX_CLASS_SEL_MASK(n) (0x3 << RX_CLASS_SEL_SHIFT((n))) - - #define ICSSG_CFG_OFFSET 0 -+#define MAC_INTERFACE_0 0x18 -+#define MAC_INTERFACE_1 0x1c - - #define ICSSG_CFG_RX_L2_G_EN BIT(2) - -@@ -287,6 +289,12 @@ static u32 rx_class_get_or(struct regmap *miig_rt, int slice, int n) - return val; - } - -+void icssg_class_set_host_mac_addr(struct regmap *miig_rt, u8 *mac) -+{ -+ regmap_write(miig_rt, MAC_INTERFACE_0, addr_to_da0(mac)); -+ regmap_write(miig_rt, MAC_INTERFACE_1, addr_to_da1(mac)); -+} -+ - void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac) - { - regmap_write(miig_rt, offs[slice].mac0, addr_to_da0(mac)); -diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c -index ec996b540ce8..8d813da0baf6 100644 ---- a/drivers/net/ethernet/ti/icssg_config.c -+++ b/drivers/net/ethernet/ti/icssg_config.c -@@ -98,6 +98,42 @@ struct map hwq_map[2][ICSSG_NUM_OTHER_QUEUES] = { - }, - }; - -+static void icssg_config_mii_init_switch(struct prueth_emac *emac) -+{ -+ struct prueth *prueth = emac->prueth; -+ struct regmap *mii_rt = prueth->mii_rt; -+ int mii = prueth_emac_slice(emac); -+ u32 rxcfg_reg, txcfg_reg, pcnt_reg; -+ u32 rxcfg, txcfg; -+ -+ rxcfg_reg = (mii == ICSS_MII0) ? PRUSS_MII_RT_RXCFG0 : -+ PRUSS_MII_RT_RXCFG1; -+ txcfg_reg = (mii == ICSS_MII0) ? PRUSS_MII_RT_TXCFG0 : -+ PRUSS_MII_RT_TXCFG1; -+ pcnt_reg = (mii == ICSS_MII0) ? PRUSS_MII_RT_RX_PCNT0 : -+ PRUSS_MII_RT_RX_PCNT1; -+ -+ rxcfg = PRUSS_MII_RT_RXCFG_RX_ENABLE | -+ PRUSS_MII_RT_RXCFG_RX_L2_EN | -+ PRUSS_MII_RT_RXCFG_RX_L2_EOF_SCLR_DIS; -+ -+ txcfg = PRUSS_MII_RT_TXCFG_TX_ENABLE | -+ PRUSS_MII_RT_TXCFG_TX_AUTO_PREAMBLE | -+ PRUSS_MII_RT_TXCFG_TX_IPG_WIRE_CLK_EN; -+ -+ if (mii == ICSS_MII1) -+ rxcfg |= PRUSS_MII_RT_RXCFG_RX_MUX_SEL; -+ -+ if (emac->phy_if == PHY_INTERFACE_MODE_MII && mii == ICSS_MII1) -+ txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL; -+ else if (emac->phy_if != PHY_INTERFACE_MODE_MII && mii == ICSS_MII0) -+ txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL; -+ -+ regmap_write(mii_rt, rxcfg_reg, rxcfg); -+ regmap_write(mii_rt, txcfg_reg, txcfg); -+ regmap_write(mii_rt, pcnt_reg, 0x1); -+} -+ - static void icssg_config_mii_init(struct prueth_emac *emac) - { - struct prueth *prueth = emac->prueth; -@@ -295,6 +331,62 @@ static int emac_r30_is_done(struct prueth_emac *emac) - return 1; - } - -+static int prueth_switch_buffer_setup(struct prueth_emac *emac) -+{ -+ struct icssg_buffer_pool_cfg *bpool_cfg; -+ struct prueth *prueth = emac->prueth; -+ int slice = prueth_emac_slice(emac); -+ struct icssg_rxq_ctx *rxq_ctx; -+ u32 addr; -+ int i; -+ -+ addr = lower_32_bits(prueth->msmcram.pa); -+ if (slice) -+ addr += PRUETH_NUM_BUF_POOLS_SR2 * PRUETH_EMAC_BUF_POOL_SIZE_SR2; -+ -+ if (addr % SZ_64K) { -+ dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n"); -+ return -EINVAL; -+ } -+ -+ bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET; -+ /* workaround for f/w bug. bpool 0 needs to be initilalized */ -+ for (i = 0; -+ i < PRUETH_NUM_BUF_POOLS_SR2; -+ i++) { -+ bpool_cfg[i].addr = cpu_to_le32(addr); -+ bpool_cfg[i].len = cpu_to_le32(PRUETH_EMAC_BUF_POOL_SIZE_SR2); -+ addr += PRUETH_EMAC_BUF_POOL_SIZE_SR2; -+ } -+ -+ if (!slice) -+ addr += PRUETH_NUM_BUF_POOLS_SR2 * PRUETH_EMAC_BUF_POOL_SIZE_SR2; -+ else -+ addr += PRUETH_SW_NUM_BUF_POOLS_HOST_SR2 * PRUETH_SW_BUF_POOL_SIZE_HOST_SR2; -+ -+ for (i = PRUETH_NUM_BUF_POOLS_SR2; -+ i < PRUETH_SW_NUM_BUF_POOLS_HOST_SR2 + PRUETH_NUM_BUF_POOLS_SR2; -+ i++) { -+ bpool_cfg[i].addr = cpu_to_le32(addr); -+ bpool_cfg[i].len = cpu_to_le32(PRUETH_SW_BUF_POOL_SIZE_HOST_SR2); -+ addr += PRUETH_SW_BUF_POOL_SIZE_HOST_SR2; -+ } -+ -+ if (!slice) -+ addr += PRUETH_SW_NUM_BUF_POOLS_HOST_SR2 * PRUETH_SW_BUF_POOL_SIZE_HOST_SR2; -+ else -+ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; -+ -+ rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET; -+ for (i = 0; i < 3; i++) -+ rxq_ctx->start[i] = cpu_to_le32(addr); -+ -+ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; -+ rxq_ctx->end = cpu_to_le32(addr) - SZ_2K; -+ -+ return 0; -+} -+ - static int prueth_emac_buffer_setup(struct prueth_emac *emac) - { - struct icssg_buffer_pool_cfg *bpool_cfg; -@@ -344,6 +436,42 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac) - return 0; - } - -+static void icssg_init_emac_mode(struct prueth *prueth) -+{ -+ u8 mac[ETH_ALEN] = { 0 }; -+ -+ if (prueth->emacs_initialized) -+ return; -+ -+ regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK, 0); -+ regmap_write(prueth->miig_rt, FDB_GEN_CFG2, 0); -+ /* Clear host MAC address */ -+ icssg_class_set_host_mac_addr(prueth->miig_rt, mac); -+} -+ -+static void icssg_init_switch_mode(struct prueth *prueth) -+{ -+ int i; -+ u32 addr = prueth->shram.pa + EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET; -+ -+ if (prueth->emacs_initialized) -+ return; -+ -+ /* Set VLAN TABLE address base */ -+ regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK, -+ addr << SMEM_VLAN_OFFSET); -+ /* Set enable VLAN aware mode, and FDBs for all PRUs */ -+ regmap_write(prueth->miig_rt, FDB_GEN_CFG2, FDB_EN_ALL); -+ prueth->vlan_tbl = prueth->shram.va + EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET; -+ for (i = 0; i < SZ_4K - 1; i++) { -+ prueth->vlan_tbl[i].fid = i; -+ prueth->vlan_tbl[i].fid_c1 = 0; -+ } -+ -+ icssg_class_set_host_mac_addr(prueth->miig_rt, prueth->hw_bridge_dev->dev_addr); -+ icssg_set_pvid(prueth, prueth->default_vlan, PRUETH_PORT_HOST); -+} -+ - int icssg_config_sr2(struct prueth *prueth, struct prueth_emac *emac, int slice) - { - void *config = emac->dram.va + ICSSG_CONFIG_OFFSET; -@@ -352,6 +480,11 @@ int icssg_config_sr2(struct prueth *prueth, struct prueth_emac *emac, int slice) - u32 mask; - int ret; - -+ if (prueth->is_switch_mode) -+ icssg_init_switch_mode(prueth); -+ else -+ icssg_init_emac_mode(prueth); -+ - memset_io(config, 0, TAS_GATE_MASK_LIST0); - icssg_miig_queues_init(prueth, slice); - -@@ -363,7 +496,10 @@ int icssg_config_sr2(struct prueth *prueth, struct prueth_emac *emac, int slice) - } - regmap_update_bits(prueth->miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_DEFAULT, ICSSG_CFG_DEFAULT); - icssg_miig_set_interface_mode(prueth->miig_rt, slice, emac->phy_if); -- icssg_config_mii_init(emac); -+ if (prueth->is_switch_mode) -+ icssg_config_mii_init_switch(emac); -+ else -+ icssg_config_mii_init(emac); - icssg_config_ipg(emac); - icssg_update_rgmii_cfg(prueth->miig_rt, emac); - -@@ -386,7 +522,10 @@ int icssg_config_sr2(struct prueth *prueth, struct prueth_emac *emac, int slice) - *(cfg_byte_ptr + SPL_PKT_DEFAULT_PRIORITY) = 0; - *(cfg_byte_ptr + QUEUE_NUM_UNTAGGED) = 0x0; - -- ret = prueth_emac_buffer_setup(emac); -+ if (prueth->is_switch_mode) -+ ret = prueth_switch_buffer_setup(emac); -+ else -+ ret = prueth_emac_buffer_setup(emac); - if (ret) - return ret; - -diff --git a/drivers/net/ethernet/ti/icssg_config.h b/drivers/net/ethernet/ti/icssg_config.h -index 887e85789f05..bcac3d6e1dd7 100644 ---- a/drivers/net/ethernet/ti/icssg_config.h -+++ b/drivers/net/ethernet/ti/icssg_config.h -@@ -105,6 +105,12 @@ struct icssg_config_sr1 { - (2 * (PRUETH_EMAC_BUF_POOL_SIZE_SR2 * PRUETH_NUM_BUF_POOLS_SR2 + \ - PRUETH_EMAC_RX_CTX_BUF_SIZE)) - -+#define PRUETH_SW_BUF_POOL_SIZE_HOST_SR2 SZ_2K -+#define PRUETH_SW_NUM_BUF_POOLS_HOST_SR2 16 -+#define MSMC_RAM_SIZE_SR2_SWITCH_MODE \ -+ (MSMC_RAM_SIZE_SR2 + \ -+ (2 * PRUETH_SW_BUF_POOL_SIZE_HOST_SR2 * PRUETH_SW_NUM_BUF_POOLS_HOST_SR2)) -+ - #define PRUETH_SWITCH_FDB_MASK ((SIZE_OF_FDB / NUMBER_OF_FDB_BUCKET_ENTRIES) - 1) - - struct icssg_rxq_ctx { -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index d58588b5294c..95e383a01bc8 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -581,6 +581,8 @@ static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) - new_skb = skb; - } else { - /* send the filled skb up the n/w stack */ -+ if (emac->prueth->is_switch_mode) -+ skb->offload_fwd_mark = emac->offload_fwd_mark; - skb_put(skb, pkt_len); - skb->protocol = eth_type_trans(skb, ndev); - netif_receive_skb(skb); -@@ -876,9 +878,10 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - } - - /* set dst tag to indicate internal qid at the firmware which is at -- * bit8..bit15 -+ * bit8..bit15. bit0..bit7 indicates port num for directed -+ * packets in case of switch mode operation - */ -- cppi5_desc_set_tags_ids(&first_desc->hdr, 0, (q_idx << 8)); -+ cppi5_desc_set_tags_ids(&first_desc->hdr, 0, (emac->port_id | (q_idx << 8))); - cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len); - swdata = cppi5_hdesc_get_swdata(first_desc); - *swdata = skb; -@@ -1155,11 +1158,49 @@ static irqreturn_t prueth_rx_irq(int irq, void *dev_id) - return IRQ_HANDLED; - } - -+struct icssg_firmwares { -+ char *pru; -+ char *rtu; -+ char *txpru; -+}; -+ -+static struct icssg_firmwares icssg_switch_firmwares[] = { -+ { -+ .pru = "ti-pruss/am65x-sr2-pru0-prusw-fw.elf", -+ .rtu = "ti-pruss/am65x-sr2-rtu0-prusw-fw.elf", -+ .txpru = "ti-pruss/am65x-sr2-txpru0-prusw-fw.elf", -+ }, -+ { -+ .pru = "ti-pruss/am65x-sr2-pru1-prusw-fw.elf", -+ .rtu = "ti-pruss/am65x-sr2-rtu1-prusw-fw.elf", -+ .txpru = "ti-pruss/am65x-sr2-txpru1-prusw-fw.elf", -+ } -+}; -+ -+static struct icssg_firmwares icssg_emac_firmwares[] = { -+ { -+ .pru = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf", -+ .rtu = "ti-pruss/am65x-sr2-rtu0-prueth-fw.elf", -+ .txpru = "ti-pruss/am65x-sr2-txpru0-prueth-fw.elf", -+ }, -+ { -+ .pru = "ti-pruss/am65x-sr2-pru1-prueth-fw.elf", -+ .rtu = "ti-pruss/am65x-sr2-rtu1-prueth-fw.elf", -+ .txpru = "ti-pruss/am65x-sr2-txpru1-prueth-fw.elf", -+ } -+}; -+ - static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac) - { -+ struct icssg_firmwares *firmwares; - struct device *dev = prueth->dev; - int slice, ret; - -+ if (prueth->is_switch_mode) -+ firmwares = icssg_switch_firmwares; -+ else -+ firmwares = icssg_emac_firmwares; -+ - slice = prueth_emac_slice(emac); - if (slice < 0) { - netdev_err(emac->ndev, "invalid port\n"); -@@ -1175,12 +1216,14 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac) - return ret; - } - -+ ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru); - ret = rproc_boot(prueth->pru[slice]); - if (ret) { - dev_err(dev, "failed to boot PRU%d: %d\n", slice, ret); - return -EINVAL; - } - -+ ret = rproc_set_firmware(prueth->rtu[slice], firmwares[slice].rtu); - ret = rproc_boot(prueth->rtu[slice]); - if (ret) { - dev_err(dev, "failed to boot RTU%d: %d\n", slice, ret); -@@ -1190,6 +1233,7 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac) - if (emac->is_sr1) - goto done; - -+ ret = rproc_set_firmware(prueth->txpru[slice], firmwares[slice].txpru); - ret = rproc_boot(prueth->txpru[slice]); - if (ret) { - dev_err(dev, "failed to boot TX_PRU%d: %d\n", slice, ret); -@@ -1700,6 +1744,18 @@ static int emac_ndo_open(struct net_device *ndev) - if (netif_msg_drv(emac)) - dev_notice(&ndev->dev, "started\n"); - -+ if (prueth->is_switch_mode) { -+ icssg_fdb_add_del(emac, eth_stp_addr, prueth->default_vlan, -+ ICSSG_FDB_ENTRY_P0_MEMBERSHIP | -+ ICSSG_FDB_ENTRY_P1_MEMBERSHIP | -+ ICSSG_FDB_ENTRY_P2_MEMBERSHIP | -+ ICSSG_FDB_ENTRY_BLOCK, -+ true); -+ icssg_vtbl_modify(emac, emac->port_vlan, BIT(emac->port_id), -+ BIT(emac->port_id), true); -+ icssg_set_pvid(emac->prueth, emac->port_vlan, emac->port_id); -+ emac_set_port_state(emac, ICSSG_EMAC_PORT_VLAN_AWARE_ENABLE); -+ } - return 0; - - reset_tx_chan: -@@ -2000,17 +2056,11 @@ static int emac_ndo_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) - return phy_mii_ioctl(emac->phydev, ifr, cmd); - } - --static int emac_ndo_get_phys_port_name(struct net_device *ndev, char *name, size_t len) -+static struct devlink_port *emac_ndo_get_devlink_port(struct net_device *ndev) - { - struct prueth_emac *emac = netdev_priv(ndev); -- int err; -- -- err = snprintf(name, len, "p%d", emac->port_id); -- -- if (err >= len) -- return -EINVAL; - -- return 0; -+ return &emac->devlink_port; - } - - static const struct net_device_ops emac_netdev_ops = { -@@ -2022,7 +2072,7 @@ static const struct net_device_ops emac_netdev_ops = { - .ndo_tx_timeout = emac_ndo_tx_timeout, - .ndo_set_rx_mode = emac_ndo_set_rx_mode, - .ndo_do_ioctl = emac_ndo_ioctl, -- .ndo_get_phys_port_name = emac_ndo_get_phys_port_name, -+ .ndo_get_devlink_port = emac_ndo_get_devlink_port, - }; - - /* get emac_port corresponding to eth_node name */ -@@ -2344,6 +2394,310 @@ static void prueth_put_cores(struct prueth *prueth, int slice) - pru_rproc_put(prueth->pru[slice]); - } - -+static void prueth_offload_fwd_mark_update(struct prueth *prueth) -+{ -+ int set_val = 0; -+ int i; -+ -+ if (prueth->br_members == (PRUETH_PORT_MII0 | PRUETH_PORT_MII1)) -+ set_val = 1; -+ -+ dev_dbg(prueth->dev, "set offload_fwd_mark %d\n", set_val); -+ -+ for (i = PRUETH_MAC0; i < PRUETH_NUM_MACS; i++) { -+ struct prueth_emac *emac = prueth->emac[i]; -+ -+ if (!emac || !emac->ndev) -+ continue; -+ -+ emac->offload_fwd_mark = set_val; -+ } -+} -+ -+bool prueth_dev_check(const struct net_device *ndev) -+{ -+ if (ndev->netdev_ops == &emac_netdev_ops && netif_running(ndev)) { -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ return emac->prueth->is_switch_mode; -+ } -+ -+ return false; -+} -+ -+static int prueth_netdevice_port_link(struct net_device *ndev, struct net_device *br_ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth *prueth = emac->prueth; -+ -+ if (!prueth->is_switch_mode) -+ return NOTIFY_DONE; -+ -+ if (!prueth->br_members) { -+ prueth->hw_bridge_dev = br_ndev; -+ } else { -+ /* This is adding the port to a second bridge, this is -+ * unsupported -+ */ -+ if (prueth->hw_bridge_dev != br_ndev) -+ return -EOPNOTSUPP; -+ } -+ -+ prueth->br_members |= BIT(emac->port_id); -+ -+ prueth_offload_fwd_mark_update(prueth); -+ -+ return NOTIFY_DONE; -+} -+ -+static void prueth_netdevice_port_unlink(struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth *prueth = emac->prueth; -+ -+ prueth->br_members &= ~BIT(emac->port_id); -+ -+ prueth_offload_fwd_mark_update(prueth); -+ -+ if (!prueth->br_members) -+ prueth->hw_bridge_dev = NULL; -+} -+ -+/* netdev notifier */ -+static int prueth_netdevice_event(struct notifier_block *unused, -+ unsigned long event, void *ptr) -+{ -+ struct net_device *ndev = netdev_notifier_info_to_dev(ptr); -+ struct netdev_notifier_changeupper_info *info; -+ int ret = NOTIFY_DONE; -+ -+ if (ndev->netdev_ops != &emac_netdev_ops) -+ return NOTIFY_DONE; -+ -+ switch (event) { -+ case NETDEV_CHANGEUPPER: -+ info = ptr; -+ -+ if (netif_is_bridge_master(info->upper_dev)) { -+ if (info->linking) -+ ret = prueth_netdevice_port_link(ndev, info->upper_dev); -+ else -+ prueth_netdevice_port_unlink(ndev); -+ } -+ break; -+ default: -+ return NOTIFY_DONE; -+ } -+ -+ return notifier_from_errno(ret); -+} -+ -+static int prueth_register_notifiers(struct prueth *prueth) -+{ -+ int ret = 0; -+ -+ prueth->prueth_netdevice_nb.notifier_call = &prueth_netdevice_event; -+ ret = register_netdevice_notifier(&prueth->prueth_netdevice_nb); -+ if (ret) { -+ dev_err(prueth->dev, "can't register netdevice notifier\n"); -+ return ret; -+ } -+ -+ ret = prueth_switchdev_register_notifiers(prueth); -+ if (ret) -+ unregister_netdevice_notifier(&prueth->prueth_netdevice_nb); -+ -+ return ret; -+} -+ -+static void prueth_unregister_notifiers(struct prueth *prueth) -+{ -+ prueth_switchdev_unregister_notifiers(prueth); -+ unregister_netdevice_notifier(&prueth->prueth_netdevice_nb); -+} -+ -+static const struct devlink_ops prueth_devlink_ops = {}; -+ -+static int prueth_dl_switch_mode_get(struct devlink *dl, u32 id, -+ struct devlink_param_gset_ctx *ctx) -+{ -+ struct prueth_devlink *dl_priv = devlink_priv(dl); -+ struct prueth *prueth = dl_priv->prueth; -+ -+ dev_dbg(prueth->dev, "%s id:%u\n", __func__, id); -+ -+ if (id != PRUETH_DL_PARAM_SWITCH_MODE) -+ return -EOPNOTSUPP; -+ -+ ctx->val.vbool = prueth->is_switch_mode; -+ -+ return 0; -+} -+ -+static int prueth_dl_switch_mode_set(struct devlink *dl, u32 id, -+ struct devlink_param_gset_ctx *ctx) -+{ -+ struct prueth_devlink *dl_priv = devlink_priv(dl); -+ struct prueth *prueth = dl_priv->prueth; -+ bool switch_en = ctx->val.vbool; -+ int i; -+ -+ dev_dbg(prueth->dev, "%s id:%u\n", __func__, id); -+ -+ if (id != PRUETH_DL_PARAM_SWITCH_MODE) -+ return -EOPNOTSUPP; -+ -+ if (switch_en == prueth->is_switch_mode) -+ return 0; -+ -+ if (!switch_en && prueth->br_members) { -+ dev_err(prueth->dev, "Remove ports from bridge before disabling switch mode\n"); -+ return -EINVAL; -+ } -+ -+ rtnl_lock(); -+ -+ prueth->default_vlan = 1; -+ prueth->is_switch_mode = switch_en; -+ -+ for (i = PRUETH_MAC0; i < PRUETH_NUM_MACS; i++) { -+ struct net_device *sl_ndev = prueth->emac[i]->ndev; -+ -+ if (!sl_ndev || !netif_running(sl_ndev)) -+ continue; -+ -+ dev_err(prueth->dev, "Cannot switch modes when i/f are up\n"); -+ goto exit; -+ } -+ -+ for (i = PRUETH_MAC0; i < PRUETH_NUM_MACS; i++) { -+ struct net_device *sl_ndev = prueth->emac[i]->ndev; -+ struct prueth_emac *emac; -+ -+ if (!sl_ndev) -+ continue; -+ -+ emac = netdev_priv(sl_ndev); -+ if (switch_en) -+ emac->port_vlan = prueth->default_vlan; -+ else -+ emac->port_vlan = 0; -+ } -+ -+ dev_info(prueth->dev, "Enabling %s mode\n", -+ switch_en ? "switch" : "Dual EMAC"); -+ -+exit: -+ rtnl_unlock(); -+ -+ return 0; -+} -+ -+static const struct devlink_param prueth_devlink_params[] = { -+ DEVLINK_PARAM_DRIVER(PRUETH_DL_PARAM_SWITCH_MODE, "switch_mode", -+ DEVLINK_PARAM_TYPE_BOOL, -+ BIT(DEVLINK_PARAM_CMODE_RUNTIME), -+ prueth_dl_switch_mode_get, -+ prueth_dl_switch_mode_set, NULL), -+}; -+ -+static void prueth_unregister_devlink_ports(struct prueth *prueth) -+{ -+ struct devlink_port *dl_port; -+ struct prueth_emac *emac; -+ int i; -+ -+ for (i = PRUETH_MAC0; i < PRUETH_NUM_MACS; i++) { -+ emac = prueth->emac[i]; -+ dl_port = &emac->devlink_port; -+ -+ if (dl_port->registered) -+ devlink_port_unregister(dl_port); -+ } -+} -+ -+static int prueth_register_devlink(struct prueth *prueth) -+{ -+ struct devlink_port_attrs attrs = {}; -+ struct prueth_devlink *dl_priv; -+ struct device *dev = prueth->dev; -+ struct devlink_port *dl_port; -+ struct prueth_emac *emac; -+ int ret = 0; -+ int i; -+ -+ prueth->devlink = -+ devlink_alloc(&prueth_devlink_ops, sizeof(*dl_priv)); -+ if (!prueth->devlink) -+ return -ENOMEM; -+ -+ dl_priv = devlink_priv(prueth->devlink); -+ dl_priv->prueth = prueth; -+ -+ ret = devlink_register(prueth->devlink, dev); -+ if (ret) { -+ dev_err(dev, "devlink reg fail ret:%d\n", ret); -+ goto dl_free; -+ } -+ -+ /* Provide devlink hook to switch mode when multiple external ports -+ * are present NUSS switchdev driver is enabled. -+ */ -+ if (prueth->is_switchmode_supported) { -+ ret = devlink_params_register(prueth->devlink, -+ prueth_devlink_params, -+ ARRAY_SIZE(prueth_devlink_params)); -+ if (ret) { -+ dev_err(dev, "devlink params reg fail ret:%d\n", ret); -+ goto dl_unreg; -+ } -+ devlink_params_publish(prueth->devlink); -+ } -+ -+ for (i = PRUETH_MAC0; i < PRUETH_NUM_MACS; i++) { -+ emac = prueth->emac[i]; -+ dl_port = &emac->devlink_port; -+ -+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; -+ attrs.phys.port_number = emac->port_id; -+ attrs.switch_id.id_len = sizeof(resource_size_t); -+ memcpy(attrs.switch_id.id, prueth->switch_id, attrs.switch_id.id_len); -+ devlink_port_attrs_set(dl_port, &attrs); -+ -+ ret = devlink_port_register(prueth->devlink, dl_port, emac->port_id); -+ if (ret) { -+ dev_err(dev, "devlink_port reg fail for port %d, ret:%d\n", -+ emac->port_id, ret); -+ goto dl_port_unreg; -+ } -+ devlink_port_type_eth_set(dl_port, emac->ndev); -+ } -+ -+ return ret; -+ -+dl_port_unreg: -+ prueth_unregister_devlink_ports(prueth); -+dl_unreg: -+ devlink_unregister(prueth->devlink); -+dl_free: -+ devlink_free(prueth->devlink); -+ -+ return ret; -+} -+ -+static void prueth_unregister_devlink(struct prueth *prueth) -+{ -+ if (prueth->is_switchmode_supported) { -+ devlink_params_unpublish(prueth->devlink); -+ devlink_params_unregister(prueth->devlink, prueth_devlink_params, -+ ARRAY_SIZE(prueth_devlink_params)); -+ } -+ -+ prueth_unregister_devlink_ports(prueth); -+ devlink_unregister(prueth->devlink); -+ devlink_free(prueth->devlink); -+} -+ - static const struct of_device_id prueth_dt_match[]; - - static int prueth_probe(struct platform_device *pdev) -@@ -2447,6 +2801,10 @@ static int prueth_probe(struct platform_device *pdev) - } - - msmc_ram_size = prueth->is_sr1 ? MSMC_RAM_SIZE_SR1 : MSMC_RAM_SIZE_SR2; -+ prueth->is_switchmode_supported = prueth->pdata.switch_mode; -+ if (prueth->is_switchmode_supported) -+ msmc_ram_size = MSMC_RAM_SIZE_SR2_SWITCH_MODE; -+ - if (prueth->is_sr1) { - prueth->msmcram.va = - (void __iomem *)gen_pool_alloc(prueth->sram_pool, -@@ -2558,6 +2916,18 @@ static int prueth_probe(struct platform_device *pdev) - prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev; - } - -+ if (prueth->is_switchmode_supported) { -+ ret = prueth_register_notifiers(prueth); -+ if (ret) -+ goto netdev_unregister; -+ -+ ret = prueth_register_devlink(prueth); -+ if (ret) -+ goto clean_unregister_notifiers; -+ -+ sprintf(prueth->switch_id, "%s", dev_name(dev)); -+ } -+ - dev_info(dev, "TI PRU ethernet driver initialized: %s EMAC mode\n", - (!eth0_node || !eth1_node) ? "single" : "dual"); - -@@ -2568,6 +2938,8 @@ static int prueth_probe(struct platform_device *pdev) - - return 0; - -+clean_unregister_notifiers: -+ prueth_unregister_notifiers(prueth); - netdev_unregister: - for (i = 0; i < PRUETH_NUM_MACS; i++) { - if (!prueth->registered_netdevs[i]) -@@ -2625,6 +2997,9 @@ static int prueth_remove(struct platform_device *pdev) - struct prueth *prueth = platform_get_drvdata(pdev); - int i; - -+ prueth_unregister_notifiers(prueth); -+ prueth_unregister_devlink(prueth); -+ - for (i = 0; i < PRUETH_NUM_MACS; i++) { - if (!prueth->registered_netdevs[i]) - continue; -@@ -2729,6 +3104,7 @@ static const struct prueth_pdata am654_icssg_pdata_sr1 = { - static const struct prueth_pdata am654_icssg_pdata = { - .fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE, - .quirk_10m_link_issue = 1, -+ .switch_mode = 1, - }; - - static const struct prueth_pdata am64x_icssg_pdata = { -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index e5068223bdf8..f1b986493218 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -298,6 +298,7 @@ struct emac_tx_ts_response { - - /* Classifier helpers */ - void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac); -+void icssg_class_set_host_mac_addr(struct regmap *miig_rt, u8 *mac); - void icssg_class_disable(struct regmap *miig_rt, int slice); - void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti, - bool is_sr1); diff --git a/recipes-kernel/linux/files/patches-5.10/0161-net-ethernet-ti-icssg_prueth-Export-prueth_iep_getti.patch b/recipes-kernel/linux/files/patches-5.10/0161-net-ethernet-ti-icssg_prueth-Export-prueth_iep_getti.patch deleted file mode 100644 index 773cb5778..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0161-net-ethernet-ti-icssg_prueth-Export-prueth_iep_getti.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Thu, 14 Oct 2021 14:26:54 +0530 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: Export prueth_iep_gettime() - to be used for TAPRIO support - -We need to know current IEP time to calculate cycles to wait before -applying taprio depending on base_time configured. Therefore export -preuth_iep_getttime to be used for taprio support - -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 2 +- - drivers/net/ethernet/ti/icssg_prueth.h | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 95e383a01bc8..8421272fad8a 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1440,7 +1440,7 @@ static void prueth_reset_rx_chan(struct prueth_rx_chn *chn, - k3_udma_glue_disable_rx_chn(chn->rx_chn); - } - --static u64 prueth_iep_gettime(void *clockops_data, struct ptp_system_timestamp *sts) -+u64 prueth_iep_gettime(void *clockops_data, struct ptp_system_timestamp *sts) - { - u32 hi_rollover_count, hi_rollover_count_r; - struct prueth_emac *emac = clockops_data; -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index f1b986493218..2aeca9c1e4db 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -349,4 +349,5 @@ void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port); - #define prueth_napi_to_tx_chn(pnapi) \ - container_of(pnapi, struct prueth_tx_chn, napi_tx) - -+u64 prueth_iep_gettime(void *clockops_data, struct ptp_system_timestamp *sts); - #endif /* __NET_TI_ICSSG_PRUETH_H */ diff --git a/recipes-kernel/linux/files/patches-5.10/0162-net-ethernet-ti-icssg_prueth-add-TAPRIO-offload-supp.patch b/recipes-kernel/linux/files/patches-5.10/0162-net-ethernet-ti-icssg_prueth-add-TAPRIO-offload-supp.patch deleted file mode 100644 index 41ffb37bf..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0162-net-ethernet-ti-icssg_prueth-add-TAPRIO-offload-supp.patch +++ /dev/null @@ -1,545 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Roger Quadros -Date: Thu, 14 Oct 2021 14:26:55 +0530 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: add TAPRIO offload support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -ICSSG dual-emac f/w supports Enhanced Scheduled Traffic (EST – defined -in P802.1Qbv/D2.2 that later got included in IEEE 802.1Q-2018) -configuration. EST allows express queue traffic to be scheduled -(placed) on the wire at specific repeatable time intervals. In -Linux kernel, EST configuration is done through tc command and -the taprio scheduler in the net core implements a software only -scheduler (SCH_TAPRIO). If the NIC is capable of EST configuration, -user indicate "flag 2" in the command which is then parsed by -taprio scheduler in net core and indicate that the command is to -be offloaded to h/w. taprio then offloads the command to the -driver by calling ndo_setup_tc() ndo ops. This patch implements -ndo_setup_tc() to offload EST configuration to ICSSG. - -[vigneshr@ti.com: -Remove cycle time limitations -Add support to specify future basetime -Use readx_poll_timeouts where possible -Fix checkpatch and build warnings] - -Signed-off-by: Roger Quadros -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/Makefile | 2 +- - drivers/net/ethernet/ti/icssg_prueth.c | 5 + - drivers/net/ethernet/ti/icssg_prueth.h | 4 + - drivers/net/ethernet/ti/icssg_qos.c | 298 +++++++++++++++++++++ - drivers/net/ethernet/ti/icssg_qos.h | 120 +++++++++ - drivers/net/ethernet/ti/icssg_switch_map.h | 2 + - 6 files changed, 430 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/ethernet/ti/icssg_qos.c - create mode 100644 drivers/net/ethernet/ti/icssg_qos.h - -diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile -index 5b4cc0a3e3f8..e136e9837075 100644 ---- a/drivers/net/ethernet/ti/Makefile -+++ b/drivers/net/ethernet/ti/Makefile -@@ -31,4 +31,4 @@ obj-$(CONFIG_TI_K3_AM65_CPTS) += am65-cpts.o - obj-$(CONFIG_TI_ICSS_IEP) += icss_iep.o - - obj-$(CONFIG_TI_ICSSG_PRUETH) += icssg-prueth.o --icssg-prueth-y := icssg_prueth.o icssg_classifier.o icssg_ethtool.o icssg_queues.o icssg_config.o k3-cppi-desc-pool.o icssg_mii_cfg.o icssg_switchdev.o -+icssg-prueth-y := icssg_prueth.o icssg_classifier.o icssg_ethtool.o icssg_queues.o icssg_config.o k3-cppi-desc-pool.o icssg_mii_cfg.o icssg_switchdev.o icssg_qos.o -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 8421272fad8a..193ec64f1341 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1733,6 +1733,8 @@ static int emac_ndo_open(struct net_device *ndev) - napi_enable(&emac->tx_chns[i].napi_tx); - napi_enable(&emac->napi_rx); - -+ icssg_qos_init(ndev); -+ - /* Get attached phy details */ - phy_attached_info(emac->phydev); - -@@ -1813,6 +1815,8 @@ static int emac_ndo_stop(struct net_device *ndev) - int rx_flow = emac->is_sr1 ? - PRUETH_RX_FLOW_DATA_SR1 : PRUETH_RX_FLOW_DATA_SR2; - -+ icssg_qos_cleanup(ndev); -+ - /* inform the upper layers. */ - netif_tx_stop_all_queues(ndev); - -@@ -2073,6 +2077,7 @@ static const struct net_device_ops emac_netdev_ops = { - .ndo_set_rx_mode = emac_ndo_set_rx_mode, - .ndo_do_ioctl = emac_ndo_ioctl, - .ndo_get_devlink_port = emac_ndo_get_devlink_port, -+ .ndo_setup_tc = icssg_qos_ndo_setup_tc, - }; - - /* get emac_port corresponding to eth_node name */ -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 2aeca9c1e4db..2ae732fec2c6 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -36,6 +36,7 @@ - #include "icssg_config.h" - #include "icss_iep.h" - #include "icssg_switch_map.h" -+#include "icssg_qos.h" - - #define ICSS_SLICE0 0 - #define ICSS_SLICE1 1 -@@ -188,6 +189,9 @@ struct prueth_emac { - bool offload_fwd_mark; - struct devlink_port devlink_port; - int port_vlan; -+ -+ struct prueth_qos qos; -+ struct work_struct ts_work; - }; - - /** -diff --git a/drivers/net/ethernet/ti/icssg_qos.c b/drivers/net/ethernet/ti/icssg_qos.c -new file mode 100644 -index 000000000000..a9086e2e374d ---- /dev/null -+++ b/drivers/net/ethernet/ti/icssg_qos.c -@@ -0,0 +1,298 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* Texas Instruments ICSSG PRUETH QoS submodule -+ * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ -+ */ -+ -+#include -+#include "icssg_prueth.h" -+#include "icssg_switch_map.h" -+ -+static void icssg_qos_tas_init(struct net_device *ndev); -+ -+void icssg_qos_init(struct net_device *ndev) -+{ -+ icssg_qos_tas_init(ndev); -+ -+ /* IET init goes here */ -+} -+ -+void icssg_qos_cleanup(struct net_device *ndev) -+{ -+ /* IET cleanup goes here */ -+} -+ -+static void tas_update_fw_list_pointers(struct prueth_emac *emac) -+{ -+ struct tas_config *tas = &emac->qos.tas.config; -+ -+ if ((readb(tas->active_list)) == TAS_LIST0) { -+ tas->firmware_active_list = emac->dram.va + TAS_GATE_MASK_LIST0; -+ tas->firmware_shadow_list = emac->dram.va + TAS_GATE_MASK_LIST1; -+ } else { -+ tas->firmware_active_list = emac->dram.va + TAS_GATE_MASK_LIST1; -+ tas->firmware_shadow_list = emac->dram.va + TAS_GATE_MASK_LIST0; -+ } -+} -+ -+static void tas_update_maxsdu_table(struct prueth_emac *emac) -+{ -+ struct tas_config *tas = &emac->qos.tas.config; -+ u16 *max_sdu_tbl_ptr; -+ u8 gate_idx; -+ -+ /* update the maxsdu table */ -+ max_sdu_tbl_ptr = emac->dram.va + TAS_QUEUE_MAX_SDU_LIST; -+ -+ for (gate_idx = 0; gate_idx < TAS_MAX_NUM_QUEUES; gate_idx++) -+ writew(tas->max_sdu_table.max_sdu[gate_idx], &max_sdu_tbl_ptr[gate_idx]); -+} -+ -+static void tas_reset(struct prueth_emac *emac) -+{ -+ struct tas_config *tas = &emac->qos.tas.config; -+ int i; -+ -+ for (i = 0; i < TAS_MAX_NUM_QUEUES; i++) -+ tas->max_sdu_table.max_sdu[i] = 2048; -+ -+ tas_update_maxsdu_table(emac); -+ -+ writeb(TAS_LIST0, tas->active_list); -+ -+ memset_io(tas->firmware_active_list, 0, sizeof(*tas->firmware_active_list)); -+ memset_io(tas->firmware_shadow_list, 0, sizeof(*tas->firmware_shadow_list)); -+} -+ -+static int tas_set_state(struct prueth_emac *emac, enum tas_state state) -+{ -+ struct tas_config *tas = &emac->qos.tas.config; -+ int ret; -+ -+ if (tas->state == state) -+ return 0; -+ -+ switch (state) { -+ case TAS_STATE_RESET: -+ tas_reset(emac); -+ ret = emac_set_port_state(emac, ICSSG_EMAC_PORT_TAS_RESET); -+ tas->state = TAS_STATE_RESET; -+ break; -+ case TAS_STATE_ENABLE: -+ ret = emac_set_port_state(emac, ICSSG_EMAC_PORT_TAS_ENABLE); -+ tas->state = TAS_STATE_ENABLE; -+ break; -+ case TAS_STATE_DISABLE: -+ ret = emac_set_port_state(emac, ICSSG_EMAC_PORT_TAS_DISABLE); -+ tas->state = TAS_STATE_DISABLE; -+ break; -+ default: -+ netdev_err(emac->ndev, "%s: unsupported state\n", __func__); -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (ret) -+ netdev_err(emac->ndev, "TAS set state failed %d\n", ret); -+ return ret; -+} -+ -+static int tas_set_trigger_list_change(struct prueth_emac *emac) -+{ -+ struct tc_taprio_qopt_offload *admin_list = emac->qos.tas.taprio_admin; -+ struct tas_config *tas = &emac->qos.tas.config; -+ struct ptp_system_timestamp sts; -+ u32 change_cycle_count; -+ u32 cycle_time; -+ u64 base_time; -+ u64 cur_time; -+ -+ cycle_time = admin_list->cycle_time - 4; /* -4ns to compensate for IEP wraparound time */ -+ base_time = admin_list->base_time; -+ cur_time = prueth_iep_gettime(emac, &sts); -+ -+ if (base_time > cur_time) -+ change_cycle_count = DIV_ROUND_UP_ULL(base_time - cur_time, cycle_time); -+ else -+ change_cycle_count = 1; -+ -+ writel(cycle_time, emac->dram.va + TAS_ADMIN_CYCLE_TIME); -+ writel(change_cycle_count, emac->dram.va + TAS_CONFIG_CHANGE_CYCLE_COUNT); -+ writeb(admin_list->num_entries, emac->dram.va + TAS_ADMIN_LIST_LENGTH); -+ -+ /* config_change cleared by f/w to ack reception of new shadow list */ -+ writeb(1, &tas->config_list->config_change); -+ /* config_pending cleared by f/w when new shadow list is copied to active list */ -+ writeb(1, &tas->config_list->config_pending); -+ -+ return emac_set_port_state(emac, ICSSG_EMAC_PORT_TAS_TRIGGER); -+} -+ -+static int tas_update_oper_list(struct prueth_emac *emac) -+{ -+ struct tas_config *tas = &emac->qos.tas.config; -+ struct tc_taprio_qopt_offload *admin_list = emac->qos.tas.taprio_admin; -+ int ret; -+ u8 win_idx, gate_idx, val; -+ u32 tas_acc_gate_close_time = 0; -+ -+ tas_update_fw_list_pointers(emac); -+ -+ for (win_idx = 0; win_idx < admin_list->num_entries; win_idx++) { -+ tas->firmware_shadow_list->gate_mask_list[win_idx] = admin_list->entries[win_idx].gate_mask; -+ tas_acc_gate_close_time += admin_list->entries[win_idx].interval; -+ -+ /* extend last entry till end of cycle time */ -+ if (win_idx == admin_list->num_entries - 1) -+ tas->firmware_shadow_list->window_end_time_list[win_idx] = admin_list->cycle_time; -+ else -+ tas->firmware_shadow_list->window_end_time_list[win_idx] = tas_acc_gate_close_time; -+ } -+ -+ /* clear remaining entries */ -+ for (win_idx = admin_list->num_entries; win_idx < TAS_MAX_CMD_LISTS; win_idx++) { -+ tas->firmware_shadow_list->gate_mask_list[win_idx] = 0; -+ tas->firmware_shadow_list->window_end_time_list[win_idx] = 0; -+ } -+ -+ /* update the Array of gate close time for each queue in each window */ -+ for (win_idx = 0 ; win_idx < admin_list->num_entries; win_idx++) { -+ /* On Linux, only PRUETH_MAX_TX_QUEUES are supported per port */ -+ for (gate_idx = 0; gate_idx < PRUETH_MAX_TX_QUEUES; gate_idx++) { -+ u32 gate_close_time = 0; -+ -+ if (tas->firmware_shadow_list->gate_mask_list[win_idx] & BIT(gate_idx)) -+ gate_close_time = tas->firmware_shadow_list->window_end_time_list[win_idx]; -+ -+ tas->firmware_shadow_list->gate_close_time_list[win_idx][gate_idx] = gate_close_time; -+ } -+ } -+ -+ /* tell f/w to swap active & shadow list */ -+ ret = tas_set_trigger_list_change(emac); -+ if (ret) { -+ netdev_err(emac->ndev, "failed to swap f/w config list: %d\n", ret); -+ return ret; -+ } -+ -+ /* Wait for completion */ -+ ret = readb_poll_timeout(&tas->config_list->config_change, val, !val, -+ USEC_PER_MSEC, 10 * USEC_PER_MSEC); -+ if (ret) { -+ netdev_err(emac->ndev, "TAS list change completion time out\n"); -+ return ret; -+ } -+ -+ tas_update_fw_list_pointers(emac); -+ -+ return 0; -+} -+ -+static int emac_set_taprio(struct prueth_emac *emac) -+{ -+ int ret; -+ struct tc_taprio_qopt_offload *taprio = emac->qos.tas.taprio_admin; -+ -+ if (!taprio->enable) -+ return tas_set_state(emac, TAS_STATE_DISABLE); -+ -+ ret = tas_update_oper_list(emac); -+ if (ret) -+ return ret; -+ -+ return tas_set_state(emac, TAS_STATE_ENABLE); -+} -+ -+static void emac_cp_taprio(struct tc_taprio_qopt_offload *from, -+ struct tc_taprio_qopt_offload *to) -+{ -+ int i; -+ -+ *to = *from; -+ for (i = 0; i < from->num_entries; i++) -+ to->entries[i] = from->entries[i]; -+} -+ -+static int emac_setup_taprio(struct net_device *ndev, struct tc_taprio_qopt_offload *taprio) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct tc_taprio_qopt_offload *est_new; -+ int ret, win_idx; -+ -+ if (!netif_running(ndev)) { -+ netdev_err(ndev, "interface is down, link speed unknown\n"); -+ return -ENETDOWN; -+ } -+ -+ if (taprio->cycle_time_extension) { -+ netdev_err(ndev, "Failed to set cycle time extension"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (taprio->num_entries == 0 || -+ taprio->num_entries > TAS_MAX_CMD_LISTS) { -+ netdev_err(ndev, "unsupported num_entries %ld in taprio config\n", -+ taprio->num_entries); -+ return -EINVAL; -+ } -+ -+ /* If any time_interval is 0 in between the list, then exit */ -+ for (win_idx = 0; win_idx < taprio->num_entries; win_idx++) { -+ if (taprio->entries[win_idx].interval == 0) { -+ netdev_err(ndev, "0 interval in taprio config not supported\n"); -+ return -EINVAL; -+ } -+ } -+ -+ if (emac->qos.tas.taprio_admin) -+ devm_kfree(&ndev->dev, emac->qos.tas.taprio_admin); -+ -+ est_new = devm_kzalloc(&ndev->dev, -+ struct_size(est_new, entries, taprio->num_entries), -+ GFP_KERNEL); -+ emac_cp_taprio(taprio, est_new); -+ emac->qos.tas.taprio_admin = est_new; -+ ret = emac_set_taprio(emac); -+ if (ret) -+ devm_kfree(&ndev->dev, est_new); -+ -+ return ret; -+} -+ -+int icssg_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type type, -+ void *type_data) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ if (emac->prueth->is_sr1) -+ return -EOPNOTSUPP; -+ -+ switch (type) { -+ case TC_SETUP_QDISC_TAPRIO: -+ return emac_setup_taprio(ndev, type_data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static void icssg_qos_tas_init(struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct tas_config *tas = &emac->qos.tas.config; -+ bool need_setup = false; -+ -+ if (emac->prueth->is_sr1) -+ return; -+ -+ if (tas->state == TAS_STATE_ENABLE) -+ need_setup = true; -+ -+ tas->config_list = emac->dram.va + TAS_CONFIG_CHANGE_TIME; -+ tas->active_list = emac->dram.va + TAS_ACTIVE_LIST_INDEX; -+ -+ tas_update_fw_list_pointers(emac); -+ -+ tas_set_state(emac, TAS_STATE_RESET); -+ -+ if (need_setup) -+ emac_set_taprio(emac); -+} -diff --git a/drivers/net/ethernet/ti/icssg_qos.h b/drivers/net/ethernet/ti/icssg_qos.h -new file mode 100644 -index 000000000000..76edc121797f ---- /dev/null -+++ b/drivers/net/ethernet/ti/icssg_qos.h -@@ -0,0 +1,120 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ -+ */ -+ -+#ifndef __NET_TI_ICSSG_QOS_H -+#define __NET_TI_ICSSG_QOS_H -+ -+#include -+#include -+#include -+ -+/** -+ * Maximum number of gate command entries in each list. -+ */ -+#define TAS_MAX_CMD_LISTS (16) -+ -+/** -+ * Maximum number of transmit queues supported by implementation -+ */ -+#define TAS_MAX_NUM_QUEUES (8) -+ -+/** -+ * Minimum cycle time supported by implementation (in ns) -+ */ -+#define TAS_MIN_CYCLE_TIME (1000000) -+ -+/** -+ * Minimum TAS window duration supported by implementation (in ns) -+ */ -+#define TAS_MIN_WINDOW_DURATION (10000) -+ -+/** -+ * List number 0 or 1. Also the value at memory location TAS_ACTIVE_LIST_INDEX -+ */ -+enum tas_list_num { -+ TAS_LIST0 = 0, -+ TAS_LIST1 = 1 -+}; -+ -+/** -+ * state of TAS in f/w -+ */ -+enum tas_state { -+ /* PRU's are idle */ -+ TAS_STATE_DISABLE = 0, -+ /* Enable TAS */ -+ TAS_STATE_ENABLE = 1, -+ /* Firmware will reset the state machine */ -+ TAS_STATE_RESET = 2, -+}; -+ -+/** -+ * Config state machine variables. See IEEE Std 802.1Q-2018 8.6.8.4 -+ */ -+struct tas_config_list { -+ /* New list is copied at this time */ -+ u64 config_change_time; -+ /* config change error counter, incremented if -+ * admin->BaseTime < current time and TAS_enabled is true -+ */ -+ u32 config_change_error_counter; -+ /* True if list update is pending */ -+ u8 config_pending; -+ /* Set to true when application trigger updating of admin list -+ * to active list, cleared when configChangeTime is updated -+ */ -+ u8 config_change; -+}; -+ -+/** -+ * Max SDU table. See IEEE Std 802.1Q-2018 12.29.1.1 -+ */ -+struct tas_max_sdu_table { -+ u16 max_sdu[TAS_MAX_NUM_QUEUES]; -+}; -+ -+/** -+ * TAS List Structure based on firmware memory map -+ */ -+struct tas_firmware_list { -+ /* window gate mask list */ -+ u8 gate_mask_list[TAS_MAX_CMD_LISTS]; -+ /* window end time list */ -+ u32 window_end_time_list[TAS_MAX_CMD_LISTS]; -+ /* Array of gate close time for each queue in each window */ -+ u32 gate_close_time_list[TAS_MAX_CMD_LISTS][TAS_MAX_NUM_QUEUES]; -+}; -+ -+/** -+ * Main Time Aware Shaper Handle -+ */ -+struct tas_config { -+ enum tas_state state; -+ struct tas_max_sdu_table max_sdu_table; -+ /* Config change variables */ -+ struct __iomem tas_config_list * config_list; -+ /* Whether list 1 or list 2 is the operating list */ -+ u8 __iomem *active_list; -+ /* active List pointer, used by firmware */ -+ struct __iomem tas_firmware_list * firmware_active_list; -+ /* shadow List pointer, used by driver */ -+ struct __iomem tas_firmware_list * firmware_shadow_list; -+}; -+ -+struct prueth_qos_tas { -+ struct tc_taprio_qopt_offload *taprio_admin; -+ struct tc_taprio_qopt_offload *taprio_oper; -+ struct tas_config config; -+}; -+ -+struct prueth_qos { -+ /* IET data structure goes here */ -+ struct prueth_qos_tas tas; -+}; -+ -+void icssg_qos_init(struct net_device *ndev); -+void icssg_qos_cleanup(struct net_device *ndev); -+int icssg_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type type, -+ void *type_data); -+#endif /* __NET_TI_ICSSG_QOS_H */ -diff --git a/drivers/net/ethernet/ti/icssg_switch_map.h b/drivers/net/ethernet/ti/icssg_switch_map.h -index 0d16544aa096..f53f5633cf42 100644 ---- a/drivers/net/ethernet/ti/icssg_switch_map.h -+++ b/drivers/net/ethernet/ti/icssg_switch_map.h -@@ -162,6 +162,8 @@ - #define HOST_RX_Q_PRE_CONTEXT_OFFSET 0x0684 - /*Buffer for 8 FDB entries to be added by 'Add Multiple FDB entries IOCTL*/ - #define FDB_CMD_BUFFER 0x0894 -+/*TAS queue max sdu length list*/ -+#define TAS_QUEUE_MAX_SDU_LIST 0x08FA - /*Used by FW to generate random number with the SEED value*/ - #define HD_RAND_SEED_OFFSET 0x0934 - diff --git a/recipes-kernel/linux/files/patches-5.10/0163-net-ethernet-ti-icssg_prueth-add-IET-Frame-preemptio.patch b/recipes-kernel/linux/files/patches-5.10/0163-net-ethernet-ti-icssg_prueth-add-IET-Frame-preemptio.patch deleted file mode 100644 index 95eda3a1b..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0163-net-ethernet-ti-icssg_prueth-add-IET-Frame-preemptio.patch +++ /dev/null @@ -1,310 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Murali Karicheri -Date: Thu, 14 Oct 2021 14:26:56 +0530 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: add IET Frame preemption - utilities - -Intersperse Express Traffic (IET) Frame preemption (FPE) feature is -defined by IEEE 802.3 2018 and IEEE 802.1Q standards and is supported -by ICSSG SR2 EMAC firmware on SR2. This patch adds utility functions -to configure firmware to enable IET FPE. The highest priority queue -is marked as Express queue and lower priority queues as pre-emptable. -Driver optionally allow configure the Verify state machine in the -firmware to check remote peer capability. If remote fails to respond -to Verify command, then FPE is disabled by firmware and TX FPE active -status is disabled. - -Signed-off-by: Murali Karicheri -Signed-off-by: Roger Quadros -[vigneshr@ti.com: Use readx_poll_timeouts where possible] -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_config.h | 9 ++ - drivers/net/ethernet/ti/icssg_qos.c | 196 ++++++++++++++++++++++++- - drivers/net/ethernet/ti/icssg_qos.h | 21 ++- - 3 files changed, 223 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_config.h b/drivers/net/ethernet/ti/icssg_config.h -index bcac3d6e1dd7..dfb75f479404 100644 ---- a/drivers/net/ethernet/ti/icssg_config.h -+++ b/drivers/net/ethernet/ti/icssg_config.h -@@ -279,4 +279,13 @@ struct prueth_fdb_slot { - u8 fid; - u8 fid_c2; - } __packed; -+ -+enum icssg_ietfpe_verify_states { -+ ICSSG_IETFPE_STATE_UNKNOWN = 0, -+ ICSSG_IETFPE_STATE_INITIAL, -+ ICSSG_IETFPE_STATE_VERIFYING, -+ ICSSG_IETFPE_STATE_SUCCEEDED, -+ ICSSG_IETFPE_STATE_FAILED, -+ ICSSG_IETFPE_STATE_DISABLED -+}; - #endif /* __NET_TI_ICSSG_CONFIG_H */ -diff --git a/drivers/net/ethernet/ti/icssg_qos.c b/drivers/net/ethernet/ti/icssg_qos.c -index a9086e2e374d..d9098eabe967 100644 ---- a/drivers/net/ethernet/ti/icssg_qos.c -+++ b/drivers/net/ethernet/ti/icssg_qos.c -@@ -7,18 +7,51 @@ - #include "icssg_prueth.h" - #include "icssg_switch_map.h" - -+/* in msec */ -+#define ICSSG_IET_FPE_VERIFY_TIMEOUT_MS 1000 -+ - static void icssg_qos_tas_init(struct net_device *ndev); -+static void icssg_prueth_iet_fpe_disable(struct prueth_qos_iet *iet); -+static int icssg_prueth_iet_fpe_enable(struct prueth_emac *emac); -+static void icssg_prueth_iet_fpe_disable(struct prueth_qos_iet *iet); -+static void icssg_qos_enable_ietfpe(struct work_struct *work); - - void icssg_qos_init(struct net_device *ndev) - { -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth_qos_iet *iet = &emac->qos.iet; -+ - icssg_qos_tas_init(ndev); - -- /* IET init goes here */ -+ if (!iet->fpe_configured) { -+ iet->fpe_mask_configured = 0; -+ return; -+ } -+ -+ iet->fpe_mask_configured = GENMASK(emac->tx_ch_num - 2, 0); -+ /* Init work queue for IET MAC verify process */ -+ iet->emac = emac; -+ INIT_WORK(&iet->fpe_config_task, icssg_qos_enable_ietfpe); -+ init_completion(&iet->fpe_config_compl); -+ -+ /* As worker may be sleeping, check this flag to abort -+ * as soon as it comes of out of sleep and cancel the -+ * fpe config task. -+ */ -+ atomic_set(&iet->cancel_fpe_config, 0); - } - - void icssg_qos_cleanup(struct net_device *ndev) - { -- /* IET cleanup goes here */ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth_qos_iet *iet = &emac->qos.iet; -+ -+ if (!iet->fpe_enabled) -+ return; -+ -+ iet->fpe_mask_configured = 0; -+ /* Send a command to firmware to stop FPE */ -+ icssg_prueth_iet_fpe_disable(iet); - } - - static void tas_update_fw_list_pointers(struct prueth_emac *emac) -@@ -34,6 +67,25 @@ static void tas_update_fw_list_pointers(struct prueth_emac *emac) - } - } - -+void icssg_qos_link_up(struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth_qos_iet *iet = &emac->qos.iet; -+ -+ if (!iet->fpe_configured) -+ return; -+ -+ icssg_prueth_iet_fpe_enable(emac); -+} -+ -+void icssg_qos_link_down(struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth_qos_iet *iet = &emac->qos.iet; -+ -+ if (iet->fpe_configured) -+ icssg_prueth_iet_fpe_disable(iet); -+} - static void tas_update_maxsdu_table(struct prueth_emac *emac) - { - struct tas_config *tas = &emac->qos.tas.config; -@@ -296,3 +348,143 @@ static void icssg_qos_tas_init(struct net_device *ndev) - if (need_setup) - emac_set_taprio(emac); - } -+ -+static int icssg_config_ietfpe(struct prueth_qos_iet *iet, bool enable) -+{ -+ void *config = iet->emac->dram.va + ICSSG_CONFIG_OFFSET; -+ u8 val; -+ int ret, i; -+ -+ /* If FPE is to be enabled, first configure MAC Verify state -+ * machine in firmware as firmware kicks the Verify process -+ * as soon as ICSSG_EMAC_PORT_PREMPT_TX_ENABLE command is -+ * received. -+ */ -+ if (enable && iet->mac_verify_configured) { -+ writeb(1, config + PRE_EMPTION_ENABLE_VERIFY); -+ /* should be a multiple of 64. TODO to configure -+ * through ethtool. -+ */ -+ writew(64, config + PRE_EMPTION_ADD_FRAG_SIZE_LOCAL); -+ writel(ICSSG_IET_FPE_VERIFY_TIMEOUT_MS, config + PRE_EMPTION_VERIFY_TIME); -+ } -+ -+ /* Send command to enable FPE Tx side. Rx is always enabled */ -+ ret = emac_set_port_state(iet->emac, -+ enable ? ICSSG_EMAC_PORT_PREMPT_TX_ENABLE : -+ ICSSG_EMAC_PORT_PREMPT_TX_DISABLE); -+ if (ret) { -+ netdev_err(iet->emac->ndev, "TX pre-empt %s command failed\n", -+ enable ? "enable" : "disable"); -+ writeb(0, config + PRE_EMPTION_ENABLE_VERIFY); -+ return ret; -+ } -+ -+ /* Update FPE Tx enable bit. Assume firmware use this bit -+ * and enable PRE_EMPTION_ACTIVE_TX if everything looks -+ * good at firmware -+ */ -+ writeb(enable ? 1 : 0, config + PRE_EMPTION_ENABLE_TX); -+ -+ if (iet->mac_verify_configured) { -+ ret = readb_poll_timeout(config + PRE_EMPTION_VERIFY_STATUS, val, -+ (val == ICSSG_IETFPE_STATE_SUCCEEDED), -+ USEC_PER_MSEC, 5 * USEC_PER_SEC); -+ if (ret == -ETIMEDOUT) { -+ netdev_err(iet->emac->ndev, -+ "timeout for MAC Verify: status %x\n", -+ val); -+ return ret; -+ } -+ } else { -+ /* Give f/w some time to update PRE_EMPTION_ACTIVE_TX state */ -+ usleep_range(100, 200); -+ } -+ -+ if (enable) { -+ val = readb(config + PRE_EMPTION_ACTIVE_TX); -+ if (val != 1) { -+ netdev_err(iet->emac->ndev, -+ "F/w fails to activate IET/FPE\n"); -+ writeb(0, config + PRE_EMPTION_ENABLE_TX); -+ return -ENODEV; -+ } -+ } -+ -+ /* Configure highest queue as express. Set Bit 4 for FPE, -+ * Reset for express -+ */ -+ -+ /* first set all 8 queues as Pre-emptive */ -+ for (i = 0; i < PRUETH_MAX_TX_QUEUES * PRUETH_NUM_MACS; i++) -+ writeb(BIT(4), config + EXPRESS_PRE_EMPTIVE_Q_MAP + i); -+ -+ /* set highest priority channel queue as express */ -+ writeb(0, config + EXPRESS_PRE_EMPTIVE_Q_MAP + iet->emac->tx_ch_num - 1); -+ -+ /* set up queue mask for FPE. 1 means express */ -+ writeb(BIT(iet->emac->tx_ch_num - 1), config + EXPRESS_PRE_EMPTIVE_Q_MASK); -+ -+ iet->fpe_enabled = true; -+ -+ return ret; -+} -+ -+static void icssg_qos_enable_ietfpe(struct work_struct *work) -+{ -+ struct prueth_qos_iet *iet = -+ container_of(work, struct prueth_qos_iet, fpe_config_task); -+ int ret; -+ -+ /* Set the required flag and send a command to ICSSG firmware to -+ * enable FPE and start MAC verify -+ */ -+ ret = icssg_config_ietfpe(iet, true); -+ -+ /* if verify configured, poll for the status and complete. -+ * Or just do completion -+ */ -+ if (!ret) -+ netdev_err(iet->emac->ndev, "IET FPE configured successfully\n"); -+ else -+ netdev_err(iet->emac->ndev, "IET FPE config error\n"); -+ complete(&iet->fpe_config_compl); -+} -+ -+static void icssg_prueth_iet_fpe_disable(struct prueth_qos_iet *iet) -+{ -+ int ret; -+ -+ atomic_set(&iet->cancel_fpe_config, 1); -+ cancel_work_sync(&iet->fpe_config_task); -+ ret = icssg_config_ietfpe(iet, false); -+ if (!ret) -+ netdev_err(iet->emac->ndev, "IET FPE disabled successfully\n"); -+ else -+ netdev_err(iet->emac->ndev, "IET FPE disable failed\n"); -+} -+ -+static int icssg_prueth_iet_fpe_enable(struct prueth_emac *emac) -+{ -+ struct prueth_qos_iet *iet = &emac->qos.iet; -+ int ret; -+ -+ /* Schedule MAC Verify and enable IET FPE if configured */ -+ atomic_set(&iet->cancel_fpe_config, 0); -+ reinit_completion(&iet->fpe_config_compl); -+ schedule_work(&iet->fpe_config_task); -+ /* By trial, found it takes about 1.5s. So -+ * wait for 10s -+ */ -+ ret = wait_for_completion_timeout(&iet->fpe_config_compl, -+ msecs_to_jiffies(10000)); -+ if (!ret) { -+ netdev_err(emac->ndev, -+ "IET verify completion timeout\n"); -+ /* cancel verify in progress */ -+ atomic_set(&iet->cancel_fpe_config, 1); -+ cancel_work_sync(&iet->fpe_config_task); -+ } -+ -+ return ret; -+} -diff --git a/drivers/net/ethernet/ti/icssg_qos.h b/drivers/net/ethernet/ti/icssg_qos.h -index 76edc121797f..f0555cf2c314 100644 ---- a/drivers/net/ethernet/ti/icssg_qos.h -+++ b/drivers/net/ethernet/ti/icssg_qos.h -@@ -108,8 +108,25 @@ struct prueth_qos_tas { - struct tas_config config; - }; - -+struct prueth_qos_iet { -+ struct work_struct fpe_config_task; -+ struct completion fpe_config_compl; -+ struct prueth_emac *emac; -+ atomic_t cancel_fpe_config; -+ /* Set through priv flags to enable IET frame preemption */ -+ bool fpe_configured; -+ /* Set if IET FPE is active */ -+ bool fpe_enabled; -+ /* Set through priv flags to enable IET MAC Verify state machine -+ * in firmware -+ */ -+ bool mac_verify_configured; -+ /* configured queue mask */ -+ u32 fpe_mask_configured; -+}; -+ - struct prueth_qos { -- /* IET data structure goes here */ -+ struct prueth_qos_iet iet; - struct prueth_qos_tas tas; - }; - -@@ -117,4 +134,6 @@ void icssg_qos_init(struct net_device *ndev); - void icssg_qos_cleanup(struct net_device *ndev); - int icssg_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type type, - void *type_data); -+void icssg_qos_link_up(struct net_device *ndev); -+void icssg_qos_link_down(struct net_device *ndev); - #endif /* __NET_TI_ICSSG_QOS_H */ diff --git a/recipes-kernel/linux/files/patches-5.10/0164-net-ethernet-ti-icssg_prueth-add-priv-flags-to-confi.patch b/recipes-kernel/linux/files/patches-5.10/0164-net-ethernet-ti-icssg_prueth-add-priv-flags-to-confi.patch deleted file mode 100644 index ba02d5a57..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0164-net-ethernet-ti-icssg_prueth-add-priv-flags-to-confi.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Murali Karicheri -Date: Thu, 14 Oct 2021 14:26:57 +0530 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: add priv-flags to configure - IET FPE - -This patch adds ethtool --set/show-priv-flags to configure IET/Frame -preemption feature in icssg prueth driver. - -Signed-off-by: Murali Karicheri -Signed-off-by: Roger Quadros -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_ethtool.c | 84 +++++++++++++++++++++++++ - 1 file changed, 84 insertions(+) - -diff --git a/drivers/net/ethernet/ti/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg_ethtool.c -index b6f7c1a86941..6aa10d9ac2e6 100644 ---- a/drivers/net/ethernet/ti/icssg_ethtool.c -+++ b/drivers/net/ethernet/ti/icssg_ethtool.c -@@ -232,11 +232,29 @@ static int emac_nway_reset(struct net_device *ndev) - return genphy_restart_aneg(emac->phydev); - } - -+/* Ethtool priv_flags for IET/Frame Preemption configuration. -+ * TODO: This is a temporary solution until upstream interface -+ * is available. -+ */ -+static const char emac_ethtool_priv_flags[][ETH_GSTRING_LEN] = { -+#define EMAC_PRIV_IET_FRAME_PREEMPTION BIT(0) -+ "iet-frame-preemption", -+#define EMAC_PRIV_IET_MAC_VERIFY BIT(1) -+ "iet-mac-verify", -+}; -+ - static int emac_get_sset_count(struct net_device *ndev, int stringset) - { -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth *prueth = emac->prueth; -+ - switch (stringset) { - case ETH_SS_STATS: - return ARRAY_SIZE(icssg_ethtool_stats); -+ case ETH_SS_PRIV_FLAGS: -+ if (!prueth->is_sr1) -+ return ARRAY_SIZE(emac_ethtool_priv_flags); -+ return -EOPNOTSUPP; - default: - return -EOPNOTSUPP; - } -@@ -244,6 +262,8 @@ static int emac_get_sset_count(struct net_device *ndev, int stringset) - - static void emac_get_strings(struct net_device *ndev, u32 stringset, u8 *data) - { -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth *prueth = emac->prueth; - u8 *p = data; - int i; - -@@ -255,6 +275,16 @@ static void emac_get_strings(struct net_device *ndev, u32 stringset, u8 *data) - p += ETH_GSTRING_LEN; - } - break; -+ case ETH_SS_PRIV_FLAGS: -+ if (prueth->is_sr1) -+ return; -+ -+ for (i = 0; i < ARRAY_SIZE(emac_ethtool_priv_flags); i++) { -+ memcpy(p, emac_ethtool_priv_flags[i], -+ ETH_GSTRING_LEN); -+ p += ETH_GSTRING_LEN; -+ } -+ break; - default: - break; - } -@@ -336,6 +366,58 @@ static int emac_set_channels(struct net_device *ndev, - return 0; - } - -+/* TODO : This is temporary until a formal ethtool interface become available -+ * in LKML to configure IET FPE. -+ */ -+static u32 emac_get_ethtool_priv_flags(struct net_device *ndev) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth_qos_iet *iet = &emac->qos.iet; -+ u32 priv_flags = 0; -+ -+ if (emac->is_sr1) -+ return priv_flags; -+ -+ /* Port specific flags */ -+ if (iet->fpe_configured) -+ priv_flags |= EMAC_PRIV_IET_FRAME_PREEMPTION; -+ if (iet->mac_verify_configured) -+ priv_flags |= EMAC_PRIV_IET_MAC_VERIFY; -+ -+ return priv_flags; -+} -+ -+static int emac_set_ethtool_priv_flags(struct net_device *ndev, u32 flags) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ struct prueth_qos_iet *iet = &emac->qos.iet; -+ int iet_fpe, mac_verify; -+ -+ if (emac->is_sr1) -+ return -EOPNOTSUPP; -+ -+ iet_fpe = !!(flags & EMAC_PRIV_IET_FRAME_PREEMPTION); -+ mac_verify = !!(flags & EMAC_PRIV_IET_MAC_VERIFY); -+ -+ if (netif_running(ndev)) -+ return -EBUSY; -+ -+ if (emac->tx_ch_num < 2 && iet_fpe) { -+ netdev_err(ndev, "IET fpe needs at least 2 h/w queues\n"); -+ return -EINVAL; -+ } -+ -+ if (mac_verify && (!iet->fpe_configured && !iet_fpe)) { -+ netdev_err(ndev, "Enable IET FPE for IET MAC verify\n"); -+ return -EINVAL; -+ } -+ -+ iet->fpe_configured = iet_fpe; -+ iet->mac_verify_configured = mac_verify; -+ -+ return 0; -+} -+ - const struct ethtool_ops icssg_ethtool_ops = { - .get_drvinfo = emac_get_drvinfo, - .get_msglevel = emac_get_msglevel, -@@ -344,6 +426,8 @@ const struct ethtool_ops icssg_ethtool_ops = { - .get_strings = emac_get_strings, - .get_ethtool_stats = emac_get_ethtool_stats, - .get_ts_info = emac_get_ts_info, -+ .get_priv_flags = emac_get_ethtool_priv_flags, -+ .set_priv_flags = emac_set_ethtool_priv_flags, - - .get_channels = emac_get_channels, - .set_channels = emac_set_channels, diff --git a/recipes-kernel/linux/files/patches-5.10/0165-net-ethernet-ti-icssg_prueth-enable-IET-FPE-feature-.patch b/recipes-kernel/linux/files/patches-5.10/0165-net-ethernet-ti-icssg_prueth-enable-IET-FPE-feature-.patch deleted file mode 100644 index f723e3a7f..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0165-net-ethernet-ti-icssg_prueth-enable-IET-FPE-feature-.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Murali Karicheri -Date: Thu, 14 Oct 2021 14:26:58 +0530 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: enable IET/FPE feature - configuration - -This adds the necessary hooks to enable IET/FPE feature in ICSSG -prueth driver. IET/FPE gets configured when Link is up and gets -disabled when link goes down or device is stopped. - -Allocate MSMC area for express RX queue. - -Signed-off-by: Murali Karicheri -Signed-off-by: Roger Quadros -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_config.c | 24 +++++++++++++++++++--- - drivers/net/ethernet/ti/icssg_config.h | 2 +- - drivers/net/ethernet/ti/icssg_prueth.c | 6 +++++- - drivers/net/ethernet/ti/icssg_switch_map.h | 2 ++ - 4 files changed, 29 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c -index 8d813da0baf6..94785a85416c 100644 ---- a/drivers/net/ethernet/ti/icssg_config.c -+++ b/drivers/net/ethernet/ti/icssg_config.c -@@ -375,14 +375,23 @@ static int prueth_switch_buffer_setup(struct prueth_emac *emac) - if (!slice) - addr += PRUETH_SW_NUM_BUF_POOLS_HOST_SR2 * PRUETH_SW_BUF_POOL_SIZE_HOST_SR2; - else -- addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; -+ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE * 2; - -+ /* Pre-emptible RX buffer queue */ - rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET; - for (i = 0; i < 3; i++) - rxq_ctx->start[i] = cpu_to_le32(addr); - - addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; -- rxq_ctx->end = cpu_to_le32(addr) - SZ_2K; -+ rxq_ctx->end = cpu_to_le32(addr); -+ -+ /* Express RX buffer queue */ -+ rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET; -+ for (i = 0; i < 3; i++) -+ rxq_ctx->start[i] = cpu_to_le32(addr); -+ -+ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; -+ rxq_ctx->end = cpu_to_le32(addr); - - return 0; - } -@@ -424,8 +433,9 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac) - - addr += PRUETH_NUM_BUF_POOLS_SR2 * PRUETH_EMAC_BUF_POOL_SIZE_SR2; - if (slice) -- addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; -+ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE * 2; - -+ /* Pre-emptible RX buffer queue */ - rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET; - for (i = 0; i < 3; i++) - rxq_ctx->start[i] = cpu_to_le32(addr); -@@ -433,6 +443,14 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac) - addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; - rxq_ctx->end = cpu_to_le32(addr); - -+ /* Express RX buffer queue */ -+ rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET; -+ for (i = 0; i < 3; i++) -+ rxq_ctx->start[i] = cpu_to_le32(addr); -+ -+ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; -+ rxq_ctx->end = cpu_to_le32(addr); -+ - return 0; - } - -diff --git a/drivers/net/ethernet/ti/icssg_config.h b/drivers/net/ethernet/ti/icssg_config.h -index dfb75f479404..1f973dd5c6f7 100644 ---- a/drivers/net/ethernet/ti/icssg_config.h -+++ b/drivers/net/ethernet/ti/icssg_config.h -@@ -103,7 +103,7 @@ struct icssg_config_sr1 { - #define PRUETH_EMAC_RX_CTX_BUF_SIZE SZ_16K /* per slice */ - #define MSMC_RAM_SIZE_SR2 \ - (2 * (PRUETH_EMAC_BUF_POOL_SIZE_SR2 * PRUETH_NUM_BUF_POOLS_SR2 + \ -- PRUETH_EMAC_RX_CTX_BUF_SIZE)) -+ PRUETH_EMAC_RX_CTX_BUF_SIZE * 2)) - - #define PRUETH_SW_BUF_POOL_SIZE_HOST_SR2 SZ_2K - #define PRUETH_SW_NUM_BUF_POOLS_HOST_SR2 16 -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 193ec64f1341..34c4c8926cdc 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1340,8 +1340,12 @@ static void emac_adjust_link(struct net_device *ndev) - /* send command to firmware to change speed and duplex - * setting when link is up. - */ -- if (emac->link) -+ if (emac->link) { - emac_change_port_speed_duplex(emac); -+ icssg_qos_link_up(ndev); -+ } else { -+ icssg_qos_link_down(ndev); -+ } - } - - if (emac->link) { -diff --git a/drivers/net/ethernet/ti/icssg_switch_map.h b/drivers/net/ethernet/ti/icssg_switch_map.h -index f53f5633cf42..a5e56b9cd820 100644 ---- a/drivers/net/ethernet/ti/icssg_switch_map.h -+++ b/drivers/net/ethernet/ti/icssg_switch_map.h -@@ -166,6 +166,8 @@ - #define TAS_QUEUE_MAX_SDU_LIST 0x08FA - /*Used by FW to generate random number with the SEED value*/ - #define HD_RAND_SEED_OFFSET 0x0934 -+/*16B for Host Egress MSMC Q (Express) context*/ -+#define HOST_RX_Q_EXP_CONTEXT_OFFSET 0x0940 - - /* Memory Usage of : DMEM1 - * diff --git a/recipes-kernel/linux/files/patches-5.10/0166-net-ethernet-ti-icssg_prueth-Support-for-transparent.patch b/recipes-kernel/linux/files/patches-5.10/0166-net-ethernet-ti-icssg_prueth-Support-for-transparent.patch deleted file mode 100644 index 524961304..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0166-net-ethernet-ti-icssg_prueth-Support-for-transparent.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Tue, 19 Oct 2021 13:01:11 +0300 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: Support for transparent ASEL - handling - -Use the glue layer's functions to convert the dma_addr_t to and from CPPI5 -address (with the ASEL bits), which should be used within the descriptors -and data buffers. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 34c4c8926cdc..0aeb18a2c962 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -121,20 +121,24 @@ static void prueth_xmit_free(struct prueth_tx_chn *tx_chn, - next_desc = first_desc; - - cppi5_hdesc_get_obuf(first_desc, &buf_dma, &buf_dma_len); -+ k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &buf_dma); - - dma_unmap_single(tx_chn->dma_dev, buf_dma, buf_dma_len, - DMA_TO_DEVICE); - - next_desc_dma = cppi5_hdesc_get_next_hbdesc(first_desc); -+ k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &next_desc_dma); - while (next_desc_dma) { - next_desc = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, - next_desc_dma); - cppi5_hdesc_get_obuf(next_desc, &buf_dma, &buf_dma_len); -+ k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &buf_dma); - - dma_unmap_page(tx_chn->dma_dev, buf_dma, buf_dma_len, - DMA_TO_DEVICE); - - next_desc_dma = cppi5_hdesc_get_next_hbdesc(next_desc); -+ k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &next_desc_dma); - - k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc); - } -@@ -481,6 +485,7 @@ static int prueth_dma_rx_push(struct prueth_emac *emac, - - cppi5_hdesc_init(desc_rx, CPPI5_INFO0_HDESC_EPIB_PRESENT, - PRUETH_NAV_PS_DATA_SIZE); -+ k3_udma_glue_rx_dma_to_cppi5_addr(rx_chn->rx_chn, &buf_dma); - cppi5_hdesc_attach_buf(desc_rx, buf_dma, skb_tailroom(skb), buf_dma, skb_tailroom(skb)); - - swdata = cppi5_hdesc_get_swdata(desc_rx); -@@ -558,6 +563,7 @@ static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) - emac_rx_timestamp(emac, skb, psdata); - - cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); -+ k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma); - pkt_len = cppi5_hdesc_get_pktlen(desc_rx); - /* firmware adds 4 CRC bytes, strip them */ - pkt_len -= 4; -@@ -614,6 +620,7 @@ static void prueth_rx_cleanup(void *data, dma_addr_t desc_dma) - swdata = cppi5_hdesc_get_swdata(desc_rx); - skb = *swdata; - cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); -+ k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma); - - dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, - DMA_FROM_DEVICE); -@@ -882,6 +889,7 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - * packets in case of switch mode operation - */ - cppi5_desc_set_tags_ids(&first_desc->hdr, 0, (emac->port_id | (q_idx << 8))); -+ k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma); - cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len); - swdata = cppi5_hdesc_get_swdata(first_desc); - *swdata = skb; -@@ -913,11 +921,13 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - } - - cppi5_hdesc_reset_hbdesc(next_desc); -+ k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma); - cppi5_hdesc_attach_buf(next_desc, - buf_dma, frag_size, buf_dma, frag_size); - - desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, - next_desc); -+ k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &desc_dma); - cppi5_hdesc_link_hbdesc(cur_desc, desc_dma); - - pkt_len += frag_size; diff --git a/recipes-kernel/linux/files/patches-5.10/0167-net-ethernet-ti-icssg_prueth-move-phy-init-in-.ndo_o.patch b/recipes-kernel/linux/files/patches-5.10/0167-net-ethernet-ti-icssg_prueth-move-phy-init-in-.ndo_o.patch deleted file mode 100644 index 65b4fb692..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0167-net-ethernet-ti-icssg_prueth-move-phy-init-in-.ndo_o.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Thu, 28 Oct 2021 17:08:35 +0300 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: move phy init in - .ndo_open/close() - -There is an issues identified with DP83869HM PHYs used on some AM64x boards -which causes PHY TX to stop working after PHY IEEE power down sequence -(BMCR bit 10 PWD_DWN 0->1->0) which is used by phy_start/stop() API. - -To fix an issues move PHY initialization (of_phy_connect()) into -.ndo_open() and disconnect PHY in .ndo_close() which will cause PHY reset -and full re-initialization. This will also required for future suspend2ram -support. - -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 59 ++++++++++++++------------ - 1 file changed, 33 insertions(+), 26 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 0aeb18a2c962..6810b6790528 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1588,6 +1588,32 @@ const struct icss_iep_clockops prueth_iep_clockops = { - .perout_enable = prueth_perout_enable, - }; - -+static int emac_phy_connect(struct prueth_emac *emac) -+{ -+ struct prueth *prueth = emac->prueth; -+ -+ /* connect PHY */ -+ emac->phydev = of_phy_connect(emac->ndev, emac->phy_node, -+ &emac_adjust_link, 0, emac->phy_if); -+ if (!emac->phydev) { -+ dev_err(prueth->dev, "couldn't connect to phy %s\n", -+ emac->phy_node->full_name); -+ return -ENODEV; -+ } -+ -+ /* remove unsupported modes */ -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Pause_BIT); -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT); -+ -+ if (emac->phy_if == PHY_INTERFACE_MODE_MII) -+ phy_set_max_speed(emac->phydev, SPEED_100); -+ -+ return 0; -+} -+ - /** - * emac_ndo_open - EMAC device open - * @ndev: network adapter device -@@ -1749,6 +1775,7 @@ static int emac_ndo_open(struct net_device *ndev) - - icssg_qos_init(ndev); - -+ emac_phy_connect(emac); - /* Get attached phy details */ - phy_attached_info(emac->phydev); - -@@ -1836,6 +1863,9 @@ static int emac_ndo_stop(struct net_device *ndev) - - /* block packets from wire */ - phy_stop(emac->phydev); -+ phy_disconnect(emac->phydev); -+ emac->phydev = NULL; -+ - icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac)); - - /* send shutdown command */ -@@ -2071,6 +2101,9 @@ static int emac_ndo_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) - break; - } - -+ if (!emac->phydev) -+ return -EOPNOTSUPP; -+ - return phy_mii_ioctl(emac->phydev, ifr, cmd); - } - -@@ -2256,30 +2289,6 @@ static int prueth_netdev_init(struct prueth *prueth, - if (ret) - goto free; - -- /* connect PHY */ -- emac->phydev = of_phy_connect(ndev, emac->phy_node, -- &emac_adjust_link, 0, emac->phy_if); -- if (!emac->phydev) { -- dev_err(prueth->dev, "couldn't connect to phy %s\n", -- emac->phy_node->full_name); -- ret = -EPROBE_DEFER; -- goto free; -- } -- -- emac->half_duplex = of_property_read_bool(eth_node, "ti,half-duplex-capable"); -- -- /* remove unsupported modes */ -- if (!emac->half_duplex) { -- phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); -- phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); -- } -- phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); -- phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Pause_BIT); -- phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT); -- -- if (emac->phy_if == PHY_INTERFACE_MODE_MII) -- phy_set_max_speed(emac->phydev, SPEED_100); -- - /* get mac address from DT and set private and netdev addr */ - mac_addr = of_get_mac_address(eth_node); - if (!IS_ERR(mac_addr)) -@@ -2325,8 +2334,6 @@ static void prueth_netdev_exit(struct prueth *prueth, - if (!emac) - return; - -- phy_disconnect(emac->phydev); -- - if (of_phy_is_fixed_link(emac->phy_node)) - of_phy_deregister_fixed_link(emac->phy_node); - diff --git a/recipes-kernel/linux/files/patches-5.10/0168-dmaengine-ti-k3-udma-Set-bchan-to-NULL-if-a-channel-.patch b/recipes-kernel/linux/files/patches-5.10/0168-dmaengine-ti-k3-udma-Set-bchan-to-NULL-if-a-channel-.patch deleted file mode 100644 index b2dcfe3a4..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0168-dmaengine-ti-k3-udma-Set-bchan-to-NULL-if-a-channel-.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Kishon Vijay Abraham I -Date: Sun, 31 Oct 2021 09:02:50 +0530 -Subject: [PATCH] dmaengine: ti: k3-udma: Set bchan to NULL if a channel - request fail - -bcdma_get_*() checks if bchan is already allocated by checking if it -has a NON NULL value. For the error cases, bchan will have error value -and bcdma_get_*() considers this as already allocated (PASS) since the -error values are NON NULL. This results in NULL pointer dereference -error while de-referencing bchan. - -Reset the value of bchan to NULL if a channel request fails. - -CC: stable@vger.kernel.org -Acked-by: Peter Ujfalusi -Signed-off-by: Kishon Vijay Abraham I ---- - drivers/dma/ti/k3-udma.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index 8e3fd1119a77..97228c4eb85b 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -1348,6 +1348,7 @@ static int bcdma_get_bchan(struct udma_chan *uc) - { - struct udma_dev *ud = uc->ud; - enum udma_tp_level tpl; -+ int ret; - - if (uc->bchan) { - dev_dbg(ud->dev, "chan%d: already have bchan%d allocated\n", -@@ -1365,8 +1366,11 @@ static int bcdma_get_bchan(struct udma_chan *uc) - tpl = ud->bchan_tpl.levels - 1; - - uc->bchan = __udma_reserve_bchan(ud, tpl, -1); -- if (IS_ERR(uc->bchan)) -- return PTR_ERR(uc->bchan); -+ if (IS_ERR(uc->bchan)) { -+ ret = PTR_ERR(uc->bchan); -+ uc->bchan = NULL; -+ return ret; -+ } - - uc->tchan = uc->bchan; - diff --git a/recipes-kernel/linux/files/patches-5.10/0169-dmaengine-ti-k3-udma-Set-r-tchan-or-rflow-to-NULL-if.patch b/recipes-kernel/linux/files/patches-5.10/0169-dmaengine-ti-k3-udma-Set-r-tchan-or-rflow-to-NULL-if.patch deleted file mode 100644 index eead26861..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0169-dmaengine-ti-k3-udma-Set-r-tchan-or-rflow-to-NULL-if.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Kishon Vijay Abraham I -Date: Sun, 31 Oct 2021 09:02:51 +0530 -Subject: [PATCH] dmaengine: ti: k3-udma: Set r/tchan or rflow to NULL if - request fail - -udma_get_*() checks if rchan/tchan/rflow is already allocated by checking -if it has a NON NULL value. For the error cases, rchan/tchan/rflow will -have error value and udma_get_*() considers this as already allocated -(PASS) since the error values are NON NULL. This results in NULL pointer -dereference error while de-referencing rchan/tchan/rflow. - -Reset the value of rchan/tchan/rflow to NULL if a channel request fails. - -CC: stable@vger.kernel.org -Acked-by: Peter Ujfalusi -Signed-off-by: Kishon Vijay Abraham I ---- - drivers/dma/ti/k3-udma.c | 24 ++++++++++++++++++++---- - 1 file changed, 20 insertions(+), 4 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index 97228c4eb85b..ff59ba1b9505 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -1380,6 +1380,7 @@ static int bcdma_get_bchan(struct udma_chan *uc) - static int udma_get_tchan(struct udma_chan *uc) - { - struct udma_dev *ud = uc->ud; -+ int ret; - - if (uc->tchan) { - dev_dbg(ud->dev, "chan%d: already have tchan%d allocated\n", -@@ -1394,8 +1395,11 @@ static int udma_get_tchan(struct udma_chan *uc) - */ - uc->tchan = __udma_reserve_tchan(ud, uc->config.channel_tpl, - uc->config.mapped_channel_id); -- if (IS_ERR(uc->tchan)) -- return PTR_ERR(uc->tchan); -+ if (IS_ERR(uc->tchan)) { -+ ret = PTR_ERR(uc->tchan); -+ uc->tchan = NULL; -+ return ret; -+ } - - if (ud->tflow_cnt) { - int tflow_id; -@@ -1425,6 +1429,7 @@ static int udma_get_tchan(struct udma_chan *uc) - static int udma_get_rchan(struct udma_chan *uc) - { - struct udma_dev *ud = uc->ud; -+ int ret; - - if (uc->rchan) { - dev_dbg(ud->dev, "chan%d: already have rchan%d allocated\n", -@@ -1439,8 +1444,13 @@ static int udma_get_rchan(struct udma_chan *uc) - */ - uc->rchan = __udma_reserve_rchan(ud, uc->config.channel_tpl, - uc->config.mapped_channel_id); -+ if (IS_ERR(uc->rchan)) { -+ ret = PTR_ERR(uc->rchan); -+ uc->rchan = NULL; -+ return ret; -+ } - -- return PTR_ERR_OR_ZERO(uc->rchan); -+ return 0; - } - - static int udma_get_chan_pair(struct udma_chan *uc) -@@ -1494,6 +1504,7 @@ static int udma_get_chan_pair(struct udma_chan *uc) - static int udma_get_rflow(struct udma_chan *uc, int flow_id) - { - struct udma_dev *ud = uc->ud; -+ int ret; - - if (!uc->rchan) { - dev_err(ud->dev, "chan%d: does not have rchan??\n", uc->id); -@@ -1507,8 +1518,13 @@ static int udma_get_rflow(struct udma_chan *uc, int flow_id) - } - - uc->rflow = __udma_get_rflow(ud, flow_id); -+ if (IS_ERR(uc->rflow)) { -+ ret = PTR_ERR(uc->rflow); -+ uc->rflow = NULL; -+ return ret; -+ } - -- return PTR_ERR_OR_ZERO(uc->rflow); -+ return 0; - } - - static void bcdma_put_bchan(struct udma_chan *uc) diff --git a/recipes-kernel/linux/files/patches-5.10/0170-net-ethernet-ti-icssg_prueth-fix-init-after-adding-s.patch b/recipes-kernel/linux/files/patches-5.10/0170-net-ethernet-ti-icssg_prueth-fix-init-after-adding-s.patch deleted file mode 100644 index cec774a16..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0170-net-ethernet-ti-icssg_prueth-fix-init-after-adding-s.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Wed, 3 Nov 2021 19:46:58 +0200 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: fix init after adding - switchdev - -After adding switchdev feature the ICSSG is broken on AM654x SR1.0 -- incorrect FW names used -- netdev renaming broken - -Fix it by using correct FW names for SR1.0 and always register devlink. - -Fixes: 3f7a788ef4c3 ("net: ethernet: ti: icssg_prueth: Add support for ICSSG switch firmware on AM654 PG2.0") -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 23 +++++++++++++++++------ - 1 file changed, 17 insertions(+), 6 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 6810b6790528..164892d5dc08 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1200,6 +1200,17 @@ static struct icssg_firmwares icssg_emac_firmwares[] = { - } - }; - -+static struct icssg_firmwares icssg_emac_firmwares_sr1[] = { -+ { -+ .pru = "ti-pruss/am65x-pru0-prueth-fw.elf", -+ .rtu = "ti-pruss/am65x-rtu0-prueth-fw.elf", -+ }, -+ { -+ .pru = "ti-pruss/am65x-pru1-prueth-fw.elf", -+ .rtu = "ti-pruss/am65x-rtu1-prueth-fw.elf", -+ } -+}; -+ - static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac) - { - struct icssg_firmwares *firmwares; -@@ -1208,6 +1219,8 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac) - - if (prueth->is_switch_mode) - firmwares = icssg_switch_firmwares; -+ else if (prueth->is_sr1) -+ firmwares = icssg_emac_firmwares_sr1; - else - firmwares = icssg_emac_firmwares; - -@@ -2942,15 +2955,15 @@ static int prueth_probe(struct platform_device *pdev) - prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev; - } - -+ ret = prueth_register_devlink(prueth); -+ if (ret) -+ goto netdev_unregister; -+ - if (prueth->is_switchmode_supported) { - ret = prueth_register_notifiers(prueth); - if (ret) - goto netdev_unregister; - -- ret = prueth_register_devlink(prueth); -- if (ret) -- goto clean_unregister_notifiers; -- - sprintf(prueth->switch_id, "%s", dev_name(dev)); - } - -@@ -2964,8 +2977,6 @@ static int prueth_probe(struct platform_device *pdev) - - return 0; - --clean_unregister_notifiers: -- prueth_unregister_notifiers(prueth); - netdev_unregister: - for (i = 0; i < PRUETH_NUM_MACS; i++) { - if (!prueth->registered_netdevs[i]) diff --git a/recipes-kernel/linux/files/patches-5.10/0171-PCI-keystone-Add-quirk-to-mark-AM654-RC-BAR-flag-as-.patch b/recipes-kernel/linux/files/patches-5.10/0171-PCI-keystone-Add-quirk-to-mark-AM654-RC-BAR-flag-as-.patch deleted file mode 100644 index d161d01fe..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0171-PCI-keystone-Add-quirk-to-mark-AM654-RC-BAR-flag-as-.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Kishon Vijay Abraham I -Date: Wed, 10 Nov 2021 13:13:43 +0530 -Subject: [PATCH] PCI: keystone: Add quirk to mark AM654 RC BAR flag as - IORESOURCE_UNSET - -AM654 RootComplex has a hard coded 64 bit BAR of size 1MB and also has -both MSI and MSI-X capability in it's config space. If PCIEPORTBUS is -enabled, it tries to configure MSI-X and msix_mask_all() adds about 10 -Second boot up delay when it tries to write to undefined location. - -Add quirk to mark AM654 RC BAR flag as IORESOURCE_UNSET so that -msix_map_region() returns NULL for Root Complex and avoid un-desirable -writes to MSI-X table. - -Signed-off-by: Kishon Vijay Abraham I -Signed-off-by: Vignesh Raghavendra ---- - drivers/pci/controller/dwc/pci-keystone.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c -index bb7190400ba8..4e973f829436 100644 ---- a/drivers/pci/controller/dwc/pci-keystone.c -+++ b/drivers/pci/controller/dwc/pci-keystone.c -@@ -650,8 +650,14 @@ static void ks_pcie_quirk(struct pci_dev *dev) - { 0, }, - }; - -- if (pci_is_root_bus(bus)) -+ if (pci_is_root_bus(bus)) { - bridge = dev; -+ if (pci_match_id(am6_pci_devids, bridge)) { -+ struct resource *r = &dev->resource[0]; -+ -+ r->flags |= IORESOURCE_UNSET; -+ } -+ } - - /* look for the host bridge */ - while (!pci_is_root_bus(bus)) { diff --git a/recipes-kernel/linux/files/patches-5.10/0172-net-ti-icssg_prueth-Fix-NULL-pointer-deference-durin.patch b/recipes-kernel/linux/files/patches-5.10/0172-net-ti-icssg_prueth-Fix-NULL-pointer-deference-durin.patch deleted file mode 100644 index 754c19533..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0172-net-ti-icssg_prueth-Fix-NULL-pointer-deference-durin.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Sat, 13 Nov 2021 13:35:06 +0530 -Subject: [PATCH] net: ti: icssg_prueth: Fix NULL pointer deference during - probe - -In case of only one EMAC port is enabled, prueth_register_devlink() try -to register devlink for both ports and leads to NULL pointer deference -and thus system crash. Fix this by checking if prueth->emac[i] is valid -before dereferencing. - -Fixes: b56dfa67ea1c ("net: ethernet: ti: icssg_prueth: fix init after adding switchdev") -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 164892d5dc08..a4ac6f0d244a 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -2695,6 +2695,9 @@ static int prueth_register_devlink(struct prueth *prueth) - - for (i = PRUETH_MAC0; i < PRUETH_NUM_MACS; i++) { - emac = prueth->emac[i]; -+ if (!emac) -+ continue; -+ - dl_port = &emac->devlink_port; - - attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; diff --git a/recipes-kernel/linux/files/patches-5.10/0173-net-ti-icssg_qos-Remove-icssg_qos_cleanup.patch b/recipes-kernel/linux/files/patches-5.10/0173-net-ti-icssg_qos-Remove-icssg_qos_cleanup.patch deleted file mode 100644 index 0842fdfb9..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0173-net-ti-icssg_qos-Remove-icssg_qos_cleanup.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Wed, 17 Nov 2021 20:27:52 +0530 -Subject: [PATCH] net: ti: icssg_qos: Remove icssg_qos_cleanup() - -icssg_qos_cleanup() does not do anything more than icssg_qos_link_down() -Since icssg_qos_link_down() is always called during emac_ndo_stop() -calling icssg_qos_cleanup() from same path is redundant. So remove the -redundant code altogether. - -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 2 -- - drivers/net/ethernet/ti/icssg_qos.c | 18 +----------------- - drivers/net/ethernet/ti/icssg_qos.h | 3 --- - 3 files changed, 1 insertion(+), 22 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index a4ac6f0d244a..a7754341eeda 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1869,8 +1869,6 @@ static int emac_ndo_stop(struct net_device *ndev) - int rx_flow = emac->is_sr1 ? - PRUETH_RX_FLOW_DATA_SR1 : PRUETH_RX_FLOW_DATA_SR2; - -- icssg_qos_cleanup(ndev); -- - /* inform the upper layers. */ - netif_tx_stop_all_queues(ndev); - -diff --git a/drivers/net/ethernet/ti/icssg_qos.c b/drivers/net/ethernet/ti/icssg_qos.c -index d9098eabe967..32e99186829d 100644 ---- a/drivers/net/ethernet/ti/icssg_qos.c -+++ b/drivers/net/ethernet/ti/icssg_qos.c -@@ -23,12 +23,9 @@ void icssg_qos_init(struct net_device *ndev) - - icssg_qos_tas_init(ndev); - -- if (!iet->fpe_configured) { -- iet->fpe_mask_configured = 0; -+ if (!iet->fpe_configured) - return; -- } - -- iet->fpe_mask_configured = GENMASK(emac->tx_ch_num - 2, 0); - /* Init work queue for IET MAC verify process */ - iet->emac = emac; - INIT_WORK(&iet->fpe_config_task, icssg_qos_enable_ietfpe); -@@ -41,19 +38,6 @@ void icssg_qos_init(struct net_device *ndev) - atomic_set(&iet->cancel_fpe_config, 0); - } - --void icssg_qos_cleanup(struct net_device *ndev) --{ -- struct prueth_emac *emac = netdev_priv(ndev); -- struct prueth_qos_iet *iet = &emac->qos.iet; -- -- if (!iet->fpe_enabled) -- return; -- -- iet->fpe_mask_configured = 0; -- /* Send a command to firmware to stop FPE */ -- icssg_prueth_iet_fpe_disable(iet); --} -- - static void tas_update_fw_list_pointers(struct prueth_emac *emac) - { - struct tas_config *tas = &emac->qos.tas.config; -diff --git a/drivers/net/ethernet/ti/icssg_qos.h b/drivers/net/ethernet/ti/icssg_qos.h -index f0555cf2c314..f29363bb1058 100644 ---- a/drivers/net/ethernet/ti/icssg_qos.h -+++ b/drivers/net/ethernet/ti/icssg_qos.h -@@ -121,8 +121,6 @@ struct prueth_qos_iet { - * in firmware - */ - bool mac_verify_configured; -- /* configured queue mask */ -- u32 fpe_mask_configured; - }; - - struct prueth_qos { -@@ -131,7 +129,6 @@ struct prueth_qos { - }; - - void icssg_qos_init(struct net_device *ndev); --void icssg_qos_cleanup(struct net_device *ndev); - int icssg_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type type, - void *type_data); - void icssg_qos_link_up(struct net_device *ndev); diff --git a/recipes-kernel/linux/files/patches-5.10/0174-net-ti-icssg_qos-Fix-IET-Frame-Preemption-disable-pa.patch b/recipes-kernel/linux/files/patches-5.10/0174-net-ti-icssg_qos-Fix-IET-Frame-Preemption-disable-pa.patch deleted file mode 100644 index 5e1ed41b2..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0174-net-ti-icssg_qos-Fix-IET-Frame-Preemption-disable-pa.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Wed, 17 Nov 2021 20:27:53 +0530 -Subject: [PATCH] net: ti: icssg_qos: Fix IET Frame Preemption disable path - -Don't wait for ICSSG_IETFPE_STATE_SUCCEEDED state when disabling IET -FPE. This state applies only on when enabling Frame Preemption - -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_qos.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/ti/icssg_qos.c b/drivers/net/ethernet/ti/icssg_qos.c -index 32e99186829d..4c341d777184 100644 ---- a/drivers/net/ethernet/ti/icssg_qos.c -+++ b/drivers/net/ethernet/ti/icssg_qos.c -@@ -370,7 +370,7 @@ static int icssg_config_ietfpe(struct prueth_qos_iet *iet, bool enable) - */ - writeb(enable ? 1 : 0, config + PRE_EMPTION_ENABLE_TX); - -- if (iet->mac_verify_configured) { -+ if (enable && iet->mac_verify_configured) { - ret = readb_poll_timeout(config + PRE_EMPTION_VERIFY_STATUS, val, - (val == ICSSG_IETFPE_STATE_SUCCEEDED), - USEC_PER_MSEC, 5 * USEC_PER_SEC); -@@ -393,6 +393,8 @@ static int icssg_config_ietfpe(struct prueth_qos_iet *iet, bool enable) - writeb(0, config + PRE_EMPTION_ENABLE_TX); - return -ENODEV; - } -+ } else { -+ return ret; - } - - /* Configure highest queue as express. Set Bit 4 for FPE, diff --git a/recipes-kernel/linux/files/patches-5.10/0175-net-ti-icssg_prueth-Fix-NULL-pointer-deference-durin.patch b/recipes-kernel/linux/files/patches-5.10/0175-net-ti-icssg_prueth-Fix-NULL-pointer-deference-durin.patch deleted file mode 100644 index a675adfe4..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0175-net-ti-icssg_prueth-Fix-NULL-pointer-deference-durin.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Kishon Vijay Abraham I -Date: Wed, 1 Dec 2021 13:17:25 +0530 -Subject: [PATCH] net: ti: icssg_prueth: Fix NULL pointer deference during - remove - -In case where only one EMAC port is enabled, -prueth_unregister_devlink_ports() tries to unregister devlink for -both ports during rmmod and leads to NULL pointer deference abort. -Fix this by checking if prueth->emac[i] is valid before dereferencing -in prueth_unregister_devlink_ports(). - -Signed-off-by: Kishon Vijay Abraham I -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index a7754341eeda..531029351504 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -2646,6 +2646,9 @@ static void prueth_unregister_devlink_ports(struct prueth *prueth) - - for (i = PRUETH_MAC0; i < PRUETH_NUM_MACS; i++) { - emac = prueth->emac[i]; -+ if (!emac) -+ continue; -+ - dl_port = &emac->devlink_port; - - if (dl_port->registered) diff --git a/recipes-kernel/linux/files/patches-5.10/0176-net-ethernet-ti-Fix-buffer-SRAM-overlaps-in-EMAC-mod.patch b/recipes-kernel/linux/files/patches-5.10/0176-net-ethernet-ti-Fix-buffer-SRAM-overlaps-in-EMAC-mod.patch deleted file mode 100644 index c7af92faa..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0176-net-ethernet-ti-Fix-buffer-SRAM-overlaps-in-EMAC-mod.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vignesh Raghavendra -Date: Mon, 6 Dec 2021 14:12:07 +0530 -Subject: [PATCH] net: ethernet: ti: Fix buffer SRAM overlaps in EMAC mode - -Buffer allocation was supposed to follow below layout as per comment in -the prueth_emac_buffer_setup() - -[1] |BPOOL0 (64K) |BPOOL1 (64K)|RX_CTX0 (32K)|RX_CTX1 (32K)| - -But at the moment tracing prueth_emac_buffer_setup() shows below layout: - -[2] |BPOOL0 (64K) |BPOOL1 (64K)|RX_CTX0 (32K)| EMPTY (64K) |RX_CTX1 (32K)| - -Additional empty 64K is not required and is a bug. This causes ICSSG0 -SRAM reservations to overlap with ICSSG1 and so on. Fix this by dropping -unintended empty 64K hole and this reverting to layout [1]. - -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_config.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c -index 94785a85416c..564bafcd6fc3 100644 ---- a/drivers/net/ethernet/ti/icssg_config.c -+++ b/drivers/net/ethernet/ti/icssg_config.c -@@ -431,8 +431,9 @@ static int prueth_emac_buffer_setup(struct prueth_emac *emac) - addr += PRUETH_EMAC_BUF_POOL_SIZE_SR2; - } - -- addr += PRUETH_NUM_BUF_POOLS_SR2 * PRUETH_EMAC_BUF_POOL_SIZE_SR2; -- if (slice) -+ if (!slice) -+ addr += PRUETH_NUM_BUF_POOLS_SR2 * PRUETH_EMAC_BUF_POOL_SIZE_SR2; -+ else - addr += PRUETH_EMAC_RX_CTX_BUF_SIZE * 2; - - /* Pre-emptible RX buffer queue */ diff --git a/recipes-kernel/linux/files/patches-5.10/0177-net-ethernet-ti-icss_iep-Add-missing-spin_lock_init.patch b/recipes-kernel/linux/files/patches-5.10/0177-net-ethernet-ti-icss_iep-Add-missing-spin_lock_init.patch deleted file mode 100644 index 7d5c0633a..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0177-net-ethernet-ti-icss_iep-Add-missing-spin_lock_init.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Kishon Vijay Abraham I -Date: Mon, 7 Feb 2022 13:18:53 +0530 -Subject: [PATCH] net: ethernet: ti: icss_iep: Add missing spin_lock_init() - -Add missing spin_lock_init() for irq_lock member of struct icss_iep. - -This fixes the following dump: -INFO: trying to register non-static key. -The code is fine but needs lockdep annotation, or maybe -you didn't initialize this object before use? -turning off the locking correctness validator. -CPU: 1 PID: 1032 Comm: sh Not tainted 5.10.65-08510-g85c8939a4059 #205 -Hardware name: Texas Instruments AM642 EVM (DT) -Call trace: - dump_backtrace+0x0/0x1d0 - show_stack+0x18/0x28 - dump_stack+0xec/0x154 - register_lock_class+0x4e8/0x508 - __lock_acquire+0x7c/0x1d60 - lock_acquire+0x154/0x410 - _raw_spin_lock_irqsave+0x70/0x144 - icss_iep_ptp_enable+0x194/0x300 [icss_iep] - pps_enable_store+0xc0/0xe0 - dev_attr_store+0x18/0x30 - sysfs_kf_write+0x4c/0x78 - kernfs_fop_write_iter+0x120/0x1b8 - new_sync_write+0xe8/0x188 - vfs_write+0x2ac/0x450 - ksys_write+0x6c/0xf8 - __arm64_sys_write+0x1c/0x28 - el0_svc_common.constprop.0+0x7c/0x1f0 - do_el0_svc+0x24/0x90 - el0_svc+0x20/0x30 - el0_sync_handler+0xb0/0xb8 - el0_sync+0x180/0x1c0 -BUG: sleeping function called from invalid context at kernel/locking/mutex.c:947 -in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 1032, name: sh -INFO: lockdep is turned off. -irq event stamp: 65068 -hardirqs last enabled at (65067): [] _raw_spin_unlock_irqrestore+0x80/0x98 -hardirqs last disabled at (65068): [] _raw_spin_lock_irqsave+0xb0/0x144 -softirqs last enabled at (64770): [] efi_header_end+0x62c/0x6b0 -softirqs last disabled at (64761): [] irq_exit+0x1c4/0x1d8 -Preemption disabled at: -[] icss_iep_ptp_enable+0x194/0x300 [icss_iep] -CPU: 1 PID: 1032 Comm: sh Not tainted 5.10.65-08510-g85c8939a4059 #205 -Hardware name: Texas Instruments AM642 EVM (DT) -Call trace: - dump_backtrace+0x0/0x1d0 - show_stack+0x18/0x28 - dump_stack+0xec/0x154 - ___might_sleep+0x194/0x240 - __might_sleep+0x50/0x88 - __mutex_lock+0x5c/0x900 - mutex_lock_nested+0x34/0x50 - regmap_lock_mutex+0x14/0x20 - regmap_write+0x3c/0x78 - icss_iep_perout_enable_hw+0x68/0x210 [icss_iep] - icss_iep_ptp_enable+0x2ac/0x300 [icss_iep] - pps_enable_store+0xc0/0xe0 - dev_attr_store+0x18/0x30 - sysfs_kf_write+0x4c/0x78 - kernfs_fop_write_iter+0x120/0x1b8 - new_sync_write+0xe8/0x188 - vfs_write+0x2ac/0x450 - ksys_write+0x6c/0xf8 - __arm64_sys_write+0x1c/0x28 - el0_svc_common.constprop.0+0x7c/0x1f0 - do_el0_svc+0x24/0x90 - el0_svc+0x20/0x30 - el0_sync_handler+0xb0/0xb8 - el0_sync+0x180/0x1c0 - -Fixes: 5d58df8eb0bb ("net: ethernet: ti: icss_iep: fix pps irq race vs pps disable") -Signed-off-by: Kishon Vijay Abraham I -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index 481dc366a7c2..48a2f76bcc1a 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -956,6 +956,7 @@ static int icss_iep_probe(struct platform_device *pdev) - - iep->ptp_info = icss_iep_ptp_info; - mutex_init(&iep->ptp_clk_mutex); -+ spin_lock_init(&iep->irq_lock); - dev_set_drvdata(dev, iep); - icss_iep_disable(iep); - diff --git a/recipes-kernel/linux/files/patches-5.10/0178-net-ethernet-ti-icss_iep-Enable-regmap-fast_io-for-i.patch b/recipes-kernel/linux/files/patches-5.10/0178-net-ethernet-ti-icss_iep-Enable-regmap-fast_io-for-i.patch deleted file mode 100644 index 86520e201..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0178-net-ethernet-ti-icss_iep-Enable-regmap-fast_io-for-i.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Kishon Vijay Abraham I -Date: Mon, 7 Feb 2022 13:18:54 +0530 -Subject: [PATCH] net: ethernet: ti: icss_iep: Enable regmap fast_io for - iep_regmap_config - -icss_iep_perout_enable_hw() is invoked with spin_lock_irqsave() and -hence cannot use sleeping lock. Enable regmap fast_io for -iep_regmap_config so that it will use spinlock instead of mutex. - -This fixes the following dump -BUG: sleeping function called from invalid context at kernel/locking/mutex.c:947 -in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 1103, name: sh -5 locks held by sh/1103: - #0: ffff00002b814438 (sb_writers#5){.+.+}-{0:0}, at: ksys_write+0x6c/0xf8 - #1: ffff0000322ae888 (&of->mutex){+.+.}-{3:3}, at: kernfs_fop_write_iter+0xf0/0x1b8 - #2: ffff0000744837d0 (kn->active#158){++++}-{0:0}, at: kernfs_fop_write_iter+0xf8/0x1b8 - #3: ffff0000344401b8 (&iep->ptp_clk_mutex){+.+.}-{3:3}, at: icss_iep_ptp_enable+0x168/0x2f0 [icss_iep] - #4: ffff0000344401f8 (&iep->irq_lock){....}-{2:2}, at: icss_iep_ptp_enable+0x19c/0x2f0 [icss_iep] -irq event stamp: 92858 -hardirqs last enabled at (92857): [] _raw_spin_unlock_irqrestore+0x80/0x98 -hardirqs last disabled at (92858): [] _raw_spin_lock_irqsave+0xb0/0x144 -softirqs last enabled at (92658): [] efi_header_end+0x62c/0x6b0 -softirqs last disabled at (92645): [] irq_exit+0x1c4/0x1d8 -Preemption disabled at: -[] icss_iep_ptp_enable+0x19c/0x2f0 [icss_iep] -CPU: 1 PID: 1103 Comm: sh Not tainted 5.10.65-08510-g2bea885230fd-dirty #204 -Hardware name: Texas Instruments AM642 EVM (DT) -Call trace: - dump_backtrace+0x0/0x1d0 - show_stack+0x18/0x28 - dump_stack+0xec/0x154 - ___might_sleep+0x194/0x240 - __might_sleep+0x50/0x88 - __mutex_lock+0x5c/0x900 - mutex_lock_nested+0x34/0x50 - regmap_lock_mutex+0x14/0x20 - regmap_write+0x3c/0x78 - icss_iep_perout_enable_hw+0xd0/0x2c0 [icss_iep] - icss_iep_ptp_enable+0x2b4/0x2f0 [icss_iep] - pps_enable_store+0xc0/0xe0 - dev_attr_store+0x18/0x30 - sysfs_kf_write+0x4c/0x78 - kernfs_fop_write_iter+0x120/0x1b8 - new_sync_write+0xe8/0x188 - vfs_write+0x2ac/0x450 - ksys_write+0x6c/0xf8 - __arm64_sys_write+0x1c/0x28 - el0_svc_common.constprop.0+0x7c/0x1f0 - do_el0_svc+0x24/0x90 - el0_svc+0x20/0x30 - el0_sync_handler+0xb0/0xb8 - el0_sync+0x180/0x1c0 - -============================= -[ BUG: Invalid wait context ] -5.10.65-08510-g2bea885230fd-dirty #204 Tainted: G W ------------------------------ -sh/1103 is trying to lock: -ffff000034440468 (icss_iep:959:(iep->plat_data->config)->lock){+.+.}-{3:3}, at: regmap_lock_mutex+0x14/0x20 -other info that might help us debug this: -context-{4:4} -5 locks held by sh/1103: - #0: ffff00002b814438 (sb_writers#5){.+.+}-{0:0}, at: ksys_write+0x6c/0xf8 - #1: ffff0000322ae888 (&of->mutex){+.+.}-{3:3}, at: kernfs_fop_write_iter+0xf0/0x1b8 - #2: ffff0000744837d0 (kn->active#158){++++}-{0:0}, at: kernfs_fop_write_iter+0xf8/0x1b8 - #3: ffff0000344401b8 (&iep->ptp_clk_mutex){+.+.}-{3:3}, at: icss_iep_ptp_enable+0x168/0x2f0 [icss_iep] - #4: ffff0000344401f8 (&iep->irq_lock){....}-{2:2}, at: icss_iep_ptp_enable+0x19c/0x2f0 [icss_iep] -stack backtrace: -CPU: 1 PID: 1103 Comm: sh Tainted: G W 5.10.65-08510-g2bea885230fd-dirty #204 -Hardware name: Texas Instruments AM642 EVM (DT) -Call trace: - dump_backtrace+0x0/0x1d0 - show_stack+0x18/0x28 - dump_stack+0xec/0x154 - __lock_acquire+0x1d38/0x1d60 - lock_acquire+0x154/0x410 - __mutex_lock+0x9c/0x900 - mutex_lock_nested+0x34/0x50 - regmap_lock_mutex+0x14/0x20 - regmap_write+0x3c/0x78 - icss_iep_perout_enable_hw+0xd0/0x2c0 [icss_iep] - icss_iep_ptp_enable+0x2b4/0x2f0 [icss_iep] - pps_enable_store+0xc0/0xe0 - dev_attr_store+0x18/0x30 - sysfs_kf_write+0x4c/0x78 - kernfs_fop_write_iter+0x120/0x1b8 - new_sync_write+0xe8/0x188 - vfs_write+0x2ac/0x450 - ksys_write+0x6c/0xf8 - __arm64_sys_write+0x1c/0x28 - el0_svc_common.constprop.0+0x7c/0x1f0 - do_el0_svc+0x24/0x90 - el0_svc+0x20/0x30 - el0_sync_handler+0xb0/0xb8 - el0_sync+0x180/0x1c0 - -Fixes: 5d58df8eb0bb ("net: ethernet: ti: icss_iep: fix pps irq race vs pps disable") -Signed-off-by: Kishon Vijay Abraham I -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_iep.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c -index 48a2f76bcc1a..4552fc07553d 100644 ---- a/drivers/net/ethernet/ti/icss_iep.c -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -1002,6 +1002,7 @@ static struct regmap_config am654_icss_iep_regmap_config = { - .reg_read = icss_iep_regmap_read, - .writeable_reg = am654_icss_iep_valid_reg, - .readable_reg = am654_icss_iep_valid_reg, -+ .fast_io = 1, - }; - - static const struct icss_iep_plat_data am654_icss_iep_plat_data = { diff --git a/recipes-kernel/linux/files/patches-5.10/0179-net-ti-icssg_prueth-Support-multiple-TX-timestamp-re.patch b/recipes-kernel/linux/files/patches-5.10/0179-net-ti-icssg_prueth-Support-multiple-TX-timestamp-re.patch deleted file mode 100644 index e27b66d84..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0179-net-ti-icssg_prueth-Support-multiple-TX-timestamp-re.patch +++ /dev/null @@ -1,207 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Roger Quadros -Date: Thu, 10 Feb 2022 11:03:53 +0200 -Subject: [PATCH] net: ti: icssg_prueth: Support multiple TX timestamp requests - -There is no firmware limitation to handle multiple TX timestamp -requests. Support upto 50 simultaneous requests. The maximum -requests can be changed by macro PRUETH_MAX_TX_TS_REQUESTS. - -Signed-off-by: Roger Quadros -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 78 +++++++++++++------------- - drivers/net/ethernet/ti/icssg_prueth.h | 11 ++-- - 2 files changed, 43 insertions(+), 46 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 531029351504..7805603c9767 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -771,12 +771,6 @@ static void tx_ts_work(struct prueth_emac *emac) - struct emac_tx_ts_response tsr; - u32 hi_sw; - -- if (!test_bit(__STATE_TX_TS_IN_PROGRESS, &emac->state)) { -- netdev_err(emac->ndev, "unexpected TS response\n"); -- return; -- } -- -- skb = emac->tx_ts_skb; - while (timeout-- > 0) { - /* wait for response or timeout */ - ret = emac_get_tx_ts(emac, &tsr); -@@ -787,13 +781,21 @@ static void tx_ts_work(struct prueth_emac *emac) - - if (ret) { - netdev_err(emac->ndev, "TX timestamp timeout\n"); -- goto error; -+ return; -+ } -+ -+ if (tsr.cookie >= PRUETH_MAX_TX_TS_REQUESTS || -+ !emac->tx_ts_skb[tsr.cookie]) { -+ netdev_err(emac->ndev, "Invalid TX TS cookie 0x%x\n", -+ tsr.cookie); -+ return; - } - -- if (tsr.cookie != emac->tx_ts_cookie) { -- netdev_err(emac->ndev, "TX TS cookie mismatch 0x%x:0x%x\n", -- tsr.cookie, emac->tx_ts_cookie); -- goto error; -+ skb = emac->tx_ts_skb[tsr.cookie]; -+ emac->tx_ts_skb[tsr.cookie] = NULL; /* free slot */ -+ if (!skb) { -+ netdev_err(emac->ndev, "Driver Bug! got NULL skb\n"); -+ return; - } - - hi_sw = readl(emac->prueth->shram.va + -@@ -801,20 +803,28 @@ static void tx_ts_work(struct prueth_emac *emac) - ns = icssg_ts_to_ns(hi_sw, tsr.hi_ts, tsr.lo_ts, - IEP_DEFAULT_CYCLE_TIME_NS); - -- emac->tx_ts_cookie++; - memset(&ssh, 0, sizeof(ssh)); - ssh.hwtstamp = ns_to_ktime(ns); -- clear_bit_unlock(__STATE_TX_TS_IN_PROGRESS, &emac->state); - - skb_tstamp_tx(skb, &ssh); - dev_consume_skb_any(skb); - - return; -+} - --error: -- dev_kfree_skb_any(skb); -- emac->tx_ts_skb = NULL; -- clear_bit_unlock(__STATE_TX_TS_IN_PROGRESS, &emac->state); -+int prueth_tx_ts_cookie_get(struct prueth_emac *emac) -+{ -+ int i; -+ -+ /* search and get the next free slot */ -+ for (i = 0; i < PRUETH_MAX_TX_TS_REQUESTS; i++) { -+ if (!emac->tx_ts_skb[i]) { -+ emac->tx_ts_skb[i] = ERR_PTR(-EBUSY); /* reserve slot */ -+ return i; -+ } -+ } -+ -+ return -EBUSY; - } - - /** -@@ -841,6 +851,7 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - void **swdata; - u32 pkt_len; - u32 *epib; -+ int tx_ts_cookie; - - pkt_len = skb_headlen(skb); - q_idx = skb_get_queue_mapping(skb); -@@ -873,13 +884,13 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && - emac->tx_ts_enabled) { - /* We currently support only one TX HW timestamp at a time */ -- if (!test_and_set_bit_lock(__STATE_TX_TS_IN_PROGRESS, -- &emac->state)) { -+ tx_ts_cookie = prueth_tx_ts_cookie_get(emac); -+ if (tx_ts_cookie >= 0) { - skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; - /* Request TX timestamp */ -- epib[0] = emac->tx_ts_cookie; -+ epib[0] = (u32)tx_ts_cookie; - epib[1] = 0x80000000; /* TX TS request */ -- emac->tx_ts_skb = skb_get(skb); -+ emac->tx_ts_skb[tx_ts_cookie] = skb_get(skb); - in_tx_ts = 1; - } - } -@@ -964,9 +975,8 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - - cleanup_tx_ts: - if (in_tx_ts) { -- dev_kfree_skb_any(emac->tx_ts_skb); -- emac->tx_ts_skb = NULL; -- clear_bit_unlock(__STATE_TX_TS_IN_PROGRESS, &emac->state); -+ dev_kfree_skb_any(emac->tx_ts_skb[tx_ts_cookie]); -+ emac->tx_ts_skb[tx_ts_cookie] = NULL; - } - - drop_free_descs: -@@ -1086,32 +1096,22 @@ static void prueth_tx_ts_sr1(struct prueth_emac *emac, - - ns = (u64)tsr->hi_ts << 32 | tsr->lo_ts; - -- if (!test_bit(__STATE_TX_TS_IN_PROGRESS, &emac->state)) { -- netdev_err(emac->ndev, "unexpected TS response\n"); -+ if (tsr->cookie >= PRUETH_MAX_TX_TS_REQUESTS) { -+ netdev_dbg(emac->ndev, "Invalid TX TS cookie 0x%x\n", -+ tsr->cookie); - return; - } - -- skb = emac->tx_ts_skb; -- if (tsr->cookie != emac->tx_ts_cookie) { -- netdev_err(emac->ndev, "TX TS cookie mismatch 0x%x:0x%x\n", -- tsr->cookie, emac->tx_ts_cookie); -- goto error; -- } -+ skb = emac->tx_ts_skb[tsr->cookie]; -+ emac->tx_ts_skb[tsr->cookie] = NULL; /* free slot */ - -- emac->tx_ts_cookie++; - memset(&ssh, 0, sizeof(ssh)); - ssh.hwtstamp = ns_to_ktime(ns); -- clear_bit_unlock(__STATE_TX_TS_IN_PROGRESS, &emac->state); - - skb_tstamp_tx(skb, &ssh); - dev_consume_skb_any(skb); - - return; -- --error: -- dev_kfree_skb_any(skb); -- emac->tx_ts_skb = NULL; -- clear_bit_unlock(__STATE_TX_TS_IN_PROGRESS, &emac->state); - } - - static irqreturn_t prueth_rx_mgm_ts_thread_sr1(int irq, void *dev_id) -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 2ae732fec2c6..b176ac96c2d7 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -113,10 +113,6 @@ struct prueth_rx_chn { - char name[32]; - }; - --enum prueth_state_flags { -- __STATE_TX_TS_IN_PROGRESS, --}; -- - enum prueth_devlink_param_id { - PRUETH_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, - PRUETH_DL_PARAM_SWITCH_MODE, -@@ -131,6 +127,8 @@ struct prueth_devlink { - */ - #define PRUETH_MAX_TX_QUEUES 4 - -+#define PRUETH_MAX_TX_TS_REQUESTS 50 /* Max simultaneous TX_TS requests */ -+ - /* data for each emac port */ - struct prueth_emac { - bool is_sr1; -@@ -170,9 +168,8 @@ struct prueth_emac { - spinlock_t lock; /* serialize access */ - - /* TX HW Timestamping */ -- u32 tx_ts_cookie; -- struct sk_buff *tx_ts_skb; -- unsigned long state; -+ /* TX TS cookie will be index to the tx_ts_skb array */ -+ struct sk_buff *tx_ts_skb[PRUETH_MAX_TX_TS_REQUESTS]; - int tx_ts_irq; - - u8 cmd_seq; diff --git a/recipes-kernel/linux/files/patches-5.10/0180-net-ti-icssg-select-NET_DEVLINK.patch b/recipes-kernel/linux/files/patches-5.10/0180-net-ti-icssg-select-NET_DEVLINK.patch deleted file mode 100644 index 10fe5a523..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0180-net-ti-icssg-select-NET_DEVLINK.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: chao zeng -Date: Fri, 11 Nov 2022 11:17:47 +0800 -Subject: [PATCH] net:ti:icssg: select NET_DEVLINK - -NET_DEVLINK is necessary for current icssg driver. -However it has not be enabled. -This configuration should report to TI. - -Signed-off-by: chao zeng ---- - drivers/net/ethernet/ti/Kconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig -index 90ede5a5f108..7830994c5a55 100644 ---- a/drivers/net/ethernet/ti/Kconfig -+++ b/drivers/net/ethernet/ti/Kconfig -@@ -184,6 +184,7 @@ config TI_ICSSG_PRUETH - select TI_DAVINCI_MDIO - select NET_PTP_CLASSIFY - select TI_ICSS_IEP -+ select NET_DEVLINK - imply PTP_1588_CLOCK - depends on PRU_REMOTEPROC - depends on NET_SWITCHDEV diff --git a/recipes-kernel/linux/files/patches-5.10/0181-net-ethernet-ti-icssg_prueth-Restore-half-duplex-sup.patch b/recipes-kernel/linux/files/patches-5.10/0181-net-ethernet-ti-icssg_prueth-Restore-half-duplex-sup.patch deleted file mode 100644 index 14a7a333a..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0181-net-ethernet-ti-icssg_prueth-Restore-half-duplex-sup.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Sat, 14 Jan 2023 19:48:15 +0100 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: Restore half-duplex support - -This was lost during refactoring. - -Fixes: 0a175a01189c ("net: ethernet: ti: icssg_prueth: move phy init in .ndo_open/close()") -Signed-off-by: Jan Kiszka ---- - drivers/net/ethernet/ti/icssg_prueth.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 7805603c9767..10ec9ebef867 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1604,6 +1604,7 @@ const struct icss_iep_clockops prueth_iep_clockops = { - static int emac_phy_connect(struct prueth_emac *emac) - { - struct prueth *prueth = emac->prueth; -+ int slice = prueth_emac_slice(emac); - - /* connect PHY */ - emac->phydev = of_phy_connect(emac->ndev, emac->phy_node, -@@ -1614,9 +1615,14 @@ static int emac_phy_connect(struct prueth_emac *emac) - return -ENODEV; - } - -+ emac->half_duplex = of_property_read_bool(prueth->eth_node[slice], -+ "ti,half-duplex-capable"); -+ - /* remove unsupported modes */ -- phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); -- phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); -+ if (!emac->half_duplex) { -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); -+ phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); -+ } - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Pause_BIT); - phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT); diff --git a/recipes-kernel/linux/files/patches-5.10/0182-net-ethernet-ti-icssg_prueth-fix-devlink-port-regist.patch b/recipes-kernel/linux/files/patches-5.10/0182-net-ethernet-ti-icssg_prueth-fix-devlink-port-regist.patch deleted file mode 100644 index 3ed3f20ea..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0182-net-ethernet-ti-icssg_prueth-fix-devlink-port-regist.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko -Date: Fri, 8 Apr 2022 12:21:32 +0300 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: fix devlink port register - sequence - -When udevd is configured to rename interfaces according to persistent -naming rules and if a network interface has phys_port_name in sysfs, its -contents will be appended to the interface name. However, register_netdev -creates device in sysfs and if devlink_port_register is called after that, -there is a timeframe in which udevd may read an empty phys_port_name value. -The consequence is that the interface will lose this suffix and its name -will not be really persistent. - -The solution is to register the port before registering a netdev. - -Fixes: 3f7a788ef4c3 ("net: ethernet: ti: icssg_prueth: Add support for ICSSG switch firmware on AM654 PG2.0") -Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 15 +++++++++------ - 1 file changed, 9 insertions(+), 6 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 10ec9ebef867..fd15611f2013 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -2719,7 +2719,6 @@ static int prueth_register_devlink(struct prueth *prueth) - emac->port_id, ret); - goto dl_port_unreg; - } -- devlink_port_type_eth_set(dl_port, emac->ndev); - } - - return ret; -@@ -2944,6 +2943,10 @@ static int prueth_probe(struct platform_device *pdev) - prueth->emac[PRUETH_MAC1]->iep = prueth->iep0; - } - -+ ret = prueth_register_devlink(prueth); -+ if (ret) -+ goto netdev_exit; -+ - /* register the network devices */ - if (eth0_node) { - ret = register_netdev(prueth->emac[PRUETH_MAC0]->ndev); -@@ -2952,6 +2955,8 @@ static int prueth_probe(struct platform_device *pdev) - goto netdev_exit; - } - -+ devlink_port_type_eth_set(&prueth->emac[PRUETH_MAC0]->devlink_port, -+ prueth->emac[PRUETH_MAC0]->ndev); - prueth->registered_netdevs[PRUETH_MAC0] = prueth->emac[PRUETH_MAC0]->ndev; - } - -@@ -2961,14 +2966,12 @@ static int prueth_probe(struct platform_device *pdev) - dev_err(dev, "can't register netdev for port MII1"); - goto netdev_unregister; - } -+ devlink_port_type_eth_set(&prueth->emac[PRUETH_MAC1]->devlink_port, -+ prueth->emac[PRUETH_MAC1]->ndev); - - prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev; - } - -- ret = prueth_register_devlink(prueth); -- if (ret) -- goto netdev_unregister; -- - if (prueth->is_switchmode_supported) { - ret = prueth_register_notifiers(prueth); - if (ret) -@@ -3045,13 +3048,13 @@ static int prueth_remove(struct platform_device *pdev) - int i; - - prueth_unregister_notifiers(prueth); -- prueth_unregister_devlink(prueth); - - for (i = 0; i < PRUETH_NUM_MACS; i++) { - if (!prueth->registered_netdevs[i]) - continue; - unregister_netdev(prueth->registered_netdevs[i]); - } -+ prueth_unregister_devlink(prueth); - - for (i = 0; i < PRUETH_NUM_MACS; i++) { - eth_node = prueth->eth_node[i]; diff --git a/recipes-kernel/linux/files/patches-5.10/0183-net-ti-icssg_prueth-clean-up-pending-TX-timestamp-re.patch b/recipes-kernel/linux/files/patches-5.10/0183-net-ti-icssg_prueth-clean-up-pending-TX-timestamp-re.patch deleted file mode 100644 index 18814d6d5..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0183-net-ti-icssg_prueth-clean-up-pending-TX-timestamp-re.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Roger Quadros -Date: Tue, 3 May 2022 15:43:20 +0300 -Subject: [PATCH] net: ti: icssg_prueth: clean up pending TX timestamp requests - at link down - -If there are any pending TX timestamp requests we have to -clean them up and release the skb() at link down. - -Fixes: 81e29e8cb07c ("net: ti: icssg_prueth: Support multiple TX timestamp requests") -Signed-off-by: Roger Quadros -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index fd15611f2013..0feb046ff253 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1300,6 +1300,18 @@ static void prueth_emac_stop(struct prueth_emac *emac) - rproc_shutdown(prueth->pru[slice]); - } - -+static void prueth_cleanup_tx_ts(struct prueth_emac *emac) -+{ -+ int i; -+ -+ for (i = 0; i < PRUETH_MAX_TX_TS_REQUESTS; i++) { -+ if (emac->tx_ts_skb[i]) { -+ dev_kfree_skb_any(emac->tx_ts_skb[i]); -+ emac->tx_ts_skb[i] = NULL; -+ } -+ } -+} -+ - /* called back by PHY layer if there is change in link state of hw port*/ - static void emac_adjust_link(struct net_device *ndev) - { -@@ -1380,6 +1392,7 @@ static void emac_adjust_link(struct net_device *ndev) - /* link OFF */ - netif_carrier_off(ndev); - netif_tx_stop_all_queues(ndev); -+ prueth_cleanup_tx_ts(emac); - } - } - diff --git a/recipes-kernel/linux/files/patches-5.10/0184-net-ti-icssg_prueth-fix-missed-back-to-back-TX-times.patch b/recipes-kernel/linux/files/patches-5.10/0184-net-ti-icssg_prueth-fix-missed-back-to-back-TX-times.patch deleted file mode 100644 index ac5bb42b6..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0184-net-ti-icssg_prueth-fix-missed-back-to-back-TX-times.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Roger Quadros -Date: Tue, 3 May 2022 15:43:21 +0300 -Subject: [PATCH] net: ti: icssg_prueth: fix missed back to back TX timestamp - responses - -There may be more than one TX timestamp responses pending -so check and process those before returning from interrupt -worker thread. - -Fixes: 81e29e8cb07c ("net: ti: icssg_prueth: Support multiple TX timestamp requests") -Signed-off-by: Roger Quadros -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 60 +++++++++++++------------- - drivers/net/ethernet/ti/icssg_prueth.h | 1 + - 2 files changed, 30 insertions(+), 31 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 0feb046ff253..dab44c8172c6 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -766,48 +766,44 @@ static void tx_ts_work(struct prueth_emac *emac) - u64 ns; - struct skb_shared_hwtstamps ssh; - struct sk_buff *skb; -- int timeout = 10; - int ret = 0; - struct emac_tx_ts_response tsr; - u32 hi_sw; - -- while (timeout-- > 0) { -- /* wait for response or timeout */ -+ /* There may be more than one pending requests */ -+ while (1) { - ret = emac_get_tx_ts(emac, &tsr); -- if (!ret) -+ if (ret) /* nothing more */ - break; -- usleep_range(10, 20); -- } - -- if (ret) { -- netdev_err(emac->ndev, "TX timestamp timeout\n"); -- return; -- } -+ if (tsr.cookie >= PRUETH_MAX_TX_TS_REQUESTS || -+ !emac->tx_ts_skb[tsr.cookie]) { -+ netdev_err(emac->ndev, "Invalid TX TS cookie 0x%x\n", -+ tsr.cookie); -+ break; -+ } - -- if (tsr.cookie >= PRUETH_MAX_TX_TS_REQUESTS || -- !emac->tx_ts_skb[tsr.cookie]) { -- netdev_err(emac->ndev, "Invalid TX TS cookie 0x%x\n", -- tsr.cookie); -- return; -- } -+ skb = emac->tx_ts_skb[tsr.cookie]; -+ emac->tx_ts_skb[tsr.cookie] = NULL; /* free slot */ -+ if (!skb) { -+ netdev_err(emac->ndev, "Driver Bug! got NULL skb\n"); -+ break; -+ } - -- skb = emac->tx_ts_skb[tsr.cookie]; -- emac->tx_ts_skb[tsr.cookie] = NULL; /* free slot */ -- if (!skb) { -- netdev_err(emac->ndev, "Driver Bug! got NULL skb\n"); -- return; -- } -+ hi_sw = readl(emac->prueth->shram.va + -+ TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET); -+ ns = icssg_ts_to_ns(hi_sw, tsr.hi_ts, tsr.lo_ts, -+ IEP_DEFAULT_CYCLE_TIME_NS); - -- hi_sw = readl(emac->prueth->shram.va + -- TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET); -- ns = icssg_ts_to_ns(hi_sw, tsr.hi_ts, tsr.lo_ts, -- IEP_DEFAULT_CYCLE_TIME_NS); -+ memset(&ssh, 0, sizeof(ssh)); -+ ssh.hwtstamp = ns_to_ktime(ns); - -- memset(&ssh, 0, sizeof(ssh)); -- ssh.hwtstamp = ns_to_ktime(ns); -+ skb_tstamp_tx(skb, &ssh); -+ dev_consume_skb_any(skb); - -- skb_tstamp_tx(skb, &ssh); -- dev_consume_skb_any(skb); -+ if (atomic_dec_and_test(&emac->tx_ts_pending)) /* no more? */ -+ break; -+ } - - return; - } -@@ -883,7 +879,6 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - epib[1] = 0; - if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && - emac->tx_ts_enabled) { -- /* We currently support only one TX HW timestamp at a time */ - tx_ts_cookie = prueth_tx_ts_cookie_get(emac); - if (tx_ts_cookie >= 0) { - skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; -@@ -961,6 +956,9 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - goto drop_free_descs; - } - -+ if (in_tx_ts) -+ atomic_inc(&emac->tx_ts_pending); -+ - if (k3_cppi_desc_pool_avail(tx_chn->desc_pool) < MAX_SKB_FRAGS) { - netif_tx_stop_queue(netif_txq); - /* Barrier, so that stop_queue visible to other cpus */ -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index b176ac96c2d7..9c0d948ed700 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -170,6 +170,7 @@ struct prueth_emac { - /* TX HW Timestamping */ - /* TX TS cookie will be index to the tx_ts_skb array */ - struct sk_buff *tx_ts_skb[PRUETH_MAX_TX_TS_REQUESTS]; -+ atomic_t tx_ts_pending; - int tx_ts_irq; - - u8 cmd_seq; diff --git a/recipes-kernel/linux/files/patches-5.10/0185-net-ti-icssg-prueth-move-phy_connect-phy_disconnect.patch b/recipes-kernel/linux/files/patches-5.10/0185-net-ti-icssg-prueth-move-phy_connect-phy_disconnect.patch deleted file mode 100644 index e64828692..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0185-net-ti-icssg-prueth-move-phy_connect-phy_disconnect.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Puranjay Mohan -Date: Mon, 9 May 2022 11:09:31 +0530 -Subject: [PATCH] net: ti: icssg-prueth: move phy_connect()/phy_disconnect() - -The phy_connect() and phy_disconnect() functions are currently called -when the interface is brought up and down using ifconfig respectively. -This causes an issue when ethtool is used after bringing down the -interface. This issue was reported by Siemens. - -Move the phy_connect()/phy_disconnect() logic to probe and remove -respectively to solve this bug. - -Signed-off-by: Puranjay Mohan -Signed-off-by: Vignesh Raghavendra -Link: https://serenity.dal.design.ti.com/lore/linux-patch-review/20220509053931.4552-1-p-mohan@ti.com ---- - drivers/net/ethernet/ti/icssg_prueth.c | 22 ++++++++++++++++------ - 1 file changed, 16 insertions(+), 6 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index dab44c8172c6..8b7c2018d094 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -1805,10 +1805,6 @@ static int emac_ndo_open(struct net_device *ndev) - - icssg_qos_init(ndev); - -- emac_phy_connect(emac); -- /* Get attached phy details */ -- phy_attached_info(emac->phydev); -- - /* start PHY */ - phy_start(emac->phydev); - -@@ -1891,8 +1887,6 @@ static int emac_ndo_stop(struct net_device *ndev) - - /* block packets from wire */ - phy_stop(emac->phydev); -- phy_disconnect(emac->phydev); -- emac->phydev = NULL; - - icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac)); - -@@ -2969,6 +2963,11 @@ static int prueth_probe(struct platform_device *pdev) - devlink_port_type_eth_set(&prueth->emac[PRUETH_MAC0]->devlink_port, - prueth->emac[PRUETH_MAC0]->ndev); - prueth->registered_netdevs[PRUETH_MAC0] = prueth->emac[PRUETH_MAC0]->ndev; -+ -+ emac_phy_connect(prueth->emac[PRUETH_MAC0]); -+ /* Get attached phy details */ -+ phy_attached_info(prueth->emac[PRUETH_MAC0]->phydev); -+ - } - - if (eth1_node) { -@@ -2977,10 +2976,15 @@ static int prueth_probe(struct platform_device *pdev) - dev_err(dev, "can't register netdev for port MII1"); - goto netdev_unregister; - } -+ - devlink_port_type_eth_set(&prueth->emac[PRUETH_MAC1]->devlink_port, - prueth->emac[PRUETH_MAC1]->ndev); - - prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev; -+ -+ emac_phy_connect(prueth->emac[PRUETH_MAC1]); -+ /* Get attached phy details */ -+ phy_attached_info(prueth->emac[PRUETH_MAC1]->phydev); - } - - if (prueth->is_switchmode_supported) { -@@ -3005,6 +3009,10 @@ static int prueth_probe(struct platform_device *pdev) - for (i = 0; i < PRUETH_NUM_MACS; i++) { - if (!prueth->registered_netdevs[i]) - continue; -+ if (prueth->emac[i]->phydev) { -+ phy_disconnect(prueth->emac[i]->phydev); -+ prueth->emac[i]->phydev = NULL; -+ } - unregister_netdev(prueth->registered_netdevs[i]); - } - -@@ -3063,6 +3071,8 @@ static int prueth_remove(struct platform_device *pdev) - for (i = 0; i < PRUETH_NUM_MACS; i++) { - if (!prueth->registered_netdevs[i]) - continue; -+ phy_disconnect(prueth->emac[i]->phydev); -+ prueth->emac[i]->phydev = NULL; - unregister_netdev(prueth->registered_netdevs[i]); - } - prueth_unregister_devlink(prueth); diff --git a/recipes-kernel/linux/files/patches-5.10/0188-net-ti-icssg_prueth-support-larger-MTU-of-upto-1982-.patch b/recipes-kernel/linux/files/patches-5.10/0188-net-ti-icssg_prueth-support-larger-MTU-of-upto-1982-.patch deleted file mode 100644 index 488e16b8a..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0188-net-ti-icssg_prueth-support-larger-MTU-of-upto-1982-.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Roger Quadros -Date: Wed, 22 Jun 2022 14:36:34 +0300 -Subject: [PATCH] net: ti: icssg_prueth: support larger MTU of upto 1982 bytes - -MII_G port defaults are 2000 bytes. -(i.e. MII_G_RT_RX_STAT_MAX_SIZE_PRU0/1 & MII_G_RT_TX_STAT_MAX_SIZE_PORT0/1) - -Removing 14 bytes of Ethernet MAC header and 4 bytes of FCS we -are left with a payload size (MTU) of 1982. - -Update MII_RT_RX_FRMS0/1 to the same (2000-1) and set max MTU of -the PRU Ethernet device driver to 1982. - -Signed-off-by: Roger Quadros -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icss_mii_rt.h | 1 + - drivers/net/ethernet/ti/icssg_mii_cfg.c | 16 ++++++++++++++++ - drivers/net/ethernet/ti/icssg_prueth.c | 10 +++++++++- - 3 files changed, 26 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/ti/icss_mii_rt.h b/drivers/net/ethernet/ti/icss_mii_rt.h -index 11c159cb8510..13c87bb567b0 100644 ---- a/drivers/net/ethernet/ti/icss_mii_rt.h -+++ b/drivers/net/ethernet/ti/icss_mii_rt.h -@@ -133,6 +133,7 @@ struct regmap; - struct prueth_emac; - - void icssg_mii_update_ipg(struct regmap *mii_rt, int mii, u32 ipg); -+void icssg_mii_update_mtu(struct regmap *mii_rt, int mii, int mtu); - void icssg_update_rgmii_cfg(struct regmap *miig_rt, struct prueth_emac *emac); - u32 icssg_rgmii_cfg_get_bitfield(struct regmap *miig_rt, u32 mask, u32 shift); - u32 icssg_rgmii_get_speed(struct regmap *miig_rt, int mii); -diff --git a/drivers/net/ethernet/ti/icssg_mii_cfg.c b/drivers/net/ethernet/ti/icssg_mii_cfg.c -index 97c2e5b2957b..8687fa3b5163 100644 ---- a/drivers/net/ethernet/ti/icssg_mii_cfg.c -+++ b/drivers/net/ethernet/ti/icssg_mii_cfg.c -@@ -26,6 +26,22 @@ void icssg_mii_update_ipg(struct regmap *mii_rt, int mii, u32 ipg) - } - } - -+void icssg_mii_update_mtu(struct regmap *mii_rt, int mii, int mtu) -+{ -+ mtu += (ETH_HLEN + ETH_FCS_LEN); -+ if (mii == ICSS_MII0) { -+ regmap_update_bits(mii_rt, -+ PRUSS_MII_RT_RX_FRMS0, -+ PRUSS_MII_RT_RX_FRMS_MAX_FRM_MASK, -+ (mtu - 1) << PRUSS_MII_RT_RX_FRMS_MAX_FRM_SHIFT); -+ } else { -+ regmap_update_bits(mii_rt, -+ PRUSS_MII_RT_RX_FRMS1, -+ PRUSS_MII_RT_RX_FRMS_MAX_FRM_MASK, -+ (mtu - 1) << PRUSS_MII_RT_RX_FRMS_MAX_FRM_SHIFT); -+ } -+} -+ - void icssg_update_rgmii_cfg(struct regmap *miig_rt, struct prueth_emac *emac) - { - u32 gig_en_mask, gig_val = 0, full_duplex_mask, full_duplex_val = 0; -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 8b7c2018d094..50bb35e93360 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -35,8 +35,12 @@ - #define PRUETH_MODULE_VERSION "0.1" - #define PRUETH_MODULE_DESCRIPTION "PRUSS ICSSG Ethernet driver" - -+/* MAX MTU set to match MII_G_RT_RX_STAT_MAX_SIZE_PRU0/1, -+ * MII_G_RT_TX_STAT_MAX_SIZE_PORT0/1 defaults -+ */ -+#define PRUETH_MAX_MTU (2000 - ETH_HLEN - ETH_FCS_LEN) - #define PRUETH_MIN_PKT_SIZE (VLAN_ETH_ZLEN) --#define PRUETH_MAX_PKT_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) -+#define PRUETH_MAX_PKT_SIZE (PRUETH_MAX_MTU + ETH_HLEN + ETH_FCS_LEN) - - /* Netif debug messages possible */ - #define PRUETH_EMAC_DEBUG (NETIF_MSG_DRV | \ -@@ -1761,6 +1765,8 @@ static int emac_ndo_open(struct net_device *ndev) - if (ret) - goto free_rx_mgmt_ts_irq; - -+ icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu); -+ - if (!emac->is_sr1 && !prueth->emacs_initialized) { - ret = icss_iep_init(emac->iep, &prueth_iep_clockops, - emac, IEP_DEFAULT_CYCLE_TIME_NS); -@@ -2322,6 +2328,8 @@ static int prueth_netdev_init(struct prueth *prueth, - } - ether_addr_copy(emac->mac_addr, ndev->dev_addr); - -+ ndev->min_mtu = PRUETH_MIN_PKT_SIZE; -+ ndev->max_mtu = PRUETH_MAX_MTU; - ndev->netdev_ops = &emac_netdev_ops; - ndev->ethtool_ops = &icssg_ethtool_ops; - ndev->hw_features = NETIF_F_SG; diff --git a/recipes-kernel/linux/files/patches-5.10/0189-dmaengine-ti-k3-udma-Reset-UDMA_CHAN_RT-byte-counter.patch b/recipes-kernel/linux/files/patches-5.10/0189-dmaengine-ti-k3-udma-Reset-UDMA_CHAN_RT-byte-counter.patch deleted file mode 100644 index 53e9a894a..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0189-dmaengine-ti-k3-udma-Reset-UDMA_CHAN_RT-byte-counter.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vaishnav Achath -Date: Tue, 2 Aug 2022 11:43:15 +0530 -Subject: [PATCH] dmaengine: ti: k3-udma: Reset UDMA_CHAN_RT byte counters to - prevent overflow - -UDMA_CHAN_RT_*BCNT_REG stores the real-time channel bytecount statistics. -These registers are 32-bit hardware counters and the driver uses these -counters to monitor the operational progress status for a channel, when -transferring more than 4GB of data it was observed that these counters -overflow and completion calculation of a operation gets affected and the -transfer hangs indefinitely. - -This commit adds changes to decrease the byte count for every complete -transaction so that these registers never overflow and the proper byte -count statistics is maintained for ongoing transaction by the RT counters. - -Earlier uc->bcnt used to maintain a count of the completed bytes at driver -side, since the RT counters maintain the statistics of current transaction -now, the maintenance of uc->bcnt is not necessary. - -Signed-off-by: Vaishnav Achath -Signed-off-by: Vignesh Raghavendra ---- - drivers/dma/ti/k3-udma.c | 25 +++++++++++++++++-------- - 1 file changed, 17 insertions(+), 8 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index ff59ba1b9505..c22f9e3de83c 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -300,8 +300,6 @@ struct udma_chan { - - struct udma_tx_drain tx_drain; - -- u32 bcnt; /* number of bytes completed since the start of the channel */ -- - /* Channel configuration parameters */ - struct udma_chan_config config; - -@@ -757,6 +755,20 @@ static void udma_reset_rings(struct udma_chan *uc) - } - } - -+static void udma_decrement_byte_counters(struct udma_chan *uc, u32 val) -+{ -+ if (uc->desc->dir == DMA_DEV_TO_MEM) { -+ udma_rchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val); -+ udma_rchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val); -+ udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); -+ } else { -+ udma_tchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val); -+ udma_tchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val); -+ if (!uc->bchan) -+ udma_tchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); -+ } -+} -+ - static void udma_reset_counters(struct udma_chan *uc) - { - u32 val; -@@ -790,8 +802,6 @@ static void udma_reset_counters(struct udma_chan *uc) - val = udma_rchanrt_read(uc, UDMA_CHAN_RT_PEER_BCNT_REG); - udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); - } -- -- uc->bcnt = 0; - } - - static int udma_reset_chan(struct udma_chan *uc, bool hard) -@@ -1115,7 +1125,7 @@ static void udma_check_tx_completion(struct work_struct *work) - if (uc->desc) { - struct udma_desc *d = uc->desc; - -- uc->bcnt += d->residue; -+ udma_decrement_byte_counters(uc, d->residue); - udma_start(uc); - vchan_cookie_complete(&d->vd); - break; -@@ -1168,7 +1178,7 @@ static irqreturn_t udma_ring_irq_handler(int irq, void *data) - vchan_cyclic_callback(&d->vd); - } else { - if (udma_is_desc_really_done(uc, d)) { -- uc->bcnt += d->residue; -+ udma_decrement_byte_counters(uc, d->residue); - udma_start(uc); - vchan_cookie_complete(&d->vd); - } else { -@@ -1204,7 +1214,7 @@ static irqreturn_t udma_udma_irq_handler(int irq, void *data) - vchan_cyclic_callback(&d->vd); - } else { - /* TODO: figure out the real amount of data */ -- uc->bcnt += d->residue; -+ udma_decrement_byte_counters(uc, d->residue); - udma_start(uc); - vchan_cookie_complete(&d->vd); - } -@@ -3810,7 +3820,6 @@ static enum dma_status udma_tx_status(struct dma_chan *chan, - bcnt = udma_tchanrt_read(uc, UDMA_CHAN_RT_BCNT_REG); - } - -- bcnt -= uc->bcnt; - if (bcnt && !(bcnt % uc->desc->residue)) - residue = 0; - else diff --git a/recipes-kernel/linux/files/patches-5.10/0191-net-ti-icssg_prueth-Fix-overflowing-of-stats.patch b/recipes-kernel/linux/files/patches-5.10/0191-net-ti-icssg_prueth-Fix-overflowing-of-stats.patch deleted file mode 100644 index 9b6ff57f1..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0191-net-ti-icssg_prueth-Fix-overflowing-of-stats.patch +++ /dev/null @@ -1,170 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MD Danish Anwar -Date: Tue, 16 Aug 2022 11:57:43 +0530 -Subject: [PATCH] net: ti: icssg_prueth: Fix overflowing of stats - -ICSSG has hardware registers for providing statistics like total rx bytes, -total tx bytes, etc. These registers are of 32 bits and hence in case of 1G -link, they overflows in around 32 seconds. The behaviour of these registers -is such that they don't roll back to 0 after overflow but rather stay at -UINT_MAX. - -These registers support a feature where the value written to them is -subtracted from the register. This feature can be utilized to fix the -overflowing of stats. - -This solution uses a Workqueues based solution where a function gets -called before the registers overflow, this function saves the register -values in local variables and resets the hardware registers. - -The ethtool callback now returns the values in the local variables -rather than reading the hardware registers directly. - -Signed-off-by: MD Danish Anwar ---- - drivers/net/ethernet/ti/icssg_ethtool.c | 46 ++++++++++++++++++++++--- - drivers/net/ethernet/ti/icssg_prueth.c | 12 +++++++ - drivers/net/ethernet/ti/icssg_prueth.h | 4 +++ - 3 files changed, 57 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg_ethtool.c -index 6aa10d9ac2e6..bb6f4010af22 100644 ---- a/drivers/net/ethernet/ti/icssg_ethtool.c -+++ b/drivers/net/ethernet/ti/icssg_ethtool.c -@@ -8,6 +8,8 @@ - #include "icssg_prueth.h" - #include - -+#define STATS_TIME_LIMIT_MS 25000000 -+ - static u32 stats_base[] = { 0x54c, /* Slice 0 stats start */ - 0xb18, /* Slice 1 stats start */ - }; -@@ -290,24 +292,58 @@ static void emac_get_strings(struct net_device *ndev, u32 stringset, u8 *data) - } - } - --static void emac_get_ethtool_stats(struct net_device *ndev, -- struct ethtool_stats *stats, u64 *data) -+static void emac_update_hardware_stats(struct prueth_emac *emac) - { -- struct prueth_emac *emac = netdev_priv(ndev); - struct prueth *prueth = emac->prueth; -- int i; - int slice = prueth_emac_slice(emac); - u32 base = stats_base[slice]; - u32 val; -+ int i; - - for (i = 0; i < ARRAY_SIZE(icssg_ethtool_stats); i++) { - regmap_read(prueth->miig_rt, - base + icssg_ethtool_stats[i].offset, - &val); -- data[i] = val; -+ regmap_write(prueth->miig_rt, -+ base + icssg_ethtool_stats[i].offset, -+ val); -+ -+ emac->stats[i] += val; - } - } - -+void emac_stats_work_handler(struct work_struct *work) -+{ -+ struct prueth_emac *emac = container_of(work, struct prueth_emac, -+ stats_work.work); -+ emac_update_hardware_stats(emac); -+ -+ queue_delayed_work(system_long_wq, &emac->stats_work, -+ msecs_to_jiffies(STATS_TIME_LIMIT_MS / emac->speed)); -+} -+ -+void emac_ethtool_stats_init(struct prueth_emac *emac) -+{ -+ if (!emac->stats) { -+ struct device *dev = emac->prueth->dev; -+ -+ emac->stats = devm_kzalloc(dev, ARRAY_SIZE(icssg_ethtool_stats) * -+ sizeof(*emac->stats), GFP_KERNEL); -+ } -+} -+ -+static void emac_get_ethtool_stats(struct net_device *ndev, -+ struct ethtool_stats *stats, u64 *data) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ int i; -+ -+ emac_update_hardware_stats(emac); -+ -+ for (i = 0; i < ARRAY_SIZE(icssg_ethtool_stats); i++) -+ data[i] = emac->stats[i]; -+} -+ - static int emac_get_ts_info(struct net_device *ndev, - struct ethtool_ts_info *info) - { -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 50bb35e93360..8fd6c24f7bd2 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1831,6 +1832,9 @@ static int emac_ndo_open(struct net_device *ndev) - icssg_set_pvid(emac->prueth, emac->port_vlan, emac->port_id); - emac_set_port_state(emac, ICSSG_EMAC_PORT_VLAN_AWARE_ENABLE); - } -+ -+ queue_work(system_long_wq, &emac->stats_work.work); -+ - return 0; - - reset_tx_chan: -@@ -1934,6 +1938,11 @@ static int emac_ndo_stop(struct net_device *ndev) - icss_iep_exit(emac->iep); - - cancel_work_sync(&emac->rx_mode_work); -+ -+ /* Destroying the queued work in ndo_stop() */ -+ -+ cancel_delayed_work_sync(&emac->stats_work); -+ - /* stop PRUs */ - prueth_emac_stop(emac); - -@@ -2251,6 +2260,9 @@ static int prueth_netdev_init(struct prueth *prueth, - } - INIT_WORK(&emac->rx_mode_work, emac_ndo_set_rx_mode_work); - -+ emac_ethtool_stats_init(emac); -+ INIT_DELAYED_WORK(&emac->stats_work, emac_stats_work_handler); -+ - ret = pruss_request_mem_region(prueth->pruss, - port == PRUETH_PORT_MII0 ? - PRUSS_MEM_DRAM0 : PRUSS_MEM_DRAM1, -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 9c0d948ed700..e761fb3d4c51 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -190,6 +190,8 @@ struct prueth_emac { - - struct prueth_qos qos; - struct work_struct ts_work; -+ struct delayed_work stats_work; -+ u64 *stats; - }; - - /** -@@ -352,4 +354,6 @@ void icssg_set_pvid(struct prueth *prueth, u8 vid, u8 port); - container_of(pnapi, struct prueth_tx_chn, napi_tx) - - u64 prueth_iep_gettime(void *clockops_data, struct ptp_system_timestamp *sts); -+void emac_stats_work_handler(struct work_struct *work); -+void emac_ethtool_stats_init(struct prueth_emac *emac); - #endif /* __NET_TI_ICSSG_PRUETH_H */ diff --git a/recipes-kernel/linux/files/patches-5.10/0192-dmaengine-ti-k3-udma-Respond-TX-done-if-DMA_PREP_INT.patch b/recipes-kernel/linux/files/patches-5.10/0192-dmaengine-ti-k3-udma-Respond-TX-done-if-DMA_PREP_INT.patch deleted file mode 100644 index f1ff6b879..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0192-dmaengine-ti-k3-udma-Respond-TX-done-if-DMA_PREP_INT.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Vaishnav Achath -Date: Tue, 11 Oct 2022 13:24:42 +0530 -Subject: [PATCH] dmaengine: ti: k3-udma: Respond TX done if DMA_PREP_INTERRUPT - is not requested - -If the DMA consumer driver does not expect the callback for TX done, then -we need not perform the channel RT byte counter calculations and estimate -the completion but return complete on first attempt itself.This assumes -that the consumer who did not request DMA_PREP_INTERRUPT has its own -mechanism for understanding TX completion, example: MCSPI EOW interrupt -can be used as TX completion signal for a SPI transaction. - -Signed-off-by: Vaishnav Achath -Acked-by: Peter Ujfalusi -Signed-off-by: Vignesh Raghavendra ---- - drivers/dma/ti/k3-udma.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index c22f9e3de83c..6b02433c7f1d 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -263,6 +263,7 @@ struct udma_chan_config { - enum udma_tp_level channel_tpl; /* Channel Throughput Level */ - - u32 tr_trigger_type; -+ unsigned long tx_flags; - - /* PKDMA mapped channel */ - int mapped_channel_id; -@@ -1055,9 +1056,14 @@ static bool udma_is_desc_really_done(struct udma_chan *uc, struct udma_desc *d) - { - u32 peer_bcnt, bcnt; - -- /* Only TX towards PDMA is affected */ -+ /* -+ * Only TX towards PDMA is affected. -+ * If DMA_PREP_INTERRUPT is not set by consumer then skip the transfer -+ * completion calculation, consumer must ensure that there is no stale -+ * data in DMA fabric in this case. -+ */ - if (uc->config.ep_type == PSIL_EP_NATIVE || -- uc->config.dir != DMA_MEM_TO_DEV) -+ uc->config.dir != DMA_MEM_TO_DEV || !(uc->config.tx_flags & DMA_PREP_INTERRUPT)) - return true; - - peer_bcnt = udma_tchanrt_read(uc, UDMA_CHAN_RT_PEER_BCNT_REG); -@@ -3419,6 +3425,8 @@ udma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, - if (!burst) - burst = 1; - -+ uc->config.tx_flags = tx_flags; -+ - if (uc->config.pkt_mode) - d = udma_prep_slave_sg_pkt(uc, sgl, sglen, dir, tx_flags, - context); diff --git a/recipes-kernel/linux/files/patches-5.10/0194-clocksource-drivers-timer-ti-dm-Add-compatible-for-a.patch b/recipes-kernel/linux/files/patches-5.10/0194-clocksource-drivers-timer-ti-dm-Add-compatible-for-a.patch deleted file mode 100644 index 9baedf62a..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0194-clocksource-drivers-timer-ti-dm-Add-compatible-for-a.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tony Lindgren -Date: Fri, 28 Oct 2022 14:29:42 -0500 -Subject: [PATCH] clocksource/drivers/timer-ti-dm: Add compatible for am6 SoCs - -Add compatible for ti,am654-timer to support the timers. For example, am654 -has four timers in the MCU domain and 12 timers in the MAIN domain. - -Cc: Keerthy -Cc: Nishanth Menon -Cc: Vignesh Raghavendra -Signed-off-by: Tony Lindgren ---- - drivers/clocksource/timer-ti-dm.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c -index e5c631f1b5cb..c993848baca4 100644 ---- a/drivers/clocksource/timer-ti-dm.c -+++ b/drivers/clocksource/timer-ti-dm.c -@@ -921,6 +921,10 @@ static const struct dmtimer_platform_data omap3plus_pdata = { - .timer_ops = &dmtimer_ops, - }; - -+static const struct dmtimer_platform_data am6_pdata = { -+ .timer_ops = &dmtimer_ops, -+}; -+ - static const struct of_device_id omap_timer_match[] = { - { - .compatible = "ti,omap2420-timer", -@@ -949,6 +953,10 @@ static const struct of_device_id omap_timer_match[] = { - .compatible = "ti,dm816-timer", - .data = &omap3plus_pdata, - }, -+ { -+ .compatible = "ti,am654-timer", -+ .data = &am6_pdata, -+ }, - {}, - }; - MODULE_DEVICE_TABLE(of, omap_timer_match); diff --git a/recipes-kernel/linux/files/patches-5.10/0198-dmaengine-ti-k3-udma-Do-conditional-decrement-of-UDM.patch b/recipes-kernel/linux/files/patches-5.10/0198-dmaengine-ti-k3-udma-Do-conditional-decrement-of-UDM.patch deleted file mode 100644 index 4484e98b5..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0198-dmaengine-ti-k3-udma-Do-conditional-decrement-of-UDM.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jayesh Choudhary -Date: Fri, 25 Nov 2022 15:09:50 +0530 -Subject: [PATCH] dmaengine: ti: k3-udma: Do conditional decrement of - UDMA_CHAN_RT_PEER_BCNT_REG - -PSIL_EP_NATIVE endpoints may not have PEER registers for BCNT and thus -udma_decrement_byte_counters() should not try to decrement these counters. -This fixes the issue of crypto IPERF testing where the client side (EVM) -hangs without transfer of packets to the server side, seen since this -function was added. - -Fixes: a85c781629b3 ("dma: ti: k3-udma: Reset UDMA_CHAN_RT byte counters -to prevent overflow") -Signed-off-by: Jayesh Choudhary ---- - drivers/dma/ti/k3-udma.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index 7dcaf7a1eedb..43442556ab1d 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -764,11 +764,12 @@ static void udma_decrement_byte_counters(struct udma_chan *uc, u32 val) - if (uc->desc->dir == DMA_DEV_TO_MEM) { - udma_rchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val); - udma_rchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val); -- udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); -+ if (uc->config.ep_type != PSIL_EP_NATIVE) -+ udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); - } else { - udma_tchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val); - udma_tchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val); -- if (!uc->bchan) -+ if (!uc->bchan && uc->config.ep_type != PSIL_EP_NATIVE) - udma_tchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); - } - } diff --git a/recipes-kernel/linux/files/patches-5.10/0199-soc-ti-k3-ringacc-drop-loglevel-for-non-fatal-probe-.patch b/recipes-kernel/linux/files/patches-5.10/0199-soc-ti-k3-ringacc-drop-loglevel-for-non-fatal-probe-.patch deleted file mode 100644 index 98f1981dc..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0199-soc-ti-k3-ringacc-drop-loglevel-for-non-fatal-probe-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jayesh Choudhary -Date: Fri, 11 Nov 2022 16:20:03 +0530 -Subject: [PATCH] soc: ti: k3: ringacc: drop loglevel for non-fatal probe - deferral log - -This error is expected due to probe deferral. It is non-fatal and -it will probe again later on. So drop the loglevel from dev_err() -to dev_dbg(). - -Fixes: 3277e8aa2504 ("soc: ti: k3: add navss ringacc driver") -Signed-off-by: Jayesh Choudhary ---- - drivers/soc/ti/k3-ringacc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c -index 086d61a86b17..16500bfe4a08 100644 ---- a/drivers/soc/ti/k3-ringacc.c -+++ b/drivers/soc/ti/k3-ringacc.c -@@ -1358,7 +1358,7 @@ static int k3_ringacc_init(struct platform_device *pdev, - dev->msi_domain = of_msi_get_domain(dev, dev->of_node, - DOMAIN_BUS_TI_SCI_INTA_MSI); - if (!dev->msi_domain) { -- dev_err(dev, "Failed to get MSI domain\n"); -+ dev_dbg(dev, "Failed to get MSI domain\n"); - return -EPROBE_DEFER; - } - diff --git a/recipes-kernel/linux/files/patches-5.10/0200-dmaengine-ti-k3-udma-drop-loglevel-for-non-fatal-pro.patch b/recipes-kernel/linux/files/patches-5.10/0200-dmaengine-ti-k3-udma-drop-loglevel-for-non-fatal-pro.patch deleted file mode 100644 index fbce2b25c..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0200-dmaengine-ti-k3-udma-drop-loglevel-for-non-fatal-pro.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jayesh Choudhary -Date: Fri, 11 Nov 2022 16:20:04 +0530 -Subject: [PATCH] dmaengine: ti: k3-udma: drop loglevel for non-fatal probe - deferral log - -This error is expected due to probe deferral. It is non-fatal and -it will probe again later on. So drop the loglevel from dev_err() -to dev_dbg(). - -Fixes: 25dcb5dd7b7c ("dmaengine: ti: New driver for K3 UDMA") -Signed-off-by: Jayesh Choudhary ---- - drivers/dma/ti/k3-udma.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index 43442556ab1d..b10b5e17d991 100644 ---- a/drivers/dma/ti/k3-udma.c -+++ b/drivers/dma/ti/k3-udma.c -@@ -5305,7 +5305,7 @@ static int udma_probe(struct platform_device *pdev) - dev->msi_domain = of_msi_get_domain(dev, dev->of_node, - DOMAIN_BUS_TI_SCI_INTA_MSI); - if (!dev->msi_domain) { -- dev_err(dev, "Failed to get MSI domain\n"); -+ dev_dbg(dev, "Failed to get MSI domain\n"); - return -EPROBE_DEFER; - } - diff --git a/recipes-kernel/linux/files/patches-5.10/0201-net-ethernet-ti-icssg_prueth-Use-page_pool-API-for-R.patch b/recipes-kernel/linux/files/patches-5.10/0201-net-ethernet-ti-icssg_prueth-Use-page_pool-API-for-R.patch deleted file mode 100644 index bede849b9..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0201-net-ethernet-ti-icssg_prueth-Use-page_pool-API-for-R.patch +++ /dev/null @@ -1,511 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Roger Quadros -Date: Thu, 19 Jan 2023 17:15:28 +0530 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: Use page_pool API for RX - buffer allocation - -This is to prepare for native XDP support. - -The page pool API is more faster in allocating pages than -__alloc_skb(). Drawback is that it works at PAGE_SIZE granularity -so we are not efficient in memory usage. -i.e. we are using PAGE_SIZE (4KB) memory for 1.5KB max packet size. - -Signed-off-by: Roger Quadros -Signed-off-by: MD Danish Anwar -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/Kconfig | 1 + - drivers/net/ethernet/ti/icssg_prueth.c | 267 ++++++++++++++++--------- - drivers/net/ethernet/ti/icssg_prueth.h | 6 + - 3 files changed, 180 insertions(+), 94 deletions(-) - -diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig -index 7830994c5a55..f7093a36f5bd 100644 ---- a/drivers/net/ethernet/ti/Kconfig -+++ b/drivers/net/ethernet/ti/Kconfig -@@ -184,6 +184,7 @@ config TI_ICSSG_PRUETH - select TI_DAVINCI_MDIO - select NET_PTP_CLASSIFY - select TI_ICSS_IEP -+ select PAGE_POOL - select NET_DEVLINK - imply PTP_1588_CLOCK - depends on PRU_REMOTEPROC -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 8fd6c24f7bd2..db88f8409e9b 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -75,6 +75,11 @@ static void prueth_cleanup_rx_chns(struct prueth_emac *emac, - struct prueth_rx_chn *rx_chn, - int max_rflows) - { -+ if (rx_chn->pg_pool) { -+ page_pool_destroy(rx_chn->pg_pool); -+ rx_chn->pg_pool = NULL; -+ } -+ - if (rx_chn->desc_pool) - k3_cppi_desc_pool_destroy(rx_chn->desc_pool); - -@@ -463,17 +468,17 @@ static int prueth_init_rx_chns(struct prueth_emac *emac, - return ret; - } - --static int prueth_dma_rx_push(struct prueth_emac *emac, -- struct sk_buff *skb, -- struct prueth_rx_chn *rx_chn) -+static int prueth_dma_rx_push_mapped(struct prueth_emac *emac, -+ struct prueth_rx_chn *rx_chn, -+ struct page *page, u32 buf_len) - { -- struct cppi5_host_desc_t *desc_rx; - struct net_device *ndev = emac->ndev; -+ struct cppi5_host_desc_t *desc_rx; - dma_addr_t desc_dma; - dma_addr_t buf_dma; -- u32 pkt_len = skb_tailroom(skb); - void **swdata; - -+ buf_dma = page_pool_get_dma_addr(page) + PRUETH_HEADROOM; - desc_rx = k3_cppi_desc_pool_alloc(rx_chn->desc_pool); - if (!desc_rx) { - netdev_err(ndev, "rx push: failed to allocate descriptor\n"); -@@ -481,20 +486,13 @@ static int prueth_dma_rx_push(struct prueth_emac *emac, - } - desc_dma = k3_cppi_desc_pool_virt2dma(rx_chn->desc_pool, desc_rx); - -- buf_dma = dma_map_single(rx_chn->dma_dev, skb->data, pkt_len, DMA_FROM_DEVICE); -- if (unlikely(dma_mapping_error(rx_chn->dma_dev, buf_dma))) { -- k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); -- netdev_err(ndev, "rx push: failed to map rx pkt buffer\n"); -- return -EINVAL; -- } -- - cppi5_hdesc_init(desc_rx, CPPI5_INFO0_HDESC_EPIB_PRESENT, - PRUETH_NAV_PS_DATA_SIZE); - k3_udma_glue_rx_dma_to_cppi5_addr(rx_chn->rx_chn, &buf_dma); -- cppi5_hdesc_attach_buf(desc_rx, buf_dma, skb_tailroom(skb), buf_dma, skb_tailroom(skb)); -+ cppi5_hdesc_attach_buf(desc_rx, buf_dma, buf_len, buf_dma, buf_len); - - swdata = cppi5_hdesc_get_swdata(desc_rx); -- *swdata = skb; -+ *swdata = page; - - return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, 0, - desc_rx, desc_dma); -@@ -535,18 +533,30 @@ static void emac_rx_timestamp(struct prueth_emac *emac, - ssh->hwtstamp = ns_to_ktime(ns); - } - -+static unsigned int prueth_rxbuf_total_len(unsigned int len) -+{ -+ len += PRUETH_HEADROOM; -+ len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -+ -+ return SKB_DATA_ALIGN(len); -+} -+ - static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) - { - struct prueth_rx_chn *rx_chn = &emac->rx_chns; -+ u32 buf_dma_len, pkt_len, port_id = 0; - struct net_device *ndev = emac->ndev; - struct cppi5_host_desc_t *desc_rx; - dma_addr_t desc_dma, buf_dma; -- u32 buf_dma_len, pkt_len, port_id = 0; -- int ret; -+ struct page *page, *new_page; -+ struct page_pool *pool; -+ struct sk_buff *skb; - void **swdata; -- struct sk_buff *skb, *new_skb; - u32 *psdata; -+ void *pa; -+ int ret; - -+ pool = rx_chn->pg_pool; - ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma); - if (ret) { - if (ret != -ENODATA) -@@ -560,12 +570,7 @@ static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) - desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma); - - swdata = cppi5_hdesc_get_swdata(desc_rx); -- skb = *swdata; -- -- psdata = cppi5_hdesc_get_psdata(desc_rx); -- /* RX HW timestamp */ -- if (emac->rx_ts_enabled) -- emac_rx_timestamp(emac, skb, psdata); -+ page = *swdata; - - cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); - k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma); -@@ -574,37 +579,57 @@ static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) - pkt_len -= 4; - cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL); - -- dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE); - k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); - -- skb->dev = ndev; -- if (!netif_running(skb->dev)) { -- dev_kfree_skb_any(skb); -+ if (!netif_running(ndev)) { -+ page_pool_recycle_direct(pool, page); - return 0; - } - -- new_skb = netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE); - /* if allocation fails we drop the packet but push the -- * descriptor back to the ring with old skb to prevent a stall -+ * descriptor back to the ring with old page to prevent a stall - */ -- if (!new_skb) { -+ new_page = page_pool_dev_alloc_pages(pool); -+ if (unlikely(!new_page)) { -+ new_page = page; - ndev->stats.rx_dropped++; -- new_skb = skb; -- } else { -- /* send the filled skb up the n/w stack */ -- if (emac->prueth->is_switch_mode) -- skb->offload_fwd_mark = emac->offload_fwd_mark; -- skb_put(skb, pkt_len); -- skb->protocol = eth_type_trans(skb, ndev); -- netif_receive_skb(skb); -- ndev->stats.rx_bytes += pkt_len; -- ndev->stats.rx_packets++; -+ goto requeue; -+ } -+ -+ /* prepare skb and send to n/w stack */ -+ pa = page_address(page); -+ skb = build_skb(pa, prueth_rxbuf_total_len(pkt_len)); -+ if (!skb) { -+ ndev->stats.rx_dropped++; -+ page_pool_recycle_direct(pool, page); -+ goto requeue; - } - -+ skb_reserve(skb, PRUETH_HEADROOM); -+ skb_put(skb, pkt_len); -+ skb->dev = ndev; -+ -+ psdata = cppi5_hdesc_get_psdata(desc_rx); -+ /* RX HW timestamp */ -+ if (emac->rx_ts_enabled) -+ emac_rx_timestamp(emac, skb, psdata); -+ -+ if (emac->prueth->is_switch_mode) -+ skb->offload_fwd_mark = emac->offload_fwd_mark; -+ skb->protocol = eth_type_trans(skb, ndev); -+ -+ /* unmap page as no recycling of netstack skb page */ -+ page_pool_release_page(pool, page); -+ netif_receive_skb(skb); -+ ndev->stats.rx_bytes += pkt_len; -+ ndev->stats.rx_packets++; -+ -+requeue: - /* queue another RX DMA */ -- ret = prueth_dma_rx_push(emac, new_skb, &emac->rx_chns); -+ ret = prueth_dma_rx_push_mapped(emac, &emac->rx_chns, new_page, -+ PRUETH_MAX_PKT_SIZE); - if (WARN_ON(ret < 0)) { -- dev_kfree_skb_any(new_skb); -+ page_pool_recycle_direct(pool, new_page); - ndev->stats.rx_errors++; - ndev->stats.rx_dropped++; - } -@@ -616,22 +641,17 @@ static void prueth_rx_cleanup(void *data, dma_addr_t desc_dma) - { - struct prueth_rx_chn *rx_chn = data; - struct cppi5_host_desc_t *desc_rx; -- struct sk_buff *skb; -- dma_addr_t buf_dma; -- u32 buf_dma_len; -+ struct page_pool *pool; -+ struct page *page; - void **swdata; - -+ pool = rx_chn->pg_pool; -+ - desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma); - swdata = cppi5_hdesc_get_swdata(desc_rx); -- skb = *swdata; -- cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); -- k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma); -- -- dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, -- DMA_FROM_DEVICE); -+ page = *swdata; -+ page_pool_recycle_direct(pool, page); - k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); -- -- dev_kfree_skb_any(skb); - } - - static int emac_get_tx_ts(struct prueth_emac *emac, -@@ -1029,17 +1049,17 @@ static irqreturn_t prueth_tx_ts_irq(int irq, void *dev_id) - * Returns skb pointer if packet found else NULL - * Caller must free the returned skb. - */ --static struct sk_buff *prueth_process_rx_mgm(struct prueth_emac *emac, -- u32 flow_id) -+static struct page *prueth_process_rx_mgm(struct prueth_emac *emac, -+ u32 flow_id) - { - struct prueth_rx_chn *rx_chn = &emac->rx_mgm_chn; -+ struct page_pool *pool = rx_chn->pg_pool; - struct net_device *ndev = emac->ndev; - struct cppi5_host_desc_t *desc_rx; -- dma_addr_t desc_dma, buf_dma; -- u32 buf_dma_len, pkt_len; -- int ret; -+ struct page *page, *new_page; -+ dma_addr_t desc_dma; - void **swdata; -- struct sk_buff *skb, *new_skb; -+ int ret; - - ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma); - if (ret) { -@@ -1060,34 +1080,29 @@ static struct sk_buff *prueth_process_rx_mgm(struct prueth_emac *emac, - } - - swdata = cppi5_hdesc_get_swdata(desc_rx); -- skb = *swdata; -- cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); -- pkt_len = cppi5_hdesc_get_pktlen(desc_rx); -+ page = *swdata; - -- dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE); - k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); - -- new_skb = netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE); - /* if allocation fails we drop the packet but push the -- * descriptor back to the ring with old skb to prevent a stall -+ * descriptor back to the ring with old page to prevent a stall - */ -- if (!new_skb) { -+ new_page = page_pool_dev_alloc_pages(pool); -+ if (unlikely(!new_page)) { - netdev_err(ndev, -- "skb alloc failed, dropped mgm pkt from flow %d\n", -+ "page alloc failed, dropped mgm pkt from flow %d\n", - flow_id); -- new_skb = skb; -- skb = NULL; /* return NULL */ -- } else { -- /* return the filled skb */ -- skb_put(skb, pkt_len); -+ new_page = page; -+ page = NULL; - } - - /* queue another DMA */ -- ret = prueth_dma_rx_push(emac, new_skb, &emac->rx_mgm_chn); -+ ret = prueth_dma_rx_push_mapped(emac, &emac->rx_mgm_chn, new_page, -+ PRUETH_MAX_PKT_SIZE); - if (WARN_ON(ret < 0)) -- dev_kfree_skb_any(new_skb); -+ page_pool_recycle_direct(pool, new_page); - -- return skb; -+ return page; - } - - static void prueth_tx_ts_sr1(struct prueth_emac *emac, -@@ -1120,14 +1135,16 @@ static void prueth_tx_ts_sr1(struct prueth_emac *emac, - static irqreturn_t prueth_rx_mgm_ts_thread_sr1(int irq, void *dev_id) - { - struct prueth_emac *emac = dev_id; -- struct sk_buff *skb; -+ struct page *page; -+ void *data; - -- skb = prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_TIMESTAMP); -- if (!skb) -+ page = prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_TIMESTAMP); -+ if (!page) - return IRQ_NONE; - -- prueth_tx_ts_sr1(emac, (void *)skb->data); -- dev_kfree_skb_any(skb); -+ data = page_address(page) + PRUETH_HEADROOM; -+ prueth_tx_ts_sr1(emac, (struct emac_tx_ts_response_sr1 *)data); -+ page_pool_recycle_direct(emac->rx_mgm_chn.pg_pool, page); - - return IRQ_HANDLED; - } -@@ -1135,15 +1152,17 @@ static irqreturn_t prueth_rx_mgm_ts_thread_sr1(int irq, void *dev_id) - static irqreturn_t prueth_rx_mgm_rsp_thread(int irq, void *dev_id) - { - struct prueth_emac *emac = dev_id; -- struct sk_buff *skb; -+ struct page *page; -+ void *data; - u32 rsp; - -- skb = prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_RESPONSE); -- if (!skb) -+ page = prueth_process_rx_mgm(emac, PRUETH_RX_MGM_FLOW_RESPONSE); -+ if (!page) - return IRQ_NONE; - -+ data = page_address(page) + PRUETH_HEADROOM; - /* Process command response */ -- rsp = le32_to_cpu(*(u32 *)skb->data); -+ rsp = le32_to_cpu(*(u32 *)data); - if ((rsp & 0xffff0000) == ICSSG_SHUTDOWN_CMD) { - netdev_dbg(emac->ndev, - "f/w Shutdown cmd resp %x\n", rsp); -@@ -1156,7 +1175,7 @@ static irqreturn_t prueth_rx_mgm_rsp_thread(int irq, void *dev_id) - complete(&emac->cmd_complete); - } - -- dev_kfree_skb_any(skb); -+ page_pool_recycle_direct(emac->rx_mgm_chn.pg_pool, page); - - return IRQ_HANDLED; - } -@@ -1432,29 +1451,89 @@ static int emac_napi_rx_poll(struct napi_struct *napi_rx, int budget) - return num_rx; - } - -+static struct page_pool *prueth_create_page_pool(struct prueth_emac *emac, -+ struct device *dma_dev, -+ int size) -+{ -+ struct page_pool_params pp_params; -+ struct page_pool *pool; -+ -+ pp_params.order = 0; -+ pp_params.flags = PP_FLAG_DMA_MAP; -+ pp_params.pool_size = size; -+ pp_params.nid = NUMA_NO_NODE; -+ pp_params.dma_dir = DMA_BIDIRECTIONAL; -+ pp_params.dev = dma_dev; -+ -+ pool = page_pool_create(&pp_params); -+ if (IS_ERR(pool)) -+ netdev_err(emac->ndev, "cannot create rx page pool\n"); -+ -+ return pool; -+} -+ -+static struct page *prueth_get_page_from_rx_chn(struct prueth_rx_chn *chn) -+{ -+ struct cppi5_host_desc_t *desc_rx; -+ dma_addr_t desc_dma; -+ struct page *page; -+ void **swdata; -+ -+ k3_udma_glue_pop_rx_chn(chn->rx_chn, 0, &desc_dma); -+ desc_rx = k3_cppi_desc_pool_dma2virt(chn->desc_pool, desc_dma); -+ swdata = cppi5_hdesc_get_swdata(desc_rx); -+ page = *swdata; -+ -+ return page; -+} -+ - static int prueth_prepare_rx_chan(struct prueth_emac *emac, - struct prueth_rx_chn *chn, - int buf_size) - { -- struct sk_buff *skb; -- int i, ret; -+ struct page_pool *pool; -+ struct page *page; -+ int i, ret, j; -+ -+ pool = prueth_create_page_pool(emac, chn->dma_dev, chn->descs_num); -+ if (IS_ERR(pool)) -+ return PTR_ERR(pool); -+ -+ chn->pg_pool = pool; - - for (i = 0; i < chn->descs_num; i++) { -- skb = __netdev_alloc_skb_ip_align(NULL, buf_size, GFP_KERNEL); -- if (!skb) -- return -ENOMEM; -+ /* NOTE: we're not using memory efficiently here. -+ * 1 full page (4KB?) used here instead of -+ * PRUETH_MAX_PKT_SIZE (~1.5KB?) -+ */ -+ page = page_pool_dev_alloc_pages(pool); -+ if (!page) { -+ netdev_err(emac->ndev, "couldn't allocate rx page\n"); -+ ret = -ENOMEM; -+ goto recycle_alloc_pg; -+ } - -- ret = prueth_dma_rx_push(emac, skb, chn); -+ ret = prueth_dma_rx_push_mapped(emac, chn, page, buf_size); - if (ret < 0) { - netdev_err(emac->ndev, - "cannot submit skb for rx chan %s ret %d\n", - chn->name, ret); -- kfree_skb(skb); -- return ret; -+ page_pool_recycle_direct(pool, page); -+ goto recycle_alloc_pg; - } - } - - return 0; -+ -+recycle_alloc_pg: -+ for (j = 0; j < i; j++) { -+ page = prueth_get_page_from_rx_chn(chn); -+ page_pool_recycle_direct(pool, page); -+ } -+ page_pool_destroy(pool); -+ chn->pg_pool = NULL; -+ -+ return ret; - } - - static void prueth_reset_tx_chan(struct prueth_emac *emac, int ch_num, -@@ -1786,7 +1865,7 @@ static int emac_ndo_open(struct net_device *ndev) - goto free_rx_ts_irq; - - if (emac->is_sr1) { -- ret = prueth_prepare_rx_chan(emac, &emac->rx_mgm_chn, 64); -+ ret = prueth_prepare_rx_chan(emac, &emac->rx_mgm_chn, PRUETH_MAX_PKT_SIZE); - if (ret) - goto reset_rx_chn; - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index e761fb3d4c51..6fc39e27a74b 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -32,6 +32,7 @@ - #include - - #include -+#include - - #include "icssg_config.h" - #include "icss_iep.h" -@@ -111,6 +112,7 @@ struct prueth_rx_chn { - u32 descs_num; - unsigned int irq[ICSSG_MAX_RFLOWS]; /* separate irq per flow */ - char name[32]; -+ struct page_pool *pg_pool; - }; - - enum prueth_devlink_param_id { -@@ -194,6 +196,10 @@ struct prueth_emac { - u64 *stats; - }; - -+/* The buf includes headroom compatible with both skb and xdpf */ -+#define PRUETH_HEADROOM_NA (max(XDP_PACKET_HEADROOM, NET_SKB_PAD) + NET_IP_ALIGN) -+#define PRUETH_HEADROOM ALIGN(PRUETH_HEADROOM_NA, sizeof(long)) -+ - /** - * struct prueth - PRUeth platform data - * @fdqring_mode: Free desc queue mode diff --git a/recipes-kernel/linux/files/patches-5.10/0202-net-ethernet-ti-icssg_prueth-introduce-and-use-pruet.patch b/recipes-kernel/linux/files/patches-5.10/0202-net-ethernet-ti-icssg_prueth-introduce-and-use-pruet.patch deleted file mode 100644 index ff7a27285..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0202-net-ethernet-ti-icssg_prueth-introduce-and-use-pruet.patch +++ /dev/null @@ -1,293 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Roger Quadros -Date: Thu, 19 Jan 2023 17:15:29 +0530 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: introduce and use - prueth_swdata struct for SWDATA - -We have different cases for SWDATA (skb, page, cmd, etc) -so it is better to have a dedicated data structure for that. -We can embed the type field inside the struct and use it -to interpret the data in completion handlers. - -Increase SWDATA size to 48 so we have some room to add -more data if required. - -Signed-off-by: Roger Quadros -Signed-off-by: MD Danish Anwar -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_config.h | 2 +- - drivers/net/ethernet/ti/icssg_prueth.c | 72 +++++++++++++++++--------- - drivers/net/ethernet/ti/icssg_prueth.h | 18 +++++++ - 3 files changed, 66 insertions(+), 26 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_config.h b/drivers/net/ethernet/ti/icssg_config.h -index 1f973dd5c6f7..75d1c2deeace 100644 ---- a/drivers/net/ethernet/ti/icssg_config.h -+++ b/drivers/net/ethernet/ti/icssg_config.h -@@ -90,7 +90,7 @@ struct icssg_config_sr1 { - - #define PRUETH_PKT_TYPE_CMD 0x10 - #define PRUETH_NAV_PS_DATA_SIZE 16 /* Protocol specific data size */ --#define PRUETH_NAV_SW_DATA_SIZE 16 /* SW related data size */ -+#define PRUETH_NAV_SW_DATA_SIZE 48 /* SW related data size */ - #define PRUETH_MAX_TX_DESC 512 - #define PRUETH_MAX_RX_DESC 512 - #define PRUETH_MAX_RX_FLOWS_SR2 1 /* excluding default flow */ -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index db88f8409e9b..81bb71d436dd 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -167,7 +167,7 @@ static int emac_tx_complete_packets(struct prueth_emac *emac, int chn, - struct sk_buff *skb; - dma_addr_t desc_dma; - int res, num_tx = 0; -- void **swdata; -+ struct prueth_swdata *swdata; - - tx_chn = &emac->tx_chns[chn]; - -@@ -188,13 +188,19 @@ static int emac_tx_complete_packets(struct prueth_emac *emac, int chn, - swdata = cppi5_hdesc_get_swdata(desc_tx); - - /* was this command's TX complete? */ -- if (emac->is_sr1 && *(swdata) == emac->cmd_data) { -+ if (emac->is_sr1 && swdata->type == PRUETH_SWDATA_CMD) { - prueth_xmit_free(tx_chn, desc_tx); - budget++; /* not a data packet */ - continue; - } - -- skb = *(swdata); -+ if (swdata->type != PRUETH_SWDATA_SKB) { -+ netdev_err(ndev, "tx_complete: invalid swdata type %d\n", swdata->type); -+ budget++; -+ continue; -+ } -+ -+ skb = swdata->data.skb; - prueth_xmit_free(tx_chn, desc_tx); - - ndev = skb->dev; -@@ -474,9 +480,9 @@ static int prueth_dma_rx_push_mapped(struct prueth_emac *emac, - { - struct net_device *ndev = emac->ndev; - struct cppi5_host_desc_t *desc_rx; -+ struct prueth_swdata *swdata; - dma_addr_t desc_dma; - dma_addr_t buf_dma; -- void **swdata; - - buf_dma = page_pool_get_dma_addr(page) + PRUETH_HEADROOM; - desc_rx = k3_cppi_desc_pool_alloc(rx_chn->desc_pool); -@@ -492,7 +498,8 @@ static int prueth_dma_rx_push_mapped(struct prueth_emac *emac, - cppi5_hdesc_attach_buf(desc_rx, buf_dma, buf_len, buf_dma, buf_len); - - swdata = cppi5_hdesc_get_swdata(desc_rx); -- *swdata = page; -+ swdata->type = PRUETH_SWDATA_PAGE; -+ swdata->data.page = page; - - return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, 0, - desc_rx, desc_dma); -@@ -548,10 +555,10 @@ static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) - struct net_device *ndev = emac->ndev; - struct cppi5_host_desc_t *desc_rx; - dma_addr_t desc_dma, buf_dma; -+ struct prueth_swdata *swdata; - struct page *page, *new_page; - struct page_pool *pool; - struct sk_buff *skb; -- void **swdata; - u32 *psdata; - void *pa; - int ret; -@@ -570,7 +577,11 @@ static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) - desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma); - - swdata = cppi5_hdesc_get_swdata(desc_rx); -- page = *swdata; -+ if (swdata->type != PRUETH_SWDATA_PAGE) { -+ netdev_err(ndev, "rx_pkt: invliad swdata->type %d\n", swdata->type); -+ return 0; -+ } -+ page = swdata->data.page; - - cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); - k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma); -@@ -641,16 +652,18 @@ static void prueth_rx_cleanup(void *data, dma_addr_t desc_dma) - { - struct prueth_rx_chn *rx_chn = data; - struct cppi5_host_desc_t *desc_rx; -+ struct prueth_swdata *swdata; - struct page_pool *pool; - struct page *page; -- void **swdata; - - pool = rx_chn->pg_pool; - - desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma); - swdata = cppi5_hdesc_get_swdata(desc_rx); -- page = *swdata; -- page_pool_recycle_direct(pool, page); -+ if (swdata->type == PRUETH_SWDATA_PAGE) { -+ page = swdata->data.page; -+ page_pool_recycle_direct(pool, page); -+ } - k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); - } - -@@ -682,11 +695,11 @@ static int emac_send_command_sr1(struct prueth_emac *emac, u32 cmd) - dma_addr_t desc_dma, buf_dma; - struct prueth_tx_chn *tx_chn; - struct cppi5_host_desc_t *first_desc; -+ u32 pkt_len = sizeof(emac->cmd_data); -+ struct prueth_swdata *swdata; -+ u32 *data = emac->cmd_data; - int ret = 0; - u32 *epib; -- u32 *data = emac->cmd_data; -- u32 pkt_len = sizeof(emac->cmd_data); -- void **swdata; - - netdev_dbg(emac->ndev, "Sending cmd %x\n", cmd); - -@@ -722,7 +735,8 @@ static int emac_send_command_sr1(struct prueth_emac *emac, u32 cmd) - - cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len); - swdata = cppi5_hdesc_get_swdata(first_desc); -- *swdata = data; -+ swdata->type = PRUETH_SWDATA_CMD; -+ swdata->data.cmd = cmd; - - cppi5_hdesc_set_pktlen(first_desc, pkt_len); - desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, first_desc); -@@ -862,17 +876,17 @@ int prueth_tx_ts_cookie_get(struct prueth_emac *emac) - */ - static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - { -- struct prueth_emac *emac = netdev_priv(ndev); - struct cppi5_host_desc_t *first_desc, *next_desc, *cur_desc; -+ struct prueth_emac *emac = netdev_priv(ndev); - struct netdev_queue *netif_txq; - struct prueth_tx_chn *tx_chn; - dma_addr_t desc_dma, buf_dma; -+ struct prueth_swdata *swdata; - int i, ret = 0, q_idx; - bool in_tx_ts = 0; -- void **swdata; -+ int tx_ts_cookie; - u32 pkt_len; - u32 *epib; -- int tx_ts_cookie; - - pkt_len = skb_headlen(skb); - q_idx = skb_get_queue_mapping(skb); -@@ -923,7 +937,8 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) - k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma); - cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len); - swdata = cppi5_hdesc_get_swdata(first_desc); -- *swdata = skb; -+ swdata->type = PRUETH_SWDATA_SKB; -+ swdata->data.skb = skb; - - if (!skb_is_nonlinear(skb)) - goto tx_push; -@@ -1023,15 +1038,16 @@ static void prueth_tx_cleanup(void *data, dma_addr_t desc_dma) - { - struct prueth_tx_chn *tx_chn = data; - struct cppi5_host_desc_t *desc_tx; -+ struct prueth_swdata *swdata; - struct sk_buff *skb; -- void **swdata; - - desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma); - swdata = cppi5_hdesc_get_swdata(desc_tx); -- skb = *(swdata); -+ skb = swdata->data.skb; - prueth_xmit_free(tx_chn, desc_tx); - -- dev_kfree_skb_any(skb); -+ if (swdata->type == PRUETH_SWDATA_SKB) -+ dev_kfree_skb_any(skb); - } - - static irqreturn_t prueth_tx_ts_irq(int irq, void *dev_id) -@@ -1057,8 +1073,8 @@ static struct page *prueth_process_rx_mgm(struct prueth_emac *emac, - struct net_device *ndev = emac->ndev; - struct cppi5_host_desc_t *desc_rx; - struct page *page, *new_page; -+ struct prueth_swdata *swdata; - dma_addr_t desc_dma; -- void **swdata; - int ret; - - ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma); -@@ -1080,7 +1096,7 @@ static struct page *prueth_process_rx_mgm(struct prueth_emac *emac, - } - - swdata = cppi5_hdesc_get_swdata(desc_rx); -- page = *swdata; -+ page = swdata->data.page; - - k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); - -@@ -1475,14 +1491,14 @@ static struct page_pool *prueth_create_page_pool(struct prueth_emac *emac, - static struct page *prueth_get_page_from_rx_chn(struct prueth_rx_chn *chn) - { - struct cppi5_host_desc_t *desc_rx; -+ struct prueth_swdata *swdata; - dma_addr_t desc_dma; - struct page *page; -- void **swdata; - - k3_udma_glue_pop_rx_chn(chn->rx_chn, 0, &desc_dma); - desc_rx = k3_cppi_desc_pool_dma2virt(chn->desc_pool, desc_dma); - swdata = cppi5_hdesc_get_swdata(desc_rx); -- page = *swdata; -+ page = swdata->data.page; - - return page; - } -@@ -2866,6 +2882,12 @@ static int prueth_probe(struct platform_device *pdev) - .align = SZ_64K, - }; - -+ if (sizeof(struct prueth_swdata) > PRUETH_NAV_SW_DATA_SIZE) { -+ dev_err(dev, "insufficient SW_DATA size: %d vs %ld\n", -+ PRUETH_NAV_SW_DATA_SIZE, sizeof(struct prueth_swdata)); -+ return -ENOMEM; -+ } -+ - match = of_match_device(prueth_dt_match, dev); - if (!match) - return -ENODEV; -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 6fc39e27a74b..eddeee7f0b5e 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -124,6 +124,24 @@ struct prueth_devlink { - struct prueth *prueth; - }; - -+enum prueth_swdata_type { -+ PRUETH_SWDATA_INVALID = 0, -+ PRUETH_SWDATA_SKB, -+ PRUETH_SWDATA_PAGE, -+ PRUETH_SWDATA_CMD, -+}; -+ -+union prueth_data { -+ struct sk_buff *skb; -+ struct page *page; -+ u32 cmd; -+}; -+ -+struct prueth_swdata { -+ union prueth_data data; -+ enum prueth_swdata_type type; -+}; -+ - /* There are 4 Tx DMA channels, but the highest priority is CH3 (thread 3) - * and lower three are lower priority channels or threads. - */ diff --git a/recipes-kernel/linux/files/patches-5.10/0203-net-ethernet-ti-icssg_prueth-Add-AF_XDP-support.patch b/recipes-kernel/linux/files/patches-5.10/0203-net-ethernet-ti-icssg_prueth-Add-AF_XDP-support.patch deleted file mode 100644 index f4f973c02..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0203-net-ethernet-ti-icssg_prueth-Add-AF_XDP-support.patch +++ /dev/null @@ -1,579 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Roger Quadros -Date: Thu, 19 Jan 2023 17:15:30 +0530 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: Add AF_XDP support - -Add native XDP support. We do not support zero copy yet. - -Signed-off-by: Roger Quadros -Signed-off-by: MD Danish Anwar -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_prueth.c | 347 +++++++++++++++++++++++-- - drivers/net/ethernet/ti/icssg_prueth.h | 15 ++ - 2 files changed, 347 insertions(+), 15 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 81bb71d436dd..49067c2919c1 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -125,11 +125,19 @@ static void prueth_xmit_free(struct prueth_tx_chn *tx_chn, - { - struct cppi5_host_desc_t *first_desc, *next_desc; - dma_addr_t buf_dma, next_desc_dma; -+ struct prueth_swdata *swdata; - u32 buf_dma_len; - - first_desc = desc; - next_desc = first_desc; - -+ swdata = cppi5_hdesc_get_swdata(desc); -+ if (swdata->type == PRUETH_SWDATA_PAGE) { -+ page_pool_recycle_direct(swdata->rx_chn->pg_pool, -+ swdata->data.page); -+ goto free_desc; -+ } -+ - cppi5_hdesc_get_obuf(first_desc, &buf_dma, &buf_dma_len); - k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &buf_dma); - -@@ -153,6 +161,7 @@ static void prueth_xmit_free(struct prueth_tx_chn *tx_chn, - k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc); - } - -+free_desc: - k3_cppi_desc_pool_free(tx_chn->desc_pool, first_desc); - } - -@@ -164,10 +173,11 @@ static int emac_tx_complete_packets(struct prueth_emac *emac, int chn, - struct netdev_queue *netif_txq; - struct prueth_tx_chn *tx_chn; - unsigned int total_bytes = 0; -+ struct prueth_swdata *swdata; -+ struct xdp_frame *xdpf; - struct sk_buff *skb; - dma_addr_t desc_dma; - int res, num_tx = 0; -- struct prueth_swdata *swdata; - - tx_chn = &emac->tx_chns[chn]; - -@@ -194,20 +204,29 @@ static int emac_tx_complete_packets(struct prueth_emac *emac, int chn, - continue; - } - -- if (swdata->type != PRUETH_SWDATA_SKB) { -+ switch (swdata->type) { -+ case PRUETH_SWDATA_SKB: -+ skb = swdata->data.skb; -+ ndev->stats.tx_bytes += skb->len; -+ ndev->stats.tx_packets++; -+ total_bytes += skb->len; -+ napi_consume_skb(skb, budget); -+ break; -+ case PRUETH_SWDATA_XDPF: -+ xdpf = swdata->data.xdpf; -+ ndev->stats.tx_bytes += xdpf->len; -+ ndev->stats.tx_packets++; -+ total_bytes += xdpf->len; -+ xdp_return_frame(xdpf); -+ break; -+ default: - netdev_err(ndev, "tx_complete: invalid swdata type %d\n", swdata->type); -+ prueth_xmit_free(tx_chn, desc_tx); - budget++; - continue; - } - -- skb = swdata->data.skb; - prueth_xmit_free(tx_chn, desc_tx); -- -- ndev = skb->dev; -- ndev->stats.tx_packets++; -- ndev->stats.tx_bytes += skb->len; -- total_bytes += skb->len; -- napi_consume_skb(skb, budget); - num_tx++; - } - -@@ -500,6 +519,7 @@ static int prueth_dma_rx_push_mapped(struct prueth_emac *emac, - swdata = cppi5_hdesc_get_swdata(desc_rx); - swdata->type = PRUETH_SWDATA_PAGE; - swdata->data.page = page; -+ swdata->rx_chn = rx_chn; - - return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, 0, - desc_rx, desc_dma); -@@ -548,7 +568,10 @@ static unsigned int prueth_rxbuf_total_len(unsigned int len) - return SKB_DATA_ALIGN(len); - } - --static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) -+static int emac_run_xdp(struct prueth_emac *emac, struct xdp_buff *xdp, -+ struct page *page); -+ -+static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id, int *xdp_state) - { - struct prueth_rx_chn *rx_chn = &emac->rx_chns; - u32 buf_dma_len, pkt_len, port_id = 0; -@@ -559,10 +582,12 @@ static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) - struct page *page, *new_page; - struct page_pool *pool; - struct sk_buff *skb; -+ struct xdp_buff xdp; - u32 *psdata; - void *pa; - int ret; - -+ *xdp_state = 0; - pool = rx_chn->pg_pool; - ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma); - if (ret) { -@@ -607,8 +632,24 @@ static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) - goto requeue; - } - -- /* prepare skb and send to n/w stack */ - pa = page_address(page); -+ if (emac->xdp_prog) { -+ /* xdp_init_buff(&xdp, PAGE_SIZE, rx_chn->xdp_rxq); */ -+ xdp.frame_sz = PAGE_SIZE; -+ xdp.rxq = &rx_chn->xdp_rxq; -+ -+ /* xdp_prepare_buff(&xdp, pa, PRUETH_HEADROOM, pkt_len, false); */ -+ xdp.data_hard_start = pa; -+ xdp.data = pa + PRUETH_HEADROOM; -+ xdp.data_end = xdp.data + pkt_len; -+ xdp.data_meta = xdp.data + 1; -+ -+ *xdp_state = emac_run_xdp(emac, &xdp, page); -+ if (*xdp_state != ICSSG_XDP_PASS) -+ goto requeue; -+ } -+ -+ /* prepare skb and send to n/w stack */ - skb = build_skb(pa, prueth_rxbuf_total_len(pkt_len)); - if (!skb) { - ndev->stats.rx_dropped++; -@@ -1039,15 +1080,26 @@ static void prueth_tx_cleanup(void *data, dma_addr_t desc_dma) - struct prueth_tx_chn *tx_chn = data; - struct cppi5_host_desc_t *desc_tx; - struct prueth_swdata *swdata; -+ struct xdp_frame *xdpf; - struct sk_buff *skb; - - desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma); - swdata = cppi5_hdesc_get_swdata(desc_tx); -- skb = swdata->data.skb; -- prueth_xmit_free(tx_chn, desc_tx); - -- if (swdata->type == PRUETH_SWDATA_SKB) -+ switch (swdata->type) { -+ case PRUETH_SWDATA_SKB: -+ skb = swdata->data.skb; - dev_kfree_skb_any(skb); -+ break; -+ case PRUETH_SWDATA_XDPF: -+ xdpf = swdata->data.xdpf; -+ xdp_return_frame(xdpf); -+ break; -+ default: -+ break; -+ } -+ -+ prueth_xmit_free(tx_chn, desc_tx); - } - - static irqreturn_t prueth_tx_ts_irq(int irq, void *dev_id) -@@ -1444,12 +1496,15 @@ static int emac_napi_rx_poll(struct napi_struct *napi_rx, int budget) - PRUETH_RX_FLOW_DATA_SR1 : PRUETH_RX_FLOW_DATA_SR2; - int cur_budget; - int ret; -+ int xdp_state; -+ int xdp_state_or = 0; - - while (flow--) { - cur_budget = budget - num_rx; - - while (cur_budget--) { -- ret = emac_rx_packet(emac, flow); -+ ret = emac_rx_packet(emac, flow, &xdp_state); -+ xdp_state_or |= xdp_state; - if (ret) - break; - num_rx++; -@@ -1459,6 +1514,9 @@ static int emac_napi_rx_poll(struct napi_struct *napi_rx, int budget) - break; - } - -+ if (xdp_state_or & ICSSG_XDP_REDIR) -+ xdp_do_flush(); -+ - if (num_rx < budget) { - napi_complete(napi_rx); - enable_irq(emac->rx_chns.irq[rx_flow]); -@@ -1744,6 +1802,33 @@ static int emac_phy_connect(struct prueth_emac *emac) - return 0; - } - -+static int prueth_create_xdp_rxqs(struct prueth_emac *emac) -+{ -+ struct xdp_rxq_info *rxq = &emac->rx_chns.xdp_rxq; -+ struct page_pool *pool = emac->rx_chns.pg_pool; -+ int ret; -+ -+ ret = xdp_rxq_info_reg(rxq, emac->ndev, 0); -+ if (ret) -+ return ret; -+ -+ ret = xdp_rxq_info_reg_mem_model(rxq, MEM_TYPE_PAGE_POOL, pool); -+ if (ret) -+ xdp_rxq_info_unreg(rxq); -+ -+ return ret; -+} -+ -+static void prueth_destroy_xdp_rxqs(struct prueth_emac *emac) -+{ -+ struct xdp_rxq_info *rxq = &emac->rx_chns.xdp_rxq; -+ -+ if (!xdp_rxq_info_is_reg(rxq)) -+ return; -+ -+ xdp_rxq_info_unreg(rxq); -+} -+ - /** - * emac_ndo_open - EMAC device open - * @ndev: network adapter device -@@ -1877,6 +1962,10 @@ static int emac_ndo_open(struct net_device *ndev) - - /* Prepare RX */ - ret = prueth_prepare_rx_chan(emac, &emac->rx_chns, PRUETH_MAX_PKT_SIZE); -+ if (ret) -+ goto destroy_xdp_rxqs; -+ -+ ret = prueth_create_xdp_rxqs(emac); - if (ret) - goto free_rx_ts_irq; - -@@ -1943,6 +2032,8 @@ static int emac_ndo_open(struct net_device *ndev) - PRUETH_MAX_RX_MGM_FLOWS, true); - reset_rx_chn: - prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, false); -+destroy_xdp_rxqs: -+ prueth_destroy_xdp_rxqs(emac); - free_rx_ts_irq: - if (!emac->is_sr1) - free_irq(emac->tx_ts_irq, emac); -@@ -2027,6 +2118,8 @@ static int emac_ndo_stop(struct net_device *ndev) - PRUETH_MAX_RX_MGM_FLOWS, true); - } - -+ prueth_destroy_xdp_rxqs(emac); -+ - napi_disable(&emac->napi_rx); - - if (!emac->is_sr1 && prueth->emacs_initialized == 1) -@@ -2246,6 +2339,228 @@ static struct devlink_port *emac_ndo_get_devlink_port(struct net_device *ndev) - return &emac->devlink_port; - } - -+/** -+ * emac_xmit_xdp_frame - transmits an XDP frame -+ * @emac: emac device -+ * @xdpf: data to transmit -+ * @page: page from page pool if already DMA mapped -+ * @q_idx: queue id -+ **/ -+static int emac_xmit_xdp_frame(struct prueth_emac *emac, -+ struct xdp_frame *xdpf, -+ struct page *page, -+ unsigned int q_idx) -+{ -+ struct cppi5_host_desc_t *first_desc; -+ struct net_device *ndev = emac->ndev; -+ struct prueth_tx_chn *tx_chn; -+ dma_addr_t desc_dma, buf_dma; -+ struct prueth_swdata *swdata; -+ u32 *epib; -+ int ret; -+ -+ void *data = xdpf->data; -+ u32 pkt_len = xdpf->len; -+ -+ if (q_idx >= PRUETH_MAX_TX_QUEUES) { -+ netdev_err(ndev, "xdp tx: invalid q_id %d\n", q_idx); -+ return ICSSG_XDP_CONSUMED; /* drop */ -+ } -+ -+ tx_chn = &emac->tx_chns[q_idx]; -+ -+ if (page) { /* already DMA mapped by page_pool */ -+ buf_dma = page_pool_get_dma_addr(page); -+ buf_dma += xdpf->headroom + sizeof(struct xdp_frame); -+ } else { /* Map the linear buffer */ -+ buf_dma = dma_map_single(tx_chn->dma_dev, data, pkt_len, DMA_TO_DEVICE); -+ if (dma_mapping_error(tx_chn->dma_dev, buf_dma)) { -+ netdev_err(ndev, "xdp tx: failed to map data buffer\n"); -+ return ICSSG_XDP_CONSUMED; /* drop */ -+ } -+ } -+ -+ first_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool); -+ if (!first_desc) { -+ netdev_dbg(ndev, "xdp tx: failed to allocate descriptor\n"); -+ if (!page) -+ dma_unmap_single(tx_chn->dma_dev, buf_dma, pkt_len, DMA_TO_DEVICE); -+ return ICSSG_XDP_CONSUMED; /* drop */ -+ } -+ -+ cppi5_hdesc_init(first_desc, CPPI5_INFO0_HDESC_EPIB_PRESENT, -+ PRUETH_NAV_PS_DATA_SIZE); -+ cppi5_hdesc_set_pkttype(first_desc, 0); -+ epib = first_desc->epib; -+ epib[0] = 0; -+ epib[1] = 0; -+ -+ /* set dst tag to indicate internal qid at the firmware which is at -+ * bit8..bit15. bit0..bit7 indicates port num for directed -+ * packets in case of switch mode operation -+ */ -+ cppi5_desc_set_tags_ids(&first_desc->hdr, 0, (emac->port_id | (q_idx << 8))); -+ k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma); -+ cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len); -+ swdata = cppi5_hdesc_get_swdata(first_desc); -+ if (page) { -+ swdata->type = PRUETH_SWDATA_PAGE; -+ swdata->data.page = page; -+ /* we assume page came from RX channel page pool */ -+ swdata->rx_chn = &emac->rx_chns; -+ } else { -+ swdata->type = PRUETH_SWDATA_XDPF; -+ swdata->data.xdpf = xdpf; -+ } -+ -+ cppi5_hdesc_set_pktlen(first_desc, pkt_len); -+ desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, first_desc); -+ -+ ret = k3_udma_glue_push_tx_chn(tx_chn->tx_chn, first_desc, desc_dma); -+ if (ret) { -+ netdev_err(ndev, "xdp tx: push failed: %d\n", ret); -+ goto drop_free_descs; -+ } -+ -+ return ICSSG_XDP_TX; -+ -+drop_free_descs: -+ prueth_xmit_free(tx_chn, first_desc); -+ return ICSSG_XDP_CONSUMED; -+} -+ -+/** -+ * emac_xdp_xmit - Implements ndo_xdp_xmit -+ * @dev: netdev -+ * @n: number of frames -+ * @frames: array of XDP buffer pointers -+ * @flags: XDP extra info -+ * -+ * Returns number of frames successfully sent. Failed frames -+ * will be free'ed by XDP core. -+ * -+ * For error cases, a negative errno code is returned and no-frames -+ * are transmitted (caller must handle freeing frames). -+ **/ -+static int emac_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames, -+ u32 flags) -+{ -+ struct prueth_emac *emac = netdev_priv(dev); -+ unsigned int q_idx; -+ int nxmit = 0; -+ int i; -+ -+ q_idx = smp_processor_id(); -+ -+ if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) -+ return -EINVAL; -+ -+ for (i = 0; i < n; i++) { -+ struct xdp_frame *xdpf = frames[i]; -+ int err; -+ -+ err = emac_xmit_xdp_frame(emac, xdpf, NULL, q_idx); -+ if (err != ICSSG_XDP_TX) -+ break; -+ nxmit++; -+ } -+ -+ return nxmit; -+} -+ -+/** -+ * emac_run_xdp - run an XDP program -+ * @emac: emac device -+ * @xdp: XDP buffer containing the frame -+ * @page: page with RX data if already DMA mapped -+ **/ -+static int emac_run_xdp(struct prueth_emac *emac, struct xdp_buff *xdp, -+ struct page *page) -+{ -+ int err, result = ICSSG_XDP_PASS; -+ struct bpf_prog *xdp_prog; -+ struct xdp_frame *xdpf; -+ u32 act; -+ int q_idx; -+ -+ xdp_prog = READ_ONCE(emac->xdp_prog); -+ -+ if (!xdp_prog) -+ return result; -+ -+ act = bpf_prog_run_xdp(xdp_prog, xdp); -+ switch (act) { -+ case XDP_PASS: -+ break; -+ case XDP_TX: -+ /* Send packet to TX ring for immediate transmission */ -+ xdpf = xdp_convert_buff_to_frame(xdp); -+ if (unlikely(!xdpf)) -+ goto drop; -+ -+ q_idx = smp_processor_id(); -+ result = emac_xmit_xdp_frame(emac, xdpf, page, q_idx); -+ if (result == ICSSG_XDP_CONSUMED) -+ goto drop; -+ break; -+ case XDP_REDIRECT: -+ err = xdp_do_redirect(emac->ndev, xdp, xdp_prog); -+ if (err) -+ goto drop; -+ result = ICSSG_XDP_REDIR; -+ break; -+ default: -+ bpf_warn_invalid_xdp_action(act); -+ fallthrough; -+ case XDP_ABORTED: -+drop: -+ trace_xdp_exception(emac->ndev, xdp_prog, act); -+ fallthrough; /* handle aborts by dropping packet */ -+ case XDP_DROP: -+ result = ICSSG_XDP_CONSUMED; -+ page_pool_recycle_direct(emac->rx_chns.pg_pool, page); -+ break; -+ } -+ -+ return result; -+} -+ -+/** -+ * emac_xdp_setup - add/remove an XDP program -+ * @emac: emac device -+ * @prog: XDP program -+ **/ -+static int emac_xdp_setup(struct prueth_emac *emac, struct netdev_bpf *bpf) -+{ -+ struct bpf_prog *prog = bpf->prog; -+ -+ if (!emac->xdpi.prog && !prog) -+ return 0; -+ -+ WRITE_ONCE(emac->xdp_prog, prog); -+ -+ xdp_attachment_setup(&emac->xdpi, bpf); -+ -+ return 0; -+} -+ -+/** -+ * emac_ndo_bpf - implements ndo_bpf for icssg_prueth -+ * @ndev: network adapter device -+ * @xdp: XDP command -+ **/ -+static int emac_ndo_bpf(struct net_device *ndev, struct netdev_bpf *bpf) -+{ -+ struct prueth_emac *emac = netdev_priv(ndev); -+ -+ switch (bpf->command) { -+ case XDP_SETUP_PROG: -+ return emac_xdp_setup(emac, bpf); -+ default: -+ return -EINVAL; -+ } -+} -+ - static const struct net_device_ops emac_netdev_ops = { - .ndo_open = emac_ndo_open, - .ndo_stop = emac_ndo_stop, -@@ -2257,6 +2572,8 @@ static const struct net_device_ops emac_netdev_ops = { - .ndo_do_ioctl = emac_ndo_ioctl, - .ndo_get_devlink_port = emac_ndo_get_devlink_port, - .ndo_setup_tc = icssg_qos_ndo_setup_tc, -+ .ndo_bpf = emac_ndo_bpf, -+ .ndo_xdp_xmit = emac_xdp_xmit, - }; - - /* get emac_port corresponding to eth_node name */ -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index eddeee7f0b5e..3e0e764a8d27 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -8,6 +8,8 @@ - #ifndef __NET_TI_ICSSG_PRUETH_H - #define __NET_TI_ICSSG_PRUETH_H - -+#include -+#include - #include - #include - #include -@@ -113,6 +115,7 @@ struct prueth_rx_chn { - unsigned int irq[ICSSG_MAX_RFLOWS]; /* separate irq per flow */ - char name[32]; - struct page_pool *pg_pool; -+ struct xdp_rxq_info xdp_rxq; - }; - - enum prueth_devlink_param_id { -@@ -129,16 +132,19 @@ enum prueth_swdata_type { - PRUETH_SWDATA_SKB, - PRUETH_SWDATA_PAGE, - PRUETH_SWDATA_CMD, -+ PRUETH_SWDATA_XDPF, - }; - - union prueth_data { - struct sk_buff *skb; - struct page *page; - u32 cmd; -+ struct xdp_frame *xdpf; - }; - - struct prueth_swdata { - union prueth_data data; -+ struct prueth_rx_chn *rx_chn; - enum prueth_swdata_type type; - }; - -@@ -149,6 +155,12 @@ struct prueth_swdata { - - #define PRUETH_MAX_TX_TS_REQUESTS 50 /* Max simultaneous TX_TS requests */ - -+/* XDP BPF state */ -+#define ICSSG_XDP_PASS 0 -+#define ICSSG_XDP_CONSUMED BIT(0) -+#define ICSSG_XDP_TX BIT(1) -+#define ICSSG_XDP_REDIR BIT(2) -+ - /* data for each emac port */ - struct prueth_emac { - bool is_sr1; -@@ -212,6 +224,9 @@ struct prueth_emac { - struct work_struct ts_work; - struct delayed_work stats_work; - u64 *stats; -+ -+ struct bpf_prog *xdp_prog; -+ struct xdp_attachment_info xdpi; - }; - - /* The buf includes headroom compatible with both skb and xdpf */ diff --git a/recipes-kernel/linux/files/patches-5.10/0204-tee-add-tee_shm_register_-user-kernel-_buf.patch b/recipes-kernel/linux/files/patches-5.10/0204-tee-add-tee_shm_register_-user-kernel-_buf.patch deleted file mode 100644 index 6d6d9afe4..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0204-tee-add-tee_shm_register_-user-kernel-_buf.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jens Wiklander -Date: Fri, 4 Feb 2022 10:33:56 +0100 -Subject: [PATCH] tee: add tee_shm_register_{user,kernel}_buf() - -Adds the two new functions tee_shm_register_user_buf() and -tee_shm_register_kernel_buf() which should be used instead of the old -tee_shm_register(). - -This avoids having the caller supplying the flags parameter which -exposes a bit more than desired of the internals of the TEE subsystem. - -Reviewed-by: Sumit Garg -Signed-off-by: Jens Wiklander ---- - drivers/tee/tee_core.c | 3 +-- - drivers/tee/tee_private.h | 2 ++ - drivers/tee/tee_shm.c | 33 +++++++++++++++++++++++++++++++++ - include/linux/tee_drv.h | 3 +++ - 4 files changed, 39 insertions(+), 2 deletions(-) - -diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c -index 9cc4a7b63b0d..3aac8a705412 100644 ---- a/drivers/tee/tee_core.c -+++ b/drivers/tee/tee_core.c -@@ -337,8 +337,7 @@ tee_ioctl_shm_register(struct tee_context *ctx, - if (!access_ok((void __user *)(unsigned long)data.addr, data.length)) - return -EFAULT; - -- shm = tee_shm_register(ctx, data.addr, data.length, -- TEE_SHM_DMA_BUF | TEE_SHM_USER_MAPPED); -+ shm = tee_shm_register_user_buf(ctx, data.addr, data.length); - if (IS_ERR(shm)) - return PTR_ERR(shm); - -diff --git a/drivers/tee/tee_private.h b/drivers/tee/tee_private.h -index e55204df31ce..c88ea9d48de7 100644 ---- a/drivers/tee/tee_private.h -+++ b/drivers/tee/tee_private.h -@@ -67,5 +67,7 @@ void tee_device_put(struct tee_device *teedev); - - void teedev_ctx_get(struct tee_context *ctx); - void teedev_ctx_put(struct tee_context *ctx); -+struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx, -+ unsigned long addr, size_t length); - - #endif /*TEE_PRIVATE_H*/ -diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c -index 6fb4400333fb..be9c8f22c0f8 100644 ---- a/drivers/tee/tee_shm.c -+++ b/drivers/tee/tee_shm.c -@@ -256,6 +256,39 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, - } - EXPORT_SYMBOL_GPL(tee_shm_register); - -+/** -+ * tee_shm_register_user_buf() - Register a userspace shared memory buffer -+ * @ctx: Context that registers the shared memory -+ * @addr: The userspace address of the shared buffer -+ * @length: Length of the shared buffer -+ * -+ * @returns a pointer to 'struct tee_shm' -+ */ -+struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx, -+ unsigned long addr, size_t length) -+{ -+ return tee_shm_register(ctx, addr, length, -+ TEE_SHM_DMA_BUF | TEE_SHM_USER_MAPPED); -+} -+ -+/** -+ * tee_shm_register_kernel_buf() - Register kernel memory to be shared with -+ * secure world -+ * @ctx: Context that registers the shared memory -+ * @addr: The buffer -+ * @length: Length of the buffer -+ * -+ * @returns a pointer to 'struct tee_shm' -+ */ -+ -+struct tee_shm *tee_shm_register_kernel_buf(struct tee_context *ctx, -+ void *addr, size_t length) -+{ -+ return tee_shm_register(ctx, (unsigned long)addr, length, -+ TEE_SHM_DMA_BUF | TEE_SHM_KERNEL_MAPPED); -+} -+EXPORT_SYMBOL_GPL(tee_shm_register_kernel_buf); -+ - static int tee_shm_fop_release(struct inode *inode, struct file *filp) - { - tee_shm_put(filp->private_data); -diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h -index 18a9949bba18..5bbbe0ab25e8 100644 ---- a/include/linux/tee_drv.h -+++ b/include/linux/tee_drv.h -@@ -347,6 +347,9 @@ struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size); - struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, - size_t length, u32 flags); - -+struct tee_shm *tee_shm_register_kernel_buf(struct tee_context *ctx, -+ void *addr, size_t length); -+ - /** - * tee_shm_is_registered() - Check if shared memory object in registered in TEE - * @shm: Shared memory handle diff --git a/recipes-kernel/linux/files/patches-5.10/0208-pinctrl-pinmux-add-function-selector-to-pinmux-funct.patch b/recipes-kernel/linux/files/patches-5.10/0208-pinctrl-pinmux-add-function-selector-to-pinmux-funct.patch deleted file mode 100644 index e72eeb964..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0208-pinctrl-pinmux-add-function-selector-to-pinmux-funct.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Drew Fustini -Date: Sat, 23 Jan 2021 12:22:14 -0800 -Subject: [PATCH] pinctrl: pinmux: add function selector to pinmux-functions - -Add the function selector to the pinmux-functions debugfs output. This -is an integer which is the index into the pinmux function tree. It will -make it easier to correlate function name to function selector without -having to count the lines in the output. - -Example output of "pinmux-functions": - -function 0: pinmux-uart0-pins, groups = [ pinmux-uart0-pins ] -function 1: pinmux-uart1-pins, groups = [ pinmux-uart1-pins ] -function 2: pinmux-uart2-pins, groups = [ pinmux-uart2-pins ] -function 3: pinmux-mmc0-pins, groups = [ pinmux-mmc0-pins ] -function 3: pinmux-mmc1-pins, groups = [ pinmux-mmc1-pins ] -function 5: pinmux-i2c0-pins, groups = [ pinmux-i2c0-pins ] -function 6: pinmux-i2c1-pins, groups = [ pinmux-i2c1-pins ] -function 7: pinmux-i2c2-pins, groups = [ pinmux-i2c2-pins ] -function 8: pinmux-pwm0-pins, groups = [ pinmux-pwm0-pins ] -function 9: pinmux-pwm1-pins, groups = [ pinmux-pwm1-pins ] -function 10: pinmux-adc-pins, groups = [ pinmux-adc-pins ] - -Cc: Jason Kridner -Cc: Robert Nelson -Cc: Linus Walleij -Cc: Tony Lindgren -Cc: Andy Shevchenko -Cc: Alexandre Belloni -Signed-off-by: Drew Fustini -Link: https://lore.kernel.org/r/20210123202212.528046-1-drew@beagleboard.org -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/pinmux.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c -index bab888fe3f8e..36a11c9e893a 100644 ---- a/drivers/pinctrl/pinmux.c -+++ b/drivers/pinctrl/pinmux.c -@@ -564,7 +564,7 @@ static int pinmux_functions_show(struct seq_file *s, void *what) - continue; - } - -- seq_printf(s, "function: %s, groups = [ ", func); -+ seq_printf(s, "function %d: %s, groups = [ ", func_selector, func); - for (i = 0; i < num_groups; i++) - seq_printf(s, "%s ", groups[i]); - seq_puts(s, "]\n"); diff --git a/recipes-kernel/linux/files/patches-5.10/0209-pinctrl-single-set-function-name-when-adding-functio.patch b/recipes-kernel/linux/files/patches-5.10/0209-pinctrl-single-set-function-name-when-adding-functio.patch deleted file mode 100644 index 0d5a7982e..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0209-pinctrl-single-set-function-name-when-adding-functio.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Drew Fustini -Date: Mon, 25 Jan 2021 12:35:43 -0800 -Subject: [PATCH] pinctrl: single: set function name when adding function - -pcs_add_function() fails to set the function name in struct pcs_function -when adding a new function. As a result this line in pcs_set_mux(): - - dev_dbg(pcs->dev, "enabling %s function%i\n", - func->name, fselector); - -prints "(null)" for the function: - -pinctrl-single 44e10800.pinmux: enabling (null) function0 -pinctrl-single 44e10800.pinmux: enabling (null) function1 -pinctrl-single 44e10800.pinmux: enabling (null) function2 -pinctrl-single 44e10800.pinmux: enabling (null) function3 - -With this fix, the output is now: - -pinctrl-single 44e10800.pinmux: enabling pinmux-uart0-pins function0 -pinctrl-single 44e10800.pinmux: enabling pinmux-mmc0-pins function1 -pinctrl-single 44e10800.pinmux: enabling pinmux-i2c0-pins function2 -pinctrl-single 44e10800.pinmux: enabling pinmux-mmc0-pins function3 - -Cc: Jason Kridner -Cc: Robert Nelson -Cc: Linus Walleij -Cc: Tony Lindgren -Signed-off-by: Drew Fustini -Acked-by: Tony Lindgren -Link: https://lore.kernel.org/r/20210125203542.51513-1-drew@beagleboard.org -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/pinctrl-single.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c -index 22e471933b37..56eaf3ed076b 100644 ---- a/drivers/pinctrl/pinctrl-single.c -+++ b/drivers/pinctrl/pinctrl-single.c -@@ -790,6 +790,7 @@ static int pcs_add_function(struct pcs_device *pcs, - - function->vals = vals; - function->nvals = nvals; -+ function->name = name; - - selector = pinmux_generic_add_function(pcs->pctl, name, - pgnames, npgnames, diff --git a/recipes-kernel/linux/files/patches-5.10/0210-pinctrl-use-to-octal-permissions-for-debugfs-files.patch b/recipes-kernel/linux/files/patches-5.10/0210-pinctrl-use-to-octal-permissions-for-debugfs-files.patch deleted file mode 100644 index 47397d273..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0210-pinctrl-use-to-octal-permissions-for-debugfs-files.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Drew Fustini -Date: Mon, 1 Mar 2021 21:30:56 -0800 -Subject: [PATCH] pinctrl: use to octal permissions for debugfs files - -Switch over pinctrl debugfs files to use octal permissions as they are -preferred over symbolic permissions. Refer to commit f90774e1fd27 -("checkpatch: look for symbolic permissions and suggest octal instead"). - -Note: S_IFREG flag is added to the mode by __debugfs_create_file() -in fs/debugfs/inode.c - -Suggested-by: Joe Perches -Suggested-by: Andy Shevchenko -Reviewed-by: Andy Shevchenko -Reviewed-by: Geert Uytterhoeven -Reviewed-by: Tony Lindgren -Signed-off-by: Drew Fustini -Link: https://lore.kernel.org/r/20210302053059.1049035-2-drew@beagleboard.org -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/core.c | 12 ++++++------ - drivers/pinctrl/pinconf.c | 4 ++-- - drivers/pinctrl/pinmux.c | 4 ++-- - 3 files changed, 10 insertions(+), 10 deletions(-) - -diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c -index 840000870d5a..aa5a1178c8eb 100644 ---- a/drivers/pinctrl/core.c -+++ b/drivers/pinctrl/core.c -@@ -1892,11 +1892,11 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) - dev_name(pctldev->dev)); - return; - } -- debugfs_create_file("pins", S_IFREG | S_IRUGO, -+ debugfs_create_file("pins", 0444, - device_root, pctldev, &pinctrl_pins_fops); -- debugfs_create_file("pingroups", S_IFREG | S_IRUGO, -+ debugfs_create_file("pingroups", 0444, - device_root, pctldev, &pinctrl_groups_fops); -- debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO, -+ debugfs_create_file("gpio-ranges", 0444, - device_root, pctldev, &pinctrl_gpioranges_fops); - if (pctldev->desc->pmxops) - pinmux_init_device_debugfs(device_root, pctldev); -@@ -1918,11 +1918,11 @@ static void pinctrl_init_debugfs(void) - return; - } - -- debugfs_create_file("pinctrl-devices", S_IFREG | S_IRUGO, -+ debugfs_create_file("pinctrl-devices", 0444, - debugfs_root, NULL, &pinctrl_devices_fops); -- debugfs_create_file("pinctrl-maps", S_IFREG | S_IRUGO, -+ debugfs_create_file("pinctrl-maps", 0444, - debugfs_root, NULL, &pinctrl_maps_fops); -- debugfs_create_file("pinctrl-handles", S_IFREG | S_IRUGO, -+ debugfs_create_file("pinctrl-handles", 0444, - debugfs_root, NULL, &pinctrl_fops); - } - -diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c -index 02c075cc010b..d9d54065472e 100644 ---- a/drivers/pinctrl/pinconf.c -+++ b/drivers/pinctrl/pinconf.c -@@ -370,9 +370,9 @@ DEFINE_SHOW_ATTRIBUTE(pinconf_groups); - void pinconf_init_device_debugfs(struct dentry *devroot, - struct pinctrl_dev *pctldev) - { -- debugfs_create_file("pinconf-pins", S_IFREG | S_IRUGO, -+ debugfs_create_file("pinconf-pins", 0444, - devroot, pctldev, &pinconf_pins_fops); -- debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO, -+ debugfs_create_file("pinconf-groups", 0444, - devroot, pctldev, &pinconf_groups_fops); - } - -diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c -index 36a11c9e893a..9c0174520e78 100644 ---- a/drivers/pinctrl/pinmux.c -+++ b/drivers/pinctrl/pinmux.c -@@ -676,9 +676,9 @@ DEFINE_SHOW_ATTRIBUTE(pinmux_pins); - void pinmux_init_device_debugfs(struct dentry *devroot, - struct pinctrl_dev *pctldev) - { -- debugfs_create_file("pinmux-functions", S_IFREG | S_IRUGO, -+ debugfs_create_file("pinmux-functions", 0444, - devroot, pctldev, &pinmux_functions_fops); -- debugfs_create_file("pinmux-pins", S_IFREG | S_IRUGO, -+ debugfs_create_file("pinmux-pins", 0444, - devroot, pctldev, &pinmux_pins_fops); - } - diff --git a/recipes-kernel/linux/files/patches-5.10/0211-pinctrl-pinmux-Add-pinmux-select-debugfs-file.patch b/recipes-kernel/linux/files/patches-5.10/0211-pinctrl-pinmux-Add-pinmux-select-debugfs-file.patch deleted file mode 100644 index 9aca8dd24..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0211-pinctrl-pinmux-Add-pinmux-select-debugfs-file.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Drew Fustini -Date: Mon, 1 Mar 2021 21:30:57 -0800 -Subject: [PATCH] pinctrl: pinmux: Add pinmux-select debugfs file - -Add "pinmux-select" to debugfs which will activate a pin function for a -given pin group: - - echo "" > pinmux-select - -The write operation pinmux_select() handles this by checking that the -names map to valid selectors and then calling ops->set_mux(). - -The existing "pinmux-functions" debugfs file lists the pin functions -registered for the pin controller. For example: - - function: pinmux-uart0, groups = [ pinmux-uart0-pins ] - function: pinmux-mmc0, groups = [ pinmux-mmc0-pins ] - function: pinmux-mmc1, groups = [ pinmux-mmc1-pins ] - function: pinmux-i2c0, groups = [ pinmux-i2c0-pins ] - function: pinmux-i2c1, groups = [ pinmux-i2c1-pins ] - function: pinmux-spi1, groups = [ pinmux-spi1-pins ] - -To activate function pinmux-i2c1 on group pinmux-i2c1-pins: - - echo "pinmux-i2c1-pins pinmux-i2c1" > pinmux-select - -Reviewed-by: Andy Shevchenko -Reviewed-by: Tony Lindgren -Reviewed-by: Geert Uytterhoeven -Tested-by: Geert Uytterhoeven -Signed-off-by: Drew Fustini -Link: https://lore.kernel.org/r/20210302053059.1049035-3-drew@beagleboard.org -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/pinmux.c | 102 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 102 insertions(+) - -diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c -index 9c0174520e78..6cdbd9ccf2f0 100644 ---- a/drivers/pinctrl/pinmux.c -+++ b/drivers/pinctrl/pinmux.c -@@ -12,6 +12,7 @@ - */ - #define pr_fmt(fmt) "pinmux core: " fmt - -+#include - #include - #include - #include -@@ -673,6 +674,105 @@ void pinmux_show_setting(struct seq_file *s, - DEFINE_SHOW_ATTRIBUTE(pinmux_functions); - DEFINE_SHOW_ATTRIBUTE(pinmux_pins); - -+#define PINMUX_SELECT_MAX 128 -+static ssize_t pinmux_select(struct file *file, const char __user *user_buf, -+ size_t len, loff_t *ppos) -+{ -+ struct seq_file *sfile = file->private_data; -+ struct pinctrl_dev *pctldev = sfile->private; -+ const struct pinmux_ops *pmxops = pctldev->desc->pmxops; -+ const char *const *groups; -+ char *buf, *gname, *fname; -+ unsigned int num_groups; -+ int fsel, gsel, ret; -+ -+ if (len > PINMUX_SELECT_MAX) -+ return -ENOMEM; -+ -+ buf = kzalloc(PINMUX_SELECT_MAX, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ ret = strncpy_from_user(buf, user_buf, PINMUX_SELECT_MAX); -+ if (ret < 0) -+ goto exit_free_buf; -+ buf[len-1] = '\0'; -+ -+ /* remove leading and trailing spaces of input buffer */ -+ gname = strstrip(buf); -+ if (*gname == '\0') { -+ ret = -EINVAL; -+ goto exit_free_buf; -+ } -+ -+ /* find a separator which is a spacelike character */ -+ for (fname = gname; !isspace(*fname); fname++) { -+ if (*fname == '\0') { -+ ret = -EINVAL; -+ goto exit_free_buf; -+ } -+ } -+ *fname = '\0'; -+ -+ /* drop extra spaces between function and group names */ -+ fname = skip_spaces(fname + 1); -+ if (*fname == '\0') { -+ ret = -EINVAL; -+ goto exit_free_buf; -+ } -+ -+ ret = pinmux_func_name_to_selector(pctldev, fname); -+ if (ret < 0) { -+ dev_err(pctldev->dev, "invalid function %s in map table\n", fname); -+ goto exit_free_buf; -+ } -+ fsel = ret; -+ -+ ret = pmxops->get_function_groups(pctldev, fsel, &groups, &num_groups); -+ if (ret) { -+ dev_err(pctldev->dev, "no groups for function %d (%s)", fsel, fname); -+ goto exit_free_buf; -+ } -+ -+ ret = match_string(groups, num_groups, gname); -+ if (ret < 0) { -+ dev_err(pctldev->dev, "invalid group %s", gname); -+ goto exit_free_buf; -+ } -+ -+ ret = pinctrl_get_group_selector(pctldev, gname); -+ if (ret < 0) { -+ dev_err(pctldev->dev, "failed to get group selector for %s", gname); -+ goto exit_free_buf; -+ } -+ gsel = ret; -+ -+ ret = pmxops->set_mux(pctldev, fsel, gsel); -+ if (ret) { -+ dev_err(pctldev->dev, "set_mux() failed: %d", ret); -+ goto exit_free_buf; -+ } -+ ret = len; -+ -+exit_free_buf: -+ kfree(buf); -+ -+ return ret; -+} -+ -+static int pinmux_select_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, NULL, inode->i_private); -+} -+ -+static const struct file_operations pinmux_select_ops = { -+ .owner = THIS_MODULE, -+ .open = pinmux_select_open, -+ .write = pinmux_select, -+ .llseek = no_llseek, -+ .release = single_release, -+}; -+ - void pinmux_init_device_debugfs(struct dentry *devroot, - struct pinctrl_dev *pctldev) - { -@@ -680,6 +780,8 @@ void pinmux_init_device_debugfs(struct dentry *devroot, - devroot, pctldev, &pinmux_functions_fops); - debugfs_create_file("pinmux-pins", 0444, - devroot, pctldev, &pinmux_pins_fops); -+ debugfs_create_file("pinmux-select", 0200, -+ devroot, pctldev, &pinmux_select_ops); - } - - #endif /* CONFIG_DEBUG_FS */ diff --git a/recipes-kernel/linux/files/patches-5.10/0212-pinctrl-core-Handling-pinmux-and-pinconf-separately.patch b/recipes-kernel/linux/files/patches-5.10/0212-pinctrl-core-Handling-pinmux-and-pinconf-separately.patch deleted file mode 100644 index 2bf6e86c0..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0212-pinctrl-core-Handling-pinmux-and-pinconf-separately.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michal Simek -Date: Wed, 10 Mar 2021 09:16:54 +0100 -Subject: [PATCH] pinctrl: core: Handling pinmux and pinconf separately - -Right now the handling order depends on how entries are coming which is -corresponding with order in DT. We have reached the case with DT overlays -where conf and mux descriptions are exchanged which ends up in sequence -that firmware has been asked to perform configuration before requesting the -pin. - -The patch is enforcing the order that pin is requested all the time first -followed by pin configuration. This change will ensure that firmware gets -requests in the right order. - -Signed-off-by: Michal Simek -Link: https://lore.kernel.org/r/cfbe01f791c2dd42a596cbda57e15599969b57aa.1615364211.git.michal.simek@xilinx.com -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/core.c | 23 ++++++++++++++++++++++- - 1 file changed, 22 insertions(+), 1 deletion(-) - -diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c -index aa5a1178c8eb..011e461a766a 100644 ---- a/drivers/pinctrl/core.c -+++ b/drivers/pinctrl/core.c -@@ -1258,13 +1258,34 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state) - - p->state = NULL; - -- /* Apply all the settings for the new state */ -+ /* Apply all the settings for the new state - pinmux first */ - list_for_each_entry(setting, &state->settings, node) { - switch (setting->type) { - case PIN_MAP_TYPE_MUX_GROUP: - ret = pinmux_enable_setting(setting); - break; - case PIN_MAP_TYPE_CONFIGS_PIN: -+ case PIN_MAP_TYPE_CONFIGS_GROUP: -+ break; -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (ret < 0) -+ goto unapply_new_state; -+ -+ /* Do not link hogs (circular dependency) */ -+ if (p != setting->pctldev->p) -+ pinctrl_link_add(setting->pctldev, p->dev); -+ } -+ -+ /* Apply all the settings for the new state - pinconf after */ -+ list_for_each_entry(setting, &state->settings, node) { -+ switch (setting->type) { -+ case PIN_MAP_TYPE_MUX_GROUP: -+ break; -+ case PIN_MAP_TYPE_CONFIGS_PIN: - case PIN_MAP_TYPE_CONFIGS_GROUP: - ret = pinconf_apply_setting(setting); - break; diff --git a/recipes-kernel/linux/files/patches-5.10/0213-pinctrl-core-Set-ret-to-0-when-group-is-skipped.patch b/recipes-kernel/linux/files/patches-5.10/0213-pinctrl-core-Set-ret-to-0-when-group-is-skipped.patch deleted file mode 100644 index c343cc088..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0213-pinctrl-core-Set-ret-to-0-when-group-is-skipped.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michal Simek -Date: Fri, 12 Mar 2021 08:31:34 +0100 -Subject: [PATCH] pinctrl: core: Set ret to 0 when group is skipped - -Static analyzer tool found that the ret variable is not initialized but -code expects ret value >=0 when pinconf is skipped in the first pinmux -loop. The same expectation is for pinmux in a pinconf loop. -That's why initialize ret to 0 to avoid uninitialized ret value in first -loop or reusing ret value from first loop in second. - -Addresses-Coverity: ("Uninitialized variables") -Signed-off-by: Michal Simek -Cc: Dan Carpenter -Reviewed-by: Colin Ian King -Link: https://lore.kernel.org/r/e5203bae68eb94b4b8b4e67e5e7b4d86bb989724.1615534291.git.michal.simek@xilinx.com -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/core.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c -index 011e461a766a..af9a3f967c99 100644 ---- a/drivers/pinctrl/core.c -+++ b/drivers/pinctrl/core.c -@@ -1266,6 +1266,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state) - break; - case PIN_MAP_TYPE_CONFIGS_PIN: - case PIN_MAP_TYPE_CONFIGS_GROUP: -+ ret = 0; - break; - default: - ret = -EINVAL; -@@ -1284,6 +1285,7 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state) - list_for_each_entry(setting, &state->settings, node) { - switch (setting->type) { - case PIN_MAP_TYPE_MUX_GROUP: -+ ret = 0; - break; - case PIN_MAP_TYPE_CONFIGS_PIN: - case PIN_MAP_TYPE_CONFIGS_GROUP: diff --git a/recipes-kernel/linux/files/patches-5.10/0214-pinctrl-pinctrl-single-remove-unused-variable.patch b/recipes-kernel/linux/files/patches-5.10/0214-pinctrl-pinctrl-single-remove-unused-variable.patch deleted file mode 100644 index 710652352..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0214-pinctrl-pinctrl-single-remove-unused-variable.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hanna Hawa -Date: Fri, 19 Mar 2021 17:21:31 +0200 -Subject: [PATCH] pinctrl: pinctrl-single: remove unused variable - -Remove unused parameter 'num_pins_in_register' from -pcs_allocate_pin_table(). - -Reported-by: kernel test robot -Signed-off-by: Hanna Hawa -Reviewed-by: Tony Lindgren -Reviewed-by: Drew Fustini -Link: https://lore.kernel.org/r/20210319152133.28705-2-hhhawa@amazon.com -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/pinctrl-single.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c -index 56eaf3ed076b..d7dd4c4ce642 100644 ---- a/drivers/pinctrl/pinctrl-single.c -+++ b/drivers/pinctrl/pinctrl-single.c -@@ -724,14 +724,12 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned int offset) - static int pcs_allocate_pin_table(struct pcs_device *pcs) - { - int mux_bytes, nr_pins, i; -- int num_pins_in_register = 0; - - mux_bytes = pcs->width / BITS_PER_BYTE; - - if (pcs->bits_per_mux && pcs->fmask) { - pcs->bits_per_pin = fls(pcs->fmask); - nr_pins = (pcs->size * BITS_PER_BYTE) / pcs->bits_per_pin; -- num_pins_in_register = pcs->width / pcs->bits_per_pin; - } else { - nr_pins = pcs->size / mux_bytes; - } diff --git a/recipes-kernel/linux/files/patches-5.10/0215-pinctrl-core-Fix-kernel-doc-string-for-pin_get_name.patch b/recipes-kernel/linux/files/patches-5.10/0215-pinctrl-core-Fix-kernel-doc-string-for-pin_get_name.patch deleted file mode 100644 index fa8002fed..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0215-pinctrl-core-Fix-kernel-doc-string-for-pin_get_name.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Andy Shevchenko -Date: Thu, 15 Apr 2021 15:35:21 +0300 -Subject: [PATCH] pinctrl: core: Fix kernel doc string for pin_get_name() - -The kernel doc string mistakenly advertises the pin_get_name_from_id(). -Fix it, otherwise kernel doc validator is not happy: - -.../core.c:168: warning: expecting prototype for pin_get_name_from_id(). Prototype was for pin_get_name() instead - -Fixes: dcb5dbc305b9 ("pinctrl: show pin name for pingroups in sysfs") -Cc: Dong Aisheng -Signed-off-by: Andy Shevchenko -Link: https://lore.kernel.org/r/20210415123521.86894-1-andriy.shevchenko@linux.intel.com -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c -index af9a3f967c99..81dbb1723ff2 100644 ---- a/drivers/pinctrl/core.c -+++ b/drivers/pinctrl/core.c -@@ -160,7 +160,7 @@ int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name) - } - - /** -- * pin_get_name_from_id() - look up a pin name from a pin id -+ * pin_get_name() - look up a pin name from a pin id - * @pctldev: the pin control device to lookup the pin on - * @pin: pin number/id to look up - */ diff --git a/recipes-kernel/linux/files/patches-5.10/0216-pinctrl-Introduce-MODE-group-in-enum-pin_config_para.patch b/recipes-kernel/linux/files/patches-5.10/0216-pinctrl-Introduce-MODE-group-in-enum-pin_config_para.patch deleted file mode 100644 index 5b1910d10..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0216-pinctrl-Introduce-MODE-group-in-enum-pin_config_para.patch +++ /dev/null @@ -1,187 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Andy Shevchenko -Date: Mon, 12 Apr 2021 17:07:40 +0300 -Subject: [PATCH] pinctrl: Introduce MODE group in enum pin_config_param - -Better to have a MODE group of settings to keep them together -when ordered alphabetically. Hence, rename PIN_CONFIG_LOW_POWER_MODE -to PIN_CONFIG_MODE_LOW_POWER. - -Signed-off-by: Andy Shevchenko -Link: https://lore.kernel.org/r/20210412140741.39946-2-andriy.shevchenko@linux.intel.com -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/pinconf-generic.c | 6 +++--- - drivers/pinctrl/pinctrl-lpc18xx.c | 4 ++-- - drivers/pinctrl/pinctrl-single.c | 6 +++--- - drivers/pinctrl/pinctrl-zynq.c | 4 ++-- - drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 4 ++-- - drivers/soc/tegra/pmc.c | 4 ++-- - include/linux/pinctrl/pinconf-generic.h | 4 ++-- - 7 files changed, 16 insertions(+), 16 deletions(-) - -diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c -index 7bfc395ae0a3..365c4b0ca465 100644 ---- a/drivers/pinctrl/pinconf-generic.c -+++ b/drivers/pinctrl/pinconf-generic.c -@@ -43,7 +43,7 @@ static const struct pin_config_item conf_items[] = { - PCONFDUMP(PIN_CONFIG_INPUT_ENABLE, "input enabled", NULL, false), - PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL, false), - PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL, false), -- PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode", true), -+ PCONFDUMP(PIN_CONFIG_MODE_LOW_POWER, "pin low power", "mode", true), - PCONFDUMP(PIN_CONFIG_OUTPUT_ENABLE, "output enabled", NULL, false), - PCONFDUMP(PIN_CONFIG_OUTPUT, "pin output", "level", true), - PCONFDUMP(PIN_CONFIG_OUTPUT_IMPEDANCE_OHMS, "output impedance", "ohms", true), -@@ -175,8 +175,8 @@ static const struct pinconf_generic_params dt_params[] = { - { "input-schmitt", PIN_CONFIG_INPUT_SCHMITT, 0 }, - { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, - { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, -- { "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 }, -- { "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 }, -+ { "low-power-disable", PIN_CONFIG_MODE_LOW_POWER, 0 }, -+ { "low-power-enable", PIN_CONFIG_MODE_LOW_POWER, 1 }, - { "output-disable", PIN_CONFIG_OUTPUT_ENABLE, 0 }, - { "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 }, - { "output-high", PIN_CONFIG_OUTPUT, 1, }, -diff --git a/drivers/pinctrl/pinctrl-lpc18xx.c b/drivers/pinctrl/pinctrl-lpc18xx.c -index 7b2f885e68bd..ed9bf2c89998 100644 ---- a/drivers/pinctrl/pinctrl-lpc18xx.c -+++ b/drivers/pinctrl/pinctrl-lpc18xx.c -@@ -646,7 +646,7 @@ static const struct pin_config_item lpc18xx_conf_items[ARRAY_SIZE(lpc18xx_params - static int lpc18xx_pconf_get_usb1(enum pin_config_param param, int *arg, u32 reg) - { - switch (param) { -- case PIN_CONFIG_LOW_POWER_MODE: -+ case PIN_CONFIG_MODE_LOW_POWER: - if (reg & LPC18XX_SCU_USB1_EPWR) - *arg = 0; - else -@@ -904,7 +904,7 @@ static int lpc18xx_pconf_set_usb1(struct pinctrl_dev *pctldev, - u32 param_val, u32 *reg) - { - switch (param) { -- case PIN_CONFIG_LOW_POWER_MODE: -+ case PIN_CONFIG_MODE_LOW_POWER: - if (param_val) - *reg &= ~LPC18XX_SCU_USB1_EPWR; - else -diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c -index d7dd4c4ce642..e56d10917645 100644 ---- a/drivers/pinctrl/pinctrl-single.c -+++ b/drivers/pinctrl/pinctrl-single.c -@@ -535,7 +535,7 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev, - break; - case PIN_CONFIG_DRIVE_STRENGTH: - case PIN_CONFIG_SLEW_RATE: -- case PIN_CONFIG_LOW_POWER_MODE: -+ case PIN_CONFIG_MODE_LOW_POWER: - default: - *config = data; - break; -@@ -573,7 +573,7 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, - case PIN_CONFIG_INPUT_SCHMITT: - case PIN_CONFIG_DRIVE_STRENGTH: - case PIN_CONFIG_SLEW_RATE: -- case PIN_CONFIG_LOW_POWER_MODE: -+ case PIN_CONFIG_MODE_LOW_POWER: - shift = ffs(func->conf[i].mask) - 1; - data &= ~func->conf[i].mask; - data |= (arg << shift) & func->conf[i].mask; -@@ -921,7 +921,7 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np, - { "pinctrl-single,drive-strength", PIN_CONFIG_DRIVE_STRENGTH, }, - { "pinctrl-single,slew-rate", PIN_CONFIG_SLEW_RATE, }, - { "pinctrl-single,input-schmitt", PIN_CONFIG_INPUT_SCHMITT, }, -- { "pinctrl-single,low-power-mode", PIN_CONFIG_LOW_POWER_MODE, }, -+ { "pinctrl-single,low-power-mode", PIN_CONFIG_MODE_LOW_POWER, }, - }; - static const struct pcs_conf_type prop4[] = { - { "pinctrl-single,bias-pullup", PIN_CONFIG_BIAS_PULL_UP, }, -diff --git a/drivers/pinctrl/pinctrl-zynq.c b/drivers/pinctrl/pinctrl-zynq.c -index c6052a0e827a..5fb924a2eedd 100644 ---- a/drivers/pinctrl/pinctrl-zynq.c -+++ b/drivers/pinctrl/pinctrl-zynq.c -@@ -1016,7 +1016,7 @@ static int zynq_pinconf_cfg_get(struct pinctrl_dev *pctldev, - case PIN_CONFIG_SLEW_RATE: - arg = !!(reg & ZYNQ_PINCONF_SPEED); - break; -- case PIN_CONFIG_LOW_POWER_MODE: -+ case PIN_CONFIG_MODE_LOW_POWER: - { - enum zynq_io_standards iostd = zynq_pinconf_iostd_get(reg); - -@@ -1087,7 +1087,7 @@ static int zynq_pinconf_cfg_set(struct pinctrl_dev *pctldev, - reg &= ~ZYNQ_PINCONF_IOTYPE_MASK; - reg |= arg << ZYNQ_PINCONF_IOTYPE_SHIFT; - break; -- case PIN_CONFIG_LOW_POWER_MODE: -+ case PIN_CONFIG_MODE_LOW_POWER: - if (arg) - reg |= ZYNQ_PINCONF_DISABLE_RECVR; - else -diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c -index eab029a21643..d2568dab8c78 100644 ---- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c -+++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c -@@ -194,7 +194,7 @@ static int pxa2xx_pconf_group_get(struct pinctrl_dev *pctldev, - - spin_lock_irqsave(&pctl->lock, flags); - val = readl_relaxed(pgsr) & BIT(pin % 32); -- *config = val ? PIN_CONFIG_LOW_POWER_MODE : 0; -+ *config = val ? PIN_CONFIG_MODE_LOW_POWER : 0; - spin_unlock_irqrestore(&pctl->lock, flags); - - dev_dbg(pctl->dev, "get sleep gpio state(pin=%d) %d\n", -@@ -217,7 +217,7 @@ static int pxa2xx_pconf_group_set(struct pinctrl_dev *pctldev, - - for (i = 0; i < num_configs; i++) { - switch (pinconf_to_config_param(configs[i])) { -- case PIN_CONFIG_LOW_POWER_MODE: -+ case PIN_CONFIG_MODE_LOW_POWER: - is_set = pinconf_to_config_argument(configs[i]); - break; - default: -diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c -index 5726c232e61d..47767b4b7436 100644 ---- a/drivers/soc/tegra/pmc.c -+++ b/drivers/soc/tegra/pmc.c -@@ -1793,7 +1793,7 @@ static int tegra_io_pad_pinconf_get(struct pinctrl_dev *pctl_dev, - arg = ret; - break; - -- case PIN_CONFIG_LOW_POWER_MODE: -+ case PIN_CONFIG_MODE_LOW_POWER: - ret = tegra_io_pad_is_powered(pmc, pad->id); - if (ret < 0) - return ret; -@@ -1830,7 +1830,7 @@ static int tegra_io_pad_pinconf_set(struct pinctrl_dev *pctl_dev, - arg = pinconf_to_config_argument(configs[i]); - - switch (param) { -- case PIN_CONFIG_LOW_POWER_MODE: -+ case PIN_CONFIG_MODE_LOW_POWER: - if (arg) - err = tegra_io_pad_power_disable(pad->id); - else -diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h -index 545e598abb0f..7b5de889574c 100644 ---- a/include/linux/pinctrl/pinconf-generic.h -+++ b/include/linux/pinctrl/pinconf-generic.h -@@ -76,7 +76,7 @@ struct pinctrl_map; - * @PIN_CONFIG_INPUT_SCHMITT_ENABLE: control schmitt-trigger mode on the pin. - * If the argument != 0, schmitt-trigger mode is enabled. If it's 0, - * schmitt-trigger mode is disabled. -- * @PIN_CONFIG_LOW_POWER_MODE: this will configure the pin for low power -+ * @PIN_CONFIG_MODE_LOW_POWER: this will configure the pin for low power - * operation, if several modes of operation are supported these can be - * passed in the argument on a custom form, else just use argument 1 - * to indicate low power mode, argument 0 turns low power mode off. -@@ -126,7 +126,7 @@ enum pin_config_param { - PIN_CONFIG_INPUT_ENABLE, - PIN_CONFIG_INPUT_SCHMITT, - PIN_CONFIG_INPUT_SCHMITT_ENABLE, -- PIN_CONFIG_LOW_POWER_MODE, -+ PIN_CONFIG_MODE_LOW_POWER, - PIN_CONFIG_OUTPUT_ENABLE, - PIN_CONFIG_OUTPUT, - PIN_CONFIG_OUTPUT_IMPEDANCE_OHMS, diff --git a/recipes-kernel/linux/files/patches-5.10/0219-net-ethernet-ti-icssg_prueth-Remove-Rx-enable-in-ini.patch b/recipes-kernel/linux/files/patches-5.10/0219-net-ethernet-ti-icssg_prueth-Remove-Rx-enable-in-ini.patch deleted file mode 100644 index faafd3393..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0219-net-ethernet-ti-icssg_prueth-Remove-Rx-enable-in-ini.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ravi Gunasekaran -Date: Thu, 23 Feb 2023 13:21:39 +0530 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: Remove Rx enable in init - sequence - -During startup, when network traffic is present and the PRU -firmware receives packets while the initialization is in process, -Rx stalls. - -Fix this by moving the Rx enable from driver to firmware. - -Signed-off-by: Ravi Gunasekaran -Signed-off-by: Vignesh Raghavendra ---- - drivers/net/ethernet/ti/icssg_config.c | 25 ++++--------------------- - 1 file changed, 4 insertions(+), 21 deletions(-) - -diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c -index 564bafcd6fc3..ada01cebf3e1 100644 ---- a/drivers/net/ethernet/ti/icssg_config.c -+++ b/drivers/net/ethernet/ti/icssg_config.c -@@ -103,33 +103,23 @@ static void icssg_config_mii_init_switch(struct prueth_emac *emac) - struct prueth *prueth = emac->prueth; - struct regmap *mii_rt = prueth->mii_rt; - int mii = prueth_emac_slice(emac); -- u32 rxcfg_reg, txcfg_reg, pcnt_reg; -- u32 rxcfg, txcfg; -+ u32 txcfg_reg, pcnt_reg; -+ u32 txcfg; - -- rxcfg_reg = (mii == ICSS_MII0) ? PRUSS_MII_RT_RXCFG0 : -- PRUSS_MII_RT_RXCFG1; - txcfg_reg = (mii == ICSS_MII0) ? PRUSS_MII_RT_TXCFG0 : - PRUSS_MII_RT_TXCFG1; - pcnt_reg = (mii == ICSS_MII0) ? PRUSS_MII_RT_RX_PCNT0 : - PRUSS_MII_RT_RX_PCNT1; - -- rxcfg = PRUSS_MII_RT_RXCFG_RX_ENABLE | -- PRUSS_MII_RT_RXCFG_RX_L2_EN | -- PRUSS_MII_RT_RXCFG_RX_L2_EOF_SCLR_DIS; -- - txcfg = PRUSS_MII_RT_TXCFG_TX_ENABLE | - PRUSS_MII_RT_TXCFG_TX_AUTO_PREAMBLE | - PRUSS_MII_RT_TXCFG_TX_IPG_WIRE_CLK_EN; - -- if (mii == ICSS_MII1) -- rxcfg |= PRUSS_MII_RT_RXCFG_RX_MUX_SEL; -- - if (emac->phy_if == PHY_INTERFACE_MODE_MII && mii == ICSS_MII1) - txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL; - else if (emac->phy_if != PHY_INTERFACE_MODE_MII && mii == ICSS_MII0) - txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL; - -- regmap_write(mii_rt, rxcfg_reg, rxcfg); - regmap_write(mii_rt, txcfg_reg, txcfg); - regmap_write(mii_rt, pcnt_reg, 0x1); - } -@@ -139,22 +129,16 @@ static void icssg_config_mii_init(struct prueth_emac *emac) - struct prueth *prueth = emac->prueth; - struct regmap *mii_rt = prueth->mii_rt; - int slice = prueth_emac_slice(emac); -- u32 rxcfg_reg, txcfg_reg, pcnt_reg; -- u32 rxcfg, txcfg; -+ u32 txcfg_reg, pcnt_reg; -+ u32 txcfg; - -- rxcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RXCFG0 : -- PRUSS_MII_RT_RXCFG1; - txcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_TXCFG0 : - PRUSS_MII_RT_TXCFG1; - pcnt_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RX_PCNT0 : - PRUSS_MII_RT_RX_PCNT1; - -- rxcfg = MII_RXCFG_DEFAULT; - txcfg = MII_TXCFG_DEFAULT; - -- if (slice == ICSS_MII1) -- rxcfg |= PRUSS_MII_RT_RXCFG_RX_MUX_SEL; -- - /* In MII mode TX lines swapped inside ICSSG, so TX_MUX_SEL cfg need - * to be swapped also comparing to RGMII mode. TODO: errata? - */ -@@ -163,7 +147,6 @@ static void icssg_config_mii_init(struct prueth_emac *emac) - else if (emac->phy_if != PHY_INTERFACE_MODE_MII && slice == ICSS_MII1) - txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL; - -- regmap_write(mii_rt, rxcfg_reg, rxcfg); - regmap_write(mii_rt, txcfg_reg, txcfg); - regmap_write(mii_rt, pcnt_reg, 0x1); - } diff --git a/recipes-kernel/linux/files/patches-5.10/0220-net-ethernet-ti-icssg_prueth-Initialize-emac-speed-o.patch b/recipes-kernel/linux/files/patches-5.10/0220-net-ethernet-ti-icssg_prueth-Initialize-emac-speed-o.patch deleted file mode 100644 index 811d84ba8..000000000 --- a/recipes-kernel/linux/files/patches-5.10/0220-net-ethernet-ti-icssg_prueth-Initialize-emac-speed-o.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Fri, 2 Jun 2023 08:07:13 +0200 -Subject: [PATCH] net: ethernet: ti: icssg_prueth: Initialize emac speed on - SR1.0 - -This fixes zero delays in emac_stats_work_handler, thus high CPU loads -if no cable is plugged. - -Signed-off-by: Jan Kiszka ---- - drivers/net/ethernet/ti/icssg_config.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/net/ethernet/ti/icssg_config.c b/drivers/net/ethernet/ti/icssg_config.c -index ada01cebf3e1..1d8806c6718e 100644 ---- a/drivers/net/ethernet/ti/icssg_config.c -+++ b/drivers/net/ethernet/ti/icssg_config.c -@@ -284,6 +284,8 @@ void icssg_config_sr1(struct prueth *prueth, struct prueth_emac *emac, - } - - memcpy_toio(va, &prueth->config[slice], sizeof(prueth->config[slice])); -+ -+ emac->speed = SPEED_1000; - } - - static void emac_r30_cmd_init(struct prueth_emac *emac) diff --git a/recipes-kernel/linux/files/patches-5.10/0050-arm64-dts-ti-iot2050-Add-layout-of-OSPI-flash.patch b/recipes-kernel/linux/files/patches-6.1/0001-arm64-dts-ti-iot2050-Add-layout-of-OSPI-flash.patch similarity index 78% rename from recipes-kernel/linux/files/patches-5.10/0050-arm64-dts-ti-iot2050-Add-layout-of-OSPI-flash.patch rename to recipes-kernel/linux/files/patches-6.1/0001-arm64-dts-ti-iot2050-Add-layout-of-OSPI-flash.patch index 14ee62dc3..5b8846ed7 100644 --- a/recipes-kernel/linux/files/patches-5.10/0050-arm64-dts-ti-iot2050-Add-layout-of-OSPI-flash.patch +++ b/recipes-kernel/linux/files/patches-6.1/0001-arm64-dts-ti-iot2050-Add-layout-of-OSPI-flash.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 1a37c2908fbcbf95cb3f3e33881a3c11810db513 Mon Sep 17 00:00:00 2001 From: Jan Kiszka -Date: Mon, 21 Mar 2022 15:53:15 +0100 -Subject: [PATCH] arm64: dts: ti: iot2050: Add layout of OSPI flash +Date: Thu, 19 Jan 2023 07:40:40 +0100 +Subject: [PATCH 01/76] arm64: dts: ti: iot2050: Add layout of OSPI flash Describe the layout of the OSPI flash as the latest firmware uses it. Specifically the location of the U-Boot envs is important for userspace @@ -9,19 +9,17 @@ in order to access it. Signed-off-by: Jan Kiszka --- - .../boot/dts/ti/k3-am65-iot2050-common.dtsi | 48 ++++++++++++++++++- - 1 file changed, 46 insertions(+), 2 deletions(-) + .../boot/dts/ti/k3-am65-iot2050-common.dtsi | 46 +++++++++++++++++++ + 1 file changed, 46 insertions(+) diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index 65da226847f4..d8661096f2de 100644 +index 32b797237581..180bfb2a9ddf 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -@@ -603,8 +603,52 @@ flash@0 { +@@ -603,6 +603,52 @@ flash@0 { cdns,tchsh-ns = <60>; cdns,tslch-ns = <60>; cdns,read-delay = <2>; -- #address-cells = <1>; -- #size-cells = <1>; + + partitions { + compatible = "fixed-partitions"; @@ -71,3 +69,6 @@ index 65da226847f4..d8661096f2de 100644 }; }; +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0002-dt-bindings-arm-ti-Add-binding-for-Siemens-IOT2050-M.patch b/recipes-kernel/linux/files/patches-6.1/0002-dt-bindings-arm-ti-Add-binding-for-Siemens-IOT2050-M.patch new file mode 100644 index 000000000..3f114a947 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0002-dt-bindings-arm-ti-Add-binding-for-Siemens-IOT2050-M.patch @@ -0,0 +1,30 @@ +From c574096089c100319f1447470241cddd05e005e3 Mon Sep 17 00:00:00 2001 +From: Jan Kiszka +Date: Thu, 19 Jan 2023 07:40:41 +0100 +Subject: [PATCH 02/76] dt-bindings: arm: ti: Add binding for Siemens IOT2050 + M.2 variant + +This new variant is derived from the Advanced PG2 board, replacing the +MiniPCI slot with B and E-keyed M.2 slots. + +Signed-off-by: Jan Kiszka +Acked-by: Krzysztof Kozlowski +--- + Documentation/devicetree/bindings/arm/ti/k3.yaml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml +index 28b8232e1c5b..d16231bdee6e 100644 +--- a/Documentation/devicetree/bindings/arm/ti/k3.yaml ++++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml +@@ -42,6 +42,7 @@ properties: + items: + - enum: + - siemens,iot2050-advanced ++ - siemens,iot2050-advanced-m2 + - siemens,iot2050-advanced-pg2 + - siemens,iot2050-basic + - siemens,iot2050-basic-pg2 +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0119-arm64-dts-ti-iot2050-Add-support-for-M.2-variant.patch b/recipes-kernel/linux/files/patches-6.1/0003-arm64-dts-ti-iot2050-Add-support-for-M.2-variant.patch similarity index 86% rename from recipes-kernel/linux/files/patches-5.10/0119-arm64-dts-ti-iot2050-Add-support-for-M.2-variant.patch rename to recipes-kernel/linux/files/patches-6.1/0003-arm64-dts-ti-iot2050-Add-support-for-M.2-variant.patch index 85699e21f..a9db47e92 100644 --- a/recipes-kernel/linux/files/patches-5.10/0119-arm64-dts-ti-iot2050-Add-support-for-M.2-variant.patch +++ b/recipes-kernel/linux/files/patches-6.1/0003-arm64-dts-ti-iot2050-Add-support-for-M.2-variant.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From aac817495c23814a8126ac8bc421b582fe05815c Mon Sep 17 00:00:00 2001 From: chao zeng -Date: Tue, 11 Jan 2022 11:28:24 +0800 -Subject: [PATCH] arm64: dts: ti: iot2050: Add support for M.2 variant +Date: Thu, 19 Jan 2023 07:40:42 +0100 +Subject: [PATCH 03/76] arm64: dts: ti: iot2050: Add support for M.2 variant The M.2 variant comes with 2 slots, one B-keyed and another one E-keyed. They are configured by the firmware during startup. Also the device tree @@ -13,35 +13,38 @@ node so that the firmware can apply overlays for the connector modes. Signed-off-by: chao zeng [Jan: refactored to a single DT] Signed-off-by: Jan Kiszka +Reviewed-by: Siddharth Vadapalli --- arch/arm64/boot/dts/ti/Makefile | 3 + - .../dts/ti/k3-am6548-iot2050-advanced-m2.dts | 118 ++++++++++++++++++ - 2 files changed, 121 insertions(+) + .../dts/ti/k3-am6548-iot2050-advanced-m2.dts | 121 ++++++++++++++++++ + 2 files changed, 124 insertions(+) create mode 100644 arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile -index e8a07d411627..dfe266547170 100644 +index 4555a5be2257..efdd3bb1e263 100644 --- a/arch/arm64/boot/dts/ti/Makefile +++ b/arch/arm64/boot/dts/ti/Makefile -@@ -11,6 +11,9 @@ dtb-$(CONFIG_ARCH_K3) += k3-am6528-iot2050-basic.dtb +@@ -10,8 +10,11 @@ dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board.dtb + dtb-$(CONFIG_ARCH_K3) += k3-am6528-iot2050-basic.dtb dtb-$(CONFIG_ARCH_K3) += k3-am6528-iot2050-basic-pg2.dtb dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced.dtb - dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced-pg2.dtb +dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced-m2.dtb -+ -+DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@ + dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced-pg2.dtb ++DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@ ++ dtb-$(CONFIG_ARCH_K3) += k3-j721e-common-proc-board.dtb + dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk.dtb diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts new file mode 100644 -index 000000000000..cbc411c8fe1d +index 000000000000..9400e35882a6 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts -@@ -0,0 +1,118 @@ +@@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0 +/* -+ * Copyright (c) Siemens AG, 2018-2022 ++ * Copyright (c) Siemens AG, 2018-2023 + * + * Authors: + * Chao Zeng @@ -107,7 +110,10 @@ index 000000000000..cbc411c8fe1d + +&main_gpio0 { + pinctrl-names = "default"; -+ pinctrl-0 = <&main_m2_pcie_mux_control &arduino_io_d4_to_d9_pins_default>; ++ pinctrl-0 = < ++ &main_m2_pcie_mux_control ++ &arduino_io_d4_to_d9_pins_default ++ >; +}; + +&main_gpio1 { @@ -157,3 +163,6 @@ index 000000000000..cbc411c8fe1d + /delete-property/ snps,dis-u1-entry-quirk; + /delete-property/ snps,dis-u2-entry-quirk; +}; +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0051-arm64-dts-ti-k3-am65-main-fix-DSS-irq-trigger-type.patch b/recipes-kernel/linux/files/patches-6.1/0004-arm64-dts-ti-k3-am65-main-fix-DSS-irq-trigger-type.patch similarity index 83% rename from recipes-kernel/linux/files/patches-5.10/0051-arm64-dts-ti-k3-am65-main-fix-DSS-irq-trigger-type.patch rename to recipes-kernel/linux/files/patches-6.1/0004-arm64-dts-ti-k3-am65-main-fix-DSS-irq-trigger-type.patch index 2643b81ad..5635b1da6 100644 --- a/recipes-kernel/linux/files/patches-5.10/0051-arm64-dts-ti-k3-am65-main-fix-DSS-irq-trigger-type.patch +++ b/recipes-kernel/linux/files/patches-6.1/0004-arm64-dts-ti-k3-am65-main-fix-DSS-irq-trigger-type.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From eff6b753588a19d931f4047dca23e1da85e6d6c0 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 31 May 2021 16:31:35 +0530 -Subject: [PATCH] arm64: dts: ti: k3-am65-main: fix DSS irq trigger type +Subject: [PATCH 04/76] arm64: dts: ti: k3-am65-main: fix DSS irq trigger type DSS irq trigger type is set to IRQ_TYPE_EDGE_RISING. For some reason this results in double the amount of expected interrupts, e.g. for normal @@ -21,10 +21,10 @@ Tested-by: Praneeth Bajjuri 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index fb94d61eae0e..9f8031fe6d08 100644 +index ebb1c5ce7aec..83dd8993027a 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -860,7 +860,7 @@ dss: dss@4a00000 { +@@ -856,7 +856,7 @@ dss: dss@4a00000 { assigned-clocks = <&k3_clks 67 2>; assigned-clock-parents = <&k3_clks 67 5>; @@ -33,3 +33,6 @@ index fb94d61eae0e..9f8031fe6d08 100644 dma-coherent; +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0005-dt-bindings-remoteproc-Add-PRU-consumer-bindings.patch b/recipes-kernel/linux/files/patches-6.1/0005-dt-bindings-remoteproc-Add-PRU-consumer-bindings.patch new file mode 100644 index 000000000..6f5daedf7 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0005-dt-bindings-remoteproc-Add-PRU-consumer-bindings.patch @@ -0,0 +1,92 @@ +From 4b8db269fe78b341a1a9c41abcd061ce1e3cd72c Mon Sep 17 00:00:00 2001 +From: Suman Anna +Date: Fri, 6 Jan 2023 17:40:41 +0530 +Subject: [PATCH 05/76] dt-bindings: remoteproc: Add PRU consumer bindings + +Add DT schema binding for PRU consumers. The binding includes +all the common properties that can be used by different PRU consumer +or application nodes and supported by the PRU remoteproc driver. +These are used to configure the PRU hardware for specific user +applications. + +The application nodes themselves should define their own bindings. + +Signed-off-by: Tero Kristo +Signed-off-by: Suman Anna +Signed-off-by: Grzegorz Jaszczyk +Signed-off-by: MD Danish Anwar +Reviewed-by: Rob Herring +--- + .../bindings/remoteproc/ti,pru-consumer.yaml | 60 +++++++++++++++++++ + 1 file changed, 60 insertions(+) + create mode 100644 Documentation/devicetree/bindings/remoteproc/ti,pru-consumer.yaml + +diff --git a/Documentation/devicetree/bindings/remoteproc/ti,pru-consumer.yaml b/Documentation/devicetree/bindings/remoteproc/ti,pru-consumer.yaml +new file mode 100644 +index 000000000000..c6d86964b72a +--- /dev/null ++++ b/Documentation/devicetree/bindings/remoteproc/ti,pru-consumer.yaml +@@ -0,0 +1,60 @@ ++# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/remoteproc/ti,pru-consumer.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Common TI PRU Consumer Binding ++ ++maintainers: ++ - Suman Anna ++ ++description: | ++ A PRU application/consumer/user node typically uses one or more PRU device ++ nodes to implement a PRU application/functionality. Each application/client ++ node would need a reference to at least a PRU node, and optionally define ++ some properties needed for hardware/firmware configuration. The below ++ properties are a list of common properties supported by the PRU remoteproc ++ infrastructure. ++ ++ The application nodes shall define their own bindings like regular platform ++ devices, so below are in addition to each node's bindings. ++ ++properties: ++ ti,prus: ++ $ref: /schemas/types.yaml#/definitions/phandle-array ++ description: phandles to the PRU, RTU or Tx_PRU nodes used ++ minItems: 1 ++ maxItems: 6 ++ items: ++ maxItems: 1 ++ ++ firmware-name: ++ $ref: /schemas/types.yaml#/definitions/string-array ++ minItems: 1 ++ maxItems: 6 ++ description: | ++ firmwares for the PRU cores, the default firmware for the core from ++ the PRU node will be used if not provided. The firmware names should ++ correspond to the PRU cores listed in the 'ti,prus' property ++ ++ ti,pruss-gp-mux-sel: ++ $ref: /schemas/types.yaml#/definitions/uint32-array ++ minItems: 1 ++ maxItems: 6 ++ items: ++ enum: [0, 1, 2, 3, 4] ++ description: | ++ array of values for the GP_MUX_SEL under PRUSS_GPCFG register for a PRU. ++ This selects the internal muxing scheme for the PRU instance. Values ++ should correspond to the PRU cores listed in the 'ti,prus' property. The ++ GP_MUX_SEL setting is a per-slice setting (one setting for PRU0, RTU0, ++ and Tx_PRU0 on K3 SoCs). Use the same value for all cores within the ++ same slice in the associative array. If the array size is smaller than ++ the size of 'ti,prus' property, the default out-of-reset value (0) for the ++ PRU core is used. ++ ++required: ++ - ti,prus ++ ++additionalProperties: true +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0006-remoteproc-pru-Add-enum-for-PRU-Core-Identifiers.patch b/recipes-kernel/linux/files/patches-6.1/0006-remoteproc-pru-Add-enum-for-PRU-Core-Identifiers.patch new file mode 100644 index 000000000..ef0ef6c1d --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0006-remoteproc-pru-Add-enum-for-PRU-Core-Identifiers.patch @@ -0,0 +1,96 @@ +From 78cb86ddb34f5fd10da026ff5ad28dad225a9703 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Fri, 6 Jan 2023 17:40:42 +0530 +Subject: [PATCH 06/76] remoteproc: pru: Add enum for PRU Core Identifiers. + +Introducing enum pruss_pru_id for PRU Core Identifiers. +PRUSS_PRU0 indicates PRU Core 0. +PRUSS_PRU1 indicates PRU Core 1. +PRUSS_NUM_PRUS indicates the total number of PRU Cores. + +Signed-off-by: MD Danish Anwar +Reviewed-by: Roger Quadros +--- + drivers/remoteproc/pru_rproc.c | 7 ++++--- + include/linux/remoteproc/pruss.h | 31 +++++++++++++++++++++++++++++++ + 2 files changed, 35 insertions(+), 3 deletions(-) + create mode 100644 include/linux/remoteproc/pruss.h + +diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c +index 128bf9912f2c..f8b196a2b72a 100644 +--- a/drivers/remoteproc/pru_rproc.c ++++ b/drivers/remoteproc/pru_rproc.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -438,7 +439,7 @@ static void *pru_d_da_to_va(struct pru_rproc *pru, u32 da, size_t len) + dram0 = pruss->mem_regions[PRUSS_MEM_DRAM0]; + dram1 = pruss->mem_regions[PRUSS_MEM_DRAM1]; + /* PRU1 has its local RAM addresses reversed */ +- if (pru->id == 1) ++ if (pru->id == PRUSS_PRU1) + swap(dram0, dram1); + shrd_ram = pruss->mem_regions[PRUSS_MEM_SHRD_RAM2]; + +@@ -747,14 +748,14 @@ static int pru_rproc_set_id(struct pru_rproc *pru) + case RTU0_IRAM_ADDR_MASK: + fallthrough; + case PRU0_IRAM_ADDR_MASK: +- pru->id = 0; ++ pru->id = PRUSS_PRU0; + break; + case TX_PRU1_IRAM_ADDR_MASK: + fallthrough; + case RTU1_IRAM_ADDR_MASK: + fallthrough; + case PRU1_IRAM_ADDR_MASK: +- pru->id = 1; ++ pru->id = PRUSS_PRU1; + break; + default: + ret = -EINVAL; +diff --git a/include/linux/remoteproc/pruss.h b/include/linux/remoteproc/pruss.h +new file mode 100644 +index 000000000000..e94a81e97a4c +--- /dev/null ++++ b/include/linux/remoteproc/pruss.h +@@ -0,0 +1,31 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/** ++ * PRU-ICSS Subsystem user interfaces ++ * ++ * Copyright (C) 2015-2022 Texas Instruments Incorporated - http://www.ti.com ++ * Suman Anna ++ */ ++ ++#ifndef __LINUX_PRUSS_H ++#define __LINUX_PRUSS_H ++ ++#include ++#include ++ ++#define PRU_RPROC_DRVNAME "pru-rproc" ++ ++/** ++ * enum pruss_pru_id - PRU core identifiers ++ * @PRUSS_PRU0: PRU Core 0. ++ * @PRUSS_PRU1: PRU Core 1. ++ * @PRUSS_NUM_PRUS: Total number of PRU Cores available. ++ * ++ */ ++ ++enum pruss_pru_id { ++ PRUSS_PRU0 = 0, ++ PRUSS_PRU1, ++ PRUSS_NUM_PRUS, ++}; ++ ++#endif /* __LINUX_PRUSS_H */ +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0059-remoteproc-pru-Add-APIs-to-get-and-put-the-PRU-cores.patch b/recipes-kernel/linux/files/patches-6.1/0007-remoteproc-pru-Add-APIs-to-get-and-put-the-PRU-cores.patch similarity index 63% rename from recipes-kernel/linux/files/patches-5.10/0059-remoteproc-pru-Add-APIs-to-get-and-put-the-PRU-cores.patch rename to recipes-kernel/linux/files/patches-6.1/0007-remoteproc-pru-Add-APIs-to-get-and-put-the-PRU-cores.patch index 7ea2d26ca..513e06118 100644 --- a/recipes-kernel/linux/files/patches-5.10/0059-remoteproc-pru-Add-APIs-to-get-and-put-the-PRU-cores.patch +++ b/recipes-kernel/linux/files/patches-6.1/0007-remoteproc-pru-Add-APIs-to-get-and-put-the-PRU-cores.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tero Kristo -Date: Fri, 26 Mar 2021 15:32:29 -0500 -Subject: [PATCH] remoteproc: pru: Add APIs to get and put the PRU cores +From ca1807fa2ed80e20d7d1475633914fdec39caa3e Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Fri, 6 Jan 2023 17:40:43 +0530 +Subject: [PATCH 07/76] remoteproc: pru: Add APIs to get and put the PRU cores Add two new APIs, pru_rproc_get() and pru_rproc_put(), to the PRU driver to allow client drivers to acquire and release the remoteproc @@ -13,39 +13,37 @@ to a PRU core identified by the device tree "ti,prus" property under the client node. The pru_rproc_put() is the complementary function to pru_rproc_get(). -Co-developed-by: Suman Anna Signed-off-by: Suman Anna Signed-off-by: Tero Kristo -Co-developed-by: Grzegorz Jaszczyk Signed-off-by: Grzegorz Jaszczyk +Signed-off-by: MD Danish Anwar +Reviewed-by: Roger Quadros --- - drivers/remoteproc/pru_rproc.c | 125 +++++++++++++++++++++++++++++++-- - include/linux/pruss.h | 56 +++++++++++++++ - 2 files changed, 177 insertions(+), 4 deletions(-) - create mode 100644 include/linux/pruss.h + drivers/remoteproc/pru_rproc.c | 128 ++++++++++++++++++++++++++++++- + include/linux/remoteproc/pruss.h | 30 ++++++++ + 2 files changed, 156 insertions(+), 2 deletions(-) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c -index d8597027a93e..0b57b3f7747f 100644 +index f8b196a2b72a..1036bfd446b6 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c -@@ -2,7 +2,7 @@ +@@ -2,12 +2,14 @@ /* * PRU-ICSS remoteproc driver for various TI SoCs * - * Copyright (C) 2014-2020 Texas Instruments Incorporated - https://www.ti.com/ -+ * Copyright (C) 2014-2021 Texas Instruments Incorporated - https://www.ti.com/ ++ * Copyright (C) 2014-2022 Texas Instruments Incorporated - https://www.ti.com/ * * Author(s): * Suman Anna -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include + * Andrew F. Davis + * Grzegorz Jaszczyk for Texas Instruments ++ * Puranjay Mohan ++ * Md Danish Anwar + */ -@@ -111,6 +112,8 @@ struct pru_private_data { + #include +@@ -112,6 +114,8 @@ struct pru_private_data { * @rproc: remoteproc pointer for this PRU core * @data: PRU core specific data * @mem_regions: data for each of the PRU memory regions @@ -54,49 +52,41 @@ index d8597027a93e..0b57b3f7747f 100644 * @fw_name: name of firmware image used during loading * @mapped_irq: virtual interrupt numbers of created fw specific mapping * @pru_interrupt_map: pointer to interrupt mapping description (firmware) -@@ -126,6 +129,8 @@ struct pru_rproc { +@@ -127,6 +131,8 @@ struct pru_rproc { struct rproc *rproc; const struct pru_private_data *data; struct pruss_mem_region mem_regions[PRU_IOMEM_MAX]; + struct device_node *client_np; -+ struct mutex lock; /* client access lock */ ++ struct mutex lock; const char *fw_name; unsigned int *mapped_irq; struct pru_irq_rsc *pru_interrupt_map; -@@ -146,6 +151,117 @@ void pru_control_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val) +@@ -147,6 +153,120 @@ void pru_control_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val) writel_relaxed(val, pru->mem_regions[PRU_IOMEM_CTRL].va + reg); } +static struct rproc *__pru_rproc_get(struct device_node *np, int index) +{ -+ struct device_node *rproc_np = NULL; -+ struct platform_device *pdev; + struct rproc *rproc; ++ phandle rproc_phandle; ++ int ret; + -+ rproc_np = of_parse_phandle(np, "ti,prus", index); -+ if (!rproc_np || !of_device_is_available(rproc_np)) -+ return ERR_PTR(-ENODEV); -+ -+ pdev = of_find_device_by_node(rproc_np); -+ of_node_put(rproc_np); ++ ret = of_property_read_u32_index(np, "ti,prus", index, &rproc_phandle); ++ if (ret) ++ return ERR_PTR(ret); + -+ if (!pdev) -+ /* probably PRU not yet probed */ -+ return ERR_PTR(-EPROBE_DEFER); ++ rproc = rproc_get_by_phandle(rproc_phandle); ++ if (!rproc) { ++ ret = -EPROBE_DEFER; ++ return ERR_PTR(ret); ++ } + + /* make sure it is PRU rproc */ -+ if (!is_pru_rproc(&pdev->dev)) { -+ put_device(&pdev->dev); ++ if (!is_pru_rproc(rproc->dev.parent)) { ++ rproc_put(rproc); + return ERR_PTR(-ENODEV); + } + -+ rproc = platform_get_drvdata(pdev); -+ put_device(&pdev->dev); -+ if (!rproc) -+ return ERR_PTR(-EPROBE_DEFER); -+ -+ get_device(&rproc->dev); -+ + return rproc; +} + @@ -126,19 +116,22 @@ index d8597027a93e..0b57b3f7747f 100644 +{ + struct rproc *rproc; + struct pru_rproc *pru; ++ struct device *dev; ++ int ret; + + rproc = __pru_rproc_get(np, index); + if (IS_ERR(rproc)) + return rproc; + + pru = rproc->priv; ++ dev = &rproc->dev; + + mutex_lock(&pru->lock); + + if (pru->client_np) { + mutex_unlock(&pru->lock); -+ put_device(&rproc->dev); -+ return ERR_PTR(-EBUSY); ++ ret = -EBUSY; ++ goto err_no_rproc_handle; + } + + pru->client_np = np; @@ -149,6 +142,10 @@ index d8597027a93e..0b57b3f7747f 100644 + *pru_id = pru->id; + + return rproc; ++ ++err_no_rproc_handle: ++ rproc_put(rproc); ++ return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(pru_rproc_get); + @@ -167,85 +164,58 @@ index d8597027a93e..0b57b3f7747f 100644 + return; + + pru = rproc->priv; -+ if (!pru->client_np) -+ return; + + mutex_lock(&pru->lock); ++ ++ if (!pru->client_np) { ++ mutex_unlock(&pru->lock); ++ return; ++ } ++ + pru->client_np = NULL; + mutex_unlock(&pru->lock); + -+ put_device(&rproc->dev); ++ rproc_put(rproc); +} +EXPORT_SYMBOL_GPL(pru_rproc_put); + static inline u32 pru_debug_read_reg(struct pru_rproc *pru, unsigned int reg) { return readl_relaxed(pru->mem_regions[PRU_IOMEM_DEBUG].va + reg); -@@ -747,14 +863,14 @@ static int pru_rproc_set_id(struct pru_rproc *pru) - case RTU0_IRAM_ADDR_MASK: - fallthrough; - case PRU0_IRAM_ADDR_MASK: -- pru->id = 0; -+ pru->id = PRUSS_PRU0; - break; - case TX_PRU1_IRAM_ADDR_MASK: - fallthrough; - case RTU1_IRAM_ADDR_MASK: - fallthrough; - case PRU1_IRAM_ADDR_MASK: -- pru->id = 1; -+ pru->id = PRUSS_PRU1; - break; - default: - ret = -EINVAL; -@@ -816,6 +932,7 @@ static int pru_rproc_probe(struct platform_device *pdev) +@@ -817,6 +937,8 @@ static int pru_rproc_probe(struct platform_device *pdev) pru->pruss = platform_get_drvdata(ppdev); pru->rproc = rproc; pru->fw_name = fw_name; ++ pru->client_np = NULL; + mutex_init(&pru->lock); for (i = 0; i < ARRAY_SIZE(mem_names); i++) { res = platform_get_resource_byname(pdev, IORESOURCE_MEM, -@@ -897,7 +1014,7 @@ MODULE_DEVICE_TABLE(of, pru_rproc_match); +@@ -905,7 +1027,7 @@ MODULE_DEVICE_TABLE(of, pru_rproc_match); static struct platform_driver pru_rproc_driver = { .driver = { - .name = "pru-rproc", -+ .name = PRU_RPROC_DRVNAME, ++ .name = PRU_RPROC_DRVNAME, .of_match_table = pru_rproc_match, .suppress_bind_attrs = true, }, -diff --git a/include/linux/pruss.h b/include/linux/pruss.h -new file mode 100644 -index 000000000000..1a97856b463a ---- /dev/null -+++ b/include/linux/pruss.h -@@ -0,0 +1,56 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/** -+ * PRU-ICSS Subsystem user interfaces -+ * -+ * Copyright (C) 2015-2021 Texas Instruments Incorporated - https://www.ti.com -+ * Suman Anna -+ */ -+ -+#ifndef __LINUX_PRUSS_H -+#define __LINUX_PRUSS_H -+ -+#include -+#include -+ -+#define PRU_RPROC_DRVNAME "pru-rproc" -+ -+/* -+ * enum pruss_pru_id - PRU core identifiers -+ */ -+enum pruss_pru_id { -+ PRUSS_PRU0 = 0, -+ PRUSS_PRU1, -+ PRUSS_NUM_PRUS, -+}; -+ +@@ -917,5 +1039,7 @@ module_platform_driver(pru_rproc_driver); + MODULE_AUTHOR("Suman Anna "); + MODULE_AUTHOR("Andrew F. Davis "); + MODULE_AUTHOR("Grzegorz Jaszczyk "); ++MODULE_AUTHOR("Puranjay Mohan "); ++MODULE_AUTHOR("Md Danish Anwar "); + MODULE_DESCRIPTION("PRU-ICSS Remote Processor Driver"); + MODULE_LICENSE("GPL v2"); +diff --git a/include/linux/remoteproc/pruss.h b/include/linux/remoteproc/pruss.h +index e94a81e97a4c..efe89c586b4b 100644 +--- a/include/linux/remoteproc/pruss.h ++++ b/include/linux/remoteproc/pruss.h +@@ -28,4 +28,34 @@ enum pruss_pru_id { + PRUSS_NUM_PRUS, + }; + +struct device_node; + +#if IS_ENABLED(CONFIG_PRU_REMOTEPROC) @@ -276,4 +246,7 @@ index 000000000000..1a97856b463a + return true; +} + -+#endif /* __LINUX_PRUSS_H */ + #endif /* __LINUX_PRUSS_H */ +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0060-remoteproc-pru-Deny-rproc-sysfs-ops-for-PRU-client-d.patch b/recipes-kernel/linux/files/patches-6.1/0008-remoteproc-pru-Make-sysfs-entries-read-only-for-PRU-.patch similarity index 60% rename from recipes-kernel/linux/files/patches-5.10/0060-remoteproc-pru-Deny-rproc-sysfs-ops-for-PRU-client-d.patch rename to recipes-kernel/linux/files/patches-6.1/0008-remoteproc-pru-Make-sysfs-entries-read-only-for-PRU-.patch index 64f2de104..311a2862d 100644 --- a/recipes-kernel/linux/files/patches-5.10/0060-remoteproc-pru-Deny-rproc-sysfs-ops-for-PRU-client-d.patch +++ b/recipes-kernel/linux/files/patches-6.1/0008-remoteproc-pru-Make-sysfs-entries-read-only-for-PRU-.patch @@ -1,42 +1,46 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 0eeb9aad692be2fd5c47352d7aaf87e1c9d08b5a Mon Sep 17 00:00:00 2001 From: Suman Anna -Date: Wed, 16 Dec 2020 17:52:37 +0100 -Subject: [PATCH] remoteproc: pru: Deny rproc sysfs ops for PRU client driven - boots +Date: Fri, 6 Jan 2023 17:40:44 +0530 +Subject: [PATCH 08/76] remoteproc: pru: Make sysfs entries read-only for PRU + client driven boots The PRU remoteproc driver is not configured for 'auto-boot' by default, and allows to be booted either by in-kernel PRU client drivers or by userspace using the generic remoteproc sysfs interfaces. The sysfs interfaces should not be permitted to change the remoteproc firmwares or states when a PRU is being managed by an in-kernel client driver. -Use the newly introduced remoteproc generic 'deny_sysfs_ops' flag to +Use the newly introduced remoteproc generic 'sysfs_read_only' flag to provide these restrictions by setting and clearing it appropriately during the PRU acquire and release steps. Signed-off-by: Suman Anna -Co-developed-by: Grzegorz Jaszczyk Signed-off-by: Grzegorz Jaszczyk +Signed-off-by: MD Danish Anwar +Reviewed-by: Roger Quadros --- drivers/remoteproc/pru_rproc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c -index 0b57b3f7747f..8fac021adc52 100644 +index 1036bfd446b6..c16242e2d435 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c -@@ -226,6 +226,7 @@ struct rproc *pru_rproc_get(struct device_node *np, int index, +@@ -223,6 +223,7 @@ struct rproc *pru_rproc_get(struct device_node *np, int index, } pru->client_np = np; -+ rproc->deny_sysfs_ops = true; ++ rproc->sysfs_read_only = true; mutex_unlock(&pru->lock); -@@ -256,6 +257,7 @@ void pru_rproc_put(struct rproc *rproc) +@@ -261,6 +262,7 @@ void pru_rproc_put(struct rproc *rproc) + } - mutex_lock(&pru->lock); pru->client_np = NULL; -+ rproc->deny_sysfs_ops = false; ++ rproc->sysfs_read_only = false; mutex_unlock(&pru->lock); - put_device(&rproc->dev); + rproc_put(rproc); +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0061-remoteproc-pru-Add-pru_rproc_set_ctable-function.patch b/recipes-kernel/linux/files/patches-6.1/0009-remoteproc-pru-Add-pru_rproc_set_ctable-function.patch similarity index 72% rename from recipes-kernel/linux/files/patches-5.10/0061-remoteproc-pru-Add-pru_rproc_set_ctable-function.patch rename to recipes-kernel/linux/files/patches-6.1/0009-remoteproc-pru-Add-pru_rproc_set_ctable-function.patch index 11330e8ff..948636d76 100644 --- a/recipes-kernel/linux/files/patches-5.10/0061-remoteproc-pru-Add-pru_rproc_set_ctable-function.patch +++ b/recipes-kernel/linux/files/patches-6.1/0009-remoteproc-pru-Add-pru_rproc_set_ctable-function.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 7c1b322eead515a648999c99238f0950565c00b0 Mon Sep 17 00:00:00 2001 From: Roger Quadros -Date: Fri, 26 Mar 2021 15:43:53 -0500 -Subject: [PATCH] remoteproc: pru: Add pru_rproc_set_ctable() function +Date: Fri, 6 Jan 2023 17:40:45 +0530 +Subject: [PATCH 09/76] remoteproc: pru: Add pru_rproc_set_ctable() function Some firmwares expect the OS drivers to configure the CTABLE entries publishing dynamically allocated memory regions. For @@ -24,23 +24,36 @@ may be needed between the PRU client drivers and firmwares if different addresses needs to be published at run-time reusing the same CTABLE entry. -Co-developed-by: Andrew F. Davis -Signed-off-by: Andrew F. Davis -Co-developed-by: Suman Anna +CTABLE for stands for "constant table". +Each CTable entry just holds the upper address bits so PRU can +reference to external memory with larger address bits. + +For use case please see +prueth_sw_emac_config() in "drivers/net/ethernet/ti/prueth_switch.c" + + /* Set in constant table C28 of PRUn to ICSS Shared memory */ + pru_rproc_set_ctable(prueth->pru0, PRU_C28, sharedramaddr); + pru_rproc_set_ctable(prueth->pru1, PRU_C28, sharedramaddr); + + /* Set in constant table C30 of PRUn to OCMC memory */ + pru_rproc_set_ctable(prueth->pru0, PRU_C30, ocmcaddr); + pru_rproc_set_ctable(prueth->pru1, PRU_C30, ocmcaddr); + +Signed-off-by: "Andrew F. Davis" Signed-off-by: Suman Anna Signed-off-by: Roger Quadros -Co-developed-by: Grzegorz Jaszczyk Signed-off-by: Grzegorz Jaszczyk +Signed-off-by: MD Danish Anwar --- - drivers/remoteproc/pru_rproc.c | 59 ++++++++++++++++++++++++++++++++++ - include/linux/pruss.h | 22 +++++++++++++ + drivers/remoteproc/pru_rproc.c | 59 ++++++++++++++++++++++++++++++++ + include/linux/remoteproc/pruss.h | 22 ++++++++++++ 2 files changed, 81 insertions(+) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c -index 8fac021adc52..90c097ebc27e 100644 +index c16242e2d435..f6ea445d2fa2 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c -@@ -118,6 +118,7 @@ struct pru_private_data { +@@ -120,6 +120,7 @@ struct pru_private_data { * @mapped_irq: virtual interrupt numbers of created fw specific mapping * @pru_interrupt_map: pointer to interrupt mapping description (firmware) * @pru_interrupt_map_sz: pru_interrupt_map size @@ -48,15 +61,15 @@ index 8fac021adc52..90c097ebc27e 100644 * @dbg_single_step: debug state variable to set PRU into single step mode * @dbg_continuous: debug state variable to restore PRU execution mode * @evt_count: number of mapped events -@@ -135,6 +136,7 @@ struct pru_rproc { +@@ -137,6 +138,7 @@ struct pru_rproc { unsigned int *mapped_irq; struct pru_irq_rsc *pru_interrupt_map; size_t pru_interrupt_map_sz; -+ spinlock_t rmw_lock; /* register access lock */ ++ spinlock_t rmw_lock; u32 dbg_single_step; u32 dbg_continuous; u8 evt_count; -@@ -151,6 +153,23 @@ void pru_control_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val) +@@ -153,6 +155,23 @@ void pru_control_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val) writel_relaxed(val, pru->mem_regions[PRU_IOMEM_CTRL].va + reg); } @@ -79,8 +92,8 @@ index 8fac021adc52..90c097ebc27e 100644 + static struct rproc *__pru_rproc_get(struct device_node *np, int index) { - struct device_node *rproc_np = NULL; -@@ -264,6 +283,45 @@ void pru_rproc_put(struct rproc *rproc) + struct rproc *rproc; +@@ -269,6 +288,45 @@ void pru_rproc_put(struct rproc *rproc) } EXPORT_SYMBOL_GPL(pru_rproc_put); @@ -126,19 +139,19 @@ index 8fac021adc52..90c097ebc27e 100644 static inline u32 pru_debug_read_reg(struct pru_rproc *pru, unsigned int reg) { return readl_relaxed(pru->mem_regions[PRU_IOMEM_DEBUG].va + reg); -@@ -934,6 +992,7 @@ static int pru_rproc_probe(struct platform_device *pdev) - pru->pruss = platform_get_drvdata(ppdev); +@@ -940,6 +998,7 @@ static int pru_rproc_probe(struct platform_device *pdev) pru->rproc = rproc; pru->fw_name = fw_name; + pru->client_np = NULL; + spin_lock_init(&pru->rmw_lock); mutex_init(&pru->lock); for (i = 0; i < ARRAY_SIZE(mem_names); i++) { -diff --git a/include/linux/pruss.h b/include/linux/pruss.h -index 1a97856b463a..e1740ff06962 100644 ---- a/include/linux/pruss.h -+++ b/include/linux/pruss.h -@@ -23,13 +23,29 @@ enum pruss_pru_id { +diff --git a/include/linux/remoteproc/pruss.h b/include/linux/remoteproc/pruss.h +index efe89c586b4b..5c20da98a4b8 100644 +--- a/include/linux/remoteproc/pruss.h ++++ b/include/linux/remoteproc/pruss.h +@@ -28,13 +28,29 @@ enum pruss_pru_id { PRUSS_NUM_PRUS, }; @@ -168,7 +181,7 @@ index 1a97856b463a..e1740ff06962 100644 #else -@@ -41,6 +57,12 @@ pru_rproc_get(struct device_node *np, int index, enum pruss_pru_id *pru_id) +@@ -46,6 +62,12 @@ pru_rproc_get(struct device_node *np, int index, enum pruss_pru_id *pru_id) static inline void pru_rproc_put(struct rproc *rproc) { } @@ -181,3 +194,6 @@ index 1a97856b463a..e1740ff06962 100644 #endif /* CONFIG_PRU_REMOTEPROC */ static inline bool is_pru_rproc(struct device *dev) +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0062-remoteproc-pru-Configure-firmware-based-on-client-se.patch b/recipes-kernel/linux/files/patches-6.1/0010-remoteproc-pru-Configure-firmware-based-on-client-se.patch similarity index 58% rename from recipes-kernel/linux/files/patches-5.10/0062-remoteproc-pru-Configure-firmware-based-on-client-se.patch rename to recipes-kernel/linux/files/patches-6.1/0010-remoteproc-pru-Configure-firmware-based-on-client-se.patch index 033c9bb6a..ee6dbe09e 100644 --- a/recipes-kernel/linux/files/patches-5.10/0062-remoteproc-pru-Configure-firmware-based-on-client-se.patch +++ b/recipes-kernel/linux/files/patches-6.1/0010-remoteproc-pru-Configure-firmware-based-on-client-se.patch @@ -1,31 +1,32 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 230027af63aeb30e504d46f7aa4f934b99f6b94e Mon Sep 17 00:00:00 2001 From: Tero Kristo -Date: Fri, 26 Mar 2021 15:50:14 -0500 -Subject: [PATCH] remoteproc: pru: Configure firmware based on client setup +Date: Fri, 6 Jan 2023 17:40:46 +0530 +Subject: [PATCH 10/76] remoteproc: pru: Configure firmware based on client + setup Client device node property firmware-name is now used to configure firmware for the PRU instances. The default firmware is also restored once releasing the PRU resource. -Co-developed-by: Suman Anna Signed-off-by: Suman Anna Signed-off-by: Tero Kristo -Co-developed-by: Grzegorz Jaszczyk Signed-off-by: Grzegorz Jaszczyk +Signed-off-by: MD Danish Anwar +Reviewed-by: Roger Quadros --- - drivers/remoteproc/pru_rproc.c | 39 +++++++++++++++++++++++++++++++++- - 1 file changed, 38 insertions(+), 1 deletion(-) + drivers/remoteproc/pru_rproc.c | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c -index 90c097ebc27e..c346899d5e3b 100644 +index f6ea445d2fa2..b76db7fa693d 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c -@@ -170,6 +170,23 @@ void pru_control_set_reg(struct pru_rproc *pru, unsigned int reg, +@@ -172,6 +172,23 @@ void pru_control_set_reg(struct pru_rproc *pru, unsigned int reg, spin_unlock_irqrestore(&pru->rmw_lock, flags); } +/** -+ * pru_rproc_set_firmware() - set firmware for a pru core ++ * pru_rproc_set_firmware() - set firmware for a PRU core + * @rproc: the rproc instance of the PRU + * @fw_name: the new firmware name, or NULL if default is desired + * @@ -43,34 +44,18 @@ index 90c097ebc27e..c346899d5e3b 100644 + static struct rproc *__pru_rproc_get(struct device_node *np, int index) { - struct device_node *rproc_np = NULL; -@@ -229,18 +246,22 @@ struct rproc *pru_rproc_get(struct device_node *np, int index, - { + struct rproc *rproc; +@@ -224,6 +241,7 @@ struct rproc *pru_rproc_get(struct device_node *np, int index, struct rproc *rproc; struct pru_rproc *pru; + struct device *dev; + const char *fw_name; -+ struct device *dev; -+ int ret; + int ret; rproc = __pru_rproc_get(np, index); - if (IS_ERR(rproc)) - return rproc; - - pru = rproc->priv; -+ dev = &rproc->dev; - - mutex_lock(&pru->lock); - - if (pru->client_np) { - mutex_unlock(&pru->lock); -- put_device(&rproc->dev); -+ put_device(dev); - return ERR_PTR(-EBUSY); - } - -@@ -249,10 +270,24 @@ struct rproc *pru_rproc_get(struct device_node *np, int index, - - mutex_unlock(&pru->lock); +@@ -249,11 +267,25 @@ struct rproc *pru_rproc_get(struct device_node *np, int index, + if (pru_id) + *pru_id = pru->id; + ret = of_property_read_string_index(np, "firmware-name", index, + &fw_name); @@ -82,10 +67,11 @@ index 90c097ebc27e..c346899d5e3b 100644 + } + } + - if (pru_id) - *pru_id = pru->id; - return rproc; + + err_no_rproc_handle: + rproc_put(rproc); + return ERR_PTR(ret); + +err: + pru_rproc_put(rproc); @@ -93,12 +79,15 @@ index 90c097ebc27e..c346899d5e3b 100644 } EXPORT_SYMBOL_GPL(pru_rproc_get); -@@ -274,6 +309,8 @@ void pru_rproc_put(struct rproc *rproc) - if (!pru->client_np) - return; +@@ -273,6 +305,8 @@ void pru_rproc_put(struct rproc *rproc) + + pru = rproc->priv; + pru_rproc_set_firmware(rproc, NULL); + mutex_lock(&pru->lock); - pru->client_np = NULL; - rproc->deny_sysfs_ops = false; + + if (!pru->client_np) { +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0063-soc-ti-pruss-Add-pruss_get-put-API.patch b/recipes-kernel/linux/files/patches-6.1/0011-soc-ti-pruss-Add-pruss_get-put-API.patch similarity index 67% rename from recipes-kernel/linux/files/patches-5.10/0063-soc-ti-pruss-Add-pruss_get-put-API.patch rename to recipes-kernel/linux/files/patches-6.1/0011-soc-ti-pruss-Add-pruss_get-put-API.patch index c6118f46f..f63cf674b 100644 --- a/recipes-kernel/linux/files/patches-5.10/0063-soc-ti-pruss-Add-pruss_get-put-API.patch +++ b/recipes-kernel/linux/files/patches-6.1/0011-soc-ti-pruss-Add-pruss_get-put-API.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From a3271e2c3504abf2b324fc052b15de6f0c974813 Mon Sep 17 00:00:00 2001 From: Tero Kristo -Date: Fri, 26 Mar 2021 15:58:00 -0500 -Subject: [PATCH] soc: ti: pruss: Add pruss_get()/put() API +Date: Fri, 14 Apr 2023 10:25:39 +0530 +Subject: [PATCH 11/76] soc: ti: pruss: Add pruss_get()/put() API Add two new get and put API, pruss_get() and pruss_put() to the PRUSS platform driver to allow client drivers to request a handle @@ -18,22 +18,22 @@ Signed-off-by: Suman Anna Signed-off-by: Tero Kristo Co-developed-by: Grzegorz Jaszczyk Signed-off-by: Grzegorz Jaszczyk +Signed-off-by: Puranjay Mohan +Reviewed-by: Roger Quadros +Reviewed-by: Tony Lindgren +Reviewed-by: Simon Horman +Acked-by: Mathieu Poirier +Signed-off-by: MD Danish Anwar --- - drivers/soc/ti/pruss.c | 60 +++++++++++++++++++++++++++++++++++- - include/linux/pruss.h | 19 ++++++++++++ - include/linux/pruss_driver.h | 3 +- - 3 files changed, 80 insertions(+), 2 deletions(-) + drivers/soc/ti/pruss.c | 62 ++++++++++++++++++++++++++++++++++++ + include/linux/pruss_driver.h | 18 +++++++++++ + 2 files changed, 80 insertions(+) diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c -index afc8aae68035..d08adff52094 100644 +index 6882c86b3ce5..3fac92df8790 100644 --- a/drivers/soc/ti/pruss.c +++ b/drivers/soc/ti/pruss.c -@@ -2,10 +2,11 @@ - /* - * PRU-ICSS platform driver for various TI SoCs - * -- * Copyright (C) 2014-2020 Texas Instruments Incorporated - http://www.ti.com/ -+ * Copyright (C) 2014-2021 Texas Instruments Incorporated - https://www.ti.com/ +@@ -6,6 +6,7 @@ * Author(s): * Suman Anna * Andrew F. Davis @@ -49,7 +49,7 @@ index afc8aae68035..d08adff52094 100644 #include /** -@@ -30,6 +32,62 @@ struct pruss_private_data { +@@ -30,6 +32,66 @@ struct pruss_private_data { bool has_core_mux_clock; }; @@ -62,6 +62,10 @@ index afc8aae68035..d08adff52094 100644 + * so always use pruss_put() to decrement it back once pruss isn't needed + * anymore. + * ++ * This API doesn't check if @rproc is valid or not. It is expected the caller ++ * will have done a pru_rproc_get() on @rproc, before calling this API to make ++ * sure that @rproc is valid. ++ * + * Return: pruss handle on success, and an ERR_PTR on failure using one + * of the following error values + * -EINVAL if invalid parameter @@ -112,31 +116,24 @@ index afc8aae68035..d08adff52094 100644 static void pruss_of_free_clk_provider(void *data) { struct device_node *clk_mux_np = data; -diff --git a/include/linux/pruss.h b/include/linux/pruss.h -index e1740ff06962..2e1f519255b9 100644 ---- a/include/linux/pruss.h -+++ b/include/linux/pruss.h -@@ -4,12 +4,14 @@ - * - * Copyright (C) 2015-2021 Texas Instruments Incorporated - https://www.ti.com - * Suman Anna -+ * Tero Kristo - */ - - #ifndef __LINUX_PRUSS_H - #define __LINUX_PRUSS_H +diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h +index ecfded30ed05..cb40c2b31045 100644 +--- a/include/linux/pruss_driver.h ++++ b/include/linux/pruss_driver.h +@@ -9,7 +9,9 @@ + #ifndef _PRUSS_DRIVER_H_ + #define _PRUSS_DRIVER_H_ - #include -+#include ++#include #include ++#include - #define PRU_RPROC_DRVNAME "pru-rproc" -@@ -39,6 +41,23 @@ enum pru_ctable_idx { + /* + * enum pruss_mem - PRUSS memory range identifiers +@@ -51,4 +53,20 @@ struct pruss { + struct clk *iep_clk_mux; + }; - struct device_node; - struct rproc; -+struct pruss; -+ +#if IS_ENABLED(CONFIG_TI_PRUSS) + +struct pruss *pruss_get(struct rproc *rproc); @@ -152,26 +149,8 @@ index e1740ff06962..2e1f519255b9 100644 +static inline void pruss_put(struct pruss *pruss) { } + +#endif /* CONFIG_TI_PRUSS */ - - #if IS_ENABLED(CONFIG_PRU_REMOTEPROC) - -diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h -index ecfded30ed05..4d1321f0d326 100644 ---- a/include/linux/pruss_driver.h -+++ b/include/linux/pruss_driver.h -@@ -2,13 +2,14 @@ - /* - * PRU-ICSS sub-system specific definitions - * -- * Copyright (C) 2014-2020 Texas Instruments Incorporated - http://www.ti.com/ -+ * Copyright (C) 2014-2021 Texas Instruments Incorporated - https://www.ti.com/ - * Suman Anna - */ - - #ifndef _PRUSS_DRIVER_H_ - #define _PRUSS_DRIVER_H_ - -+#include - #include - - /* ++ + #endif /* _PRUSS_DRIVER_H_ */ +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0064-soc-ti-pruss-Add-pruss_-request-release-_mem_region-.patch b/recipes-kernel/linux/files/patches-6.1/0012-soc-ti-pruss-Add-pruss_-request-release-_mem_region-.patch similarity index 65% rename from recipes-kernel/linux/files/patches-5.10/0064-soc-ti-pruss-Add-pruss_-request-release-_mem_region-.patch rename to recipes-kernel/linux/files/patches-6.1/0012-soc-ti-pruss-Add-pruss_-request-release-_mem_region-.patch index 7dbabc872..979b227e8 100644 --- a/recipes-kernel/linux/files/patches-5.10/0064-soc-ti-pruss-Add-pruss_-request-release-_mem_region-.patch +++ b/recipes-kernel/linux/files/patches-6.1/0012-soc-ti-pruss-Add-pruss_-request-release-_mem_region-.patch @@ -1,7 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 19e930c1da58c5980defc8a4568b85496fa28a75 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" -Date: Fri, 26 Mar 2021 16:11:42 -0500 -Subject: [PATCH] soc: ti: pruss: Add pruss_{request,release}_mem_region() API +Date: Fri, 14 Apr 2023 10:25:40 +0530 +Subject: [PATCH 12/76] soc: ti: pruss: Add + pruss_{request,release}_mem_region() API Add two new API - pruss_request_mem_region() & pruss_release_mem_region(), to the PRUSS platform driver to allow client drivers to acquire and release @@ -11,20 +12,24 @@ as per their design contract with the associated firmware. Co-developed-by: Suman Anna Signed-off-by: Suman Anna -Signed-off-by: Andrew F. Davis +Signed-off-by: "Andrew F. Davis" Co-developed-by: Grzegorz Jaszczyk Signed-off-by: Grzegorz Jaszczyk +Reviewed-by: Roger Quadros +Acked-by: Mathieu Poirier +Reviewed-by: Tony Lindgren +Reviewed-by: Simon Horman +Signed-off-by: MD Danish Anwar --- - drivers/soc/ti/pruss.c | 78 ++++++++++++++++++++++++++++++++++++ - include/linux/pruss.h | 39 ++++++++++++++++++ - include/linux/pruss_driver.h | 27 +++---------- - 3 files changed, 122 insertions(+), 22 deletions(-) + drivers/soc/ti/pruss.c | 77 ++++++++++++++++++++++++++++++++++++ + include/linux/pruss_driver.h | 22 +++++++++++ + 2 files changed, 99 insertions(+) diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c -index d08adff52094..dc1470fa33d0 100644 +index 3fac92df8790..8ada3758b31a 100644 --- a/drivers/soc/ti/pruss.c +++ b/drivers/soc/ti/pruss.c -@@ -88,6 +88,83 @@ void pruss_put(struct pruss *pruss) +@@ -92,6 +92,82 @@ void pruss_put(struct pruss *pruss) } EXPORT_SYMBOL_GPL(pruss_put); @@ -39,8 +44,8 @@ index d08adff52094..dc1470fa33d0 100644 + * memory region until released using the pruss_release_mem_region() + * API. + * -+ * Return: 0 if requested memory region is available with the memory region -+ * values returned in memory pointed by @region, an error otherwise ++ * Return: 0 if requested memory region is available (in such case pointer to ++ * memory region is returned via @region), an error otherwise + */ +int pruss_request_mem_region(struct pruss *pruss, enum pruss_mem mem_id, + struct pruss_mem_region *region) @@ -97,7 +102,6 @@ index d08adff52094..dc1470fa33d0 100644 + } + + pruss->mem_in_use[id] = NULL; -+ memset(region, 0, sizeof(*region)); + + mutex_unlock(&pruss->lock); + @@ -108,7 +112,7 @@ index d08adff52094..dc1470fa33d0 100644 static void pruss_of_free_clk_provider(void *data) { struct device_node *clk_mux_np = data; -@@ -290,6 +367,7 @@ static int pruss_probe(struct platform_device *pdev) +@@ -294,6 +370,7 @@ static int pruss_probe(struct platform_device *pdev) return -ENOMEM; pruss->dev = dev; @@ -116,40 +120,37 @@ index d08adff52094..dc1470fa33d0 100644 child = of_get_child_by_name(np, "memories"); if (!child) { -diff --git a/include/linux/pruss.h b/include/linux/pruss.h -index 2e1f519255b9..40de553d4446 100644 ---- a/include/linux/pruss.h -+++ b/include/linux/pruss.h -@@ -39,6 +39,28 @@ enum pru_ctable_idx { - PRU_C31, - }; +diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h +index cb40c2b31045..c8f2e53b911b 100644 +--- a/include/linux/pruss_driver.h ++++ b/include/linux/pruss_driver.h +@@ -9,6 +9,7 @@ + #ifndef _PRUSS_DRIVER_H_ + #define _PRUSS_DRIVER_H_ -+/* -+ * enum pruss_mem - PRUSS memory range identifiers -+ */ -+enum pruss_mem { -+ PRUSS_MEM_DRAM0 = 0, -+ PRUSS_MEM_DRAM1, -+ PRUSS_MEM_SHRD_RAM2, -+ PRUSS_MEM_MAX, -+}; -+ -+/** -+ * struct pruss_mem_region - PRUSS memory region structure -+ * @va: kernel virtual address of the PRUSS memory region -+ * @pa: physical (bus) address of the PRUSS memory region -+ * @size: size of the PRUSS memory region -+ */ -+struct pruss_mem_region { -+ void __iomem *va; -+ phys_addr_t pa; -+ size_t size; -+}; -+ - struct device_node; - struct rproc; - struct pruss; -@@ -47,6 +69,10 @@ struct pruss; ++#include + #include + #include + #include +@@ -41,6 +42,8 @@ struct pruss_mem_region { + * @cfg_base: base iomap for CFG region + * @cfg_regmap: regmap for config region + * @mem_regions: data for each of the PRUSS memory regions ++ * @mem_in_use: to indicate if memory resource is in use ++ * @lock: mutex to serialize access to resources + * @core_clk_mux: clk handle for PRUSS CORE_CLK_MUX + * @iep_clk_mux: clk handle for PRUSS IEP_CLK_MUX + */ +@@ -49,6 +52,8 @@ struct pruss { + void __iomem *cfg_base; + struct regmap *cfg_regmap; + struct pruss_mem_region mem_regions[PRUSS_MEM_MAX]; ++ struct pruss_mem_region *mem_in_use[PRUSS_MEM_MAX]; ++ struct mutex lock; /* PRU resource lock */ + struct clk *core_clk_mux; + struct clk *iep_clk_mux; + }; +@@ -57,6 +62,10 @@ struct pruss { struct pruss *pruss_get(struct rproc *rproc); void pruss_put(struct pruss *pruss); @@ -160,7 +161,7 @@ index 2e1f519255b9..40de553d4446 100644 #else -@@ -57,6 +83,19 @@ static inline struct pruss *pruss_get(struct rproc *rproc) +@@ -67,6 +76,19 @@ static inline struct pruss *pruss_get(struct rproc *rproc) static inline void pruss_put(struct pruss *pruss) { } @@ -179,58 +180,7 @@ index 2e1f519255b9..40de553d4446 100644 + #endif /* CONFIG_TI_PRUSS */ - #if IS_ENABLED(CONFIG_PRU_REMOTEPROC) -diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h -index 4d1321f0d326..f1d1197fd91a 100644 ---- a/include/linux/pruss_driver.h -+++ b/include/linux/pruss_driver.h -@@ -9,37 +9,18 @@ - #ifndef _PRUSS_DRIVER_H_ - #define _PRUSS_DRIVER_H_ - -+#include - #include - #include - --/* -- * enum pruss_mem - PRUSS memory range identifiers -- */ --enum pruss_mem { -- PRUSS_MEM_DRAM0 = 0, -- PRUSS_MEM_DRAM1, -- PRUSS_MEM_SHRD_RAM2, -- PRUSS_MEM_MAX, --}; -- --/** -- * struct pruss_mem_region - PRUSS memory region structure -- * @va: kernel virtual address of the PRUSS memory region -- * @pa: physical (bus) address of the PRUSS memory region -- * @size: size of the PRUSS memory region -- */ --struct pruss_mem_region { -- void __iomem *va; -- phys_addr_t pa; -- size_t size; --}; -- - /** - * struct pruss - PRUSS parent structure - * @dev: pruss device pointer - * @cfg_base: base iomap for CFG region - * @cfg_regmap: regmap for config region - * @mem_regions: data for each of the PRUSS memory regions -+ * @mem_in_use: to indicate if memory resource is in use -+ * @lock: mutex to serialize access to resources - * @core_clk_mux: clk handle for PRUSS CORE_CLK_MUX - * @iep_clk_mux: clk handle for PRUSS IEP_CLK_MUX - */ -@@ -48,6 +29,8 @@ struct pruss { - void __iomem *cfg_base; - struct regmap *cfg_regmap; - struct pruss_mem_region mem_regions[PRUSS_MEM_MAX]; -+ struct pruss_mem_region *mem_in_use[PRUSS_MEM_MAX]; -+ struct mutex lock; /* PRU resource lock */ - struct clk *core_clk_mux; - struct clk *iep_clk_mux; - }; + #endif /* _PRUSS_DRIVER_H_ */ +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0013-soc-ti-pruss-Add-pruss_cfg_read-update-pruss_cfg_get.patch b/recipes-kernel/linux/files/patches-6.1/0013-soc-ti-pruss-Add-pruss_cfg_read-update-pruss_cfg_get.patch new file mode 100644 index 000000000..44b008cbe --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0013-soc-ti-pruss-Add-pruss_cfg_read-update-pruss_cfg_get.patch @@ -0,0 +1,251 @@ +From 70625908394ebaa768ad920230c5bdda799e70b6 Mon Sep 17 00:00:00 2001 +From: Suman Anna +Date: Fri, 14 Apr 2023 10:25:41 +0530 +Subject: [PATCH 13/76] soc: ti: pruss: Add pruss_cfg_read()/update(), + pruss_cfg_get_gpmux()/set_gpmux() APIs + +Add two new generic API pruss_cfg_read() and pruss_cfg_update() to +the PRUSS platform driver to read and program respectively a register +within the PRUSS CFG sub-module represented by a syscon driver. These +APIs are internal to PRUSS driver. + +Add two new helper functions pruss_cfg_get_gpmux() & pruss_cfg_set_gpmux() +to get and set the GP MUX mode for programming the PRUSS internal wrapper +mux functionality as needed by usecases. + +Various useful registers and macros for certain register bit-fields and +their values have also been added. + +Signed-off-by: Suman Anna +Co-developed-by: Grzegorz Jaszczyk +Signed-off-by: Grzegorz Jaszczyk +Signed-off-by: Puranjay Mohan +Reviewed-by: Roger Quadros +Reviewed-by: Tony Lindgren +Reviewed-by: Simon Horman +Acked-by: Mathieu Poirier +Signed-off-by: MD Danish Anwar +--- + drivers/soc/ti/pruss.c | 45 ++++++++++++++++++ + drivers/soc/ti/pruss.h | 88 ++++++++++++++++++++++++++++++++++++ + include/linux/pruss_driver.h | 32 +++++++++++++ + 3 files changed, 165 insertions(+) + create mode 100644 drivers/soc/ti/pruss.h + +diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c +index 8ada3758b31a..4ad6ccb039c8 100644 +--- a/drivers/soc/ti/pruss.c ++++ b/drivers/soc/ti/pruss.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include "pruss.h" + + /** + * struct pruss_private_data - PRUSS driver private data +@@ -168,6 +169,50 @@ int pruss_release_mem_region(struct pruss *pruss, + } + EXPORT_SYMBOL_GPL(pruss_release_mem_region); + ++/** ++ * pruss_cfg_get_gpmux() - get the current GPMUX value for a PRU device ++ * @pruss: pruss instance ++ * @pru_id: PRU identifier (0-1) ++ * @mux: pointer to store the current mux value into ++ * ++ * Return: 0 on success, or an error code otherwise ++ */ ++int pruss_cfg_get_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 *mux) ++{ ++ int ret; ++ u32 val; ++ ++ if (pru_id >= PRUSS_NUM_PRUS || !mux) ++ return -EINVAL; ++ ++ ret = pruss_cfg_read(pruss, PRUSS_CFG_GPCFG(pru_id), &val); ++ if (!ret) ++ *mux = (u8)((val & PRUSS_GPCFG_PRU_MUX_SEL_MASK) >> ++ PRUSS_GPCFG_PRU_MUX_SEL_SHIFT); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(pruss_cfg_get_gpmux); ++ ++/** ++ * pruss_cfg_set_gpmux() - set the GPMUX value for a PRU device ++ * @pruss: pruss instance ++ * @pru_id: PRU identifier (0-1) ++ * @mux: new mux value for PRU ++ * ++ * Return: 0 on success, or an error code otherwise ++ */ ++int pruss_cfg_set_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 mux) ++{ ++ if (mux >= PRUSS_GP_MUX_SEL_MAX || ++ pru_id >= PRUSS_NUM_PRUS) ++ return -EINVAL; ++ ++ return pruss_cfg_update(pruss, PRUSS_CFG_GPCFG(pru_id), ++ PRUSS_GPCFG_PRU_MUX_SEL_MASK, ++ (u32)mux << PRUSS_GPCFG_PRU_MUX_SEL_SHIFT); ++} ++EXPORT_SYMBOL_GPL(pruss_cfg_set_gpmux); ++ + static void pruss_of_free_clk_provider(void *data) + { + struct device_node *clk_mux_np = data; +diff --git a/drivers/soc/ti/pruss.h b/drivers/soc/ti/pruss.h +new file mode 100644 +index 000000000000..6c55987e0e55 +--- /dev/null ++++ b/drivers/soc/ti/pruss.h +@@ -0,0 +1,88 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * PRU-ICSS Subsystem user interfaces ++ * ++ * Copyright (C) 2015-2023 Texas Instruments Incorporated - http://www.ti.com ++ * MD Danish Anwar ++ */ ++ ++#ifndef _SOC_TI_PRUSS_H_ ++#define _SOC_TI_PRUSS_H_ ++ ++#include ++#include ++ ++/* ++ * PRU_ICSS_CFG registers ++ * SYSCFG, ISRP, ISP, IESP, IECP, SCRP applicable on AMxxxx devices only ++ */ ++#define PRUSS_CFG_REVID 0x00 ++#define PRUSS_CFG_SYSCFG 0x04 ++#define PRUSS_CFG_GPCFG(x) (0x08 + (x) * 4) ++#define PRUSS_CFG_CGR 0x10 ++#define PRUSS_CFG_ISRP 0x14 ++#define PRUSS_CFG_ISP 0x18 ++#define PRUSS_CFG_IESP 0x1C ++#define PRUSS_CFG_IECP 0x20 ++#define PRUSS_CFG_SCRP 0x24 ++#define PRUSS_CFG_PMAO 0x28 ++#define PRUSS_CFG_MII_RT 0x2C ++#define PRUSS_CFG_IEPCLK 0x30 ++#define PRUSS_CFG_SPP 0x34 ++#define PRUSS_CFG_PIN_MX 0x40 ++ ++/* PRUSS_GPCFG register bits */ ++#define PRUSS_GPCFG_PRU_GPI_MODE_MASK GENMASK(1, 0) ++#define PRUSS_GPCFG_PRU_GPI_MODE_SHIFT 0 ++ ++#define PRUSS_GPCFG_PRU_MUX_SEL_SHIFT 26 ++#define PRUSS_GPCFG_PRU_MUX_SEL_MASK GENMASK(29, 26) ++ ++/* PRUSS_MII_RT register bits */ ++#define PRUSS_MII_RT_EVENT_EN BIT(0) ++ ++/* PRUSS_SPP register bits */ ++#define PRUSS_SPP_XFER_SHIFT_EN BIT(1) ++#define PRUSS_SPP_PRU1_PAD_HP_EN BIT(0) ++#define PRUSS_SPP_RTU_XFR_SHIFT_EN BIT(3) ++ ++/** ++ * pruss_cfg_read() - read a PRUSS CFG sub-module register ++ * @pruss: the pruss instance handle ++ * @reg: register offset within the CFG sub-module ++ * @val: pointer to return the value in ++ * ++ * Reads a given register within the PRUSS CFG sub-module and ++ * returns it through the passed-in @val pointer ++ * ++ * Return: 0 on success, or an error code otherwise ++ */ ++static int pruss_cfg_read(struct pruss *pruss, unsigned int reg, unsigned int *val) ++{ ++ if (IS_ERR_OR_NULL(pruss)) ++ return -EINVAL; ++ ++ return regmap_read(pruss->cfg_regmap, reg, val); ++} ++ ++/** ++ * pruss_cfg_update() - configure a PRUSS CFG sub-module register ++ * @pruss: the pruss instance handle ++ * @reg: register offset within the CFG sub-module ++ * @mask: bit mask to use for programming the @val ++ * @val: value to write ++ * ++ * Programs a given register within the PRUSS CFG sub-module ++ * ++ * Return: 0 on success, or an error code otherwise ++ */ ++static int pruss_cfg_update(struct pruss *pruss, unsigned int reg, ++ unsigned int mask, unsigned int val) ++{ ++ if (IS_ERR_OR_NULL(pruss)) ++ return -EINVAL; ++ ++ return regmap_update_bits(pruss->cfg_regmap, reg, mask, val); ++} ++ ++#endif /* _SOC_TI_PRUSS_H_ */ +diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h +index c8f2e53b911b..5bb8897724a9 100644 +--- a/include/linux/pruss_driver.h ++++ b/include/linux/pruss_driver.h +@@ -14,6 +14,24 @@ + #include + #include + ++/* ++ * enum pruss_gp_mux_sel - PRUSS GPI/O Mux modes for the ++ * PRUSS_GPCFG0/1 registers ++ * ++ * NOTE: The below defines are the most common values, but there ++ * are some exceptions like on 66AK2G, where the RESERVED and MII2 ++ * values are interchanged. Also, this bit-field does not exist on ++ * AM335x SoCs ++ */ ++enum pruss_gp_mux_sel { ++ PRUSS_GP_MUX_SEL_GP, ++ PRUSS_GP_MUX_SEL_ENDAT, ++ PRUSS_GP_MUX_SEL_RESERVED, ++ PRUSS_GP_MUX_SEL_SD, ++ PRUSS_GP_MUX_SEL_MII2, ++ PRUSS_GP_MUX_SEL_MAX, ++}; ++ + /* + * enum pruss_mem - PRUSS memory range identifiers + */ +@@ -66,6 +84,8 @@ int pruss_request_mem_region(struct pruss *pruss, enum pruss_mem mem_id, + struct pruss_mem_region *region); + int pruss_release_mem_region(struct pruss *pruss, + struct pruss_mem_region *region); ++int pruss_cfg_get_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 *mux); ++int pruss_cfg_set_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 mux); + + #else + +@@ -89,6 +109,18 @@ static inline int pruss_release_mem_region(struct pruss *pruss, + return -EOPNOTSUPP; + } + ++static inline int pruss_cfg_get_gpmux(struct pruss *pruss, ++ enum pruss_pru_id pru_id, u8 *mux) ++{ ++ return ERR_PTR(-EOPNOTSUPP); ++} ++ ++static inline int pruss_cfg_set_gpmux(struct pruss *pruss, ++ enum pruss_pru_id pru_id, u8 mux) ++{ ++ return ERR_PTR(-EOPNOTSUPP); ++} ++ + #endif /* CONFIG_TI_PRUSS */ + + #endif /* _PRUSS_DRIVER_H_ */ +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0014-soc-ti-pruss-Add-helper-functions-to-set-GPI-mode-MI.patch b/recipes-kernel/linux/files/patches-6.1/0014-soc-ti-pruss-Add-helper-functions-to-set-GPI-mode-MI.patch new file mode 100644 index 000000000..0b7c44197 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0014-soc-ti-pruss-Add-helper-functions-to-set-GPI-mode-MI.patch @@ -0,0 +1,214 @@ +From cf97943faa6ad3966cf2ebd311fe3c42a6cf59ea Mon Sep 17 00:00:00 2001 +From: Suman Anna +Date: Fri, 14 Apr 2023 10:25:42 +0530 +Subject: [PATCH 14/76] soc: ti: pruss: Add helper functions to set GPI mode, + MII_RT_event and XFR + +The PRUSS CFG module is represented as a syscon node and is currently +managed by the PRUSS platform driver. Add easy accessor functions to set +GPI mode, MII_RT event enable/disable and XFR (XIN XOUT) enable/disable +to enable the PRUSS Ethernet usecase. These functions reuse the generic +pruss_cfg_update() API function. + +Signed-off-by: Suman Anna +Co-developed-by: Grzegorz Jaszczyk +Signed-off-by: Grzegorz Jaszczyk +Signed-off-by: Puranjay Mohan +Reviewed-by: Roger Quadros +Reviewed-by: Tony Lindgren +Reviewed-by: Simon Horman +Reviewed-by: Mathieu Poirier +Signed-off-by: MD Danish Anwar +--- + drivers/remoteproc/pru_rproc.c | 15 ------- + drivers/soc/ti/pruss.c | 71 ++++++++++++++++++++++++++++++++++ + include/linux/pruss_driver.h | 51 ++++++++++++++++++++++++ + 3 files changed, 122 insertions(+), 15 deletions(-) + +diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c +index b76db7fa693d..40fc8a7bf14b 100644 +--- a/drivers/remoteproc/pru_rproc.c ++++ b/drivers/remoteproc/pru_rproc.c +@@ -81,21 +81,6 @@ enum pru_iomem { + PRU_IOMEM_MAX, + }; + +-/** +- * enum pru_type - PRU core type identifier +- * +- * @PRU_TYPE_PRU: Programmable Real-time Unit +- * @PRU_TYPE_RTU: Auxiliary Programmable Real-Time Unit +- * @PRU_TYPE_TX_PRU: Transmit Programmable Real-Time Unit +- * @PRU_TYPE_MAX: just keep this one at the end +- */ +-enum pru_type { +- PRU_TYPE_PRU = 0, +- PRU_TYPE_RTU, +- PRU_TYPE_TX_PRU, +- PRU_TYPE_MAX, +-}; +- + /** + * struct pru_private_data - device data for a PRU core + * @type: type of the PRU core (PRU, RTU, Tx_PRU) +diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c +index 4ad6ccb039c8..f002fd9e79c6 100644 +--- a/drivers/soc/ti/pruss.c ++++ b/drivers/soc/ti/pruss.c +@@ -213,6 +213,77 @@ int pruss_cfg_set_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 mux) + } + EXPORT_SYMBOL_GPL(pruss_cfg_set_gpmux); + ++/** ++ * pruss_cfg_gpimode() - set the GPI mode of the PRU ++ * @pruss: the pruss instance handle ++ * @pru_id: id of the PRU core within the PRUSS ++ * @mode: GPI mode to set ++ * ++ * Sets the GPI mode for a given PRU by programming the ++ * corresponding PRUSS_CFG_GPCFGx register ++ * ++ * Return: 0 on success, or an error code otherwise ++ */ ++int pruss_cfg_gpimode(struct pruss *pruss, enum pruss_pru_id pru_id, ++ enum pruss_gpi_mode mode) ++{ ++ if (pru_id >= PRUSS_NUM_PRUS || mode >= PRUSS_GPI_MODE_MAX) ++ return -EINVAL; ++ ++ return pruss_cfg_update(pruss, PRUSS_CFG_GPCFG(pru_id), ++ PRUSS_GPCFG_PRU_GPI_MODE_MASK, ++ mode << PRUSS_GPCFG_PRU_GPI_MODE_SHIFT); ++} ++EXPORT_SYMBOL_GPL(pruss_cfg_gpimode); ++ ++/** ++ * pruss_cfg_miirt_enable() - Enable/disable MII RT Events ++ * @pruss: the pruss instance ++ * @enable: enable/disable ++ * ++ * Enable/disable the MII RT Events for the PRUSS. ++ * ++ * Return: 0 on success, or an error code otherwise ++ */ ++int pruss_cfg_miirt_enable(struct pruss *pruss, bool enable) ++{ ++ u32 set = enable ? PRUSS_MII_RT_EVENT_EN : 0; ++ ++ return pruss_cfg_update(pruss, PRUSS_CFG_MII_RT, ++ PRUSS_MII_RT_EVENT_EN, set); ++} ++EXPORT_SYMBOL_GPL(pruss_cfg_miirt_enable); ++ ++/** ++ * pruss_cfg_xfr_enable() - Enable/disable XIN XOUT shift functionality ++ * @pruss: the pruss instance ++ * @pru_type: PRU core type identifier ++ * @enable: enable/disable ++ * ++ * Return: 0 on success, or an error code otherwise ++ */ ++int pruss_cfg_xfr_enable(struct pruss *pruss, enum pru_type pru_type, ++ bool enable) ++{ ++ u32 mask, set; ++ ++ switch (pru_type) { ++ case PRU_TYPE_PRU: ++ mask = PRUSS_SPP_XFER_SHIFT_EN; ++ break; ++ case PRU_TYPE_RTU: ++ mask = PRUSS_SPP_RTU_XFR_SHIFT_EN; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ set = enable ? mask : 0; ++ ++ return pruss_cfg_update(pruss, PRUSS_CFG_SPP, mask, set); ++} ++EXPORT_SYMBOL_GPL(pruss_cfg_xfr_enable); ++ + static void pruss_of_free_clk_provider(void *data) + { + struct device_node *clk_mux_np = data; +diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h +index 5bb8897724a9..c9a31c567e85 100644 +--- a/include/linux/pruss_driver.h ++++ b/include/linux/pruss_driver.h +@@ -32,6 +32,33 @@ enum pruss_gp_mux_sel { + PRUSS_GP_MUX_SEL_MAX, + }; + ++/* ++ * enum pruss_gpi_mode - PRUSS GPI configuration modes, used ++ * to program the PRUSS_GPCFG0/1 registers ++ */ ++enum pruss_gpi_mode { ++ PRUSS_GPI_MODE_DIRECT, ++ PRUSS_GPI_MODE_PARALLEL, ++ PRUSS_GPI_MODE_28BIT_SHIFT, ++ PRUSS_GPI_MODE_MII, ++ PRUSS_GPI_MODE_MAX, ++}; ++ ++/** ++ * enum pru_type - PRU core type identifier ++ * ++ * @PRU_TYPE_PRU: Programmable Real-time Unit ++ * @PRU_TYPE_RTU: Auxiliary Programmable Real-Time Unit ++ * @PRU_TYPE_TX_PRU: Transmit Programmable Real-Time Unit ++ * @PRU_TYPE_MAX: just keep this one at the end ++ */ ++enum pru_type { ++ PRU_TYPE_PRU, ++ PRU_TYPE_RTU, ++ PRU_TYPE_TX_PRU, ++ PRU_TYPE_MAX, ++}; ++ + /* + * enum pruss_mem - PRUSS memory range identifiers + */ +@@ -86,6 +113,11 @@ int pruss_release_mem_region(struct pruss *pruss, + struct pruss_mem_region *region); + int pruss_cfg_get_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 *mux); + int pruss_cfg_set_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 mux); ++int pruss_cfg_gpimode(struct pruss *pruss, enum pruss_pru_id pru_id, ++ enum pruss_gpi_mode mode); ++int pruss_cfg_miirt_enable(struct pruss *pruss, bool enable); ++int pruss_cfg_xfr_enable(struct pruss *pruss, enum pru_type pru_type, ++ bool enable); + + #else + +@@ -121,6 +153,25 @@ static inline int pruss_cfg_set_gpmux(struct pruss *pruss, + return ERR_PTR(-EOPNOTSUPP); + } + ++static inline int pruss_cfg_gpimode(struct pruss *pruss, ++ enum pruss_pru_id pru_id, ++ enum pruss_gpi_mode mode) ++{ ++ return ERR_PTR(-EOPNOTSUPP); ++} ++ ++static inline int pruss_cfg_miirt_enable(struct pruss *pruss, bool enable) ++{ ++ return ERR_PTR(-EOPNOTSUPP); ++} ++ ++static inline int pruss_cfg_xfr_enable(struct pruss *pruss, ++ enum pru_type pru_type, ++ bool enable); ++{ ++ return ERR_PTR(-EOPNOTSUPP); ++} ++ + #endif /* CONFIG_TI_PRUSS */ + + #endif /* _PRUSS_DRIVER_H_ */ +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0069-remoteproc-pru-add-support-for-configuring-GPMUX-bas.patch b/recipes-kernel/linux/files/patches-6.1/0015-remoteproc-pru-add-support-for-configuring-GPMUX-bas.patch similarity index 62% rename from recipes-kernel/linux/files/patches-5.10/0069-remoteproc-pru-add-support-for-configuring-GPMUX-bas.patch rename to recipes-kernel/linux/files/patches-6.1/0015-remoteproc-pru-add-support-for-configuring-GPMUX-bas.patch index 374a8565f..50b3ff432 100644 --- a/recipes-kernel/linux/files/patches-5.10/0069-remoteproc-pru-add-support-for-configuring-GPMUX-bas.patch +++ b/recipes-kernel/linux/files/patches-6.1/0015-remoteproc-pru-add-support-for-configuring-GPMUX-bas.patch @@ -1,24 +1,24 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 061ead2437c27f6e166d3b0b3522e523bcbfdbec Mon Sep 17 00:00:00 2001 From: Tero Kristo -Date: Sat, 27 Mar 2021 10:11:42 -0500 -Subject: [PATCH] remoteproc/pru: add support for configuring GPMUX based on - client setup +Date: Wed, 2 Aug 2023 12:19:25 +0530 +Subject: [PATCH 15/76] remoteproc: pru: add support for configuring GPMUX + based on client setup -Client device node property ti,pruss-gp-mux-sel can now be used to -configure the GPMUX config value for PRU. +The GPMUX config value for a PRU device can now be configured by client +by specifying it in the device node ti,pruss-gp-mux-sel. Signed-off-by: Tero Kristo -[s-anna@ti.com: simplify the pru id usage] Signed-off-by: Suman Anna +Signed-off-by: MD Danish Anwar --- - drivers/remoteproc/pru_rproc.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) + drivers/remoteproc/pru_rproc.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c -index c346899d5e3b..7ef176170b18 100644 +index 40fc8a7bf14b..a312a8bfdb86 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c -@@ -122,6 +122,7 @@ struct pru_private_data { +@@ -109,6 +109,7 @@ struct pru_private_data { * @dbg_single_step: debug state variable to set PRU into single step mode * @dbg_continuous: debug state variable to restore PRU execution mode * @evt_count: number of mapped events @@ -26,7 +26,7 @@ index c346899d5e3b..7ef176170b18 100644 */ struct pru_rproc { int id; -@@ -140,6 +141,7 @@ struct pru_rproc { +@@ -127,6 +128,7 @@ struct pru_rproc { u32 dbg_single_step; u32 dbg_continuous; u8 evt_count; @@ -34,17 +34,17 @@ index c346899d5e3b..7ef176170b18 100644 }; static inline u32 pru_control_read_reg(struct pru_rproc *pru, unsigned int reg) -@@ -249,6 +251,7 @@ struct rproc *pru_rproc_get(struct device_node *np, int index, - const char *fw_name; +@@ -228,6 +230,7 @@ struct rproc *pru_rproc_get(struct device_node *np, int index, struct device *dev; + const char *fw_name; int ret; + u32 mux; rproc = __pru_rproc_get(np, index); if (IS_ERR(rproc)) -@@ -270,6 +273,22 @@ struct rproc *pru_rproc_get(struct device_node *np, int index, - - mutex_unlock(&pru->lock); +@@ -252,6 +255,23 @@ struct rproc *pru_rproc_get(struct device_node *np, int index, + if (pru_id) + *pru_id = pru->id; + ret = pruss_cfg_get_gpmux(pru->pruss, pru->id, &pru->gpmux_save); + if (ret) { @@ -52,6 +52,7 @@ index c346899d5e3b..7ef176170b18 100644 + goto err; + } + ++ /* An error here is acceptable for backward compatibility */ + ret = of_property_read_u32_index(np, "ti,pruss-gp-mux-sel", index, + &mux); + if (!ret) { @@ -65,12 +66,15 @@ index c346899d5e3b..7ef176170b18 100644 ret = of_property_read_string_index(np, "firmware-name", index, &fw_name); if (!ret) { -@@ -309,6 +328,8 @@ void pru_rproc_put(struct rproc *rproc) - if (!pru->client_np) - return; +@@ -290,6 +310,8 @@ void pru_rproc_put(struct rproc *rproc) + + pru = rproc->priv; + pruss_cfg_set_gpmux(pru->pruss, pru->id, pru->gpmux_save); + pru_rproc_set_firmware(rproc, NULL); mutex_lock(&pru->lock); +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0016-net-ti-icssg-prueth-Add-Firmware-Interface-for-ICSSG.patch b/recipes-kernel/linux/files/patches-6.1/0016-net-ti-icssg-prueth-Add-Firmware-Interface-for-ICSSG.patch new file mode 100644 index 000000000..a1fbd1f25 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0016-net-ti-icssg-prueth-Add-Firmware-Interface-for-ICSSG.patch @@ -0,0 +1,259 @@ +From 5333dc42367e8e4cf1c87b8bb9bfa965a335c357 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Tue, 1 Aug 2023 14:44:19 +0530 +Subject: [PATCH 16/76] net: ti: icssg-prueth: Add Firmware Interface for ICSSG + Ethernet driver. + +Add firmware interface related headers and macros for ICSSG Ethernet +driver. These macros will be later used by the ICSSG ethernet driver. + +Reviewed-by: Andrew Lunn +Signed-off-by: MD Danish Anwar +--- + .../net/ethernet/ti/icssg/icssg_switch_map.h | 234 ++++++++++++++++++ + 1 file changed, 234 insertions(+) + create mode 100644 drivers/net/ethernet/ti/icssg/icssg_switch_map.h + +diff --git a/drivers/net/ethernet/ti/icssg/icssg_switch_map.h b/drivers/net/ethernet/ti/icssg/icssg_switch_map.h +new file mode 100644 +index 000000000000..424a7e945ea8 +--- /dev/null ++++ b/drivers/net/ethernet/ti/icssg/icssg_switch_map.h +@@ -0,0 +1,234 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* Texas Instruments ICSSG Ethernet driver ++ * ++ * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/ ++ * ++ */ ++ ++#ifndef __NET_TI_ICSSG_SWITCH_MAP_H ++#define __NET_TI_ICSSG_SWITCH_MAP_H ++ ++/************************* Ethernet Switch Constants *********************/ ++ ++/* if bucket size is changed in firmware then this too should be changed ++ * because it directly impacts FDB ageing calculation ++ */ ++#define NUMBER_OF_FDB_BUCKET_ENTRIES (4) ++ ++/* This is fixed in ICSSG */ ++#define SIZE_OF_FDB (2048) ++ ++#define FW_LINK_SPEED_1G (0x00) ++#define FW_LINK_SPEED_100M (0x01) ++#define FW_LINK_SPEED_10M (0x02) ++#define FW_LINK_SPEED_HD (0x80) ++ ++/* Time after which FDB entries are checked for aged out values. ++ * Values are in nanoseconds ++ */ ++#define FDB_AGEING_TIMEOUT_OFFSET 0x0014 ++ ++/* Default VLAN tag for Host Port */ ++#define HOST_PORT_DF_VLAN_OFFSET 0x001C ++ ++/* Same as HOST_PORT_DF_VLAN_OFFSET */ ++#define EMAC_ICSSG_SWITCH_PORT0_DEFAULT_VLAN_OFFSET HOST_PORT_DF_VLAN_OFFSET ++ ++/* Default VLAN tag for P1 Port */ ++#define P1_PORT_DF_VLAN_OFFSET 0x0020 ++ ++/* Same as P1_PORT_DF_VLAN_OFFSET */ ++#define EMAC_ICSSG_SWITCH_PORT1_DEFAULT_VLAN_OFFSET P1_PORT_DF_VLAN_OFFSET ++ ++/* default VLAN tag for P2 Port */ ++#define P2_PORT_DF_VLAN_OFFSET 0x0024 ++ ++/* Same as P2_PORT_DF_VLAN_OFFSET */ ++#define EMAC_ICSSG_SWITCH_PORT2_DEFAULT_VLAN_OFFSET P2_PORT_DF_VLAN_OFFSET ++ ++/* VLAN-FID Table offset. 4096 VIDs. 2B per VID = 8KB = 0x2000 */ ++#define VLAN_STATIC_REG_TABLE_OFFSET 0x0100 ++ ++/* VLAN-FID Table offset for EMAC */ ++#define EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET VLAN_STATIC_REG_TABLE_OFFSET ++ ++/* Packet descriptor Q reserved memory */ ++#define PORT_DESC0_HI 0x2104 ++ ++/* Packet descriptor Q reserved memory */ ++#define PORT_DESC0_LO 0x2F6C ++ ++/* Packet descriptor Q reserved memory */ ++#define PORT_DESC1_HI 0x3DD4 ++ ++/* Packet descriptor Q reserved memory */ ++#define PORT_DESC1_LO 0x4C3C ++ ++/* Packet descriptor Q reserved memory */ ++#define HOST_DESC0_HI 0x5AA4 ++ ++/* Packet descriptor Q reserved memory */ ++#define HOST_DESC0_LO 0x5F0C ++ ++/* Packet descriptor Q reserved memory */ ++#define HOST_DESC1_HI 0x6374 ++ ++/* Packet descriptor Q reserved memory */ ++#define HOST_DESC1_LO 0x67DC ++ ++/* Special packet descriptor Q reserved memory */ ++#define HOST_SPPD0 0x7AAC ++ ++/* Special acket descriptor Q reserved memory */ ++#define HOST_SPPD1 0x7EAC ++ ++/* IEP count cycle counter*/ ++#define TIMESYNC_FW_WC_CYCLECOUNT_OFFSET 0x83EC ++ ++/* IEP count hi roll over count */ ++#define TIMESYNC_FW_WC_HI_ROLLOVER_COUNT_OFFSET 0x83F4 ++ ++/* IEP count hi sw counter */ ++#define TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET 0x83F8 ++ ++/* Set clock descriptor */ ++#define TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET 0x83FC ++ ++/* IEP count syncout reduction factor */ ++#define TIMESYNC_FW_WC_SYNCOUT_REDUCTION_FACTOR_OFFSET 0x843C ++ ++/* IEP count syncout reduction counter */ ++#define TIMESYNC_FW_WC_SYNCOUT_REDUCTION_COUNT_OFFSET 0x8440 ++ ++/* IEP count syncout start time cycle counter */ ++#define TIMESYNC_FW_WC_SYNCOUT_START_TIME_CYCLECOUNT_OFFSET 0x8444 ++ ++/* Control variable to generate SYNC1 */ ++#define TIMESYNC_FW_WC_ISOM_PIN_SIGNAL_EN_OFFSET 0x844C ++ ++/* SystemTime Sync0 periodicity */ ++#define TIMESYNC_FW_ST_SYNCOUT_PERIOD_OFFSET 0x8450 ++ ++/* pktTxDelay for P1 = link speed dependent p1 mac delay + p1 phy delay */ ++#define TIMESYNC_FW_WC_PKTTXDELAY_P1_OFFSET 0x8454 ++ ++/* pktTxDelay for P2 = link speed dependent p2 mac delay + p2 phy delay */ ++#define TIMESYNC_FW_WC_PKTTXDELAY_P2_OFFSET 0x8458 ++ ++/* Set clock operation done signal for next task */ ++#define TIMESYNC_FW_SIG_PNFW_OFFSET 0x845C ++ ++/* Set clock operation done signal for next task */ ++#define TIMESYNC_FW_SIG_TIMESYNCFW_OFFSET 0x8460 ++ ++/* New list is copied at this time */ ++#define TAS_CONFIG_CHANGE_TIME 0x000C ++ ++/* config change error counter */ ++#define TAS_CONFIG_CHANGE_ERROR_COUNTER 0x0014 ++ ++/* TAS List update pending flag */ ++#define TAS_CONFIG_PENDING 0x0018 ++ ++/* TAS list update trigger flag */ ++#define TAS_CONFIG_CHANGE 0x0019 ++ ++/* List length for new TAS schedule */ ++#define TAS_ADMIN_LIST_LENGTH 0x001A ++ ++/* Currently active TAS list index */ ++#define TAS_ACTIVE_LIST_INDEX 0x001B ++ ++/* Cycle time for the new TAS schedule */ ++#define TAS_ADMIN_CYCLE_TIME 0x001C ++ ++/* Cycle counts remaining till the TAS list update */ ++#define TAS_CONFIG_CHANGE_CYCLE_COUNT 0x0020 ++ ++/* Base Flow ID for sending Packets to Host for Slice0 */ ++#define PSI_L_REGULAR_FLOW_ID_BASE_OFFSET 0x0024 ++ ++/* Same as PSI_L_REGULAR_FLOW_ID_BASE_OFFSET */ ++#define EMAC_ICSSG_SWITCH_PSI_L_REGULAR_FLOW_ID_BASE_OFFSET PSI_L_REGULAR_FLOW_ID_BASE_OFFSET ++ ++/* Base Flow ID for sending mgmt and Tx TS to Host for Slice0 */ ++#define PSI_L_MGMT_FLOW_ID_OFFSET 0x0026 ++ ++/* Same as PSI_L_MGMT_FLOW_ID_OFFSET */ ++#define EMAC_ICSSG_SWITCH_PSI_L_MGMT_FLOW_ID_BASE_OFFSET PSI_L_MGMT_FLOW_ID_OFFSET ++ ++/* Queue number for Special Packets written here */ ++#define SPL_PKT_DEFAULT_PRIORITY 0x0028 ++ ++/* Express Preemptible Queue Mask */ ++#define EXPRESS_PRE_EMPTIVE_Q_MASK 0x0029 ++ ++/* Port1/Port2 Default Queue number for untagged Packets, only 1B is used */ ++#define QUEUE_NUM_UNTAGGED 0x002A ++ ++/* Stores the table used for priority regeneration. 1B per PCP/Queue */ ++#define PORT_Q_PRIORITY_REGEN_OFFSET 0x002C ++ ++/* For marking Packet as priority/express (this feature is disabled) or ++ * cut-through/S&F. ++ */ ++#define EXPRESS_PRE_EMPTIVE_Q_MAP 0x0034 ++ ++/* Stores the table used for priority mapping. 1B per PCP/Queue */ ++#define PORT_Q_PRIORITY_MAPPING_OFFSET 0x003C ++ ++/* Used to notify the FW of the current link speed */ ++#define PORT_LINK_SPEED_OFFSET 0x00A8 ++ ++/* TAS gate mask for windows list0 */ ++#define TAS_GATE_MASK_LIST0 0x0100 ++ ++/* TAS gate mask for windows list1 */ ++#define TAS_GATE_MASK_LIST1 0x0350 ++ ++/* Memory to Enable/Disable Preemption on TX side */ ++#define PRE_EMPTION_ENABLE_TX 0x05A0 ++ ++/* Active State of Preemption on TX side */ ++#define PRE_EMPTION_ACTIVE_TX 0x05A1 ++ ++/* Memory to Enable/Disable Verify State Machine Preemption */ ++#define PRE_EMPTION_ENABLE_VERIFY 0x05A2 ++ ++/* Verify Status of State Machine */ ++#define PRE_EMPTION_VERIFY_STATUS 0x05A3 ++ ++/* Non Final Fragment Size supported by Link Partner */ ++#define PRE_EMPTION_ADD_FRAG_SIZE_REMOTE 0x05A4 ++ ++/* Non Final Fragment Size supported by Firmware */ ++#define PRE_EMPTION_ADD_FRAG_SIZE_LOCAL 0x05A6 ++ ++/* Time in ms the State machine waits for respond Packet */ ++#define PRE_EMPTION_VERIFY_TIME 0x05A8 ++ ++/* Memory used for R30 related management commands */ ++#define MGR_R30_CMD_OFFSET 0x05AC ++ ++/* HW Buffer Pool0 base address */ ++#define BUFFER_POOL_0_ADDR_OFFSET 0x05BC ++ ++/* 16B for Host Egress MSMC Q (Pre-emptible) context */ ++#define HOST_RX_Q_PRE_CONTEXT_OFFSET 0x0684 ++ ++/* Buffer for 8 FDB entries to be added by 'Add Multiple FDB entries IOCTL' */ ++#define FDB_CMD_BUFFER 0x0894 ++ ++/* TAS queue max sdu length list */ ++#define TAS_QUEUE_MAX_SDU_LIST 0x08FA ++ ++/* Used by FW to generate random number with the SEED value */ ++#define HD_RAND_SEED_OFFSET 0x0934 ++ ++/* 16B for Host Egress MSMC Q (Express) context */ ++#define HOST_RX_Q_EXP_CONTEXT_OFFSET 0x0940 ++ ++/* Start of 32 bits PA_STAT counters */ ++#define PA_STAT_32b_START_OFFSET 0x0080 ++ ++#endif /* __NET_TI_ICSSG_SWITCH_MAP_H */ +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0017-net-ti-icssg-prueth-Add-mii-helper-apis-and-macros.patch b/recipes-kernel/linux/files/patches-6.1/0017-net-ti-icssg-prueth-Add-mii-helper-apis-and-macros.patch new file mode 100644 index 000000000..d1547c5f3 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0017-net-ti-icssg-prueth-Add-mii-helper-apis-and-macros.patch @@ -0,0 +1,509 @@ +From 1a4c2171c75aa781e928b534f6e3ceeeb1e646bc Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Tue, 1 Aug 2023 14:44:20 +0530 +Subject: [PATCH 17/76] net: ti: icssg-prueth: Add mii helper apis and macros + +Add MII helper APIs and MACROs. These APIs and MACROs will be later used +by ICSSG Ethernet driver. Also introduce icssg_prueth.h which has +definition of prueth related structures. + +Reviewed-by: Andrew Lunn +Signed-off-by: MD Danish Anwar +--- + drivers/net/ethernet/ti/icssg/icssg_mii_cfg.c | 120 +++++++++++ + drivers/net/ethernet/ti/icssg/icssg_mii_rt.h | 151 ++++++++++++++ + drivers/net/ethernet/ti/icssg/icssg_prueth.h | 197 ++++++++++++++++++ + 3 files changed, 468 insertions(+) + create mode 100644 drivers/net/ethernet/ti/icssg/icssg_mii_cfg.c + create mode 100644 drivers/net/ethernet/ti/icssg/icssg_mii_rt.h + create mode 100644 drivers/net/ethernet/ti/icssg/icssg_prueth.h + +diff --git a/drivers/net/ethernet/ti/icssg/icssg_mii_cfg.c b/drivers/net/ethernet/ti/icssg/icssg_mii_cfg.c +new file mode 100644 +index 000000000000..92718ae40d7e +--- /dev/null ++++ b/drivers/net/ethernet/ti/icssg/icssg_mii_cfg.c +@@ -0,0 +1,120 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Texas Instruments ICSSG Ethernet Driver ++ * ++ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/ ++ * ++ */ ++ ++#include ++#include ++#include ++ ++#include "icssg_mii_rt.h" ++#include "icssg_prueth.h" ++ ++void icssg_mii_update_ipg(struct regmap *mii_rt, int mii, u32 ipg) ++{ ++ u32 val; ++ ++ if (mii == ICSS_MII0) { ++ regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG0, ipg); ++ } else { ++ regmap_read(mii_rt, PRUSS_MII_RT_TX_IPG0, &val); ++ regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG1, ipg); ++ regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG0, val); ++ } ++} ++ ++void icssg_mii_update_mtu(struct regmap *mii_rt, int mii, int mtu) ++{ ++ mtu += (ETH_HLEN + ETH_FCS_LEN); ++ if (mii == ICSS_MII0) { ++ regmap_update_bits(mii_rt, ++ PRUSS_MII_RT_RX_FRMS0, ++ PRUSS_MII_RT_RX_FRMS_MAX_FRM_MASK, ++ (mtu - 1) << PRUSS_MII_RT_RX_FRMS_MAX_FRM_SHIFT); ++ } else { ++ regmap_update_bits(mii_rt, ++ PRUSS_MII_RT_RX_FRMS1, ++ PRUSS_MII_RT_RX_FRMS_MAX_FRM_MASK, ++ (mtu - 1) << PRUSS_MII_RT_RX_FRMS_MAX_FRM_SHIFT); ++ } ++} ++ ++void icssg_update_rgmii_cfg(struct regmap *miig_rt, struct prueth_emac *emac) ++{ ++ u32 gig_en_mask, gig_val = 0, full_duplex_mask, full_duplex_val = 0; ++ int slice = prueth_emac_slice(emac); ++ u32 inband_en_mask, inband_val = 0; ++ ++ gig_en_mask = (slice == ICSS_MII0) ? RGMII_CFG_GIG_EN_MII0 : ++ RGMII_CFG_GIG_EN_MII1; ++ if (emac->speed == SPEED_1000) ++ gig_val = gig_en_mask; ++ regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, gig_en_mask, gig_val); ++ ++ inband_en_mask = (slice == ICSS_MII0) ? RGMII_CFG_INBAND_EN_MII0 : ++ RGMII_CFG_INBAND_EN_MII1; ++ if (emac->speed == SPEED_10 && phy_interface_mode_is_rgmii(emac->phy_if)) ++ inband_val = inband_en_mask; ++ regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, inband_en_mask, inband_val); ++ ++ full_duplex_mask = (slice == ICSS_MII0) ? RGMII_CFG_FULL_DUPLEX_MII0 : ++ RGMII_CFG_FULL_DUPLEX_MII1; ++ if (emac->duplex == DUPLEX_FULL) ++ full_duplex_val = full_duplex_mask; ++ regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, full_duplex_mask, ++ full_duplex_val); ++} ++ ++void icssg_miig_set_interface_mode(struct regmap *miig_rt, int mii, phy_interface_t phy_if) ++{ ++ u32 val, mask, shift; ++ ++ mask = mii == ICSS_MII0 ? ICSSG_CFG_MII0_MODE : ICSSG_CFG_MII1_MODE; ++ shift = mii == ICSS_MII0 ? ICSSG_CFG_MII0_MODE_SHIFT : ICSSG_CFG_MII1_MODE_SHIFT; ++ ++ val = MII_MODE_RGMII; ++ if (phy_if == PHY_INTERFACE_MODE_MII) ++ val = MII_MODE_MII; ++ ++ val <<= shift; ++ regmap_update_bits(miig_rt, ICSSG_CFG_OFFSET, mask, val); ++ regmap_read(miig_rt, ICSSG_CFG_OFFSET, &val); ++} ++ ++u32 icssg_rgmii_cfg_get_bitfield(struct regmap *miig_rt, u32 mask, u32 shift) ++{ ++ u32 val; ++ ++ regmap_read(miig_rt, RGMII_CFG_OFFSET, &val); ++ val &= mask; ++ val >>= shift; ++ ++ return val; ++} ++ ++u32 icssg_rgmii_get_speed(struct regmap *miig_rt, int mii) ++{ ++ u32 shift = RGMII_CFG_SPEED_MII0_SHIFT, mask = RGMII_CFG_SPEED_MII0; ++ ++ if (mii == ICSS_MII1) { ++ shift = RGMII_CFG_SPEED_MII1_SHIFT; ++ mask = RGMII_CFG_SPEED_MII1; ++ } ++ ++ return icssg_rgmii_cfg_get_bitfield(miig_rt, mask, shift); ++} ++ ++u32 icssg_rgmii_get_fullduplex(struct regmap *miig_rt, int mii) ++{ ++ u32 shift = RGMII_CFG_FULLDUPLEX_MII0_SHIFT; ++ u32 mask = RGMII_CFG_FULLDUPLEX_MII0; ++ ++ if (mii == ICSS_MII1) { ++ shift = RGMII_CFG_FULLDUPLEX_MII1_SHIFT; ++ mask = RGMII_CFG_FULLDUPLEX_MII1; ++ } ++ ++ return icssg_rgmii_cfg_get_bitfield(miig_rt, mask, shift); ++} +diff --git a/drivers/net/ethernet/ti/icssg/icssg_mii_rt.h b/drivers/net/ethernet/ti/icssg/icssg_mii_rt.h +new file mode 100644 +index 000000000000..55a59bf5299c +--- /dev/null ++++ b/drivers/net/ethernet/ti/icssg/icssg_mii_rt.h +@@ -0,0 +1,151 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++/* PRU-ICSS MII_RT register definitions ++ * ++ * Copyright (C) 2015-2022 Texas Instruments Incorporated - https://www.ti.com ++ */ ++ ++#ifndef __NET_PRUSS_MII_RT_H__ ++#define __NET_PRUSS_MII_RT_H__ ++ ++#include ++#include ++ ++/* PRUSS_MII_RT Registers */ ++#define PRUSS_MII_RT_RXCFG0 0x0 ++#define PRUSS_MII_RT_RXCFG1 0x4 ++#define PRUSS_MII_RT_TXCFG0 0x10 ++#define PRUSS_MII_RT_TXCFG1 0x14 ++#define PRUSS_MII_RT_TX_CRC0 0x20 ++#define PRUSS_MII_RT_TX_CRC1 0x24 ++#define PRUSS_MII_RT_TX_IPG0 0x30 ++#define PRUSS_MII_RT_TX_IPG1 0x34 ++#define PRUSS_MII_RT_PRS0 0x38 ++#define PRUSS_MII_RT_PRS1 0x3c ++#define PRUSS_MII_RT_RX_FRMS0 0x40 ++#define PRUSS_MII_RT_RX_FRMS1 0x44 ++#define PRUSS_MII_RT_RX_PCNT0 0x48 ++#define PRUSS_MII_RT_RX_PCNT1 0x4c ++#define PRUSS_MII_RT_RX_ERR0 0x50 ++#define PRUSS_MII_RT_RX_ERR1 0x54 ++ ++/* PRUSS_MII_RT_RXCFG0/1 bits */ ++#define PRUSS_MII_RT_RXCFG_RX_ENABLE BIT(0) ++#define PRUSS_MII_RT_RXCFG_RX_DATA_RDY_MODE_DIS BIT(1) ++#define PRUSS_MII_RT_RXCFG_RX_CUT_PREAMBLE BIT(2) ++#define PRUSS_MII_RT_RXCFG_RX_MUX_SEL BIT(3) ++#define PRUSS_MII_RT_RXCFG_RX_L2_EN BIT(4) ++#define PRUSS_MII_RT_RXCFG_RX_BYTE_SWAP BIT(5) ++#define PRUSS_MII_RT_RXCFG_RX_AUTO_FWD_PRE BIT(6) ++#define PRUSS_MII_RT_RXCFG_RX_L2_EOF_SCLR_DIS BIT(9) ++ ++/* PRUSS_MII_RT_TXCFG0/1 bits */ ++#define PRUSS_MII_RT_TXCFG_TX_ENABLE BIT(0) ++#define PRUSS_MII_RT_TXCFG_TX_AUTO_PREAMBLE BIT(1) ++#define PRUSS_MII_RT_TXCFG_TX_EN_MODE BIT(2) ++#define PRUSS_MII_RT_TXCFG_TX_BYTE_SWAP BIT(3) ++#define PRUSS_MII_RT_TXCFG_TX_MUX_SEL BIT(8) ++#define PRUSS_MII_RT_TXCFG_PRE_TX_AUTO_SEQUENCE BIT(9) ++#define PRUSS_MII_RT_TXCFG_PRE_TX_AUTO_ESC_ERR BIT(10) ++#define PRUSS_MII_RT_TXCFG_TX_32_MODE_EN BIT(11) ++#define PRUSS_MII_RT_TXCFG_TX_IPG_WIRE_CLK_EN BIT(12) /* SR2.0 onwards */ ++ ++#define PRUSS_MII_RT_TXCFG_TX_START_DELAY_SHIFT 16 ++#define PRUSS_MII_RT_TXCFG_TX_START_DELAY_MASK GENMASK(25, 16) ++ ++#define PRUSS_MII_RT_TXCFG_TX_CLK_DELAY_SHIFT 28 ++#define PRUSS_MII_RT_TXCFG_TX_CLK_DELAY_MASK GENMASK(30, 28) ++ ++/* PRUSS_MII_RT_TX_IPG0/1 bits */ ++#define PRUSS_MII_RT_TX_IPG_IPG_SHIFT 0 ++#define PRUSS_MII_RT_TX_IPG_IPG_MASK GENMASK(9, 0) ++ ++/* PRUSS_MII_RT_PRS0/1 bits */ ++#define PRUSS_MII_RT_PRS_COL BIT(0) ++#define PRUSS_MII_RT_PRS_CRS BIT(1) ++ ++/* PRUSS_MII_RT_RX_FRMS0/1 bits */ ++#define PRUSS_MII_RT_RX_FRMS_MIN_FRM_SHIFT 0 ++#define PRUSS_MII_RT_RX_FRMS_MIN_FRM_MASK GENMASK(15, 0) ++ ++#define PRUSS_MII_RT_RX_FRMS_MAX_FRM_SHIFT 16 ++#define PRUSS_MII_RT_RX_FRMS_MAX_FRM_MASK GENMASK(31, 16) ++ ++/* Min/Max in MII_RT_RX_FRMS */ ++/* For EMAC and Switch */ ++#define PRUSS_MII_RT_RX_FRMS_MAX (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) ++#define PRUSS_MII_RT_RX_FRMS_MIN_FRM (64) ++ ++/* for HSR and PRP */ ++#define PRUSS_MII_RT_RX_FRMS_MAX_FRM_LRE (PRUSS_MII_RT_RX_FRMS_MAX + \ ++ ICSS_LRE_TAG_RCT_SIZE) ++/* PRUSS_MII_RT_RX_PCNT0/1 bits */ ++#define PRUSS_MII_RT_RX_PCNT_MIN_PCNT_SHIFT 0 ++#define PRUSS_MII_RT_RX_PCNT_MIN_PCNT_MASK GENMASK(3, 0) ++ ++#define PRUSS_MII_RT_RX_PCNT_MAX_PCNT_SHIFT 4 ++#define PRUSS_MII_RT_RX_PCNT_MAX_PCNT_MASK GENMASK(7, 4) ++ ++/* PRUSS_MII_RT_RX_ERR0/1 bits */ ++#define PRUSS_MII_RT_RX_ERR_MIN_PCNT_ERR BIT(0) ++#define PRUSS_MII_RT_RX_ERR_MAX_PCNT_ERR BIT(1) ++#define PRUSS_MII_RT_RX_ERR_MIN_FRM_ERR BIT(2) ++#define PRUSS_MII_RT_RX_ERR_MAX_FRM_ERR BIT(3) ++ ++#define ICSSG_CFG_OFFSET 0 ++#define RGMII_CFG_OFFSET 4 ++ ++/* Constant to choose between MII0 and MII1 */ ++#define ICSS_MII0 0 ++#define ICSS_MII1 1 ++ ++/* ICSSG_CFG Register bits */ ++#define ICSSG_CFG_SGMII_MODE BIT(16) ++#define ICSSG_CFG_TX_PRU_EN BIT(11) ++#define ICSSG_CFG_RX_SFD_TX_SOF_EN BIT(10) ++#define ICSSG_CFG_RTU_PRU_PSI_SHARE_EN BIT(9) ++#define ICSSG_CFG_IEP1_TX_EN BIT(8) ++#define ICSSG_CFG_MII1_MODE GENMASK(6, 5) ++#define ICSSG_CFG_MII1_MODE_SHIFT 5 ++#define ICSSG_CFG_MII0_MODE GENMASK(4, 3) ++#define ICSSG_CFG_MII0_MODE_SHIFT 3 ++#define ICSSG_CFG_RX_L2_G_EN BIT(2) ++#define ICSSG_CFG_TX_L2_EN BIT(1) ++#define ICSSG_CFG_TX_L1_EN BIT(0) ++ ++enum mii_mode { ++ MII_MODE_MII = 0, ++ MII_MODE_RGMII ++}; ++ ++/* RGMII CFG Register bits */ ++#define RGMII_CFG_INBAND_EN_MII0 BIT(16) ++#define RGMII_CFG_GIG_EN_MII0 BIT(17) ++#define RGMII_CFG_INBAND_EN_MII1 BIT(20) ++#define RGMII_CFG_GIG_EN_MII1 BIT(21) ++#define RGMII_CFG_FULL_DUPLEX_MII0 BIT(18) ++#define RGMII_CFG_FULL_DUPLEX_MII1 BIT(22) ++#define RGMII_CFG_SPEED_MII0 GENMASK(2, 1) ++#define RGMII_CFG_SPEED_MII1 GENMASK(6, 5) ++#define RGMII_CFG_SPEED_MII0_SHIFT 1 ++#define RGMII_CFG_SPEED_MII1_SHIFT 5 ++#define RGMII_CFG_FULLDUPLEX_MII0 BIT(3) ++#define RGMII_CFG_FULLDUPLEX_MII1 BIT(7) ++#define RGMII_CFG_FULLDUPLEX_MII0_SHIFT 3 ++#define RGMII_CFG_FULLDUPLEX_MII1_SHIFT 7 ++#define RGMII_CFG_SPEED_10M 0 ++#define RGMII_CFG_SPEED_100M 1 ++#define RGMII_CFG_SPEED_1G 2 ++ ++struct regmap; ++struct prueth_emac; ++ ++void icssg_mii_update_ipg(struct regmap *mii_rt, int mii, u32 ipg); ++void icssg_mii_update_mtu(struct regmap *mii_rt, int mii, int mtu); ++void icssg_update_rgmii_cfg(struct regmap *miig_rt, struct prueth_emac *emac); ++u32 icssg_rgmii_cfg_get_bitfield(struct regmap *miig_rt, u32 mask, u32 shift); ++u32 icssg_rgmii_get_speed(struct regmap *miig_rt, int mii); ++u32 icssg_rgmii_get_fullduplex(struct regmap *miig_rt, int mii); ++void icssg_miig_set_interface_mode(struct regmap *miig_rt, int mii, phy_interface_t phy_if); ++ ++#endif /* __NET_PRUSS_MII_RT_H__ */ +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +new file mode 100644 +index 000000000000..8512f19a9b4d +--- /dev/null ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +@@ -0,0 +1,197 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* Texas Instruments ICSSG Ethernet driver ++ * ++ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/ ++ * ++ */ ++ ++#ifndef __NET_TI_ICSSG_PRUETH_H ++#define __NET_TI_ICSSG_PRUETH_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++#include "icssg_switch_map.h" ++ ++#define ICSS_SLICE0 0 ++#define ICSS_SLICE1 1 ++ ++#define ICSSG_MAX_RFLOWS 8 /* per slice */ ++ ++/* In switch mode there are 3 real ports i.e. 3 mac addrs. ++ * however Linux sees only the host side port. The other 2 ports ++ * are the switch ports. ++ * In emac mode there are 2 real ports i.e. 2 mac addrs. ++ * Linux sees both the ports. ++ */ ++enum prueth_port { ++ PRUETH_PORT_HOST = 0, /* host side port */ ++ PRUETH_PORT_MII0, /* physical port RG/SG MII 0 */ ++ PRUETH_PORT_MII1, /* physical port RG/SG MII 1 */ ++ PRUETH_PORT_INVALID, /* Invalid prueth port */ ++}; ++ ++enum prueth_mac { ++ PRUETH_MAC0 = 0, ++ PRUETH_MAC1, ++ PRUETH_NUM_MACS, ++ PRUETH_MAC_INVALID, ++}; ++ ++struct prueth_tx_chn { ++ struct device *dma_dev; ++ struct napi_struct napi_tx; ++ struct k3_cppi_desc_pool *desc_pool; ++ struct k3_udma_glue_tx_channel *tx_chn; ++ struct prueth_emac *emac; ++ u32 id; ++ u32 descs_num; ++ unsigned int irq; ++ char name[32]; ++}; ++ ++struct prueth_rx_chn { ++ struct device *dev; ++ struct device *dma_dev; ++ struct k3_cppi_desc_pool *desc_pool; ++ struct k3_udma_glue_rx_channel *rx_chn; ++ u32 descs_num; ++ unsigned int irq[ICSSG_MAX_RFLOWS]; /* separate irq per flow */ ++ char name[32]; ++}; ++ ++/* There are 4 Tx DMA channels, but the highest priority is CH3 (thread 3) ++ * and lower three are lower priority channels or threads. ++ */ ++#define PRUETH_MAX_TX_QUEUES 4 ++ ++/* data for each emac port */ ++struct prueth_emac { ++ bool fw_running; ++ struct prueth *prueth; ++ struct net_device *ndev; ++ u8 mac_addr[6]; ++ struct napi_struct napi_rx; ++ u32 msg_enable; ++ ++ int link; ++ int speed; ++ int duplex; ++ ++ const char *phy_id; ++ struct device_node *phy_node; ++ phy_interface_t phy_if; ++ enum prueth_port port_id; ++ ++ /* DMA related */ ++ struct prueth_tx_chn tx_chns[PRUETH_MAX_TX_QUEUES]; ++ struct completion tdown_complete; ++ atomic_t tdown_cnt; ++ struct prueth_rx_chn rx_chns; ++ int rx_flow_id_base; ++ int tx_ch_num; ++ ++ spinlock_t lock; /* serialize access */ ++ ++ unsigned long state; ++ struct completion cmd_complete; ++ /* Mutex to serialize access to firmware command interface */ ++ struct mutex cmd_lock; ++ struct work_struct rx_mode_work; ++ struct workqueue_struct *cmd_wq; ++ ++ struct pruss_mem_region dram; ++}; ++ ++/** ++ * struct prueth_pdata - PRUeth platform data ++ * @fdqring_mode: Free desc queue mode ++ * @quirk_10m_link_issue: 10M link detect errata ++ */ ++struct prueth_pdata { ++ enum k3_ring_mode fdqring_mode; ++ u32 quirk_10m_link_issue:1; ++}; ++ ++/** ++ * struct prueth - PRUeth structure ++ * @dev: device ++ * @pruss: pruss handle ++ * @pru: rproc instances of PRUs ++ * @rtu: rproc instances of RTUs ++ * @txpru: rproc instances of TX_PRUs ++ * @shram: PRUSS shared RAM region ++ * @sram_pool: MSMC RAM pool for buffers ++ * @msmcram: MSMC RAM region ++ * @eth_node: DT node for the port ++ * @emac: private EMAC data structure ++ * @registered_netdevs: list of registered netdevs ++ * @miig_rt: regmap to mii_g_rt block ++ * @mii_rt: regmap to mii_rt block ++ * @pru_id: ID for each of the PRUs ++ * @pdev: pointer to ICSSG platform device ++ * @pdata: pointer to platform data for ICSSG driver ++ * @icssg_hwcmdseq: seq counter or HWQ messages ++ * @emacs_initialized: num of EMACs/ext ports that are up/running ++ */ ++struct prueth { ++ struct device *dev; ++ struct pruss *pruss; ++ struct rproc *pru[PRUSS_NUM_PRUS]; ++ struct rproc *rtu[PRUSS_NUM_PRUS]; ++ struct rproc *txpru[PRUSS_NUM_PRUS]; ++ struct pruss_mem_region shram; ++ struct gen_pool *sram_pool; ++ struct pruss_mem_region msmcram; ++ ++ struct device_node *eth_node[PRUETH_NUM_MACS]; ++ struct prueth_emac *emac[PRUETH_NUM_MACS]; ++ struct net_device *registered_netdevs[PRUETH_NUM_MACS]; ++ struct regmap *miig_rt; ++ struct regmap *mii_rt; ++ ++ enum pruss_pru_id pru_id[PRUSS_NUM_PRUS]; ++ struct platform_device *pdev; ++ struct prueth_pdata pdata; ++ u8 icssg_hwcmdseq; ++ ++ int emacs_initialized; ++}; ++ ++/* get PRUSS SLICE number from prueth_emac */ ++static inline int prueth_emac_slice(struct prueth_emac *emac) ++{ ++ switch (emac->port_id) { ++ case PRUETH_PORT_MII0: ++ return ICSS_SLICE0; ++ case PRUETH_PORT_MII1: ++ return ICSS_SLICE1; ++ default: ++ return -EINVAL; ++ } ++} ++ ++#endif /* __NET_TI_ICSSG_PRUETH_H */ +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0018-net-ti-icssg-prueth-Add-Firmware-config-and-classifi.patch b/recipes-kernel/linux/files/patches-6.1/0018-net-ti-icssg-prueth-Add-Firmware-config-and-classifi.patch new file mode 100644 index 000000000..04f7f368c --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0018-net-ti-icssg-prueth-Add-Firmware-config-and-classifi.patch @@ -0,0 +1,1084 @@ +From f35de8fafcf78f2ecba435adce215ba87d7ae154 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Tue, 1 Aug 2023 14:44:21 +0530 +Subject: [PATCH 18/76] net: ti: icssg-prueth: Add Firmware config and + classification APIs. + +Add icssg_config.h / .c and icssg_classifier.c files. These are firmware +configuration and classification related files. These will be used by +ICSSG ethernet driver. + +Reviewed-by: Andrew Lunn +Signed-off-by: MD Danish Anwar +--- + .../net/ethernet/ti/icssg/icssg_classifier.c | 367 ++++++++++++++ + drivers/net/ethernet/ti/icssg/icssg_config.c | 450 ++++++++++++++++++ + drivers/net/ethernet/ti/icssg/icssg_config.h | 200 ++++++++ + drivers/net/ethernet/ti/icssg/icssg_prueth.h | 15 + + 4 files changed, 1032 insertions(+) + create mode 100644 drivers/net/ethernet/ti/icssg/icssg_classifier.c + create mode 100644 drivers/net/ethernet/ti/icssg/icssg_config.c + create mode 100644 drivers/net/ethernet/ti/icssg/icssg_config.h + +diff --git a/drivers/net/ethernet/ti/icssg/icssg_classifier.c b/drivers/net/ethernet/ti/icssg/icssg_classifier.c +new file mode 100644 +index 000000000000..6df53ab17fbc +--- /dev/null ++++ b/drivers/net/ethernet/ti/icssg/icssg_classifier.c +@@ -0,0 +1,367 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Texas Instruments ICSSG Ethernet Driver ++ * ++ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/ ++ * ++ */ ++ ++#include ++#include ++#include ++ ++#include "icssg_prueth.h" ++ ++#define ICSSG_NUM_CLASSIFIERS 16 ++#define ICSSG_NUM_FT1_SLOTS 8 ++#define ICSSG_NUM_FT3_SLOTS 16 ++ ++#define ICSSG_NUM_CLASSIFIERS_IN_USE 5 ++ ++/* Filter 1 - FT1 */ ++#define FT1_NUM_SLOTS 8 ++#define FT1_SLOT_SIZE 0x10 /* bytes */ ++ ++/* offsets from FT1 slot base i.e. slot 1 start */ ++#define FT1_DA0 0x0 ++#define FT1_DA1 0x4 ++#define FT1_DA0_MASK 0x8 ++#define FT1_DA1_MASK 0xc ++ ++#define FT1_N_REG(slize, n, reg) \ ++ (offs[slice].ft1_slot_base + FT1_SLOT_SIZE * (n) + (reg)) ++ ++#define FT1_LEN_MASK GENMASK(19, 16) ++#define FT1_LEN_SHIFT 16 ++#define FT1_LEN(len) (((len) << FT1_LEN_SHIFT) & FT1_LEN_MASK) ++#define FT1_START_MASK GENMASK(14, 0) ++#define FT1_START(start) ((start) & FT1_START_MASK) ++#define FT1_MATCH_SLOT(n) (GENMASK(23, 16) & (BIT(n) << 16)) ++ ++/* FT1 config type */ ++enum ft1_cfg_type { ++ FT1_CFG_TYPE_DISABLED = 0, ++ FT1_CFG_TYPE_EQ, ++ FT1_CFG_TYPE_GT, ++ FT1_CFG_TYPE_LT, ++}; ++ ++#define FT1_CFG_SHIFT(n) (2 * (n)) ++#define FT1_CFG_MASK(n) (0x3 << FT1_CFG_SHIFT((n))) ++ ++/* Filter 3 - FT3 */ ++#define FT3_NUM_SLOTS 16 ++#define FT3_SLOT_SIZE 0x20 /* bytes */ ++ ++/* offsets from FT3 slot n's base */ ++#define FT3_START 0 ++#define FT3_START_AUTO 0x4 ++#define FT3_START_OFFSET 0x8 ++#define FT3_JUMP_OFFSET 0xc ++#define FT3_LEN 0x10 ++#define FT3_CFG 0x14 ++#define FT3_T 0x18 ++#define FT3_T_MASK 0x1c ++ ++#define FT3_N_REG(slize, n, reg) \ ++ (offs[slice].ft3_slot_base + FT3_SLOT_SIZE * (n) + (reg)) ++ ++/* offsets from rx_class n's base */ ++#define RX_CLASS_AND_EN 0 ++#define RX_CLASS_OR_EN 0x4 ++#define RX_CLASS_NUM_SLOTS 16 ++#define RX_CLASS_EN_SIZE 0x8 /* bytes */ ++ ++#define RX_CLASS_N_REG(slice, n, reg) \ ++ (offs[slice].rx_class_base + RX_CLASS_EN_SIZE * (n) + (reg)) ++ ++/* RX Class Gates */ ++#define RX_CLASS_GATES_SIZE 0x4 /* bytes */ ++ ++#define RX_CLASS_GATES_N_REG(slice, n) \ ++ (offs[slice].rx_class_gates_base + RX_CLASS_GATES_SIZE * (n)) ++ ++#define RX_CLASS_GATES_ALLOW_MASK BIT(6) ++#define RX_CLASS_GATES_RAW_MASK BIT(5) ++#define RX_CLASS_GATES_PHASE_MASK BIT(4) ++ ++/* RX Class traffic data matching bits */ ++#define RX_CLASS_FT_UC BIT(31) ++#define RX_CLASS_FT_MC BIT(30) ++#define RX_CLASS_FT_BC BIT(29) ++#define RX_CLASS_FT_FW BIT(28) ++#define RX_CLASS_FT_RCV BIT(27) ++#define RX_CLASS_FT_VLAN BIT(26) ++#define RX_CLASS_FT_DA_P BIT(25) ++#define RX_CLASS_FT_DA_I BIT(24) ++#define RX_CLASS_FT_FT1_MATCH_MASK GENMASK(23, 16) ++#define RX_CLASS_FT_FT1_MATCH_SHIFT 16 ++#define RX_CLASS_FT_FT3_MATCH_MASK GENMASK(15, 0) ++#define RX_CLASS_FT_FT3_MATCH_SHIFT 0 ++ ++#define RX_CLASS_FT_FT1_MATCH(slot) \ ++ ((BIT(slot) << RX_CLASS_FT_FT1_MATCH_SHIFT) & \ ++ RX_CLASS_FT_FT1_MATCH_MASK) ++ ++/* RX class type */ ++enum rx_class_sel_type { ++ RX_CLASS_SEL_TYPE_OR = 0, ++ RX_CLASS_SEL_TYPE_AND = 1, ++ RX_CLASS_SEL_TYPE_OR_AND_AND = 2, ++ RX_CLASS_SEL_TYPE_OR_OR_AND = 3, ++}; ++ ++#define FT1_CFG_SHIFT(n) (2 * (n)) ++#define FT1_CFG_MASK(n) (0x3 << FT1_CFG_SHIFT((n))) ++ ++#define RX_CLASS_SEL_SHIFT(n) (2 * (n)) ++#define RX_CLASS_SEL_MASK(n) (0x3 << RX_CLASS_SEL_SHIFT((n))) ++ ++#define ICSSG_CFG_OFFSET 0 ++#define MAC_INTERFACE_0 0x18 ++#define MAC_INTERFACE_1 0x1c ++ ++#define ICSSG_CFG_RX_L2_G_EN BIT(2) ++ ++/* These are register offsets per PRU */ ++struct miig_rt_offsets { ++ u32 mac0; ++ u32 mac1; ++ u32 ft1_start_len; ++ u32 ft1_cfg; ++ u32 ft1_slot_base; ++ u32 ft3_slot_base; ++ u32 ft3_p_base; ++ u32 ft_rx_ptr; ++ u32 rx_class_base; ++ u32 rx_class_cfg1; ++ u32 rx_class_cfg2; ++ u32 rx_class_gates_base; ++ u32 rx_green; ++ u32 rx_rate_cfg_base; ++ u32 rx_rate_src_sel0; ++ u32 rx_rate_src_sel1; ++ u32 tx_rate_cfg_base; ++ u32 stat_base; ++ u32 tx_hsr_tag; ++ u32 tx_hsr_seq; ++ u32 tx_vlan_type; ++ u32 tx_vlan_ins; ++}; ++ ++/* These are the offset values for miig_rt_offsets registers */ ++static const struct miig_rt_offsets offs[] = { ++ /* PRU0 */ ++ { ++ 0x8, ++ 0xc, ++ 0x80, ++ 0x84, ++ 0x88, ++ 0x108, ++ 0x308, ++ 0x408, ++ 0x40c, ++ 0x48c, ++ 0x490, ++ 0x494, ++ 0x4d4, ++ 0x4e4, ++ 0x504, ++ 0x508, ++ 0x50c, ++ 0x54c, ++ 0x63c, ++ 0x640, ++ 0x644, ++ 0x648, ++ }, ++ /* PRU1 */ ++ { ++ 0x10, ++ 0x14, ++ 0x64c, ++ 0x650, ++ 0x654, ++ 0x6d4, ++ 0x8d4, ++ 0x9d4, ++ 0x9d8, ++ 0xa58, ++ 0xa5c, ++ 0xa60, ++ 0xaa0, ++ 0xab0, ++ 0xad0, ++ 0xad4, ++ 0xad8, ++ 0xb18, ++ 0xc08, ++ 0xc0c, ++ 0xc10, ++ 0xc14, ++ }, ++}; ++ ++static void rx_class_ft1_set_start_len(struct regmap *miig_rt, int slice, ++ u16 start, u8 len) ++{ ++ u32 offset, val; ++ ++ offset = offs[slice].ft1_start_len; ++ val = FT1_LEN(len) | FT1_START(start); ++ regmap_write(miig_rt, offset, val); ++} ++ ++static void rx_class_ft1_set_da(struct regmap *miig_rt, int slice, ++ int n, const u8 *addr) ++{ ++ u32 offset; ++ ++ offset = FT1_N_REG(slice, n, FT1_DA0); ++ regmap_write(miig_rt, offset, (u32)(addr[0] | addr[1] << 8 | ++ addr[2] << 16 | addr[3] << 24)); ++ offset = FT1_N_REG(slice, n, FT1_DA1); ++ regmap_write(miig_rt, offset, (u32)(addr[4] | addr[5] << 8)); ++} ++ ++static void rx_class_ft1_set_da_mask(struct regmap *miig_rt, int slice, ++ int n, const u8 *addr) ++{ ++ u32 offset; ++ ++ offset = FT1_N_REG(slice, n, FT1_DA0_MASK); ++ regmap_write(miig_rt, offset, (u32)(addr[0] | addr[1] << 8 | ++ addr[2] << 16 | addr[3] << 24)); ++ offset = FT1_N_REG(slice, n, FT1_DA1_MASK); ++ regmap_write(miig_rt, offset, (u32)(addr[4] | addr[5] << 8)); ++} ++ ++static void rx_class_ft1_cfg_set_type(struct regmap *miig_rt, int slice, int n, ++ enum ft1_cfg_type type) ++{ ++ u32 offset; ++ ++ offset = offs[slice].ft1_cfg; ++ regmap_update_bits(miig_rt, offset, FT1_CFG_MASK(n), ++ type << FT1_CFG_SHIFT(n)); ++} ++ ++static void rx_class_sel_set_type(struct regmap *miig_rt, int slice, int n, ++ enum rx_class_sel_type type) ++{ ++ u32 offset; ++ ++ offset = offs[slice].rx_class_cfg1; ++ regmap_update_bits(miig_rt, offset, RX_CLASS_SEL_MASK(n), ++ type << RX_CLASS_SEL_SHIFT(n)); ++} ++ ++static void rx_class_set_and(struct regmap *miig_rt, int slice, int n, ++ u32 data) ++{ ++ u32 offset; ++ ++ offset = RX_CLASS_N_REG(slice, n, RX_CLASS_AND_EN); ++ regmap_write(miig_rt, offset, data); ++} ++ ++static void rx_class_set_or(struct regmap *miig_rt, int slice, int n, ++ u32 data) ++{ ++ u32 offset; ++ ++ offset = RX_CLASS_N_REG(slice, n, RX_CLASS_OR_EN); ++ regmap_write(miig_rt, offset, data); ++} ++ ++void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac) ++{ ++ regmap_write(miig_rt, MAC_INTERFACE_0, (u32)(mac[0] | mac[1] << 8 | ++ mac[2] << 16 | mac[3] << 24)); ++ regmap_write(miig_rt, MAC_INTERFACE_1, (u32)(mac[4] | mac[5] << 8)); ++} ++ ++void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac) ++{ ++ regmap_write(miig_rt, offs[slice].mac0, (u32)(mac[0] | mac[1] << 8 | ++ mac[2] << 16 | mac[3] << 24)); ++ regmap_write(miig_rt, offs[slice].mac1, (u32)(mac[4] | mac[5] << 8)); ++} ++ ++/* disable all RX traffic */ ++void icssg_class_disable(struct regmap *miig_rt, int slice) ++{ ++ u32 data, offset; ++ int n; ++ ++ /* Enable RX_L2_G */ ++ regmap_update_bits(miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_RX_L2_G_EN, ++ ICSSG_CFG_RX_L2_G_EN); ++ ++ for (n = 0; n < ICSSG_NUM_CLASSIFIERS; n++) { ++ /* AND_EN = 0 */ ++ rx_class_set_and(miig_rt, slice, n, 0); ++ /* OR_EN = 0 */ ++ rx_class_set_or(miig_rt, slice, n, 0); ++ ++ /* set CFG1 to OR */ ++ rx_class_sel_set_type(miig_rt, slice, n, RX_CLASS_SEL_TYPE_OR); ++ ++ /* configure gate */ ++ offset = RX_CLASS_GATES_N_REG(slice, n); ++ regmap_read(miig_rt, offset, &data); ++ /* clear class_raw so we go through filters */ ++ data &= ~RX_CLASS_GATES_RAW_MASK; ++ /* set allow and phase mask */ ++ data |= RX_CLASS_GATES_ALLOW_MASK | RX_CLASS_GATES_PHASE_MASK; ++ regmap_write(miig_rt, offset, data); ++ } ++ ++ /* FT1 Disabled */ ++ for (n = 0; n < ICSSG_NUM_FT1_SLOTS; n++) { ++ const u8 addr[] = { 0, 0, 0, 0, 0, 0, }; ++ ++ rx_class_ft1_cfg_set_type(miig_rt, slice, n, ++ FT1_CFG_TYPE_DISABLED); ++ rx_class_ft1_set_da(miig_rt, slice, n, addr); ++ rx_class_ft1_set_da_mask(miig_rt, slice, n, addr); ++ } ++ ++ /* clear CFG2 */ ++ regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0); ++} ++ ++void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti) ++{ ++ u32 data; ++ ++ /* defaults */ ++ icssg_class_disable(miig_rt, slice); ++ ++ /* Setup Classifier */ ++ /* match on Broadcast or MAC_PRU address */ ++ data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P; ++ ++ /* multicast */ ++ if (allmulti) ++ data |= RX_CLASS_FT_MC; ++ ++ rx_class_set_or(miig_rt, slice, 0, data); ++ ++ /* set CFG1 for OR_OR_AND for classifier */ ++ rx_class_sel_set_type(miig_rt, slice, 0, RX_CLASS_SEL_TYPE_OR_OR_AND); ++ ++ /* clear CFG2 */ ++ regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0); ++} ++ ++/* required for SAV check */ ++void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr) ++{ ++ const u8 mask_addr[] = { 0, 0, 0, 0, 0, 0, }; ++ ++ rx_class_ft1_set_start_len(miig_rt, slice, 0, 6); ++ rx_class_ft1_set_da(miig_rt, slice, 0, mac_addr); ++ rx_class_ft1_set_da_mask(miig_rt, slice, 0, mask_addr); ++ rx_class_ft1_cfg_set_type(miig_rt, slice, 0, FT1_CFG_TYPE_EQ); ++} +diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c +new file mode 100644 +index 000000000000..ab648d3efe85 +--- /dev/null ++++ b/drivers/net/ethernet/ti/icssg/icssg_config.c +@@ -0,0 +1,450 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ICSSG Ethernet driver ++ * ++ * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com ++ */ ++ ++#include ++#include ++#include ++#include "icssg_config.h" ++#include "icssg_prueth.h" ++#include "icssg_switch_map.h" ++#include "icssg_mii_rt.h" ++ ++/* TX IPG Values to be set for 100M link speed. These values are ++ * in ocp_clk cycles. So need change if ocp_clk is changed for a specific ++ * h/w design. ++ */ ++ ++/* IPG is in core_clk cycles */ ++#define MII_RT_TX_IPG_100M 0x17 ++#define MII_RT_TX_IPG_1G 0xb ++ ++#define ICSSG_QUEUES_MAX 64 ++#define ICSSG_QUEUE_OFFSET 0xd00 ++#define ICSSG_QUEUE_PEEK_OFFSET 0xe00 ++#define ICSSG_QUEUE_CNT_OFFSET 0xe40 ++#define ICSSG_QUEUE_RESET_OFFSET 0xf40 ++ ++#define ICSSG_NUM_TX_QUEUES 8 ++ ++#define RECYCLE_Q_SLICE0 16 ++#define RECYCLE_Q_SLICE1 17 ++ ++#define ICSSG_NUM_OTHER_QUEUES 5 /* port, host and special queues */ ++ ++#define PORT_HI_Q_SLICE0 32 ++#define PORT_LO_Q_SLICE0 33 ++#define HOST_HI_Q_SLICE0 34 ++#define HOST_LO_Q_SLICE0 35 ++#define HOST_SPL_Q_SLICE0 40 /* Special Queue */ ++ ++#define PORT_HI_Q_SLICE1 36 ++#define PORT_LO_Q_SLICE1 37 ++#define HOST_HI_Q_SLICE1 38 ++#define HOST_LO_Q_SLICE1 39 ++#define HOST_SPL_Q_SLICE1 41 /* Special Queue */ ++ ++#define MII_RXCFG_DEFAULT (PRUSS_MII_RT_RXCFG_RX_ENABLE | \ ++ PRUSS_MII_RT_RXCFG_RX_DATA_RDY_MODE_DIS | \ ++ PRUSS_MII_RT_RXCFG_RX_L2_EN | \ ++ PRUSS_MII_RT_RXCFG_RX_L2_EOF_SCLR_DIS) ++ ++#define MII_TXCFG_DEFAULT (PRUSS_MII_RT_TXCFG_TX_ENABLE | \ ++ PRUSS_MII_RT_TXCFG_TX_AUTO_PREAMBLE | \ ++ PRUSS_MII_RT_TXCFG_TX_32_MODE_EN | \ ++ PRUSS_MII_RT_TXCFG_TX_IPG_WIRE_CLK_EN) ++ ++#define ICSSG_CFG_DEFAULT (ICSSG_CFG_TX_L1_EN | \ ++ ICSSG_CFG_TX_L2_EN | ICSSG_CFG_RX_L2_G_EN | \ ++ ICSSG_CFG_TX_PRU_EN | \ ++ ICSSG_CFG_SGMII_MODE) ++ ++#define FDB_GEN_CFG1 0x60 ++#define SMEM_VLAN_OFFSET 8 ++#define SMEM_VLAN_OFFSET_MASK GENMASK(25, 8) ++ ++#define FDB_GEN_CFG2 0x64 ++#define FDB_VLAN_EN BIT(6) ++#define FDB_HOST_EN BIT(2) ++#define FDB_PRU1_EN BIT(1) ++#define FDB_PRU0_EN BIT(0) ++#define FDB_EN_ALL (FDB_PRU0_EN | FDB_PRU1_EN | \ ++ FDB_HOST_EN | FDB_VLAN_EN) ++ ++/** ++ * struct map - ICSSG Queue Map ++ * @queue: Queue number ++ * @pd_addr_start: Packet descriptor queue reserved memory ++ * @flags: Flags ++ * @special: Indicates whether this queue is a special queue or not ++ */ ++struct map { ++ int queue; ++ u32 pd_addr_start; ++ u32 flags; ++ bool special; ++}; ++ ++/* Hardware queue map for ICSSG */ ++static const struct map hwq_map[2][ICSSG_NUM_OTHER_QUEUES] = { ++ { ++ { PORT_HI_Q_SLICE0, PORT_DESC0_HI, 0x200000, 0 }, ++ { PORT_LO_Q_SLICE0, PORT_DESC0_LO, 0, 0 }, ++ { HOST_HI_Q_SLICE0, HOST_DESC0_HI, 0x200000, 0 }, ++ { HOST_LO_Q_SLICE0, HOST_DESC0_LO, 0, 0 }, ++ { HOST_SPL_Q_SLICE0, HOST_SPPD0, 0x400000, 1 }, ++ }, ++ { ++ { PORT_HI_Q_SLICE1, PORT_DESC1_HI, 0xa00000, 0 }, ++ { PORT_LO_Q_SLICE1, PORT_DESC1_LO, 0x800000, 0 }, ++ { HOST_HI_Q_SLICE1, HOST_DESC1_HI, 0xa00000, 0 }, ++ { HOST_LO_Q_SLICE1, HOST_DESC1_LO, 0x800000, 0 }, ++ { HOST_SPL_Q_SLICE1, HOST_SPPD1, 0xc00000, 1 }, ++ }, ++}; ++ ++static void icssg_config_mii_init(struct prueth_emac *emac) ++{ ++ u32 rxcfg, txcfg, rxcfg_reg, txcfg_reg, pcnt_reg; ++ struct prueth *prueth = emac->prueth; ++ int slice = prueth_emac_slice(emac); ++ struct regmap *mii_rt; ++ ++ mii_rt = prueth->mii_rt; ++ ++ rxcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RXCFG0 : ++ PRUSS_MII_RT_RXCFG1; ++ txcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_TXCFG0 : ++ PRUSS_MII_RT_TXCFG1; ++ pcnt_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RX_PCNT0 : ++ PRUSS_MII_RT_RX_PCNT1; ++ ++ rxcfg = MII_RXCFG_DEFAULT; ++ txcfg = MII_TXCFG_DEFAULT; ++ ++ if (slice == ICSS_MII1) ++ rxcfg |= PRUSS_MII_RT_RXCFG_RX_MUX_SEL; ++ ++ /* In MII mode TX lines swapped inside ICSSG, so TX_MUX_SEL cfg need ++ * to be swapped also comparing to RGMII mode. ++ */ ++ if (emac->phy_if == PHY_INTERFACE_MODE_MII && slice == ICSS_MII0) ++ txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL; ++ else if (emac->phy_if != PHY_INTERFACE_MODE_MII && slice == ICSS_MII1) ++ txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL; ++ ++ regmap_write(mii_rt, rxcfg_reg, rxcfg); ++ regmap_write(mii_rt, txcfg_reg, txcfg); ++ regmap_write(mii_rt, pcnt_reg, 0x1); ++} ++ ++static void icssg_miig_queues_init(struct prueth *prueth, int slice) ++{ ++ struct regmap *miig_rt = prueth->miig_rt; ++ void __iomem *smem = prueth->shram.va; ++ u8 pd[ICSSG_SPECIAL_PD_SIZE]; ++ int queue = 0, i, j; ++ u32 *pdword; ++ ++ /* reset hwqueues */ ++ if (slice) ++ queue = ICSSG_NUM_TX_QUEUES; ++ ++ for (i = 0; i < ICSSG_NUM_TX_QUEUES; i++) { ++ regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue); ++ queue++; ++ } ++ ++ queue = slice ? RECYCLE_Q_SLICE1 : RECYCLE_Q_SLICE0; ++ regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue); ++ ++ for (i = 0; i < ICSSG_NUM_OTHER_QUEUES; i++) { ++ regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, ++ hwq_map[slice][i].queue); ++ } ++ ++ /* initialize packet descriptors in SMEM */ ++ /* push pakcet descriptors to hwqueues */ ++ ++ pdword = (u32 *)pd; ++ for (j = 0; j < ICSSG_NUM_OTHER_QUEUES; j++) { ++ const struct map *mp; ++ int pd_size, num_pds; ++ u32 pdaddr; ++ ++ mp = &hwq_map[slice][j]; ++ if (mp->special) { ++ pd_size = ICSSG_SPECIAL_PD_SIZE; ++ num_pds = ICSSG_NUM_SPECIAL_PDS; ++ } else { ++ pd_size = ICSSG_NORMAL_PD_SIZE; ++ num_pds = ICSSG_NUM_NORMAL_PDS; ++ } ++ ++ for (i = 0; i < num_pds; i++) { ++ memset(pd, 0, pd_size); ++ ++ pdword[0] &= ICSSG_FLAG_MASK; ++ pdword[0] |= mp->flags; ++ pdaddr = mp->pd_addr_start + i * pd_size; ++ ++ memcpy_toio(smem + pdaddr, pd, pd_size); ++ queue = mp->queue; ++ regmap_write(miig_rt, ICSSG_QUEUE_OFFSET + 4 * queue, ++ pdaddr); ++ } ++ } ++} ++ ++void icssg_config_ipg(struct prueth_emac *emac) ++{ ++ struct prueth *prueth = emac->prueth; ++ int slice = prueth_emac_slice(emac); ++ ++ switch (emac->speed) { ++ case SPEED_1000: ++ icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_1G); ++ break; ++ case SPEED_100: ++ icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_100M); ++ break; ++ default: ++ /* Other links speeds not supported */ ++ netdev_err(emac->ndev, "Unsupported link speed\n"); ++ return; ++ } ++} ++ ++static void emac_r30_cmd_init(struct prueth_emac *emac) ++{ ++ struct icssg_r30_cmd __iomem *p; ++ int i; ++ ++ p = emac->dram.va + MGR_R30_CMD_OFFSET; ++ ++ for (i = 0; i < 4; i++) ++ writel(EMAC_NONE, &p->cmd[i]); ++} ++ ++static int emac_r30_is_done(struct prueth_emac *emac) ++{ ++ const struct icssg_r30_cmd __iomem *p; ++ u32 cmd; ++ int i; ++ ++ p = emac->dram.va + MGR_R30_CMD_OFFSET; ++ ++ for (i = 0; i < 4; i++) { ++ cmd = readl(&p->cmd[i]); ++ if (cmd != EMAC_NONE) ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static int prueth_emac_buffer_setup(struct prueth_emac *emac) ++{ ++ struct icssg_buffer_pool_cfg __iomem *bpool_cfg; ++ struct icssg_rxq_ctx __iomem *rxq_ctx; ++ struct prueth *prueth = emac->prueth; ++ int slice = prueth_emac_slice(emac); ++ u32 addr; ++ int i; ++ ++ /* Layout to have 64KB aligned buffer pool ++ * |BPOOL0|BPOOL1|RX_CTX0|RX_CTX1| ++ */ ++ ++ addr = lower_32_bits(prueth->msmcram.pa); ++ if (slice) ++ addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE; ++ ++ if (addr % SZ_64K) { ++ dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n"); ++ return -EINVAL; ++ } ++ ++ bpool_cfg = emac->dram.va + BUFFER_POOL_0_ADDR_OFFSET; ++ /* workaround for f/w bug. bpool 0 needs to be initilalized */ ++ writel(addr, &bpool_cfg[0].addr); ++ writel(0, &bpool_cfg[0].len); ++ ++ for (i = PRUETH_EMAC_BUF_POOL_START; ++ i < PRUETH_EMAC_BUF_POOL_START + PRUETH_NUM_BUF_POOLS; ++ i++) { ++ writel(addr, &bpool_cfg[i].addr); ++ writel(PRUETH_EMAC_BUF_POOL_SIZE, &bpool_cfg[i].len); ++ addr += PRUETH_EMAC_BUF_POOL_SIZE; ++ } ++ ++ if (!slice) ++ addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE; ++ else ++ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE * 2; ++ ++ /* Pre-emptible RX buffer queue */ ++ rxq_ctx = emac->dram.va + HOST_RX_Q_PRE_CONTEXT_OFFSET; ++ for (i = 0; i < 3; i++) ++ writel(addr, &rxq_ctx->start[i]); ++ ++ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; ++ writel(addr, &rxq_ctx->end); ++ ++ /* Express RX buffer queue */ ++ rxq_ctx = emac->dram.va + HOST_RX_Q_EXP_CONTEXT_OFFSET; ++ for (i = 0; i < 3; i++) ++ writel(addr, &rxq_ctx->start[i]); ++ ++ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE; ++ writel(addr, &rxq_ctx->end); ++ ++ return 0; ++} ++ ++static void icssg_init_emac_mode(struct prueth *prueth) ++{ ++ /* When the device is configured as a bridge and it is being brought ++ * back to the emac mode, the host mac address has to be set as 0. ++ */ ++ u8 mac[ETH_ALEN] = { 0 }; ++ ++ if (prueth->emacs_initialized) ++ return; ++ ++ regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, ++ SMEM_VLAN_OFFSET_MASK, 0); ++ regmap_write(prueth->miig_rt, FDB_GEN_CFG2, 0); ++ /* Clear host MAC address */ ++ icssg_class_set_host_mac_addr(prueth->miig_rt, mac); ++} ++ ++int icssg_config(struct prueth *prueth, struct prueth_emac *emac, int slice) ++{ ++ void __iomem *config = emac->dram.va + ICSSG_CONFIG_OFFSET; ++ struct icssg_flow_cfg __iomem *flow_cfg; ++ int ret; ++ ++ icssg_init_emac_mode(prueth); ++ ++ memset_io(config, 0, TAS_GATE_MASK_LIST0); ++ icssg_miig_queues_init(prueth, slice); ++ ++ emac->speed = SPEED_1000; ++ emac->duplex = DUPLEX_FULL; ++ if (!phy_interface_mode_is_rgmii(emac->phy_if)) { ++ emac->speed = SPEED_100; ++ emac->duplex = DUPLEX_FULL; ++ } ++ regmap_update_bits(prueth->miig_rt, ICSSG_CFG_OFFSET, ++ ICSSG_CFG_DEFAULT, ICSSG_CFG_DEFAULT); ++ icssg_miig_set_interface_mode(prueth->miig_rt, slice, emac->phy_if); ++ icssg_config_mii_init(emac); ++ icssg_config_ipg(emac); ++ icssg_update_rgmii_cfg(prueth->miig_rt, emac); ++ ++ /* set GPI mode */ ++ pruss_cfg_gpimode(prueth->pruss, prueth->pru_id[slice], ++ PRUSS_GPI_MODE_MII); ++ ++ /* enable XFR shift for PRU and RTU */ ++ pruss_cfg_xfr_enable(prueth->pruss, PRU_TYPE_PRU, true); ++ pruss_cfg_xfr_enable(prueth->pruss, PRU_TYPE_RTU, true); ++ ++ /* set C28 to 0x100 */ ++ pru_rproc_set_ctable(prueth->pru[slice], PRU_C28, 0x100 << 8); ++ pru_rproc_set_ctable(prueth->rtu[slice], PRU_C28, 0x100 << 8); ++ pru_rproc_set_ctable(prueth->txpru[slice], PRU_C28, 0x100 << 8); ++ ++ flow_cfg = config + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET; ++ writew(emac->rx_flow_id_base, &flow_cfg->rx_base_flow); ++ writew(0, &flow_cfg->mgm_base_flow); ++ writeb(0, config + SPL_PKT_DEFAULT_PRIORITY); ++ writeb(0, config + QUEUE_NUM_UNTAGGED); ++ ++ ret = prueth_emac_buffer_setup(emac); ++ if (ret) ++ return ret; ++ ++ emac_r30_cmd_init(emac); ++ ++ return 0; ++} ++ ++/* Bitmask for ICSSG r30 commands */ ++static const struct icssg_r30_cmd emac_r32_bitmask[] = { ++ {{0xffff0004, 0xffff0100, 0xffff0100, EMAC_NONE}}, /* EMAC_PORT_DISABLE */ ++ {{0xfffb0040, 0xfeff0200, 0xfeff0200, EMAC_NONE}}, /* EMAC_PORT_BLOCK */ ++ {{0xffbb0000, 0xfcff0000, 0xdcff0000, EMAC_NONE}}, /* EMAC_PORT_FORWARD */ ++ {{0xffbb0000, 0xfcff0000, 0xfcff2000, EMAC_NONE}}, /* EMAC_PORT_FORWARD_WO_LEARNING */ ++ {{0xffff0001, EMAC_NONE, EMAC_NONE, EMAC_NONE}}, /* ACCEPT ALL */ ++ {{0xfffe0002, EMAC_NONE, EMAC_NONE, EMAC_NONE}}, /* ACCEPT TAGGED */ ++ {{0xfffc0000, EMAC_NONE, EMAC_NONE, EMAC_NONE}}, /* ACCEPT UNTAGGED and PRIO */ ++ {{EMAC_NONE, 0xffff0020, EMAC_NONE, EMAC_NONE}}, /* TAS Trigger List change */ ++ {{EMAC_NONE, 0xdfff1000, EMAC_NONE, EMAC_NONE}}, /* TAS set state ENABLE*/ ++ {{EMAC_NONE, 0xefff2000, EMAC_NONE, EMAC_NONE}}, /* TAS set state RESET*/ ++ {{EMAC_NONE, 0xcfff0000, EMAC_NONE, EMAC_NONE}}, /* TAS set state DISABLE*/ ++ {{EMAC_NONE, EMAC_NONE, 0xffff0400, EMAC_NONE}}, /* UC flooding ENABLE*/ ++ {{EMAC_NONE, EMAC_NONE, 0xfbff0000, EMAC_NONE}}, /* UC flooding DISABLE*/ ++ {{EMAC_NONE, EMAC_NONE, 0xffff0800, EMAC_NONE}}, /* MC flooding ENABLE*/ ++ {{EMAC_NONE, EMAC_NONE, 0xf7ff0000, EMAC_NONE}}, /* MC flooding DISABLE*/ ++ {{EMAC_NONE, 0xffff4000, EMAC_NONE, EMAC_NONE}}, /* Preemption on Tx ENABLE*/ ++ {{EMAC_NONE, 0xbfff0000, EMAC_NONE, EMAC_NONE}}, /* Preemption on Tx DISABLE*/ ++ {{0xffff0010, EMAC_NONE, 0xffff0010, EMAC_NONE}}, /* VLAN AWARE*/ ++ {{0xffef0000, EMAC_NONE, 0xffef0000, EMAC_NONE}} /* VLAN UNWARE*/ ++}; ++ ++int emac_set_port_state(struct prueth_emac *emac, ++ enum icssg_port_state_cmd cmd) ++{ ++ struct icssg_r30_cmd __iomem *p; ++ int ret = -ETIMEDOUT; ++ int done = 0; ++ int i; ++ ++ p = emac->dram.va + MGR_R30_CMD_OFFSET; ++ ++ if (cmd >= ICSSG_EMAC_PORT_MAX_COMMANDS) { ++ netdev_err(emac->ndev, "invalid port command\n"); ++ return -EINVAL; ++ } ++ ++ /* only one command at a time allowed to firmware */ ++ mutex_lock(&emac->cmd_lock); ++ ++ for (i = 0; i < 4; i++) ++ writel(emac_r32_bitmask[cmd].cmd[i], &p->cmd[i]); ++ ++ /* wait for done */ ++ ret = read_poll_timeout(emac_r30_is_done, done, done == 1, ++ 1000, 10000, false, emac); ++ ++ if (ret == -ETIMEDOUT) ++ netdev_err(emac->ndev, "timeout waiting for command done\n"); ++ ++ mutex_unlock(&emac->cmd_lock); ++ ++ return ret; ++} ++ ++void icssg_config_set_speed(struct prueth_emac *emac) ++{ ++ u8 fw_speed; ++ ++ switch (emac->speed) { ++ case SPEED_1000: ++ fw_speed = FW_LINK_SPEED_1G; ++ break; ++ case SPEED_100: ++ fw_speed = FW_LINK_SPEED_100M; ++ break; ++ default: ++ /* Other links speeds not supported */ ++ netdev_err(emac->ndev, "Unsupported link speed\n"); ++ return; ++ } ++ ++ writeb(fw_speed, emac->dram.va + PORT_LINK_SPEED_OFFSET); ++} +diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/ethernet/ti/icssg/icssg_config.h +new file mode 100644 +index 000000000000..43eb0922172a +--- /dev/null ++++ b/drivers/net/ethernet/ti/icssg/icssg_config.h +@@ -0,0 +1,200 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* Texas Instruments ICSSG Ethernet driver ++ * ++ * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/ ++ * ++ */ ++ ++#ifndef __NET_TI_ICSSG_CONFIG_H ++#define __NET_TI_ICSSG_CONFIG_H ++ ++struct icssg_buffer_pool_cfg { ++ __le32 addr; ++ __le32 len; ++} __packed; ++ ++struct icssg_flow_cfg { ++ __le16 rx_base_flow; ++ __le16 mgm_base_flow; ++} __packed; ++ ++#define PRUETH_PKT_TYPE_CMD 0x10 ++#define PRUETH_NAV_PS_DATA_SIZE 16 /* Protocol specific data size */ ++#define PRUETH_NAV_SW_DATA_SIZE 16 /* SW related data size */ ++#define PRUETH_MAX_TX_DESC 512 ++#define PRUETH_MAX_RX_DESC 512 ++#define PRUETH_MAX_RX_FLOWS 1 /* excluding default flow */ ++#define PRUETH_RX_FLOW_DATA 0 ++ ++#define PRUETH_EMAC_BUF_POOL_SIZE SZ_8K ++#define PRUETH_EMAC_POOLS_PER_SLICE 24 ++#define PRUETH_EMAC_BUF_POOL_START 8 ++#define PRUETH_NUM_BUF_POOLS 8 ++#define PRUETH_EMAC_RX_CTX_BUF_SIZE SZ_16K /* per slice */ ++#define MSMC_RAM_SIZE \ ++ (2 * (PRUETH_EMAC_BUF_POOL_SIZE * PRUETH_NUM_BUF_POOLS + \ ++ PRUETH_EMAC_RX_CTX_BUF_SIZE * 2)) ++ ++struct icssg_rxq_ctx { ++ __le32 start[3]; ++ __le32 end; ++} __packed; ++ ++/* Load time Fiwmware Configuration */ ++ ++#define ICSSG_FW_MGMT_CMD_HEADER 0x81 ++#define ICSSG_FW_MGMT_FDB_CMD_TYPE 0x03 ++#define ICSSG_FW_MGMT_CMD_TYPE 0x04 ++#define ICSSG_FW_MGMT_PKT 0x80000000 ++ ++struct icssg_r30_cmd { ++ u32 cmd[4]; ++} __packed; ++ ++enum icssg_port_state_cmd { ++ ICSSG_EMAC_PORT_DISABLE = 0, ++ ICSSG_EMAC_PORT_BLOCK, ++ ICSSG_EMAC_PORT_FORWARD, ++ ICSSG_EMAC_PORT_FORWARD_WO_LEARNING, ++ ICSSG_EMAC_PORT_ACCEPT_ALL, ++ ICSSG_EMAC_PORT_ACCEPT_TAGGED, ++ ICSSG_EMAC_PORT_ACCEPT_UNTAGGED_N_PRIO, ++ ICSSG_EMAC_PORT_TAS_TRIGGER, ++ ICSSG_EMAC_PORT_TAS_ENABLE, ++ ICSSG_EMAC_PORT_TAS_RESET, ++ ICSSG_EMAC_PORT_TAS_DISABLE, ++ ICSSG_EMAC_PORT_UC_FLOODING_ENABLE, ++ ICSSG_EMAC_PORT_UC_FLOODING_DISABLE, ++ ICSSG_EMAC_PORT_MC_FLOODING_ENABLE, ++ ICSSG_EMAC_PORT_MC_FLOODING_DISABLE, ++ ICSSG_EMAC_PORT_PREMPT_TX_ENABLE, ++ ICSSG_EMAC_PORT_PREMPT_TX_DISABLE, ++ ICSSG_EMAC_PORT_VLAN_AWARE_ENABLE, ++ ICSSG_EMAC_PORT_VLAN_AWARE_DISABLE, ++ ICSSG_EMAC_PORT_MAX_COMMANDS ++}; ++ ++#define EMAC_NONE 0xffff0000 ++#define EMAC_PRU0_P_DI 0xffff0004 ++#define EMAC_PRU1_P_DI 0xffff0040 ++#define EMAC_TX_P_DI 0xffff0100 ++ ++#define EMAC_PRU0_P_EN 0xfffb0000 ++#define EMAC_PRU1_P_EN 0xffbf0000 ++#define EMAC_TX_P_EN 0xfeff0000 ++ ++#define EMAC_P_BLOCK 0xffff0040 ++#define EMAC_TX_P_BLOCK 0xffff0200 ++#define EMAC_P_UNBLOCK 0xffbf0000 ++#define EMAC_TX_P_UNBLOCK 0xfdff0000 ++#define EMAC_LEAN_EN 0xfff70000 ++#define EMAC_LEAN_DI 0xffff0008 ++ ++#define EMAC_ACCEPT_ALL 0xffff0001 ++#define EMAC_ACCEPT_TAG 0xfffe0002 ++#define EMAC_ACCEPT_PRIOR 0xfffc0000 ++ ++/* Config area lies in DRAM */ ++#define ICSSG_CONFIG_OFFSET 0x0 ++ ++/* Config area lies in shared RAM */ ++#define ICSSG_CONFIG_OFFSET_SLICE0 0 ++#define ICSSG_CONFIG_OFFSET_SLICE1 0x8000 ++ ++#define ICSSG_NUM_NORMAL_PDS 64 ++#define ICSSG_NUM_SPECIAL_PDS 16 ++ ++#define ICSSG_NORMAL_PD_SIZE 8 ++#define ICSSG_SPECIAL_PD_SIZE 20 ++ ++#define ICSSG_FLAG_MASK 0xff00ffff ++ ++struct icssg_setclock_desc { ++ u8 request; ++ u8 restore; ++ u8 acknowledgment; ++ u8 cmp_status; ++ u32 margin; ++ u32 cyclecounter0_set; ++ u32 cyclecounter1_set; ++ u32 iepcount_set; ++ u32 rsvd1; ++ u32 rsvd2; ++ u32 CMP0_current; ++ u32 iepcount_current; ++ u32 difference; ++ u32 cyclecounter0_new; ++ u32 cyclecounter1_new; ++ u32 CMP0_new; ++} __packed; ++ ++#define ICSSG_CMD_POP_SLICE0 56 ++#define ICSSG_CMD_POP_SLICE1 60 ++ ++#define ICSSG_CMD_PUSH_SLICE0 57 ++#define ICSSG_CMD_PUSH_SLICE1 61 ++ ++#define ICSSG_RSP_POP_SLICE0 58 ++#define ICSSG_RSP_POP_SLICE1 62 ++ ++#define ICSSG_RSP_PUSH_SLICE0 56 ++#define ICSSG_RSP_PUSH_SLICE1 60 ++ ++#define ICSSG_TS_POP_SLICE0 59 ++#define ICSSG_TS_POP_SLICE1 63 ++ ++#define ICSSG_TS_PUSH_SLICE0 40 ++#define ICSSG_TS_PUSH_SLICE1 41 ++ ++/* FDB FID_C2 flag definitions */ ++/* Indicates host port membership.*/ ++#define ICSSG_FDB_ENTRY_P0_MEMBERSHIP BIT(0) ++/* Indicates that MAC ID is connected to physical port 1 */ ++#define ICSSG_FDB_ENTRY_P1_MEMBERSHIP BIT(1) ++/* Indicates that MAC ID is connected to physical port 2 */ ++#define ICSSG_FDB_ENTRY_P2_MEMBERSHIP BIT(2) ++/* Ageable bit is set for learned entries and cleared for static entries */ ++#define ICSSG_FDB_ENTRY_AGEABLE BIT(3) ++/* If set for DA then packet is determined to be a special packet */ ++#define ICSSG_FDB_ENTRY_BLOCK BIT(4) ++/* If set for DA then the SA from the packet is not learned */ ++#define ICSSG_FDB_ENTRY_SECURE BIT(5) ++/* If set, it means packet has been seen recently with source address + FID ++ * matching MAC address/FID of entry ++ */ ++#define ICSSG_FDB_ENTRY_TOUCHED BIT(6) ++/* Set if entry is valid */ ++#define ICSSG_FDB_ENTRY_VALID BIT(7) ++ ++/** ++ * struct prueth_vlan_tbl - VLAN table entries struct in ICSSG SMEM ++ * @fid_c1: membership and forwarding rules flag to this table. See ++ * above to defines for bit definitions ++ * @fid: FDB index for this VID (there is 1-1 mapping b/w VID and FID) ++ */ ++struct prueth_vlan_tbl { ++ u8 fid_c1; ++ u8 fid; ++} __packed; ++ ++/** ++ * struct prueth_fdb_slot - Result of FDB slot lookup ++ * @mac: MAC address ++ * @fid: fid to be associated with MAC ++ * @fid_c2: FID_C2 entry for this MAC ++ */ ++struct prueth_fdb_slot { ++ u8 mac[ETH_ALEN]; ++ u8 fid; ++ u8 fid_c2; ++} __packed; ++ ++enum icssg_ietfpe_verify_states { ++ ICSSG_IETFPE_STATE_UNKNOWN = 0, ++ ICSSG_IETFPE_STATE_INITIAL, ++ ICSSG_IETFPE_STATE_VERIFYING, ++ ICSSG_IETFPE_STATE_SUCCEEDED, ++ ICSSG_IETFPE_STATE_FAILED, ++ ICSSG_IETFPE_STATE_DISABLED ++}; ++#endif /* __NET_TI_ICSSG_CONFIG_H */ +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +index 8512f19a9b4d..e93488a79dbf 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +@@ -194,4 +194,19 @@ static inline int prueth_emac_slice(struct prueth_emac *emac) + } + } + ++/* Classifier helpers */ ++void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac); ++void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac); ++void icssg_class_disable(struct regmap *miig_rt, int slice); ++void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti); ++void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr); ++ ++/* config helpers */ ++void icssg_config_ipg(struct prueth_emac *emac); ++int icssg_config(struct prueth *prueth, struct prueth_emac *emac, ++ int slice); ++int emac_set_port_state(struct prueth_emac *emac, ++ enum icssg_port_state_cmd state); ++void icssg_config_set_speed(struct prueth_emac *emac); ++ + #endif /* __NET_TI_ICSSG_PRUETH_H */ +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0019-net-ti-icssg-prueth-Add-icssg-queues-APIs-and-macros.patch b/recipes-kernel/linux/files/patches-6.1/0019-net-ti-icssg-prueth-Add-icssg-queues-APIs-and-macros.patch new file mode 100644 index 000000000..da89065a0 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0019-net-ti-icssg-prueth-Add-icssg-queues-APIs-and-macros.patch @@ -0,0 +1,89 @@ +From 733b846cdc5b99dfa76fc7ca0a6d2767b5145779 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Tue, 1 Aug 2023 14:44:22 +0530 +Subject: [PATCH 19/76] net: ti: icssg-prueth: Add icssg queues APIs and macros + +Add icssg_queue.c file. This file introduces macros and APIs related to +ICSSG queues. These will be used by ICSSG Ethernet driver. + +Reviewed-by: Andrew Lunn +Signed-off-by: MD Danish Anwar +--- + drivers/net/ethernet/ti/icssg/icssg_prueth.h | 5 ++ + drivers/net/ethernet/ti/icssg/icssg_queues.c | 50 ++++++++++++++++++++ + 2 files changed, 55 insertions(+) + create mode 100644 drivers/net/ethernet/ti/icssg/icssg_queues.c + +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +index e93488a79dbf..42fdf4005010 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +@@ -209,4 +209,9 @@ int emac_set_port_state(struct prueth_emac *emac, + enum icssg_port_state_cmd state); + void icssg_config_set_speed(struct prueth_emac *emac); + ++/* Buffer queue helpers */ ++int icssg_queue_pop(struct prueth *prueth, u8 queue); ++void icssg_queue_push(struct prueth *prueth, int queue, u16 addr); ++u32 icssg_queue_level(struct prueth *prueth, int queue); ++ + #endif /* __NET_TI_ICSSG_PRUETH_H */ +diff --git a/drivers/net/ethernet/ti/icssg/icssg_queues.c b/drivers/net/ethernet/ti/icssg/icssg_queues.c +new file mode 100644 +index 000000000000..3c34f61ad40b +--- /dev/null ++++ b/drivers/net/ethernet/ti/icssg/icssg_queues.c +@@ -0,0 +1,50 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ICSSG Buffer queue helpers ++ * ++ * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com ++ */ ++ ++#include ++#include "icssg_prueth.h" ++ ++#define ICSSG_QUEUES_MAX 64 ++#define ICSSG_QUEUE_OFFSET 0xd00 ++#define ICSSG_QUEUE_PEEK_OFFSET 0xe00 ++#define ICSSG_QUEUE_CNT_OFFSET 0xe40 ++#define ICSSG_QUEUE_RESET_OFFSET 0xf40 ++ ++int icssg_queue_pop(struct prueth *prueth, u8 queue) ++{ ++ u32 val, cnt; ++ ++ if (queue >= ICSSG_QUEUES_MAX) ++ return -EINVAL; ++ ++ regmap_read(prueth->miig_rt, ICSSG_QUEUE_CNT_OFFSET + 4 * queue, &cnt); ++ if (!cnt) ++ return -EINVAL; ++ ++ regmap_read(prueth->miig_rt, ICSSG_QUEUE_OFFSET + 4 * queue, &val); ++ ++ return val; ++} ++ ++void icssg_queue_push(struct prueth *prueth, int queue, u16 addr) ++{ ++ if (queue >= ICSSG_QUEUES_MAX) ++ return; ++ ++ regmap_write(prueth->miig_rt, ICSSG_QUEUE_OFFSET + 4 * queue, addr); ++} ++ ++u32 icssg_queue_level(struct prueth *prueth, int queue) ++{ ++ u32 reg; ++ ++ if (queue >= ICSSG_QUEUES_MAX) ++ return 0; ++ ++ regmap_read(prueth->miig_rt, ICSSG_QUEUE_CNT_OFFSET + 4 * queue, ®); ++ ++ return reg; ++} +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0020-dt-bindings-net-Add-ICSSG-Ethernet.patch b/recipes-kernel/linux/files/patches-6.1/0020-dt-bindings-net-Add-ICSSG-Ethernet.patch new file mode 100644 index 000000000..646ad7c36 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0020-dt-bindings-net-Add-ICSSG-Ethernet.patch @@ -0,0 +1,210 @@ +From 3686a615430e1a4aac630b18ba09b3442fc4e336 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Tue, 1 Aug 2023 14:44:23 +0530 +Subject: [PATCH 20/76] dt-bindings: net: Add ICSSG Ethernet + +Add a YAML binding document for the ICSSG Programmable real time unit +based Ethernet hardware. The ICSSG driver uses the PRU and PRUSS consumer +APIs to interface the PRUs and load/run the firmware for supporting +ethernet functionality. + +Reviewed-by: Rob Herring +Signed-off-by: MD Danish Anwar +--- + .../bindings/net/ti,icssg-prueth.yaml | 184 ++++++++++++++++++ + 1 file changed, 184 insertions(+) + create mode 100644 Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml + +diff --git a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml +new file mode 100644 +index 000000000000..8ec30b3eb760 +--- /dev/null ++++ b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml +@@ -0,0 +1,184 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/net/ti,icssg-prueth.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Texas Instruments ICSSG PRUSS Ethernet ++ ++maintainers: ++ - Md Danish Anwar ++ ++description: ++ Ethernet based on the Programmable Real-Time Unit and Industrial ++ Communication Subsystem. ++ ++allOf: ++ - $ref: /schemas/remoteproc/ti,pru-consumer.yaml# ++ ++properties: ++ compatible: ++ enum: ++ - ti,am654-icssg-prueth # for AM65x SoC family ++ ++ sram: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: ++ phandle to MSMC SRAM node ++ ++ dmas: ++ maxItems: 10 ++ ++ dma-names: ++ items: ++ - const: tx0-0 ++ - const: tx0-1 ++ - const: tx0-2 ++ - const: tx0-3 ++ - const: tx1-0 ++ - const: tx1-1 ++ - const: tx1-2 ++ - const: tx1-3 ++ - const: rx0 ++ - const: rx1 ++ ++ ti,mii-g-rt: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: ++ phandle to MII_G_RT module's syscon regmap. ++ ++ ti,mii-rt: ++ $ref: /schemas/types.yaml#/definitions/phandle ++ description: ++ phandle to MII_RT module's syscon regmap ++ ++ interrupts: ++ maxItems: 2 ++ description: ++ Interrupt specifiers to TX timestamp IRQ. ++ ++ interrupt-names: ++ items: ++ - const: tx_ts0 ++ - const: tx_ts1 ++ ++ ethernet-ports: ++ type: object ++ additionalProperties: false ++ ++ properties: ++ '#address-cells': ++ const: 1 ++ '#size-cells': ++ const: 0 ++ ++ patternProperties: ++ ^port@[0-1]$: ++ type: object ++ description: ICSSG PRUETH external ports ++ $ref: ethernet-controller.yaml# ++ unevaluatedProperties: false ++ ++ properties: ++ reg: ++ items: ++ - enum: [0, 1] ++ description: ICSSG PRUETH port number ++ ++ interrupts: ++ maxItems: 1 ++ ++ ti,syscon-rgmii-delay: ++ items: ++ - items: ++ - description: phandle to system controller node ++ - description: The offset to ICSSG control register ++ $ref: /schemas/types.yaml#/definitions/phandle-array ++ description: ++ phandle to system controller node and register offset ++ to ICSSG control register for RGMII transmit delay ++ ++ required: ++ - reg ++ anyOf: ++ - required: ++ - port@0 ++ - required: ++ - port@1 ++ ++required: ++ - compatible ++ - sram ++ - dmas ++ - dma-names ++ - ethernet-ports ++ - ti,mii-g-rt ++ - interrupts ++ - interrupt-names ++ ++unevaluatedProperties: false ++ ++examples: ++ - | ++ /* Example k3-am654 base board SR2.0, dual-emac */ ++ pruss2_eth: ethernet { ++ compatible = "ti,am654-icssg-prueth"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&icssg2_rgmii_pins_default>; ++ sram = <&msmc_ram>; ++ ++ ti,prus = <&pru2_0>, <&rtu2_0>, <&tx_pru2_0>, ++ <&pru2_1>, <&rtu2_1>, <&tx_pru2_1>; ++ firmware-name = "ti-pruss/am65x-pru0-prueth-fw.elf", ++ "ti-pruss/am65x-rtu0-prueth-fw.elf", ++ "ti-pruss/am65x-txpru0-prueth-fw.elf", ++ "ti-pruss/am65x-pru1-prueth-fw.elf", ++ "ti-pruss/am65x-rtu1-prueth-fw.elf", ++ "ti-pruss/am65x-txpru1-prueth-fw.elf"; ++ ti,pruss-gp-mux-sel = <2>, /* MII mode */ ++ <2>, ++ <2>, ++ <2>, /* MII mode */ ++ <2>, ++ <2>; ++ dmas = <&main_udmap 0xc300>, /* egress slice 0 */ ++ <&main_udmap 0xc301>, /* egress slice 0 */ ++ <&main_udmap 0xc302>, /* egress slice 0 */ ++ <&main_udmap 0xc303>, /* egress slice 0 */ ++ <&main_udmap 0xc304>, /* egress slice 1 */ ++ <&main_udmap 0xc305>, /* egress slice 1 */ ++ <&main_udmap 0xc306>, /* egress slice 1 */ ++ <&main_udmap 0xc307>, /* egress slice 1 */ ++ <&main_udmap 0x4300>, /* ingress slice 0 */ ++ <&main_udmap 0x4301>; /* ingress slice 1 */ ++ dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3", ++ "tx1-0", "tx1-1", "tx1-2", "tx1-3", ++ "rx0", "rx1"; ++ ti,mii-g-rt = <&icssg2_mii_g_rt>; ++ interrupt-parent = <&icssg2_intc>; ++ interrupts = <24 0 2>, <25 1 3>; ++ interrupt-names = "tx_ts0", "tx_ts1"; ++ ethernet-ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pruss2_emac0: port@0 { ++ reg = <0>; ++ phy-handle = <&pruss2_eth0_phy>; ++ phy-mode = "rgmii-id"; ++ interrupts-extended = <&icssg2_intc 24>; ++ ti,syscon-rgmii-delay = <&scm_conf 0x4120>; ++ /* Filled in by bootloader */ ++ local-mac-address = [00 00 00 00 00 00]; ++ }; ++ ++ pruss2_emac1: port@1 { ++ reg = <1>; ++ phy-handle = <&pruss2_eth1_phy>; ++ phy-mode = "rgmii-id"; ++ interrupts-extended = <&icssg2_intc 25>; ++ ti,syscon-rgmii-delay = <&scm_conf 0x4124>; ++ /* Filled in by bootloader */ ++ local-mac-address = [00 00 00 00 00 00]; ++ }; ++ }; ++ }; +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0021-net-ti-icssg-prueth-Add-ICSSG-ethernet-driver.patch b/recipes-kernel/linux/files/patches-6.1/0021-net-ti-icssg-prueth-Add-ICSSG-ethernet-driver.patch new file mode 100644 index 000000000..7ea806ee7 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0021-net-ti-icssg-prueth-Add-ICSSG-ethernet-driver.patch @@ -0,0 +1,1957 @@ +From aaeb3e8f5dfe85455366c1d28d245f228ec4434b Mon Sep 17 00:00:00 2001 +From: Roger Quadros +Date: Tue, 1 Aug 2023 14:44:24 +0530 +Subject: [PATCH 21/76] net: ti: icssg-prueth: Add ICSSG ethernet driver + +This is the Ethernet driver for TI AM654 Silicon rev. 2 +with the ICSSG PRU Sub-system running dual-EMAC firmware. + +The Programmable Real-time Unit and Industrial Communication Subsystem +Gigabit (PRU_ICSSG) is a low-latency microcontroller subsystem in the TI +SoCs. This subsystem is provided for the use cases like implementation of +custom peripheral interfaces, offloading of tasks from the other +processor cores of the SoC, etc. + +Every ICSSG core has two Programmable Real-Time Unit(PRUs), +two auxiliary Real-Time Transfer Unit (RT_PRUs), and +two Transmit Real-Time Transfer Units (TX_PRUs). Each one of these runs +its own firmware. Every ICSSG core has two MII ports connect to these +PRUs and also a MDIO port. + +The cores can run different firmwares to support different protocols and +features like switch-dev, timestamping, etc. + +It uses System DMA to transfer and receive packets and +shared memory register emulation between the firmware and +driver for control and configuration. + +This patch adds support for basic EMAC functionality with 1Gbps +and 100Mbps link speed. 10M and half duplex mode are not supported +currently as they require IEP, the support for which will be added later. +Support for switch-dev, timestamp, etc. will be added later +by subsequent patch series. + +Signed-off-by: Roger Quadros +Signed-off-by: Vignesh Raghavendra +Signed-off-by: Grygorii Strashko +Reviewed-by: Andrew Lunn +Signed-off-by: MD Danish Anwar +--- + drivers/net/ethernet/ti/Kconfig | 13 + + drivers/net/ethernet/ti/Makefile | 8 + + drivers/net/ethernet/ti/icssg/icssg_prueth.c | 1809 ++++++++++++++++++ + drivers/net/ethernet/ti/icssg/icssg_prueth.h | 32 + + 4 files changed, 1862 insertions(+) + create mode 100644 drivers/net/ethernet/ti/icssg/icssg_prueth.c + +diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig +index fce06663e1e1..63e510b6860f 100644 +--- a/drivers/net/ethernet/ti/Kconfig ++++ b/drivers/net/ethernet/ti/Kconfig +@@ -183,4 +183,17 @@ config CPMAC + help + TI AR7 CPMAC Ethernet support + ++config TI_ICSSG_PRUETH ++ tristate "TI Gigabit PRU Ethernet driver" ++ select PHYLIB ++ depends on PRU_REMOTEPROC ++ depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER ++ help ++ Support dual Gigabit Ethernet ports over the ICSSG PRU Subsystem. ++ This subsystem is available starting with the AM65 platform. ++ ++ This driver requires firmware binaries which will run on the PRUs ++ to support the Ethernet operation. Currently, it supports Ethernet ++ with 1G and 100M link speed. ++ + endif # NET_VENDOR_TI +diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile +index 75f761efbea7..efb050cbb4a8 100644 +--- a/drivers/net/ethernet/ti/Makefile ++++ b/drivers/net/ethernet/ti/Makefile +@@ -28,3 +28,11 @@ obj-$(CONFIG_TI_K3_AM65_CPSW_NUSS) += ti-am65-cpsw-nuss.o + ti-am65-cpsw-nuss-y := am65-cpsw-nuss.o cpsw_sl.o am65-cpsw-ethtool.o cpsw_ale.o k3-cppi-desc-pool.o am65-cpsw-qos.o + ti-am65-cpsw-nuss-$(CONFIG_TI_K3_AM65_CPSW_SWITCHDEV) += am65-cpsw-switchdev.o + obj-$(CONFIG_TI_K3_AM65_CPTS) += am65-cpts.o ++ ++obj-$(CONFIG_TI_ICSSG_PRUETH) += icssg-prueth.o ++icssg-prueth-y := k3-cppi-desc-pool.o \ ++ icssg/icssg_prueth.o \ ++ icssg/icssg_classifier.o \ ++ icssg/icssg_queues.o \ ++ icssg/icssg_config.o \ ++ icssg/icssg_mii_cfg.o \ +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +new file mode 100644 +index 000000000000..1869e38f898f +--- /dev/null ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +@@ -0,0 +1,1809 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++/* Texas Instruments ICSSG Ethernet Driver ++ * ++ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/ ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "icssg_prueth.h" ++#include "icssg_mii_rt.h" ++#include "../k3-cppi-desc-pool.h" ++ ++#define PRUETH_MODULE_DESCRIPTION "PRUSS ICSSG Ethernet driver" ++ ++/* Netif debug messages possible */ ++#define PRUETH_EMAC_DEBUG (NETIF_MSG_DRV | \ ++ NETIF_MSG_PROBE | \ ++ NETIF_MSG_LINK | \ ++ NETIF_MSG_TIMER | \ ++ NETIF_MSG_IFDOWN | \ ++ NETIF_MSG_IFUP | \ ++ NETIF_MSG_RX_ERR | \ ++ NETIF_MSG_TX_ERR | \ ++ NETIF_MSG_TX_QUEUED | \ ++ NETIF_MSG_INTR | \ ++ NETIF_MSG_TX_DONE | \ ++ NETIF_MSG_RX_STATUS | \ ++ NETIF_MSG_PKTDATA | \ ++ NETIF_MSG_HW | \ ++ NETIF_MSG_WOL) ++ ++#define prueth_napi_to_emac(napi) container_of(napi, struct prueth_emac, napi_rx) ++ ++/* CTRLMMR_ICSSG_RGMII_CTRL register bits */ ++#define ICSSG_CTRL_RGMII_ID_MODE BIT(24) ++ ++static void prueth_cleanup_rx_chns(struct prueth_emac *emac, ++ struct prueth_rx_chn *rx_chn, ++ int max_rflows) ++{ ++ if (rx_chn->desc_pool) ++ k3_cppi_desc_pool_destroy(rx_chn->desc_pool); ++ ++ if (rx_chn->rx_chn) ++ k3_udma_glue_release_rx_chn(rx_chn->rx_chn); ++} ++ ++static void prueth_cleanup_tx_chns(struct prueth_emac *emac) ++{ ++ int i; ++ ++ for (i = 0; i < emac->tx_ch_num; i++) { ++ struct prueth_tx_chn *tx_chn = &emac->tx_chns[i]; ++ ++ if (tx_chn->desc_pool) ++ k3_cppi_desc_pool_destroy(tx_chn->desc_pool); ++ ++ if (tx_chn->tx_chn) ++ k3_udma_glue_release_tx_chn(tx_chn->tx_chn); ++ ++ /* Assume prueth_cleanup_tx_chns() is called at the ++ * end after all channel resources are freed ++ */ ++ memset(tx_chn, 0, sizeof(*tx_chn)); ++ } ++} ++ ++static void prueth_ndev_del_tx_napi(struct prueth_emac *emac, int num) ++{ ++ int i; ++ ++ for (i = 0; i < num; i++) { ++ struct prueth_tx_chn *tx_chn = &emac->tx_chns[i]; ++ ++ if (tx_chn->irq) ++ free_irq(tx_chn->irq, tx_chn); ++ netif_napi_del(&tx_chn->napi_tx); ++ } ++} ++ ++static void prueth_xmit_free(struct prueth_tx_chn *tx_chn, ++ struct cppi5_host_desc_t *desc) ++{ ++ struct cppi5_host_desc_t *first_desc, *next_desc; ++ dma_addr_t buf_dma, next_desc_dma; ++ u32 buf_dma_len; ++ ++ first_desc = desc; ++ next_desc = first_desc; ++ ++ cppi5_hdesc_get_obuf(first_desc, &buf_dma, &buf_dma_len); ++ k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &buf_dma); ++ ++ dma_unmap_single(tx_chn->dma_dev, buf_dma, buf_dma_len, ++ DMA_TO_DEVICE); ++ ++ next_desc_dma = cppi5_hdesc_get_next_hbdesc(first_desc); ++ k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &next_desc_dma); ++ while (next_desc_dma) { ++ next_desc = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, ++ next_desc_dma); ++ cppi5_hdesc_get_obuf(next_desc, &buf_dma, &buf_dma_len); ++ k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &buf_dma); ++ ++ dma_unmap_page(tx_chn->dma_dev, buf_dma, buf_dma_len, ++ DMA_TO_DEVICE); ++ ++ next_desc_dma = cppi5_hdesc_get_next_hbdesc(next_desc); ++ k3_udma_glue_tx_cppi5_to_dma_addr(tx_chn->tx_chn, &next_desc_dma); ++ ++ k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc); ++ } ++ ++ k3_cppi_desc_pool_free(tx_chn->desc_pool, first_desc); ++} ++ ++static int emac_tx_complete_packets(struct prueth_emac *emac, int chn, ++ int budget) ++{ ++ struct net_device *ndev = emac->ndev; ++ struct cppi5_host_desc_t *desc_tx; ++ struct netdev_queue *netif_txq; ++ struct prueth_tx_chn *tx_chn; ++ unsigned int total_bytes = 0; ++ struct sk_buff *skb; ++ dma_addr_t desc_dma; ++ int res, num_tx = 0; ++ void **swdata; ++ ++ tx_chn = &emac->tx_chns[chn]; ++ ++ while (true) { ++ res = k3_udma_glue_pop_tx_chn(tx_chn->tx_chn, &desc_dma); ++ if (res == -ENODATA) ++ break; ++ ++ /* teardown completion */ ++ if (cppi5_desc_is_tdcm(desc_dma)) { ++ if (atomic_dec_and_test(&emac->tdown_cnt)) ++ complete(&emac->tdown_complete); ++ break; ++ } ++ ++ desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, ++ desc_dma); ++ swdata = cppi5_hdesc_get_swdata(desc_tx); ++ ++ skb = *(swdata); ++ prueth_xmit_free(tx_chn, desc_tx); ++ ++ ndev = skb->dev; ++ ndev->stats.tx_packets++; ++ ndev->stats.tx_bytes += skb->len; ++ total_bytes += skb->len; ++ napi_consume_skb(skb, budget); ++ num_tx++; ++ } ++ ++ if (!num_tx) ++ return 0; ++ ++ netif_txq = netdev_get_tx_queue(ndev, chn); ++ netdev_tx_completed_queue(netif_txq, num_tx, total_bytes); ++ ++ if (netif_tx_queue_stopped(netif_txq)) { ++ /* If the TX queue was stopped, wake it now ++ * if we have enough room. ++ */ ++ __netif_tx_lock(netif_txq, smp_processor_id()); ++ if (netif_running(ndev) && ++ (k3_cppi_desc_pool_avail(tx_chn->desc_pool) >= ++ MAX_SKB_FRAGS)) ++ netif_tx_wake_queue(netif_txq); ++ __netif_tx_unlock(netif_txq); ++ } ++ ++ return num_tx; ++} ++ ++static int emac_napi_tx_poll(struct napi_struct *napi_tx, int budget) ++{ ++ struct prueth_tx_chn *tx_chn = prueth_napi_to_tx_chn(napi_tx); ++ struct prueth_emac *emac = tx_chn->emac; ++ int num_tx_packets; ++ ++ num_tx_packets = emac_tx_complete_packets(emac, tx_chn->id, budget); ++ ++ if (num_tx_packets >= budget) ++ return budget; ++ ++ if (napi_complete_done(napi_tx, num_tx_packets)) ++ enable_irq(tx_chn->irq); ++ ++ return num_tx_packets; ++} ++ ++static irqreturn_t prueth_tx_irq(int irq, void *dev_id) ++{ ++ struct prueth_tx_chn *tx_chn = dev_id; ++ ++ disable_irq_nosync(irq); ++ napi_schedule(&tx_chn->napi_tx); ++ ++ return IRQ_HANDLED; ++} ++ ++static int prueth_ndev_add_tx_napi(struct prueth_emac *emac) ++{ ++ struct prueth *prueth = emac->prueth; ++ int i, ret; ++ ++ for (i = 0; i < emac->tx_ch_num; i++) { ++ struct prueth_tx_chn *tx_chn = &emac->tx_chns[i]; ++ ++ netif_napi_add_tx(emac->ndev, &tx_chn->napi_tx, emac_napi_tx_poll); ++ ret = request_irq(tx_chn->irq, prueth_tx_irq, ++ IRQF_TRIGGER_HIGH, tx_chn->name, ++ tx_chn); ++ if (ret) { ++ netif_napi_del(&tx_chn->napi_tx); ++ dev_err(prueth->dev, "unable to request TX IRQ %d\n", ++ tx_chn->irq); ++ goto fail; ++ } ++ } ++ ++ return 0; ++fail: ++ prueth_ndev_del_tx_napi(emac, i); ++ return ret; ++} ++ ++static int prueth_init_tx_chns(struct prueth_emac *emac) ++{ ++ static const struct k3_ring_cfg ring_cfg = { ++ .elm_size = K3_RINGACC_RING_ELSIZE_8, ++ .mode = K3_RINGACC_RING_MODE_RING, ++ .flags = 0, ++ .size = PRUETH_MAX_TX_DESC, ++ }; ++ struct k3_udma_glue_tx_channel_cfg tx_cfg; ++ struct device *dev = emac->prueth->dev; ++ struct net_device *ndev = emac->ndev; ++ int ret, slice, i; ++ u32 hdesc_size; ++ ++ slice = prueth_emac_slice(emac); ++ if (slice < 0) ++ return slice; ++ ++ init_completion(&emac->tdown_complete); ++ ++ hdesc_size = cppi5_hdesc_calc_size(true, PRUETH_NAV_PS_DATA_SIZE, ++ PRUETH_NAV_SW_DATA_SIZE); ++ memset(&tx_cfg, 0, sizeof(tx_cfg)); ++ tx_cfg.swdata_size = PRUETH_NAV_SW_DATA_SIZE; ++ tx_cfg.tx_cfg = ring_cfg; ++ tx_cfg.txcq_cfg = ring_cfg; ++ ++ for (i = 0; i < emac->tx_ch_num; i++) { ++ struct prueth_tx_chn *tx_chn = &emac->tx_chns[i]; ++ ++ /* To differentiate channels for SLICE0 vs SLICE1 */ ++ snprintf(tx_chn->name, sizeof(tx_chn->name), ++ "tx%d-%d", slice, i); ++ ++ tx_chn->emac = emac; ++ tx_chn->id = i; ++ tx_chn->descs_num = PRUETH_MAX_TX_DESC; ++ ++ tx_chn->tx_chn = ++ k3_udma_glue_request_tx_chn(dev, tx_chn->name, ++ &tx_cfg); ++ if (IS_ERR(tx_chn->tx_chn)) { ++ ret = PTR_ERR(tx_chn->tx_chn); ++ tx_chn->tx_chn = NULL; ++ netdev_err(ndev, ++ "Failed to request tx dma ch: %d\n", ret); ++ goto fail; ++ } ++ ++ tx_chn->dma_dev = k3_udma_glue_tx_get_dma_device(tx_chn->tx_chn); ++ tx_chn->desc_pool = ++ k3_cppi_desc_pool_create_name(tx_chn->dma_dev, ++ tx_chn->descs_num, ++ hdesc_size, ++ tx_chn->name); ++ if (IS_ERR(tx_chn->desc_pool)) { ++ ret = PTR_ERR(tx_chn->desc_pool); ++ tx_chn->desc_pool = NULL; ++ netdev_err(ndev, "Failed to create tx pool: %d\n", ret); ++ goto fail; ++ } ++ ++ tx_chn->irq = k3_udma_glue_tx_get_irq(tx_chn->tx_chn); ++ if (tx_chn->irq <= 0) { ++ ret = -EINVAL; ++ netdev_err(ndev, "failed to get tx irq\n"); ++ goto fail; ++ } ++ ++ snprintf(tx_chn->name, sizeof(tx_chn->name), "%s-tx%d", ++ dev_name(dev), tx_chn->id); ++ } ++ ++ return 0; ++ ++fail: ++ prueth_cleanup_tx_chns(emac); ++ return ret; ++} ++ ++static int prueth_init_rx_chns(struct prueth_emac *emac, ++ struct prueth_rx_chn *rx_chn, ++ char *name, u32 max_rflows, ++ u32 max_desc_num) ++{ ++ struct k3_udma_glue_rx_channel_cfg rx_cfg; ++ struct device *dev = emac->prueth->dev; ++ struct net_device *ndev = emac->ndev; ++ u32 fdqring_id, hdesc_size; ++ int i, ret = 0, slice; ++ ++ slice = prueth_emac_slice(emac); ++ if (slice < 0) ++ return slice; ++ ++ /* To differentiate channels for SLICE0 vs SLICE1 */ ++ snprintf(rx_chn->name, sizeof(rx_chn->name), "%s%d", name, slice); ++ ++ hdesc_size = cppi5_hdesc_calc_size(true, PRUETH_NAV_PS_DATA_SIZE, ++ PRUETH_NAV_SW_DATA_SIZE); ++ memset(&rx_cfg, 0, sizeof(rx_cfg)); ++ rx_cfg.swdata_size = PRUETH_NAV_SW_DATA_SIZE; ++ rx_cfg.flow_id_num = max_rflows; ++ rx_cfg.flow_id_base = -1; /* udmax will auto select flow id base */ ++ ++ /* init all flows */ ++ rx_chn->dev = dev; ++ rx_chn->descs_num = max_desc_num; ++ ++ rx_chn->rx_chn = k3_udma_glue_request_rx_chn(dev, rx_chn->name, ++ &rx_cfg); ++ if (IS_ERR(rx_chn->rx_chn)) { ++ ret = PTR_ERR(rx_chn->rx_chn); ++ rx_chn->rx_chn = NULL; ++ netdev_err(ndev, "Failed to request rx dma ch: %d\n", ret); ++ goto fail; ++ } ++ ++ rx_chn->dma_dev = k3_udma_glue_rx_get_dma_device(rx_chn->rx_chn); ++ rx_chn->desc_pool = k3_cppi_desc_pool_create_name(rx_chn->dma_dev, ++ rx_chn->descs_num, ++ hdesc_size, ++ rx_chn->name); ++ if (IS_ERR(rx_chn->desc_pool)) { ++ ret = PTR_ERR(rx_chn->desc_pool); ++ rx_chn->desc_pool = NULL; ++ netdev_err(ndev, "Failed to create rx pool: %d\n", ret); ++ goto fail; ++ } ++ ++ emac->rx_flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn); ++ netdev_dbg(ndev, "flow id base = %d\n", emac->rx_flow_id_base); ++ ++ fdqring_id = K3_RINGACC_RING_ID_ANY; ++ for (i = 0; i < rx_cfg.flow_id_num; i++) { ++ struct k3_ring_cfg rxring_cfg = { ++ .elm_size = K3_RINGACC_RING_ELSIZE_8, ++ .mode = K3_RINGACC_RING_MODE_RING, ++ .flags = 0, ++ }; ++ struct k3_ring_cfg fdqring_cfg = { ++ .elm_size = K3_RINGACC_RING_ELSIZE_8, ++ .flags = K3_RINGACC_RING_SHARED, ++ }; ++ struct k3_udma_glue_rx_flow_cfg rx_flow_cfg = { ++ .rx_cfg = rxring_cfg, ++ .rxfdq_cfg = fdqring_cfg, ++ .ring_rxq_id = K3_RINGACC_RING_ID_ANY, ++ .src_tag_lo_sel = ++ K3_UDMA_GLUE_SRC_TAG_LO_USE_REMOTE_SRC_TAG, ++ }; ++ ++ rx_flow_cfg.ring_rxfdq0_id = fdqring_id; ++ rx_flow_cfg.rx_cfg.size = max_desc_num; ++ rx_flow_cfg.rxfdq_cfg.size = max_desc_num; ++ rx_flow_cfg.rxfdq_cfg.mode = emac->prueth->pdata.fdqring_mode; ++ ++ ret = k3_udma_glue_rx_flow_init(rx_chn->rx_chn, ++ i, &rx_flow_cfg); ++ if (ret) { ++ netdev_err(ndev, "Failed to init rx flow%d %d\n", ++ i, ret); ++ goto fail; ++ } ++ if (!i) ++ fdqring_id = k3_udma_glue_rx_flow_get_fdq_id(rx_chn->rx_chn, ++ i); ++ rx_chn->irq[i] = k3_udma_glue_rx_get_irq(rx_chn->rx_chn, i); ++ if (rx_chn->irq[i] <= 0) { ++ ret = rx_chn->irq[i]; ++ netdev_err(ndev, "Failed to get rx dma irq"); ++ goto fail; ++ } ++ } ++ ++ return 0; ++ ++fail: ++ prueth_cleanup_rx_chns(emac, rx_chn, max_rflows); ++ return ret; ++} ++ ++static int prueth_dma_rx_push(struct prueth_emac *emac, ++ struct sk_buff *skb, ++ struct prueth_rx_chn *rx_chn) ++{ ++ struct net_device *ndev = emac->ndev; ++ struct cppi5_host_desc_t *desc_rx; ++ u32 pkt_len = skb_tailroom(skb); ++ dma_addr_t desc_dma; ++ dma_addr_t buf_dma; ++ void **swdata; ++ ++ desc_rx = k3_cppi_desc_pool_alloc(rx_chn->desc_pool); ++ if (!desc_rx) { ++ netdev_err(ndev, "rx push: failed to allocate descriptor\n"); ++ return -ENOMEM; ++ } ++ desc_dma = k3_cppi_desc_pool_virt2dma(rx_chn->desc_pool, desc_rx); ++ ++ buf_dma = dma_map_single(rx_chn->dma_dev, skb->data, pkt_len, DMA_FROM_DEVICE); ++ if (unlikely(dma_mapping_error(rx_chn->dma_dev, buf_dma))) { ++ k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); ++ netdev_err(ndev, "rx push: failed to map rx pkt buffer\n"); ++ return -EINVAL; ++ } ++ ++ cppi5_hdesc_init(desc_rx, CPPI5_INFO0_HDESC_EPIB_PRESENT, ++ PRUETH_NAV_PS_DATA_SIZE); ++ k3_udma_glue_rx_dma_to_cppi5_addr(rx_chn->rx_chn, &buf_dma); ++ cppi5_hdesc_attach_buf(desc_rx, buf_dma, skb_tailroom(skb), buf_dma, skb_tailroom(skb)); ++ ++ swdata = cppi5_hdesc_get_swdata(desc_rx); ++ *swdata = skb; ++ ++ return k3_udma_glue_push_rx_chn(rx_chn->rx_chn, 0, ++ desc_rx, desc_dma); ++} ++ ++static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) ++{ ++ struct prueth_rx_chn *rx_chn = &emac->rx_chns; ++ u32 buf_dma_len, pkt_len, port_id = 0; ++ struct net_device *ndev = emac->ndev; ++ struct cppi5_host_desc_t *desc_rx; ++ struct sk_buff *skb, *new_skb; ++ dma_addr_t desc_dma, buf_dma; ++ void **swdata; ++ int ret; ++ ++ ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma); ++ if (ret) { ++ if (ret != -ENODATA) ++ netdev_err(ndev, "rx pop: failed: %d\n", ret); ++ return ret; ++ } ++ ++ if (cppi5_desc_is_tdcm(desc_dma)) /* Teardown ? */ ++ return 0; ++ ++ desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma); ++ ++ swdata = cppi5_hdesc_get_swdata(desc_rx); ++ skb = *swdata; ++ ++ cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); ++ k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma); ++ pkt_len = cppi5_hdesc_get_pktlen(desc_rx); ++ /* firmware adds 4 CRC bytes, strip them */ ++ pkt_len -= 4; ++ cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL); ++ ++ dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, DMA_FROM_DEVICE); ++ k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); ++ ++ skb->dev = ndev; ++ new_skb = netdev_alloc_skb_ip_align(ndev, PRUETH_MAX_PKT_SIZE); ++ /* if allocation fails we drop the packet but push the ++ * descriptor back to the ring with old skb to prevent a stall ++ */ ++ if (!new_skb) { ++ ndev->stats.rx_dropped++; ++ new_skb = skb; ++ } else { ++ /* send the filled skb up the n/w stack */ ++ skb_put(skb, pkt_len); ++ skb->protocol = eth_type_trans(skb, ndev); ++ napi_gro_receive(&emac->napi_rx, skb); ++ ndev->stats.rx_bytes += pkt_len; ++ ndev->stats.rx_packets++; ++ } ++ ++ /* queue another RX DMA */ ++ ret = prueth_dma_rx_push(emac, new_skb, &emac->rx_chns); ++ if (WARN_ON(ret < 0)) { ++ dev_kfree_skb_any(new_skb); ++ ndev->stats.rx_errors++; ++ ndev->stats.rx_dropped++; ++ } ++ ++ return ret; ++} ++ ++static void prueth_rx_cleanup(void *data, dma_addr_t desc_dma) ++{ ++ struct prueth_rx_chn *rx_chn = data; ++ struct cppi5_host_desc_t *desc_rx; ++ struct sk_buff *skb; ++ dma_addr_t buf_dma; ++ u32 buf_dma_len; ++ void **swdata; ++ ++ desc_rx = k3_cppi_desc_pool_dma2virt(rx_chn->desc_pool, desc_dma); ++ swdata = cppi5_hdesc_get_swdata(desc_rx); ++ skb = *swdata; ++ cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); ++ k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma); ++ ++ dma_unmap_single(rx_chn->dma_dev, buf_dma, buf_dma_len, ++ DMA_FROM_DEVICE); ++ k3_cppi_desc_pool_free(rx_chn->desc_pool, desc_rx); ++ ++ dev_kfree_skb_any(skb); ++} ++ ++/** ++ * emac_ndo_start_xmit - EMAC Transmit function ++ * @skb: SKB pointer ++ * @ndev: EMAC network adapter ++ * ++ * Called by the system to transmit a packet - we queue the packet in ++ * EMAC hardware transmit queue ++ * Doesn't wait for completion we'll check for TX completion in ++ * emac_tx_complete_packets(). ++ * ++ * Return: enum netdev_tx ++ */ ++static enum netdev_tx emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) ++{ ++ struct cppi5_host_desc_t *first_desc, *next_desc, *cur_desc; ++ struct prueth_emac *emac = netdev_priv(ndev); ++ struct netdev_queue *netif_txq; ++ struct prueth_tx_chn *tx_chn; ++ dma_addr_t desc_dma, buf_dma; ++ int i, ret = 0, q_idx; ++ void **swdata; ++ u32 pkt_len; ++ u32 *epib; ++ ++ pkt_len = skb_headlen(skb); ++ q_idx = skb_get_queue_mapping(skb); ++ ++ tx_chn = &emac->tx_chns[q_idx]; ++ netif_txq = netdev_get_tx_queue(ndev, q_idx); ++ ++ /* Map the linear buffer */ ++ buf_dma = dma_map_single(tx_chn->dma_dev, skb->data, pkt_len, DMA_TO_DEVICE); ++ if (dma_mapping_error(tx_chn->dma_dev, buf_dma)) { ++ netdev_err(ndev, "tx: failed to map skb buffer\n"); ++ ret = NETDEV_TX_OK; ++ goto drop_free_skb; ++ } ++ ++ first_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool); ++ if (!first_desc) { ++ netdev_dbg(ndev, "tx: failed to allocate descriptor\n"); ++ dma_unmap_single(tx_chn->dma_dev, buf_dma, pkt_len, DMA_TO_DEVICE); ++ goto drop_stop_q_busy; ++ } ++ ++ cppi5_hdesc_init(first_desc, CPPI5_INFO0_HDESC_EPIB_PRESENT, ++ PRUETH_NAV_PS_DATA_SIZE); ++ cppi5_hdesc_set_pkttype(first_desc, 0); ++ epib = first_desc->epib; ++ epib[0] = 0; ++ epib[1] = 0; ++ ++ /* set dst tag to indicate internal qid at the firmware which is at ++ * bit8..bit15. bit0..bit7 indicates port num for directed ++ * packets in case of switch mode operation ++ */ ++ cppi5_desc_set_tags_ids(&first_desc->hdr, 0, (emac->port_id | (q_idx << 8))); ++ k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma); ++ cppi5_hdesc_attach_buf(first_desc, buf_dma, pkt_len, buf_dma, pkt_len); ++ swdata = cppi5_hdesc_get_swdata(first_desc); ++ *swdata = skb; ++ ++ /* Handle the case where skb is fragmented in pages */ ++ cur_desc = first_desc; ++ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { ++ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; ++ u32 frag_size = skb_frag_size(frag); ++ ++ next_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool); ++ if (!next_desc) { ++ netdev_err(ndev, ++ "tx: failed to allocate frag. descriptor\n"); ++ goto free_desc_stop_q_busy; ++ } ++ ++ buf_dma = skb_frag_dma_map(tx_chn->dma_dev, frag, 0, frag_size, ++ DMA_TO_DEVICE); ++ if (dma_mapping_error(tx_chn->dma_dev, buf_dma)) { ++ netdev_err(ndev, "tx: Failed to map skb page\n"); ++ k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc); ++ ret = NETDEV_TX_OK; ++ goto drop_free_descs; ++ } ++ ++ cppi5_hdesc_reset_hbdesc(next_desc); ++ k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma); ++ cppi5_hdesc_attach_buf(next_desc, ++ buf_dma, frag_size, buf_dma, frag_size); ++ ++ desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, ++ next_desc); ++ k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &desc_dma); ++ cppi5_hdesc_link_hbdesc(cur_desc, desc_dma); ++ ++ pkt_len += frag_size; ++ cur_desc = next_desc; ++ } ++ WARN_ON_ONCE(pkt_len != skb->len); ++ ++ /* report bql before sending packet */ ++ netdev_tx_sent_queue(netif_txq, pkt_len); ++ ++ cppi5_hdesc_set_pktlen(first_desc, pkt_len); ++ desc_dma = k3_cppi_desc_pool_virt2dma(tx_chn->desc_pool, first_desc); ++ /* cppi5_desc_dump(first_desc, 64); */ ++ ++ skb_tx_timestamp(skb); /* SW timestamp if SKBTX_IN_PROGRESS not set */ ++ ret = k3_udma_glue_push_tx_chn(tx_chn->tx_chn, first_desc, desc_dma); ++ if (ret) { ++ netdev_err(ndev, "tx: push failed: %d\n", ret); ++ goto drop_free_descs; ++ } ++ ++ if (k3_cppi_desc_pool_avail(tx_chn->desc_pool) < MAX_SKB_FRAGS) { ++ netif_tx_stop_queue(netif_txq); ++ /* Barrier, so that stop_queue visible to other cpus */ ++ smp_mb__after_atomic(); ++ ++ if (k3_cppi_desc_pool_avail(tx_chn->desc_pool) >= ++ MAX_SKB_FRAGS) ++ netif_tx_wake_queue(netif_txq); ++ } ++ ++ return NETDEV_TX_OK; ++ ++drop_free_descs: ++ prueth_xmit_free(tx_chn, first_desc); ++ ++drop_free_skb: ++ dev_kfree_skb_any(skb); ++ ++ /* error */ ++ ndev->stats.tx_dropped++; ++ netdev_err(ndev, "tx: error: %d\n", ret); ++ ++ return ret; ++ ++free_desc_stop_q_busy: ++ prueth_xmit_free(tx_chn, first_desc); ++ ++drop_stop_q_busy: ++ netif_tx_stop_queue(netif_txq); ++ return NETDEV_TX_BUSY; ++} ++ ++static void prueth_tx_cleanup(void *data, dma_addr_t desc_dma) ++{ ++ struct prueth_tx_chn *tx_chn = data; ++ struct cppi5_host_desc_t *desc_tx; ++ struct sk_buff *skb; ++ void **swdata; ++ ++ desc_tx = k3_cppi_desc_pool_dma2virt(tx_chn->desc_pool, desc_dma); ++ swdata = cppi5_hdesc_get_swdata(desc_tx); ++ skb = *(swdata); ++ prueth_xmit_free(tx_chn, desc_tx); ++ ++ dev_kfree_skb_any(skb); ++} ++ ++static irqreturn_t prueth_rx_irq(int irq, void *dev_id) ++{ ++ struct prueth_emac *emac = dev_id; ++ ++ disable_irq_nosync(irq); ++ napi_schedule(&emac->napi_rx); ++ ++ return IRQ_HANDLED; ++} ++ ++struct icssg_firmwares { ++ char *pru; ++ char *rtu; ++ char *txpru; ++}; ++ ++static struct icssg_firmwares icssg_emac_firmwares[] = { ++ { ++ .pru = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf", ++ .rtu = "ti-pruss/am65x-sr2-rtu0-prueth-fw.elf", ++ .txpru = "ti-pruss/am65x-sr2-txpru0-prueth-fw.elf", ++ }, ++ { ++ .pru = "ti-pruss/am65x-sr2-pru1-prueth-fw.elf", ++ .rtu = "ti-pruss/am65x-sr2-rtu1-prueth-fw.elf", ++ .txpru = "ti-pruss/am65x-sr2-txpru1-prueth-fw.elf", ++ } ++}; ++ ++static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac) ++{ ++ struct icssg_firmwares *firmwares; ++ struct device *dev = prueth->dev; ++ int slice, ret; ++ ++ firmwares = icssg_emac_firmwares; ++ ++ slice = prueth_emac_slice(emac); ++ if (slice < 0) { ++ netdev_err(emac->ndev, "invalid port\n"); ++ return -EINVAL; ++ } ++ ++ ret = icssg_config(prueth, emac, slice); ++ if (ret) ++ return ret; ++ ++ ret = rproc_set_firmware(prueth->pru[slice], firmwares[slice].pru); ++ ret = rproc_boot(prueth->pru[slice]); ++ if (ret) { ++ dev_err(dev, "failed to boot PRU%d: %d\n", slice, ret); ++ return -EINVAL; ++ } ++ ++ ret = rproc_set_firmware(prueth->rtu[slice], firmwares[slice].rtu); ++ ret = rproc_boot(prueth->rtu[slice]); ++ if (ret) { ++ dev_err(dev, "failed to boot RTU%d: %d\n", slice, ret); ++ goto halt_pru; ++ } ++ ++ ret = rproc_set_firmware(prueth->txpru[slice], firmwares[slice].txpru); ++ ret = rproc_boot(prueth->txpru[slice]); ++ if (ret) { ++ dev_err(dev, "failed to boot TX_PRU%d: %d\n", slice, ret); ++ goto halt_rtu; ++ } ++ ++ emac->fw_running = 1; ++ return 0; ++ ++halt_rtu: ++ rproc_shutdown(prueth->rtu[slice]); ++ ++halt_pru: ++ rproc_shutdown(prueth->pru[slice]); ++ ++ return ret; ++} ++ ++static void prueth_emac_stop(struct prueth_emac *emac) ++{ ++ struct prueth *prueth = emac->prueth; ++ int slice; ++ ++ switch (emac->port_id) { ++ case PRUETH_PORT_MII0: ++ slice = ICSS_SLICE0; ++ break; ++ case PRUETH_PORT_MII1: ++ slice = ICSS_SLICE1; ++ break; ++ default: ++ netdev_err(emac->ndev, "invalid port\n"); ++ return; ++ } ++ ++ emac->fw_running = 0; ++ rproc_shutdown(prueth->txpru[slice]); ++ rproc_shutdown(prueth->rtu[slice]); ++ rproc_shutdown(prueth->pru[slice]); ++} ++ ++/* called back by PHY layer if there is change in link state of hw port*/ ++static void emac_adjust_link(struct net_device *ndev) ++{ ++ struct prueth_emac *emac = netdev_priv(ndev); ++ struct phy_device *phydev = ndev->phydev; ++ struct prueth *prueth = emac->prueth; ++ bool new_state = false; ++ unsigned long flags; ++ ++ if (phydev->link) { ++ /* check the mode of operation - full/half duplex */ ++ if (phydev->duplex != emac->duplex) { ++ new_state = true; ++ emac->duplex = phydev->duplex; ++ } ++ if (phydev->speed != emac->speed) { ++ new_state = true; ++ emac->speed = phydev->speed; ++ } ++ if (!emac->link) { ++ new_state = true; ++ emac->link = 1; ++ } ++ } else if (emac->link) { ++ new_state = true; ++ emac->link = 0; ++ ++ /* f/w should support 100 & 1000 */ ++ emac->speed = SPEED_1000; ++ ++ /* half duplex may not be supported by f/w */ ++ emac->duplex = DUPLEX_FULL; ++ } ++ ++ if (new_state) { ++ phy_print_status(phydev); ++ ++ /* update RGMII and MII configuration based on PHY negotiated ++ * values ++ */ ++ if (emac->link) { ++ /* Set the RGMII cfg for gig en and full duplex */ ++ icssg_update_rgmii_cfg(prueth->miig_rt, emac); ++ ++ /* update the Tx IPG based on 100M/1G speed */ ++ spin_lock_irqsave(&emac->lock, flags); ++ icssg_config_ipg(emac); ++ spin_unlock_irqrestore(&emac->lock, flags); ++ icssg_config_set_speed(emac); ++ emac_set_port_state(emac, ICSSG_EMAC_PORT_FORWARD); ++ ++ } else { ++ emac_set_port_state(emac, ICSSG_EMAC_PORT_DISABLE); ++ } ++ } ++ ++ if (emac->link) { ++ /* reactivate the transmit queue */ ++ netif_tx_wake_all_queues(ndev); ++ } else { ++ netif_tx_stop_all_queues(ndev); ++ } ++} ++ ++static int emac_napi_rx_poll(struct napi_struct *napi_rx, int budget) ++{ ++ struct prueth_emac *emac = prueth_napi_to_emac(napi_rx); ++ int rx_flow = PRUETH_RX_FLOW_DATA; ++ int flow = PRUETH_MAX_RX_FLOWS; ++ int num_rx = 0; ++ int cur_budget; ++ int ret; ++ ++ while (flow--) { ++ cur_budget = budget - num_rx; ++ ++ while (cur_budget--) { ++ ret = emac_rx_packet(emac, flow); ++ if (ret) ++ break; ++ num_rx++; ++ } ++ ++ if (num_rx >= budget) ++ break; ++ } ++ ++ if (num_rx < budget && napi_complete_done(napi_rx, num_rx)) ++ enable_irq(emac->rx_chns.irq[rx_flow]); ++ ++ return num_rx; ++} ++ ++static int prueth_prepare_rx_chan(struct prueth_emac *emac, ++ struct prueth_rx_chn *chn, ++ int buf_size) ++{ ++ struct sk_buff *skb; ++ int i, ret; ++ ++ for (i = 0; i < chn->descs_num; i++) { ++ skb = __netdev_alloc_skb_ip_align(NULL, buf_size, GFP_KERNEL); ++ if (!skb) ++ return -ENOMEM; ++ ++ ret = prueth_dma_rx_push(emac, skb, chn); ++ if (ret < 0) { ++ netdev_err(emac->ndev, ++ "cannot submit skb for rx chan %s ret %d\n", ++ chn->name, ret); ++ kfree_skb(skb); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static void prueth_reset_tx_chan(struct prueth_emac *emac, int ch_num, ++ bool free_skb) ++{ ++ int i; ++ ++ for (i = 0; i < ch_num; i++) { ++ if (free_skb) ++ k3_udma_glue_reset_tx_chn(emac->tx_chns[i].tx_chn, ++ &emac->tx_chns[i], ++ prueth_tx_cleanup); ++ k3_udma_glue_disable_tx_chn(emac->tx_chns[i].tx_chn); ++ } ++} ++ ++static void prueth_reset_rx_chan(struct prueth_rx_chn *chn, ++ int num_flows, bool disable) ++{ ++ int i; ++ ++ for (i = 0; i < num_flows; i++) ++ k3_udma_glue_reset_rx_chn(chn->rx_chn, i, chn, ++ prueth_rx_cleanup, !!i); ++ if (disable) ++ k3_udma_glue_disable_rx_chn(chn->rx_chn); ++} ++ ++static int emac_phy_connect(struct prueth_emac *emac) ++{ ++ struct prueth *prueth = emac->prueth; ++ struct net_device *ndev = emac->ndev; ++ /* connect PHY */ ++ ndev->phydev = of_phy_connect(emac->ndev, emac->phy_node, ++ &emac_adjust_link, 0, ++ emac->phy_if); ++ if (!ndev->phydev) { ++ dev_err(prueth->dev, "couldn't connect to phy %s\n", ++ emac->phy_node->full_name); ++ return -ENODEV; ++ } ++ ++ /* remove unsupported modes */ ++ phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); ++ phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT); ++ phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); ++ phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); ++ phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_Pause_BIT); ++ phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT); ++ ++ if (emac->phy_if == PHY_INTERFACE_MODE_MII) ++ phy_set_max_speed(ndev->phydev, SPEED_100); ++ ++ return 0; ++} ++ ++/** ++ * emac_ndo_open - EMAC device open ++ * @ndev: network adapter device ++ * ++ * Called when system wants to start the interface. ++ * ++ * Return: 0 for a successful open, or appropriate error code ++ */ ++static int emac_ndo_open(struct net_device *ndev) ++{ ++ struct prueth_emac *emac = netdev_priv(ndev); ++ int ret, i, num_data_chn = emac->tx_ch_num; ++ struct prueth *prueth = emac->prueth; ++ int slice = prueth_emac_slice(emac); ++ struct device *dev = prueth->dev; ++ int max_rx_flows; ++ int rx_flow; ++ ++ /* clear SMEM and MSMC settings for all slices */ ++ if (!prueth->emacs_initialized) { ++ memset_io(prueth->msmcram.va, 0, prueth->msmcram.size); ++ memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS); ++ } ++ ++ /* set h/w MAC as user might have re-configured */ ++ ether_addr_copy(emac->mac_addr, ndev->dev_addr); ++ ++ icssg_class_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); ++ icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr); ++ ++ icssg_class_default(prueth->miig_rt, slice, 0); ++ ++ /* Notify the stack of the actual queue counts. */ ++ ret = netif_set_real_num_tx_queues(ndev, num_data_chn); ++ if (ret) { ++ dev_err(dev, "cannot set real number of tx queues\n"); ++ return ret; ++ } ++ ++ init_completion(&emac->cmd_complete); ++ ret = prueth_init_tx_chns(emac); ++ if (ret) { ++ dev_err(dev, "failed to init tx channel: %d\n", ret); ++ return ret; ++ } ++ ++ max_rx_flows = PRUETH_MAX_RX_FLOWS; ++ ret = prueth_init_rx_chns(emac, &emac->rx_chns, "rx", ++ max_rx_flows, PRUETH_MAX_RX_DESC); ++ if (ret) { ++ dev_err(dev, "failed to init rx channel: %d\n", ret); ++ goto cleanup_tx; ++ } ++ ++ ret = prueth_ndev_add_tx_napi(emac); ++ if (ret) ++ goto cleanup_rx; ++ ++ /* we use only the highest priority flow for now i.e. @irq[3] */ ++ rx_flow = PRUETH_RX_FLOW_DATA; ++ ret = request_irq(emac->rx_chns.irq[rx_flow], prueth_rx_irq, ++ IRQF_TRIGGER_HIGH, dev_name(dev), emac); ++ if (ret) { ++ dev_err(dev, "unable to request RX IRQ\n"); ++ goto cleanup_napi; ++ } ++ ++ /* reset and start PRU firmware */ ++ ret = prueth_emac_start(prueth, emac); ++ if (ret) ++ goto free_rx_irq; ++ ++ icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu); ++ ++ /* Prepare RX */ ++ ret = prueth_prepare_rx_chan(emac, &emac->rx_chns, PRUETH_MAX_PKT_SIZE); ++ if (ret) ++ goto stop; ++ ++ ret = k3_udma_glue_enable_rx_chn(emac->rx_chns.rx_chn); ++ if (ret) ++ goto reset_rx_chn; ++ ++ for (i = 0; i < emac->tx_ch_num; i++) { ++ ret = k3_udma_glue_enable_tx_chn(emac->tx_chns[i].tx_chn); ++ if (ret) ++ goto reset_tx_chan; ++ } ++ ++ /* Enable NAPI in Tx and Rx direction */ ++ for (i = 0; i < emac->tx_ch_num; i++) ++ napi_enable(&emac->tx_chns[i].napi_tx); ++ napi_enable(&emac->napi_rx); ++ ++ /* start PHY */ ++ phy_start(ndev->phydev); ++ ++ prueth->emacs_initialized++; ++ ++ return 0; ++ ++reset_tx_chan: ++ /* Since interface is not yet up, there is wouldn't be ++ * any SKB for completion. So set false to free_skb ++ */ ++ prueth_reset_tx_chan(emac, i, false); ++reset_rx_chn: ++ prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, false); ++stop: ++ prueth_emac_stop(emac); ++free_rx_irq: ++ free_irq(emac->rx_chns.irq[rx_flow], emac); ++cleanup_napi: ++ prueth_ndev_del_tx_napi(emac, emac->tx_ch_num); ++cleanup_rx: ++ prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows); ++cleanup_tx: ++ prueth_cleanup_tx_chns(emac); ++ ++ return ret; ++} ++ ++/** ++ * emac_ndo_stop - EMAC device stop ++ * @ndev: network adapter device ++ * ++ * Called when system wants to stop or down the interface. ++ * ++ * Return: Always 0 (Success) ++ */ ++static int emac_ndo_stop(struct net_device *ndev) ++{ ++ struct prueth_emac *emac = netdev_priv(ndev); ++ struct prueth *prueth = emac->prueth; ++ int rx_flow = PRUETH_RX_FLOW_DATA; ++ int max_rx_flows; ++ int ret, i; ++ ++ /* inform the upper layers. */ ++ netif_tx_stop_all_queues(ndev); ++ ++ /* block packets from wire */ ++ if (ndev->phydev) ++ phy_stop(ndev->phydev); ++ ++ icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac)); ++ ++ atomic_set(&emac->tdown_cnt, emac->tx_ch_num); ++ /* ensure new tdown_cnt value is visible */ ++ smp_mb__after_atomic(); ++ /* tear down and disable UDMA channels */ ++ reinit_completion(&emac->tdown_complete); ++ for (i = 0; i < emac->tx_ch_num; i++) ++ k3_udma_glue_tdown_tx_chn(emac->tx_chns[i].tx_chn, false); ++ ++ ret = wait_for_completion_timeout(&emac->tdown_complete, ++ msecs_to_jiffies(1000)); ++ if (!ret) ++ netdev_err(ndev, "tx teardown timeout\n"); ++ ++ prueth_reset_tx_chan(emac, emac->tx_ch_num, true); ++ for (i = 0; i < emac->tx_ch_num; i++) ++ napi_disable(&emac->tx_chns[i].napi_tx); ++ ++ max_rx_flows = PRUETH_MAX_RX_FLOWS; ++ k3_udma_glue_tdown_rx_chn(emac->rx_chns.rx_chn, true); ++ ++ prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, true); ++ ++ napi_disable(&emac->napi_rx); ++ ++ cancel_work_sync(&emac->rx_mode_work); ++ ++ /* stop PRUs */ ++ prueth_emac_stop(emac); ++ ++ free_irq(emac->rx_chns.irq[rx_flow], emac); ++ prueth_ndev_del_tx_napi(emac, emac->tx_ch_num); ++ prueth_cleanup_tx_chns(emac); ++ ++ prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows); ++ prueth_cleanup_tx_chns(emac); ++ ++ prueth->emacs_initialized--; ++ ++ return 0; ++} ++ ++static void emac_ndo_tx_timeout(struct net_device *ndev, unsigned int txqueue) ++{ ++ ndev->stats.tx_errors++; ++} ++ ++static void emac_ndo_set_rx_mode_work(struct work_struct *work) ++{ ++ struct prueth_emac *emac = container_of(work, struct prueth_emac, rx_mode_work); ++ struct net_device *ndev = emac->ndev; ++ bool promisc, allmulti; ++ ++ if (!netif_running(ndev)) ++ return; ++ ++ promisc = ndev->flags & IFF_PROMISC; ++ allmulti = ndev->flags & IFF_ALLMULTI; ++ emac_set_port_state(emac, ICSSG_EMAC_PORT_UC_FLOODING_DISABLE); ++ emac_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_DISABLE); ++ ++ if (promisc) { ++ emac_set_port_state(emac, ICSSG_EMAC_PORT_UC_FLOODING_ENABLE); ++ emac_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_ENABLE); ++ return; ++ } ++ ++ if (allmulti) { ++ emac_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_ENABLE); ++ return; ++ } ++ ++ if (!netdev_mc_empty(ndev)) { ++ emac_set_port_state(emac, ICSSG_EMAC_PORT_MC_FLOODING_ENABLE); ++ return; ++ } ++} ++ ++/** ++ * emac_ndo_set_rx_mode - EMAC set receive mode function ++ * @ndev: The EMAC network adapter ++ * ++ * Called when system wants to set the receive mode of the device. ++ * ++ */ ++static void emac_ndo_set_rx_mode(struct net_device *ndev) ++{ ++ struct prueth_emac *emac = netdev_priv(ndev); ++ ++ queue_work(emac->cmd_wq, &emac->rx_mode_work); ++} ++ ++static int emac_ndo_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) ++{ ++ return phy_do_ioctl(ndev, ifr, cmd); ++} ++ ++static const struct net_device_ops emac_netdev_ops = { ++ .ndo_open = emac_ndo_open, ++ .ndo_stop = emac_ndo_stop, ++ .ndo_start_xmit = emac_ndo_start_xmit, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_tx_timeout = emac_ndo_tx_timeout, ++ .ndo_set_rx_mode = emac_ndo_set_rx_mode, ++ .ndo_eth_ioctl = emac_ndo_ioctl, ++}; ++ ++/* get emac_port corresponding to eth_node name */ ++static int prueth_node_port(struct device_node *eth_node) ++{ ++ u32 port_id; ++ int ret; ++ ++ ret = of_property_read_u32(eth_node, "reg", &port_id); ++ if (ret) ++ return ret; ++ ++ if (port_id == 0) ++ return PRUETH_PORT_MII0; ++ else if (port_id == 1) ++ return PRUETH_PORT_MII1; ++ else ++ return PRUETH_PORT_INVALID; ++} ++ ++/* get MAC instance corresponding to eth_node name */ ++static int prueth_node_mac(struct device_node *eth_node) ++{ ++ u32 port_id; ++ int ret; ++ ++ ret = of_property_read_u32(eth_node, "reg", &port_id); ++ if (ret) ++ return ret; ++ ++ if (port_id == 0) ++ return PRUETH_MAC0; ++ else if (port_id == 1) ++ return PRUETH_MAC1; ++ else ++ return PRUETH_MAC_INVALID; ++} ++ ++static int prueth_netdev_init(struct prueth *prueth, ++ struct device_node *eth_node) ++{ ++ int ret, num_tx_chn = PRUETH_MAX_TX_QUEUES; ++ struct prueth_emac *emac; ++ struct net_device *ndev; ++ enum prueth_port port; ++ enum prueth_mac mac; ++ ++ port = prueth_node_port(eth_node); ++ if (port == PRUETH_PORT_INVALID) ++ return -EINVAL; ++ ++ mac = prueth_node_mac(eth_node); ++ if (mac == PRUETH_MAC_INVALID) ++ return -EINVAL; ++ ++ ndev = alloc_etherdev_mq(sizeof(*emac), num_tx_chn); ++ if (!ndev) ++ return -ENOMEM; ++ ++ emac = netdev_priv(ndev); ++ emac->prueth = prueth; ++ emac->ndev = ndev; ++ emac->port_id = port; ++ emac->cmd_wq = create_singlethread_workqueue("icssg_cmd_wq"); ++ if (!emac->cmd_wq) { ++ ret = -ENOMEM; ++ goto free_ndev; ++ } ++ INIT_WORK(&emac->rx_mode_work, emac_ndo_set_rx_mode_work); ++ ++ ret = pruss_request_mem_region(prueth->pruss, ++ port == PRUETH_PORT_MII0 ? ++ PRUSS_MEM_DRAM0 : PRUSS_MEM_DRAM1, ++ &emac->dram); ++ if (ret) { ++ dev_err(prueth->dev, "unable to get DRAM: %d\n", ret); ++ ret = -ENOMEM; ++ goto free_wq; ++ } ++ ++ emac->tx_ch_num = 1; ++ ++ SET_NETDEV_DEV(ndev, prueth->dev); ++ spin_lock_init(&emac->lock); ++ mutex_init(&emac->cmd_lock); ++ ++ emac->phy_node = of_parse_phandle(eth_node, "phy-handle", 0); ++ if (!emac->phy_node && !of_phy_is_fixed_link(eth_node)) { ++ dev_err(prueth->dev, "couldn't find phy-handle\n"); ++ ret = -ENODEV; ++ goto free; ++ } else if (of_phy_is_fixed_link(eth_node)) { ++ ret = of_phy_register_fixed_link(eth_node); ++ if (ret) { ++ ret = dev_err_probe(prueth->dev, ret, ++ "failed to register fixed-link phy\n"); ++ goto free; ++ } ++ ++ emac->phy_node = eth_node; ++ } ++ ++ ret = of_get_phy_mode(eth_node, &emac->phy_if); ++ if (ret) { ++ dev_err(prueth->dev, "could not get phy-mode property\n"); ++ goto free; ++ } ++ ++ if (emac->phy_if != PHY_INTERFACE_MODE_MII && ++ !phy_interface_mode_is_rgmii(emac->phy_if)) { ++ dev_err(prueth->dev, "PHY mode unsupported %s\n", phy_modes(emac->phy_if)); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ /* AM65 SR2.0 has TX Internal delay always enabled by hardware ++ * and it is not possible to disable TX Internal delay. The below ++ * switch case block describes how we handle different phy modes ++ * based on hardware restriction. ++ */ ++ switch (emac->phy_if) { ++ case PHY_INTERFACE_MODE_RGMII_ID: ++ emac->phy_if = PHY_INTERFACE_MODE_RGMII_RXID; ++ break; ++ case PHY_INTERFACE_MODE_RGMII_TXID: ++ emac->phy_if = PHY_INTERFACE_MODE_RGMII; ++ break; ++ case PHY_INTERFACE_MODE_RGMII: ++ case PHY_INTERFACE_MODE_RGMII_RXID: ++ dev_err(prueth->dev, "RGMII mode without TX delay is not supported"); ++ ret = -EINVAL; ++ goto free; ++ default: ++ break; ++ } ++ ++ /* get mac address from DT and set private and netdev addr */ ++ ret = of_get_ethdev_address(eth_node, ndev); ++ if (!is_valid_ether_addr(ndev->dev_addr)) { ++ eth_hw_addr_random(ndev); ++ dev_warn(prueth->dev, "port %d: using random MAC addr: %pM\n", ++ port, ndev->dev_addr); ++ } ++ ether_addr_copy(emac->mac_addr, ndev->dev_addr); ++ ++ ndev->min_mtu = PRUETH_MIN_PKT_SIZE; ++ ndev->max_mtu = PRUETH_MAX_MTU; ++ ndev->netdev_ops = &emac_netdev_ops; ++ ndev->hw_features = NETIF_F_SG; ++ ndev->features = ndev->hw_features; ++ ++ netif_napi_add(ndev, &emac->napi_rx, emac_napi_rx_poll); ++ prueth->emac[mac] = emac; ++ ++ return 0; ++ ++free: ++ pruss_release_mem_region(prueth->pruss, &emac->dram); ++free_wq: ++ destroy_workqueue(emac->cmd_wq); ++free_ndev: ++ emac->ndev = NULL; ++ prueth->emac[mac] = NULL; ++ free_netdev(ndev); ++ ++ return ret; ++} ++ ++static void prueth_netdev_exit(struct prueth *prueth, ++ struct device_node *eth_node) ++{ ++ struct prueth_emac *emac; ++ enum prueth_mac mac; ++ ++ mac = prueth_node_mac(eth_node); ++ if (mac == PRUETH_MAC_INVALID) ++ return; ++ ++ emac = prueth->emac[mac]; ++ if (!emac) ++ return; ++ ++ if (of_phy_is_fixed_link(emac->phy_node)) ++ of_phy_deregister_fixed_link(emac->phy_node); ++ ++ netif_napi_del(&emac->napi_rx); ++ ++ pruss_release_mem_region(prueth->pruss, &emac->dram); ++ destroy_workqueue(emac->cmd_wq); ++ free_netdev(emac->ndev); ++ prueth->emac[mac] = NULL; ++} ++ ++static int prueth_get_cores(struct prueth *prueth, int slice) ++{ ++ struct device *dev = prueth->dev; ++ enum pruss_pru_id pruss_id; ++ struct device_node *np; ++ int idx = -1, ret; ++ ++ np = dev->of_node; ++ ++ switch (slice) { ++ case ICSS_SLICE0: ++ idx = 0; ++ break; ++ case ICSS_SLICE1: ++ idx = 3; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ prueth->pru[slice] = pru_rproc_get(np, idx, &pruss_id); ++ if (IS_ERR(prueth->pru[slice])) { ++ ret = PTR_ERR(prueth->pru[slice]); ++ prueth->pru[slice] = NULL; ++ return dev_err_probe(dev, ret, "unable to get PRU%d\n", slice); ++ } ++ prueth->pru_id[slice] = pruss_id; ++ ++ idx++; ++ prueth->rtu[slice] = pru_rproc_get(np, idx, NULL); ++ if (IS_ERR(prueth->rtu[slice])) { ++ ret = PTR_ERR(prueth->rtu[slice]); ++ prueth->rtu[slice] = NULL; ++ return dev_err_probe(dev, ret, "unable to get RTU%d\n", slice); ++ } ++ ++ idx++; ++ prueth->txpru[slice] = pru_rproc_get(np, idx, NULL); ++ if (IS_ERR(prueth->txpru[slice])) { ++ ret = PTR_ERR(prueth->txpru[slice]); ++ prueth->txpru[slice] = NULL; ++ return dev_err_probe(dev, ret, "unable to get TX_PRU%d\n", slice); ++ } ++ ++ return 0; ++} ++ ++static void prueth_put_cores(struct prueth *prueth, int slice) ++{ ++ if (prueth->txpru[slice]) ++ pru_rproc_put(prueth->txpru[slice]); ++ ++ if (prueth->rtu[slice]) ++ pru_rproc_put(prueth->rtu[slice]); ++ ++ if (prueth->pru[slice]) ++ pru_rproc_put(prueth->pru[slice]); ++} ++ ++static const struct of_device_id prueth_dt_match[]; ++ ++static int prueth_probe(struct platform_device *pdev) ++{ ++ struct device_node *eth_node, *eth_ports_node; ++ struct device_node *eth0_node = NULL; ++ struct device_node *eth1_node = NULL; ++ struct genpool_data_align gp_data = { ++ .align = SZ_64K, ++ }; ++ const struct of_device_id *match; ++ struct device *dev = &pdev->dev; ++ struct device_node *np; ++ struct prueth *prueth; ++ struct pruss *pruss; ++ u32 msmc_ram_size; ++ int i, ret; ++ ++ np = dev->of_node; ++ ++ match = of_match_device(prueth_dt_match, dev); ++ if (!match) ++ return -ENODEV; ++ ++ prueth = devm_kzalloc(dev, sizeof(*prueth), GFP_KERNEL); ++ if (!prueth) ++ return -ENOMEM; ++ ++ dev_set_drvdata(dev, prueth); ++ prueth->pdev = pdev; ++ prueth->pdata = *(const struct prueth_pdata *)match->data; ++ ++ prueth->dev = dev; ++ eth_ports_node = of_get_child_by_name(np, "ethernet-ports"); ++ if (!eth_ports_node) ++ return -ENOENT; ++ ++ for_each_child_of_node(eth_ports_node, eth_node) { ++ u32 reg; ++ ++ if (strcmp(eth_node->name, "port")) ++ continue; ++ ret = of_property_read_u32(eth_node, "reg", ®); ++ if (ret < 0) { ++ dev_err(dev, "%pOF error reading port_id %d\n", ++ eth_node, ret); ++ } ++ ++ of_node_get(eth_node); ++ ++ if (reg == 0) { ++ eth0_node = eth_node; ++ if (!of_device_is_available(eth0_node)) { ++ of_node_put(eth0_node); ++ eth0_node = NULL; ++ } ++ } else if (reg == 1) { ++ eth1_node = eth_node; ++ if (!of_device_is_available(eth1_node)) { ++ of_node_put(eth1_node); ++ eth1_node = NULL; ++ } ++ } else { ++ dev_err(dev, "port reg should be 0 or 1\n"); ++ } ++ } ++ ++ of_node_put(eth_ports_node); ++ ++ /* At least one node must be present and available else we fail */ ++ if (!eth0_node && !eth1_node) { ++ dev_err(dev, "neither port0 nor port1 node available\n"); ++ return -ENODEV; ++ } ++ ++ if (eth0_node == eth1_node) { ++ dev_err(dev, "port0 and port1 can't have same reg\n"); ++ of_node_put(eth0_node); ++ return -ENODEV; ++ } ++ ++ prueth->eth_node[PRUETH_MAC0] = eth0_node; ++ prueth->eth_node[PRUETH_MAC1] = eth1_node; ++ ++ prueth->miig_rt = syscon_regmap_lookup_by_phandle(np, "ti,mii-g-rt"); ++ if (IS_ERR(prueth->miig_rt)) { ++ dev_err(dev, "couldn't get ti,mii-g-rt syscon regmap\n"); ++ return -ENODEV; ++ } ++ ++ prueth->mii_rt = syscon_regmap_lookup_by_phandle(np, "ti,mii-rt"); ++ if (IS_ERR(prueth->mii_rt)) { ++ dev_err(dev, "couldn't get ti,mii-rt syscon regmap\n"); ++ return -ENODEV; ++ } ++ ++ if (eth0_node) { ++ ret = prueth_get_cores(prueth, ICSS_SLICE0); ++ if (ret) ++ goto put_cores; ++ } ++ ++ if (eth1_node) { ++ ret = prueth_get_cores(prueth, ICSS_SLICE1); ++ if (ret) ++ goto put_cores; ++ } ++ ++ pruss = pruss_get(eth0_node ? ++ prueth->pru[ICSS_SLICE0] : prueth->pru[ICSS_SLICE1]); ++ if (IS_ERR(pruss)) { ++ ret = PTR_ERR(pruss); ++ dev_err(dev, "unable to get pruss handle\n"); ++ goto put_cores; ++ } ++ ++ prueth->pruss = pruss; ++ ++ ret = pruss_request_mem_region(pruss, PRUSS_MEM_SHRD_RAM2, ++ &prueth->shram); ++ if (ret) { ++ dev_err(dev, "unable to get PRUSS SHRD RAM2: %d\n", ret); ++ pruss_put(prueth->pruss); ++ } ++ ++ prueth->sram_pool = of_gen_pool_get(np, "sram", 0); ++ if (!prueth->sram_pool) { ++ dev_err(dev, "unable to get SRAM pool\n"); ++ ret = -ENODEV; ++ ++ goto put_mem; ++ } ++ ++ msmc_ram_size = MSMC_RAM_SIZE; ++ ++ /* NOTE: FW bug needs buffer base to be 64KB aligned */ ++ prueth->msmcram.va = ++ (void __iomem *)gen_pool_alloc_algo(prueth->sram_pool, ++ msmc_ram_size, ++ gen_pool_first_fit_align, ++ &gp_data); ++ ++ if (!prueth->msmcram.va) { ++ ret = -ENOMEM; ++ dev_err(dev, "unable to allocate MSMC resource\n"); ++ goto put_mem; ++ } ++ prueth->msmcram.pa = gen_pool_virt_to_phys(prueth->sram_pool, ++ (unsigned long)prueth->msmcram.va); ++ prueth->msmcram.size = msmc_ram_size; ++ memset_io(prueth->msmcram.va, 0, msmc_ram_size); ++ dev_dbg(dev, "sram: pa %llx va %p size %zx\n", prueth->msmcram.pa, ++ prueth->msmcram.va, prueth->msmcram.size); ++ ++ /* setup netdev interfaces */ ++ if (eth0_node) { ++ ret = prueth_netdev_init(prueth, eth0_node); ++ if (ret) { ++ dev_err_probe(dev, ret, "netdev init %s failed\n", ++ eth0_node->name); ++ goto netdev_exit; ++ } ++ } ++ ++ if (eth1_node) { ++ ret = prueth_netdev_init(prueth, eth1_node); ++ if (ret) { ++ dev_err_probe(dev, ret, "netdev init %s failed\n", ++ eth1_node->name); ++ goto netdev_exit; ++ } ++ } ++ ++ /* register the network devices */ ++ if (eth0_node) { ++ ret = register_netdev(prueth->emac[PRUETH_MAC0]->ndev); ++ if (ret) { ++ dev_err(dev, "can't register netdev for port MII0"); ++ goto netdev_exit; ++ } ++ ++ prueth->registered_netdevs[PRUETH_MAC0] = prueth->emac[PRUETH_MAC0]->ndev; ++ ++ emac_phy_connect(prueth->emac[PRUETH_MAC0]); ++ phy_attached_info(prueth->emac[PRUETH_MAC0]->ndev->phydev); ++ } ++ ++ if (eth1_node) { ++ ret = register_netdev(prueth->emac[PRUETH_MAC1]->ndev); ++ if (ret) { ++ dev_err(dev, "can't register netdev for port MII1"); ++ goto netdev_unregister; ++ } ++ ++ prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev; ++ emac_phy_connect(prueth->emac[PRUETH_MAC1]); ++ phy_attached_info(prueth->emac[PRUETH_MAC1]->ndev->phydev); ++ } ++ ++ dev_info(dev, "TI PRU ethernet driver initialized: %s EMAC mode\n", ++ (!eth0_node || !eth1_node) ? "single" : "dual"); ++ ++ if (eth1_node) ++ of_node_put(eth1_node); ++ if (eth0_node) ++ of_node_put(eth0_node); ++ return 0; ++ ++netdev_unregister: ++ for (i = 0; i < PRUETH_NUM_MACS; i++) { ++ if (!prueth->registered_netdevs[i]) ++ continue; ++ if (prueth->emac[i]->ndev->phydev) { ++ phy_disconnect(prueth->emac[i]->ndev->phydev); ++ prueth->emac[i]->ndev->phydev = NULL; ++ } ++ unregister_netdev(prueth->registered_netdevs[i]); ++ } ++ ++netdev_exit: ++ for (i = 0; i < PRUETH_NUM_MACS; i++) { ++ eth_node = prueth->eth_node[i]; ++ if (!eth_node) ++ continue; ++ ++ prueth_netdev_exit(prueth, eth_node); ++ } ++ ++ gen_pool_free(prueth->sram_pool, ++ (unsigned long)prueth->msmcram.va, msmc_ram_size); ++ ++put_mem: ++ pruss_release_mem_region(prueth->pruss, &prueth->shram); ++ pruss_put(prueth->pruss); ++ ++put_cores: ++ if (eth1_node) { ++ prueth_put_cores(prueth, ICSS_SLICE1); ++ of_node_put(eth1_node); ++ } ++ ++ if (eth0_node) { ++ prueth_put_cores(prueth, ICSS_SLICE0); ++ of_node_put(eth0_node); ++ } ++ ++ return ret; ++} ++ ++static void prueth_remove(struct platform_device *pdev) ++{ ++ struct prueth *prueth = platform_get_drvdata(pdev); ++ struct device_node *eth_node; ++ int i; ++ ++ for (i = 0; i < PRUETH_NUM_MACS; i++) { ++ if (!prueth->registered_netdevs[i]) ++ continue; ++ phy_stop(prueth->emac[i]->ndev->phydev); ++ phy_disconnect(prueth->emac[i]->ndev->phydev); ++ prueth->emac[i]->ndev->phydev = NULL; ++ unregister_netdev(prueth->registered_netdevs[i]); ++ } ++ ++ for (i = 0; i < PRUETH_NUM_MACS; i++) { ++ eth_node = prueth->eth_node[i]; ++ if (!eth_node) ++ continue; ++ ++ prueth_netdev_exit(prueth, eth_node); ++ } ++ ++ gen_pool_free(prueth->sram_pool, ++ (unsigned long)prueth->msmcram.va, ++ MSMC_RAM_SIZE); ++ ++ pruss_release_mem_region(prueth->pruss, &prueth->shram); ++ ++ pruss_put(prueth->pruss); ++ ++ if (prueth->eth_node[PRUETH_MAC1]) ++ prueth_put_cores(prueth, ICSS_SLICE1); ++ ++ if (prueth->eth_node[PRUETH_MAC0]) ++ prueth_put_cores(prueth, ICSS_SLICE0); ++} ++ ++static const struct prueth_pdata am654_icssg_pdata = { ++ .fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE, ++ .quirk_10m_link_issue = 1, ++}; ++ ++static const struct of_device_id prueth_dt_match[] = { ++ { .compatible = "ti,am654-icssg-prueth", .data = &am654_icssg_pdata }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, prueth_dt_match); ++ ++static struct platform_driver prueth_driver = { ++ .probe = prueth_probe, ++ .remove_new = prueth_remove, ++ .driver = { ++ .name = "icssg-prueth", ++ .of_match_table = prueth_dt_match, ++ }, ++}; ++module_platform_driver(prueth_driver); ++ ++MODULE_AUTHOR("Roger Quadros "); ++MODULE_AUTHOR("Md Danish Anwar "); ++MODULE_DESCRIPTION("PRUSS ICSSG Ethernet Driver"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +index 42fdf4005010..b3a923e7a5c9 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +@@ -34,13 +34,42 @@ + + #include + ++#include "icssg_config.h" + #include "icssg_switch_map.h" + ++#define PRUETH_MAX_MTU (2000 - ETH_HLEN - ETH_FCS_LEN) ++#define PRUETH_MIN_PKT_SIZE (VLAN_ETH_ZLEN) ++#define PRUETH_MAX_PKT_SIZE (PRUETH_MAX_MTU + ETH_HLEN + ETH_FCS_LEN) ++ + #define ICSS_SLICE0 0 + #define ICSS_SLICE1 1 + ++#define ICSS_FW_PRU 0 ++#define ICSS_FW_RTU 1 ++ + #define ICSSG_MAX_RFLOWS 8 /* per slice */ + ++/* Firmware status codes */ ++#define ICSS_HS_FW_READY 0x55555555 ++#define ICSS_HS_FW_DEAD 0xDEAD0000 /* lower 16 bits contain error code */ ++ ++/* Firmware command codes */ ++#define ICSS_HS_CMD_BUSY 0x40000000 ++#define ICSS_HS_CMD_DONE 0x80000000 ++#define ICSS_HS_CMD_CANCEL 0x10000000 ++ ++/* Firmware commands */ ++#define ICSS_CMD_SPAD 0x20 ++#define ICSS_CMD_RXTX 0x10 ++#define ICSS_CMD_ADD_FDB 0x1 ++#define ICSS_CMD_DEL_FDB 0x2 ++#define ICSS_CMD_SET_RUN 0x4 ++#define ICSS_CMD_GET_FDB_SLOT 0x5 ++#define ICSS_CMD_ENABLE_VLAN 0x5 ++#define ICSS_CMD_DISABLE_VLAN 0x6 ++#define ICSS_CMD_ADD_FILTER 0x7 ++#define ICSS_CMD_ADD_MAC 0x8 ++ + /* In switch mode there are 3 real ports i.e. 3 mac addrs. + * however Linux sees only the host side port. The other 2 ports + * are the switch ports. +@@ -214,4 +243,7 @@ int icssg_queue_pop(struct prueth *prueth, u8 queue); + void icssg_queue_push(struct prueth *prueth, int queue, u16 addr); + u32 icssg_queue_level(struct prueth *prueth, int queue); + ++#define prueth_napi_to_tx_chn(pnapi) \ ++ container_of(pnapi, struct prueth_tx_chn, napi_tx) ++ + #endif /* __NET_TI_ICSSG_PRUETH_H */ +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0022-net-ti-icssg-prueth-Add-ICSSG-Stats.patch b/recipes-kernel/linux/files/patches-6.1/0022-net-ti-icssg-prueth-Add-ICSSG-Stats.patch new file mode 100644 index 000000000..7aa23a6f1 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0022-net-ti-icssg-prueth-Add-ICSSG-Stats.patch @@ -0,0 +1,331 @@ +From 38319c40544ec9e5b67ddf9a806d328f183b91a2 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Tue, 1 Aug 2023 14:44:25 +0530 +Subject: [PATCH 22/76] net: ti: icssg-prueth: Add ICSSG Stats + +Add icssg_stats.c to help dump, icssg related driver statistics. + +ICSSG has hardware registers for providing statistics like total rx bytes, +total tx bytes, etc. These registers are of 32 bits and hence in case of 1G +link, they overflows in around 32 seconds. The behaviour of these registers +is such that they don't roll back to 0 after overflow but rather stay at +UINT_MAX. + +These registers support a feature where the value written to them is +subtracted from the register. This feature can be utilized to fix the +overflowing of stats. + +This solution uses a Workqueues based solution where a function gets +called before the registers overflow (every 25 seconds in 1G link, 25000 +seconds in 100M link), this function saves the register +values in local variables and writes the last read value to the +register. So any update during the read will be taken care of. + +Signed-off-by: MD Danish Anwar +--- + drivers/net/ethernet/ti/Makefile | 1 + + drivers/net/ethernet/ti/icssg/icssg_prueth.c | 8 + + drivers/net/ethernet/ti/icssg/icssg_prueth.h | 8 + + drivers/net/ethernet/ti/icssg/icssg_stats.c | 44 ++++++ + drivers/net/ethernet/ti/icssg/icssg_stats.h | 158 +++++++++++++++++++ + 5 files changed, 219 insertions(+) + create mode 100644 drivers/net/ethernet/ti/icssg/icssg_stats.c + create mode 100644 drivers/net/ethernet/ti/icssg/icssg_stats.h + +diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile +index efb050cbb4a8..03d9b2b36b5f 100644 +--- a/drivers/net/ethernet/ti/Makefile ++++ b/drivers/net/ethernet/ti/Makefile +@@ -36,3 +36,4 @@ icssg-prueth-y := k3-cppi-desc-pool.o \ + icssg/icssg_queues.o \ + icssg/icssg_config.o \ + icssg/icssg_mii_cfg.o \ ++ icssg/icssg_stats.o \ +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +index 1869e38f898f..d0bb4db11b30 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +@@ -8,6 +8,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -1090,6 +1091,8 @@ static int emac_ndo_open(struct net_device *ndev) + + prueth->emacs_initialized++; + ++ queue_work(system_long_wq, &emac->stats_work.work); ++ + return 0; + + reset_tx_chan: +@@ -1164,6 +1167,9 @@ static int emac_ndo_stop(struct net_device *ndev) + + cancel_work_sync(&emac->rx_mode_work); + ++ /* Destroying the queued work in ndo_stop() */ ++ cancel_delayed_work_sync(&emac->stats_work); ++ + /* stop PRUs */ + prueth_emac_stop(emac); + +@@ -1313,6 +1319,8 @@ static int prueth_netdev_init(struct prueth *prueth, + } + INIT_WORK(&emac->rx_mode_work, emac_ndo_set_rx_mode_work); + ++ INIT_DELAYED_WORK(&emac->stats_work, emac_stats_work_handler); ++ + ret = pruss_request_mem_region(prueth->pruss, + port == PRUETH_PORT_MII0 ? + PRUSS_MEM_DRAM0 : PRUSS_MEM_DRAM1, +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +index b3a923e7a5c9..f13de0d2e90b 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +@@ -49,6 +49,9 @@ + + #define ICSSG_MAX_RFLOWS 8 /* per slice */ + ++/* Number of ICSSG related stats */ ++#define ICSSG_NUM_STATS 60 ++ + /* Firmware status codes */ + #define ICSS_HS_FW_READY 0x55555555 + #define ICSS_HS_FW_DEAD 0xDEAD0000 /* lower 16 bits contain error code */ +@@ -153,6 +156,9 @@ struct prueth_emac { + struct workqueue_struct *cmd_wq; + + struct pruss_mem_region dram; ++ ++ struct delayed_work stats_work; ++ u64 stats[ICSSG_NUM_STATS]; + }; + + /** +@@ -246,4 +252,6 @@ u32 icssg_queue_level(struct prueth *prueth, int queue); + #define prueth_napi_to_tx_chn(pnapi) \ + container_of(pnapi, struct prueth_tx_chn, napi_tx) + ++void emac_stats_work_handler(struct work_struct *work); ++void emac_update_hardware_stats(struct prueth_emac *emac); + #endif /* __NET_TI_ICSSG_PRUETH_H */ +diff --git a/drivers/net/ethernet/ti/icssg/icssg_stats.c b/drivers/net/ethernet/ti/icssg/icssg_stats.c +new file mode 100644 +index 000000000000..25deb368a3f0 +--- /dev/null ++++ b/drivers/net/ethernet/ti/icssg/icssg_stats.c +@@ -0,0 +1,44 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Texas Instruments ICSSG Ethernet driver ++ * ++ * Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/ ++ * ++ */ ++ ++#include "icssg_prueth.h" ++#include "icssg_stats.h" ++#include ++ ++static u32 stats_base[] = { 0x54c, /* Slice 0 stats start */ ++ 0xb18, /* Slice 1 stats start */ ++}; ++ ++void emac_update_hardware_stats(struct prueth_emac *emac) ++{ ++ struct prueth *prueth = emac->prueth; ++ int slice = prueth_emac_slice(emac); ++ u32 base = stats_base[slice]; ++ u32 val; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) { ++ regmap_read(prueth->miig_rt, ++ base + icssg_all_stats[i].offset, ++ &val); ++ regmap_write(prueth->miig_rt, ++ base + icssg_all_stats[i].offset, ++ val); ++ ++ emac->stats[i] += val; ++ } ++} ++ ++void emac_stats_work_handler(struct work_struct *work) ++{ ++ struct prueth_emac *emac = container_of(work, struct prueth_emac, ++ stats_work.work); ++ emac_update_hardware_stats(emac); ++ ++ queue_delayed_work(system_long_wq, &emac->stats_work, ++ msecs_to_jiffies((STATS_TIME_LIMIT_1G_MS * 1000) / emac->speed)); ++} +diff --git a/drivers/net/ethernet/ti/icssg/icssg_stats.h b/drivers/net/ethernet/ti/icssg/icssg_stats.h +new file mode 100644 +index 000000000000..999a4a91276c +--- /dev/null ++++ b/drivers/net/ethernet/ti/icssg/icssg_stats.h +@@ -0,0 +1,158 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* Texas Instruments ICSSG Ethernet driver ++ * ++ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/ ++ * ++ */ ++ ++#ifndef __NET_TI_ICSSG_STATS_H ++#define __NET_TI_ICSSG_STATS_H ++ ++#include "icssg_prueth.h" ++ ++#define STATS_TIME_LIMIT_1G_MS 25000 /* 25 seconds @ 1G */ ++ ++struct miig_stats_regs { ++ /* Rx */ ++ u32 rx_packets; ++ u32 rx_broadcast_frames; ++ u32 rx_multicast_frames; ++ u32 rx_crc_errors; ++ u32 rx_mii_error_frames; ++ u32 rx_odd_nibble_frames; ++ u32 rx_frame_max_size; ++ u32 rx_max_size_error_frames; ++ u32 rx_frame_min_size; ++ u32 rx_min_size_error_frames; ++ u32 rx_over_errors; ++ u32 rx_class0_hits; ++ u32 rx_class1_hits; ++ u32 rx_class2_hits; ++ u32 rx_class3_hits; ++ u32 rx_class4_hits; ++ u32 rx_class5_hits; ++ u32 rx_class6_hits; ++ u32 rx_class7_hits; ++ u32 rx_class8_hits; ++ u32 rx_class9_hits; ++ u32 rx_class10_hits; ++ u32 rx_class11_hits; ++ u32 rx_class12_hits; ++ u32 rx_class13_hits; ++ u32 rx_class14_hits; ++ u32 rx_class15_hits; ++ u32 rx_smd_frags; ++ u32 rx_bucket1_size; ++ u32 rx_bucket2_size; ++ u32 rx_bucket3_size; ++ u32 rx_bucket4_size; ++ u32 rx_64B_frames; ++ u32 rx_bucket1_frames; ++ u32 rx_bucket2_frames; ++ u32 rx_bucket3_frames; ++ u32 rx_bucket4_frames; ++ u32 rx_bucket5_frames; ++ u32 rx_bytes; ++ u32 rx_tx_total_bytes; ++ /* Tx */ ++ u32 tx_packets; ++ u32 tx_broadcast_frames; ++ u32 tx_multicast_frames; ++ u32 tx_odd_nibble_frames; ++ u32 tx_underflow_errors; ++ u32 tx_frame_max_size; ++ u32 tx_max_size_error_frames; ++ u32 tx_frame_min_size; ++ u32 tx_min_size_error_frames; ++ u32 tx_bucket1_size; ++ u32 tx_bucket2_size; ++ u32 tx_bucket3_size; ++ u32 tx_bucket4_size; ++ u32 tx_64B_frames; ++ u32 tx_bucket1_frames; ++ u32 tx_bucket2_frames; ++ u32 tx_bucket3_frames; ++ u32 tx_bucket4_frames; ++ u32 tx_bucket5_frames; ++ u32 tx_bytes; ++}; ++ ++#define ICSSG_STATS(field, stats_type) \ ++{ \ ++ #field, \ ++ offsetof(struct miig_stats_regs, field), \ ++ stats_type \ ++} ++ ++struct icssg_stats { ++ char name[ETH_GSTRING_LEN]; ++ u32 offset; ++ bool standard_stats; ++}; ++ ++static const struct icssg_stats icssg_all_stats[] = { ++ /* Rx */ ++ ICSSG_STATS(rx_packets, true), ++ ICSSG_STATS(rx_broadcast_frames, false), ++ ICSSG_STATS(rx_multicast_frames, true), ++ ICSSG_STATS(rx_crc_errors, true), ++ ICSSG_STATS(rx_mii_error_frames, false), ++ ICSSG_STATS(rx_odd_nibble_frames, false), ++ ICSSG_STATS(rx_frame_max_size, true), ++ ICSSG_STATS(rx_max_size_error_frames, false), ++ ICSSG_STATS(rx_frame_min_size, true), ++ ICSSG_STATS(rx_min_size_error_frames, false), ++ ICSSG_STATS(rx_over_errors, true), ++ ICSSG_STATS(rx_class0_hits, false), ++ ICSSG_STATS(rx_class1_hits, false), ++ ICSSG_STATS(rx_class2_hits, false), ++ ICSSG_STATS(rx_class3_hits, false), ++ ICSSG_STATS(rx_class4_hits, false), ++ ICSSG_STATS(rx_class5_hits, false), ++ ICSSG_STATS(rx_class6_hits, false), ++ ICSSG_STATS(rx_class7_hits, false), ++ ICSSG_STATS(rx_class8_hits, false), ++ ICSSG_STATS(rx_class9_hits, false), ++ ICSSG_STATS(rx_class10_hits, false), ++ ICSSG_STATS(rx_class11_hits, false), ++ ICSSG_STATS(rx_class12_hits, false), ++ ICSSG_STATS(rx_class13_hits, false), ++ ICSSG_STATS(rx_class14_hits, false), ++ ICSSG_STATS(rx_class15_hits, false), ++ ICSSG_STATS(rx_smd_frags, false), ++ ICSSG_STATS(rx_bucket1_size, true), ++ ICSSG_STATS(rx_bucket2_size, true), ++ ICSSG_STATS(rx_bucket3_size, true), ++ ICSSG_STATS(rx_bucket4_size, true), ++ ICSSG_STATS(rx_64B_frames, true), ++ ICSSG_STATS(rx_bucket1_frames, true), ++ ICSSG_STATS(rx_bucket2_frames, true), ++ ICSSG_STATS(rx_bucket3_frames, true), ++ ICSSG_STATS(rx_bucket4_frames, true), ++ ICSSG_STATS(rx_bucket5_frames, true), ++ ICSSG_STATS(rx_bytes, true), ++ ICSSG_STATS(rx_tx_total_bytes, false), ++ /* Tx */ ++ ICSSG_STATS(tx_packets, true), ++ ICSSG_STATS(tx_broadcast_frames, false), ++ ICSSG_STATS(tx_multicast_frames, false), ++ ICSSG_STATS(tx_odd_nibble_frames, false), ++ ICSSG_STATS(tx_underflow_errors, false), ++ ICSSG_STATS(tx_frame_max_size, true), ++ ICSSG_STATS(tx_max_size_error_frames, false), ++ ICSSG_STATS(tx_frame_min_size, true), ++ ICSSG_STATS(tx_min_size_error_frames, false), ++ ICSSG_STATS(tx_bucket1_size, true), ++ ICSSG_STATS(tx_bucket2_size, true), ++ ICSSG_STATS(tx_bucket3_size, true), ++ ICSSG_STATS(tx_bucket4_size, true), ++ ICSSG_STATS(tx_64B_frames, true), ++ ICSSG_STATS(tx_bucket1_frames, true), ++ ICSSG_STATS(tx_bucket2_frames, true), ++ ICSSG_STATS(tx_bucket3_frames, true), ++ ICSSG_STATS(tx_bucket4_frames, true), ++ ICSSG_STATS(tx_bucket5_frames, true), ++ ICSSG_STATS(tx_bytes, true), ++}; ++ ++#endif /* __NET_TI_ICSSG_STATS_H */ +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0023-net-ti-icssg-prueth-Add-Standard-network-staticstics.patch b/recipes-kernel/linux/files/patches-6.1/0023-net-ti-icssg-prueth-Add-Standard-network-staticstics.patch new file mode 100644 index 000000000..c2b8df458 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0023-net-ti-icssg-prueth-Add-Standard-network-staticstics.patch @@ -0,0 +1,97 @@ +From afeb18faf22d2ab6990a5e2571f020ba644ecf63 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Tue, 1 Aug 2023 14:44:26 +0530 +Subject: [PATCH 23/76] net: ti: icssg-prueth: Add Standard network staticstics + +Implement .ndo_get_stats64 to dump standard network interface +statistics for ICSSG ethernet driver. + +Signed-off-by: MD Danish Anwar +--- + drivers/net/ethernet/ti/icssg/icssg_prueth.c | 22 ++++++++++++++++++++ + drivers/net/ethernet/ti/icssg/icssg_prueth.h | 2 ++ + drivers/net/ethernet/ti/icssg/icssg_stats.c | 13 ++++++++++++ + 3 files changed, 37 insertions(+) + +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +index d0bb4db11b30..e641b6ce9415 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +@@ -1240,6 +1240,27 @@ static int emac_ndo_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) + return phy_do_ioctl(ndev, ifr, cmd); + } + ++static void emac_ndo_get_stats64(struct net_device *ndev, ++ struct rtnl_link_stats64 *stats) ++{ ++ struct prueth_emac *emac = netdev_priv(ndev); ++ ++ emac_update_hardware_stats(emac); ++ ++ stats->rx_packets = emac_get_stat_by_name(emac, "rx_packets"); ++ stats->rx_bytes = emac_get_stat_by_name(emac, "rx_bytes"); ++ stats->tx_packets = emac_get_stat_by_name(emac, "tx_packets"); ++ stats->tx_bytes = emac_get_stat_by_name(emac, "tx_bytes"); ++ stats->rx_crc_errors = emac_get_stat_by_name(emac, "rx_crc_errors"); ++ stats->rx_over_errors = emac_get_stat_by_name(emac, "rx_over_errors"); ++ stats->multicast = emac_get_stat_by_name(emac, "rx_multicast_frames"); ++ ++ stats->rx_errors = ndev->stats.rx_errors; ++ stats->rx_dropped = ndev->stats.rx_dropped; ++ stats->tx_errors = ndev->stats.tx_errors; ++ stats->tx_dropped = ndev->stats.tx_dropped; ++} ++ + static const struct net_device_ops emac_netdev_ops = { + .ndo_open = emac_ndo_open, + .ndo_stop = emac_ndo_stop, +@@ -1249,6 +1270,7 @@ static const struct net_device_ops emac_netdev_ops = { + .ndo_tx_timeout = emac_ndo_tx_timeout, + .ndo_set_rx_mode = emac_ndo_set_rx_mode, + .ndo_eth_ioctl = emac_ndo_ioctl, ++ .ndo_get_stats64 = emac_ndo_get_stats64, + }; + + /* get emac_port corresponding to eth_node name */ +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +index f13de0d2e90b..e58cd8db7ba0 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +@@ -51,6 +51,7 @@ + + /* Number of ICSSG related stats */ + #define ICSSG_NUM_STATS 60 ++#define ICSSG_NUM_STANDARD_STATS 31 + + /* Firmware status codes */ + #define ICSS_HS_FW_READY 0x55555555 +@@ -254,4 +255,5 @@ u32 icssg_queue_level(struct prueth *prueth, int queue); + + void emac_stats_work_handler(struct work_struct *work); + void emac_update_hardware_stats(struct prueth_emac *emac); ++int emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name); + #endif /* __NET_TI_ICSSG_PRUETH_H */ +diff --git a/drivers/net/ethernet/ti/icssg/icssg_stats.c b/drivers/net/ethernet/ti/icssg/icssg_stats.c +index 25deb368a3f0..bb0b33927e3b 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_stats.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_stats.c +@@ -42,3 +42,16 @@ void emac_stats_work_handler(struct work_struct *work) + queue_delayed_work(system_long_wq, &emac->stats_work, + msecs_to_jiffies((STATS_TIME_LIMIT_1G_MS * 1000) / emac->speed)); + } ++ ++int emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) { ++ if (!strcmp(icssg_all_stats[i].name, stat_name)) ++ return emac->stats[icssg_all_stats[i].offset / sizeof(u32)]; ++ } ++ ++ netdev_err(emac->ndev, "Invalid stats %s\n", stat_name); ++ return -EINVAL; ++} +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0024-net-ti-icssg-prueth-Add-ethtool-ops-for-ICSSG-Ethern.patch b/recipes-kernel/linux/files/patches-6.1/0024-net-ti-icssg-prueth-Add-ethtool-ops-for-ICSSG-Ethern.patch new file mode 100644 index 000000000..343e1b7e8 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0024-net-ti-icssg-prueth-Add-ethtool-ops-for-ICSSG-Ethern.patch @@ -0,0 +1,258 @@ +From c081d8d820d46fc7ccf1656df103d4e786b30d43 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Tue, 1 Aug 2023 14:44:27 +0530 +Subject: [PATCH 24/76] net: ti: icssg-prueth: Add ethtool ops for ICSSG + Ethernet driver + +Add icssg_ethtool.c file. This file will be used for dumping statistics +via ethtool for ICSSG ethernet driver. + +Reviewed-by: Andrew Lunn +Signed-off-by: MD Danish Anwar +--- + drivers/net/ethernet/ti/Makefile | 1 + + drivers/net/ethernet/ti/icssg/icssg_ethtool.c | 188 ++++++++++++++++++ + drivers/net/ethernet/ti/icssg/icssg_prueth.c | 1 + + drivers/net/ethernet/ti/icssg/icssg_prueth.h | 3 + + 4 files changed, 193 insertions(+) + create mode 100644 drivers/net/ethernet/ti/icssg/icssg_ethtool.c + +diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile +index 03d9b2b36b5f..9176d79c36e1 100644 +--- a/drivers/net/ethernet/ti/Makefile ++++ b/drivers/net/ethernet/ti/Makefile +@@ -37,3 +37,4 @@ icssg-prueth-y := k3-cppi-desc-pool.o \ + icssg/icssg_config.o \ + icssg/icssg_mii_cfg.o \ + icssg/icssg_stats.o \ ++ icssg/icssg_ethtool.o +diff --git a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c +new file mode 100644 +index 000000000000..02c312f01d10 +--- /dev/null ++++ b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c +@@ -0,0 +1,188 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Texas Instruments ICSSG Ethernet driver ++ * ++ * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/ ++ * ++ */ ++ ++#include "icssg_prueth.h" ++#include "icssg_stats.h" ++ ++static void emac_get_drvinfo(struct net_device *ndev, ++ struct ethtool_drvinfo *info) ++{ ++ struct prueth_emac *emac = netdev_priv(ndev); ++ struct prueth *prueth = emac->prueth; ++ ++ strscpy(info->driver, dev_driver_string(prueth->dev), ++ sizeof(info->driver)); ++ strscpy(info->bus_info, dev_name(prueth->dev), sizeof(info->bus_info)); ++} ++ ++static u32 emac_get_msglevel(struct net_device *ndev) ++{ ++ struct prueth_emac *emac = netdev_priv(ndev); ++ ++ return emac->msg_enable; ++} ++ ++static void emac_set_msglevel(struct net_device *ndev, u32 value) ++{ ++ struct prueth_emac *emac = netdev_priv(ndev); ++ ++ emac->msg_enable = value; ++} ++ ++static int emac_get_link_ksettings(struct net_device *ndev, ++ struct ethtool_link_ksettings *ecmd) ++{ ++ return phy_ethtool_get_link_ksettings(ndev, ecmd); ++} ++ ++static int emac_set_link_ksettings(struct net_device *ndev, ++ const struct ethtool_link_ksettings *ecmd) ++{ ++ return phy_ethtool_set_link_ksettings(ndev, ecmd); ++} ++ ++static int emac_get_eee(struct net_device *ndev, struct ethtool_eee *edata) ++{ ++ if (!ndev->phydev) ++ return -EOPNOTSUPP; ++ ++ return phy_ethtool_get_eee(ndev->phydev, edata); ++} ++ ++static int emac_set_eee(struct net_device *ndev, struct ethtool_eee *edata) ++{ ++ if (!ndev->phydev) ++ return -EOPNOTSUPP; ++ ++ return phy_ethtool_set_eee(ndev->phydev, edata); ++} ++ ++static int emac_nway_reset(struct net_device *ndev) ++{ ++ return phy_ethtool_nway_reset(ndev); ++} ++ ++static int emac_get_sset_count(struct net_device *ndev, int stringset) ++{ ++ switch (stringset) { ++ case ETH_SS_STATS: ++ return ICSSG_NUM_ETHTOOL_STATS; ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ ++static void emac_get_strings(struct net_device *ndev, u32 stringset, u8 *data) ++{ ++ u8 *p = data; ++ int i; ++ ++ switch (stringset) { ++ case ETH_SS_STATS: ++ for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) { ++ if (!icssg_all_stats[i].standard_stats) { ++ memcpy(p, icssg_all_stats[i].name, ++ ETH_GSTRING_LEN); ++ p += ETH_GSTRING_LEN; ++ } ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++static void emac_get_ethtool_stats(struct net_device *ndev, ++ struct ethtool_stats *stats, u64 *data) ++{ ++ struct prueth_emac *emac = netdev_priv(ndev); ++ int i; ++ ++ emac_update_hardware_stats(emac); ++ ++ for (i = 0; i < ARRAY_SIZE(icssg_all_stats); i++) ++ if (!icssg_all_stats[i].standard_stats) ++ *(data++) = emac->stats[i]; ++} ++ ++static int emac_set_channels(struct net_device *ndev, ++ struct ethtool_channels *ch) ++{ ++ struct prueth_emac *emac = netdev_priv(ndev); ++ ++ /* Check if interface is up. Can change the num queues when ++ * the interface is down. ++ */ ++ if (netif_running(emac->ndev)) ++ return -EBUSY; ++ ++ emac->tx_ch_num = ch->tx_count; ++ ++ return 0; ++} ++ ++static void emac_get_channels(struct net_device *ndev, ++ struct ethtool_channels *ch) ++{ ++ struct prueth_emac *emac = netdev_priv(ndev); ++ ++ ch->max_rx = 1; ++ ch->max_tx = PRUETH_MAX_TX_QUEUES; ++ ch->rx_count = 1; ++ ch->tx_count = emac->tx_ch_num; ++} ++ ++static const struct ethtool_rmon_hist_range emac_rmon_ranges[] = { ++ { 0, 64}, ++ { 65, 128}, ++ { 129, 256}, ++ { 257, 512}, ++ { 513, PRUETH_MAX_PKT_SIZE}, ++ {} ++}; ++ ++static void emac_get_rmon_stats(struct net_device *ndev, ++ struct ethtool_rmon_stats *rmon_stats, ++ const struct ethtool_rmon_hist_range **ranges) ++{ ++ struct prueth_emac *emac = netdev_priv(ndev); ++ ++ *ranges = emac_rmon_ranges; ++ ++ rmon_stats->undersize_pkts = emac_get_stat_by_name(emac, "rx_bucket1_frames") - ++ emac_get_stat_by_name(emac, "rx_64B_frames"); ++ ++ rmon_stats->hist[0] = emac_get_stat_by_name(emac, "rx_bucket1_frames"); ++ rmon_stats->hist[1] = emac_get_stat_by_name(emac, "rx_bucket2_frames"); ++ rmon_stats->hist[2] = emac_get_stat_by_name(emac, "rx_bucket3_frames"); ++ rmon_stats->hist[3] = emac_get_stat_by_name(emac, "rx_bucket4_frames"); ++ rmon_stats->hist[4] = emac_get_stat_by_name(emac, "rx_bucket5_frames"); ++ ++ rmon_stats->hist_tx[0] = emac_get_stat_by_name(emac, "tx_bucket1_frames"); ++ rmon_stats->hist_tx[1] = emac_get_stat_by_name(emac, "tx_bucket2_frames"); ++ rmon_stats->hist_tx[2] = emac_get_stat_by_name(emac, "tx_bucket3_frames"); ++ rmon_stats->hist_tx[3] = emac_get_stat_by_name(emac, "tx_bucket4_frames"); ++ rmon_stats->hist_tx[4] = emac_get_stat_by_name(emac, "tx_bucket5_frames"); ++} ++ ++const struct ethtool_ops icssg_ethtool_ops = { ++ .get_drvinfo = emac_get_drvinfo, ++ .get_msglevel = emac_get_msglevel, ++ .set_msglevel = emac_set_msglevel, ++ .get_sset_count = emac_get_sset_count, ++ .get_ethtool_stats = emac_get_ethtool_stats, ++ .get_strings = emac_get_strings, ++ .get_channels = emac_get_channels, ++ .set_channels = emac_set_channels, ++ .get_link_ksettings = emac_get_link_ksettings, ++ .set_link_ksettings = emac_set_link_ksettings, ++ .get_link = ethtool_op_get_link, ++ .get_eee = emac_get_eee, ++ .set_eee = emac_set_eee, ++ .nway_reset = emac_nway_reset, ++ .get_rmon_stats = emac_get_rmon_stats, ++}; +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +index e641b6ce9415..80721d82f6c5 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +@@ -1421,6 +1421,7 @@ static int prueth_netdev_init(struct prueth *prueth, + ndev->min_mtu = PRUETH_MIN_PKT_SIZE; + ndev->max_mtu = PRUETH_MAX_MTU; + ndev->netdev_ops = &emac_netdev_ops; ++ ndev->ethtool_ops = &icssg_ethtool_ops; + ndev->hw_features = NETIF_F_SG; + ndev->features = ndev->hw_features; + +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +index e58cd8db7ba0..a8ce4d01ef16 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +@@ -52,6 +52,7 @@ + /* Number of ICSSG related stats */ + #define ICSSG_NUM_STATS 60 + #define ICSSG_NUM_STANDARD_STATS 31 ++#define ICSSG_NUM_ETHTOOL_STATS (ICSSG_NUM_STATS - ICSSG_NUM_STANDARD_STATS) + + /* Firmware status codes */ + #define ICSS_HS_FW_READY 0x55555555 +@@ -230,6 +231,8 @@ static inline int prueth_emac_slice(struct prueth_emac *emac) + } + } + ++extern const struct ethtool_ops icssg_ethtool_ops; ++ + /* Classifier helpers */ + void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac); + void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac); +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0025-net-ti-icssg-prueth-Add-Power-management-support.patch b/recipes-kernel/linux/files/patches-6.1/0025-net-ti-icssg-prueth-Add-Power-management-support.patch new file mode 100644 index 000000000..27a026b43 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0025-net-ti-icssg-prueth-Add-Power-management-support.patch @@ -0,0 +1,92 @@ +From f1f70582eccf6cfeed090256a9e21fec8bf1d63b Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Tue, 1 Aug 2023 14:44:28 +0530 +Subject: [PATCH 25/76] net: ti: icssg-prueth: Add Power management support + +Add suspend / resume APIs to support power management in ICSSG ethernet +driver. + +Reviewed-by: Andrew Lunn +Signed-off-by: MD Danish Anwar +--- + drivers/net/ethernet/ti/icssg/icssg_prueth.c | 57 ++++++++++++++++++++ + 1 file changed, 57 insertions(+) + +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +index 80721d82f6c5..47b941fb0198 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +@@ -1813,6 +1813,62 @@ static void prueth_remove(struct platform_device *pdev) + prueth_put_cores(prueth, ICSS_SLICE0); + } + ++#ifdef CONFIG_PM_SLEEP ++static int prueth_suspend(struct device *dev) ++{ ++ struct prueth *prueth = dev_get_drvdata(dev); ++ struct net_device *ndev; ++ int i, ret; ++ ++ for (i = 0; i < PRUETH_NUM_MACS; i++) { ++ ndev = prueth->registered_netdevs[i]; ++ ++ if (!ndev) ++ continue; ++ ++ if (netif_running(ndev)) { ++ netif_device_detach(ndev); ++ ret = emac_ndo_stop(ndev); ++ if (ret < 0) { ++ netdev_err(ndev, "failed to stop: %d", ret); ++ return ret; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static int prueth_resume(struct device *dev) ++{ ++ struct prueth *prueth = dev_get_drvdata(dev); ++ struct net_device *ndev; ++ int i, ret; ++ ++ for (i = 0; i < PRUETH_NUM_MACS; i++) { ++ ndev = prueth->registered_netdevs[i]; ++ ++ if (!ndev) ++ continue; ++ ++ if (netif_running(ndev)) { ++ ret = emac_ndo_open(ndev); ++ if (ret < 0) { ++ netdev_err(ndev, "failed to start: %d", ret); ++ return ret; ++ } ++ netif_device_attach(ndev); ++ } ++ } ++ ++ return 0; ++} ++#endif /* CONFIG_PM_SLEEP */ ++ ++static const struct dev_pm_ops prueth_dev_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(prueth_suspend, prueth_resume) ++}; ++ + static const struct prueth_pdata am654_icssg_pdata = { + .fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE, + .quirk_10m_link_issue = 1, +@@ -1830,6 +1886,7 @@ static struct platform_driver prueth_driver = { + .driver = { + .name = "icssg-prueth", + .of_match_table = prueth_dt_match, ++ .pm = &prueth_dev_pm_ops, + }, + }; + module_platform_driver(prueth_driver); +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0026-dt-bindings-net-Add-ICSS-IEP.patch b/recipes-kernel/linux/files/patches-6.1/0026-dt-bindings-net-Add-ICSS-IEP.patch new file mode 100644 index 000000000..6d49f0276 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0026-dt-bindings-net-Add-ICSS-IEP.patch @@ -0,0 +1,71 @@ +From fc5a0fbb09562bbda6059a456bf185ec296ee62d Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Thu, 24 Aug 2023 17:16:14 +0530 +Subject: [PATCH 26/76] dt-bindings: net: Add ICSS IEP + +Add a DT binding document for the ICSS Industrial Ethernet Peripheral(IEP) +hardware. IEP supports packet timestamping, PTP and PPS. + +Reviewed-by: Conor Dooley +Reviewed-by: Roger Quadros +Reviewed-by: Simon Horman +Signed-off-by: MD Danish Anwar +--- + .../devicetree/bindings/net/ti,icss-iep.yaml | 45 +++++++++++++++++++ + 1 file changed, 45 insertions(+) + create mode 100644 Documentation/devicetree/bindings/net/ti,icss-iep.yaml + +diff --git a/Documentation/devicetree/bindings/net/ti,icss-iep.yaml b/Documentation/devicetree/bindings/net/ti,icss-iep.yaml +new file mode 100644 +index 000000000000..f5c22d6dcaee +--- /dev/null ++++ b/Documentation/devicetree/bindings/net/ti,icss-iep.yaml +@@ -0,0 +1,45 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/net/ti,icss-iep.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Texas Instruments ICSS Industrial Ethernet Peripheral (IEP) module ++ ++maintainers: ++ - Md Danish Anwar ++ ++properties: ++ compatible: ++ oneOf: ++ - items: ++ - enum: ++ - ti,am642-icss-iep ++ - ti,j721e-icss-iep ++ - const: ti,am654-icss-iep ++ ++ - const: ti,am654-icss-iep ++ ++ ++ reg: ++ maxItems: 1 ++ ++ clocks: ++ maxItems: 1 ++ description: phandle to the IEP source clock ++ ++required: ++ - compatible ++ - reg ++ - clocks ++ ++additionalProperties: false ++ ++examples: ++ - | ++ /* AM65x */ ++ icssg0_iep0: iep@2e000 { ++ compatible = "ti,am654-icss-iep"; ++ reg = <0x2e000 0x1000>; ++ clocks = <&icssg0_iepclk_mux>; ++ }; +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0027-dt-bindings-net-Add-IEP-property-in-ICSSG.patch b/recipes-kernel/linux/files/patches-6.1/0027-dt-bindings-net-Add-IEP-property-in-ICSSG.patch new file mode 100644 index 000000000..acc937baf --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0027-dt-bindings-net-Add-IEP-property-in-ICSSG.patch @@ -0,0 +1,48 @@ +From 5ec9e4893e3f3fc319befd0e867ed6c44fdb4480 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Thu, 24 Aug 2023 17:16:15 +0530 +Subject: [PATCH 27/76] dt-bindings: net: Add IEP property in ICSSG + +Add IEP property in ICSSG hardware DT binding document. +ICSSG uses IEP (Industrial Ethernet Peripheral) to support timestamping +of ethernet packets, PTP and PPS. + +Reviewed-by: Conor Dooley +Reviewed-by: Roger Quadros +Reviewed-by: Simon Horman +Signed-off-by: MD Danish Anwar +Reviewed-by: Rob Herring +--- + .../devicetree/bindings/net/ti,icssg-prueth.yaml | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml +index 8ec30b3eb760..311c570165f9 100644 +--- a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml ++++ b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml +@@ -52,6 +52,14 @@ properties: + description: + phandle to MII_RT module's syscon regmap + ++ ti,iep: ++ $ref: /schemas/types.yaml#/definitions/phandle-array ++ maxItems: 2 ++ items: ++ maxItems: 1 ++ description: ++ phandle to IEP (Industrial Ethernet Peripheral) for ICSSG ++ + interrupts: + maxItems: 2 + description: +@@ -155,6 +163,7 @@ examples: + "tx1-0", "tx1-1", "tx1-2", "tx1-3", + "rx0", "rx1"; + ti,mii-g-rt = <&icssg2_mii_g_rt>; ++ ti,iep = <&icssg2_iep0>, <&icssg2_iep1>; + interrupt-parent = <&icssg2_intc>; + interrupts = <24 0 2>, <25 1 3>; + interrupt-names = "tx_ts0", "tx_ts1"; +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0070-net-ethernet-ti-prueth-Add-IEP-driver.patch b/recipes-kernel/linux/files/patches-6.1/0028-net-ti-icss-iep-Add-IEP-driver.patch similarity index 69% rename from recipes-kernel/linux/files/patches-5.10/0070-net-ethernet-ti-prueth-Add-IEP-driver.patch rename to recipes-kernel/linux/files/patches-6.1/0028-net-ti-icss-iep-Add-IEP-driver.patch index e2b17ef5e..ed9c1fead 100644 --- a/recipes-kernel/linux/files/patches-5.10/0070-net-ethernet-ti-prueth-Add-IEP-driver.patch +++ b/recipes-kernel/linux/files/patches-6.1/0028-net-ti-icss-iep-Add-IEP-driver.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 25fc91e60604d8e7af846dff5d63468f57428977 Mon Sep 17 00:00:00 2001 From: Roger Quadros -Date: Tue, 20 Apr 2021 13:17:30 +0530 -Subject: [PATCH] net: ethernet: ti: prueth: Add IEP driver +Date: Thu, 24 Aug 2023 17:16:16 +0530 +Subject: [PATCH 28/76] net: ti: icss-iep: Add IEP driver Add a driver for Industrial Ethernet Peripheral (IEP) block of PRUSS to support timestamping of ethernet packets and thus support PTP and PPS @@ -11,52 +11,57 @@ Signed-off-by: Roger Quadros Signed-off-by: Lokesh Vutla Signed-off-by: Murali Karicheri Signed-off-by: Vignesh Raghavendra +Reviewed-by: Simon Horman +Signed-off-by: MD Danish Anwar --- - drivers/net/ethernet/ti/Kconfig | 8 + - drivers/net/ethernet/ti/Makefile | 2 + - drivers/net/ethernet/ti/icss_iep.c | 1049 ++++++++++++++++++++++++++++ - drivers/net/ethernet/ti/icss_iep.h | 37 + - 4 files changed, 1096 insertions(+) - create mode 100644 drivers/net/ethernet/ti/icss_iep.c - create mode 100644 drivers/net/ethernet/ti/icss_iep.h + drivers/net/ethernet/ti/Kconfig | 11 + + drivers/net/ethernet/ti/Makefile | 1 + + drivers/net/ethernet/ti/icssg/icss_iep.c | 939 +++++++++++++++++++++++ + drivers/net/ethernet/ti/icssg/icss_iep.h | 38 + + 4 files changed, 989 insertions(+) + create mode 100644 drivers/net/ethernet/ti/icssg/icss_iep.c + create mode 100644 drivers/net/ethernet/ti/icssg/icss_iep.h diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig -index abfc4c435d59..bf497da88814 100644 +index 63e510b6860f..1af5a90720ec 100644 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig -@@ -171,4 +171,12 @@ config CPMAC - help - TI AR7 CPMAC Ethernet support +@@ -196,4 +196,15 @@ config TI_ICSSG_PRUETH + to support the Ethernet operation. Currently, it supports Ethernet + with 1G and 100M link speed. +config TI_ICSS_IEP + tristate "TI PRU ICSS IEP driver" + depends on TI_PRUSS + default TI_PRUSS + help -+ This enables support for the PRU-ICSS Industrial Ethernet Peripheral -+ within a PRU-ICSS subsystem present on various TI SoCs. ++ This driver enables support for the PRU-ICSS Industrial Ethernet ++ Peripheral within a PRU-ICSS subsystem present on various TI SoCs. ++ ++ To compile this driver as a module, choose M here. The module ++ will be called icss_iep. + endif # NET_VENDOR_TI diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile -index 6e779292545d..ec94422a572f 100644 +index 9176d79c36e1..34fd7a716ba6 100644 --- a/drivers/net/ethernet/ti/Makefile +++ b/drivers/net/ethernet/ti/Makefile -@@ -27,3 +27,5 @@ keystone_netcp_ethss-y := netcp_ethss.o netcp_sgmii.o netcp_xgbepcsr.o cpsw_ale. - obj-$(CONFIG_TI_K3_AM65_CPSW_NUSS) += ti-am65-cpsw-nuss.o - ti-am65-cpsw-nuss-y := am65-cpsw-nuss.o cpsw_sl.o am65-cpsw-ethtool.o cpsw_ale.o k3-cppi-desc-pool.o am65-cpsw-qos.o - obj-$(CONFIG_TI_K3_AM65_CPTS) += am65-cpts.o -+ -+obj-$(CONFIG_TI_ICSS_IEP) += icss_iep.o -diff --git a/drivers/net/ethernet/ti/icss_iep.c b/drivers/net/ethernet/ti/icss_iep.c +@@ -38,3 +38,4 @@ icssg-prueth-y := k3-cppi-desc-pool.o \ + icssg/icssg_mii_cfg.o \ + icssg/icssg_stats.o \ + icssg/icssg_ethtool.o ++obj-$(CONFIG_TI_ICSS_IEP) += icssg/icss_iep.o +diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c new file mode 100644 -index 000000000000..234972a034a9 +index 000000000000..bcc056bf45da --- /dev/null -+++ b/drivers/net/ethernet/ti/icss_iep.c -@@ -0,0 +1,1049 @@ ++++ b/drivers/net/ethernet/ti/icssg/icss_iep.c +@@ -0,0 +1,939 @@ +// SPDX-License-Identifier: GPL-2.0 ++ +/* Texas Instruments ICSSG Industrial Ethernet Peripheral (IEP) Driver + * -+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com ++ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com + * + */ + @@ -86,7 +91,6 @@ index 000000000000..234972a034a9 + +#define IEP_GLOBAL_STATUS_CNT_OVF BIT(0) + -+#define CMP_INDEX(sync) ((sync) + 1) +#define IEP_CMP_CFG_SHADOW_EN BIT(17) +#define IEP_CMP_CFG_CMP0_RST_CNT_EN BIT(0) +#define IEP_CMP_CFG_CMP_EN(cmp) (GENMASK(16, 1) & (1 << ((cmp) + 1))) @@ -105,7 +109,6 @@ index 000000000000..234972a034a9 + +#define LATCH_INDEX(ts_index) ((ts_index) + 6) +#define IEP_CAP_CFG_CAPNR_1ST_EVENT_EN(n) BIT(LATCH_INDEX(n)) -+#define IEP_CAP_CFG_CAPNF_1ST_EVENT_EN(n) BIT(LATCH_INDEX(n) + 1) +#define IEP_CAP_CFG_CAP_ASYNC_EN(n) BIT(LATCH_INDEX(n) + 10) + +enum { @@ -120,13 +123,9 @@ index 000000000000..234972a034a9 + + ICSS_IEP_CAP6_RISE_REG0, + ICSS_IEP_CAP6_RISE_REG1, -+ ICSS_IEP_CAP6_FALL_REG0, -+ ICSS_IEP_CAP6_FALL_REG1, + + ICSS_IEP_CAP7_RISE_REG0, + ICSS_IEP_CAP7_RISE_REG1, -+ ICSS_IEP_CAP7_FALL_REG0, -+ ICSS_IEP_CAP7_FALL_REG1, + + ICSS_IEP_CMP_CFG_REG, + ICSS_IEP_CMP_STAT_REG, @@ -170,6 +169,7 @@ index 000000000000..234972a034a9 + struct ptp_clock_info ptp_info; + struct ptp_clock *ptp_clock; + struct mutex ptp_clk_mutex; /* PHC access serializer */ ++ spinlock_t irq_lock; /* CMP IRQ vs icss_iep_ptp_enable access */ + u32 def_inc; + s16 slow_cmp_inc; + u32 slow_cmp_count; @@ -179,7 +179,7 @@ index 000000000000..234972a034a9 + u32 perout_enabled; + bool pps_enabled; + int cap_cmp_irq; -+ struct ptp_clock_time period; ++ u64 period; + u32 latch_enable; +}; + @@ -194,7 +194,7 @@ index 000000000000..234972a034a9 + u32 val = 0; + + if (iep && (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)) -+ regmap_read(iep->map, ICSS_IEP_COUNT_REG1, &val); ++ val = readl(iep->base + iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG1]); + + return val; +} @@ -211,7 +211,7 @@ index 000000000000..234972a034a9 + u32 val = 0; + + if (iep) -+ regmap_read(iep->map, ICSS_IEP_COUNT_REG0, &val); ++ val = readl(iep->base + iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG0]); + + return val; +} @@ -234,36 +234,76 @@ index 000000000000..234972a034a9 +static void icss_iep_set_counter(struct icss_iep *iep, u64 ns) +{ + if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) -+ regmap_write(iep->map, ICSS_IEP_COUNT_REG1, upper_32_bits(ns)); -+ regmap_write(iep->map, ICSS_IEP_COUNT_REG0, lower_32_bits(ns)); ++ writel(upper_32_bits(ns), iep->base + ++ iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG1]); ++ writel(upper_32_bits(ns), iep->base + iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG0]); +} + ++static void icss_iep_update_to_next_boundary(struct icss_iep *iep, u64 start_ns); ++ ++/** ++ * icss_iep_settime() - Set time of the PTP clock using IEP driver ++ * @iep: Pointer to structure representing IEP. ++ * @ns: Time to be set in nanoseconds ++ * ++ * This API uses writel() instead of regmap_write() for write operations as ++ * regmap_write() is too slow and this API is time sensitive. ++ */ +static void icss_iep_settime(struct icss_iep *iep, u64 ns) +{ ++ unsigned long flags; ++ + if (iep->ops && iep->ops->settime) { + iep->ops->settime(iep->clockops_data, ns); + return; + } + ++ spin_lock_irqsave(&iep->irq_lock, flags); ++ if (iep->pps_enabled || iep->perout_enabled) ++ writel(0, iep->base + iep->plat_data->reg_offs[ICSS_IEP_SYNC_CTRL_REG]); ++ + icss_iep_set_counter(iep, ns); ++ ++ if (iep->pps_enabled || iep->perout_enabled) { ++ icss_iep_update_to_next_boundary(iep, ns); ++ writel(IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN, ++ iep->base + iep->plat_data->reg_offs[ICSS_IEP_SYNC_CTRL_REG]); ++ } ++ spin_unlock_irqrestore(&iep->irq_lock, flags); +} + -+static u64 icss_iep_gettime(struct icss_iep *iep) ++/** ++ * icss_iep_gettime() - Get time of the PTP clock using IEP driver ++ * @iep: Pointer to structure representing IEP. ++ * @sts: Pointer to structure representing PTP system timestamp. ++ * ++ * This API uses readl() instead of regmap_read() for read operations as ++ * regmap_read() is too slow and this API is time sensitive. ++ * ++ * Return: The current timestamp of the PTP clock using IEP driver ++ */ ++static u64 icss_iep_gettime(struct icss_iep *iep, ++ struct ptp_system_timestamp *sts) +{ -+ u64 val; -+ u32 tmp; ++ u32 ts_hi = 0, ts_lo; ++ unsigned long flags; + + if (iep->ops && iep->ops->gettime) -+ return iep->ops->gettime(iep->clockops_data); ++ return iep->ops->gettime(iep->clockops_data, sts); + -+ regmap_read(iep->map, ICSS_IEP_COUNT_REG0, &tmp); -+ val = tmp; -+ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) { -+ regmap_read(iep->map, ICSS_IEP_COUNT_REG1, &tmp); -+ val |= (u64)tmp << 32; -+ } ++ /* use local_irq_x() to make it work for both RT/non-RT */ ++ local_irq_save(flags); + -+ return val; ++ /* no need to play with hi-lo, hi is latched when lo is read */ ++ ptp_read_system_prets(sts); ++ ts_lo = readl(iep->base + iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG0]); ++ ptp_read_system_postts(sts); ++ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) ++ ts_hi = readl(iep->base + iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG1]); ++ ++ local_irq_restore(flags); ++ ++ return (u64)ts_lo | (u64)ts_hi << 32; +} + +static void icss_iep_enable(struct icss_iep *iep) @@ -280,13 +320,12 @@ index 000000000000..234972a034a9 + 0); +} + -+static void icss_iep_enable_shadow_mode(struct icss_iep *iep, u32 cycle_time_ns) ++static void icss_iep_enable_shadow_mode(struct icss_iep *iep) +{ + u32 cycle_time; + int cmp; + -+ /* FIXME: check why we need to decrement by def_inc */ -+ cycle_time = cycle_time_ns - iep->def_inc; ++ cycle_time = iep->cycle_time_ns - iep->def_inc; + + icss_iep_disable(iep); + @@ -323,8 +362,10 @@ index 000000000000..234972a034a9 + + /* set CMP0 value to cycle time */ + regmap_write(iep->map, ICSS_IEP_CMP0_REG0, cycle_time); -+ regmap_write(iep->map, ICSS_IEP_CMP0_REG1, cycle_time); ++ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) ++ regmap_write(iep->map, ICSS_IEP_CMP0_REG1, cycle_time); + ++ icss_iep_set_counter(iep, 0); + icss_iep_enable(iep); +} + @@ -371,9 +412,10 @@ index 000000000000..234972a034a9 +} + +/* PTP PHC operations */ -+static int icss_iep_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) ++static int icss_iep_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) +{ + struct icss_iep *iep = container_of(ptp, struct icss_iep, ptp_info); ++ s32 ppb = scaled_ppm_to_ppb(scaled_ppm); + u32 cyc_count; + u16 cmp_inc; + @@ -432,7 +474,7 @@ index 000000000000..234972a034a9 + if (iep->ops && iep->ops->adjtime) { + iep->ops->adjtime(iep->clockops_data, delta); + } else { -+ ns = icss_iep_gettime(iep); ++ ns = icss_iep_gettime(iep, NULL); + ns += delta; + icss_iep_settime(iep, ns); + } @@ -441,14 +483,15 @@ index 000000000000..234972a034a9 + return 0; +} + -+static int icss_iep_ptp_gettime(struct ptp_clock_info *ptp, -+ struct timespec64 *ts) ++static int icss_iep_ptp_gettimeex(struct ptp_clock_info *ptp, ++ struct timespec64 *ts, ++ struct ptp_system_timestamp *sts) +{ + struct icss_iep *iep = container_of(ptp, struct icss_iep, ptp_info); + u64 ns; + + mutex_lock(&iep->ptp_clk_mutex); -+ ns = icss_iep_gettime(iep); ++ ns = icss_iep_gettime(iep, sts); + *ts = ns_to_timespec64(ns); + mutex_unlock(&iep->ptp_clk_mutex); + @@ -469,23 +512,26 @@ index 000000000000..234972a034a9 + return 0; +} + -+static void icss_iep_update_to_next_boundary(struct icss_iep *iep) ++static void icss_iep_update_to_next_boundary(struct icss_iep *iep, u64 start_ns) +{ + u64 ns, p_ns; + u32 offset; + -+ ns = icss_iep_gettime(iep); -+ p_ns = ((u64)iep->period.sec * NSEC_PER_SEC) + iep->period.nsec; ++ ns = icss_iep_gettime(iep, NULL); ++ if (start_ns < ns) ++ start_ns = ns; ++ p_ns = iep->period; + /* Round up to next period boundary */ -+ ns += p_ns - 1; -+ offset = do_div(ns, p_ns); -+ ns = ns * p_ns; ++ start_ns += p_ns - 1; ++ offset = do_div(start_ns, p_ns); ++ start_ns = start_ns * p_ns; + /* If it is too close to update, shift to next boundary */ + if (p_ns - offset < 10) -+ ns += p_ns; ++ start_ns += p_ns; + -+ regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(ns)); -+ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(ns)); ++ regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(start_ns)); ++ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) ++ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(start_ns)); +} + +static int icss_iep_perout_enable_hw(struct icss_iep *iep, @@ -502,9 +548,10 @@ index 000000000000..234972a034a9 + if (on) { + /* Configure CMP */ + regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(cmp)); -+ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(cmp)); -+ /* Configure SYNC */ -+ regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG, 1000000); /* 1ms pulse width */ ++ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) ++ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(cmp)); ++ /* Configure SYNC, 1ms pulse width */ ++ regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG, 1000000); + regmap_write(iep->map, ICSS_IEP_SYNC0_PERIOD_REG, 0); + regmap_write(iep->map, ICSS_IEP_SYNC_START_REG, 0); + regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0); /* one-shot mode */ @@ -518,12 +565,19 @@ index 000000000000..234972a034a9 + + /* clear regs */ + regmap_write(iep->map, ICSS_IEP_CMP1_REG0, 0); -+ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, 0); ++ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) ++ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, 0); + } + } else { + if (on) { -+ iep->period = req->period; -+ icss_iep_update_to_next_boundary(iep); ++ u64 start_ns; ++ ++ iep->period = ((u64)req->period.sec * NSEC_PER_SEC) + ++ req->period.nsec; ++ start_ns = ((u64)req->period.sec * NSEC_PER_SEC) ++ + req->period.nsec; ++ icss_iep_update_to_next_boundary(iep, start_ns); ++ + /* Enable Sync in single shot mode */ + regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, + IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN); @@ -537,7 +591,8 @@ index 000000000000..234972a034a9 + + /* clear CMP regs */ + regmap_write(iep->map, ICSS_IEP_CMP1_REG0, 0); -+ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, 0); ++ if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) ++ regmap_write(iep->map, ICSS_IEP_CMP1_REG1, 0); + + /* Disable sync */ + regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0); @@ -550,6 +605,7 @@ index 000000000000..234972a034a9 +static int icss_iep_perout_enable(struct icss_iep *iep, + struct ptp_perout_request *req, int on) +{ ++ unsigned long flags; + int ret = 0; + + mutex_lock(&iep->ptp_clk_mutex); @@ -562,9 +618,11 @@ index 000000000000..234972a034a9 + if (iep->perout_enabled == !!on) + goto exit; + ++ spin_lock_irqsave(&iep->irq_lock, flags); + ret = icss_iep_perout_enable_hw(iep, req, on); + if (!ret) + iep->perout_enabled = !!on; ++ spin_unlock_irqrestore(&iep->irq_lock, flags); + +exit: + mutex_unlock(&iep->ptp_clk_mutex); @@ -572,58 +630,12 @@ index 000000000000..234972a034a9 + return ret; +} + -+static irqreturn_t icss_iep_cap_cmp_handler(int irq, void *dev_id) -+{ -+ struct icss_iep *iep = (struct icss_iep *)dev_id; -+ unsigned int val, index = 0, i, sts; -+ struct ptp_clock_event pevent; -+ irqreturn_t ret = IRQ_NONE; -+ u64 ns; -+ -+ regmap_read(iep->map, ICSS_IEP_CMP_STAT_REG, &val); -+ if (val & BIT(CMP_INDEX(index))) { -+ regmap_write(iep->map, ICSS_IEP_CMP_STAT_REG, BIT(CMP_INDEX(index))); -+ regmap_read(iep->map, ICSS_IEP_CMP1_REG0, &val); -+ ns = val; -+ regmap_read(iep->map, ICSS_IEP_CMP1_REG1, &val); -+ ns |= (u64)val << 32; -+ icss_iep_update_to_next_boundary(iep); -+ -+ pevent.pps_times.ts_real = ns_to_timespec64(ns); -+ pevent.type = PTP_CLOCK_PPSUSR; -+ pevent.index = index; -+ ptp_clock_event(iep->ptp_clock, &pevent); -+ dev_dbg(iep->dev, "IEP:pps ts: %llu\n", ns); -+ ret = IRQ_HANDLED; -+ } -+ -+ regmap_read(iep->map, ICSS_IEP_CAPTURE_STAT_REG, &sts); -+ if (!sts) -+ return ret; -+ -+ for (i = 0; i < iep->ptp_info.n_ext_ts; i++) { -+ if (sts & IEP_CAP_CFG_CAPNR_1ST_EVENT_EN(i * 2)) { -+ regmap_read(iep->map, ICSS_IEP_CAP6_RISE_REG0 + (i * 2), &val); -+ ns = val; -+ regmap_read(iep->map, ICSS_IEP_CAP6_RISE_REG0 + (i * 2) + 1, &val); -+ ns |= (u64)val << 32; -+ pevent.timestamp = ns; -+ pevent.type = PTP_CLOCK_EXTTS; -+ pevent.index = i; -+ ptp_clock_event(iep->ptp_clock, &pevent); -+ dev_dbg(iep->dev, "IEP:extts index=%d ts: %llu\n", i, ns); -+ ret = IRQ_HANDLED; -+ } -+ } -+ -+ return ret; -+} -+ +static int icss_iep_pps_enable(struct icss_iep *iep, int on) +{ -+ int ret = 0; -+ struct timespec64 ts; + struct ptp_clock_request rq; ++ struct timespec64 ts; ++ unsigned long flags; ++ int ret = 0; + u64 ns; + + mutex_lock(&iep->ptp_clk_mutex); @@ -636,9 +648,11 @@ index 000000000000..234972a034a9 + if (iep->pps_enabled == !!on) + goto exit; + ++ spin_lock_irqsave(&iep->irq_lock, flags); ++ + rq.perout.index = 0; + if (on) { -+ ns = icss_iep_gettime(iep); ++ ns = icss_iep_gettime(iep, NULL); + ts = ns_to_timespec64(ns); + rq.perout.period.sec = 1; + rq.perout.period.nsec = 0; @@ -652,6 +666,8 @@ index 000000000000..234972a034a9 + if (!ret) + iep->pps_enabled = !!on; + ++ spin_unlock_irqrestore(&iep->irq_lock, flags); ++ +exit: + mutex_unlock(&iep->ptp_clk_mutex); + @@ -669,7 +685,7 @@ index 000000000000..234972a034a9 + goto exit; + } + -+ if (!!(iep->latch_enable & BIT(index)) == !!on) ++ if (((iep->latch_enable & BIT(index)) >> index) == on) + goto exit; + + regmap_read(iep->map, ICSS_IEP_CAPTURE_CFG_REG, &val); @@ -712,21 +728,20 @@ index 000000000000..234972a034a9 + .owner = THIS_MODULE, + .name = "ICSS IEP timer", + .max_adj = 10000000, -+ .adjfreq = icss_iep_ptp_adjfreq, ++ .adjfine = icss_iep_ptp_adjfine, + .adjtime = icss_iep_ptp_adjtime, -+ .gettime64 = icss_iep_ptp_gettime, ++ .gettimex64 = icss_iep_ptp_gettimeex, + .settime64 = icss_iep_ptp_settime, + .enable = icss_iep_ptp_enable, +}; + -+struct icss_iep *icss_iep_get(struct device_node *np) ++struct icss_iep *icss_iep_get_idx(struct device_node *np, int idx) +{ + struct platform_device *pdev; + struct device_node *iep_np; + struct icss_iep *iep; -+ int ret; + -+ iep_np = of_parse_phandle(np, "iep", 0); ++ iep_np = of_parse_phandle(np, "ti,iep", idx); + if (!iep_np || !of_device_is_available(iep_np)) + return ERR_PTR(-ENODEV); + @@ -752,34 +767,13 @@ index 000000000000..234972a034a9 + device_unlock(iep->dev); + get_device(iep->dev); + -+ iep->cap_cmp_irq = of_irq_get_byname(np, "iep_cap_cmp"); -+ if (iep->cap_cmp_irq < 0) { -+ iep->cap_cmp_irq = 0; -+ } else { -+ ret = request_irq(iep->cap_cmp_irq, icss_iep_cap_cmp_handler, IRQF_TRIGGER_HIGH, -+ "iep_cap_cmp", iep); -+ if (ret) { -+ dev_err(iep->dev, "Request irq failed for cap_cmp %d\n", ret); -+ goto put_iep_device; -+ } -+ } -+ -+ iep->ptp_info = icss_iep_ptp_info; -+ -+ if (iep->cap_cmp_irq || (iep->ops && iep->ops->perout_enable)) { -+ iep->ptp_info.n_per_out = 1; -+ iep->ptp_info.pps = 1; -+ } -+ -+ if (iep->cap_cmp_irq || (iep->ops && iep->ops->extts_enable)) -+ iep->ptp_info.n_ext_ts = 2; -+ + return iep; ++} ++EXPORT_SYMBOL_GPL(icss_iep_get_idx); + -+put_iep_device: -+ put_device(iep->dev); -+ -+ return ERR_PTR(ret); ++struct icss_iep *icss_iep_get(struct device_node *np) ++{ ++ return icss_iep_get_idx(np, 0); +} +EXPORT_SYMBOL_GPL(icss_iep_get); + @@ -789,41 +783,44 @@ index 000000000000..234972a034a9 + iep->client_np = NULL; + device_unlock(iep->dev); + put_device(iep->dev); -+ if (iep->cap_cmp_irq) -+ free_irq(iep->cap_cmp_irq, iep); +} +EXPORT_SYMBOL_GPL(icss_iep_put); + +int icss_iep_init(struct icss_iep *iep, const struct icss_iep_clockops *clkops, + void *clockops_data, u32 cycle_time_ns) +{ -+ u32 def_inc; + int ret = 0; + -+ def_inc = NSEC_PER_SEC / iep->refclk_freq; /* ns per clock tick */ -+ if (def_inc > IEP_MAX_DEF_INC) -+ /* iep_core_clk too slow to be supported */ -+ return -EINVAL; -+ -+ iep->def_inc = def_inc; ++ iep->cycle_time_ns = cycle_time_ns; ++ iep->clk_tick_time = iep->def_inc; + iep->ops = clkops; + iep->clockops_data = clockops_data; -+ icss_iep_set_default_inc(iep, def_inc); -+ icss_iep_set_compensation_inc(iep, def_inc); ++ icss_iep_set_default_inc(iep, iep->def_inc); ++ icss_iep_set_compensation_inc(iep, iep->def_inc); + icss_iep_set_compensation_count(iep, 0); + regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG, iep->refclk_freq / 10); /* 100 ms pulse */ + regmap_write(iep->map, ICSS_IEP_SYNC0_PERIOD_REG, 0); + if (iep->plat_data->flags & ICSS_IEP_SLOW_COMPEN_REG_SUPPORT) + icss_iep_set_slow_compensation_count(iep, 0); ++ ++ if (!(iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT) || ++ !(iep->plat_data->flags & ICSS_IEP_SLOW_COMPEN_REG_SUPPORT)) ++ goto skip_perout; ++ ++ if (iep->ops && iep->ops->perout_enable) { ++ iep->ptp_info.n_per_out = 1; ++ iep->ptp_info.pps = 1; ++ } ++ ++ if (iep->ops && iep->ops->extts_enable) ++ iep->ptp_info.n_ext_ts = 2; ++ ++skip_perout: + if (cycle_time_ns) -+ icss_iep_enable_shadow_mode(iep, cycle_time_ns); ++ icss_iep_enable_shadow_mode(iep); + else + icss_iep_enable(iep); -+ -+ iep->cycle_time_ns = cycle_time_ns; -+ icss_iep_set_counter(iep, 0); -+ -+ iep->clk_tick_time = def_inc; ++ icss_iep_settime(iep, ktime_get_real_ns()); + + iep->ptp_clock = ptp_clock_register(&iep->ptp_info, iep->dev); + if (IS_ERR(iep->ptp_clock)) { @@ -848,13 +845,10 @@ index 000000000000..234972a034a9 +} +EXPORT_SYMBOL_GPL(icss_iep_exit); + -+static const struct of_device_id icss_iep_of_match[]; -+ +static int icss_iep_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct icss_iep *iep; -+ struct resource *res; + struct clk *iep_clk; + + iep = devm_kzalloc(dev, sizeof(*iep), GFP_KERNEL); @@ -862,8 +856,7 @@ index 000000000000..234972a034a9 + return -ENOMEM; + + iep->dev = dev; -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ iep->base = devm_ioremap_resource(dev, res); ++ iep->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(iep->base)) + return -ENODEV; + @@ -873,7 +866,14 @@ index 000000000000..234972a034a9 + + iep->refclk_freq = clk_get_rate(iep_clk); + -+ iep->plat_data = of_device_get_match_data(dev); ++ iep->def_inc = NSEC_PER_SEC / iep->refclk_freq; /* ns per clock tick */ ++ if (iep->def_inc > IEP_MAX_DEF_INC) { ++ dev_err(dev, "Failed to set def_inc %d. IEP_clock is too slow to be supported\n", ++ iep->def_inc); ++ return -EINVAL; ++ } ++ ++ iep->plat_data = device_get_match_data(dev); + if (!iep->plat_data) + return -EINVAL; + @@ -884,7 +884,9 @@ index 000000000000..234972a034a9 + return PTR_ERR(iep->map); + } + ++ iep->ptp_info = icss_iep_ptp_info; + mutex_init(&iep->ptp_clk_mutex); ++ spin_lock_init(&iep->irq_lock); + dev_set_drvdata(dev, iep); + icss_iep_disable(iep); + @@ -930,6 +932,7 @@ index 000000000000..234972a034a9 + .reg_read = icss_iep_regmap_read, + .writeable_reg = am654_icss_iep_valid_reg, + .readable_reg = am654_icss_iep_valid_reg, ++ .fast_io = 1, +}; + +static const struct icss_iep_plat_data am654_icss_iep_plat_data = { @@ -947,55 +950,9 @@ index 000000000000..234972a034a9 + + [ICSS_IEP_CAP6_RISE_REG0] = 0x50, + [ICSS_IEP_CAP6_RISE_REG1] = 0x54, -+ [ICSS_IEP_CAP6_FALL_REG0] = 0x58, -+ [ICSS_IEP_CAP6_FALL_REG1] = 0x5c, -+ -+ [ICSS_IEP_CAP7_RISE_REG0] = 0x60, -+ [ICSS_IEP_CAP7_RISE_REG1] = 0x64, -+ [ICSS_IEP_CAP7_FALL_REG0] = 0x68, -+ [ICSS_IEP_CAP7_FALL_REG1] = 0x6c, -+ -+ [ICSS_IEP_CMP_CFG_REG] = 0x70, -+ [ICSS_IEP_CMP_STAT_REG] = 0x74, -+ [ICSS_IEP_CMP0_REG0] = 0x78, -+ [ICSS_IEP_CMP0_REG1] = 0x7c, -+ [ICSS_IEP_CMP1_REG0] = 0x80, -+ [ICSS_IEP_CMP1_REG1] = 0x84, -+ -+ [ICSS_IEP_CMP8_REG0] = 0xc0, -+ [ICSS_IEP_CMP8_REG1] = 0xc4, -+ [ICSS_IEP_SYNC_CTRL_REG] = 0x180, -+ [ICSS_IEP_SYNC0_STAT_REG] = 0x188, -+ [ICSS_IEP_SYNC1_STAT_REG] = 0x18c, -+ [ICSS_IEP_SYNC_PWIDTH_REG] = 0x190, -+ [ICSS_IEP_SYNC0_PERIOD_REG] = 0x194, -+ [ICSS_IEP_SYNC1_DELAY_REG] = 0x198, -+ [ICSS_IEP_SYNC_START_REG] = 0x19c, -+ }, -+ .config = &am654_icss_iep_regmap_config, -+}; -+ -+static const struct icss_iep_plat_data am57xx_icss_iep_plat_data = { -+ .flags = ICSS_IEP_64BIT_COUNTER_SUPPORT | -+ ICSS_IEP_SLOW_COMPEN_REG_SUPPORT, -+ .reg_offs = { -+ [ICSS_IEP_GLOBAL_CFG_REG] = 0x00, -+ [ICSS_IEP_COMPEN_REG] = 0x08, -+ [ICSS_IEP_SLOW_COMPEN_REG] = 0x0C, -+ [ICSS_IEP_COUNT_REG0] = 0x10, -+ [ICSS_IEP_COUNT_REG1] = 0x14, -+ [ICSS_IEP_CAPTURE_CFG_REG] = 0x18, -+ [ICSS_IEP_CAPTURE_STAT_REG] = 0x1c, -+ -+ [ICSS_IEP_CAP6_RISE_REG0] = 0x50, -+ [ICSS_IEP_CAP6_RISE_REG1] = 0x54, -+ [ICSS_IEP_CAP6_FALL_REG0] = 0x58, -+ [ICSS_IEP_CAP6_FALL_REG1] = 0x5c, + + [ICSS_IEP_CAP7_RISE_REG0] = 0x60, + [ICSS_IEP_CAP7_RISE_REG1] = 0x64, -+ [ICSS_IEP_CAP7_FALL_REG0] = 0x68, -+ [ICSS_IEP_CAP7_FALL_REG1] = 0x6c, + + [ICSS_IEP_CMP_CFG_REG] = 0x70, + [ICSS_IEP_CMP_STAT_REG] = 0x74, @@ -1017,75 +974,11 @@ index 000000000000..234972a034a9 + .config = &am654_icss_iep_regmap_config, +}; + -+static bool am335x_icss_iep_valid_reg(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case ICSS_IEP_GLOBAL_CFG_REG ... ICSS_IEP_CAPTURE_STAT_REG: -+ case ICSS_IEP_CAP6_RISE_REG0: -+ case ICSS_IEP_CAP6_FALL_REG0: -+ case ICSS_IEP_CMP_CFG_REG ... ICSS_IEP_CMP0_REG0: -+ case ICSS_IEP_CMP8_REG0 ... ICSS_IEP_SYNC_START_REG: -+ return true; -+ default: -+ return false; -+ } -+ -+ return false; -+} -+ -+static struct regmap_config am335x_icss_iep_regmap_config = { -+ .name = "icss iep", -+ .reg_stride = 1, -+ .reg_write = icss_iep_regmap_write, -+ .reg_read = icss_iep_regmap_read, -+ .writeable_reg = am335x_icss_iep_valid_reg, -+ .readable_reg = am335x_icss_iep_valid_reg, -+}; -+ -+static const struct icss_iep_plat_data am335x_icss_iep_plat_data = { -+ .flags = 0, -+ .reg_offs = { -+ [ICSS_IEP_GLOBAL_CFG_REG] = 0x00, -+ [ICSS_IEP_COMPEN_REG] = 0x08, -+ [ICSS_IEP_COUNT_REG0] = 0x0C, -+ [ICSS_IEP_CAPTURE_CFG_REG] = 0x10, -+ [ICSS_IEP_CAPTURE_STAT_REG] = 0x14, -+ -+ [ICSS_IEP_CAP6_RISE_REG0] = 0x30, -+ [ICSS_IEP_CAP6_FALL_REG0] = 0x34, -+ -+ [ICSS_IEP_CAP7_RISE_REG0] = 0x38, -+ [ICSS_IEP_CAP7_FALL_REG0] = 0x3C, -+ -+ [ICSS_IEP_CMP_CFG_REG] = 0x40, -+ [ICSS_IEP_CMP_STAT_REG] = 0x44, -+ [ICSS_IEP_CMP0_REG0] = 0x48, -+ -+ [ICSS_IEP_CMP8_REG0] = 0x88, -+ [ICSS_IEP_SYNC_CTRL_REG] = 0x100, -+ [ICSS_IEP_SYNC0_STAT_REG] = 0x108, -+ [ICSS_IEP_SYNC1_STAT_REG] = 0x10C, -+ [ICSS_IEP_SYNC_PWIDTH_REG] = 0x110, -+ [ICSS_IEP_SYNC0_PERIOD_REG] = 0x114, -+ [ICSS_IEP_SYNC1_DELAY_REG] = 0x118, -+ [ICSS_IEP_SYNC_START_REG] = 0x11C, -+ }, -+ .config = &am335x_icss_iep_regmap_config, -+}; -+ +static const struct of_device_id icss_iep_of_match[] = { + { + .compatible = "ti,am654-icss-iep", + .data = &am654_icss_iep_plat_data, + }, -+ { -+ .compatible = "ti,am5728-icss-iep", -+ .data = &am57xx_icss_iep_plat_data, -+ }, -+ { -+ .compatible = "ti,am3356-icss-iep", -+ .data = &am335x_icss_iep_plat_data, -+ }, + {}, +}; +MODULE_DEVICE_TABLE(of, icss_iep_of_match); @@ -1093,25 +986,26 @@ index 000000000000..234972a034a9 +static struct platform_driver icss_iep_driver = { + .driver = { + .name = "icss-iep", -+ .of_match_table = of_match_ptr(icss_iep_of_match), ++ .of_match_table = icss_iep_of_match, + }, + .probe = icss_iep_probe, +}; +module_platform_driver(icss_iep_driver); + -+MODULE_LICENSE("GPL v2"); ++MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("TI ICSS IEP driver"); +MODULE_AUTHOR("Roger Quadros "); -diff --git a/drivers/net/ethernet/ti/icss_iep.h b/drivers/net/ethernet/ti/icss_iep.h ++MODULE_AUTHOR("Md Danish Anwar "); +diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.h b/drivers/net/ethernet/ti/icssg/icss_iep.h new file mode 100644 -index 000000000000..a41e18df666e +index 000000000000..9eee44ae4990 --- /dev/null -+++ b/drivers/net/ethernet/ti/icss_iep.h -@@ -0,0 +1,37 @@ ++++ b/drivers/net/ethernet/ti/icssg/icss_iep.h +@@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Texas Instruments ICSSG Industrial Ethernet Peripheral (IEP) Driver + * -+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ ++ * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/ + * + */ + @@ -1128,7 +1022,7 @@ index 000000000000..a41e18df666e +struct icss_iep_clockops { + void (*settime)(void *clockops_data, u64 ns); + void (*adjtime)(void *clockops_data, s64 delta); -+ u64 (*gettime)(void *clockops_data); ++ u64 (*gettime)(void *clockops_data, struct ptp_system_timestamp *sts); + int (*perout_enable)(void *clockops_data, + struct ptp_perout_request *req, int on, + u64 *cmp); @@ -1136,6 +1030,7 @@ index 000000000000..a41e18df666e +}; + +struct icss_iep *icss_iep_get(struct device_node *np); ++struct icss_iep *icss_iep_get_idx(struct device_node *np, int idx); +void icss_iep_put(struct icss_iep *iep); +int icss_iep_init(struct icss_iep *iep, const struct icss_iep_clockops *clkops, + void *clockops_data, u32 cycle_time_ns); @@ -1145,3 +1040,6 @@ index 000000000000..a41e18df666e +int icss_iep_get_ptp_clock_idx(struct icss_iep *iep); + +#endif /* __NET_TI_ICSS_IEP_H */ +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0084-arm64-dts-ti-k3-am65-main-Add-ICSSG-IEP-nodes.patch b/recipes-kernel/linux/files/patches-6.1/0029-arm64-dts-ti-k3-am65-main-Add-ICSSG-IEP-nodes.patch similarity index 78% rename from recipes-kernel/linux/files/patches-5.10/0084-arm64-dts-ti-k3-am65-main-Add-ICSSG-IEP-nodes.patch rename to recipes-kernel/linux/files/patches-6.1/0029-arm64-dts-ti-k3-am65-main-Add-ICSSG-IEP-nodes.patch index 2c6b8f2b6..ef50263ba 100644 --- a/recipes-kernel/linux/files/patches-5.10/0084-arm64-dts-ti-k3-am65-main-Add-ICSSG-IEP-nodes.patch +++ b/recipes-kernel/linux/files/patches-6.1/0029-arm64-dts-ti-k3-am65-main-Add-ICSSG-IEP-nodes.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Suman Anna -Date: Tue, 16 Mar 2021 18:00:25 -0500 -Subject: [PATCH] arm64: dts: ti: k3-am65-main: Add ICSSG IEP nodes +From 468f8404bbc5d44a6f5aa760a4bfa2f5abc5dde2 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Mon, 11 Sep 2023 12:42:43 +0530 +Subject: [PATCH 29/76] arm64: dts: ti: k3-am65-main: Add ICSSG IEP nodes The ICSSG IP on AM65x SoCs have two Industrial Ethernet Peripherals (IEPs) to manage/generate Industrial Ethernet functions such as time stamping. @@ -9,17 +9,16 @@ Each IEP sub-module is sourced from an internal clock mux that can be sourced from either of the IP instance's ICSSG_IEP_GCLK or ICSSG_ICLK. Add the IEP nodes for all the ICSSG instances. -Signed-off-by: Suman Anna -Signed-off-by: Lokesh Vutla +Signed-off-by: MD Danish Anwar --- arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index 49f731818961..e9785a9180b7 100644 +index 83dd8993027a..e239287ee9d7 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -997,6 +997,18 @@ icssg0_iepclk_mux: iepclk-mux@30 { +@@ -967,6 +967,18 @@ icssg0_iepclk_mux: iepclk-mux@30 { }; }; @@ -38,7 +37,7 @@ index 49f731818961..e9785a9180b7 100644 icssg0_mii_rt: mii-rt@32000 { compatible = "ti,pruss-mii", "syscon"; reg = <0x32000 0x100>; -@@ -1138,6 +1150,18 @@ icssg1_iepclk_mux: iepclk-mux@30 { +@@ -1108,6 +1120,18 @@ icssg1_iepclk_mux: iepclk-mux@30 { }; }; @@ -57,7 +56,7 @@ index 49f731818961..e9785a9180b7 100644 icssg1_mii_rt: mii-rt@32000 { compatible = "ti,pruss-mii", "syscon"; reg = <0x32000 0x100>; -@@ -1279,6 +1303,18 @@ icssg2_iepclk_mux: iepclk-mux@30 { +@@ -1249,6 +1273,18 @@ icssg2_iepclk_mux: iepclk-mux@30 { }; }; @@ -76,3 +75,6 @@ index 49f731818961..e9785a9180b7 100644 icssg2_mii_rt: mii-rt@32000 { compatible = "ti,pruss-mii", "syscon"; reg = <0x32000 0x100>; +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0093-net-ti-ethernet-icssg-prueth-add-packet-timestamping.patch b/recipes-kernel/linux/files/patches-6.1/0030-net-ti-icssg-prueth-add-packet-timestamping-and-ptp-.patch similarity index 53% rename from recipes-kernel/linux/files/patches-5.10/0093-net-ti-ethernet-icssg-prueth-add-packet-timestamping.patch rename to recipes-kernel/linux/files/patches-6.1/0030-net-ti-icssg-prueth-add-packet-timestamping-and-ptp-.patch index 5eea406f0..5ad7ec2ff 100644 --- a/recipes-kernel/linux/files/patches-5.10/0093-net-ti-ethernet-icssg-prueth-add-packet-timestamping.patch +++ b/recipes-kernel/linux/files/patches-6.1/0030-net-ti-icssg-prueth-add-packet-timestamping-and-ptp-.patch @@ -1,26 +1,12 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 78035d6340d76c87b5c652272081ddc36aad8f40 Mon Sep 17 00:00:00 2001 From: Roger Quadros -Date: Tue, 18 May 2021 23:37:30 +0300 -Subject: [PATCH] net: ti: ethernet: icssg-prueth: add packet timestamping and - ptp support +Date: Thu, 24 Aug 2023 17:16:17 +0530 +Subject: [PATCH 30/76] net: ti: icssg-prueth: add packet timestamping and ptp + support Add packet timestamping TS and PTP PHC clock support. -SR1.0: - - IEP0/IEP1 independent, assigned to each port under full control of the -Linux. - - The IEP0/IEP1 are configured in 64bit mode and provide timestamps and -time in ns - DMEM registers needs to be used to calculate ns timestamp -along with IEP count register. - - Each IEPx is registered as separate PTP PHC clock for each PRUeth port. -The jbod mode has to be used with boundary clock and ext. synchronization. - - Each IEPx supports PPS, periodic output and extts timestamping. For PPS -- FW takes care of setting the SYNC_EN pulse every cycle. - - RX TS provided with each packet in CPPI5 descriptor. - - TX TS returned through separate management DMA flow. Only one packet at -time can be requested for TX TS. - -SR2.0 +For AM65x and AM64x: - IEP1 is not used - IEP0 is configured in shadow mode with 1ms cycle and shared between Linux and FW. It provides time and TS in number cycles, so special @@ -37,49 +23,46 @@ Signed-off-by: Roger Quadros Co-developed-by: Grygorii Strashko Signed-off-by: Grygorii Strashko Signed-off-by: Vignesh Raghavendra +Reviewed-by: Simon Horman +Signed-off-by: MD Danish Anwar --- - drivers/net/ethernet/ti/icssg_config.h | 19 + - drivers/net/ethernet/ti/icssg_ethtool.c | 21 + - drivers/net/ethernet/ti/icssg_prueth.c | 487 +++++++++++++++++++++++- - drivers/net/ethernet/ti/icssg_prueth.h | 17 + - 4 files changed, 538 insertions(+), 6 deletions(-) + drivers/net/ethernet/ti/Kconfig | 1 + + drivers/net/ethernet/ti/icssg/icss_iep.h | 1 + + drivers/net/ethernet/ti/icssg/icssg_ethtool.c | 21 + + drivers/net/ethernet/ti/icssg/icssg_prueth.c | 424 +++++++++++++++++- + drivers/net/ethernet/ti/icssg/icssg_prueth.h | 26 +- + 5 files changed, 467 insertions(+), 6 deletions(-) -diff --git a/drivers/net/ethernet/ti/icssg_config.h b/drivers/net/ethernet/ti/icssg_config.h -index e8f02208fe4f..82930383204b 100644 ---- a/drivers/net/ethernet/ti/icssg_config.h -+++ b/drivers/net/ethernet/ti/icssg_config.h -@@ -171,6 +171,25 @@ enum icssg_port_state_cmd { - - #define ICSSG_FLAG_MASK 0xff00ffff - -+struct icssg_setclock_desc { -+ u8 request; -+ u8 restore; -+ u8 acknowledgment; -+ u8 cmp_status; -+ u32 margin; -+ u32 cyclecounter0_set; -+ u32 cyclecounter1_set; -+ u32 iepcount_set; -+ u32 rsvd1; -+ u32 rsvd2; -+ u32 CMP0_current; -+ u32 iepcount_current; -+ u32 difference; -+ u32 cyclecounter0_new; -+ u32 cyclecounter1_new; -+ u32 CMP0_new; -+} __packed; -+ - #define ICSSG_CMD_POP_SLICE0 56 - #define ICSSG_CMD_POP_SLICE1 60 - -diff --git a/drivers/net/ethernet/ti/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg_ethtool.c -index b43fb0e6109a..b6f7c1a86941 100644 ---- a/drivers/net/ethernet/ti/icssg_ethtool.c -+++ b/drivers/net/ethernet/ti/icssg_ethtool.c -@@ -278,6 +278,26 @@ static void emac_get_ethtool_stats(struct net_device *ndev, - } +diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig +index 1af5a90720ec..88b5b1b47779 100644 +--- a/drivers/net/ethernet/ti/Kconfig ++++ b/drivers/net/ethernet/ti/Kconfig +@@ -186,6 +186,7 @@ config CPMAC + config TI_ICSSG_PRUETH + tristate "TI Gigabit PRU Ethernet driver" + select PHYLIB ++ select TI_ICSS_IEP + depends on PRU_REMOTEPROC + depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER + help +diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.h b/drivers/net/ethernet/ti/icssg/icss_iep.h +index 9eee44ae4990..9c7f4d0a0916 100644 +--- a/drivers/net/ethernet/ti/icssg/icss_iep.h ++++ b/drivers/net/ethernet/ti/icssg/icss_iep.h +@@ -13,6 +13,7 @@ + #include + + struct icss_iep; ++extern const struct icss_iep_clockops prueth_iep_clockops; + + /* Firmware specific clock operations */ + struct icss_iep_clockops { +diff --git a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c +index 02c312f01d10..a27ec1dcc8d5 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c +@@ -109,6 +109,26 @@ static void emac_get_ethtool_stats(struct net_device *ndev, + *(data++) = emac->stats[i]; } +static int emac_get_ts_info(struct net_device *ndev, @@ -102,31 +85,31 @@ index b43fb0e6109a..b6f7c1a86941 100644 + return 0; +} + - static void emac_get_channels(struct net_device *ndev, - struct ethtool_channels *ch) + static int emac_set_channels(struct net_device *ndev, + struct ethtool_channels *ch) { -@@ -323,6 +343,7 @@ const struct ethtool_ops icssg_ethtool_ops = { +@@ -176,6 +196,7 @@ const struct ethtool_ops icssg_ethtool_ops = { .get_sset_count = emac_get_sset_count, - .get_strings = emac_get_strings, .get_ethtool_stats = emac_get_ethtool_stats, + .get_strings = emac_get_strings, + .get_ts_info = emac_get_ts_info, - .get_channels = emac_get_channels, .set_channels = emac_set_channels, -diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c -index 90cb3418d72f..f18af03964b1 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.c -+++ b/drivers/net/ethernet/ti/icssg_prueth.c -@@ -59,6 +59,8 @@ + .get_link_ksettings = emac_get_link_ksettings, +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +index 47b941fb0198..1bcb4e174652 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +@@ -56,6 +56,8 @@ /* CTRLMMR_ICSSG_RGMII_CTRL register bits */ - #define ICSSG_CTRL_RGMII_ID_MODE BIT(24) + #define ICSSG_CTRL_RGMII_ID_MODE BIT(24) +#define IEP_DEFAULT_CYCLE_TIME_NS 1000000 /* 1 ms */ + - static int debug_level = -1; - module_param(debug_level, int, 0644); - MODULE_PARM_DESC(debug_level, "PRUETH debug level (NETIF_MSG bits)"); -@@ -487,6 +489,41 @@ static int prueth_dma_rx_push(struct prueth_emac *emac, + static void prueth_cleanup_rx_chns(struct prueth_emac *emac, + struct prueth_rx_chn *rx_chn, + int max_rflows) +@@ -471,6 +473,37 @@ static int prueth_dma_rx_push(struct prueth_emac *emac, desc_rx, desc_dma); } @@ -151,14 +134,10 @@ index 90cb3418d72f..f18af03964b1 100644 + struct skb_shared_hwtstamps *ssh; + u64 ns; + -+ if (emac->is_sr1) { -+ ns = (u64)psdata[1] << 32 | psdata[0]; -+ } else { -+ u32 hi_sw = readl(emac->prueth->shram.va + -+ TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET); -+ ns = icssg_ts_to_ns(hi_sw, psdata[1], psdata[0], -+ IEP_DEFAULT_CYCLE_TIME_NS); -+ } ++ u32 hi_sw = readl(emac->prueth->shram.va + ++ TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET); ++ ns = icssg_ts_to_ns(hi_sw, psdata[1], psdata[0], ++ IEP_DEFAULT_CYCLE_TIME_NS); + + ssh = skb_hwtstamps(skb); + memset(ssh, 0, sizeof(*ssh)); @@ -168,17 +147,27 @@ index 90cb3418d72f..f18af03964b1 100644 static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) { struct prueth_rx_chn *rx_chn = &emac->rx_chns; -@@ -515,6 +552,9 @@ static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) +@@ -480,6 +513,7 @@ static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) + struct sk_buff *skb, *new_skb; + dma_addr_t desc_dma, buf_dma; + void **swdata; ++ u32 *psdata; + int ret; + + ret = k3_udma_glue_pop_rx_chn(rx_chn->rx_chn, flow_id, &desc_dma); +@@ -497,6 +531,11 @@ static int emac_rx_packet(struct prueth_emac *emac, u32 flow_id) + swdata = cppi5_hdesc_get_swdata(desc_rx); skb = *swdata; - psdata = cppi5_hdesc_get_psdata(desc_rx); ++ psdata = cppi5_hdesc_get_psdata(desc_rx); + /* RX HW timestamp */ + if (emac->rx_ts_enabled) + emac_rx_timestamp(emac, skb, psdata); - ++ cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); + k3_udma_glue_rx_cppi5_to_dma_addr(rx_chn->rx_chn, &buf_dma); pkt_len = cppi5_hdesc_get_pktlen(desc_rx); -@@ -579,6 +619,26 @@ static void prueth_rx_cleanup(void *data, dma_addr_t desc_dma) +@@ -557,6 +596,86 @@ static void prueth_rx_cleanup(void *data, dma_addr_t desc_dma) dev_kfree_skb_any(skb); } @@ -202,133 +191,152 @@ index 90cb3418d72f..f18af03964b1 100644 + return 0; +} + - /* TODO: Convert this to use worker/workqueue mechanism to serialize the - * request to firmware - */ -@@ -691,6 +751,62 @@ static int emac_shutdown(struct net_device *ndev) - return emac_send_command_sr1(emac, ICSSG_SHUTDOWN_CMD); - } - +static void tx_ts_work(struct prueth_emac *emac) +{ -+ u64 ns; + struct skb_shared_hwtstamps ssh; ++ struct emac_tx_ts_response tsr; + struct sk_buff *skb; -+ int timeout = 10; + int ret = 0; -+ struct emac_tx_ts_response tsr; + u32 hi_sw; ++ u64 ns; + -+ if (!test_bit(__STATE_TX_TS_IN_PROGRESS, &emac->state)) { -+ netdev_err(emac->ndev, "unexpected TS response\n"); -+ return; -+ } -+ -+ skb = emac->tx_ts_skb; -+ while (timeout-- > 0) { -+ /* wait for response or timeout */ ++ /* There may be more than one pending requests */ ++ while (1) { + ret = emac_get_tx_ts(emac, &tsr); -+ if (!ret) ++ if (ret) /* nothing more */ + break; -+ usleep_range(10, 20); -+ } + -+ if (ret) { -+ netdev_err(emac->ndev, "TX timestamp timeout\n"); -+ goto error; -+ } ++ if (tsr.cookie >= PRUETH_MAX_TX_TS_REQUESTS || ++ !emac->tx_ts_skb[tsr.cookie]) { ++ netdev_err(emac->ndev, "Invalid TX TS cookie 0x%x\n", ++ tsr.cookie); ++ break; ++ } + -+ if (tsr.cookie != emac->tx_ts_cookie) { -+ netdev_err(emac->ndev, "TX TS cookie mismatch 0x%x:0x%x\n", -+ tsr.cookie, emac->tx_ts_cookie); -+ goto error; -+ } ++ skb = emac->tx_ts_skb[tsr.cookie]; ++ emac->tx_ts_skb[tsr.cookie] = NULL; /* free slot */ ++ if (!skb) { ++ netdev_err(emac->ndev, "Driver Bug! got NULL skb\n"); ++ break; ++ } + -+ hi_sw = readl(emac->prueth->shram.va + -+ TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET); -+ ns = icssg_ts_to_ns(hi_sw, tsr.hi_ts, tsr.lo_ts, -+ IEP_DEFAULT_CYCLE_TIME_NS); ++ hi_sw = readl(emac->prueth->shram.va + ++ TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET); ++ ns = icssg_ts_to_ns(hi_sw, tsr.hi_ts, tsr.lo_ts, ++ IEP_DEFAULT_CYCLE_TIME_NS); ++ ++ memset(&ssh, 0, sizeof(ssh)); ++ ssh.hwtstamp = ns_to_ktime(ns); + -+ emac->tx_ts_cookie++; -+ memset(&ssh, 0, sizeof(ssh)); -+ ssh.hwtstamp = ns_to_ktime(ns); -+ clear_bit_unlock(__STATE_TX_TS_IN_PROGRESS, &emac->state); ++ skb_tstamp_tx(skb, &ssh); ++ dev_consume_skb_any(skb); + -+ skb_tstamp_tx(skb, &ssh); -+ dev_consume_skb_any(skb); ++ if (atomic_dec_and_test(&emac->tx_ts_pending)) /* no more? */ ++ break; ++ } ++} + -+ return; ++static int prueth_tx_ts_cookie_get(struct prueth_emac *emac) ++{ ++ int i; + -+error: -+ dev_kfree_skb_any(skb); -+ emac->tx_ts_skb = NULL; -+ clear_bit_unlock(__STATE_TX_TS_IN_PROGRESS, &emac->state); ++ /* search and get the next free slot */ ++ for (i = 0; i < PRUETH_MAX_TX_TS_REQUESTS; i++) { ++ if (!emac->tx_ts_skb[i]) { ++ emac->tx_ts_skb[i] = ERR_PTR(-EBUSY); /* reserve slot */ ++ return i; ++ } ++ } ++ ++ return -EBUSY; +} + /** * emac_ndo_start_xmit - EMAC Transmit function * @skb: SKB pointer -@@ -711,6 +827,7 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) +@@ -577,6 +696,8 @@ static enum netdev_tx emac_ndo_start_xmit(struct sk_buff *skb, struct net_device struct prueth_tx_chn *tx_chn; dma_addr_t desc_dma, buf_dma; int i, ret = 0, q_idx; + bool in_tx_ts = 0; ++ int tx_ts_cookie; void **swdata; u32 pkt_len; u32 *epib; -@@ -743,6 +860,19 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) +@@ -608,6 +729,18 @@ static enum netdev_tx emac_ndo_start_xmit(struct sk_buff *skb, struct net_device epib = first_desc->epib; epib[0] = 0; epib[1] = 0; + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && + emac->tx_ts_enabled) { -+ /* We currently support only one TX HW timestamp at a time */ -+ if (!test_and_set_bit_lock(__STATE_TX_TS_IN_PROGRESS, -+ &emac->state)) { ++ tx_ts_cookie = prueth_tx_ts_cookie_get(emac); ++ if (tx_ts_cookie >= 0) { + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + /* Request TX timestamp */ -+ epib[0] = emac->tx_ts_cookie; ++ epib[0] = (u32)tx_ts_cookie; + epib[1] = 0x80000000; /* TX TS request */ -+ emac->tx_ts_skb = skb_get(skb); ++ emac->tx_ts_skb[tx_ts_cookie] = skb_get(skb); + in_tx_ts = 1; + } + } /* set dst tag to indicate internal qid at the firmware which is at - * bit8..bit15 -@@ -766,7 +896,7 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) + * bit8..bit15. bit0..bit7 indicates port num for directed +@@ -629,7 +762,7 @@ static enum netdev_tx emac_ndo_start_xmit(struct sk_buff *skb, struct net_device + if (!next_desc) { netdev_err(ndev, "tx: failed to allocate frag. descriptor\n"); - ret = -ENOMEM; -- goto drop_free_descs; -+ goto cleanup_tx_ts; +- goto free_desc_stop_q_busy; ++ goto free_desc_stop_q_busy_cleanup_tx_ts; } buf_dma = skb_frag_dma_map(tx_chn->dma_dev, frag, 0, frag_size, -@@ -775,7 +905,7 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) +@@ -638,7 +771,7 @@ static enum netdev_tx emac_ndo_start_xmit(struct sk_buff *skb, struct net_device netdev_err(ndev, "tx: Failed to map skb page\n"); k3_cppi_desc_pool_free(tx_chn->desc_pool, next_desc); - ret = -EINVAL; + ret = NETDEV_TX_OK; - goto drop_free_descs; + goto cleanup_tx_ts; } cppi5_hdesc_reset_hbdesc(next_desc); -@@ -818,6 +948,13 @@ static int emac_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) +@@ -670,6 +803,9 @@ static enum netdev_tx emac_ndo_start_xmit(struct sk_buff *skb, struct net_device + goto drop_free_descs; + } + ++ if (in_tx_ts) ++ atomic_inc(&emac->tx_ts_pending); ++ + if (k3_cppi_desc_pool_avail(tx_chn->desc_pool) < MAX_SKB_FRAGS) { + netif_tx_stop_queue(netif_txq); + /* Barrier, so that stop_queue visible to other cpus */ +@@ -682,6 +818,12 @@ static enum netdev_tx emac_ndo_start_xmit(struct sk_buff *skb, struct net_device return NETDEV_TX_OK; +cleanup_tx_ts: + if (in_tx_ts) { -+ dev_kfree_skb_any(emac->tx_ts_skb); -+ emac->tx_ts_skb = NULL; -+ clear_bit_unlock(__STATE_TX_TS_IN_PROGRESS, &emac->state); ++ dev_kfree_skb_any(emac->tx_ts_skb[tx_ts_cookie]); ++ emac->tx_ts_skb[tx_ts_cookie] = NULL; + } + drop_free_descs: prueth_xmit_free(tx_chn, first_desc); - drop_stop_q: -@@ -850,6 +987,16 @@ static void prueth_tx_cleanup(void *data, dma_addr_t desc_dma) + +@@ -694,7 +836,11 @@ static enum netdev_tx emac_ndo_start_xmit(struct sk_buff *skb, struct net_device + + return ret; + +-free_desc_stop_q_busy: ++free_desc_stop_q_busy_cleanup_tx_ts: ++ if (in_tx_ts) { ++ dev_kfree_skb_any(emac->tx_ts_skb[tx_ts_cookie]); ++ emac->tx_ts_skb[tx_ts_cookie] = NULL; ++ } + prueth_xmit_free(tx_chn, first_desc); + + drop_stop_q_busy: +@@ -717,6 +863,16 @@ static void prueth_tx_cleanup(void *data, dma_addr_t desc_dma) dev_kfree_skb_any(skb); } @@ -342,68 +350,41 @@ index 90cb3418d72f..f18af03964b1 100644 + return IRQ_HANDLED; +} + - /* get one packet from requested flow_id - * - * Returns skb pointer if packet found else NULL -@@ -916,7 +1063,44 @@ static struct sk_buff *prueth_process_rx_mgm(struct prueth_emac *emac, - return skb; + static irqreturn_t prueth_rx_irq(int irq, void *dev_id) + { + struct prueth_emac *emac = dev_id; +@@ -820,6 +976,18 @@ static void prueth_emac_stop(struct prueth_emac *emac) + rproc_shutdown(prueth->pru[slice]); } --static irqreturn_t prueth_rx_mgm_ts_thread(int irq, void *dev_id) -+static void prueth_tx_ts_sr1(struct prueth_emac *emac, -+ struct emac_tx_ts_response_sr1 *tsr) ++static void prueth_cleanup_tx_ts(struct prueth_emac *emac) +{ -+ u64 ns; -+ struct skb_shared_hwtstamps ssh; -+ struct sk_buff *skb; -+ -+ ns = (u64)tsr->hi_ts << 32 | tsr->lo_ts; ++ int i; + -+ if (!test_bit(__STATE_TX_TS_IN_PROGRESS, &emac->state)) { -+ netdev_err(emac->ndev, "unexpected TS response\n"); -+ return; -+ } -+ -+ skb = emac->tx_ts_skb; -+ if (tsr->cookie != emac->tx_ts_cookie) { -+ netdev_err(emac->ndev, "TX TS cookie mismatch 0x%x:0x%x\n", -+ tsr->cookie, emac->tx_ts_cookie); -+ goto error; ++ for (i = 0; i < PRUETH_MAX_TX_TS_REQUESTS; i++) { ++ if (emac->tx_ts_skb[i]) { ++ dev_kfree_skb_any(emac->tx_ts_skb[i]); ++ emac->tx_ts_skb[i] = NULL; ++ } + } -+ -+ emac->tx_ts_cookie++; -+ memset(&ssh, 0, sizeof(ssh)); -+ ssh.hwtstamp = ns_to_ktime(ns); -+ clear_bit_unlock(__STATE_TX_TS_IN_PROGRESS, &emac->state); -+ -+ skb_tstamp_tx(skb, &ssh); -+ dev_consume_skb_any(skb); -+ -+ return; -+ -+error: -+ dev_kfree_skb_any(skb); -+ emac->tx_ts_skb = NULL; -+ clear_bit_unlock(__STATE_TX_TS_IN_PROGRESS, &emac->state); +} + -+static irqreturn_t prueth_rx_mgm_ts_thread_sr1(int irq, void *dev_id) + /* called back by PHY layer if there is change in link state of hw port*/ + static void emac_adjust_link(struct net_device *ndev) { - struct prueth_emac *emac = dev_id; - struct sk_buff *skb; -@@ -925,6 +1109,7 @@ static irqreturn_t prueth_rx_mgm_ts_thread(int irq, void *dev_id) - if (!skb) - return IRQ_NONE; - -+ prueth_tx_ts_sr1(emac, (void *)skb->data); - dev_kfree_skb_any(skb); +@@ -881,6 +1049,7 @@ static void emac_adjust_link(struct net_device *ndev) + netif_tx_wake_all_queues(ndev); + } else { + netif_tx_stop_all_queues(ndev); ++ prueth_cleanup_tx_ts(emac); + } + } - return IRQ_HANDLED; -@@ -1204,6 +1389,135 @@ static void prueth_reset_rx_chan(struct prueth_rx_chn *chn, - k3_udma_glue_disable_rx_chn(chn->rx_chn); +@@ -992,6 +1161,139 @@ static int emac_phy_connect(struct prueth_emac *emac) + return 0; } -+static u64 prueth_iep_gettime(void *clockops_data) ++static u64 prueth_iep_gettime(void *clockops_data, struct ptp_system_timestamp *sts) +{ + u32 hi_rollover_count, hi_rollover_count_r; + struct prueth_emac *emac = clockops_data; @@ -411,23 +392,28 @@ index 90cb3418d72f..f18af03964b1 100644 + void __iomem *fw_hi_r_count_addr; + void __iomem *fw_count_hi_addr; + u32 iepcount_hi, iepcount_hi_r; ++ unsigned long flags; + u32 iepcount_lo; + u64 ts = 0; + + fw_count_hi_addr = prueth->shram.va + TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET; + fw_hi_r_count_addr = prueth->shram.va + TIMESYNC_FW_WC_HI_ROLLOVER_COUNT_OFFSET; + ++ local_irq_save(flags); + do { + iepcount_hi = icss_iep_get_count_hi(emac->iep); + iepcount_hi += readl(fw_count_hi_addr); + hi_rollover_count = readl(fw_hi_r_count_addr); ++ ptp_read_system_prets(sts); + iepcount_lo = icss_iep_get_count_low(emac->iep); ++ ptp_read_system_postts(sts); + + iepcount_hi_r = icss_iep_get_count_hi(emac->iep); + iepcount_hi_r += readl(fw_count_hi_addr); + hi_rollover_count_r = readl(fw_hi_r_count_addr); + } while ((iepcount_hi_r != iepcount_hi) || + (hi_rollover_count != hi_rollover_count_r)); ++ local_irq_restore(flags); + + ts = ((u64)hi_rollover_count) << 23 | iepcount_hi; + ts = ts * (u64)IEP_DEFAULT_CYCLE_TIME_NS + iepcount_lo; @@ -437,8 +423,9 @@ index 90cb3418d72f..f18af03964b1 100644 + +static void prueth_iep_settime(void *clockops_data, u64 ns) +{ -+ struct icssg_setclock_desc sc_desc, *sc_descp; ++ struct icssg_setclock_desc __iomem *sc_descp; + struct prueth_emac *emac = clockops_data; ++ struct icssg_setclock_desc sc_desc; + u64 cyclecount; + u32 cycletime; + int timeout; @@ -518,7 +505,6 @@ index 90cb3418d72f..f18af03964b1 100644 + writel(reduction_factor, emac->prueth->shram.va + + TIMESYNC_FW_WC_SYNCOUT_REDUCTION_FACTOR_OFFSET); + -+ /* HACK: till f/w supports START_TIME cyclcount we set it to 0 */ + writel(0, emac->prueth->shram.va + + TIMESYNC_FW_WC_SYNCOUT_START_TIME_CYCLECOUNT_OFFSET); + @@ -528,77 +514,60 @@ index 90cb3418d72f..f18af03964b1 100644 +const struct icss_iep_clockops prueth_iep_clockops = { + .settime = prueth_iep_settime, + .gettime = prueth_iep_gettime, -+ /* FIXME: add adjtime to use relative mode */ + .perout_enable = prueth_perout_enable, +}; + /** * emac_ndo_open - EMAC device open * @ndev: network adapter device -@@ -1304,7 +1618,7 @@ static int emac_ndo_open(struct net_device *ndev) - } +@@ -1066,10 +1368,20 @@ static int emac_ndo_open(struct net_device *ndev) - ret = request_threaded_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_TIMESTAMP], -- NULL, prueth_rx_mgm_ts_thread, -+ NULL, prueth_rx_mgm_ts_thread_sr1, - IRQF_ONESHOT | IRQF_TRIGGER_HIGH, - dev_name(dev), emac); - if (ret) { -@@ -1318,10 +1632,23 @@ static int emac_ndo_open(struct net_device *ndev) - if (ret) - goto free_rx_mgmt_ts_irq; + icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu); -+ if (!emac->is_sr1 && !prueth->iep_initialized) { ++ if (!prueth->emacs_initialized) { + ret = icss_iep_init(emac->iep, &prueth_iep_clockops, + emac, IEP_DEFAULT_CYCLE_TIME_NS); + } -+ prueth->iep_initialized++; + -+ if (!emac->is_sr1) { -+ ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq, -+ IRQF_ONESHOT, dev_name(dev), emac); -+ if (ret) -+ goto stop; -+ } ++ ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq, ++ IRQF_ONESHOT, dev_name(dev), emac); ++ if (ret) ++ goto stop; + /* Prepare RX */ ret = prueth_prepare_rx_chan(emac, &emac->rx_chns, PRUETH_MAX_PKT_SIZE); if (ret) - goto stop; -+ goto free_rx_ts_irq; ++ goto free_tx_ts_irq; - if (emac->is_sr1) { - ret = prueth_prepare_rx_chan(emac, &emac->rx_mgm_chn, 64); -@@ -1373,6 +1700,9 @@ static int emac_ndo_open(struct net_device *ndev) - PRUETH_MAX_RX_MGM_FLOWS, true); + ret = k3_udma_glue_enable_rx_chn(emac->rx_chns.rx_chn); + if (ret) +@@ -1102,6 +1414,8 @@ static int emac_ndo_open(struct net_device *ndev) + prueth_reset_tx_chan(emac, i, false); reset_rx_chn: prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, false); -+free_rx_ts_irq: -+ if (!emac->is_sr1) -+ free_irq(emac->tx_ts_irq, emac); ++free_tx_ts_irq: ++ free_irq(emac->tx_ts_irq, emac); stop: prueth_emac_stop(emac); - free_rx_mgmt_ts_irq: -@@ -1455,9 +1785,17 @@ static int emac_ndo_stop(struct net_device *ndev) - - napi_disable(&emac->napi_rx); + free_rx_irq: +@@ -1173,6 +1487,14 @@ static int emac_ndo_stop(struct net_device *ndev) + /* stop PRUs */ + prueth_emac_stop(emac); -+ if (!emac->is_sr1 && prueth->iep_initialized == 1) ++ if (prueth->emacs_initialized == 1) + icss_iep_exit(emac->iep); + -+ prueth->iep_initialized--; ++ /* stop PRUs */ ++ prueth_emac_stop(emac); + - /* stop PRUs */ - prueth_emac_stop(emac); - -+ if (!emac->is_sr1) -+ free_irq(emac->tx_ts_irq, emac); ++ free_irq(emac->tx_ts_irq, emac); + - if (emac->is_sr1) { - free_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_TIMESTAMP], - emac); -@@ -1558,10 +1896,81 @@ static void emac_ndo_set_rx_mode(struct net_device *ndev) - } + free_irq(emac->rx_chns.irq[rx_flow], emac); + prueth_ndev_del_tx_napi(emac, emac->tx_ch_num); + prueth_cleanup_tx_chns(emac); +@@ -1235,8 +1557,79 @@ static void emac_ndo_set_rx_mode(struct net_device *ndev) + queue_work(emac->cmd_wq, &emac->rx_mode_work); } +static int emac_set_ts_config(struct net_device *ndev, struct ifreq *ifr) @@ -665,8 +634,6 @@ index 90cb3418d72f..f18af03964b1 100644 + static int emac_ndo_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) { - struct prueth_emac *emac = netdev_priv(ndev); - + switch (cmd) { + case SIOCGHWTSTAMP: + return emac_get_ts_config(ndev, ifr); @@ -676,24 +643,21 @@ index 90cb3418d72f..f18af03964b1 100644 + break; + } + - return phy_mii_ioctl(emac->phydev, ifr, cmd); + return phy_do_ioctl(ndev, ifr, cmd); } -@@ -1621,6 +2030,7 @@ static int prueth_netdev_init(struct prueth *prueth, +@@ -1316,6 +1709,7 @@ static int prueth_netdev_init(struct prueth *prueth, struct prueth_emac *emac; struct net_device *ndev; enum prueth_port port; + const char *irq_name; enum prueth_mac mac; - const u8 *mac_addr; -@@ -1662,8 +2072,19 @@ static int prueth_netdev_init(struct prueth *prueth, - * messages which is +1 of highest priority data channel. - */ - emac->tx_ch_num++; -+ goto skip_irq; -+ } -+ + port = prueth_node_port(eth_node); +@@ -1355,6 +1749,15 @@ static int prueth_netdev_init(struct prueth *prueth, + + emac->tx_ch_num = 1; + + irq_name = "tx_ts0"; + if (emac->port_id == PRUETH_PORT_MII1) + irq_name = "tx_ts1"; @@ -701,13 +665,12 @@ index 90cb3418d72f..f18af03964b1 100644 + if (emac->tx_ts_irq < 0) { + ret = dev_err_probe(prueth->dev, emac->tx_ts_irq, "could not get tx_ts_irq\n"); + goto free; - } - -+skip_irq: ++ } ++ SET_NETDEV_DEV(ndev, prueth->dev); - emac->msg_enable = netif_msg_init(debug_level, PRUETH_EMAC_DEBUG); spin_lock_init(&emac->lock); -@@ -2006,6 +2427,37 @@ static int prueth_probe(struct platform_device *pdev) + mutex_init(&emac->cmd_lock); +@@ -1680,6 +2083,13 @@ static int prueth_probe(struct platform_device *pdev) dev_dbg(dev, "sram: pa %llx va %p size %zx\n", prueth->msmcram.pa, prueth->msmcram.va, prueth->msmcram.size); @@ -717,114 +680,68 @@ index 90cb3418d72f..f18af03964b1 100644 + prueth->iep0 = NULL; + goto free_pool; + } -+ -+ prueth->iep1 = icss_iep_get_idx(np, 1); -+ if (IS_ERR(prueth->iep1)) { -+ ret = dev_err_probe(dev, PTR_ERR(prueth->iep1), "iep1 get failed\n"); -+ icss_iep_put(prueth->iep1); -+ prueth->iep0 = NULL; -+ prueth->iep1 = NULL; -+ goto free_pool; -+ } -+ -+ if (prueth->is_sr1) { -+ ret = icss_iep_init(prueth->iep0, NULL, NULL, 0); -+ if (ret) { -+ dev_err(dev, "failed to init iep0\n"); -+ goto free_iep; -+ } -+ -+ ret = icss_iep_init(prueth->iep1, NULL, NULL, 0); -+ if (ret) { -+ dev_err(dev, "failed to init iep1\n"); -+ icss_iep_exit(prueth->iep1); -+ goto free_iep; -+ } -+ } + /* setup netdev interfaces */ if (eth0_node) { ret = prueth_netdev_init(prueth, eth0_node); -@@ -2014,8 +2466,9 @@ static int prueth_probe(struct platform_device *pdev) - dev_err(dev, "netdev init %s failed: %d\n", - eth0_node->name, ret); - } -- goto free_pool; -+ goto exit_iep; +@@ -1688,6 +2098,7 @@ static int prueth_probe(struct platform_device *pdev) + eth0_node->name); + goto netdev_exit; } + prueth->emac[PRUETH_MAC0]->iep = prueth->iep0; } if (eth1_node) { -@@ -2027,6 +2480,11 @@ static int prueth_probe(struct platform_device *pdev) - } +@@ -1697,6 +2108,8 @@ static int prueth_probe(struct platform_device *pdev) + eth1_node->name); goto netdev_exit; } + -+ if (prueth->is_sr1) -+ prueth->emac[PRUETH_MAC1]->iep = prueth->iep1; -+ else -+ prueth->emac[PRUETH_MAC1]->iep = prueth->iep0; ++ prueth->emac[PRUETH_MAC1]->iep = prueth->iep0; } /* register the network devices */ -@@ -2077,6 +2535,15 @@ static int prueth_probe(struct platform_device *pdev) - +@@ -1754,6 +2167,7 @@ static int prueth_probe(struct platform_device *pdev) prueth_netdev_exit(prueth, eth_node); } -+exit_iep: -+ if (prueth->is_sr1) { -+ icss_iep_exit(prueth->iep1); -+ icss_iep_exit(prueth->iep0); -+ } -+ -+free_iep: -+ icss_iep_put(prueth->iep1); -+ icss_iep_put(prueth->iep0); - free_pool: ++free_pool: gen_pool_free(prueth->sram_pool, -@@ -2120,6 +2587,14 @@ static int prueth_remove(struct platform_device *pdev) + (unsigned long)prueth->msmcram.va, msmc_ram_size); + +@@ -1798,6 +2212,8 @@ static void prueth_remove(struct platform_device *pdev) prueth_netdev_exit(prueth, eth_node); } -+ if (prueth->is_sr1) { -+ icss_iep_exit(prueth->iep1); -+ icss_iep_exit(prueth->iep0); -+ } -+ -+ icss_iep_put(prueth->iep1); + icss_iep_put(prueth->iep0); + gen_pool_free(prueth->sram_pool, (unsigned long)prueth->msmcram.va, - prueth->is_sr1 ? MSMC_RAM_SIZE_SR1 : MSMC_RAM_SIZE_SR2); -diff --git a/drivers/net/ethernet/ti/icssg_prueth.h b/drivers/net/ethernet/ti/icssg_prueth.h -index 2e8d45c8c25d..156716bf0a76 100644 ---- a/drivers/net/ethernet/ti/icssg_prueth.h -+++ b/drivers/net/ethernet/ti/icssg_prueth.h -@@ -32,6 +32,7 @@ - #include + MSMC_RAM_SIZE); +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +index a8ce4d01ef16..a56ab4cdc83c 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +@@ -35,6 +35,7 @@ + #include #include "icssg_config.h" +#include "icss_iep.h" #include "icssg_switch_map.h" - #define ICSS_SLICE0 0 -@@ -107,6 +108,10 @@ struct prueth_rx_chn { - char name[32]; - }; + #define PRUETH_MAX_MTU (2000 - ETH_HLEN - ETH_FCS_LEN) +@@ -122,6 +123,8 @@ struct prueth_rx_chn { + */ + #define PRUETH_MAX_TX_QUEUES 4 -+enum prueth_state_flags { -+ __STATE_TX_TS_IN_PROGRESS, -+}; ++#define PRUETH_MAX_TX_TS_REQUESTS 50 /* Max simultaneous TX_TS requests */ + - /* There are 4 Tx DMA channels, but the highest priority is CH3 (thread 3) - * and lower three are lower priority channels or threads. - */ -@@ -131,6 +136,9 @@ struct prueth_emac { + /* data for each emac port */ + struct prueth_emac { + bool fw_running; +@@ -139,6 +142,9 @@ struct prueth_emac { + struct device_node *phy_node; phy_interface_t phy_if; - struct phy_device *phydev; enum prueth_port port_id; + struct icss_iep *iep; + unsigned int rx_ts_enabled : 1; @@ -832,26 +749,48 @@ index 2e8d45c8c25d..156716bf0a76 100644 /* DMA related */ struct prueth_tx_chn tx_chns[PRUETH_MAX_TX_QUEUES]; -@@ -146,6 +154,12 @@ struct prueth_emac { +@@ -150,7 +156,15 @@ struct prueth_emac { spinlock_t lock; /* serialize access */ +- unsigned long state; + /* TX HW Timestamping */ -+ u32 tx_ts_cookie; -+ struct sk_buff *tx_ts_skb; -+ unsigned long state; ++ /* TX TS cookie will be index to the tx_ts_skb array */ ++ struct sk_buff *tx_ts_skb[PRUETH_MAX_TX_TS_REQUESTS]; ++ atomic_t tx_ts_pending; + int tx_ts_irq; + - u8 cmd_seq; - /* shutdown related */ - u32 cmd_data[4]; -@@ -197,6 +211,9 @@ struct prueth { - - enum pruss_pru_id pru_id[PRUSS_NUM_PRUS]; ++ u8 cmd_seq; ++ /* shutdown related */ ++ u32 cmd_data[4]; + struct completion cmd_complete; + /* Mutex to serialize access to firmware command interface */ + struct mutex cmd_lock; +@@ -193,6 +207,7 @@ struct prueth_pdata { + * @pdata: pointer to platform data for ICSSG driver + * @icssg_hwcmdseq: seq counter or HWQ messages + * @emacs_initialized: num of EMACs/ext ports that are up/running ++ * @iep0: pointer to IEP0 device + */ + struct prueth { + struct device *dev; +@@ -214,8 +229,15 @@ struct prueth { struct platform_device *pdev; + struct prueth_pdata pdata; + u8 icssg_hwcmdseq; +- + int emacs_initialized; + struct icss_iep *iep0; -+ struct icss_iep *iep1; -+ int iep_initialized; ++}; ++ ++struct emac_tx_ts_response { ++ u32 reserved[2]; ++ u32 cookie; ++ u32 lo_ts; ++ u32 hi_ts; }; - struct emac_tx_ts_response_sr1 { + /* get PRUSS SLICE number from prueth_emac */ +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0031-net-ti-icssg-prueth-am65x-SR2.0-add-10M-full-duplex-.patch b/recipes-kernel/linux/files/patches-6.1/0031-net-ti-icssg-prueth-am65x-SR2.0-add-10M-full-duplex-.patch new file mode 100644 index 000000000..93eddf765 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0031-net-ti-icssg-prueth-am65x-SR2.0-add-10M-full-duplex-.patch @@ -0,0 +1,193 @@ +From c7076ecb60091469856cac4f0ab3165c2ac0ef5c Mon Sep 17 00:00:00 2001 +From: Grygorii Strashko +Date: Thu, 24 Aug 2023 17:16:18 +0530 +Subject: [PATCH 31/76] net: ti: icssg-prueth: am65x SR2.0 add 10M full duplex + support + +For AM65x SR2.0 it's required to enable IEP1 in raw 64bit mode which is +used by PRU FW to monitor the link and apply w/a for 10M link issue. +Note. No public errata available yet. + +Without this w/a the PRU FW will stuck if link state changes under TX +traffic pressure. + +Hence, add support for 10M full duplex for AM65x SR2.0: + - add new IEP API to enable IEP, but without PTP support + - add pdata quirk_10m_link_issue to enable 10M link issue w/a. + +Signed-off-by: Grygorii Strashko +Signed-off-by: Vignesh Raghavendra +Reviewed-by: Roger Quadros +Reviewed-by: Simon Horman +Reviewed-by: Jacob Keller +Signed-off-by: MD Danish Anwar +--- + drivers/net/ethernet/ti/icssg/icss_iep.c | 26 +++++++++++++++++++ + drivers/net/ethernet/ti/icssg/icss_iep.h | 2 ++ + drivers/net/ethernet/ti/icssg/icssg_config.c | 7 +++++ + drivers/net/ethernet/ti/icssg/icssg_prueth.c | 27 ++++++++++++++++++-- + drivers/net/ethernet/ti/icssg/icssg_prueth.h | 2 ++ + 5 files changed, 62 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.c b/drivers/net/ethernet/ti/icssg/icss_iep.c +index bcc056bf45da..4cf2a52e4378 100644 +--- a/drivers/net/ethernet/ti/icssg/icss_iep.c ++++ b/drivers/net/ethernet/ti/icssg/icss_iep.c +@@ -727,6 +727,32 @@ void icss_iep_put(struct icss_iep *iep) + } + EXPORT_SYMBOL_GPL(icss_iep_put); + ++void icss_iep_init_fw(struct icss_iep *iep) ++{ ++ /* start IEP for FW use in raw 64bit mode, no PTP support */ ++ iep->clk_tick_time = iep->def_inc; ++ iep->cycle_time_ns = 0; ++ iep->ops = NULL; ++ iep->clockops_data = NULL; ++ icss_iep_set_default_inc(iep, iep->def_inc); ++ icss_iep_set_compensation_inc(iep, iep->def_inc); ++ icss_iep_set_compensation_count(iep, 0); ++ regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG, iep->refclk_freq / 10); /* 100 ms pulse */ ++ regmap_write(iep->map, ICSS_IEP_SYNC0_PERIOD_REG, 0); ++ if (iep->plat_data->flags & ICSS_IEP_SLOW_COMPEN_REG_SUPPORT) ++ icss_iep_set_slow_compensation_count(iep, 0); ++ ++ icss_iep_enable(iep); ++ icss_iep_settime(iep, 0); ++} ++EXPORT_SYMBOL_GPL(icss_iep_init_fw); ++ ++void icss_iep_exit_fw(struct icss_iep *iep) ++{ ++ icss_iep_disable(iep); ++} ++EXPORT_SYMBOL_GPL(icss_iep_exit_fw); ++ + int icss_iep_init(struct icss_iep *iep, const struct icss_iep_clockops *clkops, + void *clockops_data, u32 cycle_time_ns) + { +diff --git a/drivers/net/ethernet/ti/icssg/icss_iep.h b/drivers/net/ethernet/ti/icssg/icss_iep.h +index 9c7f4d0a0916..803a4b714893 100644 +--- a/drivers/net/ethernet/ti/icssg/icss_iep.h ++++ b/drivers/net/ethernet/ti/icssg/icss_iep.h +@@ -35,5 +35,7 @@ int icss_iep_exit(struct icss_iep *iep); + int icss_iep_get_count_low(struct icss_iep *iep); + int icss_iep_get_count_hi(struct icss_iep *iep); + int icss_iep_get_ptp_clock_idx(struct icss_iep *iep); ++void icss_iep_init_fw(struct icss_iep *iep); ++void icss_iep_exit_fw(struct icss_iep *iep); + + #endif /* __NET_TI_ICSS_IEP_H */ +diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c +index ab648d3efe85..933b84666574 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_config.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_config.c +@@ -210,6 +210,10 @@ void icssg_config_ipg(struct prueth_emac *emac) + case SPEED_100: + icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_100M); + break; ++ case SPEED_10: ++ /* IPG for 10M is same as 100M */ ++ icssg_mii_update_ipg(prueth->mii_rt, slice, MII_RT_TX_IPG_100M); ++ break; + default: + /* Other links speeds not supported */ + netdev_err(emac->ndev, "Unsupported link speed\n"); +@@ -440,6 +444,9 @@ void icssg_config_set_speed(struct prueth_emac *emac) + case SPEED_100: + fw_speed = FW_LINK_SPEED_100M; + break; ++ case SPEED_10: ++ fw_speed = FW_LINK_SPEED_10M; ++ break; + default: + /* Other links speeds not supported */ + netdev_err(emac->ndev, "Unsupported link speed\n"); +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +index 1bcb4e174652..410612f43cbd 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +@@ -1149,7 +1149,6 @@ static int emac_phy_connect(struct prueth_emac *emac) + + /* remove unsupported modes */ + phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); +- phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT); + phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); + phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); + phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_Pause_BIT); +@@ -2090,13 +2089,29 @@ static int prueth_probe(struct platform_device *pdev) + goto free_pool; + } + ++ prueth->iep1 = icss_iep_get_idx(np, 1); ++ if (IS_ERR(prueth->iep1)) { ++ ret = dev_err_probe(dev, PTR_ERR(prueth->iep1), "iep1 get failed\n"); ++ icss_iep_put(prueth->iep0); ++ prueth->iep0 = NULL; ++ prueth->iep1 = NULL; ++ goto free_pool; ++ } ++ ++ if (prueth->pdata.quirk_10m_link_issue) { ++ /* Enable IEP1 for FW in 64bit mode as W/A for 10M FD link detect issue under TX ++ * traffic. ++ */ ++ icss_iep_init_fw(prueth->iep1); ++ } ++ + /* setup netdev interfaces */ + if (eth0_node) { + ret = prueth_netdev_init(prueth, eth0_node); + if (ret) { + dev_err_probe(dev, ret, "netdev init %s failed\n", + eth0_node->name); +- goto netdev_exit; ++ goto exit_iep; + } + prueth->emac[PRUETH_MAC0]->iep = prueth->iep0; + } +@@ -2167,6 +2182,10 @@ static int prueth_probe(struct platform_device *pdev) + prueth_netdev_exit(prueth, eth_node); + } + ++exit_iep: ++ if (prueth->pdata.quirk_10m_link_issue) ++ icss_iep_exit_fw(prueth->iep1); ++ + free_pool: + gen_pool_free(prueth->sram_pool, + (unsigned long)prueth->msmcram.va, msmc_ram_size); +@@ -2212,6 +2231,10 @@ static void prueth_remove(struct platform_device *pdev) + prueth_netdev_exit(prueth, eth_node); + } + ++ if (prueth->pdata.quirk_10m_link_issue) ++ icss_iep_exit_fw(prueth->iep1); ++ ++ icss_iep_put(prueth->iep1); + icss_iep_put(prueth->iep0); + + gen_pool_free(prueth->sram_pool, +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +index a56ab4cdc83c..3fe80a8758d3 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +@@ -208,6 +208,7 @@ struct prueth_pdata { + * @icssg_hwcmdseq: seq counter or HWQ messages + * @emacs_initialized: num of EMACs/ext ports that are up/running + * @iep0: pointer to IEP0 device ++ * @iep1: pointer to IEP1 device + */ + struct prueth { + struct device *dev; +@@ -231,6 +232,7 @@ struct prueth { + u8 icssg_hwcmdseq; + int emacs_initialized; + struct icss_iep *iep0; ++ struct icss_iep *iep1; + }; + + struct emac_tx_ts_response { +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0032-dt-bindings-net-Add-compatible-for-AM64x-in-ICSSG.patch b/recipes-kernel/linux/files/patches-6.1/0032-dt-bindings-net-Add-compatible-for-AM64x-in-ICSSG.patch new file mode 100644 index 000000000..91436601c --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0032-dt-bindings-net-Add-compatible-for-AM64x-in-ICSSG.patch @@ -0,0 +1,30 @@ +From 1fae30e56cc69ca21c1bfc81ca2432f8e20053b5 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Mon, 11 Sep 2023 11:13:07 +0530 +Subject: [PATCH 32/76] dt-bindings: net: Add compatible for AM64x in ICSSG + +Add compatible for AM64x in icssg-prueth dt bindings. AM64x supports +ICSSG similar to AM65x SR2.0. + +Acked-by: Krzysztof Kozlowski +Reviewed-by: Roger Quadros +Signed-off-by: MD Danish Anwar +--- + Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml +index 311c570165f9..836d2d60e87d 100644 +--- a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml ++++ b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml +@@ -19,6 +19,7 @@ allOf: + properties: + compatible: + enum: ++ - ti,am642-icssg-prueth # for AM64x SoC family + - ti,am654-icssg-prueth # for AM65x SoC family + + sram: +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0033-net-ti-icssg-prueth-Add-AM64x-icssg-support.patch b/recipes-kernel/linux/files/patches-6.1/0033-net-ti-icssg-prueth-Add-AM64x-icssg-support.patch new file mode 100644 index 000000000..6710dfe84 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0033-net-ti-icssg-prueth-Add-AM64x-icssg-support.patch @@ -0,0 +1,37 @@ +From e92a87dcf44d0b42210d8f6641e8d9fadda805c5 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Mon, 11 Sep 2023 11:13:08 +0530 +Subject: [PATCH 33/76] net: ti: icssg-prueth: Add AM64x icssg support + +Add AM64x ICSSG support which is similar to am65x SR2.0, but required: +- all ring configured in exposed ring mode +- always fill both original and buffer fields in cppi5 desc + +Reviewed-by: Andrew Lunn +Reviewed-by: Roger Quadros +Signed-off-by: MD Danish Anwar +--- + drivers/net/ethernet/ti/icssg/icssg_prueth.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +index 410612f43cbd..92b13057d4de 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +@@ -2313,8 +2313,13 @@ static const struct prueth_pdata am654_icssg_pdata = { + .quirk_10m_link_issue = 1, + }; + ++static const struct prueth_pdata am64x_icssg_pdata = { ++ .fdqring_mode = K3_RINGACC_RING_MODE_RING, ++}; ++ + static const struct of_device_id prueth_dt_match[] = { + { .compatible = "ti,am654-icssg-prueth", .data = &am654_icssg_pdata }, ++ { .compatible = "ti,am642-icssg-prueth", .data = &am64x_icssg_pdata }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, prueth_dt_match); +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0034-dt-bindings-net-Add-documentation-for-Half-duplex-su.patch b/recipes-kernel/linux/files/patches-6.1/0034-dt-bindings-net-Add-documentation-for-Half-duplex-su.patch new file mode 100644 index 000000000..d75d541c6 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0034-dt-bindings-net-Add-documentation-for-Half-duplex-su.patch @@ -0,0 +1,45 @@ +From 588a6ef014731822cc39d799ad7fa21dff12e496 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Wed, 13 Sep 2023 14:40:10 +0530 +Subject: [PATCH 34/76] dt-bindings: net: Add documentation for Half duplex + support. + +In order to support half-duplex operation at 10M and 100M link speeds, the +PHY collision detection signal (COL) should be routed to ICSSG +GPIO pin (PRGx_PRU0/1_GPI10) so that firmware can detect collision signal +and apply the CSMA/CD algorithm applicable for half duplex operation. A DT +property, "ti,half-duplex-capable" is introduced for this purpose. If +board has PHY COL pin conencted to PRGx_PRU1_GPIO10, this DT property can +be added to eth node of ICSSG, MII port to support half duplex operation at +that port. + +Reviewed-by: Roger Quadros +Signed-off-by: MD Danish Anwar +Reviewed-by: Rob Herring +Acked-by: Conor Dooley +Reviewed-by: Andrew Lunn +--- + Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml +index 836d2d60e87d..229c8f32019f 100644 +--- a/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml ++++ b/Documentation/devicetree/bindings/net/ti,icssg-prueth.yaml +@@ -107,6 +107,13 @@ properties: + phandle to system controller node and register offset + to ICSSG control register for RGMII transmit delay + ++ ti,half-duplex-capable: ++ type: boolean ++ description: ++ Indicates that the PHY output pin COL is routed to ICSSG GPIO pin ++ (PRGx_PRU0/1_GPIO10) as input so that the ICSSG MII port is ++ capable of half duplex operations. ++ + required: + - reg + anyOf: +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0035-net-ti-icssg-prueth-Add-support-for-half-duplex-oper.patch b/recipes-kernel/linux/files/patches-6.1/0035-net-ti-icssg-prueth-Add-support-for-half-duplex-oper.patch new file mode 100644 index 000000000..39862ec88 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0035-net-ti-icssg-prueth-Add-support-for-half-duplex-oper.patch @@ -0,0 +1,130 @@ +From c2082e37e4007631367dcba20f225e49bf287a02 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Wed, 13 Sep 2023 14:40:11 +0530 +Subject: [PATCH 35/76] net: ti: icssg-prueth: Add support for half duplex + operation + +This patch adds support for half duplex operation at 10M and 100M link +speeds for AM654x/AM64x devices. +- Driver configures rand_seed, a random number, in DMEM HD_RAND_SEED_OFFSET +field, which will be used by firmware for Back off time calculation. +- Driver informs FW about half duplex link operation in DMEM +PORT_LINK_SPEED_OFFSET field by setting bit 7 for 10/100M HD. + +Hence, the half duplex operation depends on board design the +"ti,half-duplex-capable" property has to be enabled for ICSS-G ports if HW +is capable to perform half duplex. + +Reviewed-by: Andrew Lunn +Reviewed-by: Roger Quadros +Signed-off-by: MD Danish Anwar +--- + drivers/net/ethernet/ti/icssg/icssg_config.c | 14 ++++++++++++++ + drivers/net/ethernet/ti/icssg/icssg_prueth.c | 17 +++++++++++++++-- + drivers/net/ethernet/ti/icssg/icssg_prueth.h | 2 ++ + 3 files changed, 31 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.c b/drivers/net/ethernet/ti/icssg/icssg_config.c +index 933b84666574..c1da70f247d4 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_config.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_config.c +@@ -433,6 +433,17 @@ int emac_set_port_state(struct prueth_emac *emac, + return ret; + } + ++void icssg_config_half_duplex(struct prueth_emac *emac) ++{ ++ u32 val; ++ ++ if (!emac->half_duplex) ++ return; ++ ++ val = get_random_u32(); ++ writel(val, emac->dram.va + HD_RAND_SEED_OFFSET); ++} ++ + void icssg_config_set_speed(struct prueth_emac *emac) + { + u8 fw_speed; +@@ -453,5 +464,8 @@ void icssg_config_set_speed(struct prueth_emac *emac) + return; + } + ++ if (emac->duplex == DUPLEX_HALF) ++ fw_speed |= FW_LINK_SPEED_HD; ++ + writeb(fw_speed, emac->dram.va + PORT_LINK_SPEED_OFFSET); + } +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +index 92b13057d4de..6635b28bc672 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c +@@ -1029,6 +1029,8 @@ static void emac_adjust_link(struct net_device *ndev) + * values + */ + if (emac->link) { ++ if (emac->duplex == DUPLEX_HALF) ++ icssg_config_half_duplex(emac); + /* Set the RGMII cfg for gig en and full duplex */ + icssg_update_rgmii_cfg(prueth->miig_rt, emac); + +@@ -1147,9 +1149,13 @@ static int emac_phy_connect(struct prueth_emac *emac) + return -ENODEV; + } + ++ if (!emac->half_duplex) { ++ dev_dbg(prueth->dev, "half duplex mode is not supported\n"); ++ phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); ++ phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); ++ } ++ + /* remove unsupported modes */ +- phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT); +- phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT); + phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT); + phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_Pause_BIT); + phy_remove_link_mode(ndev->phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT); +@@ -2113,6 +2119,10 @@ static int prueth_probe(struct platform_device *pdev) + eth0_node->name); + goto exit_iep; + } ++ ++ if (of_find_property(eth0_node, "ti,half-duplex-capable", NULL)) ++ prueth->emac[PRUETH_MAC0]->half_duplex = 1; ++ + prueth->emac[PRUETH_MAC0]->iep = prueth->iep0; + } + +@@ -2124,6 +2134,9 @@ static int prueth_probe(struct platform_device *pdev) + goto netdev_exit; + } + ++ if (of_find_property(eth1_node, "ti,half-duplex-capable", NULL)) ++ prueth->emac[PRUETH_MAC1]->half_duplex = 1; ++ + prueth->emac[PRUETH_MAC1]->iep = prueth->iep0; + } + +diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +index 3fe80a8758d3..8b6d6b497010 100644 +--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h ++++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h +@@ -145,6 +145,7 @@ struct prueth_emac { + struct icss_iep *iep; + unsigned int rx_ts_enabled : 1; + unsigned int tx_ts_enabled : 1; ++ unsigned int half_duplex : 1; + + /* DMA related */ + struct prueth_tx_chn tx_chns[PRUETH_MAX_TX_QUEUES]; +@@ -271,6 +272,7 @@ int icssg_config(struct prueth *prueth, struct prueth_emac *emac, + int emac_set_port_state(struct prueth_emac *emac, + enum icssg_port_state_cmd state); + void icssg_config_set_speed(struct prueth_emac *emac); ++void icssg_config_half_duplex(struct prueth_emac *emac); + + /* Buffer queue helpers */ + int icssg_queue_pop(struct prueth *prueth, u8 queue); +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0101-arm64-dts-ti-iot2050-Add-icssg-prueth-nodes-for-PG1-.patch b/recipes-kernel/linux/files/patches-6.1/0036-arm64-dts-ti-iot2050-Add-icssg-prueth-nodes-for-PG1-.patch similarity index 72% rename from recipes-kernel/linux/files/patches-5.10/0101-arm64-dts-ti-iot2050-Add-icssg-prueth-nodes-for-PG1-.patch rename to recipes-kernel/linux/files/patches-6.1/0036-arm64-dts-ti-iot2050-Add-icssg-prueth-nodes-for-PG1-.patch index 6f6fcf13a..81d5c5461 100644 --- a/recipes-kernel/linux/files/patches-5.10/0101-arm64-dts-ti-iot2050-Add-icssg-prueth-nodes-for-PG1-.patch +++ b/recipes-kernel/linux/files/patches-6.1/0036-arm64-dts-ti-iot2050-Add-icssg-prueth-nodes-for-PG1-.patch @@ -1,53 +1,19 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 29c412349778db6788028c05325edc1ee2fd8a5d Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Sat, 27 Jun 2020 10:53:13 +0200 -Subject: [PATCH] arm64: dts: ti: iot2050: Add icssg-prueth nodes for PG1 and - PG2 devices +Subject: [PATCH 36/76] arm64: dts: ti: iot2050: Add icssg-prueth nodes for PG1 + and PG2 devices Add the required nodes to enable ICSSG SR1.0 and SR2.0 based prueth networking. Signed-off-by: Jan Kiszka --- - .../dts/ti/k3-am65-iot2050-common-pg1.dtsi | 25 ++++ - .../boot/dts/ti/k3-am65-iot2050-common.dtsi | 121 +++++++++++++++++- - 2 files changed, 145 insertions(+), 1 deletion(-) + .../boot/dts/ti/k3-am65-iot2050-common.dtsi | 129 +++++++++++++++++- + 1 file changed, 128 insertions(+), 1 deletion(-) -diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi -index 51f902fa35a7..45c559ad25dc 100644 ---- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi -+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi -@@ -44,3 +44,28 @@ &tx_pru2_0 { - &tx_pru2_1 { - status = "disabled"; - }; -+ -+&icssg0_eth { -+ compatible = "ti,am654-icssg-prueth-sr1"; -+ ti,prus = <&pru0_0>, <&rtu0_0>, <&pru0_1>, <&rtu0_1>; -+ firmware-name = "ti-pruss/am65x-pru0-prueth-fw.elf", -+ "ti-pruss/am65x-rtu0-prueth-fw.elf", -+ "ti-pruss/am65x-pru1-prueth-fw.elf", -+ "ti-pruss/am65x-rtu1-prueth-fw.elf"; -+ ti,pruss-gp-mux-sel = <2>, /* MII mode */ -+ <2>, -+ <2>, /* MII mode */ -+ <2>; -+}; -+ -+&icssg0_iep0 { -+ interrupt-parent = <&icssg0_intc>; -+ interrupts = <7 7 8>; -+ interrupt-names = "iep_cap_cmp"; -+}; -+ -+&icssg0_iep1 { -+ interrupt-parent = <&icssg0_intc>; -+ interrupts = <56 8 9>; -+ interrupt-names = "iep_cap_cmp"; -+}; diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index d8661096f2de..51e82e08550a 100644 +index 180bfb2a9ddf..1be99de1cae2 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi @@ -11,12 +11,15 @@ @@ -66,7 +32,7 @@ index d8661096f2de..51e82e08550a 100644 }; chosen { -@@ -102,6 +105,72 @@ dp_refclk: clock { +@@ -102,6 +105,80 @@ dp_refclk: clock { #clock-cells = <0>; clock-frequency = <19200000>; }; @@ -94,9 +60,9 @@ index d8661096f2de..51e82e08550a 100644 + <2>, + <2>; + -+ mii-g-rt = <&icssg0_mii_g_rt>; -+ mii-rt = <&icssg0_mii_rt>; -+ iep = <&icssg0_iep0>, <&icssg0_iep1>; ++ ti,mii-g-rt = <&icssg0_mii_g_rt>; ++ ti,mii-rt = <&icssg0_mii_rt>; ++ ti,iep = <&icssg0_iep0>, <&icssg0_iep1>; + + interrupt-parent = <&icssg0_intc>; + interrupts = <24 0 2>, <25 1 3>; @@ -120,26 +86,34 @@ index d8661096f2de..51e82e08550a 100644 + "rx0", "rx1", + "rxmgm0", "rxmgm1"; + -+ icssg0_emac0: ethernet-mii0 { -+ phy-handle = <&icssg0_eth0_phy>; -+ phy-mode = "rgmii-rxid"; -+ syscon-rgmii-delay = <&scm_conf 0x4100>; -+ /* Filled in by bootloader */ -+ local-mac-address = [00 00 00 00 00 00]; -+ }; -+ -+ icssg0_emac1: ethernet-mii1 { -+ phy-handle = <&icssg0_eth1_phy>; -+ phy-mode = "rgmii-rxid"; -+ syscon-rgmii-delay = <&scm_conf 0x4104>; -+ /* Filled in by bootloader */ -+ local-mac-address = [00 00 00 00 00 00]; ++ ethernet-ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ icssg0_emac0: port@0 { ++ reg = <0>; ++ phy-handle = <&icssg0_eth0_phy>; ++ phy-mode = "rgmii-id"; ++ ti,syscon-rgmii-delay = <&scm_conf 0x4100>; ++ ti,half-duplex-capable; ++ /* Filled in by bootloader */ ++ local-mac-address = [00 00 00 00 00 00]; ++ }; ++ ++ icssg0_emac1: port@1 { ++ reg = <1>; ++ phy-handle = <&icssg0_eth1_phy>; ++ phy-mode = "rgmii-id"; ++ ti,syscon-rgmii-delay = <&scm_conf 0x4104>; ++ ti,half-duplex-capable; ++ /* Filled in by bootloader */ ++ local-mac-address = [00 00 00 00 00 00]; ++ }; + }; + }; }; &wkup_pmx0 { -@@ -330,6 +399,43 @@ AM65X_IOPAD(0x0074, PIN_INPUT, 5) /* (T27) I2C2_SCL */ +@@ -330,6 +407,43 @@ AM65X_IOPAD(0x0074, PIN_INPUT, 5) /* (T27) I2C2_SCL */ AM65X_IOPAD(0x0070, PIN_INPUT, 5) /* (R25) I2C2_SDA */ >; }; @@ -183,7 +157,7 @@ index d8661096f2de..51e82e08550a 100644 }; &main_pmx1 { -@@ -765,7 +871,20 @@ &mcu_r5fss0_core1 { +@@ -773,7 +887,20 @@ &mcu_r5fss0_core1 { }; &icssg0_mdio { @@ -205,3 +179,6 @@ index d8661096f2de..51e82e08550a 100644 }; &icssg1_mdio { +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0143-irqchip-irq-pruss-intc-Fix-enabling-of-intc-events.patch b/recipes-kernel/linux/files/patches-6.1/0037-irqchip-irq-pruss-intc-Fix-enabling-of-intc-events.patch similarity index 88% rename from recipes-kernel/linux/files/patches-5.10/0143-irqchip-irq-pruss-intc-Fix-enabling-of-intc-events.patch rename to recipes-kernel/linux/files/patches-6.1/0037-irqchip-irq-pruss-intc-Fix-enabling-of-intc-events.patch index e7cf437af..585620ed7 100644 --- a/recipes-kernel/linux/files/patches-5.10/0143-irqchip-irq-pruss-intc-Fix-enabling-of-intc-events.patch +++ b/recipes-kernel/linux/files/patches-6.1/0037-irqchip-irq-pruss-intc-Fix-enabling-of-intc-events.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 0ad7211ec7254eb1b5e85a7d928bfdb1c887cc6b Mon Sep 17 00:00:00 2001 From: Suman Anna -Date: Fri, 28 May 2021 14:00:50 -0500 -Subject: [PATCH] irqchip/irq-pruss-intc: Fix enabling of intc events +Date: Tue, 19 Sep 2023 11:48:58 +0530 +Subject: [PATCH 37/76] irqchip/irq-pruss-intc: Fix enabling of intc events PRUSS INTC events are enabled by default once IRQ events are mapped to channel:host pair. This may cause issues with undesirable IRQs triggering @@ -13,14 +13,17 @@ various PRU cores (Host IRQs 0, 1; 10 through 19 on K3 SoCs), and any other reserved IRQs routed to other processors. The unmasking of IRQs is the responsibility of Linux IRQ core when IRQ is actually requested. +Fixes: 04e2d1e06978 ("irqchip/irq-pruss-intc: Add a PRUSS irqchip driver for PRUSS interrupts") + Signed-off-by: Grygorii Strashko Signed-off-by: Suman Anna +Signed-off-by: MD Danish Anwar --- drivers/irqchip/irq-pruss-intc.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c -index 92fb5780dc10..b3839dbfb738 100644 +index fa8d89b02ec0..58f835c2ffa4 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -101,6 +101,7 @@ struct pruss_intc_match_data { @@ -95,7 +98,7 @@ index 92fb5780dc10..b3839dbfb738 100644 } /* clear all interrupt channel map registers, 4 events per register */ -@@ -524,7 +536,7 @@ static int pruss_intc_probe(struct platform_device *pdev) +@@ -521,7 +533,7 @@ static int pruss_intc_probe(struct platform_device *pdev) struct pruss_intc *intc; struct pruss_host_irq_data *host_data; int i, irq, ret; @@ -104,7 +107,7 @@ index 92fb5780dc10..b3839dbfb738 100644 data = of_device_get_match_data(dev); if (!data) -@@ -545,7 +557,7 @@ static int pruss_intc_probe(struct platform_device *pdev) +@@ -542,7 +554,7 @@ static int pruss_intc_probe(struct platform_device *pdev) return PTR_ERR(intc->base); ret = of_property_read_u8(dev->of_node, "ti,irqs-reserved", @@ -113,7 +116,7 @@ index 92fb5780dc10..b3839dbfb738 100644 /* * The irqs-reserved is used only for some SoC's therefore not having -@@ -564,7 +576,7 @@ static int pruss_intc_probe(struct platform_device *pdev) +@@ -561,7 +573,7 @@ static int pruss_intc_probe(struct platform_device *pdev) return -ENOMEM; for (i = 0; i < MAX_NUM_HOST_IRQS; i++) { @@ -122,3 +125,6 @@ index 92fb5780dc10..b3839dbfb738 100644 continue; irq = platform_get_irq_byname(pdev, irq_names[i]); +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0144-irqchip-irq-pruss-intc-Fix-listed-IRQ-type-in-proc-i.patch b/recipes-kernel/linux/files/patches-6.1/0038-irqchip-irq-pruss-intc-Fix-listed-IRQ-type-in-proc-i.patch similarity index 81% rename from recipes-kernel/linux/files/patches-5.10/0144-irqchip-irq-pruss-intc-Fix-listed-IRQ-type-in-proc-i.patch rename to recipes-kernel/linux/files/patches-6.1/0038-irqchip-irq-pruss-intc-Fix-listed-IRQ-type-in-proc-i.patch index edbc2bbbd..6b52cdb8b 100644 --- a/recipes-kernel/linux/files/patches-5.10/0144-irqchip-irq-pruss-intc-Fix-listed-IRQ-type-in-proc-i.patch +++ b/recipes-kernel/linux/files/patches-6.1/0038-irqchip-irq-pruss-intc-Fix-listed-IRQ-type-in-proc-i.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From a01b47f9a97ccdb228e2f793171457423f0c14e0 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko -Date: Fri, 28 May 2021 14:10:24 -0500 -Subject: [PATCH] irqchip/irq-pruss-intc: Fix listed IRQ type in +Date: Tue, 19 Sep 2023 11:48:59 +0530 +Subject: [PATCH 38/76] irqchip/irq-pruss-intc: Fix listed IRQ type in /proc/interrupts The PRUSS INTC driver doesn't have .irq_set_type() callback implemented and @@ -15,14 +15,17 @@ Example: Fix this by adding a simple .irq_set_type() implementation which checks the requested IRQ triggering type. +Fixes: 04e2d1e06978 ("irqchip/irq-pruss-intc: Add a PRUSS irqchip driver for PRUSS interrupts") + Signed-off-by: Grygorii Strashko Signed-off-by: Suman Anna +Signed-off-by: MD Danish Anwar --- drivers/irqchip/irq-pruss-intc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c -index b3839dbfb738..d2bb1b086c99 100644 +index 58f835c2ffa4..fbf570c374da 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -373,6 +373,14 @@ static int pruss_intc_irq_set_irqchip_state(struct irq_data *data, @@ -48,3 +51,6 @@ index b3839dbfb738..d2bb1b086c99 100644 }; static int pruss_intc_validate_mapping(struct pruss_intc *intc, int event, +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0145-HACK-irqchip-irq-pruss-intc-Fix-processing-of-IEP-in.patch b/recipes-kernel/linux/files/patches-6.1/0039-irqchip-irq-pruss-intc-Fix-processing-of-IEP-interru.patch similarity index 76% rename from recipes-kernel/linux/files/patches-5.10/0145-HACK-irqchip-irq-pruss-intc-Fix-processing-of-IEP-in.patch rename to recipes-kernel/linux/files/patches-6.1/0039-irqchip-irq-pruss-intc-Fix-processing-of-IEP-interru.patch index 01b1dba2d..1d79ad5bd 100644 --- a/recipes-kernel/linux/files/patches-5.10/0145-HACK-irqchip-irq-pruss-intc-Fix-processing-of-IEP-in.patch +++ b/recipes-kernel/linux/files/patches-6.1/0039-irqchip-irq-pruss-intc-Fix-processing-of-IEP-interru.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From d7be122925d816349fe288c09ff80cda6c003c77 Mon Sep 17 00:00:00 2001 From: Suman Anna -Date: Fri, 28 May 2021 15:51:37 -0500 -Subject: [PATCH] HACK: irqchip/irq-pruss-intc: Fix processing of IEP +Date: Tue, 19 Sep 2023 11:49:00 +0530 +Subject: [PATCH 39/76] irqchip/irq-pruss-intc: Fix processing of IEP interrupts It was discovered that IEP capture/compare IRQs (event #7 on all SoCs @@ -24,22 +24,19 @@ An example of the problem is: The solution is to actually ack these IRQs from pruss_intc_irq_unmask() after the IRQ source is cleared in HW. -NOTE: -1. The current solution provides a decent generic framework to scale - for any additional events that might be discovered in the future. -2. The solution can be reworked using soc_device_attributes() if a - per-SoC solution is desired. The current solution applies to all - SoCs accounting for single IEP on non-K3 SoCs and for 2 IEPs on - all K3 SoCs. +No public errata available for this yet. + +Fixes: 04e2d1e06978 ("irqchip/irq-pruss-intc: Add a PRUSS irqchip driver for PRUSS interrupts") Signed-off-by: Grygorii Strashko Signed-off-by: Suman Anna +Signed-off-by: MD Danish Anwar --- drivers/irqchip/irq-pruss-intc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c -index d2bb1b086c99..74f7d51236f7 100644 +index fbf570c374da..61c5604921d5 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -70,6 +70,8 @@ @@ -70,7 +67,7 @@ index d2bb1b086c99..74f7d51236f7 100644 unsigned int hwirq = data->hwirq; + if (hwirq < MAX_PRU_INT_EVENTS && -+ intc->soc_config->quirky_events & BIT(hwirq)) ++ intc->soc_config->quirky_events & BIT_ULL(hwirq)) + return; + pruss_intc_write_reg(intc, PRU_INTC_SICR, hwirq); @@ -81,22 +78,25 @@ index d2bb1b086c99..74f7d51236f7 100644 unsigned int hwirq = data->hwirq; + if (hwirq < MAX_PRU_INT_EVENTS && -+ intc->soc_config->quirky_events & BIT(hwirq)) ++ intc->soc_config->quirky_events & BIT_ULL(hwirq)) + pruss_intc_write_reg(intc, PRU_INTC_SICR, hwirq); pruss_intc_write_reg(intc, PRU_INTC_EISR, hwirq); } -@@ -647,11 +659,13 @@ static int pruss_intc_remove(struct platform_device *pdev) +@@ -644,11 +656,13 @@ static int pruss_intc_remove(struct platform_device *pdev) static const struct pruss_intc_match_data pruss_intc_data = { .num_system_events = 64, .num_host_events = 10, -+ .quirky_events = BIT(7), /* IEP capture/compare event */ ++ .quirky_events = BIT_ULL(7), /* IEP capture/compare event */ }; static const struct pruss_intc_match_data icssg_intc_data = { .num_system_events = 160, .num_host_events = 20, -+ .quirky_events = BIT(7) | BIT(56), /* IEP{0,1} capture/compare events */ ++ .quirky_events = BIT_ULL(7) | BIT_ULL(56), /* IEP{0,1} capture/compare events */ }; static const struct of_device_id pruss_intc_of_match[] = { +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0153-dmaengine-ti-k3-udma-glue-do-not-create-glue-dma-dev.patch b/recipes-kernel/linux/files/patches-6.1/0040-dmaengine-ti-k3-udma-glue-do-not-create-glue-dma-dev.patch similarity index 82% rename from recipes-kernel/linux/files/patches-5.10/0153-dmaengine-ti-k3-udma-glue-do-not-create-glue-dma-dev.patch rename to recipes-kernel/linux/files/patches-6.1/0040-dmaengine-ti-k3-udma-glue-do-not-create-glue-dma-dev.patch index c1d0c8e6e..6bc90f9d7 100644 --- a/recipes-kernel/linux/files/patches-5.10/0153-dmaengine-ti-k3-udma-glue-do-not-create-glue-dma-dev.patch +++ b/recipes-kernel/linux/files/patches-6.1/0040-dmaengine-ti-k3-udma-glue-do-not-create-glue-dma-dev.patch @@ -1,8 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From c050e79f9b8164776eb5747d38830af3279350b8 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko -Date: Mon, 20 Sep 2021 17:51:17 +0300 -Subject: [PATCH] dmaengine: ti: k3-udma-glue: do not create glue dma devices - for udma channels +Date: Wed, 5 Apr 2023 10:41:12 +0530 +Subject: [PATCH 40/76] dmaengine: ti: k3-udma-glue: do not create glue dma + devices for udma channels In case K3 DMA glue layer is using UDMA channels (AM65/J721E/J7200) it doesn't need to create own DMA devices per RX/TX channels as they are never @@ -14,16 +14,16 @@ channels only in case of PKTDMA (AM64) where coherency configurable per DMA channel. Signed-off-by: Grygorii Strashko -Signed-off-by: Vignesh Raghavendra +Signed-off-by: Siddharth Vadapalli --- - drivers/dma/ti/k3-udma-glue.c | 67 ++++++++++++++++++----------------- - 1 file changed, 34 insertions(+), 33 deletions(-) + drivers/dma/ti/k3-udma-glue.c | 73 ++++++++++++++++++----------------- + 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c -index 4fdd9f06b723..2a683fee70ed 100644 +index 4f1aeb81e9c7..3ad57ad91c91 100644 --- a/drivers/dma/ti/k3-udma-glue.c +++ b/drivers/dma/ti/k3-udma-glue.c -@@ -292,18 +292,18 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev, +@@ -292,19 +292,19 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev, } tx_chn->udma_tchan_id = xudma_tchan_get_id(tx_chn->udma_tchanx); @@ -34,6 +34,7 @@ index 4fdd9f06b723..2a683fee70ed 100644 - ret = device_register(&tx_chn->common.chan_dev); - if (ret) { - dev_err(dev, "Channel Device registration failed %d\n", ret); +- put_device(&tx_chn->common.chan_dev); - tx_chn->common.chan_dev.parent = NULL; - goto err; - } @@ -46,6 +47,7 @@ index 4fdd9f06b723..2a683fee70ed 100644 + ret = device_register(&tx_chn->common.chan_dev); + if (ret) { + dev_err(dev, "Channel Device registration failed %d\n", ret); ++ put_device(&tx_chn->common.chan_dev); + tx_chn->common.chan_dev.parent = NULL; + goto err; + } @@ -53,7 +55,7 @@ index 4fdd9f06b723..2a683fee70ed 100644 /* prepare the channel device as coherent */ tx_chn->common.chan_dev.dma_coherent = true; dma_coerce_mask_and_coherent(&tx_chn->common.chan_dev, -@@ -910,18 +910,18 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, const char *name, +@@ -911,19 +911,19 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, const char *name, } rx_chn->udma_rchan_id = xudma_rchan_get_id(rx_chn->udma_rchanx); @@ -64,6 +66,7 @@ index 4fdd9f06b723..2a683fee70ed 100644 - ret = device_register(&rx_chn->common.chan_dev); - if (ret) { - dev_err(dev, "Channel Device registration failed %d\n", ret); +- put_device(&rx_chn->common.chan_dev); - rx_chn->common.chan_dev.parent = NULL; - goto err; - } @@ -76,6 +79,7 @@ index 4fdd9f06b723..2a683fee70ed 100644 + ret = device_register(&rx_chn->common.chan_dev); + if (ret) { + dev_err(dev, "Channel Device registration failed %d\n", ret); ++ put_device(&rx_chn->common.chan_dev); + rx_chn->common.chan_dev.parent = NULL; + goto err; + } @@ -83,7 +87,7 @@ index 4fdd9f06b723..2a683fee70ed 100644 /* prepare the channel device as coherent */ rx_chn->common.chan_dev.dma_coherent = true; dma_coerce_mask_and_coherent(&rx_chn->common.chan_dev, -@@ -1041,18 +1041,19 @@ k3_udma_glue_request_remote_rx_chn(struct device *dev, const char *name, +@@ -1043,19 +1043,20 @@ k3_udma_glue_request_remote_rx_chn(struct device *dev, const char *name, goto err; } @@ -94,6 +98,7 @@ index 4fdd9f06b723..2a683fee70ed 100644 - ret = device_register(&rx_chn->common.chan_dev); - if (ret) { - dev_err(dev, "Channel Device registration failed %d\n", ret); +- put_device(&rx_chn->common.chan_dev); - rx_chn->common.chan_dev.parent = NULL; - goto err; - } @@ -107,6 +112,7 @@ index 4fdd9f06b723..2a683fee70ed 100644 + ret = device_register(&rx_chn->common.chan_dev); + if (ret) { + dev_err(dev, "Channel Device registration failed %d\n", ret); ++ put_device(&rx_chn->common.chan_dev); + rx_chn->common.chan_dev.parent = NULL; + goto err; + } @@ -114,3 +120,6 @@ index 4fdd9f06b723..2a683fee70ed 100644 /* prepare the channel device as coherent */ rx_chn->common.chan_dev.dma_coherent = true; dma_coerce_mask_and_coherent(&rx_chn->common.chan_dev, +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0193-dmaengine-k3-udma-Add-system-suspend-resume-support.patch b/recipes-kernel/linux/files/patches-6.1/0041-dmaengine-ti-k3-udma-Add-system-suspend-resume-suppo.patch similarity index 59% rename from recipes-kernel/linux/files/patches-5.10/0193-dmaengine-k3-udma-Add-system-suspend-resume-support.patch rename to recipes-kernel/linux/files/patches-6.1/0041-dmaengine-ti-k3-udma-Add-system-suspend-resume-suppo.patch index 07267a716..cd51582a4 100644 --- a/recipes-kernel/linux/files/patches-5.10/0193-dmaengine-k3-udma-Add-system-suspend-resume-support.patch +++ b/recipes-kernel/linux/files/patches-6.1/0041-dmaengine-ti-k3-udma-Add-system-suspend-resume-suppo.patch @@ -1,7 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 1589b27664c64da3e2ff7b4c2e7c5c3e45007ade Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra -Date: Mon, 10 Oct 2022 23:07:02 +0300 -Subject: [PATCH] dmaengine: k3-udma: Add system suspend/resume support +Date: Wed, 29 Mar 2023 21:23:49 +0530 +Subject: [PATCH 41/76] dmaengine: ti: k3-udma: Add system suspend/resume + support The K3 platforms configure the DMA resources with the help of the TI's System Firmware's Device Manager(DM) @@ -10,7 +11,7 @@ TISCI messages includes: INTA, RINGACC, UDMAP, and PSI-L. This configuration however, does not persist in the DM after leaving from Suspend-to-RAM state. We have to restore the DMA channel configuration over TISCI for all configured -channels when entering suspend. +channels when returning from suspend. The TISCI resource management calls for each DMA type (UDMA, PKTDMA, BCDMA) happen in device_free_chan_resources() and @@ -19,32 +20,27 @@ the current udma_chan_config for channels that still have attached clients and call device_free_chan_resources(). In pm_resume() restore the udma_channel_config from backup and call device_alloc_chan_resources() for those channels. -Drivers like CPSW do their own DMA resource management, -so use the late system suspend/resume hooks. + +Drivers like CPSW that use k3-udma-glue already do their own +DMA resource management so use the late system suspend/resume hooks. [1] https://software-dl.ti.com/tisci/esd/latest/2_tisci_msgs/index.html#resource-management-rm -Signed-off-by: Vignesh Raghavendra -[g-vlaev@ti.com: Add udma_chan_config backup] [g-vlaev@ti.com: Supend only channels with clients] + +Signed-off-by: Vignesh Raghavendra +[g-vlaev@ti.com: Add patch description and config backup] Signed-off-by: Georgi Vlaev +Acked-by: Peter Ujfalusi --- - drivers/dma/ti/k3-udma.c | 57 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 57 insertions(+) + drivers/dma/ti/k3-udma.c | 54 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index 6b02433c7f1d..3a0582f99208 100644 +index b86b809eb1f7..b0286df3383d 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c -@@ -193,6 +193,7 @@ struct udma_dev { - int rchan_cnt; - int rflow_cnt; - int tflow_cnt; -+ int ch_count; - unsigned long *bchan_map; - unsigned long *tchan_map; - unsigned long *rchan_map; -@@ -303,6 +304,8 @@ struct udma_chan { +@@ -303,6 +303,8 @@ struct udma_chan { /* Channel configuration parameters */ struct udma_chan_config config; @@ -53,30 +49,22 @@ index 6b02433c7f1d..3a0582f99208 100644 /* dmapool for packet mode descriptors */ bool use_dma_pool; -@@ -4948,6 +4951,7 @@ static int setup_resources(struct udma_dev *ud) - if (!ch_count) - return -ENODEV; - -+ ud->ch_count = ch_count; - ud->channels = devm_kcalloc(dev, ch_count, sizeof(*ud->channels), - GFP_KERNEL); - if (!ud->channels) -@@ -5444,11 +5448,62 @@ static int udma_probe(struct platform_device *pdev) +@@ -5504,11 +5506,63 @@ static int udma_probe(struct platform_device *pdev) return ret; } +static int udma_pm_suspend(struct device *dev) +{ + struct udma_dev *ud = dev_get_drvdata(dev); ++ struct dma_device *dma_dev = &ud->ddev; + struct dma_chan *chan; -+ int i; ++ struct udma_chan *uc; + -+ for (i = 0; i < ud->ch_count; i++) { -+ chan = &ud->channels[i].vc.chan; ++ list_for_each_entry(chan, &dma_dev->channels, device_node) { + if (chan->client_count) { ++ uc = to_udma_chan(chan); + /* backup the channel configuration */ -+ memcpy(&ud->channels[i].backup_config, -+ &ud->channels[i].config, ++ memcpy(&uc->backup_config, &uc->config, + sizeof(struct udma_chan_config)); + dev_dbg(dev, "Suspending channel %s\n", + dma_chan_name(chan)); @@ -90,15 +78,16 @@ index 6b02433c7f1d..3a0582f99208 100644 +static int udma_pm_resume(struct device *dev) +{ + struct udma_dev *ud = dev_get_drvdata(dev); ++ struct dma_device *dma_dev = &ud->ddev; + struct dma_chan *chan; -+ int ret, i; ++ struct udma_chan *uc; ++ int ret; + -+ for (i = 0; i < ud->ch_count; i++) { -+ chan = &ud->channels[i].vc.chan; ++ list_for_each_entry(chan, &dma_dev->channels, device_node) { + if (chan->client_count) { ++ uc = to_udma_chan(chan); + /* restore the channel configuration */ -+ memcpy(&ud->channels[i].config, -+ &ud->channels[i].backup_config, ++ memcpy(&uc->config, &uc->backup_config, + sizeof(struct udma_chan_config)); + dev_dbg(dev, "Resuming channel %s\n", + dma_chan_name(chan)); @@ -124,19 +113,6 @@ index 6b02433c7f1d..3a0582f99208 100644 }, .probe = udma_probe, }; -@@ -5459,6 +5514,7 @@ static struct platform_driver bcdma_driver = { - .name = "ti-bcdma", - .of_match_table = bcdma_of_match, - .suppress_bind_attrs = true, -+ .pm = &udma_pm_ops, - }, - .probe = udma_probe, - }; -@@ -5469,6 +5525,7 @@ static struct platform_driver pktdma_driver = { - .name = "ti-pktdma", - .of_match_table = pktdma_of_match, - .suppress_bind_attrs = true, -+ .pm = &udma_pm_ops, - }, - .probe = udma_probe, - }; +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0042-of-irq-export-of_msi_get_domain.patch b/recipes-kernel/linux/files/patches-6.1/0042-of-irq-export-of_msi_get_domain.patch new file mode 100644 index 000000000..35221dc6e --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0042-of-irq-export-of_msi_get_domain.patch @@ -0,0 +1,31 @@ +From a82cf71beea94bcb654a58169998d5bd9f8e93e5 Mon Sep 17 00:00:00 2001 +From: Kevin Hilman +Date: Thu, 29 Sep 2022 16:48:18 -0700 +Subject: [PATCH 42/76] of/irq: export of_msi_get_domain + +Export of_mis_get_domain to enable it for users from outside. + +Signed-off-by: Matthias Brugger +Acked-by: Rob Herring +Signed-off-by: Peter Ujfalusi +Link: https://lore.kernel.org/r/20200122104723.16955-1-peter.ujfalusi@ti.com +Signed-off-by: Kevin Hilman +--- + drivers/of/irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/of/irq.c b/drivers/of/irq.c +index 2bac44f09554..e9bf5236ed89 100644 +--- a/drivers/of/irq.c ++++ b/drivers/of/irq.c +@@ -730,6 +730,7 @@ struct irq_domain *of_msi_get_domain(struct device *dev, + + return NULL; + } ++EXPORT_SYMBOL_GPL(of_msi_get_domain); + + /** + * of_msi_configure - Set the msi_domain field of a device +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0043-dmaengine-ti-convert-k3-udma-to-module.patch b/recipes-kernel/linux/files/patches-6.1/0043-dmaengine-ti-convert-k3-udma-to-module.patch new file mode 100644 index 000000000..bdedb0366 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0043-dmaengine-ti-convert-k3-udma-to-module.patch @@ -0,0 +1,148 @@ +From 7e2d39412fdfa000a1026a57a06b39e0563c1e9c Mon Sep 17 00:00:00 2001 +From: Kevin Hilman +Date: Thu, 29 Sep 2022 16:48:19 -0700 +Subject: [PATCH 43/76] dmaengine: ti: convert k3-udma to module + +Currently k3-udma driver is built as separate platform drivers with a +shared probe and identical code path, just differnet platform data. + +To enable to build as module, convert the separate platform driver +into a single module_platform_driver with the data selection done via +compatible string and of_match. The separate of_match tables are also +combined into a single table to avoid the multiple calls to +of_match_node() + +Since all modern TI platforms using this are DT enabled, the removal +of separate platform_drivers should have no functional change. + +Acked-by: Peter Ujfalusi +Signed-off-by: Kevin Hilman +--- + drivers/dma/ti/Kconfig | 4 ++-- + drivers/dma/ti/k3-udma-glue.c | 5 ++++- + drivers/dma/ti/k3-udma.c | 40 +++++------------------------------ + 3 files changed, 11 insertions(+), 38 deletions(-) + +diff --git a/drivers/dma/ti/Kconfig b/drivers/dma/ti/Kconfig +index 79618fac119a..f196be3b222f 100644 +--- a/drivers/dma/ti/Kconfig ++++ b/drivers/dma/ti/Kconfig +@@ -35,7 +35,7 @@ config DMA_OMAP + DMA engine is found on OMAP and DRA7xx parts. + + config TI_K3_UDMA +- bool "Texas Instruments UDMA support" ++ tristate "Texas Instruments UDMA support" + depends on ARCH_K3 + depends on TI_SCI_PROTOCOL + depends on TI_SCI_INTA_IRQCHIP +@@ -48,7 +48,7 @@ config TI_K3_UDMA + DMA engine is used in AM65x and j721e. + + config TI_K3_UDMA_GLUE_LAYER +- bool "Texas Instruments UDMA Glue layer for non DMAengine users" ++ tristate "Texas Instruments UDMA Glue layer for non DMAengine users" + depends on ARCH_K3 + depends on TI_K3_UDMA + help +diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c +index 3ad57ad91c91..ab8ac52e38e4 100644 +--- a/drivers/dma/ti/k3-udma-glue.c ++++ b/drivers/dma/ti/k3-udma-glue.c +@@ -6,6 +6,7 @@ + * + */ + ++#include + #include + #include + #include +@@ -1437,4 +1438,6 @@ static int __init k3_udma_glue_class_init(void) + { + return class_register(&k3_udma_glue_devclass); + } +-arch_initcall(k3_udma_glue_class_init); ++ ++module_init(k3_udma_glue_class_init); ++MODULE_LICENSE("GPL v2"); +diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c +index b0286df3383d..84337526e251 100644 +--- a/drivers/dma/ti/k3-udma.c ++++ b/drivers/dma/ti/k3-udma.c +@@ -5,6 +5,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -4338,18 +4339,10 @@ static const struct of_device_id udma_of_match[] = { + .compatible = "ti,j721e-navss-mcu-udmap", + .data = &j721e_mcu_data, + }, +- { /* Sentinel */ }, +-}; +- +-static const struct of_device_id bcdma_of_match[] = { + { + .compatible = "ti,am64-dmss-bcdma", + .data = &am64_bcdma_data, + }, +- { /* Sentinel */ }, +-}; +- +-static const struct of_device_id pktdma_of_match[] = { + { + .compatible = "ti,am64-dmss-pktdma", + .data = &am64_pktdma_data, +@@ -5274,14 +5267,9 @@ static int udma_probe(struct platform_device *pdev) + return -ENOMEM; + + match = of_match_node(udma_of_match, dev->of_node); +- if (!match) +- match = of_match_node(bcdma_of_match, dev->of_node); + if (!match) { +- match = of_match_node(pktdma_of_match, dev->of_node); +- if (!match) { +- dev_err(dev, "No compatible match found\n"); +- return -ENODEV; +- } ++ dev_err(dev, "No compatible match found\n"); ++ return -ENODEV; + } + ud->match_data = match->data; + +@@ -5566,27 +5554,9 @@ static struct platform_driver udma_driver = { + }, + .probe = udma_probe, + }; +-builtin_platform_driver(udma_driver); + +-static struct platform_driver bcdma_driver = { +- .driver = { +- .name = "ti-bcdma", +- .of_match_table = bcdma_of_match, +- .suppress_bind_attrs = true, +- }, +- .probe = udma_probe, +-}; +-builtin_platform_driver(bcdma_driver); +- +-static struct platform_driver pktdma_driver = { +- .driver = { +- .name = "ti-pktdma", +- .of_match_table = pktdma_of_match, +- .suppress_bind_attrs = true, +- }, +- .probe = udma_probe, +-}; +-builtin_platform_driver(pktdma_driver); ++module_platform_driver(udma_driver); ++MODULE_LICENSE("GPL v2"); + + /* Private interfaces to UDMA */ + #include "k3-udma-private.c" +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0044-dmaengine-ti-convert-PSIL-to-be-buildable-as-module.patch b/recipes-kernel/linux/files/patches-6.1/0044-dmaengine-ti-convert-PSIL-to-be-buildable-as-module.patch new file mode 100644 index 000000000..91a99ac89 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0044-dmaengine-ti-convert-PSIL-to-be-buildable-as-module.patch @@ -0,0 +1,74 @@ +From 0267d2a9baffe479e9b5b3d26130f2ceff3f60a8 Mon Sep 17 00:00:00 2001 +From: Kevin Hilman +Date: Thu, 29 Sep 2022 16:48:20 -0700 +Subject: [PATCH 44/76] dmaengine: ti: convert PSIL to be buildable as module + +Combine all the SoC specific files into a single lib that can be +built-in or built as a module. + +Acked-by: Peter Ujfalusi +Signed-off-by: Kevin Hilman +--- + drivers/dma/ti/Kconfig | 3 ++- + drivers/dma/ti/Makefile | 15 ++++++++------- + drivers/dma/ti/k3-psil.c | 2 ++ + 3 files changed, 12 insertions(+), 8 deletions(-) + +diff --git a/drivers/dma/ti/Kconfig b/drivers/dma/ti/Kconfig +index f196be3b222f..2adc2cca10e9 100644 +--- a/drivers/dma/ti/Kconfig ++++ b/drivers/dma/ti/Kconfig +@@ -56,7 +56,8 @@ config TI_K3_UDMA_GLUE_LAYER + If unsure, say N. + + config TI_K3_PSIL +- bool ++ tristate ++ default TI_K3_UDMA + + config TI_DMA_CROSSBAR + bool +diff --git a/drivers/dma/ti/Makefile b/drivers/dma/ti/Makefile +index d3a303f0d7c6..b53d05b11ca5 100644 +--- a/drivers/dma/ti/Makefile ++++ b/drivers/dma/ti/Makefile +@@ -4,11 +4,12 @@ obj-$(CONFIG_TI_EDMA) += edma.o + obj-$(CONFIG_DMA_OMAP) += omap-dma.o + obj-$(CONFIG_TI_K3_UDMA) += k3-udma.o + obj-$(CONFIG_TI_K3_UDMA_GLUE_LAYER) += k3-udma-glue.o +-obj-$(CONFIG_TI_K3_PSIL) += k3-psil.o \ +- k3-psil-am654.o \ +- k3-psil-j721e.o \ +- k3-psil-j7200.o \ +- k3-psil-am64.o \ +- k3-psil-j721s2.o \ +- k3-psil-am62.o ++k3-psil-lib-objs := k3-psil.o \ ++ k3-psil-am654.o \ ++ k3-psil-j721e.o \ ++ k3-psil-j7200.o \ ++ k3-psil-am64.o \ ++ k3-psil-j721s2.o \ ++ k3-psil-am62.o ++obj-$(CONFIG_TI_K3_PSIL) += k3-psil-lib.o + obj-$(CONFIG_TI_DMA_CROSSBAR) += dma-crossbar.o +diff --git a/drivers/dma/ti/k3-psil.c b/drivers/dma/ti/k3-psil.c +index 761a384093d2..8b6533a1eeeb 100644 +--- a/drivers/dma/ti/k3-psil.c ++++ b/drivers/dma/ti/k3-psil.c +@@ -5,6 +5,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -101,3 +102,4 @@ int psil_set_new_ep_config(struct device *dev, const char *name, + return 0; + } + EXPORT_SYMBOL_GPL(psil_set_new_ep_config); ++MODULE_LICENSE("GPL v2"); +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0045-dt-bindings-dma-ti-k3-bcdma-Add-bindings-for-BCDMA-C.patch b/recipes-kernel/linux/files/patches-6.1/0045-dt-bindings-dma-ti-k3-bcdma-Add-bindings-for-BCDMA-C.patch new file mode 100644 index 000000000..8ff5ad66c --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0045-dt-bindings-dma-ti-k3-bcdma-Add-bindings-for-BCDMA-C.patch @@ -0,0 +1,129 @@ +From d9c280f675bb0c86d8783226788863cc8e7378a3 Mon Sep 17 00:00:00 2001 +From: Vignesh Raghavendra +Date: Tue, 13 Dec 2022 22:13:00 +0530 +Subject: [PATCH 45/76] dt-bindings: dma: ti: k3-bcdma: Add bindings for BCDMA + CSI RX + +AM62A SoC has a dedicated BCDMA that serves Camera Serial Interface +(CSI) IP. Add new compatible for the same. Unlike system +BCDMA, this instance only has RX DMA channels and lack TX or block copy +channel. Thus make those properties optional. Additionally CSI RX has +independent power domain, add the binding for the same. + +Signed-off-by: Vignesh Raghavendra +Reviewed-by: Krzysztof Kozlowski +--- + .../devicetree/bindings/dma/ti/k3-bcdma.yaml | 77 ++++++++++++++----- + 1 file changed, 59 insertions(+), 18 deletions(-) + +diff --git a/Documentation/devicetree/bindings/dma/ti/k3-bcdma.yaml b/Documentation/devicetree/bindings/dma/ti/k3-bcdma.yaml +index 08627d91e607..2bc48dfd3396 100644 +--- a/Documentation/devicetree/bindings/dma/ti/k3-bcdma.yaml ++++ b/Documentation/devicetree/bindings/dma/ti/k3-bcdma.yaml +@@ -28,13 +28,19 @@ description: | + PDMAs can be configured via BCDMA split channel's peer registers to match with + the configuration of the legacy peripheral. + +-allOf: +- - $ref: /schemas/dma/dma-controller.yaml# +- - $ref: /schemas/arm/keystone/ti,k3-sci-common.yaml# +- + properties: + compatible: +- const: ti,am64-dmss-bcdma ++ enum: ++ - ti,am62a-dmss-bcdma-csirx ++ - ti,am64-dmss-bcdma ++ ++ reg: ++ minItems: 3 ++ maxItems: 5 ++ ++ reg-names: ++ minItems: 3 ++ maxItems: 5 + + "#dma-cells": + const: 3 +@@ -65,19 +71,13 @@ properties: + + cell 3: ASEL value for the channel + +- reg: +- maxItems: 5 +- +- reg-names: +- items: +- - const: gcfg +- - const: bchanrt +- - const: rchanrt +- - const: tchanrt +- - const: ringrt +- + msi-parent: true + ++ power-domains: ++ description: ++ Power domain if available ++ maxItems: 1 ++ + ti,asel: + $ref: /schemas/types.yaml#/definitions/uint32 + description: ASEL value for non slave channels +@@ -123,10 +123,51 @@ required: + - msi-parent + - ti,sci + - ti,sci-dev-id +- - ti,sci-rm-range-bchan +- - ti,sci-rm-range-tchan + - ti,sci-rm-range-rchan + ++allOf: ++ - $ref: /schemas/dma/dma-controller.yaml# ++ - $ref: /schemas/arm/keystone/ti,k3-sci-common.yaml# ++ ++ - if: ++ properties: ++ compatible: ++ contains: ++ const: ti,am62a-dmss-bcdma-csirx ++ then: ++ properties: ++ ti,sci-rm-range-bchan: false ++ ti,sci-rm-range-tchan: false ++ ++ reg: ++ maxItems: 3 ++ ++ reg-names: ++ items: ++ - const: gcfg ++ - const: rchanrt ++ - const: ringrt ++ ++ required: ++ - power-domains ++ ++ else: ++ properties: ++ reg: ++ minItems: 5 ++ ++ reg-names: ++ items: ++ - const: gcfg ++ - const: bchanrt ++ - const: rchanrt ++ - const: tchanrt ++ - const: ringrt ++ ++ required: ++ - ti,sci-rm-range-bchan ++ - ti,sci-rm-range-tchan ++ + unevaluatedProperties: false + + examples: +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0197-dmaengine-ti-k3-udma-Fix-BCDMA-for-case-w-o-BCHAN.patch b/recipes-kernel/linux/files/patches-6.1/0046-dmaengine-ti-k3-udma-Fix-BCDMA-for-case-w-o-BCHAN.patch similarity index 55% rename from recipes-kernel/linux/files/patches-5.10/0197-dmaengine-ti-k3-udma-Fix-BCDMA-for-case-w-o-BCHAN.patch rename to recipes-kernel/linux/files/patches-6.1/0046-dmaengine-ti-k3-udma-Fix-BCDMA-for-case-w-o-BCHAN.patch index 989ab50da..9a481a1e9 100644 --- a/recipes-kernel/linux/files/patches-5.10/0197-dmaengine-ti-k3-udma-Fix-BCDMA-for-case-w-o-BCHAN.patch +++ b/recipes-kernel/linux/files/patches-6.1/0046-dmaengine-ti-k3-udma-Fix-BCDMA-for-case-w-o-BCHAN.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From e10889ef0d5e96671155e4750465f322bb80a184 Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra -Date: Tue, 13 Dec 2022 22:49:03 +0530 -Subject: [PATCH] dmaengine: ti: k3-udma: Fix BCDMA for case w/o BCHAN +Date: Tue, 13 Dec 2022 22:13:01 +0530 +Subject: [PATCH 46/76] dmaengine: ti: k3-udma: Fix BCDMA for case w/o BCHAN Reusing loop iterator fails if BCHAN is not present as iterator is uninitialized @@ -12,12 +12,12 @@ Signed-off-by: Vignesh Raghavendra 1 file changed, 3 insertions(+) diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c -index 3a0582f99208..7dcaf7a1eedb 100644 +index 84337526e251..a9d19689eba4 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c -@@ -4757,7 +4757,10 @@ static int bcdma_setup_resources(struct udma_dev *ud) - oes->bcdma_bchan_ring; - irq_res.desc[i].num = rm_res->desc[i].num; +@@ -4777,7 +4777,10 @@ static int bcdma_setup_resources(struct udma_dev *ud) + irq_res.desc[i].num = rm_res->desc[i].num; + } } + } else { + i = 0; @@ -25,4 +25,7 @@ index 3a0582f99208..7dcaf7a1eedb 100644 + if (ud->tchan_cnt) { rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN]; - for (j = 0; j < rm_res->sets; j++, i += 2) { + if (IS_ERR(rm_res)) { +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0047-dmaengine-ti-k3-psil-am62a-Add-AM62Ax-PSIL-and-PDMA-.patch b/recipes-kernel/linux/files/patches-6.1/0047-dmaengine-ti-k3-psil-am62a-Add-AM62Ax-PSIL-and-PDMA-.patch new file mode 100644 index 000000000..6d5978f28 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0047-dmaengine-ti-k3-psil-am62a-Add-AM62Ax-PSIL-and-PDMA-.patch @@ -0,0 +1,259 @@ +From 65372a1165cf84765deee4f3cd3619ef73274dcb Mon Sep 17 00:00:00 2001 +From: Jai Luthra +Date: Tue, 13 Dec 2022 22:13:02 +0530 +Subject: [PATCH 47/76] dmaengine: ti: k3-psil-am62a: Add AM62Ax PSIL and PDMA + data + +Add PSIL and PDMA data for AM62Ax SoC. + +Signed-off-by: Jai Luthra +Signed-off-by: Vignesh Raghavendra +--- + drivers/dma/ti/Makefile | 3 +- + drivers/dma/ti/k3-psil-am62a.c | 196 +++++++++++++++++++++++++++++++++ + drivers/dma/ti/k3-psil-priv.h | 1 + + drivers/dma/ti/k3-psil.c | 1 + + 4 files changed, 200 insertions(+), 1 deletion(-) + create mode 100644 drivers/dma/ti/k3-psil-am62a.c + +diff --git a/drivers/dma/ti/Makefile b/drivers/dma/ti/Makefile +index b53d05b11ca5..bd1e07fda559 100644 +--- a/drivers/dma/ti/Makefile ++++ b/drivers/dma/ti/Makefile +@@ -10,6 +10,7 @@ k3-psil-lib-objs := k3-psil.o \ + k3-psil-j7200.o \ + k3-psil-am64.o \ + k3-psil-j721s2.o \ +- k3-psil-am62.o ++ k3-psil-am62.o \ ++ k3-psil-am62a.o + obj-$(CONFIG_TI_K3_PSIL) += k3-psil-lib.o + obj-$(CONFIG_TI_DMA_CROSSBAR) += dma-crossbar.o +diff --git a/drivers/dma/ti/k3-psil-am62a.c b/drivers/dma/ti/k3-psil-am62a.c +new file mode 100644 +index 000000000000..ca9d71f91422 +--- /dev/null ++++ b/drivers/dma/ti/k3-psil-am62a.c +@@ -0,0 +1,196 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com ++ */ ++ ++#include ++ ++#include "k3-psil-priv.h" ++ ++#define PSIL_PDMA_XY_TR(x) \ ++ { \ ++ .thread_id = x, \ ++ .ep_config = { \ ++ .ep_type = PSIL_EP_PDMA_XY, \ ++ .mapped_channel_id = -1, \ ++ .default_flow_id = -1, \ ++ }, \ ++ } ++ ++#define PSIL_PDMA_XY_PKT(x) \ ++ { \ ++ .thread_id = x, \ ++ .ep_config = { \ ++ .ep_type = PSIL_EP_PDMA_XY, \ ++ .mapped_channel_id = -1, \ ++ .default_flow_id = -1, \ ++ .pkt_mode = 1, \ ++ }, \ ++ } ++ ++#define PSIL_ETHERNET(x, ch, flow_base, flow_cnt) \ ++ { \ ++ .thread_id = x, \ ++ .ep_config = { \ ++ .ep_type = PSIL_EP_NATIVE, \ ++ .pkt_mode = 1, \ ++ .needs_epib = 1, \ ++ .psd_size = 16, \ ++ .mapped_channel_id = ch, \ ++ .flow_start = flow_base, \ ++ .flow_num = flow_cnt, \ ++ .default_flow_id = flow_base, \ ++ }, \ ++ } ++ ++#define PSIL_SAUL(x, ch, flow_base, flow_cnt, default_flow, tx) \ ++ { \ ++ .thread_id = x, \ ++ .ep_config = { \ ++ .ep_type = PSIL_EP_NATIVE, \ ++ .pkt_mode = 1, \ ++ .needs_epib = 1, \ ++ .psd_size = 64, \ ++ .mapped_channel_id = ch, \ ++ .flow_start = flow_base, \ ++ .flow_num = flow_cnt, \ ++ .default_flow_id = default_flow, \ ++ .notdpkt = tx, \ ++ }, \ ++ } ++ ++#define PSIL_PDMA_MCASP(x) \ ++ { \ ++ .thread_id = x, \ ++ .ep_config = { \ ++ .ep_type = PSIL_EP_PDMA_XY, \ ++ .pdma_acc32 = 1, \ ++ .pdma_burst = 1, \ ++ }, \ ++ } ++ ++#define PSIL_CSI2RX(x) \ ++ { \ ++ .thread_id = x, \ ++ .ep_config = { \ ++ .ep_type = PSIL_EP_NATIVE, \ ++ }, \ ++ } ++ ++/* PSI-L source thread IDs, used for RX (DMA_DEV_TO_MEM) */ ++static struct psil_ep am62a_src_ep_map[] = { ++ /* SAUL */ ++ PSIL_SAUL(0x7504, 20, 35, 8, 35, 0), ++ PSIL_SAUL(0x7505, 21, 35, 8, 36, 0), ++ PSIL_SAUL(0x7506, 22, 43, 8, 43, 0), ++ PSIL_SAUL(0x7507, 23, 43, 8, 44, 0), ++ /* PDMA_MAIN0 - SPI0-3 */ ++ PSIL_PDMA_XY_PKT(0x4302), ++ PSIL_PDMA_XY_PKT(0x4303), ++ PSIL_PDMA_XY_PKT(0x4304), ++ PSIL_PDMA_XY_PKT(0x4305), ++ PSIL_PDMA_XY_PKT(0x4306), ++ PSIL_PDMA_XY_PKT(0x4307), ++ PSIL_PDMA_XY_PKT(0x4308), ++ PSIL_PDMA_XY_PKT(0x4309), ++ PSIL_PDMA_XY_PKT(0x430a), ++ PSIL_PDMA_XY_PKT(0x430b), ++ PSIL_PDMA_XY_PKT(0x430c), ++ PSIL_PDMA_XY_PKT(0x430d), ++ /* PDMA_MAIN1 - UART0-6 */ ++ PSIL_PDMA_XY_PKT(0x4400), ++ PSIL_PDMA_XY_PKT(0x4401), ++ PSIL_PDMA_XY_PKT(0x4402), ++ PSIL_PDMA_XY_PKT(0x4403), ++ PSIL_PDMA_XY_PKT(0x4404), ++ PSIL_PDMA_XY_PKT(0x4405), ++ PSIL_PDMA_XY_PKT(0x4406), ++ /* PDMA_MAIN2 - MCASP0-2 */ ++ PSIL_PDMA_MCASP(0x4500), ++ PSIL_PDMA_MCASP(0x4501), ++ PSIL_PDMA_MCASP(0x4502), ++ /* CPSW3G */ ++ PSIL_ETHERNET(0x4600, 19, 19, 16), ++ /* CSI2RX */ ++ PSIL_CSI2RX(0x5000), ++ PSIL_CSI2RX(0x5001), ++ PSIL_CSI2RX(0x5002), ++ PSIL_CSI2RX(0x5003), ++ PSIL_CSI2RX(0x5004), ++ PSIL_CSI2RX(0x5005), ++ PSIL_CSI2RX(0x5006), ++ PSIL_CSI2RX(0x5007), ++ PSIL_CSI2RX(0x5008), ++ PSIL_CSI2RX(0x5009), ++ PSIL_CSI2RX(0x500a), ++ PSIL_CSI2RX(0x500b), ++ PSIL_CSI2RX(0x500c), ++ PSIL_CSI2RX(0x500d), ++ PSIL_CSI2RX(0x500e), ++ PSIL_CSI2RX(0x500f), ++ PSIL_CSI2RX(0x5010), ++ PSIL_CSI2RX(0x5011), ++ PSIL_CSI2RX(0x5012), ++ PSIL_CSI2RX(0x5013), ++ PSIL_CSI2RX(0x5014), ++ PSIL_CSI2RX(0x5015), ++ PSIL_CSI2RX(0x5016), ++ PSIL_CSI2RX(0x5017), ++ PSIL_CSI2RX(0x5018), ++ PSIL_CSI2RX(0x5019), ++ PSIL_CSI2RX(0x501a), ++ PSIL_CSI2RX(0x501b), ++ PSIL_CSI2RX(0x501c), ++ PSIL_CSI2RX(0x501d), ++ PSIL_CSI2RX(0x501e), ++ PSIL_CSI2RX(0x501f), ++}; ++ ++/* PSI-L destination thread IDs, used for TX (DMA_MEM_TO_DEV) */ ++static struct psil_ep am62a_dst_ep_map[] = { ++ /* SAUL */ ++ PSIL_SAUL(0xf500, 27, 83, 8, 83, 1), ++ PSIL_SAUL(0xf501, 28, 91, 8, 91, 1), ++ /* PDMA_MAIN0 - SPI0-3 */ ++ PSIL_PDMA_XY_PKT(0xc302), ++ PSIL_PDMA_XY_PKT(0xc303), ++ PSIL_PDMA_XY_PKT(0xc304), ++ PSIL_PDMA_XY_PKT(0xc305), ++ PSIL_PDMA_XY_PKT(0xc306), ++ PSIL_PDMA_XY_PKT(0xc307), ++ PSIL_PDMA_XY_PKT(0xc308), ++ PSIL_PDMA_XY_PKT(0xc309), ++ PSIL_PDMA_XY_PKT(0xc30a), ++ PSIL_PDMA_XY_PKT(0xc30b), ++ PSIL_PDMA_XY_PKT(0xc30c), ++ PSIL_PDMA_XY_PKT(0xc30d), ++ /* PDMA_MAIN1 - UART0-6 */ ++ PSIL_PDMA_XY_PKT(0xc400), ++ PSIL_PDMA_XY_PKT(0xc401), ++ PSIL_PDMA_XY_PKT(0xc402), ++ PSIL_PDMA_XY_PKT(0xc403), ++ PSIL_PDMA_XY_PKT(0xc404), ++ PSIL_PDMA_XY_PKT(0xc405), ++ PSIL_PDMA_XY_PKT(0xc406), ++ /* PDMA_MAIN2 - MCASP0-2 */ ++ PSIL_PDMA_MCASP(0xc500), ++ PSIL_PDMA_MCASP(0xc501), ++ PSIL_PDMA_MCASP(0xc502), ++ /* CPSW3G */ ++ PSIL_ETHERNET(0xc600, 19, 19, 8), ++ PSIL_ETHERNET(0xc601, 20, 27, 8), ++ PSIL_ETHERNET(0xc602, 21, 35, 8), ++ PSIL_ETHERNET(0xc603, 22, 43, 8), ++ PSIL_ETHERNET(0xc604, 23, 51, 8), ++ PSIL_ETHERNET(0xc605, 24, 59, 8), ++ PSIL_ETHERNET(0xc606, 25, 67, 8), ++ PSIL_ETHERNET(0xc607, 26, 75, 8), ++}; ++ ++struct psil_ep_map am62a_ep_map = { ++ .name = "am62a", ++ .src = am62a_src_ep_map, ++ .src_count = ARRAY_SIZE(am62a_src_ep_map), ++ .dst = am62a_dst_ep_map, ++ .dst_count = ARRAY_SIZE(am62a_dst_ep_map), ++}; +diff --git a/drivers/dma/ti/k3-psil-priv.h b/drivers/dma/ti/k3-psil-priv.h +index 74fa9ec02968..abd650bb7600 100644 +--- a/drivers/dma/ti/k3-psil-priv.h ++++ b/drivers/dma/ti/k3-psil-priv.h +@@ -43,5 +43,6 @@ extern struct psil_ep_map j7200_ep_map; + extern struct psil_ep_map am64_ep_map; + extern struct psil_ep_map j721s2_ep_map; + extern struct psil_ep_map am62_ep_map; ++extern struct psil_ep_map am62a_ep_map; + + #endif /* K3_PSIL_PRIV_H_ */ +diff --git a/drivers/dma/ti/k3-psil.c b/drivers/dma/ti/k3-psil.c +index 8b6533a1eeeb..2da6988a0e7b 100644 +--- a/drivers/dma/ti/k3-psil.c ++++ b/drivers/dma/ti/k3-psil.c +@@ -24,6 +24,7 @@ static const struct soc_device_attribute k3_soc_devices[] = { + { .family = "AM64X", .data = &am64_ep_map }, + { .family = "J721S2", .data = &j721s2_ep_map }, + { .family = "AM62X", .data = &am62_ep_map }, ++ { .family = "AM62AX", .data = &am62a_ep_map }, + { /* sentinel */ } + }; + +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0048-dmaengine-ti-k3-udma-Add-support-for-DMAs-on-AM62A-S.patch b/recipes-kernel/linux/files/patches-6.1/0048-dmaengine-ti-k3-udma-Add-support-for-DMAs-on-AM62A-S.patch new file mode 100644 index 000000000..606f8fcf7 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0048-dmaengine-ti-k3-udma-Add-support-for-DMAs-on-AM62A-S.patch @@ -0,0 +1,29 @@ +From 894b378febfbfa8a44db11646880e643200d4956 Mon Sep 17 00:00:00 2001 +From: Vignesh Raghavendra +Date: Tue, 13 Dec 2022 22:13:03 +0530 +Subject: [PATCH 48/76] dmaengine: ti: k3-udma: Add support for DMAs on AM62A + SoC + +AM62A SoC has a BCDMA and PKTDMA as systems DMAs for service various +peripherals similar to AM64 SoC. Add support for the same. + +Signed-off-by: Vignesh Raghavendra +--- + drivers/dma/ti/k3-udma.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c +index a9d19689eba4..94271a8391ea 100644 +--- a/drivers/dma/ti/k3-udma.c ++++ b/drivers/dma/ti/k3-udma.c +@@ -4389,6 +4389,7 @@ static const struct soc_device_attribute k3_soc_devices[] = { + { .family = "AM64X", .data = &am64_soc_data }, + { .family = "J721S2", .data = &j721e_soc_data}, + { .family = "AM62X", .data = &am64_soc_data }, ++ { .family = "AM62AX", .data = &am64_soc_data }, + { /* sentinel */ } + }; + +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0049-dmaengine-ti-k3-udma-Add-support-for-BCDMA-CSI-RX.patch b/recipes-kernel/linux/files/patches-6.1/0049-dmaengine-ti-k3-udma-Add-support-for-BCDMA-CSI-RX.patch new file mode 100644 index 000000000..729b1edc3 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0049-dmaengine-ti-k3-udma-Add-support-for-BCDMA-CSI-RX.patch @@ -0,0 +1,86 @@ +From f2d345bc1bd14f9e17e25c8084a6ea86ca0ff2b3 Mon Sep 17 00:00:00 2001 +From: Vignesh Raghavendra +Date: Tue, 13 Dec 2022 22:13:04 +0530 +Subject: [PATCH 49/76] dmaengine: ti: k3-udma: Add support for BCDMA CSI RX + +BCDMA CSI RX present on AM62Ax SoC is a dedicated DMA for servicing +Camera Serial Interface (CSI) IP. Add support for the same. + +Signed-off-by: Vignesh Raghavendra +--- + drivers/dma/ti/k3-udma.c | 37 ++++++++++++++++++++++++++++++++----- + 1 file changed, 32 insertions(+), 5 deletions(-) + +diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c +index 94271a8391ea..1d7e8822be7a 100644 +--- a/drivers/dma/ti/k3-udma.c ++++ b/drivers/dma/ti/k3-udma.c +@@ -135,6 +135,7 @@ struct udma_match_data { + u32 flags; + u32 statictr_z_mask; + u8 burst_size[3]; ++ struct udma_soc_data *soc_data; + }; + + struct udma_soc_data { +@@ -4298,6 +4299,25 @@ static struct udma_match_data j721e_mcu_data = { + }, + }; + ++static struct udma_soc_data am62a_dmss_csi_soc_data = { ++ .oes = { ++ .bcdma_rchan_data = 0xe00, ++ .bcdma_rchan_ring = 0x1000, ++ }, ++}; ++ ++static struct udma_match_data am62a_bcdma_csirx_data = { ++ .type = DMA_TYPE_BCDMA, ++ .psil_base = 0x3100, ++ .enable_memcpy_support = false, ++ .burst_size = { ++ TI_SCI_RM_UDMAP_CHAN_BURST_SIZE_64_BYTES, /* Normal Channels */ ++ 0, /* No H Channels */ ++ 0, /* No UH Channels */ ++ }, ++ .soc_data = &am62a_dmss_csi_soc_data, ++}; ++ + static struct udma_match_data am64_bcdma_data = { + .type = DMA_TYPE_BCDMA, + .psil_base = 0x2000, /* for tchan and rchan, not applicable to bchan */ +@@ -4347,6 +4367,10 @@ static const struct of_device_id udma_of_match[] = { + .compatible = "ti,am64-dmss-pktdma", + .data = &am64_pktdma_data, + }, ++ { ++ .compatible = "ti,am62a-dmss-bcdma-csirx", ++ .data = &am62a_bcdma_csirx_data, ++ }, + { /* Sentinel */ }, + }; + +@@ -5277,12 +5301,15 @@ static int udma_probe(struct platform_device *pdev) + } + ud->match_data = match->data; + +- soc = soc_device_match(k3_soc_devices); +- if (!soc) { +- dev_err(dev, "No compatible SoC found\n"); +- return -ENODEV; ++ ud->soc_data = ud->match_data->soc_data; ++ if (!ud->soc_data) { ++ soc = soc_device_match(k3_soc_devices); ++ if (!soc) { ++ dev_err(dev, "No compatible SoC found\n"); ++ return -ENODEV; ++ } ++ ud->soc_data = soc->data; + } +- ud->soc_data = soc->data; + + ret = udma_get_mmrs(pdev, ud); + if (ret) +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0050-soc-ti-k3-ringacc-remove-non-fatal-probe-deferral-lo.patch b/recipes-kernel/linux/files/patches-6.1/0050-soc-ti-k3-ringacc-remove-non-fatal-probe-deferral-lo.patch new file mode 100644 index 000000000..1d174a10f --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0050-soc-ti-k3-ringacc-remove-non-fatal-probe-deferral-lo.patch @@ -0,0 +1,34 @@ +From d77406fb171d83f538f77fe0885aff20bce997c1 Mon Sep 17 00:00:00 2001 +From: Jayesh Choudhary +Date: Fri, 28 Jul 2023 11:03:56 +0530 +Subject: [PATCH 50/76] soc: ti: k3-ringacc: remove non-fatal probe deferral + log + +Drop the non-fatal probe deferral log for getting MSI domain. +This makes the kernel log clean and we do not get recurring logs +stating: "Failed to get MSI domain". + +Signed-off-by: Jayesh Choudhary +--- + drivers/soc/ti/k3-ringacc.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c +index f7bf18b8229a..10a180be75dc 100644 +--- a/drivers/soc/ti/k3-ringacc.c ++++ b/drivers/soc/ti/k3-ringacc.c +@@ -1358,10 +1358,8 @@ static int k3_ringacc_init(struct platform_device *pdev, + + dev->msi.domain = of_msi_get_domain(dev, dev->of_node, + DOMAIN_BUS_TI_SCI_INTA_MSI); +- if (!dev->msi.domain) { +- dev_err(dev, "Failed to get MSI domain\n"); ++ if (!dev->msi.domain) + return -EPROBE_DEFER; +- } + + ret = k3_ringacc_probe_dt(ringacc); + if (ret) +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0051-dmaengine-ti-k3-udma-remove-non-fatal-probe-deferral.patch b/recipes-kernel/linux/files/patches-6.1/0051-dmaengine-ti-k3-udma-remove-non-fatal-probe-deferral.patch new file mode 100644 index 000000000..06213b968 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0051-dmaengine-ti-k3-udma-remove-non-fatal-probe-deferral.patch @@ -0,0 +1,31 @@ +From 3e1df348cd2d8169dabf581b52db91d6483bf22d Mon Sep 17 00:00:00 2001 +From: Jayesh Choudhary +Date: Tue, 17 Jan 2023 10:48:55 +0530 +Subject: [PATCH 51/76] dmaengine: ti: k3-udma: remove non-fatal probe deferral + log + +Drop the non-fatal probe deferral log for getting MSI domain. +This makes the kernel log clean and we do not get recurring logs +stating: "Failed to get MSI domain". + +Signed-off-by: Jayesh Choudhary +Acked-by: Peter Ujfalusi +--- + drivers/dma/ti/k3-udma.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c +index 1d7e8822be7a..f652a217be76 100644 +--- a/drivers/dma/ti/k3-udma.c ++++ b/drivers/dma/ti/k3-udma.c +@@ -5378,7 +5378,6 @@ static int udma_probe(struct platform_device *pdev) + dev->msi.domain = of_msi_get_domain(dev, dev->of_node, + DOMAIN_BUS_TI_SCI_INTA_MSI); + if (!dev->msi.domain) { +- dev_err(dev, "Failed to get MSI domain\n"); + return -EPROBE_DEFER; + } + +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0104-WIP-arm64-dts-ti-iot2050-Add-node-for-generic-spidev.patch b/recipes-kernel/linux/files/patches-6.1/0052-WIP-arm64-dts-ti-iot2050-Add-node-for-generic-spidev.patch similarity index 77% rename from recipes-kernel/linux/files/patches-5.10/0104-WIP-arm64-dts-ti-iot2050-Add-node-for-generic-spidev.patch rename to recipes-kernel/linux/files/patches-6.1/0052-WIP-arm64-dts-ti-iot2050-Add-node-for-generic-spidev.patch index 5114126c3..a9f53f945 100644 --- a/recipes-kernel/linux/files/patches-5.10/0104-WIP-arm64-dts-ti-iot2050-Add-node-for-generic-spidev.patch +++ b/recipes-kernel/linux/files/patches-6.1/0052-WIP-arm64-dts-ti-iot2050-Add-node-for-generic-spidev.patch @@ -1,7 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 6cc7a727db54d094ebf301cda39b4079992b3a3d Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Thu, 11 Mar 2021 15:28:21 +0100 -Subject: [PATCH] WIP: arm64: dts: ti: iot2050: Add node for generic spidev +Subject: [PATCH 52/76] WIP: arm64: dts: ti: iot2050: Add node for generic + spidev This allows to use mcu_spi0 via userspace spidev. @@ -15,12 +16,12 @@ Signed-off-by: Jan Kiszka 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index 51e82e08550a..fcf877d3d504 100644 +index 1be99de1cae2..7e24686c8cc8 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -@@ -682,6 +682,12 @@ &mcu_spi0 { +@@ -690,6 +690,12 @@ &mcu_spi0 { #address-cells = <1>; - #size-cells= <0>; + #size-cells = <0>; ti,pindir-d0-out-d1-in; + + spidev@0 { @@ -31,3 +32,6 @@ index 51e82e08550a..fcf877d3d504 100644 }; &tscadc0 { +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0118-arm64-dts-ti-Indicate-the-green-light-is-off-when-pa.patch b/recipes-kernel/linux/files/patches-6.1/0053-arm64-dts-ti-Indicate-the-green-light-is-off-when-pa.patch similarity index 77% rename from recipes-kernel/linux/files/patches-5.10/0118-arm64-dts-ti-Indicate-the-green-light-is-off-when-pa.patch rename to recipes-kernel/linux/files/patches-6.1/0053-arm64-dts-ti-Indicate-the-green-light-is-off-when-pa.patch index 20449868f..961645b61 100644 --- a/recipes-kernel/linux/files/patches-5.10/0118-arm64-dts-ti-Indicate-the-green-light-is-off-when-pa.patch +++ b/recipes-kernel/linux/files/patches-6.1/0053-arm64-dts-ti-Indicate-the-green-light-is-off-when-pa.patch @@ -1,7 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 04d780bfa56e72d48e84493a9520a2cf9f1046c8 Mon Sep 17 00:00:00 2001 From: chao zeng Date: Thu, 16 Dec 2021 15:09:25 +0800 -Subject: [PATCH] arm64: dts: ti: Indicate the green light is off when panic +Subject: [PATCH 53/76] arm64: dts: ti: Indicate the green light is off when + panic The green light is out of control when panic occurs. it should be off thhen @@ -12,7 +13,7 @@ Signed-off-by: chao zeng 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index ea8ff74c681c..3310880e83ee 100644 +index 7e24686c8cc8..07da59fb1dd9 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi @@ -81,6 +81,7 @@ status-led-red { @@ -23,3 +24,6 @@ index ea8ff74c681c..3310880e83ee 100644 }; user-led1-red { +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0054-dt-bindings-remoteproc-pru-Add-Interrupt-property.patch b/recipes-kernel/linux/files/patches-6.1/0054-dt-bindings-remoteproc-pru-Add-Interrupt-property.patch new file mode 100644 index 000000000..e7a23653b --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0054-dt-bindings-remoteproc-pru-Add-Interrupt-property.patch @@ -0,0 +1,78 @@ +From 210401ca0a19f6a5d21b0c6ab54364509e911fd6 Mon Sep 17 00:00:00 2001 +From: MD Danish Anwar +Date: Mon, 14 Aug 2023 15:21:41 +0530 +Subject: [PATCH 54/76] dt-bindings: remoteproc: pru: Add Interrupt property + +Add interrupts and interrupt-names protperties for PRU and RTU cores. + +Signed-off-by: MD Danish Anwar +Reviewed-by: Conor Dooley +--- + .../bindings/remoteproc/ti,pru-rproc.yaml | 23 +++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/Documentation/devicetree/bindings/remoteproc/ti,pru-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/ti,pru-rproc.yaml +index cd55d80137f7..fc81ba2ad2da 100644 +--- a/Documentation/devicetree/bindings/remoteproc/ti,pru-rproc.yaml ++++ b/Documentation/devicetree/bindings/remoteproc/ti,pru-rproc.yaml +@@ -66,6 +66,17 @@ properties: + Should contain the name of the default firmware image + file located on the firmware search path. + ++ interrupts: ++ maxItems: 1 ++ description: ++ Interrupt specifiers enable the virtio/rpmsg communication between MPU ++ and the PRU/RTU cores. For the values of the interrupt cells please refer ++ to interrupt-controller/ti,pruss-intc.yaml schema. ++ ++ interrupt-names: ++ items: ++ - const: vring ++ + if: + properties: + compatible: +@@ -171,6 +182,9 @@ examples: + <0x22400 0x100>; + reg-names = "iram", "control", "debug"; + firmware-name = "am65x-pru0_0-fw"; ++ interrupt-parent = <&icssg0_intc>; ++ interrupts = <16 2 2>; ++ interrupt-names = "vring"; + }; + + rtu0_0: rtu@4000 { +@@ -180,6 +194,9 @@ examples: + <0x23400 0x100>; + reg-names = "iram", "control", "debug"; + firmware-name = "am65x-rtu0_0-fw"; ++ interrupt-parent = <&icssg0_intc>; ++ interrupts = <20 4 4>; ++ interrupt-names = "vring"; + }; + + tx_pru0_0: txpru@a000 { +@@ -198,6 +215,9 @@ examples: + <0x24400 0x100>; + reg-names = "iram", "control", "debug"; + firmware-name = "am65x-pru0_1-fw"; ++ interrupt-parent = <&icssg0_intc>; ++ interrupts = <18 3 3>; ++ interrupt-names = "vring"; + }; + + rtu0_1: rtu@6000 { +@@ -207,6 +227,9 @@ examples: + <0x23c00 0x100>; + reg-names = "iram", "control", "debug"; + firmware-name = "am65x-rtu0_1-fw"; ++ interrupt-parent = <&icssg0_intc>; ++ interrupts = <22 5 5>; ++ interrupt-names = "vring"; + }; + + tx_pru0_1: txpru@c000 { +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0147-arm64-dts-ti-k3-am65-main-Add-PRU-system-events-for-.patch b/recipes-kernel/linux/files/patches-6.1/0055-arm64-dts-ti-k3-am65-main-Add-PRU-system-events-for-.patch similarity index 84% rename from recipes-kernel/linux/files/patches-5.10/0147-arm64-dts-ti-k3-am65-main-Add-PRU-system-events-for-.patch rename to recipes-kernel/linux/files/patches-6.1/0055-arm64-dts-ti-k3-am65-main-Add-PRU-system-events-for-.patch index 470e9e62d..33a1951cf 100644 --- a/recipes-kernel/linux/files/patches-5.10/0147-arm64-dts-ti-k3-am65-main-Add-PRU-system-events-for-.patch +++ b/recipes-kernel/linux/files/patches-6.1/0055-arm64-dts-ti-k3-am65-main-Add-PRU-system-events-for-.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From dff886496d88d7afdb3af2f6113b60de934ad9b3 Mon Sep 17 00:00:00 2001 From: Suman Anna -Date: Mon, 18 Oct 2021 11:29:18 +0000 -Subject: [PATCH] arm64: dts: ti: k3-am65-main: Add PRU system events for +Date: Mon, 7 Aug 2023 16:48:54 +0530 +Subject: [PATCH 55/76] arm64: dts: ti: k3-am65-main: Add PRU system events for virtio A PRU system event "vring" has been added to each PRU and RTU @@ -24,15 +24,16 @@ loaded/booted on the PRU. Signed-off-by: Suman Anna Signed-off-by: Kishon Vijay Abraham I +Signed-off-by: MD Danish Anwar --- arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index e9785a9180b7..60cfc2214883 100644 +index e239287ee9d7..231634fdc469 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -1045,6 +1045,9 @@ pru0_0: pru@34000 { +@@ -1015,6 +1015,9 @@ pru0_0: pru@34000 { <0x22400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am65x-pru0_0-fw"; @@ -42,7 +43,7 @@ index e9785a9180b7..60cfc2214883 100644 }; rtu0_0: rtu@4000 { -@@ -1054,6 +1057,9 @@ rtu0_0: rtu@4000 { +@@ -1024,6 +1027,9 @@ rtu0_0: rtu@4000 { <0x23400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am65x-rtu0_0-fw"; @@ -52,7 +53,7 @@ index e9785a9180b7..60cfc2214883 100644 }; tx_pru0_0: txpru@a000 { -@@ -1072,6 +1078,9 @@ pru0_1: pru@38000 { +@@ -1042,6 +1048,9 @@ pru0_1: pru@38000 { <0x24400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am65x-pru0_1-fw"; @@ -62,7 +63,7 @@ index e9785a9180b7..60cfc2214883 100644 }; rtu0_1: rtu@6000 { -@@ -1081,6 +1090,9 @@ rtu0_1: rtu@6000 { +@@ -1051,6 +1060,9 @@ rtu0_1: rtu@6000 { <0x23c00 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am65x-rtu0_1-fw"; @@ -72,7 +73,7 @@ index e9785a9180b7..60cfc2214883 100644 }; tx_pru0_1: txpru@c000 { -@@ -1198,6 +1210,9 @@ pru1_0: pru@34000 { +@@ -1168,6 +1180,9 @@ pru1_0: pru@34000 { <0x22400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am65x-pru1_0-fw"; @@ -82,7 +83,7 @@ index e9785a9180b7..60cfc2214883 100644 }; rtu1_0: rtu@4000 { -@@ -1207,6 +1222,9 @@ rtu1_0: rtu@4000 { +@@ -1177,6 +1192,9 @@ rtu1_0: rtu@4000 { <0x23400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am65x-rtu1_0-fw"; @@ -92,7 +93,7 @@ index e9785a9180b7..60cfc2214883 100644 }; tx_pru1_0: txpru@a000 { -@@ -1225,6 +1243,9 @@ pru1_1: pru@38000 { +@@ -1195,6 +1213,9 @@ pru1_1: pru@38000 { <0x24400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am65x-pru1_1-fw"; @@ -102,7 +103,7 @@ index e9785a9180b7..60cfc2214883 100644 }; rtu1_1: rtu@6000 { -@@ -1234,6 +1255,9 @@ rtu1_1: rtu@6000 { +@@ -1204,6 +1225,9 @@ rtu1_1: rtu@6000 { <0x23c00 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am65x-rtu1_1-fw"; @@ -112,7 +113,7 @@ index e9785a9180b7..60cfc2214883 100644 }; tx_pru1_1: txpru@c000 { -@@ -1351,6 +1375,9 @@ pru2_0: pru@34000 { +@@ -1321,6 +1345,9 @@ pru2_0: pru@34000 { <0x22400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am65x-pru2_0-fw"; @@ -122,7 +123,7 @@ index e9785a9180b7..60cfc2214883 100644 }; rtu2_0: rtu@4000 { -@@ -1360,6 +1387,9 @@ rtu2_0: rtu@4000 { +@@ -1330,6 +1357,9 @@ rtu2_0: rtu@4000 { <0x23400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am65x-rtu2_0-fw"; @@ -132,7 +133,7 @@ index e9785a9180b7..60cfc2214883 100644 }; tx_pru2_0: txpru@a000 { -@@ -1378,6 +1408,9 @@ pru2_1: pru@38000 { +@@ -1348,6 +1378,9 @@ pru2_1: pru@38000 { <0x24400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am65x-pru2_1-fw"; @@ -142,7 +143,7 @@ index e9785a9180b7..60cfc2214883 100644 }; rtu2_1: rtu@6000 { -@@ -1387,6 +1420,9 @@ rtu2_1: rtu@6000 { +@@ -1357,6 +1390,9 @@ rtu2_1: rtu@6000 { <0x23c00 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am65x-rtu2_1-fw"; @@ -152,3 +153,6 @@ index e9785a9180b7..60cfc2214883 100644 }; tx_pru2_1: txpru@c000 { +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0217-arm64-dts-ti-iot2050-Definitions-for-runtime-pinmuxi.patch b/recipes-kernel/linux/files/patches-6.1/0056-arm64-dts-ti-iot2050-Definitions-for-runtime-pinmuxi.patch similarity index 95% rename from recipes-kernel/linux/files/patches-5.10/0217-arm64-dts-ti-iot2050-Definitions-for-runtime-pinmuxi.patch rename to recipes-kernel/linux/files/patches-6.1/0056-arm64-dts-ti-iot2050-Definitions-for-runtime-pinmuxi.patch index b1ca8f266..cc5252993 100644 --- a/recipes-kernel/linux/files/patches-5.10/0217-arm64-dts-ti-iot2050-Definitions-for-runtime-pinmuxi.patch +++ b/recipes-kernel/linux/files/patches-6.1/0056-arm64-dts-ti-iot2050-Definitions-for-runtime-pinmuxi.patch @@ -1,7 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From eff8bdd384f62caa8598ef0cb7c5a92a55053a86 Mon Sep 17 00:00:00 2001 From: Benedikt Niedermayr Date: Tue, 21 Feb 2023 11:03:42 +0100 -Subject: [PATCH] arm64: dts: ti: iot2050: Definitions for runtime pinmuxing +Subject: [PATCH 56/76] arm64: dts: ti: iot2050: Definitions for runtime + pinmuxing Add multiple device tree nodes in order to support runtime pinmuxing via debugfs. @@ -16,14 +17,14 @@ function mask to 32-Bit allows writes to the whole register. Signed-off-by: Benedikt Niedermayr --- .../boot/dts/ti/k3-am65-iot2050-common.dtsi | 669 +++++++++++++++++- - .../dts/ti/k3-am6548-iot2050-advanced-m2.dts | 2 +- - 2 files changed, 631 insertions(+), 40 deletions(-) + .../dts/ti/k3-am6548-iot2050-advanced-m2.dts | 5 +- + 2 files changed, 631 insertions(+), 43 deletions(-) diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index 3310880e83ee..94fdd776113f 100644 +index 07da59fb1dd9..192938c511ae 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -@@ -177,6 +177,425 @@ icssg0_emac1: ethernet-mii1 { +@@ -183,6 +183,425 @@ icssg0_emac1: port@1 { }; &wkup_pmx0 { @@ -449,7 +450,7 @@ index 3310880e83ee..94fdd776113f 100644 wkup_i2c0_pins_default: wkup-i2c0-pins-default { pinctrl-single,pins = < /* (AC7) WKUP_I2C0_SCL */ -@@ -209,23 +628,6 @@ AM65X_WKUP_IOPAD(0x0034, PIN_INPUT, 7) +@@ -215,23 +634,6 @@ AM65X_WKUP_IOPAD(0x0034, PIN_INPUT, 7) >; }; @@ -473,7 +474,7 @@ index 3310880e83ee..94fdd776113f 100644 arduino_io_oe_pins_default: arduino-io-oe-pins-default { pinctrl-single,pins = < -@@ -240,6 +642,8 @@ AM65X_WKUP_IOPAD(0x0068, PIN_OUTPUT, 7) +@@ -246,6 +648,8 @@ AM65X_WKUP_IOPAD(0x0068, PIN_OUTPUT, 7) /* (M1) WKUP_GPIO0_41 */ AM65X_WKUP_IOPAD(0x0074, PIN_OUTPUT, 7) >; @@ -482,7 +483,7 @@ index 3310880e83ee..94fdd776113f 100644 }; mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins-default { -@@ -305,6 +709,214 @@ AM65X_WKUP_IOPAD(0x003C, PIN_OUTPUT, 7) +@@ -311,6 +715,214 @@ AM65X_WKUP_IOPAD(0x003C, PIN_OUTPUT, 7) }; &main_pmx0 { @@ -697,7 +698,7 @@ index 3310880e83ee..94fdd776113f 100644 main_uart1_pins_default: main-uart1-pins-default { pinctrl-single,pins = < AM65X_IOPAD(0x0174, PIN_INPUT, 6) /* (AE23) UART1_RXD */ -@@ -346,17 +958,6 @@ AM65X_IOPAD(0x02c0, PIN_OUTPUT, 0) /* (AC8) USB1_DRVVBUS */ +@@ -352,17 +964,6 @@ AM65X_IOPAD(0x02c0, PIN_OUTPUT, 0) /* (AC8) USB1_DRVVBUS */ >; }; @@ -715,7 +716,7 @@ index 3310880e83ee..94fdd776113f 100644 dss_vout1_pins_default: dss-vout1-pins-default { pinctrl-single,pins = < AM65X_IOPAD(0x0000, PIN_OUTPUT, 1) /* VOUT1_DATA0 */ -@@ -477,14 +1078,7 @@ &main_uart2 { +@@ -483,14 +1084,7 @@ &main_uart2 { status = "disabled"; }; @@ -730,7 +731,7 @@ index 3310880e83ee..94fdd776113f 100644 gpio-line-names = "main_gpio0-base", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", -@@ -497,12 +1091,12 @@ &main_gpio0 { +@@ -503,12 +1097,12 @@ &main_gpio0 { &wkup_gpio0 { pinctrl-names = "default"; pinctrl-0 = < @@ -744,7 +745,7 @@ index 3310880e83ee..94fdd776113f 100644 gpio-line-names = /* 0..9 */ "wkup_gpio0-base", "", "", "", "UART0-mode1", "UART0-mode0", -@@ -679,9 +1273,6 @@ &usb1 { +@@ -685,9 +1279,6 @@ &usb1 { }; &mcu_spi0 { @@ -752,18 +753,24 @@ index 3310880e83ee..94fdd776113f 100644 - pinctrl-0 = <&mcu_spi0_pins_default>; - #address-cells = <1>; - #size-cells= <0>; + #size-cells = <0>; ti,pindir-d0-out-d1-in; diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts -index cbc411c8fe1d..aacbf7c6a3c4 100644 +index 9400e35882a6..b3a21765c9ed 100644 --- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts +++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts -@@ -66,7 +66,7 @@ AM65X_IOPAD(0x001c, PIN_INPUT_PULLUP, 7) /* (C23) GPIO1_89 */ +@@ -66,10 +66,7 @@ AM65X_IOPAD(0x001c, PIN_INPUT_PULLUP, 7) /* (C23) GPIO1_89 */ &main_gpio0 { pinctrl-names = "default"; -- pinctrl-0 = <&main_m2_pcie_mux_control &arduino_io_d4_to_d9_pins_default>; +- pinctrl-0 = < +- &main_m2_pcie_mux_control +- &arduino_io_d4_to_d9_pins_default +- >; + pinctrl-0 = <&main_m2_pcie_mux_control>; }; &main_gpio1 { +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0218-arm64-dts-ti-iot2050-Refactor-the-m.2-and-minipcie-p.patch b/recipes-kernel/linux/files/patches-6.1/0057-arm64-dts-ti-iot2050-Refactor-the-m.2-and-minipcie-p.patch similarity index 89% rename from recipes-kernel/linux/files/patches-5.10/0218-arm64-dts-ti-iot2050-Refactor-the-m.2-and-minipcie-p.patch rename to recipes-kernel/linux/files/patches-6.1/0057-arm64-dts-ti-iot2050-Refactor-the-m.2-and-minipcie-p.patch index 00e4654b7..0f49c277d 100644 --- a/recipes-kernel/linux/files/patches-5.10/0218-arm64-dts-ti-iot2050-Refactor-the-m.2-and-minipcie-p.patch +++ b/recipes-kernel/linux/files/patches-6.1/0057-arm64-dts-ti-iot2050-Refactor-the-m.2-and-minipcie-p.patch @@ -1,8 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 78228123b4ac84458471cf3dc6e2332077f3d601 Mon Sep 17 00:00:00 2001 From: Su Bao Cheng Date: Fri, 19 May 2023 10:16:39 +0800 -Subject: [PATCH] arm64: dts: ti: iot2050: Refactor the m.2 and minipcie power - pin +Subject: [PATCH 57/76] arm64: dts: ti: iot2050: Refactor the m.2 and minipcie + power pin Make the m.2 power control pin also available on miniPCIE variants. @@ -33,10 +33,10 @@ index e73458ca6900..0dada0b39e36 100644 "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index 94fdd776113f..871b86b3ff60 100644 +index 192938c511ae..edd475eb898c 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -@@ -917,6 +917,12 @@ AM65X_IOPAD(0x00CC, PIN_INPUT_PULLDOWN, 7) +@@ -923,6 +923,12 @@ AM65X_IOPAD(0x00CC, PIN_INPUT_PULLDOWN, 7) >; }; @@ -49,7 +49,7 @@ index 94fdd776113f..871b86b3ff60 100644 main_uart1_pins_default: main-uart1-pins-default { pinctrl-single,pins = < AM65X_IOPAD(0x0174, PIN_INPUT, 6) /* (AE23) UART1_RXD */ -@@ -1088,6 +1094,11 @@ &main_gpio0 { +@@ -1094,6 +1100,11 @@ &main_gpio0 { "", "IO9"; }; @@ -62,7 +62,7 @@ index 94fdd776113f..871b86b3ff60 100644 pinctrl-names = "default"; pinctrl-0 = < diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts -index aacbf7c6a3c4..6ec25bfc97bf 100644 +index b3a21765c9ed..663ff4d501c2 100644 --- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts +++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts @@ -27,12 +27,6 @@ &mcu_r5fss0 { @@ -87,3 +87,6 @@ index aacbf7c6a3c4..6ec25bfc97bf 100644 &main_pmx0_m2_config_pins_default &main_pmx1_m2_config_pins_default &cp2102n_reset_pin_default +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0186-mmc-sdhci_am654-Disable-data-error-interrupts-while-.patch b/recipes-kernel/linux/files/patches-6.1/0058-mmc-sdhci_am654-Disable-data-error-interrupts-while-.patch similarity index 89% rename from recipes-kernel/linux/files/patches-5.10/0186-mmc-sdhci_am654-Disable-data-error-interrupts-while-.patch rename to recipes-kernel/linux/files/patches-6.1/0058-mmc-sdhci_am654-Disable-data-error-interrupts-while-.patch index d475a813f..39104b710 100644 --- a/recipes-kernel/linux/files/patches-5.10/0186-mmc-sdhci_am654-Disable-data-error-interrupts-while-.patch +++ b/recipes-kernel/linux/files/patches-6.1/0058-mmc-sdhci_am654-Disable-data-error-interrupts-while-.patch @@ -1,7 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 3a9bfc4f2e43a11c92c98a5c09e41f3b9c262012 Mon Sep 17 00:00:00 2001 From: Aswath Govindraju Date: Wed, 13 Apr 2022 18:44:03 +0530 -Subject: [PATCH] mmc: sdhci_am654: Disable data error interrupts while tuning +Subject: [PATCH 58/76] mmc: sdhci_am654: Disable data error interrupts while + tuning Data end bit errors, data CRC errors and data timeout errors are expected while tuning and are to ignored. Therefore, disable these data error @@ -14,7 +15,7 @@ Signed-off-by: Vignesh Raghavendra 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c -index c72e10f36c1c..3378421c9366 100644 +index 8e22b375247e..5deb26c9fe36 100644 --- a/drivers/mmc/host/sdhci_am654.c +++ b/drivers/mmc/host/sdhci_am654.c @@ -389,8 +389,18 @@ static void sdhci_am654_reset(struct sdhci_host *host, u8 mask) @@ -51,3 +52,6 @@ index c72e10f36c1c..3378421c9366 100644 return 0; } +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0187-mmc-sdhci_am654-Add-support-for-PM-suspend-resume.patch b/recipes-kernel/linux/files/patches-6.1/0059-mmc-sdhci_am654-Add-support-for-PM-suspend-resume.patch similarity index 93% rename from recipes-kernel/linux/files/patches-5.10/0187-mmc-sdhci_am654-Add-support-for-PM-suspend-resume.patch rename to recipes-kernel/linux/files/patches-6.1/0059-mmc-sdhci_am654-Add-support-for-PM-suspend-resume.patch index 8e8a41e66..0a04e7b6a 100644 --- a/recipes-kernel/linux/files/patches-5.10/0187-mmc-sdhci_am654-Add-support-for-PM-suspend-resume.patch +++ b/recipes-kernel/linux/files/patches-6.1/0059-mmc-sdhci_am654-Add-support-for-PM-suspend-resume.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 8fece7308bd90990429ebe5f7964d611e8871bed Mon Sep 17 00:00:00 2001 From: Aswath Govindraju Date: Wed, 13 Apr 2022 18:44:04 +0530 -Subject: [PATCH] mmc: sdhci_am654: Add support for PM suspend/resume +Subject: [PATCH 59/76] mmc: sdhci_am654: Add support for PM suspend/resume Add support for suspend/resume and pm_runtime resume/suspend. @@ -12,7 +12,7 @@ Signed-off-by: Vignesh Raghavendra 1 file changed, 131 insertions(+), 16 deletions(-) diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c -index 3378421c9366..18a1d85910fe 100644 +index 5deb26c9fe36..136022de43b8 100644 --- a/drivers/mmc/host/sdhci_am654.c +++ b/drivers/mmc/host/sdhci_am654.c @@ -85,6 +85,7 @@ @@ -23,7 +23,7 @@ index 3378421c9366..18a1d85910fe 100644 /* Command Queue Host Controller Interface Base address */ #define SDHCI_AM654_CQE_BASE_ADDR 0x200 -@@ -816,16 +817,10 @@ static int sdhci_am654_probe(struct platform_device *pdev) +@@ -825,16 +826,10 @@ static int sdhci_am654_probe(struct platform_device *pdev) pltfm_host->clk = clk_xin; @@ -41,7 +41,7 @@ index 3378421c9366..18a1d85910fe 100644 } sdhci_am654->base = devm_regmap_init_mmio(dev, base, -@@ -833,31 +828,47 @@ static int sdhci_am654_probe(struct platform_device *pdev) +@@ -842,31 +837,47 @@ static int sdhci_am654_probe(struct platform_device *pdev) if (IS_ERR(sdhci_am654->base)) { dev_err(dev, "Failed to initialize regmap\n"); ret = PTR_ERR(sdhci_am654->base); @@ -96,7 +96,7 @@ index 3378421c9366..18a1d85910fe 100644 err_pltfm_free: sdhci_pltfm_free(pdev); return ret; -@@ -866,23 +877,127 @@ static int sdhci_am654_probe(struct platform_device *pdev) +@@ -875,23 +886,127 @@ static int sdhci_am654_probe(struct platform_device *pdev) static int sdhci_am654_remove(struct platform_device *pdev) { struct sdhci_host *host = platform_get_drvdata(pdev); @@ -226,3 +226,6 @@ index 3378421c9366..18a1d85910fe 100644 .of_match_table = sdhci_am654_of_match, }, .probe = sdhci_am654_probe, +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0190-mmc-host-sdhci_am654.c-Modified-autosuspend-delay.patch b/recipes-kernel/linux/files/patches-6.1/0060-mmc-host-sdhci_am654.c-Modified-autosuspend-delay.patch similarity index 80% rename from recipes-kernel/linux/files/patches-5.10/0190-mmc-host-sdhci_am654.c-Modified-autosuspend-delay.patch rename to recipes-kernel/linux/files/patches-6.1/0060-mmc-host-sdhci_am654.c-Modified-autosuspend-delay.patch index fbe200b91..a7864faa9 100644 --- a/recipes-kernel/linux/files/patches-5.10/0190-mmc-host-sdhci_am654.c-Modified-autosuspend-delay.patch +++ b/recipes-kernel/linux/files/patches-6.1/0060-mmc-host-sdhci_am654.c-Modified-autosuspend-delay.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From db50b068e9ab73047d8cb1b6dad8e11c45dedd35 Mon Sep 17 00:00:00 2001 From: Bhavya Kapoor Date: Fri, 12 Aug 2022 02:52:45 +0530 -Subject: [PATCH] mmc: host: sdhci_am654.c: Modified autosuspend delay +Subject: [PATCH 60/76] mmc: host: sdhci_am654.c: Modified autosuspend delay MMC controller gets suspended automatically after 100ms of inactivity. Removed autosuspend feature by changing autosuspend delay @@ -13,7 +13,7 @@ Signed-off-by: Bhavya Kapoor 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c -index 18a1d85910fe..216a141d03a7 100644 +index 136022de43b8..0ef4eb6992fb 100644 --- a/drivers/mmc/host/sdhci_am654.c +++ b/drivers/mmc/host/sdhci_am654.c @@ -85,7 +85,7 @@ @@ -25,3 +25,6 @@ index 18a1d85910fe..216a141d03a7 100644 /* Command Queue Host Controller Interface Base address */ #define SDHCI_AM654_CQE_BASE_ADDR 0x200 +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0195-drivers-mmc-host-sdhci_am654-fix-start-loop-index.patch b/recipes-kernel/linux/files/patches-6.1/0061-drivers-mmc-host-sdhci_am654-fix-start-loop-index.patch similarity index 77% rename from recipes-kernel/linux/files/patches-5.10/0195-drivers-mmc-host-sdhci_am654-fix-start-loop-index.patch rename to recipes-kernel/linux/files/patches-6.1/0061-drivers-mmc-host-sdhci_am654-fix-start-loop-index.patch index c68563177..7321edeb3 100644 --- a/recipes-kernel/linux/files/patches-5.10/0195-drivers-mmc-host-sdhci_am654-fix-start-loop-index.patch +++ b/recipes-kernel/linux/files/patches-6.1/0061-drivers-mmc-host-sdhci_am654-fix-start-loop-index.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From ea97907d6aebba29f1b5e8cd2f595862cf1c012c Mon Sep 17 00:00:00 2001 From: Nitin Yadav Date: Mon, 28 Nov 2022 16:25:36 +0530 -Subject: [PATCH] drivers: mmc: host: sdhci_am654: fix start loop index +Subject: [PATCH 61/76] drivers: mmc: host: sdhci_am654: fix start loop index ti,otap-del-sel-legacy/ti,itap-del-sel-legacy passed from DT are currently ignored for all SD/MMC and eMMC @@ -15,10 +15,10 @@ Signed-off-by: Nitin Yadav 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c -index 216a141d03a7..a1f7351712f3 100644 +index 0ef4eb6992fb..5540cac19e4d 100644 --- a/drivers/mmc/host/sdhci_am654.c +++ b/drivers/mmc/host/sdhci_am654.c -@@ -618,7 +618,7 @@ static int sdhci_am654_get_otap_delay(struct sdhci_host *host, +@@ -615,7 +615,7 @@ static int sdhci_am654_get_otap_delay(struct sdhci_host *host, return 0; } @@ -27,3 +27,6 @@ index 216a141d03a7..a1f7351712f3 100644 ret = device_property_read_u32(dev, td[i].otap_binding, &sdhci_am654->otap_del_sel[i]); +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0196-drivers-mmc-host-sdhci_am654-update-OTAP-and-ITAP-de.patch b/recipes-kernel/linux/files/patches-6.1/0062-drivers-mmc-host-sdhci_am654-update-OTAP-and-ITAP-de.patch similarity index 88% rename from recipes-kernel/linux/files/patches-5.10/0196-drivers-mmc-host-sdhci_am654-update-OTAP-and-ITAP-de.patch rename to recipes-kernel/linux/files/patches-6.1/0062-drivers-mmc-host-sdhci_am654-update-OTAP-and-ITAP-de.patch index 90ff6b620..c6ad86148 100644 --- a/recipes-kernel/linux/files/patches-5.10/0196-drivers-mmc-host-sdhci_am654-update-OTAP-and-ITAP-de.patch +++ b/recipes-kernel/linux/files/patches-6.1/0062-drivers-mmc-host-sdhci_am654-update-OTAP-and-ITAP-de.patch @@ -1,7 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 5e42927c78fbaf2b44770c6d0088ed0f92ec1b1c Mon Sep 17 00:00:00 2001 From: Nitin Yadav Date: Mon, 28 Nov 2022 16:25:37 +0530 -Subject: [PATCH] drivers: mmc: host: sdhci_am654: update OTAP and ITAP delay +Subject: [PATCH 62/76] drivers: mmc: host: sdhci_am654: update OTAP and ITAP + delay Linux is fail to detect class U1 UHS SD cards (such as microcenter) due to incorrect OTAP and ITAP delay select values. Update OTAP and @@ -13,7 +14,7 @@ Signed-off-by: Nitin Yadav 1 file changed, 8 insertions(+) diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c -index a1f7351712f3..a00d7de095c3 100644 +index 5540cac19e4d..af3d77bc506b 100644 --- a/drivers/mmc/host/sdhci_am654.c +++ b/drivers/mmc/host/sdhci_am654.c @@ -311,6 +311,7 @@ static void sdhci_j721e_4bit_set_clock(struct sdhci_host *host, @@ -39,3 +40,6 @@ index a1f7351712f3..a00d7de095c3 100644 regmap_update_bits(sdhci_am654->base, PHY_CTRL5, CLKBUFSEL_MASK, sdhci_am654->clkbuf_sel); +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0221-dt-bindings-watchdog-ti-rti-wdt-Add-support-for-WDIO.patch b/recipes-kernel/linux/files/patches-6.1/0063-dt-bindings-watchdog-ti-rti-wdt-Add-support-for-WDIO.patch similarity index 85% rename from recipes-kernel/linux/files/patches-5.10/0221-dt-bindings-watchdog-ti-rti-wdt-Add-support-for-WDIO.patch rename to recipes-kernel/linux/files/patches-6.1/0063-dt-bindings-watchdog-ti-rti-wdt-Add-support-for-WDIO.patch index 0a8282e6a..56f566c84 100644 --- a/recipes-kernel/linux/files/patches-5.10/0221-dt-bindings-watchdog-ti-rti-wdt-Add-support-for-WDIO.patch +++ b/recipes-kernel/linux/files/patches-6.1/0063-dt-bindings-watchdog-ti-rti-wdt-Add-support-for-WDIO.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 05381e985e8caba500ffe25edb9f33dcee31d283 Mon Sep 17 00:00:00 2001 From: Li Hua Qian -Date: Fri, 7 Jul 2023 16:47:41 +0800 -Subject: [PATCH] dt-bindings: watchdog: ti,rti-wdt: Add support for +Date: Tue, 18 Jul 2023 10:10:05 +0800 +Subject: [PATCH 63/76] dt-bindings: watchdog: ti,rti-wdt: Add support for WDIOF_CARDRESET TI RTI (Real Time Interrupt) Watchdog doesn't support to record the @@ -11,16 +11,18 @@ saved to indicate whether the watchdog reset was triggered in last boot. Signed-off-by: Li Hua Qian +Reviewed-by: Guenter Roeck +Reviewed-by: Krzysztof Kozlowski --- .../bindings/watchdog/ti,rti-wdt.yaml | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml b/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml -index c1348db59374..c10c571bf3c9 100644 +index 2f33635876ff..794219eb5bbc 100644 --- a/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/ti,rti-wdt.yaml -@@ -40,6 +40,20 @@ properties: - assigned-clocks-parents: +@@ -34,6 +34,20 @@ properties: + power-domains: maxItems: 1 + memory-region: @@ -40,7 +42,7 @@ index c1348db59374..c10c571bf3c9 100644 required: - compatible - reg -@@ -53,7 +67,18 @@ examples: +@@ -47,7 +61,18 @@ examples: /* * RTI WDT in main domain on J721e SoC. Assigned clocks are used to * select the source clock for the watchdog, forcing it to tick with @@ -60,9 +62,12 @@ index c1348db59374..c10c571bf3c9 100644 */ #include -@@ -64,4 +89,5 @@ examples: +@@ -58,4 +83,5 @@ examples: power-domains = <&k3_pds 252 TI_SCI_PD_EXCLUSIVE>; assigned-clocks = <&k3_clks 252 1>; assigned-clock-parents = <&k3_clks 252 5>; + memory-region = <&wdt_reset_memory_region>; }; +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0222-arm64-dts-ti-Add-reserved-memory-for-watchdog.patch b/recipes-kernel/linux/files/patches-6.1/0064-arm64-dts-ti-Add-reserved-memory-for-watchdog.patch similarity index 83% rename from recipes-kernel/linux/files/patches-5.10/0222-arm64-dts-ti-Add-reserved-memory-for-watchdog.patch rename to recipes-kernel/linux/files/patches-6.1/0064-arm64-dts-ti-Add-reserved-memory-for-watchdog.patch index 6af594ece..cdf2007b8 100644 --- a/recipes-kernel/linux/files/patches-5.10/0222-arm64-dts-ti-Add-reserved-memory-for-watchdog.patch +++ b/recipes-kernel/linux/files/patches-6.1/0064-arm64-dts-ti-Add-reserved-memory-for-watchdog.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 71f68073c59bd4a580082edf98ffa70c54b14dba Mon Sep 17 00:00:00 2001 From: Li Hua Qian Date: Mon, 12 Jun 2023 16:21:36 +0800 -Subject: [PATCH] arm64: dts: ti: Add reserved memory for watchdog +Subject: [PATCH 64/76] arm64: dts: ti: Add reserved memory for watchdog This patch adds a reserved memory for the TI AM65X platform watchdog to reserve the specific info, triggering the watchdog reset in last boot, @@ -13,7 +13,7 @@ Signed-off-by: Li Hua Qian 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi -index 3310880e83ee..5961b0943cf5 100644 +index edd475eb898c..debd5719f32d 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi @@ -67,6 +67,12 @@ rtos_ipc_memory_region: ipc-memories@a2000000 { @@ -29,7 +29,7 @@ index 3310880e83ee..5961b0943cf5 100644 }; leds { -@@ -879,6 +885,10 @@ &mcu_r5fss0_core1 { +@@ -1495,6 +1501,10 @@ &mcu_r5fss0_core1 { mboxes = <&mailbox0_cluster1 &mbox_mcu_r5fss0_core1>; }; @@ -40,3 +40,6 @@ index 3310880e83ee..5961b0943cf5 100644 &icssg0_mdio { pinctrl-names = "default"; pinctrl-0 = <&icssg0_mdio_pins_default>; +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0223-watchdog-rit_wdt-Add-support-for-WDIOF_CARDRESET.patch b/recipes-kernel/linux/files/patches-6.1/0065-watchdog-rit_wdt-Add-support-for-WDIOF_CARDRESET.patch similarity index 86% rename from recipes-kernel/linux/files/patches-5.10/0223-watchdog-rit_wdt-Add-support-for-WDIOF_CARDRESET.patch rename to recipes-kernel/linux/files/patches-6.1/0065-watchdog-rit_wdt-Add-support-for-WDIOF_CARDRESET.patch index 7fb637732..5a698002f 100644 --- a/recipes-kernel/linux/files/patches-5.10/0223-watchdog-rit_wdt-Add-support-for-WDIOF_CARDRESET.patch +++ b/recipes-kernel/linux/files/patches-6.1/0065-watchdog-rit_wdt-Add-support-for-WDIOF_CARDRESET.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 46d3aa292c29267c1b0841ed2b966200dc3609bd Mon Sep 17 00:00:00 2001 From: Li Hua Qian -Date: Mon, 12 Jun 2023 16:21:36 +0800 -Subject: [PATCH] watchdog:rit_wdt: Add support for WDIOF_CARDRESET +Date: Tue, 18 Jul 2023 10:10:07 +0800 +Subject: [PATCH 65/76] watchdog:rit_wdt: Add support for WDIOF_CARDRESET This patch adds the WDIOF_CARDRESET support for the platform watchdog whose hardware does not support this feature, to know if the board @@ -11,12 +11,13 @@ This is done via reserved memory(RAM), which indicates if specific info saved, triggering the watchdog reset in last boot. Signed-off-by: Li Hua Qian +Reviewed-by: Guenter Roeck --- drivers/watchdog/rti_wdt.c | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c -index 15a476b8aa78..6821bd5a42d6 100644 +index 6e9253761fc1..38de325fc347 100644 --- a/drivers/watchdog/rti_wdt.c +++ b/drivers/watchdog/rti_wdt.c @@ -14,6 +14,8 @@ @@ -40,7 +41,7 @@ index 15a476b8aa78..6821bd5a42d6 100644 static int heartbeat = DEFAULT_HEARTBEAT; /* -@@ -215,6 +222,11 @@ static int rti_wdt_probe(struct platform_device *pdev) +@@ -198,6 +205,11 @@ static int rti_wdt_probe(struct platform_device *pdev) struct rti_wdt_device *wdt; struct clk *clk; u32 last_ping = 0; @@ -52,7 +53,7 @@ index 15a476b8aa78..6821bd5a42d6 100644 wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); if (!wdt) -@@ -303,6 +315,42 @@ static int rti_wdt_probe(struct platform_device *pdev) +@@ -284,6 +296,42 @@ static int rti_wdt_probe(struct platform_device *pdev) } } @@ -95,3 +96,6 @@ index 15a476b8aa78..6821bd5a42d6 100644 watchdog_init_timeout(wdd, heartbeat, dev); ret = watchdog_register_device(wdd); +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0053-PCI-keystone-Convert-to-using-hierarchy-domain-for-l.patch b/recipes-kernel/linux/files/patches-6.1/0066-PCI-keystone-Convert-to-using-hierarchy-domain-for-l.patch similarity index 87% rename from recipes-kernel/linux/files/patches-5.10/0053-PCI-keystone-Convert-to-using-hierarchy-domain-for-l.patch rename to recipes-kernel/linux/files/patches-6.1/0066-PCI-keystone-Convert-to-using-hierarchy-domain-for-l.patch index d7af72844..f8dbc142d 100644 --- a/recipes-kernel/linux/files/patches-5.10/0053-PCI-keystone-Convert-to-using-hierarchy-domain-for-l.patch +++ b/recipes-kernel/linux/files/patches-6.1/0066-PCI-keystone-Convert-to-using-hierarchy-domain-for-l.patch @@ -1,21 +1,23 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From f04c1dba18f8e7debee799a18859d771170443dd Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I -Date: Tue, 30 Mar 2021 17:24:47 +0530 -Subject: [PATCH] PCI: keystone: Convert to using hierarchy domain for legacy - interrupts +Date: Tue, 11 Jul 2023 18:02:22 +0530 +Subject: [PATCH 66/76] PCI: keystone: Convert to using hierarchy domain for + legacy interrupts K2G provides separate IRQ lines for each of the four legacy interrupts. Model this using hierarchy domain instead of linear domain with chained IRQ handler. Signed-off-by: Kishon Vijay Abraham I +Signed-off-by: Achal Verma +Link: https://lore.kernel.org/linux-pci/20210325090026.8843-5-kishon@ti.com/ Signed-off-by: Vignesh Raghavendra --- - drivers/pci/controller/dwc/pci-keystone.c | 214 ++++++++++++---------- - 1 file changed, 120 insertions(+), 94 deletions(-) + drivers/pci/controller/dwc/pci-keystone.c | 211 ++++++++++++---------- + 1 file changed, 120 insertions(+), 91 deletions(-) diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c -index 90482d5246ff..0493e43ba416 100644 +index 78818853af9e..44545536641d 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -69,6 +69,7 @@ @@ -34,7 +36,7 @@ index 90482d5246ff..0493e43ba416 100644 struct device_node *legacy_intc_np; int msi_host_irq; -@@ -124,7 +124,6 @@ struct keystone_pcie { +@@ -125,7 +125,6 @@ struct keystone_pcie { struct phy **phy; struct device_link **link; struct device_node *msi_intc_np; @@ -42,7 +44,7 @@ index 90482d5246ff..0493e43ba416 100644 struct device_node *np; /* Application register space */ -@@ -252,26 +251,6 @@ static int ks_pcie_msi_host_init(struct pcie_port *pp) +@@ -253,24 +252,6 @@ static int ks_pcie_msi_host_init(struct dw_pcie_rp *pp) return dw_pcie_allocate_domains(pp); } @@ -52,24 +54,22 @@ index 90482d5246ff..0493e43ba416 100644 - struct dw_pcie *pci = ks_pcie->pci; - struct device *dev = pci->dev; - u32 pending; -- int virq; - - pending = ks_pcie_app_readl(ks_pcie, IRQ_STATUS(offset)); - - if (BIT(0) & pending) { -- virq = irq_linear_revmap(ks_pcie->legacy_irq_domain, offset); -- dev_dbg(dev, ": irq: irq_offset %d, virq %d\n", offset, virq); -- generic_handle_irq(virq); +- dev_dbg(dev, ": irq: irq_offset %d", offset); +- generic_handle_domain_irq(ks_pcie->legacy_irq_domain, offset); - } - - /* EOI the INTx interrupt */ - ks_pcie_app_writel(ks_pcie, IRQ_EOI, offset); -} - - /* - * Dummy function so that DW core doesn't configure MSI - */ -@@ -317,39 +296,120 @@ static irqreturn_t ks_pcie_handle_error_irq(struct keystone_pcie *ks_pcie) + static void ks_pcie_enable_error_irq(struct keystone_pcie *ks_pcie) + { + ks_pcie_app_writel(ks_pcie, ERR_IRQ_ENABLE_SET, ERR_IRQ_ALL); +@@ -308,39 +289,120 @@ static irqreturn_t ks_pcie_handle_error_irq(struct keystone_pcie *ks_pcie) return IRQ_HANDLED; } @@ -155,7 +155,7 @@ index 90482d5246ff..0493e43ba416 100644 + + ret = irq_domain_alloc_irqs_parent(domain, virq, 1, &parent_fwspec); + if (ret < 0) { -+ pr_err("Failed to allocate parent IRQ %u: %d\n", ++ pr_err("Failed to allocate parent irq %u: %d\n", + parent_fwspec.param[0], ret); + return ret; + } @@ -205,13 +205,12 @@ index 90482d5246ff..0493e43ba416 100644 }; /** -@@ -616,35 +676,6 @@ static void ks_pcie_msi_irq_handler(struct irq_desc *desc) +@@ -605,34 +667,6 @@ static void ks_pcie_msi_irq_handler(struct irq_desc *desc) chained_irq_exit(chip, desc); } -/** - * ks_pcie_legacy_irq_handler() - Handle legacy interrupt -- * @irq: IRQ line for legacy interrupts - * @desc: Pointer to irq descriptor - * - * Traverse through pending legacy interrupts and invoke handler for each. Also @@ -241,7 +240,7 @@ index 90482d5246ff..0493e43ba416 100644 static int ks_pcie_config_msi_irq(struct keystone_pcie *ks_pcie) { struct device *dev = ks_pcie->pci->dev; -@@ -704,20 +735,33 @@ static int ks_pcie_config_legacy_irq(struct keystone_pcie *ks_pcie) +@@ -692,20 +726,33 @@ static int ks_pcie_config_legacy_irq(struct keystone_pcie *ks_pcie) struct device *dev = ks_pcie->pci->dev; struct irq_domain *legacy_irq_domain; struct device_node *np = ks_pcie->np; @@ -267,14 +266,14 @@ index 90482d5246ff..0493e43ba416 100644 + + parent_node = of_irq_find_parent(intc_np); + if (!parent_node) { -+ dev_err(dev, "Unable to obtain parent node\n"); ++ dev_err(dev, "unable to obtain parent node\n"); + ret = -ENXIO; + goto err; + } + + parent_domain = irq_find_host(parent_node); + if (!parent_domain) { -+ dev_err(dev, "Unable to obtain parent domain\n"); ++ dev_err(dev, "unable to obtain parent domain\n"); + ret = -ENXIO; + goto err; + } @@ -283,7 +282,7 @@ index 90482d5246ff..0493e43ba416 100644 irq_count = of_irq_count(intc_np); if (!irq_count) { -@@ -726,31 +770,13 @@ static int ks_pcie_config_legacy_irq(struct keystone_pcie *ks_pcie) +@@ -714,31 +761,13 @@ static int ks_pcie_config_legacy_irq(struct keystone_pcie *ks_pcie) goto err; } @@ -317,3 +316,6 @@ index 90482d5246ff..0493e43ba416 100644 err: of_node_put(intc_np); +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0054-PCI-keystone-Add-PCI-legacy-interrupt-support-for-AM.patch b/recipes-kernel/linux/files/patches-6.1/0067-PCI-keystone-Add-PCI-legacy-interrupt-support-for-AM.patch similarity index 78% rename from recipes-kernel/linux/files/patches-5.10/0054-PCI-keystone-Add-PCI-legacy-interrupt-support-for-AM.patch rename to recipes-kernel/linux/files/patches-6.1/0067-PCI-keystone-Add-PCI-legacy-interrupt-support-for-AM.patch index bea73360a..cb92dbbee 100644 --- a/recipes-kernel/linux/files/patches-5.10/0054-PCI-keystone-Add-PCI-legacy-interrupt-support-for-AM.patch +++ b/recipes-kernel/linux/files/patches-6.1/0067-PCI-keystone-Add-PCI-legacy-interrupt-support-for-AM.patch @@ -1,7 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 243468780e9e5fa758b3f6bce19c6dac921f0a9c Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I -Date: Tue, 30 Mar 2021 17:24:48 +0530 -Subject: [PATCH] PCI: keystone: Add PCI legacy interrupt support for AM654 +Date: Tue, 11 Jul 2023 18:02:23 +0530 +Subject: [PATCH 67/76] PCI: keystone: Add PCI legacy interrupt support for + AM654 Add PCI legacy interrupt support for AM654. AM654 has a single HW interrupt line for all the four legacy interrupts INTA/INTB/INTC/INTD. @@ -14,13 +15,15 @@ legacy interrupt and re-triggers pulse interrupt invoking the handler again. Signed-off-by: Kishon Vijay Abraham I +Signed-off-by: Achal Verma +Link: https://lore.kernel.org/linux-pci/20210325090026.8843-6-kishon@ti.com/ Signed-off-by: Vignesh Raghavendra --- - drivers/pci/controller/dwc/pci-keystone.c | 80 ++++++++++++++++++++++- - 1 file changed, 78 insertions(+), 2 deletions(-) + drivers/pci/controller/dwc/pci-keystone.c | 87 +++++++++++++++++++++-- + 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c -index 0493e43ba416..0460ed2a277a 100644 +index 44545536641d..5797818860e5 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -118,6 +118,7 @@ struct keystone_pcie { @@ -31,7 +34,7 @@ index 0493e43ba416..0460ed2a277a 100644 int msi_host_irq; int num_lanes; -@@ -296,6 +297,29 @@ static irqreturn_t ks_pcie_handle_error_irq(struct keystone_pcie *ks_pcie) +@@ -289,6 +290,29 @@ static irqreturn_t ks_pcie_handle_error_irq(struct keystone_pcie *ks_pcie) return IRQ_HANDLED; } @@ -61,7 +64,7 @@ index 0493e43ba416..0460ed2a277a 100644 void ks_pcie_irq_eoi(struct irq_data *data) { struct keystone_pcie *ks_pcie = irq_data_get_irq_chip_data(data); -@@ -730,6 +754,54 @@ static int ks_pcie_config_msi_irq(struct keystone_pcie *ks_pcie) +@@ -721,6 +745,54 @@ static int ks_pcie_config_msi_irq(struct keystone_pcie *ks_pcie) return ret; } @@ -102,7 +105,7 @@ index 0493e43ba416..0460ed2a277a 100644 + legacy_irq_domain = irq_domain_add_linear(intc_np, PCI_NUM_INTX, + &ks_pcie_am654_irq_domain_ops, ks_pcie); + if (!legacy_irq_domain) { -+ dev_err(dev, "Failed to add IRQ domain for legacy IRQS\n"); ++ dev_err(dev, "Failed to add irq domain for legacy irqs\n"); + return -EINVAL; + } + ks_pcie->legacy_irq_domain = legacy_irq_domain; @@ -116,20 +119,29 @@ index 0493e43ba416..0460ed2a277a 100644 static int ks_pcie_config_legacy_irq(struct keystone_pcie *ks_pcie) { struct device *dev = ks_pcie->pci->dev; -@@ -837,10 +909,14 @@ static int __init ks_pcie_host_init(struct pcie_port *pp) +@@ -835,12 +907,17 @@ static int __init ks_pcie_host_init(struct dw_pcie_rp *pp) int ret; pp->bridge->ops = &ks_pcie_ops; - if (!ks_pcie->is_am6) -+ +- pp->bridge->child_ops = &ks_child_pcie_ops; + +- ret = ks_pcie_config_legacy_irq(ks_pcie); +- if (ret) +- return ret; + if (!ks_pcie->is_am6) { - pp->bridge->child_ops = &ks_child_pcie_ops; ++ pp->bridge->child_ops = &ks_child_pcie_ops; + ret = ks_pcie_config_legacy_irq(ks_pcie); ++ if (ret) ++ return ret; + } else { + ret = ks_pcie_am654_config_legacy_irq(ks_pcie); ++ if (ret) ++ return ret; + } -- ret = ks_pcie_config_legacy_irq(ks_pcie); + ret = ks_pcie_config_msi_irq(ks_pcie); if (ret) - return ret; - +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0055-PCI-keystone-Add-workaround-for-Errata-i2037-AM65x-S.patch b/recipes-kernel/linux/files/patches-6.1/0068-PCI-keystone-Add-workaround-for-Errata-i2037-AM65x-S.patch similarity index 68% rename from recipes-kernel/linux/files/patches-5.10/0055-PCI-keystone-Add-workaround-for-Errata-i2037-AM65x-S.patch rename to recipes-kernel/linux/files/patches-6.1/0068-PCI-keystone-Add-workaround-for-Errata-i2037-AM65x-S.patch index 334e638d5..d90990bb0 100644 --- a/recipes-kernel/linux/files/patches-5.10/0055-PCI-keystone-Add-workaround-for-Errata-i2037-AM65x-S.patch +++ b/recipes-kernel/linux/files/patches-6.1/0068-PCI-keystone-Add-workaround-for-Errata-i2037-AM65x-S.patch @@ -1,34 +1,33 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 003813dc21974d394af737ea2fb1f7f1b1833b35 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I -Date: Tue, 30 Mar 2021 17:24:49 +0530 -Subject: [PATCH] PCI: keystone: Add workaround for Errata #i2037 (AM65x SR - 1.0) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Date: Tue, 11 Jul 2023 18:02:26 +0530 +Subject: [PATCH 68/76] PCI: keystone: Add workaround for Errata #i2037 (AM65x + SR 1.0) Errata #i2037 in AM65x/DRA80xM Processors Silicon Revision 1.0 -(Silicon Errata SPRZ452E–July 2018–Revised June 2020 [1]) mentions -when an inbound PCIe TLP spans more than two internal AXI 128-byte -bursts, the bus may corrupt the packet payload and the corrupt data -may cause associated applications or the processor to hang. +(SPRZ452D_July 2018_Revised December 2019 [1]) mentions when an +inbound PCIe TLP spans more than two internal AXI 128-byte bursts, +the bus may corrupt the packet payload and the corrupt data may +cause associated applications or the processor to hang. The workaround for Errata #i2037 is to limit the maximum read -request size and maximum payload size to 128 bytes. Add workaround +request size and maximum payload size to 128 Bytes. Add workaround for Errata #i2037 here. The errata and workaround is applicable only to AM65x SR 1.0 and later versions of the silicon will have this fixed. -[1] -> https://www.ti.com/lit/er/sprz452e/sprz452e.pdf +[1] -> http://www.ti.com/lit/er/sprz452d/sprz452d.pdf Signed-off-by: Kishon Vijay Abraham I +Signed-off-by: Achal Verma +Link: https://lore.kernel.org/linux-pci/20210325090026.8843-7-kishon@ti.com/ Signed-off-by: Vignesh Raghavendra --- drivers/pci/controller/dwc/pci-keystone.c | 42 +++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c -index 0460ed2a277a..bb7190400ba8 100644 +index 5797818860e5..fefb375a777a 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -35,6 +35,11 @@ @@ -52,7 +51,7 @@ index 0460ed2a277a..bb7190400ba8 100644 struct ks_pcie_of_data { enum dw_pcie_device_mode mode; const struct dw_pcie_host_ops *host_ops; -@@ -621,7 +628,11 @@ static int ks_pcie_start_link(struct dw_pcie *pci) +@@ -614,7 +621,11 @@ static int ks_pcie_start_link(struct dw_pcie *pci) static void ks_pcie_quirk(struct pci_dev *dev) { struct pci_bus *bus = dev->bus; @@ -63,9 +62,9 @@ index 0460ed2a277a..bb7190400ba8 100644 + static const struct pci_device_id rc_pci_devids[] = { { PCI_DEVICE(PCI_VENDOR_ID_TI, PCIE_RC_K2HK), - .class = PCI_CLASS_BRIDGE_PCI << 8, .class_mask = ~0, }, -@@ -633,6 +644,11 @@ static void ks_pcie_quirk(struct pci_dev *dev) - .class = PCI_CLASS_BRIDGE_PCI << 8, .class_mask = ~0, }, + .class = PCI_CLASS_BRIDGE_PCI_NORMAL, .class_mask = ~0, }, +@@ -626,6 +637,11 @@ static void ks_pcie_quirk(struct pci_dev *dev) + .class = PCI_CLASS_BRIDGE_PCI_NORMAL, .class_mask = ~0, }, { 0, }, }; + static const struct pci_device_id am6_pci_devids[] = { @@ -76,14 +75,14 @@ index 0460ed2a277a..bb7190400ba8 100644 if (pci_is_root_bus(bus)) bridge = dev; -@@ -658,6 +674,32 @@ static void ks_pcie_quirk(struct pci_dev *dev) +@@ -651,6 +667,32 @@ static void ks_pcie_quirk(struct pci_dev *dev) pcie_set_readrq(dev, 256); } } + + /* + * Memory transactions fail with PCI controller in AM654 PG1.0 -+ * when MRRS is set to more than 128 bytes. Force the MRRS to ++ * when MRRS is set to more than 128 Bytes. Force the MRRS to + * 128 Bytes in all downstream devices. + */ + if (pci_match_id(am6_pci_devids, bridge)) { @@ -102,10 +101,13 @@ index 0460ed2a277a..bb7190400ba8 100644 + return; + + if (pcie_get_readrq(dev) > 128) { -+ dev_info(&dev->dev, "limiting MRRS to 128 bytes\n"); ++ dev_info(&dev->dev, "limiting MRRS to 128\n"); + pcie_set_readrq(dev, 128); + } + } } DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, ks_pcie_quirk); +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0056-arm64-dts-ti-k3-am65-main-Add-properties-to-support-.patch b/recipes-kernel/linux/files/patches-6.1/0069-arm64-dts-ti-k3-am65-main-Add-properties-to-support-.patch similarity index 52% rename from recipes-kernel/linux/files/patches-5.10/0056-arm64-dts-ti-k3-am65-main-Add-properties-to-support-.patch rename to recipes-kernel/linux/files/patches-6.1/0069-arm64-dts-ti-k3-am65-main-Add-properties-to-support-.patch index df89edf56..5b582072e 100644 --- a/recipes-kernel/linux/files/patches-5.10/0056-arm64-dts-ti-k3-am65-main-Add-properties-to-support-.patch +++ b/recipes-kernel/linux/files/patches-6.1/0069-arm64-dts-ti-k3-am65-main-Add-properties-to-support-.patch @@ -1,36 +1,25 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 7a1369dcd267d5adbab902451a37cedb9c37948e Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I -Date: Tue, 30 Mar 2021 17:38:07 +0530 -Subject: [PATCH] arm64: dts: ti: k3-am65-main: Add properties to support +Date: Tue, 11 Jul 2023 18:02:25 +0530 +Subject: [PATCH 69/76] arm64: dts: ti: k3-am65-main: Add properties to support legacy interrupts Add DT properties in PCIe DT node to support legacy interrupts. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Sekhar Nori +Signed-off-by: Achal Verma +Link: https://serenity.dal.design.ti.com/patchwork/project/linux-patch-review/patch/20210330120812.23944-10-kishon@ti.com/ Signed-off-by: Vignesh Raghavendra -[Jan: rebased over upstream] -Signed-off-by: Jan Kiszka --- - arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 34 +++++++++++++++++++++--- - 1 file changed, 30 insertions(+), 4 deletions(-) + arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 26 ++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -index 9f8031fe6d08..49f731818961 100644 +index 231634fdc469..b781aea9979c 100644 --- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi -@@ -699,8 +699,8 @@ pcie0_rc: pcie@5500000 { - power-domains = <&k3_pds 120 TI_SCI_PD_EXCLUSIVE>; - #address-cells = <3>; - #size-cells = <2>; -- ranges = <0x81000000 0 0 0x0 0x10020000 0 0x00010000 -- 0x82000000 0 0x10030000 0x0 0x10030000 0 0x07FD0000>; -+ ranges = <0x81000000 0 0 0x0 0x10020000 0 0x00010000>, -+ <0x82000000 0 0x10030000 0x0 0x10030000 0 0x07FD0000>; - ti,syscon-pcie-id = <&pcie_devid>; - ti,syscon-pcie-mode = <&pcie0_mode>; - bus-range = <0x0 0xff>; -@@ -710,6 +710,19 @@ pcie0_rc: pcie@5500000 { +@@ -706,6 +706,19 @@ pcie0_rc: pcie@5500000 { interrupts = ; msi-map = <0x0 &gic_its 0x0 0x10000>; device_type = "pci"; @@ -50,18 +39,7 @@ index 9f8031fe6d08..49f731818961 100644 }; pcie0_ep: pcie-ep@5500000 { -@@ -732,8 +745,8 @@ pcie1_rc: pcie@5600000 { - power-domains = <&k3_pds 121 TI_SCI_PD_EXCLUSIVE>; - #address-cells = <3>; - #size-cells = <2>; -- ranges = <0x81000000 0 0 0x0 0x18020000 0 0x00010000 -- 0x82000000 0 0x18030000 0x0 0x18030000 0 0x07FD0000>; -+ ranges = <0x81000000 0 0 0x0 0x18020000 0 0x00010000>, -+ <0x82000000 0 0x18030000 0x0 0x18030000 0 0x07FD0000>; - ti,syscon-pcie-id = <&pcie_devid>; - ti,syscon-pcie-mode = <&pcie1_mode>; - bus-range = <0x0 0xff>; -@@ -743,6 +756,19 @@ pcie1_rc: pcie@5600000 { +@@ -739,6 +752,19 @@ pcie1_rc: pcie@5600000 { interrupts = ; msi-map = <0x0 &gic_its 0x10000 0x10000>; device_type = "pci"; @@ -81,3 +59,6 @@ index 9f8031fe6d08..49f731818961 100644 }; pcie1_ep: pcie-ep@5600000 { +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0102-HACK-setting-the-RJ45-port-led-behavior.patch b/recipes-kernel/linux/files/patches-6.1/0070-HACK-setting-the-RJ45-port-led-behavior.patch similarity index 76% rename from recipes-kernel/linux/files/patches-5.10/0102-HACK-setting-the-RJ45-port-led-behavior.patch rename to recipes-kernel/linux/files/patches-6.1/0070-HACK-setting-the-RJ45-port-led-behavior.patch index 157e37a26..f13736f66 100644 --- a/recipes-kernel/linux/files/patches-5.10/0102-HACK-setting-the-RJ45-port-led-behavior.patch +++ b/recipes-kernel/linux/files/patches-6.1/0070-HACK-setting-the-RJ45-port-led-behavior.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 43506f37c26f592a6a30d0a14777d9e8d79f6ccc Mon Sep 17 00:00:00 2001 From: zengchao Date: Wed, 6 Nov 2019 11:21:49 +0800 -Subject: [PATCH] HACK: setting the RJ45 port led behavior +Subject: [PATCH 70/76] HACK: setting the RJ45 port led behavior Temporary needed until we have a proper, likely LED-class based solution upstream. @@ -12,10 +12,10 @@ Signed-off-by: zengchao 1 file changed, 7 insertions(+) diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c -index 5fabcd15ef77..dcf61ec6eee6 100644 +index f7436191fa80..e8950dcd6506 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c -@@ -54,6 +54,10 @@ +@@ -55,6 +55,10 @@ #define DP83867_10M_SGMII_CFG 0x016F #define DP83867_10M_SGMII_RATE_ADAPT_MASK BIT(7) @@ -26,7 +26,7 @@ index 5fabcd15ef77..dcf61ec6eee6 100644 #define DP83867_SW_RESET BIT(15) #define DP83867_SW_RESTART BIT(14) -@@ -485,6 +489,9 @@ static int dp83867_verify_rgmii_cfg(struct phy_device *phydev) +@@ -520,6 +524,9 @@ static int dp83867_verify_rgmii_cfg(struct phy_device *phydev) return -EINVAL; } @@ -36,3 +36,6 @@ index 5fabcd15ef77..dcf61ec6eee6 100644 return 0; } +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0071-tee-optee-Fix-supplicant-based-device-enumeration.patch b/recipes-kernel/linux/files/patches-6.1/0071-tee-optee-Fix-supplicant-based-device-enumeration.patch new file mode 100644 index 000000000..d03d1977a --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0071-tee-optee-Fix-supplicant-based-device-enumeration.patch @@ -0,0 +1,130 @@ +From 66602ceb7b0097f80ecdf295668b9d864026127a Mon Sep 17 00:00:00 2001 +From: Sumit Garg +Date: Fri, 28 Jul 2023 19:18:32 +0530 +Subject: [PATCH 71/76] tee: optee: Fix supplicant based device enumeration + +Currently supplicant dependent optee device enumeration only registers +devices whenever tee-supplicant is invoked for the first time. But it +forgets to remove devices when tee-supplicant daemon stops running and +closes its context gracefully. This leads to following error for fTPM +driver during reboot/shutdown: + +[ 73.466791] tpm tpm0: ftpm_tee_tpm_op_send: SUBMIT_COMMAND invoke error: 0xffff3024 + +Fix this by separating supplicant dependent devices so that the +user-space service can detach supplicant devices before closing the +supplicant. While at it use the global system workqueue for OP-TEE bus +scanning work rather than our own custom one. + +Reported-by: Jan Kiszka +Link: https://github.com/OP-TEE/optee_os/issues/6094 +Fixes: 5f178bb71e3a ("optee: enable support for multi-stage bus enumeration") +Signed-off-by: Sumit Garg +Tested-by: Masahisa Kojima +--- + drivers/tee/optee/core.c | 13 ++----------- + drivers/tee/optee/device.c | 13 ++++++++++--- + drivers/tee/optee/optee_private.h | 2 -- + 3 files changed, 12 insertions(+), 16 deletions(-) + +diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c +index daf07737c4fd..52c08055826b 100644 +--- a/drivers/tee/optee/core.c ++++ b/drivers/tee/optee/core.c +@@ -15,7 +15,6 @@ + #include + #include + #include +-#include + #include "optee_private.h" + + int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm, +@@ -110,12 +109,7 @@ int optee_open(struct tee_context *ctx, bool cap_memref_null) + + if (!optee->scan_bus_done) { + INIT_WORK(&optee->scan_bus_work, optee_bus_scan); +- optee->scan_bus_wq = create_workqueue("optee_bus_scan"); +- if (!optee->scan_bus_wq) { +- kfree(ctxdata); +- return -ECHILD; +- } +- queue_work(optee->scan_bus_wq, &optee->scan_bus_work); ++ schedule_work(&optee->scan_bus_work); + optee->scan_bus_done = true; + } + } +@@ -158,10 +152,7 @@ void optee_release_supp(struct tee_context *ctx) + struct optee *optee = tee_get_drvdata(ctx->teedev); + + optee_release_helper(ctx, optee_close_session_helper); +- if (optee->scan_bus_wq) { +- destroy_workqueue(optee->scan_bus_wq); +- optee->scan_bus_wq = NULL; +- } ++ + optee_supp_release(&optee->supp); + } + +diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c +index 64f0e047c23d..78fc0a15c463 100644 +--- a/drivers/tee/optee/device.c ++++ b/drivers/tee/optee/device.c +@@ -60,9 +60,10 @@ static void optee_release_device(struct device *dev) + kfree(optee_device); + } + +-static int optee_register_device(const uuid_t *device_uuid) ++static int optee_register_device(const uuid_t *device_uuid, u32 func) + { + struct tee_client_device *optee_device = NULL; ++ const char *dev_name_fmt = NULL; + int rc; + + optee_device = kzalloc(sizeof(*optee_device), GFP_KERNEL); +@@ -71,7 +72,13 @@ static int optee_register_device(const uuid_t *device_uuid) + + optee_device->dev.bus = &tee_bus_type; + optee_device->dev.release = optee_release_device; +- if (dev_set_name(&optee_device->dev, "optee-ta-%pUb", device_uuid)) { ++ ++ if (func == PTA_CMD_GET_DEVICES_SUPP) ++ dev_name_fmt = "optee-ta-supp-%pUb"; ++ else ++ dev_name_fmt = "optee-ta-%pUb"; ++ ++ if (dev_set_name(&optee_device->dev, dev_name_fmt, device_uuid)) { + kfree(optee_device); + return -ENOMEM; + } +@@ -142,7 +149,7 @@ static int __optee_enumerate_devices(u32 func) + num_devices = shm_size / sizeof(uuid_t); + + for (idx = 0; idx < num_devices; idx++) { +- rc = optee_register_device(&device_uuid[idx]); ++ rc = optee_register_device(&device_uuid[idx], func); + if (rc) + goto out_shm; + } +diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h +index 04ae58892608..7e9b3e7cd26b 100644 +--- a/drivers/tee/optee/optee_private.h ++++ b/drivers/tee/optee/optee_private.h +@@ -154,7 +154,6 @@ struct optee_ops { + * @pool: shared memory pool + * @rpc_param_count: If > 0 number of RPC parameters to make room for + * @scan_bus_done flag if device registation was already done. +- * @scan_bus_wq workqueue to scan optee bus and register optee drivers + * @scan_bus_work workq to scan optee bus and register optee drivers + */ + struct optee { +@@ -173,7 +172,6 @@ struct optee { + struct tee_shm_pool *pool; + unsigned int rpc_param_count; + bool scan_bus_done; +- struct workqueue_struct *scan_bus_wq; + struct work_struct scan_bus_work; + }; + +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0072-efivarfs-expose-used-and-total-size.patch b/recipes-kernel/linux/files/patches-6.1/0072-efivarfs-expose-used-and-total-size.patch new file mode 100644 index 000000000..1e0e4ae18 --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0072-efivarfs-expose-used-and-total-size.patch @@ -0,0 +1,182 @@ +From 4cb194cfc1ae94218073519caca7ecf65119569d Mon Sep 17 00:00:00 2001 +From: Anisse Astier +Date: Wed, 17 May 2023 17:38:12 +0200 +Subject: [PATCH 72/76] efivarfs: expose used and total size + +When writing EFI variables, one might get errors with no other message +on why it fails. Being able to see how much is used by EFI variables +helps analyzing such issues. + +Since this is not a conventional filesystem, block size is intentionally +set to 1 instead of PAGE_SIZE. + +x86 quirks of reserved size are taken into account; so that available +and free size can be different, further helping debugging space issues. + +With this patch, one can see the remaining space in EFI variable storage +via efivarfs, like this: + + $ df -h /sys/firmware/efi/efivars/ + Filesystem Size Used Avail Use% Mounted on + efivarfs 176K 106K 66K 62% /sys/firmware/efi/efivars + +Signed-off-by: Anisse Astier +[ardb: - rename efi_reserved_space() to efivar_reserved_space() + - whitespace/coding style tweaks] +Signed-off-by: Ard Biesheuvel +--- + arch/x86/platform/efi/quirks.c | 8 +++++++ + drivers/firmware/efi/efi.c | 1 + + drivers/firmware/efi/vars.c | 12 +++++++++++ + fs/efivarfs/super.c | 39 +++++++++++++++++++++++++++++++++- + include/linux/efi.h | 11 ++++++++++ + 5 files changed, 70 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c +index b0b848d6933a..f0cc00032751 100644 +--- a/arch/x86/platform/efi/quirks.c ++++ b/arch/x86/platform/efi/quirks.c +@@ -114,6 +114,14 @@ void efi_delete_dummy_variable(void) + EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL); + } + ++u64 efivar_reserved_space(void) ++{ ++ if (efi_no_storage_paranoia) ++ return 0; ++ return EFI_MIN_RESERVE; ++} ++EXPORT_SYMBOL_GPL(efivar_reserved_space); ++ + /* + * In the nonblocking case we do not attempt to perform garbage + * collection if we do not have enough free space. Rather, we do the +diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c +index b43e5e6ddaf6..db3c0ce08e44 100644 +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -190,6 +190,7 @@ static int generic_ops_register(void) + generic_ops.get_variable = efi.get_variable; + generic_ops.get_next_variable = efi.get_next_variable; + generic_ops.query_variable_store = efi_query_variable_store; ++ generic_ops.query_variable_info = efi.query_variable_info; + + if (efi_rt_services_supported(EFI_RT_SUPPORTED_SET_VARIABLE)) { + generic_ops.set_variable = efi.set_variable; +diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c +index 0ba9f18312f5..de36d4e4bd95 100644 +--- a/drivers/firmware/efi/vars.c ++++ b/drivers/firmware/efi/vars.c +@@ -241,3 +241,15 @@ efi_status_t efivar_set_variable(efi_char16_t *name, efi_guid_t *vendor, + return status; + } + EXPORT_SYMBOL_NS_GPL(efivar_set_variable, EFIVAR); ++ ++efi_status_t efivar_query_variable_info(u32 attr, ++ u64 *storage_space, ++ u64 *remaining_space, ++ u64 *max_variable_size) ++{ ++ if (!__efivars->ops->query_variable_info) ++ return EFI_UNSUPPORTED; ++ return __efivars->ops->query_variable_info(attr, storage_space, ++ remaining_space, max_variable_size); ++} ++EXPORT_SYMBOL_NS_GPL(efivar_query_variable_info, EFIVAR); +diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c +index 6780fc81cc11..0994446a3544 100644 +--- a/fs/efivarfs/super.c ++++ b/fs/efivarfs/super.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + + #include "internal.h" + +@@ -23,8 +24,44 @@ static void efivarfs_evict_inode(struct inode *inode) + clear_inode(inode); + } + ++static int efivarfs_statfs(struct dentry *dentry, struct kstatfs *buf) ++{ ++ const u32 attr = EFI_VARIABLE_NON_VOLATILE | ++ EFI_VARIABLE_BOOTSERVICE_ACCESS | ++ EFI_VARIABLE_RUNTIME_ACCESS; ++ u64 storage_space, remaining_space, max_variable_size; ++ efi_status_t status; ++ ++ status = efivar_query_variable_info(attr, &storage_space, &remaining_space, ++ &max_variable_size); ++ if (status != EFI_SUCCESS) ++ return efi_status_to_err(status); ++ ++ /* ++ * This is not a normal filesystem, so no point in pretending it has a block ++ * size; we declare f_bsize to 1, so that we can then report the exact value ++ * sent by EFI QueryVariableInfo in f_blocks and f_bfree ++ */ ++ buf->f_bsize = 1; ++ buf->f_namelen = NAME_MAX; ++ buf->f_blocks = storage_space; ++ buf->f_bfree = remaining_space; ++ buf->f_type = dentry->d_sb->s_magic; ++ ++ /* ++ * In f_bavail we declare the free space that the kernel will allow writing ++ * when the storage_paranoia x86 quirk is active. To use more, users ++ * should boot the kernel with efi_no_storage_paranoia. ++ */ ++ if (remaining_space > efivar_reserved_space()) ++ buf->f_bavail = remaining_space - efivar_reserved_space(); ++ else ++ buf->f_bavail = 0; ++ ++ return 0; ++} + static const struct super_operations efivarfs_ops = { +- .statfs = simple_statfs, ++ .statfs = efivarfs_statfs, + .drop_inode = generic_delete_inode, + .evict_inode = efivarfs_evict_inode, + }; +diff --git a/include/linux/efi.h b/include/linux/efi.h +index 4e1bfee9675d..b8cd4db7a1bf 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -1045,6 +1045,7 @@ struct efivar_operations { + efi_set_variable_t *set_variable; + efi_set_variable_t *set_variable_nonblocking; + efi_query_variable_store_t *query_variable_store; ++ efi_query_variable_info_t *query_variable_info; + }; + + struct efivars { +@@ -1053,6 +1054,12 @@ struct efivars { + const struct efivar_operations *ops; + }; + ++#ifdef CONFIG_X86 ++u64 __attribute_const__ efivar_reserved_space(void); ++#else ++static inline u64 efivar_reserved_space(void) { return 0; } ++#endif ++ + /* + * The maximum size of VariableName + Data = 1024 + * Therefore, it's reasonable to save that much +@@ -1087,6 +1094,10 @@ efi_status_t efivar_set_variable_locked(efi_char16_t *name, efi_guid_t *vendor, + efi_status_t efivar_set_variable(efi_char16_t *name, efi_guid_t *vendor, + u32 attr, unsigned long data_size, void *data); + ++efi_status_t efivar_query_variable_info(u32 attr, u64 *storage_space, ++ u64 *remaining_space, ++ u64 *max_variable_size); ++ + #if IS_ENABLED(CONFIG_EFI_CAPSULE_LOADER) + extern bool efi_capsule_pending(int *reset_type); + +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-6.1/0073-efi-efivars-drop-kobject-from-efivars_register.patch b/recipes-kernel/linux/files/patches-6.1/0073-efi-efivars-drop-kobject-from-efivars_register.patch new file mode 100644 index 000000000..5ba91a34c --- /dev/null +++ b/recipes-kernel/linux/files/patches-6.1/0073-efi-efivars-drop-kobject-from-efivars_register.patch @@ -0,0 +1,149 @@ +From ee2c06a9ce472bd05091e7fa571bb8ff61fbdd76 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 17 Jan 2023 13:43:09 +0100 +Subject: [PATCH 73/76] efi: efivars: drop kobject from efivars_register() + +Since commit 0f5b2c69a4cb ("efi: vars: Remove deprecated 'efivars' sysfs +interface") and the removal of the sysfs interface there are no users of +the efivars kobject. + +Drop the kobject argument from efivars_register() and add a new +efivar_is_available() helper in favour of the old efivars_kobject(). + +Note that the new helper uses the prefix 'efivar' (i.e. without an 's') +for consistency with efivar_supports_writes() and the rest of the +interface (except the registration functions). + +For the benefit of drivers with optional EFI support, also provide a +dummy implementation of efivar_is_available(). + +Signed-off-by: Johan Hovold +Signed-off-by: Ard Biesheuvel +--- + drivers/firmware/efi/efi.c | 2 +- + drivers/firmware/efi/vars.c | 19 ++++++------------- + drivers/firmware/google/gsmi.c | 2 +- + fs/efivarfs/super.c | 2 +- + include/linux/efi.h | 11 +++++++---- + 5 files changed, 16 insertions(+), 20 deletions(-) + +diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c +index db3c0ce08e44..54dda4309892 100644 +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -196,7 +196,7 @@ static int generic_ops_register(void) + generic_ops.set_variable = efi.set_variable; + generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking; + } +- return efivars_register(&generic_efivars, &generic_ops, efi_kobj); ++ return efivars_register(&generic_efivars, &generic_ops); + } + + static void generic_ops_unregister(void) +diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c +index de36d4e4bd95..26a05bf37fdd 100644 +--- a/drivers/firmware/efi/vars.c ++++ b/drivers/firmware/efi/vars.c +@@ -40,37 +40,30 @@ static efi_status_t check_var_size(bool nonblocking, u32 attributes, + } + + /** +- * efivars_kobject - get the kobject for the registered efivars ++ * efivar_is_available - check if efivars is available + * +- * If efivars_register() has not been called we return NULL, +- * otherwise return the kobject used at registration time. ++ * @return true iff evivars is currently registered + */ +-struct kobject *efivars_kobject(void) ++bool efivar_is_available(void) + { +- if (!__efivars) +- return NULL; +- +- return __efivars->kobject; ++ return __efivars != NULL; + } +-EXPORT_SYMBOL_GPL(efivars_kobject); ++EXPORT_SYMBOL_GPL(efivar_is_available); + + /** + * efivars_register - register an efivars + * @efivars: efivars to register + * @ops: efivars operations +- * @kobject: @efivars-specific kobject + * + * Only a single efivars can be registered at any time. + */ + int efivars_register(struct efivars *efivars, +- const struct efivar_operations *ops, +- struct kobject *kobject) ++ const struct efivar_operations *ops) + { + if (down_interruptible(&efivars_lock)) + return -EINTR; + + efivars->ops = ops; +- efivars->kobject = kobject; + + __efivars = efivars; + +diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c +index 871bedf533a8..96ea1fa76d35 100644 +--- a/drivers/firmware/google/gsmi.c ++++ b/drivers/firmware/google/gsmi.c +@@ -1030,7 +1030,7 @@ static __init int gsmi_init(void) + } + + #ifdef CONFIG_EFI +- ret = efivars_register(&efivars, &efivar_ops, gsmi_kobj); ++ ret = efivars_register(&efivars, &efivar_ops); + if (ret) { + printk(KERN_INFO "gsmi: Failed to register efivars\n"); + sysfs_remove_files(gsmi_kobj, gsmi_attrs); +diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c +index 0994446a3544..36d5fcf2591e 100644 +--- a/fs/efivarfs/super.c ++++ b/fs/efivarfs/super.c +@@ -290,7 +290,7 @@ static struct file_system_type efivarfs_type = { + + static __init int efivarfs_init(void) + { +- if (!efivars_kobject()) ++ if (!efivar_is_available()) + return -ENODEV; + + return register_filesystem(&efivarfs_type); +diff --git a/include/linux/efi.h b/include/linux/efi.h +index b8cd4db7a1bf..953575e29da6 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -1050,7 +1050,6 @@ struct efivar_operations { + + struct efivars { + struct kset *kset; +- struct kobject *kobject; + const struct efivar_operations *ops; + }; + +@@ -1070,10 +1069,14 @@ static inline u64 efivar_reserved_space(void) { return 0; } + #define EFI_VAR_NAME_LEN 1024 + + int efivars_register(struct efivars *efivars, +- const struct efivar_operations *ops, +- struct kobject *kobject); ++ const struct efivar_operations *ops); + int efivars_unregister(struct efivars *efivars); +-struct kobject *efivars_kobject(void); ++ ++#ifdef CONFIG_EFI ++bool efivar_is_available(void); ++#else ++static inline bool efivar_is_available(void) { return false; } ++#endif + + int efivar_supports_writes(void); + +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0205-efi-expose-efivar-generic-ops-register-function.patch b/recipes-kernel/linux/files/patches-6.1/0074-efi-expose-efivar-generic-ops-register-function.patch similarity index 68% rename from recipes-kernel/linux/files/patches-5.10/0205-efi-expose-efivar-generic-ops-register-function.patch rename to recipes-kernel/linux/files/patches-6.1/0074-efi-expose-efivar-generic-ops-register-function.patch index 156405b2d..3edf2aab3 100644 --- a/recipes-kernel/linux/files/patches-5.10/0205-efi-expose-efivar-generic-ops-register-function.patch +++ b/recipes-kernel/linux/files/patches-6.1/0074-efi-expose-efivar-generic-ops-register-function.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From baec694c1e7527950e8d39f2aff2a3cf0b0d3195 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima -Date: Mon, 20 Feb 2023 14:17:19 +0900 -Subject: [PATCH] efi: expose efivar generic ops register function +Date: Mon, 7 Aug 2023 11:53:38 +0900 +Subject: [PATCH 74/76] efi: expose efivar generic ops register function This is a preparation for supporting efivar operations provided by other than efi subsystem. @@ -9,6 +9,7 @@ Both register and unregister functions are exposed so that non-efi subsystem can revert the efi generic operation. +Acked-by: Sumit Garg Co-developed-by: Ilias Apalodimas Signed-off-by: Ilias Apalodimas Signed-off-by: Masahisa Kojima @@ -18,10 +19,10 @@ Signed-off-by: Masahisa Kojima 2 files changed, 15 insertions(+) diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c -index 332739f3eded..9ac2495c60bb 100644 +index 54dda4309892..65850e445f93 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c -@@ -195,6 +195,18 @@ static void generic_ops_unregister(void) +@@ -204,6 +204,18 @@ static void generic_ops_unregister(void) efivars_unregister(&generic_efivars); } @@ -38,17 +39,20 @@ index 332739f3eded..9ac2495c60bb 100644 +EXPORT_SYMBOL_GPL(efivars_generic_ops_unregister); + #ifdef CONFIG_EFI_CUSTOM_SSDT_OVERLAYS - #define EFIVAR_SSDT_NAME_MAX 16 + #define EFIVAR_SSDT_NAME_MAX 16UL static char efivar_ssdt[EFIVAR_SSDT_NAME_MAX] __initdata; diff --git a/include/linux/efi.h b/include/linux/efi.h -index 084990390420..de9c96cdd612 100644 +index 953575e29da6..f19abc71995b 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h -@@ -1278,4 +1278,7 @@ static inline struct efi_mokvar_table_entry *efi_mokvar_entry_find( - } - #endif +@@ -1370,4 +1370,7 @@ struct linux_efi_initrd { + /* Header of a populated EFI secret area */ + #define EFI_SECRET_TABLE_HEADER_GUID EFI_GUID(0x1e74f542, 0x71dd, 0x4d66, 0x96, 0x3e, 0xef, 0x42, 0x87, 0xff, 0x17, 0x3b) +void efivars_generic_ops_register(void); +void efivars_generic_ops_unregister(void); + #endif /* _LINUX_EFI_H */ +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0206-efi-Add-EFI_ACCESS_DENIED-status-code.patch b/recipes-kernel/linux/files/patches-6.1/0075-efi-Add-EFI_ACCESS_DENIED-status-code.patch similarity index 77% rename from recipes-kernel/linux/files/patches-5.10/0206-efi-Add-EFI_ACCESS_DENIED-status-code.patch rename to recipes-kernel/linux/files/patches-6.1/0075-efi-Add-EFI_ACCESS_DENIED-status-code.patch index 6ef50c4e8..f43135846 100644 --- a/recipes-kernel/linux/files/patches-5.10/0206-efi-Add-EFI_ACCESS_DENIED-status-code.patch +++ b/recipes-kernel/linux/files/patches-6.1/0075-efi-Add-EFI_ACCESS_DENIED-status-code.patch @@ -1,10 +1,11 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 4342d5fcdf66d49c5499b9796d4bc646ec656c74 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima -Date: Mon, 20 Feb 2023 14:17:20 +0900 -Subject: [PATCH] efi: Add EFI_ACCESS_DENIED status code +Date: Mon, 7 Aug 2023 11:53:39 +0900 +Subject: [PATCH 75/76] efi: Add EFI_ACCESS_DENIED status code This commit adds the EFI_ACCESS_DENIED status code. +Acked-by: Sumit Garg Co-developed-by: Ilias Apalodimas Signed-off-by: Ilias Apalodimas Signed-off-by: Masahisa Kojima @@ -13,7 +14,7 @@ Signed-off-by: Masahisa Kojima 1 file changed, 1 insertion(+) diff --git a/include/linux/efi.h b/include/linux/efi.h -index de9c96cdd612..a02c1bdfe4b2 100644 +index f19abc71995b..776c362b086b 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -39,6 +39,7 @@ @@ -24,3 +25,6 @@ index de9c96cdd612..a02c1bdfe4b2 100644 #define EFI_TIMEOUT (18 | (1UL << (BITS_PER_LONG-1))) #define EFI_ABORTED (21 | (1UL << (BITS_PER_LONG-1))) #define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1))) +-- +2.42.0 + diff --git a/recipes-kernel/linux/files/patches-5.10/0207-efi-Add-tee-based-EFI-variable-driver.patch b/recipes-kernel/linux/files/patches-6.1/0076-efi-Add-tee-based-EFI-variable-driver.patch similarity index 89% rename from recipes-kernel/linux/files/patches-5.10/0207-efi-Add-tee-based-EFI-variable-driver.patch rename to recipes-kernel/linux/files/patches-6.1/0076-efi-Add-tee-based-EFI-variable-driver.patch index 791a7a11f..fdf1d8b20 100644 --- a/recipes-kernel/linux/files/patches-5.10/0207-efi-Add-tee-based-EFI-variable-driver.patch +++ b/recipes-kernel/linux/files/patches-6.1/0076-efi-Add-tee-based-EFI-variable-driver.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 320de024c151e124cfe96c860fe20a9e3e74edaa Mon Sep 17 00:00:00 2001 From: Masahisa Kojima -Date: Fri, 26 May 2023 03:07:47 +0200 -Subject: [PATCH] efi: Add tee-based EFI variable driver +Date: Mon, 7 Aug 2023 11:53:40 +0900 +Subject: [PATCH 76/76] efi: Add tee-based EFI variable driver When the flash is not owned by the non-secure world, accessing the EFI variables is straightforward and done via EFI Runtime Variable Services. @@ -33,31 +33,30 @@ Acked-by: Sumit Garg Co-developed-by: Ilias Apalodimas Signed-off-by: Ilias Apalodimas Signed-off-by: Masahisa Kojima -[Jan: ported to 5.10] -Signed-off-by: Jan Kiszka --- drivers/firmware/efi/Kconfig | 15 + drivers/firmware/efi/Makefile | 1 + drivers/firmware/efi/stmm/mm_communication.h | 236 +++++++ - drivers/firmware/efi/stmm/tee_stmm_efi.c | 607 +++++++++++++++++++ - 4 files changed, 859 insertions(+) + drivers/firmware/efi/stmm/tee_stmm_efi.c | 612 +++++++++++++++++++ + 4 files changed, 864 insertions(+) create mode 100644 drivers/firmware/efi/stmm/mm_communication.h create mode 100644 drivers/firmware/efi/stmm/tee_stmm_efi.c diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig -index d9895491ff34..75431115eae4 100644 +index 6787ed8dfacf..fafcfb651085 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig -@@ -263,6 +263,21 @@ config UEFI_CPER_X86 +@@ -332,3 +332,18 @@ config UEFI_CPER_X86 + bool depends on UEFI_CPER && X86 default y - ++ +config TEE_STMM_EFI -+ tristate "TEE based EFI runtime variable service driver" ++ tristate "TEE-based EFI runtime variable service driver" + depends on EFI && OPTEE && !EFI_VARS_PSTORE + help + Select this config option if TEE is compiled to include StandAloneMM -+ as a separate secure partition it has the ability to check and store ++ as a separate secure partition. It has the ability to check and store + EFI variables on an RPMB or any other non-volatile medium used by + StandAloneMM. + @@ -66,15 +65,11 @@ index d9895491ff34..75431115eae4 100644 + + To compile this driver as a module, choose M here: the module + will be called tee_stmm_efi. -+ - config EFI_DEV_PATH_PARSER - bool - depends on ACPI diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile -index d6ca2da19339..6a5b4d81672a 100644 +index 8d151e332584..d0171a121c0f 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile -@@ -42,3 +42,4 @@ obj-$(CONFIG_EFI_CAPSULE_LOADER) += capsule-loader.o +@@ -46,3 +46,4 @@ obj-$(CONFIG_EFI_CAPSULE_LOADER) += capsule-loader.o obj-$(CONFIG_EFI_EARLYCON) += earlycon.o obj-$(CONFIG_UEFI_CPER_ARM) += cper-arm.o obj-$(CONFIG_UEFI_CPER_X86) += cper-x86.o @@ -323,10 +318,10 @@ index 000000000000..52a1f32cd1eb +#endif /* _MM_COMMUNICATION_H_ */ diff --git a/drivers/firmware/efi/stmm/tee_stmm_efi.c b/drivers/firmware/efi/stmm/tee_stmm_efi.c new file mode 100644 -index 000000000000..ece95bf1ff77 +index 000000000000..e03475966dc1 --- /dev/null +++ b/drivers/firmware/efi/stmm/tee_stmm_efi.c -@@ -0,0 +1,607 @@ +@@ -0,0 +1,612 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * EFI variable service via TEE @@ -336,7 +331,6 @@ index 000000000000..ece95bf1ff77 + +#include +#include -+#include +#include +#include +#include @@ -382,7 +376,6 @@ index 000000000000..ece95bf1ff77 +static efi_status_t tee_mm_communicate(void *comm_buf, size_t dsize) +{ + size_t buf_size; -+ efi_status_t ret; + struct efi_mm_communicate_header *mm_hdr; + struct tee_ioctl_invoke_arg arg; + struct tee_param param[4]; @@ -428,26 +421,20 @@ index 000000000000..ece95bf1ff77 + + switch (param[1].u.value.a) { + case ARM_SVC_SPM_RET_SUCCESS: -+ ret = EFI_SUCCESS; -+ break; ++ return EFI_SUCCESS; + + case ARM_SVC_SPM_RET_INVALID_PARAMS: -+ ret = EFI_INVALID_PARAMETER; -+ break; ++ return EFI_INVALID_PARAMETER; + + case ARM_SVC_SPM_RET_DENIED: -+ ret = EFI_ACCESS_DENIED; -+ break; ++ return EFI_ACCESS_DENIED; + + case ARM_SVC_SPM_RET_NO_MEMORY: -+ ret = EFI_OUT_OF_RESOURCES; -+ break; ++ return EFI_OUT_OF_RESOURCES; + + default: -+ ret = EFI_ACCESS_DENIED; ++ return EFI_ACCESS_DENIED; + } -+ -+ return ret; +} + +/** @@ -544,17 +531,15 @@ index 000000000000..ece95bf1ff77 + u8 *comm_buf = NULL; + efi_status_t ret; + -+ if (!size) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } ++ if (!size) ++ return EFI_INVALID_PARAMETER; + + payload_size = sizeof(*var_payload); + var_payload = setup_mm_hdr(&comm_buf, payload_size, + SMM_VARIABLE_FUNCTION_GET_PAYLOAD_SIZE, + &ret); -+ if (!comm_buf) -+ goto out; ++ if (!var_payload) ++ return EFI_OUT_OF_RESOURCES; + + ret = mm_communicate(comm_buf, payload_size); + if (ret != EFI_SUCCESS) @@ -593,15 +578,14 @@ index 000000000000..ece95bf1ff77 + + memset(var_property, 0, sizeof(*var_property)); + payload_size = sizeof(*smm_property) + name_size; -+ if (payload_size > max_payload_size) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } ++ if (payload_size > max_payload_size) ++ return EFI_INVALID_PARAMETER; ++ + smm_property = setup_mm_hdr( + &comm_buf, payload_size, + SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET, &ret); -+ if (!comm_buf) -+ goto out; ++ if (!smm_property) ++ return EFI_OUT_OF_RESOURCES; + + memcpy(&smm_property->guid, vendor, sizeof(smm_property->guid)); + smm_property->name_size = name_size; @@ -638,16 +622,12 @@ index 000000000000..ece95bf1ff77 + u8 *comm_buf = NULL; + efi_status_t ret; + -+ if (!name || !vendor || !data_size) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } ++ if (!name || !vendor || !data_size) ++ return EFI_INVALID_PARAMETER; + + name_size = (ucs2_strnlen(name, EFI_VAR_NAME_LEN) + 1) * sizeof(u16); -+ if (name_size > max_payload_size - MM_VARIABLE_ACCESS_HEADER_SIZE) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } ++ if (name_size > max_payload_size - MM_VARIABLE_ACCESS_HEADER_SIZE) ++ return EFI_INVALID_PARAMETER; + + /* Trim output buffer size */ + tmp_dsize = *data_size; @@ -657,12 +637,11 @@ index 000000000000..ece95bf1ff77 + name_size; + } + -+ /* Get communication buffer and initialize header */ + payload_size = MM_VARIABLE_ACCESS_HEADER_SIZE + name_size + tmp_dsize; + var_acc = setup_mm_hdr(&comm_buf, payload_size, + SMM_VARIABLE_FUNCTION_GET_VARIABLE, &ret); -+ if (!comm_buf) -+ goto out; ++ if (!var_acc) ++ return EFI_OUT_OF_RESOURCES; + + /* Fill in contents */ + memcpy(&var_acc->guid, vendor, sizeof(var_acc->guid)); @@ -671,7 +650,6 @@ index 000000000000..ece95bf1ff77 + var_acc->attr = attributes ? *attributes : 0; + memcpy(var_acc->name, name, name_size); + -+ /* Communicate */ + ret = mm_communicate(comm_buf, payload_size); + if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) + /* Update with reported data size for trimmed case */ @@ -686,12 +664,12 @@ index 000000000000..ece95bf1ff77 + if (attributes) + *attributes = var_acc->attr; + -+ if (data) -+ memcpy(data, (u8 *)var_acc->name + var_acc->name_size, -+ var_acc->data_size); -+ else ++ if (!data) { + ret = EFI_INVALID_PARAMETER; -+ ++ goto out; ++ } ++ memcpy(data, (u8 *)var_acc->name + var_acc->name_size, ++ var_acc->data_size); +out: + kfree(comm_buf); + return ret; @@ -707,24 +685,17 @@ index 000000000000..ece95bf1ff77 + u8 *comm_buf = NULL; + efi_status_t ret; + -+ if (!name_size || !name || !guid) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } ++ if (!name_size || !name || !guid) ++ return EFI_INVALID_PARAMETER; + + out_name_size = *name_size; + in_name_size = (ucs2_strnlen(name, EFI_VAR_NAME_LEN) + 1) * sizeof(u16); + -+ if (out_name_size < in_name_size) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } ++ if (out_name_size < in_name_size) ++ return EFI_INVALID_PARAMETER; + -+ if (in_name_size > -+ max_payload_size - MM_VARIABLE_GET_NEXT_HEADER_SIZE) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } ++ if (in_name_size > max_payload_size - MM_VARIABLE_GET_NEXT_HEADER_SIZE) ++ return EFI_INVALID_PARAMETER; + + /* Trim output buffer size */ + if (out_name_size > max_payload_size - MM_VARIABLE_GET_NEXT_HEADER_SIZE) @@ -735,8 +706,8 @@ index 000000000000..ece95bf1ff77 + var_getnext = setup_mm_hdr(&comm_buf, payload_size, + SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME, + &ret); -+ if (!comm_buf) -+ goto out; ++ if (!var_getnext) ++ return EFI_OUT_OF_RESOURCES; + + /* Fill in contents */ + memcpy(&var_getnext->guid, guid, sizeof(var_getnext->guid)); @@ -745,7 +716,6 @@ index 000000000000..ece95bf1ff77 + memset((u8 *)var_getnext->name + in_name_size, 0x0, + out_name_size - in_name_size); + -+ /* Communicate */ + ret = mm_communicate(comm_buf, payload_size); + if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) { + /* Update with reported data size for trimmed case */ @@ -773,21 +743,17 @@ index 000000000000..ece95bf1ff77 + size_t name_size; + u8 *comm_buf = NULL; + -+ if (!name || name[0] == 0 || !vendor) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } -+ if (data_size > 0 && !data) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } ++ if (!name || name[0] == 0 || !vendor) ++ return EFI_INVALID_PARAMETER; ++ ++ if (data_size > 0 && !data) ++ return EFI_INVALID_PARAMETER; ++ + /* Check payload size */ + name_size = (ucs2_strnlen(name, EFI_VAR_NAME_LEN) + 1) * sizeof(u16); + payload_size = MM_VARIABLE_ACCESS_HEADER_SIZE + name_size + data_size; -+ if (payload_size > max_payload_size) { -+ ret = EFI_INVALID_PARAMETER; -+ goto out; -+ } ++ if (payload_size > max_payload_size) ++ return EFI_INVALID_PARAMETER; + + /* + * Allocate the buffer early, before switching to RW (if needed) @@ -796,8 +762,8 @@ index 000000000000..ece95bf1ff77 + */ + var_acc = setup_mm_hdr(&comm_buf, payload_size, + SMM_VARIABLE_FUNCTION_SET_VARIABLE, &ret); -+ if (!comm_buf) -+ goto out; ++ if (!var_acc) ++ return EFI_OUT_OF_RESOURCES; + + /* + * The API has the ability to override RO flags. If no RO check was @@ -822,8 +788,6 @@ index 000000000000..ece95bf1ff77 + memcpy(var_acc->name, name, name_size); + memcpy((u8 *)var_acc->name + name_size, data, data_size); + -+ -+ /* Communicate */ + ret = mm_communicate(comm_buf, payload_size); + dev_dbg(pvt_data.dev, "Set Variable %s %d %lx\n", __FILE__, __LINE__, ret); +out: @@ -840,6 +804,47 @@ index 000000000000..ece95bf1ff77 + return EFI_UNSUPPORTED; +} + ++static efi_status_t tee_query_variable_info(u32 attributes, ++ u64 *max_variable_storage_size, ++ u64 *remain_variable_storage_size, ++ u64 *max_variable_size) ++{ ++ struct smm_variable_query_info *mm_query_info; ++ size_t payload_size; ++ efi_status_t ret; ++ u8 *comm_buf; ++ ++ payload_size = sizeof(*mm_query_info); ++ mm_query_info = setup_mm_hdr(&comm_buf, payload_size, ++ SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO, ++ &ret); ++ if (!mm_query_info) ++ return EFI_OUT_OF_RESOURCES; ++ ++ mm_query_info->attr = attributes; ++ ret = mm_communicate(comm_buf, payload_size); ++ if (ret != EFI_SUCCESS) ++ goto out; ++ *max_variable_storage_size = mm_query_info->max_variable_storage; ++ *remain_variable_storage_size = ++ mm_query_info->remaining_variable_storage; ++ *max_variable_size = mm_query_info->max_variable_size; ++ ++out: ++ kfree(comm_buf); ++ return ret; ++} ++ ++static void tee_stmm_efi_close_context(void *data) ++{ ++ tee_client_close_context(pvt_data.ctx); ++} ++ ++static void tee_stmm_efi_close_session(void *data) ++{ ++ tee_client_close_session(pvt_data.ctx, pvt_data.session); ++} ++ +static int tee_stmm_efi_probe(struct device *dev) +{ + struct tee_ioctl_open_session_arg sess_arg; @@ -851,6 +856,10 @@ index 000000000000..ece95bf1ff77 + if (IS_ERR(pvt_data.ctx)) + return -ENODEV; + ++ rc = devm_add_action_or_reset(dev, tee_stmm_efi_close_context, NULL); ++ if (rc) ++ return rc; ++ + /* Open session with StMM PTA */ + memset(&sess_arg, 0, sizeof(sess_arg)); + export_uuid(sess_arg.uuid, &tee_stmm_efi_id_table[0].uuid); @@ -858,17 +867,17 @@ index 000000000000..ece95bf1ff77 + if ((rc < 0) || (sess_arg.ret != 0)) { + dev_err(dev, "tee_client_open_session failed, err: %x\n", + sess_arg.ret); -+ rc = -EINVAL; -+ goto out_ctx; ++ return -EINVAL; + } + pvt_data.session = sess_arg.session; + pvt_data.dev = dev; ++ rc = devm_add_action_or_reset(dev, tee_stmm_efi_close_session, NULL); ++ if (rc) ++ return rc; + + ret = get_max_payload(&max_payload_size); -+ if (ret != EFI_SUCCESS) { -+ rc = -EIO; -+ goto out_sess; -+ } ++ if (ret != EFI_SUCCESS) ++ return -EIO; + + max_buffer_size = MM_COMMUNICATE_HEADER_SIZE + + MM_VARIABLE_COMMUNICATE_SIZE + @@ -879,19 +888,13 @@ index 000000000000..ece95bf1ff77 + tee_efivar_ops.set_variable = tee_set_variable; + tee_efivar_ops.set_variable_nonblocking = tee_set_variable_nonblocking; + tee_efivar_ops.query_variable_store = efi_query_variable_store; ++ tee_efivar_ops.query_variable_info = tee_query_variable_info; + + efivars_generic_ops_unregister(); + pr_info("Use tee-based EFI runtime variable services\n"); -+ efivars_register(&tee_efivars, &tee_efivar_ops, NULL); ++ efivars_register(&tee_efivars, &tee_efivar_ops); + + return 0; -+ -+out_sess: -+ tee_client_close_session(pvt_data.ctx, pvt_data.session); -+out_ctx: -+ tee_client_close_context(pvt_data.ctx); -+ -+ return rc; +} + +static int tee_stmm_efi_remove(struct device *dev) @@ -899,9 +902,6 @@ index 000000000000..ece95bf1ff77 + efivars_unregister(&tee_efivars); + efivars_generic_ops_register(); + -+ tee_client_close_session(pvt_data.ctx, pvt_data.session); -+ tee_client_close_context(pvt_data.ctx); -+ + return 0; +} + @@ -934,3 +934,6 @@ index 000000000000..ece95bf1ff77 +MODULE_AUTHOR("Ilias Apalodimas "); +MODULE_AUTHOR("Masahisa Kojima "); +MODULE_DESCRIPTION("TEE based EFI runtime variable service driver"); +-- +2.42.0 + diff --git a/recipes-kernel/linux/linux-iot2050-5.10.inc b/recipes-kernel/linux/linux-iot2050-6.1.inc similarity index 80% rename from recipes-kernel/linux/linux-iot2050-5.10.inc rename to recipes-kernel/linux/linux-iot2050-6.1.inc index 2241949b8..28a21cf88 100644 --- a/recipes-kernel/linux/linux-iot2050-5.10.inc +++ b/recipes-kernel/linux/linux-iot2050-6.1.inc @@ -18,9 +18,9 @@ def get_patches(d, patchdir): return ' '.join(['file://' + patch[len(files_dir)+1:] for patch in patches]) SRC_URI += " \ - https://git.kernel.org/pub/scm/linux/kernel/git/cip/linux-cip.git/snapshot/linux-cip-${PV}.tar.gz \ - ${@get_patches(d, 'patches-5.10')} \ - file://patches-5.10/ \ + https://cdn.kernel.org/pub/linux/kernel/projects/cip/6.1/linux-cip-${PV}.tar.gz \ + ${@get_patches(d, 'patches-6.1')} \ + file://patches-6.1/ \ file://${KERNEL_DEFCONFIG} \ file://iot2050_defconfig_extra.cfg" diff --git a/recipes-kernel/linux/linux-iot2050-rt_5.10.184-cip36-rt14.bb b/recipes-kernel/linux/linux-iot2050-rt_6.1.54-cip6-rt3.bb similarity index 63% rename from recipes-kernel/linux/linux-iot2050-rt_5.10.184-cip36-rt14.bb rename to recipes-kernel/linux/linux-iot2050-rt_6.1.54-cip6-rt3.bb index f17bc8f11..e9e2d497f 100644 --- a/recipes-kernel/linux/linux-iot2050-rt_5.10.184-cip36-rt14.bb +++ b/recipes-kernel/linux/linux-iot2050-rt_6.1.54-cip6-rt3.bb @@ -5,8 +5,8 @@ # COPYING.MIT file in the top-level directory. # -require linux-iot2050-5.10.inc +require linux-iot2050-6.1.inc -SRC_URI[sha256sum] = "f45c47c9944c53920d483eb9b9be205e42c7d0af89f8c8c9bc0d3fb56a95e5c8" +SRC_URI[sha256sum] = "8c9cb5edc7318cdf8b50594003934bb1465ab8aabc76393f5f402690b2c1f071" SRC_URI += "file://iot2050-rt.cfg" diff --git a/recipes-kernel/linux/linux-iot2050_5.10.184-cip36.bb b/recipes-kernel/linux/linux-iot2050_6.1.54-cip6.bb similarity index 58% rename from recipes-kernel/linux/linux-iot2050_5.10.184-cip36.bb rename to recipes-kernel/linux/linux-iot2050_6.1.54-cip6.bb index 9c11e8ac6..a69f6395c 100644 --- a/recipes-kernel/linux/linux-iot2050_5.10.184-cip36.bb +++ b/recipes-kernel/linux/linux-iot2050_6.1.54-cip6.bb @@ -5,6 +5,6 @@ # COPYING.MIT file in the top-level directory. # -require linux-iot2050-5.10.inc +require linux-iot2050-6.1.inc -SRC_URI[sha256sum] = "a6405d852023099891f8d0530bf332c6cdba7654d6497ce83452df6ec1293152" +SRC_URI[sha256sum] = "431498a219a445a17b79c7a4467dda912e4a31e1add35684aa6e36483c898304"