1 /*
2 * drivers/net/titan_mdio.c - Driver for Titan ethernet ports
3 *
4 * Copyright (C) 2003 PMC-Sierra Inc.
5 * Author : Manish Lachwani (lachwani@pmc-sierra.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * Management Data IO (MDIO) driver for the Titan GMII. Interacts with the Marvel PHY
22 * on the Titan. No support for the TBI as yet.
23 *
24 */
25
26 #include "titan_mdio.h"
27
28 #define MDIO_DEBUG
29
30 /*
31 * Local constants
32 */
33 #define MAX_CLKA 1023
34 #define MAX_PHY_DEV 31
35 #define MAX_PHY_REG 31
36 #define WRITEADDRS_OPCODE 0x0
37 #define READ_OPCODE 0x2
38 #define WRITE_OPCODE 0x1
39 #define MAX_MDIO_POLL 100
40
41 /*
42 * Titan MDIO and SCMB registers
43 */
44 #define TITAN_GE_SCMB_CONTROL 0x01c0 /* SCMB Control */
45 #define TITAN_GE_SCMB_CLKA 0x01c4 /* SCMB Clock A */
46 #define TITAN_GE_MDIO_COMMAND 0x01d0 /* MDIO Command */
47 #define TITAN_GE_MDIO_DEVICE_PORT_ADDRESS 0x01d4 /* MDIO Device and Port addrs */
48 #define TITAN_GE_MDIO_DATA 0x01d8 /* MDIO Data */
49 #define TITAN_GE_MDIO_INTERRUPTS 0x01dC /* MDIO Interrupts */
50
51 /*
52 * Function to poll the MDIO
53 */
titan_ge_mdio_poll()54 static int titan_ge_mdio_poll()
55 {
56 int i, val;
57
58 for (i = 0; i < MAX_MDIO_POLL; i++) {
59 val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
60
61 if (!(val & 0x8000))
62 return TITAN_GE_MDIO_GOOD;
63 }
64
65 return TITAN_GE_MDIO_ERROR;
66 }
67
68
69 /*
70 * Initialize and configure the MDIO
71 */
titan_ge_mdio_setup(titan_ge_mdio_config * titan_mdio)72 int titan_ge_mdio_setup(titan_ge_mdio_config *titan_mdio)
73 {
74 unsigned long val;
75
76 /* Reset the SCMB and program into MDIO mode*/
77 TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CONTROL, 0x9000);
78 TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CONTROL, 0x1000);
79
80 /* CLK A */
81 val = TITAN_GE_MDIO_READ(TITAN_GE_SCMB_CLKA);
82 val = ( (val & ~(0x03ff)) | (titan_mdio->clka & 0x03ff));
83 TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CLKA, val);
84
85 /* Preamble Suppresion */
86 val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
87 val = ( (val & ~(0x0001)) | (titan_mdio->mdio_spre & 0x0001));
88 TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
89
90 /* MDIO mode */
91 val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
92 val = ( (val & ~(0x4000)) | (titan_mdio->mdio_mode & 0x4000));
93 TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
94
95 return TITAN_GE_MDIO_GOOD;
96 }
97
98 /*
99 * Set the PHY address in indirect mode
100 */
titan_ge_mdio_inaddrs(int dev_addr,int reg_addr)101 int titan_ge_mdio_inaddrs(int dev_addr, int reg_addr)
102 {
103 volatile unsigned long val;
104
105 /* Setup the PHY device */
106 val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
107 val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
108 val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
109 TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
110
111 /* Write the new address */
112 val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
113 val = ( (val & ~(0x0300)) | ( (WRITEADDRS_OPCODE << 8) & 0x0300));
114 TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
115
116 return TITAN_GE_MDIO_GOOD;
117 }
118
119 /*
120 * Read the MDIO register. This is what the individual parametes mean:
121 *
122 * dev_addr : PHY ID
123 * reg_addr : register offset
124 *
125 * See the spec for the Titan MAC. We operate in the Direct Mode.
126 */
127
128 #define MAX_RETRIES 2
129
titan_ge_mdio_read(int dev_addr,int reg_addr,unsigned int * pdata)130 int titan_ge_mdio_read(int dev_addr, int reg_addr, unsigned int *pdata)
131 {
132 volatile unsigned long val;
133 int retries = 0;
134
135 /* Setup the PHY device */
136
137 again:
138 val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
139 val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
140 val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
141 val |= 0x4000;
142 TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
143
144 udelay(30);
145
146 /* Issue the read command */
147 val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
148 val = ( (val & ~(0x0300)) | ( (READ_OPCODE << 8) & 0x0300));
149 TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
150
151 udelay(30);
152
153 if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
154 return TITAN_GE_MDIO_ERROR;
155
156 *pdata = (unsigned int)TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DATA);
157 val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_INTERRUPTS);
158
159 udelay(30);
160
161 if (val & 0x2) {
162 if (retries == MAX_RETRIES)
163 return TITAN_GE_MDIO_ERROR;
164 else {
165 retries++;
166 goto again;
167 }
168 }
169
170 return TITAN_GE_MDIO_GOOD;
171 }
172
173 /*
174 * Write to the MDIO register
175 *
176 * dev_addr : PHY ID
177 * reg_addr : register that needs to be written to
178 *
179 */
titan_ge_mdio_write(int dev_addr,int reg_addr,unsigned int data)180 int titan_ge_mdio_write(int dev_addr, int reg_addr, unsigned int data)
181 {
182 volatile unsigned long val;
183
184 if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
185 return TITAN_GE_MDIO_ERROR;
186
187 /* Setup the PHY device */
188 val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
189 val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
190 val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
191 val |= 0x4000;
192 TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
193
194 udelay(30);
195
196 /* Setup the data to write */
197 TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DATA, data);
198
199 udelay(30);
200
201 /* Issue the write command */
202 val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
203 val = ( (val & ~(0x0300)) | ( (WRITE_OPCODE << 8) & 0x0300));
204 TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
205
206 udelay(30);
207
208 if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
209 return TITAN_GE_MDIO_ERROR;
210
211 val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_INTERRUPTS);
212 if (val & 0x2)
213 return TITAN_GE_MDIO_ERROR;
214
215 return TITAN_GE_MDIO_GOOD;
216 }
217
218