]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/freescale/mx35_3stack/mx35_3stack.c
imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
[karo-tx-uboot.git] / board / freescale / mx35_3stack / mx35_3stack.c
1 /*
2  * Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
3  *
4  * (C) Copyright 2008-2010 Freescale Semiconductor, Inc.
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24
25 #include <common.h>
26 #include <asm/io.h>
27 #include <asm/errno.h>
28 #include <asm/arch/mx35.h>
29 #include <asm/arch/mx35_pins.h>
30 #include <asm/arch/iomux.h>
31 #include <i2c.h>
32 #include <linux/types.h>
33
34 #ifdef CONFIG_CMD_MMC
35 #include <mmc.h>
36 #include <fsl_esdhc.h>
37 #endif
38
39 #ifdef CONFIG_ARCH_MMU
40 #include <asm/mmu.h>
41 #include <asm/arch/mmu.h>
42 #endif
43
44 DECLARE_GLOBAL_DATA_PTR;
45
46 static u32 system_rev;
47
48 u32 get_board_rev(void)
49 {
50         return system_rev;
51 }
52
53 static inline void setup_soc_rev(void)
54 {
55         int reg;
56         reg = __REG(IIM_BASE_ADDR + IIM_SREV);
57         if (!reg) {
58                 reg = __REG(ROMPATCH_REV);
59                 reg <<= 4;
60         } else
61                 reg += CHIP_REV_1_0;
62         system_rev = 0x35000 + (reg & 0xFF);
63 }
64
65 static inline void set_board_rev(int rev)
66 {
67         system_rev =  (system_rev & ~(0xF << 8)) | (rev & 0xF) << 8;
68 }
69
70 int is_soc_rev(int rev)
71 {
72         return (system_rev & 0xFF) - rev;
73 }
74
75 #ifdef CONFIG_ARCH_MMU
76 void board_mmu_init(void)
77 {
78         unsigned long ttb_base = PHYS_SDRAM_1 + 0x4000;
79         unsigned long i;
80
81         /*
82          * Set the TTB register
83          */
84         asm volatile ("mcr  p15,0,%0,c2,c0,0" : : "r"(ttb_base) /*:*/);
85
86         /*
87          * Set the Domain Access Control Register
88          */
89         i = ARM_ACCESS_DACR_DEFAULT;
90         asm volatile ("mcr  p15,0,%0,c3,c0,0" : : "r"(i) /*:*/);
91
92         /*
93          * First clear all TT entries - ie Set them to Faulting
94          */
95         memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
96         /* Actual   Virtual  Size   Attributes          Function */
97         /* Base     Base     MB     cached? buffered?  access permissions */
98         /* xxx00000 xxx00000 */
99         X_ARM_MMU_SECTION(0x000, 0xF00, 0x1,
100                           ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
101                           ARM_ACCESS_PERM_RW_RW); /* ROM */
102         X_ARM_MMU_SECTION(0x100, 0x100, 0x1,
103                           ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
104                           ARM_ACCESS_PERM_RW_RW); /* iRAM */
105         X_ARM_MMU_SECTION(0x300, 0x300, 0x1,
106                           ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
107                           ARM_ACCESS_PERM_RW_RW); /* L2CC */
108         /* Internal Regsisters upto SDRAM*/
109         X_ARM_MMU_SECTION(0x400, 0x400, 0x400,
110                           ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
111                           ARM_ACCESS_PERM_RW_RW);
112         X_ARM_MMU_SECTION(0x800, 0x000, 0x80,
113                           ARM_CACHEABLE, ARM_BUFFERABLE,
114                           ARM_ACCESS_PERM_RW_RW); /* SDRAM 0:128M*/
115         X_ARM_MMU_SECTION(0x800, 0x800, 0x80,
116                           ARM_CACHEABLE, ARM_BUFFERABLE,
117                           ARM_ACCESS_PERM_RW_RW); /* SDRAM 0:128M*/
118         X_ARM_MMU_SECTION(0x800, 0x880, 0x80,
119                           ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
120                           ARM_ACCESS_PERM_RW_RW); /* SDRAM 0:128M*/
121         X_ARM_MMU_SECTION(0x900, 0x900, 0x80,
122                           ARM_CACHEABLE, ARM_BUFFERABLE,
123                           ARM_ACCESS_PERM_RW_RW); /* SDRAM 1:128M*/
124         X_ARM_MMU_SECTION(0xA00, 0xA00, 0x40,
125                           ARM_CACHEABLE, ARM_BUFFERABLE,
126                           ARM_ACCESS_PERM_RW_RW); /* Flash */
127         X_ARM_MMU_SECTION(0xB00, 0xB00, 0x20,
128                           ARM_CACHEABLE, ARM_BUFFERABLE,
129                           ARM_ACCESS_PERM_RW_RW); /* PSRAM */
130         /* ESDCTL, WEIM, M3IF, EMI, NFC, External I/O */
131         X_ARM_MMU_SECTION(0xB20, 0xB20, 0x1E0,
132                           ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
133                           ARM_ACCESS_PERM_RW_RW);
134
135         /* Enable MMU */
136         MMU_ON();
137 }
138 #endif
139
140 int dram_init(void)
141 {
142         gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
143         gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
144
145         return 0;
146 }
147
148 int board_init(void)
149 {
150         int pad;
151
152 #ifdef CONFIG_MFG
153 /* MFG firmware need reset usb to avoid host crash firstly */
154 #define USBCMD 0x53FF4140
155         int val = readl(USBCMD);
156         val &= ~0x1; /*RS bit*/
157         writel(val, USBCMD);
158 #endif
159
160         setup_soc_rev();
161
162         /* enable clocks */
163         __REG(CCM_BASE_ADDR + CLKCTL_CGR0) |= 0x003F0000;
164         __REG(CCM_BASE_ADDR + CLKCTL_CGR1) |= 0x00030FFF;
165
166         /* setup pins for I2C1 */
167         mxc_request_iomux(MX35_PIN_I2C1_CLK, MUX_CONFIG_SION);
168         mxc_request_iomux(MX35_PIN_I2C1_DAT, MUX_CONFIG_SION);
169
170         pad = (PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE \
171                         | PAD_CTL_PUE_PUD | PAD_CTL_ODE_OpenDrain);
172
173         mxc_iomux_set_pad(MX35_PIN_I2C1_CLK, pad);
174         mxc_iomux_set_pad(MX35_PIN_I2C1_DAT, pad);
175
176         /* setup pins for FEC */
177         mxc_request_iomux(MX35_PIN_FEC_TX_CLK, MUX_CONFIG_FUNC);
178         mxc_request_iomux(MX35_PIN_FEC_RX_CLK, MUX_CONFIG_FUNC);
179         mxc_request_iomux(MX35_PIN_FEC_RX_DV, MUX_CONFIG_FUNC);
180         mxc_request_iomux(MX35_PIN_FEC_COL, MUX_CONFIG_FUNC);
181         mxc_request_iomux(MX35_PIN_FEC_RDATA0, MUX_CONFIG_FUNC);
182         mxc_request_iomux(MX35_PIN_FEC_TDATA0, MUX_CONFIG_FUNC);
183         mxc_request_iomux(MX35_PIN_FEC_TX_EN, MUX_CONFIG_FUNC);
184         mxc_request_iomux(MX35_PIN_FEC_MDC, MUX_CONFIG_FUNC);
185         mxc_request_iomux(MX35_PIN_FEC_MDIO, MUX_CONFIG_FUNC);
186         mxc_request_iomux(MX35_PIN_FEC_TX_ERR, MUX_CONFIG_FUNC);
187         mxc_request_iomux(MX35_PIN_FEC_RX_ERR, MUX_CONFIG_FUNC);
188         mxc_request_iomux(MX35_PIN_FEC_CRS, MUX_CONFIG_FUNC);
189         mxc_request_iomux(MX35_PIN_FEC_RDATA1, MUX_CONFIG_FUNC);
190         mxc_request_iomux(MX35_PIN_FEC_TDATA1, MUX_CONFIG_FUNC);
191         mxc_request_iomux(MX35_PIN_FEC_RDATA2, MUX_CONFIG_FUNC);
192         mxc_request_iomux(MX35_PIN_FEC_TDATA2, MUX_CONFIG_FUNC);
193         mxc_request_iomux(MX35_PIN_FEC_RDATA3, MUX_CONFIG_FUNC);
194         mxc_request_iomux(MX35_PIN_FEC_TDATA3, MUX_CONFIG_FUNC);
195
196         pad = (PAD_CTL_DRV_3_3V | PAD_CTL_PUE_PUD | PAD_CTL_ODE_CMOS | \
197                         PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW);
198
199         mxc_iomux_set_pad(MX35_PIN_FEC_TX_CLK, pad | PAD_CTL_HYS_SCHMITZ | \
200                         PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
201         mxc_iomux_set_pad(MX35_PIN_FEC_RX_CLK, pad | PAD_CTL_HYS_SCHMITZ | \
202                         PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
203         mxc_iomux_set_pad(MX35_PIN_FEC_RX_DV, pad | PAD_CTL_HYS_SCHMITZ | \
204                          PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
205         mxc_iomux_set_pad(MX35_PIN_FEC_COL, pad | PAD_CTL_HYS_SCHMITZ | \
206                           PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
207         mxc_iomux_set_pad(MX35_PIN_FEC_RDATA0, pad | PAD_CTL_HYS_SCHMITZ | \
208                           PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
209         mxc_iomux_set_pad(MX35_PIN_FEC_TDATA0, pad | PAD_CTL_HYS_CMOS | \
210                           PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
211         mxc_iomux_set_pad(MX35_PIN_FEC_TX_EN, pad | PAD_CTL_HYS_CMOS | \
212                           PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
213         mxc_iomux_set_pad(MX35_PIN_FEC_MDC, pad | PAD_CTL_HYS_CMOS | \
214                           PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
215         mxc_iomux_set_pad(MX35_PIN_FEC_MDIO, pad | PAD_CTL_HYS_SCHMITZ | \
216                           PAD_CTL_PKE_ENABLE | PAD_CTL_22K_PU);
217         mxc_iomux_set_pad(MX35_PIN_FEC_TX_ERR, pad | PAD_CTL_HYS_CMOS | \
218                           PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
219         mxc_iomux_set_pad(MX35_PIN_FEC_RX_ERR, pad | PAD_CTL_HYS_SCHMITZ | \
220                           PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
221         mxc_iomux_set_pad(MX35_PIN_FEC_CRS, pad | PAD_CTL_HYS_SCHMITZ | \
222                           PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
223         mxc_iomux_set_pad(MX35_PIN_FEC_RDATA1, pad | PAD_CTL_HYS_SCHMITZ | \
224                           PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
225         mxc_iomux_set_pad(MX35_PIN_FEC_TDATA1, pad | PAD_CTL_HYS_CMOS | \
226                           PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
227         mxc_iomux_set_pad(MX35_PIN_FEC_RDATA2, pad | PAD_CTL_HYS_SCHMITZ | \
228                           PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
229         mxc_iomux_set_pad(MX35_PIN_FEC_TDATA2, pad | PAD_CTL_HYS_CMOS | \
230                           PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
231         mxc_iomux_set_pad(MX35_PIN_FEC_RDATA3, pad | PAD_CTL_HYS_SCHMITZ | \
232                           PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
233         mxc_iomux_set_pad(MX35_PIN_FEC_TDATA3, pad | PAD_CTL_HYS_CMOS | \
234                           PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
235
236         gd->bd->bi_arch_number = MACH_TYPE_MX35_3DS;    /* board id for linux */
237         gd->bd->bi_boot_params = 0x80000100;    /* address of boot parameters */
238
239         return 0;
240 }
241
242 #ifdef BOARD_LATE_INIT
243 static inline int board_detect(void)
244 {
245         u8 buf[4];
246         int id;
247
248         if (i2c_read(0x08, 0x7, 1, buf, 3) < 0) {
249                 printf("board_late_init: read PMIC@0x08:0x7 fail\n");
250                 return 0;
251         }
252         id = (buf[0] << 16) + (buf[1] << 8) + buf[2];
253         printf("PMIC@0x08:0x7 is %x\n", id);
254         id = (id >> 6) & 0x7;
255         if (id == 0x7) {
256                 set_board_rev(1);
257                 return 1;
258         }
259         set_board_rev(0);
260         return 0;
261 }
262
263 int board_late_init(void)
264 {
265         u8 reg[3];
266         int i;
267
268         if (board_detect()) {
269                 mxc_request_iomux(MX35_PIN_WATCHDOG_RST, MUX_CONFIG_SION |
270                                         MUX_CONFIG_ALT1);
271                 printf("i.MX35 CPU board version 2.0\n");
272                 if (i2c_read(0x08, 0x1E, 1, reg, 3)) {
273                         printf("board_late_init: read PMIC@0x08:0x1E fail\n");
274                         return 0;
275                 }
276                 reg[2] |= 0x3;
277                 if (i2c_write(0x08, 0x1E, 1, reg, 3)) {
278                         printf("board_late_init: write PMIC@0x08:0x1E fail\n");
279                         return 0;
280                 }
281                 if (i2c_read(0x08, 0x20, 1, reg, 3)) {
282                         printf("board_late_init: read PMIC@0x08:0x20 fail\n");
283                         return 0;
284                 }
285                 reg[2] |= 0x1;
286                 if (i2c_write(0x08, 0x20, 1, reg, 3)) {
287                         printf("board_late_init: write PMIC@0x08:0x20 fail\n");
288                         return 0;
289                 }
290                 mxc_request_iomux(MX35_PIN_COMPARE, MUX_CONFIG_GPIO);
291                 mxc_iomux_set_input(MUX_IN_GPIO1_IN_5, INPUT_CTL_PATH0);
292                 __REG(GPIO1_BASE_ADDR + 0x04) |= 1 << 5;
293                 __REG(GPIO1_BASE_ADDR) |= 1 << 5;
294         } else
295                 printf("i.MX35 CPU board version 1.0\n");
296
297         if (i2c_read(0x69, 0x20, 1, reg, 1) < 0) {
298                 printf("board_late_init: read PMIC@0x69:0x20 fail\n");
299                 return 0;
300         }
301
302         reg[0] |= 0x4;
303         if (i2c_write(0x69, 0x20, 1, reg, 1) < 0) {
304                 printf("board_late_init: write back PMIC@0x69:0x20 fail\n");
305                 return 0;
306         }
307
308         for (i = 0; i < 1000; i++)
309                 udelay(200);
310
311         if (i2c_read(0x69, 0x1A, 1, reg, 1) < 0) {
312                 printf("board_late_init: read PMIC@0x69:0x1A fail\n");
313                 return 0;
314         }
315
316         reg[0] &= 0x7F;
317         if (i2c_write(0x69, 0x1A, 1, reg, 1) < 0) {
318                 printf("board_late_init: write back PMIC@0x69:0x1A fail\n");
319                 return 0;
320         }
321         for (i = 0; i < 1000; i++)
322                 udelay(200);
323
324         reg[0] |= 0x80;
325         if (i2c_write(0x69, 0x1A, 1, reg, 1) < 0) {
326                 printf("board_late_init: 2st write back PMIC@0x69:0x1A fail\n");
327                 return 0;
328         }
329
330         return 0;
331 }
332 #endif
333
334 int checkboard(void)
335 {
336         printf("Board: MX35 3STACK ");
337
338         if (system_rev & CHIP_REV_2_0)
339                 printf("2.0 [");
340         else
341                 printf("1.0 [");
342
343         switch (__REG(CCM_BASE_ADDR + CLKCTL_RCSR) & 0x0F) {
344         case 0x0000:
345                 printf("POR");
346                 break;
347         case 0x0002:
348                 printf("JTAG");
349                 break;
350         case 0x0004:
351                 printf("RST");
352                 break;
353         case 0x0008:
354                 printf("WDT");
355                 break;
356         default:
357                 printf("unknown");
358         }
359         printf("]\n");
360         return 0;
361 }
362
363 #if defined(CONFIG_SMC911X)
364 extern int smc911x_initialize(u8 dev_num, int base_addr);
365 #endif
366
367 int board_eth_init(bd_t *bis)
368 {
369         int rc = -ENODEV;
370 #if defined(CONFIG_SMC911X)
371         rc = smc911x_initialize(0, CONFIG_SMC911X_BASE);
372 #endif
373
374         cpu_eth_init(bis);
375
376         return rc;
377 }
378
379 #ifdef CONFIG_CMD_MMC
380
381 struct fsl_esdhc_cfg esdhc_cfg[2] = {
382         {MMC_SDHC1_BASE_ADDR, 1, 1},
383         {MMC_SDHC2_BASE_ADDR, 1, 1},
384 };
385
386 int esdhc_gpio_init(bd_t *bis)
387 {
388         u32 pad_val = 0, index = 0;
389         s32 status = 0;
390
391         /* IOMUX PROGRAMMING */
392         for (index = 0; index < CONFIG_SYS_FSL_ESDHC_NUM;
393                 ++index) {
394                 switch (index) {
395                 case 0:
396                         pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
397                                 PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_HIGH |
398                                 PAD_CTL_100K_PD | PAD_CTL_SRE_FAST;
399                         mxc_request_iomux(MX35_PIN_SD1_CMD,
400                                 MUX_CONFIG_FUNC | MUX_CONFIG_SION);
401                         mxc_iomux_set_pad(MX35_PIN_SD1_CMD, pad_val);
402
403                         pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
404                                         PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_HIGH |
405                                         PAD_CTL_100K_PU | PAD_CTL_SRE_FAST;
406                         mxc_request_iomux(MX35_PIN_SD1_CLK,
407                                         MUX_CONFIG_FUNC | MUX_CONFIG_SION);
408                         mxc_iomux_set_pad(MX35_PIN_SD1_CLK, pad_val);
409                         mxc_request_iomux(MX35_PIN_SD1_DATA0,
410                                         MUX_CONFIG_FUNC);
411                         mxc_iomux_set_pad(MX35_PIN_SD1_DATA0, pad_val);
412                         mxc_request_iomux(MX35_PIN_SD1_DATA3,
413                                         MUX_CONFIG_FUNC);
414                         mxc_iomux_set_pad(MX35_PIN_SD1_DATA3, pad_val);
415
416                         break;
417                 case 1:
418                         mxc_request_iomux(MX35_PIN_SD2_CLK,
419                                         MUX_CONFIG_FUNC | MUX_CONFIG_SION);
420                         mxc_request_iomux(MX35_PIN_SD2_CMD,
421                                         MUX_CONFIG_FUNC | MUX_CONFIG_SION);
422                         mxc_request_iomux(MX35_PIN_SD2_DATA0,
423                                         MUX_CONFIG_FUNC);
424                         mxc_request_iomux(MX35_PIN_SD2_DATA3,
425                                         MUX_CONFIG_FUNC);
426
427                         pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
428                                         PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_MAX |
429                                         PAD_CTL_100K_PD | PAD_CTL_SRE_FAST;
430                         mxc_iomux_set_pad(MX35_PIN_SD2_CMD, pad_val);
431
432                         pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
433                                         PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_HIGH |
434                                         PAD_CTL_100K_PU | PAD_CTL_SRE_FAST;
435                         mxc_iomux_set_pad(MX35_PIN_SD2_CLK, pad_val);
436                         mxc_iomux_set_pad(MX35_PIN_SD2_DATA0, pad_val);
437                         mxc_iomux_set_pad(MX35_PIN_SD2_DATA3, pad_val);
438
439                         break;
440                 default:
441                         printf("Warning: you configured more ESDHC controller"
442                                 "(%d) as supported by the board(2)\n",
443                                 CONFIG_SYS_FSL_ESDHC_NUM);
444                         return status;
445                         break;
446                 }
447                 status |= fsl_esdhc_initialize(bis, &esdhc_cfg[index]);
448         }
449
450         return status;
451 }
452
453 int board_mmc_init(bd_t *bis)
454 {
455         if (!esdhc_gpio_init(bis))
456                 return 0;
457         else
458                 return -1;
459 }
460 #endif