2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2003-2012 Broadcom Corporation
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
18 * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 #include <sys/types.h>
34 #include <sys/systm.h>
36 #include <mips/nlm/hal/mips-extns.h>
37 #include <mips/nlm/hal/haldefs.h>
38 #include <mips/nlm/hal/iomap.h>
39 #include <mips/nlm/hal/sys.h>
40 #include <mips/nlm/hal/nae.h>
41 #include <mips/nlm/hal/mdio.h>
43 #include <mips/nlm/xlp.h>
45 /* Internal MDIO READ/WRITE Routines */
47 nlm_int_gmac_mdio_read(uint64_t nae_base, int bus, int block,
48 int intf_type, int phyaddr, int regidx)
53 ctrlval = INT_MDIO_CTRL_SMP |
54 (phyaddr << INT_MDIO_CTRL_PHYADDR_POS) |
55 (regidx << INT_MDIO_CTRL_DEVTYPE_POS) |
56 (2 << INT_MDIO_CTRL_OP_POS) |
57 (1 << INT_MDIO_CTRL_ST_POS) |
58 (7 << INT_MDIO_CTRL_XDIV_POS) |
59 (2 << INT_MDIO_CTRL_TA_POS) |
60 (2 << INT_MDIO_CTRL_MIIM_POS) |
61 (1 << INT_MDIO_CTRL_MCDIV_POS);
63 mdio_ld_cmd = nlm_read_nae_reg(nae_base,
64 NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)));
65 if (mdio_ld_cmd & INT_MDIO_CTRL_CMD_LOAD) {
66 nlm_write_nae_reg(nae_base,
67 NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus*4)),
68 (mdio_ld_cmd & ~INT_MDIO_CTRL_CMD_LOAD));
71 nlm_write_nae_reg(nae_base,
72 NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
75 /* Toggle Load Cmd Bit */
76 nlm_write_nae_reg(nae_base,
77 NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
78 ctrlval | (1 << INT_MDIO_CTRL_LOAD_POS));
80 /* poll master busy bit until it is not busy */
81 while(nlm_read_nae_reg(nae_base,
82 NAE_REG(block, intf_type, (INT_MDIO_RD_STAT + bus * 4))) &
86 nlm_write_nae_reg(nae_base,
87 NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
90 /* Read the data back */
91 return nlm_read_nae_reg(nae_base,
92 NAE_REG(block, intf_type, (INT_MDIO_RD_STAT + bus * 4)));
95 /* Internal MDIO WRITE Routines */
97 nlm_int_gmac_mdio_write(uint64_t nae_base, int bus, int block,
98 int intf_type, int phyaddr, int regidx, uint16_t val)
100 uint32_t mdio_ld_cmd;
103 ctrlval = INT_MDIO_CTRL_SMP |
104 (phyaddr << INT_MDIO_CTRL_PHYADDR_POS) |
105 (regidx << INT_MDIO_CTRL_DEVTYPE_POS) |
106 (1 << INT_MDIO_CTRL_OP_POS) |
107 (1 << INT_MDIO_CTRL_ST_POS) |
108 (7 << INT_MDIO_CTRL_XDIV_POS) |
109 (2 << INT_MDIO_CTRL_TA_POS) |
110 (1 << INT_MDIO_CTRL_MIIM_POS) |
111 (1 << INT_MDIO_CTRL_MCDIV_POS);
113 mdio_ld_cmd = nlm_read_nae_reg(nae_base,
114 NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)));
115 if (mdio_ld_cmd & INT_MDIO_CTRL_CMD_LOAD) {
116 nlm_write_nae_reg(nae_base,
117 NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus*4)),
118 (mdio_ld_cmd & ~INT_MDIO_CTRL_CMD_LOAD));
121 /* load data into ctrl data reg */
122 nlm_write_nae_reg(nae_base,
123 NAE_REG(block, intf_type, (INT_MDIO_CTRL_DATA + bus * 4)),
126 nlm_write_nae_reg(nae_base,
127 NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
130 nlm_write_nae_reg(nae_base,
131 NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
132 ctrlval | (1 << INT_MDIO_CTRL_LOAD_POS));
134 /* poll master busy bit until it is not busy */
135 while(nlm_read_nae_reg(nae_base,
136 NAE_REG(block, intf_type, (INT_MDIO_RD_STAT + bus * 4))) &
137 INT_MDIO_STAT_MBSY) {
140 nlm_write_nae_reg(nae_base,
141 NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
148 nlm_int_gmac_mdio_reset(uint64_t nae_base, int bus, int block,
153 val = (7 << INT_MDIO_CTRL_XDIV_POS) |
154 (1 << INT_MDIO_CTRL_MCDIV_POS) |
157 nlm_write_nae_reg(nae_base,
158 NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
159 val | INT_MDIO_CTRL_RST);
161 nlm_write_nae_reg(nae_base,
162 NAE_REG(block, intf_type, (INT_MDIO_CTRL + bus * 4)),
169 * nae_gmac_mdio_read - Read sgmii phy register
172 * bus - bus number, nae has two external gmac bus: 0 and 1
173 * phyaddr - PHY's address
174 * regidx - index of register to read
177 * value read (16 bits), or 0xffffffff if an error occurred.
180 nlm_gmac_mdio_read(uint64_t nae_base, int bus, int block,
181 int intf_type, int phyaddr, int regidx)
183 uint32_t mdio_ld_cmd;
186 mdio_ld_cmd = nlm_read_nae_reg(nae_base, NAE_REG(block, intf_type,
187 (EXT_G0_MDIO_CTRL + bus * 4)));
188 if (mdio_ld_cmd & EXT_G_MDIO_CMD_LCD) {
189 nlm_write_nae_reg(nae_base,
190 NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
191 (mdio_ld_cmd & ~EXT_G_MDIO_CMD_LCD));
192 while(nlm_read_nae_reg(nae_base,
193 NAE_REG(block, intf_type,
194 (EXT_G0_MDIO_RD_STAT + bus * 4))) &
195 EXT_G_MDIO_STAT_MBSY);
198 ctrlval = EXT_G_MDIO_CMD_SP |
199 (phyaddr << EXT_G_MDIO_PHYADDR_POS) |
200 (regidx << EXT_G_MDIO_REGADDR_POS);
201 if (nlm_is_xlp8xx_ax() || nlm_is_xlp8xx_b0() || nlm_is_xlp3xx_ax())
202 ctrlval |= EXT_G_MDIO_DIV;
204 ctrlval |= EXT_G_MDIO_DIV_WITH_HW_DIV64;
206 nlm_write_nae_reg(nae_base,
207 NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
210 nlm_write_nae_reg(nae_base,
211 NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
214 /* poll master busy bit until it is not busy */
215 while(nlm_read_nae_reg(nae_base,
216 NAE_REG(block, intf_type, (EXT_G0_MDIO_RD_STAT + bus * 4))) &
217 EXT_G_MDIO_STAT_MBSY);
219 nlm_write_nae_reg(nae_base,
220 NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
223 /* Read the data back */
224 return nlm_read_nae_reg(nae_base,
225 NAE_REG(block, intf_type, (EXT_G0_MDIO_RD_STAT + bus * 4)));
229 * nae_gmac_mdio_write -Write sgmac mii PHY register.
232 * bus - bus number, nae has two external gmac bus: 0 and 1
233 * phyaddr - PHY to use
234 * regidx - register within the PHY
235 * val - data to write to register
241 nlm_gmac_mdio_write(uint64_t nae_base, int bus, int block,
242 int intf_type, int phyaddr, int regidx, uint16_t val)
244 uint32_t mdio_ld_cmd;
247 mdio_ld_cmd = nlm_read_nae_reg(nae_base, NAE_REG(block, intf_type,
248 (EXT_G0_MDIO_CTRL + bus * 4)));
249 if (mdio_ld_cmd & EXT_G_MDIO_CMD_LCD) {
250 nlm_write_nae_reg(nae_base,
251 NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
252 (mdio_ld_cmd & ~EXT_G_MDIO_CMD_LCD));
253 while(nlm_read_nae_reg(nae_base,
254 NAE_REG(block, intf_type,
255 (EXT_G0_MDIO_RD_STAT + bus * 4))) &
256 EXT_G_MDIO_STAT_MBSY);
259 /* load data into ctrl data reg */
260 nlm_write_nae_reg(nae_base,
261 NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL_DATA+bus*4)),
264 ctrlval = EXT_G_MDIO_CMD_SP |
265 (phyaddr << EXT_G_MDIO_PHYADDR_POS) |
266 (regidx << EXT_G_MDIO_REGADDR_POS);
267 if (nlm_is_xlp8xx_ax() || nlm_is_xlp8xx_b0() || nlm_is_xlp3xx_ax())
268 ctrlval |= EXT_G_MDIO_DIV;
270 ctrlval |= EXT_G_MDIO_DIV_WITH_HW_DIV64;
272 nlm_write_nae_reg(nae_base,
273 NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
276 nlm_write_nae_reg(nae_base,
277 NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
278 ctrlval | EXT_G_MDIO_CMD_LCD);
281 /* poll master busy bit until it is not busy */
282 while(nlm_read_nae_reg(nae_base,
283 NAE_REG(block, intf_type,
284 (EXT_G0_MDIO_RD_STAT + bus * 4))) & EXT_G_MDIO_STAT_MBSY);
286 nlm_write_nae_reg(nae_base,
287 NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
294 * nae_gmac_mdio_reset -Reset sgmii mdio module.
297 * bus - bus number, nae has two external gmac bus: 0 and 1
303 nlm_gmac_mdio_reset(uint64_t nae_base, int bus, int block,
308 ctrlval = nlm_read_nae_reg(nae_base,
309 NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)));
311 if (nlm_is_xlp8xx_ax() || nlm_is_xlp8xx_b0() || nlm_is_xlp3xx_ax())
312 ctrlval |= EXT_G_MDIO_DIV;
314 ctrlval |= EXT_G_MDIO_DIV_WITH_HW_DIV64;
316 nlm_write_nae_reg(nae_base,
317 NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL + bus * 4)),
318 EXT_G_MDIO_MMRST | ctrlval);
319 nlm_write_nae_reg(nae_base,
320 NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL + bus * 4)), ctrlval);
325 * nlm_mdio_reset_all : reset all internal and external MDIO
328 nlm_mdio_reset_all(uint64_t nae_base)
330 /* reset internal MDIO */
331 nlm_int_gmac_mdio_reset(nae_base, 0, BLOCK_7, LANE_CFG);
332 /* reset external MDIO */
333 nlm_gmac_mdio_reset(nae_base, 0, BLOCK_7, LANE_CFG);
334 nlm_gmac_mdio_reset(nae_base, 1, BLOCK_7, LANE_CFG);