You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.9 KiB

/*
* Copyright (c) Company 2018-2019. All rights reserved.
* Description: The header file of GMAC mdio driver
*/
#ifndef __SOCT_GMAC_MDIO_H__
#define __SOCT_GMAC_MDIO_H__
#include "gmac.h"
#define GMAC_MDIO_IO_BASE 0x10090000
#define GMAC_MDIO_IO_SIZE 0x1000
#define GMAC_MDIO_FRQDIV 0
#define REG_MDIO_SINGLE_CMD 0x000003C0
#define REG_MDIO_SINGLE_DATA 0x000003C4
#define REG_MDIO_RDATA_STATUS 0x000003D0
/* 0:mdio operation done, 1: start mdio operation */
#define MDIO_CMD mk_bits(20, 1)
#define MDIO_WR_DATA mk_bits(0, 16)
#define MDIO_RDATA_STATUS mk_bits(0, 1)
#define MDIO_CMD_READ 2
#define MDIO_CMD_WRITE 1
#define gmac_mdio_readl(ld, ofs) \
({ unsigned int reg = readl((ld)->gmac_iobase + (ofs)); \
gmac_trace(2, "readl(0x%04X) = 0x%08X", (ofs), reg); reg; })
#define gmac_mdio_writel(ld, v, ofs) \
do { writel(v, (ld)->gmac_iobase + (ofs)); \
gmac_trace(2, "writel(0x%04X) = 0x%08X", (ofs), \
(unsigned int)(v)); \
} while (0)
#define gmac_mdio_writel_bits(ld, v, ofs, bits_desc) \
do { \
unsigned int _bits_desc = bits_desc; \
unsigned int _shift = (_bits_desc) >> 16; \
unsigned int _reg = gmac_mdio_readl(ld, ofs); \
unsigned int _mask = ((_bits_desc & 0x3F) < 32) ? \
(((1 << (_bits_desc & 0x3F)) - 1) << (_shift)) : 0xffffffff; \
gmac_mdio_writel(ld, (_reg & (~_mask)) \
| (((unsigned int)(v) << (_shift)) & _mask), ofs); \
} while (0)
#define gmac_mdio_readl_bits(ld, ofs, bits_desc) \
({ unsigned int _bits_desc = bits_desc; \
unsigned int _shift = (_bits_desc) >> 16; \
unsigned int _mask = ((_bits_desc & 0x3F) < 32) ? \
(((1 << (_bits_desc & 0x3F)) - 1) << (_shift)) : 0xffffffff; \
(gmac_mdio_readl(ld, ofs) & _mask) >> (_shift); })
#define mdio_mk_rwctl(rw, phy_exaddr, phy_regnum) \
(((0x1)<<20) | \
(((rw)&0x3)<<16) | \
(((phy_exaddr)&0x1f)<<8) | \
((phy_regnum)&0x1f))
#define mdio_start_phyread(ld, phy_addr, regnum) \
gmac_mdio_writel(ld, \
mdio_mk_rwctl(MDIO_CMD_READ, phy_addr, regnum), \
REG_MDIO_SINGLE_CMD)
#define mdio_get_phyread_val(ld) \
(gmac_mdio_readl(ld, REG_MDIO_SINGLE_DATA) >> 16)
#define mdio_set_phywrite_val(ld, val) \
do { \
unsigned int reg = 0; \
gmac_mdio_writel_bits(ld, val, REG_MDIO_SINGLE_DATA, MDIO_WR_DATA); \
reg = gmac_mdio_readl(ld, REG_MDIO_SINGLE_DATA); \
gmac_trace(2, "write reg 0x%x, bits:0x%x= 0x%x, then read = 0x%x", \
REG_MDIO_SINGLE_DATA, MDIO_WR_DATA, val, reg); \
} while (0)
#define mdio_phywrite(ld, phy_addr, regnum) \
gmac_mdio_writel(ld, \
mdio_mk_rwctl(MDIO_CMD_WRITE, phy_addr, regnum), \
REG_MDIO_SINGLE_CMD)
#define test_mdio_ready(ld) \
(gmac_mdio_readl_bits((ld), REG_MDIO_SINGLE_CMD, MDIO_CMD) == 0)
#define test_mdio_read_data_done(ld) \
(gmac_mdio_readl_bits(ld, REG_MDIO_RDATA_STATUS, MDIO_RDATA_STATUS) \
== 0)
int gmac_mdio_read(struct mii_bus *bus, int phy, int reg);
int gmac_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val);
#endif