common: Drop linux/bitops.h from common header
[oweals/u-boot.git] / drivers / net / ti / cpsw_mdio.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * CPSW MDIO generic driver for TI AMxx/K2x/EMAC devices.
4  *
5  * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
6  */
7
8 #include <common.h>
9 #include <log.h>
10 #include <malloc.h>
11 #include <asm/io.h>
12 #include <miiphy.h>
13 #include <wait_bit.h>
14 #include <linux/bitops.h>
15 #include <linux/delay.h>
16
17 struct cpsw_mdio_regs {
18         u32     version;
19         u32     control;
20 #define CONTROL_IDLE            BIT(31)
21 #define CONTROL_ENABLE          BIT(30)
22 #define CONTROL_FAULT           BIT(19)
23 #define CONTROL_FAULT_ENABLE    BIT(18)
24 #define CONTROL_DIV_MASK        GENMASK(15, 0)
25
26         u32     alive;
27         u32     link;
28         u32     linkintraw;
29         u32     linkintmasked;
30         u32     __reserved_0[2];
31         u32     userintraw;
32         u32     userintmasked;
33         u32     userintmaskset;
34         u32     userintmaskclr;
35         u32     __reserved_1[20];
36
37         struct {
38                 u32             access;
39                 u32             physel;
40 #define USERACCESS_GO           BIT(31)
41 #define USERACCESS_WRITE        BIT(30)
42 #define USERACCESS_ACK          BIT(29)
43 #define USERACCESS_READ         (0)
44 #define USERACCESS_PHY_REG_SHIFT        (21)
45 #define USERACCESS_PHY_ADDR_SHIFT       (16)
46 #define USERACCESS_DATA         GENMASK(15, 0)
47         } user[0];
48 };
49
50 #define CPSW_MDIO_DIV_DEF       0xff
51 #define PHY_REG_MASK            0x1f
52 #define PHY_ID_MASK             0x1f
53
54 /*
55  * This timeout definition is a worst-case ultra defensive measure against
56  * unexpected controller lock ups.  Ideally, we should never ever hit this
57  * scenario in practice.
58  */
59 #define CPSW_MDIO_TIMEOUT            100 /* msecs */
60
61 struct cpsw_mdio {
62         struct cpsw_mdio_regs *regs;
63         struct mii_dev *bus;
64         int div;
65 };
66
67 /* wait until hardware is ready for another user access */
68 static int cpsw_mdio_wait_for_user_access(struct cpsw_mdio *mdio)
69 {
70         return wait_for_bit_le32(&mdio->regs->user[0].access,
71                                  USERACCESS_GO, false,
72                                  CPSW_MDIO_TIMEOUT, false);
73 }
74
75 static int cpsw_mdio_read(struct mii_dev *bus, int phy_id,
76                           int dev_addr, int phy_reg)
77 {
78         struct cpsw_mdio *mdio = bus->priv;
79         int data, ret;
80         u32 reg;
81
82         if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
83                 return -EINVAL;
84
85         ret = cpsw_mdio_wait_for_user_access(mdio);
86         if (ret)
87                 return ret;
88         reg = (USERACCESS_GO | USERACCESS_READ |
89                (phy_reg << USERACCESS_PHY_REG_SHIFT) |
90                (phy_id << USERACCESS_PHY_ADDR_SHIFT));
91         writel(reg, &mdio->regs->user[0].access);
92         ret = cpsw_mdio_wait_for_user_access(mdio);
93         if (ret)
94                 return ret;
95
96         reg = readl(&mdio->regs->user[0].access);
97         data = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -1;
98         return data;
99 }
100
101 static int cpsw_mdio_write(struct mii_dev *bus, int phy_id, int dev_addr,
102                            int phy_reg, u16 data)
103 {
104         struct cpsw_mdio *mdio = bus->priv;
105         u32 reg;
106         int ret;
107
108         if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
109                 return -EINVAL;
110
111         ret = cpsw_mdio_wait_for_user_access(mdio);
112         if (ret)
113                 return ret;
114         reg = (USERACCESS_GO | USERACCESS_WRITE |
115                (phy_reg << USERACCESS_PHY_REG_SHIFT) |
116                (phy_id << USERACCESS_PHY_ADDR_SHIFT) |
117                (data & USERACCESS_DATA));
118         writel(reg, &mdio->regs->user[0].access);
119
120         return cpsw_mdio_wait_for_user_access(mdio);
121 }
122
123 u32 cpsw_mdio_get_alive(struct mii_dev *bus)
124 {
125         struct cpsw_mdio *mdio = bus->priv;
126         u32 val;
127
128         val = readl(&mdio->regs->control);
129         return val & GENMASK(15, 0);
130 }
131
132 struct mii_dev *cpsw_mdio_init(const char *name, phys_addr_t mdio_base,
133                                u32 bus_freq, int fck_freq)
134 {
135         struct cpsw_mdio *cpsw_mdio;
136         int ret;
137
138         cpsw_mdio = calloc(1, sizeof(*cpsw_mdio));
139         if (!cpsw_mdio) {
140                 debug("failed to alloc cpsw_mdio\n");
141                 return NULL;
142         }
143
144         cpsw_mdio->bus = mdio_alloc();
145         if (!cpsw_mdio->bus) {
146                 debug("failed to alloc mii bus\n");
147                 free(cpsw_mdio);
148                 return NULL;
149         }
150
151         cpsw_mdio->regs = (struct cpsw_mdio_regs *)(uintptr_t)mdio_base;
152
153         if (!bus_freq || !fck_freq)
154                 cpsw_mdio->div = CPSW_MDIO_DIV_DEF;
155         else
156                 cpsw_mdio->div = (fck_freq / bus_freq) - 1;
157         cpsw_mdio->div &= CONTROL_DIV_MASK;
158
159         /* set enable and clock divider */
160         writel(cpsw_mdio->div | CONTROL_ENABLE | CONTROL_FAULT |
161                CONTROL_FAULT_ENABLE, &cpsw_mdio->regs->control);
162         wait_for_bit_le32(&cpsw_mdio->regs->control,
163                           CONTROL_IDLE, false, CPSW_MDIO_TIMEOUT, true);
164
165         /*
166          * wait for scan logic to settle:
167          * the scan time consists of (a) a large fixed component, and (b) a
168          * small component that varies with the mii bus frequency.  These
169          * were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x
170          * silicon.  Since the effect of (b) was found to be largely
171          * negligible, we keep things simple here.
172          */
173         mdelay(1);
174
175         cpsw_mdio->bus->read = cpsw_mdio_read;
176         cpsw_mdio->bus->write = cpsw_mdio_write;
177         cpsw_mdio->bus->priv = cpsw_mdio;
178         snprintf(cpsw_mdio->bus->name, sizeof(cpsw_mdio->bus->name), name);
179
180         ret = mdio_register(cpsw_mdio->bus);
181         if (ret < 0) {
182                 debug("failed to register mii bus\n");
183                 goto free_bus;
184         }
185
186         return cpsw_mdio->bus;
187
188 free_bus:
189         mdio_free(cpsw_mdio->bus);
190         free(cpsw_mdio);
191         return NULL;
192 }
193
194 void cpsw_mdio_free(struct mii_dev *bus)
195 {
196         struct cpsw_mdio *mdio = bus->priv;
197         u32 reg;
198
199         /* disable mdio */
200         reg = readl(&mdio->regs->control);
201         reg &= ~CONTROL_ENABLE;
202         writel(reg, &mdio->regs->control);
203
204         mdio_unregister(bus);
205         mdio_free(bus);
206         free(mdio);
207 }