All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
@ 2023-12-19 10:34 MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 01/16] dma: ti: k3-udma: Use ring_idx to pair k3 nav rings MD Danish Anwar
                   ` (15 more replies)
  0 siblings, 16 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used in TI
AM654 SR2.0.

The ICSSG PRU Sub-system runs on EMAC firmware. This series Introduces
support for ICSSG driver in uboot. This series also adds the driver's
dependencies.

The ICSSG2 node is added in device tree overlay so that it remains in
sync with linux kernel.

The series introduces device tree and config changes and AM65x
to enable ICSSG driver. The series also enables SPL_LOAD_FIT_APPLY_OVERLAY
for AM65x in order to load overlay over spl.

This series has been tested on AM65x SR2.0, and the ICSSG interface is
able to ping / dhcp and boot kernel using tftp in uboot.

To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to PRU RPROC
cores and RPROC cores need to be booted with the firmware. This step is
done inside driver in kernel as kernel supports APIs like
rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't have these
APIs, the same needs to be done via u-boot cmds.

To make sure icssg-eth works we need to
do below steps.

1. Initialize rproc cores i.e. rproc_init()
2. Load $firmware_file from partition '1:2' (root) on device (mmc in this
   example)
3. Load the firmware file to rproc cores passing. i.e. rproc_load()
   taking rproc_id, loadaddr and file size as arguments.
4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments

The above steps are done by running the below commands at u-boot prompt.

=> setenv start_icssg2 'rproc start 14; rproc start 15; rproc start 16; rproc start 17; rproc start 18; rproc start 19'
=> setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop 16; rproc stop 17; rproc stop 18; rproc stop 19'
=> setenv firmware_dir '/lib/firmware/ti-pruss'
=> setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr} ${firmware_dir}/${firmware_file}'

=> setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload no; rproc init; setenv loadaddr 0x80000000; \
    setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
    setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15 0x89000000 ${filesize}; \
    setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load 16 0x90000000 ${filesize}; \
    setenv loadaddr 0x80000000; setenv firmware_file am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17 0x80000000 ${filesize}; \
    setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18 0x89000000 ${filesize}; \
    setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load 19 0x90000000 ${filesize}; \
    run start_icssg2;'

=> run init_icssg2
=> dhcp
k3-navss-ringacc ringacc@3c000000: Ring Accelerator probed rings:818, gp-rings[304,100] sci-dev-id:187
k3-navss-ringacc ringacc@3c000000: dma-ring-reset-quirk: disabled
prueth icssg2-eth: K3 ICSSG: rflow_id_base: 8, chn_name = rx0
link up on port 0, speed 1000, full duplex
BOOTP broadcast 1
BOOTP broadcast 2
BOOTP broadcast 3
DHCP client bound to address 192.168.4.58 (1020 ms)

Thanks and Regards,
MD Danish Anwar

MD Danish Anwar (16):
  dma: ti: k3-udma: Use ring_idx to pair k3 nav rings
  net: ti: icssg: Add Firmware Interface for ICSSG Ethernet driver.
  net: ti: icssg: Add Firmware config and classification APIs.
  net: ti: icssg: Add icssg queues APIs and macros
  net: ti: icssg: Add ICSSG ethernet driver
  net: ti: icssg: Add support sending FDB command to update rx_flow_id
  net: ti: icssg: Enforce pinctrl state on the MDIO child node
  arm: dts: k3-am65: Add additional regs for DMA components
  arm: dts: k3-am65: Add cfg reg region to ringacc node
  arm: dts: k3-am65-main: Add ICSSG IEP nodes
  arm: dts: k3-am654-base-board: Add ICSSG2 Ethernet support
  arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration
  configs: am65x_evm_a53: Enable ICSSG Driver
  configs: am65x_evm_a53_defconfig: add SPL_LOAD_FIT_APPLY_OVERLAY
  tools/fdtgrep: Include __symbols__ table
  board: ti: am65x: Add check for k3-am654-icssg2 in
    board_fit_config_match()

 arch/arm/dts/Makefile             |   3 +-
 arch/arm/dts/k3-am65-main.dtsi    |  49 ++-
 arch/arm/dts/k3-am65-mcu.dtsi     |  13 +-
 arch/arm/dts/k3-am654-icssg2.dtso | 145 +++++++
 arch/arm/dts/k3-am65x-binman.dtsi |  85 ++++
 board/ti/am65x/evm.c              |  11 +-
 configs/am65x_evm_a53_defconfig   |   4 +
 drivers/dma/ti/k3-udma.c          |  11 +-
 drivers/net/ti/Kconfig            |   9 +
 drivers/net/ti/Makefile           |   1 +
 drivers/net/ti/icss_mii_rt.h      | 192 +++++++++
 drivers/net/ti/icssg_classifier.c | 376 +++++++++++++++++
 drivers/net/ti/icssg_config.c     | 469 +++++++++++++++++++++
 drivers/net/ti/icssg_config.h     | 195 +++++++++
 drivers/net/ti/icssg_prueth.c     | 654 ++++++++++++++++++++++++++++++
 drivers/net/ti/icssg_prueth.h     |  89 ++++
 drivers/net/ti/icssg_queues.c     |  51 +++
 drivers/net/ti/icssg_switch_map.h | 209 ++++++++++
 tools/fdtgrep.c                   |   8 +
 19 files changed, 2559 insertions(+), 15 deletions(-)
 create mode 100644 arch/arm/dts/k3-am654-icssg2.dtso
 create mode 100644 drivers/net/ti/icss_mii_rt.h
 create mode 100644 drivers/net/ti/icssg_classifier.c
 create mode 100644 drivers/net/ti/icssg_config.c
 create mode 100644 drivers/net/ti/icssg_config.h
 create mode 100644 drivers/net/ti/icssg_prueth.c
 create mode 100644 drivers/net/ti/icssg_prueth.h
 create mode 100644 drivers/net/ti/icssg_queues.c
 create mode 100644 drivers/net/ti/icssg_switch_map.h

base:commit: a6f86132e30a407c7f96461df53c62fbe52e2b54
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [RFC PATCH 01/16] dma: ti: k3-udma: Use ring_idx to pair k3 nav rings
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 02/16] net: ti: icssg: Add Firmware Interface for ICSSG Ethernet driver MD Danish Anwar
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Use ring_idx to pair rings. ring_idx will be same as tx flow_id for all
non-negative flow_ids. For negative flow_ids, ring_idx will be tchan->id
added with bchan_cnt.

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 drivers/dma/ti/k3-udma.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index 8a62d63dfe..eea9ec9659 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -876,13 +876,20 @@ static int udma_alloc_tx_resources(struct udma_chan *uc)
 {
 	struct k3_nav_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_nav_ringacc_request_rings_pair(ud->ringacc, uc->tchan->id, -1,
+	tchan = uc->tchan;
+	if (tchan->tflow_id >= 0)
+		ring_idx = tchan->tflow_id;
+	else
+		ring_idx = ud->bchan_cnt + tchan->id;
+
+	ret = k3_nav_ringacc_request_rings_pair(ud->ringacc, ring_idx, -1,
 						&uc->tchan->t_ring,
 						&uc->tchan->tc_ring);
 	if (ret) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 02/16] net: ti: icssg: Add Firmware Interface for ICSSG Ethernet driver.
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 01/16] dma: ti: k3-udma: Use ring_idx to pair k3 nav rings MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 03/16] net: ti: icssg: Add Firmware config and classification APIs MD Danish Anwar
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Add firmware interface related headers and macros for ICSSG Ethernet
driver. These macros will be later used by the ICSSG ethernet driver.

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 drivers/net/ti/icssg_switch_map.h | 209 ++++++++++++++++++++++++++++++
 1 file changed, 209 insertions(+)
 create mode 100644 drivers/net/ti/icssg_switch_map.h

diff --git a/drivers/net/ti/icssg_switch_map.h b/drivers/net/ti/icssg_switch_map.h
new file mode 100644
index 0000000000..ba87a44023
--- /dev/null
+++ b/drivers/net/ti/icssg_switch_map.h
@@ -0,0 +1,209 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Texas Instruments ICSSG Ethernet driver
+ *
+ * Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+#ifndef __NET_TI_ICSSG_SWITCH_MAP_H
+#define __NET_TI_ICSSG_SWITCH_MAP_H
+
+/*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
+
+/*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
+
+/*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.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 03/16] net: ti: icssg: Add Firmware config and classification APIs.
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 01/16] dma: ti: k3-udma: Use ring_idx to pair k3 nav rings MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 02/16] net: ti: icssg: Add Firmware Interface for ICSSG Ethernet driver MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 04/16] net: ti: icssg: Add icssg queues APIs and macros MD Danish Anwar
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Add icssg_config.h / .c and icssg_classifier.c files. These are firmware
configuration and classification related files. 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.

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 drivers/net/ti/icss_mii_rt.h      | 192 ++++++++++++++
 drivers/net/ti/icssg_classifier.c | 376 ++++++++++++++++++++++++++++
 drivers/net/ti/icssg_config.c     | 403 ++++++++++++++++++++++++++++++
 drivers/net/ti/icssg_config.h     | 177 +++++++++++++
 drivers/net/ti/icssg_prueth.h     |  78 ++++++
 5 files changed, 1226 insertions(+)
 create mode 100644 drivers/net/ti/icss_mii_rt.h
 create mode 100644 drivers/net/ti/icssg_classifier.c
 create mode 100644 drivers/net/ti/icssg_config.c
 create mode 100644 drivers/net/ti/icssg_config.h
 create mode 100644 drivers/net/ti/icssg_prueth.h

diff --git a/drivers/net/ti/icss_mii_rt.h b/drivers/net/ti/icss_mii_rt.h
new file mode 100644
index 0000000000..6b2449e736
--- /dev/null
+++ b/drivers/net/ti/icss_mii_rt.h
@@ -0,0 +1,192 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* PRU-ICSS MII_RT register definitions
+ *
+ * Copyright (C) 2015-2020 Texas Instruments Incorporated - http://www.ti.com
+ */
+
+#ifndef __NET_PRUSS_MII_RT_H__
+#define __NET_PRUSS_MII_RT_H__
+
+#include <regmap.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)
+
+/* 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, 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)
+#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, int speed,
+					  bool full_duplex, int slice, struct prueth *priv)
+{
+	u32 gig_en_mask, gig_val = 0, full_duplex_mask, full_duplex_val = 0;
+	u32 inband_en_mask, inband_val = 0;
+
+	gig_en_mask = (slice == 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 = (slice == ICSS_MII0) ? RGMII_CFG_INBAND_EN_MII0 :
+					RGMII_CFG_INBAND_EN_MII1;
+	if (speed == SPEED_10 && phy_interface_is_rgmii(priv->phydev))
+		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 (full_duplex)
+		full_duplex_val = full_duplex_mask;
+	regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, full_duplex_mask,
+			   full_duplex_val);
+}
+
+static inline void icssg_miig_set_interface_mode(struct regmap *miig_rt, int mii, int 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);
+}
+
+#endif /* __NET_PRUSS_MII_RT_H__ */
diff --git a/drivers/net/ti/icssg_classifier.c b/drivers/net/ti/icssg_classifier.c
new file mode 100644
index 0000000000..f2440a5a5f
--- /dev/null
+++ b/drivers/net/ti/icssg_classifier.c
@@ -0,0 +1,376 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Texas Instruments ICSSG Ethernet Driver
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ */
+
+#include <dm/ofnode.h>
+#include <regmap.h>
+
+#define ICSSG_NUM_CLASSIFIERS	16
+#define ICSSG_NUM_FT1_SLOTS	8
+#define ICSSG_NUM_FT3_SLOTS	16
+
+#define ICSSG_NUM_CLASSIFIERS_IN_USE	1
+
+/* 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 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;
+};
+
+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);
+}
+
+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));
+	regmap_write(miig_rt, offs[slice].mac1, addr_to_da1(mac));
+}
+
+void icssg_class_disable_n(struct regmap *miig_rt, int slice, int n)
+{
+	u32 data, offset;
+
+	/* 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);
+}
+
+/* disable all RX traffic */
+void icssg_class_disable(struct regmap *miig_rt, int slice)
+{
+	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++)
+		icssg_class_disable_n(miig_rt, slice, n);
+
+	/* 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)
+{
+	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 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, 6, 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/ti/icssg_config.c b/drivers/net/ti/icssg_config.c
new file mode 100644
index 0000000000..33298c3374
--- /dev/null
+++ b/drivers/net/ti/icssg_config.c
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: GPL-2.0
+/* ICSSG Ethernet driver
+ *
+ * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
+ */
+
+#include <phy.h>
+#include "icssg_prueth.h"
+#include "icssg_switch_map.h"
+#include "icss_mii_rt.h"
+#include <dm/device_compat.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.
+ */
+
+/* SR2.0 IPG is in rgmii_clk (125MHz) clock cycles + 1 */
+#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 | /* 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;
+	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 slice)
+{
+	struct regmap *mii_rt = prueth->mii_rt;
+	u32 txcfg_reg, pcnt_reg;
+	u32 txcfg;
+
+	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;
+
+	txcfg = MII_TXCFG_DEFAULT;
+
+	if (prueth->phy_interface == PHY_INTERFACE_MODE_MII && slice == ICSS_MII0)
+		txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
+	else if (prueth->phy_interface != PHY_INTERFACE_MODE_MII && slice == ICSS_MII1)
+		txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
+
+	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)
+{
+	void __iomem *smem = (void __iomem *)prueth->shram.pa;
+	struct regmap *miig_rt = prueth->miig_rt;
+	int queue = 0, i, j;
+	u8 pd[ICSSG_SPECIAL_PD_SIZE];
+	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++) {
+		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, MII_RT_TX_IPG_1G);
+		break;
+	case SPEED_100:
+		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");
+		return;
+	}
+}
+
+static void emac_r30_cmd_init(struct prueth *prueth)
+{
+	int i;
+	struct icssg_r30_cmd *p;
+
+	p = (struct icssg_r30_cmd *)(prueth->dram.pa + MGR_R30_CMD_OFFSET);
+
+	for (i = 0; i < 4; i++)
+		writel(EMAC_NONE, &p->cmd[i]);
+}
+
+static int emac_r30_is_done(struct prueth *prueth)
+{
+	const struct icssg_r30_cmd *p;
+	int i;
+	u32 cmd;
+
+	p = (const struct icssg_r30_cmd *)(prueth->dram.pa + 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 *prueth)
+{
+	struct icssg_buffer_pool_cfg *bpool_cfg;
+	struct icssg_rxq_ctx *rxq_ctx;
+	int slice = prueth->slice;
+	u32 addr;
+	int i;
+
+	/* Layout to have 64KB aligned buffer pool
+	 * |BPOOL0|BPOOL1|RX_CTX0|RX_CTX1|
+	 */
+
+	addr = lower_32_bits(prueth->sram_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 = (struct icssg_buffer_pool_cfg *)(prueth->dram.pa + 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;
+	     i < (PRUETH_EMAC_BUF_POOL_START + PRUETH_NUM_BUF_POOLS);
+	     i++) {
+		bpool_cfg[i].addr = cpu_to_le32(addr);
+		bpool_cfg[i].len = cpu_to_le32(PRUETH_EMAC_BUF_POOL_SIZE);
+		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;
+
+	rxq_ctx = (struct icssg_rxq_ctx *)(prueth->dram.pa + 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);
+
+	/* Express RX buffer queue */
+	rxq_ctx = (struct icssg_rxq_ctx *)(prueth->dram.pa + 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;
+}
+
+static void icssg_init_emac_mode(struct prueth *prueth)
+{
+	u8 mac[6] = { 0 };
+
+	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)
+{
+	void *config = (void *)(prueth->dram.pa + ICSSG_CONFIG_OFFSET);
+	u8 *cfg_byte_ptr = config;
+	struct icssg_flow_cfg *flow_cfg;
+	u32 mask;
+	int ret;
+
+	int slice = prueth->slice;
+
+	icssg_init_emac_mode(prueth);
+
+	memset_io(config, 0, TAS_GATE_MASK_LIST0);
+	icssg_miig_queues_init(prueth, slice);
+
+	prueth->speed = SPEED_1000;
+	prueth->duplex = DUPLEX_FULL;
+	if (!phy_interface_is_rgmii(prueth->phydev)) {
+		prueth->speed = SPEED_100;
+		prueth->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, prueth->phy_interface);
+	icssg_config_mii_init(prueth, slice);
+
+	icssg_config_ipg(prueth, SPEED_1000, slice);
+	icssg_update_rgmii_cfg(prueth->miig_rt, SPEED_1000, true, slice, prueth);
+
+	/* set GPI mode */
+	pruss_cfg_gpimode(prueth->pruss, 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 */
+/*	This is currently hacked into pru_rproc.c
+ *	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;
+	flow_cfg->rx_base_flow = prueth->dma_rx.id;
+	flow_cfg->mgm_base_flow = 0;
+	*(cfg_byte_ptr + SPL_PKT_DEFAULT_PRIORITY) = 0;
+	*(cfg_byte_ptr + QUEUE_NUM_UNTAGGED) = 0x0;
+
+	ret = prueth_emac_buffer_setup(prueth);
+
+	if (ret)
+		return ret;
+
+	emac_r30_cmd_init(prueth);
+	return 0;
+}
+
+/* commands to program ICSSG R30 registers */
+static struct icssg_r30_cmd emac_r32_bitmask[] = {
+	{{0xffff0004, 0xffff0100, 0xffff0004, EMAC_NONE}},	/* EMAC_PORT_DISABLE */
+	{{0xfffb0040, 0xfeff0200, 0xfeff0200, EMAC_NONE}},	/* EMAC_PORT_BLOCK */
+	{{0xffbb0000, 0xfcff0000, 0xdcfb0000, 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 *prueth,
+			enum icssg_port_state_cmd cmd)
+{
+	struct icssg_r30_cmd *p;
+	int ret = -ETIMEDOUT;
+	int timeout = 10;
+	int i;
+
+	p = (struct icssg_r30_cmd *)(prueth->dram.pa + MGR_R30_CMD_OFFSET);
+
+	if (cmd >= ICSSG_EMAC_PORT_MAX_COMMANDS) {
+		dev_err(prueth->dev, "invalid port command\n");
+		return -EINVAL;
+	}
+
+	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(prueth)) {
+			ret = 0;
+			break;
+		}
+
+		udelay(2000);
+		timeout--;
+	}
+
+	if (ret == -ETIMEDOUT)
+		dev_err(prueth->dev, "timeout waiting for command done\n");
+
+	return ret;
+}
diff --git a/drivers/net/ti/icssg_config.h b/drivers/net/ti/icssg_config.h
new file mode 100644
index 0000000000..fc6eae0426
--- /dev/null
+++ b/drivers/net/ti/icssg_config.h
@@ -0,0 +1,177 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Texas Instruments ICSSG Ethernet driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://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;
+
+/* Config area lies in shared RAM */
+#define ICSSG_CONFIG_OFFSET_SLICE0   0
+#define ICSSG_CONFIG_OFFSET_SLICE1   0x8000
+
+/* 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
+#define ICSSG_PSTATE_FULL_DUPLEX	BIT(3)
+#define ICSSG_PSTATE_SPEED_100		BIT(1)
+#define ICSSG_PSTATE_SPEED_1000		BIT(2)
+
+/* Flow IDs used in config structure to firmware. Should match with
+ * flow_id in struct dma for rx channels.
+ */
+#define ICSSG_RX_CHAN_FLOW_ID		0 /* flow id for host port */
+#define ICSSG_RX_MGM_CHAN_FLOW_ID	1 /* flow id for command response */
+
+/* Used to notify the FW of the current link speed */
+#define PORT_LINK_SPEED_OFFSET			   0x00A8
+
+#define FW_LINK_SPEED_1G                           (0x00)
+#define FW_LINK_SPEED_100M                         (0x01)
+#define FW_LINK_SPEED_10M                          (0x02)
+#define FW_LINK_SPEED_HD                           (0x80)
+
+#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_RX_FLOWS	1	/* excluding default flow */
+#define PRUETH_RX_FLOW_DATA	0	/* FIXME: f/w bug to change to highest priority flow */
+
+#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))
+
+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
+
+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
+
+#endif /* __NET_TI_ICSSG_CONFIG_H */
diff --git a/drivers/net/ti/icssg_prueth.h b/drivers/net/ti/icssg_prueth.h
new file mode 100644
index 0000000000..26b77dd8f3
--- /dev/null
+++ b/drivers/net/ti/icssg_prueth.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Texas Instruments K3 AM65 Ethernet Switch SubSystem Driver
+ *
+ * Copyright (C) 2019, Texas Instruments, Incorporated
+ *
+ */
+
+#ifndef __NET_TI_ICSSG_PRUETH_H
+#define __NET_TI_ICSSG_PRUETH_H
+
+#include <asm/io.h>
+#include <clk.h>
+#include <dm/lists.h>
+#include <dm/ofnode.h>
+#include <dm/device.h>
+#include <dma-uclass.h>
+#include <regmap.h>
+#include <linux/sizes.h>
+#include <linux/pruss_driver.h>
+#include "icssg_config.h"
+#include "icssg_switch_map.h"
+
+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);
+void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr);
+
+enum prueth_mac {
+	PRUETH_MAC0 = 0,
+	PRUETH_MAC1,
+	PRUETH_NUM_MACS,
+};
+
+enum prueth_port {
+	PRUETH_PORT_HOST = 0,	/* host side port */
+	PRUETH_PORT_MII0,	/* physical port MII 0 */
+	PRUETH_PORT_MII1,	/* physical port MII 1 */
+};
+
+struct prueth {
+	struct udevice		*dev;
+	struct udevice		*pruss;
+	struct regmap		*miig_rt;
+	struct regmap		*mii_rt;
+	fdt_addr_t		mdio_base;
+	struct pruss_mem_region shram;
+	struct pruss_mem_region dram;
+	phys_addr_t		tmaddr;
+	struct mii_dev		*bus;
+	u32			port_id;
+	u32			sram_pa;
+	struct phy_device	*phydev;
+	bool			has_phy;
+	ofnode			phy_node;
+	u32			phy_addr;
+	ofnode			eth_node[PRUETH_NUM_MACS];
+	u32			mdio_freq;
+	int			phy_interface;
+	struct			clk mdiofck;
+	struct dma		dma_tx;
+	struct dma		dma_rx;
+	struct dma		dma_rx_mgm;
+	u32			rx_next;
+	u32			rx_pend;
+	int			slice;
+	bool			mdio_manual_mode;
+	int			speed;
+	int			duplex;
+};
+
+/* config helpers */
+void icssg_config_ipg(struct prueth *prueth, int speed, int mii);
+int icssg_config(struct prueth *prueth);
+int emac_set_port_state(struct prueth *prueth, enum icssg_port_state_cmd cmd);
+
+#endif /* __NET_TI_ICSSG_PRUETH_H */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 04/16] net: ti: icssg: Add icssg queues APIs and macros
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
                   ` (2 preceding siblings ...)
  2023-12-19 10:34 ` [RFC PATCH 03/16] net: ti: icssg: Add Firmware config and classification APIs MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 05/16] net: ti: icssg: Add ICSSG ethernet driver MD Danish Anwar
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Add icssg_queue.c file. This file introduces macros and APIs related to
ICSSG queues. These will be used by ICSSG Ethernet driver.

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 drivers/net/ti/icssg_prueth.h |  5 ++++
 drivers/net/ti/icssg_queues.c | 51 +++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+)
 create mode 100644 drivers/net/ti/icssg_queues.c

diff --git a/drivers/net/ti/icssg_prueth.h b/drivers/net/ti/icssg_prueth.h
index 26b77dd8f3..f34ab5d6d4 100644
--- a/drivers/net/ti/icssg_prueth.h
+++ b/drivers/net/ti/icssg_prueth.h
@@ -75,4 +75,9 @@ void icssg_config_ipg(struct prueth *prueth, int speed, int mii);
 int icssg_config(struct prueth *prueth);
 int emac_set_port_state(struct prueth *prueth, enum icssg_port_state_cmd cmd);
 
+/* 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/ti/icssg_queues.c b/drivers/net/ti/icssg_queues.c
new file mode 100644
index 0000000000..6a95ef5d58
--- /dev/null
+++ b/drivers/net/ti/icssg_queues.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
+/* ICSSG Buffer queue helpers
+ *
+ * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com
+ */
+
+#include <dm/ofnode.h>
+#include <regmap.h>
+#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, &reg);
+
+	return reg;
+}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 05/16] net: ti: icssg: Add ICSSG ethernet driver
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
                   ` (3 preceding siblings ...)
  2023-12-19 10:34 ` [RFC PATCH 04/16] net: ti: icssg: Add icssg queues APIs and macros MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 06/16] net: ti: icssg: Add support sending FDB command to update rx_flow_id MD Danish Anwar
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

This is the PURSS Ethernet driver for TI AM654 Sr2.0 and laterSoCs
with the ICSSG PRU Sub-system running EMAC firmware.
This driver caters to either of the slices(pru/rtu pair)
of the icssg subsystem.

One and exactly one of the slices is supported
as the u-boot ethernet supports probing one interface
at a time.

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 drivers/net/ti/Kconfig        |   8 +
 drivers/net/ti/Makefile       |   1 +
 drivers/net/ti/icssg_prueth.c | 589 ++++++++++++++++++++++++++++++++++
 3 files changed, 598 insertions(+)
 create mode 100644 drivers/net/ti/icssg_prueth.c

diff --git a/drivers/net/ti/Kconfig b/drivers/net/ti/Kconfig
index c75f418628..9fead2c7ce 100644
--- a/drivers/net/ti/Kconfig
+++ b/drivers/net/ti/Kconfig
@@ -49,3 +49,11 @@ config TI_AM65_CPSW_NUSS
 	help
 	  This driver supports TI K3 MCU CPSW Nuss Ethernet controller
 	  in Texas Instruments K3 AM65x SoCs.
+
+config TI_ICSSG_PRUETH
+	bool "TI Gigabit PRU Ethernet driver"
+	depends on ARCH_K3
+	select PHYLIB
+	help
+	  Support Gigabit Ethernet ports over the ICSSG PRU Subsystem
+	  This subsystem is available starting with the AM65 platform.
diff --git a/drivers/net/ti/Makefile b/drivers/net/ti/Makefile
index 0ce0cf2828..5af760572f 100644
--- a/drivers/net/ti/Makefile
+++ b/drivers/net/ti/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o cpsw-common.o cpsw_mdio.o
 obj-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o
 obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o cpsw_mdio.o
 obj-$(CONFIG_TI_AM65_CPSW_NUSS) += am65-cpsw-nuss.o cpsw_mdio.o
+obj-$(CONFIG_TI_ICSSG_PRUETH) += icssg_prueth.o cpsw_mdio.o icssg_classifier.o icssg_config.o icssg_queues.o
diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
new file mode 100644
index 0000000000..9cc700eca5
--- /dev/null
+++ b/drivers/net/ti/icssg_prueth.c
@@ -0,0 +1,589 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Texas Instruments K3 AM65 PRU Ethernet Driver
+ *
+ * Copyright (C) 2019-2021, Texas Instruments, Incorporated
+ *
+ */
+
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <clk.h>
+#include <dm/lists.h>
+#include <dm/device.h>
+#include <dma-uclass.h>
+#include <dm/of_access.h>
+#include <fs_loader.h>
+#include <miiphy.h>
+#include <net.h>
+#include <phy.h>
+#include <power-domain.h>
+#include <linux/soc/ti/ti-udma.h>
+#include <regmap.h>
+#include <remoteproc.h>
+#include <syscon.h>
+#include <soc.h>
+#include <linux/pruss_driver.h>
+#include <dm/device_compat.h>
+
+#include "cpsw_mdio.h"
+#include "icssg_prueth.h"
+#include "icss_mii_rt.h"
+
+#define ICSS_SLICE0     0
+#define ICSS_SLICE1     1
+
+#ifdef PKTSIZE_ALIGN
+#define UDMA_RX_BUF_SIZE PKTSIZE_ALIGN
+#else
+#define UDMA_RX_BUF_SIZE ALIGN(1522, ARCH_DMA_MINALIGN)
+#endif
+
+#ifdef PKTBUFSRX
+#define UDMA_RX_DESC_NUM PKTBUFSRX
+#else
+#define UDMA_RX_DESC_NUM 4
+#endif
+
+/* Config region lies in shared RAM */
+#define ICSS_CONFIG_OFFSET_SLICE0	0
+#define ICSS_CONFIG_OFFSET_SLICE1	0x8000
+
+/* 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 */
+
+/* CTRLMMR_ICSSG_RGMII_CTRL register bits */
+#define ICSSG_CTRL_RGMII_ID_MODE		BIT(24)
+
+/* Management packet type */
+#define PRUETH_PKT_TYPE_CMD		0x10
+
+static int icssg_phy_init(struct udevice *dev)
+{
+	struct prueth *priv = dev_get_priv(dev);
+	struct phy_device *phydev;
+	u32 supported = PHY_GBIT_FEATURES;
+	int ret;
+
+	phydev = phy_connect(priv->bus,
+			     priv->phy_addr,
+			     priv->dev,
+			     priv->phy_interface);
+
+	if (!phydev) {
+		dev_err(dev, "phy_connect() failed\n");
+		return -ENODEV;
+	}
+
+	/* disable unsupported features */
+	supported &= ~(PHY_10BT_FEATURES |
+			SUPPORTED_100baseT_Half |
+			SUPPORTED_1000baseT_Half |
+			SUPPORTED_Pause |
+			SUPPORTED_Asym_Pause);
+
+	phydev->supported &= supported;
+	phydev->advertising = phydev->supported;
+
+	if (IS_ENABLED(CONFIG_DM_ETH))
+		if (ofnode_valid(priv->phy_node))
+			phydev->node = priv->phy_node;
+
+	priv->phydev = phydev;
+	ret = phy_config(phydev);
+	if (ret < 0)
+		pr_err("phy_config() failed: %d", ret);
+
+	return ret;
+}
+
+static int icssg_mdio_init(struct udevice *dev)
+{
+	struct prueth *prueth = dev_get_priv(dev);
+
+	prueth->bus = cpsw_mdio_init(dev->name, prueth->mdio_base,
+				     prueth->mdio_freq,
+				     clk_get_rate(&prueth->mdiofck),
+				     prueth->mdio_manual_mode);
+	if (!prueth->bus)
+		return -EFAULT;
+
+	return 0;
+}
+
+static void icssg_config_set_speed(struct prueth *priv, int speed)
+{
+	u8 fw_speed;
+
+	switch (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 */
+		dev_err(priv->dev, "Unsupported link speed\n");
+		return;
+	}
+
+	writeb(fw_speed, priv->dram.pa + PORT_LINK_SPEED_OFFSET);
+}
+
+static int icssg_update_link(struct prueth *priv)
+{
+	struct phy_device *phy = priv->phydev;
+	bool gig_en = false, full_duplex = false;
+
+	if (phy->link) { /* link up */
+		if (phy->speed == SPEED_1000)
+			gig_en = true;
+		if (phy->duplex == DUPLEX_FULL)
+			full_duplex = true;
+		/* Set the RGMII cfg for gig en and full duplex */
+		icssg_update_rgmii_cfg(priv->miig_rt, phy->speed, full_duplex,
+				       priv->slice, priv);
+		/* update the Tx IPG based on 100M/1G speed */
+		icssg_config_ipg(priv, phy->speed, priv->slice);
+
+		/* Send command to firmware to update Speed setting */
+		icssg_config_set_speed(priv, phy->speed);
+
+		/* Enable PORT FORWARDING */
+		emac_set_port_state(priv, ICSSG_EMAC_PORT_FORWARD);
+
+		printf("link up on port %d, speed %d, %s duplex\n",
+		       priv->port_id, phy->speed,
+		       (phy->duplex == DUPLEX_FULL) ? "full" : "half");
+	} else {
+		emac_set_port_state(priv, ICSSG_EMAC_PORT_DISABLE);
+		printf("link down on port %d\n", priv->port_id);
+	}
+
+	return phy->link;
+}
+
+static int prueth_start(struct udevice *dev)
+{
+	struct ti_udma_drv_chan_cfg_data *dma_rx_cfg_data;
+	struct prueth *priv = dev_get_priv(dev);
+	struct icssg_flow_cfg *flow_cfg;
+	char chn_name[16];
+	void *config;
+	int ret, i;
+
+	/* To differentiate channels for SLICE0 vs SLICE1 */
+	snprintf(chn_name, sizeof(chn_name), "tx%d-0", priv->slice);
+
+	ret = dma_get_by_name(dev, chn_name, &priv->dma_tx);
+	if (ret)
+		dev_err(dev, "TX dma get failed %d\n", ret);
+
+	snprintf(chn_name, sizeof(chn_name), "rx%d", priv->slice);
+	ret = dma_get_by_name(dev, chn_name, &priv->dma_rx);
+	if (ret)
+		dev_err(dev, "RX dma get failed %d\n", ret);
+
+	for (i = 0; i < UDMA_RX_DESC_NUM; i++) {
+		ret = dma_prepare_rcv_buf(&priv->dma_rx,
+					  net_rx_packets[i],
+					  UDMA_RX_BUF_SIZE);
+		if (ret)
+			dev_err(dev, "RX dma add buf failed %d\n", ret);
+	}
+
+	ret = dma_enable(&priv->dma_tx);
+	if (ret) {
+		dev_err(dev, "TX dma_enable failed %d\n", ret);
+		goto tx_fail;
+	}
+
+	ret = dma_enable(&priv->dma_rx);
+	if (ret) {
+		dev_err(dev, "RX dma_enable failed %d\n", ret);
+		goto rx_fail;
+	}
+
+	/* check if the rx_flow_id of dma_rx is as expected since
+	 * driver hardcode that value in config struct to firmware
+	 * in probe. Just add this sanity check to catch any change
+	 * to rx channel assignment in the future.
+	 */
+	dma_get_cfg(&priv->dma_rx, 0, (void **)&dma_rx_cfg_data);
+	config = (void *)(priv->dram.pa + ICSSG_CONFIG_OFFSET);
+	flow_cfg = config + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
+	writew(dma_rx_cfg_data->flow_id_base, &flow_cfg->rx_base_flow);
+	writew(0, &flow_cfg->mgm_base_flow);
+
+	dev_info(dev, "K3 ICSSG: rflow_id_base: %u, chn_name = %s\n",
+		 dma_rx_cfg_data->flow_id_base, chn_name);
+
+	ret = phy_startup(priv->phydev);
+	if (ret) {
+		dev_err(dev, "phy_startup failed\n");
+		goto phy_fail;
+	}
+
+	ret = icssg_update_link(priv);
+	if (!ret) {
+		ret = -ENODEV;
+		goto phy_shut;
+	}
+
+	return 0;
+
+phy_shut:
+	phy_shutdown(priv->phydev);
+phy_fail:
+	dma_disable(&priv->dma_rx);
+	dma_free(&priv->dma_rx);
+rx_fail:
+	dma_disable(&priv->dma_tx);
+	dma_free(&priv->dma_tx);
+
+tx_fail:
+	icssg_class_disable(priv->miig_rt, priv->slice);
+
+	return ret;
+}
+
+static int prueth_send(struct udevice *dev, void *packet, int length)
+{
+	struct prueth *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = dma_send(&priv->dma_tx, packet, length, NULL);
+
+	return ret;
+}
+
+static int prueth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+	struct prueth *priv = dev_get_priv(dev);
+	int ret;
+
+	/* try to receive a new packet */
+	ret = dma_receive(&priv->dma_rx, (void **)packetp, NULL);
+
+	return ret;
+}
+
+static int prueth_free_pkt(struct udevice *dev, uchar *packet, int length)
+{
+	struct prueth *priv = dev_get_priv(dev);
+	int ret = 0;
+
+	if (length > 0) {
+		u32 pkt = priv->rx_next % UDMA_RX_DESC_NUM;
+
+		dev_dbg(dev, "%s length:%d pkt:%u\n", __func__, length, pkt);
+
+		ret = dma_prepare_rcv_buf(&priv->dma_rx,
+					  net_rx_packets[pkt],
+					  UDMA_RX_BUF_SIZE);
+		priv->rx_next++;
+	}
+
+	return ret;
+}
+
+static void prueth_stop(struct udevice *dev)
+{
+	struct prueth *priv = dev_get_priv(dev);
+
+	phy_shutdown(priv->phydev);
+
+	dma_disable(&priv->dma_tx);
+	dma_free(&priv->dma_tx);
+
+	dma_disable(&priv->dma_rx);
+	dma_free(&priv->dma_rx);
+}
+
+static int prueth_write_hwaddr(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	struct prueth *prueth = dev_get_priv(dev);
+	u8 *hwaddr = pdata->enetaddr;
+
+	icssg_class_set_mac_addr(prueth->miig_rt, prueth->slice, hwaddr);
+
+	icssg_ft1_set_mac_addr(prueth->miig_rt, prueth->slice, hwaddr);
+
+	icssg_class_default(prueth->miig_rt, prueth->slice, 0);
+
+	/* Set Load time configuration */
+	icssg_config(prueth);
+
+	dev_dbg(dev, "Set MAC address to %pM\n", hwaddr);
+	return 0;
+}
+
+static const struct eth_ops prueth_ops = {
+	.start		= prueth_start,
+	.send		= prueth_send,
+	.recv		= prueth_recv,
+	.free_pkt	= prueth_free_pkt,
+	.stop		= prueth_stop,
+	.write_hwaddr   = prueth_write_hwaddr,
+};
+
+static int icssg_ofdata_parse_phy(struct udevice *dev, ofnode port_np)
+{
+	struct prueth *priv = dev_get_priv(dev);
+	struct ofnode_phandle_args out_args;
+	int ret = 0;
+
+	priv->phy_interface = ofnode_read_phy_mode(port_np);
+
+	if (priv->phy_interface == PHY_INTERFACE_MODE_NA) {
+		dev_err(dev, "Invalid PHY mode '%s'\n",
+			phy_string_for_interface(priv->phy_interface));
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = ofnode_parse_phandle_with_args(port_np, "phy-handle",
+					     NULL, 0, 0, &out_args);
+	if (ret) {
+		dev_err(dev, "can't parse phy-handle port (%d)\n", ret);
+		ret = 0;
+	}
+
+	priv->phy_node = out_args.node;
+	ret = ofnode_read_u32(priv->phy_node, "reg", &priv->phy_addr);
+	if (ret)
+		dev_err(dev, "failed to get phy_addr port (%d)\n", ret);
+
+out:
+	return ret;
+}
+
+static const struct soc_attr k3_mdio_soc_data[] = {
+	{ .family = "AM62X", .revision = "SR1.0" },
+	{ .family = "AM64X", .revision = "SR1.0" },
+	{ .family = "AM64X", .revision = "SR2.0" },
+	{ .family = "AM65X", .revision = "SR1.0" },
+	{ .family = "AM65X", .revision = "SR2.0" },
+	{ .family = "J7200", .revision = "SR1.0" },
+	{ .family = "J7200", .revision = "SR2.0" },
+	{ .family = "J721E", .revision = "SR1.0" },
+	{ .family = "J721E", .revision = "SR1.1" },
+	{ .family = "J721S2", .revision = "SR1.0" },
+	{ /* sentinel */ },
+};
+
+static int prueth_probe(struct udevice *dev)
+{
+	ofnode eth_ports_node, eth0_node, eth1_node, eth_node;
+	ofnode node, pruss_node, mdio_node, sram_node;
+	struct prueth *prueth = dev_get_priv(dev);
+	struct udevice **prussdev = NULL;
+	u32 phandle, err, sp;
+	int ret = 0;
+
+	prueth = dev_get_priv(dev);
+	prueth->dev = dev;
+	err = ofnode_read_u32(dev_ofnode(dev), "ti,prus", &phandle);
+	if (err)
+		return err;
+
+	node = ofnode_get_by_phandle(phandle);
+	if (!ofnode_valid(node))
+		return -EINVAL;
+
+	pruss_node = ofnode_get_parent(node);
+	ret = device_get_global_by_ofnode(pruss_node, prussdev);
+	if (ret)
+		dev_err(dev, "error getting the pruss dev\n");
+	prueth->pruss = *prussdev;
+
+	ret = pruss_request_mem_region(*prussdev, PRUSS_MEM_SHRD_RAM2,
+				       &prueth->shram);
+	if (ret)
+		return ret;
+
+	ret = pruss_request_tm_region(*prussdev, &prueth->tmaddr);
+	if (ret)
+		return ret;
+
+	eth_ports_node = dev_read_subnode(dev, "ethernet-ports");
+	if (!ofnode_valid(eth_ports_node))
+		return -ENOENT;
+
+	ofnode_for_each_subnode(eth_node, eth_ports_node) {
+		const char *node_name;
+		u32 reg;
+
+		node_name = ofnode_get_name(eth_node);
+		ret = ofnode_read_u32(eth_node, "reg", &reg);
+		if (ret)
+			dev_err(dev, "%s: error reading port_id (%d)\n", node_name, ret);
+
+		if (reg >= PRUETH_NUM_MACS) {
+			dev_err(dev, "%s: invalid port_id (%d)\n", node_name, reg);
+			return -EINVAL;
+		}
+
+		if (reg == 0)
+			eth0_node = eth_node;
+		else if (reg == 1)
+			eth1_node = eth_node;
+		else
+			dev_err(dev, "port reg should be 0 or 1\n");
+	}
+
+	/* one node must be present and available else we fail */
+	if (!ofnode_is_enabled(eth0_node) && !ofnode_is_enabled(eth1_node)) {
+		dev_err(dev, "neither port@0 nor port@1 node available\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * Uboot ethernet framework does not support two interfaces in a single
+	 * probe. If the eth0_node is enabled in DT, we'll only probe eth0_node.
+	 * If the eth0_node is not enabled in DT, we'll check for eth1_node and
+	 * probe the eth1_node if enabled.
+	 */
+	if (ofnode_is_enabled(eth0_node)) {
+		if (ofnode_valid(eth0_node) && ofnode_is_enabled(eth0_node)) {
+			prueth->slice = 0;
+			icssg_ofdata_parse_phy(dev, eth0_node);
+			prueth->eth_node[PRUETH_MAC0] = eth0_node;
+			dev_dbg(dev, "Using port0\n");
+		}
+	} else if (ofnode_is_enabled(eth1_node)) {
+		if (ofnode_valid(eth1_node) && ofnode_is_enabled(eth1_node)) {
+			prueth->slice = 1;
+			icssg_ofdata_parse_phy(dev, eth1_node);
+			prueth->eth_node[PRUETH_MAC0] = eth1_node;
+			dev_dbg(dev, "Using port1\n");
+		}
+	}
+
+	ret = pruss_request_mem_region(*prussdev,
+				       prueth->slice ? PRUSS_MEM_DRAM1 : PRUSS_MEM_DRAM0,
+				       &prueth->dram);
+	if (ret) {
+		dev_err(dev, "could not request DRAM%d region\n", prueth->slice);
+		return ret;
+	}
+
+	prueth->miig_rt = syscon_regmap_lookup_by_phandle(dev, "ti,mii-g-rt");
+	if (!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(dev, "ti,mii-rt");
+	if (!prueth->mii_rt) {
+		dev_err(dev, "couldn't get mii-rt syscon regmap\n");
+		return -ENODEV;
+	}
+
+	ret = ofnode_read_u32(dev_ofnode(dev), "sram", &sp);
+	if (ret) {
+		dev_err(dev, "sram node fetch failed %d\n", ret);
+		return ret;
+	}
+
+	sram_node = ofnode_get_by_phandle(sp);
+	if (!ofnode_valid(sram_node))
+		return -EINVAL;
+
+	prueth->sram_pa = ofnode_get_addr(sram_node);
+	if (prueth->sram_pa % SZ_64K != 0) {
+		/* This is constraint for SR2.0 firmware */
+		dev_err(dev, "sram address needs to be 64KB aligned\n");
+		return -EINVAL;
+	}
+
+	if (prueth->phy_interface != PHY_INTERFACE_MODE_MII &&
+	    prueth->phy_interface < PHY_INTERFACE_MODE_RGMII &&
+	    prueth->phy_interface > PHY_INTERFACE_MODE_RGMII_TXID) {
+		dev_err(prueth->dev, "PHY mode unsupported %s\n",
+			phy_string_for_interface(prueth->phy_interface));
+		return -EINVAL;
+	}
+
+	/* 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 (prueth->phy_interface) {
+	case PHY_INTERFACE_MODE_RGMII_ID:
+		prueth->phy_interface = PHY_INTERFACE_MODE_RGMII_RXID;
+		break;
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		prueth->phy_interface = 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");
+		return -EINVAL;
+	default:
+		break;
+	}
+
+	mdio_node = ofnode_find_subnode(pruss_node, "mdio");
+	prueth->mdio_base = ofnode_get_addr(mdio_node);
+	ofnode_read_u32(mdio_node, "bus_freq", &prueth->mdio_freq);
+
+	ret = clk_get_by_name_nodev(mdio_node, "fck", &prueth->mdiofck);
+	if (ret) {
+		dev_err(dev, "failed to get clock %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_enable(&prueth->mdiofck);
+	if (ret) {
+		dev_err(dev, "clk_enable failed %d\n", ret);
+		return ret;
+	}
+
+	prueth->mdio_manual_mode = false;
+	if (soc_device_match(k3_mdio_soc_data))
+		prueth->mdio_manual_mode = true;
+
+	ret = icssg_mdio_init(dev);
+	if (ret)
+		return ret;
+
+	ret = icssg_phy_init(dev);
+	if (ret) {
+		dev_err(dev, "phy_init failed\n");
+		goto out;
+	}
+
+	return 0;
+out:
+	cpsw_mdio_free(prueth->bus);
+	clk_disable(&prueth->mdiofck);
+
+	return ret;
+}
+
+static const struct udevice_id prueth_ids[] = {
+	{ .compatible = "ti,am654-icssg-prueth" },
+	{ .compatible = "ti,am642-icssg-prueth" },
+	{ }
+};
+
+U_BOOT_DRIVER(prueth) = {
+	.name	= "prueth",
+	.id	= UCLASS_ETH,
+	.of_match = prueth_ids,
+	.probe	= prueth_probe,
+	.ops	= &prueth_ops,
+	.priv_auto = sizeof(struct prueth),
+	.plat_auto = sizeof(struct eth_pdata),
+	.flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 06/16] net: ti: icssg: Add support sending FDB command to update rx_flow_id
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
                   ` (4 preceding siblings ...)
  2023-12-19 10:34 ` [RFC PATCH 05/16] net: ti: icssg: Add ICSSG ethernet driver MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 07/16] net: ti: icssg: Enforce pinctrl state on the MDIO child node MD Danish Anwar
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

ICSSG firmware supports FDB commands. Add support to send FDB commands
from driver. Once rx_flow_id is obtained from dma, let firmware know that
we are using this rx_flow_id by sending a FDB command.

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 drivers/net/ti/icssg_config.c | 66 +++++++++++++++++++++++++++++++++++
 drivers/net/ti/icssg_config.h | 18 ++++++++++
 drivers/net/ti/icssg_prueth.c |  6 ++++
 drivers/net/ti/icssg_prueth.h |  6 ++++
 4 files changed, 96 insertions(+)

diff --git a/drivers/net/ti/icssg_config.c b/drivers/net/ti/icssg_config.c
index 33298c3374..7e11ef128f 100644
--- a/drivers/net/ti/icssg_config.c
+++ b/drivers/net/ti/icssg_config.c
@@ -9,6 +9,7 @@
 #include "icssg_switch_map.h"
 #include "icss_mii_rt.h"
 #include <dm/device_compat.h>
+#include <linux/iopoll.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
@@ -401,3 +402,68 @@ int emac_set_port_state(struct prueth *prueth,
 
 	return ret;
 }
+
+int icssg_send_fdb_msg(struct prueth *prueth, struct mgmt_cmd *cmd,
+		       struct mgmt_cmd_rsp *rsp)
+{
+	int slice = prueth->slice;
+	int ret, addr;
+
+	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((void __iomem *)prueth->shram.pa + addr + 4, cmd, sizeof(*cmd));
+	icssg_queue_push(prueth, slice == 0 ?
+			 ICSSG_CMD_PUSH_SLICE0 : ICSSG_CMD_PUSH_SLICE1, addr);
+	ret = read_poll_timeout(icssg_queue_pop, addr, addr >= 0,
+				2000, 20000000, prueth, slice == 0 ?
+				ICSSG_RSP_POP_SLICE0 : ICSSG_RSP_POP_SLICE1);
+
+	if (ret) {
+		dev_err(prueth->dev, "Timedout sending HWQ message\n");
+		return ret;
+	}
+
+	memcpy_fromio(rsp, (void __iomem *)prueth->shram.pa + addr, sizeof(*rsp));
+	/* Return buffer back for to pool */
+	icssg_queue_push(prueth, slice == 0 ?
+			 ICSSG_RSP_PUSH_SLICE0 : ICSSG_RSP_PUSH_SLICE1, addr);
+
+	return 0;
+}
+
+int emac_fdb_flow_id_updated(struct prueth *prueth)
+{
+	struct mgmt_cmd_rsp fdb_cmd_rsp = { 0 };
+	int slice = prueth->slice;
+	struct mgmt_cmd fdb_cmd = { 0 };
+	int ret = 0;
+
+	fdb_cmd.header = ICSSG_FW_MGMT_CMD_HEADER;
+	fdb_cmd.type   = ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW;
+	fdb_cmd.seqnum = ++(prueth->icssg_hwcmdseq);
+	fdb_cmd.param  = 0;
+
+	fdb_cmd.param |= (slice << 4);
+	fdb_cmd.cmd_args[0] = 0;
+
+	ret = icssg_send_fdb_msg(prueth, &fdb_cmd, &fdb_cmd_rsp);
+	if (ret)
+		return ret;
+
+	if (fdb_cmd.seqnum != fdb_cmd_rsp.seqnum) {
+		dev_err(prueth->dev, "seqnum doesn't match, cmd.seqnum %d != rsp.seqnum %d\n",
+			fdb_cmd.seqnum, fdb_cmd_rsp.seqnum);
+		return -EINVAL;
+	}
+
+	if (fdb_cmd_rsp.status == 1)
+		return 0;
+
+	return -EINVAL;
+}
diff --git a/drivers/net/ti/icssg_config.h b/drivers/net/ti/icssg_config.h
index fc6eae0426..156127bd3d 100644
--- a/drivers/net/ti/icssg_config.h
+++ b/drivers/net/ti/icssg_config.h
@@ -80,6 +80,7 @@ struct icssg_rxq_ctx {
 #define ICSSG_FW_MGMT_FDB_CMD_TYPE	0x03
 #define ICSSG_FW_MGMT_CMD_TYPE		0x04
 #define ICSSG_FW_MGMT_PKT		0x80000000
+#define ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW	0x05
 
 struct icssg_r30_cmd {
 	u32 cmd[4];
@@ -156,6 +157,23 @@ struct icssg_setclock_desc {
 	u32 CMP0_new;
 } __packed;
 
+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;
+
 #define ICSSG_CMD_POP_SLICE0	56
 #define ICSSG_CMD_POP_SLICE1	60
 
diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
index 9cc700eca5..1a7445a015 100644
--- a/drivers/net/ti/icssg_prueth.c
+++ b/drivers/net/ti/icssg_prueth.c
@@ -225,6 +225,12 @@ static int prueth_start(struct udevice *dev)
 	dev_info(dev, "K3 ICSSG: rflow_id_base: %u, chn_name = %s\n",
 		 dma_rx_cfg_data->flow_id_base, chn_name);
 
+	ret = emac_fdb_flow_id_updated(priv);
+	if (ret) {
+		dev_err(dev, "Failed to update Rx Flow ID %d", ret);
+		goto phy_fail;
+	}
+
 	ret = phy_startup(priv->phydev);
 	if (ret) {
 		dev_err(dev, "phy_startup failed\n");
diff --git a/drivers/net/ti/icssg_prueth.h b/drivers/net/ti/icssg_prueth.h
index f34ab5d6d4..e41ed16a05 100644
--- a/drivers/net/ti/icssg_prueth.h
+++ b/drivers/net/ti/icssg_prueth.h
@@ -68,6 +68,7 @@ struct prueth {
 	bool			mdio_manual_mode;
 	int			speed;
 	int			duplex;
+	u8			icssg_hwcmdseq;
 };
 
 /* config helpers */
@@ -80,4 +81,9 @@ 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);
 
+/* FDB helpers */
+int icssg_send_fdb_msg(struct prueth *prueth, struct mgmt_cmd *cmd,
+		       struct mgmt_cmd_rsp *rsp);
+int emac_fdb_flow_id_updated(struct prueth *prueth);
+
 #endif /* __NET_TI_ICSSG_PRUETH_H */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 07/16] net: ti: icssg: Enforce pinctrl state on the MDIO child node
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
                   ` (5 preceding siblings ...)
  2023-12-19 10:34 ` [RFC PATCH 06/16] net: ti: icssg: Add support sending FDB command to update rx_flow_id MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 08/16] arm: dts: k3-am65: Add additional regs for DMA components MD Danish Anwar
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

The binding represents the MDIO controller as a child device tree
node of the MAC device tree node.

The U-Boot driver mostly ignores that child device tree node and just
hardcodes the resources it uses to support both the MAC and MDIO in a
single driver.

However, some resources like pinctrl muxing states are thus ignored.
This has been a problem with some device trees that will put some
pinctrl states on the MDIO device tree node.

Let's rework the driver a bit to create a dummy MDIO driver that we will
then get during our initialization to force the core to select the right
muxing.

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 drivers/net/ti/Kconfig        |  1 +
 drivers/net/ti/icssg_prueth.c | 59 +++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/drivers/net/ti/Kconfig b/drivers/net/ti/Kconfig
index 9fead2c7ce..6935b70e12 100644
--- a/drivers/net/ti/Kconfig
+++ b/drivers/net/ti/Kconfig
@@ -53,6 +53,7 @@ config TI_AM65_CPSW_NUSS
 config TI_ICSSG_PRUETH
 	bool "TI Gigabit PRU Ethernet driver"
 	depends on ARCH_K3
+	imply DM_MDIO
 	select PHYLIB
 	help
 	  Support Gigabit Ethernet ports over the ICSSG PRU Subsystem
diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
index 1a7445a015..40ad827e49 100644
--- a/drivers/net/ti/icssg_prueth.c
+++ b/drivers/net/ti/icssg_prueth.c
@@ -13,6 +13,7 @@
 #include <dm/device.h>
 #include <dma-uclass.h>
 #include <dm/of_access.h>
+#include <dm/pinctrl.h>
 #include <fs_loader.h>
 #include <miiphy.h>
 #include <net.h>
@@ -100,9 +101,56 @@ static int icssg_phy_init(struct udevice *dev)
 	return ret;
 }
 
+static ofnode prueth_find_mdio(ofnode parent)
+{
+	ofnode node;
+
+	ofnode_for_each_subnode(node, parent)
+		if (ofnode_device_is_compatible(node, "ti,davinci_mdio"))
+			return node;
+
+	return ofnode_null();
+}
+
+static int prueth_mdio_setup(struct udevice *dev)
+{
+	struct prueth *priv = dev_get_priv(dev);
+	struct udevice *mdio_dev;
+	ofnode mdio;
+	int ret;
+
+	mdio = prueth_find_mdio(dev_ofnode(priv->pruss));
+	if (!ofnode_valid(mdio))
+		return 0;
+
+	/*
+	 * The MDIO controller is represented in the DT binding by a
+	 * subnode of the MAC controller.
+	 *
+	 * We don't have a DM driver for the MDIO device yet, and thus any
+	 * pinctrl setting on its node will be ignored.
+	 *
+	 * However, we do need to make sure the pins states tied to the
+	 * MDIO node are configured properly. Fortunately, the core DM
+	 * does that for use when we get a device, so we can work around
+	 * that whole issue by just requesting a dummy MDIO driver to
+	 * probe, and our pins will get muxed.
+	 */
+	ret = uclass_get_device_by_ofnode(UCLASS_MDIO, mdio, &mdio_dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static int icssg_mdio_init(struct udevice *dev)
 {
 	struct prueth *prueth = dev_get_priv(dev);
+	int ret;
+
+	ret = prueth_mdio_setup(dev);
+	if (ret)
+		return ret;
 
 	prueth->bus = cpsw_mdio_init(dev->name, prueth->mdio_base,
 				     prueth->mdio_freq,
@@ -593,3 +641,14 @@ U_BOOT_DRIVER(prueth) = {
 	.plat_auto = sizeof(struct eth_pdata),
 	.flags = DM_FLAG_ALLOC_PRIV_DMA,
 };
+
+static const struct udevice_id prueth_mdio_ids[] = {
+	{ .compatible = "ti,davinci_mdio" },
+	{ }
+};
+
+U_BOOT_DRIVER(prueth_mdio) = {
+	.name		= "prueth_mdio",
+	.id			= UCLASS_MDIO,
+	.of_match	= prueth_mdio_ids,
+};
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 08/16] arm: dts: k3-am65: Add additional regs for DMA components
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
                   ` (6 preceding siblings ...)
  2023-12-19 10:34 ` [RFC PATCH 07/16] net: ti: icssg: Enforce pinctrl state on the MDIO child node MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 09/16] arm: dts: k3-am65: Add cfg reg region to ringacc node MD Danish Anwar
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Add additional reg properties for UDMA and RingAcc nodes which are
mostly used by bootloader components before Device Manager firmware
services are available, in order to setup DMA transfers.

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 arch/arm/dts/k3-am65-main.dtsi | 8 ++++++--
 arch/arm/dts/k3-am65-mcu.dtsi  | 8 ++++++--
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/arch/arm/dts/k3-am65-main.dtsi b/arch/arm/dts/k3-am65-main.dtsi
index ba4e5d3e1e..691c9978e6 100644
--- a/arch/arm/dts/k3-am65-main.dtsi
+++ b/arch/arm/dts/k3-am65-main.dtsi
@@ -616,8 +616,12 @@
 			compatible = "ti,am654-navss-main-udmap";
 			reg =	<0x0 0x31150000 0x0 0x100>,
 				<0x0 0x34000000 0x0 0x100000>,
-				<0x0 0x35000000 0x0 0x100000>;
-			reg-names = "gcfg", "rchanrt", "tchanrt";
+				<0x0 0x35000000 0x0 0x100000>,
+				<0x0 0x30b00000 0x0 0x20000>,
+				<0x0 0x30c00000 0x0 0x8000>,
+				<0x0 0x30d00000 0x0 0x4000>;
+			reg-names = "gcfg", "rchanrt", "tchanrt",
+				    "tchan", "rchan", "rflow";
 			msi-parent = <&inta_main_udmass>;
 			#dma-cells = <1>;
 
diff --git a/arch/arm/dts/k3-am65-mcu.dtsi b/arch/arm/dts/k3-am65-mcu.dtsi
index c93ff1520a..d7111aa8b2 100644
--- a/arch/arm/dts/k3-am65-mcu.dtsi
+++ b/arch/arm/dts/k3-am65-mcu.dtsi
@@ -142,8 +142,12 @@
 			compatible = "ti,am654-navss-mcu-udmap";
 			reg =	<0x0 0x285c0000 0x0 0x100>,
 				<0x0 0x2a800000 0x0 0x40000>,
-				<0x0 0x2aa00000 0x0 0x40000>;
-			reg-names = "gcfg", "rchanrt", "tchanrt";
+				<0x0 0x2aa00000 0x0 0x40000>,
+				<0x0 0x284a0000 0x0 0x4000>,
+				<0x0 0x284c0000 0x0 0x4000>,
+				<0x0 0x28400000 0x0 0x2000>;
+			reg-names = "gcfg", "rchanrt", "tchanrt",
+				    "tchan", "rchan", "rflow";
 			msi-parent = <&inta_main_udmass>;
 			#dma-cells = <1>;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 09/16] arm: dts: k3-am65: Add cfg reg region to ringacc node
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
                   ` (7 preceding siblings ...)
  2023-12-19 10:34 ` [RFC PATCH 08/16] arm: dts: k3-am65: Add additional regs for DMA components MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 10/16] arm: dts: k3-am65-main: Add ICSSG IEP nodes MD Danish Anwar
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Add register range of ringacc cfg node to k3-am65* dtsi files. This is
normally under Device Management firmware control but some entities like
bootloader have to access directly and thus required to be present in
DT.

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 arch/arm/dts/k3-am65-main.dtsi | 5 +++--
 arch/arm/dts/k3-am65-mcu.dtsi  | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/arm/dts/k3-am65-main.dtsi b/arch/arm/dts/k3-am65-main.dtsi
index 691c9978e6..7f10520236 100644
--- a/arch/arm/dts/k3-am65-main.dtsi
+++ b/arch/arm/dts/k3-am65-main.dtsi
@@ -603,8 +603,9 @@
 			reg =	<0x0 0x3c000000 0x0 0x400000>,
 				<0x0 0x38000000 0x0 0x400000>,
 				<0x0 0x31120000 0x0 0x100>,
-				<0x0 0x33000000 0x0 0x40000>;
-			reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target";
+				<0x0 0x33000000 0x0 0x40000>,
+				<0x0 0x31080000 0x0 0x40000>;
+			reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target", "cfg";
 			ti,num-rings = <818>;
 			ti,sci-rm-range-gp-rings = <0x1>; /* GP ring range */
 			ti,sci = <&dmsc>;
diff --git a/arch/arm/dts/k3-am65-mcu.dtsi b/arch/arm/dts/k3-am65-mcu.dtsi
index d7111aa8b2..b7f0456de7 100644
--- a/arch/arm/dts/k3-am65-mcu.dtsi
+++ b/arch/arm/dts/k3-am65-mcu.dtsi
@@ -129,8 +129,9 @@
 			reg =	<0x0 0x2b800000 0x0 0x400000>,
 				<0x0 0x2b000000 0x0 0x400000>,
 				<0x0 0x28590000 0x0 0x100>,
-				<0x0 0x2a500000 0x0 0x40000>;
-			reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target";
+				<0x0 0x2a500000 0x0 0x40000>,
+				<0x0 0x28440000 0x0 0x40000>;
+			reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target", "cfg";
 			ti,num-rings = <286>;
 			ti,sci-rm-range-gp-rings = <0x1>; /* GP ring range */
 			ti,sci = <&dmsc>;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 10/16] arm: dts: k3-am65-main: Add ICSSG IEP nodes
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
                   ` (8 preceding siblings ...)
  2023-12-19 10:34 ` [RFC PATCH 09/16] arm: dts: k3-am65: Add cfg reg region to ringacc node MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-19 17:46   ` Tom Rini
  2023-12-19 10:34 ` [RFC PATCH 11/16] arm: dts: k3-am654-base-board: Add ICSSG2 Ethernet support MD Danish Anwar
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

The ICSSG IP on AM65x SoCs have two Industrial Ethernet Peripherals (IEPs)
to manage/generate Industrial Ethernet functions such as time stamping.
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: MD Danish Anwar <danishanwar@ti.com>
---
 arch/arm/dts/k3-am65-main.dtsi | 36 ++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/arch/arm/dts/k3-am65-main.dtsi b/arch/arm/dts/k3-am65-main.dtsi
index 7f10520236..da48887559 100644
--- a/arch/arm/dts/k3-am65-main.dtsi
+++ b/arch/arm/dts/k3-am65-main.dtsi
@@ -969,6 +969,18 @@
 			};
 		};
 
+		icssg0_iep0: iep@2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
+		icssg0_iep1: iep@2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg0_iepclk_mux>;
+		};
+
 		icssg0_mii_rt: mii-rt@32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;
@@ -1110,6 +1122,18 @@
 			};
 		};
 
+		icssg1_iep0: iep@2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
+		icssg1_iep1: iep@2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg1_iepclk_mux>;
+		};
+
 		icssg1_mii_rt: mii-rt@32000 {
 			compatible = "ti,pruss-mii", "syscon";
 			reg = <0x32000 0x100>;
@@ -1256,6 +1280,18 @@
 			reg = <0x32000 0x100>;
 		};
 
+		icssg2_iep0: iep@2e000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2e000 0x1000>;
+			clocks = <&icssg2_iepclk_mux>;
+		};
+
+		icssg2_iep1: iep@2f000 {
+			compatible = "ti,am654-icss-iep";
+			reg = <0x2f000 0x1000>;
+			clocks = <&icssg2_iepclk_mux>;
+		};
+
 		icssg2_mii_g_rt: mii-g-rt@33000 {
 			compatible = "ti,pruss-mii-g", "syscon";
 			reg = <0x33000 0x1000>;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 11/16] arm: dts: k3-am654-base-board: Add ICSSG2 Ethernet support
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
                   ` (9 preceding siblings ...)
  2023-12-19 10:34 ` [RFC PATCH 10/16] arm: dts: k3-am65-main: Add ICSSG IEP nodes MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-20 10:08   ` Roger Quadros
  2023-12-19 10:34 ` [RFC PATCH 12/16] arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration MD Danish Anwar
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

ICSSG2 provides dual Gigabit Ethernet support.
Add ICSSG2 ethernet node to an overlay k3-am654-icssg2.dtso

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 arch/arm/dts/Makefile             |   3 +-
 arch/arm/dts/k3-am654-icssg2.dtso | 145 ++++++++++++++++++++++++++++++
 2 files changed, 147 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/dts/k3-am654-icssg2.dtso

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index e9e58c5478..2bc53fba89 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1396,7 +1396,8 @@ dtb-$(CONFIG_SOC_K3_AM654) += \
 	k3-am6548-iot2050-advanced-pg2.dtb \
 	k3-am6548-iot2050-advanced-m2.dtb \
 	k3-am6548-iot2050-advanced-m2-bkey-usb3-overlay.dtbo \
-	k3-am6548-iot2050-advanced-m2-bkey-ekey-pcie-overlay.dtbo
+	k3-am6548-iot2050-advanced-m2-bkey-ekey-pcie-overlay.dtbo \
+	k3-am654-icssg2.dtbo
 dtb-$(CONFIG_SOC_K3_J721E) += k3-j721e-common-proc-board.dtb \
 			      k3-j721e-r5-common-proc-board.dtb \
 			      k3-j7200-common-proc-board.dtb \
diff --git a/arch/arm/dts/k3-am654-icssg2.dtso b/arch/arm/dts/k3-am654-icssg2.dtso
new file mode 100644
index 0000000000..faefa2febc
--- /dev/null
+++ b/arch/arm/dts/k3-am654-icssg2.dtso
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * DT overlay for enabling ICSSG2 on AM654 EVM
+ *
+ * Copyright (C) 2018-2023 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/net/ti-dp83867.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+	aliases {
+		ethernet1 = "/icssg2-eth/ethernet-ports/port@0";
+		ethernet2 = "/icssg2-eth/ethernet-ports/port@1";
+	};
+
+	/* Ethernet node on PRU-ICSSG2 */
+	icssg2_eth: icssg2-eth {
+		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-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>;
+
+		ti,mii-g-rt = <&icssg2_mii_g_rt>;
+		ti,mii-rt = <&icssg2_mii_rt>;
+		ti,iep = <&icssg2_iep0>, <&icssg2_iep1>;
+
+		interrupt-parent = <&icssg2_intc>;
+		interrupts = <24 0 2>, <25 1 3>;
+		interrupt-names = "tx_ts0", "tx_ts1";
+
+		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";
+		ethernet-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			icssg2_emac0: port@0 {
+				reg = <0>;
+				phy-handle = <&icssg2_phy0>;
+				phy-mode = "rgmii-id";
+				ti,syscon-rgmii-delay = <&scm_conf 0x4120>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+			};
+			icssg2_emac1: port@1 {
+				reg = <1>;
+				phy-handle = <&icssg2_phy1>;
+				phy-mode = "rgmii-id";
+				ti,syscon-rgmii-delay = <&scm_conf 0x4124>;
+				/* Filled in by bootloader */
+				local-mac-address = [00 00 00 00 00 00];
+			};
+		};
+	};
+};
+
+&main_pmx0 {
+
+	icssg2_mdio_pins_default: icssg2-mdio-default-pins {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x0094, PIN_INPUT, 2) /* (AC19) PRG2_PRU0_GPO7.PRG2_MDIO0_MDIO */
+			AM65X_IOPAD(0x00c8, PIN_OUTPUT, 2) /* (AE15) PRG2_PRU1_GPO7.PRG2_MDIO0_MDC */
+		>;
+	};
+
+	icssg2_rgmii_pins_default: icssg2-rgmii-default-pins {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x00ac, PIN_INPUT, 2) /* (AH15) PRG2_PRU1_GPO0.PRG2_RGMII2_RD0 */
+			AM65X_IOPAD(0x00b0, PIN_INPUT, 2) /* (AC16) PRG2_PRU1_GPO1.PRG2_RGMII2_RD1 */
+			AM65X_IOPAD(0x00b4, PIN_INPUT, 2) /* (AD17) PRG2_PRU1_GPO2.PRG2_RGMII2_RD2 */
+			AM65X_IOPAD(0x00b8, PIN_INPUT, 2) /* (AH14) PRG2_PRU1_GPO3.PRG2_RGMII2_RD3 */
+			AM65X_IOPAD(0x00cc, PIN_OUTPUT, 2) /* (AD15) PRG2_PRU1_GPO8.PRG2_RGMII2_TD0 */
+			AM65X_IOPAD(0x00d0, PIN_OUTPUT, 2) /* (AF14) PRG2_PRU1_GPO9.PRG2_RGMII2_TD1 */
+			AM65X_IOPAD(0x00d4, PIN_OUTPUT, 2) /* (AC15) PRG2_PRU1_GPO10.PRG2_RGMII2_TD2 */
+			AM65X_IOPAD(0x00d8, PIN_OUTPUT, 2) /* (AD14) PRG2_PRU1_GPO11.PRG2_RGMII2_TD3 */
+			AM65X_IOPAD(0x00dc, PIN_INPUT, 2) /* (AE14) PRG2_PRU1_GPO16.PRG2_RGMII2_TXC */
+			AM65X_IOPAD(0x00c4, PIN_OUTPUT, 2) /* (AC17) PRG2_PRU1_GPO6.PRG2_RGMII2_TX_CTL */
+			AM65X_IOPAD(0x00c0, PIN_INPUT, 2) /* (AG15) PRG2_PRU1_GPO5.PRG2_RGMII2_RXC */
+			AM65X_IOPAD(0x00bc, PIN_INPUT, 2) /* (AG14) PRG2_PRU1_GPO4.PRG2_RGMII2_RX_CTL */
+
+			AM65X_IOPAD(0x0078, PIN_INPUT, 2) /* (AF18) PRG2_PRU0_GPO0.PRG2_RGMII1_RD0 */
+			AM65X_IOPAD(0x007c, PIN_INPUT, 2) /* (AE18) PRG2_PRU0_GPO1.PRG2_RGMII1_RD1 */
+			AM65X_IOPAD(0x0080, PIN_INPUT, 2) /* (AH17) PRG2_PRU0_GPO2.PRG2_RGMII1_RD2 */
+			AM65X_IOPAD(0x0084, PIN_INPUT, 2) /* (AG18) PRG2_PRU0_GPO3.PRG2_RGMII1_RD3 */
+			AM65X_IOPAD(0x0098, PIN_OUTPUT, 2) /* (AH16) PRG2_PRU0_GPO8.PRG2_RGMII1_TD0 */
+			AM65X_IOPAD(0x009c, PIN_OUTPUT, 2) /* (AG16) PRG2_PRU0_GPO9.PRG2_RGMII1_TD1 */
+			AM65X_IOPAD(0x00a0, PIN_OUTPUT, 2) /* (AF16) PRG2_PRU0_GPO10.PRG2_RGMII1_TD2 */
+			AM65X_IOPAD(0x00a4, PIN_OUTPUT, 2) /* (AE16) PRG2_PRU0_GPO11.PRG2_RGMII1_TD3 */
+			AM65X_IOPAD(0x00a8, PIN_INPUT, 2) /* (AD16) PRG2_PRU0_GPO16.PRG2_RGMII1_TXC */
+			AM65X_IOPAD(0x0090, PIN_OUTPUT, 2) /* (AE17) PRG2_PRU0_GPO6.PRG2_RGMII1_TX_CTL */
+			AM65X_IOPAD(0x008c, PIN_INPUT, 2) /* (AF17) PRG2_PRU0_GPO5.PRG2_RGMII1_RXC */
+			AM65X_IOPAD(0x0088, PIN_INPUT, 2) /* (AG17) PRG2_PRU0_GPO4.PRG2_RGMII1_RX_CTL */
+		>;
+	};
+};
+
+&icssg2_mdio {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&icssg2_mdio_pins_default>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	icssg2_phy0: ethernet-phy@0 {
+		reg = <0>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+	};
+
+	icssg2_phy1: ethernet-phy@3 {
+		reg = <3>;
+		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
+		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+	};
+};
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 12/16] arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
                   ` (10 preceding siblings ...)
  2023-12-19 10:34 ` [RFC PATCH 11/16] arm: dts: k3-am654-base-board: Add ICSSG2 Ethernet support MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-20 10:40   ` Roger Quadros
  2023-12-19 10:34 ` [RFC PATCH 13/16] configs: am65x_evm_a53: Enable ICSSG Driver MD Danish Anwar
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Add ICSSG2 overlay and configuration to tispl and u-boot images.

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 arch/arm/dts/k3-am65x-binman.dtsi | 85 +++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/arch/arm/dts/k3-am65x-binman.dtsi b/arch/arm/dts/k3-am65x-binman.dtsi
index 8cc24da1f3..9a0c0fca47 100644
--- a/arch/arm/dts/k3-am65x-binman.dtsi
+++ b/arch/arm/dts/k3-am65x-binman.dtsi
@@ -98,6 +98,8 @@
 #define SPL_AM654_EVM_DTB "spl/dts/k3-am654-base-board.dtb"
 #define AM654_EVM_DTB "u-boot.dtb"
 
+#define AM654_EVM_ICSSG2_DTBO "arch/arm/dts/k3-am654-icssg2.dtbo"
+
 &binman {
 	ti-spl {
 		insert-template = <&ti_spl_template>;
@@ -124,6 +126,20 @@
 						filename = SPL_AM654_EVM_DTB;
 					};
 				};
+
+				fdt-1 {
+					description = "k3-am654-icssg2 overlay";
+					type = "flat_dt";
+					arch = "arm";
+					compression = "none";
+					ti-secure {
+						content = <&spl_am65x_evm_icssg2_dtb>;
+						keyfile = "custMpk.pem";
+					};
+					spl_am65x_evm_icssg2_dtb: blob-ext {
+						filename = AM654_EVM_ICSSG2_DTBO;
+					};
+				};
 			};
 
 			configurations {
@@ -135,6 +151,13 @@
 					loadables = "tee", "dm", "spl";
 					fdt = "fdt-0";
 				};
+
+				conf-1 {
+					description = "k3-am654-icssg2";
+					firmware = "atf";
+					loadables = "tee", "dm", "spl";
+					fdt = "fdt-0", "fdt-1";
+				};
 			};
 		};
 	};
@@ -168,6 +191,24 @@
 					};
 				};
 
+				fdt-1 {
+					description = "k3-am654-icssg2 overlay";
+					type = "flat_dt";
+					arch = "arm";
+					compression = "none";
+					ti-secure {
+						content = <&am65x_evm_icssg2_dtb>;
+						keyfile = "custMpk.pem";
+
+					};
+					am65x_evm_icssg2_dtb: blob-ext {
+						filename = AM654_EVM_ICSSG2_DTBO;
+					};
+					hash {
+						algo = "crc32";
+					};
+				};
+
 			};
 
 			configurations {
@@ -179,6 +220,13 @@
 					loadables = "uboot";
 					fdt = "fdt-0";
 				};
+
+				conf-1 {
+					description = "k3-am654-icssg2";
+					firmware = "uboot";
+					loadables = "uboot";
+					fdt = "fdt-0", "fdt-1";
+				};
 			};
 		};
 	};
@@ -205,6 +253,16 @@
 						filename = SPL_AM654_EVM_DTB;
 					};
 				};
+
+				fdt-1 {
+					description = "k3-am654-icssg2 overlay";
+					type = "flat_dt";
+					arch = "arm";
+					compression = "none";
+					blob {
+						filename = AM654_EVM_ICSSG2_DTBO;
+					};
+				};
 			};
 
 			configurations {
@@ -216,6 +274,13 @@
 					loadables = "tee", "dm", "spl";
 					fdt = "fdt-0";
 				};
+
+				conf-1 {
+					description = "k3-am654-icssg2";
+					firmware = "atf";
+					loadables = "tee", "dm", "spl";
+					fdt = "fdt-0", "fdt-1";
+				};
 			};
 		};
 	};
@@ -243,6 +308,19 @@
 						algo = "crc32";
 					};
 				};
+
+				fdt-1 {
+					description = "k3-am654-icssg2";
+					type = "flat_dt";
+					arch = "arm";
+					compression = "none";
+					blob {
+						filename = AM654_EVM_ICSSG2_DTBO;
+					};
+					hash {
+						algo = "crc32";
+					};
+				};
 			};
 
 			configurations {
@@ -254,6 +332,13 @@
 					loadables = "uboot";
 					fdt = "fdt-0";
 				};
+
+				conf-1 {
+					description = "k3-am654-icssg2";
+					firmware = "uboot";
+					loadables = "uboot";
+					fdt = "fdt-0", "fdt-1";
+				};
 			};
 		};
 	};
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 13/16] configs: am65x_evm_a53: Enable ICSSG Driver
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
                   ` (11 preceding siblings ...)
  2023-12-19 10:34 ` [RFC PATCH 12/16] arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 14/16] configs: am65x_evm_a53_defconfig: add SPL_LOAD_FIT_APPLY_OVERLAY MD Danish Anwar
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Enable ICSSG driver in am65x_evm_a53_defconfig

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 configs/am65x_evm_a53_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig
index 55289b967b..e79a961317 100644
--- a/configs/am65x_evm_a53_defconfig
+++ b/configs/am65x_evm_a53_defconfig
@@ -130,6 +130,7 @@ CONFIG_PHY_FIXED=y
 CONFIG_E1000=y
 CONFIG_CMD_E1000=y
 CONFIG_TI_AM65_CPSW_NUSS=y
+CONFIG_TI_ICSSG_PRUETH=y
 CONFIG_PCI_KEYSTONE=y
 CONFIG_PHY=y
 CONFIG_SPL_PHY=y
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 14/16] configs: am65x_evm_a53_defconfig: add SPL_LOAD_FIT_APPLY_OVERLAY
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
                   ` (12 preceding siblings ...)
  2023-12-19 10:34 ` [RFC PATCH 13/16] configs: am65x_evm_a53: Enable ICSSG Driver MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-20 10:02   ` Roger Quadros
  2023-12-19 10:34 ` [RFC PATCH 15/16] tools/fdtgrep: Include __symbols__ table MD Danish Anwar
  2023-12-19 10:34 ` [RFC PATCH 16/16] board: ti: am65x: Add check for k3-am654-icssg2 in board_fit_config_match() MD Danish Anwar
  15 siblings, 1 reply; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

We want SPL to apply DTB overlays (e.g. NAND card overlay) so
enable SPL_LOAD_FIT_APPLY_OVERLAY.
Increase SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ and
SPL_STACK_R_MALLOC_SIMPLE_LEN. Without this SPL hangs.

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 configs/am65x_evm_a53_defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig
index e79a961317..2755d7082f 100644
--- a/configs/am65x_evm_a53_defconfig
+++ b/configs/am65x_evm_a53_defconfig
@@ -70,6 +70,9 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_PCI=y
 CONFIG_CMD_REMOTEPROC=y
+CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY=y
+CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ=0x100000
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x1000000
 CONFIG_CMD_USB=y
 CONFIG_CMD_TIME=y
 CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0"
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 15/16] tools/fdtgrep: Include __symbols__ table
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
                   ` (13 preceding siblings ...)
  2023-12-19 10:34 ` [RFC PATCH 14/16] configs: am65x_evm_a53_defconfig: add SPL_LOAD_FIT_APPLY_OVERLAY MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  2023-12-26  9:47   ` Simon Glass
  2023-12-19 10:34 ` [RFC PATCH 16/16] board: ti: am65x: Add check for k3-am654-icssg2 in board_fit_config_match() MD Danish Anwar
  15 siblings, 1 reply; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

This is required for overlays to work at SPL.

Loading of symbol table depends on DT Overlay support in SPL
so make it compile-time dependent. Without this SPL fails to
boot some platforms where this feature is not enabled
(e.g. dra71-evm.)

Without including the <linux/kconfig.h> file, the symbol
CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY will not be visible and
we will never include the symbol table.

So include <linux/kconfig.h>

Due to some reason it needs to be included after
[#include "fdt_host.h"] otherwise it causes a build error.

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 tools/fdtgrep.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/tools/fdtgrep.c b/tools/fdtgrep.c
index 7eabcab439..706b4a35f4 100644
--- a/tools/fdtgrep.c
+++ b/tools/fdtgrep.c
@@ -22,6 +22,8 @@
 #include "fdt_host.h"
 #include "libfdt_internal.h"
 
+#include <linux/kconfig.h>
+
 /* Define DEBUG to get some debugging output on stderr */
 #ifdef DEBUG
 #define debug(a, b...) fprintf(stderr, a, ## b)
@@ -1234,6 +1236,12 @@ int main(int argc, char *argv[])
 		disp.fout = stdout;
 	}
 
+	if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY)) {
+		/* include symbol table */
+		if (value_add(&disp, &disp.value_head, FDT_IS_NODE, 1, "/__symbols__"))
+			usage("Cannot add __symbols__ value");
+	}
+
 	/* Run the grep and output the results */
 	ret = do_fdtgrep(&disp, filename);
 	if (disp.output_fname)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 16/16] board: ti: am65x: Add check for k3-am654-icssg2 in board_fit_config_match()
  2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
                   ` (14 preceding siblings ...)
  2023-12-19 10:34 ` [RFC PATCH 15/16] tools/fdtgrep: Include __symbols__ table MD Danish Anwar
@ 2023-12-19 10:34 ` MD Danish Anwar
  15 siblings, 0 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:34 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

When CONFIG_TI_ICSSG_PRUETH is enabled, add config name check for the
icssg2 overlay in board_fit_config_match() API.

Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
---
 board/ti/am65x/evm.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/board/ti/am65x/evm.c b/board/ti/am65x/evm.c
index df209021c1..0b661f0084 100644
--- a/board/ti/am65x/evm.c
+++ b/board/ti/am65x/evm.c
@@ -90,10 +90,13 @@ int dram_init_banksize(void)
 #ifdef CONFIG_SPL_LOAD_FIT
 int board_fit_config_name_match(const char *name)
 {
-#ifdef CONFIG_TARGET_AM654_A53_EVM
-	if (!strcmp(name, "k3-am654-base-board"))
-		return 0;
-#endif
+	if (IS_ENABLED(CONFIG_TI_ICSSG_PRUETH)) {
+		if (!strcmp(name, "k3-am654-icssg2"))
+			return 0;
+	} else {
+		if (!strcmp(name, "k3-am654-base-board"))
+			return 0;
+	}
 
 	return -1;
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 10/16] arm: dts: k3-am65-main: Add ICSSG IEP nodes
  2023-12-19 10:34 ` [RFC PATCH 10/16] arm: dts: k3-am65-main: Add ICSSG IEP nodes MD Danish Anwar
@ 2023-12-19 17:46   ` Tom Rini
  2023-12-20  4:47     ` MD Danish Anwar
  0 siblings, 1 reply; 48+ messages in thread
From: Tom Rini @ 2023-12-19 17:46 UTC (permalink / raw)
  To: MD Danish Anwar
  Cc: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass, u-boot,
	srk, r-gunasekaran

[-- Attachment #1: Type: text/plain, Size: 670 bytes --]

On Tue, Dec 19, 2023 at 04:04:12PM +0530, MD Danish Anwar wrote:

> The ICSSG IP on AM65x SoCs have two Industrial Ethernet Peripherals (IEPs)
> to manage/generate Industrial Ethernet functions such as time stamping.
> 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: MD Danish Anwar <danishanwar@ti.com>
> ---
>  arch/arm/dts/k3-am65-main.dtsi | 36 ++++++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)

What's the status of all of the DT side of this, upstream?

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 10/16] arm: dts: k3-am65-main: Add ICSSG IEP nodes
  2023-12-19 17:46   ` Tom Rini
@ 2023-12-20  4:47     ` MD Danish Anwar
  2023-12-20 12:52       ` Nishanth Menon
  0 siblings, 1 reply; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-20  4:47 UTC (permalink / raw)
  To: Tom Rini
  Cc: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass, u-boot,
	srk, r-gunasekaran

Hi Tom,

On 19/12/23 11:16 pm, Tom Rini wrote:
> On Tue, Dec 19, 2023 at 04:04:12PM +0530, MD Danish Anwar wrote:
> 
>> The ICSSG IP on AM65x SoCs have two Industrial Ethernet Peripherals (IEPs)
>> to manage/generate Industrial Ethernet functions such as time stamping.
>> 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: MD Danish Anwar <danishanwar@ti.com>
>> ---
>>  arch/arm/dts/k3-am65-main.dtsi | 36 ++++++++++++++++++++++++++++++++++
>>  1 file changed, 36 insertions(+)
> 
> What's the status of all of the DT side of this, upstream?
> 

All of the DT patches are already part of upstream linux kernel except
for patch 08/16. This patch is currently in linux-next and will be in
linux in 6.8-rc1.

-- 
Thanks and Regards,
Danish

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 14/16] configs: am65x_evm_a53_defconfig: add SPL_LOAD_FIT_APPLY_OVERLAY
  2023-12-19 10:34 ` [RFC PATCH 14/16] configs: am65x_evm_a53_defconfig: add SPL_LOAD_FIT_APPLY_OVERLAY MD Danish Anwar
@ 2023-12-20 10:02   ` Roger Quadros
  2023-12-21  5:57     ` MD Danish Anwar
  0 siblings, 1 reply; 48+ messages in thread
From: Roger Quadros @ 2023-12-20 10:02 UTC (permalink / raw)
  To: MD Danish Anwar, Maxime Ripard, Siddharth Vadapalli,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran



On 19/12/2023 12:34, MD Danish Anwar wrote:
> We want SPL to apply DTB overlays (e.g. NAND card overlay) so
> enable SPL_LOAD_FIT_APPLY_OVERLAY.
> Increase SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ and
> SPL_STACK_R_MALLOC_SIMPLE_LEN. Without this SPL hangs.
> 
> Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
> ---
>  configs/am65x_evm_a53_defconfig | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig
> index e79a961317..2755d7082f 100644
> --- a/configs/am65x_evm_a53_defconfig
> +++ b/configs/am65x_evm_a53_defconfig
> @@ -70,6 +70,9 @@ CONFIG_CMD_I2C=y
>  CONFIG_CMD_MMC=y
>  CONFIG_CMD_PCI=y
>  CONFIG_CMD_REMOTEPROC=y
> +CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY=y
> +CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ=0x100000
> +CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x1000000

This change to 16MB is not required. I suppose default is 4MB.
Did you face issues with it?

>  CONFIG_CMD_USB=y
>  CONFIG_CMD_TIME=y
>  CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0"

-- 
cheers,
-roger

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 11/16] arm: dts: k3-am654-base-board: Add ICSSG2 Ethernet support
  2023-12-19 10:34 ` [RFC PATCH 11/16] arm: dts: k3-am654-base-board: Add ICSSG2 Ethernet support MD Danish Anwar
@ 2023-12-20 10:08   ` Roger Quadros
  2023-12-20 10:13     ` Anwar, Md Danish
  0 siblings, 1 reply; 48+ messages in thread
From: Roger Quadros @ 2023-12-20 10:08 UTC (permalink / raw)
  To: MD Danish Anwar, Maxime Ripard, Siddharth Vadapalli,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran



On 19/12/2023 12:34, MD Danish Anwar wrote:
> ICSSG2 provides dual Gigabit Ethernet support.
> Add ICSSG2 ethernet node to an overlay k3-am654-icssg2.dtso
> 
> Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
> ---
>  arch/arm/dts/Makefile             |   3 +-
>  arch/arm/dts/k3-am654-icssg2.dtso | 145 ++++++++++++++++++++++++++++++
>  2 files changed, 147 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/dts/k3-am654-icssg2.dtso
> 
> diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
> index e9e58c5478..2bc53fba89 100644
> --- a/arch/arm/dts/Makefile
> +++ b/arch/arm/dts/Makefile
> @@ -1396,7 +1396,8 @@ dtb-$(CONFIG_SOC_K3_AM654) += \
>  	k3-am6548-iot2050-advanced-pg2.dtb \
>  	k3-am6548-iot2050-advanced-m2.dtb \
>  	k3-am6548-iot2050-advanced-m2-bkey-usb3-overlay.dtbo \
> -	k3-am6548-iot2050-advanced-m2-bkey-ekey-pcie-overlay.dtbo
> +	k3-am6548-iot2050-advanced-m2-bkey-ekey-pcie-overlay.dtbo \
> +	k3-am654-icssg2.dtbo
>  dtb-$(CONFIG_SOC_K3_J721E) += k3-j721e-common-proc-board.dtb \
>  			      k3-j721e-r5-common-proc-board.dtb \
>  			      k3-j7200-common-proc-board.dtb \
> diff --git a/arch/arm/dts/k3-am654-icssg2.dtso b/arch/arm/dts/k3-am654-icssg2.dtso
> new file mode 100644
> index 0000000000..faefa2febc
> --- /dev/null
> +++ b/arch/arm/dts/k3-am654-icssg2.dtso

Why is this an overlay file? Isn't ICSSG2 part of base board?

> @@ -0,0 +1,145 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/**
> + * DT overlay for enabling ICSSG2 on AM654 EVM
> + *
> + * Copyright (C) 2018-2023 Texas Instruments Incorporated - https://www.ti.com/
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +#include <dt-bindings/net/ti-dp83867.h>
> +#include "k3-pinctrl.h"
> +
> +&{/} {
> +	aliases {
> +		ethernet1 = "/icssg2-eth/ethernet-ports/port@0";
> +		ethernet2 = "/icssg2-eth/ethernet-ports/port@1";
> +	};
> +
> +	/* Ethernet node on PRU-ICSSG2 */
> +	icssg2_eth: icssg2-eth {
> +		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-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>;
> +
> +		ti,mii-g-rt = <&icssg2_mii_g_rt>;
> +		ti,mii-rt = <&icssg2_mii_rt>;
> +		ti,iep = <&icssg2_iep0>, <&icssg2_iep1>;
> +
> +		interrupt-parent = <&icssg2_intc>;
> +		interrupts = <24 0 2>, <25 1 3>;
> +		interrupt-names = "tx_ts0", "tx_ts1";
> +
> +		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";
> +		ethernet-ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			icssg2_emac0: port@0 {
> +				reg = <0>;
> +				phy-handle = <&icssg2_phy0>;
> +				phy-mode = "rgmii-id";
> +				ti,syscon-rgmii-delay = <&scm_conf 0x4120>;
> +				/* Filled in by bootloader */
> +				local-mac-address = [00 00 00 00 00 00];
> +			};
> +			icssg2_emac1: port@1 {
> +				reg = <1>;
> +				phy-handle = <&icssg2_phy1>;
> +				phy-mode = "rgmii-id";
> +				ti,syscon-rgmii-delay = <&scm_conf 0x4124>;
> +				/* Filled in by bootloader */
> +				local-mac-address = [00 00 00 00 00 00];
> +			};
> +		};
> +	};
> +};
> +
> +&main_pmx0 {
> +
> +	icssg2_mdio_pins_default: icssg2-mdio-default-pins {
> +		pinctrl-single,pins = <
> +			AM65X_IOPAD(0x0094, PIN_INPUT, 2) /* (AC19) PRG2_PRU0_GPO7.PRG2_MDIO0_MDIO */
> +			AM65X_IOPAD(0x00c8, PIN_OUTPUT, 2) /* (AE15) PRG2_PRU1_GPO7.PRG2_MDIO0_MDC */
> +		>;
> +	};
> +
> +	icssg2_rgmii_pins_default: icssg2-rgmii-default-pins {
> +		pinctrl-single,pins = <
> +			AM65X_IOPAD(0x00ac, PIN_INPUT, 2) /* (AH15) PRG2_PRU1_GPO0.PRG2_RGMII2_RD0 */
> +			AM65X_IOPAD(0x00b0, PIN_INPUT, 2) /* (AC16) PRG2_PRU1_GPO1.PRG2_RGMII2_RD1 */
> +			AM65X_IOPAD(0x00b4, PIN_INPUT, 2) /* (AD17) PRG2_PRU1_GPO2.PRG2_RGMII2_RD2 */
> +			AM65X_IOPAD(0x00b8, PIN_INPUT, 2) /* (AH14) PRG2_PRU1_GPO3.PRG2_RGMII2_RD3 */
> +			AM65X_IOPAD(0x00cc, PIN_OUTPUT, 2) /* (AD15) PRG2_PRU1_GPO8.PRG2_RGMII2_TD0 */
> +			AM65X_IOPAD(0x00d0, PIN_OUTPUT, 2) /* (AF14) PRG2_PRU1_GPO9.PRG2_RGMII2_TD1 */
> +			AM65X_IOPAD(0x00d4, PIN_OUTPUT, 2) /* (AC15) PRG2_PRU1_GPO10.PRG2_RGMII2_TD2 */
> +			AM65X_IOPAD(0x00d8, PIN_OUTPUT, 2) /* (AD14) PRG2_PRU1_GPO11.PRG2_RGMII2_TD3 */
> +			AM65X_IOPAD(0x00dc, PIN_INPUT, 2) /* (AE14) PRG2_PRU1_GPO16.PRG2_RGMII2_TXC */
> +			AM65X_IOPAD(0x00c4, PIN_OUTPUT, 2) /* (AC17) PRG2_PRU1_GPO6.PRG2_RGMII2_TX_CTL */
> +			AM65X_IOPAD(0x00c0, PIN_INPUT, 2) /* (AG15) PRG2_PRU1_GPO5.PRG2_RGMII2_RXC */
> +			AM65X_IOPAD(0x00bc, PIN_INPUT, 2) /* (AG14) PRG2_PRU1_GPO4.PRG2_RGMII2_RX_CTL */
> +
> +			AM65X_IOPAD(0x0078, PIN_INPUT, 2) /* (AF18) PRG2_PRU0_GPO0.PRG2_RGMII1_RD0 */
> +			AM65X_IOPAD(0x007c, PIN_INPUT, 2) /* (AE18) PRG2_PRU0_GPO1.PRG2_RGMII1_RD1 */
> +			AM65X_IOPAD(0x0080, PIN_INPUT, 2) /* (AH17) PRG2_PRU0_GPO2.PRG2_RGMII1_RD2 */
> +			AM65X_IOPAD(0x0084, PIN_INPUT, 2) /* (AG18) PRG2_PRU0_GPO3.PRG2_RGMII1_RD3 */
> +			AM65X_IOPAD(0x0098, PIN_OUTPUT, 2) /* (AH16) PRG2_PRU0_GPO8.PRG2_RGMII1_TD0 */
> +			AM65X_IOPAD(0x009c, PIN_OUTPUT, 2) /* (AG16) PRG2_PRU0_GPO9.PRG2_RGMII1_TD1 */
> +			AM65X_IOPAD(0x00a0, PIN_OUTPUT, 2) /* (AF16) PRG2_PRU0_GPO10.PRG2_RGMII1_TD2 */
> +			AM65X_IOPAD(0x00a4, PIN_OUTPUT, 2) /* (AE16) PRG2_PRU0_GPO11.PRG2_RGMII1_TD3 */
> +			AM65X_IOPAD(0x00a8, PIN_INPUT, 2) /* (AD16) PRG2_PRU0_GPO16.PRG2_RGMII1_TXC */
> +			AM65X_IOPAD(0x0090, PIN_OUTPUT, 2) /* (AE17) PRG2_PRU0_GPO6.PRG2_RGMII1_TX_CTL */
> +			AM65X_IOPAD(0x008c, PIN_INPUT, 2) /* (AF17) PRG2_PRU0_GPO5.PRG2_RGMII1_RXC */
> +			AM65X_IOPAD(0x0088, PIN_INPUT, 2) /* (AG17) PRG2_PRU0_GPO4.PRG2_RGMII1_RX_CTL */
> +		>;
> +	};
> +};
> +
> +&icssg2_mdio {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&icssg2_mdio_pins_default>;
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +
> +	icssg2_phy0: ethernet-phy@0 {
> +		reg = <0>;
> +		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
> +		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
> +	};
> +
> +	icssg2_phy1: ethernet-phy@3 {
> +		reg = <3>;
> +		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
> +		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
> +	};
> +};

-- 
cheers,
-roger

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 11/16] arm: dts: k3-am654-base-board: Add ICSSG2 Ethernet support
  2023-12-20 10:08   ` Roger Quadros
@ 2023-12-20 10:13     ` Anwar, Md Danish
  0 siblings, 0 replies; 48+ messages in thread
From: Anwar, Md Danish @ 2023-12-20 10:13 UTC (permalink / raw)
  To: Roger Quadros, MD Danish Anwar, Maxime Ripard,
	Siddharth Vadapalli, Nishanth Menon, Vignesh Raghavendra,
	Matthias Schiffer, Kamlesh Gurudasani, Manorit Chawdhry,
	Neha Malcom Francis, Andrew Davis, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

On 12/20/2023 3:38 PM, Roger Quadros wrote:
> 
> 
> On 19/12/2023 12:34, MD Danish Anwar wrote:
>> ICSSG2 provides dual Gigabit Ethernet support.
>> Add ICSSG2 ethernet node to an overlay k3-am654-icssg2.dtso
>>
>> Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
>> ---
>>  arch/arm/dts/Makefile             |   3 +-
>>  arch/arm/dts/k3-am654-icssg2.dtso | 145 ++++++++++++++++++++++++++++++
>>  2 files changed, 147 insertions(+), 1 deletion(-)
>>  create mode 100644 arch/arm/dts/k3-am654-icssg2.dtso
>>
>> diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
>> index e9e58c5478..2bc53fba89 100644
>> --- a/arch/arm/dts/Makefile
>> +++ b/arch/arm/dts/Makefile
>> @@ -1396,7 +1396,8 @@ dtb-$(CONFIG_SOC_K3_AM654) += \
>>  	k3-am6548-iot2050-advanced-pg2.dtb \
>>  	k3-am6548-iot2050-advanced-m2.dtb \
>>  	k3-am6548-iot2050-advanced-m2-bkey-usb3-overlay.dtbo \
>> -	k3-am6548-iot2050-advanced-m2-bkey-ekey-pcie-overlay.dtbo
>> +	k3-am6548-iot2050-advanced-m2-bkey-ekey-pcie-overlay.dtbo \
>> +	k3-am654-icssg2.dtbo
>>  dtb-$(CONFIG_SOC_K3_J721E) += k3-j721e-common-proc-board.dtb \
>>  			      k3-j721e-r5-common-proc-board.dtb \
>>  			      k3-j7200-common-proc-board.dtb \
>> diff --git a/arch/arm/dts/k3-am654-icssg2.dtso b/arch/arm/dts/k3-am654-icssg2.dtso
>> new file mode 100644
>> index 0000000000..faefa2febc
>> --- /dev/null
>> +++ b/arch/arm/dts/k3-am654-icssg2.dtso
> 
> Why is this an overlay file? Isn't ICSSG2 part of base board?
> 

It was decided during linux upstreaming [1] of this patch that ICSSG2
node should be added in overlay (suggested by 'Andrew Davis
<afd@ti.com>'). As this node is in overlay in upstream linux, I kept it
in overlay in upstream uboot as well.

[1] https://lore.kernel.org/all/f1fe8dab-350d-002e-c922-58e5912bd76f@ti.com/

>> @@ -0,0 +1,145 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/**
>> + * DT overlay for enabling ICSSG2 on AM654 EVM
>> + *
>> + * Copyright (C) 2018-2023 Texas Instruments Incorporated - https://www.ti.com/
>> + */
>> +

[ ... ]

-- 
Thanks and Regards,
Md Danish Anwar

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 12/16] arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration
  2023-12-19 10:34 ` [RFC PATCH 12/16] arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration MD Danish Anwar
@ 2023-12-20 10:40   ` Roger Quadros
  2023-12-27 10:19     ` MD Danish Anwar
  0 siblings, 1 reply; 48+ messages in thread
From: Roger Quadros @ 2023-12-20 10:40 UTC (permalink / raw)
  To: MD Danish Anwar, Maxime Ripard, Siddharth Vadapalli,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran



On 19/12/2023 12:34, MD Danish Anwar wrote:
> Add ICSSG2 overlay and configuration to tispl and u-boot images.
> 
> Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
> ---
>  arch/arm/dts/k3-am65x-binman.dtsi | 85 +++++++++++++++++++++++++++++++
>  1 file changed, 85 insertions(+)
> 
> diff --git a/arch/arm/dts/k3-am65x-binman.dtsi b/arch/arm/dts/k3-am65x-binman.dtsi
> index 8cc24da1f3..9a0c0fca47 100644
> --- a/arch/arm/dts/k3-am65x-binman.dtsi
> +++ b/arch/arm/dts/k3-am65x-binman.dtsi
> @@ -98,6 +98,8 @@
>  #define SPL_AM654_EVM_DTB "spl/dts/k3-am654-base-board.dtb"
>  #define AM654_EVM_DTB "u-boot.dtb"
>  
> +#define AM654_EVM_ICSSG2_DTBO "arch/arm/dts/k3-am654-icssg2.dtbo"
> +
>  &binman {
>  	ti-spl {
>  		insert-template = <&ti_spl_template>;
> @@ -124,6 +126,20 @@
>  						filename = SPL_AM654_EVM_DTB;
>  					};
>  				};
> +
> +				fdt-1 {
> +					description = "k3-am654-icssg2 overlay";
> +					type = "flat_dt";
> +					arch = "arm";
> +					compression = "none";
> +					ti-secure {
> +						content = <&spl_am65x_evm_icssg2_dtb>;
> +						keyfile = "custMpk.pem";
> +					};
> +					spl_am65x_evm_icssg2_dtb: blob-ext {
> +						filename = AM654_EVM_ICSSG2_DTBO;
> +					};

This is wrong.

ICSSG2 Ethernet should be part of the fdt-0 configuration as the 2 Ethernet ports
on the board are hardwired to ICSSG2. Not having them working by default
is an invalid configuration.

> +				};
>  			};
>  
>  			configurations {
> @@ -135,6 +151,13 @@
>  					loadables = "tee", "dm", "spl";
>  					fdt = "fdt-0";
>  				};
> +
> +				conf-1 {
> +					description = "k3-am654-icssg2";
> +					firmware = "atf";
> +					loadables = "tee", "dm", "spl";
> +					fdt = "fdt-0", "fdt-1";
> +				};
>  			};
>  		};
>  	};
> @@ -168,6 +191,24 @@
>  					};
>  				};
>  
> +				fdt-1 {
> +					description = "k3-am654-icssg2 overlay";
> +					type = "flat_dt";
> +					arch = "arm";
> +					compression = "none";
> +					ti-secure {
> +						content = <&am65x_evm_icssg2_dtb>;
> +						keyfile = "custMpk.pem";
> +
> +					};
> +					am65x_evm_icssg2_dtb: blob-ext {
> +						filename = AM654_EVM_ICSSG2_DTBO;
> +					};
> +					hash {
> +						algo = "crc32";
> +					};
> +				};
> +
>  			};
>  
>  			configurations {
> @@ -179,6 +220,13 @@
>  					loadables = "uboot";
>  					fdt = "fdt-0";
>  				};
> +
> +				conf-1 {
> +					description = "k3-am654-icssg2";
> +					firmware = "uboot";
> +					loadables = "uboot";
> +					fdt = "fdt-0", "fdt-1";
> +				};
>  			};
>  		};
>  	};
> @@ -205,6 +253,16 @@
>  						filename = SPL_AM654_EVM_DTB;
>  					};
>  				};
> +
> +				fdt-1 {
> +					description = "k3-am654-icssg2 overlay";
> +					type = "flat_dt";
> +					arch = "arm";
> +					compression = "none";
> +					blob {
> +						filename = AM654_EVM_ICSSG2_DTBO;
> +					};
> +				};
>  			};
>  
>  			configurations {
> @@ -216,6 +274,13 @@
>  					loadables = "tee", "dm", "spl";
>  					fdt = "fdt-0";
>  				};
> +
> +				conf-1 {
> +					description = "k3-am654-icssg2";
> +					firmware = "atf";
> +					loadables = "tee", "dm", "spl";
> +					fdt = "fdt-0", "fdt-1";
> +				};
>  			};
>  		};
>  	};
> @@ -243,6 +308,19 @@
>  						algo = "crc32";
>  					};
>  				};
> +
> +				fdt-1 {
> +					description = "k3-am654-icssg2";
> +					type = "flat_dt";
> +					arch = "arm";
> +					compression = "none";
> +					blob {
> +						filename = AM654_EVM_ICSSG2_DTBO;
> +					};
> +					hash {
> +						algo = "crc32";
> +					};
> +				};
>  			};
>  
>  			configurations {
> @@ -254,6 +332,13 @@
>  					loadables = "uboot";
>  					fdt = "fdt-0";
>  				};
> +
> +				conf-1 {
> +					description = "k3-am654-icssg2";
> +					firmware = "uboot";
> +					loadables = "uboot";
> +					fdt = "fdt-0", "fdt-1";
> +				};
>  			};
>  		};
>  	};

-- 
cheers,
-roger

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 10/16] arm: dts: k3-am65-main: Add ICSSG IEP nodes
  2023-12-20  4:47     ` MD Danish Anwar
@ 2023-12-20 12:52       ` Nishanth Menon
  2023-12-20 13:23         ` Anwar, Md Danish
  0 siblings, 1 reply; 48+ messages in thread
From: Nishanth Menon @ 2023-12-20 12:52 UTC (permalink / raw)
  To: MD Danish Anwar
  Cc: Tom Rini, Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Vignesh Raghavendra, Matthias Schiffer, Kamlesh Gurudasani,
	Manorit Chawdhry, Neha Malcom Francis, Andrew Davis, Ramon Fried,
	Joe Hershberger, Simon Glass, u-boot, srk, r-gunasekaran

On 10:17-20231220, MD Danish Anwar wrote:
> Hi Tom,
> 
> On 19/12/23 11:16 pm, Tom Rini wrote:
> > On Tue, Dec 19, 2023 at 04:04:12PM +0530, MD Danish Anwar wrote:
> > 
> >> The ICSSG IP on AM65x SoCs have two Industrial Ethernet Peripherals (IEPs)
> >> to manage/generate Industrial Ethernet functions such as time stamping.
> >> 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: MD Danish Anwar <danishanwar@ti.com>
> >> ---
> >>  arch/arm/dts/k3-am65-main.dtsi | 36 ++++++++++++++++++++++++++++++++++
> >>  1 file changed, 36 insertions(+)
> > 
> > What's the status of all of the DT side of this, upstream?
> > 
> 
> All of the DT patches are already part of upstream linux kernel except
> for patch 08/16. This patch is currently in linux-next and will be in
> linux in 6.8-rc1.
> 

NAK.

Send a sync at 6.8-rc1 and then start working - DONOT SEND patches
modifying SoC dtsi or evm files directly in u-boot.

I think you need to start talking to other folks in the team who have
have received the same feedback.

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 10/16] arm: dts: k3-am65-main: Add ICSSG IEP nodes
  2023-12-20 12:52       ` Nishanth Menon
@ 2023-12-20 13:23         ` Anwar, Md Danish
  0 siblings, 0 replies; 48+ messages in thread
From: Anwar, Md Danish @ 2023-12-20 13:23 UTC (permalink / raw)
  To: Nishanth Menon, MD Danish Anwar
  Cc: Tom Rini, Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Vignesh Raghavendra, Matthias Schiffer, Kamlesh Gurudasani,
	Manorit Chawdhry, Neha Malcom Francis, Andrew Davis, Ramon Fried,
	Joe Hershberger, Simon Glass, u-boot, srk, r-gunasekaran

On 12/20/2023 6:22 PM, Nishanth Menon wrote:
> On 10:17-20231220, MD Danish Anwar wrote:
>> Hi Tom,
>>
>> On 19/12/23 11:16 pm, Tom Rini wrote:
>>> On Tue, Dec 19, 2023 at 04:04:12PM +0530, MD Danish Anwar wrote:
>>>
>>>> The ICSSG IP on AM65x SoCs have two Industrial Ethernet Peripherals (IEPs)
>>>> to manage/generate Industrial Ethernet functions such as time stamping.
>>>> 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: MD Danish Anwar <danishanwar@ti.com>
>>>> ---
>>>>  arch/arm/dts/k3-am65-main.dtsi | 36 ++++++++++++++++++++++++++++++++++
>>>>  1 file changed, 36 insertions(+)
>>>
>>> What's the status of all of the DT side of this, upstream?
>>>
>>
>> All of the DT patches are already part of upstream linux kernel except
>> for patch 08/16. This patch is currently in linux-next and will be in
>> linux in 6.8-rc1.
>>
> 
> NAK.
> 
> Send a sync at 6.8-rc1 and then start working - DONOT SEND patches
> modifying SoC dtsi or evm files directly in u-boot.
> 

Sorry. I wasn't aware of this. I will resend this only after the changes
are in mainline linux.

> I think you need to start talking to other folks in the team who have
> have received the same feedback.
> 

Sure Nishant. Will do.

-- 
Thanks and Regards,
Md Danish Anwar

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 14/16] configs: am65x_evm_a53_defconfig: add SPL_LOAD_FIT_APPLY_OVERLAY
  2023-12-20 10:02   ` Roger Quadros
@ 2023-12-21  5:57     ` MD Danish Anwar
  0 siblings, 0 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-21  5:57 UTC (permalink / raw)
  To: Roger Quadros, Maxime Ripard, Siddharth Vadapalli,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Roger,

On 20/12/23 3:32 pm, Roger Quadros wrote:
> 
> 
> On 19/12/2023 12:34, MD Danish Anwar wrote:
>> We want SPL to apply DTB overlays (e.g. NAND card overlay) so
>> enable SPL_LOAD_FIT_APPLY_OVERLAY.
>> Increase SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ and
>> SPL_STACK_R_MALLOC_SIMPLE_LEN. Without this SPL hangs.
>>
>> Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
>> ---
>>  configs/am65x_evm_a53_defconfig | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig
>> index e79a961317..2755d7082f 100644
>> --- a/configs/am65x_evm_a53_defconfig
>> +++ b/configs/am65x_evm_a53_defconfig
>> @@ -70,6 +70,9 @@ CONFIG_CMD_I2C=y
>>  CONFIG_CMD_MMC=y
>>  CONFIG_CMD_PCI=y
>>  CONFIG_CMD_REMOTEPROC=y
>> +CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY=y
>> +CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ=0x100000
>> +CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x1000000
> 
> This change to 16MB is not required. I suppose default is 4MB.
> Did you face issues with it?
> 

Without these I see below error in uboot,

U-Boot SPL 2024.01-rc5-00539-gdc3afd4d5b (Dec 21 2023 - 11:23:56 +0530)
SYSFW ABI: 3.1 (firmware rev 0x0009 '9.1.6--v09.01.06 (Kool Koala)')
Trying to boot from MMC2
spl_register_fat_device: fat register err - -1
spl_load_image_fat: error reading image u-boot.img, err - -1
SPL: failed to boot from all boot devices
### ERROR ### Please RESET the board ###

The only way to recover from here is to do a power cycle reset. But when
you boot again, the issue is seen again. So I think these changes are
also needed. Without this, SPL doesn't work properly.

>>  CONFIG_CMD_USB=y
>>  CONFIG_CMD_TIME=y
>>  CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0"
> 

-- 
Thanks and Regards,
Danish

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 15/16] tools/fdtgrep: Include __symbols__ table
  2023-12-19 10:34 ` [RFC PATCH 15/16] tools/fdtgrep: Include __symbols__ table MD Danish Anwar
@ 2023-12-26  9:47   ` Simon Glass
  2024-01-10  9:52     ` MD Danish Anwar
  0 siblings, 1 reply; 48+ messages in thread
From: Simon Glass @ 2023-12-26  9:47 UTC (permalink / raw)
  To: MD Danish Anwar
  Cc: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Tom Rini, u-boot,
	srk, r-gunasekaran

Hi,

On Tue, Dec 19, 2023 at 10:34 AM MD Danish Anwar <danishanwar@ti.com> wrote:
>
> This is required for overlays to work at SPL.
>
> Loading of symbol table depends on DT Overlay support in SPL
> so make it compile-time dependent. Without this SPL fails to
> boot some platforms where this feature is not enabled
> (e.g. dra71-evm.)
>
> Without including the <linux/kconfig.h> file, the symbol
> CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY will not be visible and
> we will never include the symbol table.
>
> So include <linux/kconfig.h>
>
> Due to some reason it needs to be included after
> [#include "fdt_host.h"] otherwise it causes a build error.
>
> Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
> ---
>  tools/fdtgrep.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/tools/fdtgrep.c b/tools/fdtgrep.c
> index 7eabcab439..706b4a35f4 100644
> --- a/tools/fdtgrep.c
> +++ b/tools/fdtgrep.c
> @@ -22,6 +22,8 @@
>  #include "fdt_host.h"
>  #include "libfdt_internal.h"
>
> +#include <linux/kconfig.h>
> +
>  /* Define DEBUG to get some debugging output on stderr */
>  #ifdef DEBUG
>  #define debug(a, b...) fprintf(stderr, a, ## b)
> @@ -1234,6 +1236,12 @@ int main(int argc, char *argv[])
>                 disp.fout = stdout;
>         }
>
> +       if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY)) {
> +               /* include symbol table */
> +               if (value_add(&disp, &disp.value_head, FDT_IS_NODE, 1, "/__symbols__"))
> +                       usage("Cannot add __symbols__ value");
> +       }
> +
>         /* Run the grep and output the results */
>         ret = do_fdtgrep(&disp, filename);
>         if (disp.output_fname)
> --
> 2.34.1
>

I may have replied elsewhere, but please use a new fdtgrep option for this.

Regards,
Simon

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 12/16] arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration
  2023-12-20 10:40   ` Roger Quadros
@ 2023-12-27 10:19     ` MD Danish Anwar
  2024-01-10  6:50       ` MD Danish Anwar
  0 siblings, 1 reply; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-27 10:19 UTC (permalink / raw)
  To: Roger Quadros, Maxime Ripard, Siddharth Vadapalli,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran

On 20/12/23 4:10 pm, Roger Quadros wrote:
> 
> 
> On 19/12/2023 12:34, MD Danish Anwar wrote:
>> Add ICSSG2 overlay and configuration to tispl and u-boot images.
>>
>> Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
>> ---
>>  arch/arm/dts/k3-am65x-binman.dtsi | 85 +++++++++++++++++++++++++++++++
>>  1 file changed, 85 insertions(+)
>>
>> diff --git a/arch/arm/dts/k3-am65x-binman.dtsi b/arch/arm/dts/k3-am65x-binman.dtsi
>> index 8cc24da1f3..9a0c0fca47 100644
>> --- a/arch/arm/dts/k3-am65x-binman.dtsi
>> +++ b/arch/arm/dts/k3-am65x-binman.dtsi
>> @@ -98,6 +98,8 @@
>>  #define SPL_AM654_EVM_DTB "spl/dts/k3-am654-base-board.dtb"
>>  #define AM654_EVM_DTB "u-boot.dtb"
>>  
>> +#define AM654_EVM_ICSSG2_DTBO "arch/arm/dts/k3-am654-icssg2.dtbo"
>> +
>>  &binman {
>>  	ti-spl {
>>  		insert-template = <&ti_spl_template>;
>> @@ -124,6 +126,20 @@
>>  						filename = SPL_AM654_EVM_DTB;
>>  					};
>>  				};
>> +
>> +				fdt-1 {
>> +					description = "k3-am654-icssg2 overlay";
>> +					type = "flat_dt";
>> +					arch = "arm";
>> +					compression = "none";
>> +					ti-secure {
>> +						content = <&spl_am65x_evm_icssg2_dtb>;
>> +						keyfile = "custMpk.pem";
>> +					};
>> +					spl_am65x_evm_icssg2_dtb: blob-ext {
>> +						filename = AM654_EVM_ICSSG2_DTBO;
>> +					};
> 
> This is wrong.
> 
> ICSSG2 Ethernet should be part of the fdt-0 configuration as the 2 Ethernet ports
> on the board are hardwired to ICSSG2. Not having them working by default
> is an invalid configuration.
> 

ICSSG2 ethernet ports should be enabled by default. But the ICSSG2 nodes
is added in the overlay file (k3-am654-icssg2.dtso) in kernel so they
are added in same overlay file in u-boot as well.

I am keeping,
fdt-0  as k3-am654-base-board dtb,
fdt-1  as k3-am654-icssg2 dtbo,
conf-0 as k3-am654-base-board and
conf-1 as k3-am654-icssg2.

Do you want me to keep k3-am654-icssg2 dtbo as fdt-0 and
k3-am654-base-board as fdt-1? I tried doing this but this results into
u-boot getting stuck. The tispl and u-boot images are not able to load
if I swap fdt-0 and fdt-1 , and conf-0 and conf-1.

If the current combination doesn't look OK, please let me know what
should be the correct combinations for fdt-0, fdt-1, conf-0 and conf-1.

>> +				};
>>  			};
>>  
>>  			configurations {
>> @@ -135,6 +151,13 @@
>>  					loadables = "tee", "dm", "spl";
>>  					fdt = "fdt-0";
>>  				};
>> +
>> +				conf-1 {
>> +					description = "k3-am654-icssg2";
>> +					firmware = "atf";
>> +					loadables = "tee", "dm", "spl";
>> +					fdt = "fdt-0", "fdt-1";
>> +				};
>>  			};
>>  		};
>>  	};s
>> @@ -168,6 +191,24 @@
>>  					};
>>  				};
>>  
>> +				fdt-1 {
>> +					description = "k3-am654-icssg2 overlay";
>> +					type = "flat_dt";
>> +					arch = "arm";
>> +					compression = "none";
>> +					ti-secure {
>> +						content = <&am65x_evm_icssg2_dtb>;
>> +						keyfile = "custMpk.pem";
>> +
>> +					};
>> +					am65x_evm_icssg2_dtb: blob-ext {
>> +						filename = AM654_EVM_ICSSG2_DTBO;
>> +					};
>> +					hash {
>> +						algo = "crc32";
>> +					};
>> +				};
>> +
>>  			};
>>  
>>  			configurations {
>> @@ -179,6 +220,13 @@
>>  					loadables = "uboot";
>>  					fdt = "fdt-0";
>>  				};
>> +
>> +				conf-1 {
>> +					description = "k3-am654-icssg2";
>> +					firmware = "uboot";
>> +					loadables = "uboot";
>> +					fdt = "fdt-0", "fdt-1";
>> +				};
>>  			};
>>  		};
>>  	};
>> @@ -205,6 +253,16 @@
>>  						filename = SPL_AM654_EVM_DTB;
>>  					};
>>  				};
>> +
>> +				fdt-1 {
>> +					description = "k3-am654-icssg2 overlay";
>> +					type = "flat_dt";
>> +					arch = "arm";
>> +					compression = "none";
>> +					blob {
>> +						filename = AM654_EVM_ICSSG2_DTBO;
>> +					};
>> +				};
>>  			};
>>  
>>  			configurations {
>> @@ -216,6 +274,13 @@
>>  					loadables = "tee", "dm", "spl";
>>  					fdt = "fdt-0";
>>  				};
>> +
>> +				conf-1 {
>> +					description = "k3-am654-icssg2";
>> +					firmware = "atf";
>> +					loadables = "tee", "dm", "spl";
>> +					fdt = "fdt-0", "fdt-1";
>> +				};
>>  			};
>>  		};
>>  	};
>> @@ -243,6 +308,19 @@
>>  						algo = "crc32";
>>  					};
>>  				};
>> +
>> +				fdt-1 {
>> +					description = "k3-am654-icssg2";
>> +					type = "flat_dt";
>> +					arch = "arm";
>> +					compression = "none";
>> +					blob {
>> +						filename = AM654_EVM_ICSSG2_DTBO;
>> +					};
>> +					hash {
>> +						algo = "crc32";
>> +					};
>> +				};
>>  			};
>>  
>>  			configurations {
>> @@ -254,6 +332,13 @@
>>  					loadables = "uboot";
>>  					fdt = "fdt-0";
>>  				};
>> +
>> +				conf-1 {
>> +					description = "k3-am654-icssg2";
>> +					firmware = "uboot";
>> +					loadables = "uboot";
>> +					fdt = "fdt-0", "fdt-1";
>> +				};
>>  			};
>>  		};
>>  	};
> 

-- 
Thanks and Regards,
Danish

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 12/16] arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration
  2023-12-27 10:19     ` MD Danish Anwar
@ 2024-01-10  6:50       ` MD Danish Anwar
  2024-01-10  8:54         ` Roger Quadros
  0 siblings, 1 reply; 48+ messages in thread
From: MD Danish Anwar @ 2024-01-10  6:50 UTC (permalink / raw)
  To: Roger Quadros, Maxime Ripard, Siddharth Vadapalli,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Hi Roger,

On 27/12/23 3:49 pm, MD Danish Anwar wrote:
> On 20/12/23 4:10 pm, Roger Quadros wrote:
>>
>>
>> On 19/12/2023 12:34, MD Danish Anwar wrote:
>>> Add ICSSG2 overlay and configuration to tispl and u-boot images.
>>>
>>> Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
>>> ---
>>>  arch/arm/dts/k3-am65x-binman.dtsi | 85 +++++++++++++++++++++++++++++++
>>>  1 file changed, 85 insertions(+)
>>>
>>> diff --git a/arch/arm/dts/k3-am65x-binman.dtsi b/arch/arm/dts/k3-am65x-binman.dtsi
>>> index 8cc24da1f3..9a0c0fca47 100644
>>> --- a/arch/arm/dts/k3-am65x-binman.dtsi
>>> +++ b/arch/arm/dts/k3-am65x-binman.dtsi
>>> @@ -98,6 +98,8 @@
>>>  #define SPL_AM654_EVM_DTB "spl/dts/k3-am654-base-board.dtb"
>>>  #define AM654_EVM_DTB "u-boot.dtb"
>>>  
>>> +#define AM654_EVM_ICSSG2_DTBO "arch/arm/dts/k3-am654-icssg2.dtbo"
>>> +
>>>  &binman {
>>>  	ti-spl {
>>>  		insert-template = <&ti_spl_template>;
>>> @@ -124,6 +126,20 @@
>>>  						filename = SPL_AM654_EVM_DTB;
>>>  					};
>>>  				};
>>> +
>>> +				fdt-1 {
>>> +					description = "k3-am654-icssg2 overlay";
>>> +					type = "flat_dt";
>>> +					arch = "arm";
>>> +					compression = "none";
>>> +					ti-secure {
>>> +						content = <&spl_am65x_evm_icssg2_dtb>;
>>> +						keyfile = "custMpk.pem";
>>> +					};
>>> +					spl_am65x_evm_icssg2_dtb: blob-ext {
>>> +						filename = AM654_EVM_ICSSG2_DTBO;
>>> +					};
>>
>> This is wrong.
>>
>> ICSSG2 Ethernet should be part of the fdt-0 configuration as the 2 Ethernet ports
>> on the board are hardwired to ICSSG2. Not having them working by default
>> is an invalid configuration.
>>
> 
> ICSSG2 ethernet ports should be enabled by default. But the ICSSG2 nodes
> is added in the overlay file (k3-am654-icssg2.dtso) in kernel so they
> are added in same overlay file in u-boot as well.
> 
> I am keeping,
> fdt-0  as k3-am654-base-board dtb,
> fdt-1  as k3-am654-icssg2 dtbo,
> conf-0 as k3-am654-base-board and
> conf-1 as k3-am654-icssg2.
> 
> Do you want me to keep k3-am654-icssg2 dtbo as fdt-0 and
> k3-am654-base-board as fdt-1? I tried doing this but this results into
> u-boot getting stuck. The tispl and u-boot images are not able to load
> if I swap fdt-0 and fdt-1 , and conf-0 and conf-1.
> 
> If the current combination doesn't look OK, please let me know what
> should be the correct combinations for fdt-0, fdt-1, conf-0 and conf-1.
> 

Can you please comment on this. I'll send v2 with all the suggested
changes once you confirm the correct fdt and configurations.

<snip>

-- 
Thanks and Regards,
Danish

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 12/16] arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration
  2024-01-10  6:50       ` MD Danish Anwar
@ 2024-01-10  8:54         ` Roger Quadros
  2024-01-10  9:02           ` MD Danish Anwar
  0 siblings, 1 reply; 48+ messages in thread
From: Roger Quadros @ 2024-01-10  8:54 UTC (permalink / raw)
  To: MD Danish Anwar, Maxime Ripard, Siddharth Vadapalli,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran

On 10/01/2024 08:50, MD Danish Anwar wrote:
> Hi Roger,
> 
> On 27/12/23 3:49 pm, MD Danish Anwar wrote:
>> On 20/12/23 4:10 pm, Roger Quadros wrote:
>>>
>>>
>>> On 19/12/2023 12:34, MD Danish Anwar wrote:
>>>> Add ICSSG2 overlay and configuration to tispl and u-boot images.
>>>>
>>>> Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
>>>> ---
>>>>  arch/arm/dts/k3-am65x-binman.dtsi | 85 +++++++++++++++++++++++++++++++
>>>>  1 file changed, 85 insertions(+)
>>>>
>>>> diff --git a/arch/arm/dts/k3-am65x-binman.dtsi b/arch/arm/dts/k3-am65x-binman.dtsi
>>>> index 8cc24da1f3..9a0c0fca47 100644
>>>> --- a/arch/arm/dts/k3-am65x-binman.dtsi
>>>> +++ b/arch/arm/dts/k3-am65x-binman.dtsi
>>>> @@ -98,6 +98,8 @@
>>>>  #define SPL_AM654_EVM_DTB "spl/dts/k3-am654-base-board.dtb"
>>>>  #define AM654_EVM_DTB "u-boot.dtb"
>>>>  
>>>> +#define AM654_EVM_ICSSG2_DTBO "arch/arm/dts/k3-am654-icssg2.dtbo"
>>>> +
>>>>  &binman {
>>>>  	ti-spl {
>>>>  		insert-template = <&ti_spl_template>;
>>>> @@ -124,6 +126,20 @@
>>>>  						filename = SPL_AM654_EVM_DTB;
>>>>  					};
>>>>  				};
>>>> +
>>>> +				fdt-1 {
>>>> +					description = "k3-am654-icssg2 overlay";
>>>> +					type = "flat_dt";
>>>> +					arch = "arm";
>>>> +					compression = "none";
>>>> +					ti-secure {
>>>> +						content = <&spl_am65x_evm_icssg2_dtb>;
>>>> +						keyfile = "custMpk.pem";
>>>> +					};
>>>> +					spl_am65x_evm_icssg2_dtb: blob-ext {
>>>> +						filename = AM654_EVM_ICSSG2_DTBO;
>>>> +					};
>>>
>>> This is wrong.
>>>
>>> ICSSG2 Ethernet should be part of the fdt-0 configuration as the 2 Ethernet ports
>>> on the board are hardwired to ICSSG2. Not having them working by default
>>> is an invalid configuration.
>>>
>>
>> ICSSG2 ethernet ports should be enabled by default. But the ICSSG2 nodes
>> is added in the overlay file (k3-am654-icssg2.dtso) in kernel so they
>> are added in same overlay file in u-boot as well.
>>
>> I am keeping,
>> fdt-0  as k3-am654-base-board dtb,
>> fdt-1  as k3-am654-icssg2 dtbo,
>> conf-0 as k3-am654-base-board and
>> conf-1 as k3-am654-icssg2.
>>
>> Do you want me to keep k3-am654-icssg2 dtbo as fdt-0 and
>> k3-am654-base-board as fdt-1? I tried doing this but this results into
>> u-boot getting stuck. The tispl and u-boot images are not able to load
>> if I swap fdt-0 and fdt-1 , and conf-0 and conf-1.
>>
>> If the current combination doesn't look OK, please let me know what
>> should be the correct combinations for fdt-0, fdt-1, conf-0 and conf-1.
>>
> 
> Can you please comment on this. I'll send v2 with all the suggested
> changes once you confirm the correct fdt and configurations.
> 
Sorry, I missed this.

fdt-0 = k3-am654-base-board dtb
fdt-1 = k3-am654-icssg2 dtbo

conf-0 = fdt-0 and ftd-1

as icssg2 ethernet is present on the base board, and should be part of the base board configuration.

-- 
cheers,
-roger

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 12/16] arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration
  2024-01-10  8:54         ` Roger Quadros
@ 2024-01-10  9:02           ` MD Danish Anwar
  2024-01-10 11:42             ` Roger Quadros
  0 siblings, 1 reply; 48+ messages in thread
From: MD Danish Anwar @ 2024-01-10  9:02 UTC (permalink / raw)
  To: Roger Quadros, Maxime Ripard, Siddharth Vadapalli,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran



On 10/01/24 2:24 pm, Roger Quadros wrote:
> On 10/01/2024 08:50, MD Danish Anwar wrote:
>> Hi Roger,
>>
>> On 27/12/23 3:49 pm, MD Danish Anwar wrote:
>>> On 20/12/23 4:10 pm, Roger Quadros wrote:
>>>>
>>>>
>>>> On 19/12/2023 12:34, MD Danish Anwar wrote:
>>>>> Add ICSSG2 overlay and configuration to tispl and u-boot images.
>>>>>
>>>>> Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
>>>>> ---
>>>>>  arch/arm/dts/k3-am65x-binman.dtsi | 85 +++++++++++++++++++++++++++++++
>>>>>  1 file changed, 85 insertions(+)
>>>>>
>>>>> diff --git a/arch/arm/dts/k3-am65x-binman.dtsi b/arch/arm/dts/k3-am65x-binman.dtsi
>>>>> index 8cc24da1f3..9a0c0fca47 100644
>>>>> --- a/arch/arm/dts/k3-am65x-binman.dtsi
>>>>> +++ b/arch/arm/dts/k3-am65x-binman.dtsi
>>>>> @@ -98,6 +98,8 @@
>>>>>  #define SPL_AM654_EVM_DTB "spl/dts/k3-am654-base-board.dtb"
>>>>>  #define AM654_EVM_DTB "u-boot.dtb"
>>>>>  
>>>>> +#define AM654_EVM_ICSSG2_DTBO "arch/arm/dts/k3-am654-icssg2.dtbo"
>>>>> +
>>>>>  &binman {
>>>>>  	ti-spl {
>>>>>  		insert-template = <&ti_spl_template>;
>>>>> @@ -124,6 +126,20 @@
>>>>>  						filename = SPL_AM654_EVM_DTB;
>>>>>  					};
>>>>>  				};
>>>>> +
>>>>> +				fdt-1 {
>>>>> +					description = "k3-am654-icssg2 overlay";
>>>>> +					type = "flat_dt";
>>>>> +					arch = "arm";
>>>>> +					compression = "none";
>>>>> +					ti-secure {
>>>>> +						content = <&spl_am65x_evm_icssg2_dtb>;
>>>>> +						keyfile = "custMpk.pem";
>>>>> +					};
>>>>> +					spl_am65x_evm_icssg2_dtb: blob-ext {
>>>>> +						filename = AM654_EVM_ICSSG2_DTBO;
>>>>> +					};
>>>>
>>>> This is wrong.
>>>>
>>>> ICSSG2 Ethernet should be part of the fdt-0 configuration as the 2 Ethernet ports
>>>> on the board are hardwired to ICSSG2. Not having them working by default
>>>> is an invalid configuration.
>>>>
>>>
>>> ICSSG2 ethernet ports should be enabled by default. But the ICSSG2 nodes
>>> is added in the overlay file (k3-am654-icssg2.dtso) in kernel so they
>>> are added in same overlay file in u-boot as well.
>>>
>>> I am keeping,
>>> fdt-0  as k3-am654-base-board dtb,
>>> fdt-1  as k3-am654-icssg2 dtbo,
>>> conf-0 as k3-am654-base-board and
>>> conf-1 as k3-am654-icssg2.
>>>
>>> Do you want me to keep k3-am654-icssg2 dtbo as fdt-0 and
>>> k3-am654-base-board as fdt-1? I tried doing this but this results into
>>> u-boot getting stuck. The tispl and u-boot images are not able to load
>>> if I swap fdt-0 and fdt-1 , and conf-0 and conf-1.
>>>
>>> If the current combination doesn't look OK, please let me know what
>>> should be the correct combinations for fdt-0, fdt-1, conf-0 and conf-1.
>>>
>>
>> Can you please comment on this. I'll send v2 with all the suggested
>> changes once you confirm the correct fdt and configurations.
>>
> Sorry, I missed this.
> 
> fdt-0 = k3-am654-base-board dtb
> fdt-1 = k3-am654-icssg2 dtbo
> 
> conf-0 = fdt-0 and ftd-1
> 

What about conf-1? Should I leave it as it is(currently conf-1 is fdt-0
and fdt-1)?

> as icssg2 ethernet is present on the base board, and should be part of the base board configuration.
> 

-- 
Thanks and Regards,
Danish

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 15/16] tools/fdtgrep: Include __symbols__ table
  2023-12-26  9:47   ` Simon Glass
@ 2024-01-10  9:52     ` MD Danish Anwar
  0 siblings, 0 replies; 48+ messages in thread
From: MD Danish Anwar @ 2024-01-10  9:52 UTC (permalink / raw)
  To: Simon Glass
  Cc: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Tom Rini, u-boot,
	srk, r-gunasekaran

Hi Simon,

On 26/12/23 3:17 pm, Simon Glass wrote:
> Hi,
> 
> On Tue, Dec 19, 2023 at 10:34 AM MD Danish Anwar <danishanwar@ti.com> wrote:
>>
>> This is required for overlays to work at SPL.
>>
>> Loading of symbol table depends on DT Overlay support in SPL
>> so make it compile-time dependent. Without this SPL fails to
>> boot some platforms where this feature is not enabled
>> (e.g. dra71-evm.)
>>
>> Without including the <linux/kconfig.h> file, the symbol
>> CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY will not be visible and
>> we will never include the symbol table.
>>
>> So include <linux/kconfig.h>
>>
>> Due to some reason it needs to be included after
>> [#include "fdt_host.h"] otherwise it causes a build error.
>>
>> Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
>> ---
>>  tools/fdtgrep.c | 8 ++++++++
>>  1 file changed, 8 insertions(+)
>>
>> diff --git a/tools/fdtgrep.c b/tools/fdtgrep.c
>> index 7eabcab439..706b4a35f4 100644
>> --- a/tools/fdtgrep.c
>> +++ b/tools/fdtgrep.c
>> @@ -22,6 +22,8 @@
>>  #include "fdt_host.h"
>>  #include "libfdt_internal.h"
>>
>> +#include <linux/kconfig.h>
>> +
>>  /* Define DEBUG to get some debugging output on stderr */
>>  #ifdef DEBUG
>>  #define debug(a, b...) fprintf(stderr, a, ## b)
>> @@ -1234,6 +1236,12 @@ int main(int argc, char *argv[])
>>                 disp.fout = stdout;
>>         }
>>
>> +       if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY)) {
>> +               /* include symbol table */
>> +               if (value_add(&disp, &disp.value_head, FDT_IS_NODE, 1, "/__symbols__"))
>> +                       usage("Cannot add __symbols__ value");
>> +       }
>> +
>>         /* Run the grep and output the results */
>>         ret = do_fdtgrep(&disp, filename);
>>         if (disp.output_fname)
>> --
>> 2.34.1
>>
> 
> I may have replied elsewhere, but please use a new fdtgrep option for this.
> 
> Regards,
> Simon

This patch is actually not needed. Without this patch also I am able to
apply overlays at SPL. Even without this patch I see symbols table
getting included while using fdtgrep tool. I will drop this patch in v2.

-- 
Thanks and Regards,
Danish

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 12/16] arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration
  2024-01-10  9:02           ` MD Danish Anwar
@ 2024-01-10 11:42             ` Roger Quadros
  0 siblings, 0 replies; 48+ messages in thread
From: Roger Quadros @ 2024-01-10 11:42 UTC (permalink / raw)
  To: MD Danish Anwar, Maxime Ripard, Siddharth Vadapalli,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran



On 10/01/2024 11:02, MD Danish Anwar wrote:
> 
> 
> On 10/01/24 2:24 pm, Roger Quadros wrote:
>> On 10/01/2024 08:50, MD Danish Anwar wrote:
>>> Hi Roger,
>>>
>>> On 27/12/23 3:49 pm, MD Danish Anwar wrote:
>>>> On 20/12/23 4:10 pm, Roger Quadros wrote:
>>>>>
>>>>>
>>>>> On 19/12/2023 12:34, MD Danish Anwar wrote:
>>>>>> Add ICSSG2 overlay and configuration to tispl and u-boot images.
>>>>>>
>>>>>> Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
>>>>>> ---
>>>>>>  arch/arm/dts/k3-am65x-binman.dtsi | 85 +++++++++++++++++++++++++++++++
>>>>>>  1 file changed, 85 insertions(+)
>>>>>>
>>>>>> diff --git a/arch/arm/dts/k3-am65x-binman.dtsi b/arch/arm/dts/k3-am65x-binman.dtsi
>>>>>> index 8cc24da1f3..9a0c0fca47 100644
>>>>>> --- a/arch/arm/dts/k3-am65x-binman.dtsi
>>>>>> +++ b/arch/arm/dts/k3-am65x-binman.dtsi
>>>>>> @@ -98,6 +98,8 @@
>>>>>>  #define SPL_AM654_EVM_DTB "spl/dts/k3-am654-base-board.dtb"
>>>>>>  #define AM654_EVM_DTB "u-boot.dtb"
>>>>>>  
>>>>>> +#define AM654_EVM_ICSSG2_DTBO "arch/arm/dts/k3-am654-icssg2.dtbo"
>>>>>> +
>>>>>>  &binman {
>>>>>>  	ti-spl {
>>>>>>  		insert-template = <&ti_spl_template>;
>>>>>> @@ -124,6 +126,20 @@
>>>>>>  						filename = SPL_AM654_EVM_DTB;
>>>>>>  					};
>>>>>>  				};
>>>>>> +
>>>>>> +				fdt-1 {
>>>>>> +					description = "k3-am654-icssg2 overlay";
>>>>>> +					type = "flat_dt";
>>>>>> +					arch = "arm";
>>>>>> +					compression = "none";
>>>>>> +					ti-secure {
>>>>>> +						content = <&spl_am65x_evm_icssg2_dtb>;
>>>>>> +						keyfile = "custMpk.pem";
>>>>>> +					};
>>>>>> +					spl_am65x_evm_icssg2_dtb: blob-ext {
>>>>>> +						filename = AM654_EVM_ICSSG2_DTBO;
>>>>>> +					};
>>>>>
>>>>> This is wrong.
>>>>>
>>>>> ICSSG2 Ethernet should be part of the fdt-0 configuration as the 2 Ethernet ports
>>>>> on the board are hardwired to ICSSG2. Not having them working by default
>>>>> is an invalid configuration.
>>>>>
>>>>
>>>> ICSSG2 ethernet ports should be enabled by default. But the ICSSG2 nodes
>>>> is added in the overlay file (k3-am654-icssg2.dtso) in kernel so they
>>>> are added in same overlay file in u-boot as well.
>>>>
>>>> I am keeping,
>>>> fdt-0  as k3-am654-base-board dtb,
>>>> fdt-1  as k3-am654-icssg2 dtbo,
>>>> conf-0 as k3-am654-base-board and
>>>> conf-1 as k3-am654-icssg2.
>>>>
>>>> Do you want me to keep k3-am654-icssg2 dtbo as fdt-0 and
>>>> k3-am654-base-board as fdt-1? I tried doing this but this results into
>>>> u-boot getting stuck. The tispl and u-boot images are not able to load
>>>> if I swap fdt-0 and fdt-1 , and conf-0 and conf-1.
>>>>
>>>> If the current combination doesn't look OK, please let me know what
>>>> should be the correct combinations for fdt-0, fdt-1, conf-0 and conf-1.
>>>>
>>>
>>> Can you please comment on this. I'll send v2 with all the suggested
>>> changes once you confirm the correct fdt and configurations.
>>>
>> Sorry, I missed this.
>>
>> fdt-0 = k3-am654-base-board dtb
>> fdt-1 = k3-am654-icssg2 dtbo
>>
>> conf-0 = fdt-0 and ftd-1
>>
> 
> What about conf-1? Should I leave it as it is(currently conf-1 is fdt-0
> and fdt-1)?

I don't think we need conf-1.

> 
>> as icssg2 ethernet is present on the base board, and should be part of the base board configuration.
>>
> 

-- 
cheers,
-roger

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
  2024-01-09  9:49                       ` MD Danish Anwar
@ 2024-01-09 12:34                         ` Roger Quadros
  0 siblings, 0 replies; 48+ messages in thread
From: Roger Quadros @ 2024-01-09 12:34 UTC (permalink / raw)
  To: MD Danish Anwar, Anwar, Md Danish, Andrew Davis, Maxime Ripard,
	Siddharth Vadapalli, Nishanth Menon, Vignesh Raghavendra,
	Matthias Schiffer, Kamlesh Gurudasani, Manorit Chawdhry,
	Neha Malcom Francis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran



On 09/01/2024 11:49, MD Danish Anwar wrote:
> 
> 
> On 09/01/24 2:56 pm, Roger Quadros wrote:
>>
>>
>> On 08/01/2024 12:25, MD Danish Anwar wrote:
>>> On 08/01/24 3:00 pm, Roger Quadros wrote:
>>>>
>>>>
>>>> On 05/01/2024 12:15, Anwar, Md Danish wrote:
>>>>>
>>>>>
>>>>> On 1/5/2024 1:49 PM, Roger Quadros wrote:
>>>>>>
>>>>>>
>>>>>> On 03/01/2024 12:27, MD Danish Anwar wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 02/01/24 7:26 pm, Andrew Davis wrote:
>>>>>>>> On 12/27/23 12:56 AM, MD Danish Anwar wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 22/12/23 6:13 pm, Roger Quadros wrote:
>>>>>>>>>>
>>>>>>>>>> On 22/12/2023 12:26, MD Danish Anwar wrote:
>>>>>>>>>>> Hi Roger,
>>>>>>>>>>>
>>>>>>>>>>> On 20/12/23 3:29 pm, Roger Quadros wrote:
>>>>>>>>>>>> Hi,
>>>>>>>>>>>>
>>>>>>>>>>>> On 19/12/2023 12:11, MD Danish Anwar wrote:
>>>>>>>>>>>>> Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used
>>>>>>>>>>>>> in TI
>>>>>>>>>>>>> AM654 SR2.0.
>>>>>>>>>>>>>
>>>>>>>>>>>>> The ICSSG PRU Sub-system runs on EMAC firmware. This series
>>>>>>>>>>>>> Introduces
>>>>>>>>>>>>> support for ICSSG driver in uboot. This series also adds the driver's
>>>>>>>>>>>>> dependencies.
>>>>>>>>>>>>>
>>>>>>>>>>>>> The ICSSG2 node is added in device tree overlay so that it remains in
>>>>>>>>>>>>> sync with linux kernel.
>>>>>>>>>>>>>
>>>>>>>>>>>>> The series introduces device tree and config changes and AM65x
>>>>>>>>>>>>> to enable ICSSG driver. The series also enables
>>>>>>>>>>>>> SPL_LOAD_FIT_APPLY_OVERLAY
>>>>>>>>>>>>> for AM65x in order to load overlay over spl.
>>>>>>>>>>>>>
>>>>>>>>>>>>> This series has been tested on AM65x SR2.0, and the ICSSG
>>>>>>>>>>>>> interface is
>>>>>>>>>>>>> able to ping / dhcp and boot kernel using tftp in uboot.
>>>>>>>>>>>>>
>>>>>>>>>>>>> To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to
>>>>>>>>>>>>> PRU RPROC
>>>>>>>>>>>>> cores and RPROC cores need to be booted with the firmware. This
>>>>>>>>>>>>> step is
>>>>>>>>>>>>> done inside driver in kernel as kernel supports APIs like
>>>>>>>>>>>>> rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't
>>>>>>>>>>>>> have these
>>>>>>>>>>>>> APIs, the same needs to be done via u-boot cmds.
>>>>>>>>>>>>>
>>>>>>>>>>>>> To make sure icssg-eth works we need to do below steps.
>>>>>>>>>>>>>
>>>>>>>>>>>>> 1. Initialize rproc cores i.e. rproc_init()
>>>>>>>>>>>>> 2. Load $firmware_file from partition '1:2' (root) on device (mmc
>>>>>>>>>>>>> in this
>>>>>>>>>>>>>     example)
>>>>>>>>>>>>> 3. Load the firmware file to rproc cores passing. i.e. rproc_load()
>>>>>>>>>>>>>     taking rproc_id, loadaddr and file size as arguments.
>>>>>>>>>>>>> 4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments
>>>>>>>>>>>>>
>>>>>>>>>>>>> The above steps are done by running the below commands at u-boot
>>>>>>>>>>>>> prompt.
>>>>>>>>>>>>>
>>>>>>>>>>>>> => setenv start_icssg2 'rproc start 14; rproc start 15; rproc
>>>>>>>>>>>>> start 16; rproc start 17; rproc start 18; rproc start 19'
>>>>>>>>>>>>> => setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop
>>>>>>>>>>>>> 16; rproc stop 17; rproc stop 18; rproc stop 19'
>>>>>>>>>>>>> => setenv firmware_dir '/lib/firmware/ti-pruss'
>>>>>>>>>>>>> => setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr}
>>>>>>>>>>>>> ${firmware_dir}/${firmware_file}'
>>>>>>>>>>>>>
>>>>>>>>>>>>> => setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload
>>>>>>>>>>>>> no; rproc init; setenv loadaddr 0x80000000; \
>>>>>>>>>>>>>      setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run
>>>>>>>>>>>>> get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
>>>>>>>>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>>>>>>>>> am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15
>>>>>>>>>>>>> 0x89000000 ${filesize}; \
>>>>>>>>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>>>>>>>>> am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>>>>>>>>> 16 0x90000000 ${filesize}; \
>>>>>>>>>>>>>      setenv loadaddr 0x80000000; setenv firmware_file
>>>>>>>>>>>>> am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17
>>>>>>>>>>>>> 0x80000000 ${filesize}; \
>>>>>>>>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>>>>>>>>> am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18
>>>>>>>>>>>>> 0x89000000 ${filesize}; \
>>>>>>>>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>>>>>>>>> am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>>>>>>>>> 19 0x90000000 ${filesize}; \
>>>>>>>>>>>>>      run start_icssg2;'
>>>>>>>>>>>>
>>>>>>>>>>>> A whole bunch of commands are required to get ethernet functional.
>>>>>>>>>>>> This is not at all user friendly and will be a maintenance nightmare.
>>>>>>>>>>>> What worries me is tracking the 6 different rproc cores and the 6
>>>>>>>>>>>> different firmware files to start 1 ethernet device.
>>>>>>>>>>>> This will get even more interesting when we have to deal with
>>>>>>>>>>>> different ICSSG instances on different boards.
>>>>>>>>>>>>
>>>>>>>>>>>> What is preventing the driver from starting the rproc cores it
>>>>>>>>>>>> needs so user doesn't need to care about it?
>>>>>>>>>>>> All the necessary information is in the Device tree. At least this
>>>>>>>>>>>> is how it is done on Linux.
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> I tried removing the need for these commands and implementing them
>>>>>>>>>>> inside the driver only. I am able to load the firmware from driver
>>>>>>>>>>> using
>>>>>>>>>>> the fs_loader API request_firmware_into_buf(). It requires changes to
>>>>>>>>>>> dt. A DT node called fs-loader needs to be added also CONFIG_FS_LOADER
>>>>>>>>>>> needs to enabled. In the DT node we need to specify the storage media
>>>>>>>>>>> that we are using i.e. mmc, ospi, usb. It's upto user to modify the
>>>>>>>>>>> storage media, the driver will take the media from DT and try to laod
>>>>>>>>>>> firmware from their.
>>>>>>>>>>>
>>>>>>>>>>> For loading firmwares to rproc cores, rproc_load() API is needed. Now
>>>>>>>>>>> this API takes rproc_id, loadaddr and firmware_size as arguments.
>>>>>>>>>>> loadaddr is fixed for all three pru cores. firmware_size is obtained
>>>>>>>>>>> from request_firmware_into_buf() but I couldn't find a way to get the
>>>>>>>>>>> rproc_id. For now based on the ICSSG instance and slice number I am
>>>>>>>>>>> figuring out the rproc_id and passing it to rproc_load() and
>>>>>>>>>>> rproc_start() APIs. Please let me know if you have any other / better
>>>>>>>>>>> way of finding rproc_id.
>>>>>>>>>>>
>>>>>>>>>>> Below is the entire diff to remove these commands and move their
>>>>>>>>>>> functionality to driver. Please have a look and let me know if this
>>>>>>>>>>> is ok.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Good to see you got something working so quickly.
>>>>>>>>>> It has some rough edges but nothing that is blocking.
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Save New Duplicate & Edit Just Text Twitter
>>>>>>>>>>> diff --git a/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>>>>> b/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>>>>> index cfbcebfa37..c8da72e49c 100644
>>>>>>>>>>> --- a/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>>>>> +++ b/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>>>>> @@ -16,6 +16,13 @@
>>>>>>>>>>>       chosen {
>>>>>>>>>>>           stdout-path = "serial2:115200n8";
>>>>>>>>>>>           bootargs = "earlycon=ns16550a,mmio32,0x02800000";
>>>>>>>>>>> +        firmware-loader = <&fs_loader0>;
>>>>>>>>>>> +    };
>>>>>>>>>>> +
>>>>>>>>>>> +    fs_loader0: fs-loader {
>>>>>>>>>>> +        bootph-all;
>>>>>>>>>>> +        compatible = "u-boot,fs-loader";
>>>>>>>>>>> +        phandlepart = <&sdhci1 2>;
>>>>>>>>>>>       };
>>>>>>>>>>
>>>>>>>>>> This is has 2 issues
>>>>>>>>>> 1) It will not be accepted in Kernel DT. Maybe it could be done in
>>>>>>>>>> -u-boot.dtsi file.
>>>>>>>>>
>>>>>>>>> Sure. I'll move this to k3-am654-base-board-u-boot.dtsi
>>>>>>>>>
>>>>>>>>>> 2) You cannot assume boot medium is always sdhci1 2
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Yes. It's upto user to provide the boot medium and boot partition for
>>>>>>>>> loading firmware. By default the firmware is loacated in root partion of
>>>>>>>>> shdci1 on am65x so I am adding this as default. But user can easily
>>>>>>>>> modify this to any other medium / partition needed.
>>>>>>>>>
>>>>>>>>
>>>>>>>> Users should not have to modify DT to pick a boot medium/partition.
>>>>>>>> What would you do for complex cases or non block devices like eth/uart
>>>>>>>
>>>>>> I agree with Andrew here.
>>>>>>
>>>>>>> In order to load firmware files from driver, we need to add the node for
>>>>>>> fs-loader. The fs-loader has a phandlepart property which takes the boot
>>>>>>> medium and the partition as input. Based on the medium and partition it
>>>>>>> looks for the requested file and loads it to a given address. I am not
>>>>>>> sure if there is any other way to load firmware from driver without
>>>>>>> using the fs-loader.
>>>>>>>
>>>>>>>
>>>>>>>> booting? This is one reason kernel moved firmware loading to
>>>>>>>> userspace. The equivalant in U-Boot is the shell and scripts. Your
>>>>>>>> original command based loading was the correct solution IMHO.
>>>>>>>
>>>>>>> I intended to go ahead with command base approach only but as Roger
>>>>>>> pointed out the command based approach is not very user friendly.
>>>>>>>
>>>>>>> We need to align on what should be the correct approach for loading
>>>>>>> firmware.
>>>>>>>
>>>>>>> Roger, can you please chime in here.
>>>>>>
>>>>>> My intention was to make it user friendly so he does not have to
>>>>>> deal with 6 different Rproc IDs that can change between
>>>>>> platforms. The solution also has to be seamless between different
>>>>>> boot mediums. I think we can assume that the firmware will come from the
>>>>>> same medium that the platform was booted.
>>>>>>
>>>>>
>>>>> Yes and the with changes done by me using ICSSG port seems much easier
>>>>> and user friendly. Just doing `dhcp` at u-boot prompt is enough to use
>>>>> ICSSG port so the driver changes effectively makes the usage for user
>>>>> friendly. But only way I have found to load the firmware files is to use
>>>>> fs-loader that requires the boot medium and boot partition. I am not
>>>>> sure how can I re-use the the boot medium used for booting u-boot images.
>>>>>
>>>>> Also in SD card, u-boot images are located in /boot partition where as
>>>>> firmware is located inside /root partition. So we'll need to specify the
>>>>> partition.
>>>>>
>>>>> Currently I don't have any way to load the firmware files from driver
>>>>> without using below DT change
>>>>>
>>>>> fs_loader0: fs-loader {
>>>>>         bootph-all;
>>>>>         compatible = "u-boot,fs-loader";
>>>>>         phandlepart = <&sdhci1 2>;
>>>>> };
>>>>>
>>>>
>>>> Fromdoc/develop/driver-model/fs_firmware_loader.rst
>>>>
>>>> "Firmware loader driver is also designed to support U-Boot environment
>>>> variables, so all these data from FDT can be overwritten
>>>> through the U-Boot environment variable during run time.
>>>>
>>>> For examples:
>>>>
>>>> storage_interface:
>>>>   Storage interface, it can be "mmc", "usb", "sata" or "ubi".
>>>> fw_dev_part:
>>>>   Block device number and its partition, it can be "0:1".
>>>> fw_ubi_mtdpart:
>>>>   UBI device mtd partition, it can be "UBI".
>>>> fw_ubi_volume:
>>>>   UBI volume, it can be "ubi0".
>>>>
>>>> When above environment variables are set, environment values would be
>>>> used instead of data from FDT.
>>>> The benefit of this design allows user to change storage attribute data
>>>> at run time through U-Boot console and saving the setting as default
>>>> environment values in the storage for the next power cycle, so no
>>>> compilation is required for both driver and FDT."
>>>>
>>>> So looks like we should provide this in environment variables instead of DT?
>>>>
>>>
>>> Thanks Roger for digging this up. I tried setting the below environment
>>> values and it works.
>>>
>>> 	storage_interface=mmc
>>> 	fw_dev_part=1:2
>>>
>>> No need to add the fs-loader node in DT. We can directly set the env
>>> values and fs_loader will use them to load file. I will drop the DT
>>> change for fs-loader. I think this env approach is same as running the
>>> load command at u-boot (the initial approach). I think any medium that
>>> could be used using load command, can be used here by setting
>>> appropriate env values.
>>>
>>> Roger, Should I add the below code to include/env/ti/ti_common.env or
>>> board/ti/am65x/am65x.env so that we don't need to set these variables
>>> manually everytime we try to use ICSSG Ethernet and by default these
>>> variables will be set to mmc and 1:2. User can definately modify these
>>> at u-boot prompt and set appropriate values before running `dhcp`.
>>>
>>> diff --git a/include/env/ti/ti_common.env b/include/env/ti/ti_common.env
>>> index f0f89a2287..0861d3be34 100644
>>> --- a/include/env/ti/ti_common.env
>>> +++ b/include/env/ti/ti_common.env
>>> @@ -35,3 +35,8 @@ bootcmd_ti_mmc=
>>>         else;
>>>                 run get_kern_${boot}; run get_fdt_${boot}; run
>>> get_overlay_${boot}; run run_kern;
>>>         fi;
>>> +
>>> +#if CONFIG_TI_ICSSG_PRUETH
>>> +storage_interface=mmc
>>
>> "storage_interface" is vague. It should be updated to fw_storage_interface in fs-loader driver
>> and environment. It could fallback to storage_interface to not break existing implementations.
>>
> 
> Sure. But changing "storage_interface" to "fw_storage_interface" in  the
> fs-loader driver will also require changing the variable name in all the
> users drivers (e.g. arch/arm/mach-k3/common.c)
> 

That's why I said to fallback to "storage_interface" i.e. not drop it entirely.
FS-loader Documentation will also need to be updated.

>>> +fw_dev_part=1:2
>>> +#endif
>>>
>>
>> I think it should go in the respective <board>.env file as not all TI platforms
>> have the same boot/firmware partition.
>> so I would put it in board/ti/am65x/am65x.env
>>
> 
> Sure, I'll keep it in board/ti/am65x/am65x.env.
> 
> Andrew, Can you please confirm if you are okay with this approach. I
> will post v2 soon, once you confirm.
> 
>>>
>>>>>>>
>>>>>>>>
>>>>>>>> If we want to try to hide some of that then we need a way to
>>>>>>>> run a user provided script from the environement to handle
>>>>>>>> the general cases for firmware loading.
>>>>>>
>>>>>> Assuming we go with the "script provided in environment: route,
>>>>>> how do we deal with the Rproc IDs? I'm not sure if they are constant
>>>>>> and can probably change based on which Rproc is registered first.
>>>>>> So there needs to be some way to make sure user can reference
>>>>>> the correct Rproc.
>>>>>>
>>>>>
>>>>> The Rproc IDs aren't constant. I think the IDs depend on the sequence of
>>>>> init. The only way to know the IDs of different Rprocs is to run `rproc
>>>>> init` and then `rproc list`. Mostly on AM65x I have seen Rporc ID 0 and
>>>>> 1 to be of r5 rprocs and from 2 to 19 of differnet PRUs (Total 18, 6 per
>>>>> ICSSG instance). If r5 is not enabled, the sequence changes. Similarly
>>>>> if some other rproc is enabled sequence will change.
>>>>>
>>>>> The script should be able to read the list and determine which rproc
>>>>> needs to be loaded based on the port we want to use. I am not sure how
>>>>> to do this during u-boot.
>>>>>
>>>>
>>>> rproc list gives an output in the following format.
>>>>
>>>> => rproc list
>>>> 0 - Name:'r5f@41000000' type:'internal memory mapped' supports: load start stop reset
>>>> 1 - Name:'r5f@41400000' type:'internal memory mapped' supports: load start stop reset
>>>> 2 - Name:'r5f@5c00000' type:'internal memory mapped' supports: load start stop reset
>>>> 3 - Name:'r5f@5d00000' type:'internal memory mapped' supports: load start stop reset
>>>> 4 - Name:'r5f@5e00000' type:'internal memory mapped' supports: load start stop reset
>>>> 5 - Name:'r5f@5f00000' type:'internal memory mapped' supports: load start stop reset
>>>> 6 - Name:'dsp@4d80800000' type:'internal memory mapped' supports: load start stop reset
>>>> 7 - Name:'dsp@4d81800000' type:'internal memory mapped' supports: load start stop reset
>>>> 8 - Name:'dsp@64800000' type:'internal memory mapped' supports: load start stop reset
>>>>
>>>> How can the script know which rproc to start for a specific Ethernet interface?
>>>>
>>>
>>> I am not sure. For ICSSGx port-y, we need to start pru_x_y, rtu_x_y,
>>> tx_pru_x_y. The script could search for these core names and start the
>>> core number corresponding to these names in the result of `rproc list`.
>>>
>>> I think it will not be needed now as we can modify the envs to select
>>> different mediums, instead of hardcoding DT.
>>>
>>
>> OK.
>>
> 

-- 
cheers,
-roger

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
  2024-01-09  9:26                     ` Roger Quadros
@ 2024-01-09  9:49                       ` MD Danish Anwar
  2024-01-09 12:34                         ` Roger Quadros
  0 siblings, 1 reply; 48+ messages in thread
From: MD Danish Anwar @ 2024-01-09  9:49 UTC (permalink / raw)
  To: Roger Quadros, Anwar, Md Danish, Andrew Davis, Maxime Ripard,
	Siddharth Vadapalli, Nishanth Menon, Vignesh Raghavendra,
	Matthias Schiffer, Kamlesh Gurudasani, Manorit Chawdhry,
	Neha Malcom Francis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran



On 09/01/24 2:56 pm, Roger Quadros wrote:
> 
> 
> On 08/01/2024 12:25, MD Danish Anwar wrote:
>> On 08/01/24 3:00 pm, Roger Quadros wrote:
>>>
>>>
>>> On 05/01/2024 12:15, Anwar, Md Danish wrote:
>>>>
>>>>
>>>> On 1/5/2024 1:49 PM, Roger Quadros wrote:
>>>>>
>>>>>
>>>>> On 03/01/2024 12:27, MD Danish Anwar wrote:
>>>>>>
>>>>>>
>>>>>> On 02/01/24 7:26 pm, Andrew Davis wrote:
>>>>>>> On 12/27/23 12:56 AM, MD Danish Anwar wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 22/12/23 6:13 pm, Roger Quadros wrote:
>>>>>>>>>
>>>>>>>>> On 22/12/2023 12:26, MD Danish Anwar wrote:
>>>>>>>>>> Hi Roger,
>>>>>>>>>>
>>>>>>>>>> On 20/12/23 3:29 pm, Roger Quadros wrote:
>>>>>>>>>>> Hi,
>>>>>>>>>>>
>>>>>>>>>>> On 19/12/2023 12:11, MD Danish Anwar wrote:
>>>>>>>>>>>> Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used
>>>>>>>>>>>> in TI
>>>>>>>>>>>> AM654 SR2.0.
>>>>>>>>>>>>
>>>>>>>>>>>> The ICSSG PRU Sub-system runs on EMAC firmware. This series
>>>>>>>>>>>> Introduces
>>>>>>>>>>>> support for ICSSG driver in uboot. This series also adds the driver's
>>>>>>>>>>>> dependencies.
>>>>>>>>>>>>
>>>>>>>>>>>> The ICSSG2 node is added in device tree overlay so that it remains in
>>>>>>>>>>>> sync with linux kernel.
>>>>>>>>>>>>
>>>>>>>>>>>> The series introduces device tree and config changes and AM65x
>>>>>>>>>>>> to enable ICSSG driver. The series also enables
>>>>>>>>>>>> SPL_LOAD_FIT_APPLY_OVERLAY
>>>>>>>>>>>> for AM65x in order to load overlay over spl.
>>>>>>>>>>>>
>>>>>>>>>>>> This series has been tested on AM65x SR2.0, and the ICSSG
>>>>>>>>>>>> interface is
>>>>>>>>>>>> able to ping / dhcp and boot kernel using tftp in uboot.
>>>>>>>>>>>>
>>>>>>>>>>>> To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to
>>>>>>>>>>>> PRU RPROC
>>>>>>>>>>>> cores and RPROC cores need to be booted with the firmware. This
>>>>>>>>>>>> step is
>>>>>>>>>>>> done inside driver in kernel as kernel supports APIs like
>>>>>>>>>>>> rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't
>>>>>>>>>>>> have these
>>>>>>>>>>>> APIs, the same needs to be done via u-boot cmds.
>>>>>>>>>>>>
>>>>>>>>>>>> To make sure icssg-eth works we need to do below steps.
>>>>>>>>>>>>
>>>>>>>>>>>> 1. Initialize rproc cores i.e. rproc_init()
>>>>>>>>>>>> 2. Load $firmware_file from partition '1:2' (root) on device (mmc
>>>>>>>>>>>> in this
>>>>>>>>>>>>     example)
>>>>>>>>>>>> 3. Load the firmware file to rproc cores passing. i.e. rproc_load()
>>>>>>>>>>>>     taking rproc_id, loadaddr and file size as arguments.
>>>>>>>>>>>> 4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments
>>>>>>>>>>>>
>>>>>>>>>>>> The above steps are done by running the below commands at u-boot
>>>>>>>>>>>> prompt.
>>>>>>>>>>>>
>>>>>>>>>>>> => setenv start_icssg2 'rproc start 14; rproc start 15; rproc
>>>>>>>>>>>> start 16; rproc start 17; rproc start 18; rproc start 19'
>>>>>>>>>>>> => setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop
>>>>>>>>>>>> 16; rproc stop 17; rproc stop 18; rproc stop 19'
>>>>>>>>>>>> => setenv firmware_dir '/lib/firmware/ti-pruss'
>>>>>>>>>>>> => setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr}
>>>>>>>>>>>> ${firmware_dir}/${firmware_file}'
>>>>>>>>>>>>
>>>>>>>>>>>> => setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload
>>>>>>>>>>>> no; rproc init; setenv loadaddr 0x80000000; \
>>>>>>>>>>>>      setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run
>>>>>>>>>>>> get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
>>>>>>>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>>>>>>>> am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15
>>>>>>>>>>>> 0x89000000 ${filesize}; \
>>>>>>>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>>>>>>>> am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>>>>>>>> 16 0x90000000 ${filesize}; \
>>>>>>>>>>>>      setenv loadaddr 0x80000000; setenv firmware_file
>>>>>>>>>>>> am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17
>>>>>>>>>>>> 0x80000000 ${filesize}; \
>>>>>>>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>>>>>>>> am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18
>>>>>>>>>>>> 0x89000000 ${filesize}; \
>>>>>>>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>>>>>>>> am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>>>>>>>> 19 0x90000000 ${filesize}; \
>>>>>>>>>>>>      run start_icssg2;'
>>>>>>>>>>>
>>>>>>>>>>> A whole bunch of commands are required to get ethernet functional.
>>>>>>>>>>> This is not at all user friendly and will be a maintenance nightmare.
>>>>>>>>>>> What worries me is tracking the 6 different rproc cores and the 6
>>>>>>>>>>> different firmware files to start 1 ethernet device.
>>>>>>>>>>> This will get even more interesting when we have to deal with
>>>>>>>>>>> different ICSSG instances on different boards.
>>>>>>>>>>>
>>>>>>>>>>> What is preventing the driver from starting the rproc cores it
>>>>>>>>>>> needs so user doesn't need to care about it?
>>>>>>>>>>> All the necessary information is in the Device tree. At least this
>>>>>>>>>>> is how it is done on Linux.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> I tried removing the need for these commands and implementing them
>>>>>>>>>> inside the driver only. I am able to load the firmware from driver
>>>>>>>>>> using
>>>>>>>>>> the fs_loader API request_firmware_into_buf(). It requires changes to
>>>>>>>>>> dt. A DT node called fs-loader needs to be added also CONFIG_FS_LOADER
>>>>>>>>>> needs to enabled. In the DT node we need to specify the storage media
>>>>>>>>>> that we are using i.e. mmc, ospi, usb. It's upto user to modify the
>>>>>>>>>> storage media, the driver will take the media from DT and try to laod
>>>>>>>>>> firmware from their.
>>>>>>>>>>
>>>>>>>>>> For loading firmwares to rproc cores, rproc_load() API is needed. Now
>>>>>>>>>> this API takes rproc_id, loadaddr and firmware_size as arguments.
>>>>>>>>>> loadaddr is fixed for all three pru cores. firmware_size is obtained
>>>>>>>>>> from request_firmware_into_buf() but I couldn't find a way to get the
>>>>>>>>>> rproc_id. For now based on the ICSSG instance and slice number I am
>>>>>>>>>> figuring out the rproc_id and passing it to rproc_load() and
>>>>>>>>>> rproc_start() APIs. Please let me know if you have any other / better
>>>>>>>>>> way of finding rproc_id.
>>>>>>>>>>
>>>>>>>>>> Below is the entire diff to remove these commands and move their
>>>>>>>>>> functionality to driver. Please have a look and let me know if this
>>>>>>>>>> is ok.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Good to see you got something working so quickly.
>>>>>>>>> It has some rough edges but nothing that is blocking.
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Save New Duplicate & Edit Just Text Twitter
>>>>>>>>>> diff --git a/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>>>> b/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>>>> index cfbcebfa37..c8da72e49c 100644
>>>>>>>>>> --- a/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>>>> +++ b/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>>>> @@ -16,6 +16,13 @@
>>>>>>>>>>       chosen {
>>>>>>>>>>           stdout-path = "serial2:115200n8";
>>>>>>>>>>           bootargs = "earlycon=ns16550a,mmio32,0x02800000";
>>>>>>>>>> +        firmware-loader = <&fs_loader0>;
>>>>>>>>>> +    };
>>>>>>>>>> +
>>>>>>>>>> +    fs_loader0: fs-loader {
>>>>>>>>>> +        bootph-all;
>>>>>>>>>> +        compatible = "u-boot,fs-loader";
>>>>>>>>>> +        phandlepart = <&sdhci1 2>;
>>>>>>>>>>       };
>>>>>>>>>
>>>>>>>>> This is has 2 issues
>>>>>>>>> 1) It will not be accepted in Kernel DT. Maybe it could be done in
>>>>>>>>> -u-boot.dtsi file.
>>>>>>>>
>>>>>>>> Sure. I'll move this to k3-am654-base-board-u-boot.dtsi
>>>>>>>>
>>>>>>>>> 2) You cannot assume boot medium is always sdhci1 2
>>>>>>>>>
>>>>>>>>
>>>>>>>> Yes. It's upto user to provide the boot medium and boot partition for
>>>>>>>> loading firmware. By default the firmware is loacated in root partion of
>>>>>>>> shdci1 on am65x so I am adding this as default. But user can easily
>>>>>>>> modify this to any other medium / partition needed.
>>>>>>>>
>>>>>>>
>>>>>>> Users should not have to modify DT to pick a boot medium/partition.
>>>>>>> What would you do for complex cases or non block devices like eth/uart
>>>>>>
>>>>> I agree with Andrew here.
>>>>>
>>>>>> In order to load firmware files from driver, we need to add the node for
>>>>>> fs-loader. The fs-loader has a phandlepart property which takes the boot
>>>>>> medium and the partition as input. Based on the medium and partition it
>>>>>> looks for the requested file and loads it to a given address. I am not
>>>>>> sure if there is any other way to load firmware from driver without
>>>>>> using the fs-loader.
>>>>>>
>>>>>>
>>>>>>> booting? This is one reason kernel moved firmware loading to
>>>>>>> userspace. The equivalant in U-Boot is the shell and scripts. Your
>>>>>>> original command based loading was the correct solution IMHO.
>>>>>>
>>>>>> I intended to go ahead with command base approach only but as Roger
>>>>>> pointed out the command based approach is not very user friendly.
>>>>>>
>>>>>> We need to align on what should be the correct approach for loading
>>>>>> firmware.
>>>>>>
>>>>>> Roger, can you please chime in here.
>>>>>
>>>>> My intention was to make it user friendly so he does not have to
>>>>> deal with 6 different Rproc IDs that can change between
>>>>> platforms. The solution also has to be seamless between different
>>>>> boot mediums. I think we can assume that the firmware will come from the
>>>>> same medium that the platform was booted.
>>>>>
>>>>
>>>> Yes and the with changes done by me using ICSSG port seems much easier
>>>> and user friendly. Just doing `dhcp` at u-boot prompt is enough to use
>>>> ICSSG port so the driver changes effectively makes the usage for user
>>>> friendly. But only way I have found to load the firmware files is to use
>>>> fs-loader that requires the boot medium and boot partition. I am not
>>>> sure how can I re-use the the boot medium used for booting u-boot images.
>>>>
>>>> Also in SD card, u-boot images are located in /boot partition where as
>>>> firmware is located inside /root partition. So we'll need to specify the
>>>> partition.
>>>>
>>>> Currently I don't have any way to load the firmware files from driver
>>>> without using below DT change
>>>>
>>>> fs_loader0: fs-loader {
>>>>         bootph-all;
>>>>         compatible = "u-boot,fs-loader";
>>>>         phandlepart = <&sdhci1 2>;
>>>> };
>>>>
>>>
>>> Fromdoc/develop/driver-model/fs_firmware_loader.rst
>>>
>>> "Firmware loader driver is also designed to support U-Boot environment
>>> variables, so all these data from FDT can be overwritten
>>> through the U-Boot environment variable during run time.
>>>
>>> For examples:
>>>
>>> storage_interface:
>>>   Storage interface, it can be "mmc", "usb", "sata" or "ubi".
>>> fw_dev_part:
>>>   Block device number and its partition, it can be "0:1".
>>> fw_ubi_mtdpart:
>>>   UBI device mtd partition, it can be "UBI".
>>> fw_ubi_volume:
>>>   UBI volume, it can be "ubi0".
>>>
>>> When above environment variables are set, environment values would be
>>> used instead of data from FDT.
>>> The benefit of this design allows user to change storage attribute data
>>> at run time through U-Boot console and saving the setting as default
>>> environment values in the storage for the next power cycle, so no
>>> compilation is required for both driver and FDT."
>>>
>>> So looks like we should provide this in environment variables instead of DT?
>>>
>>
>> Thanks Roger for digging this up. I tried setting the below environment
>> values and it works.
>>
>> 	storage_interface=mmc
>> 	fw_dev_part=1:2
>>
>> No need to add the fs-loader node in DT. We can directly set the env
>> values and fs_loader will use them to load file. I will drop the DT
>> change for fs-loader. I think this env approach is same as running the
>> load command at u-boot (the initial approach). I think any medium that
>> could be used using load command, can be used here by setting
>> appropriate env values.
>>
>> Roger, Should I add the below code to include/env/ti/ti_common.env or
>> board/ti/am65x/am65x.env so that we don't need to set these variables
>> manually everytime we try to use ICSSG Ethernet and by default these
>> variables will be set to mmc and 1:2. User can definately modify these
>> at u-boot prompt and set appropriate values before running `dhcp`.
>>
>> diff --git a/include/env/ti/ti_common.env b/include/env/ti/ti_common.env
>> index f0f89a2287..0861d3be34 100644
>> --- a/include/env/ti/ti_common.env
>> +++ b/include/env/ti/ti_common.env
>> @@ -35,3 +35,8 @@ bootcmd_ti_mmc=
>>         else;
>>                 run get_kern_${boot}; run get_fdt_${boot}; run
>> get_overlay_${boot}; run run_kern;
>>         fi;
>> +
>> +#if CONFIG_TI_ICSSG_PRUETH
>> +storage_interface=mmc
> 
> "storage_interface" is vague. It should be updated to fw_storage_interface in fs-loader driver
> and environment. It could fallback to storage_interface to not break existing implementations.
> 

Sure. But changing "storage_interface" to "fw_storage_interface" in  the
fs-loader driver will also require changing the variable name in all the
users drivers (e.g. arch/arm/mach-k3/common.c)

>> +fw_dev_part=1:2
>> +#endif
>>
> 
> I think it should go in the respective <board>.env file as not all TI platforms
> have the same boot/firmware partition.
> so I would put it in board/ti/am65x/am65x.env
> 

Sure, I'll keep it in board/ti/am65x/am65x.env.

Andrew, Can you please confirm if you are okay with this approach. I
will post v2 soon, once you confirm.

>>
>>>>>>
>>>>>>>
>>>>>>> If we want to try to hide some of that then we need a way to
>>>>>>> run a user provided script from the environement to handle
>>>>>>> the general cases for firmware loading.
>>>>>
>>>>> Assuming we go with the "script provided in environment: route,
>>>>> how do we deal with the Rproc IDs? I'm not sure if they are constant
>>>>> and can probably change based on which Rproc is registered first.
>>>>> So there needs to be some way to make sure user can reference
>>>>> the correct Rproc.
>>>>>
>>>>
>>>> The Rproc IDs aren't constant. I think the IDs depend on the sequence of
>>>> init. The only way to know the IDs of different Rprocs is to run `rproc
>>>> init` and then `rproc list`. Mostly on AM65x I have seen Rporc ID 0 and
>>>> 1 to be of r5 rprocs and from 2 to 19 of differnet PRUs (Total 18, 6 per
>>>> ICSSG instance). If r5 is not enabled, the sequence changes. Similarly
>>>> if some other rproc is enabled sequence will change.
>>>>
>>>> The script should be able to read the list and determine which rproc
>>>> needs to be loaded based on the port we want to use. I am not sure how
>>>> to do this during u-boot.
>>>>
>>>
>>> rproc list gives an output in the following format.
>>>
>>> => rproc list
>>> 0 - Name:'r5f@41000000' type:'internal memory mapped' supports: load start stop reset
>>> 1 - Name:'r5f@41400000' type:'internal memory mapped' supports: load start stop reset
>>> 2 - Name:'r5f@5c00000' type:'internal memory mapped' supports: load start stop reset
>>> 3 - Name:'r5f@5d00000' type:'internal memory mapped' supports: load start stop reset
>>> 4 - Name:'r5f@5e00000' type:'internal memory mapped' supports: load start stop reset
>>> 5 - Name:'r5f@5f00000' type:'internal memory mapped' supports: load start stop reset
>>> 6 - Name:'dsp@4d80800000' type:'internal memory mapped' supports: load start stop reset
>>> 7 - Name:'dsp@4d81800000' type:'internal memory mapped' supports: load start stop reset
>>> 8 - Name:'dsp@64800000' type:'internal memory mapped' supports: load start stop reset
>>>
>>> How can the script know which rproc to start for a specific Ethernet interface?
>>>
>>
>> I am not sure. For ICSSGx port-y, we need to start pru_x_y, rtu_x_y,
>> tx_pru_x_y. The script could search for these core names and start the
>> core number corresponding to these names in the result of `rproc list`.
>>
>> I think it will not be needed now as we can modify the envs to select
>> different mediums, instead of hardcoding DT.
>>
> 
> OK.
> 

-- 
Thanks and Regards,
Danish

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
  2024-01-08 10:25                   ` MD Danish Anwar
@ 2024-01-09  9:26                     ` Roger Quadros
  2024-01-09  9:49                       ` MD Danish Anwar
  0 siblings, 1 reply; 48+ messages in thread
From: Roger Quadros @ 2024-01-09  9:26 UTC (permalink / raw)
  To: MD Danish Anwar, Anwar, Md Danish, Andrew Davis, Maxime Ripard,
	Siddharth Vadapalli, Nishanth Menon, Vignesh Raghavendra,
	Matthias Schiffer, Kamlesh Gurudasani, Manorit Chawdhry,
	Neha Malcom Francis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran



On 08/01/2024 12:25, MD Danish Anwar wrote:
> On 08/01/24 3:00 pm, Roger Quadros wrote:
>>
>>
>> On 05/01/2024 12:15, Anwar, Md Danish wrote:
>>>
>>>
>>> On 1/5/2024 1:49 PM, Roger Quadros wrote:
>>>>
>>>>
>>>> On 03/01/2024 12:27, MD Danish Anwar wrote:
>>>>>
>>>>>
>>>>> On 02/01/24 7:26 pm, Andrew Davis wrote:
>>>>>> On 12/27/23 12:56 AM, MD Danish Anwar wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 22/12/23 6:13 pm, Roger Quadros wrote:
>>>>>>>>
>>>>>>>> On 22/12/2023 12:26, MD Danish Anwar wrote:
>>>>>>>>> Hi Roger,
>>>>>>>>>
>>>>>>>>> On 20/12/23 3:29 pm, Roger Quadros wrote:
>>>>>>>>>> Hi,
>>>>>>>>>>
>>>>>>>>>> On 19/12/2023 12:11, MD Danish Anwar wrote:
>>>>>>>>>>> Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used
>>>>>>>>>>> in TI
>>>>>>>>>>> AM654 SR2.0.
>>>>>>>>>>>
>>>>>>>>>>> The ICSSG PRU Sub-system runs on EMAC firmware. This series
>>>>>>>>>>> Introduces
>>>>>>>>>>> support for ICSSG driver in uboot. This series also adds the driver's
>>>>>>>>>>> dependencies.
>>>>>>>>>>>
>>>>>>>>>>> The ICSSG2 node is added in device tree overlay so that it remains in
>>>>>>>>>>> sync with linux kernel.
>>>>>>>>>>>
>>>>>>>>>>> The series introduces device tree and config changes and AM65x
>>>>>>>>>>> to enable ICSSG driver. The series also enables
>>>>>>>>>>> SPL_LOAD_FIT_APPLY_OVERLAY
>>>>>>>>>>> for AM65x in order to load overlay over spl.
>>>>>>>>>>>
>>>>>>>>>>> This series has been tested on AM65x SR2.0, and the ICSSG
>>>>>>>>>>> interface is
>>>>>>>>>>> able to ping / dhcp and boot kernel using tftp in uboot.
>>>>>>>>>>>
>>>>>>>>>>> To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to
>>>>>>>>>>> PRU RPROC
>>>>>>>>>>> cores and RPROC cores need to be booted with the firmware. This
>>>>>>>>>>> step is
>>>>>>>>>>> done inside driver in kernel as kernel supports APIs like
>>>>>>>>>>> rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't
>>>>>>>>>>> have these
>>>>>>>>>>> APIs, the same needs to be done via u-boot cmds.
>>>>>>>>>>>
>>>>>>>>>>> To make sure icssg-eth works we need to do below steps.
>>>>>>>>>>>
>>>>>>>>>>> 1. Initialize rproc cores i.e. rproc_init()
>>>>>>>>>>> 2. Load $firmware_file from partition '1:2' (root) on device (mmc
>>>>>>>>>>> in this
>>>>>>>>>>>     example)
>>>>>>>>>>> 3. Load the firmware file to rproc cores passing. i.e. rproc_load()
>>>>>>>>>>>     taking rproc_id, loadaddr and file size as arguments.
>>>>>>>>>>> 4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments
>>>>>>>>>>>
>>>>>>>>>>> The above steps are done by running the below commands at u-boot
>>>>>>>>>>> prompt.
>>>>>>>>>>>
>>>>>>>>>>> => setenv start_icssg2 'rproc start 14; rproc start 15; rproc
>>>>>>>>>>> start 16; rproc start 17; rproc start 18; rproc start 19'
>>>>>>>>>>> => setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop
>>>>>>>>>>> 16; rproc stop 17; rproc stop 18; rproc stop 19'
>>>>>>>>>>> => setenv firmware_dir '/lib/firmware/ti-pruss'
>>>>>>>>>>> => setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr}
>>>>>>>>>>> ${firmware_dir}/${firmware_file}'
>>>>>>>>>>>
>>>>>>>>>>> => setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload
>>>>>>>>>>> no; rproc init; setenv loadaddr 0x80000000; \
>>>>>>>>>>>      setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run
>>>>>>>>>>> get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
>>>>>>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>>>>>>> am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15
>>>>>>>>>>> 0x89000000 ${filesize}; \
>>>>>>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>>>>>>> am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>>>>>>> 16 0x90000000 ${filesize}; \
>>>>>>>>>>>      setenv loadaddr 0x80000000; setenv firmware_file
>>>>>>>>>>> am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17
>>>>>>>>>>> 0x80000000 ${filesize}; \
>>>>>>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>>>>>>> am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18
>>>>>>>>>>> 0x89000000 ${filesize}; \
>>>>>>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>>>>>>> am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>>>>>>> 19 0x90000000 ${filesize}; \
>>>>>>>>>>>      run start_icssg2;'
>>>>>>>>>>
>>>>>>>>>> A whole bunch of commands are required to get ethernet functional.
>>>>>>>>>> This is not at all user friendly and will be a maintenance nightmare.
>>>>>>>>>> What worries me is tracking the 6 different rproc cores and the 6
>>>>>>>>>> different firmware files to start 1 ethernet device.
>>>>>>>>>> This will get even more interesting when we have to deal with
>>>>>>>>>> different ICSSG instances on different boards.
>>>>>>>>>>
>>>>>>>>>> What is preventing the driver from starting the rproc cores it
>>>>>>>>>> needs so user doesn't need to care about it?
>>>>>>>>>> All the necessary information is in the Device tree. At least this
>>>>>>>>>> is how it is done on Linux.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> I tried removing the need for these commands and implementing them
>>>>>>>>> inside the driver only. I am able to load the firmware from driver
>>>>>>>>> using
>>>>>>>>> the fs_loader API request_firmware_into_buf(). It requires changes to
>>>>>>>>> dt. A DT node called fs-loader needs to be added also CONFIG_FS_LOADER
>>>>>>>>> needs to enabled. In the DT node we need to specify the storage media
>>>>>>>>> that we are using i.e. mmc, ospi, usb. It's upto user to modify the
>>>>>>>>> storage media, the driver will take the media from DT and try to laod
>>>>>>>>> firmware from their.
>>>>>>>>>
>>>>>>>>> For loading firmwares to rproc cores, rproc_load() API is needed. Now
>>>>>>>>> this API takes rproc_id, loadaddr and firmware_size as arguments.
>>>>>>>>> loadaddr is fixed for all three pru cores. firmware_size is obtained
>>>>>>>>> from request_firmware_into_buf() but I couldn't find a way to get the
>>>>>>>>> rproc_id. For now based on the ICSSG instance and slice number I am
>>>>>>>>> figuring out the rproc_id and passing it to rproc_load() and
>>>>>>>>> rproc_start() APIs. Please let me know if you have any other / better
>>>>>>>>> way of finding rproc_id.
>>>>>>>>>
>>>>>>>>> Below is the entire diff to remove these commands and move their
>>>>>>>>> functionality to driver. Please have a look and let me know if this
>>>>>>>>> is ok.
>>>>>>>>>
>>>>>>>>
>>>>>>>> Good to see you got something working so quickly.
>>>>>>>> It has some rough edges but nothing that is blocking.
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Save New Duplicate & Edit Just Text Twitter
>>>>>>>>> diff --git a/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>>> b/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>>> index cfbcebfa37..c8da72e49c 100644
>>>>>>>>> --- a/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>>> +++ b/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>>> @@ -16,6 +16,13 @@
>>>>>>>>>       chosen {
>>>>>>>>>           stdout-path = "serial2:115200n8";
>>>>>>>>>           bootargs = "earlycon=ns16550a,mmio32,0x02800000";
>>>>>>>>> +        firmware-loader = <&fs_loader0>;
>>>>>>>>> +    };
>>>>>>>>> +
>>>>>>>>> +    fs_loader0: fs-loader {
>>>>>>>>> +        bootph-all;
>>>>>>>>> +        compatible = "u-boot,fs-loader";
>>>>>>>>> +        phandlepart = <&sdhci1 2>;
>>>>>>>>>       };
>>>>>>>>
>>>>>>>> This is has 2 issues
>>>>>>>> 1) It will not be accepted in Kernel DT. Maybe it could be done in
>>>>>>>> -u-boot.dtsi file.
>>>>>>>
>>>>>>> Sure. I'll move this to k3-am654-base-board-u-boot.dtsi
>>>>>>>
>>>>>>>> 2) You cannot assume boot medium is always sdhci1 2
>>>>>>>>
>>>>>>>
>>>>>>> Yes. It's upto user to provide the boot medium and boot partition for
>>>>>>> loading firmware. By default the firmware is loacated in root partion of
>>>>>>> shdci1 on am65x so I am adding this as default. But user can easily
>>>>>>> modify this to any other medium / partition needed.
>>>>>>>
>>>>>>
>>>>>> Users should not have to modify DT to pick a boot medium/partition.
>>>>>> What would you do for complex cases or non block devices like eth/uart
>>>>>
>>>> I agree with Andrew here.
>>>>
>>>>> In order to load firmware files from driver, we need to add the node for
>>>>> fs-loader. The fs-loader has a phandlepart property which takes the boot
>>>>> medium and the partition as input. Based on the medium and partition it
>>>>> looks for the requested file and loads it to a given address. I am not
>>>>> sure if there is any other way to load firmware from driver without
>>>>> using the fs-loader.
>>>>>
>>>>>
>>>>>> booting? This is one reason kernel moved firmware loading to
>>>>>> userspace. The equivalant in U-Boot is the shell and scripts. Your
>>>>>> original command based loading was the correct solution IMHO.
>>>>>
>>>>> I intended to go ahead with command base approach only but as Roger
>>>>> pointed out the command based approach is not very user friendly.
>>>>>
>>>>> We need to align on what should be the correct approach for loading
>>>>> firmware.
>>>>>
>>>>> Roger, can you please chime in here.
>>>>
>>>> My intention was to make it user friendly so he does not have to
>>>> deal with 6 different Rproc IDs that can change between
>>>> platforms. The solution also has to be seamless between different
>>>> boot mediums. I think we can assume that the firmware will come from the
>>>> same medium that the platform was booted.
>>>>
>>>
>>> Yes and the with changes done by me using ICSSG port seems much easier
>>> and user friendly. Just doing `dhcp` at u-boot prompt is enough to use
>>> ICSSG port so the driver changes effectively makes the usage for user
>>> friendly. But only way I have found to load the firmware files is to use
>>> fs-loader that requires the boot medium and boot partition. I am not
>>> sure how can I re-use the the boot medium used for booting u-boot images.
>>>
>>> Also in SD card, u-boot images are located in /boot partition where as
>>> firmware is located inside /root partition. So we'll need to specify the
>>> partition.
>>>
>>> Currently I don't have any way to load the firmware files from driver
>>> without using below DT change
>>>
>>> fs_loader0: fs-loader {
>>>         bootph-all;
>>>         compatible = "u-boot,fs-loader";
>>>         phandlepart = <&sdhci1 2>;
>>> };
>>>
>>
>> Fromdoc/develop/driver-model/fs_firmware_loader.rst
>>
>> "Firmware loader driver is also designed to support U-Boot environment
>> variables, so all these data from FDT can be overwritten
>> through the U-Boot environment variable during run time.
>>
>> For examples:
>>
>> storage_interface:
>>   Storage interface, it can be "mmc", "usb", "sata" or "ubi".
>> fw_dev_part:
>>   Block device number and its partition, it can be "0:1".
>> fw_ubi_mtdpart:
>>   UBI device mtd partition, it can be "UBI".
>> fw_ubi_volume:
>>   UBI volume, it can be "ubi0".
>>
>> When above environment variables are set, environment values would be
>> used instead of data from FDT.
>> The benefit of this design allows user to change storage attribute data
>> at run time through U-Boot console and saving the setting as default
>> environment values in the storage for the next power cycle, so no
>> compilation is required for both driver and FDT."
>>
>> So looks like we should provide this in environment variables instead of DT?
>>
> 
> Thanks Roger for digging this up. I tried setting the below environment
> values and it works.
> 
> 	storage_interface=mmc
> 	fw_dev_part=1:2
> 
> No need to add the fs-loader node in DT. We can directly set the env
> values and fs_loader will use them to load file. I will drop the DT
> change for fs-loader. I think this env approach is same as running the
> load command at u-boot (the initial approach). I think any medium that
> could be used using load command, can be used here by setting
> appropriate env values.
> 
> Roger, Should I add the below code to include/env/ti/ti_common.env or
> board/ti/am65x/am65x.env so that we don't need to set these variables
> manually everytime we try to use ICSSG Ethernet and by default these
> variables will be set to mmc and 1:2. User can definately modify these
> at u-boot prompt and set appropriate values before running `dhcp`.
> 
> diff --git a/include/env/ti/ti_common.env b/include/env/ti/ti_common.env
> index f0f89a2287..0861d3be34 100644
> --- a/include/env/ti/ti_common.env
> +++ b/include/env/ti/ti_common.env
> @@ -35,3 +35,8 @@ bootcmd_ti_mmc=
>         else;
>                 run get_kern_${boot}; run get_fdt_${boot}; run
> get_overlay_${boot}; run run_kern;
>         fi;
> +
> +#if CONFIG_TI_ICSSG_PRUETH
> +storage_interface=mmc

"storage_interface" is vague. It should be updated to fw_storage_interface in fs-loader driver
and environment. It could fallback to storage_interface to not break existing implementations.

> +fw_dev_part=1:2
> +#endif
> 

I think it should go in the respective <board>.env file as not all TI platforms
have the same boot/firmware partition.
so I would put it in board/ti/am65x/am65x.env

> 
>>>>>
>>>>>>
>>>>>> If we want to try to hide some of that then we need a way to
>>>>>> run a user provided script from the environement to handle
>>>>>> the general cases for firmware loading.
>>>>
>>>> Assuming we go with the "script provided in environment: route,
>>>> how do we deal with the Rproc IDs? I'm not sure if they are constant
>>>> and can probably change based on which Rproc is registered first.
>>>> So there needs to be some way to make sure user can reference
>>>> the correct Rproc.
>>>>
>>>
>>> The Rproc IDs aren't constant. I think the IDs depend on the sequence of
>>> init. The only way to know the IDs of different Rprocs is to run `rproc
>>> init` and then `rproc list`. Mostly on AM65x I have seen Rporc ID 0 and
>>> 1 to be of r5 rprocs and from 2 to 19 of differnet PRUs (Total 18, 6 per
>>> ICSSG instance). If r5 is not enabled, the sequence changes. Similarly
>>> if some other rproc is enabled sequence will change.
>>>
>>> The script should be able to read the list and determine which rproc
>>> needs to be loaded based on the port we want to use. I am not sure how
>>> to do this during u-boot.
>>>
>>
>> rproc list gives an output in the following format.
>>
>> => rproc list
>> 0 - Name:'r5f@41000000' type:'internal memory mapped' supports: load start stop reset
>> 1 - Name:'r5f@41400000' type:'internal memory mapped' supports: load start stop reset
>> 2 - Name:'r5f@5c00000' type:'internal memory mapped' supports: load start stop reset
>> 3 - Name:'r5f@5d00000' type:'internal memory mapped' supports: load start stop reset
>> 4 - Name:'r5f@5e00000' type:'internal memory mapped' supports: load start stop reset
>> 5 - Name:'r5f@5f00000' type:'internal memory mapped' supports: load start stop reset
>> 6 - Name:'dsp@4d80800000' type:'internal memory mapped' supports: load start stop reset
>> 7 - Name:'dsp@4d81800000' type:'internal memory mapped' supports: load start stop reset
>> 8 - Name:'dsp@64800000' type:'internal memory mapped' supports: load start stop reset
>>
>> How can the script know which rproc to start for a specific Ethernet interface?
>>
> 
> I am not sure. For ICSSGx port-y, we need to start pru_x_y, rtu_x_y,
> tx_pru_x_y. The script could search for these core names and start the
> core number corresponding to these names in the result of `rproc list`.
> 
> I think it will not be needed now as we can modify the envs to select
> different mediums, instead of hardcoding DT.
> 

OK.

-- 
cheers,
-roger

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
  2024-01-08  9:30                 ` Roger Quadros
@ 2024-01-08 10:25                   ` MD Danish Anwar
  2024-01-09  9:26                     ` Roger Quadros
  0 siblings, 1 reply; 48+ messages in thread
From: MD Danish Anwar @ 2024-01-08 10:25 UTC (permalink / raw)
  To: Roger Quadros, Anwar, Md Danish, Andrew Davis, Maxime Ripard,
	Siddharth Vadapalli, Nishanth Menon, Vignesh Raghavendra,
	Matthias Schiffer, Kamlesh Gurudasani, Manorit Chawdhry,
	Neha Malcom Francis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran

On 08/01/24 3:00 pm, Roger Quadros wrote:
> 
> 
> On 05/01/2024 12:15, Anwar, Md Danish wrote:
>>
>>
>> On 1/5/2024 1:49 PM, Roger Quadros wrote:
>>>
>>>
>>> On 03/01/2024 12:27, MD Danish Anwar wrote:
>>>>
>>>>
>>>> On 02/01/24 7:26 pm, Andrew Davis wrote:
>>>>> On 12/27/23 12:56 AM, MD Danish Anwar wrote:
>>>>>>
>>>>>>
>>>>>> On 22/12/23 6:13 pm, Roger Quadros wrote:
>>>>>>>
>>>>>>> On 22/12/2023 12:26, MD Danish Anwar wrote:
>>>>>>>> Hi Roger,
>>>>>>>>
>>>>>>>> On 20/12/23 3:29 pm, Roger Quadros wrote:
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> On 19/12/2023 12:11, MD Danish Anwar wrote:
>>>>>>>>>> Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used
>>>>>>>>>> in TI
>>>>>>>>>> AM654 SR2.0.
>>>>>>>>>>
>>>>>>>>>> The ICSSG PRU Sub-system runs on EMAC firmware. This series
>>>>>>>>>> Introduces
>>>>>>>>>> support for ICSSG driver in uboot. This series also adds the driver's
>>>>>>>>>> dependencies.
>>>>>>>>>>
>>>>>>>>>> The ICSSG2 node is added in device tree overlay so that it remains in
>>>>>>>>>> sync with linux kernel.
>>>>>>>>>>
>>>>>>>>>> The series introduces device tree and config changes and AM65x
>>>>>>>>>> to enable ICSSG driver. The series also enables
>>>>>>>>>> SPL_LOAD_FIT_APPLY_OVERLAY
>>>>>>>>>> for AM65x in order to load overlay over spl.
>>>>>>>>>>
>>>>>>>>>> This series has been tested on AM65x SR2.0, and the ICSSG
>>>>>>>>>> interface is
>>>>>>>>>> able to ping / dhcp and boot kernel using tftp in uboot.
>>>>>>>>>>
>>>>>>>>>> To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to
>>>>>>>>>> PRU RPROC
>>>>>>>>>> cores and RPROC cores need to be booted with the firmware. This
>>>>>>>>>> step is
>>>>>>>>>> done inside driver in kernel as kernel supports APIs like
>>>>>>>>>> rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't
>>>>>>>>>> have these
>>>>>>>>>> APIs, the same needs to be done via u-boot cmds.
>>>>>>>>>>
>>>>>>>>>> To make sure icssg-eth works we need to do below steps.
>>>>>>>>>>
>>>>>>>>>> 1. Initialize rproc cores i.e. rproc_init()
>>>>>>>>>> 2. Load $firmware_file from partition '1:2' (root) on device (mmc
>>>>>>>>>> in this
>>>>>>>>>>     example)
>>>>>>>>>> 3. Load the firmware file to rproc cores passing. i.e. rproc_load()
>>>>>>>>>>     taking rproc_id, loadaddr and file size as arguments.
>>>>>>>>>> 4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments
>>>>>>>>>>
>>>>>>>>>> The above steps are done by running the below commands at u-boot
>>>>>>>>>> prompt.
>>>>>>>>>>
>>>>>>>>>> => setenv start_icssg2 'rproc start 14; rproc start 15; rproc
>>>>>>>>>> start 16; rproc start 17; rproc start 18; rproc start 19'
>>>>>>>>>> => setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop
>>>>>>>>>> 16; rproc stop 17; rproc stop 18; rproc stop 19'
>>>>>>>>>> => setenv firmware_dir '/lib/firmware/ti-pruss'
>>>>>>>>>> => setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr}
>>>>>>>>>> ${firmware_dir}/${firmware_file}'
>>>>>>>>>>
>>>>>>>>>> => setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload
>>>>>>>>>> no; rproc init; setenv loadaddr 0x80000000; \
>>>>>>>>>>      setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run
>>>>>>>>>> get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
>>>>>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>>>>>> am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15
>>>>>>>>>> 0x89000000 ${filesize}; \
>>>>>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>>>>>> am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>>>>>> 16 0x90000000 ${filesize}; \
>>>>>>>>>>      setenv loadaddr 0x80000000; setenv firmware_file
>>>>>>>>>> am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17
>>>>>>>>>> 0x80000000 ${filesize}; \
>>>>>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>>>>>> am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18
>>>>>>>>>> 0x89000000 ${filesize}; \
>>>>>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>>>>>> am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>>>>>> 19 0x90000000 ${filesize}; \
>>>>>>>>>>      run start_icssg2;'
>>>>>>>>>
>>>>>>>>> A whole bunch of commands are required to get ethernet functional.
>>>>>>>>> This is not at all user friendly and will be a maintenance nightmare.
>>>>>>>>> What worries me is tracking the 6 different rproc cores and the 6
>>>>>>>>> different firmware files to start 1 ethernet device.
>>>>>>>>> This will get even more interesting when we have to deal with
>>>>>>>>> different ICSSG instances on different boards.
>>>>>>>>>
>>>>>>>>> What is preventing the driver from starting the rproc cores it
>>>>>>>>> needs so user doesn't need to care about it?
>>>>>>>>> All the necessary information is in the Device tree. At least this
>>>>>>>>> is how it is done on Linux.
>>>>>>>>>
>>>>>>>>
>>>>>>>> I tried removing the need for these commands and implementing them
>>>>>>>> inside the driver only. I am able to load the firmware from driver
>>>>>>>> using
>>>>>>>> the fs_loader API request_firmware_into_buf(). It requires changes to
>>>>>>>> dt. A DT node called fs-loader needs to be added also CONFIG_FS_LOADER
>>>>>>>> needs to enabled. In the DT node we need to specify the storage media
>>>>>>>> that we are using i.e. mmc, ospi, usb. It's upto user to modify the
>>>>>>>> storage media, the driver will take the media from DT and try to laod
>>>>>>>> firmware from their.
>>>>>>>>
>>>>>>>> For loading firmwares to rproc cores, rproc_load() API is needed. Now
>>>>>>>> this API takes rproc_id, loadaddr and firmware_size as arguments.
>>>>>>>> loadaddr is fixed for all three pru cores. firmware_size is obtained
>>>>>>>> from request_firmware_into_buf() but I couldn't find a way to get the
>>>>>>>> rproc_id. For now based on the ICSSG instance and slice number I am
>>>>>>>> figuring out the rproc_id and passing it to rproc_load() and
>>>>>>>> rproc_start() APIs. Please let me know if you have any other / better
>>>>>>>> way of finding rproc_id.
>>>>>>>>
>>>>>>>> Below is the entire diff to remove these commands and move their
>>>>>>>> functionality to driver. Please have a look and let me know if this
>>>>>>>> is ok.
>>>>>>>>
>>>>>>>
>>>>>>> Good to see you got something working so quickly.
>>>>>>> It has some rough edges but nothing that is blocking.
>>>>>>>
>>>>>>>>
>>>>>>>> Save New Duplicate & Edit Just Text Twitter
>>>>>>>> diff --git a/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>> b/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>> index cfbcebfa37..c8da72e49c 100644
>>>>>>>> --- a/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>> +++ b/arch/arm/dts/k3-am654-base-board.dts
>>>>>>>> @@ -16,6 +16,13 @@
>>>>>>>>       chosen {
>>>>>>>>           stdout-path = "serial2:115200n8";
>>>>>>>>           bootargs = "earlycon=ns16550a,mmio32,0x02800000";
>>>>>>>> +        firmware-loader = <&fs_loader0>;
>>>>>>>> +    };
>>>>>>>> +
>>>>>>>> +    fs_loader0: fs-loader {
>>>>>>>> +        bootph-all;
>>>>>>>> +        compatible = "u-boot,fs-loader";
>>>>>>>> +        phandlepart = <&sdhci1 2>;
>>>>>>>>       };
>>>>>>>
>>>>>>> This is has 2 issues
>>>>>>> 1) It will not be accepted in Kernel DT. Maybe it could be done in
>>>>>>> -u-boot.dtsi file.
>>>>>>
>>>>>> Sure. I'll move this to k3-am654-base-board-u-boot.dtsi
>>>>>>
>>>>>>> 2) You cannot assume boot medium is always sdhci1 2
>>>>>>>
>>>>>>
>>>>>> Yes. It's upto user to provide the boot medium and boot partition for
>>>>>> loading firmware. By default the firmware is loacated in root partion of
>>>>>> shdci1 on am65x so I am adding this as default. But user can easily
>>>>>> modify this to any other medium / partition needed.
>>>>>>
>>>>>
>>>>> Users should not have to modify DT to pick a boot medium/partition.
>>>>> What would you do for complex cases or non block devices like eth/uart
>>>>
>>> I agree with Andrew here.
>>>
>>>> In order to load firmware files from driver, we need to add the node for
>>>> fs-loader. The fs-loader has a phandlepart property which takes the boot
>>>> medium and the partition as input. Based on the medium and partition it
>>>> looks for the requested file and loads it to a given address. I am not
>>>> sure if there is any other way to load firmware from driver without
>>>> using the fs-loader.
>>>>
>>>>
>>>>> booting? This is one reason kernel moved firmware loading to
>>>>> userspace. The equivalant in U-Boot is the shell and scripts. Your
>>>>> original command based loading was the correct solution IMHO.
>>>>
>>>> I intended to go ahead with command base approach only but as Roger
>>>> pointed out the command based approach is not very user friendly.
>>>>
>>>> We need to align on what should be the correct approach for loading
>>>> firmware.
>>>>
>>>> Roger, can you please chime in here.
>>>
>>> My intention was to make it user friendly so he does not have to
>>> deal with 6 different Rproc IDs that can change between
>>> platforms. The solution also has to be seamless between different
>>> boot mediums. I think we can assume that the firmware will come from the
>>> same medium that the platform was booted.
>>>
>>
>> Yes and the with changes done by me using ICSSG port seems much easier
>> and user friendly. Just doing `dhcp` at u-boot prompt is enough to use
>> ICSSG port so the driver changes effectively makes the usage for user
>> friendly. But only way I have found to load the firmware files is to use
>> fs-loader that requires the boot medium and boot partition. I am not
>> sure how can I re-use the the boot medium used for booting u-boot images.
>>
>> Also in SD card, u-boot images are located in /boot partition where as
>> firmware is located inside /root partition. So we'll need to specify the
>> partition.
>>
>> Currently I don't have any way to load the firmware files from driver
>> without using below DT change
>>
>> fs_loader0: fs-loader {
>>         bootph-all;
>>         compatible = "u-boot,fs-loader";
>>         phandlepart = <&sdhci1 2>;
>> };
>>
> 
> Fromdoc/develop/driver-model/fs_firmware_loader.rst
> 
> "Firmware loader driver is also designed to support U-Boot environment
> variables, so all these data from FDT can be overwritten
> through the U-Boot environment variable during run time.
> 
> For examples:
> 
> storage_interface:
>   Storage interface, it can be "mmc", "usb", "sata" or "ubi".
> fw_dev_part:
>   Block device number and its partition, it can be "0:1".
> fw_ubi_mtdpart:
>   UBI device mtd partition, it can be "UBI".
> fw_ubi_volume:
>   UBI volume, it can be "ubi0".
> 
> When above environment variables are set, environment values would be
> used instead of data from FDT.
> The benefit of this design allows user to change storage attribute data
> at run time through U-Boot console and saving the setting as default
> environment values in the storage for the next power cycle, so no
> compilation is required for both driver and FDT."
> 
> So looks like we should provide this in environment variables instead of DT?
> 

Thanks Roger for digging this up. I tried setting the below environment
values and it works.

	storage_interface=mmc
	fw_dev_part=1:2

No need to add the fs-loader node in DT. We can directly set the env
values and fs_loader will use them to load file. I will drop the DT
change for fs-loader. I think this env approach is same as running the
load command at u-boot (the initial approach). I think any medium that
could be used using load command, can be used here by setting
appropriate env values.

Roger, Should I add the below code to include/env/ti/ti_common.env or
board/ti/am65x/am65x.env so that we don't need to set these variables
manually everytime we try to use ICSSG Ethernet and by default these
variables will be set to mmc and 1:2. User can definately modify these
at u-boot prompt and set appropriate values before running `dhcp`.

diff --git a/include/env/ti/ti_common.env b/include/env/ti/ti_common.env
index f0f89a2287..0861d3be34 100644
--- a/include/env/ti/ti_common.env
+++ b/include/env/ti/ti_common.env
@@ -35,3 +35,8 @@ bootcmd_ti_mmc=
        else;
                run get_kern_${boot}; run get_fdt_${boot}; run
get_overlay_${boot}; run run_kern;
        fi;
+
+#if CONFIG_TI_ICSSG_PRUETH
+storage_interface=mmc
+fw_dev_part=1:2
+#endif


>>>>
>>>>>
>>>>> If we want to try to hide some of that then we need a way to
>>>>> run a user provided script from the environement to handle
>>>>> the general cases for firmware loading.
>>>
>>> Assuming we go with the "script provided in environment: route,
>>> how do we deal with the Rproc IDs? I'm not sure if they are constant
>>> and can probably change based on which Rproc is registered first.
>>> So there needs to be some way to make sure user can reference
>>> the correct Rproc.
>>>
>>
>> The Rproc IDs aren't constant. I think the IDs depend on the sequence of
>> init. The only way to know the IDs of different Rprocs is to run `rproc
>> init` and then `rproc list`. Mostly on AM65x I have seen Rporc ID 0 and
>> 1 to be of r5 rprocs and from 2 to 19 of differnet PRUs (Total 18, 6 per
>> ICSSG instance). If r5 is not enabled, the sequence changes. Similarly
>> if some other rproc is enabled sequence will change.
>>
>> The script should be able to read the list and determine which rproc
>> needs to be loaded based on the port we want to use. I am not sure how
>> to do this during u-boot.
>>
> 
> rproc list gives an output in the following format.
> 
> => rproc list
> 0 - Name:'r5f@41000000' type:'internal memory mapped' supports: load start stop reset
> 1 - Name:'r5f@41400000' type:'internal memory mapped' supports: load start stop reset
> 2 - Name:'r5f@5c00000' type:'internal memory mapped' supports: load start stop reset
> 3 - Name:'r5f@5d00000' type:'internal memory mapped' supports: load start stop reset
> 4 - Name:'r5f@5e00000' type:'internal memory mapped' supports: load start stop reset
> 5 - Name:'r5f@5f00000' type:'internal memory mapped' supports: load start stop reset
> 6 - Name:'dsp@4d80800000' type:'internal memory mapped' supports: load start stop reset
> 7 - Name:'dsp@4d81800000' type:'internal memory mapped' supports: load start stop reset
> 8 - Name:'dsp@64800000' type:'internal memory mapped' supports: load start stop reset
> 
> How can the script know which rproc to start for a specific Ethernet interface?
> 

I am not sure. For ICSSGx port-y, we need to start pru_x_y, rtu_x_y,
tx_pru_x_y. The script could search for these core names and start the
core number corresponding to these names in the result of `rproc list`.

I think it will not be needed now as we can modify the envs to select
different mediums, instead of hardcoding DT.

-- 
Thanks and Regards,
Danish

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
  2024-01-05 10:15               ` Anwar, Md Danish
@ 2024-01-08  9:30                 ` Roger Quadros
  2024-01-08 10:25                   ` MD Danish Anwar
  0 siblings, 1 reply; 48+ messages in thread
From: Roger Quadros @ 2024-01-08  9:30 UTC (permalink / raw)
  To: Anwar, Md Danish, MD Danish Anwar, Andrew Davis, Maxime Ripard,
	Siddharth Vadapalli, Nishanth Menon, Vignesh Raghavendra,
	Matthias Schiffer, Kamlesh Gurudasani, Manorit Chawdhry,
	Neha Malcom Francis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran



On 05/01/2024 12:15, Anwar, Md Danish wrote:
> 
> 
> On 1/5/2024 1:49 PM, Roger Quadros wrote:
>>
>>
>> On 03/01/2024 12:27, MD Danish Anwar wrote:
>>>
>>>
>>> On 02/01/24 7:26 pm, Andrew Davis wrote:
>>>> On 12/27/23 12:56 AM, MD Danish Anwar wrote:
>>>>>
>>>>>
>>>>> On 22/12/23 6:13 pm, Roger Quadros wrote:
>>>>>>
>>>>>> On 22/12/2023 12:26, MD Danish Anwar wrote:
>>>>>>> Hi Roger,
>>>>>>>
>>>>>>> On 20/12/23 3:29 pm, Roger Quadros wrote:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> On 19/12/2023 12:11, MD Danish Anwar wrote:
>>>>>>>>> Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used
>>>>>>>>> in TI
>>>>>>>>> AM654 SR2.0.
>>>>>>>>>
>>>>>>>>> The ICSSG PRU Sub-system runs on EMAC firmware. This series
>>>>>>>>> Introduces
>>>>>>>>> support for ICSSG driver in uboot. This series also adds the driver's
>>>>>>>>> dependencies.
>>>>>>>>>
>>>>>>>>> The ICSSG2 node is added in device tree overlay so that it remains in
>>>>>>>>> sync with linux kernel.
>>>>>>>>>
>>>>>>>>> The series introduces device tree and config changes and AM65x
>>>>>>>>> to enable ICSSG driver. The series also enables
>>>>>>>>> SPL_LOAD_FIT_APPLY_OVERLAY
>>>>>>>>> for AM65x in order to load overlay over spl.
>>>>>>>>>
>>>>>>>>> This series has been tested on AM65x SR2.0, and the ICSSG
>>>>>>>>> interface is
>>>>>>>>> able to ping / dhcp and boot kernel using tftp in uboot.
>>>>>>>>>
>>>>>>>>> To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to
>>>>>>>>> PRU RPROC
>>>>>>>>> cores and RPROC cores need to be booted with the firmware. This
>>>>>>>>> step is
>>>>>>>>> done inside driver in kernel as kernel supports APIs like
>>>>>>>>> rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't
>>>>>>>>> have these
>>>>>>>>> APIs, the same needs to be done via u-boot cmds.
>>>>>>>>>
>>>>>>>>> To make sure icssg-eth works we need to do below steps.
>>>>>>>>>
>>>>>>>>> 1. Initialize rproc cores i.e. rproc_init()
>>>>>>>>> 2. Load $firmware_file from partition '1:2' (root) on device (mmc
>>>>>>>>> in this
>>>>>>>>>     example)
>>>>>>>>> 3. Load the firmware file to rproc cores passing. i.e. rproc_load()
>>>>>>>>>     taking rproc_id, loadaddr and file size as arguments.
>>>>>>>>> 4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments
>>>>>>>>>
>>>>>>>>> The above steps are done by running the below commands at u-boot
>>>>>>>>> prompt.
>>>>>>>>>
>>>>>>>>> => setenv start_icssg2 'rproc start 14; rproc start 15; rproc
>>>>>>>>> start 16; rproc start 17; rproc start 18; rproc start 19'
>>>>>>>>> => setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop
>>>>>>>>> 16; rproc stop 17; rproc stop 18; rproc stop 19'
>>>>>>>>> => setenv firmware_dir '/lib/firmware/ti-pruss'
>>>>>>>>> => setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr}
>>>>>>>>> ${firmware_dir}/${firmware_file}'
>>>>>>>>>
>>>>>>>>> => setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload
>>>>>>>>> no; rproc init; setenv loadaddr 0x80000000; \
>>>>>>>>>      setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run
>>>>>>>>> get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
>>>>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>>>>> am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15
>>>>>>>>> 0x89000000 ${filesize}; \
>>>>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>>>>> am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>>>>> 16 0x90000000 ${filesize}; \
>>>>>>>>>      setenv loadaddr 0x80000000; setenv firmware_file
>>>>>>>>> am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17
>>>>>>>>> 0x80000000 ${filesize}; \
>>>>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>>>>> am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18
>>>>>>>>> 0x89000000 ${filesize}; \
>>>>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>>>>> am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>>>>> 19 0x90000000 ${filesize}; \
>>>>>>>>>      run start_icssg2;'
>>>>>>>>
>>>>>>>> A whole bunch of commands are required to get ethernet functional.
>>>>>>>> This is not at all user friendly and will be a maintenance nightmare.
>>>>>>>> What worries me is tracking the 6 different rproc cores and the 6
>>>>>>>> different firmware files to start 1 ethernet device.
>>>>>>>> This will get even more interesting when we have to deal with
>>>>>>>> different ICSSG instances on different boards.
>>>>>>>>
>>>>>>>> What is preventing the driver from starting the rproc cores it
>>>>>>>> needs so user doesn't need to care about it?
>>>>>>>> All the necessary information is in the Device tree. At least this
>>>>>>>> is how it is done on Linux.
>>>>>>>>
>>>>>>>
>>>>>>> I tried removing the need for these commands and implementing them
>>>>>>> inside the driver only. I am able to load the firmware from driver
>>>>>>> using
>>>>>>> the fs_loader API request_firmware_into_buf(). It requires changes to
>>>>>>> dt. A DT node called fs-loader needs to be added also CONFIG_FS_LOADER
>>>>>>> needs to enabled. In the DT node we need to specify the storage media
>>>>>>> that we are using i.e. mmc, ospi, usb. It's upto user to modify the
>>>>>>> storage media, the driver will take the media from DT and try to laod
>>>>>>> firmware from their.
>>>>>>>
>>>>>>> For loading firmwares to rproc cores, rproc_load() API is needed. Now
>>>>>>> this API takes rproc_id, loadaddr and firmware_size as arguments.
>>>>>>> loadaddr is fixed for all three pru cores. firmware_size is obtained
>>>>>>> from request_firmware_into_buf() but I couldn't find a way to get the
>>>>>>> rproc_id. For now based on the ICSSG instance and slice number I am
>>>>>>> figuring out the rproc_id and passing it to rproc_load() and
>>>>>>> rproc_start() APIs. Please let me know if you have any other / better
>>>>>>> way of finding rproc_id.
>>>>>>>
>>>>>>> Below is the entire diff to remove these commands and move their
>>>>>>> functionality to driver. Please have a look and let me know if this
>>>>>>> is ok.
>>>>>>>
>>>>>>
>>>>>> Good to see you got something working so quickly.
>>>>>> It has some rough edges but nothing that is blocking.
>>>>>>
>>>>>>>
>>>>>>> Save New Duplicate & Edit Just Text Twitter
>>>>>>> diff --git a/arch/arm/dts/k3-am654-base-board.dts
>>>>>>> b/arch/arm/dts/k3-am654-base-board.dts
>>>>>>> index cfbcebfa37..c8da72e49c 100644
>>>>>>> --- a/arch/arm/dts/k3-am654-base-board.dts
>>>>>>> +++ b/arch/arm/dts/k3-am654-base-board.dts
>>>>>>> @@ -16,6 +16,13 @@
>>>>>>>       chosen {
>>>>>>>           stdout-path = "serial2:115200n8";
>>>>>>>           bootargs = "earlycon=ns16550a,mmio32,0x02800000";
>>>>>>> +        firmware-loader = <&fs_loader0>;
>>>>>>> +    };
>>>>>>> +
>>>>>>> +    fs_loader0: fs-loader {
>>>>>>> +        bootph-all;
>>>>>>> +        compatible = "u-boot,fs-loader";
>>>>>>> +        phandlepart = <&sdhci1 2>;
>>>>>>>       };
>>>>>>
>>>>>> This is has 2 issues
>>>>>> 1) It will not be accepted in Kernel DT. Maybe it could be done in
>>>>>> -u-boot.dtsi file.
>>>>>
>>>>> Sure. I'll move this to k3-am654-base-board-u-boot.dtsi
>>>>>
>>>>>> 2) You cannot assume boot medium is always sdhci1 2
>>>>>>
>>>>>
>>>>> Yes. It's upto user to provide the boot medium and boot partition for
>>>>> loading firmware. By default the firmware is loacated in root partion of
>>>>> shdci1 on am65x so I am adding this as default. But user can easily
>>>>> modify this to any other medium / partition needed.
>>>>>
>>>>
>>>> Users should not have to modify DT to pick a boot medium/partition.
>>>> What would you do for complex cases or non block devices like eth/uart
>>>
>> I agree with Andrew here.
>>
>>> In order to load firmware files from driver, we need to add the node for
>>> fs-loader. The fs-loader has a phandlepart property which takes the boot
>>> medium and the partition as input. Based on the medium and partition it
>>> looks for the requested file and loads it to a given address. I am not
>>> sure if there is any other way to load firmware from driver without
>>> using the fs-loader.
>>>
>>>
>>>> booting? This is one reason kernel moved firmware loading to
>>>> userspace. The equivalant in U-Boot is the shell and scripts. Your
>>>> original command based loading was the correct solution IMHO.
>>>
>>> I intended to go ahead with command base approach only but as Roger
>>> pointed out the command based approach is not very user friendly.
>>>
>>> We need to align on what should be the correct approach for loading
>>> firmware.
>>>
>>> Roger, can you please chime in here.
>>
>> My intention was to make it user friendly so he does not have to
>> deal with 6 different Rproc IDs that can change between
>> platforms. The solution also has to be seamless between different
>> boot mediums. I think we can assume that the firmware will come from the
>> same medium that the platform was booted.
>>
> 
> Yes and the with changes done by me using ICSSG port seems much easier
> and user friendly. Just doing `dhcp` at u-boot prompt is enough to use
> ICSSG port so the driver changes effectively makes the usage for user
> friendly. But only way I have found to load the firmware files is to use
> fs-loader that requires the boot medium and boot partition. I am not
> sure how can I re-use the the boot medium used for booting u-boot images.
> 
> Also in SD card, u-boot images are located in /boot partition where as
> firmware is located inside /root partition. So we'll need to specify the
> partition.
> 
> Currently I don't have any way to load the firmware files from driver
> without using below DT change
> 
> fs_loader0: fs-loader {
>         bootph-all;
>         compatible = "u-boot,fs-loader";
>         phandlepart = <&sdhci1 2>;
> };
> 

Fromdoc/develop/driver-model/fs_firmware_loader.rst

"Firmware loader driver is also designed to support U-Boot environment
variables, so all these data from FDT can be overwritten
through the U-Boot environment variable during run time.

For examples:

storage_interface:
  Storage interface, it can be "mmc", "usb", "sata" or "ubi".
fw_dev_part:
  Block device number and its partition, it can be "0:1".
fw_ubi_mtdpart:
  UBI device mtd partition, it can be "UBI".
fw_ubi_volume:
  UBI volume, it can be "ubi0".

When above environment variables are set, environment values would be
used instead of data from FDT.
The benefit of this design allows user to change storage attribute data
at run time through U-Boot console and saving the setting as default
environment values in the storage for the next power cycle, so no
compilation is required for both driver and FDT."

So looks like we should provide this in environment variables instead of DT?

>>>
>>>>
>>>> If we want to try to hide some of that then we need a way to
>>>> run a user provided script from the environement to handle
>>>> the general cases for firmware loading.
>>
>> Assuming we go with the "script provided in environment: route,
>> how do we deal with the Rproc IDs? I'm not sure if they are constant
>> and can probably change based on which Rproc is registered first.
>> So there needs to be some way to make sure user can reference
>> the correct Rproc.
>>
> 
> The Rproc IDs aren't constant. I think the IDs depend on the sequence of
> init. The only way to know the IDs of different Rprocs is to run `rproc
> init` and then `rproc list`. Mostly on AM65x I have seen Rporc ID 0 and
> 1 to be of r5 rprocs and from 2 to 19 of differnet PRUs (Total 18, 6 per
> ICSSG instance). If r5 is not enabled, the sequence changes. Similarly
> if some other rproc is enabled sequence will change.
> 
> The script should be able to read the list and determine which rproc
> needs to be loaded based on the port we want to use. I am not sure how
> to do this during u-boot.
> 

rproc list gives an output in the following format.

=> rproc list
0 - Name:'r5f@41000000' type:'internal memory mapped' supports: load start stop reset
1 - Name:'r5f@41400000' type:'internal memory mapped' supports: load start stop reset
2 - Name:'r5f@5c00000' type:'internal memory mapped' supports: load start stop reset
3 - Name:'r5f@5d00000' type:'internal memory mapped' supports: load start stop reset
4 - Name:'r5f@5e00000' type:'internal memory mapped' supports: load start stop reset
5 - Name:'r5f@5f00000' type:'internal memory mapped' supports: load start stop reset
6 - Name:'dsp@4d80800000' type:'internal memory mapped' supports: load start stop reset
7 - Name:'dsp@4d81800000' type:'internal memory mapped' supports: load start stop reset
8 - Name:'dsp@64800000' type:'internal memory mapped' supports: load start stop reset

How can the script know which rproc to start for a specific Ethernet interface?

-- 
cheers,
-roger

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
  2024-01-05  8:19             ` Roger Quadros
@ 2024-01-05 10:15               ` Anwar, Md Danish
  2024-01-08  9:30                 ` Roger Quadros
  0 siblings, 1 reply; 48+ messages in thread
From: Anwar, Md Danish @ 2024-01-05 10:15 UTC (permalink / raw)
  To: Roger Quadros, MD Danish Anwar, Andrew Davis, Maxime Ripard,
	Siddharth Vadapalli, Nishanth Menon, Vignesh Raghavendra,
	Matthias Schiffer, Kamlesh Gurudasani, Manorit Chawdhry,
	Neha Malcom Francis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran



On 1/5/2024 1:49 PM, Roger Quadros wrote:
> 
> 
> On 03/01/2024 12:27, MD Danish Anwar wrote:
>>
>>
>> On 02/01/24 7:26 pm, Andrew Davis wrote:
>>> On 12/27/23 12:56 AM, MD Danish Anwar wrote:
>>>>
>>>>
>>>> On 22/12/23 6:13 pm, Roger Quadros wrote:
>>>>>
>>>>> On 22/12/2023 12:26, MD Danish Anwar wrote:
>>>>>> Hi Roger,
>>>>>>
>>>>>> On 20/12/23 3:29 pm, Roger Quadros wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> On 19/12/2023 12:11, MD Danish Anwar wrote:
>>>>>>>> Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used
>>>>>>>> in TI
>>>>>>>> AM654 SR2.0.
>>>>>>>>
>>>>>>>> The ICSSG PRU Sub-system runs on EMAC firmware. This series
>>>>>>>> Introduces
>>>>>>>> support for ICSSG driver in uboot. This series also adds the driver's
>>>>>>>> dependencies.
>>>>>>>>
>>>>>>>> The ICSSG2 node is added in device tree overlay so that it remains in
>>>>>>>> sync with linux kernel.
>>>>>>>>
>>>>>>>> The series introduces device tree and config changes and AM65x
>>>>>>>> to enable ICSSG driver. The series also enables
>>>>>>>> SPL_LOAD_FIT_APPLY_OVERLAY
>>>>>>>> for AM65x in order to load overlay over spl.
>>>>>>>>
>>>>>>>> This series has been tested on AM65x SR2.0, and the ICSSG
>>>>>>>> interface is
>>>>>>>> able to ping / dhcp and boot kernel using tftp in uboot.
>>>>>>>>
>>>>>>>> To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to
>>>>>>>> PRU RPROC
>>>>>>>> cores and RPROC cores need to be booted with the firmware. This
>>>>>>>> step is
>>>>>>>> done inside driver in kernel as kernel supports APIs like
>>>>>>>> rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't
>>>>>>>> have these
>>>>>>>> APIs, the same needs to be done via u-boot cmds.
>>>>>>>>
>>>>>>>> To make sure icssg-eth works we need to do below steps.
>>>>>>>>
>>>>>>>> 1. Initialize rproc cores i.e. rproc_init()
>>>>>>>> 2. Load $firmware_file from partition '1:2' (root) on device (mmc
>>>>>>>> in this
>>>>>>>>     example)
>>>>>>>> 3. Load the firmware file to rproc cores passing. i.e. rproc_load()
>>>>>>>>     taking rproc_id, loadaddr and file size as arguments.
>>>>>>>> 4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments
>>>>>>>>
>>>>>>>> The above steps are done by running the below commands at u-boot
>>>>>>>> prompt.
>>>>>>>>
>>>>>>>> => setenv start_icssg2 'rproc start 14; rproc start 15; rproc
>>>>>>>> start 16; rproc start 17; rproc start 18; rproc start 19'
>>>>>>>> => setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop
>>>>>>>> 16; rproc stop 17; rproc stop 18; rproc stop 19'
>>>>>>>> => setenv firmware_dir '/lib/firmware/ti-pruss'
>>>>>>>> => setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr}
>>>>>>>> ${firmware_dir}/${firmware_file}'
>>>>>>>>
>>>>>>>> => setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload
>>>>>>>> no; rproc init; setenv loadaddr 0x80000000; \
>>>>>>>>      setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run
>>>>>>>> get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
>>>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>>>> am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15
>>>>>>>> 0x89000000 ${filesize}; \
>>>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>>>> am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>>>> 16 0x90000000 ${filesize}; \
>>>>>>>>      setenv loadaddr 0x80000000; setenv firmware_file
>>>>>>>> am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17
>>>>>>>> 0x80000000 ${filesize}; \
>>>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>>>> am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18
>>>>>>>> 0x89000000 ${filesize}; \
>>>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>>>> am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>>>> 19 0x90000000 ${filesize}; \
>>>>>>>>      run start_icssg2;'
>>>>>>>
>>>>>>> A whole bunch of commands are required to get ethernet functional.
>>>>>>> This is not at all user friendly and will be a maintenance nightmare.
>>>>>>> What worries me is tracking the 6 different rproc cores and the 6
>>>>>>> different firmware files to start 1 ethernet device.
>>>>>>> This will get even more interesting when we have to deal with
>>>>>>> different ICSSG instances on different boards.
>>>>>>>
>>>>>>> What is preventing the driver from starting the rproc cores it
>>>>>>> needs so user doesn't need to care about it?
>>>>>>> All the necessary information is in the Device tree. At least this
>>>>>>> is how it is done on Linux.
>>>>>>>
>>>>>>
>>>>>> I tried removing the need for these commands and implementing them
>>>>>> inside the driver only. I am able to load the firmware from driver
>>>>>> using
>>>>>> the fs_loader API request_firmware_into_buf(). It requires changes to
>>>>>> dt. A DT node called fs-loader needs to be added also CONFIG_FS_LOADER
>>>>>> needs to enabled. In the DT node we need to specify the storage media
>>>>>> that we are using i.e. mmc, ospi, usb. It's upto user to modify the
>>>>>> storage media, the driver will take the media from DT and try to laod
>>>>>> firmware from their.
>>>>>>
>>>>>> For loading firmwares to rproc cores, rproc_load() API is needed. Now
>>>>>> this API takes rproc_id, loadaddr and firmware_size as arguments.
>>>>>> loadaddr is fixed for all three pru cores. firmware_size is obtained
>>>>>> from request_firmware_into_buf() but I couldn't find a way to get the
>>>>>> rproc_id. For now based on the ICSSG instance and slice number I am
>>>>>> figuring out the rproc_id and passing it to rproc_load() and
>>>>>> rproc_start() APIs. Please let me know if you have any other / better
>>>>>> way of finding rproc_id.
>>>>>>
>>>>>> Below is the entire diff to remove these commands and move their
>>>>>> functionality to driver. Please have a look and let me know if this
>>>>>> is ok.
>>>>>>
>>>>>
>>>>> Good to see you got something working so quickly.
>>>>> It has some rough edges but nothing that is blocking.
>>>>>
>>>>>>
>>>>>> Save New Duplicate & Edit Just Text Twitter
>>>>>> diff --git a/arch/arm/dts/k3-am654-base-board.dts
>>>>>> b/arch/arm/dts/k3-am654-base-board.dts
>>>>>> index cfbcebfa37..c8da72e49c 100644
>>>>>> --- a/arch/arm/dts/k3-am654-base-board.dts
>>>>>> +++ b/arch/arm/dts/k3-am654-base-board.dts
>>>>>> @@ -16,6 +16,13 @@
>>>>>>       chosen {
>>>>>>           stdout-path = "serial2:115200n8";
>>>>>>           bootargs = "earlycon=ns16550a,mmio32,0x02800000";
>>>>>> +        firmware-loader = <&fs_loader0>;
>>>>>> +    };
>>>>>> +
>>>>>> +    fs_loader0: fs-loader {
>>>>>> +        bootph-all;
>>>>>> +        compatible = "u-boot,fs-loader";
>>>>>> +        phandlepart = <&sdhci1 2>;
>>>>>>       };
>>>>>
>>>>> This is has 2 issues
>>>>> 1) It will not be accepted in Kernel DT. Maybe it could be done in
>>>>> -u-boot.dtsi file.
>>>>
>>>> Sure. I'll move this to k3-am654-base-board-u-boot.dtsi
>>>>
>>>>> 2) You cannot assume boot medium is always sdhci1 2
>>>>>
>>>>
>>>> Yes. It's upto user to provide the boot medium and boot partition for
>>>> loading firmware. By default the firmware is loacated in root partion of
>>>> shdci1 on am65x so I am adding this as default. But user can easily
>>>> modify this to any other medium / partition needed.
>>>>
>>>
>>> Users should not have to modify DT to pick a boot medium/partition.
>>> What would you do for complex cases or non block devices like eth/uart
>>
> I agree with Andrew here.
> 
>> In order to load firmware files from driver, we need to add the node for
>> fs-loader. The fs-loader has a phandlepart property which takes the boot
>> medium and the partition as input. Based on the medium and partition it
>> looks for the requested file and loads it to a given address. I am not
>> sure if there is any other way to load firmware from driver without
>> using the fs-loader.
>>
>>
>>> booting? This is one reason kernel moved firmware loading to
>>> userspace. The equivalant in U-Boot is the shell and scripts. Your
>>> original command based loading was the correct solution IMHO.
>>
>> I intended to go ahead with command base approach only but as Roger
>> pointed out the command based approach is not very user friendly.
>>
>> We need to align on what should be the correct approach for loading
>> firmware.
>>
>> Roger, can you please chime in here.
> 
> My intention was to make it user friendly so he does not have to
> deal with 6 different Rproc IDs that can change between
> platforms. The solution also has to be seamless between different
> boot mediums. I think we can assume that the firmware will come from the
> same medium that the platform was booted.
> 

Yes and the with changes done by me using ICSSG port seems much easier
and user friendly. Just doing `dhcp` at u-boot prompt is enough to use
ICSSG port so the driver changes effectively makes the usage for user
friendly. But only way I have found to load the firmware files is to use
fs-loader that requires the boot medium and boot partition. I am not
sure how can I re-use the the boot medium used for booting u-boot images.

Also in SD card, u-boot images are located in /boot partition where as
firmware is located inside /root partition. So we'll need to specify the
partition.

Currently I don't have any way to load the firmware files from driver
without using below DT change

fs_loader0: fs-loader {
        bootph-all;
        compatible = "u-boot,fs-loader";
        phandlepart = <&sdhci1 2>;
};

>>
>>>
>>> If we want to try to hide some of that then we need a way to
>>> run a user provided script from the environement to handle
>>> the general cases for firmware loading.
> 
> Assuming we go with the "script provided in environment: route,
> how do we deal with the Rproc IDs? I'm not sure if they are constant
> and can probably change based on which Rproc is registered first.
> So there needs to be some way to make sure user can reference
> the correct Rproc.
> 

The Rproc IDs aren't constant. I think the IDs depend on the sequence of
init. The only way to know the IDs of different Rprocs is to run `rproc
init` and then `rproc list`. Mostly on AM65x I have seen Rporc ID 0 and
1 to be of r5 rprocs and from 2 to 19 of differnet PRUs (Total 18, 6 per
ICSSG instance). If r5 is not enabled, the sequence changes. Similarly
if some other rproc is enabled sequence will change.

The script should be able to read the list and determine which rproc
needs to be loaded based on the port we want to use. I am not sure how
to do this during u-boot.

>>>
>>> Andrew
> 
> <snip>
> 

-- 
Thanks and Regards,
Md Danish Anwar

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
  2024-01-03 10:27           ` MD Danish Anwar
@ 2024-01-05  8:19             ` Roger Quadros
  2024-01-05 10:15               ` Anwar, Md Danish
  0 siblings, 1 reply; 48+ messages in thread
From: Roger Quadros @ 2024-01-05  8:19 UTC (permalink / raw)
  To: MD Danish Anwar, Andrew Davis, Maxime Ripard,
	Siddharth Vadapalli, Nishanth Menon, Vignesh Raghavendra,
	Matthias Schiffer, Kamlesh Gurudasani, Manorit Chawdhry,
	Neha Malcom Francis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran



On 03/01/2024 12:27, MD Danish Anwar wrote:
> 
> 
> On 02/01/24 7:26 pm, Andrew Davis wrote:
>> On 12/27/23 12:56 AM, MD Danish Anwar wrote:
>>>
>>>
>>> On 22/12/23 6:13 pm, Roger Quadros wrote:
>>>>
>>>> On 22/12/2023 12:26, MD Danish Anwar wrote:
>>>>> Hi Roger,
>>>>>
>>>>> On 20/12/23 3:29 pm, Roger Quadros wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On 19/12/2023 12:11, MD Danish Anwar wrote:
>>>>>>> Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used
>>>>>>> in TI
>>>>>>> AM654 SR2.0.
>>>>>>>
>>>>>>> The ICSSG PRU Sub-system runs on EMAC firmware. This series
>>>>>>> Introduces
>>>>>>> support for ICSSG driver in uboot. This series also adds the driver's
>>>>>>> dependencies.
>>>>>>>
>>>>>>> The ICSSG2 node is added in device tree overlay so that it remains in
>>>>>>> sync with linux kernel.
>>>>>>>
>>>>>>> The series introduces device tree and config changes and AM65x
>>>>>>> to enable ICSSG driver. The series also enables
>>>>>>> SPL_LOAD_FIT_APPLY_OVERLAY
>>>>>>> for AM65x in order to load overlay over spl.
>>>>>>>
>>>>>>> This series has been tested on AM65x SR2.0, and the ICSSG
>>>>>>> interface is
>>>>>>> able to ping / dhcp and boot kernel using tftp in uboot.
>>>>>>>
>>>>>>> To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to
>>>>>>> PRU RPROC
>>>>>>> cores and RPROC cores need to be booted with the firmware. This
>>>>>>> step is
>>>>>>> done inside driver in kernel as kernel supports APIs like
>>>>>>> rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't
>>>>>>> have these
>>>>>>> APIs, the same needs to be done via u-boot cmds.
>>>>>>>
>>>>>>> To make sure icssg-eth works we need to do below steps.
>>>>>>>
>>>>>>> 1. Initialize rproc cores i.e. rproc_init()
>>>>>>> 2. Load $firmware_file from partition '1:2' (root) on device (mmc
>>>>>>> in this
>>>>>>>     example)
>>>>>>> 3. Load the firmware file to rproc cores passing. i.e. rproc_load()
>>>>>>>     taking rproc_id, loadaddr and file size as arguments.
>>>>>>> 4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments
>>>>>>>
>>>>>>> The above steps are done by running the below commands at u-boot
>>>>>>> prompt.
>>>>>>>
>>>>>>> => setenv start_icssg2 'rproc start 14; rproc start 15; rproc
>>>>>>> start 16; rproc start 17; rproc start 18; rproc start 19'
>>>>>>> => setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop
>>>>>>> 16; rproc stop 17; rproc stop 18; rproc stop 19'
>>>>>>> => setenv firmware_dir '/lib/firmware/ti-pruss'
>>>>>>> => setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr}
>>>>>>> ${firmware_dir}/${firmware_file}'
>>>>>>>
>>>>>>> => setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload
>>>>>>> no; rproc init; setenv loadaddr 0x80000000; \
>>>>>>>      setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run
>>>>>>> get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
>>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>>> am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15
>>>>>>> 0x89000000 ${filesize}; \
>>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>>> am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>>> 16 0x90000000 ${filesize}; \
>>>>>>>      setenv loadaddr 0x80000000; setenv firmware_file
>>>>>>> am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17
>>>>>>> 0x80000000 ${filesize}; \
>>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>>> am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18
>>>>>>> 0x89000000 ${filesize}; \
>>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>>> am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>>> 19 0x90000000 ${filesize}; \
>>>>>>>      run start_icssg2;'
>>>>>>
>>>>>> A whole bunch of commands are required to get ethernet functional.
>>>>>> This is not at all user friendly and will be a maintenance nightmare.
>>>>>> What worries me is tracking the 6 different rproc cores and the 6
>>>>>> different firmware files to start 1 ethernet device.
>>>>>> This will get even more interesting when we have to deal with
>>>>>> different ICSSG instances on different boards.
>>>>>>
>>>>>> What is preventing the driver from starting the rproc cores it
>>>>>> needs so user doesn't need to care about it?
>>>>>> All the necessary information is in the Device tree. At least this
>>>>>> is how it is done on Linux.
>>>>>>
>>>>>
>>>>> I tried removing the need for these commands and implementing them
>>>>> inside the driver only. I am able to load the firmware from driver
>>>>> using
>>>>> the fs_loader API request_firmware_into_buf(). It requires changes to
>>>>> dt. A DT node called fs-loader needs to be added also CONFIG_FS_LOADER
>>>>> needs to enabled. In the DT node we need to specify the storage media
>>>>> that we are using i.e. mmc, ospi, usb. It's upto user to modify the
>>>>> storage media, the driver will take the media from DT and try to laod
>>>>> firmware from their.
>>>>>
>>>>> For loading firmwares to rproc cores, rproc_load() API is needed. Now
>>>>> this API takes rproc_id, loadaddr and firmware_size as arguments.
>>>>> loadaddr is fixed for all three pru cores. firmware_size is obtained
>>>>> from request_firmware_into_buf() but I couldn't find a way to get the
>>>>> rproc_id. For now based on the ICSSG instance and slice number I am
>>>>> figuring out the rproc_id and passing it to rproc_load() and
>>>>> rproc_start() APIs. Please let me know if you have any other / better
>>>>> way of finding rproc_id.
>>>>>
>>>>> Below is the entire diff to remove these commands and move their
>>>>> functionality to driver. Please have a look and let me know if this
>>>>> is ok.
>>>>>
>>>>
>>>> Good to see you got something working so quickly.
>>>> It has some rough edges but nothing that is blocking.
>>>>
>>>>>
>>>>> Save New Duplicate & Edit Just Text Twitter
>>>>> diff --git a/arch/arm/dts/k3-am654-base-board.dts
>>>>> b/arch/arm/dts/k3-am654-base-board.dts
>>>>> index cfbcebfa37..c8da72e49c 100644
>>>>> --- a/arch/arm/dts/k3-am654-base-board.dts
>>>>> +++ b/arch/arm/dts/k3-am654-base-board.dts
>>>>> @@ -16,6 +16,13 @@
>>>>>       chosen {
>>>>>           stdout-path = "serial2:115200n8";
>>>>>           bootargs = "earlycon=ns16550a,mmio32,0x02800000";
>>>>> +        firmware-loader = <&fs_loader0>;
>>>>> +    };
>>>>> +
>>>>> +    fs_loader0: fs-loader {
>>>>> +        bootph-all;
>>>>> +        compatible = "u-boot,fs-loader";
>>>>> +        phandlepart = <&sdhci1 2>;
>>>>>       };
>>>>
>>>> This is has 2 issues
>>>> 1) It will not be accepted in Kernel DT. Maybe it could be done in
>>>> -u-boot.dtsi file.
>>>
>>> Sure. I'll move this to k3-am654-base-board-u-boot.dtsi
>>>
>>>> 2) You cannot assume boot medium is always sdhci1 2
>>>>
>>>
>>> Yes. It's upto user to provide the boot medium and boot partition for
>>> loading firmware. By default the firmware is loacated in root partion of
>>> shdci1 on am65x so I am adding this as default. But user can easily
>>> modify this to any other medium / partition needed.
>>>
>>
>> Users should not have to modify DT to pick a boot medium/partition.
>> What would you do for complex cases or non block devices like eth/uart
> 
I agree with Andrew here.

> In order to load firmware files from driver, we need to add the node for
> fs-loader. The fs-loader has a phandlepart property which takes the boot
> medium and the partition as input. Based on the medium and partition it
> looks for the requested file and loads it to a given address. I am not
> sure if there is any other way to load firmware from driver without
> using the fs-loader.
> 
> 
>> booting? This is one reason kernel moved firmware loading to
>> userspace. The equivalant in U-Boot is the shell and scripts. Your
>> original command based loading was the correct solution IMHO.
> 
> I intended to go ahead with command base approach only but as Roger
> pointed out the command based approach is not very user friendly.
> 
> We need to align on what should be the correct approach for loading
> firmware.
> 
> Roger, can you please chime in here.

My intention was to make it user friendly so he does not have to
deal with 6 different Rproc IDs that can change between
platforms. The solution also has to be seamless between different
boot mediums. I think we can assume that the firmware will come from the
same medium that the platform was booted.

> 
>>
>> If we want to try to hide some of that then we need a way to
>> run a user provided script from the environement to handle
>> the general cases for firmware loading.

Assuming we go with the "script provided in environment: route,
how do we deal with the Rproc IDs? I'm not sure if they are constant
and can probably change based on which Rproc is registered first.
So there needs to be some way to make sure user can reference
the correct Rproc.

>>
>> Andrew

<snip>

-- 
cheers,
-roger

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
  2024-01-02 13:56         ` Andrew Davis
@ 2024-01-03 10:27           ` MD Danish Anwar
  2024-01-05  8:19             ` Roger Quadros
  0 siblings, 1 reply; 48+ messages in thread
From: MD Danish Anwar @ 2024-01-03 10:27 UTC (permalink / raw)
  To: Andrew Davis, Roger Quadros, Maxime Ripard, Siddharth Vadapalli,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Ramon Fried, Joe Hershberger, Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran



On 02/01/24 7:26 pm, Andrew Davis wrote:
> On 12/27/23 12:56 AM, MD Danish Anwar wrote:
>>
>>
>> On 22/12/23 6:13 pm, Roger Quadros wrote:
>>>
>>> On 22/12/2023 12:26, MD Danish Anwar wrote:
>>>> Hi Roger,
>>>>
>>>> On 20/12/23 3:29 pm, Roger Quadros wrote:
>>>>> Hi,
>>>>>
>>>>> On 19/12/2023 12:11, MD Danish Anwar wrote:
>>>>>> Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used
>>>>>> in TI
>>>>>> AM654 SR2.0.
>>>>>>
>>>>>> The ICSSG PRU Sub-system runs on EMAC firmware. This series
>>>>>> Introduces
>>>>>> support for ICSSG driver in uboot. This series also adds the driver's
>>>>>> dependencies.
>>>>>>
>>>>>> The ICSSG2 node is added in device tree overlay so that it remains in
>>>>>> sync with linux kernel.
>>>>>>
>>>>>> The series introduces device tree and config changes and AM65x
>>>>>> to enable ICSSG driver. The series also enables
>>>>>> SPL_LOAD_FIT_APPLY_OVERLAY
>>>>>> for AM65x in order to load overlay over spl.
>>>>>>
>>>>>> This series has been tested on AM65x SR2.0, and the ICSSG
>>>>>> interface is
>>>>>> able to ping / dhcp and boot kernel using tftp in uboot.
>>>>>>
>>>>>> To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to
>>>>>> PRU RPROC
>>>>>> cores and RPROC cores need to be booted with the firmware. This
>>>>>> step is
>>>>>> done inside driver in kernel as kernel supports APIs like
>>>>>> rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't
>>>>>> have these
>>>>>> APIs, the same needs to be done via u-boot cmds.
>>>>>>
>>>>>> To make sure icssg-eth works we need to do below steps.
>>>>>>
>>>>>> 1. Initialize rproc cores i.e. rproc_init()
>>>>>> 2. Load $firmware_file from partition '1:2' (root) on device (mmc
>>>>>> in this
>>>>>>     example)
>>>>>> 3. Load the firmware file to rproc cores passing. i.e. rproc_load()
>>>>>>     taking rproc_id, loadaddr and file size as arguments.
>>>>>> 4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments
>>>>>>
>>>>>> The above steps are done by running the below commands at u-boot
>>>>>> prompt.
>>>>>>
>>>>>> => setenv start_icssg2 'rproc start 14; rproc start 15; rproc
>>>>>> start 16; rproc start 17; rproc start 18; rproc start 19'
>>>>>> => setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop
>>>>>> 16; rproc stop 17; rproc stop 18; rproc stop 19'
>>>>>> => setenv firmware_dir '/lib/firmware/ti-pruss'
>>>>>> => setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr}
>>>>>> ${firmware_dir}/${firmware_file}'
>>>>>>
>>>>>> => setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload
>>>>>> no; rproc init; setenv loadaddr 0x80000000; \
>>>>>>      setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run
>>>>>> get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>> am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15
>>>>>> 0x89000000 ${filesize}; \
>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>> am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>> 16 0x90000000 ${filesize}; \
>>>>>>      setenv loadaddr 0x80000000; setenv firmware_file
>>>>>> am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17
>>>>>> 0x80000000 ${filesize}; \
>>>>>>      setenv loadaddr 0x89000000; setenv firmware_file
>>>>>> am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18
>>>>>> 0x89000000 ${filesize}; \
>>>>>>      setenv loadaddr 0x90000000; setenv firmware_file
>>>>>> am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load
>>>>>> 19 0x90000000 ${filesize}; \
>>>>>>      run start_icssg2;'
>>>>>
>>>>> A whole bunch of commands are required to get ethernet functional.
>>>>> This is not at all user friendly and will be a maintenance nightmare.
>>>>> What worries me is tracking the 6 different rproc cores and the 6
>>>>> different firmware files to start 1 ethernet device.
>>>>> This will get even more interesting when we have to deal with
>>>>> different ICSSG instances on different boards.
>>>>>
>>>>> What is preventing the driver from starting the rproc cores it
>>>>> needs so user doesn't need to care about it?
>>>>> All the necessary information is in the Device tree. At least this
>>>>> is how it is done on Linux.
>>>>>
>>>>
>>>> I tried removing the need for these commands and implementing them
>>>> inside the driver only. I am able to load the firmware from driver
>>>> using
>>>> the fs_loader API request_firmware_into_buf(). It requires changes to
>>>> dt. A DT node called fs-loader needs to be added also CONFIG_FS_LOADER
>>>> needs to enabled. In the DT node we need to specify the storage media
>>>> that we are using i.e. mmc, ospi, usb. It's upto user to modify the
>>>> storage media, the driver will take the media from DT and try to laod
>>>> firmware from their.
>>>>
>>>> For loading firmwares to rproc cores, rproc_load() API is needed. Now
>>>> this API takes rproc_id, loadaddr and firmware_size as arguments.
>>>> loadaddr is fixed for all three pru cores. firmware_size is obtained
>>>> from request_firmware_into_buf() but I couldn't find a way to get the
>>>> rproc_id. For now based on the ICSSG instance and slice number I am
>>>> figuring out the rproc_id and passing it to rproc_load() and
>>>> rproc_start() APIs. Please let me know if you have any other / better
>>>> way of finding rproc_id.
>>>>
>>>> Below is the entire diff to remove these commands and move their
>>>> functionality to driver. Please have a look and let me know if this
>>>> is ok.
>>>>
>>>
>>> Good to see you got something working so quickly.
>>> It has some rough edges but nothing that is blocking.
>>>
>>>>
>>>> Save New Duplicate & Edit Just Text Twitter
>>>> diff --git a/arch/arm/dts/k3-am654-base-board.dts
>>>> b/arch/arm/dts/k3-am654-base-board.dts
>>>> index cfbcebfa37..c8da72e49c 100644
>>>> --- a/arch/arm/dts/k3-am654-base-board.dts
>>>> +++ b/arch/arm/dts/k3-am654-base-board.dts
>>>> @@ -16,6 +16,13 @@
>>>>       chosen {
>>>>           stdout-path = "serial2:115200n8";
>>>>           bootargs = "earlycon=ns16550a,mmio32,0x02800000";
>>>> +        firmware-loader = <&fs_loader0>;
>>>> +    };
>>>> +
>>>> +    fs_loader0: fs-loader {
>>>> +        bootph-all;
>>>> +        compatible = "u-boot,fs-loader";
>>>> +        phandlepart = <&sdhci1 2>;
>>>>       };
>>>
>>> This is has 2 issues
>>> 1) It will not be accepted in Kernel DT. Maybe it could be done in
>>> -u-boot.dtsi file.
>>
>> Sure. I'll move this to k3-am654-base-board-u-boot.dtsi
>>
>>> 2) You cannot assume boot medium is always sdhci1 2
>>>
>>
>> Yes. It's upto user to provide the boot medium and boot partition for
>> loading firmware. By default the firmware is loacated in root partion of
>> shdci1 on am65x so I am adding this as default. But user can easily
>> modify this to any other medium / partition needed.
>>
> 
> Users should not have to modify DT to pick a boot medium/partition.
> What would you do for complex cases or non block devices like eth/uart

In order to load firmware files from driver, we need to add the node for
fs-loader. The fs-loader has a phandlepart property which takes the boot
medium and the partition as input. Based on the medium and partition it
looks for the requested file and loads it to a given address. I am not
sure if there is any other way to load firmware from driver without
using the fs-loader.


> booting? This is one reason kernel moved firmware loading to
> userspace. The equivalant in U-Boot is the shell and scripts. Your
> original command based loading was the correct solution IMHO.

I intended to go ahead with command base approach only but as Roger
pointed out the command based approach is not very user friendly.

We need to align on what should be the correct approach for loading
firmware.

Roger, can you please chime in here.

> 
> If we want to try to hide some of that then we need a way to
> run a user provided script from the environement to handle
> the general cases for firmware loading.
> 
> Andrew
> 
>>>>
>>>>       memory@80000000 {
>>>> diff --git a/configs/am65x_evm_a53_defconfig
>>>> b/configs/am65x_evm_a53_defconfig
>>>> index 2755d7082f..c53e938abb 100644
>>>> --- a/configs/am65x_evm_a53_defconfig
>>>> +++ b/configs/am65x_evm_a53_defconfig
>>>> @@ -112,6 +112,7 @@ CONFIG_DM_I2C_GPIO=y
>>>>   CONFIG_SYS_I2C_OMAP24XX=y
>>>>   CONFIG_DM_MAILBOX=y
>>>>   CONFIG_K3_SEC_PROXY=y
>>>> +CONFIG_FS_LOADER=y
>>>>   CONFIG_SUPPORT_EMMC_BOOT=y
>>>>   CONFIG_MMC_IO_VOLTAGE=y
>>>>   CONFIG_MMC_UHS_SUPPORT=y
>>>> diff --git a/configs/am65x_evm_r5_defconfig
>>>> b/configs/am65x_evm_r5_defconfig
>>>> index b2f1e721b3..2d19935a41 100644
>>>> --- a/configs/am65x_evm_r5_defconfig
>>>> +++ b/configs/am65x_evm_r5_defconfig
>>>> @@ -98,6 +98,7 @@ CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
>>>>   CONFIG_SYS_I2C_OMAP24XX=y
>>>>   CONFIG_DM_MAILBOX=y
>>>>   CONFIG_K3_SEC_PROXY=y
>>>> +CONFIG_FS_LOADER=y
>>>>   CONFIG_K3_AVS0=y
>>>>   CONFIG_SUPPORT_EMMC_BOOT=y
>>>>   CONFIG_MMC_HS200_SUPPORT=y
>>>> diff --git a/drivers/net/ti/icssg_prueth.c
>>>> b/drivers/net/ti/icssg_prueth.c
>>>> index 40ad827e49..1c4edeb7b7 100644
>>>> --- a/drivers/net/ti/icssg_prueth.c
>>>> +++ b/drivers/net/ti/icssg_prueth.c
>>>> @@ -227,6 +227,10 @@ static int prueth_start(struct udevice *dev)
>>>>       void *config;
>>>>       int ret, i;
>>>>
>>>> +    ret = icssg_start_pru_cores(dev);
>>>> +    if (ret)
>>>> +        return ret;
>>>> +
>>>>       /* To differentiate channels for SLICE0 vs SLICE1 */
>>>>       snprintf(chn_name, sizeof(chn_name), "tx%d-0", priv->slice);
>>>>
>>>> @@ -355,9 +359,11 @@ static void prueth_stop(struct udevice *dev)
>>>>       phy_shutdown(priv->phydev);
>>>>
>>>>       dma_disable(&priv->dma_tx);
>>>> -    dma_free(&priv->dma_tx);
>>>> -
>>>>       dma_disable(&priv->dma_rx);
>>>> +
>>>> +    icssg_stop_pru_cores(dev);
>>>> +
>>>> +    dma_free(&priv->dma_tx);
>>>>       dma_free(&priv->dma_rx);
>>>>   }
>>>>
>>>> @@ -434,6 +440,181 @@ static const struct soc_attr
>>>> k3_mdio_soc_data[] = {
>>>>       { /* sentinel */ },
>>>>   };
>>>>
>>>> +struct icssg_firmware_load_address {
>>>> +    u32 pru;
>>>> +    u32 rtu;
>>>> +    u32 txpru;
>>>> +};
>>>> +
>>>> +struct icssg_firmwares {
>>>> +    char *pru;
>>>> +    char *rtu;
>>>> +    char *txpru;
>>>> +};
>>>> +
>>>> +static struct icssg_firmwares icssg_emac_firmwares[] = {
>>>> +    {
>>>> +        .pru = "/lib/firmware/ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
>>>> +        .rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
>>>> +        .txpru =
>>>> "/lib/firmware/ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
>>>> +    },
>>>> +    {
>>>> +        .pru = "/lib/firmware/ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
>>>> +        .rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
>>>> +        .txpru =
>>>> "/lib/firmware/ti-pruss/am65x-sr2-txpru1-prueth-fw.elf",
>>>> +    }
>>>> +};
>>>
>>> This information is contained in the DT.
>>>
>>>         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";
>>>
>>
>> Yes it is. But the linux driver uses the firmware strcuture inside
>> driver only. The firmware-name property is not being used. The firmware
>> names for all applicable SoCs (AM65x and AM64x) is same so instead of
>> reading it from DT, the driver hardcodes the firmware names in linux. I
>> think the thought here was to use firmware-name property from DT when
>> different firmwares are needed for different SoCs. I am just following
>> the same here in uboot as well.
>>
>>> You will need to introduce a rproc_set_firmware() API so clients can
>>> set their own firmware names.
>>>
>>
>> Sure. I will add an element 'fw_name' in struct dm_rproc_uclass_pdata
>> and set this fw_name to the firmware name requested by client using
>> rproc_set_firmware().
>>
>> The client drivers can call rproc_set_firmware(dev, firmware_name) to
>> set the firmware name.
>>
>>>> +
>>>> +int load_firmware(char *name_fw, u32 *loadaddr)
>>>> +{
>>>> +    struct udevice *fsdev;
>>>> +    int size = 0;
>>>> +
>>>> +    if (!IS_ENABLED(CONFIG_FS_LOADER))
>>>> +        return -EINVAL;
>>>> +
>>>> +    if (!*loadaddr)
>>>> +        return -EINVAL;
>>>> +
>>>> +    if (!get_fs_loader(&fsdev))
>>>> +        size = request_firmware_into_buf(fsdev, name_fw, (void
>>>> *)*loadaddr,
>>>> 40524, 0);
>>>> +
>>>> +    return size;
>>>> +}
>>>
>>> On Linux rproc_boot() does both loading the firmware and starting the
>>> rproc
>>> as that is farely generic.
>>> You should introduce rproc_boot() API so loading is taken care of at
>>> rproc driver.
>>> All you need to do is call rproc_set_firmware() before rproc_boot().
>>>
>>
>> Sure. I'll introduce rproc_boot() which will load the firmware to a
>> buffer and then load the firmware / buffer to rproc core usinig
>> rproc_load.
>>
>> For allocating memory for reading firmware we need to provide the size
>> of memory required as well. So rproc_boot will take two arguments.
>> 1. dev (rproc device)
>> 2. size (Maximum memory required to read firmware)
>>
>>>> +
>>>> +static int icssg_get_instance(struct udevice *dev)
>>>> +{
>>>> +    if (!strcmp(dev->name, "icssg2-eth"))
>>>> +        return 2;
>>>> +    else if (!strcmp(dev->name, "icssg1-eth"))
>>>> +        return 1;
>>>> +    else if (!strcmp(dev->name, "icssg0-eth"))
>>>> +        return 0;
>>>> +
>>>> +    dev_err(dev, "Invalid icssg instance\n");
>>>> +    return -EINVAL;
>>>> +}
>>>> +
>>>> +static int icssg_get_pru_core_number(struct udevice *dev, int slice)
>>>> +{
>>>> +    int instance, num_r5_cores;
>>>> +
>>>> +    instance = icssg_get_instance(dev);
>>>> +    if (instance < 0)
>>>> +        return instance;
>>>> +
>>>> +    if (IS_ENABLED(CONFIG_REMOTEPROC_TI_K3_R5F))
>>>> +        num_r5_cores = 2;
>>>> +
>>>> +    return num_r5_cores +
>>>> +           instance * PRU_TYPE_MAX * PRUETH_NUM_MACS +
>>>> +           slice * PRU_TYPE_MAX;
>>>
>>> All this doesn't look right. What we need is the rproc device
>>> that matches the PRU/RTU rprocs that we are interested in.
>>>
>>> The DT already has this information
>>>
>>>         ti,prus = <&pru2_0>, <&rtu2_0>, <&tx_pru2_0>,
>>>             <&pru2_1>, <&rtu2_1>, <&tx_pru2_1>;
>>>
>>>
>>> All the current rproc APIs use the below to get rproc device from ID
>>> ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev);
>>>
>>> You just need to introduce APIs that takes rproc device directly as
>>> argument.
>>>
>>> In your driver you can call uclass_get_device_by_phandle_id() to get the
>>> rproc device from the rproc phandle?
>>
>> Sure. I'll do that. Based on the icssg slice first I will get the
>> phandle for prus.
>>
>> Index will be 0,1,2 for slice 0 and 3,4,5 for slice 1.
>>
>> ofnode_read_u32_index(dev_ofnode(dev), "ti,prus", index, &phandle);
>>
>> Then for each phandle I can call uclass_get_device_by_phandle_id() and
>> get the rproc device.
>>
>>>
>>>
>>>> +}
>>>> +
>>>> +int icssg_start_pru_cores(struct udevice *dev)
>>>> +{
>>>> +    struct prueth *prueth = dev_get_priv(dev);
>>>> +    struct icssg_firmwares *firmwares;
>>>> +    u32 pru_fw_loadaddr = 0x80000000;
>>>> +    u32 rtu_fw_loadaddr = 0x89000000;
>>>> +    u32 txpru_fw_loadaddr = 0x90000000;
>>>
>>> Please avoid hardcoding. You can use malloc to get a temporary buffer
>>> area?
>>>
>>> Why do you need 3 different addresses?
>>> Once you do a rproc_load isn't the buffer already copied to rproc's
>>> memory
>>> so you can discard it or use it for the other rprocs?
>>>
>>
>> Sure I'll use malloc to get temporary buffer. Only thing is that to get
>> temporary buffer I will need to provide size as well.
>>
>> void *addr = malloc(fw_size);
>>
>> User needs to provide this fw_size to rproc_boot(). In my case the max
>> size the firmware can have is 64KB so I will be passing 64K as size to
>> rproc driver.
>>
>>>> +    int slice, ret, core_id;
>>>> +
>>>> +    firmwares = icssg_emac_firmwares;
>>>> +    slice = prueth->slice;
>>>> +
>>>> +    core_id = icssg_get_pru_core_number(dev, slice);
>>>> +    if (core_id < 0)
>>>> +        return core_id;
>>>> +
>>>> +    /* Initialize all rproc cores */
>>>> +    rproc_init();
>>>> +
>>>> +    /* Loading PRU firmware to PRU core */
>>>> +    ret = load_firmware(firmwares[slice].pru, &pru_fw_loadaddr);
>>>
>>> On Linux, loading the firmware is the responsibility of the rproc
>>> driver.
>>> Shouldn't it be the same in u-boot?
>>>
>>
>> Sure I'll move this to rproc driver.
>>
>>>> +
>>>> +    if (ret < 0) {
>>>> +        dev_err(dev, "Unable to load_firmware %s at addr 0x%x err
>>>> %d\n",
>>>> +            firmwares[slice].pru, pru_fw_loadaddr, ret);
>>>> +        return ret;
>>>> +    }
>>>> +
>>>> +    dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d
>>>> Bytes\n",
>>>> +        firmwares[slice].pru, pru_fw_loadaddr, ret);
>>>
>>> dev_dbg() here an at all dev_info().
>>>
>>>> +    rproc_load(core_id + PRU_TYPE_PRU, pru_fw_loadaddr, ret);
>>>> +
>>>> +    /* Loading RTU firmware to RTU core */
>>>> +    ret = load_firmware(firmwares[slice].rtu, &rtu_fw_loadaddr);
>>>> +
>>>> +    if (ret < 0) {
>>>> +        dev_err(dev, "Unable to load_firmware %s at addr 0x%x err
>>>> %d\n",
>>>> +            firmwares[slice].rtu, rtu_fw_loadaddr, ret);
>>>> +        return ret;
>>>> +    }
>>>> +
>>>> +    dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d
>>>> Bytes\n",
>>>> +        firmwares[slice].rtu, rtu_fw_loadaddr, ret);
>>>> +    rproc_load(core_id + PRU_TYPE_RTU, rtu_fw_loadaddr, ret);
>>>> +
>>>> +    /* Loading TX_PRU firmware to TX_PRU core */
>>>> +    ret = load_firmware(firmwares[slice].txpru, &txpru_fw_loadaddr);
>>>> +
>>>> +    if (ret < 0) {
>>>> +        dev_err(dev, "Unable to load_firmware %s at addr 0x%x err
>>>> %d\n",
>>>> +            firmwares[slice].txpru, txpru_fw_loadaddr, ret);
>>>> +        return ret;
>>>> +    }
>>>> +
>>>> +    dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d
>>>> Bytes\n",
>>>> +        firmwares[slice].txpru, txpru_fw_loadaddr, ret);
>>>> +    rproc_load(core_id + PRU_TYPE_TX_PRU, txpru_fw_loadaddr, ret);
>>>> +
>>>> +    ret = rproc_start(core_id + PRU_TYPE_PRU);
>>>> +    if (ret) {
>>>> +        dev_err(dev, "failed to start PRU%d: %d\n", slice, ret);
>>>> +        return ret;
>>>> +    }
>>>> +
>>>> +    ret = rproc_start(core_id + PRU_TYPE_RTU);
>>>> +    if (ret) {
>>>> +        dev_err(dev, "failed to start RTU%d: %d\n", slice, ret);
>>>> +        goto halt_pru;
>>>> +    }
>>>> +
>>>> +    ret = rproc_start(core_id + PRU_TYPE_TX_PRU);
>>>> +    if (ret) {
>>>> +        dev_err(dev, "failed to start TX_PRU%d: %d\n", slice, ret);
>>>> +        goto halt_rtu;
>>>> +    }
>>>> +
>>>> +    return 0;
>>>> +
>>>> +halt_rtu:
>>>> +    rproc_stop(core_id + PRU_TYPE_RTU);
>>>> +
>>>> +halt_pru:
>>>> +    rproc_stop(PRU_TYPE_PRU);
>>>> +    return ret;
>>>> +}
>>>> +
>>>> +int icssg_stop_pru_cores(struct udevice *dev)
>>>> +{
>>>> +    struct prueth *prueth = dev_get_priv(dev);
>>>> +    int slice, core_id;
>>>> +
>>>> +    slice = prueth->slice;
>>>> +
>>>> +    core_id = icssg_get_pru_core_number(dev, slice);
>>>> +    if (core_id < 0)
>>>> +        return core_id;
>>>> +
>>>> +    rproc_stop(core_id + PRU_TYPE_PRU);
>>>> +    rproc_stop(core_id + PRU_TYPE_RTU);
>>>> +    rproc_stop(core_id + PRU_TYPE_TX_PRU);
>>>> +
>>>> +    return 0;
>>>> +}
>>>> +
>>>>   static int prueth_probe(struct udevice *dev)
>>>>   {
>>>>       ofnode eth_ports_node, eth0_node, eth1_node, eth_node;
>>>> diff --git a/include/linux/pruss_driver.h
>>>> b/include/linux/pruss_driver.h
>>>> index 25272e850e..f17fe8bf58 100644
>>>> --- a/include/linux/pruss_driver.h
>>>> +++ b/include/linux/pruss_driver.h
>>>> @@ -114,6 +114,21 @@ enum pru_ctable_idx {
>>>>       PRU_C31,
>>>>   };
>>>>
>>>> +/**
>>>> + * 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
>>>>    */
>>>>
>>>> with this diff, user don't need to run any extra commands at u-boot.
>>>> Once u-boot prompt is reached, just running ping / dhcp will suffice.
>>>>
>>> Great!
>>>
>>> <snip>
>>>
>>
>> I have addressed all the above comments and made the changes needed.
>> below is the diff. Please have a look at it and let me know if it
>> looks OK.
>>
>> diff --git a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
>> b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
>> index 11d83927ac..0b2b72b2c5 100644
>> --- a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
>> +++ b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
>> @@ -6,6 +6,18 @@
>>   #include "k3-am654-r5-base-board-u-boot.dtsi"
>>   #include "k3-am65x-binman.dtsi"
>>
>> +/ {
>> +    chosen {
>> +        firmware-loader = <&fs_loader0>;
>> +    };
>> +
>> +    fs_loader0: fs-loader {
>> +        bootph-all;
>> +        compatible = "u-boot,fs-loader";
>> +        phandlepart = <&sdhci1 2>;
>> +    };
>> +};
>> +
>>   &pru0_0 {
>>       remoteproc-name = "pru0_0";
>>   };
>> diff --git a/configs/am65x_evm_a53_defconfig
>> b/configs/am65x_evm_a53_defconfig
>> index 2755d7082f..c53e938abb 100644
>> --- a/configs/am65x_evm_a53_defconfig
>> +++ b/configs/am65x_evm_a53_defconfig
>> @@ -112,6 +112,7 @@ CONFIG_DM_I2C_GPIO=y
>>   CONFIG_SYS_I2C_OMAP24XX=y
>>   CONFIG_DM_MAILBOX=y
>>   CONFIG_K3_SEC_PROXY=y
>> +CONFIG_FS_LOADER=y
>>   CONFIG_SUPPORT_EMMC_BOOT=y
>>   CONFIG_MMC_IO_VOLTAGE=y
>>   CONFIG_MMC_UHS_SUPPORT=y
>> diff --git a/configs/am65x_evm_r5_defconfig
>> b/configs/am65x_evm_r5_defconfig
>> index b2f1e721b3..2d19935a41 100644
>> --- a/configs/am65x_evm_r5_defconfig
>> +++ b/configs/am65x_evm_r5_defconfig
>> @@ -98,6 +98,7 @@ CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
>>   CONFIG_SYS_I2C_OMAP24XX=y
>>   CONFIG_DM_MAILBOX=y
>>   CONFIG_K3_SEC_PROXY=y
>> +CONFIG_FS_LOADER=y
>>   CONFIG_K3_AVS0=y
>>   CONFIG_SUPPORT_EMMC_BOOT=y
>>   CONFIG_MMC_HS200_SUPPORT=y
>> diff --git a/drivers/net/ti/icssg_prueth.c
>> b/drivers/net/ti/icssg_prueth.c
>> index 40ad827e49..a2e3595956 100644
>> --- a/drivers/net/ti/icssg_prueth.c
>> +++ b/drivers/net/ti/icssg_prueth.c
>> @@ -62,6 +62,9 @@
>>   /* Management packet type */
>>   #define PRUETH_PKT_TYPE_CMD        0x10
>>
>> +/* Number of PRU Cores per Slice */
>> +#define ICSSG_NUM_PRU_CORES        3
>> +
>>   static int icssg_phy_init(struct udevice *dev)
>>   {
>>       struct prueth *priv = dev_get_priv(dev);
>> @@ -218,6 +221,116 @@ static int icssg_update_link(struct prueth *priv)
>>       return phy->link;
>>   }
>>
>> +struct icssg_firmwares {
>> +    char *pru;
>> +    char *rtu;
>> +    char *txpru;
>> +};
>> +
>> +static struct icssg_firmwares icssg_emac_firmwares[] = {
>> +    {
>> +        .pru = "/lib/firmware/ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
>> +        .rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
>> +        .txpru =
>> "/lib/firmware/ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
>> +    },
>> +    {
>> +        .pru = "/lib/firmware/ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
>> +        .rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
>> +        .txpru =
>> "/lib/firmware/ti-pruss/am65x-sr2-txpru1-prueth-fw.elf",
>> +    }
>> +};
>> +
>> +static int icssg_start_pru_cores(struct udevice *dev)
>> +{
>> +    struct prueth *prueth = dev_get_priv(dev);
>> +    struct icssg_firmwares *firmwares;
>> +    struct udevice *rproc_dev = NULL;
>> +    int ret, slice;
>> +    u32 phandle;
>> +    u8 index;
>> +
>> +    slice = prueth->slice;
>> +    index = slice * ICSSG_NUM_PRU_CORES;
>> +    firmwares = icssg_emac_firmwares;
>> +
>> +    ofnode_read_u32_index(dev_ofnode(dev), "ti,prus", index, &phandle);
>> +    ret = uclass_get_device_by_phandle_id(UCLASS_REMOTEPROC, phandle,
>> &rproc_dev);
>> +    if (ret) {
>> +        dev_err(dev, "Unknown remote processor with phandle '0x%x'
>> requested(%d)\n",
>> +               phandle, ret);
>> +        return ret;
>> +    }
>> +
>> +    prueth->pru_core_id = dev_seq(rproc_dev);
>> +    ret = rproc_set_firmware(rproc_dev, firmwares[slice].pru);
>> +    if (ret)
>> +        return ret;
>> +
>> +    ret = rproc_boot(rproc_dev, SZ_64K);
>> +    if (ret) {
>> +        dev_err(dev, "failed to boot PRU%d: %d\n", slice, ret);
>> +        return -EINVAL;
>> +    }
>> +
>> +    ofnode_read_u32_index(dev_ofnode(dev), "ti,prus", index + 1,
>> &phandle);
>> +    ret = uclass_get_device_by_phandle_id(UCLASS_REMOTEPROC, phandle,
>> &rproc_dev);
>> +    if (ret) {
>> +        dev_err(dev, "Unknown remote processor with phandle '0x%x'
>> requested(%d)\n",
>> +               phandle, ret);
>> +        goto halt_pru;
>> +    }
>> +
>> +    prueth->rtu_core_id = dev_seq(rproc_dev);
>> +    ret = rproc_set_firmware(rproc_dev, firmwares[slice].rtu);
>> +    if (ret)
>> +        goto halt_pru;
>> +
>> +    ret = rproc_boot(rproc_dev, SZ_64K);
>> +    if (ret) {
>> +        dev_err(dev, "failed to boot RTU%d: %d\n", slice, ret);
>> +        goto halt_pru;
>> +    }
>> +
>> +    ofnode_read_u32_index(dev_ofnode(dev), "ti,prus", index + 2,
>> &phandle);
>> +    ret = uclass_get_device_by_phandle_id(UCLASS_REMOTEPROC, phandle,
>> &rproc_dev);
>> +    if (ret) {
>> +        dev_err(dev, "Unknown remote processor with phandle '0x%x'
>> requested(%d)\n",
>> +               phandle, ret);
>> +        goto halt_rtu;
>> +    }
>> +
>> +    prueth->txpru_core_id = dev_seq(rproc_dev);
>> +    ret = rproc_set_firmware(rproc_dev, firmwares[slice].txpru);
>> +    if (ret)
>> +        goto halt_rtu;
>> +
>> +    ret = rproc_boot(rproc_dev, SZ_64K);
>> +    if (ret) {
>> +        dev_err(dev, "failed to boot TXPRU%d: %d\n", slice, ret);
>> +        goto halt_rtu;
>> +    }
>> +
>> +    return 0;
>> +
>> +halt_rtu:
>> +    rproc_stop(prueth->rtu_core_id);
>> +
>> +halt_pru:
>> +    rproc_stop(prueth->pru_core_id);
>> +    return ret;
>> +}
>> +
>> +static int icssg_stop_pru_cores(struct udevice *dev)
>> +{
>> +    struct prueth *prueth = dev_get_priv(dev);
>> +
>> +    rproc_stop(prueth->pru_core_id);
>> +    rproc_stop(prueth->rtu_core_id);
>> +    rproc_stop(prueth->txpru_core_id);
>> +
>> +    return 0;
>> +}
>> +
>>   static int prueth_start(struct udevice *dev)
>>   {
>>       struct ti_udma_drv_chan_cfg_data *dma_rx_cfg_data;
>> @@ -227,6 +340,10 @@ static int prueth_start(struct udevice *dev)
>>       void *config;
>>       int ret, i;
>>
>> +    ret = icssg_start_pru_cores(dev);
>> +    if (ret)
>> +        return ret;
>> +
>>       /* To differentiate channels for SLICE0 vs SLICE1 */
>>       snprintf(chn_name, sizeof(chn_name), "tx%d-0", priv->slice);
>>
>> @@ -355,9 +472,11 @@ static void prueth_stop(struct udevice *dev)
>>       phy_shutdown(priv->phydev);
>>
>>       dma_disable(&priv->dma_tx);
>> -    dma_free(&priv->dma_tx);
>> -
>>       dma_disable(&priv->dma_rx);
>> +
>> +    icssg_stop_pru_cores(dev);
>> +
>> +    dma_free(&priv->dma_tx);
>>       dma_free(&priv->dma_rx);
>>   }
>>
>> diff --git a/drivers/net/ti/icssg_prueth.h
>> b/drivers/net/ti/icssg_prueth.h
>> index e41ed16a05..c92660401b 100644
>> --- a/drivers/net/ti/icssg_prueth.h
>> +++ b/drivers/net/ti/icssg_prueth.h
>> @@ -69,6 +69,9 @@ struct prueth {
>>       int            speed;
>>       int            duplex;
>>       u8            icssg_hwcmdseq;
>> +    u8             pru_core_id;
>> +    u8             rtu_core_id;
>> +    u8             txpru_core_id;
>>   };
>>
>>   /* config helpers */
>> diff --git a/drivers/remoteproc/rproc-uclass.c
>> b/drivers/remoteproc/rproc-uclass.c
>> index 28b362c887..a085c44eaa 100644
>> --- a/drivers/remoteproc/rproc-uclass.c
>> +++ b/drivers/remoteproc/rproc-uclass.c
>> @@ -13,6 +13,7 @@
>>   #include <log.h>
>>   #include <malloc.h>
>>   #include <virtio_ring.h>
>> +#include <fs_loader.h>
>>   #include <remoteproc.h>
>>   #include <asm/io.h>
>>   #include <dm/device-internal.h>
>> @@ -961,3 +962,90 @@ unsigned long rproc_parse_resource_table(struct
>> udevice *dev, struct rproc *cfg)
>>
>>       return 1;
>>   }
>> +
>> +int rproc_set_firmware(struct udevice *rproc_dev, const char *fw_name)
>> +{
>> +    struct dm_rproc_uclass_pdata *uc_pdata;
>> +    int len;
>> +    char *p;
>> +
>> +    if (!rproc_dev || !fw_name)
>> +        return -EINVAL;
>> +
>> +    uc_pdata = dev_get_uclass_plat(rproc_dev);
>> +
>> +    len = strcspn(fw_name, "\n");
>> +    if (!len) {
>> +        debug("can't provide empty string for firmware name\n");
>> +        return -EINVAL;
>> +    }
>> +
>> +    p = strndup(fw_name, len);
>> +    if (!p)
>> +        return -ENOMEM;
>> +
>> +    uc_pdata->fw_name = p;
>> +
>> +    return 0;
>> +}
>> +
>> +int rproc_boot(struct udevice *rproc_dev, size_t fw_size)
>> +{
>> +    struct dm_rproc_uclass_pdata *uc_pdata;
>> +    struct udevice *fs_loader;
>> +    void *addr = malloc(fw_size);
>> +    int core_id, ret = 0;
>> +    char *firmware;
>> +    ulong rproc_addr;
>> +
>> +    if (!rproc_dev)
>> +        return -EINVAL;
>> +
>> +    if (!addr)
>> +        return -ENOMEM;
>> +
>> +    uc_pdata = dev_get_uclass_plat(rproc_dev);
>> +    core_id = dev_seq(rproc_dev);
>> +    firmware = uc_pdata->fw_name;
>> +
>> +    if (!firmware) {
>> +        debug("No firmware set for rproc core %d\n", core_id);
>> +        return -EINVAL;
>> +    }
>> +
>> +    /* Initialize all rproc cores */
>> +    rproc_init();
>> +
>> +    /* Loading firmware to a given address */
>> +    ret = get_fs_loader(&fs_loader);
>> +    if (ret) {
>> +        debug("could not get fs loader: %d\n", ret);
>> +        return ret;
>> +    }
>> +
>> +    ret = request_firmware_into_buf(fs_loader, firmware, addr,
>> fw_size, 0);
>> +    if (ret < 0) {
>> +        debug("could not request %s: %d\n", firmware, ret);
>> +        return ret;
>> +    }
>> +
>> +    rproc_addr = (ulong)addr;
>> +
>> +    debug("Loaded %s to 0x%08lX size = %d Bytes\n",
>> +        uc_pdata->fw_name, rproc_addr, ret);
>> +
>> +    ret = rproc_load(core_id, rproc_addr, ret);
>> +    if (ret) {
>> +        debug("failed to load %s to rproc core %d from addr 0x%08lX
>> err %d\n",
>> +               uc_pdata->fw_name, core_id, rproc_addr, ret);
>> +        return ret;
>> +    }
>> +
>> +    ret = rproc_start(core_id);
>> +    if (ret) {
>> +        debug("failed to start rproc core %d\n", core_id);
>> +        return ret;
>> +    }
>> +
>> +    return ret;
>> +}
>> diff --git a/include/remoteproc.h b/include/remoteproc.h
>> index a11dc8a9b6..65b0ff7477 100644
>> --- a/include/remoteproc.h
>> +++ b/include/remoteproc.h
>> @@ -402,6 +402,7 @@ enum rproc_mem_type {
>>    * @name: Platform-specific way of naming the Remote proc
>>    * @mem_type: one of 'enum rproc_mem_type'
>>    * @driver_plat_data: driver specific platform data that may be needed.
>> + * @fw_name: firmware name
>>    *
>>    * This can be accessed with dev_get_uclass_plat() for any
>> UCLASS_REMOTEPROC
>>    * device.
>> @@ -411,6 +412,7 @@ struct dm_rproc_uclass_pdata {
>>       const char *name;
>>       enum rproc_mem_type mem_type;
>>       void *driver_plat_data;
>> +    char *fw_name;
>>   };
>>
>>   /**
>> @@ -704,6 +706,35 @@ unsigned long rproc_parse_resource_table(struct
>> udevice *dev,
>>   struct resource_table *rproc_find_resource_table(struct udevice *dev,
>>                            unsigned int addr,
>>                            int *tablesz);
>> +/**
>> + * rproc_set_firmware() - assign a new firmware
>> + * @rproc_dev: device for wich 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. The function does not trigger a remote processor boot,
>> + * only sets the firmware name used for a subsequent boot.
>> + *
>> + * This function sets the fw_name field in uclass pdata of the Remote
>> proc
>> + *
>> + * Return: 0 on success or a negative value upon failure
>> + */
>> +int rproc_set_firmware(struct udevice *rproc_dev, const char *fw_name);
>> +
>> +/**
>> + * rproc_boot() - boot a remote processor
>> + * @rproc_dev: rproc device to boot
>> + * @fw_size: Size of the memory to allocate for firmeware
>> + *
>> + * Boot a remote processor (i.e. load its firmware, power it on, ...).
>> + *
>> + * This function first loads the firmware set in the uclass pdata of
>> Remote
>> + * processor to a buffer and then loads firmware to the remote processor
>> + * using rproc_load().
>> + *
>> + * Return: 0 on success, and an appropriate error value otherwise
>> + */
>> +int rproc_boot(struct udevice *rproc_dev, size_t fw_size);
>>   #else
>>   static inline int rproc_init(void) { return -ENOSYS; }
>>   static inline int rproc_dev_init(int id) { return -ENOSYS; }
>> @@ -743,6 +774,10 @@ static inline int rproc_elf_load_rsc_table(struct
>> udevice *dev, ulong fw_addr,
>>                          ulong fw_size, ulong *rsc_addr,
>>                          ulong *rsc_size)
>>   { return -ENOSYS; }
>> +static inline int rproc_set_firmware(struct udevice *rproc_dev, const
>> char *fw_name)
>> +{ return -ENOSYS; }
>> +static inline int rproc_boot(struct udevice *rproc_dev, size_t fw_size)
>> +{ return -ENOSYS; }
>>   #endif
>>
>>   #endif    /* _RPROC_H_ */
>>
>>

-- 
Thanks and Regards,
Danish

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
  2023-12-27  6:56       ` MD Danish Anwar
@ 2024-01-02 13:56         ` Andrew Davis
  2024-01-03 10:27           ` MD Danish Anwar
  0 siblings, 1 reply; 48+ messages in thread
From: Andrew Davis @ 2024-01-02 13:56 UTC (permalink / raw)
  To: MD Danish Anwar, Roger Quadros, Maxime Ripard,
	Siddharth Vadapalli, Nishanth Menon, Vignesh Raghavendra,
	Matthias Schiffer, Kamlesh Gurudasani, Manorit Chawdhry,
	Neha Malcom Francis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran

On 12/27/23 12:56 AM, MD Danish Anwar wrote:
> 
> 
> On 22/12/23 6:13 pm, Roger Quadros wrote:
>>
>> On 22/12/2023 12:26, MD Danish Anwar wrote:
>>> Hi Roger,
>>>
>>> On 20/12/23 3:29 pm, Roger Quadros wrote:
>>>> Hi,
>>>>
>>>> On 19/12/2023 12:11, MD Danish Anwar wrote:
>>>>> Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used in TI
>>>>> AM654 SR2.0.
>>>>>
>>>>> The ICSSG PRU Sub-system runs on EMAC firmware. This series Introduces
>>>>> support for ICSSG driver in uboot. This series also adds the driver's
>>>>> dependencies.
>>>>>
>>>>> The ICSSG2 node is added in device tree overlay so that it remains in
>>>>> sync with linux kernel.
>>>>>
>>>>> The series introduces device tree and config changes and AM65x
>>>>> to enable ICSSG driver. The series also enables SPL_LOAD_FIT_APPLY_OVERLAY
>>>>> for AM65x in order to load overlay over spl.
>>>>>
>>>>> This series has been tested on AM65x SR2.0, and the ICSSG interface is
>>>>> able to ping / dhcp and boot kernel using tftp in uboot.
>>>>>
>>>>> To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to PRU RPROC
>>>>> cores and RPROC cores need to be booted with the firmware. This step is
>>>>> done inside driver in kernel as kernel supports APIs like
>>>>> rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't have these
>>>>> APIs, the same needs to be done via u-boot cmds.
>>>>>
>>>>> To make sure icssg-eth works we need to do below steps.
>>>>>
>>>>> 1. Initialize rproc cores i.e. rproc_init()
>>>>> 2. Load $firmware_file from partition '1:2' (root) on device (mmc in this
>>>>>     example)
>>>>> 3. Load the firmware file to rproc cores passing. i.e. rproc_load()
>>>>>     taking rproc_id, loadaddr and file size as arguments.
>>>>> 4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments
>>>>>
>>>>> The above steps are done by running the below commands at u-boot prompt.
>>>>>
>>>>> => setenv start_icssg2 'rproc start 14; rproc start 15; rproc start 16; rproc start 17; rproc start 18; rproc start 19'
>>>>> => setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop 16; rproc stop 17; rproc stop 18; rproc stop 19'
>>>>> => setenv firmware_dir '/lib/firmware/ti-pruss'
>>>>> => setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr} ${firmware_dir}/${firmware_file}'
>>>>>
>>>>> => setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload no; rproc init; setenv loadaddr 0x80000000; \
>>>>>      setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
>>>>>      setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15 0x89000000 ${filesize}; \
>>>>>      setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load 16 0x90000000 ${filesize}; \
>>>>>      setenv loadaddr 0x80000000; setenv firmware_file am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17 0x80000000 ${filesize}; \
>>>>>      setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18 0x89000000 ${filesize}; \
>>>>>      setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load 19 0x90000000 ${filesize}; \
>>>>>      run start_icssg2;'
>>>>
>>>> A whole bunch of commands are required to get ethernet functional.
>>>> This is not at all user friendly and will be a maintenance nightmare.
>>>> What worries me is tracking the 6 different rproc cores and the 6 different firmware files to start 1 ethernet device.
>>>> This will get even more interesting when we have to deal with different ICSSG instances on different boards.
>>>>
>>>> What is preventing the driver from starting the rproc cores it needs so user doesn't need to care about it?
>>>> All the necessary information is in the Device tree. At least this is how it is done on Linux.
>>>>
>>>
>>> I tried removing the need for these commands and implementing them
>>> inside the driver only. I am able to load the firmware from driver using
>>> the fs_loader API request_firmware_into_buf(). It requires changes to
>>> dt. A DT node called fs-loader needs to be added also CONFIG_FS_LOADER
>>> needs to enabled. In the DT node we need to specify the storage media
>>> that we are using i.e. mmc, ospi, usb. It's upto user to modify the
>>> storage media, the driver will take the media from DT and try to laod
>>> firmware from their.
>>>
>>> For loading firmwares to rproc cores, rproc_load() API is needed. Now
>>> this API takes rproc_id, loadaddr and firmware_size as arguments.
>>> loadaddr is fixed for all three pru cores. firmware_size is obtained
>>> from request_firmware_into_buf() but I couldn't find a way to get the
>>> rproc_id. For now based on the ICSSG instance and slice number I am
>>> figuring out the rproc_id and passing it to rproc_load() and
>>> rproc_start() APIs. Please let me know if you have any other / better
>>> way of finding rproc_id.
>>>
>>> Below is the entire diff to remove these commands and move their
>>> functionality to driver. Please have a look and let me know if this is ok.
>>>
>>
>> Good to see you got something working so quickly.
>> It has some rough edges but nothing that is blocking.
>>
>>>
>>> Save New Duplicate & Edit Just Text Twitter
>>> diff --git a/arch/arm/dts/k3-am654-base-board.dts
>>> b/arch/arm/dts/k3-am654-base-board.dts
>>> index cfbcebfa37..c8da72e49c 100644
>>> --- a/arch/arm/dts/k3-am654-base-board.dts
>>> +++ b/arch/arm/dts/k3-am654-base-board.dts
>>> @@ -16,6 +16,13 @@
>>>   	chosen {
>>>   		stdout-path = "serial2:115200n8";
>>>   		bootargs = "earlycon=ns16550a,mmio32,0x02800000";
>>> +		firmware-loader = <&fs_loader0>;
>>> +	};
>>> +
>>> +	fs_loader0: fs-loader {
>>> +		bootph-all;
>>> +		compatible = "u-boot,fs-loader";
>>> +		phandlepart = <&sdhci1 2>;
>>>   	};
>>
>> This is has 2 issues
>> 1) It will not be accepted in Kernel DT. Maybe it could be done in -u-boot.dtsi file.
> 
> Sure. I'll move this to k3-am654-base-board-u-boot.dtsi
> 
>> 2) You cannot assume boot medium is always sdhci1 2
>>
> 
> Yes. It's upto user to provide the boot medium and boot partition for
> loading firmware. By default the firmware is loacated in root partion of
> shdci1 on am65x so I am adding this as default. But user can easily
> modify this to any other medium / partition needed.
> 

Users should not have to modify DT to pick a boot medium/partition.
What would you do for complex cases or non block devices like eth/uart
booting? This is one reason kernel moved firmware loading to
userspace. The equivalant in U-Boot is the shell and scripts. Your
original command based loading was the correct solution IMHO.

If we want to try to hide some of that then we need a way to
run a user provided script from the environement to handle
the general cases for firmware loading.

Andrew

>>>
>>>   	memory@80000000 {
>>> diff --git a/configs/am65x_evm_a53_defconfig
>>> b/configs/am65x_evm_a53_defconfig
>>> index 2755d7082f..c53e938abb 100644
>>> --- a/configs/am65x_evm_a53_defconfig
>>> +++ b/configs/am65x_evm_a53_defconfig
>>> @@ -112,6 +112,7 @@ CONFIG_DM_I2C_GPIO=y
>>>   CONFIG_SYS_I2C_OMAP24XX=y
>>>   CONFIG_DM_MAILBOX=y
>>>   CONFIG_K3_SEC_PROXY=y
>>> +CONFIG_FS_LOADER=y
>>>   CONFIG_SUPPORT_EMMC_BOOT=y
>>>   CONFIG_MMC_IO_VOLTAGE=y
>>>   CONFIG_MMC_UHS_SUPPORT=y
>>> diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig
>>> index b2f1e721b3..2d19935a41 100644
>>> --- a/configs/am65x_evm_r5_defconfig
>>> +++ b/configs/am65x_evm_r5_defconfig
>>> @@ -98,6 +98,7 @@ CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
>>>   CONFIG_SYS_I2C_OMAP24XX=y
>>>   CONFIG_DM_MAILBOX=y
>>>   CONFIG_K3_SEC_PROXY=y
>>> +CONFIG_FS_LOADER=y
>>>   CONFIG_K3_AVS0=y
>>>   CONFIG_SUPPORT_EMMC_BOOT=y
>>>   CONFIG_MMC_HS200_SUPPORT=y
>>> diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
>>> index 40ad827e49..1c4edeb7b7 100644
>>> --- a/drivers/net/ti/icssg_prueth.c
>>> +++ b/drivers/net/ti/icssg_prueth.c
>>> @@ -227,6 +227,10 @@ static int prueth_start(struct udevice *dev)
>>>   	void *config;
>>>   	int ret, i;
>>>
>>> +	ret = icssg_start_pru_cores(dev);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>>   	/* To differentiate channels for SLICE0 vs SLICE1 */
>>>   	snprintf(chn_name, sizeof(chn_name), "tx%d-0", priv->slice);
>>>
>>> @@ -355,9 +359,11 @@ static void prueth_stop(struct udevice *dev)
>>>   	phy_shutdown(priv->phydev);
>>>
>>>   	dma_disable(&priv->dma_tx);
>>> -	dma_free(&priv->dma_tx);
>>> -
>>>   	dma_disable(&priv->dma_rx);
>>> +
>>> +	icssg_stop_pru_cores(dev);
>>> +
>>> +	dma_free(&priv->dma_tx);
>>>   	dma_free(&priv->dma_rx);
>>>   }
>>>
>>> @@ -434,6 +440,181 @@ static const struct soc_attr k3_mdio_soc_data[] = {
>>>   	{ /* sentinel */ },
>>>   };
>>>
>>> +struct icssg_firmware_load_address {
>>> +	u32 pru;
>>> +	u32 rtu;
>>> +	u32 txpru;
>>> +};
>>> +
>>> +struct icssg_firmwares {
>>> +	char *pru;
>>> +	char *rtu;
>>> +	char *txpru;
>>> +};
>>> +
>>> +static struct icssg_firmwares icssg_emac_firmwares[] = {
>>> +	{
>>> +		.pru = "/lib/firmware/ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
>>> +		.rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
>>> +		.txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
>>> +	},
>>> +	{
>>> +		.pru = "/lib/firmware/ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
>>> +		.rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
>>> +		.txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru1-prueth-fw.elf",
>>> +	}
>>> +};
>>
>> This information is contained in the DT.
>>
>> 		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";
>>
> 
> Yes it is. But the linux driver uses the firmware strcuture inside
> driver only. The firmware-name property is not being used. The firmware
> names for all applicable SoCs (AM65x and AM64x) is same so instead of
> reading it from DT, the driver hardcodes the firmware names in linux. I
> think the thought here was to use firmware-name property from DT when
> different firmwares are needed for different SoCs. I am just following
> the same here in uboot as well.
> 
>> You will need to introduce a rproc_set_firmware() API so clients can
>> set their own firmware names.
>>
> 
> Sure. I will add an element 'fw_name' in struct dm_rproc_uclass_pdata
> and set this fw_name to the firmware name requested by client using
> rproc_set_firmware().
> 
> The client drivers can call rproc_set_firmware(dev, firmware_name) to
> set the firmware name.
> 
>>> +
>>> +int load_firmware(char *name_fw, u32 *loadaddr)
>>> +{
>>> +	struct udevice *fsdev;
>>> +	int size = 0;
>>> +
>>> +	if (!IS_ENABLED(CONFIG_FS_LOADER))
>>> +		return -EINVAL;
>>> +
>>> +	if (!*loadaddr)
>>> +		return -EINVAL;
>>> +
>>> +	if (!get_fs_loader(&fsdev))
>>> +		size = request_firmware_into_buf(fsdev, name_fw, (void *)*loadaddr,
>>> 40524, 0);
>>> +
>>> +	return size;
>>> +}
>>
>> On Linux rproc_boot() does both loading the firmware and starting the rproc
>> as that is farely generic.
>> You should introduce rproc_boot() API so loading is taken care of at rproc driver.
>> All you need to do is call rproc_set_firmware() before rproc_boot().
>>
> 
> Sure. I'll introduce rproc_boot() which will load the firmware to a
> buffer and then load the firmware / buffer to rproc core usinig rproc_load.
> 
> For allocating memory for reading firmware we need to provide the size
> of memory required as well. So rproc_boot will take two arguments.
> 1. dev (rproc device)
> 2. size (Maximum memory required to read firmware)
> 
>>> +
>>> +static int icssg_get_instance(struct udevice *dev)
>>> +{
>>> +	if (!strcmp(dev->name, "icssg2-eth"))
>>> +		return 2;
>>> +	else if (!strcmp(dev->name, "icssg1-eth"))
>>> +		return 1;
>>> +	else if (!strcmp(dev->name, "icssg0-eth"))
>>> +		return 0;
>>> +
>>> +	dev_err(dev, "Invalid icssg instance\n");
>>> +	return -EINVAL;
>>> +}
>>> +
>>> +static int icssg_get_pru_core_number(struct udevice *dev, int slice)
>>> +{
>>> +	int instance, num_r5_cores;
>>> +
>>> +	instance = icssg_get_instance(dev);
>>> +	if (instance < 0)
>>> +		return instance;
>>> +
>>> +	if (IS_ENABLED(CONFIG_REMOTEPROC_TI_K3_R5F))
>>> +		num_r5_cores = 2;
>>> +
>>> +	return num_r5_cores +
>>> +	       instance * PRU_TYPE_MAX * PRUETH_NUM_MACS +
>>> +	       slice * PRU_TYPE_MAX;
>>
>> All this doesn't look right. What we need is the rproc device
>> that matches the PRU/RTU rprocs that we are interested in.
>>
>> The DT already has this information
>>
>> 		ti,prus = <&pru2_0>, <&rtu2_0>, <&tx_pru2_0>,
>> 			<&pru2_1>, <&rtu2_1>, <&tx_pru2_1>;
>>
>>
>> All the current rproc APIs use the below to get rproc device from ID
>> ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev);
>>
>> You just need to introduce APIs that takes rproc device directly as argument.
>>
>> In your driver you can call uclass_get_device_by_phandle_id() to get the
>> rproc device from the rproc phandle?
> 
> Sure. I'll do that. Based on the icssg slice first I will get the
> phandle for prus.
> 
> Index will be 0,1,2 for slice 0 and 3,4,5 for slice 1.
> 
> ofnode_read_u32_index(dev_ofnode(dev), "ti,prus", index, &phandle);
> 
> Then for each phandle I can call uclass_get_device_by_phandle_id() and
> get the rproc device.
> 
>>
>>
>>> +}
>>> +
>>> +int icssg_start_pru_cores(struct udevice *dev)
>>> +{
>>> +	struct prueth *prueth = dev_get_priv(dev);
>>> +	struct icssg_firmwares *firmwares;
>>> +	u32 pru_fw_loadaddr = 0x80000000;
>>> +	u32 rtu_fw_loadaddr = 0x89000000;
>>> +	u32 txpru_fw_loadaddr = 0x90000000;
>>
>> Please avoid hardcoding. You can use malloc to get a temporary buffer area?
>>
>> Why do you need 3 different addresses?
>> Once you do a rproc_load isn't the buffer already copied to rproc's memory
>> so you can discard it or use it for the other rprocs?
>>
> 
> Sure I'll use malloc to get temporary buffer. Only thing is that to get
> temporary buffer I will need to provide size as well.
> 
> void *addr = malloc(fw_size);
> 
> User needs to provide this fw_size to rproc_boot(). In my case the max
> size the firmware can have is 64KB so I will be passing 64K as size to
> rproc driver.
> 
>>> +	int slice, ret, core_id;
>>> +
>>> +	firmwares = icssg_emac_firmwares;
>>> +	slice = prueth->slice;
>>> +
>>> +	core_id = icssg_get_pru_core_number(dev, slice);
>>> +	if (core_id < 0)
>>> +		return core_id;
>>> +
>>> +	/* Initialize all rproc cores */
>>> +	rproc_init();
>>> +
>>> +	/* Loading PRU firmware to PRU core */
>>> +	ret = load_firmware(firmwares[slice].pru, &pru_fw_loadaddr);
>>
>> On Linux, loading the firmware is the responsibility of the rproc driver.
>> Shouldn't it be the same in u-boot?
>>
> 
> Sure I'll move this to rproc driver.
> 
>>> +
>>> +	if (ret < 0) {
>>> +		dev_err(dev, "Unable to load_firmware %s at addr 0x%x err %d\n",
>>> +			firmwares[slice].pru, pru_fw_loadaddr, ret);
>>> +		return ret;
>>> +	}
>>> +
>>> +	dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d Bytes\n",
>>> +		firmwares[slice].pru, pru_fw_loadaddr, ret);
>>
>> dev_dbg() here an at all dev_info().
>>
>>> +	rproc_load(core_id + PRU_TYPE_PRU, pru_fw_loadaddr, ret);
>>> +
>>> +	/* Loading RTU firmware to RTU core */
>>> +	ret = load_firmware(firmwares[slice].rtu, &rtu_fw_loadaddr);
>>> +
>>> +	if (ret < 0) {
>>> +		dev_err(dev, "Unable to load_firmware %s at addr 0x%x err %d\n",
>>> +			firmwares[slice].rtu, rtu_fw_loadaddr, ret);
>>> +		return ret;
>>> +	}
>>> +
>>> +	dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d Bytes\n",
>>> +		firmwares[slice].rtu, rtu_fw_loadaddr, ret);
>>> +	rproc_load(core_id + PRU_TYPE_RTU, rtu_fw_loadaddr, ret);
>>> +
>>> +	/* Loading TX_PRU firmware to TX_PRU core */
>>> +	ret = load_firmware(firmwares[slice].txpru, &txpru_fw_loadaddr);
>>> +
>>> +	if (ret < 0) {
>>> +		dev_err(dev, "Unable to load_firmware %s at addr 0x%x err %d\n",
>>> +			firmwares[slice].txpru, txpru_fw_loadaddr, ret);
>>> +		return ret;
>>> +	}
>>> +
>>> +	dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d Bytes\n",
>>> +		firmwares[slice].txpru, txpru_fw_loadaddr, ret);
>>> +	rproc_load(core_id + PRU_TYPE_TX_PRU, txpru_fw_loadaddr, ret);
>>> +
>>> +	ret = rproc_start(core_id + PRU_TYPE_PRU);
>>> +	if (ret) {
>>> +		dev_err(dev, "failed to start PRU%d: %d\n", slice, ret);
>>> +		return ret;
>>> +	}
>>> +
>>> +	ret = rproc_start(core_id + PRU_TYPE_RTU);
>>> +	if (ret) {
>>> +		dev_err(dev, "failed to start RTU%d: %d\n", slice, ret);
>>> +		goto halt_pru;
>>> +	}
>>> +
>>> +	ret = rproc_start(core_id + PRU_TYPE_TX_PRU);
>>> +	if (ret) {
>>> +		dev_err(dev, "failed to start TX_PRU%d: %d\n", slice, ret);
>>> +		goto halt_rtu;
>>> +	}
>>> +
>>> +	return 0;
>>> +
>>> +halt_rtu:
>>> +	rproc_stop(core_id + PRU_TYPE_RTU);
>>> +
>>> +halt_pru:
>>> +	rproc_stop(PRU_TYPE_PRU);
>>> +	return ret;
>>> +}
>>> +
>>> +int icssg_stop_pru_cores(struct udevice *dev)
>>> +{
>>> +	struct prueth *prueth = dev_get_priv(dev);
>>> +	int slice, core_id;
>>> +
>>> +	slice = prueth->slice;
>>> +
>>> +	core_id = icssg_get_pru_core_number(dev, slice);
>>> +	if (core_id < 0)
>>> +		return core_id;
>>> +
>>> +	rproc_stop(core_id + PRU_TYPE_PRU);
>>> +	rproc_stop(core_id + PRU_TYPE_RTU);
>>> +	rproc_stop(core_id + PRU_TYPE_TX_PRU);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>>   static int prueth_probe(struct udevice *dev)
>>>   {
>>>   	ofnode eth_ports_node, eth0_node, eth1_node, eth_node;
>>> diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h
>>> index 25272e850e..f17fe8bf58 100644
>>> --- a/include/linux/pruss_driver.h
>>> +++ b/include/linux/pruss_driver.h
>>> @@ -114,6 +114,21 @@ enum pru_ctable_idx {
>>>   	PRU_C31,
>>>   };
>>>
>>> +/**
>>> + * 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
>>>    */
>>>
>>> with this diff, user don't need to run any extra commands at u-boot.
>>> Once u-boot prompt is reached, just running ping / dhcp will suffice.
>>>
>> Great!
>>
>> <snip>
>>
> 
> I have addressed all the above comments and made the changes needed.
> below is the diff. Please have a look at it and let me know if it looks OK.
> 
> diff --git a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
> b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
> index 11d83927ac..0b2b72b2c5 100644
> --- a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
> +++ b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
> @@ -6,6 +6,18 @@
>   #include "k3-am654-r5-base-board-u-boot.dtsi"
>   #include "k3-am65x-binman.dtsi"
> 
> +/ {
> +	chosen {
> +		firmware-loader = <&fs_loader0>;
> +	};
> +
> +	fs_loader0: fs-loader {
> +		bootph-all;
> +		compatible = "u-boot,fs-loader";
> +		phandlepart = <&sdhci1 2>;
> +	};
> +};
> +
>   &pru0_0 {
>   	remoteproc-name = "pru0_0";
>   };
> diff --git a/configs/am65x_evm_a53_defconfig
> b/configs/am65x_evm_a53_defconfig
> index 2755d7082f..c53e938abb 100644
> --- a/configs/am65x_evm_a53_defconfig
> +++ b/configs/am65x_evm_a53_defconfig
> @@ -112,6 +112,7 @@ CONFIG_DM_I2C_GPIO=y
>   CONFIG_SYS_I2C_OMAP24XX=y
>   CONFIG_DM_MAILBOX=y
>   CONFIG_K3_SEC_PROXY=y
> +CONFIG_FS_LOADER=y
>   CONFIG_SUPPORT_EMMC_BOOT=y
>   CONFIG_MMC_IO_VOLTAGE=y
>   CONFIG_MMC_UHS_SUPPORT=y
> diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig
> index b2f1e721b3..2d19935a41 100644
> --- a/configs/am65x_evm_r5_defconfig
> +++ b/configs/am65x_evm_r5_defconfig
> @@ -98,6 +98,7 @@ CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
>   CONFIG_SYS_I2C_OMAP24XX=y
>   CONFIG_DM_MAILBOX=y
>   CONFIG_K3_SEC_PROXY=y
> +CONFIG_FS_LOADER=y
>   CONFIG_K3_AVS0=y
>   CONFIG_SUPPORT_EMMC_BOOT=y
>   CONFIG_MMC_HS200_SUPPORT=y
> diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
> index 40ad827e49..a2e3595956 100644
> --- a/drivers/net/ti/icssg_prueth.c
> +++ b/drivers/net/ti/icssg_prueth.c
> @@ -62,6 +62,9 @@
>   /* Management packet type */
>   #define PRUETH_PKT_TYPE_CMD		0x10
> 
> +/* Number of PRU Cores per Slice */
> +#define ICSSG_NUM_PRU_CORES		3
> +
>   static int icssg_phy_init(struct udevice *dev)
>   {
>   	struct prueth *priv = dev_get_priv(dev);
> @@ -218,6 +221,116 @@ static int icssg_update_link(struct prueth *priv)
>   	return phy->link;
>   }
> 
> +struct icssg_firmwares {
> +	char *pru;
> +	char *rtu;
> +	char *txpru;
> +};
> +
> +static struct icssg_firmwares icssg_emac_firmwares[] = {
> +	{
> +		.pru = "/lib/firmware/ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
> +		.rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
> +		.txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
> +	},
> +	{
> +		.pru = "/lib/firmware/ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
> +		.rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
> +		.txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru1-prueth-fw.elf",
> +	}
> +};
> +
> +static int icssg_start_pru_cores(struct udevice *dev)
> +{
> +	struct prueth *prueth = dev_get_priv(dev);
> +	struct icssg_firmwares *firmwares;
> +	struct udevice *rproc_dev = NULL;
> +	int ret, slice;
> +	u32 phandle;
> +	u8 index;
> +
> +	slice = prueth->slice;
> +	index = slice * ICSSG_NUM_PRU_CORES;
> +	firmwares = icssg_emac_firmwares;
> +
> +	ofnode_read_u32_index(dev_ofnode(dev), "ti,prus", index, &phandle);
> +	ret = uclass_get_device_by_phandle_id(UCLASS_REMOTEPROC, phandle,
> &rproc_dev);
> +	if (ret) {
> +		dev_err(dev, "Unknown remote processor with phandle '0x%x'
> requested(%d)\n",
> +		       phandle, ret);
> +		return ret;
> +	}
> +
> +	prueth->pru_core_id = dev_seq(rproc_dev);
> +	ret = rproc_set_firmware(rproc_dev, firmwares[slice].pru);
> +	if (ret)
> +		return ret;
> +
> +	ret = rproc_boot(rproc_dev, SZ_64K);
> +	if (ret) {
> +		dev_err(dev, "failed to boot PRU%d: %d\n", slice, ret);
> +		return -EINVAL;
> +	}
> +
> +	ofnode_read_u32_index(dev_ofnode(dev), "ti,prus", index + 1, &phandle);
> +	ret = uclass_get_device_by_phandle_id(UCLASS_REMOTEPROC, phandle,
> &rproc_dev);
> +	if (ret) {
> +		dev_err(dev, "Unknown remote processor with phandle '0x%x'
> requested(%d)\n",
> +		       phandle, ret);
> +		goto halt_pru;
> +	}
> +
> +	prueth->rtu_core_id = dev_seq(rproc_dev);
> +	ret = rproc_set_firmware(rproc_dev, firmwares[slice].rtu);
> +	if (ret)
> +		goto halt_pru;
> +
> +	ret = rproc_boot(rproc_dev, SZ_64K);
> +	if (ret) {
> +		dev_err(dev, "failed to boot RTU%d: %d\n", slice, ret);
> +		goto halt_pru;
> +	}
> +
> +	ofnode_read_u32_index(dev_ofnode(dev), "ti,prus", index + 2, &phandle);
> +	ret = uclass_get_device_by_phandle_id(UCLASS_REMOTEPROC, phandle,
> &rproc_dev);
> +	if (ret) {
> +		dev_err(dev, "Unknown remote processor with phandle '0x%x'
> requested(%d)\n",
> +		       phandle, ret);
> +		goto halt_rtu;
> +	}
> +
> +	prueth->txpru_core_id = dev_seq(rproc_dev);
> +	ret = rproc_set_firmware(rproc_dev, firmwares[slice].txpru);
> +	if (ret)
> +		goto halt_rtu;
> +
> +	ret = rproc_boot(rproc_dev, SZ_64K);
> +	if (ret) {
> +		dev_err(dev, "failed to boot TXPRU%d: %d\n", slice, ret);
> +		goto halt_rtu;
> +	}
> +
> +	return 0;
> +
> +halt_rtu:
> +	rproc_stop(prueth->rtu_core_id);
> +
> +halt_pru:
> +	rproc_stop(prueth->pru_core_id);
> +	return ret;
> +}
> +
> +static int icssg_stop_pru_cores(struct udevice *dev)
> +{
> +	struct prueth *prueth = dev_get_priv(dev);
> +
> +	rproc_stop(prueth->pru_core_id);
> +	rproc_stop(prueth->rtu_core_id);
> +	rproc_stop(prueth->txpru_core_id);
> +
> +	return 0;
> +}
> +
>   static int prueth_start(struct udevice *dev)
>   {
>   	struct ti_udma_drv_chan_cfg_data *dma_rx_cfg_data;
> @@ -227,6 +340,10 @@ static int prueth_start(struct udevice *dev)
>   	void *config;
>   	int ret, i;
> 
> +	ret = icssg_start_pru_cores(dev);
> +	if (ret)
> +		return ret;
> +
>   	/* To differentiate channels for SLICE0 vs SLICE1 */
>   	snprintf(chn_name, sizeof(chn_name), "tx%d-0", priv->slice);
> 
> @@ -355,9 +472,11 @@ static void prueth_stop(struct udevice *dev)
>   	phy_shutdown(priv->phydev);
> 
>   	dma_disable(&priv->dma_tx);
> -	dma_free(&priv->dma_tx);
> -
>   	dma_disable(&priv->dma_rx);
> +
> +	icssg_stop_pru_cores(dev);
> +
> +	dma_free(&priv->dma_tx);
>   	dma_free(&priv->dma_rx);
>   }
> 
> diff --git a/drivers/net/ti/icssg_prueth.h b/drivers/net/ti/icssg_prueth.h
> index e41ed16a05..c92660401b 100644
> --- a/drivers/net/ti/icssg_prueth.h
> +++ b/drivers/net/ti/icssg_prueth.h
> @@ -69,6 +69,9 @@ struct prueth {
>   	int			speed;
>   	int			duplex;
>   	u8			icssg_hwcmdseq;
> +	u8 			pru_core_id;
> +	u8 			rtu_core_id;
> +	u8 			txpru_core_id;
>   };
> 
>   /* config helpers */
> diff --git a/drivers/remoteproc/rproc-uclass.c
> b/drivers/remoteproc/rproc-uclass.c
> index 28b362c887..a085c44eaa 100644
> --- a/drivers/remoteproc/rproc-uclass.c
> +++ b/drivers/remoteproc/rproc-uclass.c
> @@ -13,6 +13,7 @@
>   #include <log.h>
>   #include <malloc.h>
>   #include <virtio_ring.h>
> +#include <fs_loader.h>
>   #include <remoteproc.h>
>   #include <asm/io.h>
>   #include <dm/device-internal.h>
> @@ -961,3 +962,90 @@ unsigned long rproc_parse_resource_table(struct
> udevice *dev, struct rproc *cfg)
> 
>   	return 1;
>   }
> +
> +int rproc_set_firmware(struct udevice *rproc_dev, const char *fw_name)
> +{
> +	struct dm_rproc_uclass_pdata *uc_pdata;
> +	int len;
> +	char *p;
> +
> +	if (!rproc_dev || !fw_name)
> +		return -EINVAL;
> +
> +	uc_pdata = dev_get_uclass_plat(rproc_dev);
> +
> +	len = strcspn(fw_name, "\n");
> +	if (!len) {
> +		debug("can't provide empty string for firmware name\n");
> +		return -EINVAL;
> +	}
> +
> +	p = strndup(fw_name, len);
> +	if (!p)
> +		return -ENOMEM;
> +
> +	uc_pdata->fw_name = p;
> +
> +	return 0;
> +}
> +
> +int rproc_boot(struct udevice *rproc_dev, size_t fw_size)
> +{
> +	struct dm_rproc_uclass_pdata *uc_pdata;
> +	struct udevice *fs_loader;
> +	void *addr = malloc(fw_size);
> +	int core_id, ret = 0;
> +	char *firmware;
> +	ulong rproc_addr;
> +
> +	if (!rproc_dev)
> +		return -EINVAL;
> +
> +	if (!addr)
> +		return -ENOMEM;
> +
> +	uc_pdata = dev_get_uclass_plat(rproc_dev);
> +	core_id = dev_seq(rproc_dev);
> +	firmware = uc_pdata->fw_name;
> +
> +	if (!firmware) {
> +		debug("No firmware set for rproc core %d\n", core_id);
> +		return -EINVAL;
> +	}
> +
> +	/* Initialize all rproc cores */
> +	rproc_init();
> +
> +	/* Loading firmware to a given address */
> +	ret = get_fs_loader(&fs_loader);
> +	if (ret) {
> +		debug("could not get fs loader: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = request_firmware_into_buf(fs_loader, firmware, addr, fw_size, 0);
> +	if (ret < 0) {
> +		debug("could not request %s: %d\n", firmware, ret);
> +		return ret;
> +	}
> +
> +	rproc_addr = (ulong)addr;
> +
> +	debug("Loaded %s to 0x%08lX size = %d Bytes\n",
> +		uc_pdata->fw_name, rproc_addr, ret);
> +
> +	ret = rproc_load(core_id, rproc_addr, ret);
> +	if (ret) {
> +		debug("failed to load %s to rproc core %d from addr 0x%08lX err %d\n",
> +		       uc_pdata->fw_name, core_id, rproc_addr, ret);
> +		return ret;
> +	}
> +
> +	ret = rproc_start(core_id);
> +	if (ret) {
> +		debug("failed to start rproc core %d\n", core_id);
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> diff --git a/include/remoteproc.h b/include/remoteproc.h
> index a11dc8a9b6..65b0ff7477 100644
> --- a/include/remoteproc.h
> +++ b/include/remoteproc.h
> @@ -402,6 +402,7 @@ enum rproc_mem_type {
>    * @name: Platform-specific way of naming the Remote proc
>    * @mem_type: one of 'enum rproc_mem_type'
>    * @driver_plat_data: driver specific platform data that may be needed.
> + * @fw_name: firmware name
>    *
>    * This can be accessed with dev_get_uclass_plat() for any
> UCLASS_REMOTEPROC
>    * device.
> @@ -411,6 +412,7 @@ struct dm_rproc_uclass_pdata {
>   	const char *name;
>   	enum rproc_mem_type mem_type;
>   	void *driver_plat_data;
> +	char *fw_name;
>   };
> 
>   /**
> @@ -704,6 +706,35 @@ unsigned long rproc_parse_resource_table(struct
> udevice *dev,
>   struct resource_table *rproc_find_resource_table(struct udevice *dev,
>   						 unsigned int addr,
>   						 int *tablesz);
> +/**
> + * rproc_set_firmware() - assign a new firmware
> + * @rproc_dev: device for wich 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. The function does not trigger a remote processor boot,
> + * only sets the firmware name used for a subsequent boot.
> + *
> + * This function sets the fw_name field in uclass pdata of the Remote proc
> + *
> + * Return: 0 on success or a negative value upon failure
> + */
> +int rproc_set_firmware(struct udevice *rproc_dev, const char *fw_name);
> +
> +/**
> + * rproc_boot() - boot a remote processor
> + * @rproc_dev: rproc device to boot
> + * @fw_size: Size of the memory to allocate for firmeware
> + *
> + * Boot a remote processor (i.e. load its firmware, power it on, ...).
> + *
> + * This function first loads the firmware set in the uclass pdata of Remote
> + * processor to a buffer and then loads firmware to the remote processor
> + * using rproc_load().
> + *
> + * Return: 0 on success, and an appropriate error value otherwise
> + */
> +int rproc_boot(struct udevice *rproc_dev, size_t fw_size);
>   #else
>   static inline int rproc_init(void) { return -ENOSYS; }
>   static inline int rproc_dev_init(int id) { return -ENOSYS; }
> @@ -743,6 +774,10 @@ static inline int rproc_elf_load_rsc_table(struct
> udevice *dev, ulong fw_addr,
>   					   ulong fw_size, ulong *rsc_addr,
>   					   ulong *rsc_size)
>   { return -ENOSYS; }
> +static inline int rproc_set_firmware(struct udevice *rproc_dev, const
> char *fw_name)
> +{ return -ENOSYS; }
> +static inline int rproc_boot(struct udevice *rproc_dev, size_t fw_size)
> +{ return -ENOSYS; }
>   #endif
> 
>   #endif	/* _RPROC_H_ */
> 
> 

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
  2023-12-22 12:43     ` Roger Quadros
@ 2023-12-27  6:56       ` MD Danish Anwar
  2024-01-02 13:56         ` Andrew Davis
  0 siblings, 1 reply; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-27  6:56 UTC (permalink / raw)
  To: Roger Quadros, Maxime Ripard, Siddharth Vadapalli,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran



On 22/12/23 6:13 pm, Roger Quadros wrote:
> 
> On 22/12/2023 12:26, MD Danish Anwar wrote:
>> Hi Roger,
>>
>> On 20/12/23 3:29 pm, Roger Quadros wrote:
>>> Hi,
>>>
>>> On 19/12/2023 12:11, MD Danish Anwar wrote:
>>>> Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used in TI
>>>> AM654 SR2.0.
>>>>
>>>> The ICSSG PRU Sub-system runs on EMAC firmware. This series Introduces
>>>> support for ICSSG driver in uboot. This series also adds the driver's
>>>> dependencies.
>>>>
>>>> The ICSSG2 node is added in device tree overlay so that it remains in
>>>> sync with linux kernel.
>>>>
>>>> The series introduces device tree and config changes and AM65x
>>>> to enable ICSSG driver. The series also enables SPL_LOAD_FIT_APPLY_OVERLAY
>>>> for AM65x in order to load overlay over spl.
>>>>
>>>> This series has been tested on AM65x SR2.0, and the ICSSG interface is
>>>> able to ping / dhcp and boot kernel using tftp in uboot.
>>>>
>>>> To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to PRU RPROC
>>>> cores and RPROC cores need to be booted with the firmware. This step is
>>>> done inside driver in kernel as kernel supports APIs like
>>>> rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't have these
>>>> APIs, the same needs to be done via u-boot cmds.
>>>>
>>>> To make sure icssg-eth works we need to do below steps.
>>>>
>>>> 1. Initialize rproc cores i.e. rproc_init()
>>>> 2. Load $firmware_file from partition '1:2' (root) on device (mmc in this
>>>>    example)
>>>> 3. Load the firmware file to rproc cores passing. i.e. rproc_load()
>>>>    taking rproc_id, loadaddr and file size as arguments.
>>>> 4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments
>>>>
>>>> The above steps are done by running the below commands at u-boot prompt.
>>>>
>>>> => setenv start_icssg2 'rproc start 14; rproc start 15; rproc start 16; rproc start 17; rproc start 18; rproc start 19'
>>>> => setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop 16; rproc stop 17; rproc stop 18; rproc stop 19'
>>>> => setenv firmware_dir '/lib/firmware/ti-pruss'
>>>> => setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr} ${firmware_dir}/${firmware_file}'
>>>>
>>>> => setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload no; rproc init; setenv loadaddr 0x80000000; \
>>>>     setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
>>>>     setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15 0x89000000 ${filesize}; \
>>>>     setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load 16 0x90000000 ${filesize}; \
>>>>     setenv loadaddr 0x80000000; setenv firmware_file am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17 0x80000000 ${filesize}; \
>>>>     setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18 0x89000000 ${filesize}; \
>>>>     setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load 19 0x90000000 ${filesize}; \
>>>>     run start_icssg2;'
>>>
>>> A whole bunch of commands are required to get ethernet functional.
>>> This is not at all user friendly and will be a maintenance nightmare.
>>> What worries me is tracking the 6 different rproc cores and the 6 different firmware files to start 1 ethernet device.
>>> This will get even more interesting when we have to deal with different ICSSG instances on different boards.
>>>
>>> What is preventing the driver from starting the rproc cores it needs so user doesn't need to care about it?
>>> All the necessary information is in the Device tree. At least this is how it is done on Linux.
>>>
>>
>> I tried removing the need for these commands and implementing them
>> inside the driver only. I am able to load the firmware from driver using
>> the fs_loader API request_firmware_into_buf(). It requires changes to
>> dt. A DT node called fs-loader needs to be added also CONFIG_FS_LOADER
>> needs to enabled. In the DT node we need to specify the storage media
>> that we are using i.e. mmc, ospi, usb. It's upto user to modify the
>> storage media, the driver will take the media from DT and try to laod
>> firmware from their.
>>
>> For loading firmwares to rproc cores, rproc_load() API is needed. Now
>> this API takes rproc_id, loadaddr and firmware_size as arguments.
>> loadaddr is fixed for all three pru cores. firmware_size is obtained
>> from request_firmware_into_buf() but I couldn't find a way to get the
>> rproc_id. For now based on the ICSSG instance and slice number I am
>> figuring out the rproc_id and passing it to rproc_load() and
>> rproc_start() APIs. Please let me know if you have any other / better
>> way of finding rproc_id.
>>
>> Below is the entire diff to remove these commands and move their
>> functionality to driver. Please have a look and let me know if this is ok.
>>
> 
> Good to see you got something working so quickly.
> It has some rough edges but nothing that is blocking.
> 
>>
>> Save New Duplicate & Edit Just Text Twitter
>> diff --git a/arch/arm/dts/k3-am654-base-board.dts
>> b/arch/arm/dts/k3-am654-base-board.dts
>> index cfbcebfa37..c8da72e49c 100644
>> --- a/arch/arm/dts/k3-am654-base-board.dts
>> +++ b/arch/arm/dts/k3-am654-base-board.dts
>> @@ -16,6 +16,13 @@
>>  	chosen {
>>  		stdout-path = "serial2:115200n8";
>>  		bootargs = "earlycon=ns16550a,mmio32,0x02800000";
>> +		firmware-loader = <&fs_loader0>;
>> +	};
>> +
>> +	fs_loader0: fs-loader {
>> +		bootph-all;
>> +		compatible = "u-boot,fs-loader";
>> +		phandlepart = <&sdhci1 2>;
>>  	};
> 
> This is has 2 issues
> 1) It will not be accepted in Kernel DT. Maybe it could be done in -u-boot.dtsi file.

Sure. I'll move this to k3-am654-base-board-u-boot.dtsi

> 2) You cannot assume boot medium is always sdhci1 2
> 

Yes. It's upto user to provide the boot medium and boot partition for
loading firmware. By default the firmware is loacated in root partion of
shdci1 on am65x so I am adding this as default. But user can easily
modify this to any other medium / partition needed.

>>
>>  	memory@80000000 {
>> diff --git a/configs/am65x_evm_a53_defconfig
>> b/configs/am65x_evm_a53_defconfig
>> index 2755d7082f..c53e938abb 100644
>> --- a/configs/am65x_evm_a53_defconfig
>> +++ b/configs/am65x_evm_a53_defconfig
>> @@ -112,6 +112,7 @@ CONFIG_DM_I2C_GPIO=y
>>  CONFIG_SYS_I2C_OMAP24XX=y
>>  CONFIG_DM_MAILBOX=y
>>  CONFIG_K3_SEC_PROXY=y
>> +CONFIG_FS_LOADER=y
>>  CONFIG_SUPPORT_EMMC_BOOT=y
>>  CONFIG_MMC_IO_VOLTAGE=y
>>  CONFIG_MMC_UHS_SUPPORT=y
>> diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig
>> index b2f1e721b3..2d19935a41 100644
>> --- a/configs/am65x_evm_r5_defconfig
>> +++ b/configs/am65x_evm_r5_defconfig
>> @@ -98,6 +98,7 @@ CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
>>  CONFIG_SYS_I2C_OMAP24XX=y
>>  CONFIG_DM_MAILBOX=y
>>  CONFIG_K3_SEC_PROXY=y
>> +CONFIG_FS_LOADER=y
>>  CONFIG_K3_AVS0=y
>>  CONFIG_SUPPORT_EMMC_BOOT=y
>>  CONFIG_MMC_HS200_SUPPORT=y
>> diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
>> index 40ad827e49..1c4edeb7b7 100644
>> --- a/drivers/net/ti/icssg_prueth.c
>> +++ b/drivers/net/ti/icssg_prueth.c
>> @@ -227,6 +227,10 @@ static int prueth_start(struct udevice *dev)
>>  	void *config;
>>  	int ret, i;
>>
>> +	ret = icssg_start_pru_cores(dev);
>> +	if (ret)
>> +		return ret;
>> +
>>  	/* To differentiate channels for SLICE0 vs SLICE1 */
>>  	snprintf(chn_name, sizeof(chn_name), "tx%d-0", priv->slice);
>>
>> @@ -355,9 +359,11 @@ static void prueth_stop(struct udevice *dev)
>>  	phy_shutdown(priv->phydev);
>>
>>  	dma_disable(&priv->dma_tx);
>> -	dma_free(&priv->dma_tx);
>> -
>>  	dma_disable(&priv->dma_rx);
>> +
>> +	icssg_stop_pru_cores(dev);
>> +
>> +	dma_free(&priv->dma_tx);
>>  	dma_free(&priv->dma_rx);
>>  }
>>
>> @@ -434,6 +440,181 @@ static const struct soc_attr k3_mdio_soc_data[] = {
>>  	{ /* sentinel */ },
>>  };
>>
>> +struct icssg_firmware_load_address {
>> +	u32 pru;
>> +	u32 rtu;
>> +	u32 txpru;
>> +};
>> +
>> +struct icssg_firmwares {
>> +	char *pru;
>> +	char *rtu;
>> +	char *txpru;
>> +};
>> +
>> +static struct icssg_firmwares icssg_emac_firmwares[] = {
>> +	{
>> +		.pru = "/lib/firmware/ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
>> +		.rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
>> +		.txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
>> +	},
>> +	{
>> +		.pru = "/lib/firmware/ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
>> +		.rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
>> +		.txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru1-prueth-fw.elf",
>> +	}
>> +};
> 
> This information is contained in the DT.
> 
> 		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";
> 

Yes it is. But the linux driver uses the firmware strcuture inside
driver only. The firmware-name property is not being used. The firmware
names for all applicable SoCs (AM65x and AM64x) is same so instead of
reading it from DT, the driver hardcodes the firmware names in linux. I
think the thought here was to use firmware-name property from DT when
different firmwares are needed for different SoCs. I am just following
the same here in uboot as well.

> You will need to introduce a rproc_set_firmware() API so clients can
> set their own firmware names.
> 

Sure. I will add an element 'fw_name' in struct dm_rproc_uclass_pdata
and set this fw_name to the firmware name requested by client using
rproc_set_firmware().

The client drivers can call rproc_set_firmware(dev, firmware_name) to
set the firmware name.

>> +
>> +int load_firmware(char *name_fw, u32 *loadaddr)
>> +{
>> +	struct udevice *fsdev;
>> +	int size = 0;
>> +
>> +	if (!IS_ENABLED(CONFIG_FS_LOADER))
>> +		return -EINVAL;
>> +
>> +	if (!*loadaddr)
>> +		return -EINVAL;
>> +
>> +	if (!get_fs_loader(&fsdev))
>> +		size = request_firmware_into_buf(fsdev, name_fw, (void *)*loadaddr,
>> 40524, 0);
>> +
>> +	return size;
>> +}
> 
> On Linux rproc_boot() does both loading the firmware and starting the rproc
> as that is farely generic.
> You should introduce rproc_boot() API so loading is taken care of at rproc driver.
> All you need to do is call rproc_set_firmware() before rproc_boot().
> 

Sure. I'll introduce rproc_boot() which will load the firmware to a
buffer and then load the firmware / buffer to rproc core usinig rproc_load.

For allocating memory for reading firmware we need to provide the size
of memory required as well. So rproc_boot will take two arguments.
1. dev (rproc device)
2. size (Maximum memory required to read firmware)

>> +
>> +static int icssg_get_instance(struct udevice *dev)
>> +{
>> +	if (!strcmp(dev->name, "icssg2-eth"))
>> +		return 2;
>> +	else if (!strcmp(dev->name, "icssg1-eth"))
>> +		return 1;
>> +	else if (!strcmp(dev->name, "icssg0-eth"))
>> +		return 0;
>> +
>> +	dev_err(dev, "Invalid icssg instance\n");
>> +	return -EINVAL;
>> +}
>> +
>> +static int icssg_get_pru_core_number(struct udevice *dev, int slice)
>> +{
>> +	int instance, num_r5_cores;
>> +
>> +	instance = icssg_get_instance(dev);
>> +	if (instance < 0)
>> +		return instance;
>> +
>> +	if (IS_ENABLED(CONFIG_REMOTEPROC_TI_K3_R5F))
>> +		num_r5_cores = 2;
>> +
>> +	return num_r5_cores +
>> +	       instance * PRU_TYPE_MAX * PRUETH_NUM_MACS +
>> +	       slice * PRU_TYPE_MAX;
> 
> All this doesn't look right. What we need is the rproc device
> that matches the PRU/RTU rprocs that we are interested in.
> 
> The DT already has this information
> 
> 		ti,prus = <&pru2_0>, <&rtu2_0>, <&tx_pru2_0>,
> 			<&pru2_1>, <&rtu2_1>, <&tx_pru2_1>;
> 
> 
> All the current rproc APIs use the below to get rproc device from ID
> ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev);
> 
> You just need to introduce APIs that takes rproc device directly as argument.
> 
> In your driver you can call uclass_get_device_by_phandle_id() to get the
> rproc device from the rproc phandle?

Sure. I'll do that. Based on the icssg slice first I will get the
phandle for prus.

Index will be 0,1,2 for slice 0 and 3,4,5 for slice 1.

ofnode_read_u32_index(dev_ofnode(dev), "ti,prus", index, &phandle);

Then for each phandle I can call uclass_get_device_by_phandle_id() and
get the rproc device.

> 
> 
>> +}
>> +
>> +int icssg_start_pru_cores(struct udevice *dev)
>> +{
>> +	struct prueth *prueth = dev_get_priv(dev);
>> +	struct icssg_firmwares *firmwares;
>> +	u32 pru_fw_loadaddr = 0x80000000;
>> +	u32 rtu_fw_loadaddr = 0x89000000;
>> +	u32 txpru_fw_loadaddr = 0x90000000;
> 
> Please avoid hardcoding. You can use malloc to get a temporary buffer area?
> 
> Why do you need 3 different addresses?
> Once you do a rproc_load isn't the buffer already copied to rproc's memory
> so you can discard it or use it for the other rprocs?
> 

Sure I'll use malloc to get temporary buffer. Only thing is that to get
temporary buffer I will need to provide size as well.

void *addr = malloc(fw_size);

User needs to provide this fw_size to rproc_boot(). In my case the max
size the firmware can have is 64KB so I will be passing 64K as size to
rproc driver.

>> +	int slice, ret, core_id;
>> +
>> +	firmwares = icssg_emac_firmwares;
>> +	slice = prueth->slice;
>> +
>> +	core_id = icssg_get_pru_core_number(dev, slice);
>> +	if (core_id < 0)
>> +		return core_id;
>> +
>> +	/* Initialize all rproc cores */
>> +	rproc_init();
>> +
>> +	/* Loading PRU firmware to PRU core */
>> +	ret = load_firmware(firmwares[slice].pru, &pru_fw_loadaddr);
> 
> On Linux, loading the firmware is the responsibility of the rproc driver.
> Shouldn't it be the same in u-boot?
> 

Sure I'll move this to rproc driver.

>> +
>> +	if (ret < 0) {
>> +		dev_err(dev, "Unable to load_firmware %s at addr 0x%x err %d\n",
>> +			firmwares[slice].pru, pru_fw_loadaddr, ret);
>> +		return ret;
>> +	}
>> +
>> +	dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d Bytes\n",
>> +		firmwares[slice].pru, pru_fw_loadaddr, ret);
> 
> dev_dbg() here an at all dev_info().
> 
>> +	rproc_load(core_id + PRU_TYPE_PRU, pru_fw_loadaddr, ret);
>> +
>> +	/* Loading RTU firmware to RTU core */
>> +	ret = load_firmware(firmwares[slice].rtu, &rtu_fw_loadaddr);
>> +
>> +	if (ret < 0) {
>> +		dev_err(dev, "Unable to load_firmware %s at addr 0x%x err %d\n",
>> +			firmwares[slice].rtu, rtu_fw_loadaddr, ret);
>> +		return ret;
>> +	}
>> +
>> +	dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d Bytes\n",
>> +		firmwares[slice].rtu, rtu_fw_loadaddr, ret);
>> +	rproc_load(core_id + PRU_TYPE_RTU, rtu_fw_loadaddr, ret);
>> +
>> +	/* Loading TX_PRU firmware to TX_PRU core */
>> +	ret = load_firmware(firmwares[slice].txpru, &txpru_fw_loadaddr);
>> +
>> +	if (ret < 0) {
>> +		dev_err(dev, "Unable to load_firmware %s at addr 0x%x err %d\n",
>> +			firmwares[slice].txpru, txpru_fw_loadaddr, ret);
>> +		return ret;
>> +	}
>> +
>> +	dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d Bytes\n",
>> +		firmwares[slice].txpru, txpru_fw_loadaddr, ret);
>> +	rproc_load(core_id + PRU_TYPE_TX_PRU, txpru_fw_loadaddr, ret);
>> +
>> +	ret = rproc_start(core_id + PRU_TYPE_PRU);
>> +	if (ret) {
>> +		dev_err(dev, "failed to start PRU%d: %d\n", slice, ret);
>> +		return ret;
>> +	}
>> +
>> +	ret = rproc_start(core_id + PRU_TYPE_RTU);
>> +	if (ret) {
>> +		dev_err(dev, "failed to start RTU%d: %d\n", slice, ret);
>> +		goto halt_pru;
>> +	}
>> +
>> +	ret = rproc_start(core_id + PRU_TYPE_TX_PRU);
>> +	if (ret) {
>> +		dev_err(dev, "failed to start TX_PRU%d: %d\n", slice, ret);
>> +		goto halt_rtu;
>> +	}
>> +
>> +	return 0;
>> +
>> +halt_rtu:
>> +	rproc_stop(core_id + PRU_TYPE_RTU);
>> +
>> +halt_pru:
>> +	rproc_stop(PRU_TYPE_PRU);
>> +	return ret;
>> +}
>> +
>> +int icssg_stop_pru_cores(struct udevice *dev)
>> +{
>> +	struct prueth *prueth = dev_get_priv(dev);
>> +	int slice, core_id;
>> +
>> +	slice = prueth->slice;
>> +
>> +	core_id = icssg_get_pru_core_number(dev, slice);
>> +	if (core_id < 0)
>> +		return core_id;
>> +
>> +	rproc_stop(core_id + PRU_TYPE_PRU);
>> +	rproc_stop(core_id + PRU_TYPE_RTU);
>> +	rproc_stop(core_id + PRU_TYPE_TX_PRU);
>> +
>> +	return 0;
>> +}
>> +
>>  static int prueth_probe(struct udevice *dev)
>>  {
>>  	ofnode eth_ports_node, eth0_node, eth1_node, eth_node;
>> diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h
>> index 25272e850e..f17fe8bf58 100644
>> --- a/include/linux/pruss_driver.h
>> +++ b/include/linux/pruss_driver.h
>> @@ -114,6 +114,21 @@ enum pru_ctable_idx {
>>  	PRU_C31,
>>  };
>>
>> +/**
>> + * 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
>>   */
>>
>> with this diff, user don't need to run any extra commands at u-boot.
>> Once u-boot prompt is reached, just running ping / dhcp will suffice.
>>
> Great!
> 
> <snip>
> 

I have addressed all the above comments and made the changes needed.
below is the diff. Please have a look at it and let me know if it looks OK.

diff --git a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
index 11d83927ac..0b2b72b2c5 100644
--- a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
+++ b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
@@ -6,6 +6,18 @@
 #include "k3-am654-r5-base-board-u-boot.dtsi"
 #include "k3-am65x-binman.dtsi"

+/ {
+	chosen {
+		firmware-loader = <&fs_loader0>;
+	};
+
+	fs_loader0: fs-loader {
+		bootph-all;
+		compatible = "u-boot,fs-loader";
+		phandlepart = <&sdhci1 2>;
+	};
+};
+
 &pru0_0 {
 	remoteproc-name = "pru0_0";
 };
diff --git a/configs/am65x_evm_a53_defconfig
b/configs/am65x_evm_a53_defconfig
index 2755d7082f..c53e938abb 100644
--- a/configs/am65x_evm_a53_defconfig
+++ b/configs/am65x_evm_a53_defconfig
@@ -112,6 +112,7 @@ CONFIG_DM_I2C_GPIO=y
 CONFIG_SYS_I2C_OMAP24XX=y
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
+CONFIG_FS_LOADER=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig
index b2f1e721b3..2d19935a41 100644
--- a/configs/am65x_evm_r5_defconfig
+++ b/configs/am65x_evm_r5_defconfig
@@ -98,6 +98,7 @@ CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 CONFIG_SYS_I2C_OMAP24XX=y
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
+CONFIG_FS_LOADER=y
 CONFIG_K3_AVS0=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_HS200_SUPPORT=y
diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
index 40ad827e49..a2e3595956 100644
--- a/drivers/net/ti/icssg_prueth.c
+++ b/drivers/net/ti/icssg_prueth.c
@@ -62,6 +62,9 @@
 /* Management packet type */
 #define PRUETH_PKT_TYPE_CMD		0x10

+/* Number of PRU Cores per Slice */
+#define ICSSG_NUM_PRU_CORES		3
+
 static int icssg_phy_init(struct udevice *dev)
 {
 	struct prueth *priv = dev_get_priv(dev);
@@ -218,6 +221,116 @@ static int icssg_update_link(struct prueth *priv)
 	return phy->link;
 }

+struct icssg_firmwares {
+	char *pru;
+	char *rtu;
+	char *txpru;
+};
+
+static struct icssg_firmwares icssg_emac_firmwares[] = {
+	{
+		.pru = "/lib/firmware/ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
+		.rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
+		.txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
+	},
+	{
+		.pru = "/lib/firmware/ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
+		.rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
+		.txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru1-prueth-fw.elf",
+	}
+};
+
+static int icssg_start_pru_cores(struct udevice *dev)
+{
+	struct prueth *prueth = dev_get_priv(dev);
+	struct icssg_firmwares *firmwares;
+	struct udevice *rproc_dev = NULL;
+	int ret, slice;
+	u32 phandle;
+	u8 index;
+
+	slice = prueth->slice;
+	index = slice * ICSSG_NUM_PRU_CORES;
+	firmwares = icssg_emac_firmwares;
+
+	ofnode_read_u32_index(dev_ofnode(dev), "ti,prus", index, &phandle);
+	ret = uclass_get_device_by_phandle_id(UCLASS_REMOTEPROC, phandle,
&rproc_dev);
+	if (ret) {
+		dev_err(dev, "Unknown remote processor with phandle '0x%x'
requested(%d)\n",
+		       phandle, ret);
+		return ret;
+	}
+
+	prueth->pru_core_id = dev_seq(rproc_dev);
+	ret = rproc_set_firmware(rproc_dev, firmwares[slice].pru);
+	if (ret)
+		return ret;
+
+	ret = rproc_boot(rproc_dev, SZ_64K);
+	if (ret) {
+		dev_err(dev, "failed to boot PRU%d: %d\n", slice, ret);
+		return -EINVAL;
+	}
+
+	ofnode_read_u32_index(dev_ofnode(dev), "ti,prus", index + 1, &phandle);
+	ret = uclass_get_device_by_phandle_id(UCLASS_REMOTEPROC, phandle,
&rproc_dev);
+	if (ret) {
+		dev_err(dev, "Unknown remote processor with phandle '0x%x'
requested(%d)\n",
+		       phandle, ret);
+		goto halt_pru;
+	}
+
+	prueth->rtu_core_id = dev_seq(rproc_dev);
+	ret = rproc_set_firmware(rproc_dev, firmwares[slice].rtu);
+	if (ret)
+		goto halt_pru;
+
+	ret = rproc_boot(rproc_dev, SZ_64K);
+	if (ret) {
+		dev_err(dev, "failed to boot RTU%d: %d\n", slice, ret);
+		goto halt_pru;
+	}
+
+	ofnode_read_u32_index(dev_ofnode(dev), "ti,prus", index + 2, &phandle);
+	ret = uclass_get_device_by_phandle_id(UCLASS_REMOTEPROC, phandle,
&rproc_dev);
+	if (ret) {
+		dev_err(dev, "Unknown remote processor with phandle '0x%x'
requested(%d)\n",
+		       phandle, ret);
+		goto halt_rtu;
+	}
+
+	prueth->txpru_core_id = dev_seq(rproc_dev);
+	ret = rproc_set_firmware(rproc_dev, firmwares[slice].txpru);
+	if (ret)
+		goto halt_rtu;
+
+	ret = rproc_boot(rproc_dev, SZ_64K);
+	if (ret) {
+		dev_err(dev, "failed to boot TXPRU%d: %d\n", slice, ret);
+		goto halt_rtu;
+	}
+
+	return 0;
+
+halt_rtu:
+	rproc_stop(prueth->rtu_core_id);
+
+halt_pru:
+	rproc_stop(prueth->pru_core_id);
+	return ret;
+}
+
+static int icssg_stop_pru_cores(struct udevice *dev)
+{
+	struct prueth *prueth = dev_get_priv(dev);
+
+	rproc_stop(prueth->pru_core_id);
+	rproc_stop(prueth->rtu_core_id);
+	rproc_stop(prueth->txpru_core_id);
+
+	return 0;
+}
+
 static int prueth_start(struct udevice *dev)
 {
 	struct ti_udma_drv_chan_cfg_data *dma_rx_cfg_data;
@@ -227,6 +340,10 @@ static int prueth_start(struct udevice *dev)
 	void *config;
 	int ret, i;

+	ret = icssg_start_pru_cores(dev);
+	if (ret)
+		return ret;
+
 	/* To differentiate channels for SLICE0 vs SLICE1 */
 	snprintf(chn_name, sizeof(chn_name), "tx%d-0", priv->slice);

@@ -355,9 +472,11 @@ static void prueth_stop(struct udevice *dev)
 	phy_shutdown(priv->phydev);

 	dma_disable(&priv->dma_tx);
-	dma_free(&priv->dma_tx);
-
 	dma_disable(&priv->dma_rx);
+
+	icssg_stop_pru_cores(dev);
+
+	dma_free(&priv->dma_tx);
 	dma_free(&priv->dma_rx);
 }

diff --git a/drivers/net/ti/icssg_prueth.h b/drivers/net/ti/icssg_prueth.h
index e41ed16a05..c92660401b 100644
--- a/drivers/net/ti/icssg_prueth.h
+++ b/drivers/net/ti/icssg_prueth.h
@@ -69,6 +69,9 @@ struct prueth {
 	int			speed;
 	int			duplex;
 	u8			icssg_hwcmdseq;
+	u8 			pru_core_id;
+	u8 			rtu_core_id;
+	u8 			txpru_core_id;
 };

 /* config helpers */
diff --git a/drivers/remoteproc/rproc-uclass.c
b/drivers/remoteproc/rproc-uclass.c
index 28b362c887..a085c44eaa 100644
--- a/drivers/remoteproc/rproc-uclass.c
+++ b/drivers/remoteproc/rproc-uclass.c
@@ -13,6 +13,7 @@
 #include <log.h>
 #include <malloc.h>
 #include <virtio_ring.h>
+#include <fs_loader.h>
 #include <remoteproc.h>
 #include <asm/io.h>
 #include <dm/device-internal.h>
@@ -961,3 +962,90 @@ unsigned long rproc_parse_resource_table(struct
udevice *dev, struct rproc *cfg)

 	return 1;
 }
+
+int rproc_set_firmware(struct udevice *rproc_dev, const char *fw_name)
+{
+	struct dm_rproc_uclass_pdata *uc_pdata;
+	int len;
+	char *p;
+
+	if (!rproc_dev || !fw_name)
+		return -EINVAL;
+
+	uc_pdata = dev_get_uclass_plat(rproc_dev);
+
+	len = strcspn(fw_name, "\n");
+	if (!len) {
+		debug("can't provide empty string for firmware name\n");
+		return -EINVAL;
+	}
+
+	p = strndup(fw_name, len);
+	if (!p)
+		return -ENOMEM;
+
+	uc_pdata->fw_name = p;
+
+	return 0;
+}
+
+int rproc_boot(struct udevice *rproc_dev, size_t fw_size)
+{
+	struct dm_rproc_uclass_pdata *uc_pdata;
+	struct udevice *fs_loader;
+	void *addr = malloc(fw_size);
+	int core_id, ret = 0;
+	char *firmware;
+	ulong rproc_addr;
+
+	if (!rproc_dev)
+		return -EINVAL;
+
+	if (!addr)
+		return -ENOMEM;
+
+	uc_pdata = dev_get_uclass_plat(rproc_dev);
+	core_id = dev_seq(rproc_dev);
+	firmware = uc_pdata->fw_name;
+
+	if (!firmware) {
+		debug("No firmware set for rproc core %d\n", core_id);
+		return -EINVAL;
+	}
+
+	/* Initialize all rproc cores */
+	rproc_init();
+
+	/* Loading firmware to a given address */
+	ret = get_fs_loader(&fs_loader);
+	if (ret) {
+		debug("could not get fs loader: %d\n", ret);
+		return ret;
+	}
+
+	ret = request_firmware_into_buf(fs_loader, firmware, addr, fw_size, 0);
+	if (ret < 0) {
+		debug("could not request %s: %d\n", firmware, ret);
+		return ret;
+	}
+
+	rproc_addr = (ulong)addr;
+
+	debug("Loaded %s to 0x%08lX size = %d Bytes\n",
+		uc_pdata->fw_name, rproc_addr, ret);
+
+	ret = rproc_load(core_id, rproc_addr, ret);
+	if (ret) {
+		debug("failed to load %s to rproc core %d from addr 0x%08lX err %d\n",
+		       uc_pdata->fw_name, core_id, rproc_addr, ret);
+		return ret;
+	}
+
+	ret = rproc_start(core_id);
+	if (ret) {
+		debug("failed to start rproc core %d\n", core_id);
+		return ret;
+	}
+
+	return ret;
+}
diff --git a/include/remoteproc.h b/include/remoteproc.h
index a11dc8a9b6..65b0ff7477 100644
--- a/include/remoteproc.h
+++ b/include/remoteproc.h
@@ -402,6 +402,7 @@ enum rproc_mem_type {
  * @name: Platform-specific way of naming the Remote proc
  * @mem_type: one of 'enum rproc_mem_type'
  * @driver_plat_data: driver specific platform data that may be needed.
+ * @fw_name: firmware name
  *
  * This can be accessed with dev_get_uclass_plat() for any
UCLASS_REMOTEPROC
  * device.
@@ -411,6 +412,7 @@ struct dm_rproc_uclass_pdata {
 	const char *name;
 	enum rproc_mem_type mem_type;
 	void *driver_plat_data;
+	char *fw_name;
 };

 /**
@@ -704,6 +706,35 @@ unsigned long rproc_parse_resource_table(struct
udevice *dev,
 struct resource_table *rproc_find_resource_table(struct udevice *dev,
 						 unsigned int addr,
 						 int *tablesz);
+/**
+ * rproc_set_firmware() - assign a new firmware
+ * @rproc_dev: device for wich 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. The function does not trigger a remote processor boot,
+ * only sets the firmware name used for a subsequent boot.
+ *
+ * This function sets the fw_name field in uclass pdata of the Remote proc
+ *
+ * Return: 0 on success or a negative value upon failure
+ */
+int rproc_set_firmware(struct udevice *rproc_dev, const char *fw_name);
+
+/**
+ * rproc_boot() - boot a remote processor
+ * @rproc_dev: rproc device to boot
+ * @fw_size: Size of the memory to allocate for firmeware
+ *
+ * Boot a remote processor (i.e. load its firmware, power it on, ...).
+ *
+ * This function first loads the firmware set in the uclass pdata of Remote
+ * processor to a buffer and then loads firmware to the remote processor
+ * using rproc_load().
+ *
+ * Return: 0 on success, and an appropriate error value otherwise
+ */
+int rproc_boot(struct udevice *rproc_dev, size_t fw_size);
 #else
 static inline int rproc_init(void) { return -ENOSYS; }
 static inline int rproc_dev_init(int id) { return -ENOSYS; }
@@ -743,6 +774,10 @@ static inline int rproc_elf_load_rsc_table(struct
udevice *dev, ulong fw_addr,
 					   ulong fw_size, ulong *rsc_addr,
 					   ulong *rsc_size)
 { return -ENOSYS; }
+static inline int rproc_set_firmware(struct udevice *rproc_dev, const
char *fw_name)
+{ return -ENOSYS; }
+static inline int rproc_boot(struct udevice *rproc_dev, size_t fw_size)
+{ return -ENOSYS; }
 #endif

 #endif	/* _RPROC_H_ */


-- 
Thanks and Regards,
Danish

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
  2023-12-22 10:26   ` MD Danish Anwar
@ 2023-12-22 12:43     ` Roger Quadros
  2023-12-27  6:56       ` MD Danish Anwar
  0 siblings, 1 reply; 48+ messages in thread
From: Roger Quadros @ 2023-12-22 12:43 UTC (permalink / raw)
  To: MD Danish Anwar, Maxime Ripard, Siddharth Vadapalli,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran


On 22/12/2023 12:26, MD Danish Anwar wrote:
> Hi Roger,
> 
> On 20/12/23 3:29 pm, Roger Quadros wrote:
>> Hi,
>>
>> On 19/12/2023 12:11, MD Danish Anwar wrote:
>>> Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used in TI
>>> AM654 SR2.0.
>>>
>>> The ICSSG PRU Sub-system runs on EMAC firmware. This series Introduces
>>> support for ICSSG driver in uboot. This series also adds the driver's
>>> dependencies.
>>>
>>> The ICSSG2 node is added in device tree overlay so that it remains in
>>> sync with linux kernel.
>>>
>>> The series introduces device tree and config changes and AM65x
>>> to enable ICSSG driver. The series also enables SPL_LOAD_FIT_APPLY_OVERLAY
>>> for AM65x in order to load overlay over spl.
>>>
>>> This series has been tested on AM65x SR2.0, and the ICSSG interface is
>>> able to ping / dhcp and boot kernel using tftp in uboot.
>>>
>>> To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to PRU RPROC
>>> cores and RPROC cores need to be booted with the firmware. This step is
>>> done inside driver in kernel as kernel supports APIs like
>>> rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't have these
>>> APIs, the same needs to be done via u-boot cmds.
>>>
>>> To make sure icssg-eth works we need to do below steps.
>>>
>>> 1. Initialize rproc cores i.e. rproc_init()
>>> 2. Load $firmware_file from partition '1:2' (root) on device (mmc in this
>>>    example)
>>> 3. Load the firmware file to rproc cores passing. i.e. rproc_load()
>>>    taking rproc_id, loadaddr and file size as arguments.
>>> 4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments
>>>
>>> The above steps are done by running the below commands at u-boot prompt.
>>>
>>> => setenv start_icssg2 'rproc start 14; rproc start 15; rproc start 16; rproc start 17; rproc start 18; rproc start 19'
>>> => setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop 16; rproc stop 17; rproc stop 18; rproc stop 19'
>>> => setenv firmware_dir '/lib/firmware/ti-pruss'
>>> => setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr} ${firmware_dir}/${firmware_file}'
>>>
>>> => setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload no; rproc init; setenv loadaddr 0x80000000; \
>>>     setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
>>>     setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15 0x89000000 ${filesize}; \
>>>     setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load 16 0x90000000 ${filesize}; \
>>>     setenv loadaddr 0x80000000; setenv firmware_file am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17 0x80000000 ${filesize}; \
>>>     setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18 0x89000000 ${filesize}; \
>>>     setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load 19 0x90000000 ${filesize}; \
>>>     run start_icssg2;'
>>
>> A whole bunch of commands are required to get ethernet functional.
>> This is not at all user friendly and will be a maintenance nightmare.
>> What worries me is tracking the 6 different rproc cores and the 6 different firmware files to start 1 ethernet device.
>> This will get even more interesting when we have to deal with different ICSSG instances on different boards.
>>
>> What is preventing the driver from starting the rproc cores it needs so user doesn't need to care about it?
>> All the necessary information is in the Device tree. At least this is how it is done on Linux.
>>
> 
> I tried removing the need for these commands and implementing them
> inside the driver only. I am able to load the firmware from driver using
> the fs_loader API request_firmware_into_buf(). It requires changes to
> dt. A DT node called fs-loader needs to be added also CONFIG_FS_LOADER
> needs to enabled. In the DT node we need to specify the storage media
> that we are using i.e. mmc, ospi, usb. It's upto user to modify the
> storage media, the driver will take the media from DT and try to laod
> firmware from their.
> 
> For loading firmwares to rproc cores, rproc_load() API is needed. Now
> this API takes rproc_id, loadaddr and firmware_size as arguments.
> loadaddr is fixed for all three pru cores. firmware_size is obtained
> from request_firmware_into_buf() but I couldn't find a way to get the
> rproc_id. For now based on the ICSSG instance and slice number I am
> figuring out the rproc_id and passing it to rproc_load() and
> rproc_start() APIs. Please let me know if you have any other / better
> way of finding rproc_id.
> 
> Below is the entire diff to remove these commands and move their
> functionality to driver. Please have a look and let me know if this is ok.
> 

Good to see you got something working so quickly.
It has some rough edges but nothing that is blocking.

> 
> Save New Duplicate & Edit Just Text Twitter
> diff --git a/arch/arm/dts/k3-am654-base-board.dts
> b/arch/arm/dts/k3-am654-base-board.dts
> index cfbcebfa37..c8da72e49c 100644
> --- a/arch/arm/dts/k3-am654-base-board.dts
> +++ b/arch/arm/dts/k3-am654-base-board.dts
> @@ -16,6 +16,13 @@
>  	chosen {
>  		stdout-path = "serial2:115200n8";
>  		bootargs = "earlycon=ns16550a,mmio32,0x02800000";
> +		firmware-loader = <&fs_loader0>;
> +	};
> +
> +	fs_loader0: fs-loader {
> +		bootph-all;
> +		compatible = "u-boot,fs-loader";
> +		phandlepart = <&sdhci1 2>;
>  	};

This is has 2 issues
1) It will not be accepted in Kernel DT. Maybe it could be done in -u-boot.dtsi file.
2) You cannot assume boot medium is always sdhci1 2

> 
>  	memory@80000000 {
> diff --git a/configs/am65x_evm_a53_defconfig
> b/configs/am65x_evm_a53_defconfig
> index 2755d7082f..c53e938abb 100644
> --- a/configs/am65x_evm_a53_defconfig
> +++ b/configs/am65x_evm_a53_defconfig
> @@ -112,6 +112,7 @@ CONFIG_DM_I2C_GPIO=y
>  CONFIG_SYS_I2C_OMAP24XX=y
>  CONFIG_DM_MAILBOX=y
>  CONFIG_K3_SEC_PROXY=y
> +CONFIG_FS_LOADER=y
>  CONFIG_SUPPORT_EMMC_BOOT=y
>  CONFIG_MMC_IO_VOLTAGE=y
>  CONFIG_MMC_UHS_SUPPORT=y
> diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig
> index b2f1e721b3..2d19935a41 100644
> --- a/configs/am65x_evm_r5_defconfig
> +++ b/configs/am65x_evm_r5_defconfig
> @@ -98,6 +98,7 @@ CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
>  CONFIG_SYS_I2C_OMAP24XX=y
>  CONFIG_DM_MAILBOX=y
>  CONFIG_K3_SEC_PROXY=y
> +CONFIG_FS_LOADER=y
>  CONFIG_K3_AVS0=y
>  CONFIG_SUPPORT_EMMC_BOOT=y
>  CONFIG_MMC_HS200_SUPPORT=y
> diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
> index 40ad827e49..1c4edeb7b7 100644
> --- a/drivers/net/ti/icssg_prueth.c
> +++ b/drivers/net/ti/icssg_prueth.c
> @@ -227,6 +227,10 @@ static int prueth_start(struct udevice *dev)
>  	void *config;
>  	int ret, i;
> 
> +	ret = icssg_start_pru_cores(dev);
> +	if (ret)
> +		return ret;
> +
>  	/* To differentiate channels for SLICE0 vs SLICE1 */
>  	snprintf(chn_name, sizeof(chn_name), "tx%d-0", priv->slice);
> 
> @@ -355,9 +359,11 @@ static void prueth_stop(struct udevice *dev)
>  	phy_shutdown(priv->phydev);
> 
>  	dma_disable(&priv->dma_tx);
> -	dma_free(&priv->dma_tx);
> -
>  	dma_disable(&priv->dma_rx);
> +
> +	icssg_stop_pru_cores(dev);
> +
> +	dma_free(&priv->dma_tx);
>  	dma_free(&priv->dma_rx);
>  }
> 
> @@ -434,6 +440,181 @@ static const struct soc_attr k3_mdio_soc_data[] = {
>  	{ /* sentinel */ },
>  };
> 
> +struct icssg_firmware_load_address {
> +	u32 pru;
> +	u32 rtu;
> +	u32 txpru;
> +};
> +
> +struct icssg_firmwares {
> +	char *pru;
> +	char *rtu;
> +	char *txpru;
> +};
> +
> +static struct icssg_firmwares icssg_emac_firmwares[] = {
> +	{
> +		.pru = "/lib/firmware/ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
> +		.rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
> +		.txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
> +	},
> +	{
> +		.pru = "/lib/firmware/ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
> +		.rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
> +		.txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru1-prueth-fw.elf",
> +	}
> +};

This information is contained in the DT.

		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";

You will need to introduce a rproc_set_firmware() API so clients can
set their own firmware names.

> +
> +int load_firmware(char *name_fw, u32 *loadaddr)
> +{
> +	struct udevice *fsdev;
> +	int size = 0;
> +
> +	if (!IS_ENABLED(CONFIG_FS_LOADER))
> +		return -EINVAL;
> +
> +	if (!*loadaddr)
> +		return -EINVAL;
> +
> +	if (!get_fs_loader(&fsdev))
> +		size = request_firmware_into_buf(fsdev, name_fw, (void *)*loadaddr,
> 40524, 0);
> +
> +	return size;
> +}

On Linux rproc_boot() does both loading the firmware and starting the rproc
as that is farely generic.
You should introduce rproc_boot() API so loading is taken care of at rproc driver.
All you need to do is call rproc_set_firmware() before rproc_boot().

> +
> +static int icssg_get_instance(struct udevice *dev)
> +{
> +	if (!strcmp(dev->name, "icssg2-eth"))
> +		return 2;
> +	else if (!strcmp(dev->name, "icssg1-eth"))
> +		return 1;
> +	else if (!strcmp(dev->name, "icssg0-eth"))
> +		return 0;
> +
> +	dev_err(dev, "Invalid icssg instance\n");
> +	return -EINVAL;
> +}
> +
> +static int icssg_get_pru_core_number(struct udevice *dev, int slice)
> +{
> +	int instance, num_r5_cores;
> +
> +	instance = icssg_get_instance(dev);
> +	if (instance < 0)
> +		return instance;
> +
> +	if (IS_ENABLED(CONFIG_REMOTEPROC_TI_K3_R5F))
> +		num_r5_cores = 2;
> +
> +	return num_r5_cores +
> +	       instance * PRU_TYPE_MAX * PRUETH_NUM_MACS +
> +	       slice * PRU_TYPE_MAX;

All this doesn't look right. What we need is the rproc device
that matches the PRU/RTU rprocs that we are interested in.

The DT already has this information

		ti,prus = <&pru2_0>, <&rtu2_0>, <&tx_pru2_0>,
			<&pru2_1>, <&rtu2_1>, <&tx_pru2_1>;


All the current rproc APIs use the below to get rproc device from ID
ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev);

You just need to introduce APIs that takes rproc device directly as argument.

In your driver you can call uclass_get_device_by_phandle_id() to get the
rproc device from the rproc phandle?


> +}
> +
> +int icssg_start_pru_cores(struct udevice *dev)
> +{
> +	struct prueth *prueth = dev_get_priv(dev);
> +	struct icssg_firmwares *firmwares;
> +	u32 pru_fw_loadaddr = 0x80000000;
> +	u32 rtu_fw_loadaddr = 0x89000000;
> +	u32 txpru_fw_loadaddr = 0x90000000;

Please avoid hardcoding. You can use malloc to get a temporary buffer area?

Why do you need 3 different addresses?
Once you do a rproc_load isn't the buffer already copied to rproc's memory
so you can discard it or use it for the other rprocs?

> +	int slice, ret, core_id;
> +
> +	firmwares = icssg_emac_firmwares;
> +	slice = prueth->slice;
> +
> +	core_id = icssg_get_pru_core_number(dev, slice);
> +	if (core_id < 0)
> +		return core_id;
> +
> +	/* Initialize all rproc cores */
> +	rproc_init();
> +
> +	/* Loading PRU firmware to PRU core */
> +	ret = load_firmware(firmwares[slice].pru, &pru_fw_loadaddr);

On Linux, loading the firmware is the responsibility of the rproc driver.
Shouldn't it be the same in u-boot?

> +
> +	if (ret < 0) {
> +		dev_err(dev, "Unable to load_firmware %s at addr 0x%x err %d\n",
> +			firmwares[slice].pru, pru_fw_loadaddr, ret);
> +		return ret;
> +	}
> +
> +	dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d Bytes\n",
> +		firmwares[slice].pru, pru_fw_loadaddr, ret);

dev_dbg() here an at all dev_info().

> +	rproc_load(core_id + PRU_TYPE_PRU, pru_fw_loadaddr, ret);
> +
> +	/* Loading RTU firmware to RTU core */
> +	ret = load_firmware(firmwares[slice].rtu, &rtu_fw_loadaddr);
> +
> +	if (ret < 0) {
> +		dev_err(dev, "Unable to load_firmware %s at addr 0x%x err %d\n",
> +			firmwares[slice].rtu, rtu_fw_loadaddr, ret);
> +		return ret;
> +	}
> +
> +	dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d Bytes\n",
> +		firmwares[slice].rtu, rtu_fw_loadaddr, ret);
> +	rproc_load(core_id + PRU_TYPE_RTU, rtu_fw_loadaddr, ret);
> +
> +	/* Loading TX_PRU firmware to TX_PRU core */
> +	ret = load_firmware(firmwares[slice].txpru, &txpru_fw_loadaddr);
> +
> +	if (ret < 0) {
> +		dev_err(dev, "Unable to load_firmware %s at addr 0x%x err %d\n",
> +			firmwares[slice].txpru, txpru_fw_loadaddr, ret);
> +		return ret;
> +	}
> +
> +	dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d Bytes\n",
> +		firmwares[slice].txpru, txpru_fw_loadaddr, ret);
> +	rproc_load(core_id + PRU_TYPE_TX_PRU, txpru_fw_loadaddr, ret);
> +
> +	ret = rproc_start(core_id + PRU_TYPE_PRU);
> +	if (ret) {
> +		dev_err(dev, "failed to start PRU%d: %d\n", slice, ret);
> +		return ret;
> +	}
> +
> +	ret = rproc_start(core_id + PRU_TYPE_RTU);
> +	if (ret) {
> +		dev_err(dev, "failed to start RTU%d: %d\n", slice, ret);
> +		goto halt_pru;
> +	}
> +
> +	ret = rproc_start(core_id + PRU_TYPE_TX_PRU);
> +	if (ret) {
> +		dev_err(dev, "failed to start TX_PRU%d: %d\n", slice, ret);
> +		goto halt_rtu;
> +	}
> +
> +	return 0;
> +
> +halt_rtu:
> +	rproc_stop(core_id + PRU_TYPE_RTU);
> +
> +halt_pru:
> +	rproc_stop(PRU_TYPE_PRU);
> +	return ret;
> +}
> +
> +int icssg_stop_pru_cores(struct udevice *dev)
> +{
> +	struct prueth *prueth = dev_get_priv(dev);
> +	int slice, core_id;
> +
> +	slice = prueth->slice;
> +
> +	core_id = icssg_get_pru_core_number(dev, slice);
> +	if (core_id < 0)
> +		return core_id;
> +
> +	rproc_stop(core_id + PRU_TYPE_PRU);
> +	rproc_stop(core_id + PRU_TYPE_RTU);
> +	rproc_stop(core_id + PRU_TYPE_TX_PRU);
> +
> +	return 0;
> +}
> +
>  static int prueth_probe(struct udevice *dev)
>  {
>  	ofnode eth_ports_node, eth0_node, eth1_node, eth_node;
> diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h
> index 25272e850e..f17fe8bf58 100644
> --- a/include/linux/pruss_driver.h
> +++ b/include/linux/pruss_driver.h
> @@ -114,6 +114,21 @@ enum pru_ctable_idx {
>  	PRU_C31,
>  };
> 
> +/**
> + * 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
>   */
> 
> with this diff, user don't need to run any extra commands at u-boot.
> Once u-boot prompt is reached, just running ping / dhcp will suffice.
> 
Great!

<snip>

-- 
cheers,
-roger

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
  2023-12-20  9:59 ` Roger Quadros
@ 2023-12-22 10:26   ` MD Danish Anwar
  2023-12-22 12:43     ` Roger Quadros
  0 siblings, 1 reply; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-22 10:26 UTC (permalink / raw)
  To: Roger Quadros, Maxime Ripard, Siddharth Vadapalli,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Hi Roger,

On 20/12/23 3:29 pm, Roger Quadros wrote:
> Hi,
> 
> On 19/12/2023 12:11, MD Danish Anwar wrote:
>> Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used in TI
>> AM654 SR2.0.
>>
>> The ICSSG PRU Sub-system runs on EMAC firmware. This series Introduces
>> support for ICSSG driver in uboot. This series also adds the driver's
>> dependencies.
>>
>> The ICSSG2 node is added in device tree overlay so that it remains in
>> sync with linux kernel.
>>
>> The series introduces device tree and config changes and AM65x
>> to enable ICSSG driver. The series also enables SPL_LOAD_FIT_APPLY_OVERLAY
>> for AM65x in order to load overlay over spl.
>>
>> This series has been tested on AM65x SR2.0, and the ICSSG interface is
>> able to ping / dhcp and boot kernel using tftp in uboot.
>>
>> To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to PRU RPROC
>> cores and RPROC cores need to be booted with the firmware. This step is
>> done inside driver in kernel as kernel supports APIs like
>> rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't have these
>> APIs, the same needs to be done via u-boot cmds.
>>
>> To make sure icssg-eth works we need to do below steps.
>>
>> 1. Initialize rproc cores i.e. rproc_init()
>> 2. Load $firmware_file from partition '1:2' (root) on device (mmc in this
>>    example)
>> 3. Load the firmware file to rproc cores passing. i.e. rproc_load()
>>    taking rproc_id, loadaddr and file size as arguments.
>> 4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments
>>
>> The above steps are done by running the below commands at u-boot prompt.
>>
>> => setenv start_icssg2 'rproc start 14; rproc start 15; rproc start 16; rproc start 17; rproc start 18; rproc start 19'
>> => setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop 16; rproc stop 17; rproc stop 18; rproc stop 19'
>> => setenv firmware_dir '/lib/firmware/ti-pruss'
>> => setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr} ${firmware_dir}/${firmware_file}'
>>
>> => setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload no; rproc init; setenv loadaddr 0x80000000; \
>>     setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
>>     setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15 0x89000000 ${filesize}; \
>>     setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load 16 0x90000000 ${filesize}; \
>>     setenv loadaddr 0x80000000; setenv firmware_file am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17 0x80000000 ${filesize}; \
>>     setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18 0x89000000 ${filesize}; \
>>     setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load 19 0x90000000 ${filesize}; \
>>     run start_icssg2;'
> 
> A whole bunch of commands are required to get ethernet functional.
> This is not at all user friendly and will be a maintenance nightmare.
> What worries me is tracking the 6 different rproc cores and the 6 different firmware files to start 1 ethernet device.
> This will get even more interesting when we have to deal with different ICSSG instances on different boards.
> 
> What is preventing the driver from starting the rproc cores it needs so user doesn't need to care about it?
> All the necessary information is in the Device tree. At least this is how it is done on Linux.
> 

I tried removing the need for these commands and implementing them
inside the driver only. I am able to load the firmware from driver using
the fs_loader API request_firmware_into_buf(). It requires changes to
dt. A DT node called fs-loader needs to be added also CONFIG_FS_LOADER
needs to enabled. In the DT node we need to specify the storage media
that we are using i.e. mmc, ospi, usb. It's upto user to modify the
storage media, the driver will take the media from DT and try to laod
firmware from their.

For loading firmwares to rproc cores, rproc_load() API is needed. Now
this API takes rproc_id, loadaddr and firmware_size as arguments.
loadaddr is fixed for all three pru cores. firmware_size is obtained
from request_firmware_into_buf() but I couldn't find a way to get the
rproc_id. For now based on the ICSSG instance and slice number I am
figuring out the rproc_id and passing it to rproc_load() and
rproc_start() APIs. Please let me know if you have any other / better
way of finding rproc_id.

Below is the entire diff to remove these commands and move their
functionality to driver. Please have a look and let me know if this is ok.


Save New Duplicate & Edit Just Text Twitter
diff --git a/arch/arm/dts/k3-am654-base-board.dts
b/arch/arm/dts/k3-am654-base-board.dts
index cfbcebfa37..c8da72e49c 100644
--- a/arch/arm/dts/k3-am654-base-board.dts
+++ b/arch/arm/dts/k3-am654-base-board.dts
@@ -16,6 +16,13 @@
 	chosen {
 		stdout-path = "serial2:115200n8";
 		bootargs = "earlycon=ns16550a,mmio32,0x02800000";
+		firmware-loader = <&fs_loader0>;
+	};
+
+	fs_loader0: fs-loader {
+		bootph-all;
+		compatible = "u-boot,fs-loader";
+		phandlepart = <&sdhci1 2>;
 	};

 	memory@80000000 {
diff --git a/configs/am65x_evm_a53_defconfig
b/configs/am65x_evm_a53_defconfig
index 2755d7082f..c53e938abb 100644
--- a/configs/am65x_evm_a53_defconfig
+++ b/configs/am65x_evm_a53_defconfig
@@ -112,6 +112,7 @@ CONFIG_DM_I2C_GPIO=y
 CONFIG_SYS_I2C_OMAP24XX=y
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
+CONFIG_FS_LOADER=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_IO_VOLTAGE=y
 CONFIG_MMC_UHS_SUPPORT=y
diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig
index b2f1e721b3..2d19935a41 100644
--- a/configs/am65x_evm_r5_defconfig
+++ b/configs/am65x_evm_r5_defconfig
@@ -98,6 +98,7 @@ CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 CONFIG_SYS_I2C_OMAP24XX=y
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
+CONFIG_FS_LOADER=y
 CONFIG_K3_AVS0=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_HS200_SUPPORT=y
diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
index 40ad827e49..1c4edeb7b7 100644
--- a/drivers/net/ti/icssg_prueth.c
+++ b/drivers/net/ti/icssg_prueth.c
@@ -227,6 +227,10 @@ static int prueth_start(struct udevice *dev)
 	void *config;
 	int ret, i;

+	ret = icssg_start_pru_cores(dev);
+	if (ret)
+		return ret;
+
 	/* To differentiate channels for SLICE0 vs SLICE1 */
 	snprintf(chn_name, sizeof(chn_name), "tx%d-0", priv->slice);

@@ -355,9 +359,11 @@ static void prueth_stop(struct udevice *dev)
 	phy_shutdown(priv->phydev);

 	dma_disable(&priv->dma_tx);
-	dma_free(&priv->dma_tx);
-
 	dma_disable(&priv->dma_rx);
+
+	icssg_stop_pru_cores(dev);
+
+	dma_free(&priv->dma_tx);
 	dma_free(&priv->dma_rx);
 }

@@ -434,6 +440,181 @@ static const struct soc_attr k3_mdio_soc_data[] = {
 	{ /* sentinel */ },
 };

+struct icssg_firmware_load_address {
+	u32 pru;
+	u32 rtu;
+	u32 txpru;
+};
+
+struct icssg_firmwares {
+	char *pru;
+	char *rtu;
+	char *txpru;
+};
+
+static struct icssg_firmwares icssg_emac_firmwares[] = {
+	{
+		.pru = "/lib/firmware/ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
+		.rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
+		.txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
+	},
+	{
+		.pru = "/lib/firmware/ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
+		.rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
+		.txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru1-prueth-fw.elf",
+	}
+};
+
+int load_firmware(char *name_fw, u32 *loadaddr)
+{
+	struct udevice *fsdev;
+	int size = 0;
+
+	if (!IS_ENABLED(CONFIG_FS_LOADER))
+		return -EINVAL;
+
+	if (!*loadaddr)
+		return -EINVAL;
+
+	if (!get_fs_loader(&fsdev))
+		size = request_firmware_into_buf(fsdev, name_fw, (void *)*loadaddr,
40524, 0);
+
+	return size;
+}
+
+static int icssg_get_instance(struct udevice *dev)
+{
+	if (!strcmp(dev->name, "icssg2-eth"))
+		return 2;
+	else if (!strcmp(dev->name, "icssg1-eth"))
+		return 1;
+	else if (!strcmp(dev->name, "icssg0-eth"))
+		return 0;
+
+	dev_err(dev, "Invalid icssg instance\n");
+	return -EINVAL;
+}
+
+static int icssg_get_pru_core_number(struct udevice *dev, int slice)
+{
+	int instance, num_r5_cores;
+
+	instance = icssg_get_instance(dev);
+	if (instance < 0)
+		return instance;
+
+	if (IS_ENABLED(CONFIG_REMOTEPROC_TI_K3_R5F))
+		num_r5_cores = 2;
+
+	return num_r5_cores +
+	       instance * PRU_TYPE_MAX * PRUETH_NUM_MACS +
+	       slice * PRU_TYPE_MAX;
+}
+
+int icssg_start_pru_cores(struct udevice *dev)
+{
+	struct prueth *prueth = dev_get_priv(dev);
+	struct icssg_firmwares *firmwares;
+	u32 pru_fw_loadaddr = 0x80000000;
+	u32 rtu_fw_loadaddr = 0x89000000;
+	u32 txpru_fw_loadaddr = 0x90000000;
+	int slice, ret, core_id;
+
+	firmwares = icssg_emac_firmwares;
+	slice = prueth->slice;
+
+	core_id = icssg_get_pru_core_number(dev, slice);
+	if (core_id < 0)
+		return core_id;
+
+	/* Initialize all rproc cores */
+	rproc_init();
+
+	/* Loading PRU firmware to PRU core */
+	ret = load_firmware(firmwares[slice].pru, &pru_fw_loadaddr);
+
+	if (ret < 0) {
+		dev_err(dev, "Unable to load_firmware %s at addr 0x%x err %d\n",
+			firmwares[slice].pru, pru_fw_loadaddr, ret);
+		return ret;
+	}
+
+	dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d Bytes\n",
+		firmwares[slice].pru, pru_fw_loadaddr, ret);
+	rproc_load(core_id + PRU_TYPE_PRU, pru_fw_loadaddr, ret);
+
+	/* Loading RTU firmware to RTU core */
+	ret = load_firmware(firmwares[slice].rtu, &rtu_fw_loadaddr);
+
+	if (ret < 0) {
+		dev_err(dev, "Unable to load_firmware %s at addr 0x%x err %d\n",
+			firmwares[slice].rtu, rtu_fw_loadaddr, ret);
+		return ret;
+	}
+
+	dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d Bytes\n",
+		firmwares[slice].rtu, rtu_fw_loadaddr, ret);
+	rproc_load(core_id + PRU_TYPE_RTU, rtu_fw_loadaddr, ret);
+
+	/* Loading TX_PRU firmware to TX_PRU core */
+	ret = load_firmware(firmwares[slice].txpru, &txpru_fw_loadaddr);
+
+	if (ret < 0) {
+		dev_err(dev, "Unable to load_firmware %s at addr 0x%x err %d\n",
+			firmwares[slice].txpru, txpru_fw_loadaddr, ret);
+		return ret;
+	}
+
+	dev_info(dev, "Loaded FW %s successfully at addr 0x%x Size = %d Bytes\n",
+		firmwares[slice].txpru, txpru_fw_loadaddr, ret);
+	rproc_load(core_id + PRU_TYPE_TX_PRU, txpru_fw_loadaddr, ret);
+
+	ret = rproc_start(core_id + PRU_TYPE_PRU);
+	if (ret) {
+		dev_err(dev, "failed to start PRU%d: %d\n", slice, ret);
+		return ret;
+	}
+
+	ret = rproc_start(core_id + PRU_TYPE_RTU);
+	if (ret) {
+		dev_err(dev, "failed to start RTU%d: %d\n", slice, ret);
+		goto halt_pru;
+	}
+
+	ret = rproc_start(core_id + PRU_TYPE_TX_PRU);
+	if (ret) {
+		dev_err(dev, "failed to start TX_PRU%d: %d\n", slice, ret);
+		goto halt_rtu;
+	}
+
+	return 0;
+
+halt_rtu:
+	rproc_stop(core_id + PRU_TYPE_RTU);
+
+halt_pru:
+	rproc_stop(PRU_TYPE_PRU);
+	return ret;
+}
+
+int icssg_stop_pru_cores(struct udevice *dev)
+{
+	struct prueth *prueth = dev_get_priv(dev);
+	int slice, core_id;
+
+	slice = prueth->slice;
+
+	core_id = icssg_get_pru_core_number(dev, slice);
+	if (core_id < 0)
+		return core_id;
+
+	rproc_stop(core_id + PRU_TYPE_PRU);
+	rproc_stop(core_id + PRU_TYPE_RTU);
+	rproc_stop(core_id + PRU_TYPE_TX_PRU);
+
+	return 0;
+}
+
 static int prueth_probe(struct udevice *dev)
 {
 	ofnode eth_ports_node, eth0_node, eth1_node, eth_node;
diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h
index 25272e850e..f17fe8bf58 100644
--- a/include/linux/pruss_driver.h
+++ b/include/linux/pruss_driver.h
@@ -114,6 +114,21 @@ enum pru_ctable_idx {
 	PRU_C31,
 };

+/**
+ * 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
  */

with this diff, user don't need to run any extra commands at u-boot.
Once u-boot prompt is reached, just running ping / dhcp will suffice.

>>
>> => run init_icssg2
>> => dhcp
>> k3-navss-ringacc ringacc@3c000000: Ring Accelerator probed rings:818, gp-rings[304,100] sci-dev-id:187
>> k3-navss-ringacc ringacc@3c000000: dma-ring-reset-quirk: disabled
>> prueth icssg2-eth: K3 ICSSG: rflow_id_base: 8, chn_name = rx0
>> link up on port 0, speed 1000, full duplex
>> BOOTP broadcast 1
>> BOOTP broadcast 2
>> BOOTP broadcast 3
>> DHCP client bound to address 192.168.4.58 (1020 ms)
>>
> 
> What about shutting down the interface?
> I believe this has to be done manually too?
> 

Yes that is also needed.

>> Thanks and Regards,
>> MD Danish Anwar
>>
>> MD Danish Anwar (16):
>>   net: ti: icssg: Add Firmware Interface for ICSSG Ethernet driver.
>>   net: ti: icssg: Add Firmware config and classification APIs.
>>   net: ti: icssg: Add icssg queues APIs and macros
>>   net: ti: icssg: Add ICSSG ethernet driver
>>   net: ti: icssg: Add support sending FDB command to update rx_flow_id
>>   net: ti: icssg: Enforce pinctrl state on the MDIO child node
>>   arm: dts: k3-am65: Add additional regs for DMA components
>>   arm: dts: k3-am65: Add cfg reg region to ringacc node
>>   arm: dts: k3-am65-main: Add ICSSG IEP nodes
>>   arm: dts: k3-am654-base-board: Add ICSSG2 Ethernet support
>>   arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration
>>   configs: am65x_evm_a53: Enable ICSSG Driver
>>   configs: am65x_evm_a53_defconfig: add SPL_LOAD_FIT_APPLY_OVERLAY
>>   tools/fdtgrep: Include __symbols__ table
>>   board: ti: am65x: Add check for k3-am654-icssg2 in
>>     board_fit_config_match()
>>   Revert "dm: core: Report bootph-pre-ram/sram node as pre-reloc after
>>     relocation"
>>
>>  arch/arm/dts/Makefile             |   3 +-
>>  arch/arm/dts/k3-am65-main.dtsi    |  49 ++-
>>  arch/arm/dts/k3-am65-mcu.dtsi     |  13 +-
>>  arch/arm/dts/k3-am654-icssg2.dtso | 145 +++++++
>>  arch/arm/dts/k3-am65x-binman.dtsi |  85 ++++
>>  board/ti/am65x/evm.c              |  11 +-
>>  configs/am65x_evm_a53_defconfig   |   4 +
>>  drivers/core/ofnode.c             |   2 +-
>>  drivers/net/ti/Kconfig            |   9 +
>>  drivers/net/ti/Makefile           |   1 +
>>  drivers/net/ti/icss_mii_rt.h      | 192 +++++++++
>>  drivers/net/ti/icssg_classifier.c | 376 +++++++++++++++++
>>  drivers/net/ti/icssg_config.c     | 469 +++++++++++++++++++++
>>  drivers/net/ti/icssg_config.h     | 195 +++++++++
>>  drivers/net/ti/icssg_prueth.c     | 654 ++++++++++++++++++++++++++++++
>>  drivers/net/ti/icssg_prueth.h     |  89 ++++
>>  drivers/net/ti/icssg_queues.c     |  51 +++
>>  drivers/net/ti/icssg_switch_map.h | 209 ++++++++++
>>  include/dm/ofnode.h               |   8 +-
>>  tools/fdtgrep.c                   |   8 +
>>  20 files changed, 2555 insertions(+), 18 deletions(-)
>>  create mode 100644 arch/arm/dts/k3-am654-icssg2.dtso
>>  create mode 100644 drivers/net/ti/icss_mii_rt.h
>>  create mode 100644 drivers/net/ti/icssg_classifier.c
>>  create mode 100644 drivers/net/ti/icssg_config.c
>>  create mode 100644 drivers/net/ti/icssg_config.h
>>  create mode 100644 drivers/net/ti/icssg_prueth.c
>>  create mode 100644 drivers/net/ti/icssg_prueth.h
>>  create mode 100644 drivers/net/ti/icssg_queues.c
>>  create mode 100644 drivers/net/ti/icssg_switch_map.h
>>
>> base:commit: a6f86132e30a407c7f96461df53c62fbe52e2b54
> 

-- 
Thanks and Regards,
Danish

^ permalink raw reply related	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
  2023-12-19 10:11 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
  2023-12-19 10:30 ` MD Danish Anwar
@ 2023-12-20  9:59 ` Roger Quadros
  2023-12-22 10:26   ` MD Danish Anwar
  1 sibling, 1 reply; 48+ messages in thread
From: Roger Quadros @ 2023-12-20  9:59 UTC (permalink / raw)
  To: MD Danish Anwar, Maxime Ripard, Siddharth Vadapalli,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Hi,

On 19/12/2023 12:11, MD Danish Anwar wrote:
> Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used in TI
> AM654 SR2.0.
> 
> The ICSSG PRU Sub-system runs on EMAC firmware. This series Introduces
> support for ICSSG driver in uboot. This series also adds the driver's
> dependencies.
> 
> The ICSSG2 node is added in device tree overlay so that it remains in
> sync with linux kernel.
> 
> The series introduces device tree and config changes and AM65x
> to enable ICSSG driver. The series also enables SPL_LOAD_FIT_APPLY_OVERLAY
> for AM65x in order to load overlay over spl.
> 
> This series has been tested on AM65x SR2.0, and the ICSSG interface is
> able to ping / dhcp and boot kernel using tftp in uboot.
> 
> To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to PRU RPROC
> cores and RPROC cores need to be booted with the firmware. This step is
> done inside driver in kernel as kernel supports APIs like
> rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't have these
> APIs, the same needs to be done via u-boot cmds.
> 
> To make sure icssg-eth works we need to do below steps.
> 
> 1. Initialize rproc cores i.e. rproc_init()
> 2. Load $firmware_file from partition '1:2' (root) on device (mmc in this
>    example)
> 3. Load the firmware file to rproc cores passing. i.e. rproc_load()
>    taking rproc_id, loadaddr and file size as arguments.
> 4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments
> 
> The above steps are done by running the below commands at u-boot prompt.
> 
> => setenv start_icssg2 'rproc start 14; rproc start 15; rproc start 16; rproc start 17; rproc start 18; rproc start 19'
> => setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop 16; rproc stop 17; rproc stop 18; rproc stop 19'
> => setenv firmware_dir '/lib/firmware/ti-pruss'
> => setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr} ${firmware_dir}/${firmware_file}'
> 
> => setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload no; rproc init; setenv loadaddr 0x80000000; \
>     setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
>     setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15 0x89000000 ${filesize}; \
>     setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load 16 0x90000000 ${filesize}; \
>     setenv loadaddr 0x80000000; setenv firmware_file am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17 0x80000000 ${filesize}; \
>     setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18 0x89000000 ${filesize}; \
>     setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load 19 0x90000000 ${filesize}; \
>     run start_icssg2;'

A whole bunch of commands are required to get ethernet functional.
This is not at all user friendly and will be a maintenance nightmare.
What worries me is tracking the 6 different rproc cores and the 6 different firmware files to start 1 ethernet device.
This will get even more interesting when we have to deal with different ICSSG instances on different boards.

What is preventing the driver from starting the rproc cores it needs so user doesn't need to care about it?
All the necessary information is in the Device tree. At least this is how it is done on Linux.

> 
> => run init_icssg2
> => dhcp
> k3-navss-ringacc ringacc@3c000000: Ring Accelerator probed rings:818, gp-rings[304,100] sci-dev-id:187
> k3-navss-ringacc ringacc@3c000000: dma-ring-reset-quirk: disabled
> prueth icssg2-eth: K3 ICSSG: rflow_id_base: 8, chn_name = rx0
> link up on port 0, speed 1000, full duplex
> BOOTP broadcast 1
> BOOTP broadcast 2
> BOOTP broadcast 3
> DHCP client bound to address 192.168.4.58 (1020 ms)
> 

What about shutting down the interface?
I believe this has to be done manually too?

> Thanks and Regards,
> MD Danish Anwar
> 
> MD Danish Anwar (16):
>   net: ti: icssg: Add Firmware Interface for ICSSG Ethernet driver.
>   net: ti: icssg: Add Firmware config and classification APIs.
>   net: ti: icssg: Add icssg queues APIs and macros
>   net: ti: icssg: Add ICSSG ethernet driver
>   net: ti: icssg: Add support sending FDB command to update rx_flow_id
>   net: ti: icssg: Enforce pinctrl state on the MDIO child node
>   arm: dts: k3-am65: Add additional regs for DMA components
>   arm: dts: k3-am65: Add cfg reg region to ringacc node
>   arm: dts: k3-am65-main: Add ICSSG IEP nodes
>   arm: dts: k3-am654-base-board: Add ICSSG2 Ethernet support
>   arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration
>   configs: am65x_evm_a53: Enable ICSSG Driver
>   configs: am65x_evm_a53_defconfig: add SPL_LOAD_FIT_APPLY_OVERLAY
>   tools/fdtgrep: Include __symbols__ table
>   board: ti: am65x: Add check for k3-am654-icssg2 in
>     board_fit_config_match()
>   Revert "dm: core: Report bootph-pre-ram/sram node as pre-reloc after
>     relocation"
> 
>  arch/arm/dts/Makefile             |   3 +-
>  arch/arm/dts/k3-am65-main.dtsi    |  49 ++-
>  arch/arm/dts/k3-am65-mcu.dtsi     |  13 +-
>  arch/arm/dts/k3-am654-icssg2.dtso | 145 +++++++
>  arch/arm/dts/k3-am65x-binman.dtsi |  85 ++++
>  board/ti/am65x/evm.c              |  11 +-
>  configs/am65x_evm_a53_defconfig   |   4 +
>  drivers/core/ofnode.c             |   2 +-
>  drivers/net/ti/Kconfig            |   9 +
>  drivers/net/ti/Makefile           |   1 +
>  drivers/net/ti/icss_mii_rt.h      | 192 +++++++++
>  drivers/net/ti/icssg_classifier.c | 376 +++++++++++++++++
>  drivers/net/ti/icssg_config.c     | 469 +++++++++++++++++++++
>  drivers/net/ti/icssg_config.h     | 195 +++++++++
>  drivers/net/ti/icssg_prueth.c     | 654 ++++++++++++++++++++++++++++++
>  drivers/net/ti/icssg_prueth.h     |  89 ++++
>  drivers/net/ti/icssg_queues.c     |  51 +++
>  drivers/net/ti/icssg_switch_map.h | 209 ++++++++++
>  include/dm/ofnode.h               |   8 +-
>  tools/fdtgrep.c                   |   8 +
>  20 files changed, 2555 insertions(+), 18 deletions(-)
>  create mode 100644 arch/arm/dts/k3-am654-icssg2.dtso
>  create mode 100644 drivers/net/ti/icss_mii_rt.h
>  create mode 100644 drivers/net/ti/icssg_classifier.c
>  create mode 100644 drivers/net/ti/icssg_config.c
>  create mode 100644 drivers/net/ti/icssg_config.h
>  create mode 100644 drivers/net/ti/icssg_prueth.c
>  create mode 100644 drivers/net/ti/icssg_prueth.h
>  create mode 100644 drivers/net/ti/icssg_queues.c
>  create mode 100644 drivers/net/ti/icssg_switch_map.h
> 
> base:commit: a6f86132e30a407c7f96461df53c62fbe52e2b54

-- 
cheers,
-roger

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
  2023-12-19 10:11 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
@ 2023-12-19 10:30 ` MD Danish Anwar
  2023-12-20  9:59 ` Roger Quadros
  1 sibling, 0 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:30 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, Ramon Fried, Joe Hershberger, Simon Glass,
	Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Hi All,

Please ignore this thread. Some mails seems to have been duplicated.
I will post another thread soon. Pls ignore this.
Sorry for the inconvenience.

On 19/12/23 3:41 pm, MD Danish Anwar wrote:
> Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used in TI
> AM654 SR2.0.
> 
> The ICSSG PRU Sub-system runs on EMAC firmware. This series Introduces
> support for ICSSG driver in uboot. This series also adds the driver's
> dependencies.
> 
> The ICSSG2 node is added in device tree overlay so that it remains in
> sync with linux kernel.
> 
> The series introduces device tree and config changes and AM65x
> to enable ICSSG driver. The series also enables SPL_LOAD_FIT_APPLY_OVERLAY
> for AM65x in order to load overlay over spl.
> 
> This series has been tested on AM65x SR2.0, and the ICSSG interface is
> able to ping / dhcp and boot kernel using tftp in uboot.
> 
> To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to PRU RPROC
> cores and RPROC cores need to be booted with the firmware. This step is
> done inside driver in kernel as kernel supports APIs like
> rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't have these
> APIs, the same needs to be done via u-boot cmds.
> 
> To make sure icssg-eth works we need to do below steps.
> 
> 1. Initialize rproc cores i.e. rproc_init()
> 2. Load $firmware_file from partition '1:2' (root) on device (mmc in this
>    example)
> 3. Load the firmware file to rproc cores passing. i.e. rproc_load()
>    taking rproc_id, loadaddr and file size as arguments.
> 4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments
> 
> The above steps are done by running the below commands at u-boot prompt.
> 
> => setenv start_icssg2 'rproc start 14; rproc start 15; rproc start 16; rproc start 17; rproc start 18; rproc start 19'
> => setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop 16; rproc stop 17; rproc stop 18; rproc stop 19'
> => setenv firmware_dir '/lib/firmware/ti-pruss'
> => setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr} ${firmware_dir}/${firmware_file}'
> 
> => setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload no; rproc init; setenv loadaddr 0x80000000; \
>     setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
>     setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15 0x89000000 ${filesize}; \
>     setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load 16 0x90000000 ${filesize}; \
>     setenv loadaddr 0x80000000; setenv firmware_file am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17 0x80000000 ${filesize}; \
>     setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18 0x89000000 ${filesize}; \
>     setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load 19 0x90000000 ${filesize}; \
>     run start_icssg2;'
> 
> => run init_icssg2
> => dhcp
> k3-navss-ringacc ringacc@3c000000: Ring Accelerator probed rings:818, gp-rings[304,100] sci-dev-id:187
> k3-navss-ringacc ringacc@3c000000: dma-ring-reset-quirk: disabled
> prueth icssg2-eth: K3 ICSSG: rflow_id_base: 8, chn_name = rx0
> link up on port 0, speed 1000, full duplex
> BOOTP broadcast 1
> BOOTP broadcast 2
> BOOTP broadcast 3
> DHCP client bound to address 192.168.4.58 (1020 ms)
> 
> Thanks and Regards,
> MD Danish Anwar
> 
> MD Danish Anwar (16):
>   net: ti: icssg: Add Firmware Interface for ICSSG Ethernet driver.
>   net: ti: icssg: Add Firmware config and classification APIs.
>   net: ti: icssg: Add icssg queues APIs and macros
>   net: ti: icssg: Add ICSSG ethernet driver
>   net: ti: icssg: Add support sending FDB command to update rx_flow_id
>   net: ti: icssg: Enforce pinctrl state on the MDIO child node
>   arm: dts: k3-am65: Add additional regs for DMA components
>   arm: dts: k3-am65: Add cfg reg region to ringacc node
>   arm: dts: k3-am65-main: Add ICSSG IEP nodes
>   arm: dts: k3-am654-base-board: Add ICSSG2 Ethernet support
>   arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration
>   configs: am65x_evm_a53: Enable ICSSG Driver
>   configs: am65x_evm_a53_defconfig: add SPL_LOAD_FIT_APPLY_OVERLAY
>   tools/fdtgrep: Include __symbols__ table
>   board: ti: am65x: Add check for k3-am654-icssg2 in
>     board_fit_config_match()
>   Revert "dm: core: Report bootph-pre-ram/sram node as pre-reloc after
>     relocation"
> 
>  arch/arm/dts/Makefile             |   3 +-
>  arch/arm/dts/k3-am65-main.dtsi    |  49 ++-
>  arch/arm/dts/k3-am65-mcu.dtsi     |  13 +-
>  arch/arm/dts/k3-am654-icssg2.dtso | 145 +++++++
>  arch/arm/dts/k3-am65x-binman.dtsi |  85 ++++
>  board/ti/am65x/evm.c              |  11 +-
>  configs/am65x_evm_a53_defconfig   |   4 +
>  drivers/core/ofnode.c             |   2 +-
>  drivers/net/ti/Kconfig            |   9 +
>  drivers/net/ti/Makefile           |   1 +
>  drivers/net/ti/icss_mii_rt.h      | 192 +++++++++
>  drivers/net/ti/icssg_classifier.c | 376 +++++++++++++++++
>  drivers/net/ti/icssg_config.c     | 469 +++++++++++++++++++++
>  drivers/net/ti/icssg_config.h     | 195 +++++++++
>  drivers/net/ti/icssg_prueth.c     | 654 ++++++++++++++++++++++++++++++
>  drivers/net/ti/icssg_prueth.h     |  89 ++++
>  drivers/net/ti/icssg_queues.c     |  51 +++
>  drivers/net/ti/icssg_switch_map.h | 209 ++++++++++
>  include/dm/ofnode.h               |   8 +-
>  tools/fdtgrep.c                   |   8 +
>  20 files changed, 2555 insertions(+), 18 deletions(-)
>  create mode 100644 arch/arm/dts/k3-am654-icssg2.dtso
>  create mode 100644 drivers/net/ti/icss_mii_rt.h
>  create mode 100644 drivers/net/ti/icssg_classifier.c
>  create mode 100644 drivers/net/ti/icssg_config.c
>  create mode 100644 drivers/net/ti/icssg_config.h
>  create mode 100644 drivers/net/ti/icssg_prueth.c
>  create mode 100644 drivers/net/ti/icssg_prueth.h
>  create mode 100644 drivers/net/ti/icssg_queues.c
>  create mode 100644 drivers/net/ti/icssg_switch_map.h
> 
> base:commit: a6f86132e30a407c7f96461df53c62fbe52e2b54

-- 
Thanks and Regards,
Danish

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [RFC PATCH 00/16] Introduce ICSSG Ethernet driver
@ 2023-12-19 10:11 MD Danish Anwar
  2023-12-19 10:30 ` MD Danish Anwar
  2023-12-20  9:59 ` Roger Quadros
  0 siblings, 2 replies; 48+ messages in thread
From: MD Danish Anwar @ 2023-12-19 10:11 UTC (permalink / raw)
  To: Maxime Ripard, Siddharth Vadapalli, Roger Quadros,
	Nishanth Menon, Vignesh Raghavendra, Matthias Schiffer,
	Kamlesh Gurudasani, Manorit Chawdhry, Neha Malcom Francis,
	Andrew Davis, MD Danish Anwar, Ramon Fried, Joe Hershberger,
	Simon Glass, Tom Rini
  Cc: u-boot, srk, r-gunasekaran

Introduce ICSSG PRUETH support in uboot. The ICSSG driver is used in TI
AM654 SR2.0.

The ICSSG PRU Sub-system runs on EMAC firmware. This series Introduces
support for ICSSG driver in uboot. This series also adds the driver's
dependencies.

The ICSSG2 node is added in device tree overlay so that it remains in
sync with linux kernel.

The series introduces device tree and config changes and AM65x
to enable ICSSG driver. The series also enables SPL_LOAD_FIT_APPLY_OVERLAY
for AM65x in order to load overlay over spl.

This series has been tested on AM65x SR2.0, and the ICSSG interface is
able to ping / dhcp and boot kernel using tftp in uboot.

To use ICSSG2 ethernet, the ICSSG firmware needs to be loaded to PRU RPROC
cores and RPROC cores need to be booted with the firmware. This step is
done inside driver in kernel as kernel supports APIs like
rproc_set_firmware() and rproc_fw_boot(). But as u-boot doesn't have these
APIs, the same needs to be done via u-boot cmds.

To make sure icssg-eth works we need to do below steps.

1. Initialize rproc cores i.e. rproc_init()
2. Load $firmware_file from partition '1:2' (root) on device (mmc in this
   example)
3. Load the firmware file to rproc cores passing. i.e. rproc_load()
   taking rproc_id, loadaddr and file size as arguments.
4. Start rproc cores. i.e. rproc_start() taking rproc_id as arguments

The above steps are done by running the below commands at u-boot prompt.

=> setenv start_icssg2 'rproc start 14; rproc start 15; rproc start 16; rproc start 17; rproc start 18; rproc start 19'
=> setenv stop_icssg2 'rproc stop 14; rproc stop 15; rproc stop 16; rproc stop 17; rproc stop 18; rproc stop 19'
=> setenv firmware_dir '/lib/firmware/ti-pruss'
=> setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr} ${firmware_dir}/${firmware_file}'

=> setenv init_icssg2 'setenv ethact icssg2-eth; setenv autoload no; rproc init; setenv loadaddr 0x80000000; \
    setenv firmware_file am65x-sr2-pru0-prueth-fw.elf; run get_firmware_mmc;  rproc load 14 0x80000000 ${filesize}; \
    setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 15 0x89000000 ${filesize}; \
    setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru0-prueth-fw.elf; run get_firmware_mmc; rproc load 16 0x90000000 ${filesize}; \
    setenv loadaddr 0x80000000; setenv firmware_file am65x-sr2-pru1-prueth-fw.elf; run get_firmware_mmc; rproc load 17 0x80000000 ${filesize}; \
    setenv loadaddr 0x89000000; setenv firmware_file am65x-sr2-rtu1-prueth-fw.elf; run get_firmware_mmc; rproc load 18 0x89000000 ${filesize}; \
    setenv loadaddr 0x90000000; setenv firmware_file am65x-sr2-txpru1-prueth-fw.elf; run get_firmware_mmc; rproc load 19 0x90000000 ${filesize}; \
    run start_icssg2;'

=> run init_icssg2
=> dhcp
k3-navss-ringacc ringacc@3c000000: Ring Accelerator probed rings:818, gp-rings[304,100] sci-dev-id:187
k3-navss-ringacc ringacc@3c000000: dma-ring-reset-quirk: disabled
prueth icssg2-eth: K3 ICSSG: rflow_id_base: 8, chn_name = rx0
link up on port 0, speed 1000, full duplex
BOOTP broadcast 1
BOOTP broadcast 2
BOOTP broadcast 3
DHCP client bound to address 192.168.4.58 (1020 ms)

Thanks and Regards,
MD Danish Anwar

MD Danish Anwar (16):
  net: ti: icssg: Add Firmware Interface for ICSSG Ethernet driver.
  net: ti: icssg: Add Firmware config and classification APIs.
  net: ti: icssg: Add icssg queues APIs and macros
  net: ti: icssg: Add ICSSG ethernet driver
  net: ti: icssg: Add support sending FDB command to update rx_flow_id
  net: ti: icssg: Enforce pinctrl state on the MDIO child node
  arm: dts: k3-am65: Add additional regs for DMA components
  arm: dts: k3-am65: Add cfg reg region to ringacc node
  arm: dts: k3-am65-main: Add ICSSG IEP nodes
  arm: dts: k3-am654-base-board: Add ICSSG2 Ethernet support
  arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration
  configs: am65x_evm_a53: Enable ICSSG Driver
  configs: am65x_evm_a53_defconfig: add SPL_LOAD_FIT_APPLY_OVERLAY
  tools/fdtgrep: Include __symbols__ table
  board: ti: am65x: Add check for k3-am654-icssg2 in
    board_fit_config_match()
  Revert "dm: core: Report bootph-pre-ram/sram node as pre-reloc after
    relocation"

 arch/arm/dts/Makefile             |   3 +-
 arch/arm/dts/k3-am65-main.dtsi    |  49 ++-
 arch/arm/dts/k3-am65-mcu.dtsi     |  13 +-
 arch/arm/dts/k3-am654-icssg2.dtso | 145 +++++++
 arch/arm/dts/k3-am65x-binman.dtsi |  85 ++++
 board/ti/am65x/evm.c              |  11 +-
 configs/am65x_evm_a53_defconfig   |   4 +
 drivers/core/ofnode.c             |   2 +-
 drivers/net/ti/Kconfig            |   9 +
 drivers/net/ti/Makefile           |   1 +
 drivers/net/ti/icss_mii_rt.h      | 192 +++++++++
 drivers/net/ti/icssg_classifier.c | 376 +++++++++++++++++
 drivers/net/ti/icssg_config.c     | 469 +++++++++++++++++++++
 drivers/net/ti/icssg_config.h     | 195 +++++++++
 drivers/net/ti/icssg_prueth.c     | 654 ++++++++++++++++++++++++++++++
 drivers/net/ti/icssg_prueth.h     |  89 ++++
 drivers/net/ti/icssg_queues.c     |  51 +++
 drivers/net/ti/icssg_switch_map.h | 209 ++++++++++
 include/dm/ofnode.h               |   8 +-
 tools/fdtgrep.c                   |   8 +
 20 files changed, 2555 insertions(+), 18 deletions(-)
 create mode 100644 arch/arm/dts/k3-am654-icssg2.dtso
 create mode 100644 drivers/net/ti/icss_mii_rt.h
 create mode 100644 drivers/net/ti/icssg_classifier.c
 create mode 100644 drivers/net/ti/icssg_config.c
 create mode 100644 drivers/net/ti/icssg_config.h
 create mode 100644 drivers/net/ti/icssg_prueth.c
 create mode 100644 drivers/net/ti/icssg_prueth.h
 create mode 100644 drivers/net/ti/icssg_queues.c
 create mode 100644 drivers/net/ti/icssg_switch_map.h

base:commit: a6f86132e30a407c7f96461df53c62fbe52e2b54
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

end of thread, other threads:[~2024-01-10 11:42 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-19 10:34 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
2023-12-19 10:34 ` [RFC PATCH 01/16] dma: ti: k3-udma: Use ring_idx to pair k3 nav rings MD Danish Anwar
2023-12-19 10:34 ` [RFC PATCH 02/16] net: ti: icssg: Add Firmware Interface for ICSSG Ethernet driver MD Danish Anwar
2023-12-19 10:34 ` [RFC PATCH 03/16] net: ti: icssg: Add Firmware config and classification APIs MD Danish Anwar
2023-12-19 10:34 ` [RFC PATCH 04/16] net: ti: icssg: Add icssg queues APIs and macros MD Danish Anwar
2023-12-19 10:34 ` [RFC PATCH 05/16] net: ti: icssg: Add ICSSG ethernet driver MD Danish Anwar
2023-12-19 10:34 ` [RFC PATCH 06/16] net: ti: icssg: Add support sending FDB command to update rx_flow_id MD Danish Anwar
2023-12-19 10:34 ` [RFC PATCH 07/16] net: ti: icssg: Enforce pinctrl state on the MDIO child node MD Danish Anwar
2023-12-19 10:34 ` [RFC PATCH 08/16] arm: dts: k3-am65: Add additional regs for DMA components MD Danish Anwar
2023-12-19 10:34 ` [RFC PATCH 09/16] arm: dts: k3-am65: Add cfg reg region to ringacc node MD Danish Anwar
2023-12-19 10:34 ` [RFC PATCH 10/16] arm: dts: k3-am65-main: Add ICSSG IEP nodes MD Danish Anwar
2023-12-19 17:46   ` Tom Rini
2023-12-20  4:47     ` MD Danish Anwar
2023-12-20 12:52       ` Nishanth Menon
2023-12-20 13:23         ` Anwar, Md Danish
2023-12-19 10:34 ` [RFC PATCH 11/16] arm: dts: k3-am654-base-board: Add ICSSG2 Ethernet support MD Danish Anwar
2023-12-20 10:08   ` Roger Quadros
2023-12-20 10:13     ` Anwar, Md Danish
2023-12-19 10:34 ` [RFC PATCH 12/16] arm: dts: k3-am65x-binman: Add ICSSG2 overlay and configuration MD Danish Anwar
2023-12-20 10:40   ` Roger Quadros
2023-12-27 10:19     ` MD Danish Anwar
2024-01-10  6:50       ` MD Danish Anwar
2024-01-10  8:54         ` Roger Quadros
2024-01-10  9:02           ` MD Danish Anwar
2024-01-10 11:42             ` Roger Quadros
2023-12-19 10:34 ` [RFC PATCH 13/16] configs: am65x_evm_a53: Enable ICSSG Driver MD Danish Anwar
2023-12-19 10:34 ` [RFC PATCH 14/16] configs: am65x_evm_a53_defconfig: add SPL_LOAD_FIT_APPLY_OVERLAY MD Danish Anwar
2023-12-20 10:02   ` Roger Quadros
2023-12-21  5:57     ` MD Danish Anwar
2023-12-19 10:34 ` [RFC PATCH 15/16] tools/fdtgrep: Include __symbols__ table MD Danish Anwar
2023-12-26  9:47   ` Simon Glass
2024-01-10  9:52     ` MD Danish Anwar
2023-12-19 10:34 ` [RFC PATCH 16/16] board: ti: am65x: Add check for k3-am654-icssg2 in board_fit_config_match() MD Danish Anwar
  -- strict thread matches above, loose matches on Subject: below --
2023-12-19 10:11 [RFC PATCH 00/16] Introduce ICSSG Ethernet driver MD Danish Anwar
2023-12-19 10:30 ` MD Danish Anwar
2023-12-20  9:59 ` Roger Quadros
2023-12-22 10:26   ` MD Danish Anwar
2023-12-22 12:43     ` Roger Quadros
2023-12-27  6:56       ` MD Danish Anwar
2024-01-02 13:56         ` Andrew Davis
2024-01-03 10:27           ` MD Danish Anwar
2024-01-05  8:19             ` Roger Quadros
2024-01-05 10:15               ` Anwar, Md Danish
2024-01-08  9:30                 ` Roger Quadros
2024-01-08 10:25                   ` MD Danish Anwar
2024-01-09  9:26                     ` Roger Quadros
2024-01-09  9:49                       ` MD Danish Anwar
2024-01-09 12:34                         ` Roger Quadros

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.