aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mx3
diff options
context:
space:
mode:
authorIlya Yanok <yanok@emcraft.com>2009-03-10 20:22:00 -0400
committerSascha Hauer <s.hauer@pengutronix.de>2009-03-13 05:35:05 -0400
commit148854c65ea8046b045672fd49f4333aefaa3ab5 (patch)
tree5f9e4ffd0b9a5b77e814ca17a37681578907179f /arch/arm/mach-mx3
parent7c107dcb652c2101426adfc3193140db95b44594 (diff)
qong: basic support for Dave/DENX QongEVB-LITE board
This patch adds basic support for Dave/DENX QongEVB-LITE i.MX31-based board. It includes support for clocks initialization, UART1, NOR-flash, FPGA-attached NAND flash and DNET ethernet controller (inside FPGA). Signed-off-by: Ilya Yanok <yanok@emcraft.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-mx3')
-rw-r--r--arch/arm/mach-mx3/Kconfig8
-rw-r--r--arch/arm/mach-mx3/Makefile1
-rw-r--r--arch/arm/mach-mx3/qong.c312
3 files changed, 321 insertions, 0 deletions
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
index 7c939c69d6df..d6235583e979 100644
--- a/arch/arm/mach-mx3/Kconfig
+++ b/arch/arm/mach-mx3/Kconfig
@@ -56,4 +56,12 @@ config MACH_MX31MOBOARD
56 Include support for mx31moboard platform. This includes specific 56 Include support for mx31moboard platform. This includes specific
57 configurations for the board and its peripherals. 57 configurations for the board and its peripherals.
58 58
59config MACH_QONG
60 bool "Support Dave/DENX QongEVB-LITE platform"
61 select ARCH_MX31
62 default n
63 help
64 Include support for Dave/DENX QongEVB-LITE platform. This includes
65 specific configurations for the board and its peripherals.
66
59endif 67endif
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
index ab0bec0a4d92..272c8a953b30 100644
--- a/arch/arm/mach-mx3/Makefile
+++ b/arch/arm/mach-mx3/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_MACH_PCM037) += pcm037.o
13obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o 13obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o
14obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o mx31moboard-devboard.o \ 14obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o mx31moboard-devboard.o \
15 mx31moboard-marxbot.o 15 mx31moboard-marxbot.o
16obj-$(CONFIG_MACH_QONG) += qong.o
diff --git a/arch/arm/mach-mx3/qong.c b/arch/arm/mach-mx3/qong.c
new file mode 100644
index 000000000000..6c4283cec6f4
--- /dev/null
+++ b/arch/arm/mach-mx3/qong.c
@@ -0,0 +1,312 @@
1/*
2 * Copyright (C) 2009 Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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 */
18
19#include <linux/types.h>
20#include <linux/init.h>
21#include <linux/kernel.h>
22#include <linux/memory.h>
23#include <linux/platform_device.h>
24#include <linux/mtd/physmap.h>
25#include <linux/mtd/nand.h>
26#include <linux/gpio.h>
27
28#include <mach/hardware.h>
29#include <mach/irqs.h>
30#include <asm/mach-types.h>
31#include <asm/mach/arch.h>
32#include <asm/mach/time.h>
33#include <asm/mach/map.h>
34#include <mach/common.h>
35#include <asm/page.h>
36#include <asm/setup.h>
37#include <mach/board-qong.h>
38#include <mach/imx-uart.h>
39#include <mach/iomux-mx3.h>
40#include "devices.h"
41
42/* FPGA defines */
43#define QONG_FPGA_VERSION(major, minor, rev) \
44 (((major & 0xF) << 12) | ((minor & 0xF) << 8) | (rev & 0xFF))
45
46#define QONG_FPGA_BASEADDR CS1_BASE_ADDR
47#define QONG_FPGA_PERIPH_SIZE (1 << 24)
48
49#define QONG_FPGA_CTRL_BASEADDR QONG_FPGA_BASEADDR
50#define QONG_FPGA_CTRL_SIZE 0x10
51/* FPGA control registers */
52#define QONG_FPGA_CTRL_VERSION 0x00
53
54#define QONG_DNET_ID 1
55#define QONG_DNET_BASEADDR \
56 (QONG_FPGA_BASEADDR + QONG_DNET_ID * QONG_FPGA_PERIPH_SIZE)
57#define QONG_DNET_SIZE 0x00001000
58
59#define QONG_FPGA_IRQ IOMUX_TO_IRQ(MX31_PIN_DTR_DCE1)
60
61/*
62 * This file contains the board-specific initialization routines.
63 */
64
65static struct imxuart_platform_data uart_pdata = {
66 .flags = IMXUART_HAVE_RTSCTS,
67};
68
69static int uart_pins[] = {
70 MX31_PIN_CTS1__CTS1,
71 MX31_PIN_RTS1__RTS1,
72 MX31_PIN_TXD1__TXD1,
73 MX31_PIN_RXD1__RXD1
74};
75
76static inline void mxc_init_imx_uart(void)
77{
78 mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins),
79 "uart-0");
80 mxc_register_device(&mxc_uart_device0, &uart_pdata);
81}
82
83static struct resource dnet_resources[] = {
84 [0] = {
85 .name = "dnet-memory",
86 .start = QONG_DNET_BASEADDR,
87 .end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1,
88 .flags = IORESOURCE_MEM,
89 },
90 [1] = {
91 .start = QONG_FPGA_IRQ,
92 .end = QONG_FPGA_IRQ,
93 .flags = IORESOURCE_IRQ,
94 },
95};
96
97static struct platform_device dnet_device = {
98 .name = "dnet",
99 .id = -1,
100 .num_resources = ARRAY_SIZE(dnet_resources),
101 .resource = dnet_resources,
102};
103
104static int __init qong_init_dnet(void)
105{
106 int ret;
107
108 ret = platform_device_register(&dnet_device);
109 return ret;
110}
111
112/* MTD NOR flash */
113
114static struct physmap_flash_data qong_flash_data = {
115 .width = 2,
116};
117
118static struct resource qong_flash_resource = {
119 .start = CS0_BASE_ADDR,
120 .end = CS0_BASE_ADDR + QONG_NOR_SIZE - 1,
121 .flags = IORESOURCE_MEM,
122};
123
124static struct platform_device qong_nor_mtd_device = {
125 .name = "physmap-flash",
126 .id = 0,
127 .dev = {
128 .platform_data = &qong_flash_data,
129 },
130 .resource = &qong_flash_resource,
131 .num_resources = 1,
132};
133
134static void qong_init_nor_mtd(void)
135{
136 (void)platform_device_register(&qong_nor_mtd_device);
137}
138
139/*
140 * Hardware specific access to control-lines
141 */
142static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
143{
144 struct nand_chip *nand_chip = mtd->priv;
145
146 if (cmd == NAND_CMD_NONE)
147 return;
148
149 if (ctrl & NAND_CLE)
150 writeb(cmd, nand_chip->IO_ADDR_W + (1 << 24));
151 else
152 writeb(cmd, nand_chip->IO_ADDR_W + (1 << 23));
153}
154
155/*
156 * Read the Device Ready pin.
157 */
158static int qong_nand_device_ready(struct mtd_info *mtd)
159{
160 return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB));
161}
162
163static void qong_nand_select_chip(struct mtd_info *mtd, int chip)
164{
165 if (chip >= 0)
166 gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
167 else
168 gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1);
169}
170
171static struct platform_nand_data qong_nand_data = {
172 .chip = {
173 .chip_delay = 20,
174 .options = 0,
175 },
176 .ctrl = {
177 .cmd_ctrl = qong_nand_cmd_ctrl,
178 .dev_ready = qong_nand_device_ready,
179 .select_chip = qong_nand_select_chip,
180 }
181};
182
183static struct resource qong_nand_resource = {
184 .start = CS3_BASE_ADDR,
185 .end = CS3_BASE_ADDR + SZ_32M - 1,
186 .flags = IORESOURCE_MEM,
187};
188
189static struct platform_device qong_nand_device = {
190 .name = "gen_nand",
191 .id = -1,
192 .dev = {
193 .platform_data = &qong_nand_data,
194 },
195 .num_resources = 1,
196 .resource = &qong_nand_resource,
197};
198
199static void __init qong_init_nand_mtd(void)
200{
201 /* init CS */
202 __raw_writel(0x00004f00, CSCR_U(3));
203 __raw_writel(0x20013b31, CSCR_L(3));
204 __raw_writel(0x00020800, CSCR_A(3));
205 mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true);
206
207 /* enable pin */
208 mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFCE_B, IOMUX_CONFIG_GPIO));
209 if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), "nand_enable"))
210 gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
211
212 /* ready/busy pin */
213 mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFRB, IOMUX_CONFIG_GPIO));
214 if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFRB), "nand_rdy"))
215 gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFRB));
216
217 /* write protect pin */
218 mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFWP_B, IOMUX_CONFIG_GPIO));
219 if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFWP_B), "nand_wp"))
220 gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFWP_B));
221
222 platform_device_register(&qong_nand_device);
223}
224
225static void __init qong_init_fpga(void)
226{
227 void __iomem *regs;
228 u32 fpga_ver;
229
230 regs = ioremap(QONG_FPGA_CTRL_BASEADDR, QONG_FPGA_CTRL_SIZE);
231 if (!regs) {
232 printk(KERN_ERR "%s: failed to map registers, aborting.\n",
233 __func__);
234 return;
235 }
236
237 fpga_ver = readl(regs + QONG_FPGA_CTRL_VERSION);
238 iounmap(regs);
239 printk(KERN_INFO "Qong FPGA version %d.%d.%d\n",
240 (fpga_ver & 0xF000) >> 12,
241 (fpga_ver & 0x0F00) >> 8, fpga_ver & 0x00FF);
242 if (fpga_ver < QONG_FPGA_VERSION(0, 8, 7)) {
243 printk(KERN_ERR "qong: Unexpected FPGA version, FPGA-based "
244 "devices won't be registered!\n");
245 return;
246 }
247
248 /* register FPGA-based devices */
249 qong_init_nand_mtd();
250 qong_init_dnet();
251}
252
253/*
254 * This structure defines the MX31 memory map.
255 */
256static struct map_desc qong_io_desc[] __initdata = {
257 {
258 .virtual = AIPS1_BASE_ADDR_VIRT,
259 .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
260 .length = AIPS1_SIZE,
261 .type = MT_DEVICE_NONSHARED
262 }, {
263 .virtual = AIPS2_BASE_ADDR_VIRT,
264 .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
265 .length = AIPS2_SIZE,
266 .type = MT_DEVICE_NONSHARED
267 }
268};
269
270/*
271 * Set up static virtual mappings.
272 */
273static void __init qong_map_io(void)
274{
275 mxc_map_io();
276 iotable_init(qong_io_desc, ARRAY_SIZE(qong_io_desc));
277}
278
279/*
280 * Board specific initialization.
281 */
282static void __init mxc_board_init(void)
283{
284 mxc_init_imx_uart();
285 qong_init_nor_mtd();
286 qong_init_fpga();
287}
288
289static void __init qong_timer_init(void)
290{
291 mx31_clocks_init(26000000);
292}
293
294static struct sys_timer qong_timer = {
295 .init = qong_timer_init,
296};
297
298/*
299 * The following uses standard kernel macros defined in arch.h in order to
300 * initialize __mach_desc_QONG data structure.
301 */
302
303MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")
304 /* Maintainer: DENX Software Engineering GmbH */
305 .phys_io = AIPS1_BASE_ADDR,
306 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
307 .boot_params = PHYS_OFFSET + 0x100,
308 .map_io = qong_map_io,
309 .init_irq = mxc_init_irq,
310 .init_machine = mxc_board_init,
311 .timer = &qong_timer,
312MACHINE_END