1 //==========================================================================
5 // HAL misc board support code for the board
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //========================================================================*/
42 #include <pkgconf/hal.h>
43 #include <pkgconf/system.h>
45 #include CYGBLD_HAL_PLATFORM_H
47 #include <cyg/infra/cyg_type.h> // base types
48 #include <cyg/infra/cyg_trac.h> // tracing macros
49 #include <cyg/infra/cyg_ass.h> // assertion macros
51 #include <cyg/hal/hal_io.h> // IO macros
52 #include <cyg/hal/hal_arch.h> // Register state info
53 #include <cyg/hal/hal_diag.h>
54 #include <cyg/hal/hal_intr.h> // Interrupt names
55 #include <cyg/hal/hal_cache.h>
56 #include <cyg/hal/hal_soc.h> // Hardware definitions
57 #include <cyg/hal/fsl_board.h> // Platform specifics
58 #include <cyg/infra/diag.h> // diag_printf
60 // All the MM table layout is here:
61 #include <cyg/hal/hal_mm.h>
63 externC void* memset(void *, int, size_t);
64 unsigned int cpld_base_addr;
66 void hal_mmu_init(void)
68 unsigned long ttb_base = RAM_BANK0_BASE + 0x4000;
72 * Set the TTB register
74 asm volatile ("mcr p15,0,%0,c2,c0,0" : : "r"(ttb_base) /*:*/);
77 * Set the Domain Access Control Register
79 i = ARM_ACCESS_DACR_DEFAULT;
80 asm volatile ("mcr p15,0,%0,c3,c0,0" : : "r"(i) /*:*/);
83 * First clear all TT entries - ie Set them to Faulting
85 memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
87 /* Actual Virtual Size Attributes Function */
88 /* Base Base MB cached? buffered? access permissions */
89 /* xxx00000 xxx00000 */
90 X_ARM_MMU_SECTION(0x000, 0x200, 0x1, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* ROM */
91 X_ARM_MMU_SECTION(0x1FF, 0x1FF, 0x001, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* IRAM */
92 X_ARM_MMU_SECTION(0x300, 0x300, 0x100, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* GPU */
93 X_ARM_MMU_SECTION(0x400, 0x400, 0x200, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* IPUv3D */
94 X_ARM_MMU_SECTION(0x600, 0x600, 0x300, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* periperals */
95 X_ARM_MMU_SECTION(0x900, 0x000, 0x1FF, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
96 X_ARM_MMU_SECTION(0x900, 0x900, 0x200, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
97 X_ARM_MMU_SECTION(0x900, 0xE00, 0x200, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM 0:128M*/
98 X_ARM_MMU_SECTION(0xB80, 0xB80, 0x10, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* CS1 EIM control*/
99 X_ARM_MMU_SECTION(0xCC0, 0xCC0, 0x040, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* CS4/5/NAND Flash buffer */
102 static void mxc_fec_setup(void)
104 volatile unsigned int reg;
107 writel(0x3, IOMUXC_BASE_ADDR + 0x0D4);
108 writel(0x1FD, IOMUXC_BASE_ADDR + 0x0468);
109 writel(0x0, IOMUXC_BASE_ADDR + 0x0954);
112 writel(0x2, IOMUXC_BASE_ADDR + 0x13C);
113 writel(0x2004, IOMUXC_BASE_ADDR + 0x0524);
116 writel(0x3, IOMUXC_BASE_ADDR + 0x0EC);
117 writel(0x180, IOMUXC_BASE_ADDR + 0x0480);
118 writel(0x0, IOMUXC_BASE_ADDR + 0x0964);
121 writel(0x3, IOMUXC_BASE_ADDR + 0x0E8);
122 writel(0x180, IOMUXC_BASE_ADDR + 0x047C);
123 writel(0x0, IOMUXC_BASE_ADDR + 0x0960);
126 writel(0x3, IOMUXC_BASE_ADDR + 0x0d8);
127 writel(0x180, IOMUXC_BASE_ADDR + 0x046C);
128 writel(0x0, IOMUXC_BASE_ADDR + 0x095C);
131 writel(0x2, IOMUXC_BASE_ADDR + 0x016C);
132 writel(0x2180, IOMUXC_BASE_ADDR + 0x0554);
133 writel(0x0, IOMUXC_BASE_ADDR + 0x0958);
136 writel(0x2, IOMUXC_BASE_ADDR + 0x148);
137 writel(0x2004, IOMUXC_BASE_ADDR + 0x0530);
140 writel(0x2, IOMUXC_BASE_ADDR + 0x144);
141 writel(0x2004, IOMUXC_BASE_ADDR + 0x052C);
144 writel(0x2, IOMUXC_BASE_ADDR + 0x140);
145 writel(0x2004, IOMUXC_BASE_ADDR + 0x0528);
148 writel(0x2, IOMUXC_BASE_ADDR + 0x0170);
149 writel(0x2004, IOMUXC_BASE_ADDR + 0x0558);
152 writel(0x1, IOMUXC_BASE_ADDR + 0x014C);
153 writel(0x2004, IOMUXC_BASE_ADDR + 0x0534);
156 writel(0x2, IOMUXC_BASE_ADDR + 0x0138);
157 writel(0x2004, IOMUXC_BASE_ADDR + 0x0520);
160 writel(0x1, IOMUXC_BASE_ADDR + 0x0150);
161 writel(0x2180, IOMUXC_BASE_ADDR + 0x0538);
162 writel(0x0, IOMUXC_BASE_ADDR + 0x0974);
165 writel(0x1, IOMUXC_BASE_ADDR + 0x0124);
166 writel(0x2180, IOMUXC_BASE_ADDR + 0x0500);
167 writel(0x0, IOMUXC_BASE_ADDR + 0x094c);
170 writel(0x1, IOMUXC_BASE_ADDR + 0x0128);
171 writel(0x2180, IOMUXC_BASE_ADDR + 0x0504);
172 writel(0x0, IOMUXC_BASE_ADDR + 0x0968);
175 writel(0x3, IOMUXC_BASE_ADDR + 0x0f4);
176 writel(0x180, IOMUXC_BASE_ADDR + 0x0488);
177 writel(0x0, IOMUXC_BASE_ADDR + 0x0950);
180 writel(0x3, IOMUXC_BASE_ADDR + 0x0f0);
181 writel(0x180, IOMUXC_BASE_ADDR + 0x0484);
182 writel(0x0, IOMUXC_BASE_ADDR + 0x0970);
185 writel(0x2, IOMUXC_BASE_ADDR + 0x164);
186 writel(0x2180, IOMUXC_BASE_ADDR + 0x054C);
187 writel(0x0, IOMUXC_BASE_ADDR + 0x096C);
190 #include <cyg/io/imx_spi.h>
191 struct spi_v2_3_reg spi_pmic_reg;
193 struct imx_spi_dev imx_spi_pmic = {
194 base : CSPI1_BASE_ADDR,
196 ss_pol : IMX_SPI_ACTIVE_HIGH,
197 ss : 0, // slave select 0
202 struct spi_v2_3_reg spi_nor_reg;
204 struct imx_spi_dev imx_spi_nor = {
205 base : CSPI1_BASE_ADDR,
207 ss_pol : IMX_SPI_ACTIVE_LOW,
208 ss : 1, // slave select 1
214 imx_spi_init_func_t *spi_nor_init;
215 imx_spi_xfer_func_t *spi_nor_xfer;
217 imx_spi_init_func_t *spi_pmic_init;
218 imx_spi_xfer_func_t *spi_pmic_xfer;
221 // Platform specific initialization
223 static void babbage_power_init(void);
225 void plf_hardware_init(void)
229 spi_nor_init = (imx_spi_init_func_t *)imx_spi_init_v2_3;
230 spi_nor_xfer = (imx_spi_xfer_func_t *)imx_spi_xfer_v2_3;
232 spi_pmic_init = (imx_spi_init_func_t *)imx_spi_init_v2_3;
233 spi_pmic_xfer = (imx_spi_xfer_func_t *)imx_spi_xfer_v2_3;
234 spi_pmic_init(&imx_spi_pmic);
236 babbage_power_init();
240 writel(0x0, IOMUXC_BASE_ADDR + 0x228);
241 writel(0x1C5, IOMUXC_BASE_ADDR + 0x618);
243 writel(0x0, IOMUXC_BASE_ADDR + 0x22c);
244 writel(0x1C5, IOMUXC_BASE_ADDR + 0x61c);
246 writel(0x0, IOMUXC_BASE_ADDR + 0x230);
247 writel(0x1C4, IOMUXC_BASE_ADDR + 0x620);
249 writel(0x0, IOMUXC_BASE_ADDR + 0x234);
250 writel(0x1C4, IOMUXC_BASE_ADDR + 0x624);
251 // enable GPIO1_9 for CLKO and GPIO1_8 for CLKO2
252 writel(0x00000004, 0x73fa83E8);
253 writel(0x00000004, 0x73fa83Ec);
255 // enable ARM clock div by 8
256 writel(0x010900F0, CCM_BASE_ADDR + CLKCTL_CCOSR);
258 /* Configure UART3_RXD pin for GPIO */
259 writel(0x3, IOMUXC_BASE_ADDR + 0x240);
260 reg = readl(GPIO1_BASE_ADDR + 0x4);
261 reg &= ~0x400000; // configure GPIO lines as input
262 writel(reg, GPIO1_BASE_ADDR + 0x4);
264 if ((readl(GPIO1_BASE_ADDR + 0x0) & (0x1 << 22)) == 0) {
266 system_rev |= 0x1 << BOARD_VER_OFFSET;
267 HAL_PLATFORM_EXTRA[32] = '5';
271 void mxc_mmc_init(unsigned int base_address)
273 switch(base_address) {
274 case MMC_SDHC1_BASE_ADDR:
275 /* SD1 CMD, SION bit */
276 writel(0x10, IOMUXC_BASE_ADDR + 0x394);
277 /* Configure SW PAD */
279 writel(0xd5, IOMUXC_BASE_ADDR + 0x79C);
281 writel(0xd5, IOMUXC_BASE_ADDR + 0x7A0);
283 writel(0xd5, IOMUXC_BASE_ADDR + 0x7A4);
285 writel(0xd5, IOMUXC_BASE_ADDR + 0x7A8);
287 writel(0xd5, IOMUXC_BASE_ADDR + 0x7AC);
289 writel(0xd5, IOMUXC_BASE_ADDR + 0x7B0);
291 case MMC_SDHC2_BASE_ADDR:
292 /* SD2 CMD, SION bit */
293 writel(0x10, IOMUXC_BASE_ADDR + 0x3b4);
294 /* Configure SW PAD */
296 writel(0x20f4, IOMUXC_BASE_ADDR + 0x7bc);
298 writel(0x20d4, IOMUXC_BASE_ADDR + 0x7c0);
300 writel(0x20e4, IOMUXC_BASE_ADDR + 0x7c4);
302 writel(0x21d4, IOMUXC_BASE_ADDR + 0x7c8);
304 writel(0x21d4, IOMUXC_BASE_ADDR + 0x7cc);
306 writel(0x20e4, IOMUXC_BASE_ADDR + 0x7d0);
312 #include CYGHWR_MEMORY_LAYOUT_H
314 typedef void code_fun(void);
316 void board_program_new_stack(void *func)
318 register CYG_ADDRESS stack_ptr asm("sp");
319 register CYG_ADDRESS old_stack asm("r4");
320 register code_fun *new_func asm("r0");
321 old_stack = stack_ptr;
322 stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
323 new_func = (code_fun*)func;
325 stack_ptr = old_stack;
328 void increase_core_voltage(bool i)
332 val = pmic_reg(24, 0, 0);
335 /* Set core voltage to 1.175V */
336 val = val & (~0x1F) | 0x17;
338 /* Set core voltage to 1.05V */
339 val = val & (~0x1F) | 0x12;
342 pmic_reg(24, val, 1);
345 extern unsigned int pmic_reg(unsigned int reg, unsigned int val, unsigned int write);
346 static void babbage_power_init(void)
349 volatile unsigned int reg;
351 /* Write needed to Power Gate 2 register */
352 val = pmic_reg(34, 0, 0);
354 pmic_reg(34, val, 1);
356 /* Write needed to update Charger 0 */
357 pmic_reg(48, 0x0023807F, 1);
359 if (((system_rev >> MAJOR_NUMBER_OFFSET) & 0xf) <= 0x2) {
360 /* Set core voltage to 1.1V */
361 val = pmic_reg(24, 0, 0);
362 val = val & (~0x1F) | 0x14;
363 pmic_reg(24, val, 1);
365 /* Setup VCC (SW2) to 1.25 */
366 val = pmic_reg(25, 0, 0);
367 val = val & (~0x1F) | 0x1A;
368 pmic_reg(25, val, 1);
370 /* Setup 1V2_DIG1 (SW3) to 1.25 */
371 val = pmic_reg(26, 0, 0);
372 val = val & (~0x1F) | 0x1A;
373 pmic_reg(26, val, 1);
375 /* Raise the core frequency to 800MHz */
376 writel(0x0, CCM_BASE_ADDR + CLKCTL_CACRR);
379 /* Setup VCC (SW2) to 1.225 */
380 val = pmic_reg(25, 0, 0);
381 val = val & (~0x1F) | 0x19;
382 pmic_reg(25, val, 1);
384 /* Setup 1V2_DIG1 (SW3) to 1.2 */
385 val = pmic_reg(26, 0, 0);
386 val = val & (~0x1F) | 0x18;
387 pmic_reg(26, val, 1);
390 if (((pmic_reg(7, 0, 0) & 0x1F) < REV_ATLAS_LITE_2_0) || (((pmic_reg(7, 0, 0) >> 9) & 0x3) == 0)) {
391 /* Set switchers in PWM mode for Atlas 2.0 and lower */
392 /* Setup the switcher mode for SW1 & SW2*/
393 val = pmic_reg(28, 0, 0);
394 val = val & (~0x3C0F) | 0x1405;
395 pmic_reg(28, val, 1);
397 /* Setup the switcher mode for SW3 & SW4 */
398 val = pmic_reg(29, 0, 0);
399 val = val & (~0xF0F) | 0x505;
400 pmic_reg(29, val, 1);
402 /* Set switchers in Auto in NORMAL mode & STANDBY mode for Atlas 2.0a */
403 /* Setup the switcher mode for SW1 & SW2*/
404 val = pmic_reg(28, 0, 0);
405 val = val & (~0x3C0F) | 0x2008;
406 pmic_reg(28, val, 1);
408 /* Setup the switcher mode for SW3 & SW4 */
409 val = pmic_reg(29, 0, 0);
410 val = val & (~0xF0F) | 0x808;
411 pmic_reg(29, val, 1);
414 /* Set VDIG to 1.65V, VGEN3 to 1.8V, VCAM to 2.5V */
415 val = pmic_reg(30, 0, 0);
418 pmic_reg(30, val, 1);
420 /* Set VVIDEO to 2.775V, VAUDIO to 3V, VSD to 3.15V */
421 val = pmic_reg(31, 0, 0);
424 pmic_reg(31, val, 1);
426 /* Configure VGEN3 and VCAM regulators to use external PNP */
428 pmic_reg(33, val, 1);
431 reg = readl(GPIO2_BASE_ADDR + 0x0);
432 reg &= ~0x4000; // Lower reset line
433 writel(reg, GPIO2_BASE_ADDR + 0x0);
435 reg = readl(GPIO2_BASE_ADDR + 0x4);
436 reg |= 0x4000; // configure GPIO lines as output
437 writel(reg, GPIO2_BASE_ADDR + 0x4);
439 /* Reset the ethernet controller over GPIO */
440 writel(0x1, IOMUXC_BASE_ADDR + 0x0AC);
442 /* Enable VGEN3, VCAM, VAUDIO, VVIDEO, VSD regulators */
444 pmic_reg(33, val, 1);
448 reg = readl(GPIO2_BASE_ADDR + 0x0);
450 writel(reg, GPIO2_BASE_ADDR + 0x0);
452 /* Setup the FEC after enabling the regulators */
456 void io_cfg_spi(struct imx_spi_dev *dev)
459 case CSPI1_BASE_ADDR:
460 // 000: Select mux mode: ALT0 mux port: MOSI of instance: ecspi1
461 writel(0x0, IOMUXC_BASE_ADDR + 0x210);
462 writel(0x105, IOMUXC_BASE_ADDR + 0x600);
464 // 000: Select mux mode: ALT0 mux port: MISO of instance: ecspi1.
465 writel(0x0, IOMUXC_BASE_ADDR + 0x214);
466 writel(0x105, IOMUXC_BASE_ADDR + 0x604);
468 // de-select SS1 of instance: ecspi1.
469 writel(0x3, IOMUXC_BASE_ADDR + 0x21C);
470 writel(0x85, IOMUXC_BASE_ADDR + 0x60C);
471 // 000: Select mux mode: ALT0 mux port: SS0 of instance: ecspi1.
472 writel(0x0, IOMUXC_BASE_ADDR + 0x218);
473 writel(0x185, IOMUXC_BASE_ADDR + 0x608);
474 } else if (dev->ss == 1) {
475 // de-select SS0 of instance: ecspi1.
476 writel(0x3, IOMUXC_BASE_ADDR + 0x218);
477 writel(0x85, IOMUXC_BASE_ADDR + 0x608);
478 // 000: Select mux mode: ALT0 mux port: SS1 of instance: ecspi1.
479 writel(0x0, IOMUXC_BASE_ADDR + 0x21C);
480 writel(0x105, IOMUXC_BASE_ADDR + 0x60C);
482 // 000: Select mux mode: ALT0 mux port: RDY of instance: ecspi1.
483 writel(0x0, IOMUXC_BASE_ADDR + 0x220);
484 writel(0x180, IOMUXC_BASE_ADDR + 0x610);
486 // 000: Select mux mode: ALT0 mux port: SCLK of instance: ecspi1.
487 writel(0x0, IOMUXC_BASE_ADDR + 0x224);
488 writel(0x105, IOMUXC_BASE_ADDR + 0x614);
490 case CSPI2_BASE_ADDR: