]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/mx51/babbage/v2_0/src/board_misc.c
TX51 pre-release
[karo-tx-redboot.git] / packages / hal / arm / mx51 / babbage / v2_0 / src / board_misc.c
1 //==========================================================================
2 //
3 //      board_misc.c
4 //
5 //      HAL misc board support code for the board
6 //
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.
12 //
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.
16 //
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
20 // for more details.
21 //
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.
25 //
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.
32 //
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.
35 //
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 //========================================================================*/
41
42 #include <pkgconf/hal.h>
43 #include <pkgconf/system.h>
44 #include <redboot.h>
45 #include CYGBLD_HAL_PLATFORM_H
46
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
50
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
59
60 // All the MM table layout is here:
61 #include <cyg/hal/hal_mm.h>
62
63 externC void* memset(void *, int, size_t);
64 unsigned int cpld_base_addr;
65
66 void hal_mmu_init(void)
67 {
68     unsigned long ttb_base = RAM_BANK0_BASE + 0x4000;
69     unsigned long i;
70
71     /*
72      * Set the TTB register
73      */
74     asm volatile ("mcr  p15,0,%0,c2,c0,0" : : "r"(ttb_base) /*:*/);
75
76     /*
77      * Set the Domain Access Control Register
78      */
79     i = ARM_ACCESS_DACR_DEFAULT;
80     asm volatile ("mcr  p15,0,%0,c3,c0,0" : : "r"(i) /*:*/);
81
82     /*
83      * First clear all TT entries - ie Set them to Faulting
84      */
85     memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
86
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 */
100 }
101
102 static void mxc_fec_setup(void)
103 {
104     volatile unsigned int reg;
105
106     /*FEC_MDIO*/
107     writel(0x3, IOMUXC_BASE_ADDR + 0x0D4);
108     writel(0x1FD, IOMUXC_BASE_ADDR + 0x0468);
109     writel(0x0, IOMUXC_BASE_ADDR + 0x0954);
110
111     /*FEC_MDC*/
112     writel(0x2, IOMUXC_BASE_ADDR + 0x13C);
113     writel(0x2004, IOMUXC_BASE_ADDR + 0x0524);
114
115     /* FEC RDATA[3] */
116     writel(0x3, IOMUXC_BASE_ADDR + 0x0EC);
117     writel(0x180, IOMUXC_BASE_ADDR + 0x0480);
118     writel(0x0, IOMUXC_BASE_ADDR + 0x0964);
119
120     /* FEC RDATA[2] */
121     writel(0x3, IOMUXC_BASE_ADDR + 0x0E8);
122     writel(0x180, IOMUXC_BASE_ADDR + 0x047C);
123     writel(0x0, IOMUXC_BASE_ADDR + 0x0960);
124
125     /* FEC RDATA[1] */
126     writel(0x3, IOMUXC_BASE_ADDR + 0x0d8);
127     writel(0x180, IOMUXC_BASE_ADDR + 0x046C);
128     writel(0x0, IOMUXC_BASE_ADDR + 0x095C);
129
130     /* FEC RDATA[0] */
131     writel(0x2, IOMUXC_BASE_ADDR + 0x016C);
132     writel(0x2180, IOMUXC_BASE_ADDR + 0x0554);
133     writel(0x0, IOMUXC_BASE_ADDR + 0x0958);
134
135     /* FEC TDATA[3] */
136     writel(0x2, IOMUXC_BASE_ADDR + 0x148);
137     writel(0x2004, IOMUXC_BASE_ADDR + 0x0530);
138
139     /* FEC TDATA[2] */
140     writel(0x2, IOMUXC_BASE_ADDR + 0x144);
141     writel(0x2004, IOMUXC_BASE_ADDR + 0x052C);
142
143     /* FEC TDATA[1] */
144     writel(0x2, IOMUXC_BASE_ADDR + 0x140);
145     writel(0x2004, IOMUXC_BASE_ADDR + 0x0528);
146
147     /* FEC TDATA[0] */
148     writel(0x2, IOMUXC_BASE_ADDR + 0x0170);
149     writel(0x2004, IOMUXC_BASE_ADDR + 0x0558);
150
151     /* FEC TX_EN */
152     writel(0x1, IOMUXC_BASE_ADDR + 0x014C);
153     writel(0x2004, IOMUXC_BASE_ADDR + 0x0534);
154
155     /* FEC TX_ER */
156     writel(0x2, IOMUXC_BASE_ADDR + 0x0138);
157     writel(0x2004, IOMUXC_BASE_ADDR + 0x0520);
158
159     /* FEC TX_CLK */
160     writel(0x1, IOMUXC_BASE_ADDR + 0x0150);
161     writel(0x2180, IOMUXC_BASE_ADDR + 0x0538);
162     writel(0x0, IOMUXC_BASE_ADDR + 0x0974);
163
164     /* FEC COL */
165     writel(0x1, IOMUXC_BASE_ADDR + 0x0124);
166     writel(0x2180, IOMUXC_BASE_ADDR + 0x0500);
167     writel(0x0, IOMUXC_BASE_ADDR + 0x094c);
168
169     /* FEC RX_CLK */
170     writel(0x1, IOMUXC_BASE_ADDR + 0x0128);
171     writel(0x2180, IOMUXC_BASE_ADDR + 0x0504);
172     writel(0x0, IOMUXC_BASE_ADDR + 0x0968);
173
174     /* FEC CRS */
175     writel(0x3, IOMUXC_BASE_ADDR + 0x0f4);
176     writel(0x180, IOMUXC_BASE_ADDR + 0x0488);
177     writel(0x0, IOMUXC_BASE_ADDR + 0x0950);
178
179     /* FEC RX_ER */
180     writel(0x3, IOMUXC_BASE_ADDR + 0x0f0);
181     writel(0x180, IOMUXC_BASE_ADDR + 0x0484);
182     writel(0x0, IOMUXC_BASE_ADDR + 0x0970);
183
184     /* FEC RX_DV */
185     writel(0x2, IOMUXC_BASE_ADDR + 0x164);
186     writel(0x2180, IOMUXC_BASE_ADDR + 0x054C);
187     writel(0x0, IOMUXC_BASE_ADDR + 0x096C);
188 }
189
190 #include <cyg/io/imx_spi.h>
191 struct spi_v2_3_reg spi_pmic_reg;
192
193 struct imx_spi_dev imx_spi_pmic = {
194     base : CSPI1_BASE_ADDR,
195     freq : 25000000,
196     ss_pol : IMX_SPI_ACTIVE_HIGH,
197     ss : 0,                     // slave select 0
198     fifo_sz : 32,
199     reg : &spi_pmic_reg,
200 };
201
202 struct spi_v2_3_reg spi_nor_reg;
203
204 struct imx_spi_dev imx_spi_nor = {
205     base : CSPI1_BASE_ADDR,
206     freq : 25000000,
207     ss_pol : IMX_SPI_ACTIVE_LOW,
208     ss : 1,                     // slave select 1
209     fifo_sz : 32,
210     us_delay: 0,
211     reg : &spi_nor_reg,
212 };
213
214 imx_spi_init_func_t *spi_nor_init;
215 imx_spi_xfer_func_t *spi_nor_xfer;
216
217 imx_spi_init_func_t *spi_pmic_init;
218 imx_spi_xfer_func_t *spi_pmic_xfer;
219
220 //
221 // Platform specific initialization
222 //
223 static void babbage_power_init(void);
224
225 void plf_hardware_init(void)
226 {
227     unsigned int reg;
228
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;
231
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);
235
236     babbage_power_init();
237
238     // UART1
239     //RXD
240     writel(0x0, IOMUXC_BASE_ADDR + 0x228);
241     writel(0x1C5, IOMUXC_BASE_ADDR + 0x618);
242     //TXD
243     writel(0x0, IOMUXC_BASE_ADDR + 0x22c);
244     writel(0x1C5, IOMUXC_BASE_ADDR + 0x61c);
245     //RTS
246     writel(0x0, IOMUXC_BASE_ADDR + 0x230);
247     writel(0x1C4, IOMUXC_BASE_ADDR + 0x620);
248     //CTS
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);
254
255     // enable ARM clock div by 8
256     writel(0x010900F0, CCM_BASE_ADDR + CLKCTL_CCOSR);
257
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);
263
264     if ((readl(GPIO1_BASE_ADDR + 0x0) & (0x1 << 22)) == 0) {
265         /* Babbage 2.5 */
266         system_rev |= 0x1 << BOARD_VER_OFFSET;
267         HAL_PLATFORM_EXTRA[32] = '5';
268     }
269 }
270
271 void mxc_mmc_init(unsigned int base_address)
272 {
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 */
278         /* SD1 CMD */
279         writel(0xd5, IOMUXC_BASE_ADDR + 0x79C);
280         /* SD1 CLK */
281         writel(0xd5, IOMUXC_BASE_ADDR + 0x7A0);
282         /* SD1 DAT0 */
283         writel(0xd5, IOMUXC_BASE_ADDR + 0x7A4);
284         /* SD1 DAT1 */
285         writel(0xd5, IOMUXC_BASE_ADDR + 0x7A8);
286         /* SD1 DAT2 */
287         writel(0xd5, IOMUXC_BASE_ADDR + 0x7AC);
288         /* SD1 DAT3 */
289         writel(0xd5, IOMUXC_BASE_ADDR + 0x7B0);
290         break;
291     case MMC_SDHC2_BASE_ADDR:
292         /* SD2 CMD, SION bit */
293         writel(0x10, IOMUXC_BASE_ADDR + 0x3b4);
294         /* Configure SW PAD */
295         /* SD2 CMD */
296         writel(0x20f4, IOMUXC_BASE_ADDR + 0x7bc);
297         /* SD2 CLK */
298         writel(0x20d4, IOMUXC_BASE_ADDR + 0x7c0);
299         /* SD2 DAT0 */
300         writel(0x20e4, IOMUXC_BASE_ADDR + 0x7c4);
301         /* SD2 DAT1 */
302         writel(0x21d4, IOMUXC_BASE_ADDR + 0x7c8);
303         /* SD2 DAT2 */
304         writel(0x21d4, IOMUXC_BASE_ADDR + 0x7cc);
305         /* SD2 DAT3 */
306         writel(0x20e4, IOMUXC_BASE_ADDR + 0x7d0);
307     default:
308         break;
309     }
310 }
311
312 #include CYGHWR_MEMORY_LAYOUT_H
313
314 typedef void code_fun(void);
315
316 void board_program_new_stack(void *func)
317 {
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;
324     new_func();
325     stack_ptr = old_stack;
326 }
327
328 void increase_core_voltage(bool i)
329 {
330     unsigned int val;
331
332     val = pmic_reg(24, 0, 0);
333
334     if (i) {
335         /* Set core voltage to 1.175V */
336         val = val & (~0x1F) | 0x17;
337     } else {
338         /* Set core voltage to 1.05V */
339         val = val & (~0x1F) | 0x12;
340     }
341
342     pmic_reg(24, val, 1);
343 }
344
345 extern unsigned int pmic_reg(unsigned int reg, unsigned int val, unsigned int write);
346 static void babbage_power_init(void)
347 {
348     unsigned int val;
349     volatile unsigned int reg;
350
351     /* Write needed to Power Gate 2 register */
352     val = pmic_reg(34, 0, 0);
353     val &= ~0x10000;
354     pmic_reg(34, val, 1);
355
356     /* Write needed to update Charger 0 */
357     pmic_reg(48, 0x0023807F, 1);
358
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);
364
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);
369
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);
374         hal_delay_us(50);
375         /* Raise the core frequency to 800MHz */
376         writel(0x0, CCM_BASE_ADDR + CLKCTL_CACRR);
377     } else {
378         /* TO 3.0 */
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);
383
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);
388     }
389
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);
396
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);
401     } else {
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);
407
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);
412     }
413
414     /* Set VDIG to 1.65V, VGEN3 to 1.8V, VCAM to 2.5V */
415     val = pmic_reg(30, 0, 0);
416     val &= ~0x34030;
417     val |= 0x10020;
418     pmic_reg(30, val, 1);
419
420     /* Set VVIDEO to 2.775V, VAUDIO to 3V, VSD to 3.15V */
421     val = pmic_reg(31, 0, 0);
422     val &= ~0x1FC;
423     val |= 0x1F4;
424     pmic_reg(31, val, 1);
425
426     /* Configure VGEN3 and VCAM regulators to use external PNP */
427     val = 0x208;
428     pmic_reg(33, val, 1);
429     hal_delay_us(200);
430
431     reg = readl(GPIO2_BASE_ADDR + 0x0);
432     reg &= ~0x4000;  // Lower reset line
433     writel(reg, GPIO2_BASE_ADDR + 0x0);
434
435     reg = readl(GPIO2_BASE_ADDR + 0x4);
436     reg |= 0x4000;  // configure GPIO lines as output
437     writel(reg, GPIO2_BASE_ADDR + 0x4);
438
439     /* Reset the ethernet controller over GPIO */
440     writel(0x1, IOMUXC_BASE_ADDR + 0x0AC);
441
442     /* Enable VGEN3, VCAM, VAUDIO, VVIDEO, VSD regulators */
443     val = 0x49249;
444     pmic_reg(33, val, 1);
445
446     hal_delay_us(500);
447
448     reg = readl(GPIO2_BASE_ADDR + 0x0);
449     reg |= 0x4000;
450     writel(reg, GPIO2_BASE_ADDR + 0x0);
451
452     /* Setup the FEC after enabling the regulators */
453     mxc_fec_setup();
454 }
455
456 void io_cfg_spi(struct imx_spi_dev *dev)
457 {
458     switch (dev->base) {
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);
463
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);
467         if (dev->ss == 0) {
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);
481         }
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);
485
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);
489         break;
490     case CSPI2_BASE_ADDR:
491     default:
492         break;
493     }
494 }