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