1 /*
2  * The setup file for ethernet related hardware on PMC-Sierra MSP processors.
3  *
4  * Copyright 2010 PMC-Sierra, Inc.
5  *
6  *  This program is free software; you can redistribute  it and/or modify it
7  *  under  the terms of  the GNU General  Public License as published by the
8  *  Free Software Foundation;  either version 2 of the  License, or (at your
9  *  option) any later version.
10  *
11  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
12  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
13  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
14  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
15  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
17  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
18  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
19  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
20  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21  *
22  *  You should have received a copy of the  GNU General Public License along
23  *  with this program; if not, write  to the Free Software Foundation, Inc.,
24  *  675 Mass Ave, Cambridge, MA 02139, USA.
25  */
26 
27 #include <linux/init.h>
28 #include <linux/kernel.h>
29 #include <linux/ioport.h>
30 #include <linux/platform_device.h>
31 #include <linux/delay.h>
32 #include <msp_regs.h>
33 #include <msp_int.h>
34 #include <msp_gpio_macros.h>
35 
36 
37 #define MSP_ETHERNET_GPIO0	14
38 #define MSP_ETHERNET_GPIO1	15
39 #define MSP_ETHERNET_GPIO2	16
40 
41 #ifdef CONFIG_MSP_HAS_TSMAC
42 #define MSP_TSMAC_SIZE	0x10020
43 #define MSP_TSMAC_ID	"pmc_tsmac"
44 
45 static struct resource msp_tsmac0_resources[] = {
46 	[0] = {
47 		.start	= MSP_MAC0_BASE,
48 		.end	= MSP_MAC0_BASE + MSP_TSMAC_SIZE - 1,
49 		.flags	= IORESOURCE_MEM,
50 	},
51 	[1] = {
52 		.start	= MSP_INT_MAC0,
53 		.end	= MSP_INT_MAC0,
54 		.flags	= IORESOURCE_IRQ,
55 	},
56 };
57 
58 static struct resource msp_tsmac1_resources[] = {
59 	[0] = {
60 		.start	= MSP_MAC1_BASE,
61 		.end	= MSP_MAC1_BASE + MSP_TSMAC_SIZE - 1,
62 		.flags	= IORESOURCE_MEM,
63 	},
64 	[1] = {
65 		.start	= MSP_INT_MAC1,
66 		.end	= MSP_INT_MAC1,
67 		.flags	= IORESOURCE_IRQ,
68 	},
69 };
70 static struct resource msp_tsmac2_resources[] = {
71 	[0] = {
72 		.start	= MSP_MAC2_BASE,
73 		.end	= MSP_MAC2_BASE + MSP_TSMAC_SIZE - 1,
74 		.flags	= IORESOURCE_MEM,
75 	},
76 	[1] = {
77 		.start	= MSP_INT_SAR,
78 		.end	= MSP_INT_SAR,
79 		.flags	= IORESOURCE_IRQ,
80 	},
81 };
82 
83 
84 static struct platform_device tsmac_device[] = {
85 	[0] = {
86 		.name	= MSP_TSMAC_ID,
87 		.id	= 0,
88 		.num_resources = ARRAY_SIZE(msp_tsmac0_resources),
89 		.resource = msp_tsmac0_resources,
90 	},
91 	[1] = {
92 		.name	= MSP_TSMAC_ID,
93 		.id	= 1,
94 		.num_resources = ARRAY_SIZE(msp_tsmac1_resources),
95 		.resource = msp_tsmac1_resources,
96 	},
97 	[2] = {
98 		.name	= MSP_TSMAC_ID,
99 		.id	= 2,
100 		.num_resources = ARRAY_SIZE(msp_tsmac2_resources),
101 		.resource = msp_tsmac2_resources,
102 	},
103 };
104 #define msp_eth_devs	tsmac_device
105 
106 #else
107 /* If it is not TSMAC assume MSP_ETH (100Mbps) */
108 #define MSP_ETH_ID	"pmc_mspeth"
109 #define MSP_ETH_SIZE	0xE0
110 static struct resource msp_eth0_resources[] = {
111 	[0] = {
112 		.start	= MSP_MAC0_BASE,
113 		.end	= MSP_MAC0_BASE + MSP_ETH_SIZE - 1,
114 		.flags	= IORESOURCE_MEM,
115 	},
116 	[1] = {
117 		.start	= MSP_INT_MAC0,
118 		.end	= MSP_INT_MAC0,
119 		.flags	= IORESOURCE_IRQ,
120 	},
121 };
122 
123 static struct resource msp_eth1_resources[] = {
124 	[0] = {
125 		.start	= MSP_MAC1_BASE,
126 		.end	= MSP_MAC1_BASE + MSP_ETH_SIZE - 1,
127 		.flags	= IORESOURCE_MEM,
128 	},
129 	[1] = {
130 		.start	= MSP_INT_MAC1,
131 		.end	= MSP_INT_MAC1,
132 		.flags	= IORESOURCE_IRQ,
133 	},
134 };
135 
136 
137 
138 static struct platform_device mspeth_device[] = {
139 	[0] = {
140 		.name	= MSP_ETH_ID,
141 		.id	= 0,
142 		.num_resources = ARRAY_SIZE(msp_eth0_resources),
143 		.resource = msp_eth0_resources,
144 	},
145 	[1] = {
146 		.name	= MSP_ETH_ID,
147 		.id	= 1,
148 		.num_resources = ARRAY_SIZE(msp_eth1_resources),
149 		.resource = msp_eth1_resources,
150 	},
151 
152 };
153 #define msp_eth_devs	mspeth_device
154 
155 #endif
msp_eth_setup(void)156 int __init msp_eth_setup(void)
157 {
158 	int i, ret = 0;
159 
160 	/* Configure the GPIO and take the ethernet PHY out of reset */
161 	msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO0);
162 	msp_gpio_pin_hi(MSP_ETHERNET_GPIO0);
163 
164 #ifdef CONFIG_MSP_HAS_TSMAC
165 	/* 3 phys on boards with TSMAC */
166 	msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO1);
167 	msp_gpio_pin_hi(MSP_ETHERNET_GPIO1);
168 
169 	msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO2);
170 	msp_gpio_pin_hi(MSP_ETHERNET_GPIO2);
171 #endif
172 	for (i = 0; i < ARRAY_SIZE(msp_eth_devs); i++) {
173 		ret = platform_device_register(&msp_eth_devs[i]);
174 		printk(KERN_INFO "device: %d, return value = %d\n", i, ret);
175 		if (ret) {
176 			platform_device_unregister(&msp_eth_devs[i]);
177 			break;
178 		}
179 	}
180 
181 	if (ret)
182 		printk(KERN_WARNING "Could not initialize "
183 						"MSPETH device structures.\n");
184 
185 	return ret;
186 }
187 subsys_initcall(msp_eth_setup);
188