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