]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/mx51/babbage/v2_0/src/board_misc.c
Initial revision
[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 + 0x0470);
109     writel(0x0, IOMUXC_BASE_ADDR + 0x09B0);
110
111     /*FEC_RDATA1*/
112     writel(0x3, IOMUXC_BASE_ADDR + 0x0D8);
113     writel(0x180, IOMUXC_BASE_ADDR + 0x0474);
114     writel(0x0, IOMUXC_BASE_ADDR + 0x09B8);
115
116     /*FEC_RDATA2*/
117     writel(0x3, IOMUXC_BASE_ADDR + 0x0E8);
118     writel(0x180, IOMUXC_BASE_ADDR + 0x0484);
119     writel(0x0, IOMUXC_BASE_ADDR + 0x09BC);
120
121     /*FEC_RDATA3*/
122     writel(0x3, IOMUXC_BASE_ADDR + 0x0EC);
123     writel(0x180, IOMUXC_BASE_ADDR + 0x0488);
124     writel(0x0, IOMUXC_BASE_ADDR + 0x09C0);
125
126     /*FEC_RX_ERR*/
127     writel(0x3, IOMUXC_BASE_ADDR + 0x0F0);
128     writel(0x180, IOMUXC_BASE_ADDR + 0x048C);
129     writel(0x0, IOMUXC_BASE_ADDR + 0x09CC);
130
131     /*FEC_CRS*/
132     writel(0x3, IOMUXC_BASE_ADDR + 0x0F4);
133     writel(0x180, IOMUXC_BASE_ADDR + 0x0490);
134     writel(0x0, IOMUXC_BASE_ADDR + 0x09AC);
135
136     /*FEC_COL*/
137     writel(0x1, IOMUXC_BASE_ADDR + 0x0124);
138     writel(0x180, IOMUXC_BASE_ADDR + 0x05CC);
139     writel(0x0, IOMUXC_BASE_ADDR + 0x9A8);
140
141     /*FEC_RX_CLK*/
142     writel(0x1, IOMUXC_BASE_ADDR + 0x0128);
143     writel(0x180, IOMUXC_BASE_ADDR + 0x05D0);
144     writel(0x0, IOMUXC_BASE_ADDR + 0x09C4);
145
146     /*FEC_RX_DV*/
147     writel(0x1, IOMUXC_BASE_ADDR + 0x012C);
148     writel(0x180, IOMUXC_BASE_ADDR + 0x05D4);
149     writel(0x0, IOMUXC_BASE_ADDR + 0x09C8);
150
151     /*FEC_RDATA0*/
152     writel(0x1, IOMUXC_BASE_ADDR + 0x0134);
153     writel(0x2180, IOMUXC_BASE_ADDR + 0x05DC);
154     writel(0x0, IOMUXC_BASE_ADDR + 0x09B4);
155
156     /*FEC_TDATA0*/
157     writel(0x1, IOMUXC_BASE_ADDR + 0x0138);
158     writel(0x2004, IOMUXC_BASE_ADDR + 0x5E0);
159
160     /*FEC_TX_ERR*/
161     writel(0x2, IOMUXC_BASE_ADDR + 0x0144);
162     writel(0x2004, IOMUXC_BASE_ADDR + 0x05EC);
163
164     /*FEC_MDC*/
165     writel(0x2, IOMUXC_BASE_ADDR + 0x0148);
166     writel(0x2004, IOMUXC_BASE_ADDR + 0x05F0);
167
168     /*FEC_TDATA1*/
169     writel(0x2, IOMUXC_BASE_ADDR + 0x014C);
170     writel(0x2004, IOMUXC_BASE_ADDR + 0x05F4);
171
172     /*FEC_TDATA2*/
173     writel(0x2, IOMUXC_BASE_ADDR + 0x0150);
174     writel(0x2004, IOMUXC_BASE_ADDR + 0x05F8);
175
176     /*FEC_TDATA3*/
177     writel(0x2, IOMUXC_BASE_ADDR + 0x0154);
178     writel(0x2004, IOMUXC_BASE_ADDR + 0x05FC);
179
180     /*FEC_TX_EN*/
181     writel(0x1, IOMUXC_BASE_ADDR + 0x0158);
182     writel(0x2004, IOMUXC_BASE_ADDR + 0x0600);
183
184     /*FEC_TX_CLK*/
185     writel(0x1, IOMUXC_BASE_ADDR + 0x015C);
186     writel(0x2180, IOMUXC_BASE_ADDR + 0x0604);
187     writel(0x0, IOMUXC_BASE_ADDR + 0x09D0);
188
189     reg = readl(GPIO2_BASE_ADDR + 0x0);
190     reg &= ~0x4000;  // Lower reset line
191     writel(reg, GPIO2_BASE_ADDR + 0x0);
192
193     reg = readl(GPIO2_BASE_ADDR + 0x4);
194     reg |= 0x4000;  // configure GPIO lines as output
195     writel(reg, GPIO2_BASE_ADDR + 0x4);
196
197     /* Reset the ethernet controller over GPIO */
198     writel(0x1, IOMUXC_BASE_ADDR + 0x0AC);
199
200     hal_delay_us(200);
201
202     reg = readl(GPIO2_BASE_ADDR + 0x0);
203     reg |= 0x4000;
204     writel(reg, GPIO2_BASE_ADDR + 0x0);
205 }
206
207 #include <cyg/io/imx_spi.h>
208 struct spi_v2_3_reg spi_pmic_reg;
209
210 struct imx_spi_dev imx_spi_pmic = {
211     base : CSPI1_BASE_ADDR,
212     freq : 25000000,
213     ss_pol : IMX_SPI_ACTIVE_HIGH,
214     ss : 0,                     // slave select 0
215     fifo_sz : 64 * 4,
216     reg : &spi_pmic_reg,
217 };
218
219 struct spi_v2_3_reg spi_nor_reg;
220
221 struct imx_spi_dev imx_spi_nor = {
222     base : CSPI1_BASE_ADDR,
223     freq : 25000000,
224     ss_pol : IMX_SPI_ACTIVE_LOW,
225     ss : 1,                     // slave select 1
226     fifo_sz : 64 * 4,
227     us_delay: 0,
228     reg : &spi_nor_reg,
229 };
230
231 imx_spi_init_func_t *spi_nor_init;
232 imx_spi_xfer_func_t *spi_nor_xfer;
233
234 imx_spi_init_func_t *spi_pmic_init;
235 imx_spi_xfer_func_t *spi_pmic_xfer;
236
237 //
238 // Platform specific initialization
239 //
240
241 void plf_hardware_init(void)
242 {
243     unsigned int reg;
244
245     /* Disable IPU and HSC dividers */
246     writel(0x60000, CCM_BASE_ADDR + CLKCTL_CCDR);
247     /* Change the DDR divider to run at 166MHz on CPU 2 */
248     reg = readl(CCM_BASE_ADDR + CLKCTL_CBCDR);
249     reg = (reg & (~0x70000)) | 0x40000;
250     writel(reg, CCM_BASE_ADDR + CLKCTL_CBCDR);
251      /* make sure divider effective */
252     while (readl(CCM_BASE_ADDR + CLKCTL_CDHIPR) != 0);
253     writel(0x0, CCM_BASE_ADDR + CLKCTL_CCDR);
254
255     // UART1
256     //RXD
257     writel(0x0, IOMUXC_BASE_ADDR + 0x234);
258     writel(0x1C5, IOMUXC_BASE_ADDR + 0x6E4);
259
260     //TXD
261     writel(0x0, IOMUXC_BASE_ADDR + 0x238);
262     writel(0x1C5, IOMUXC_BASE_ADDR + 0x6E8);
263
264     //RTS
265     writel(0x0, IOMUXC_BASE_ADDR + 0x23C);
266     writel(0x1C4, IOMUXC_BASE_ADDR + 0x6EC);
267
268     //CTS
269     writel(0x0, IOMUXC_BASE_ADDR + 0x240);
270     writel(0x1C4, IOMUXC_BASE_ADDR + 0x6F0);
271
272     // enable GPIO1_9 for CLKO and GPIO1_8 for CLKO2
273     writel(0x00000004, 0x73fa83F4);
274     writel(0x00000004, 0x73fa83F0);
275     // enable ARM clock div by 8
276     writel(0x010900F0, CCM_BASE_ADDR + CLKCTL_CCOSR);
277
278     spi_nor_init = (imx_spi_init_func_t *)imx_spi_init_v2_3;
279     spi_nor_xfer = (imx_spi_xfer_func_t *)imx_spi_xfer_v2_3;
280
281     spi_pmic_init = (imx_spi_init_func_t *)imx_spi_init_v2_3;
282     spi_pmic_xfer = (imx_spi_xfer_func_t *)imx_spi_xfer_v2_3;
283 }
284
285 void mxc_mmc_init(unsigned int base_address)
286 {
287     switch(base_address) {
288     case MMC_SDHC1_BASE_ADDR:
289         //diag_printf("Configure IOMUX of ESDHC1 on i.MX51\n");
290         /* SD1 CMD, SION bit */
291         writel(0x10, IOMUXC_BASE_ADDR + 0x39c);
292
293         /* SD1 CD, as gpio1_0 */
294         writel(0x01, IOMUXC_BASE_ADDR + 0x3b4);
295         /* Configure SW PAD */
296         /* SD1 CMD */
297         writel(0x20d4, IOMUXC_BASE_ADDR + 0x868);
298         /* SD1 CLK */
299         writel(0x20d4, IOMUXC_BASE_ADDR + 0x86c);
300         /* SD1 DAT0 */
301         writel(0x20d4, IOMUXC_BASE_ADDR + 0x870);
302         /* SD1 DAT1 */
303         writel(0x20d4, IOMUXC_BASE_ADDR + 0x874);
304         /* SD1 DAT2 */
305         writel(0x20d4, IOMUXC_BASE_ADDR + 0x878);
306         /* SD1 DAT3 */
307         writel(0x20d4, IOMUXC_BASE_ADDR + 0x87c);
308         /* SD1 CD as gpio1_0 */
309         writel(0x1e2, IOMUXC_BASE_ADDR + 0x880);
310         break;
311     default:
312         break;
313     }
314 }
315
316 #include CYGHWR_MEMORY_LAYOUT_H
317
318 typedef void code_fun(void);
319
320 void board_program_new_stack(void *func)
321 {
322     register CYG_ADDRESS stack_ptr asm("sp");
323     register CYG_ADDRESS old_stack asm("r4");
324     register code_fun *new_func asm("r0");
325     old_stack = stack_ptr;
326     stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
327     new_func = (code_fun*)func;
328     new_func();
329     stack_ptr = old_stack;
330 }
331
332 void increase_core_voltage(bool i)
333 {
334     unsigned int val;
335
336     val = pmic_reg(24, 0, 0);
337
338     if (i) {
339         /* Set core voltage to 1.175V */
340         val = val & (~0x1F) | 0x17;
341     } else {
342         /* Set core voltage to 1.05V */
343         val = val & (~0x1F) | 0x12;
344     }
345
346     pmic_reg(24, val, 1);
347 }
348
349 extern unsigned int pmic_reg(unsigned int reg, unsigned int val, unsigned int write);
350 static void babbage_power_init(void)
351 {
352     unsigned int val;
353
354     /* power up the system first */
355     pmic_reg(34, 0x00200000, 1);
356
357     if (pll_clock(PLL1) > 800000000) {
358         /* Set core voltage to 1.175V */
359         val = pmic_reg(24, 0, 0);
360         val = val & (~0x1F) | 0x17;
361         pmic_reg(24, val, 1);
362     }
363
364     /* Set VDIG to 1.65V, VGEN3 to 1.8V, VCAM to 2.5V */
365     val = pmic_reg(30, 0, 0);
366     val &= ~0x34030;
367     val |= 0x10020;
368     pmic_reg(30, val, 1);
369
370     /* Set VVIDEO to 2.775V, VAUDIO to 2.775V, VSD to 3.15V */
371     val = pmic_reg(31, 0, 0);
372     val &= ~0x1FC;
373     val |= 0x1F4;
374     pmic_reg(31, val, 1);
375
376     /* Configure VGEN3 and VCAM regulators to use external PNP */
377     val = 0x208;
378     pmic_reg(33, val, 1);
379     hal_delay_us(200);
380
381     /* Enable VGEN1 regulator */
382     val = pmic_reg(32, val, 0);
383     val |= 0x1;
384     pmic_reg(32, val, 1);
385
386     /* Enable VGEN3, VCAM, VAUDIO, VVIDEO, VSD regulators */
387     val = 0x49249;
388     pmic_reg(33, val, 1);
389
390     hal_delay_us(200);
391
392     /* Setup the FEC after enabling the regulators */
393     mxc_fec_setup();
394 }
395
396 RedBoot_init(babbage_power_init, RedBoot_INIT_PRIO(900));
397
398 void io_cfg_spi(struct imx_spi_dev *dev)
399 {
400     switch (dev->base) {
401     case CSPI1_BASE_ADDR:
402         // 000: Select mux mode: ALT0 mux port: MOSI of instance: ecspi1
403         writel(0x0, IOMUXC_BASE_ADDR + 0x21C);
404         writel(0x105, IOMUXC_BASE_ADDR + 0x6CC);
405
406         // 000: Select mux mode: ALT0 mux port: MISO of instance: ecspi1.
407         writel(0x0, IOMUXC_BASE_ADDR + 0x220);
408         writel(0x105, IOMUXC_BASE_ADDR + 0x6D0);
409         if (dev->ss == 0) {
410             // de-select SS1 of instance: ecspi1.
411             writel(0x3, IOMUXC_BASE_ADDR + 0x228);
412             writel(0x85, IOMUXC_BASE_ADDR + 0x6D8);
413             // 000: Select mux mode: ALT0 mux port: SS0 of instance: ecspi1.
414             writel(0x0, IOMUXC_BASE_ADDR + 0x224);
415             writel(0x185, IOMUXC_BASE_ADDR + 0x6D4);
416         } else if (dev->ss == 1) {
417             // de-select SS0 of instance: ecspi1.
418             writel(0x3, IOMUXC_BASE_ADDR + 0x224);
419             writel(0x85, IOMUXC_BASE_ADDR + 0x6D4);
420             // 000: Select mux mode: ALT0 mux port: SS1 of instance: ecspi1.
421             writel(0x0, IOMUXC_BASE_ADDR + 0x228);
422             writel(0x105, IOMUXC_BASE_ADDR + 0x6D8);
423         }
424         // 000: Select mux mode: ALT0 mux port: RDY of instance: ecspi1.
425         writel(0x0, IOMUXC_BASE_ADDR + 0x22C);
426         writel(0x180, IOMUXC_BASE_ADDR + 0x6DC);
427
428         // 000: Select mux mode: ALT0 mux port: SCLK of instance: ecspi1.
429         writel(0x0, IOMUXC_BASE_ADDR + 0x230);
430         writel(0x105, IOMUXC_BASE_ADDR + 0x6E0);
431         break;
432     case CSPI2_BASE_ADDR:
433     default:
434         break;
435     }
436 }