All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v3 0/4] Add network support for Jaguar2 SoCs
@ 2019-03-30 10:16 Horatiu Vultur
  2019-03-30 10:17 ` [U-Boot] [PATCH v3 1/4] net: Add MSCC Jaguar2 network driver Horatiu Vultur
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Horatiu Vultur @ 2019-03-30 10:16 UTC (permalink / raw)
  To: u-boot

v3-changes:
 - move serdes setup in network driver and read serdes
   configuration from DT.

v2-changes:
 - create serdes6g_setup and serdes1g_setup functions to be
   easier to extand for future boards.

Horatiu Vultur (4):
  net: Add MSCC Jaguar2 network driver.
  board: mscc: jr2: Update MSCC Jaguar2 boards
  net: mscc: jaguar2: Add ethenet nodes for Jaguar2.
  configs: mscc_jr2: Add network support

 arch/mips/dts/jr2_pcb110.dts          |   76 +++
 arch/mips/dts/jr2_pcb111.dts          |  400 ++++++++++++
 arch/mips/dts/mscc,jr2.dtsi           |  116 ++++
 arch/mips/dts/serval2_pcb112.dts      |   44 ++
 board/mscc/jr2/jr2.c                  |   23 +
 configs/mscc_jr2_defconfig            |    6 +-
 drivers/net/mscc_eswitch/Kconfig      |    7 +
 drivers/net/mscc_eswitch/Makefile     |    1 +
 drivers/net/mscc_eswitch/jr2_switch.c | 1075 +++++++++++++++++++++++++++++++++
 include/configs/vcoreiii.h            |    2 +-
 include/dt-bindings/mscc/jr2_data.h   |   19 +
 11 files changed, 1767 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/mscc_eswitch/jr2_switch.c
 create mode 100644 include/dt-bindings/mscc/jr2_data.h

-- 
2.7.4

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

* [U-Boot] [PATCH v3 1/4] net: Add MSCC Jaguar2 network driver.
  2019-03-30 10:16 [U-Boot] [PATCH v3 0/4] Add network support for Jaguar2 SoCs Horatiu Vultur
@ 2019-03-30 10:17 ` Horatiu Vultur
  2019-04-03 10:18   ` Daniel Schwierzeck
  2019-03-30 10:17 ` [U-Boot] [PATCH v3 2/4] board: mscc: jr2: Update MSCC Jaguar2 boards Horatiu Vultur
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Horatiu Vultur @ 2019-03-30 10:17 UTC (permalink / raw)
  To: u-boot

Add network driver for Microsemi Ethernet switch.
It is present on Jaguar2 SoCs.

Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
 drivers/net/mscc_eswitch/Kconfig      |    7 +
 drivers/net/mscc_eswitch/Makefile     |    1 +
 drivers/net/mscc_eswitch/jr2_switch.c | 1075 +++++++++++++++++++++++++++++++++
 include/configs/vcoreiii.h            |    2 +-
 4 files changed, 1084 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/mscc_eswitch/jr2_switch.c

diff --git a/drivers/net/mscc_eswitch/Kconfig b/drivers/net/mscc_eswitch/Kconfig
index 88e5a97..3f9d14b 100644
--- a/drivers/net/mscc_eswitch/Kconfig
+++ b/drivers/net/mscc_eswitch/Kconfig
@@ -15,3 +15,10 @@ config MSCC_LUTON_SWITCH
 	select PHYLIB
 	help
 	  This driver supports the Luton network switch device.
+
+config MSCC_JR2_SWITCH
+	bool "Jaguar2 switch driver"
+	depends on DM_ETH && ARCH_MSCC
+	select PHYLIB
+	help
+	  This driver supports the Jaguar2 network switch device.
diff --git a/drivers/net/mscc_eswitch/Makefile b/drivers/net/mscc_eswitch/Makefile
index 751a839..0a1b863 100644
--- a/drivers/net/mscc_eswitch/Makefile
+++ b/drivers/net/mscc_eswitch/Makefile
@@ -1,3 +1,4 @@
 
 obj-$(CONFIG_MSCC_OCELOT_SWITCH) += ocelot_switch.o mscc_miim.o mscc_xfer.o mscc_mac_table.o
 obj-$(CONFIG_MSCC_LUTON_SWITCH) += luton_switch.o mscc_miim.o mscc_xfer.o mscc_mac_table.o
+obj-$(CONFIG_MSCC_JR2_SWITCH) += jr2_switch.o mscc_xfer.o
diff --git a/drivers/net/mscc_eswitch/jr2_switch.c b/drivers/net/mscc_eswitch/jr2_switch.c
new file mode 100644
index 0000000..d4a2498
--- /dev/null
+++ b/drivers/net/mscc_eswitch/jr2_switch.c
@@ -0,0 +1,1075 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+#include <config.h>
+#include <dm.h>
+#include <dm/of_access.h>
+#include <dm/of_addr.h>
+#include <fdt_support.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <miiphy.h>
+#include <net.h>
+#include <wait_bit.h>
+
+#include <dt-bindings/mscc/jr2_data.h>
+#include "mscc_xfer.h"
+
+#define GCB_MIIM_MII_STATUS		0x0
+#define		GCB_MIIM_STAT_BUSY		BIT(3)
+#define GCB_MIIM_MII_CMD		0x8
+#define		GCB_MIIM_MII_CMD_SCAN		BIT(0)
+#define		GCB_MIIM_MII_CMD_OPR_WRITE	BIT(1)
+#define		GCB_MIIM_MII_CMD_OPR_READ	BIT(2)
+#define		GCB_MIIM_MII_CMD_SINGLE_SCAN	BIT(3)
+#define		GCB_MIIM_MII_CMD_WRDATA(x)	((x) << 4)
+#define		GCB_MIIM_MII_CMD_REGAD(x)	((x) << 20)
+#define		GCB_MIIM_MII_CMD_PHYAD(x)	((x) << 25)
+#define		GCB_MIIM_MII_CMD_VLD		BIT(31)
+#define GCB_MIIM_DATA			0xC
+#define		GCB_MIIM_DATA_ERROR		(0x3 << 16)
+
+#define ANA_AC_RAM_CTRL_RAM_INIT		0x94358
+#define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET	0x94370
+
+#define ANA_CL_PORT_VLAN_CFG(x)			(0x24018 + 0xc8 * (x))
+#define		ANA_CL_PORT_VLAN_CFG_AWARE_ENA			BIT(19)
+#define		ANA_CL_PORT_VLAN_CFG_POP_CNT(x)			((x) << 17)
+
+#define ANA_L2_COMMON_FWD_CFG			0x8a2a8
+#define		ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA	BIT(6)
+
+#define ASM_CFG_STAT_CFG			0x3508
+#define ASM_CFG_PORT(x)				(0x36c4 + 0x4 * (x))
+#define		ASM_CFG_PORT_NO_PREAMBLE_ENA		BIT(8)
+#define		ASM_CFG_PORT_INJ_FORMAT_CFG(x)		((x) << 1)
+#define ASM_RAM_CTRL_RAM_INIT			0x39b8
+
+#define DEV_DEV_CFG_DEV_RST_CTRL		0x0
+#define		DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(x)	((x) << 20)
+#define DEV_MAC_CFG_MAC_ENA		0x1c
+#define		DEV_MAC_CFG_MAC_ENA_RX_ENA		BIT(4)
+#define		DEV_MAC_CFG_MAC_ENA_TX_ENA		BIT(0)
+#define	DEV_MAC_CFG_MAC_IFG		0x34
+#define		DEV_MAC_CFG_MAC_IFG_TX_IFG(x)		((x) << 8)
+#define		DEV_MAC_CFG_MAC_IFG_RX_IFG2(x)		((x) << 4)
+#define		DEV_MAC_CFG_MAC_IFG_RX_IFG1(x)		(x)
+#define	DEV_PCS1G_CFG_PCS1G_CFG		0x40
+#define		DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA		BIT(0)
+#define	DEV_PCS1G_CFG_PCS1G_MODE	0x44
+#define	DEV_PCS1G_CFG_PCS1G_SD		0x48
+#define	DEV_PCS1G_CFG_PCS1G_ANEG	0x4c
+#define		DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(x)	((x) << 16)
+
+#define DSM_RAM_CTRL_RAM_INIT		0x8
+
+#define HSIO_ANA_SERDES1G_DES_CFG		0xac
+#define		HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(x)		((x) << 1)
+#define		HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(x)		((x) << 5)
+#define		HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(x)		((x) << 8)
+#define		HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(x)		((x) << 13)
+#define HSIO_ANA_SERDES1G_IB_CFG		0xb0
+#define		HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(x)	(x)
+#define		HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(x)		((x) << 6)
+#define		HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP	BIT(9)
+#define		HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV		BIT(11)
+#define		HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM		BIT(13)
+#define		HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(x)		((x) << 19)
+#define		HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(x)		((x) << 24)
+#define HSIO_ANA_SERDES1G_OB_CFG		0xb4
+#define		HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(x)	(x)
+#define		HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(x)		((x) << 4)
+#define		HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(x)	((x) << 10)
+#define		HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(x)		((x) << 13)
+#define		HSIO_ANA_SERDES1G_OB_CFG_SLP(x)			((x) << 17)
+#define HSIO_ANA_SERDES1G_SER_CFG		0xb8
+#define HSIO_ANA_SERDES1G_COMMON_CFG		0xbc
+#define		HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE		BIT(0)
+#define		HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE		BIT(18)
+#define		HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST		BIT(31)
+#define HSIO_ANA_SERDES1G_PLL_CFG		0xc0
+#define		HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA		BIT(7)
+#define		HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(x)	((x) << 8)
+#define		HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2		BIT(21)
+#define HSIO_DIG_SERDES1G_DFT_CFG0		0xc8
+#define HSIO_DIG_SERDES1G_TP_CFG		0xd4
+#define HSIO_DIG_SERDES1G_MISC_CFG		0xdc
+#define		HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST		BIT(0)
+#define HSIO_MCB_SERDES1G_CFG			0xe8
+#define		HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT		BIT(31)
+#define		HSIO_MCB_SERDES1G_CFG_ADDR(x)			(x)
+
+#define HSIO_ANA_SERDES6G_DES_CFG		0x11c
+#define		HSIO_ANA_SERDES6G_DES_CFG_SWAP_ANA		BIT(0)
+#define		HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(x)		((x) << 1)
+#define		HSIO_ANA_SERDES6G_DES_CFG_SWAP_HYST		BIT(4)
+#define		HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(x)		((x) << 5)
+#define		HSIO_ANA_SERDES6G_DES_CFG_CPMD_SEL(x)		((x) << 8)
+#define		HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(x)		((x) << 10)
+#define		HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(x)		((x) << 13)
+#define HSIO_ANA_SERDES6G_IB_CFG		0x120
+#define		HSIO_ANA_SERDES6G_IB_CFG_REG_ENA		BIT(0)
+#define		HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA		BIT(1)
+#define		HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA		BIT(2)
+#define		HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(x)		((x) << 3)
+#define		HSIO_ANA_SERDES6G_IB_CFG_CONCUR			BIT(4)
+#define		HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA		BIT(5)
+#define		HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(x)	((x) << 7)
+#define		HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(x)	((x) << 9)
+#define		HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(x)	((x) << 11)
+#define		HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(x)	((x) << 13)
+#define		HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(x)	((x) << 15)
+#define		HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(x)	((x) << 18)
+#define		HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(x)		((x) << 20)
+#define		HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(x)		((x) << 24)
+#define		HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL		BIT(28)
+#define		HSIO_ANA_SERDES6G_IB_CFG_SOFSI(x)		((x) << 29)
+#define HSIO_ANA_SERDES6G_IB_CFG1		0x124
+#define		HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET		BIT(4)
+#define		HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP		BIT(5)
+#define		HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID		BIT(6)
+#define		HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP		BIT(7)
+#define		HSIO_ANA_SERDES6G_IB_CFG1_SCALY(x)		((x) << 8)
+#define		HSIO_ANA_SERDES6G_IB_CFG1_TSDET(x)		((x) << 12)
+#define		HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(x)		((x) << 17)
+#define HSIO_ANA_SERDES6G_IB_CFG2		0x128
+#define		HSIO_ANA_SERDES6G_IB_CFG2_UREG(x)		(x)
+#define		HSIO_ANA_SERDES6G_IB_CFG2_UMAX(x)		((x) << 3)
+#define		HSIO_ANA_SERDES6G_IB_CFG2_TCALV(x)		((x) << 5)
+#define		HSIO_ANA_SERDES6G_IB_CFG2_OCALS(x)		((x) << 10)
+#define		HSIO_ANA_SERDES6G_IB_CFG2_OINFS(x)		((x) << 16)
+#define		HSIO_ANA_SERDES6G_IB_CFG2_OINFI(x)		((x) << 22)
+#define		HSIO_ANA_SERDES6G_IB_CFG2_TINFV(x)		((x) << 27)
+#define HSIO_ANA_SERDES6G_IB_CFG3		0x12c
+#define		HSIO_ANA_SERDES6G_IB_CFG3_INI_OFFSET(x)		(x)
+#define		HSIO_ANA_SERDES6G_IB_CFG3_INI_LP(x)		((x) << 6)
+#define		HSIO_ANA_SERDES6G_IB_CFG3_INI_MID(x)		((x) << 12)
+#define		HSIO_ANA_SERDES6G_IB_CFG3_INI_HP(x)		((x) << 18)
+#define HSIO_ANA_SERDES6G_IB_CFG4		0x130
+#define		HSIO_ANA_SERDES6G_IB_CFG4_MAX_OFFSET(x)		(x)
+#define		HSIO_ANA_SERDES6G_IB_CFG4_MAX_LP(x)		((x) << 6)
+#define		HSIO_ANA_SERDES6G_IB_CFG4_MAX_MID(x)		((x) << 12)
+#define		HSIO_ANA_SERDES6G_IB_CFG4_MAX_HP(x)		((x) << 18)
+#define HSIO_ANA_SERDES6G_IB_CFG5		0x134
+#define		HSIO_ANA_SERDES6G_IB_CFG4_MIN_OFFSET(x)		(x)
+#define		HSIO_ANA_SERDES6G_IB_CFG4_MIN_LP(x)		((x) << 6)
+#define		HSIO_ANA_SERDES6G_IB_CFG4_MIN_MID(x)		((x) << 12)
+#define		HSIO_ANA_SERDES6G_IB_CFG4_MIN_HP(x)		((x) << 18)
+#define HSIO_ANA_SERDES6G_OB_CFG		0x138
+#define		HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(x)	(x)
+#define		HSIO_ANA_SERDES6G_OB_CFG_SR(x)			((x) << 4)
+#define		HSIO_ANA_SERDES6G_OB_CFG_SR_H			BIT(8)
+#define		HSIO_ANA_SERDES6G_OB_CFG_SEL_RCTRL		BIT(9)
+#define		HSIO_ANA_SERDES6G_OB_CFG_R_COR			BIT(10)
+#define		HSIO_ANA_SERDES6G_OB_CFG_POST1(x)		((x) << 11)
+#define		HSIO_ANA_SERDES6G_OB_CFG_R_ADJ_PDR		BIT(16)
+#define		HSIO_ANA_SERDES6G_OB_CFG_R_ADJ_MUX		BIT(17)
+#define		HSIO_ANA_SERDES6G_OB_CFG_PREC(x)		((x) << 18)
+#define		HSIO_ANA_SERDES6G_OB_CFG_POST0(x)		((x) << 23)
+#define		HSIO_ANA_SERDES6G_OB_CFG_POL			BIT(29)
+#define		HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(x)		((x) << 30)
+#define		HSIO_ANA_SERDES6G_OB_CFG_IDLE			BIT(31)
+#define HSIO_ANA_SERDES6G_OB_CFG1		0x13c
+#define		HSIO_ANA_SERDES6G_OB_CFG1_LEV(x)		(x)
+#define		HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(x)		((x) << 6)
+#define HSIO_ANA_SERDES6G_SER_CFG		0x140
+#define HSIO_ANA_SERDES6G_COMMON_CFG		0x144
+#define		HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(x)		(x)
+#define		HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(x)		(x << 2)
+#define		HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE		BIT(14)
+#define		HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST		BIT(16)
+#define HSIO_ANA_SERDES6G_PLL_CFG		0x148
+#define		HSIO_ANA_SERDES6G_PLL_CFG_ROT_FRQ		BIT(0)
+#define		HSIO_ANA_SERDES6G_PLL_CFG_ROT_DIR		BIT(1)
+#define		HSIO_ANA_SERDES6G_PLL_CFG_RB_DATA_SEL		BIT(2)
+#define		HSIO_ANA_SERDES6G_PLL_CFG_FSM_OOR_RECAL_ENA	BIT(3)
+#define		HSIO_ANA_SERDES6G_PLL_CFG_FSM_FORCE_SET_ENA	BIT(4)
+#define		HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA		BIT(5)
+#define		HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(x)	((x) << 6)
+#define		HSIO_ANA_SERDES6G_PLL_CFG_ENA_ROT		BIT(14)
+#define		HSIO_ANA_SERDES6G_PLL_CFG_DIV4			BIT(15)
+#define		HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(x)		((x) << 16)
+#define HSIO_DIG_SERDES6G_MISC_CFG		0x108
+#define		HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST		BIT(0)
+#define HSIO_MCB_SERDES6G_CFG			0x168
+#define		HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT		BIT(31)
+#define		HSIO_MCB_SERDES6G_CFG_ADDR(x)			(x)
+#define HSIO_HW_CFGSTAT_HW_CFG			0x16c
+
+#define LRN_COMMON_ACCESS_CTRL			0x0
+#define		LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT	BIT(0)
+#define LRN_COMMON_MAC_ACCESS_CFG0		0x4
+#define LRN_COMMON_MAC_ACCESS_CFG1		0x8
+#define LRN_COMMON_MAC_ACCESS_CFG2		0xc
+#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(x)	(x)
+#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(x)	((x) << 12)
+#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD	BIT(15)
+#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED	BIT(16)
+#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY	BIT(23)
+#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(x)	((x) << 24)
+
+#define QFWD_SYSTEM_SWITCH_PORT_MODE(x)		(0x4 * (x))
+#define		QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA		BIT(17)
+
+#define QS_XTR_GRP_CFG(x)		(0x0 + 4 * (x))
+#define QS_INJ_GRP_CFG(x)		(0x24 + (x) * 4)
+
+#define QSYS_SYSTEM_RESET_CFG			0xf0
+#define QSYS_CALCFG_CAL_AUTO(x)			(0x3d4 + 4 * (x))
+#define QSYS_CALCFG_CAL_CTRL			0x3e8
+#define		QSYS_CALCFG_CAL_CTRL_CAL_MODE(x)		((x) << 11)
+#define QSYS_RAM_CTRL_RAM_INIT			0x3ec
+
+#define REW_RAM_CTRL_RAM_INIT			0x53528
+
+#define VOP_RAM_CTRL_RAM_INIT			0x43638
+
+#define XTR_VALID_BYTES(x)	(4 - ((x) & 3))
+#define MAC_VID			0
+#define CPU_PORT		53
+#define IFH_LEN			7
+#define JR2_BUF_CELL_SZ		60
+#define ETH_ALEN		6
+#define PGID_BROADCAST		510
+#define PGID_UNICAST		511
+
+static char *regs_names[] = {
+	"port0", "port1", "port2", "port3", "port4", "port5", "port6", "port7",
+	"port8", "port9", "port10", "port11", "port12", "port13", "port14",
+	"port15", "port16", "port17", "port18", "port19", "port20", "port21",
+	"port22", "port23", "port24", "port25", "port26", "port27", "port28",
+	"port29", "port30", "port31", "port32", "port33", "port34", "port35",
+	"port36", "port37", "port38", "port39", "port40", "port41", "port42",
+	"port43", "port44", "port45", "port46", "port47",
+	"ana_ac", "ana_cl", "ana_l2", "asm", "hsio", "lrn",
+	"qfwd", "qs", "qsys", "rew",
+};
+
+#define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1
+#define MAX_PORT 48
+
+enum jr2_ctrl_regs {
+	ANA_AC = MAX_PORT,
+	ANA_CL,
+	ANA_L2,
+	ASM,
+	HSIO,
+	LRN,
+	QFWD,
+	QS,
+	QSYS,
+	REW,
+};
+
+#define JR2_MIIM_BUS_COUNT 3
+
+struct jr2_phy_port_t {
+	size_t phy_addr;
+	struct mii_dev *bus;
+	u8 serdes_index;
+	u8 phy_mode;
+};
+
+struct jr2_private {
+	void __iomem *regs[REGS_NAMES_COUNT];
+	struct mii_dev *bus[JR2_MIIM_BUS_COUNT];
+	struct jr2_phy_port_t ports[MAX_PORT];
+};
+
+struct jr2_miim_dev {
+	void __iomem *regs;
+	phys_addr_t miim_base;
+	unsigned long miim_size;
+	struct mii_dev *bus;
+};
+
+static const unsigned long jr2_regs_qs[] = {
+	[MSCC_QS_XTR_RD] = 0x8,
+	[MSCC_QS_XTR_FLUSH] = 0x18,
+	[MSCC_QS_XTR_DATA_PRESENT] = 0x1c,
+	[MSCC_QS_INJ_WR] = 0x2c,
+	[MSCC_QS_INJ_CTRL] = 0x34,
+};
+
+static struct jr2_miim_dev miim[JR2_MIIM_BUS_COUNT];
+static int miim_count = -1;
+
+static int mscc_miim_wait_ready(struct jr2_miim_dev *miim)
+{
+	unsigned long deadline;
+	u32 val;
+
+	deadline = timer_get_us() + 250000;
+
+	do {
+		val = readl(miim->regs + GCB_MIIM_MII_STATUS);
+	} while (timer_get_us() <= deadline && (val & GCB_MIIM_STAT_BUSY));
+
+	if (val & GCB_MIIM_STAT_BUSY)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+	struct jr2_miim_dev *miim = (struct jr2_miim_dev *)bus->priv;
+	u32 val;
+	int ret;
+
+	ret = mscc_miim_wait_ready(miim);
+	if (ret)
+		goto out;
+
+	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
+	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
+	       miim->regs + GCB_MIIM_MII_CMD);
+
+	ret = mscc_miim_wait_ready(miim);
+	if (ret)
+		goto out;
+
+	val = readl(miim->regs + GCB_MIIM_DATA);
+	if (val & GCB_MIIM_DATA_ERROR) {
+		ret = -EIO;
+		goto out;
+	}
+
+	ret = val & 0xFFFF;
+ out:
+	return ret;
+}
+
+static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
+			   u16 val)
+{
+	struct jr2_miim_dev *miim = (struct jr2_miim_dev *)bus->priv;
+	int ret;
+
+	ret = mscc_miim_wait_ready(miim);
+	if (ret < 0)
+		goto out;
+
+	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
+	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
+	       GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
+
+ out:
+	return ret;
+}
+
+static struct mii_dev *jr2_mdiobus_init(phys_addr_t miim_base,
+					unsigned long miim_size)
+{
+	struct mii_dev *bus;
+
+	bus = mdio_alloc();
+	if (!bus)
+		return NULL;
+
+	++miim_count;
+	sprintf(bus->name, "miim-bus%d", miim_count);
+
+	miim[miim_count].regs = ioremap(miim_base, miim_size);
+	miim[miim_count].miim_base = miim_base;
+	miim[miim_count].miim_size = miim_size;
+	bus->priv = &miim[miim_count];
+	bus->read = mscc_miim_read;
+	bus->write = mscc_miim_write;
+
+	if (mdio_register(bus))
+		return NULL;
+
+	miim[miim_count].bus = bus;
+	return bus;
+}
+
+static void jr2_cpu_capture_setup(struct jr2_private *priv)
+{
+	/* ASM: No preamble and IFH prefix on CPU injected frames */
+	writel(ASM_CFG_PORT_NO_PREAMBLE_ENA |
+	       ASM_CFG_PORT_INJ_FORMAT_CFG(1),
+	       priv->regs[ASM] + ASM_CFG_PORT(CPU_PORT));
+
+	/* Set Manual injection via DEVCPU_QS registers for CPU queue 0 */
+	writel(0x5, priv->regs[QS] + QS_INJ_GRP_CFG(0));
+
+	/* Set Manual extraction via DEVCPU_QS registers for CPU queue 0 */
+	writel(0x7, priv->regs[QS] + QS_XTR_GRP_CFG(0));
+
+	/* Enable CPU port for any frame transfer */
+	setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(CPU_PORT),
+		     QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
+
+	/* Send a copy to CPU when found as forwarding entry */
+	setbits_le32(priv->regs[ANA_L2] + ANA_L2_COMMON_FWD_CFG,
+		     ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA);
+}
+
+static void jr2_port_init(struct jr2_private *priv, int port)
+{
+	void __iomem *regs = priv->regs[port];
+
+	/* Enable PCS */
+	writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA,
+	       regs + DEV_PCS1G_CFG_PCS1G_CFG);
+
+	/* Disable Signal Detect */
+	writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD);
+
+	/* Enable MAC RX and TX */
+	writel(DEV_MAC_CFG_MAC_ENA_RX_ENA |
+	       DEV_MAC_CFG_MAC_ENA_TX_ENA,
+	       regs + DEV_MAC_CFG_MAC_ENA);
+
+	/* Clear sgmii_mode_ena */
+	writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE);
+
+	/*
+	 * Clear sw_resolve_ena(bit 0) and set adv_ability to
+	 * something meaningful just in case
+	 */
+	writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20),
+	       regs + DEV_PCS1G_CFG_PCS1G_ANEG);
+
+	/* Set MAC IFG Gaps */
+	writel(DEV_MAC_CFG_MAC_IFG_TX_IFG(4) |
+	       DEV_MAC_CFG_MAC_IFG_RX_IFG1(5) |
+	       DEV_MAC_CFG_MAC_IFG_RX_IFG2(1),
+	       regs + DEV_MAC_CFG_MAC_IFG);
+
+	/* Set link speed and release all resets */
+	writel(DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(2),
+	       regs + DEV_DEV_CFG_DEV_RST_CTRL);
+
+	/* Make VLAN aware for CPU traffic */
+	writel(ANA_CL_PORT_VLAN_CFG_AWARE_ENA |
+	       ANA_CL_PORT_VLAN_CFG_POP_CNT(1) |
+	       MAC_VID,
+	       priv->regs[ANA_CL] + ANA_CL_PORT_VLAN_CFG(port));
+
+	/* Enable CPU port for any frame transfer */
+	setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(port),
+		     QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
+}
+
+static void serdes6g_write(void __iomem *base, u32 addr)
+{
+	u32 data;
+
+	writel(HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT |
+	       HSIO_MCB_SERDES6G_CFG_ADDR(addr),
+	       base + HSIO_MCB_SERDES6G_CFG);
+
+	do {
+		data = readl(base + HSIO_MCB_SERDES6G_CFG);
+	} while (data & HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT);
+}
+
+static void serdes6g_setup(void __iomem *base, uint32_t addr,
+			   phy_interface_t interface)
+{
+	u32 ib_if_mode = 0;
+	u32 ib_qrate = 0;
+	u32 ib_cal_ena = 0;
+	u32 ib1_tsdet = 0;
+	u32 ob_lev = 0;
+	u32 ob_ena_cas = 0;
+	u32 ob_ena1v_mode = 0;
+	u32 des_bw_ana = 0;
+	u32 pll_fsm_ctrl_data = 0;
+
+	switch (interface) {
+	case PHY_INTERFACE_MODE_SGMII:
+		ib_if_mode = 1;
+		ib_qrate = 1;
+		ib_cal_ena = 1;
+		ib1_tsdet = 3;
+		ob_lev = 48;
+		ob_ena_cas = 2;
+		ob_ena1v_mode = 1;
+		des_bw_ana = 3;
+		pll_fsm_ctrl_data = 60;
+		break;
+	case PHY_INTERFACE_MODE_QSGMII:
+		ib_if_mode = 3;
+		ib1_tsdet = 16;
+		ob_lev = 24;
+		des_bw_ana = 5;
+		pll_fsm_ctrl_data = 120;
+		break;
+	default:
+		pr_err("Interface not supported\n");
+		return;
+	}
+
+	if (interface == PHY_INTERFACE_MODE_QSGMII)
+		writel(0xfff, base + HSIO_HW_CFGSTAT_HW_CFG);
+
+	writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(3),
+	       base + HSIO_ANA_SERDES6G_COMMON_CFG);
+	writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(120) |
+	       HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
+	       base + HSIO_ANA_SERDES6G_PLL_CFG);
+	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
+	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
+	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) |
+	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
+	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
+	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
+	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
+	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
+	       base + HSIO_ANA_SERDES6G_IB_CFG);
+	writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
+	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
+	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
+	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
+	       HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
+	       HSIO_ANA_SERDES6G_IB_CFG1_TSDET(3) |
+	       HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
+	       base + HSIO_ANA_SERDES6G_IB_CFG1);
+	writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST,
+	       base + HSIO_DIG_SERDES6G_MISC_CFG);
+
+	serdes6g_write(base, addr);
+
+	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
+	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
+	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) |
+	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
+	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
+	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
+	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
+	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
+	       base + HSIO_ANA_SERDES6G_IB_CFG);
+	writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
+	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
+	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
+	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
+	       HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
+	       HSIO_ANA_SERDES6G_IB_CFG1_TSDET(16) |
+	       HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
+	       base + HSIO_ANA_SERDES6G_IB_CFG1);
+
+	writel(0x0, base + HSIO_ANA_SERDES6G_SER_CFG);
+	writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(ib_if_mode) |
+	       HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(ib_qrate) |
+	       HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE |
+	       HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST,
+	       base + HSIO_ANA_SERDES6G_COMMON_CFG);
+	writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST,
+	       base + HSIO_DIG_SERDES6G_MISC_CFG);
+
+	writel(HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(1) |
+	       HSIO_ANA_SERDES6G_OB_CFG_SR(7) |
+	       HSIO_ANA_SERDES6G_OB_CFG_SR_H |
+	       HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(ob_ena1v_mode) |
+	       HSIO_ANA_SERDES6G_OB_CFG_POL, base + HSIO_ANA_SERDES6G_OB_CFG);
+	writel(HSIO_ANA_SERDES6G_OB_CFG1_LEV(ob_lev) |
+	       HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(ob_ena_cas),
+	       base + HSIO_ANA_SERDES6G_OB_CFG1);
+
+	writel(HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(des_bw_ana) |
+	       HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(5) |
+	       HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(2) |
+	       HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(6),
+	       base + HSIO_ANA_SERDES6G_DES_CFG);
+	writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) |
+	       HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
+	       base + HSIO_ANA_SERDES6G_PLL_CFG);
+
+	serdes6g_write(base, addr);
+
+	/* set pll_fsm_ena = 1 */
+	writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA |
+	       HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) |
+	       HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
+	       base + HSIO_ANA_SERDES6G_PLL_CFG);
+
+	serdes6g_write(base, addr);
+
+	/* wait 20ms for pll bringup */
+	mdelay(20);
+
+	/* start IB calibration by setting ib_cal_ena and clearing lane_rst */
+	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(ib_cal_ena) |
+	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
+	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
+	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) |
+	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
+	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
+	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
+	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
+	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
+	       base + HSIO_ANA_SERDES6G_IB_CFG);
+	writel(0x0, base + HSIO_DIG_SERDES6G_MISC_CFG);
+
+	serdes6g_write(base, addr);
+
+	/* wait 60 for calibration */
+	mdelay(60);
+
+	/* set ib_tsdet and ib_reg_pat_sel_offset back to correct values */
+	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(ib_cal_ena) |
+	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
+	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
+	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
+	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) |
+	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
+	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
+	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
+	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
+	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
+	       base + HSIO_ANA_SERDES6G_IB_CFG);
+	writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
+	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
+	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
+	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
+	       HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
+	       HSIO_ANA_SERDES6G_IB_CFG1_TSDET(ib1_tsdet) |
+	       HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
+	       base + HSIO_ANA_SERDES6G_IB_CFG1);
+
+	serdes6g_write(base, addr);
+}
+
+static void serdes1g_write(void __iomem *base, u32 addr)
+{
+	u32 data;
+
+	writel(HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT |
+	       HSIO_MCB_SERDES1G_CFG_ADDR(addr),
+	       base + HSIO_MCB_SERDES1G_CFG);
+
+	do {
+		data = readl(base + HSIO_MCB_SERDES1G_CFG);
+	} while (data & HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT);
+}
+
+static void serdes1g_setup(void __iomem *base, uint32_t addr,
+			   phy_interface_t interface)
+{
+	writel(0x0, base + HSIO_ANA_SERDES1G_SER_CFG);
+	writel(0x0, base + HSIO_DIG_SERDES1G_TP_CFG);
+	writel(0x0, base + HSIO_DIG_SERDES1G_DFT_CFG0);
+	writel(HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(1) |
+	       HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(4) |
+	       HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(2) |
+	       HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(12) |
+	       HSIO_ANA_SERDES1G_OB_CFG_SLP(3),
+	       base + HSIO_ANA_SERDES1G_OB_CFG);
+	writel(HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(13) |
+	       HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(2) |
+	       HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP |
+	       HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV |
+	       HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM |
+	       HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(3) |
+	       HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(1),
+	       base + HSIO_ANA_SERDES1G_IB_CFG);
+	writel(HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(7) |
+	       HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(6) |
+	       HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(2) |
+	       HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(6),
+	       base + HSIO_ANA_SERDES1G_DES_CFG);
+	writel(HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST,
+	       base + HSIO_DIG_SERDES1G_MISC_CFG);
+	writel(HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA |
+	       HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(0xc8) |
+	       HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2,
+	       base + HSIO_ANA_SERDES1G_PLL_CFG);
+	writel(HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE |
+	       HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE |
+	       HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST,
+	       base + HSIO_ANA_SERDES1G_COMMON_CFG);
+
+	serdes1g_write(base, addr);
+
+	setbits_le32(base + HSIO_ANA_SERDES1G_COMMON_CFG,
+		     HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST);
+
+	serdes1g_write(base, addr);
+
+	clrbits_le32(base + HSIO_DIG_SERDES1G_MISC_CFG,
+		     HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST);
+
+	serdes1g_write(base, addr);
+}
+
+static int ram_init(u32 val, void __iomem *addr)
+{
+	writel(val, addr);
+
+	if (wait_for_bit_le32(addr, BIT(1), false, 2000, false)) {
+		printf("Timeout in memory reset, reg = 0x%08x\n", val);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int jr2_switch_init(struct jr2_private *priv)
+{
+	/* Initialize memories */
+	ram_init(0x3, priv->regs[QSYS] + QSYS_RAM_CTRL_RAM_INIT);
+	ram_init(0x3, priv->regs[ASM] + ASM_RAM_CTRL_RAM_INIT);
+	ram_init(0x3, priv->regs[ANA_AC] + ANA_AC_RAM_CTRL_RAM_INIT);
+	ram_init(0x3, priv->regs[REW] + REW_RAM_CTRL_RAM_INIT);
+
+	/* Reset counters */
+	writel(0x1, priv->regs[ANA_AC] + ANA_AC_STAT_GLOBAL_CFG_PORT_RESET);
+	writel(0x1, priv->regs[ASM] + ASM_CFG_STAT_CFG);
+
+	/* Enable switch-core and queue system */
+	writel(0x1, priv->regs[QSYS] + QSYS_SYSTEM_RESET_CFG);
+
+	return 0;
+}
+
+static void jr2_switch_config(struct jr2_private *priv)
+{
+	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(0));
+	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(1));
+	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(2));
+	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(3));
+
+	writel(readl(priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL) |
+	       QSYS_CALCFG_CAL_CTRL_CAL_MODE(8),
+	       priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL);
+}
+
+static int jr2_initialize(struct jr2_private *priv)
+{
+	int ret, i;
+
+	/* Initialize switch memories, enable core */
+	ret = jr2_switch_init(priv);
+	if (ret)
+		return ret;
+
+	jr2_switch_config(priv);
+
+	for (i = 0; i < MAX_PORT; i++)
+		jr2_port_init(priv, i);
+
+	jr2_cpu_capture_setup(priv);
+
+	return 0;
+}
+
+static inline int jr2_vlant_wait_for_completion(struct jr2_private *priv)
+{
+	if (wait_for_bit_le32(priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL,
+			      LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
+			      false, 2000, false))
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int jr2_mac_table_add(struct jr2_private *priv,
+			     const unsigned char mac[ETH_ALEN], int pgid)
+{
+	u32 macl = 0, mach = 0;
+
+	/*
+	 * Set the MAC address to handle and the vlan associated in a format
+	 * understood by the hardware.
+	 */
+	mach |= MAC_VID << 16;
+	mach |= ((u32)mac[0]) << 8;
+	mach |= ((u32)mac[1]) << 0;
+	macl |= ((u32)mac[2]) << 24;
+	macl |= ((u32)mac[3]) << 16;
+	macl |= ((u32)mac[4]) << 8;
+	macl |= ((u32)mac[5]) << 0;
+
+	writel(mach, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG0);
+	writel(macl, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG1);
+
+	writel(LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(pgid) |
+	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(0x3) |
+	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY |
+	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(0) |
+	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD |
+	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED,
+	       priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG2);
+
+	writel(LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
+	       priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL);
+
+	return jr2_vlant_wait_for_completion(priv);
+}
+
+static int jr2_write_hwaddr(struct udevice *dev)
+{
+	struct jr2_private *priv = dev_get_priv(dev);
+	struct eth_pdata *pdata = dev_get_platdata(dev);
+
+	return jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
+}
+
+static void serdes_setup(struct jr2_private *priv)
+{
+	size_t mask;
+	int i = 0;
+
+	for (i = 0; i < MAX_PORT; ++i) {
+		if (!priv->ports[i].bus || priv->ports[i].serdes_index == 0xff)
+			continue;
+
+		mask = BIT(priv->ports[i].serdes_index);
+		if (priv->ports[i].serdes_index < SERDES1G_MAX) {
+			serdes1g_setup(priv->regs[HSIO], mask,
+				       priv->ports[i].phy_mode);
+		} else {
+			mask >>= SERDES6G(0);
+			serdes6g_setup(priv->regs[HSIO], mask,
+				       priv->ports[i].phy_mode);
+		}
+	}
+}
+
+static int jr2_start(struct udevice *dev)
+{
+	struct jr2_private *priv = dev_get_priv(dev);
+	struct eth_pdata *pdata = dev_get_platdata(dev);
+	const unsigned char mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff };
+	int ret;
+
+	ret = jr2_initialize(priv);
+	if (ret)
+		return ret;
+
+	/* Set MAC address tables entries for CPU redirection */
+	ret = jr2_mac_table_add(priv, mac, PGID_BROADCAST);
+	if (ret)
+		return ret;
+
+	ret = jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
+	if (ret)
+		return ret;
+
+	serdes_setup(priv);
+
+	return 0;
+}
+
+static void jr2_stop(struct udevice *dev)
+{
+}
+
+static int jr2_send(struct udevice *dev, void *packet, int length)
+{
+	struct jr2_private *priv = dev_get_priv(dev);
+	u32 ifh[IFH_LEN];
+	u32 *buf = packet;
+
+	memset(ifh, '\0', IFH_LEN);
+
+	/* Set DST PORT_MASK */
+	ifh[0] = htonl(0);
+	ifh[1] = htonl(0x1FFFFF);
+	ifh[2] = htonl(~0);
+	/* Set DST_MODE to INJECT and UPDATE_FCS */
+	ifh[5] = htonl(0x4c0);
+
+	return mscc_send(priv->regs[QS], jr2_regs_qs,
+			 ifh, IFH_LEN, buf, length);
+}
+
+static int jr2_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+	struct jr2_private *priv = dev_get_priv(dev);
+	u32 *rxbuf = (u32 *)net_rx_packets[0];
+	int byte_cnt = 0;
+
+	byte_cnt = mscc_recv(priv->regs[QS], jr2_regs_qs, rxbuf, IFH_LEN,
+			     false);
+
+	*packetp = net_rx_packets[0];
+
+	return byte_cnt;
+}
+
+static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
+{
+	int i = 0;
+
+	for (i = 0; i < JR2_MIIM_BUS_COUNT; ++i)
+		if (miim[i].miim_base == base && miim[i].miim_size == size)
+			return miim[i].bus;
+
+	return NULL;
+}
+
+static void add_port_entry(struct jr2_private *priv, size_t index,
+			   size_t phy_addr, struct mii_dev *bus,
+			   u8 serdes_index, u8 phy_mode)
+{
+	priv->ports[index].phy_addr = phy_addr;
+	priv->ports[index].bus = bus;
+	priv->ports[index].serdes_index = serdes_index;
+	priv->ports[index].phy_mode = phy_mode;
+}
+
+static int jr2_probe(struct udevice *dev)
+{
+	struct jr2_private *priv = dev_get_priv(dev);
+	int i;
+	int ret;
+	struct resource res;
+	fdt32_t faddr;
+	phys_addr_t addr_base;
+	unsigned long addr_size;
+	ofnode eth_node, node, mdio_node;
+	size_t phy_addr;
+	struct mii_dev *bus;
+	struct ofnode_phandle_args phandle;
+	struct phy_device *phy;
+
+	if (!priv)
+		return -EINVAL;
+
+	/* Get registers and map them to the private structure */
+	for (i = 0; i < ARRAY_SIZE(regs_names); i++) {
+		priv->regs[i] = dev_remap_addr_name(dev, regs_names[i]);
+		if (!priv->regs[i]) {
+			debug
+			    ("Error can't get regs base addresses for %s\n",
+			     regs_names[i]);
+			return -ENOMEM;
+		}
+	}
+
+	/* Initialize miim buses */
+	memset(&miim, 0x0, sizeof(struct jr2_miim_dev) * JR2_MIIM_BUS_COUNT);
+
+	/* iterate all the ports and find out on which bus they are */
+	i = 0;
+	eth_node = dev_read_first_subnode(dev);
+	for (node = ofnode_first_subnode(eth_node);
+	     ofnode_valid(node);
+	     node = ofnode_next_subnode(node)) {
+		if (ofnode_read_resource(node, 0, &res))
+			return -ENOMEM;
+		i = res.start;
+
+		ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL,
+						     0, 0, &phandle);
+		if (ret)
+			continue;
+
+		/* Get phy address on mdio bus */
+		if (ofnode_read_resource(phandle.node, 0, &res))
+			return -ENOMEM;
+		phy_addr = res.start;
+
+		/* Get mdio node */
+		mdio_node = ofnode_get_parent(phandle.node);
+
+		if (ofnode_read_resource(mdio_node, 0, &res))
+			return -ENOMEM;
+		faddr = cpu_to_fdt32(res.start);
+
+		addr_base = ofnode_translate_address(mdio_node, &faddr);
+		addr_size = res.end - res.start;
+
+		/* If the bus is new then create a new bus */
+		if (!get_mdiobus(addr_base, addr_size))
+			priv->bus[miim_count] =
+				jr2_mdiobus_init(addr_base, addr_size);
+
+		/* Connect mdio bus with the port */
+		bus = get_mdiobus(addr_base, addr_size);
+
+		/* Get serdes info */
+		ret = ofnode_parse_phandle_with_args(node, "phys", NULL,
+						     3, 0, &phandle);
+		if (ret)
+			return -ENOMEM;
+
+		add_port_entry(priv, i, phy_addr, bus, phandle.args[1],
+			       phandle.args[2]);
+	}
+
+	for (i = 0; i < MAX_PORT; i++) {
+		if (!priv->ports[i].bus)
+			continue;
+
+		phy = phy_connect(priv->ports[i].bus,
+				  priv->ports[i].phy_addr, dev,
+				  PHY_INTERFACE_MODE_NONE);
+		if (phy)
+			board_phy_config(phy);
+	}
+
+	return 0;
+}
+
+static int jr2_remove(struct udevice *dev)
+{
+	struct jr2_private *priv = dev_get_priv(dev);
+	int i;
+
+	for (i = 0; i < JR2_MIIM_BUS_COUNT; i++) {
+		mdio_unregister(priv->bus[i]);
+		mdio_free(priv->bus[i]);
+	}
+
+	return 0;
+}
+
+static const struct eth_ops jr2_ops = {
+	.start        = jr2_start,
+	.stop         = jr2_stop,
+	.send         = jr2_send,
+	.recv         = jr2_recv,
+	.write_hwaddr = jr2_write_hwaddr,
+};
+
+static const struct udevice_id mscc_jr2_ids[] = {
+	{.compatible = "mscc,vsc7454-switch" },
+	{ /* Sentinel */ }
+};
+
+U_BOOT_DRIVER(jr2) = {
+	.name				= "jr2-switch",
+	.id				= UCLASS_ETH,
+	.of_match			= mscc_jr2_ids,
+	.probe				= jr2_probe,
+	.remove				= jr2_remove,
+	.ops				= &jr2_ops,
+	.priv_auto_alloc_size		= sizeof(struct jr2_private),
+	.platdata_auto_alloc_size	= sizeof(struct eth_pdata),
+};
diff --git a/include/configs/vcoreiii.h b/include/configs/vcoreiii.h
index 2840c7b..aeef58d 100644
--- a/include/configs/vcoreiii.h
+++ b/include/configs/vcoreiii.h
@@ -10,7 +10,7 @@
 
 /* Onboard devices */
 
-#define CONFIG_SYS_MALLOC_LEN		0x100000
+#define CONFIG_SYS_MALLOC_LEN		0x1F0000
 #define CONFIG_SYS_LOAD_ADDR		0x00100000
 #define CONFIG_SYS_INIT_SP_OFFSET       0x400000
 
-- 
2.7.4

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

* [U-Boot] [PATCH v3 2/4] board: mscc: jr2: Update MSCC Jaguar2 boards
  2019-03-30 10:16 [U-Boot] [PATCH v3 0/4] Add network support for Jaguar2 SoCs Horatiu Vultur
  2019-03-30 10:17 ` [U-Boot] [PATCH v3 1/4] net: Add MSCC Jaguar2 network driver Horatiu Vultur
@ 2019-03-30 10:17 ` Horatiu Vultur
  2019-03-30 10:17 ` [U-Boot] [PATCH v3 3/4] net: mscc: jaguar2: Add ethenet nodes for Jaguar2 Horatiu Vultur
  2019-03-30 10:17 ` [U-Boot] [PATCH v3 4/4] configs: mscc_jr2: Add network support Horatiu Vultur
  3 siblings, 0 replies; 7+ messages in thread
From: Horatiu Vultur @ 2019-03-30 10:17 UTC (permalink / raw)
  To: u-boot

In Jaguar2 SoC family there are 3 different pcb. Each of this needs
to configure the phys in different ways. Therefore implement the
function board_phy_config and based on pcb configure them accordingly.

Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
 board/mscc/jr2/jr2.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/board/mscc/jr2/jr2.c b/board/mscc/jr2/jr2.c
index 58a4a04..6e5ef4c 100644
--- a/board/mscc/jr2/jr2.c
+++ b/board/mscc/jr2/jr2.c
@@ -6,6 +6,7 @@
 #include <common.h>
 #include <asm/io.h>
 #include <led.h>
+#include <miiphy.h>
 
 enum {
 	BOARD_TYPE_PCB110 = 0xAABBCE00,
@@ -64,6 +65,28 @@ static void vcoreiii_gpio_set_alternate(int gpio, int mode)
 	}
 }
 
+int board_phy_config(struct phy_device *phydev)
+{
+	if (gd->board_type == BOARD_TYPE_PCB110 ||
+	    gd->board_type == BOARD_TYPE_PCB112) {
+		phy_write(phydev, 0, 31, 0x10);
+		phy_write(phydev, 0, 18, 0x80F0);
+		while (phy_read(phydev, 0, 18) & 0x8000)
+			;
+		phy_write(phydev, 0, 31, 0);
+	}
+	if (gd->board_type == BOARD_TYPE_PCB111) {
+		phy_write(phydev, 0, 31, 0x10);
+		phy_write(phydev, 0, 18, 0x80A0);
+		while (phy_read(phydev, 0, 18) & 0x8000)
+			;
+		phy_write(phydev, 0, 14, 0x800);
+		phy_write(phydev, 0, 31, 0);
+	}
+
+	return 0;
+}
+
 void board_debug_uart_init(void)
 {
 	/* too early for the pinctrl driver, so configure the UART pins here */
-- 
2.7.4

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

* [U-Boot] [PATCH v3 3/4] net: mscc: jaguar2: Add ethenet nodes for Jaguar2.
  2019-03-30 10:16 [U-Boot] [PATCH v3 0/4] Add network support for Jaguar2 SoCs Horatiu Vultur
  2019-03-30 10:17 ` [U-Boot] [PATCH v3 1/4] net: Add MSCC Jaguar2 network driver Horatiu Vultur
  2019-03-30 10:17 ` [U-Boot] [PATCH v3 2/4] board: mscc: jr2: Update MSCC Jaguar2 boards Horatiu Vultur
@ 2019-03-30 10:17 ` Horatiu Vultur
  2019-03-30 10:17 ` [U-Boot] [PATCH v3 4/4] configs: mscc_jr2: Add network support Horatiu Vultur
  3 siblings, 0 replies; 7+ messages in thread
From: Horatiu Vultur @ 2019-03-30 10:17 UTC (permalink / raw)
  To: u-boot

Add ethernet nodes for Jaguar2 SoCs family. There are 3 pcb in this
family: pcb110, pcb111 and pcb112.

Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
 arch/mips/dts/jr2_pcb110.dts        |  76 +++++++
 arch/mips/dts/jr2_pcb111.dts        | 400 ++++++++++++++++++++++++++++++++++++
 arch/mips/dts/mscc,jr2.dtsi         | 116 +++++++++++
 arch/mips/dts/serval2_pcb112.dts    |  44 ++++
 include/dt-bindings/mscc/jr2_data.h |  19 ++
 5 files changed, 655 insertions(+)
 create mode 100644 include/dt-bindings/mscc/jr2_data.h

diff --git a/arch/mips/dts/jr2_pcb110.dts b/arch/mips/dts/jr2_pcb110.dts
index ddc30ff..4a5a584 100644
--- a/arch/mips/dts/jr2_pcb110.dts
+++ b/arch/mips/dts/jr2_pcb110.dts
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 #include "mscc,jr2.dtsi"
+#include <dt-bindings/mscc/jr2_data.h>
 
 / {
 	model = "Jaguar2 Cu8-Sfp16 PCB110 Reference Board";
@@ -72,3 +73,78 @@
 	sgpio-ports = <0x3f00ffff>;
 	gpio-ranges = <&sgpio2 0 0 96>;
 };
+
+&mdio1 {
+	status = "okay";
+
+	phy0: ethernet-phy at 0 {
+		reg = <0>;
+	};
+	phy1: ethernet-phy at 1 {
+		reg = <1>;
+	};
+	phy2: ethernet-phy at 2 {
+		reg = <2>;
+	};
+	phy3: ethernet-phy at 3 {
+		reg = <3>;
+	};
+	phy4: ethernet-phy at 4 {
+		reg = <4>;
+	};
+	phy5: ethernet-phy at 5 {
+		reg = <5>;
+	};
+	phy6: ethernet-phy at 6 {
+		reg = <6>;
+	};
+	phy7: ethernet-phy at 7 {
+		reg = <7>;
+	};
+};
+
+&switch {
+	ethernet-ports {
+
+		port0: port at 0 {
+			reg = <0>;
+			phy-handle = <&phy0>;
+			phys = <&serdes_hsio 0 SERDES1G(1) PHY_MODE_SGMII>;
+		};
+		port1: port at 1 {
+			reg = <1>;
+			phy-handle = <&phy1>;
+			phys = <&serdes_hsio 1 SERDES1G(2) PHY_MODE_SGMII>;
+		};
+		port2: port at 2 {
+			reg = <2>;
+			phy-handle = <&phy2>;
+			phys = <&serdes_hsio 2 SERDES1G(3) PHY_MODE_SGMII>;
+		};
+		port3: port at 3 {
+			reg = <3>;
+			phy-handle = <&phy3>;
+			phys = <&serdes_hsio 3 SERDES1G(4) PHY_MODE_SGMII>;
+		};
+		port4: port at 4 {
+			reg = <4>;
+			phy-handle = <&phy4>;
+			phys = <&serdes_hsio 4 SERDES1G(5) PHY_MODE_SGMII>;
+		};
+		port5: port at 5 {
+			reg = <5>;
+			phy-handle = <&phy5>;
+			phys = <&serdes_hsio 5 SERDES1G(6) PHY_MODE_SGMII>;
+		};
+		port6: port at 6 {
+			reg = <6>;
+			phy-handle = <&phy6>;
+			phys = <&serdes_hsio 6 SERDES1G(7) PHY_MODE_SGMII>;
+		};
+		port7: port at 7 {
+			reg = <7>;
+			phy-handle = <&phy7>;
+			phys = <&serdes_hsio 7 SERDES1G(8) PHY_MODE_SGMII>;
+		};
+	};
+};
diff --git a/arch/mips/dts/jr2_pcb111.dts b/arch/mips/dts/jr2_pcb111.dts
index 4d411b6..f37ebc7 100644
--- a/arch/mips/dts/jr2_pcb111.dts
+++ b/arch/mips/dts/jr2_pcb111.dts
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 #include "mscc,jr2.dtsi"
+#include <dt-bindings/mscc/jr2_data.h>
 
 / {
 	model = "Jaguar2 Cu48 PCB111 Reference Board";
@@ -72,3 +73,402 @@
 	sgpio-ports = <0xff000000>;
 	gpio-ranges = <&sgpio2 0 0 96>;
 };
+
+&mdio1 {
+	status = "okay";
+
+	phy0: ethernet-phy at 0 {
+		reg = <0>;
+	};
+	phy1: ethernet-phy at 1 {
+		reg = <1>;
+	};
+	phy2: ethernet-phy at 2 {
+		reg = <2>;
+	};
+	phy3: ethernet-phy at 3 {
+		reg = <3>;
+	};
+	phy4: ethernet-phy at 4 {
+		reg = <4>;
+	};
+	phy5: ethernet-phy at 5 {
+		reg = <5>;
+	};
+	phy6: ethernet-phy at 6 {
+		reg = <6>;
+	};
+	phy7: ethernet-phy at 7 {
+		reg = <7>;
+	};
+	phy8: ethernet-phy at 8 {
+		reg = <8>;
+	};
+	phy9: ethernet-phy at 9 {
+		reg = <9>;
+	};
+	phy10: ethernet-phy at 10 {
+		reg = <10>;
+	};
+	phy11: ethernet-phy at 11 {
+		reg = <11>;
+	};
+	phy12: ethernet-phy at 12 {
+		reg = <12>;
+	};
+	phy13: ethernet-phy at 13 {
+		reg = <13>;
+	};
+	phy14: ethernet-phy at 14 {
+		reg = <14>;
+	};
+	phy15: ethernet-phy at 15 {
+		reg = <15>;
+	};
+	phy16: ethernet-phy at 16 {
+		reg = <16>;
+	};
+	phy17: ethernet-phy at 17 {
+		reg = <17>;
+	};
+	phy18: ethernet-phy at 18 {
+		reg = <18>;
+	};
+	phy19: ethernet-phy at 19 {
+		reg = <19>;
+	};
+	phy20: ethernet-phy at 20 {
+		reg = <20>;
+	};
+	phy21: ethernet-phy at 21 {
+		reg = <21>;
+	};
+	phy22: ethernet-phy at 22 {
+		reg = <22>;
+	};
+	phy23: ethernet-phy at 23 {
+		reg = <23>;
+	};
+};
+
+&mdio2 {
+	status = "okay";
+
+	phy24: ethernet-phy at 24 {
+		reg = <0>;
+	};
+	phy25: ethernet-phy at 25 {
+		reg = <1>;
+	};
+	phy26: ethernet-phy at 26 {
+		reg = <2>;
+	};
+	phy27: ethernet-phy at 27 {
+		reg = <3>;
+	};
+	phy28: ethernet-phy at 28 {
+		reg = <4>;
+	};
+	phy29: ethernet-phy at 29 {
+		reg = <5>;
+	};
+	phy30: ethernet-phy at 30 {
+		reg = <6>;
+	};
+	phy31: ethernet-phy at 31 {
+		reg = <7>;
+	};
+	phy32: ethernet-phy at 32 {
+		reg = <8>;
+	};
+	phy33: ethernet-phy at 33 {
+		reg = <9>;
+	};
+	phy34: ethernet-phy at 34 {
+		reg = <10>;
+	};
+	phy35: ethernet-phy at 35 {
+		reg = <11>;
+	};
+	phy36: ethernet-phy at 36 {
+		reg = <12>;
+	};
+	phy37: ethernet-phy at 37 {
+		reg = <13>;
+	};
+	phy38: ethernet-phy at 38 {
+		reg = <14>;
+	};
+	phy39: ethernet-phy at 39 {
+		reg = <15>;
+	};
+	phy40: ethernet-phy at 40 {
+		reg = <16>;
+	};
+	phy41: ethernet-phy at 41 {
+		reg = <17>;
+	};
+	phy42: ethernet-phy at 42 {
+		reg = <18>;
+	};
+	phy43: ethernet-phy at 43 {
+		reg = <19>;
+	};
+	phy44: ethernet-phy at 44 {
+		reg = <20>;
+	};
+	phy45: ethernet-phy at 45 {
+		reg = <21>;
+	};
+	phy46: ethernet-phy at 46 {
+		reg = <22>;
+	};
+	phy47: ethernet-phy at 47 {
+		reg = <23>;
+	};
+};
+
+&switch {
+	ethernet-ports {
+		port0: port at 0 {
+			reg = <0>;
+			phy-handle = <&phy0>;
+			phys = <&serdes_hsio 0 SERDES6G(4) PHY_MODE_QSGMII>;
+		};
+		port1: port at 1 {
+			reg = <1>;
+			phy-handle = <&phy1>;
+			phys = <&serdes_hsio 1 0xff PHY_MODE_QSGMII>;
+		};
+		port2: port at 2 {
+			reg = <2>;
+			phy-handle = <&phy2>;
+			phys = <&serdes_hsio 2 0xff PHY_MODE_QSGMII>;
+		};
+		port3: port at 3 {
+			reg = <3>;
+			phy-handle = <&phy3>;
+			phys = <&serdes_hsio 3 0xff PHY_MODE_QSGMII>;
+		};
+		port4: port at 4 {
+			reg = <4>;
+			phy-handle = <&phy4>;
+			phys = <&serdes_hsio 4 SERDES6G(5) PHY_MODE_QSGMII>;
+		};
+		port5: port at 5 {
+			reg = <5>;
+			phy-handle = <&phy5>;
+			phys = <&serdes_hsio 5 0xff PHY_MODE_QSGMII>;
+		};
+		port6: port at 6 {
+			reg = <6>;
+			phy-handle = <&phy6>;
+			phys = <&serdes_hsio 6 0xff PHY_MODE_QSGMII>;
+		};
+		port7: port at 7 {
+			reg = <7>;
+			phy-handle = <&phy7>;
+			phys = <&serdes_hsio 7 0xff PHY_MODE_QSGMII>;
+		};
+		port8: port at 8 {
+			reg = <8>;
+			phy-handle = <&phy8>;
+			phys = <&serdes_hsio 8 SERDES6G(6) PHY_MODE_QSGMII>;
+		};
+		port9: port at 9 {
+			reg = <9>;
+			phy-handle = <&phy9>;
+			phys = <&serdes_hsio 9 0xff PHY_MODE_QSGMII>;
+		};
+		port10: port at 10 {
+			reg = <10>;
+			phy-handle = <&phy10>;
+			phys = <&serdes_hsio 10 0xff PHY_MODE_QSGMII>;
+		};
+		port11: port at 11 {
+			reg = <11>;
+			phy-handle = <&phy11>;
+			phys = <&serdes_hsio 11 0xff PHY_MODE_QSGMII>;
+		};
+		port12: port at 12 {
+			reg = <12>;
+			phy-handle = <&phy12>;
+			phys = <&serdes_hsio 12 SERDES6G(7) PHY_MODE_QSGMII>;
+		};
+		port13: port at 13 {
+			reg = <13>;
+			phy-handle = <&phy13>;
+			phys = <&serdes_hsio 13 0xff PHY_MODE_QSGMII>;
+		};
+		port14: port at 14 {
+			reg = <14>;
+			phy-handle = <&phy14>;
+			phys = <&serdes_hsio 14 0xff PHY_MODE_QSGMII>;
+		};
+		port15: port at 15 {
+			reg = <15>;
+			phy-handle = <&phy15>;
+			phys = <&serdes_hsio 15 0xff PHY_MODE_QSGMII>;
+		};
+		port16: port at 16 {
+			reg = <16>;
+			phy-handle = <&phy16>;
+			phys = <&serdes_hsio 16 SERDES6G(8) PHY_MODE_QSGMII>;
+		};
+		port17: port at 17 {
+			reg = <17>;
+			phy-handle = <&phy17>;
+			phys = <&serdes_hsio 17 0xff PHY_MODE_QSGMII>;
+		};
+		port18: port at 18 {
+			reg = <18>;
+			phy-handle = <&phy18>;
+			phys = <&serdes_hsio 18 0xff PHY_MODE_QSGMII>;
+		};
+		port19: port at 19 {
+			reg = <19>;
+			phy-handle = <&phy19>;
+			phys = <&serdes_hsio 19 0xff PHY_MODE_QSGMII>;
+		};
+		port20: port at 20 {
+			reg = <20>;
+			phy-handle = <&phy20>;
+			phys = <&serdes_hsio 20 SERDES6G(9) PHY_MODE_QSGMII>;
+		};
+		port21: port at 21 {
+			reg = <21>;
+			phy-handle = <&phy21>;
+			phys = <&serdes_hsio 21 0xff PHY_MODE_QSGMII>;
+		};
+		port22: port at 22 {
+			reg = <22>;
+			phy-handle = <&phy22>;
+			phys = <&serdes_hsio 22 0xff PHY_MODE_QSGMII>;
+		};
+		port23: port at 23 {
+			reg = <23>;
+			phy-handle = <&phy23>;
+			phys = <&serdes_hsio 23 0xff PHY_MODE_QSGMII>;
+		};
+		port24: port at 24 {
+			reg = <24>;
+			phy-handle = <&phy24>;
+			phys = <&serdes_hsio 24 SERDES6G(10) PHY_MODE_QSGMII>;
+		};
+		port25: port at 25 {
+			reg = <25>;
+			phy-handle = <&phy25>;
+			phys = <&serdes_hsio 25 0xff PHY_MODE_QSGMII>;
+		};
+		port26: port at 26 {
+			reg = <26>;
+			phy-handle = <&phy26>;
+			phys = <&serdes_hsio 26 0xff PHY_MODE_QSGMII>;
+		};
+		port27: port at 27 {
+			reg = <27>;
+			phy-handle = <&phy27>;
+			phys = <&serdes_hsio 27 0xff PHY_MODE_QSGMII>;
+		};
+		port28: port at 28 {
+			reg = <28>;
+			phy-handle = <&phy28>;
+			phys = <&serdes_hsio 28 SERDES6G(11) PHY_MODE_QSGMII>;
+		};
+		port29: port at 29 {
+			reg = <29>;
+			phy-handle = <&phy29>;
+			phys = <&serdes_hsio 29 0xff PHY_MODE_QSGMII>;
+		};
+		port30: port at 30 {
+			reg = <30>;
+			phy-handle = <&phy30>;
+			phys = <&serdes_hsio 30 0xff PHY_MODE_QSGMII>;
+		};
+		port31: port at 31 {
+			reg = <31>;
+			phy-handle = <&phy31>;
+			phys = <&serdes_hsio 31 0xff PHY_MODE_QSGMII>;
+		};
+		port32: port at 32 {
+			reg = <32>;
+			phy-handle = <&phy32>;
+			phys = <&serdes_hsio 32 SERDES6G(12) PHY_MODE_QSGMII>;
+		};
+		port33: port at 33 {
+			reg = <33>;
+			phy-handle = <&phy33>;
+			phys = <&serdes_hsio 33 0xff PHY_MODE_QSGMII>;
+		};
+		port34: port at 34 {
+			reg = <34>;
+			phy-handle = <&phy34>;
+			phys = <&serdes_hsio 34 0xff PHY_MODE_QSGMII>;
+		};
+		port35: port at 35 {
+			reg = <35>;
+			phy-handle = <&phy35>;
+			phys = <&serdes_hsio 35 0xff PHY_MODE_QSGMII>;
+		};
+		port36: port at 36 {
+			reg = <36>;
+			phy-handle = <&phy36>;
+			phys = <&serdes_hsio 36 SERDES6G(13) PHY_MODE_QSGMII>;
+		};
+		port37: port at 37 {
+			reg = <37>;
+			phy-handle = <&phy37>;
+			phys = <&serdes_hsio 37 0xff PHY_MODE_QSGMII>;
+		};
+		port38: port at 38 {
+			reg = <38>;
+			phy-handle = <&phy38>;
+			phys = <&serdes_hsio 38 0xff PHY_MODE_QSGMII>;
+		};
+		port39: port at 39 {
+			reg = <39>;
+			phy-handle = <&phy39>;
+			phys = <&serdes_hsio 39 0xff PHY_MODE_QSGMII>;
+		};
+		port40: port at 40 {
+			reg = <40>;
+			phy-handle = <&phy40>;
+			phys = <&serdes_hsio 40 SERDES6G(14) PHY_MODE_QSGMII>;
+		};
+		port41: port at 41 {
+			reg = <41>;
+			phy-handle = <&phy41>;
+			phys = <&serdes_hsio 41 0xff PHY_MODE_QSGMII>;
+		};
+		port42: port at 42 {
+			reg = <42>;
+			phy-handle = <&phy42>;
+			phys = <&serdes_hsio 42 0xff PHY_MODE_QSGMII>;
+		};
+		port43: port at 43 {
+			reg = <43>;
+			phy-handle = <&phy43>;
+			phys = <&serdes_hsio 43 0xff PHY_MODE_QSGMII>;
+		};
+		port44: port at 44 {
+			reg = <44>;
+			phy-handle = <&phy44>;
+			phys = <&serdes_hsio 44 SERDES6G(15) PHY_MODE_QSGMII>;
+		};
+		port45: port at 45 {
+			reg = <45>;
+			phy-handle = <&phy45>;
+			phys = <&serdes_hsio 45 0xff PHY_MODE_QSGMII>;
+		};
+		port46: port at 46 {
+			reg = <46>;
+			phy-handle = <&phy46>;
+			phys = <&serdes_hsio 46 0xff PHY_MODE_QSGMII>;
+		};
+		port47: port at 47 {
+			reg = <47>;
+			phy-handle = <&phy47>;
+			phys = <&serdes_hsio 47 0xff PHY_MODE_QSGMII>;
+		};
+	};
+};
diff --git a/arch/mips/dts/mscc,jr2.dtsi b/arch/mips/dts/mscc,jr2.dtsi
index 0900926..7f5a96f 100644
--- a/arch/mips/dts/mscc,jr2.dtsi
+++ b/arch/mips/dts/mscc,jr2.dtsi
@@ -183,5 +183,121 @@
 			gpio-bank-name = "sgpio2_";
 			sgpio-clock = <0x14>;
 		};
+
+		switch: switch at 1010000 {
+			compatible = "mscc,vsc7454-switch";
+			reg = <0x01040000 0x0100>,   // VTSS_TO_DEV_0
+			      <0x01050000 0x0100>,   // VTSS_TO_DEV_1
+			      <0x01060000 0x0100>,   // VTSS_TO_DEV_2
+			      <0x01070000 0x0100>,   // VTSS_TO_DEV_3
+			      <0x01080000 0x0100>,   // VTSS_TO_DEV_4
+			      <0x01090000 0x0100>,   // VTSS_TO_DEV_5
+			      <0x010a0000 0x0100>,   // VTSS_TO_DEV_6
+			      <0x010b0000 0x0100>,   // VTSS_TO_DEV_7
+			      <0x010c0000 0x0100>,   // VTSS_TO_DEV_8
+			      <0x010d0000 0x0100>,   // VTSS_TO_DEV_9
+			      <0x010e0000 0x0100>,   // VTSS_TO_DEV_10
+			      <0x010f0000 0x0100>,   // VTSS_TO_DEV_11
+			      <0x01100000 0x0100>,   // VTSS_TO_DEV_12
+			      <0x01110000 0x0100>,   // VTSS_TO_DEV_13
+			      <0x01120000 0x0100>,   // VTSS_TO_DEV_14
+			      <0x01130000 0x0100>,   // VTSS_TO_DEV_15
+			      <0x01140000 0x0100>,   // VTSS_TO_DEV_16
+			      <0x01150000 0x0100>,   // VTSS_TO_DEV_17
+			      <0x01160000 0x0100>,   // VTSS_TO_DEV_18
+			      <0x01170000 0x0100>,   // VTSS_TO_DEV_19
+			      <0x01180000 0x0100>,   // VTSS_TO_DEV_20
+			      <0x01190000 0x0100>,   // VTSS_TO_DEV_21
+			      <0x011a0000 0x0100>,   // VTSS_TO_DEV_22
+			      <0x011b0000 0x0100>,   // VTSS_TO_DEV_23
+			      <0x011c0000 0x0100>,   // VTSS_TO_DEV_24
+			      <0x011d0000 0x0100>,   // VTSS_TO_DEV_25
+			      <0x011e0000 0x0100>,   // VTSS_TO_DEV_26
+			      <0x011f0000 0x0100>,   // VTSS_TO_DEV_27
+			      <0x01200000 0x0100>,   // VTSS_TO_DEV_28
+			      <0x01210000 0x0100>,   // VTSS_TO_DEV_29
+			      <0x01220000 0x0100>,   // VTSS_TO_DEV_30
+			      <0x01230000 0x0100>,   // VTSS_TO_DEV_31
+			      <0x01240000 0x0100>,   // VTSS_TO_DEV_32
+			      <0x01250000 0x0100>,   // VTSS_TO_DEV_33
+			      <0x01260000 0x0100>,   // VTSS_TO_DEV_34
+			      <0x01270000 0x0100>,   // VTSS_TO_DEV_35
+			      <0x01280000 0x0100>,   // VTSS_TO_DEV_36
+			      <0x01290000 0x0100>,   // VTSS_TO_DEV_37
+			      <0x012a0000 0x0100>,   // VTSS_TO_DEV_38
+			      <0x012b0000 0x0100>,   // VTSS_TO_DEV_39
+			      <0x012c0000 0x0100>,   // VTSS_TO_DEV_40
+			      <0x012d0000 0x0100>,   // VTSS_TO_DEV_41
+			      <0x012e0000 0x0100>,   // VTSS_TO_DEV_42
+			      <0x012f0000 0x0100>,   // VTSS_TO_DEV_43
+			      <0x01300000 0x0100>,   // VTSS_TO_DEV_44
+			      <0x01310000 0x0100>,   // VTSS_TO_DEV_45
+			      <0x01320000 0x0100>,   // VTSS_TO_DEV_46
+			      <0x01330000 0x0100>,   // VTSS_TO_DEV_47
+			      <0x01f00000 0x100000>, // ANA_AC
+			      <0x01d00000 0x100000>, // ANA_CL
+			      <0x01e00000 0x100000>, // ANA_L2
+			      <0x01410000 0x10000>,  // ASM
+			      <0x01460000 0x10000>,  // HSIO
+			      <0x01420000 0x00000>,  // LRN
+			      <0x017d0000 0x10000>,  // QFWD
+			      <0x01020000 0x20000>,  // QS
+			      <0x017e0000 0x10000>,  // QSYS
+			      <0x01b00000 0x80000>;  // REW
+			reg-names = "port0", "port1", "port2", "port3", "port4",
+				    "port5", "port6", "port7", "port8", "port9",
+				    "port10", "port11", "port12", "port13",
+				    "port14", "port15", "port16", "port17",
+				    "port18", "port19", "port20", "port21",
+				    "port22", "port23", "port24", "port25",
+				    "port26", "port27", "port28", "port29",
+				    "port30", "port31", "port32", "port33",
+				    "port34", "port35", "port36", "port37",
+				    "port38", "port39", "port40", "port41",
+				    "port42", "port43", "port44", "port45",
+				    "port46", "port47", "ana_ac", "ana_cl",
+				    "ana_l2", "asm", "hsio", "lrn", "qfwd",
+				    "qs", "qsys", "rew";
+			status = "okay";
+
+			ethernet-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
+		mdio0: mdio at 010100c8 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "mscc,jr2-miim";
+			reg = <0x010100c8 0x24>;
+			status = "disabled";
+		};
+
+		mdio1: mdio at 010100ec {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "mscc,jr2-miim";
+			reg = <0x010100ec 0x24>;
+			status = "disabled";
+		};
+
+		mdio2: mdio at 01010110 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "mscc,jr2-miim";
+			reg = <0x01010110 0x24>;
+			status = "disabled";
+		};
+
+		hsio: syscon at 10d0000 {
+			compatible = "mscc,jr2-hsio", "syscon", "simple-mfd";
+			reg = <0x10d0000 0x10000>;
+
+			serdes_hsio: serdes_hsio {
+				compatible = "mscc,vsc7454-serdes";
+				#phy-cells = <3>;
+			};
+		};
 	};
 };
diff --git a/arch/mips/dts/serval2_pcb112.dts b/arch/mips/dts/serval2_pcb112.dts
index fe025f4..7a9d595 100644
--- a/arch/mips/dts/serval2_pcb112.dts
+++ b/arch/mips/dts/serval2_pcb112.dts
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 #include "mscc,jr2.dtsi"
+#include <dt-bindings/mscc/jr2_data.h>
 
 / {
 	model = "Serval2 NID PCB112 Reference Board";
@@ -58,3 +59,46 @@
 	status = "okay";
 	sgpio-ports = <0x3fe0ffff>;
 };
+
+&mdio0 {
+	status = "okay";
+
+	phy16: ethernet-phy at 16 {
+		reg = <16>;
+	};
+	phy17: ethernet-phy at 17 {
+		reg = <17>;
+	};
+	phy18: ethernet-phy at 18 {
+		reg = <18>;
+	};
+	phy19: ethernet-phy at 19 {
+		reg = <19>;
+	};
+};
+
+&switch {
+	ethernet-ports {
+
+		port0: port at 0 {
+			reg = <24>;
+			phy-handle = <&phy16>;
+			phys = <&serdes_hsio 24 SERDES6G(0) PHY_MODE_SGMII>;
+		};
+		port1: port at 1 {
+			reg = <25>;
+			phy-handle = <&phy17>;
+			phys = <&serdes_hsio 25 SERDES6G(1) PHY_MODE_SGMII>;
+		};
+		port2: port at 2 {
+			reg = <26>;
+			phy-handle = <&phy18>;
+			phys = <&serdes_hsio 26 SERDES6G(2) PHY_MODE_SGMII>;
+		};
+		port3: port at 3 {
+			reg = <27>;
+			phy-handle = <&phy19>;
+			phys = <&serdes_hsio 27 SERDES6G(3) PHY_MODE_SGMII>;
+		};
+	};
+};
diff --git a/include/dt-bindings/mscc/jr2_data.h b/include/dt-bindings/mscc/jr2_data.h
new file mode 100644
index 0000000..2f06fc5
--- /dev/null
+++ b/include/dt-bindings/mscc/jr2_data.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _JR2_DATA_H_
+#define _JR2_DATA_H_
+
+#define SERDES1G(x)     (x)
+#define SERDES1G_MAX    SERDES1G(10)
+#define SERDES6G(x)     (SERDES1G_MAX + 1 + (x))
+#define SERDES6G_MAX    SERDES6G(17)
+#define SERDES_MAX      (SERDES6G_MAX + 1)
+
+/* similar with phy_interface_t */
+#define PHY_MODE_SGMII  2
+#define PHY_MODE_QSGMII 4
+
+#endif
-- 
2.7.4

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

* [U-Boot] [PATCH v3 4/4] configs: mscc_jr2: Add network support
  2019-03-30 10:16 [U-Boot] [PATCH v3 0/4] Add network support for Jaguar2 SoCs Horatiu Vultur
                   ` (2 preceding siblings ...)
  2019-03-30 10:17 ` [U-Boot] [PATCH v3 3/4] net: mscc: jaguar2: Add ethenet nodes for Jaguar2 Horatiu Vultur
@ 2019-03-30 10:17 ` Horatiu Vultur
  3 siblings, 0 replies; 7+ messages in thread
From: Horatiu Vultur @ 2019-03-30 10:17 UTC (permalink / raw)
  To: u-boot

Update default confing to use network driver for Jaguar2 SoCs.

Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
 configs/mscc_jr2_defconfig | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/configs/mscc_jr2_defconfig b/configs/mscc_jr2_defconfig
index 95562b7..92c22b8 100644
--- a/configs/mscc_jr2_defconfig
+++ b/configs/mscc_jr2_defconfig
@@ -28,7 +28,10 @@ CONFIG_CMD_MEMTEST=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_SF=y
 CONFIG_CMD_SPI=y
-# CONFIG_CMD_NET is not set
+CONFIG_CMD_DHCP=y
+# CONFIG_NET_TFTP_VARS is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nor0=spi_flash"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:1m(UBoot),256k(Env),256k(Env.bk)"
@@ -66,3 +69,4 @@ CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_LZMA=y
+CONFIG_MSCC_JR2_SWITCH=y
-- 
2.7.4

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

* [U-Boot] [PATCH v3 1/4] net: Add MSCC Jaguar2 network driver.
  2019-03-30 10:17 ` [U-Boot] [PATCH v3 1/4] net: Add MSCC Jaguar2 network driver Horatiu Vultur
@ 2019-04-03 10:18   ` Daniel Schwierzeck
  2019-04-03 10:59     ` Horatiu Vultur
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel Schwierzeck @ 2019-04-03 10:18 UTC (permalink / raw)
  To: u-boot



Am 30.03.19 um 11:17 schrieb Horatiu Vultur:
> Add network driver for Microsemi Ethernet switch.
> It is present on Jaguar2 SoCs.
> 
> Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
> ---
>  drivers/net/mscc_eswitch/Kconfig      |    7 +
>  drivers/net/mscc_eswitch/Makefile     |    1 +
>  drivers/net/mscc_eswitch/jr2_switch.c | 1075 +++++++++++++++++++++++++++++++++
>  include/configs/vcoreiii.h            |    2 +-
>  4 files changed, 1084 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/net/mscc_eswitch/jr2_switch.c

Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>

nits below

> 
> diff --git a/drivers/net/mscc_eswitch/Kconfig b/drivers/net/mscc_eswitch/Kconfig
> index 88e5a97..3f9d14b 100644
> --- a/drivers/net/mscc_eswitch/Kconfig
> +++ b/drivers/net/mscc_eswitch/Kconfig
> @@ -15,3 +15,10 @@ config MSCC_LUTON_SWITCH
>  	select PHYLIB
>  	help
>  	  This driver supports the Luton network switch device.
> +
> +config MSCC_JR2_SWITCH
> +	bool "Jaguar2 switch driver"
> +	depends on DM_ETH && ARCH_MSCC
> +	select PHYLIB
> +	help
> +	  This driver supports the Jaguar2 network switch device.
> diff --git a/drivers/net/mscc_eswitch/Makefile b/drivers/net/mscc_eswitch/Makefile
> index 751a839..0a1b863 100644
> --- a/drivers/net/mscc_eswitch/Makefile
> +++ b/drivers/net/mscc_eswitch/Makefile
> @@ -1,3 +1,4 @@
>  
>  obj-$(CONFIG_MSCC_OCELOT_SWITCH) += ocelot_switch.o mscc_miim.o mscc_xfer.o mscc_mac_table.o
>  obj-$(CONFIG_MSCC_LUTON_SWITCH) += luton_switch.o mscc_miim.o mscc_xfer.o mscc_mac_table.o
> +obj-$(CONFIG_MSCC_JR2_SWITCH) += jr2_switch.o mscc_xfer.o
> diff --git a/drivers/net/mscc_eswitch/jr2_switch.c b/drivers/net/mscc_eswitch/jr2_switch.c
> new file mode 100644
> index 0000000..d4a2498
> --- /dev/null
> +++ b/drivers/net/mscc_eswitch/jr2_switch.c
> @@ -0,0 +1,1075 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2018 Microsemi Corporation
> + */
> +
> +#include <common.h>
> +#include <config.h>
> +#include <dm.h>
> +#include <dm/of_access.h>
> +#include <dm/of_addr.h>
> +#include <fdt_support.h>
> +#include <linux/io.h>
> +#include <linux/ioport.h>
> +#include <miiphy.h>
> +#include <net.h>
> +#include <wait_bit.h>
> +
> +#include <dt-bindings/mscc/jr2_data.h>
> +#include "mscc_xfer.h"
> +
> +#define GCB_MIIM_MII_STATUS		0x0
> +#define		GCB_MIIM_STAT_BUSY		BIT(3)
> +#define GCB_MIIM_MII_CMD		0x8
> +#define		GCB_MIIM_MII_CMD_SCAN		BIT(0)
> +#define		GCB_MIIM_MII_CMD_OPR_WRITE	BIT(1)
> +#define		GCB_MIIM_MII_CMD_OPR_READ	BIT(2)
> +#define		GCB_MIIM_MII_CMD_SINGLE_SCAN	BIT(3)
> +#define		GCB_MIIM_MII_CMD_WRDATA(x)	((x) << 4)
> +#define		GCB_MIIM_MII_CMD_REGAD(x)	((x) << 20)
> +#define		GCB_MIIM_MII_CMD_PHYAD(x)	((x) << 25)
> +#define		GCB_MIIM_MII_CMD_VLD		BIT(31)
> +#define GCB_MIIM_DATA			0xC
> +#define		GCB_MIIM_DATA_ERROR		(0x3 << 16)
> +
> +#define ANA_AC_RAM_CTRL_RAM_INIT		0x94358
> +#define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET	0x94370
> +
> +#define ANA_CL_PORT_VLAN_CFG(x)			(0x24018 + 0xc8 * (x))
> +#define		ANA_CL_PORT_VLAN_CFG_AWARE_ENA			BIT(19)
> +#define		ANA_CL_PORT_VLAN_CFG_POP_CNT(x)			((x) << 17)
> +
> +#define ANA_L2_COMMON_FWD_CFG			0x8a2a8
> +#define		ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA	BIT(6)
> +
> +#define ASM_CFG_STAT_CFG			0x3508
> +#define ASM_CFG_PORT(x)				(0x36c4 + 0x4 * (x))
> +#define		ASM_CFG_PORT_NO_PREAMBLE_ENA		BIT(8)
> +#define		ASM_CFG_PORT_INJ_FORMAT_CFG(x)		((x) << 1)
> +#define ASM_RAM_CTRL_RAM_INIT			0x39b8
> +
> +#define DEV_DEV_CFG_DEV_RST_CTRL		0x0
> +#define		DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(x)	((x) << 20)
> +#define DEV_MAC_CFG_MAC_ENA		0x1c
> +#define		DEV_MAC_CFG_MAC_ENA_RX_ENA		BIT(4)
> +#define		DEV_MAC_CFG_MAC_ENA_TX_ENA		BIT(0)
> +#define	DEV_MAC_CFG_MAC_IFG		0x34
> +#define		DEV_MAC_CFG_MAC_IFG_TX_IFG(x)		((x) << 8)
> +#define		DEV_MAC_CFG_MAC_IFG_RX_IFG2(x)		((x) << 4)
> +#define		DEV_MAC_CFG_MAC_IFG_RX_IFG1(x)		(x)
> +#define	DEV_PCS1G_CFG_PCS1G_CFG		0x40
> +#define		DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA		BIT(0)
> +#define	DEV_PCS1G_CFG_PCS1G_MODE	0x44
> +#define	DEV_PCS1G_CFG_PCS1G_SD		0x48
> +#define	DEV_PCS1G_CFG_PCS1G_ANEG	0x4c
> +#define		DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(x)	((x) << 16)
> +
> +#define DSM_RAM_CTRL_RAM_INIT		0x8
> +
> +#define HSIO_ANA_SERDES1G_DES_CFG		0xac
> +#define		HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(x)		((x) << 1)
> +#define		HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(x)		((x) << 5)
> +#define		HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(x)		((x) << 8)
> +#define		HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(x)		((x) << 13)
> +#define HSIO_ANA_SERDES1G_IB_CFG		0xb0
> +#define		HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(x)	(x)
> +#define		HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(x)		((x) << 6)
> +#define		HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP	BIT(9)
> +#define		HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV		BIT(11)
> +#define		HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM		BIT(13)
> +#define		HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(x)		((x) << 19)
> +#define		HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(x)		((x) << 24)
> +#define HSIO_ANA_SERDES1G_OB_CFG		0xb4
> +#define		HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(x)	(x)
> +#define		HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(x)		((x) << 4)
> +#define		HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(x)	((x) << 10)
> +#define		HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(x)		((x) << 13)
> +#define		HSIO_ANA_SERDES1G_OB_CFG_SLP(x)			((x) << 17)
> +#define HSIO_ANA_SERDES1G_SER_CFG		0xb8
> +#define HSIO_ANA_SERDES1G_COMMON_CFG		0xbc
> +#define		HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE		BIT(0)
> +#define		HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE		BIT(18)
> +#define		HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST		BIT(31)
> +#define HSIO_ANA_SERDES1G_PLL_CFG		0xc0
> +#define		HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA		BIT(7)
> +#define		HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(x)	((x) << 8)
> +#define		HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2		BIT(21)
> +#define HSIO_DIG_SERDES1G_DFT_CFG0		0xc8
> +#define HSIO_DIG_SERDES1G_TP_CFG		0xd4
> +#define HSIO_DIG_SERDES1G_MISC_CFG		0xdc
> +#define		HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST		BIT(0)
> +#define HSIO_MCB_SERDES1G_CFG			0xe8
> +#define		HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT		BIT(31)
> +#define		HSIO_MCB_SERDES1G_CFG_ADDR(x)			(x)
> +
> +#define HSIO_ANA_SERDES6G_DES_CFG		0x11c
> +#define		HSIO_ANA_SERDES6G_DES_CFG_SWAP_ANA		BIT(0)
> +#define		HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(x)		((x) << 1)
> +#define		HSIO_ANA_SERDES6G_DES_CFG_SWAP_HYST		BIT(4)
> +#define		HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(x)		((x) << 5)
> +#define		HSIO_ANA_SERDES6G_DES_CFG_CPMD_SEL(x)		((x) << 8)
> +#define		HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(x)		((x) << 10)
> +#define		HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(x)		((x) << 13)
> +#define HSIO_ANA_SERDES6G_IB_CFG		0x120
> +#define		HSIO_ANA_SERDES6G_IB_CFG_REG_ENA		BIT(0)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA		BIT(1)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA		BIT(2)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(x)		((x) << 3)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_CONCUR			BIT(4)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA		BIT(5)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(x)	((x) << 7)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(x)	((x) << 9)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(x)	((x) << 11)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(x)	((x) << 13)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(x)	((x) << 15)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(x)	((x) << 18)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(x)		((x) << 20)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(x)		((x) << 24)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL		BIT(28)
> +#define		HSIO_ANA_SERDES6G_IB_CFG_SOFSI(x)		((x) << 29)
> +#define HSIO_ANA_SERDES6G_IB_CFG1		0x124
> +#define		HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET		BIT(4)
> +#define		HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP		BIT(5)
> +#define		HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID		BIT(6)
> +#define		HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP		BIT(7)
> +#define		HSIO_ANA_SERDES6G_IB_CFG1_SCALY(x)		((x) << 8)
> +#define		HSIO_ANA_SERDES6G_IB_CFG1_TSDET(x)		((x) << 12)
> +#define		HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(x)		((x) << 17)
> +#define HSIO_ANA_SERDES6G_IB_CFG2		0x128
> +#define		HSIO_ANA_SERDES6G_IB_CFG2_UREG(x)		(x)
> +#define		HSIO_ANA_SERDES6G_IB_CFG2_UMAX(x)		((x) << 3)
> +#define		HSIO_ANA_SERDES6G_IB_CFG2_TCALV(x)		((x) << 5)
> +#define		HSIO_ANA_SERDES6G_IB_CFG2_OCALS(x)		((x) << 10)
> +#define		HSIO_ANA_SERDES6G_IB_CFG2_OINFS(x)		((x) << 16)
> +#define		HSIO_ANA_SERDES6G_IB_CFG2_OINFI(x)		((x) << 22)
> +#define		HSIO_ANA_SERDES6G_IB_CFG2_TINFV(x)		((x) << 27)
> +#define HSIO_ANA_SERDES6G_IB_CFG3		0x12c
> +#define		HSIO_ANA_SERDES6G_IB_CFG3_INI_OFFSET(x)		(x)
> +#define		HSIO_ANA_SERDES6G_IB_CFG3_INI_LP(x)		((x) << 6)
> +#define		HSIO_ANA_SERDES6G_IB_CFG3_INI_MID(x)		((x) << 12)
> +#define		HSIO_ANA_SERDES6G_IB_CFG3_INI_HP(x)		((x) << 18)
> +#define HSIO_ANA_SERDES6G_IB_CFG4		0x130
> +#define		HSIO_ANA_SERDES6G_IB_CFG4_MAX_OFFSET(x)		(x)
> +#define		HSIO_ANA_SERDES6G_IB_CFG4_MAX_LP(x)		((x) << 6)
> +#define		HSIO_ANA_SERDES6G_IB_CFG4_MAX_MID(x)		((x) << 12)
> +#define		HSIO_ANA_SERDES6G_IB_CFG4_MAX_HP(x)		((x) << 18)
> +#define HSIO_ANA_SERDES6G_IB_CFG5		0x134
> +#define		HSIO_ANA_SERDES6G_IB_CFG4_MIN_OFFSET(x)		(x)
> +#define		HSIO_ANA_SERDES6G_IB_CFG4_MIN_LP(x)		((x) << 6)
> +#define		HSIO_ANA_SERDES6G_IB_CFG4_MIN_MID(x)		((x) << 12)
> +#define		HSIO_ANA_SERDES6G_IB_CFG4_MIN_HP(x)		((x) << 18)
> +#define HSIO_ANA_SERDES6G_OB_CFG		0x138
> +#define		HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(x)	(x)
> +#define		HSIO_ANA_SERDES6G_OB_CFG_SR(x)			((x) << 4)
> +#define		HSIO_ANA_SERDES6G_OB_CFG_SR_H			BIT(8)
> +#define		HSIO_ANA_SERDES6G_OB_CFG_SEL_RCTRL		BIT(9)
> +#define		HSIO_ANA_SERDES6G_OB_CFG_R_COR			BIT(10)
> +#define		HSIO_ANA_SERDES6G_OB_CFG_POST1(x)		((x) << 11)
> +#define		HSIO_ANA_SERDES6G_OB_CFG_R_ADJ_PDR		BIT(16)
> +#define		HSIO_ANA_SERDES6G_OB_CFG_R_ADJ_MUX		BIT(17)
> +#define		HSIO_ANA_SERDES6G_OB_CFG_PREC(x)		((x) << 18)
> +#define		HSIO_ANA_SERDES6G_OB_CFG_POST0(x)		((x) << 23)
> +#define		HSIO_ANA_SERDES6G_OB_CFG_POL			BIT(29)
> +#define		HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(x)		((x) << 30)
> +#define		HSIO_ANA_SERDES6G_OB_CFG_IDLE			BIT(31)
> +#define HSIO_ANA_SERDES6G_OB_CFG1		0x13c
> +#define		HSIO_ANA_SERDES6G_OB_CFG1_LEV(x)		(x)
> +#define		HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(x)		((x) << 6)
> +#define HSIO_ANA_SERDES6G_SER_CFG		0x140
> +#define HSIO_ANA_SERDES6G_COMMON_CFG		0x144
> +#define		HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(x)		(x)
> +#define		HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(x)		(x << 2)
> +#define		HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE		BIT(14)
> +#define		HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST		BIT(16)
> +#define HSIO_ANA_SERDES6G_PLL_CFG		0x148
> +#define		HSIO_ANA_SERDES6G_PLL_CFG_ROT_FRQ		BIT(0)
> +#define		HSIO_ANA_SERDES6G_PLL_CFG_ROT_DIR		BIT(1)
> +#define		HSIO_ANA_SERDES6G_PLL_CFG_RB_DATA_SEL		BIT(2)
> +#define		HSIO_ANA_SERDES6G_PLL_CFG_FSM_OOR_RECAL_ENA	BIT(3)
> +#define		HSIO_ANA_SERDES6G_PLL_CFG_FSM_FORCE_SET_ENA	BIT(4)
> +#define		HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA		BIT(5)
> +#define		HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(x)	((x) << 6)
> +#define		HSIO_ANA_SERDES6G_PLL_CFG_ENA_ROT		BIT(14)
> +#define		HSIO_ANA_SERDES6G_PLL_CFG_DIV4			BIT(15)
> +#define		HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(x)		((x) << 16)
> +#define HSIO_DIG_SERDES6G_MISC_CFG		0x108
> +#define		HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST		BIT(0)
> +#define HSIO_MCB_SERDES6G_CFG			0x168
> +#define		HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT		BIT(31)
> +#define		HSIO_MCB_SERDES6G_CFG_ADDR(x)			(x)
> +#define HSIO_HW_CFGSTAT_HW_CFG			0x16c
> +
> +#define LRN_COMMON_ACCESS_CTRL			0x0
> +#define		LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT	BIT(0)
> +#define LRN_COMMON_MAC_ACCESS_CFG0		0x4
> +#define LRN_COMMON_MAC_ACCESS_CFG1		0x8
> +#define LRN_COMMON_MAC_ACCESS_CFG2		0xc
> +#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(x)	(x)
> +#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(x)	((x) << 12)
> +#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD	BIT(15)
> +#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED	BIT(16)
> +#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY	BIT(23)
> +#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(x)	((x) << 24)
> +
> +#define QFWD_SYSTEM_SWITCH_PORT_MODE(x)		(0x4 * (x))
> +#define		QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA		BIT(17)
> +
> +#define QS_XTR_GRP_CFG(x)		(0x0 + 4 * (x))
> +#define QS_INJ_GRP_CFG(x)		(0x24 + (x) * 4)
> +
> +#define QSYS_SYSTEM_RESET_CFG			0xf0
> +#define QSYS_CALCFG_CAL_AUTO(x)			(0x3d4 + 4 * (x))
> +#define QSYS_CALCFG_CAL_CTRL			0x3e8
> +#define		QSYS_CALCFG_CAL_CTRL_CAL_MODE(x)		((x) << 11)
> +#define QSYS_RAM_CTRL_RAM_INIT			0x3ec
> +
> +#define REW_RAM_CTRL_RAM_INIT			0x53528
> +
> +#define VOP_RAM_CTRL_RAM_INIT			0x43638
> +
> +#define XTR_VALID_BYTES(x)	(4 - ((x) & 3))
> +#define MAC_VID			0
> +#define CPU_PORT		53
> +#define IFH_LEN			7
> +#define JR2_BUF_CELL_SZ		60
> +#define ETH_ALEN		6
> +#define PGID_BROADCAST		510
> +#define PGID_UNICAST		511
> +
> +static char *regs_names[] = {
> +	"port0", "port1", "port2", "port3", "port4", "port5", "port6", "port7",
> +	"port8", "port9", "port10", "port11", "port12", "port13", "port14",
> +	"port15", "port16", "port17", "port18", "port19", "port20", "port21",
> +	"port22", "port23", "port24", "port25", "port26", "port27", "port28",
> +	"port29", "port30", "port31", "port32", "port33", "port34", "port35",
> +	"port36", "port37", "port38", "port39", "port40", "port41", "port42",
> +	"port43", "port44", "port45", "port46", "port47",
> +	"ana_ac", "ana_cl", "ana_l2", "asm", "hsio", "lrn",
> +	"qfwd", "qs", "qsys", "rew",
> +};

this could be made const

> +
> +#define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1
> +#define MAX_PORT 48
> +
> +enum jr2_ctrl_regs {
> +	ANA_AC = MAX_PORT,
> +	ANA_CL,
> +	ANA_L2,
> +	ASM,
> +	HSIO,
> +	LRN,
> +	QFWD,
> +	QS,
> +	QSYS,
> +	REW,
> +};
> +
> +#define JR2_MIIM_BUS_COUNT 3
> +
> +struct jr2_phy_port_t {
> +	size_t phy_addr;
> +	struct mii_dev *bus;
> +	u8 serdes_index;
> +	u8 phy_mode;
> +};
> +
> +struct jr2_private {
> +	void __iomem *regs[REGS_NAMES_COUNT];
> +	struct mii_dev *bus[JR2_MIIM_BUS_COUNT];
> +	struct jr2_phy_port_t ports[MAX_PORT];
> +};
> +
> +struct jr2_miim_dev {
> +	void __iomem *regs;
> +	phys_addr_t miim_base;
> +	unsigned long miim_size;
> +	struct mii_dev *bus;
> +};
> +
> +static const unsigned long jr2_regs_qs[] = {
> +	[MSCC_QS_XTR_RD] = 0x8,
> +	[MSCC_QS_XTR_FLUSH] = 0x18,
> +	[MSCC_QS_XTR_DATA_PRESENT] = 0x1c,
> +	[MSCC_QS_INJ_WR] = 0x2c,
> +	[MSCC_QS_INJ_CTRL] = 0x34,
> +};
> +
> +static struct jr2_miim_dev miim[JR2_MIIM_BUS_COUNT];
> +static int miim_count = -1;
> +
> +static int mscc_miim_wait_ready(struct jr2_miim_dev *miim)
> +{
> +	unsigned long deadline;
> +	u32 val;
> +
> +	deadline = timer_get_us() + 250000;
> +
> +	do {
> +		val = readl(miim->regs + GCB_MIIM_MII_STATUS);
> +	} while (timer_get_us() <= deadline && (val & GCB_MIIM_STAT_BUSY));
> +
> +	if (val & GCB_MIIM_STAT_BUSY)
> +		return -ETIMEDOUT;
> +
> +	return 0;
> +}
> +
> +static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
> +{
> +	struct jr2_miim_dev *miim = (struct jr2_miim_dev *)bus->priv;
> +	u32 val;
> +	int ret;
> +
> +	ret = mscc_miim_wait_ready(miim);
> +	if (ret)
> +		goto out;
> +
> +	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
> +	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
> +	       miim->regs + GCB_MIIM_MII_CMD);
> +
> +	ret = mscc_miim_wait_ready(miim);
> +	if (ret)
> +		goto out;
> +
> +	val = readl(miim->regs + GCB_MIIM_DATA);
> +	if (val & GCB_MIIM_DATA_ERROR) {
> +		ret = -EIO;
> +		goto out;
> +	}
> +
> +	ret = val & 0xFFFF;
> + out:
> +	return ret;
> +}
> +
> +static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
> +			   u16 val)
> +{
> +	struct jr2_miim_dev *miim = (struct jr2_miim_dev *)bus->priv;
> +	int ret;
> +
> +	ret = mscc_miim_wait_ready(miim);
> +	if (ret < 0)
> +		goto out;
> +
> +	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
> +	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
> +	       GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
> +
> + out:
> +	return ret;
> +}
> +
> +static struct mii_dev *jr2_mdiobus_init(phys_addr_t miim_base,
> +					unsigned long miim_size)
> +{
> +	struct mii_dev *bus;
> +
> +	bus = mdio_alloc();
> +	if (!bus)
> +		return NULL;
> +
> +	++miim_count;
> +	sprintf(bus->name, "miim-bus%d", miim_count);
> +
> +	miim[miim_count].regs = ioremap(miim_base, miim_size);
> +	miim[miim_count].miim_base = miim_base;
> +	miim[miim_count].miim_size = miim_size;
> +	bus->priv = &miim[miim_count];
> +	bus->read = mscc_miim_read;
> +	bus->write = mscc_miim_write;
> +
> +	if (mdio_register(bus))
> +		return NULL;
> +
> +	miim[miim_count].bus = bus;
> +	return bus;
> +}
> +
> +static void jr2_cpu_capture_setup(struct jr2_private *priv)
> +{
> +	/* ASM: No preamble and IFH prefix on CPU injected frames */
> +	writel(ASM_CFG_PORT_NO_PREAMBLE_ENA |
> +	       ASM_CFG_PORT_INJ_FORMAT_CFG(1),
> +	       priv->regs[ASM] + ASM_CFG_PORT(CPU_PORT));
> +
> +	/* Set Manual injection via DEVCPU_QS registers for CPU queue 0 */
> +	writel(0x5, priv->regs[QS] + QS_INJ_GRP_CFG(0));
> +
> +	/* Set Manual extraction via DEVCPU_QS registers for CPU queue 0 */
> +	writel(0x7, priv->regs[QS] + QS_XTR_GRP_CFG(0));
> +
> +	/* Enable CPU port for any frame transfer */
> +	setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(CPU_PORT),
> +		     QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
> +
> +	/* Send a copy to CPU when found as forwarding entry */
> +	setbits_le32(priv->regs[ANA_L2] + ANA_L2_COMMON_FWD_CFG,
> +		     ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA);
> +}
> +
> +static void jr2_port_init(struct jr2_private *priv, int port)
> +{
> +	void __iomem *regs = priv->regs[port];
> +
> +	/* Enable PCS */
> +	writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA,
> +	       regs + DEV_PCS1G_CFG_PCS1G_CFG);
> +
> +	/* Disable Signal Detect */
> +	writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD);
> +
> +	/* Enable MAC RX and TX */
> +	writel(DEV_MAC_CFG_MAC_ENA_RX_ENA |
> +	       DEV_MAC_CFG_MAC_ENA_TX_ENA,
> +	       regs + DEV_MAC_CFG_MAC_ENA);
> +
> +	/* Clear sgmii_mode_ena */
> +	writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE);
> +
> +	/*
> +	 * Clear sw_resolve_ena(bit 0) and set adv_ability to
> +	 * something meaningful just in case
> +	 */
> +	writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20),
> +	       regs + DEV_PCS1G_CFG_PCS1G_ANEG);
> +
> +	/* Set MAC IFG Gaps */
> +	writel(DEV_MAC_CFG_MAC_IFG_TX_IFG(4) |
> +	       DEV_MAC_CFG_MAC_IFG_RX_IFG1(5) |
> +	       DEV_MAC_CFG_MAC_IFG_RX_IFG2(1),
> +	       regs + DEV_MAC_CFG_MAC_IFG);
> +
> +	/* Set link speed and release all resets */
> +	writel(DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(2),
> +	       regs + DEV_DEV_CFG_DEV_RST_CTRL);
> +
> +	/* Make VLAN aware for CPU traffic */
> +	writel(ANA_CL_PORT_VLAN_CFG_AWARE_ENA |
> +	       ANA_CL_PORT_VLAN_CFG_POP_CNT(1) |
> +	       MAC_VID,
> +	       priv->regs[ANA_CL] + ANA_CL_PORT_VLAN_CFG(port));
> +
> +	/* Enable CPU port for any frame transfer */
> +	setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(port),
> +		     QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
> +}
> +
> +static void serdes6g_write(void __iomem *base, u32 addr)
> +{
> +	u32 data;
> +
> +	writel(HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT |
> +	       HSIO_MCB_SERDES6G_CFG_ADDR(addr),
> +	       base + HSIO_MCB_SERDES6G_CFG);
> +
> +	do {
> +		data = readl(base + HSIO_MCB_SERDES6G_CFG);
> +	} while (data & HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT);
> +}
> +
> +static void serdes6g_setup(void __iomem *base, uint32_t addr,
> +			   phy_interface_t interface)
> +{
> +	u32 ib_if_mode = 0;
> +	u32 ib_qrate = 0;
> +	u32 ib_cal_ena = 0;
> +	u32 ib1_tsdet = 0;
> +	u32 ob_lev = 0;
> +	u32 ob_ena_cas = 0;
> +	u32 ob_ena1v_mode = 0;
> +	u32 des_bw_ana = 0;
> +	u32 pll_fsm_ctrl_data = 0;
> +
> +	switch (interface) {
> +	case PHY_INTERFACE_MODE_SGMII:
> +		ib_if_mode = 1;
> +		ib_qrate = 1;
> +		ib_cal_ena = 1;
> +		ib1_tsdet = 3;
> +		ob_lev = 48;
> +		ob_ena_cas = 2;
> +		ob_ena1v_mode = 1;
> +		des_bw_ana = 3;
> +		pll_fsm_ctrl_data = 60;
> +		break;
> +	case PHY_INTERFACE_MODE_QSGMII:
> +		ib_if_mode = 3;
> +		ib1_tsdet = 16;
> +		ob_lev = 24;
> +		des_bw_ana = 5;
> +		pll_fsm_ctrl_data = 120;
> +		break;
> +	default:
> +		pr_err("Interface not supported\n");
> +		return;
> +	}
> +
> +	if (interface == PHY_INTERFACE_MODE_QSGMII)
> +		writel(0xfff, base + HSIO_HW_CFGSTAT_HW_CFG);
> +
> +	writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(3),
> +	       base + HSIO_ANA_SERDES6G_COMMON_CFG);
> +	writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(120) |
> +	       HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
> +	       base + HSIO_ANA_SERDES6G_PLL_CFG);
> +	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
> +	       base + HSIO_ANA_SERDES6G_IB_CFG);
> +	writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_TSDET(3) |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
> +	       base + HSIO_ANA_SERDES6G_IB_CFG1);
> +	writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST,
> +	       base + HSIO_DIG_SERDES6G_MISC_CFG);
> +
> +	serdes6g_write(base, addr);
> +
> +	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
> +	       base + HSIO_ANA_SERDES6G_IB_CFG);
> +	writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_TSDET(16) |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
> +	       base + HSIO_ANA_SERDES6G_IB_CFG1);
> +
> +	writel(0x0, base + HSIO_ANA_SERDES6G_SER_CFG);
> +	writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(ib_if_mode) |
> +	       HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(ib_qrate) |
> +	       HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE |
> +	       HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST,
> +	       base + HSIO_ANA_SERDES6G_COMMON_CFG);
> +	writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST,
> +	       base + HSIO_DIG_SERDES6G_MISC_CFG);
> +
> +	writel(HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(1) |
> +	       HSIO_ANA_SERDES6G_OB_CFG_SR(7) |
> +	       HSIO_ANA_SERDES6G_OB_CFG_SR_H |
> +	       HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(ob_ena1v_mode) |
> +	       HSIO_ANA_SERDES6G_OB_CFG_POL, base + HSIO_ANA_SERDES6G_OB_CFG);
> +	writel(HSIO_ANA_SERDES6G_OB_CFG1_LEV(ob_lev) |
> +	       HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(ob_ena_cas),
> +	       base + HSIO_ANA_SERDES6G_OB_CFG1);
> +
> +	writel(HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(des_bw_ana) |
> +	       HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(5) |
> +	       HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(2) |
> +	       HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(6),
> +	       base + HSIO_ANA_SERDES6G_DES_CFG);
> +	writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) |
> +	       HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
> +	       base + HSIO_ANA_SERDES6G_PLL_CFG);
> +
> +	serdes6g_write(base, addr);
> +
> +	/* set pll_fsm_ena = 1 */
> +	writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA |
> +	       HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) |
> +	       HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
> +	       base + HSIO_ANA_SERDES6G_PLL_CFG);
> +
> +	serdes6g_write(base, addr);
> +
> +	/* wait 20ms for pll bringup */
> +	mdelay(20);
> +
> +	/* start IB calibration by setting ib_cal_ena and clearing lane_rst */
> +	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(ib_cal_ena) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
> +	       base + HSIO_ANA_SERDES6G_IB_CFG);
> +	writel(0x0, base + HSIO_DIG_SERDES6G_MISC_CFG);
> +
> +	serdes6g_write(base, addr);
> +
> +	/* wait 60 for calibration */
> +	mdelay(60);
> +
> +	/* set ib_tsdet and ib_reg_pat_sel_offset back to correct values */
> +	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(ib_cal_ena) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
> +	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
> +	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
> +	       base + HSIO_ANA_SERDES6G_IB_CFG);
> +	writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_TSDET(ib1_tsdet) |
> +	       HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
> +	       base + HSIO_ANA_SERDES6G_IB_CFG1);
> +
> +	serdes6g_write(base, addr);
> +}
> +
> +static void serdes1g_write(void __iomem *base, u32 addr)
> +{
> +	u32 data;
> +
> +	writel(HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT |
> +	       HSIO_MCB_SERDES1G_CFG_ADDR(addr),
> +	       base + HSIO_MCB_SERDES1G_CFG);
> +
> +	do {
> +		data = readl(base + HSIO_MCB_SERDES1G_CFG);
> +	} while (data & HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT);
> +}
> +
> +static void serdes1g_setup(void __iomem *base, uint32_t addr,
> +			   phy_interface_t interface)
> +{
> +	writel(0x0, base + HSIO_ANA_SERDES1G_SER_CFG);
> +	writel(0x0, base + HSIO_DIG_SERDES1G_TP_CFG);
> +	writel(0x0, base + HSIO_DIG_SERDES1G_DFT_CFG0);
> +	writel(HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(1) |
> +	       HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(4) |
> +	       HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(2) |
> +	       HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(12) |
> +	       HSIO_ANA_SERDES1G_OB_CFG_SLP(3),
> +	       base + HSIO_ANA_SERDES1G_OB_CFG);
> +	writel(HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(13) |
> +	       HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(2) |
> +	       HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP |
> +	       HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV |
> +	       HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM |
> +	       HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(3) |
> +	       HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(1),
> +	       base + HSIO_ANA_SERDES1G_IB_CFG);
> +	writel(HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(7) |
> +	       HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(6) |
> +	       HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(2) |
> +	       HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(6),
> +	       base + HSIO_ANA_SERDES1G_DES_CFG);
> +	writel(HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST,
> +	       base + HSIO_DIG_SERDES1G_MISC_CFG);
> +	writel(HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA |
> +	       HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(0xc8) |
> +	       HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2,
> +	       base + HSIO_ANA_SERDES1G_PLL_CFG);
> +	writel(HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE |
> +	       HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE |
> +	       HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST,
> +	       base + HSIO_ANA_SERDES1G_COMMON_CFG);
> +
> +	serdes1g_write(base, addr);
> +
> +	setbits_le32(base + HSIO_ANA_SERDES1G_COMMON_CFG,
> +		     HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST);
> +
> +	serdes1g_write(base, addr);
> +
> +	clrbits_le32(base + HSIO_DIG_SERDES1G_MISC_CFG,
> +		     HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST);
> +
> +	serdes1g_write(base, addr);
> +}
> +
> +static int ram_init(u32 val, void __iomem *addr)
> +{
> +	writel(val, addr);
> +
> +	if (wait_for_bit_le32(addr, BIT(1), false, 2000, false)) {
> +		printf("Timeout in memory reset, reg = 0x%08x\n", val);
> +		return 1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int jr2_switch_init(struct jr2_private *priv)
> +{
> +	/* Initialize memories */
> +	ram_init(0x3, priv->regs[QSYS] + QSYS_RAM_CTRL_RAM_INIT);
> +	ram_init(0x3, priv->regs[ASM] + ASM_RAM_CTRL_RAM_INIT);
> +	ram_init(0x3, priv->regs[ANA_AC] + ANA_AC_RAM_CTRL_RAM_INIT);
> +	ram_init(0x3, priv->regs[REW] + REW_RAM_CTRL_RAM_INIT);
> +
> +	/* Reset counters */
> +	writel(0x1, priv->regs[ANA_AC] + ANA_AC_STAT_GLOBAL_CFG_PORT_RESET);
> +	writel(0x1, priv->regs[ASM] + ASM_CFG_STAT_CFG);
> +
> +	/* Enable switch-core and queue system */
> +	writel(0x1, priv->regs[QSYS] + QSYS_SYSTEM_RESET_CFG);
> +
> +	return 0;
> +}
> +
> +static void jr2_switch_config(struct jr2_private *priv)
> +{
> +	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(0));
> +	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(1));
> +	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(2));
> +	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(3));
> +
> +	writel(readl(priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL) |
> +	       QSYS_CALCFG_CAL_CTRL_CAL_MODE(8),
> +	       priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL);
> +}
> +
> +static int jr2_initialize(struct jr2_private *priv)
> +{
> +	int ret, i;
> +
> +	/* Initialize switch memories, enable core */
> +	ret = jr2_switch_init(priv);
> +	if (ret)
> +		return ret;
> +
> +	jr2_switch_config(priv);
> +
> +	for (i = 0; i < MAX_PORT; i++)
> +		jr2_port_init(priv, i);
> +
> +	jr2_cpu_capture_setup(priv);
> +
> +	return 0;
> +}
> +
> +static inline int jr2_vlant_wait_for_completion(struct jr2_private *priv)
> +{
> +	if (wait_for_bit_le32(priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL,
> +			      LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
> +			      false, 2000, false))
> +		return -ETIMEDOUT;
> +
> +	return 0;
> +}
> +
> +static int jr2_mac_table_add(struct jr2_private *priv,
> +			     const unsigned char mac[ETH_ALEN], int pgid)
> +{
> +	u32 macl = 0, mach = 0;
> +
> +	/*
> +	 * Set the MAC address to handle and the vlan associated in a format
> +	 * understood by the hardware.
> +	 */
> +	mach |= MAC_VID << 16;
> +	mach |= ((u32)mac[0]) << 8;
> +	mach |= ((u32)mac[1]) << 0;
> +	macl |= ((u32)mac[2]) << 24;
> +	macl |= ((u32)mac[3]) << 16;
> +	macl |= ((u32)mac[4]) << 8;
> +	macl |= ((u32)mac[5]) << 0;
> +
> +	writel(mach, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG0);
> +	writel(macl, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG1);
> +
> +	writel(LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(pgid) |
> +	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(0x3) |
> +	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY |
> +	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(0) |
> +	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD |
> +	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED,
> +	       priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG2);
> +
> +	writel(LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
> +	       priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL);
> +
> +	return jr2_vlant_wait_for_completion(priv);
> +}
> +
> +static int jr2_write_hwaddr(struct udevice *dev)
> +{
> +	struct jr2_private *priv = dev_get_priv(dev);
> +	struct eth_pdata *pdata = dev_get_platdata(dev);
> +
> +	return jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
> +}
> +
> +static void serdes_setup(struct jr2_private *priv)
> +{
> +	size_t mask;
> +	int i = 0;
> +
> +	for (i = 0; i < MAX_PORT; ++i) {
> +		if (!priv->ports[i].bus || priv->ports[i].serdes_index == 0xff)
> +			continue;
> +
> +		mask = BIT(priv->ports[i].serdes_index);
> +		if (priv->ports[i].serdes_index < SERDES1G_MAX) {
> +			serdes1g_setup(priv->regs[HSIO], mask,
> +				       priv->ports[i].phy_mode);
> +		} else {
> +			mask >>= SERDES6G(0);
> +			serdes6g_setup(priv->regs[HSIO], mask,
> +				       priv->ports[i].phy_mode);
> +		}
> +	}
> +}
> +
> +static int jr2_start(struct udevice *dev)
> +{
> +	struct jr2_private *priv = dev_get_priv(dev);
> +	struct eth_pdata *pdata = dev_get_platdata(dev);
> +	const unsigned char mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff,
> +		0xff };
> +	int ret;
> +
> +	ret = jr2_initialize(priv);
> +	if (ret)
> +		return ret;
> +
> +	/* Set MAC address tables entries for CPU redirection */
> +	ret = jr2_mac_table_add(priv, mac, PGID_BROADCAST);
> +	if (ret)
> +		return ret;
> +
> +	ret = jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
> +	if (ret)
> +		return ret;
> +
> +	serdes_setup(priv);
> +
> +	return 0;
> +}
> +
> +static void jr2_stop(struct udevice *dev)
> +{

if you leave this empty I assume you can call jr2_start() multiple times
without site effects and don't need to reverse some init stuff? Note
that start() and stop() are called for each executed network command.

> +}
> +
> +static int jr2_send(struct udevice *dev, void *packet, int length)
> +{
> +	struct jr2_private *priv = dev_get_priv(dev);
> +	u32 ifh[IFH_LEN];
> +	u32 *buf = packet;
> +
> +	memset(ifh, '\0', IFH_LEN);
> +
> +	/* Set DST PORT_MASK */
> +	ifh[0] = htonl(0);
> +	ifh[1] = htonl(0x1FFFFF);
> +	ifh[2] = htonl(~0);
> +	/* Set DST_MODE to INJECT and UPDATE_FCS */
> +	ifh[5] = htonl(0x4c0);
> +
> +	return mscc_send(priv->regs[QS], jr2_regs_qs,
> +			 ifh, IFH_LEN, buf, length);
> +}
> +
> +static int jr2_recv(struct udevice *dev, int flags, uchar **packetp)
> +{
> +	struct jr2_private *priv = dev_get_priv(dev);
> +	u32 *rxbuf = (u32 *)net_rx_packets[0];
> +	int byte_cnt = 0;
> +
> +	byte_cnt = mscc_recv(priv->regs[QS], jr2_regs_qs, rxbuf, IFH_LEN,
> +			     false);
> +
> +	*packetp = net_rx_packets[0];
> +
> +	return byte_cnt;
> +}
> +
> +static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
> +{
> +	int i = 0;
> +
> +	for (i = 0; i < JR2_MIIM_BUS_COUNT; ++i)
> +		if (miim[i].miim_base == base && miim[i].miim_size == size)
> +			return miim[i].bus;
> +
> +	return NULL;
> +}
> +
> +static void add_port_entry(struct jr2_private *priv, size_t index,
> +			   size_t phy_addr, struct mii_dev *bus,
> +			   u8 serdes_index, u8 phy_mode)
> +{
> +	priv->ports[index].phy_addr = phy_addr;
> +	priv->ports[index].bus = bus;
> +	priv->ports[index].serdes_index = serdes_index;
> +	priv->ports[index].phy_mode = phy_mode;
> +}
> +
> +static int jr2_probe(struct udevice *dev)
> +{
> +	struct jr2_private *priv = dev_get_priv(dev);
> +	int i;
> +	int ret;
> +	struct resource res;
> +	fdt32_t faddr;
> +	phys_addr_t addr_base;
> +	unsigned long addr_size;
> +	ofnode eth_node, node, mdio_node;
> +	size_t phy_addr;
> +	struct mii_dev *bus;
> +	struct ofnode_phandle_args phandle;
> +	struct phy_device *phy;
> +
> +	if (!priv)
> +		return -EINVAL;
> +
> +	/* Get registers and map them to the private structure */
> +	for (i = 0; i < ARRAY_SIZE(regs_names); i++) {
> +		priv->regs[i] = dev_remap_addr_name(dev, regs_names[i]);
> +		if (!priv->regs[i]) {
> +			debug
> +			    ("Error can't get regs base addresses for %s\n",
> +			     regs_names[i]);
> +			return -ENOMEM;
> +		}
> +	}
> +
> +	/* Initialize miim buses */
> +	memset(&miim, 0x0, sizeof(struct jr2_miim_dev) * JR2_MIIM_BUS_COUNT);
> +
> +	/* iterate all the ports and find out on which bus they are */
> +	i = 0;
> +	eth_node = dev_read_first_subnode(dev);
> +	for (node = ofnode_first_subnode(eth_node);
> +	     ofnode_valid(node);
> +	     node = ofnode_next_subnode(node)) {
> +		if (ofnode_read_resource(node, 0, &res))
> +			return -ENOMEM;
> +		i = res.start;
> +
> +		ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL,
> +						     0, 0, &phandle);
> +		if (ret)
> +			continue;
> +
> +		/* Get phy address on mdio bus */
> +		if (ofnode_read_resource(phandle.node, 0, &res))
> +			return -ENOMEM;
> +		phy_addr = res.start;
> +
> +		/* Get mdio node */
> +		mdio_node = ofnode_get_parent(phandle.node);
> +
> +		if (ofnode_read_resource(mdio_node, 0, &res))
> +			return -ENOMEM;
> +		faddr = cpu_to_fdt32(res.start);
> +
> +		addr_base = ofnode_translate_address(mdio_node, &faddr);
> +		addr_size = res.end - res.start;
> +
> +		/* If the bus is new then create a new bus */
> +		if (!get_mdiobus(addr_base, addr_size))
> +			priv->bus[miim_count] =
> +				jr2_mdiobus_init(addr_base, addr_size);
> +
> +		/* Connect mdio bus with the port */
> +		bus = get_mdiobus(addr_base, addr_size);
> +
> +		/* Get serdes info */
> +		ret = ofnode_parse_phandle_with_args(node, "phys", NULL,
> +						     3, 0, &phandle);
> +		if (ret)
> +			return -ENOMEM;
> +
> +		add_port_entry(priv, i, phy_addr, bus, phandle.args[1],
> +			       phandle.args[2]);
> +	}
> +
> +	for (i = 0; i < MAX_PORT; i++) {
> +		if (!priv->ports[i].bus)
> +			continue;
> +
> +		phy = phy_connect(priv->ports[i].bus,
> +				  priv->ports[i].phy_addr, dev,
> +				  PHY_INTERFACE_MODE_NONE);
> +		if (phy)
> +			board_phy_config(phy);
> +	}
> +
> +	return 0;
> +}
> +
> +static int jr2_remove(struct udevice *dev)
> +{
> +	struct jr2_private *priv = dev_get_priv(dev);
> +	int i;
> +
> +	for (i = 0; i < JR2_MIIM_BUS_COUNT; i++) {
> +		mdio_unregister(priv->bus[i]);
> +		mdio_free(priv->bus[i]);
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct eth_ops jr2_ops = {
> +	.start        = jr2_start,
> +	.stop         = jr2_stop,
> +	.send         = jr2_send,
> +	.recv         = jr2_recv,
> +	.write_hwaddr = jr2_write_hwaddr,
> +};
> +
> +static const struct udevice_id mscc_jr2_ids[] = {
> +	{.compatible = "mscc,vsc7454-switch" },
> +	{ /* Sentinel */ }
> +};
> +
> +U_BOOT_DRIVER(jr2) = {
> +	.name				= "jr2-switch",
> +	.id				= UCLASS_ETH,
> +	.of_match			= mscc_jr2_ids,
> +	.probe				= jr2_probe,
> +	.remove				= jr2_remove,
> +	.ops				= &jr2_ops,
> +	.priv_auto_alloc_size		= sizeof(struct jr2_private),
> +	.platdata_auto_alloc_size	= sizeof(struct eth_pdata),
> +};
> diff --git a/include/configs/vcoreiii.h b/include/configs/vcoreiii.h
> index 2840c7b..aeef58d 100644
> --- a/include/configs/vcoreiii.h
> +++ b/include/configs/vcoreiii.h
> @@ -10,7 +10,7 @@
>  
>  /* Onboard devices */
>  
> -#define CONFIG_SYS_MALLOC_LEN		0x100000
> +#define CONFIG_SYS_MALLOC_LEN		0x1F0000
>  #define CONFIG_SYS_LOAD_ADDR		0x00100000
>  #define CONFIG_SYS_INIT_SP_OFFSET       0x400000
>  
> 

-- 
- Daniel

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

* [U-Boot] [PATCH v3 1/4] net: Add MSCC Jaguar2 network driver.
  2019-04-03 10:18   ` Daniel Schwierzeck
@ 2019-04-03 10:59     ` Horatiu Vultur
  0 siblings, 0 replies; 7+ messages in thread
From: Horatiu Vultur @ 2019-04-03 10:59 UTC (permalink / raw)
  To: u-boot

Hi Daniel,

The 04/03/2019 12:18, Daniel Schwierzeck wrote:
> External E-Mail
> 
> 
> 
> Am 30.03.19 um 11:17 schrieb Horatiu Vultur:
> > Add network driver for Microsemi Ethernet switch.
> > It is present on Jaguar2 SoCs.
> > 
> > Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
> > ---
> >  drivers/net/mscc_eswitch/Kconfig      |    7 +
> >  drivers/net/mscc_eswitch/Makefile     |    1 +
> >  drivers/net/mscc_eswitch/jr2_switch.c | 1075 +++++++++++++++++++++++++++++++++
> >  include/configs/vcoreiii.h            |    2 +-
> >  4 files changed, 1084 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/net/mscc_eswitch/jr2_switch.c
> 
> Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> 
> nits below
> 
> > 
> > diff --git a/drivers/net/mscc_eswitch/Kconfig b/drivers/net/mscc_eswitch/Kconfig
> > index 88e5a97..3f9d14b 100644
> > --- a/drivers/net/mscc_eswitch/Kconfig
> > +++ b/drivers/net/mscc_eswitch/Kconfig
> > @@ -15,3 +15,10 @@ config MSCC_LUTON_SWITCH
> >  	select PHYLIB
> >  	help
> >  	  This driver supports the Luton network switch device.
> > +
> > +config MSCC_JR2_SWITCH
> > +	bool "Jaguar2 switch driver"
> > +	depends on DM_ETH && ARCH_MSCC
> > +	select PHYLIB
> > +	help
> > +	  This driver supports the Jaguar2 network switch device.
> > diff --git a/drivers/net/mscc_eswitch/Makefile b/drivers/net/mscc_eswitch/Makefile
> > index 751a839..0a1b863 100644
> > --- a/drivers/net/mscc_eswitch/Makefile
> > +++ b/drivers/net/mscc_eswitch/Makefile
> > @@ -1,3 +1,4 @@
> >  
> >  obj-$(CONFIG_MSCC_OCELOT_SWITCH) += ocelot_switch.o mscc_miim.o mscc_xfer.o mscc_mac_table.o
> >  obj-$(CONFIG_MSCC_LUTON_SWITCH) += luton_switch.o mscc_miim.o mscc_xfer.o mscc_mac_table.o
> > +obj-$(CONFIG_MSCC_JR2_SWITCH) += jr2_switch.o mscc_xfer.o
> > diff --git a/drivers/net/mscc_eswitch/jr2_switch.c b/drivers/net/mscc_eswitch/jr2_switch.c
> > new file mode 100644
> > index 0000000..d4a2498
> > --- /dev/null
> > +++ b/drivers/net/mscc_eswitch/jr2_switch.c
> > @@ -0,0 +1,1075 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Copyright (c) 2018 Microsemi Corporation
> > + */
> > +
> > +#include <common.h>
> > +#include <config.h>
> > +#include <dm.h>
> > +#include <dm/of_access.h>
> > +#include <dm/of_addr.h>
> > +#include <fdt_support.h>
> > +#include <linux/io.h>
> > +#include <linux/ioport.h>
> > +#include <miiphy.h>
> > +#include <net.h>
> > +#include <wait_bit.h>
> > +
> > +#include <dt-bindings/mscc/jr2_data.h>
> > +#include "mscc_xfer.h"
> > +
> > +#define GCB_MIIM_MII_STATUS		0x0
> > +#define		GCB_MIIM_STAT_BUSY		BIT(3)
> > +#define GCB_MIIM_MII_CMD		0x8
> > +#define		GCB_MIIM_MII_CMD_SCAN		BIT(0)
> > +#define		GCB_MIIM_MII_CMD_OPR_WRITE	BIT(1)
> > +#define		GCB_MIIM_MII_CMD_OPR_READ	BIT(2)
> > +#define		GCB_MIIM_MII_CMD_SINGLE_SCAN	BIT(3)
> > +#define		GCB_MIIM_MII_CMD_WRDATA(x)	((x) << 4)
> > +#define		GCB_MIIM_MII_CMD_REGAD(x)	((x) << 20)
> > +#define		GCB_MIIM_MII_CMD_PHYAD(x)	((x) << 25)
> > +#define		GCB_MIIM_MII_CMD_VLD		BIT(31)
> > +#define GCB_MIIM_DATA			0xC
> > +#define		GCB_MIIM_DATA_ERROR		(0x3 << 16)
> > +
> > +#define ANA_AC_RAM_CTRL_RAM_INIT		0x94358
> > +#define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET	0x94370
> > +
> > +#define ANA_CL_PORT_VLAN_CFG(x)			(0x24018 + 0xc8 * (x))
> > +#define		ANA_CL_PORT_VLAN_CFG_AWARE_ENA			BIT(19)
> > +#define		ANA_CL_PORT_VLAN_CFG_POP_CNT(x)			((x) << 17)
> > +
> > +#define ANA_L2_COMMON_FWD_CFG			0x8a2a8
> > +#define		ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA	BIT(6)
> > +
> > +#define ASM_CFG_STAT_CFG			0x3508
> > +#define ASM_CFG_PORT(x)				(0x36c4 + 0x4 * (x))
> > +#define		ASM_CFG_PORT_NO_PREAMBLE_ENA		BIT(8)
> > +#define		ASM_CFG_PORT_INJ_FORMAT_CFG(x)		((x) << 1)
> > +#define ASM_RAM_CTRL_RAM_INIT			0x39b8
> > +
> > +#define DEV_DEV_CFG_DEV_RST_CTRL		0x0
> > +#define		DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(x)	((x) << 20)
> > +#define DEV_MAC_CFG_MAC_ENA		0x1c
> > +#define		DEV_MAC_CFG_MAC_ENA_RX_ENA		BIT(4)
> > +#define		DEV_MAC_CFG_MAC_ENA_TX_ENA		BIT(0)
> > +#define	DEV_MAC_CFG_MAC_IFG		0x34
> > +#define		DEV_MAC_CFG_MAC_IFG_TX_IFG(x)		((x) << 8)
> > +#define		DEV_MAC_CFG_MAC_IFG_RX_IFG2(x)		((x) << 4)
> > +#define		DEV_MAC_CFG_MAC_IFG_RX_IFG1(x)		(x)
> > +#define	DEV_PCS1G_CFG_PCS1G_CFG		0x40
> > +#define		DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA		BIT(0)
> > +#define	DEV_PCS1G_CFG_PCS1G_MODE	0x44
> > +#define	DEV_PCS1G_CFG_PCS1G_SD		0x48
> > +#define	DEV_PCS1G_CFG_PCS1G_ANEG	0x4c
> > +#define		DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(x)	((x) << 16)
> > +
> > +#define DSM_RAM_CTRL_RAM_INIT		0x8
> > +
> > +#define HSIO_ANA_SERDES1G_DES_CFG		0xac
> > +#define		HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(x)		((x) << 1)
> > +#define		HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(x)		((x) << 5)
> > +#define		HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(x)		((x) << 8)
> > +#define		HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(x)		((x) << 13)
> > +#define HSIO_ANA_SERDES1G_IB_CFG		0xb0
> > +#define		HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(x)	(x)
> > +#define		HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(x)		((x) << 6)
> > +#define		HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP	BIT(9)
> > +#define		HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV		BIT(11)
> > +#define		HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM		BIT(13)
> > +#define		HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(x)		((x) << 19)
> > +#define		HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(x)		((x) << 24)
> > +#define HSIO_ANA_SERDES1G_OB_CFG		0xb4
> > +#define		HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(x)	(x)
> > +#define		HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(x)		((x) << 4)
> > +#define		HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(x)	((x) << 10)
> > +#define		HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(x)		((x) << 13)
> > +#define		HSIO_ANA_SERDES1G_OB_CFG_SLP(x)			((x) << 17)
> > +#define HSIO_ANA_SERDES1G_SER_CFG		0xb8
> > +#define HSIO_ANA_SERDES1G_COMMON_CFG		0xbc
> > +#define		HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE		BIT(0)
> > +#define		HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE		BIT(18)
> > +#define		HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST		BIT(31)
> > +#define HSIO_ANA_SERDES1G_PLL_CFG		0xc0
> > +#define		HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA		BIT(7)
> > +#define		HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(x)	((x) << 8)
> > +#define		HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2		BIT(21)
> > +#define HSIO_DIG_SERDES1G_DFT_CFG0		0xc8
> > +#define HSIO_DIG_SERDES1G_TP_CFG		0xd4
> > +#define HSIO_DIG_SERDES1G_MISC_CFG		0xdc
> > +#define		HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST		BIT(0)
> > +#define HSIO_MCB_SERDES1G_CFG			0xe8
> > +#define		HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT		BIT(31)
> > +#define		HSIO_MCB_SERDES1G_CFG_ADDR(x)			(x)
> > +
> > +#define HSIO_ANA_SERDES6G_DES_CFG		0x11c
> > +#define		HSIO_ANA_SERDES6G_DES_CFG_SWAP_ANA		BIT(0)
> > +#define		HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(x)		((x) << 1)
> > +#define		HSIO_ANA_SERDES6G_DES_CFG_SWAP_HYST		BIT(4)
> > +#define		HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(x)		((x) << 5)
> > +#define		HSIO_ANA_SERDES6G_DES_CFG_CPMD_SEL(x)		((x) << 8)
> > +#define		HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(x)		((x) << 10)
> > +#define		HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(x)		((x) << 13)
> > +#define HSIO_ANA_SERDES6G_IB_CFG		0x120
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_REG_ENA		BIT(0)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA		BIT(1)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA		BIT(2)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(x)		((x) << 3)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_CONCUR			BIT(4)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA		BIT(5)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(x)	((x) << 7)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(x)	((x) << 9)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(x)	((x) << 11)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(x)	((x) << 13)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(x)	((x) << 15)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(x)	((x) << 18)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(x)		((x) << 20)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(x)		((x) << 24)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL		BIT(28)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG_SOFSI(x)		((x) << 29)
> > +#define HSIO_ANA_SERDES6G_IB_CFG1		0x124
> > +#define		HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET		BIT(4)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP		BIT(5)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID		BIT(6)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP		BIT(7)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG1_SCALY(x)		((x) << 8)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG1_TSDET(x)		((x) << 12)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(x)		((x) << 17)
> > +#define HSIO_ANA_SERDES6G_IB_CFG2		0x128
> > +#define		HSIO_ANA_SERDES6G_IB_CFG2_UREG(x)		(x)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG2_UMAX(x)		((x) << 3)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG2_TCALV(x)		((x) << 5)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG2_OCALS(x)		((x) << 10)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG2_OINFS(x)		((x) << 16)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG2_OINFI(x)		((x) << 22)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG2_TINFV(x)		((x) << 27)
> > +#define HSIO_ANA_SERDES6G_IB_CFG3		0x12c
> > +#define		HSIO_ANA_SERDES6G_IB_CFG3_INI_OFFSET(x)		(x)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG3_INI_LP(x)		((x) << 6)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG3_INI_MID(x)		((x) << 12)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG3_INI_HP(x)		((x) << 18)
> > +#define HSIO_ANA_SERDES6G_IB_CFG4		0x130
> > +#define		HSIO_ANA_SERDES6G_IB_CFG4_MAX_OFFSET(x)		(x)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG4_MAX_LP(x)		((x) << 6)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG4_MAX_MID(x)		((x) << 12)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG4_MAX_HP(x)		((x) << 18)
> > +#define HSIO_ANA_SERDES6G_IB_CFG5		0x134
> > +#define		HSIO_ANA_SERDES6G_IB_CFG4_MIN_OFFSET(x)		(x)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG4_MIN_LP(x)		((x) << 6)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG4_MIN_MID(x)		((x) << 12)
> > +#define		HSIO_ANA_SERDES6G_IB_CFG4_MIN_HP(x)		((x) << 18)
> > +#define HSIO_ANA_SERDES6G_OB_CFG		0x138
> > +#define		HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(x)	(x)
> > +#define		HSIO_ANA_SERDES6G_OB_CFG_SR(x)			((x) << 4)
> > +#define		HSIO_ANA_SERDES6G_OB_CFG_SR_H			BIT(8)
> > +#define		HSIO_ANA_SERDES6G_OB_CFG_SEL_RCTRL		BIT(9)
> > +#define		HSIO_ANA_SERDES6G_OB_CFG_R_COR			BIT(10)
> > +#define		HSIO_ANA_SERDES6G_OB_CFG_POST1(x)		((x) << 11)
> > +#define		HSIO_ANA_SERDES6G_OB_CFG_R_ADJ_PDR		BIT(16)
> > +#define		HSIO_ANA_SERDES6G_OB_CFG_R_ADJ_MUX		BIT(17)
> > +#define		HSIO_ANA_SERDES6G_OB_CFG_PREC(x)		((x) << 18)
> > +#define		HSIO_ANA_SERDES6G_OB_CFG_POST0(x)		((x) << 23)
> > +#define		HSIO_ANA_SERDES6G_OB_CFG_POL			BIT(29)
> > +#define		HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(x)		((x) << 30)
> > +#define		HSIO_ANA_SERDES6G_OB_CFG_IDLE			BIT(31)
> > +#define HSIO_ANA_SERDES6G_OB_CFG1		0x13c
> > +#define		HSIO_ANA_SERDES6G_OB_CFG1_LEV(x)		(x)
> > +#define		HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(x)		((x) << 6)
> > +#define HSIO_ANA_SERDES6G_SER_CFG		0x140
> > +#define HSIO_ANA_SERDES6G_COMMON_CFG		0x144
> > +#define		HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(x)		(x)
> > +#define		HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(x)		(x << 2)
> > +#define		HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE		BIT(14)
> > +#define		HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST		BIT(16)
> > +#define HSIO_ANA_SERDES6G_PLL_CFG		0x148
> > +#define		HSIO_ANA_SERDES6G_PLL_CFG_ROT_FRQ		BIT(0)
> > +#define		HSIO_ANA_SERDES6G_PLL_CFG_ROT_DIR		BIT(1)
> > +#define		HSIO_ANA_SERDES6G_PLL_CFG_RB_DATA_SEL		BIT(2)
> > +#define		HSIO_ANA_SERDES6G_PLL_CFG_FSM_OOR_RECAL_ENA	BIT(3)
> > +#define		HSIO_ANA_SERDES6G_PLL_CFG_FSM_FORCE_SET_ENA	BIT(4)
> > +#define		HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA		BIT(5)
> > +#define		HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(x)	((x) << 6)
> > +#define		HSIO_ANA_SERDES6G_PLL_CFG_ENA_ROT		BIT(14)
> > +#define		HSIO_ANA_SERDES6G_PLL_CFG_DIV4			BIT(15)
> > +#define		HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(x)		((x) << 16)
> > +#define HSIO_DIG_SERDES6G_MISC_CFG		0x108
> > +#define		HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST		BIT(0)
> > +#define HSIO_MCB_SERDES6G_CFG			0x168
> > +#define		HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT		BIT(31)
> > +#define		HSIO_MCB_SERDES6G_CFG_ADDR(x)			(x)
> > +#define HSIO_HW_CFGSTAT_HW_CFG			0x16c
> > +
> > +#define LRN_COMMON_ACCESS_CTRL			0x0
> > +#define		LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT	BIT(0)
> > +#define LRN_COMMON_MAC_ACCESS_CFG0		0x4
> > +#define LRN_COMMON_MAC_ACCESS_CFG1		0x8
> > +#define LRN_COMMON_MAC_ACCESS_CFG2		0xc
> > +#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(x)	(x)
> > +#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(x)	((x) << 12)
> > +#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD	BIT(15)
> > +#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED	BIT(16)
> > +#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY	BIT(23)
> > +#define		LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(x)	((x) << 24)
> > +
> > +#define QFWD_SYSTEM_SWITCH_PORT_MODE(x)		(0x4 * (x))
> > +#define		QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA		BIT(17)
> > +
> > +#define QS_XTR_GRP_CFG(x)		(0x0 + 4 * (x))
> > +#define QS_INJ_GRP_CFG(x)		(0x24 + (x) * 4)
> > +
> > +#define QSYS_SYSTEM_RESET_CFG			0xf0
> > +#define QSYS_CALCFG_CAL_AUTO(x)			(0x3d4 + 4 * (x))
> > +#define QSYS_CALCFG_CAL_CTRL			0x3e8
> > +#define		QSYS_CALCFG_CAL_CTRL_CAL_MODE(x)		((x) << 11)
> > +#define QSYS_RAM_CTRL_RAM_INIT			0x3ec
> > +
> > +#define REW_RAM_CTRL_RAM_INIT			0x53528
> > +
> > +#define VOP_RAM_CTRL_RAM_INIT			0x43638
> > +
> > +#define XTR_VALID_BYTES(x)	(4 - ((x) & 3))
> > +#define MAC_VID			0
> > +#define CPU_PORT		53
> > +#define IFH_LEN			7
> > +#define JR2_BUF_CELL_SZ		60
> > +#define ETH_ALEN		6
> > +#define PGID_BROADCAST		510
> > +#define PGID_UNICAST		511
> > +
> > +static char *regs_names[] = {
> > +	"port0", "port1", "port2", "port3", "port4", "port5", "port6", "port7",
> > +	"port8", "port9", "port10", "port11", "port12", "port13", "port14",
> > +	"port15", "port16", "port17", "port18", "port19", "port20", "port21",
> > +	"port22", "port23", "port24", "port25", "port26", "port27", "port28",
> > +	"port29", "port30", "port31", "port32", "port33", "port34", "port35",
> > +	"port36", "port37", "port38", "port39", "port40", "port41", "port42",
> > +	"port43", "port44", "port45", "port46", "port47",
> > +	"ana_ac", "ana_cl", "ana_l2", "asm", "hsio", "lrn",
> > +	"qfwd", "qs", "qsys", "rew",
> > +};
> 
> this could be made const
> 
> > +
> > +#define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1
> > +#define MAX_PORT 48
> > +
> > +enum jr2_ctrl_regs {
> > +	ANA_AC = MAX_PORT,
> > +	ANA_CL,
> > +	ANA_L2,
> > +	ASM,
> > +	HSIO,
> > +	LRN,
> > +	QFWD,
> > +	QS,
> > +	QSYS,
> > +	REW,
> > +};
> > +
> > +#define JR2_MIIM_BUS_COUNT 3
> > +
> > +struct jr2_phy_port_t {
> > +	size_t phy_addr;
> > +	struct mii_dev *bus;
> > +	u8 serdes_index;
> > +	u8 phy_mode;
> > +};
> > +
> > +struct jr2_private {
> > +	void __iomem *regs[REGS_NAMES_COUNT];
> > +	struct mii_dev *bus[JR2_MIIM_BUS_COUNT];
> > +	struct jr2_phy_port_t ports[MAX_PORT];
> > +};
> > +
> > +struct jr2_miim_dev {
> > +	void __iomem *regs;
> > +	phys_addr_t miim_base;
> > +	unsigned long miim_size;
> > +	struct mii_dev *bus;
> > +};
> > +
> > +static const unsigned long jr2_regs_qs[] = {
> > +	[MSCC_QS_XTR_RD] = 0x8,
> > +	[MSCC_QS_XTR_FLUSH] = 0x18,
> > +	[MSCC_QS_XTR_DATA_PRESENT] = 0x1c,
> > +	[MSCC_QS_INJ_WR] = 0x2c,
> > +	[MSCC_QS_INJ_CTRL] = 0x34,
> > +};
> > +
> > +static struct jr2_miim_dev miim[JR2_MIIM_BUS_COUNT];
> > +static int miim_count = -1;
> > +
> > +static int mscc_miim_wait_ready(struct jr2_miim_dev *miim)
> > +{
> > +	unsigned long deadline;
> > +	u32 val;
> > +
> > +	deadline = timer_get_us() + 250000;
> > +
> > +	do {
> > +		val = readl(miim->regs + GCB_MIIM_MII_STATUS);
> > +	} while (timer_get_us() <= deadline && (val & GCB_MIIM_STAT_BUSY));
> > +
> > +	if (val & GCB_MIIM_STAT_BUSY)
> > +		return -ETIMEDOUT;
> > +
> > +	return 0;
> > +}
> > +
> > +static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
> > +{
> > +	struct jr2_miim_dev *miim = (struct jr2_miim_dev *)bus->priv;
> > +	u32 val;
> > +	int ret;
> > +
> > +	ret = mscc_miim_wait_ready(miim);
> > +	if (ret)
> > +		goto out;
> > +
> > +	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
> > +	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
> > +	       miim->regs + GCB_MIIM_MII_CMD);
> > +
> > +	ret = mscc_miim_wait_ready(miim);
> > +	if (ret)
> > +		goto out;
> > +
> > +	val = readl(miim->regs + GCB_MIIM_DATA);
> > +	if (val & GCB_MIIM_DATA_ERROR) {
> > +		ret = -EIO;
> > +		goto out;
> > +	}
> > +
> > +	ret = val & 0xFFFF;
> > + out:
> > +	return ret;
> > +}
> > +
> > +static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
> > +			   u16 val)
> > +{
> > +	struct jr2_miim_dev *miim = (struct jr2_miim_dev *)bus->priv;
> > +	int ret;
> > +
> > +	ret = mscc_miim_wait_ready(miim);
> > +	if (ret < 0)
> > +		goto out;
> > +
> > +	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
> > +	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
> > +	       GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
> > +
> > + out:
> > +	return ret;
> > +}
> > +
> > +static struct mii_dev *jr2_mdiobus_init(phys_addr_t miim_base,
> > +					unsigned long miim_size)
> > +{
> > +	struct mii_dev *bus;
> > +
> > +	bus = mdio_alloc();
> > +	if (!bus)
> > +		return NULL;
> > +
> > +	++miim_count;
> > +	sprintf(bus->name, "miim-bus%d", miim_count);
> > +
> > +	miim[miim_count].regs = ioremap(miim_base, miim_size);
> > +	miim[miim_count].miim_base = miim_base;
> > +	miim[miim_count].miim_size = miim_size;
> > +	bus->priv = &miim[miim_count];
> > +	bus->read = mscc_miim_read;
> > +	bus->write = mscc_miim_write;
> > +
> > +	if (mdio_register(bus))
> > +		return NULL;
> > +
> > +	miim[miim_count].bus = bus;
> > +	return bus;
> > +}
> > +
> > +static void jr2_cpu_capture_setup(struct jr2_private *priv)
> > +{
> > +	/* ASM: No preamble and IFH prefix on CPU injected frames */
> > +	writel(ASM_CFG_PORT_NO_PREAMBLE_ENA |
> > +	       ASM_CFG_PORT_INJ_FORMAT_CFG(1),
> > +	       priv->regs[ASM] + ASM_CFG_PORT(CPU_PORT));
> > +
> > +	/* Set Manual injection via DEVCPU_QS registers for CPU queue 0 */
> > +	writel(0x5, priv->regs[QS] + QS_INJ_GRP_CFG(0));
> > +
> > +	/* Set Manual extraction via DEVCPU_QS registers for CPU queue 0 */
> > +	writel(0x7, priv->regs[QS] + QS_XTR_GRP_CFG(0));
> > +
> > +	/* Enable CPU port for any frame transfer */
> > +	setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(CPU_PORT),
> > +		     QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
> > +
> > +	/* Send a copy to CPU when found as forwarding entry */
> > +	setbits_le32(priv->regs[ANA_L2] + ANA_L2_COMMON_FWD_CFG,
> > +		     ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA);
> > +}
> > +
> > +static void jr2_port_init(struct jr2_private *priv, int port)
> > +{
> > +	void __iomem *regs = priv->regs[port];
> > +
> > +	/* Enable PCS */
> > +	writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA,
> > +	       regs + DEV_PCS1G_CFG_PCS1G_CFG);
> > +
> > +	/* Disable Signal Detect */
> > +	writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD);
> > +
> > +	/* Enable MAC RX and TX */
> > +	writel(DEV_MAC_CFG_MAC_ENA_RX_ENA |
> > +	       DEV_MAC_CFG_MAC_ENA_TX_ENA,
> > +	       regs + DEV_MAC_CFG_MAC_ENA);
> > +
> > +	/* Clear sgmii_mode_ena */
> > +	writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE);
> > +
> > +	/*
> > +	 * Clear sw_resolve_ena(bit 0) and set adv_ability to
> > +	 * something meaningful just in case
> > +	 */
> > +	writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20),
> > +	       regs + DEV_PCS1G_CFG_PCS1G_ANEG);
> > +
> > +	/* Set MAC IFG Gaps */
> > +	writel(DEV_MAC_CFG_MAC_IFG_TX_IFG(4) |
> > +	       DEV_MAC_CFG_MAC_IFG_RX_IFG1(5) |
> > +	       DEV_MAC_CFG_MAC_IFG_RX_IFG2(1),
> > +	       regs + DEV_MAC_CFG_MAC_IFG);
> > +
> > +	/* Set link speed and release all resets */
> > +	writel(DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(2),
> > +	       regs + DEV_DEV_CFG_DEV_RST_CTRL);
> > +
> > +	/* Make VLAN aware for CPU traffic */
> > +	writel(ANA_CL_PORT_VLAN_CFG_AWARE_ENA |
> > +	       ANA_CL_PORT_VLAN_CFG_POP_CNT(1) |
> > +	       MAC_VID,
> > +	       priv->regs[ANA_CL] + ANA_CL_PORT_VLAN_CFG(port));
> > +
> > +	/* Enable CPU port for any frame transfer */
> > +	setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(port),
> > +		     QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
> > +}
> > +
> > +static void serdes6g_write(void __iomem *base, u32 addr)
> > +{
> > +	u32 data;
> > +
> > +	writel(HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT |
> > +	       HSIO_MCB_SERDES6G_CFG_ADDR(addr),
> > +	       base + HSIO_MCB_SERDES6G_CFG);
> > +
> > +	do {
> > +		data = readl(base + HSIO_MCB_SERDES6G_CFG);
> > +	} while (data & HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT);
> > +}
> > +
> > +static void serdes6g_setup(void __iomem *base, uint32_t addr,
> > +			   phy_interface_t interface)
> > +{
> > +	u32 ib_if_mode = 0;
> > +	u32 ib_qrate = 0;
> > +	u32 ib_cal_ena = 0;
> > +	u32 ib1_tsdet = 0;
> > +	u32 ob_lev = 0;
> > +	u32 ob_ena_cas = 0;
> > +	u32 ob_ena1v_mode = 0;
> > +	u32 des_bw_ana = 0;
> > +	u32 pll_fsm_ctrl_data = 0;
> > +
> > +	switch (interface) {
> > +	case PHY_INTERFACE_MODE_SGMII:
> > +		ib_if_mode = 1;
> > +		ib_qrate = 1;
> > +		ib_cal_ena = 1;
> > +		ib1_tsdet = 3;
> > +		ob_lev = 48;
> > +		ob_ena_cas = 2;
> > +		ob_ena1v_mode = 1;
> > +		des_bw_ana = 3;
> > +		pll_fsm_ctrl_data = 60;
> > +		break;
> > +	case PHY_INTERFACE_MODE_QSGMII:
> > +		ib_if_mode = 3;
> > +		ib1_tsdet = 16;
> > +		ob_lev = 24;
> > +		des_bw_ana = 5;
> > +		pll_fsm_ctrl_data = 120;
> > +		break;
> > +	default:
> > +		pr_err("Interface not supported\n");
> > +		return;
> > +	}
> > +
> > +	if (interface == PHY_INTERFACE_MODE_QSGMII)
> > +		writel(0xfff, base + HSIO_HW_CFGSTAT_HW_CFG);
> > +
> > +	writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(3),
> > +	       base + HSIO_ANA_SERDES6G_COMMON_CFG);
> > +	writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(120) |
> > +	       HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
> > +	       base + HSIO_ANA_SERDES6G_PLL_CFG);
> > +	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
> > +	       base + HSIO_ANA_SERDES6G_IB_CFG);
> > +	writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_TSDET(3) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
> > +	       base + HSIO_ANA_SERDES6G_IB_CFG1);
> > +	writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST,
> > +	       base + HSIO_DIG_SERDES6G_MISC_CFG);
> > +
> > +	serdes6g_write(base, addr);
> > +
> > +	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
> > +	       base + HSIO_ANA_SERDES6G_IB_CFG);
> > +	writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_TSDET(16) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
> > +	       base + HSIO_ANA_SERDES6G_IB_CFG1);
> > +
> > +	writel(0x0, base + HSIO_ANA_SERDES6G_SER_CFG);
> > +	writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(ib_if_mode) |
> > +	       HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(ib_qrate) |
> > +	       HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE |
> > +	       HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST,
> > +	       base + HSIO_ANA_SERDES6G_COMMON_CFG);
> > +	writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST,
> > +	       base + HSIO_DIG_SERDES6G_MISC_CFG);
> > +
> > +	writel(HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(1) |
> > +	       HSIO_ANA_SERDES6G_OB_CFG_SR(7) |
> > +	       HSIO_ANA_SERDES6G_OB_CFG_SR_H |
> > +	       HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(ob_ena1v_mode) |
> > +	       HSIO_ANA_SERDES6G_OB_CFG_POL, base + HSIO_ANA_SERDES6G_OB_CFG);
> > +	writel(HSIO_ANA_SERDES6G_OB_CFG1_LEV(ob_lev) |
> > +	       HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(ob_ena_cas),
> > +	       base + HSIO_ANA_SERDES6G_OB_CFG1);
> > +
> > +	writel(HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(des_bw_ana) |
> > +	       HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(5) |
> > +	       HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(2) |
> > +	       HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(6),
> > +	       base + HSIO_ANA_SERDES6G_DES_CFG);
> > +	writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) |
> > +	       HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
> > +	       base + HSIO_ANA_SERDES6G_PLL_CFG);
> > +
> > +	serdes6g_write(base, addr);
> > +
> > +	/* set pll_fsm_ena = 1 */
> > +	writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA |
> > +	       HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) |
> > +	       HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
> > +	       base + HSIO_ANA_SERDES6G_PLL_CFG);
> > +
> > +	serdes6g_write(base, addr);
> > +
> > +	/* wait 20ms for pll bringup */
> > +	mdelay(20);
> > +
> > +	/* start IB calibration by setting ib_cal_ena and clearing lane_rst */
> > +	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(ib_cal_ena) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
> > +	       base + HSIO_ANA_SERDES6G_IB_CFG);
> > +	writel(0x0, base + HSIO_DIG_SERDES6G_MISC_CFG);
> > +
> > +	serdes6g_write(base, addr);
> > +
> > +	/* wait 60 for calibration */
> > +	mdelay(60);
> > +
> > +	/* set ib_tsdet and ib_reg_pat_sel_offset back to correct values */
> > +	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(ib_cal_ena) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
> > +	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
> > +	       base + HSIO_ANA_SERDES6G_IB_CFG);
> > +	writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_TSDET(ib1_tsdet) |
> > +	       HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
> > +	       base + HSIO_ANA_SERDES6G_IB_CFG1);
> > +
> > +	serdes6g_write(base, addr);
> > +}
> > +
> > +static void serdes1g_write(void __iomem *base, u32 addr)
> > +{
> > +	u32 data;
> > +
> > +	writel(HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT |
> > +	       HSIO_MCB_SERDES1G_CFG_ADDR(addr),
> > +	       base + HSIO_MCB_SERDES1G_CFG);
> > +
> > +	do {
> > +		data = readl(base + HSIO_MCB_SERDES1G_CFG);
> > +	} while (data & HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT);
> > +}
> > +
> > +static void serdes1g_setup(void __iomem *base, uint32_t addr,
> > +			   phy_interface_t interface)
> > +{
> > +	writel(0x0, base + HSIO_ANA_SERDES1G_SER_CFG);
> > +	writel(0x0, base + HSIO_DIG_SERDES1G_TP_CFG);
> > +	writel(0x0, base + HSIO_DIG_SERDES1G_DFT_CFG0);
> > +	writel(HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(1) |
> > +	       HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(4) |
> > +	       HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(2) |
> > +	       HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(12) |
> > +	       HSIO_ANA_SERDES1G_OB_CFG_SLP(3),
> > +	       base + HSIO_ANA_SERDES1G_OB_CFG);
> > +	writel(HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(13) |
> > +	       HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(2) |
> > +	       HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP |
> > +	       HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV |
> > +	       HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM |
> > +	       HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(3) |
> > +	       HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(1),
> > +	       base + HSIO_ANA_SERDES1G_IB_CFG);
> > +	writel(HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(7) |
> > +	       HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(6) |
> > +	       HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(2) |
> > +	       HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(6),
> > +	       base + HSIO_ANA_SERDES1G_DES_CFG);
> > +	writel(HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST,
> > +	       base + HSIO_DIG_SERDES1G_MISC_CFG);
> > +	writel(HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA |
> > +	       HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(0xc8) |
> > +	       HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2,
> > +	       base + HSIO_ANA_SERDES1G_PLL_CFG);
> > +	writel(HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE |
> > +	       HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE |
> > +	       HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST,
> > +	       base + HSIO_ANA_SERDES1G_COMMON_CFG);
> > +
> > +	serdes1g_write(base, addr);
> > +
> > +	setbits_le32(base + HSIO_ANA_SERDES1G_COMMON_CFG,
> > +		     HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST);
> > +
> > +	serdes1g_write(base, addr);
> > +
> > +	clrbits_le32(base + HSIO_DIG_SERDES1G_MISC_CFG,
> > +		     HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST);
> > +
> > +	serdes1g_write(base, addr);
> > +}
> > +
> > +static int ram_init(u32 val, void __iomem *addr)
> > +{
> > +	writel(val, addr);
> > +
> > +	if (wait_for_bit_le32(addr, BIT(1), false, 2000, false)) {
> > +		printf("Timeout in memory reset, reg = 0x%08x\n", val);
> > +		return 1;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int jr2_switch_init(struct jr2_private *priv)
> > +{
> > +	/* Initialize memories */
> > +	ram_init(0x3, priv->regs[QSYS] + QSYS_RAM_CTRL_RAM_INIT);
> > +	ram_init(0x3, priv->regs[ASM] + ASM_RAM_CTRL_RAM_INIT);
> > +	ram_init(0x3, priv->regs[ANA_AC] + ANA_AC_RAM_CTRL_RAM_INIT);
> > +	ram_init(0x3, priv->regs[REW] + REW_RAM_CTRL_RAM_INIT);
> > +
> > +	/* Reset counters */
> > +	writel(0x1, priv->regs[ANA_AC] + ANA_AC_STAT_GLOBAL_CFG_PORT_RESET);
> > +	writel(0x1, priv->regs[ASM] + ASM_CFG_STAT_CFG);
> > +
> > +	/* Enable switch-core and queue system */
> > +	writel(0x1, priv->regs[QSYS] + QSYS_SYSTEM_RESET_CFG);
> > +
> > +	return 0;
> > +}
> > +
> > +static void jr2_switch_config(struct jr2_private *priv)
> > +{
> > +	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(0));
> > +	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(1));
> > +	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(2));
> > +	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(3));
> > +
> > +	writel(readl(priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL) |
> > +	       QSYS_CALCFG_CAL_CTRL_CAL_MODE(8),
> > +	       priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL);
> > +}
> > +
> > +static int jr2_initialize(struct jr2_private *priv)
> > +{
> > +	int ret, i;
> > +
> > +	/* Initialize switch memories, enable core */
> > +	ret = jr2_switch_init(priv);
> > +	if (ret)
> > +		return ret;
> > +
> > +	jr2_switch_config(priv);
> > +
> > +	for (i = 0; i < MAX_PORT; i++)
> > +		jr2_port_init(priv, i);
> > +
> > +	jr2_cpu_capture_setup(priv);
> > +
> > +	return 0;
> > +}
> > +
> > +static inline int jr2_vlant_wait_for_completion(struct jr2_private *priv)
> > +{
> > +	if (wait_for_bit_le32(priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL,
> > +			      LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
> > +			      false, 2000, false))
> > +		return -ETIMEDOUT;
> > +
> > +	return 0;
> > +}
> > +
> > +static int jr2_mac_table_add(struct jr2_private *priv,
> > +			     const unsigned char mac[ETH_ALEN], int pgid)
> > +{
> > +	u32 macl = 0, mach = 0;
> > +
> > +	/*
> > +	 * Set the MAC address to handle and the vlan associated in a format
> > +	 * understood by the hardware.
> > +	 */
> > +	mach |= MAC_VID << 16;
> > +	mach |= ((u32)mac[0]) << 8;
> > +	mach |= ((u32)mac[1]) << 0;
> > +	macl |= ((u32)mac[2]) << 24;
> > +	macl |= ((u32)mac[3]) << 16;
> > +	macl |= ((u32)mac[4]) << 8;
> > +	macl |= ((u32)mac[5]) << 0;
> > +
> > +	writel(mach, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG0);
> > +	writel(macl, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG1);
> > +
> > +	writel(LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(pgid) |
> > +	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(0x3) |
> > +	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY |
> > +	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(0) |
> > +	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD |
> > +	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED,
> > +	       priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG2);
> > +
> > +	writel(LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
> > +	       priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL);
> > +
> > +	return jr2_vlant_wait_for_completion(priv);
> > +}
> > +
> > +static int jr2_write_hwaddr(struct udevice *dev)
> > +{
> > +	struct jr2_private *priv = dev_get_priv(dev);
> > +	struct eth_pdata *pdata = dev_get_platdata(dev);
> > +
> > +	return jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
> > +}
> > +
> > +static void serdes_setup(struct jr2_private *priv)
> > +{
> > +	size_t mask;
> > +	int i = 0;
> > +
> > +	for (i = 0; i < MAX_PORT; ++i) {
> > +		if (!priv->ports[i].bus || priv->ports[i].serdes_index == 0xff)
> > +			continue;
> > +
> > +		mask = BIT(priv->ports[i].serdes_index);
> > +		if (priv->ports[i].serdes_index < SERDES1G_MAX) {
> > +			serdes1g_setup(priv->regs[HSIO], mask,
> > +				       priv->ports[i].phy_mode);
> > +		} else {
> > +			mask >>= SERDES6G(0);
> > +			serdes6g_setup(priv->regs[HSIO], mask,
> > +				       priv->ports[i].phy_mode);
> > +		}
> > +	}
> > +}
> > +
> > +static int jr2_start(struct udevice *dev)
> > +{
> > +	struct jr2_private *priv = dev_get_priv(dev);
> > +	struct eth_pdata *pdata = dev_get_platdata(dev);
> > +	const unsigned char mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff,
> > +		0xff };
> > +	int ret;
> > +
> > +	ret = jr2_initialize(priv);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* Set MAC address tables entries for CPU redirection */
> > +	ret = jr2_mac_table_add(priv, mac, PGID_BROADCAST);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
> > +	if (ret)
> > +		return ret;
> > +
> > +	serdes_setup(priv);
> > +
> > +	return 0;
> > +}
> > +
> > +static void jr2_stop(struct udevice *dev)
> > +{
> 
> if you leave this empty I assume you can call jr2_start() multiple times
> without site effects and don't need to reverse some init stuff? Note
> that start() and stop() are called for each executed network command.

Yes, you are right, there are no side effects by calling jr2_start()
multiple times.

> 
> > +}
> > +
> > +static int jr2_send(struct udevice *dev, void *packet, int length)
> > +{
> > +	struct jr2_private *priv = dev_get_priv(dev);
> > +	u32 ifh[IFH_LEN];
> > +	u32 *buf = packet;
> > +
> > +	memset(ifh, '\0', IFH_LEN);
> > +
> > +	/* Set DST PORT_MASK */
> > +	ifh[0] = htonl(0);
> > +	ifh[1] = htonl(0x1FFFFF);
> > +	ifh[2] = htonl(~0);
> > +	/* Set DST_MODE to INJECT and UPDATE_FCS */
> > +	ifh[5] = htonl(0x4c0);
> > +
> > +	return mscc_send(priv->regs[QS], jr2_regs_qs,
> > +			 ifh, IFH_LEN, buf, length);
> > +}
> > +
> > +static int jr2_recv(struct udevice *dev, int flags, uchar **packetp)
> > +{
> > +	struct jr2_private *priv = dev_get_priv(dev);
> > +	u32 *rxbuf = (u32 *)net_rx_packets[0];
> > +	int byte_cnt = 0;
> > +
> > +	byte_cnt = mscc_recv(priv->regs[QS], jr2_regs_qs, rxbuf, IFH_LEN,
> > +			     false);
> > +
> > +	*packetp = net_rx_packets[0];
> > +
> > +	return byte_cnt;
> > +}
> > +
> > +static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
> > +{
> > +	int i = 0;
> > +
> > +	for (i = 0; i < JR2_MIIM_BUS_COUNT; ++i)
> > +		if (miim[i].miim_base == base && miim[i].miim_size == size)
> > +			return miim[i].bus;
> > +
> > +	return NULL;
> > +}
> > +
> > +static void add_port_entry(struct jr2_private *priv, size_t index,
> > +			   size_t phy_addr, struct mii_dev *bus,
> > +			   u8 serdes_index, u8 phy_mode)
> > +{
> > +	priv->ports[index].phy_addr = phy_addr;
> > +	priv->ports[index].bus = bus;
> > +	priv->ports[index].serdes_index = serdes_index;
> > +	priv->ports[index].phy_mode = phy_mode;
> > +}
> > +
> > +static int jr2_probe(struct udevice *dev)
> > +{
> > +	struct jr2_private *priv = dev_get_priv(dev);
> > +	int i;
> > +	int ret;
> > +	struct resource res;
> > +	fdt32_t faddr;
> > +	phys_addr_t addr_base;
> > +	unsigned long addr_size;
> > +	ofnode eth_node, node, mdio_node;
> > +	size_t phy_addr;
> > +	struct mii_dev *bus;
> > +	struct ofnode_phandle_args phandle;
> > +	struct phy_device *phy;
> > +
> > +	if (!priv)
> > +		return -EINVAL;
> > +
> > +	/* Get registers and map them to the private structure */
> > +	for (i = 0; i < ARRAY_SIZE(regs_names); i++) {
> > +		priv->regs[i] = dev_remap_addr_name(dev, regs_names[i]);
> > +		if (!priv->regs[i]) {
> > +			debug
> > +			    ("Error can't get regs base addresses for %s\n",
> > +			     regs_names[i]);
> > +			return -ENOMEM;
> > +		}
> > +	}
> > +
> > +	/* Initialize miim buses */
> > +	memset(&miim, 0x0, sizeof(struct jr2_miim_dev) * JR2_MIIM_BUS_COUNT);
> > +
> > +	/* iterate all the ports and find out on which bus they are */
> > +	i = 0;
> > +	eth_node = dev_read_first_subnode(dev);
> > +	for (node = ofnode_first_subnode(eth_node);
> > +	     ofnode_valid(node);
> > +	     node = ofnode_next_subnode(node)) {
> > +		if (ofnode_read_resource(node, 0, &res))
> > +			return -ENOMEM;
> > +		i = res.start;
> > +
> > +		ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL,
> > +						     0, 0, &phandle);
> > +		if (ret)
> > +			continue;
> > +
> > +		/* Get phy address on mdio bus */
> > +		if (ofnode_read_resource(phandle.node, 0, &res))
> > +			return -ENOMEM;
> > +		phy_addr = res.start;
> > +
> > +		/* Get mdio node */
> > +		mdio_node = ofnode_get_parent(phandle.node);
> > +
> > +		if (ofnode_read_resource(mdio_node, 0, &res))
> > +			return -ENOMEM;
> > +		faddr = cpu_to_fdt32(res.start);
> > +
> > +		addr_base = ofnode_translate_address(mdio_node, &faddr);
> > +		addr_size = res.end - res.start;
> > +
> > +		/* If the bus is new then create a new bus */
> > +		if (!get_mdiobus(addr_base, addr_size))
> > +			priv->bus[miim_count] =
> > +				jr2_mdiobus_init(addr_base, addr_size);
> > +
> > +		/* Connect mdio bus with the port */
> > +		bus = get_mdiobus(addr_base, addr_size);
> > +
> > +		/* Get serdes info */
> > +		ret = ofnode_parse_phandle_with_args(node, "phys", NULL,
> > +						     3, 0, &phandle);
> > +		if (ret)
> > +			return -ENOMEM;
> > +
> > +		add_port_entry(priv, i, phy_addr, bus, phandle.args[1],
> > +			       phandle.args[2]);
> > +	}
> > +
> > +	for (i = 0; i < MAX_PORT; i++) {
> > +		if (!priv->ports[i].bus)
> > +			continue;
> > +
> > +		phy = phy_connect(priv->ports[i].bus,
> > +				  priv->ports[i].phy_addr, dev,
> > +				  PHY_INTERFACE_MODE_NONE);
> > +		if (phy)
> > +			board_phy_config(phy);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int jr2_remove(struct udevice *dev)
> > +{
> > +	struct jr2_private *priv = dev_get_priv(dev);
> > +	int i;
> > +
> > +	for (i = 0; i < JR2_MIIM_BUS_COUNT; i++) {
> > +		mdio_unregister(priv->bus[i]);
> > +		mdio_free(priv->bus[i]);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct eth_ops jr2_ops = {
> > +	.start        = jr2_start,
> > +	.stop         = jr2_stop,
> > +	.send         = jr2_send,
> > +	.recv         = jr2_recv,
> > +	.write_hwaddr = jr2_write_hwaddr,
> > +};
> > +
> > +static const struct udevice_id mscc_jr2_ids[] = {
> > +	{.compatible = "mscc,vsc7454-switch" },
> > +	{ /* Sentinel */ }
> > +};
> > +
> > +U_BOOT_DRIVER(jr2) = {
> > +	.name				= "jr2-switch",
> > +	.id				= UCLASS_ETH,
> > +	.of_match			= mscc_jr2_ids,
> > +	.probe				= jr2_probe,
> > +	.remove				= jr2_remove,
> > +	.ops				= &jr2_ops,
> > +	.priv_auto_alloc_size		= sizeof(struct jr2_private),
> > +	.platdata_auto_alloc_size	= sizeof(struct eth_pdata),
> > +};
> > diff --git a/include/configs/vcoreiii.h b/include/configs/vcoreiii.h
> > index 2840c7b..aeef58d 100644
> > --- a/include/configs/vcoreiii.h
> > +++ b/include/configs/vcoreiii.h
> > @@ -10,7 +10,7 @@
> >  
> >  /* Onboard devices */
> >  
> > -#define CONFIG_SYS_MALLOC_LEN		0x100000
> > +#define CONFIG_SYS_MALLOC_LEN		0x1F0000
> >  #define CONFIG_SYS_LOAD_ADDR		0x00100000
> >  #define CONFIG_SYS_INIT_SP_OFFSET       0x400000
> >  
> > 
> 
> -- 
> - Daniel

-- 
/Horatiu

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

end of thread, other threads:[~2019-04-03 10:59 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-30 10:16 [U-Boot] [PATCH v3 0/4] Add network support for Jaguar2 SoCs Horatiu Vultur
2019-03-30 10:17 ` [U-Boot] [PATCH v3 1/4] net: Add MSCC Jaguar2 network driver Horatiu Vultur
2019-04-03 10:18   ` Daniel Schwierzeck
2019-04-03 10:59     ` Horatiu Vultur
2019-03-30 10:17 ` [U-Boot] [PATCH v3 2/4] board: mscc: jr2: Update MSCC Jaguar2 boards Horatiu Vultur
2019-03-30 10:17 ` [U-Boot] [PATCH v3 3/4] net: mscc: jaguar2: Add ethenet nodes for Jaguar2 Horatiu Vultur
2019-03-30 10:17 ` [U-Boot] [PATCH v3 4/4] configs: mscc_jr2: Add network support Horatiu Vultur

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.