xref: /rk3399_rockchip-uboot/board/phytec/pcm051/board.c (revision 81df2bab46d3bed319e21571c68db8e0a048bbfd)
11c1b7c37SLars Poeschel /*
21c1b7c37SLars Poeschel  * board.c
31c1b7c37SLars Poeschel  *
41c1b7c37SLars Poeschel  * Board functions for Phytec phyCORE-AM335x (pcm051) based boards
51c1b7c37SLars Poeschel  *
61c1b7c37SLars Poeschel  * Copyright (C) 2013 Lemonage Software GmbH
71c1b7c37SLars Poeschel  * Author Lars Poeschel <poeschel@lemonage.de>
81c1b7c37SLars Poeschel  *
91c1b7c37SLars Poeschel  * This program is free software; you can redistribute it and/or
101c1b7c37SLars Poeschel  * modify it under the terms of the GNU General Public License as
111c1b7c37SLars Poeschel  * published by the Free Software Foundation; either version 2 of
121c1b7c37SLars Poeschel  * the License, or (at your option) any later version.
131c1b7c37SLars Poeschel  *
141c1b7c37SLars Poeschel  * This program is distributed in the hope that it will be useful,
151c1b7c37SLars Poeschel  * but WITHOUT ANY WARRANTY; without even the implied warranty of
161c1b7c37SLars Poeschel  * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the
171c1b7c37SLars Poeschel  * GNU General Public License for more details.
181c1b7c37SLars Poeschel  */
191c1b7c37SLars Poeschel 
201c1b7c37SLars Poeschel #include <common.h>
211c1b7c37SLars Poeschel #include <errno.h>
221c1b7c37SLars Poeschel #include <spl.h>
231c1b7c37SLars Poeschel #include <asm/arch/cpu.h>
241c1b7c37SLars Poeschel #include <asm/arch/hardware.h>
251c1b7c37SLars Poeschel #include <asm/arch/omap.h>
261c1b7c37SLars Poeschel #include <asm/arch/ddr_defs.h>
271c1b7c37SLars Poeschel #include <asm/arch/clock.h>
281c1b7c37SLars Poeschel #include <asm/arch/gpio.h>
291c1b7c37SLars Poeschel #include <asm/arch/mmc_host_def.h>
301c1b7c37SLars Poeschel #include <asm/arch/sys_proto.h>
311c1b7c37SLars Poeschel #include <asm/io.h>
321c1b7c37SLars Poeschel #include <asm/emif.h>
331c1b7c37SLars Poeschel #include <asm/gpio.h>
341c1b7c37SLars Poeschel #include <i2c.h>
351c1b7c37SLars Poeschel #include <miiphy.h>
361c1b7c37SLars Poeschel #include <cpsw.h>
371c1b7c37SLars Poeschel #include "board.h"
381c1b7c37SLars Poeschel 
391c1b7c37SLars Poeschel DECLARE_GLOBAL_DATA_PTR;
401c1b7c37SLars Poeschel 
411c1b7c37SLars Poeschel static struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
421c1b7c37SLars Poeschel #ifdef CONFIG_SPL_BUILD
431c1b7c37SLars Poeschel static struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
441c1b7c37SLars Poeschel #endif
451c1b7c37SLars Poeschel 
461c1b7c37SLars Poeschel /* MII mode defines */
471c1b7c37SLars Poeschel #define MII_MODE_ENABLE		0x0
481c1b7c37SLars Poeschel #define RGMII_MODE_ENABLE	0xA
491c1b7c37SLars Poeschel #define RMII_RGMII2_MODE_ENABLE	0x49
501c1b7c37SLars Poeschel 
511c1b7c37SLars Poeschel static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
521c1b7c37SLars Poeschel 
531c1b7c37SLars Poeschel /* UART defines */
541c1b7c37SLars Poeschel #ifdef CONFIG_SPL_BUILD
551c1b7c37SLars Poeschel #define UART_RESET		(0x1 << 1)
561c1b7c37SLars Poeschel #define UART_CLK_RUNNING_MASK	0x1
571c1b7c37SLars Poeschel #define UART_SMART_IDLE_EN	(0x1 << 0x3)
581c1b7c37SLars Poeschel 
591c1b7c37SLars Poeschel /* DDR RAM defines */
601c1b7c37SLars Poeschel #define DDR_CLK_MHZ		303 /* DDR_DPLL_MULT value */
611c1b7c37SLars Poeschel 
621c1b7c37SLars Poeschel static void rtc32k_enable(void)
631c1b7c37SLars Poeschel {
64*81df2babSMatt Porter 	struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE;
651c1b7c37SLars Poeschel 
661c1b7c37SLars Poeschel 	/*
671c1b7c37SLars Poeschel 	 * Unlock the RTC's registers.  For more details please see the
681c1b7c37SLars Poeschel 	 * RTC_SS section of the TRM.  In order to unlock we need to
691c1b7c37SLars Poeschel 	 * write these specific values (keys) in this order.
701c1b7c37SLars Poeschel 	 */
711c1b7c37SLars Poeschel 	writel(0x83e70b13, &rtc->kick0r);
721c1b7c37SLars Poeschel 	writel(0x95a4f1e0, &rtc->kick1r);
731c1b7c37SLars Poeschel 
741c1b7c37SLars Poeschel 	/* Enable the RTC 32K OSC by setting bits 3 and 6. */
751c1b7c37SLars Poeschel 	writel((1 << 3) | (1 << 6), &rtc->osc);
761c1b7c37SLars Poeschel }
771c1b7c37SLars Poeschel 
781c1b7c37SLars Poeschel static const struct ddr_data ddr3_data = {
791c1b7c37SLars Poeschel 	.datardsratio0 = MT41J256M8HX15E_RD_DQS,
801c1b7c37SLars Poeschel 	.datawdsratio0 = MT41J256M8HX15E_WR_DQS,
811c1b7c37SLars Poeschel 	.datafwsratio0 = MT41J256M8HX15E_PHY_FIFO_WE,
821c1b7c37SLars Poeschel 	.datawrsratio0 = MT41J256M8HX15E_PHY_WR_DATA,
831c1b7c37SLars Poeschel 	.datadldiff0 = PHY_DLL_LOCK_DIFF,
841c1b7c37SLars Poeschel };
851c1b7c37SLars Poeschel 
861c1b7c37SLars Poeschel static const struct cmd_control ddr3_cmd_ctrl_data = {
871c1b7c37SLars Poeschel 	.cmd0csratio = MT41J256M8HX15E_RATIO,
881c1b7c37SLars Poeschel 	.cmd0dldiff = MT41J256M8HX15E_DLL_LOCK_DIFF,
891c1b7c37SLars Poeschel 	.cmd0iclkout = MT41J256M8HX15E_INVERT_CLKOUT,
901c1b7c37SLars Poeschel 
911c1b7c37SLars Poeschel 	.cmd1csratio = MT41J256M8HX15E_RATIO,
921c1b7c37SLars Poeschel 	.cmd1dldiff = MT41J256M8HX15E_DLL_LOCK_DIFF,
931c1b7c37SLars Poeschel 	.cmd1iclkout = MT41J256M8HX15E_INVERT_CLKOUT,
941c1b7c37SLars Poeschel 
951c1b7c37SLars Poeschel 	.cmd2csratio = MT41J256M8HX15E_RATIO,
961c1b7c37SLars Poeschel 	.cmd2dldiff = MT41J256M8HX15E_DLL_LOCK_DIFF,
971c1b7c37SLars Poeschel 	.cmd2iclkout = MT41J256M8HX15E_INVERT_CLKOUT,
981c1b7c37SLars Poeschel };
991c1b7c37SLars Poeschel 
1001c1b7c37SLars Poeschel static struct emif_regs ddr3_emif_reg_data = {
1011c1b7c37SLars Poeschel 	.sdram_config = MT41J256M8HX15E_EMIF_SDCFG,
1021c1b7c37SLars Poeschel 	.ref_ctrl = MT41J256M8HX15E_EMIF_SDREF,
1031c1b7c37SLars Poeschel 	.sdram_tim1 = MT41J256M8HX15E_EMIF_TIM1,
1041c1b7c37SLars Poeschel 	.sdram_tim2 = MT41J256M8HX15E_EMIF_TIM2,
1051c1b7c37SLars Poeschel 	.sdram_tim3 = MT41J256M8HX15E_EMIF_TIM3,
1061c1b7c37SLars Poeschel 	.zq_config = MT41J256M8HX15E_ZQ_CFG,
1071c1b7c37SLars Poeschel 	.emif_ddr_phy_ctlr_1 = MT41J256M8HX15E_EMIF_READ_LATENCY,
1081c1b7c37SLars Poeschel };
1091c1b7c37SLars Poeschel #endif
1101c1b7c37SLars Poeschel 
1111c1b7c37SLars Poeschel /*
1121c1b7c37SLars Poeschel  * early system init of muxing and clocks.
1131c1b7c37SLars Poeschel  */
1141c1b7c37SLars Poeschel void s_init(void)
1151c1b7c37SLars Poeschel {
1161c1b7c37SLars Poeschel 	/*
1171c1b7c37SLars Poeschel 	 * WDT1 is already running when the bootloader gets control
1181c1b7c37SLars Poeschel 	 * Disable it to avoid "random" resets
1191c1b7c37SLars Poeschel 	 */
1201c1b7c37SLars Poeschel 	writel(0xAAAA, &wdtimer->wdtwspr);
1211c1b7c37SLars Poeschel 	while (readl(&wdtimer->wdtwwps) != 0x0)
1221c1b7c37SLars Poeschel 		;
1231c1b7c37SLars Poeschel 	writel(0x5555, &wdtimer->wdtwspr);
1241c1b7c37SLars Poeschel 	while (readl(&wdtimer->wdtwwps) != 0x0)
1251c1b7c37SLars Poeschel 		;
1261c1b7c37SLars Poeschel 
1271c1b7c37SLars Poeschel #ifdef CONFIG_SPL_BUILD
1281c1b7c37SLars Poeschel 	/* Setup the PLLs and the clocks for the peripherals */
1291c1b7c37SLars Poeschel 	pll_init();
1301c1b7c37SLars Poeschel 
1311c1b7c37SLars Poeschel 	/* Enable RTC32K clock */
1321c1b7c37SLars Poeschel 	rtc32k_enable();
1331c1b7c37SLars Poeschel 
1341c1b7c37SLars Poeschel 	/* UART softreset */
1351c1b7c37SLars Poeschel 	u32 regval;
1361c1b7c37SLars Poeschel 
1371c1b7c37SLars Poeschel 	enable_uart0_pin_mux();
1381c1b7c37SLars Poeschel 
1391c1b7c37SLars Poeschel 	regval = readl(&uart_base->uartsyscfg);
1401c1b7c37SLars Poeschel 	regval |= UART_RESET;
1411c1b7c37SLars Poeschel 	writel(regval, &uart_base->uartsyscfg);
1421c1b7c37SLars Poeschel 	while ((readl(&uart_base->uartsyssts) &	UART_CLK_RUNNING_MASK)
1431c1b7c37SLars Poeschel 		!= UART_CLK_RUNNING_MASK)
1441c1b7c37SLars Poeschel 		;
1451c1b7c37SLars Poeschel 
1461c1b7c37SLars Poeschel 	/* Disable smart idle */
1471c1b7c37SLars Poeschel 	regval = readl(&uart_base->uartsyscfg);
1481c1b7c37SLars Poeschel 	regval |= UART_SMART_IDLE_EN;
1491c1b7c37SLars Poeschel 	writel(regval, &uart_base->uartsyscfg);
1501c1b7c37SLars Poeschel 
1511c1b7c37SLars Poeschel 	gd = &gdata;
1521c1b7c37SLars Poeschel 
1531c1b7c37SLars Poeschel 	preloader_console_init();
1541c1b7c37SLars Poeschel 
1551c1b7c37SLars Poeschel 	/* Initalize the board header */
1561c1b7c37SLars Poeschel 	enable_i2c0_pin_mux();
1571c1b7c37SLars Poeschel 	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
1581c1b7c37SLars Poeschel 
1591c1b7c37SLars Poeschel 	enable_board_pin_mux();
1601c1b7c37SLars Poeschel 
1611c1b7c37SLars Poeschel 	config_ddr(DDR_CLK_MHZ, MT41J256M8HX15E_IOCTRL_VALUE, &ddr3_data,
1621c1b7c37SLars Poeschel 			&ddr3_cmd_ctrl_data, &ddr3_emif_reg_data);
1631c1b7c37SLars Poeschel #endif
1641c1b7c37SLars Poeschel }
1651c1b7c37SLars Poeschel 
1661c1b7c37SLars Poeschel /*
1671c1b7c37SLars Poeschel  * Basic board specific setup.  Pinmux has been handled already.
1681c1b7c37SLars Poeschel  */
1691c1b7c37SLars Poeschel int board_init(void)
1701c1b7c37SLars Poeschel {
1711c1b7c37SLars Poeschel 	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
1721c1b7c37SLars Poeschel 
1731c1b7c37SLars Poeschel 	gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
1741c1b7c37SLars Poeschel 
1751c1b7c37SLars Poeschel 	return 0;
1761c1b7c37SLars Poeschel }
1771c1b7c37SLars Poeschel 
1781c1b7c37SLars Poeschel #ifdef CONFIG_DRIVER_TI_CPSW
1791c1b7c37SLars Poeschel static void cpsw_control(int enabled)
1801c1b7c37SLars Poeschel {
1811c1b7c37SLars Poeschel 	/* VTP can be added here */
1821c1b7c37SLars Poeschel 
1831c1b7c37SLars Poeschel 	return;
1841c1b7c37SLars Poeschel }
1851c1b7c37SLars Poeschel 
1861c1b7c37SLars Poeschel static struct cpsw_slave_data cpsw_slaves[] = {
1871c1b7c37SLars Poeschel 	{
1881c1b7c37SLars Poeschel 		.slave_reg_ofs	= 0x208,
1891c1b7c37SLars Poeschel 		.sliver_reg_ofs	= 0xd80,
1901c1b7c37SLars Poeschel 		.phy_id		= 0,
1911c1b7c37SLars Poeschel 		.phy_if		= PHY_INTERFACE_MODE_RGMII,
1921c1b7c37SLars Poeschel 	},
1931c1b7c37SLars Poeschel 	{
1941c1b7c37SLars Poeschel 		.slave_reg_ofs	= 0x308,
1951c1b7c37SLars Poeschel 		.sliver_reg_ofs	= 0xdc0,
1961c1b7c37SLars Poeschel 		.phy_id		= 1,
1971c1b7c37SLars Poeschel 		.phy_if		= PHY_INTERFACE_MODE_RGMII,
1981c1b7c37SLars Poeschel 	},
1991c1b7c37SLars Poeschel };
2001c1b7c37SLars Poeschel 
2011c1b7c37SLars Poeschel static struct cpsw_platform_data cpsw_data = {
202*81df2babSMatt Porter 	.mdio_base		= CPSW_MDIO_BASE,
203*81df2babSMatt Porter 	.cpsw_base		= CPSW_BASE,
2041c1b7c37SLars Poeschel 	.mdio_div		= 0xff,
2051c1b7c37SLars Poeschel 	.channels		= 8,
2061c1b7c37SLars Poeschel 	.cpdma_reg_ofs		= 0x800,
2071c1b7c37SLars Poeschel 	.slaves			= 1,
2081c1b7c37SLars Poeschel 	.slave_data		= cpsw_slaves,
2091c1b7c37SLars Poeschel 	.ale_reg_ofs		= 0xd00,
2101c1b7c37SLars Poeschel 	.ale_entries		= 1024,
2111c1b7c37SLars Poeschel 	.host_port_reg_ofs	= 0x108,
2121c1b7c37SLars Poeschel 	.hw_stats_reg_ofs	= 0x900,
2131c1b7c37SLars Poeschel 	.mac_control		= (1 << 5),
2141c1b7c37SLars Poeschel 	.control		= cpsw_control,
2151c1b7c37SLars Poeschel 	.host_port_num		= 0,
2161c1b7c37SLars Poeschel 	.version		= CPSW_CTRL_VERSION_2,
2171c1b7c37SLars Poeschel };
2181c1b7c37SLars Poeschel #endif
2191c1b7c37SLars Poeschel 
2201c1b7c37SLars Poeschel #if defined(CONFIG_DRIVER_TI_CPSW) || \
2211c1b7c37SLars Poeschel 	(defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET))
2221c1b7c37SLars Poeschel int board_eth_init(bd_t *bis)
2231c1b7c37SLars Poeschel {
2241c1b7c37SLars Poeschel 	int rv, n = 0;
2251c1b7c37SLars Poeschel #ifdef CONFIG_DRIVER_TI_CPSW
2261c1b7c37SLars Poeschel 	uint8_t mac_addr[6];
2271c1b7c37SLars Poeschel 	uint32_t mac_hi, mac_lo;
2281c1b7c37SLars Poeschel 
2291c1b7c37SLars Poeschel 	if (!eth_getenv_enetaddr("ethaddr", mac_addr)) {
2301c1b7c37SLars Poeschel 		printf("<ethaddr> not set. Reading from E-fuse\n");
2311c1b7c37SLars Poeschel 		/* try reading mac address from efuse */
2321c1b7c37SLars Poeschel 		mac_lo = readl(&cdev->macid0l);
2331c1b7c37SLars Poeschel 		mac_hi = readl(&cdev->macid0h);
2341c1b7c37SLars Poeschel 		mac_addr[0] = mac_hi & 0xFF;
2351c1b7c37SLars Poeschel 		mac_addr[1] = (mac_hi & 0xFF00) >> 8;
2361c1b7c37SLars Poeschel 		mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
2371c1b7c37SLars Poeschel 		mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
2381c1b7c37SLars Poeschel 		mac_addr[4] = mac_lo & 0xFF;
2391c1b7c37SLars Poeschel 		mac_addr[5] = (mac_lo & 0xFF00) >> 8;
2401c1b7c37SLars Poeschel 
2411c1b7c37SLars Poeschel 		if (is_valid_ether_addr(mac_addr))
2421c1b7c37SLars Poeschel 			eth_setenv_enetaddr("ethaddr", mac_addr);
2431c1b7c37SLars Poeschel 		else
2441c1b7c37SLars Poeschel 			goto try_usbether;
2451c1b7c37SLars Poeschel 	}
2461c1b7c37SLars Poeschel 
2471c1b7c37SLars Poeschel 	writel(RMII_RGMII2_MODE_ENABLE, &cdev->miisel);
2481c1b7c37SLars Poeschel 
2491c1b7c37SLars Poeschel 	rv = cpsw_register(&cpsw_data);
2501c1b7c37SLars Poeschel 	if (rv < 0)
2511c1b7c37SLars Poeschel 		printf("Error %d registering CPSW switch\n", rv);
2521c1b7c37SLars Poeschel 	else
2531c1b7c37SLars Poeschel 		n += rv;
2541c1b7c37SLars Poeschel try_usbether:
2551c1b7c37SLars Poeschel #endif
2561c1b7c37SLars Poeschel 
2571c1b7c37SLars Poeschel #if defined(CONFIG_USB_ETHER) && !defined(CONFIG_SPL_BUILD)
2581c1b7c37SLars Poeschel 	rv = usb_eth_initialize(bis);
2591c1b7c37SLars Poeschel 	if (rv < 0)
2601c1b7c37SLars Poeschel 		printf("Error %d registering USB_ETHER\n", rv);
2611c1b7c37SLars Poeschel 	else
2621c1b7c37SLars Poeschel 		n += rv;
2631c1b7c37SLars Poeschel #endif
2641c1b7c37SLars Poeschel 	return n;
2651c1b7c37SLars Poeschel }
2661c1b7c37SLars Poeschel #endif
267