2 * Copyright 2008-2013 Freescale Semiconductor Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 * * Neither the name of Freescale Semiconductor nor the
12 * names of its contributors may be used to endorse or promote products
13 * derived from this software without specific prior written permission.
16 * ALTERNATIVELY, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL") as published by the Free Software
18 * Foundation, either version 2 of that License or (at your option) any
21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "fsl_fman_memac_mii_acc.h"
36 static void write_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
37 uint8_t phy_addr, uint8_t reg, uint16_t data)
41 tmp_reg = ioread32be(&mii_regs->mdio_cfg);
42 /* Leave only MDIO_CLK_DIV bits set on */
43 tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
44 /* Set maximum MDIO_HOLD value to allow phy to see
45 change of data signal */
46 tmp_reg |= MDIO_CFG_HOLD_MASK;
47 /* Add 10G interface mode */
48 tmp_reg |= MDIO_CFG_ENC45;
49 iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
51 /* Wait for command completion */
52 while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
55 /* Specify phy and register to be accessed */
56 iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
57 iowrite32be(reg, &mii_regs->mdio_addr);
60 while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
64 iowrite32be(data, &mii_regs->mdio_data);
67 /* Wait for write transaction end */
68 while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
72 static uint32_t read_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
73 uint8_t phy_addr, uint8_t reg, uint16_t *data)
77 tmp_reg = ioread32be(&mii_regs->mdio_cfg);
78 /* Leave only MDIO_CLK_DIV bits set on */
79 tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
80 /* Set maximum MDIO_HOLD value to allow phy to see
81 change of data signal */
82 tmp_reg |= MDIO_CFG_HOLD_MASK;
83 /* Add 10G interface mode */
84 tmp_reg |= MDIO_CFG_ENC45;
85 iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
87 /* Wait for command completion */
88 while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
91 /* Specify phy and register to be accessed */
92 iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
93 iowrite32be(reg, &mii_regs->mdio_addr);
96 while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
101 tmp_reg |= MDIO_CTL_READ;
102 iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
105 /* Wait for data to be available */
106 while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
109 *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
111 /* Check if there was an error */
112 return ioread32be(&mii_regs->mdio_cfg);
115 static void write_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
116 uint8_t phy_addr, uint8_t reg, uint16_t data)
120 /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
121 tmp_reg = ioread32be(&mii_regs->mdio_cfg);
122 tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
123 iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
125 /* Wait for command completion */
126 while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
129 /* Write transaction */
130 tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
132 iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
134 while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
137 iowrite32be(data, &mii_regs->mdio_data);
141 /* Wait for write transaction to end */
142 while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
146 static uint32_t read_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
147 uint8_t phy_addr, uint8_t reg, uint16_t *data)
151 /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
152 tmp_reg = ioread32be(&mii_regs->mdio_cfg);
153 tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
154 iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
156 /* Wait for command completion */
157 while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
160 /* Read transaction */
161 tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
163 tmp_reg |= MDIO_CTL_READ;
164 iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
166 while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
169 /* Wait for data to be available */
170 while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
173 *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
176 return ioread32be(&mii_regs->mdio_cfg);
179 /*****************************************************************************/
180 int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
181 uint8_t phy_addr, uint8_t reg, uint16_t data,
182 enum enet_speed enet_speed)
184 /* Figure out interface type - 10G vs 1G.
185 In 10G interface both phy_addr and devAddr present. */
186 if (enet_speed == E_ENET_SPEED_10000)
187 write_phy_reg_10g(mii_regs, phy_addr, reg, data);
189 write_phy_reg_1g(mii_regs, phy_addr, reg, data);
194 /*****************************************************************************/
195 int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
196 uint8_t phy_addr, uint8_t reg, uint16_t *data,
197 enum enet_speed enet_speed)
200 /* Figure out interface type - 10G vs 1G.
201 In 10G interface both phy_addr and devAddr present. */
202 if (enet_speed == E_ENET_SPEED_10000)
203 ans = read_phy_reg_10g(mii_regs, phy_addr, reg, data);
205 ans = read_phy_reg_1g(mii_regs, phy_addr, reg, data);
207 if (ans & MDIO_CFG_READ_ERR)
212 /* ......................................................................... */