aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLothar Waßmann <LW@KARO-electronics.de>2010-12-10 10:22:47 -0500
committerSascha Hauer <s.hauer@pengutronix.de>2011-03-07 13:29:07 -0500
commit1cb59f9f79f4ed89845f6f8bebf0273442e1ccd5 (patch)
treed9455a01c8ec8a8218284468c117575930117f21 /arch/arm
parentccb24d50b7ee242a2bf2dd208193f7335a3a0d7d (diff)
ARM: mxs: Initial support for Ka-Ro TX28
Based on code created by Lothar Waßmann, Sascha Hauer, Wolfram Sang and me. Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-mxs/Kconfig12
-rw-r--r--arch/arm/mach-mxs/Makefile2
-rw-r--r--arch/arm/mach-mxs/include/mach/mxs.h9
-rw-r--r--arch/arm/mach-mxs/include/mach/uncompress.h1
-rw-r--r--arch/arm/mach-mxs/mach-tx28.c173
-rw-r--r--arch/arm/mach-mxs/module-tx28.c131
-rw-r--r--arch/arm/mach-mxs/module-tx28.h9
7 files changed, 335 insertions, 2 deletions
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index 836cc81a63a1..895d06604e15 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -39,4 +39,16 @@ config MACH_MX28EVK
39 Include support for MX28EVK platform. This includes specific 39 Include support for MX28EVK platform. This includes specific
40 configurations for the board and its peripherals. 40 configurations for the board and its peripherals.
41 41
42config MODULE_TX28
43 bool
44 select SOC_IMX28
45 select MXS_HAVE_AMBA_DUART
46 select MXS_HAVE_PLATFORM_AUART
47 select MXS_HAVE_PLATFORM_FEC
48 select MXS_HAVE_PLATFORM_MXS_PWM
49
50config MACH_TX28
51 bool "Ka-Ro TX28 module"
52 select MODULE_TX28
53
42endif 54endif
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 6b26f02e72a2..2f1f6141ca71 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -9,5 +9,7 @@ obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
9 9
10obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o 10obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
11obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o 11obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
12obj-$(CONFIG_MODULE_TX28) += module-tx28.o
13obj-$(CONFIG_MACH_TX28) += mach-tx28.o
12 14
13obj-y += devices/ 15obj-y += devices/
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
index f186c08c2911..35a89dd27242 100644
--- a/arch/arm/mach-mxs/include/mach/mxs.h
+++ b/arch/arm/mach-mxs/include/mach/mxs.h
@@ -28,8 +28,13 @@
28/* 28/*
29 * MXS CPU types 29 * MXS CPU types
30 */ 30 */
31#define cpu_is_mx23() (machine_is_mx23evk()) 31#define cpu_is_mx23() ( \
32#define cpu_is_mx28() (machine_is_mx28evk()) 32 machine_is_mx23evk() || \
33 0)
34#define cpu_is_mx28() ( \
35 machine_is_mx28evk() || \
36 machine_is_tx28() || \
37 0)
33 38
34/* 39/*
35 * IO addresses common to MXS-based 40 * IO addresses common to MXS-based
diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
index a005e76f34f9..f12a1732d8b8 100644
--- a/arch/arm/mach-mxs/include/mach/uncompress.h
+++ b/arch/arm/mach-mxs/include/mach/uncompress.h
@@ -63,6 +63,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id)
63 mxs_duart_base = MX23_DUART_BASE_ADDR; 63 mxs_duart_base = MX23_DUART_BASE_ADDR;
64 break; 64 break;
65 case MACH_TYPE_MX28EVK: 65 case MACH_TYPE_MX28EVK:
66 case MACH_TYPE_TX28:
66 mxs_duart_base = MX28_DUART_BASE_ADDR; 67 mxs_duart_base = MX28_DUART_BASE_ADDR;
67 break; 68 break;
68 default: 69 default:
diff --git a/arch/arm/mach-mxs/mach-tx28.c b/arch/arm/mach-mxs/mach-tx28.c
new file mode 100644
index 000000000000..b609b84784d0
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-tx28.c
@@ -0,0 +1,173 @@
1/*
2 * Copyright (C) 2010 <LW@KARO-electronics.de>
3 *
4 * based on: mach-mx28_evk.c
5 * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
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 * version 2 as published by the Free Software Foundation
10 */
11#include <linux/kernel.h>
12#include <linux/gpio.h>
13#include <linux/leds.h>
14#include <linux/platform_device.h>
15#include <linux/spi/spi.h>
16#include <linux/spi/spi_gpio.h>
17
18#include <asm/mach/arch.h>
19#include <asm/mach/time.h>
20
21#include <mach/common.h>
22#include <mach/iomux-mx28.h>
23
24#include "devices-mx28.h"
25#include "module-tx28.h"
26
27#define TX28_STK5_GPIO_LED MXS_GPIO_NR(4, 10)
28
29static const iomux_cfg_t tx28_stk5v3_pads[] __initconst = {
30 /* LED */
31 MX28_PAD_ENET0_RXD3__GPIO_4_10 |
32 MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL,
33
34 /* framebuffer */
35#define LCD_MODE (MXS_PAD_3V3 | MXS_PAD_4MA)
36 MX28_PAD_LCD_D00__LCD_D0 | LCD_MODE,
37 MX28_PAD_LCD_D01__LCD_D1 | LCD_MODE,
38 MX28_PAD_LCD_D02__LCD_D2 | LCD_MODE,
39 MX28_PAD_LCD_D03__LCD_D3 | LCD_MODE,
40 MX28_PAD_LCD_D04__LCD_D4 | LCD_MODE,
41 MX28_PAD_LCD_D05__LCD_D5 | LCD_MODE,
42 MX28_PAD_LCD_D06__LCD_D6 | LCD_MODE,
43 MX28_PAD_LCD_D07__LCD_D7 | LCD_MODE,
44 MX28_PAD_LCD_D08__LCD_D8 | LCD_MODE,
45 MX28_PAD_LCD_D09__LCD_D9 | LCD_MODE,
46 MX28_PAD_LCD_D10__LCD_D10 | LCD_MODE,
47 MX28_PAD_LCD_D11__LCD_D11 | LCD_MODE,
48 MX28_PAD_LCD_D12__LCD_D12 | LCD_MODE,
49 MX28_PAD_LCD_D13__LCD_D13 | LCD_MODE,
50 MX28_PAD_LCD_D14__LCD_D14 | LCD_MODE,
51 MX28_PAD_LCD_D15__LCD_D15 | LCD_MODE,
52 MX28_PAD_LCD_D16__LCD_D16 | LCD_MODE,
53 MX28_PAD_LCD_D17__LCD_D17 | LCD_MODE,
54 MX28_PAD_LCD_D18__LCD_D18 | LCD_MODE,
55 MX28_PAD_LCD_D19__LCD_D19 | LCD_MODE,
56 MX28_PAD_LCD_D20__LCD_D20 | LCD_MODE,
57 MX28_PAD_LCD_D21__LCD_D21 | LCD_MODE,
58 MX28_PAD_LCD_D22__LCD_D22 | LCD_MODE,
59 MX28_PAD_LCD_D23__LCD_D23 | LCD_MODE,
60 MX28_PAD_LCD_RD_E__LCD_VSYNC | LCD_MODE,
61 MX28_PAD_LCD_WR_RWN__LCD_HSYNC | LCD_MODE,
62 MX28_PAD_LCD_RS__LCD_DOTCLK | LCD_MODE,
63 MX28_PAD_LCD_CS__LCD_CS | LCD_MODE,
64 MX28_PAD_LCD_VSYNC__LCD_VSYNC | LCD_MODE,
65 MX28_PAD_LCD_HSYNC__LCD_HSYNC | LCD_MODE,
66 MX28_PAD_LCD_DOTCLK__LCD_DOTCLK | LCD_MODE,
67 MX28_PAD_LCD_ENABLE__GPIO_1_31 | LCD_MODE,
68 MX28_PAD_LCD_RESET__GPIO_3_30 | LCD_MODE,
69 MX28_PAD_PWM0__PWM_0 | LCD_MODE,
70
71 /* UART1 */
72 MX28_PAD_AUART0_CTS__DUART_RX,
73 MX28_PAD_AUART0_RTS__DUART_TX,
74 MX28_PAD_AUART0_TX__DUART_RTS,
75 MX28_PAD_AUART0_RX__DUART_CTS,
76
77 /* UART2 */
78 MX28_PAD_AUART1_RX__AUART1_RX,
79 MX28_PAD_AUART1_TX__AUART1_TX,
80 MX28_PAD_AUART1_RTS__AUART1_RTS,
81 MX28_PAD_AUART1_CTS__AUART1_CTS,
82
83 /* CAN */
84 MX28_PAD_GPMI_RDY2__CAN0_TX,
85 MX28_PAD_GPMI_RDY3__CAN0_RX,
86
87 /* I2C */
88 MX28_PAD_I2C0_SCL__I2C0_SCL,
89 MX28_PAD_I2C0_SDA__I2C0_SDA,
90
91 /* TSC2007 */
92 MX28_PAD_SAIF0_MCLK__GPIO_3_20 | MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP,
93
94 /* MMC0 */
95 MX28_PAD_SSP0_DATA0__SSP0_D0 |
96 (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
97 MX28_PAD_SSP0_DATA1__SSP0_D1 |
98 (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
99 MX28_PAD_SSP0_DATA2__SSP0_D2 |
100 (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
101 MX28_PAD_SSP0_DATA3__SSP0_D3 |
102 (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
103 MX28_PAD_SSP0_DATA4__SSP0_D4 |
104 (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
105 MX28_PAD_SSP0_DATA5__SSP0_D5 |
106 (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
107 MX28_PAD_SSP0_DATA6__SSP0_D6 |
108 (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
109 MX28_PAD_SSP0_DATA7__SSP0_D7 |
110 (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
111 MX28_PAD_SSP0_CMD__SSP0_CMD |
112 (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
113 MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT |
114 (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
115 MX28_PAD_SSP0_SCK__SSP0_SCK |
116 (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
117};
118
119static struct gpio_led tx28_stk5v3_leds[] = {
120 {
121 .name = "GPIO-LED",
122 .default_trigger = "heartbeat",
123 .gpio = TX28_STK5_GPIO_LED,
124 },
125};
126
127static const struct gpio_led_platform_data tx28_stk5v3_led_data __initconst = {
128 .leds = tx28_stk5v3_leds,
129 .num_leds = ARRAY_SIZE(tx28_stk5v3_leds),
130};
131
132static struct spi_board_info tx28_spi_board_info[] = {
133 {
134 .modalias = "spidev",
135 .max_speed_hz = 20000000,
136 .bus_num = 0,
137 .chip_select = 1,
138 .controller_data = (void *)SPI_GPIO_NO_CHIPSELECT,
139 .mode = SPI_MODE_0,
140 },
141};
142
143static void __init tx28_stk5v3_init(void)
144{
145 mxs_iomux_setup_multiple_pads(tx28_stk5v3_pads,
146 ARRAY_SIZE(tx28_stk5v3_pads));
147
148 mx28_add_duart(); /* UART1 */
149 mx28_add_auart(1); /* UART2 */
150
151 tx28_add_fec0();
152 /* spi via ssp will be added when available */
153 spi_register_board_info(tx28_spi_board_info,
154 ARRAY_SIZE(tx28_spi_board_info));
155 mxs_add_platform_device("leds-gpio", 0, NULL, 0,
156 &tx28_stk5v3_led_data, sizeof(tx28_stk5v3_led_data));
157}
158
159static void __init tx28_timer_init(void)
160{
161 mx28_clocks_init();
162}
163
164static struct sys_timer tx28_timer = {
165 .init = tx28_timer_init,
166};
167
168MACHINE_START(TX28, "Ka-Ro electronics TX28 module")
169 .map_io = mx28_map_io,
170 .init_irq = mx28_init_irq,
171 .init_machine = tx28_stk5v3_init,
172 .timer = &tx28_timer,
173MACHINE_END
diff --git a/arch/arm/mach-mxs/module-tx28.c b/arch/arm/mach-mxs/module-tx28.c
new file mode 100644
index 000000000000..fa0b154da67b
--- /dev/null
+++ b/arch/arm/mach-mxs/module-tx28.c
@@ -0,0 +1,131 @@
1/*
2 * Copyright (C) 2010 <LW@KARO-electronics.de>
3 *
4 * This program is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License version 2 as published by the
6 * Free Software Foundation.
7 */
8
9#include <linux/delay.h>
10#include <linux/fec.h>
11#include <linux/gpio.h>
12
13#include <mach/iomux-mx28.h>
14#include "../devices-mx28.h"
15
16#include "module-tx28.h"
17
18#define TX28_FEC_PHY_POWER MXS_GPIO_NR(3, 29)
19#define TX28_FEC_PHY_RESET MXS_GPIO_NR(4, 13)
20
21static const iomux_cfg_t tx28_fec_gpio_pads[] __initconst = {
22 /* PHY POWER */
23 MX28_PAD_PWM4__GPIO_3_29 |
24 MXS_PAD_4MA | MXS_PAD_NOPULL | MXS_PAD_3V3,
25 /* PHY RESET */
26 MX28_PAD_ENET0_RX_CLK__GPIO_4_13 |
27 MXS_PAD_4MA | MXS_PAD_NOPULL | MXS_PAD_3V3,
28 /* Mode strap pins 0-2 */
29 MX28_PAD_ENET0_RXD0__GPIO_4_3 |
30 MXS_PAD_8MA | MXS_PAD_PULLUP | MXS_PAD_3V3,
31 MX28_PAD_ENET0_RXD1__GPIO_4_4 |
32 MXS_PAD_8MA | MXS_PAD_PULLUP | MXS_PAD_3V3,
33 MX28_PAD_ENET0_RX_EN__GPIO_4_2 |
34 MXS_PAD_8MA | MXS_PAD_PULLUP | MXS_PAD_3V3,
35 /* nINT */
36 MX28_PAD_ENET0_TX_CLK__GPIO_4_5 |
37 MXS_PAD_4MA | MXS_PAD_NOPULL | MXS_PAD_3V3,
38
39 MX28_PAD_ENET0_MDC__GPIO_4_0,
40 MX28_PAD_ENET0_MDIO__GPIO_4_1,
41 MX28_PAD_ENET0_TX_EN__GPIO_4_6,
42 MX28_PAD_ENET0_TXD0__GPIO_4_7,
43 MX28_PAD_ENET0_TXD1__GPIO_4_8,
44 MX28_PAD_ENET_CLK__GPIO_4_16,
45};
46
47#define FEC_MODE (MXS_PAD_8MA | MXS_PAD_PULLUP | MXS_PAD_3V3)
48static const iomux_cfg_t tx28_fec_pads[] __initconst = {
49 MX28_PAD_ENET0_MDC__ENET0_MDC | FEC_MODE,
50 MX28_PAD_ENET0_MDIO__ENET0_MDIO | FEC_MODE,
51 MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | FEC_MODE,
52 MX28_PAD_ENET0_RXD0__ENET0_RXD0 | FEC_MODE,
53 MX28_PAD_ENET0_RXD1__ENET0_RXD1 | FEC_MODE,
54 MX28_PAD_ENET0_TX_EN__ENET0_TX_EN | FEC_MODE,
55 MX28_PAD_ENET0_TXD0__ENET0_TXD0 | FEC_MODE,
56 MX28_PAD_ENET0_TXD1__ENET0_TXD1 | FEC_MODE,
57 MX28_PAD_ENET_CLK__CLKCTRL_ENET | FEC_MODE,
58};
59
60static const struct fec_platform_data tx28_fec_data __initconst = {
61 .phy = PHY_INTERFACE_MODE_RMII,
62};
63
64int __init tx28_add_fec0(void)
65{
66 int i, ret;
67
68 pr_debug("%s: Switching FEC PHY power off\n", __func__);
69 ret = mxs_iomux_setup_multiple_pads(tx28_fec_gpio_pads,
70 ARRAY_SIZE(tx28_fec_gpio_pads));
71 for (i = 0; i < ARRAY_SIZE(tx28_fec_gpio_pads); i++) {
72 unsigned int gpio = MXS_GPIO_NR(PAD_BANK(tx28_fec_gpio_pads[i]),
73 PAD_PIN(tx28_fec_gpio_pads[i]));
74
75 ret = gpio_request(gpio, "FEC");
76 if (ret) {
77 pr_err("Failed to request GPIO_%d_%d: %d\n",
78 PAD_BANK(tx28_fec_gpio_pads[i]),
79 PAD_PIN(tx28_fec_gpio_pads[i]), ret);
80 goto free_gpios;
81 }
82 ret = gpio_direction_output(gpio, 0);
83 if (ret) {
84 pr_err("Failed to set direction of GPIO_%d_%d to output: %d\n",
85 gpio / 32 + 1, gpio % 32, ret);
86 goto free_gpios;
87 }
88 }
89
90 /* Power up fec phy */
91 pr_debug("%s: Switching FEC PHY power on\n", __func__);
92 ret = gpio_direction_output(TX28_FEC_PHY_POWER, 1);
93 if (ret) {
94 pr_err("Failed to power on PHY: %d\n", ret);
95 goto free_gpios;
96 }
97 mdelay(26); /* 25ms according to data sheet */
98
99 /* nINT */
100 gpio_direction_input(MXS_GPIO_NR(4, 5));
101 /* Mode strap pins */
102 gpio_direction_output(MXS_GPIO_NR(4, 2), 1);
103 gpio_direction_output(MXS_GPIO_NR(4, 3), 1);
104 gpio_direction_output(MXS_GPIO_NR(4, 4), 1);
105
106 udelay(100); /* minimum assertion time for nRST */
107
108 pr_debug("%s: Deasserting FEC PHY RESET\n", __func__);
109 gpio_set_value(TX28_FEC_PHY_RESET, 1);
110
111 ret = mxs_iomux_setup_multiple_pads(tx28_fec_pads,
112 ARRAY_SIZE(tx28_fec_pads));
113 if (ret) {
114 pr_debug("%s: mxs_iomux_setup_multiple_pads() failed with rc: %d\n",
115 __func__, ret);
116 goto free_gpios;
117 }
118 pr_debug("%s: Registering FEC device\n", __func__);
119 mx28_add_fec(0, &tx28_fec_data);
120 return 0;
121
122free_gpios:
123 while (--i >= 0) {
124 unsigned int gpio = MXS_GPIO_NR(PAD_BANK(tx28_fec_gpio_pads[i]),
125 PAD_PIN(tx28_fec_gpio_pads[i]));
126
127 gpio_free(gpio);
128 }
129
130 return ret;
131}
diff --git a/arch/arm/mach-mxs/module-tx28.h b/arch/arm/mach-mxs/module-tx28.h
new file mode 100644
index 000000000000..df9e1b6e81bf
--- /dev/null
+++ b/arch/arm/mach-mxs/module-tx28.h
@@ -0,0 +1,9 @@
1/*
2 * Copyright (C) 2010 Pengutronix
3 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
8 */
9int __init tx28_add_fec0(void);