xref: /openbmc/u-boot/board/isee/igep00x0/igep00x0.c (revision 17fa0326)
177eea280SJavier Martinez Canillas /*
277eea280SJavier Martinez Canillas  * (C) Copyright 2010
377eea280SJavier Martinez Canillas  * ISEE 2007 SL, <www.iseebcn.com>
477eea280SJavier Martinez Canillas  *
51a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
677eea280SJavier Martinez Canillas  */
777eea280SJavier Martinez Canillas #include <common.h>
8f3b4bc45SEnric Balletbo i Serra #include <status_led.h>
9b3f4ca11SSimon Glass #include <dm.h>
10b3f4ca11SSimon Glass #include <ns16550.h>
1177eea280SJavier Martinez Canillas #include <twl4030.h>
1277eea280SJavier Martinez Canillas #include <netdev.h>
13fe9f6289SLadislav Michl #include <spl.h>
1477eea280SJavier Martinez Canillas #include <asm/gpio.h>
1577eea280SJavier Martinez Canillas #include <asm/io.h>
1677eea280SJavier Martinez Canillas #include <asm/arch/mem.h>
1777eea280SJavier Martinez Canillas #include <asm/arch/mmc_host_def.h>
1877eea280SJavier Martinez Canillas #include <asm/arch/mux.h>
1977eea280SJavier Martinez Canillas #include <asm/arch/sys_proto.h>
2077eea280SJavier Martinez Canillas #include <asm/mach-types.h>
21a5debaa3SLadislav Michl #include <linux/mtd/mtd.h>
2297ee7060SLadislav Michl #include <linux/mtd/nand.h>
2397ee7060SLadislav Michl #include <linux/mtd/nand.h>
2497ee7060SLadislav Michl #include <linux/mtd/onenand.h>
2597ee7060SLadislav Michl #include <jffs2/load_kernel.h>
26568b471eSLadislav Michl #include <mtd_node.h>
27568b471eSLadislav Michl #include <fdt_support.h>
2877eea280SJavier Martinez Canillas #include "igep00x0.h"
2977eea280SJavier Martinez Canillas 
3077eea280SJavier Martinez Canillas DECLARE_GLOBAL_DATA_PTR;
3177eea280SJavier Martinez Canillas 
32b3f4ca11SSimon Glass static const struct ns16550_platdata igep_serial = {
332f6ed3b8SAdam Ford 	.base = OMAP34XX_UART3,
342f6ed3b8SAdam Ford 	.reg_shift = 2,
35*17fa0326SHeiko Schocher 	.clock = V_NS16550_CLK,
36*17fa0326SHeiko Schocher 	.fcr = UART_FCR_DEFVAL,
37b3f4ca11SSimon Glass };
38b3f4ca11SSimon Glass 
39b3f4ca11SSimon Glass U_BOOT_DEVICE(igep_uart) = {
40c7b9686dSThomas Chou 	"ns16550_serial",
41b3f4ca11SSimon Glass 	&igep_serial
42b3f4ca11SSimon Glass };
43b3f4ca11SSimon Glass 
4477eea280SJavier Martinez Canillas /*
4577eea280SJavier Martinez Canillas  * Routine: board_init
4677eea280SJavier Martinez Canillas  * Description: Early hardware init.
4777eea280SJavier Martinez Canillas  */
4877eea280SJavier Martinez Canillas int board_init(void)
4977eea280SJavier Martinez Canillas {
5097ee7060SLadislav Michl 	int loops = 100;
5197ee7060SLadislav Michl 
5297ee7060SLadislav Michl 	/* find out flash memory type, assume NAND first */
5397ee7060SLadislav Michl 	gpmc_cs0_flash = MTD_DEV_TYPE_NAND;
5497ee7060SLadislav Michl 	gpmc_init();
5597ee7060SLadislav Michl 
5697ee7060SLadislav Michl 	/* Issue a RESET and then READID */
5797ee7060SLadislav Michl 	writeb(NAND_CMD_RESET, &gpmc_cfg->cs[0].nand_cmd);
5897ee7060SLadislav Michl 	writeb(NAND_CMD_STATUS, &gpmc_cfg->cs[0].nand_cmd);
5997ee7060SLadislav Michl 	while ((readl(&gpmc_cfg->cs[0].nand_dat) & NAND_STATUS_READY)
6097ee7060SLadislav Michl 	                                        != NAND_STATUS_READY) {
6197ee7060SLadislav Michl 		udelay(1);
6297ee7060SLadislav Michl 		if (--loops == 0) {
6397ee7060SLadislav Michl 			gpmc_cs0_flash = MTD_DEV_TYPE_ONENAND;
6497ee7060SLadislav Michl 			gpmc_init();	/* reinitialize for OneNAND */
6597ee7060SLadislav Michl 			break;
6697ee7060SLadislav Michl 		}
6797ee7060SLadislav Michl 	}
6897ee7060SLadislav Michl 
6977eea280SJavier Martinez Canillas 	/* boot param addr */
7077eea280SJavier Martinez Canillas 	gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100);
7177eea280SJavier Martinez Canillas 
72f3b4bc45SEnric Balletbo i Serra #if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT)
73f3b4bc45SEnric Balletbo i Serra 	status_led_set(STATUS_LED_BOOT, STATUS_LED_ON);
74f3b4bc45SEnric Balletbo i Serra #endif
75f3b4bc45SEnric Balletbo i Serra 
7677eea280SJavier Martinez Canillas 	return 0;
7777eea280SJavier Martinez Canillas }
7877eea280SJavier Martinez Canillas 
7977eea280SJavier Martinez Canillas #ifdef CONFIG_SPL_BUILD
8077eea280SJavier Martinez Canillas /*
8177eea280SJavier Martinez Canillas  * Routine: get_board_mem_timings
8277eea280SJavier Martinez Canillas  * Description: If we use SPL then there is no x-loader nor config header
8377eea280SJavier Martinez Canillas  * so we have to setup the DDR timings ourself on both banks.
8477eea280SJavier Martinez Canillas  */
8577eea280SJavier Martinez Canillas void get_board_mem_timings(struct board_sdrc_timings *timings)
8677eea280SJavier Martinez Canillas {
8797ee7060SLadislav Michl 	int mfr, id, err = identify_nand_chip(&mfr, &id);
8897ee7060SLadislav Michl 
8977eea280SJavier Martinez Canillas 	timings->mr = MICRON_V_MR_165;
904fa72bd3SLadislav Michl 	if (!err) {
914fa72bd3SLadislav Michl 		switch (mfr) {
924fa72bd3SLadislav Michl 		case NAND_MFR_HYNIX:
934fa72bd3SLadislav Michl 			timings->mcfg = HYNIX_V_MCFG_200(256 << 20);
944fa72bd3SLadislav Michl 			timings->ctrla = HYNIX_V_ACTIMA_200;
954fa72bd3SLadislav Michl 			timings->ctrlb = HYNIX_V_ACTIMB_200;
964fa72bd3SLadislav Michl 			break;
974fa72bd3SLadislav Michl 		case NAND_MFR_MICRON:
9877eea280SJavier Martinez Canillas 			timings->mcfg = MICRON_V_MCFG_200(256 << 20);
9977eea280SJavier Martinez Canillas 			timings->ctrla = MICRON_V_ACTIMA_200;
10077eea280SJavier Martinez Canillas 			timings->ctrlb = MICRON_V_ACTIMB_200;
1014fa72bd3SLadislav Michl 			break;
1024fa72bd3SLadislav Michl 		default:
1034fa72bd3SLadislav Michl 			/* Should not happen... */
1044fa72bd3SLadislav Michl 			break;
1054fa72bd3SLadislav Michl 		}
10677eea280SJavier Martinez Canillas 		timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
10797ee7060SLadislav Michl 		gpmc_cs0_flash = MTD_DEV_TYPE_NAND;
10897ee7060SLadislav Michl 	} else {
10977eea280SJavier Martinez Canillas 		if (get_cpu_family() == CPU_OMAP34XX) {
11077eea280SJavier Martinez Canillas 			timings->mcfg = NUMONYX_V_MCFG_165(256 << 20);
11177eea280SJavier Martinez Canillas 			timings->ctrla = NUMONYX_V_ACTIMA_165;
11277eea280SJavier Martinez Canillas 			timings->ctrlb = NUMONYX_V_ACTIMB_165;
11377eea280SJavier Martinez Canillas 			timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
11477eea280SJavier Martinez Canillas 		} else {
11577eea280SJavier Martinez Canillas 			timings->mcfg = NUMONYX_V_MCFG_200(256 << 20);
11677eea280SJavier Martinez Canillas 			timings->ctrla = NUMONYX_V_ACTIMA_200;
11777eea280SJavier Martinez Canillas 			timings->ctrlb = NUMONYX_V_ACTIMB_200;
11877eea280SJavier Martinez Canillas 			timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
11977eea280SJavier Martinez Canillas 		}
12097ee7060SLadislav Michl 		gpmc_cs0_flash = MTD_DEV_TYPE_ONENAND;
12197ee7060SLadislav Michl 	}
12277eea280SJavier Martinez Canillas }
123fe9f6289SLadislav Michl 
124fe9f6289SLadislav Michl #ifdef CONFIG_SPL_OS_BOOT
125fe9f6289SLadislav Michl int spl_start_uboot(void)
126fe9f6289SLadislav Michl {
127fe9f6289SLadislav Michl 	/* break into full u-boot on 'c' */
128fe9f6289SLadislav Michl 	if (serial_tstc() && serial_getc() == 'c')
129fe9f6289SLadislav Michl 		return 1;
130fe9f6289SLadislav Michl 
131fe9f6289SLadislav Michl 	return 0;
132fe9f6289SLadislav Michl }
133fe9f6289SLadislav Michl #endif
13477eea280SJavier Martinez Canillas #endif
13577eea280SJavier Martinez Canillas 
13697ee7060SLadislav Michl int onenand_board_init(struct mtd_info *mtd)
13797ee7060SLadislav Michl {
13897ee7060SLadislav Michl 	if (gpmc_cs0_flash == MTD_DEV_TYPE_ONENAND) {
13997ee7060SLadislav Michl 		struct onenand_chip *this = mtd->priv;
14097ee7060SLadislav Michl 		this->base = (void *)CONFIG_SYS_ONENAND_BASE;
14197ee7060SLadislav Michl 		return 0;
14297ee7060SLadislav Michl 	}
14397ee7060SLadislav Michl 	return 1;
14497ee7060SLadislav Michl }
14597ee7060SLadislav Michl 
14677eea280SJavier Martinez Canillas #if defined(CONFIG_CMD_NET)
1476ed75ba7SLadislav Michl static void reset_net_chip(int gpio)
1486ed75ba7SLadislav Michl {
1496ed75ba7SLadislav Michl 	if (!gpio_request(gpio, "eth nrst")) {
1506ed75ba7SLadislav Michl 		gpio_direction_output(gpio, 1);
1516ed75ba7SLadislav Michl 		udelay(1);
1526ed75ba7SLadislav Michl 		gpio_set_value(gpio, 0);
1536ed75ba7SLadislav Michl 		udelay(40);
1546ed75ba7SLadislav Michl 		gpio_set_value(gpio, 1);
1556ed75ba7SLadislav Michl 		mdelay(10);
1566ed75ba7SLadislav Michl 	}
1576ed75ba7SLadislav Michl }
1586ed75ba7SLadislav Michl 
15977eea280SJavier Martinez Canillas /*
16077eea280SJavier Martinez Canillas  * Routine: setup_net_chip
16177eea280SJavier Martinez Canillas  * Description: Setting up the configuration GPMC registers specific to the
16277eea280SJavier Martinez Canillas  *		Ethernet hardware.
16377eea280SJavier Martinez Canillas  */
16477eea280SJavier Martinez Canillas static void setup_net_chip(void)
16577eea280SJavier Martinez Canillas {
16677eea280SJavier Martinez Canillas 	struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE;
167b0c47633SLadislav Michl 	static const u32 gpmc_lan_config[] = {
168b0c47633SLadislav Michl 		NET_LAN9221_GPMC_CONFIG1,
169b0c47633SLadislav Michl 		NET_LAN9221_GPMC_CONFIG2,
170b0c47633SLadislav Michl 		NET_LAN9221_GPMC_CONFIG3,
171b0c47633SLadislav Michl 		NET_LAN9221_GPMC_CONFIG4,
172b0c47633SLadislav Michl 		NET_LAN9221_GPMC_CONFIG5,
173b0c47633SLadislav Michl 		NET_LAN9221_GPMC_CONFIG6,
174b0c47633SLadislav Michl 	};
17577eea280SJavier Martinez Canillas 
1766ed75ba7SLadislav Michl 	enable_gpmc_cs_config(gpmc_lan_config, &gpmc_cfg->cs[5],
1776ed75ba7SLadislav Michl 			CONFIG_SMC911X_BASE, GPMC_SIZE_16M);
17877eea280SJavier Martinez Canillas 
17977eea280SJavier Martinez Canillas 	/* Enable off mode for NWE in PADCONF_GPMC_NWE register */
18077eea280SJavier Martinez Canillas 	writew(readw(&ctrl_base->gpmc_nwe) | 0x0E00, &ctrl_base->gpmc_nwe);
18177eea280SJavier Martinez Canillas 	/* Enable off mode for NOE in PADCONF_GPMC_NADV_ALE register */
18277eea280SJavier Martinez Canillas 	writew(readw(&ctrl_base->gpmc_noe) | 0x0E00, &ctrl_base->gpmc_noe);
18377eea280SJavier Martinez Canillas 	/* Enable off mode for ALE in PADCONF_GPMC_NADV_ALE register */
18477eea280SJavier Martinez Canillas 	writew(readw(&ctrl_base->gpmc_nadv_ale) | 0x0E00,
18577eea280SJavier Martinez Canillas 		&ctrl_base->gpmc_nadv_ale);
18677eea280SJavier Martinez Canillas 
1876ed75ba7SLadislav Michl 	reset_net_chip(64);
18877eea280SJavier Martinez Canillas }
189b0c47633SLadislav Michl 
190b0c47633SLadislav Michl int board_eth_init(bd_t *bis)
191b0c47633SLadislav Michl {
192b0c47633SLadislav Michl #ifdef CONFIG_SMC911X
193b0c47633SLadislav Michl 	return smc911x_initialize(0, CONFIG_SMC911X_BASE);
194b0c47633SLadislav Michl #else
195b0c47633SLadislav Michl 	return 0;
196b0c47633SLadislav Michl #endif
197b0c47633SLadislav Michl }
19877eea280SJavier Martinez Canillas #else
19977eea280SJavier Martinez Canillas static inline void setup_net_chip(void) {}
20077eea280SJavier Martinez Canillas #endif
20177eea280SJavier Martinez Canillas 
20277eea280SJavier Martinez Canillas #if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
20377eea280SJavier Martinez Canillas int board_mmc_init(bd_t *bis)
20477eea280SJavier Martinez Canillas {
205e3913f56SNikita Kiryanov 	return omap_mmc_init(0, 0, 0, -1, -1);
20677eea280SJavier Martinez Canillas }
20777eea280SJavier Martinez Canillas #endif
20877eea280SJavier Martinez Canillas 
209aac5450eSPaul Kocialkowski #if defined(CONFIG_GENERIC_MMC)
210aac5450eSPaul Kocialkowski void board_mmc_power_init(void)
211aac5450eSPaul Kocialkowski {
212aac5450eSPaul Kocialkowski 	twl4030_power_mmc_init(0);
213aac5450eSPaul Kocialkowski }
214aac5450eSPaul Kocialkowski #endif
215aac5450eSPaul Kocialkowski 
216568b471eSLadislav Michl #ifdef CONFIG_OF_BOARD_SETUP
217568b471eSLadislav Michl int ft_board_setup(void *blob, bd_t *bd)
218568b471eSLadislav Michl {
219568b471eSLadislav Michl #ifdef CONFIG_FDT_FIXUP_PARTITIONS
220568b471eSLadislav Michl 	static struct node_info nodes[] = {
221568b471eSLadislav Michl 		{ "ti,omap2-nand", MTD_DEV_TYPE_NAND, },
222568b471eSLadislav Michl 		{ "ti,omap2-onenand", MTD_DEV_TYPE_ONENAND, },
223568b471eSLadislav Michl 	};
224568b471eSLadislav Michl 
225568b471eSLadislav Michl 	fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
226568b471eSLadislav Michl #endif
227568b471eSLadislav Michl 	return 0;
228568b471eSLadislav Michl }
229568b471eSLadislav Michl #endif
230568b471eSLadislav Michl 
231a2fa28bcSJavier Martinez Canillas void set_fdt(void)
232a2fa28bcSJavier Martinez Canillas {
233a2fa28bcSJavier Martinez Canillas 	switch (gd->bd->bi_arch_number) {
234a2fa28bcSJavier Martinez Canillas 	case MACH_TYPE_IGEP0020:
23540372244SEnric Balletbò i Serra 		setenv("fdtfile", "omap3-igep0020.dtb");
236a2fa28bcSJavier Martinez Canillas 		break;
237a2fa28bcSJavier Martinez Canillas 	case MACH_TYPE_IGEP0030:
23840372244SEnric Balletbò i Serra 		setenv("fdtfile", "omap3-igep0030.dtb");
239a2fa28bcSJavier Martinez Canillas 		break;
240a2fa28bcSJavier Martinez Canillas 	}
241a2fa28bcSJavier Martinez Canillas }
242a2fa28bcSJavier Martinez Canillas 
24377eea280SJavier Martinez Canillas /*
24477eea280SJavier Martinez Canillas  * Routine: misc_init_r
24577eea280SJavier Martinez Canillas  * Description: Configure board specific parts
24677eea280SJavier Martinez Canillas  */
24777eea280SJavier Martinez Canillas int misc_init_r(void)
24877eea280SJavier Martinez Canillas {
24977eea280SJavier Martinez Canillas 	twl4030_power_init();
25077eea280SJavier Martinez Canillas 
25177eea280SJavier Martinez Canillas 	setup_net_chip();
25277eea280SJavier Martinez Canillas 
253679f82c3SPaul Kocialkowski 	omap_die_id_display();
25477eea280SJavier Martinez Canillas 
255a2fa28bcSJavier Martinez Canillas 	set_fdt();
256a2fa28bcSJavier Martinez Canillas 
25777eea280SJavier Martinez Canillas 	return 0;
25877eea280SJavier Martinez Canillas }
25977eea280SJavier Martinez Canillas 
260a5debaa3SLadislav Michl void board_mtdparts_default(const char **mtdids, const char **mtdparts)
261a5debaa3SLadislav Michl {
262a5debaa3SLadislav Michl 	struct mtd_info *mtd = get_mtd_device(NULL, 0);
263a5debaa3SLadislav Michl 	if (mtd) {
264a5debaa3SLadislav Michl 		static char ids[24];
265a5debaa3SLadislav Michl 		static char parts[48];
266a5debaa3SLadislav Michl 		const char *linux_name = "omap2-nand";
267a5debaa3SLadislav Michl 		if (strncmp(mtd->name, "onenand0", 8) == 0)
268a5debaa3SLadislav Michl 			linux_name = "omap2-onenand";
269a5debaa3SLadislav Michl 		snprintf(ids, sizeof(ids), "%s=%s", mtd->name, linux_name);
270a5debaa3SLadislav Michl 		snprintf(parts, sizeof(parts), "mtdparts=%s:%dk(SPL),-(UBI)",
271a5debaa3SLadislav Michl 		         linux_name, 4 * mtd->erasesize >> 10);
272a5debaa3SLadislav Michl 		*mtdids = ids;
273a5debaa3SLadislav Michl 		*mtdparts = parts;
274a5debaa3SLadislav Michl 	}
275a5debaa3SLadislav Michl }
276a5debaa3SLadislav Michl 
27777eea280SJavier Martinez Canillas /*
27877eea280SJavier Martinez Canillas  * Routine: set_muxconf_regs
27977eea280SJavier Martinez Canillas  * Description: Setting up the configuration Mux registers specific to the
28077eea280SJavier Martinez Canillas  *		hardware. Many pins need to be moved from protect to primary
28177eea280SJavier Martinez Canillas  *		mode.
28277eea280SJavier Martinez Canillas  */
28377eea280SJavier Martinez Canillas void set_muxconf_regs(void)
28477eea280SJavier Martinez Canillas {
28577eea280SJavier Martinez Canillas 	MUX_DEFAULT();
28677eea280SJavier Martinez Canillas 
28777eea280SJavier Martinez Canillas #if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0020)
28877eea280SJavier Martinez Canillas 	MUX_IGEP0020();
28977eea280SJavier Martinez Canillas #endif
29077eea280SJavier Martinez Canillas 
29177eea280SJavier Martinez Canillas #if (CONFIG_MACH_TYPE == MACH_TYPE_IGEP0030)
29277eea280SJavier Martinez Canillas 	MUX_IGEP0030();
29377eea280SJavier Martinez Canillas #endif
29477eea280SJavier Martinez Canillas }
295