1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
2 | /* Applied Micro X-Gene SoC MDIO Driver |
3 | * |
4 | * Copyright (c) 2016, Applied Micro Circuits Corporation |
5 | * Author: Iyappan Subramanian <isubramanian@apm.com> |
6 | */ |
7 | |
8 | #ifndef __MDIO_XGENE_H__ |
9 | #define __MDIO_XGENE_H__ |
10 | |
11 | #include <linux/bits.h> |
12 | #include <linux/spinlock.h> |
13 | #include <linux/types.h> |
14 | |
15 | #define BLOCK_XG_MDIO_CSR_OFFSET 0x5000 |
16 | #define BLOCK_DIAG_CSR_OFFSET 0xd000 |
17 | #define XGENET_CONFIG_REG_ADDR 0x20 |
18 | |
19 | #define MAC_ADDR_REG_OFFSET 0x00 |
20 | #define MAC_COMMAND_REG_OFFSET 0x04 |
21 | #define MAC_WRITE_REG_OFFSET 0x08 |
22 | #define MAC_READ_REG_OFFSET 0x0c |
23 | #define MAC_COMMAND_DONE_REG_OFFSET 0x10 |
24 | |
25 | #define CLKEN_OFFSET 0x08 |
26 | #define SRST_OFFSET 0x00 |
27 | |
28 | #define MENET_CFG_MEM_RAM_SHUTDOWN_ADDR 0x70 |
29 | #define MENET_BLOCK_MEM_RDY_ADDR 0x74 |
30 | |
31 | #define MAC_CONFIG_1_ADDR 0x00 |
32 | #define MII_MGMT_COMMAND_ADDR 0x24 |
33 | #define MII_MGMT_ADDRESS_ADDR 0x28 |
34 | #define MII_MGMT_CONTROL_ADDR 0x2c |
35 | #define MII_MGMT_STATUS_ADDR 0x30 |
36 | #define MII_MGMT_INDICATORS_ADDR 0x34 |
37 | #define SOFT_RESET BIT(31) |
38 | |
39 | #define MII_MGMT_CONFIG_ADDR 0x20 |
40 | #define MII_MGMT_COMMAND_ADDR 0x24 |
41 | #define MII_MGMT_ADDRESS_ADDR 0x28 |
42 | #define MII_MGMT_CONTROL_ADDR 0x2c |
43 | #define MII_MGMT_STATUS_ADDR 0x30 |
44 | #define MII_MGMT_INDICATORS_ADDR 0x34 |
45 | |
46 | #define MIIM_COMMAND_ADDR 0x20 |
47 | #define MIIM_FIELD_ADDR 0x24 |
48 | #define MIIM_CONFIGURATION_ADDR 0x28 |
49 | #define MIIM_LINKFAILVECTOR_ADDR 0x2c |
50 | #define MIIM_INDICATOR_ADDR 0x30 |
51 | #define MIIMRD_FIELD_ADDR 0x34 |
52 | |
53 | #define MDIO_CSR_OFFSET 0x5000 |
54 | |
55 | #define REG_ADDR_POS 0 |
56 | #define REG_ADDR_LEN 5 |
57 | #define PHY_ADDR_POS 8 |
58 | #define PHY_ADDR_LEN 5 |
59 | |
60 | #define HSTMIIMWRDAT_POS 0 |
61 | #define HSTMIIMWRDAT_LEN 16 |
62 | #define HSTPHYADX_POS 23 |
63 | #define HSTPHYADX_LEN 5 |
64 | #define HSTREGADX_POS 18 |
65 | #define HSTREGADX_LEN 5 |
66 | #define HSTLDCMD BIT(3) |
67 | #define HSTMIIMCMD_POS 0 |
68 | #define HSTMIIMCMD_LEN 3 |
69 | |
70 | #define BUSY_MASK BIT(0) |
71 | #define READ_CYCLE_MASK BIT(0) |
72 | |
73 | enum xgene_enet_cmd { |
74 | XGENE_ENET_WR_CMD = BIT(31), |
75 | XGENE_ENET_RD_CMD = BIT(30) |
76 | }; |
77 | |
78 | enum { |
79 | MIIM_CMD_IDLE, |
80 | MIIM_CMD_LEGACY_WRITE, |
81 | MIIM_CMD_LEGACY_READ, |
82 | }; |
83 | |
84 | enum xgene_mdio_id { |
85 | XGENE_MDIO_RGMII = 1, |
86 | XGENE_MDIO_XFI |
87 | }; |
88 | |
89 | struct xgene_mdio_pdata { |
90 | struct clk *clk; |
91 | struct device *dev; |
92 | void __iomem *mac_csr_addr; |
93 | void __iomem *diag_csr_addr; |
94 | void __iomem *mdio_csr_addr; |
95 | struct mii_bus *mdio_bus; |
96 | int mdio_id; |
97 | spinlock_t mac_lock; /* mac lock */ |
98 | }; |
99 | |
100 | /* Set the specified value into a bit-field defined by its starting position |
101 | * and length within a single u64. |
102 | */ |
103 | static inline u64 xgene_enet_set_field_value(int pos, int len, u64 val) |
104 | { |
105 | return (val & ((1ULL << len) - 1)) << pos; |
106 | } |
107 | |
108 | #define SET_VAL(field, val) \ |
109 | xgene_enet_set_field_value(field ## _POS, field ## _LEN, val) |
110 | |
111 | #define SET_BIT(field) \ |
112 | xgene_enet_set_field_value(field ## _POS, 1, 1) |
113 | |
114 | /* Get the value from a bit-field defined by its starting position |
115 | * and length within the specified u64. |
116 | */ |
117 | static inline u64 xgene_enet_get_field_value(int pos, int len, u64 src) |
118 | { |
119 | return (src >> pos) & ((1ULL << len) - 1); |
120 | } |
121 | |
122 | #define GET_VAL(field, src) \ |
123 | xgene_enet_get_field_value(field ## _POS, field ## _LEN, src) |
124 | |
125 | #define GET_BIT(field, src) \ |
126 | xgene_enet_get_field_value(field ## _POS, 1, src) |
127 | |
128 | u32 xgene_mdio_rd_mac(struct xgene_mdio_pdata *pdata, u32 rd_addr); |
129 | void xgene_mdio_wr_mac(struct xgene_mdio_pdata *pdata, u32 wr_addr, u32 data); |
130 | int xgene_mdio_rgmii_read(struct mii_bus *bus, int phy_id, int reg); |
131 | int xgene_mdio_rgmii_write(struct mii_bus *bus, int phy_id, int reg, u16 data); |
132 | struct phy_device *xgene_enet_phy_register(struct mii_bus *bus, int phy_addr); |
133 | |
134 | #endif /* __MDIO_XGENE_H__ */ |
135 | |