aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mx3
diff options
context:
space:
mode:
authorQuinn Jensen <qcjensen@gmail.com>2007-07-09 17:06:53 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-07-22 10:44:46 -0400
commit52c543f90c4095dff71dc125017594b61a753069 (patch)
tree0b88dafea91f1fd2cb44bb863271503e765f7156 /arch/arm/mach-mx3
parent4b300c362d690c8e0788f69ed91c22a0a76f7ce2 (diff)
[ARM] 4461/1: MXC platform and i.MX31ADS core support
This patch adds the foundation pieces for the Freescale MXC platforms, including i.MX2 and i.MX3 based systems. The bare-bones MX31 support in this patch boots to the rootdev panic with 8250 serial console configured "console=ttyS0,115200". It assumes that Redboot is the boot loader. Signed-off-by: Quinn Jensen <quinn.jensen@freescale.com> Acked-by: Lennert Buytenhek <buytenh@wantstofly.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-mx3')
-rw-r--r--arch/arm/mach-mx3/Kconfig12
-rw-r--r--arch/arm/mach-mx3/Makefile8
-rw-r--r--arch/arm/mach-mx3/Makefile.boot3
-rw-r--r--arch/arm/mach-mx3/mm.c64
-rw-r--r--arch/arm/mach-mx3/mx31ads.c142
-rw-r--r--arch/arm/mach-mx3/time.c152
6 files changed, 381 insertions, 0 deletions
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
new file mode 100644
index 000000000000..5fe8606cac08
--- /dev/null
+++ b/arch/arm/mach-mx3/Kconfig
@@ -0,0 +1,12 @@
1menu "MX3 Options"
2 depends on ARCH_MX3
3
4config MACH_MX31ADS
5 bool "Support MX31ADS platforms"
6 default y
7 help
8 Include support for MX31ADS platform. This includes specific
9 configurations for the board and its peripherals.
10
11endmenu
12
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
new file mode 100644
index 000000000000..cbec997f332a
--- /dev/null
+++ b/arch/arm/mach-mx3/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for the linux kernel.
3#
4
5# Object file lists.
6
7obj-y := mm.o time.o
8obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o
diff --git a/arch/arm/mach-mx3/Makefile.boot b/arch/arm/mach-mx3/Makefile.boot
new file mode 100644
index 000000000000..e1dd366f836b
--- /dev/null
+++ b/arch/arm/mach-mx3/Makefile.boot
@@ -0,0 +1,3 @@
1 zreladdr-y := 0x80008000
2params_phys-y := 0x80000100
3initrd_phys-y := 0x80800000
diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c
new file mode 100644
index 000000000000..41dad485ded9
--- /dev/null
+++ b/arch/arm/mach-mx3/mm.c
@@ -0,0 +1,64 @@
1/*
2 * Copyright (C) 1999,2000 Arm Limited
3 * Copyright (C) 2000 Deep Blue Solutions Ltd
4 * Copyright (C) 2002 Shane Nay (shane@minirl.com)
5 * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
6 * - add MX31 specific definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/mm.h>
24#include <linux/init.h>
25#include <asm/hardware.h>
26#include <asm/pgtable.h>
27#include <asm/mach/map.h>
28#include <asm/arch/common.h>
29
30/*!
31 * @file mm.c
32 *
33 * @brief This file creates static virtual to physical mappings, common to all MX3 boards.
34 *
35 * @ingroup Memory
36 */
37
38/*!
39 * This table defines static virtual address mappings for I/O regions.
40 * These are the mappings common across all MX3 boards.
41 */
42static struct map_desc mxc_io_desc[] __initdata = {
43 {
44 .virtual = X_MEMC_BASE_ADDR_VIRT,
45 .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR),
46 .length = X_MEMC_SIZE,
47 .type = MT_DEVICE
48 }, {
49 .virtual = AVIC_BASE_ADDR_VIRT,
50 .pfn = __phys_to_pfn(AVIC_BASE_ADDR),
51 .length = AVIC_SIZE,
52 .type = MT_NONSHARED_DEVICE
53 },
54};
55
56/*!
57 * This function initializes the memory map. It is called during the
58 * system startup to create static physical to virtual memory mappings
59 * for the IO modules.
60 */
61void __init mxc_map_io(void)
62{
63 iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
64}
diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c
new file mode 100644
index 000000000000..7e89bdc23a9f
--- /dev/null
+++ b/arch/arm/mach-mx3/mx31ads.c
@@ -0,0 +1,142 @@
1/*
2 * Copyright (C) 2000 Deep Blue Solutions Ltd
3 * Copyright (C) 2002 Shane Nay (shane@minirl.com)
4 * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/types.h>
22#include <linux/init.h>
23#include <linux/clk.h>
24#include <linux/serial_8250.h>
25
26#include <asm/hardware.h>
27#include <asm/mach-types.h>
28#include <asm/mach/arch.h>
29#include <asm/memory.h>
30#include <asm/mach/map.h>
31#include <asm/arch/common.h>
32
33/*!
34 * @file mx31ads.c
35 *
36 * @brief This file contains the board-specific initialization routines.
37 *
38 * @ingroup System
39 */
40
41#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
42/*!
43 * The serial port definition structure.
44 */
45static struct plat_serial8250_port serial_platform_data[] = {
46 {
47 .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA),
48 .mapbase = (unsigned long)(CS4_BASE_ADDR + PBC_SC16C652_UARTA),
49 .irq = EXPIO_INT_XUART_INTA,
50 .uartclk = 14745600,
51 .regshift = 0,
52 .iotype = UPIO_MEM,
53 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
54 }, {
55 .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB),
56 .mapbase = (unsigned long)(CS4_BASE_ADDR + PBC_SC16C652_UARTB),
57 .irq = EXPIO_INT_XUART_INTB,
58 .uartclk = 14745600,
59 .regshift = 0,
60 .iotype = UPIO_MEM,
61 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
62 },
63 {},
64};
65
66static struct platform_device serial_device = {
67 .name = "serial8250",
68 .id = 0,
69 .dev = {
70 .platform_data = serial_platform_data,
71 },
72};
73
74static int __init mxc_init_extuart(void)
75{
76 return platform_device_register(&serial_device);
77}
78#else
79static inline int mxc_init_extuart(void)
80{
81 return 0;
82}
83#endif
84
85/*!
86 * This structure defines static mappings for the i.MX31ADS board.
87 */
88static struct map_desc mx31ads_io_desc[] __initdata = {
89 {
90 .virtual = AIPS1_BASE_ADDR_VIRT,
91 .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
92 .length = AIPS1_SIZE,
93 .type = MT_NONSHARED_DEVICE
94 }, {
95 .virtual = SPBA0_BASE_ADDR_VIRT,
96 .pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
97 .length = SPBA0_SIZE,
98 .type = MT_NONSHARED_DEVICE
99 }, {
100 .virtual = AIPS2_BASE_ADDR_VIRT,
101 .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
102 .length = AIPS2_SIZE,
103 .type = MT_NONSHARED_DEVICE
104 }, {
105 .virtual = CS4_BASE_ADDR_VIRT,
106 .pfn = __phys_to_pfn(CS4_BASE_ADDR),
107 .length = CS4_SIZE / 2,
108 .type = MT_DEVICE
109 },
110};
111
112/*!
113 * Set up static virtual mappings.
114 */
115void __init mx31ads_map_io(void)
116{
117 mxc_map_io();
118 iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc));
119}
120
121/*!
122 * Board specific initialization.
123 */
124static void __init mxc_board_init(void)
125{
126 mxc_init_extuart();
127}
128
129/*
130 * The following uses standard kernel macros defined in arch.h in order to
131 * initialize __mach_desc_MX31ADS data structure.
132 */
133MACHINE_START(MX31ADS, "Freescale MX31ADS")
134 /* Maintainer: Freescale Semiconductor, Inc. */
135 .phys_io = AIPS1_BASE_ADDR,
136 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
137 .boot_params = PHYS_OFFSET + 0x100,
138 .map_io = mx31ads_map_io,
139 .init_irq = mxc_init_irq,
140 .init_machine = mxc_board_init,
141 .timer = &mxc_timer,
142MACHINE_END
diff --git a/arch/arm/mach-mx3/time.c b/arch/arm/mach-mx3/time.c
new file mode 100644
index 000000000000..e81fb5c5d7c3
--- /dev/null
+++ b/arch/arm/mach-mx3/time.c
@@ -0,0 +1,152 @@
1/*
2 * System Timer Interrupt reconfigured to run in free-run mode.
3 * Author: Vitaly Wool
4 * Copyright 2004 MontaVista Software Inc.
5 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
6 */
7
8/*
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14/*!
15 * @file time.c
16 * @brief This file contains OS tick and wdog timer implementations.
17 *
18 * This file contains OS tick and wdog timer implementations.
19 *
20 * @ingroup Timers
21 */
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/interrupt.h>
26#include <linux/irq.h>
27#include <asm/hardware.h>
28#include <asm/mach/time.h>
29#include <asm/io.h>
30#include <asm/arch/common.h>
31
32/*!
33 * This is the timer interrupt service routine to do required tasks.
34 * It also services the WDOG timer at the frequency of twice per WDOG
35 * timeout value. For example, if the WDOG's timeout value is 4 (2
36 * seconds since the WDOG runs at 0.5Hz), it will be serviced once
37 * every 2/2=1 second.
38 *
39 * @param irq GPT interrupt source number (not used)
40 * @param dev_id this parameter is not used
41 * @return always returns \b IRQ_HANDLED as defined in
42 * include/linux/interrupt.h.
43 */
44static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
45{
46 unsigned int next_match;
47
48 write_seqlock(&xtime_lock);
49
50 if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) {
51 do {
52 timer_tick();
53 next_match = __raw_readl(MXC_GPT_GPTOCR1) + LATCH;
54 __raw_writel(GPTSR_OF1, MXC_GPT_GPTSR);
55 __raw_writel(next_match, MXC_GPT_GPTOCR1);
56 } while ((signed long)(next_match -
57 __raw_readl(MXC_GPT_GPTCNT)) <= 0);
58 }
59
60 write_sequnlock(&xtime_lock);
61
62 return IRQ_HANDLED;
63}
64
65/*!
66 * This function is used to obtain the number of microseconds since the last
67 * timer interrupt. Note that interrupts is disabled by do_gettimeofday().
68 *
69 * @return the number of microseconds since the last timer interrupt.
70 */
71static unsigned long mxc_gettimeoffset(void)
72{
73 unsigned long ticks_to_match, elapsed, usec, tick_usec, i;
74
75 /* Get ticks before next timer match */
76 ticks_to_match =
77 __raw_readl(MXC_GPT_GPTOCR1) - __raw_readl(MXC_GPT_GPTCNT);
78
79 /* We need elapsed ticks since last match */
80 elapsed = LATCH - ticks_to_match;
81
82 /* Now convert them to usec */
83 /* Insure no overflow when calculating the usec below */
84 for (i = 1, tick_usec = tick_nsec / 1000;; i *= 2) {
85 tick_usec /= i;
86 if ((0xFFFFFFFF / tick_usec) > elapsed)
87 break;
88 }
89 usec = (unsigned long)(elapsed * tick_usec) / (LATCH / i);
90
91 return usec;
92}
93
94/*!
95 * The OS tick timer interrupt structure.
96 */
97static struct irqaction timer_irq = {
98 .name = "MXC Timer Tick",
99 .flags = IRQF_DISABLED | IRQF_TIMER,
100 .handler = mxc_timer_interrupt
101};
102
103/*!
104 * This function is used to initialize the GPT to produce an interrupt
105 * based on HZ. It is called by start_kernel() during system startup.
106 */
107void __init mxc_init_time(void)
108{
109 u32 reg, v;
110 reg = __raw_readl(MXC_GPT_GPTCR);
111 reg &= ~GPTCR_ENABLE;
112 __raw_writel(reg, MXC_GPT_GPTCR);
113 reg |= GPTCR_SWR;
114 __raw_writel(reg, MXC_GPT_GPTCR);
115
116 while ((__raw_readl(MXC_GPT_GPTCR) & GPTCR_SWR) != 0)
117 cpu_relax();
118
119 reg = GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ;
120 __raw_writel(reg, MXC_GPT_GPTCR);
121
122 /* TODO: get timer rate from clk driver */
123 v = 66500000;
124
125 __raw_writel((v / CLOCK_TICK_RATE) - 1, MXC_GPT_GPTPR);
126
127 if ((v % CLOCK_TICK_RATE) != 0) {
128 pr_info("\nWARNING: Can't generate CLOCK_TICK_RATE at %d Hz\n",
129 CLOCK_TICK_RATE);
130 }
131 pr_info("Actual CLOCK_TICK_RATE is %d Hz\n",
132 v / ((__raw_readl(MXC_GPT_GPTPR) & 0xFFF) + 1));
133
134 reg = __raw_readl(MXC_GPT_GPTCNT);
135 reg += LATCH;
136 __raw_writel(reg, MXC_GPT_GPTOCR1);
137
138 setup_irq(MXC_INT_GPT, &timer_irq);
139
140 reg = __raw_readl(MXC_GPT_GPTCR);
141 reg =
142 GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ | GPTCR_STOPEN | GPTCR_DOZEN |
143 GPTCR_WAITEN | GPTCR_ENMOD | GPTCR_ENABLE;
144 __raw_writel(reg, MXC_GPT_GPTCR);
145
146 __raw_writel(GPTIR_OF1IE, MXC_GPT_GPTIR);
147}
148
149struct sys_timer mxc_timer = {
150 .init = mxc_init_time,
151 .offset = mxc_gettimeoffset,
152};