barebox_default_env: fix out of tree build
[barebox-mini2440.git] / board / eukrea_cpuimx35 / eukrea_cpuimx35.c
blob7f1c782f1e318d11204a14a22ea6015a4563a164
1 /*
2 * Copyright (C) 2007 Sascha Hauer, Pengutronix
3 * 2009 Marc Kleine-Budde, Pengutronix
4 * (c) 2010 Eukrea Electromatique, Eric BĂ©nard <eric@eukrea.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
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.
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,
19 * MA 02111-1307 USA
21 * Derived from:
23 * * mx35_3stack.c - board file for uboot-v1
24 * Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
25 * (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
29 #include <common.h>
30 #include <command.h>
31 #include <environment.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <fec.h>
35 #include <fs.h>
36 #include <init.h>
37 #include <nand.h>
38 #include <net.h>
39 #include <partition.h>
41 #include <asm/armlinux.h>
42 #include <asm/io.h>
43 #include <asm/mach-types.h>
44 #include <asm/mmu.h>
46 #include <mach/gpio.h>
47 #include <mach/imx-nand.h>
48 #include <mach/imx-regs.h>
49 #include <mach/iomux-mx35.h>
50 #include <mach/iomux-v3.h>
51 #include <mach/pmic.h>
52 #include <mach/imx-ipu-fb.h>
53 #include <mach/imx-pll.h>
55 static struct fec_platform_data fec_info = {
56 .xcv_type = MII100,
57 .phy_addr = 0x1F,
60 static struct device_d fec_dev = {
61 .name = "fec_imx",
62 .map_base = IMX_FEC_BASE,
63 .platform_data = &fec_info,
66 static struct memory_platform_data sdram_pdata = {
67 .name = "ram0",
68 .flags = DEVFS_RDWR,
71 static struct device_d sdram_dev = {
72 .name = "mem",
73 .map_base = IMX_SDRAM_CS0,
74 .size = 128 * 1024 * 1024,
75 .platform_data = &sdram_pdata,
78 struct imx_nand_platform_data nand_info = {
79 .width = 1,
80 .hw_ecc = 1,
81 .flash_bbt = 1,
84 static struct device_d nand_dev = {
85 .name = "imx_nand",
86 .map_base = IMX_NFC_BASE,
87 .platform_data = &nand_info,
90 static struct fb_videomode imxfb_mode = {
91 .name = "CMO_QVGA",
92 .refresh = 60,
93 .xres = 320,
94 .yres = 240,
95 .pixclock = KHZ2PICOS(7000),
96 .left_margin = 68,
97 .right_margin = 20,
98 .upper_margin = 15,
99 .lower_margin = 4,
100 .hsync_len = 30,
101 .vsync_len = 3,
102 .sync = FB_SYNC_OE_ACT_HIGH,
103 .vmode = FB_VMODE_NONINTERLACED,
104 .flag = 0,
107 static struct imx_ipu_fb_platform_data ipu_fb_data = {
108 .mode = &imxfb_mode,
109 .bpp = 16,
112 static struct device_d imxfb_dev = {
113 .name = "imx-ipu-fb",
114 .map_base = 0x53fc0000,
115 .size = 0x1000,
116 .platform_data = &ipu_fb_data,
119 #ifdef CONFIG_MMU
120 static int eukrea_cpuimx35_mmu_init(void)
122 mmu_init();
124 arm_create_section(0x80000000, 0x80000000, 128, PMD_SECT_DEF_CACHED);
125 arm_create_section(0x90000000, 0x80000000, 128, PMD_SECT_DEF_UNCACHED);
127 setup_dma_coherent(0x10000000);
129 #if TEXT_BASE & (0x100000 - 1)
130 #warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary
131 #else
132 arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED);
133 #endif
134 mmu_enable();
136 #ifdef CONFIG_CACHE_L2X0
137 l2x0_init((void __iomem *)0x30000000, 0x00030024, 0x00000000);
138 #endif
139 return 0;
141 postcore_initcall(eukrea_cpuimx35_mmu_init);
142 #endif
144 static int eukrea_cpuimx35_devices_init(void)
146 register_device(&nand_dev);
148 devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED, "self_raw");
149 dev_add_bb_dev("self_raw", "self0");
150 devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED, "env_raw");
151 dev_add_bb_dev("env_raw", "env0");
153 register_device(&fec_dev);
155 register_device(&sdram_dev);
156 register_device(&imxfb_dev);
158 armlinux_add_dram(&sdram_dev);
159 armlinux_set_bootparams((void *)0x80000100);
160 armlinux_set_architecture(MACH_TYPE_EUKREA_CPUIMX35);
162 return 0;
165 device_initcall(eukrea_cpuimx35_devices_init);
167 static int eukrea_cpuimx35_enable_display(void)
169 gpio_direction_output(1, 1);
170 gpio_direction_output(0, 0);
171 return 0;
174 late_initcall(eukrea_cpuimx35_enable_display);
176 static struct device_d eukrea_cpuimx35_serial_device = {
177 .name = "imx_serial",
178 .map_base = IMX_UART1_BASE,
179 .size = 4096,
182 static struct pad_desc eukrea_cpuimx35_pads[] = {
183 MX35_PAD_FEC_TX_CLK__FEC_TX_CLK,
184 MX35_PAD_FEC_RX_CLK__FEC_RX_CLK,
185 MX35_PAD_FEC_RX_DV__FEC_RX_DV,
186 MX35_PAD_FEC_COL__FEC_COL,
187 MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
188 MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
189 MX35_PAD_FEC_TX_EN__FEC_TX_EN,
190 MX35_PAD_FEC_MDC__FEC_MDC,
191 MX35_PAD_FEC_MDIO__FEC_MDIO,
192 MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
193 MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
194 MX35_PAD_FEC_CRS__FEC_CRS,
195 MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
196 MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
197 MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
198 MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
199 MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
200 MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
201 MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
202 MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
204 MX35_PAD_RXD1__UART1_RXD_MUX,
205 MX35_PAD_TXD1__UART1_TXD_MUX,
206 MX35_PAD_RTS1__UART1_RTS,
207 MX35_PAD_CTS1__UART1_CTS,
210 static int eukrea_cpuimx35_console_init(void)
212 mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads,
213 ARRAY_SIZE(eukrea_cpuimx35_pads));
215 register_device(&eukrea_cpuimx35_serial_device);
216 return 0;
219 console_initcall(eukrea_cpuimx35_console_init);
221 static int eukrea_cpuimx35_core_init(void)
223 u32 reg;
225 /* enable clock for I2C1 and FEC */
226 reg = readl(IMX_CCM_BASE + CCM_CGR1);
227 reg |= 0x3 << CCM_CGR1_FEC_SHIFT;
228 reg = writel(reg, IMX_CCM_BASE + CCM_CGR1);
230 /* AIPS setup - Only setup MPROTx registers. The PACR default values are good.*/
232 * Set all MPROTx to be non-bufferable, trusted for R/W,
233 * not forced to user-mode.
235 writel(0x77777777, IMX_AIPS1_BASE);
236 writel(0x77777777, IMX_AIPS1_BASE + 0x4);
237 writel(0x77777777, IMX_AIPS2_BASE);
238 writel(0x77777777, IMX_AIPS2_BASE + 0x4);
241 * Clear the on and off peripheral modules Supervisor Protect bit
242 * for SDMA to access them. Did not change the AIPS control registers
243 * (offset 0x20) access type
245 writel(0x0, IMX_AIPS1_BASE + 0x40);
246 writel(0x0, IMX_AIPS1_BASE + 0x44);
247 writel(0x0, IMX_AIPS1_BASE + 0x48);
248 writel(0x0, IMX_AIPS1_BASE + 0x4C);
249 reg = readl(IMX_AIPS1_BASE + 0x50);
250 reg &= 0x00FFFFFF;
251 writel(reg, IMX_AIPS1_BASE + 0x50);
253 writel(0x0, IMX_AIPS2_BASE + 0x40);
254 writel(0x0, IMX_AIPS2_BASE + 0x44);
255 writel(0x0, IMX_AIPS2_BASE + 0x48);
256 writel(0x0, IMX_AIPS2_BASE + 0x4C);
257 reg = readl(IMX_AIPS2_BASE + 0x50);
258 reg &= 0x00FFFFFF;
259 writel(reg, IMX_AIPS2_BASE + 0x50);
261 /* MAX (Multi-Layer AHB Crossbar Switch) setup */
263 /* MPR - priority is M4 > M2 > M3 > M5 > M0 > M1 */
264 #define MAX_PARAM1 0x00302154
265 writel(MAX_PARAM1, IMX_MAX_BASE + 0x000); /* for S0 */
266 writel(MAX_PARAM1, IMX_MAX_BASE + 0x100); /* for S1 */
267 writel(MAX_PARAM1, IMX_MAX_BASE + 0x200); /* for S2 */
268 writel(MAX_PARAM1, IMX_MAX_BASE + 0x300); /* for S3 */
269 writel(MAX_PARAM1, IMX_MAX_BASE + 0x400); /* for S4 */
271 /* SGPCR - always park on last master */
272 writel(0x10, IMX_MAX_BASE + 0x10); /* for S0 */
273 writel(0x10, IMX_MAX_BASE + 0x110); /* for S1 */
274 writel(0x10, IMX_MAX_BASE + 0x210); /* for S2 */
275 writel(0x10, IMX_MAX_BASE + 0x310); /* for S3 */
276 writel(0x10, IMX_MAX_BASE + 0x410); /* for S4 */
278 /* MGPCR - restore default values */
279 writel(0x0, IMX_MAX_BASE + 0x800); /* for M0 */
280 writel(0x0, IMX_MAX_BASE + 0x900); /* for M1 */
281 writel(0x0, IMX_MAX_BASE + 0xa00); /* for M2 */
282 writel(0x0, IMX_MAX_BASE + 0xb00); /* for M3 */
283 writel(0x0, IMX_MAX_BASE + 0xc00); /* for M4 */
284 writel(0x0, IMX_MAX_BASE + 0xd00); /* for M5 */
287 * M3IF Control Register (M3IFCTL)
288 * MRRP[0] = L2CC0 not on priority list (0 << 0) = 0x00000000
289 * MRRP[1] = MAX1 not on priority list (0 << 0) = 0x00000000
290 * MRRP[2] = L2CC1 not on priority list (0 << 0) = 0x00000000
291 * MRRP[3] = USB not on priority list (0 << 0) = 0x00000000
292 * MRRP[4] = SDMA not on priority list (0 << 0) = 0x00000000
293 * MRRP[5] = GPU not on priority list (0 << 0) = 0x00000000
294 * MRRP[6] = IPU1 on priority list (1 << 6) = 0x00000040
295 * MRRP[7] = IPU2 not on priority list (0 << 0) = 0x00000000
296 * ------------
297 * 0x00000040
299 writel(0x40, IMX_M3IF_BASE);
301 return 0;
304 core_initcall(eukrea_cpuimx35_core_init);
306 #define MPCTL_PARAM_399 (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5))
307 #define MPCTL_PARAM_532 ((1 << 31) | IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1))
309 static int do_cpufreq(struct command *cmdtp, int argc, char *argv[])
311 unsigned long freq;
313 if (argc != 2)
314 return COMMAND_ERROR_USAGE;
316 freq = simple_strtoul(argv[1], NULL, 0);
318 switch (freq) {
319 case 399:
320 writel(MPCTL_PARAM_399, IMX_CCM_BASE + CCM_MPCTL);
321 break;
322 case 532:
323 writel(MPCTL_PARAM_532, IMX_CCM_BASE + CCM_MPCTL);
324 break;
325 default:
326 return COMMAND_ERROR_USAGE;
329 printf("Switched CPU frequency to %dMHz\n", freq);
331 return 0;
334 static const __maybe_unused char cmd_cpufreq_help[] =
335 "Usage: cpufreq 399|532\n"
336 "\n"
337 "Set CPU frequency to <freq> MHz\n";
339 BAREBOX_CMD_START(cpufreq)
340 .cmd = do_cpufreq,
341 .usage = "adjust CPU frequency",
342 BAREBOX_CMD_HELP(cmd_cpufreq_help)
343 BAREBOX_CMD_END