[U-Boot] [PATCH 2/6] mips: mscc: Add generic PHY MIIM utility functions

Lars Povlsen lars.povlsen at microchip.com
Wed Dec 19 12:42:29 UTC 2018


The PHY MIIM utility functions can/will be used for board detection
purposes.

Signed-off-by: Lars Povlsen <lars.povlsen at microchip.com>
---
 arch/mips/mach-mscc/Makefile                  |  2 +-
 arch/mips/mach-mscc/include/mach/common.h     | 20 +++++
 .../mach/luton/luton_devcpu_gcb_miim_regs.h   | 26 +++++++
 .../mach/ocelot/ocelot_devcpu_gcb_miim_regs.h | 25 +++++++
 arch/mips/mach-mscc/phy.c                     | 73 +++++++++++++++++++
 5 files changed, 145 insertions(+), 1 deletion(-)
 create mode 100644 arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb_miim_regs.h
 create mode 100644 arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb_miim_regs.h
 create mode 100644 arch/mips/mach-mscc/phy.c

diff --git a/arch/mips/mach-mscc/Makefile b/arch/mips/mach-mscc/Makefile
index 6c60f26ca4..300c88b5cd 100644
--- a/arch/mips/mach-mscc/Makefile
+++ b/arch/mips/mach-mscc/Makefile
@@ -2,5 +2,5 @@
 
 CFLAGS_cpu.o += -finline-limit=64000
 
-obj-y += cpu.o dram.o reset.o lowlevel_init.o
+obj-y += cpu.o dram.o reset.o phy.o lowlevel_init.o
 obj-$(CONFIG_SOC_LUTON) += lowlevel_init_luton.o
diff --git a/arch/mips/mach-mscc/include/mach/common.h b/arch/mips/mach-mscc/include/mach/common.h
index 931ecd7985..92a055561e 100644
--- a/arch/mips/mach-mscc/include/mach/common.h
+++ b/arch/mips/mach-mscc/include/mach/common.h
@@ -9,10 +9,12 @@
 #if defined(CONFIG_SOC_OCELOT)
 #include <mach/ocelot/ocelot.h>
 #include <mach/ocelot/ocelot_devcpu_gcb.h>
+#include <mach/ocelot/ocelot_devcpu_gcb_miim_regs.h>
 #include <mach/ocelot/ocelot_icpu_cfg.h>
 #elif defined(CONFIG_SOC_LUTON)
 #include <mach/luton/luton.h>
 #include <mach/luton/luton_devcpu_gcb.h>
+#include <mach/luton/luton_devcpu_gcb_miim_regs.h>
 #include <mach/luton/luton_icpu_cfg.h>
 #else
 #error Unsupported platform
@@ -25,4 +27,22 @@
 
 #define VCOREIII_TIMER_DIVIDER 25	/* Clock tick ~ 0.1 us */
 
+/* Common utility functions */
+
+int mscc_phy_rd_wr(u8 read,
+		   u32 miim_controller,
+		   u8 miim_addr,
+		   u8 addr,
+		   u16 *value);
+
+int mscc_phy_rd(u32 miim_controller,
+		u8 miim_addr,
+		u8 addr,
+		u16 *value);
+
+int mscc_phy_wr(u32 miim_controller,
+		u8 miim_addr,
+		u8 addr,
+		u16 value);
+
 #endif				/* __ASM_MACH_COMMON_H */
diff --git a/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb_miim_regs.h b/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb_miim_regs.h
new file mode 100644
index 0000000000..2303734894
--- /dev/null
+++ b/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb_miim_regs.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Microsemi Ocelot Switch driver
+ *
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_LUTON_MIIM_REGS_H_
+#define _MSCC_LUTON_MIIM_REGS_H_
+
+#define MIIM_MII_STATUS(gi) (0xa0 + (gi * 36))
+#define MIIM_MII_CMD(gi)    (0xa8 + (gi * 36))
+#define MIIM_MII_DATA(gi)   (0xac + (gi * 36))
+
+#define MSCC_F_MII_STATUS_MIIM_STAT_BUSY(x)   (x ? BIT(3) : 0)
+
+#define MSCC_F_MII_CMD_MIIM_CMD_VLD(x)        (x ? BIT(31) : 0)
+#define MSCC_F_MII_CMD_MIIM_CMD_PHYAD(x)      (GENMASK(29, 25) & (x << 25))
+#define MSCC_F_MII_CMD_MIIM_CMD_REGAD(x)      (GENMASK(24, 20) & (x << 20))
+#define MSCC_F_MII_CMD_MIIM_CMD_WRDATA(x)     (GENMASK(19, 4) & (x << 4))
+#define MSCC_F_MII_CMD_MIIM_CMD_OPR_FIELD(x)  (GENMASK(2, 1) & (x << 1))
+
+#define MSCC_M_MII_DATA_MIIM_DATA_SUCCESS     GENMASK(17, 16)
+#define MSCC_X_MII_DATA_MIIM_DATA_RDDATA(x)   ((x >> 0) & GENMASK(15, 0))
+
+#endif
diff --git a/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb_miim_regs.h b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb_miim_regs.h
new file mode 100644
index 0000000000..4ad92214a3
--- /dev/null
+++ b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb_miim_regs.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_DEVCPU_GCB_MIIM_REGS_H_
+#define _MSCC_OCELOT_DEVCPU_GCB_MIIM_REGS_H_
+
+#define MIIM_MII_STATUS(gi) (0x9c + (gi * 36))
+#define MIIM_MII_CMD(gi)    (0xa4 + (gi * 36))
+#define MIIM_MII_DATA(gi)   (0xa8 + (gi * 36))
+
+#define MSCC_F_MII_STATUS_MIIM_STAT_BUSY(x)   ((x) ? BIT(3) : 0)
+
+#define MSCC_F_MII_CMD_MIIM_CMD_VLD(x)        ((x) ? BIT(31) : 0)
+#define MSCC_F_MII_CMD_MIIM_CMD_PHYAD(x)      (GENMASK(29, 25) & ((x) << 25))
+#define MSCC_F_MII_CMD_MIIM_CMD_REGAD(x)      (GENMASK(24, 20) & ((x) << 20))
+#define MSCC_F_MII_CMD_MIIM_CMD_WRDATA(x)     (GENMASK(19, 4) & ((x) << 4))
+#define MSCC_F_MII_CMD_MIIM_CMD_OPR_FIELD(x)  (GENMASK(2, 1) & ((x) << 1))
+#define MSCC_F_MII_CMD_MIIM_CMD_SCAN(x)       ((x) ? BIT(0) : 0)
+
+#define MSCC_M_MII_DATA_MIIM_DATA_SUCCESS     GENMASK(17, 16)
+#define MSCC_X_MII_DATA_MIIM_DATA_RDDATA(x)   (((x) >> 0) & GENMASK(15, 0))
+
+#endif
diff --git a/arch/mips/mach-mscc/phy.c b/arch/mips/mach-mscc/phy.c
new file mode 100644
index 0000000000..add6280e38
--- /dev/null
+++ b/arch/mips/mach-mscc/phy.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+int mscc_phy_rd_wr(u8 read,
+		   u32 miimdev,
+		   u8 miim_addr,
+		   u8 addr,
+		   u16 *value)
+{
+	u32 data;
+	int i;
+
+	/* Command part */
+	data = (read ? MSCC_F_MII_CMD_MIIM_CMD_OPR_FIELD(2) : /* Read */
+		MSCC_F_MII_CMD_MIIM_CMD_OPR_FIELD(1) | /* Write */
+		MSCC_F_MII_CMD_MIIM_CMD_WRDATA(*value)); /* value */
+
+	/* Addressing part */
+	data |=
+		MSCC_F_MII_CMD_MIIM_CMD_VLD(1) | /* Valid command */
+		MSCC_F_MII_CMD_MIIM_CMD_REGAD(addr) | /* Reg addr */
+		MSCC_F_MII_CMD_MIIM_CMD_PHYAD(miim_addr); /* Miim addr */
+
+	/* Enqueue MIIM operation to be executed */
+	writel(data, BASE_DEVCPU_GCB + MIIM_MII_CMD(miimdev));
+
+	/* Wait for MIIM operation to finish */
+	i = 0;
+	do {
+		if (i++ > 100) {
+			debug("Miim timeout");
+			return -1;
+		}
+		data = readl(BASE_DEVCPU_GCB + MIIM_MII_STATUS(miimdev));
+		debug("Read status miim(%d): 0x%08x\n", miimdev, data);
+	} while (data & MSCC_F_MII_STATUS_MIIM_STAT_BUSY(1));
+
+	if (read) {
+		data = readl(BASE_DEVCPU_GCB + MIIM_MII_DATA(miimdev));
+		if (data & MSCC_M_MII_DATA_MIIM_DATA_SUCCESS) {
+			debug("Read(%d, %d) returned 0x%08x\n",
+			      miim_addr, addr, data);
+			return -1;
+		}
+		*value = MSCC_X_MII_DATA_MIIM_DATA_RDDATA(data);
+	}
+
+	return 0;
+}
+
+int mscc_phy_rd(u32 miimdev,
+		u8 miim_addr,
+		u8 addr,
+		u16 *value)
+{
+	if (mscc_phy_rd_wr(1, miimdev, miim_addr, addr, value) == 0)
+		return 0;
+	debug("Read(%d, %d) returned error\n", miim_addr, addr);
+	return -1;
+}
+
+int mscc_phy_wr(u32 miimdev,
+		u8 miim_addr,
+		u8 addr,
+		u16 value)
+{
+	return mscc_phy_rd_wr(0, miimdev, miim_addr, addr, &value);
+}
-- 
2.19.2



More information about the U-Boot mailing list