mips: mscc: Add generic PHY MIIM utility functions
The PHY MIIM utility functions can/will be used for board detection purposes. Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com>
This commit is contained in:
		
							parent
							
								
									d3689267f9
								
							
						
					
					
						commit
						3098ade229
					
				| 
						 | 
					@ -2,5 +2,5 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CFLAGS_cpu.o += -finline-limit=64000
 | 
					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
 | 
					obj-$(CONFIG_SOC_LUTON) += lowlevel_init_luton.o
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,10 +9,12 @@
 | 
				
			||||||
#if defined(CONFIG_SOC_OCELOT)
 | 
					#if defined(CONFIG_SOC_OCELOT)
 | 
				
			||||||
#include <mach/ocelot/ocelot.h>
 | 
					#include <mach/ocelot/ocelot.h>
 | 
				
			||||||
#include <mach/ocelot/ocelot_devcpu_gcb.h>
 | 
					#include <mach/ocelot/ocelot_devcpu_gcb.h>
 | 
				
			||||||
 | 
					#include <mach/ocelot/ocelot_devcpu_gcb_miim_regs.h>
 | 
				
			||||||
#include <mach/ocelot/ocelot_icpu_cfg.h>
 | 
					#include <mach/ocelot/ocelot_icpu_cfg.h>
 | 
				
			||||||
#elif defined(CONFIG_SOC_LUTON)
 | 
					#elif defined(CONFIG_SOC_LUTON)
 | 
				
			||||||
#include <mach/luton/luton.h>
 | 
					#include <mach/luton/luton.h>
 | 
				
			||||||
#include <mach/luton/luton_devcpu_gcb.h>
 | 
					#include <mach/luton/luton_devcpu_gcb.h>
 | 
				
			||||||
 | 
					#include <mach/luton/luton_devcpu_gcb_miim_regs.h>
 | 
				
			||||||
#include <mach/luton/luton_icpu_cfg.h>
 | 
					#include <mach/luton/luton_icpu_cfg.h>
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#error Unsupported platform
 | 
					#error Unsupported platform
 | 
				
			||||||
| 
						 | 
					@ -25,4 +27,22 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VCOREIII_TIMER_DIVIDER 25	/* Clock tick ~ 0.1 us */
 | 
					#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 */
 | 
					#endif				/* __ASM_MACH_COMMON_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
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue