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