aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mx3/mach-mx31_3ds.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-07-31 09:20:16 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-07-31 09:20:16 -0400
commit7b70c4275f28702b76b273c8534c38f8313812e9 (patch)
tree1df2229ca02466bd1adda814ac5c37aa0a597db1 /arch/arm/mach-mx3/mach-mx31_3ds.c
parentceb0885d3b01bb2e2f18765770e212914f2864be (diff)
parenta20df564d15bd28e3df24e1c65b885bd74d23f17 (diff)
Merge branch 'devel-stable' into devel
Conflicts: arch/arm/kernel/entry-armv.S arch/arm/kernel/setup.c arch/arm/mm/init.c
Diffstat (limited to 'arch/arm/mach-mx3/mach-mx31_3ds.c')
-rw-r--r--arch/arm/mach-mx3/mach-mx31_3ds.c256
1 files changed, 68 insertions, 188 deletions
diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c
index 58e57291b79d..6fe69e124d30 100644
--- a/arch/arm/mach-mx3/mach-mx31_3ds.c
+++ b/arch/arm/mach-mx3/mach-mx31_3ds.c
@@ -10,10 +10,6 @@
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */ 13 */
18 14
19#include <linux/delay.h> 15#include <linux/delay.h>
@@ -22,7 +18,6 @@
22#include <linux/clk.h> 18#include <linux/clk.h>
23#include <linux/irq.h> 19#include <linux/irq.h>
24#include <linux/gpio.h> 20#include <linux/gpio.h>
25#include <linux/smsc911x.h>
26#include <linux/platform_device.h> 21#include <linux/platform_device.h>
27#include <linux/mfd/mc13783.h> 22#include <linux/mfd/mc13783.h>
28#include <linux/spi/spi.h> 23#include <linux/spi/spi.h>
@@ -37,19 +32,47 @@
37#include <asm/memory.h> 32#include <asm/memory.h>
38#include <asm/mach/map.h> 33#include <asm/mach/map.h>
39#include <mach/common.h> 34#include <mach/common.h>
40#include <mach/board-mx31_3ds.h>
41#include <mach/imx-uart.h>
42#include <mach/iomux-mx3.h> 35#include <mach/iomux-mx3.h>
43#include <mach/mxc_nand.h> 36#include <mach/3ds_debugboard.h>
44#include <mach/spi.h> 37
38#include "devices-imx31.h"
45#include "devices.h" 39#include "devices.h"
46 40
47/*! 41/* Definitions for components on the Debug board */
48 * @file mx31_3ds.c 42
49 * 43/* Base address of CPLD controller on the Debug board */
50 * @brief This file contains the board-specific initialization routines. 44#define DEBUG_BASE_ADDRESS CS5_IO_ADDRESS(MX3x_CS5_BASE_ADDR)
51 * 45
52 * @ingroup System 46/* LAN9217 ethernet base address */
47#define LAN9217_BASE_ADDR MX3x_CS5_BASE_ADDR
48
49/* CPLD config and interrupt base address */
50#define CPLD_ADDR (DEBUG_BASE_ADDRESS + 0x20000)
51
52/* status, interrupt */
53#define CPLD_INT_STATUS_REG (CPLD_ADDR + 0x10)
54#define CPLD_INT_MASK_REG (CPLD_ADDR + 0x38)
55#define CPLD_INT_RESET_REG (CPLD_ADDR + 0x20)
56/* magic word for debug CPLD */
57#define CPLD_MAGIC_NUMBER1_REG (CPLD_ADDR + 0x40)
58#define CPLD_MAGIC_NUMBER2_REG (CPLD_ADDR + 0x48)
59/* CPLD code version */
60#define CPLD_CODE_VER_REG (CPLD_ADDR + 0x50)
61/* magic word for debug CPLD */
62#define CPLD_MAGIC_NUMBER3_REG (CPLD_ADDR + 0x58)
63
64/* CPLD IRQ line for external uart, external ethernet etc */
65#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
66
67#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
68#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE)
69
70#define EXPIO_INT_ENET (MXC_EXP_IO_BASE + 0)
71
72#define MXC_MAX_EXP_IO_LINES 16
73
74/*
75 * This file contains the board-specific initialization routines.
53 */ 76 */
54 77
55static int mx31_3ds_pins[] = { 78static int mx31_3ds_pins[] = {
@@ -145,7 +168,7 @@ static int spi1_internal_chipselect[] = {
145 MXC_SPI_CS(2), 168 MXC_SPI_CS(2),
146}; 169};
147 170
148static struct spi_imx_master spi1_pdata = { 171static const struct spi_imx_master spi1_pdata __initconst = {
149 .chipselect = spi1_internal_chipselect, 172 .chipselect = spi1_internal_chipselect,
150 .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect), 173 .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect),
151}; 174};
@@ -165,7 +188,8 @@ static struct spi_board_info mx31_3ds_spi_devs[] __initdata = {
165/* 188/*
166 * NAND Flash 189 * NAND Flash
167 */ 190 */
168static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = { 191static const struct mxc_nand_platform_data
192mx31_3ds_nand_board_info __initconst = {
169 .width = 1, 193 .width = 1,
170 .hw_ecc = 1, 194 .hw_ecc = 1,
171#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT 195#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT
@@ -182,8 +206,10 @@ static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = {
182 206
183#define USBOTG_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_PWR) 207#define USBOTG_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_PWR)
184 208
185static void mx31_3ds_usbotg_init(void) 209static int mx31_3ds_usbotg_init(void)
186{ 210{
211 int err;
212
187 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG); 213 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
188 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG); 214 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
189 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG); 215 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
@@ -197,10 +223,25 @@ static void mx31_3ds_usbotg_init(void)
197 mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG); 223 mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
198 mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG); 224 mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
199 225
200 gpio_request(USBOTG_RST_B, "otgusb-reset"); 226 err = gpio_request(USBOTG_RST_B, "otgusb-reset");
201 gpio_direction_output(USBOTG_RST_B, 0); 227 if (err) {
228 pr_err("Failed to request the USB OTG reset gpio\n");
229 return err;
230 }
231
232 err = gpio_direction_output(USBOTG_RST_B, 0);
233 if (err) {
234 pr_err("Failed to drive the USB OTG reset gpio\n");
235 goto usbotg_free_reset;
236 }
237
202 mdelay(1); 238 mdelay(1);
203 gpio_set_value(USBOTG_RST_B, 1); 239 gpio_set_value(USBOTG_RST_B, 1);
240 return 0;
241
242usbotg_free_reset:
243 gpio_free(USBOTG_RST_B);
244 return err;
204} 245}
205 246
206static struct fsl_usb2_platform_data usbotg_pdata = { 247static struct fsl_usb2_platform_data usbotg_pdata = {
@@ -208,178 +249,16 @@ static struct fsl_usb2_platform_data usbotg_pdata = {
208 .phy_mode = FSL_USB2_PHY_ULPI, 249 .phy_mode = FSL_USB2_PHY_ULPI,
209}; 250};
210 251
211static struct imxuart_platform_data uart_pdata = { 252static const struct imxuart_platform_data uart_pdata __initconst = {
212 .flags = IMXUART_HAVE_RTSCTS, 253 .flags = IMXUART_HAVE_RTSCTS,
213}; 254};
214 255
215/* 256/*
216 * Support for the SMSC9217 on the Debug board.
217 */
218
219static struct smsc911x_platform_config smsc911x_config = {
220 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
221 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
222 .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
223 .phy_interface = PHY_INTERFACE_MODE_MII,
224};
225
226static struct resource smsc911x_resources[] = {
227 {
228 .start = LAN9217_BASE_ADDR,
229 .end = LAN9217_BASE_ADDR + 0xff,
230 .flags = IORESOURCE_MEM,
231 }, {
232 .start = EXPIO_INT_ENET,
233 .end = EXPIO_INT_ENET,
234 .flags = IORESOURCE_IRQ,
235 },
236};
237
238static struct platform_device smsc911x_device = {
239 .name = "smsc911x",
240 .id = -1,
241 .num_resources = ARRAY_SIZE(smsc911x_resources),
242 .resource = smsc911x_resources,
243 .dev = {
244 .platform_data = &smsc911x_config,
245 },
246};
247
248/*
249 * Routines for the CPLD on the debug board. It contains a CPLD handling
250 * LEDs, switches, interrupts for Ethernet.
251 */
252
253static void mx31_3ds_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
254{
255 uint32_t imr_val;
256 uint32_t int_valid;
257 uint32_t expio_irq;
258
259 imr_val = __raw_readw(CPLD_INT_MASK_REG);
260 int_valid = __raw_readw(CPLD_INT_STATUS_REG) & ~imr_val;
261
262 expio_irq = MXC_EXP_IO_BASE;
263 for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
264 if ((int_valid & 1) == 0)
265 continue;
266 generic_handle_irq(expio_irq);
267 }
268}
269
270/*
271 * Disable an expio pin's interrupt by setting the bit in the imr.
272 * @param irq an expio virtual irq number
273 */
274static void expio_mask_irq(uint32_t irq)
275{
276 uint16_t reg;
277 uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
278
279 /* mask the interrupt */
280 reg = __raw_readw(CPLD_INT_MASK_REG);
281 reg |= 1 << expio;
282 __raw_writew(reg, CPLD_INT_MASK_REG);
283}
284
285/*
286 * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
287 * @param irq an expanded io virtual irq number
288 */
289static void expio_ack_irq(uint32_t irq)
290{
291 uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
292
293 /* clear the interrupt status */
294 __raw_writew(1 << expio, CPLD_INT_RESET_REG);
295 __raw_writew(0, CPLD_INT_RESET_REG);
296 /* mask the interrupt */
297 expio_mask_irq(irq);
298}
299
300/*
301 * Enable a expio pin's interrupt by clearing the bit in the imr.
302 * @param irq a expio virtual irq number
303 */
304static void expio_unmask_irq(uint32_t irq)
305{
306 uint16_t reg;
307 uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
308
309 /* unmask the interrupt */
310 reg = __raw_readw(CPLD_INT_MASK_REG);
311 reg &= ~(1 << expio);
312 __raw_writew(reg, CPLD_INT_MASK_REG);
313}
314
315static struct irq_chip expio_irq_chip = {
316 .ack = expio_ack_irq,
317 .mask = expio_mask_irq,
318 .unmask = expio_unmask_irq,
319};
320
321static int __init mx31_3ds_init_expio(void)
322{
323 int i;
324 int ret;
325
326 /* Check if there's a debug board connected */
327 if ((__raw_readw(CPLD_MAGIC_NUMBER1_REG) != 0xAAAA) ||
328 (__raw_readw(CPLD_MAGIC_NUMBER2_REG) != 0x5555) ||
329 (__raw_readw(CPLD_MAGIC_NUMBER3_REG) != 0xCAFE)) {
330 /* No Debug board found */
331 return -ENODEV;
332 }
333
334 pr_info("i.MX31 3DS Debug board detected, rev = 0x%04X\n",
335 __raw_readw(CPLD_CODE_VER_REG));
336
337 /*
338 * Configure INT line as GPIO input
339 */
340 ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "sms9217-irq");
341 if (ret)
342 pr_warning("could not get LAN irq gpio\n");
343 else
344 gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1));
345
346 /* Disable the interrupts and clear the status */
347 __raw_writew(0, CPLD_INT_MASK_REG);
348 __raw_writew(0xFFFF, CPLD_INT_RESET_REG);
349 __raw_writew(0, CPLD_INT_RESET_REG);
350 __raw_writew(0x1F, CPLD_INT_MASK_REG);
351 for (i = MXC_EXP_IO_BASE;
352 i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
353 i++) {
354 set_irq_chip(i, &expio_irq_chip);
355 set_irq_handler(i, handle_level_irq);
356 set_irq_flags(i, IRQF_VALID);
357 }
358 set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW);
359 set_irq_chained_handler(EXPIO_PARENT_INT, mx31_3ds_expio_irq_handler);
360
361 return 0;
362}
363
364/*
365 * This structure defines the MX31 memory map.
366 */
367static struct map_desc mx31_3ds_io_desc[] __initdata = {
368 {
369 .virtual = MX31_CS5_BASE_ADDR_VIRT,
370 .pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR),
371 .length = MX31_CS5_SIZE,
372 .type = MT_DEVICE,
373 },
374};
375
376/*
377 * Set up static virtual mappings. 257 * Set up static virtual mappings.
378 */ 258 */
379static void __init mx31_3ds_map_io(void) 259static void __init mx31_3ds_map_io(void)
380{ 260{
381 mx31_map_io(); 261 mx31_map_io();
382 iotable_init(mx31_3ds_io_desc, ARRAY_SIZE(mx31_3ds_io_desc));
383} 262}
384 263
385/*! 264/*!
@@ -390,10 +269,10 @@ static void __init mxc_board_init(void)
390 mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins), 269 mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
391 "mx31_3ds"); 270 "mx31_3ds");
392 271
393 mxc_register_device(&mxc_uart_device0, &uart_pdata); 272 imx31_add_imx_uart0(&uart_pdata);
394 mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata); 273 imx31_add_mxc_nand(&mx31_3ds_nand_board_info);
395 274
396 mxc_register_device(&mxc_spi_device1, &spi1_pdata); 275 imx31_add_spi_imx0(&spi1_pdata);
397 spi_register_board_info(mx31_3ds_spi_devs, 276 spi_register_board_info(mx31_3ds_spi_devs,
398 ARRAY_SIZE(mx31_3ds_spi_devs)); 277 ARRAY_SIZE(mx31_3ds_spi_devs));
399 278
@@ -402,8 +281,9 @@ static void __init mxc_board_init(void)
402 mx31_3ds_usbotg_init(); 281 mx31_3ds_usbotg_init();
403 mxc_register_device(&mxc_otg_udc_device, &usbotg_pdata); 282 mxc_register_device(&mxc_otg_udc_device, &usbotg_pdata);
404 283
405 if (!mx31_3ds_init_expio()) 284 if (!mxc_expio_init(CS5_BASE_ADDR, EXPIO_PARENT_INT))
406 platform_device_register(&smsc911x_device); 285 printk(KERN_WARNING "Init of the debugboard failed, all "
286 "devices on the board are unusable.\n");
407} 287}
408 288
409static void __init mx31_3ds_timer_init(void) 289static void __init mx31_3ds_timer_init(void)