]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - board/freescale/mx25_3stack/mx25_3stack.c
imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
[karo-tx-uboot.git] / board / freescale / mx25_3stack / mx25_3stack.c
1 /*
2  * (c) Copyright 2009-2010 Freescale Semiconductor
3  *
4  * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
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
26 #include <common.h>
27 #include <asm/io.h>
28 #include <asm/errno.h>
29 #include <asm/arch/mx25.h>
30 #include <asm/arch/mx25-regs.h>
31 #include <asm/arch/mx25_pins.h>
32 #include <asm/arch/iomux.h>
33 #include <asm/arch/gpio.h>
34 #include <imx_spi.h>
35
36 #ifdef CONFIG_LCD
37 #include <mx2fb.h>
38 #include <lcd.h>
39 #endif
40
41 #ifdef CONFIG_GET_FEC_MAC_ADDR_FROM_IIM
42 #include <asm/imx_iim.h>
43 #endif
44
45 #ifdef CONFIG_CMD_MMC
46 #include <mmc.h>
47 #include <fsl_esdhc.h>
48 #endif
49
50 DECLARE_GLOBAL_DATA_PTR;
51
52 static u32 system_rev;
53 #ifdef CONFIG_LCD
54 char lcd_cmap[256];
55 #endif
56
57 u32 get_board_rev(void)
58 {
59         return system_rev;
60 }
61
62 static inline void setup_soc_rev(void)
63 {
64         int reg;
65         reg = __REG(IIM_BASE + IIM_SREV);
66         if (!reg) {
67                 reg = __REG(ROMPATCH_REV);
68                 reg <<= 4;
69         } else
70                 reg += CHIP_REV_1_0;
71         system_rev = 0x25000 + (reg & 0xFF);
72 }
73
74 inline int is_soc_rev(int rev)
75 {
76         return (system_rev & 0xFF) - rev;
77 }
78
79 int dram_init(void)
80 {
81         gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
82         gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
83
84         return 0;
85 }
86
87 #ifdef CONFIG_CMD_MMC
88
89 struct fsl_esdhc_cfg esdhc_cfg[2] = {
90         {MMC_SDHC1_BASE, 1, 1},
91         {MMC_SDHC2_BASE, 1, 1},
92 };
93
94 int esdhc_gpio_init(bd_t *bis)
95 {
96         s32 status = 0;
97         u32 index = 0;
98         u32 val = 0;
99
100         for (index = 0; index < CONFIG_SYS_FSL_ESDHC_NUM;
101                 ++index) {
102                 switch (index) {
103                 case 0:
104                         /* Pins */
105                         writel(0x10, IOMUXC_BASE + 0x190); /* SD1_CMD */
106                         writel(0x10, IOMUXC_BASE + 0x194); /* SD1_CLK */
107                         writel(0x00, IOMUXC_BASE + 0x198); /* SD1_DATA0 */
108                         writel(0x00, IOMUXC_BASE + 0x19c); /* SD1_DATA1 */
109                         writel(0x00, IOMUXC_BASE + 0x1a0); /* SD1_DATA2 */
110                         writel(0x00, IOMUXC_BASE + 0x1a4); /* SD1_DATA3 */
111                         writel(0x06, IOMUXC_BASE + 0x094); /* D12 (SD1_DATA4) */
112                         writel(0x06, IOMUXC_BASE + 0x090); /* D13 (SD1_DATA5) */
113                         writel(0x06, IOMUXC_BASE + 0x08c); /* D14 (SD1_DATA6) */
114                         writel(0x06, IOMUXC_BASE + 0x088); /* D15 (SD1_DATA7) */
115                         writel(0x05, IOMUXC_BASE + 0x010); /* A14 (SD1_WP) */
116                         writel(0x05, IOMUXC_BASE + 0x014); /* A15 (SD1_DET) */
117
118                         /* Pads */
119                         writel(0xD1, IOMUXC_BASE + 0x388); /* SD1_CMD */
120                         writel(0xD1, IOMUXC_BASE + 0x38c); /* SD1_CLK */
121                         writel(0xD1, IOMUXC_BASE + 0x390); /* SD1_DATA0 */
122                         writel(0xD1, IOMUXC_BASE + 0x394); /* SD1_DATA1 */
123                         writel(0xD1, IOMUXC_BASE + 0x398); /* SD1_DATA2 */
124                         writel(0xD1, IOMUXC_BASE + 0x39c); /* SD1_DATA3 */
125                         writel(0xD1, IOMUXC_BASE + 0x28c); /* D12 (SD1_DATA4) */
126                         writel(0xD1, IOMUXC_BASE + 0x288); /* D13 (SD1_DATA5) */
127                         writel(0xD1, IOMUXC_BASE + 0x284); /* D14 (SD1_DATA6) */
128                         writel(0xD1, IOMUXC_BASE + 0x280); /* D15 (SD1_DATA7) */
129                         writel(0xD1, IOMUXC_BASE + 0x230); /* A14 (SD1_WP) */
130                         writel(0xD1, IOMUXC_BASE + 0x234); /* A15 (SD1_DET) */
131
132                         /*
133                          * Set write protect and card detect gpio as inputs
134                          * A14 (SD1_WP) and A15 (SD1_DET)
135                          */
136                         val = ~(3 << 0) & readl(GPIO1_BASE + GPIO_GDIR);
137                         writel(val, GPIO1_BASE + GPIO_GDIR);
138                         break;
139                 case 1:
140                         /* Pins */
141                         writel(0x16, IOMUXC_BASE + 0x0e8); /* LD8 (SD1_CMD) */
142                         writel(0x16, IOMUXC_BASE + 0x0ec); /* LD9 (SD1_CLK) */
143                         writel(0x06, IOMUXC_BASE + 0x0f0); /* LD10 (SD1_DATA0)*/
144                         writel(0x06, IOMUXC_BASE + 0x0f4); /* LD11 (SD1_DATA1)*/
145                         writel(0x06, IOMUXC_BASE + 0x0f8); /* LD12 (SD1_DATA2)*/
146                         writel(0x06, IOMUXC_BASE + 0x0fc); /* LD13 (SD1_DATA3)*/
147                         /* CSI_D2 (SD1_DATA4) */
148                         writel(0x02, IOMUXC_BASE + 0x120);
149                         /* CSI_D3 (SD1_DATA5) */
150                         writel(0x02, IOMUXC_BASE + 0x124);
151                         /* CSI_D4 (SD1_DATA6) */
152                         writel(0x02, IOMUXC_BASE + 0x128);
153                         /* CSI_D5 (SD1_DATA7) */
154                         writel(0x02, IOMUXC_BASE + 0x12c);
155
156                         /* Pads */
157                         writel(0xD1, IOMUXC_BASE + 0x2e0); /* LD8 (SD1_CMD) */
158                         writel(0xD1, IOMUXC_BASE + 0x2e4); /* LD9 (SD1_CLK) */
159                         writel(0xD1, IOMUXC_BASE + 0x2e8); /* LD10 (SD1_DATA0)*/
160                         writel(0xD1, IOMUXC_BASE + 0x2ec); /* LD11 (SD1_DATA1)*/
161                         writel(0xD1, IOMUXC_BASE + 0x2f0); /* LD12 (SD1_DATA2)*/
162                         writel(0xD1, IOMUXC_BASE + 0x2f4); /* LD13 (SD1_DATA3)*/
163                         /* CSI_D2 (SD1_DATA4) */
164                         writel(0xD1, IOMUXC_BASE + 0x318);
165                         /* CSI_D3 (SD1_DATA5) */
166                         writel(0xD1, IOMUXC_BASE + 0x31c);
167                         /* CSI_D4 (SD1_DATA6) */
168                         writel(0xD1, IOMUXC_BASE + 0x320);
169                         /* CSI_D5 (SD1_DATA7) */
170                         writel(0xD1, IOMUXC_BASE + 0x324);
171                         break;
172                 default:
173                         printf("Warning: you configured more ESDHC controller"
174                                 "(%d) as supported by the board(2)\n",
175                                 CONFIG_SYS_FSL_ESDHC_NUM);
176                         return status;
177                         break;
178                 }
179                 status |= fsl_esdhc_initialize(bis, &esdhc_cfg[index]);
180         }
181         return 0;
182 }
183
184 int board_mmc_init(bd_t *bis)
185 {
186         if (!esdhc_gpio_init(bis))
187                 return 0;
188         else
189                 return -1;
190 }
191 #endif
192
193 s32 spi_get_cfg(struct imx_spi_dev_t *dev)
194 {
195         switch (dev->slave.cs) {
196         case 0:
197                 /* cpld */
198                 dev->base = CSPI1_BASE;
199                 dev->freq = 25000000;
200                 dev->ss_pol = IMX_SPI_ACTIVE_LOW;
201                 dev->ss = 0;
202                 dev->fifo_sz = 32;
203                 dev->us_delay = 0;
204                 break;
205         default:
206                 printf("Invalid Bus ID! \n");
207                 break;
208         }
209
210         return 0;
211 }
212
213 void spi_io_init(struct imx_spi_dev_t *dev)
214 {
215         switch (dev->base) {
216         case CSPI1_BASE:
217                 writel(0, IOMUXC_BASE + 0x180);         /* CSPI1 SCLK */
218                 writel(0x1C0, IOMUXC_BASE + 0x5c4);
219                 writel(0, IOMUXC_BASE + 0x184);         /* SPI_RDY */
220                 writel(0x1E0, IOMUXC_BASE + 0x5c8);
221                 writel(0, IOMUXC_BASE + 0x170);         /* MOSI */
222                 writel(0x1C0, IOMUXC_BASE + 0x5b4);
223                 writel(0, IOMUXC_BASE + 0x174);         /* MISO */
224                 writel(0x1C0, IOMUXC_BASE + 0x5b8);
225                 writel(0, IOMUXC_BASE + 0x17C);         /* SS1 */
226                 writel(0x1E0, IOMUXC_BASE + 0x5C0);
227                 break;
228         default:
229                 break;
230         }
231 }
232
233 #ifdef CONFIG_LCD
234
235 vidinfo_t panel_info = {
236         vl_refresh:60,
237         vl_col:640,
238         vl_row:480,
239         vl_pixclock:39683,
240         vl_left_margin:45,
241         vl_right_margin:114,
242         vl_upper_margin:33,
243         vl_lower_margin:11,
244         vl_hsync:1,
245         vl_vsync:1,
246         vl_sync : FB_SYNC_CLK_LAT_FALL,
247         vl_mode:0,
248         vl_flag:0,
249         vl_bpix:4,
250         cmap : (void *)lcd_cmap,
251 };
252
253 void lcdc_hw_init(void)
254 {
255         /* Set VSTBY_REQ as GPIO3[17] on ALT5 */
256         mxc_request_iomux(MX25_PIN_VSTBY_REQ, MUX_CONFIG_ALT5);
257
258         /* Set GPIO3[17] as output */
259         writel(0x20000, GPIO3_BASE + 0x04);
260
261         /* Set GPIOE as LCDC_LD[16] on ALT2 */
262         mxc_request_iomux(MX25_PIN_GPIO_E, MUX_CONFIG_ALT2);
263
264         /* Set GPIOF as LCDC_LD[17] on ALT2 */
265         mxc_request_iomux(MX25_PIN_GPIO_F, MUX_CONFIG_ALT2);
266
267         /* Enable pull up on LCDC_LD[16]        */
268         mxc_iomux_set_pad(MX25_PIN_GPIO_E,
269                         PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU);
270
271         /* Enable pull up on LCDC_LD[17]        */
272         mxc_iomux_set_pad(MX25_PIN_GPIO_F,
273                         PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU);
274
275         /* Enable Pull/Keeper for pad LSCKL */
276         mxc_iomux_set_pad(MX25_PIN_LSCLK,
277                         PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD |
278                         PAD_CTL_100K_PU | PAD_CTL_SRE_FAST);
279
280         gd->fb_base = CONFIG_FB_BASE;
281 }
282
283 #ifdef CONFIG_SPLASH_SCREEN
284 int setup_splash_img()
285 {
286 #ifdef CONFIG_SPLASH_IS_IN_MMC
287         int mmc_dev = CONFIG_SPLASH_IMG_MMC_DEV;
288         ulong offset = CONFIG_SPLASH_IMG_OFFSET;
289         ulong size = CONFIG_SPLASH_IMG_SIZE;
290         ulong addr = 0;
291         char *s = NULL;
292         struct mmc *mmc = find_mmc_device(mmc_dev);
293         uint blk_start, blk_cnt, n;
294
295         s = getenv("splashimage");
296
297         if (NULL == s) {
298                 puts("env splashimage not found!\n");
299                 return -1;
300         }
301         addr = simple_strtoul(s, NULL, 16);
302
303         if (!mmc) {
304                 printf("MMC Device %d not found\n",
305                         mmc_dev);
306                 return -1;
307         }
308
309         if (mmc_init(mmc)) {
310                 puts("MMC init failed\n");
311                 return  -1;
312         }
313
314         blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
315         blk_cnt   = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len;
316         n = mmc->block_dev.block_read(mmc_dev, blk_start,
317                                         blk_cnt, (u_char *)addr);
318         flush_cache((ulong)addr, blk_cnt * mmc->read_bl_len);
319
320         return (n == blk_cnt) ? 0 : -1;
321 #endif
322 }
323 #endif
324 #endif
325
326 #ifdef CONFIG_GET_FEC_MAC_ADDR_FROM_IIM
327
328 int fec_get_mac_addr(unsigned char *mac)
329 {
330         u32 *iim0_mac_base =
331                 (u32 *)(IIM_BASE + IIM_BANK_AREA_0_OFFSET +
332                         CONFIG_IIM_MAC_ADDR_OFFSET);
333         int i;
334
335         for (i = 0; i < 6; ++i, ++iim0_mac_base)
336                 mac[i] = readl(iim0_mac_base);
337
338         return 0;
339 }
340 #endif
341
342 int board_init(void)
343 {
344
345 #ifdef CONFIG_MFG
346         /* MFG firmware need reset usb to avoid host crash firstly */
347 #define USBCMD 0x140
348         int val = readl(USB_BASE + USBCMD);
349         val &= ~0x1; /*RS bit*/
350         writel(val, USB_BASE + USBCMD);
351 #endif
352
353         setup_soc_rev();
354
355         /* setup pins for UART1 */
356         /* UART 1 IOMUX Configs */
357         mxc_request_iomux(MX25_PIN_UART1_RXD, MUX_CONFIG_FUNC);
358         mxc_request_iomux(MX25_PIN_UART1_TXD, MUX_CONFIG_FUNC);
359         mxc_request_iomux(MX25_PIN_UART1_RTS, MUX_CONFIG_FUNC);
360         mxc_request_iomux(MX25_PIN_UART1_CTS, MUX_CONFIG_FUNC);
361         mxc_iomux_set_pad(MX25_PIN_UART1_RXD,
362                         PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
363                         PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
364         mxc_iomux_set_pad(MX25_PIN_UART1_TXD,
365                         PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
366         mxc_iomux_set_pad(MX25_PIN_UART1_RTS,
367                         PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
368                         PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
369         mxc_iomux_set_pad(MX25_PIN_UART1_CTS,
370                         PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
371
372         /* setup pins for FEC */
373         mxc_request_iomux(MX25_PIN_FEC_TX_CLK, MUX_CONFIG_FUNC);
374         mxc_request_iomux(MX25_PIN_FEC_RX_DV, MUX_CONFIG_FUNC);
375         mxc_request_iomux(MX25_PIN_FEC_RDATA0, MUX_CONFIG_FUNC);
376         mxc_request_iomux(MX25_PIN_FEC_TDATA0, MUX_CONFIG_FUNC);
377         mxc_request_iomux(MX25_PIN_FEC_TX_EN, MUX_CONFIG_FUNC);
378         mxc_request_iomux(MX25_PIN_FEC_MDC, MUX_CONFIG_FUNC);
379         mxc_request_iomux(MX25_PIN_FEC_MDIO, MUX_CONFIG_FUNC);
380         mxc_request_iomux(MX25_PIN_FEC_RDATA1, MUX_CONFIG_FUNC);
381         mxc_request_iomux(MX25_PIN_FEC_TDATA1, MUX_CONFIG_FUNC);
382         mxc_request_iomux(MX25_PIN_POWER_FAIL, MUX_CONFIG_FUNC); /* PHY INT */
383
384 #define FEC_PAD_CTL1 (PAD_CTL_HYS_SCHMITZ | PAD_CTL_PUE_PUD | \
385                         PAD_CTL_PKE_ENABLE)
386 #define FEC_PAD_CTL2 (PAD_CTL_PUE_PUD)
387
388         mxc_iomux_set_pad(MX25_PIN_FEC_TX_CLK, FEC_PAD_CTL1);
389         mxc_iomux_set_pad(MX25_PIN_FEC_RX_DV, FEC_PAD_CTL1);
390         mxc_iomux_set_pad(MX25_PIN_FEC_RDATA0, FEC_PAD_CTL1);
391         mxc_iomux_set_pad(MX25_PIN_FEC_TDATA0, FEC_PAD_CTL2);
392         mxc_iomux_set_pad(MX25_PIN_FEC_TX_EN, FEC_PAD_CTL2);
393         mxc_iomux_set_pad(MX25_PIN_FEC_MDC, FEC_PAD_CTL2);
394         mxc_iomux_set_pad(MX25_PIN_FEC_MDIO, FEC_PAD_CTL1 | PAD_CTL_22K_PU);
395         mxc_iomux_set_pad(MX25_PIN_FEC_RDATA1, FEC_PAD_CTL1);
396         mxc_iomux_set_pad(MX25_PIN_FEC_TDATA1, FEC_PAD_CTL2);
397         mxc_iomux_set_pad(MX25_PIN_POWER_FAIL, FEC_PAD_CTL1);
398
399         /*
400          * Set up the FEC_RESET_B and FEC_ENABLE GPIO pins.
401          * Assert FEC_RESET_B, then power up the PHY by asserting
402          * FEC_ENABLE, at the same time lifting FEC_RESET_B.
403          *
404          * FEC_RESET_B: gpio2[3] is ALT 5 mode of pin D12
405          * FEC_ENABLE_B: gpio4[8] is ALT 5 mode of pin A17
406          */
407         mxc_request_iomux(MX25_PIN_A17, MUX_CONFIG_ALT5); /* FEC_EN */
408         mxc_request_iomux(MX25_PIN_D12, MUX_CONFIG_ALT5); /* FEC_RESET_B */
409
410         mxc_iomux_set_pad(MX25_PIN_A17, PAD_CTL_ODE_OpenDrain);
411         mxc_iomux_set_pad(MX25_PIN_D12, 0);
412
413         mxc_set_gpio_direction(MX25_PIN_A17, 0); /* FEC_EN */
414         mxc_set_gpio_direction(MX25_PIN_D12, 0); /* FEC_RESET_B */
415
416         /* drop PHY power */
417         mxc_set_gpio_dataout(MX25_PIN_A17, 0);  /* FEC_EN */
418
419         /* assert reset */
420         mxc_set_gpio_dataout(MX25_PIN_D12, 0);  /* FEC_RESET_B */
421         udelay(2);              /* spec says 1us min */
422
423         /* turn on PHY power and lift reset */
424         mxc_set_gpio_dataout(MX25_PIN_A17, 1);  /* FEC_EN */
425         mxc_set_gpio_dataout(MX25_PIN_D12, 1);  /* FEC_RESET_B */
426
427 #define I2C_PAD_CTL (PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | \
428                 PAD_CTL_PUE_PUD | PAD_CTL_100K_PU | PAD_CTL_ODE_OpenDrain)
429
430         mxc_request_iomux(MX25_PIN_I2C1_CLK, MUX_CONFIG_SION);
431         mxc_request_iomux(MX25_PIN_I2C1_DAT, MUX_CONFIG_SION);
432         mxc_iomux_set_pad(MX25_PIN_I2C1_CLK, 0x1E8);
433         mxc_iomux_set_pad(MX25_PIN_I2C1_DAT, 0x1E8);
434
435 #ifdef CONFIG_LCD
436         lcdc_hw_init();
437 #endif
438
439         gd->bd->bi_arch_number = MACH_TYPE_MX25_3DS;    /* board id for linux */
440         gd->bd->bi_boot_params = 0x80000100;    /* address of boot parameters */
441
442         return 0;
443
444 #undef FEC_PAD_CTL1
445 #undef FEC_PAD_CTL2
446 #undef I2C_PAD_CTL
447 }
448
449 #ifdef BOARD_LATE_INIT
450 int board_late_init(void)
451 {
452         u8 reg[4];
453
454         /* Turn PMIC On*/
455         reg[0] = 0x09;
456         i2c_write(0x54, 0x02, 1, reg, 1);
457
458 #ifdef CONFIG_IMX_SPI_CPLD
459         mxc_cpld_spi_init();
460 #endif
461
462 #ifdef CONFIG_SPLASH_SCREEN
463         if (!setup_splash_img())
464                 printf("Read splash screen failed!\n");
465 #endif
466
467         return 0;
468 }
469 #endif
470
471
472 int checkboard(void)
473 {
474         printf("Board: i.MX25 MAX PDK (3DS)\n");
475         return 0;
476 }
477
478 int board_eth_init(bd_t *bis)
479 {
480         int rc = -ENODEV;
481 #if defined(CONFIG_SMC911X)
482         rc = smc911x_initialize(0, CONFIG_SMC911X_BASE);
483 #endif
484
485         cpu_eth_init(bis);
486
487         return rc;
488 }
489