xref: /rk3399_rockchip-uboot/board/atmel/sama5d2_xplained/sama5d2_xplained.c (revision 00caae6d47645e68d6e5277aceb69592b49381a6)
175238f23SWenyou Yang /*
275238f23SWenyou Yang  * Copyright (C) 2015 Atmel Corporation
375238f23SWenyou Yang  *		      Wenyou.Yang <wenyou.yang@atmel.com>
475238f23SWenyou Yang  *
575238f23SWenyou Yang  * SPDX-License-Identifier:	GPL-2.0+
675238f23SWenyou Yang  */
775238f23SWenyou Yang 
875238f23SWenyou Yang #include <common.h>
975238f23SWenyou Yang #include <atmel_hlcdc.h>
102992dd83SWenyou Yang #include <debug_uart.h>
110daa2e18SWenyou Yang #include <dm.h>
120daa2e18SWenyou Yang #include <i2c.h>
1375238f23SWenyou Yang #include <lcd.h>
1475238f23SWenyou Yang #include <version.h>
1575238f23SWenyou Yang #include <asm/io.h>
1675238f23SWenyou Yang #include <asm/arch/at91_common.h>
1775238f23SWenyou Yang #include <asm/arch/atmel_pio4.h>
1837dadbcaSWenyou Yang #include <asm/arch/atmel_mpddrc.h>
1975238f23SWenyou Yang #include <asm/arch/atmel_sdhci.h>
2075238f23SWenyou Yang #include <asm/arch/clk.h>
2175238f23SWenyou Yang #include <asm/arch/gpio.h>
2275238f23SWenyou Yang #include <asm/arch/sama5d2.h>
2375238f23SWenyou Yang 
2475238f23SWenyou Yang DECLARE_GLOBAL_DATA_PTR;
2575238f23SWenyou Yang 
board_usb_hw_init(void)2675238f23SWenyou Yang static void board_usb_hw_init(void)
2775238f23SWenyou Yang {
2875238f23SWenyou Yang 	atmel_pio4_set_pio_output(AT91_PIO_PORTB, 10, 1);
2975238f23SWenyou Yang }
3075238f23SWenyou Yang 
3175238f23SWenyou Yang #ifdef CONFIG_LCD
3275238f23SWenyou Yang vidinfo_t panel_info = {
3375238f23SWenyou Yang 	.vl_col = 480,
3475238f23SWenyou Yang 	.vl_row = 272,
3575238f23SWenyou Yang 	.vl_clk = 9000000,
3675238f23SWenyou Yang 	.vl_bpix = LCD_BPP,
3775238f23SWenyou Yang 	.vl_tft = 1,
3875238f23SWenyou Yang 	.vl_hsync_len = 41,
3975238f23SWenyou Yang 	.vl_left_margin = 2,
4075238f23SWenyou Yang 	.vl_right_margin = 2,
4175238f23SWenyou Yang 	.vl_vsync_len = 11,
4275238f23SWenyou Yang 	.vl_upper_margin = 2,
4375238f23SWenyou Yang 	.vl_lower_margin = 2,
4475238f23SWenyou Yang 	.mmio = ATMEL_BASE_LCDC,
4575238f23SWenyou Yang };
4675238f23SWenyou Yang 
4775238f23SWenyou Yang /* No power up/down pin for the LCD pannel */
lcd_enable(void)4875238f23SWenyou Yang void lcd_enable(void)	{ /* Empty! */ }
lcd_disable(void)4975238f23SWenyou Yang void lcd_disable(void)	{ /* Empty! */ }
5075238f23SWenyou Yang 
has_lcdc(void)5175238f23SWenyou Yang unsigned int has_lcdc(void)
5275238f23SWenyou Yang {
5375238f23SWenyou Yang 	return 1;
5475238f23SWenyou Yang }
5575238f23SWenyou Yang 
board_lcd_hw_init(void)5675238f23SWenyou Yang static void board_lcd_hw_init(void)
5775238f23SWenyou Yang {
5875238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 28, 0);	/* LCDPWM */
5975238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 29, 0);	/* LCDDISP */
6075238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 30, 0);	/* LCDVSYNC */
6175238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 31, 0);	/* LCDHSYNC */
6275238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTD,  0, 0);	/* LCDPCK */
6375238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTD,  1, 0);	/* LCDDEN */
6475238f23SWenyou Yang 
6575238f23SWenyou Yang 	/* LCDDAT0 */
6675238f23SWenyou Yang 	/* LCDDAT1 */
6775238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 10, 0);	/* LCDDAT2 */
6875238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 11, 0);	/* LCDDAT3 */
6975238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 12, 0);	/* LCDDAT4 */
7075238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 13, 0);	/* LCDDAT5 */
7175238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 14, 0);	/* LCDDAT6 */
7275238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 15, 0);	/* LCDDAT7 */
7375238f23SWenyou Yang 
7475238f23SWenyou Yang 	/* LCDDAT8 */
7575238f23SWenyou Yang 	/* LCDDAT9 */
7675238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 16, 0);	/* LCDDAT10 */
7775238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 17, 0);	/* LCDDAT11 */
7875238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 18, 0);	/* LCDDAT12 */
7975238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 19, 0);	/* LCDDAT13 */
8075238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 20, 0);	/* LCDDAT14 */
8175238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 21, 0);	/* LCDDAT15 */
8275238f23SWenyou Yang 
8375238f23SWenyou Yang 	/* LCDD16 */
8475238f23SWenyou Yang 	/* LCDD17 */
8575238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 22, 0);	/* LCDDAT18 */
8675238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 23, 0);	/* LCDDAT19 */
8775238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 24, 0);	/* LCDDAT20 */
8875238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 25, 0);	/* LCDDAT21 */
8975238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 26, 0);	/* LCDDAT22 */
9075238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTC, 27, 0);	/* LCDDAT23 */
9175238f23SWenyou Yang 
9275238f23SWenyou Yang 	at91_periph_clk_enable(ATMEL_ID_LCDC);
9375238f23SWenyou Yang }
9475238f23SWenyou Yang 
9575238f23SWenyou Yang #ifdef CONFIG_LCD_INFO
lcd_show_board_info(void)9675238f23SWenyou Yang void lcd_show_board_info(void)
9775238f23SWenyou Yang {
9875238f23SWenyou Yang 	ulong dram_size;
9975238f23SWenyou Yang 	int i;
10075238f23SWenyou Yang 	char temp[32];
10175238f23SWenyou Yang 
10275238f23SWenyou Yang 	lcd_printf("%s\n", U_BOOT_VERSION);
10375238f23SWenyou Yang 	lcd_printf("2015 ATMEL Corp\n");
10475238f23SWenyou Yang 	lcd_printf("%s CPU at %s MHz\n", get_cpu_name(),
10575238f23SWenyou Yang 		   strmhz(temp, get_cpu_clk_rate()));
10675238f23SWenyou Yang 
10775238f23SWenyou Yang 	dram_size = 0;
10875238f23SWenyou Yang 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
10975238f23SWenyou Yang 		dram_size += gd->bd->bi_dram[i].size;
11075238f23SWenyou Yang 
11175238f23SWenyou Yang 	lcd_printf("%ld MB SDRAM\n", dram_size >> 20);
11275238f23SWenyou Yang }
11375238f23SWenyou Yang #endif /* CONFIG_LCD_INFO */
11475238f23SWenyou Yang #endif /* CONFIG_LCD */
11575238f23SWenyou Yang 
116ed03b1baSWenyou Yang #ifdef CONFIG_DEBUG_UART_BOARD_INIT
board_uart1_hw_init(void)11775238f23SWenyou Yang static void board_uart1_hw_init(void)
11875238f23SWenyou Yang {
11975238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTD, 2, 1);	/* URXD1 */
12075238f23SWenyou Yang 	atmel_pio4_set_a_periph(AT91_PIO_PORTD, 3, 0);	/* UTXD1 */
12175238f23SWenyou Yang 
12275238f23SWenyou Yang 	at91_periph_clk_enable(ATMEL_ID_UART1);
12375238f23SWenyou Yang }
12475238f23SWenyou Yang 
board_debug_uart_init(void)1252992dd83SWenyou Yang void board_debug_uart_init(void)
12675238f23SWenyou Yang {
12775238f23SWenyou Yang 	board_uart1_hw_init();
1282992dd83SWenyou Yang }
1292992dd83SWenyou Yang #endif
1302992dd83SWenyou Yang 
1312992dd83SWenyou Yang #ifdef CONFIG_BOARD_EARLY_INIT_F
board_early_init_f(void)1322992dd83SWenyou Yang int board_early_init_f(void)
1332992dd83SWenyou Yang {
1342992dd83SWenyou Yang #ifdef CONFIG_DEBUG_UART
1352992dd83SWenyou Yang 	debug_uart_init();
1362992dd83SWenyou Yang #endif
13775238f23SWenyou Yang 
13875238f23SWenyou Yang 	return 0;
13975238f23SWenyou Yang }
1402992dd83SWenyou Yang #endif
14175238f23SWenyou Yang 
board_init(void)14275238f23SWenyou Yang int board_init(void)
14375238f23SWenyou Yang {
14475238f23SWenyou Yang 	/* address of boot parameters */
14575238f23SWenyou Yang 	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
14675238f23SWenyou Yang 
14775238f23SWenyou Yang #ifdef CONFIG_LCD
14875238f23SWenyou Yang 	board_lcd_hw_init();
14975238f23SWenyou Yang #endif
15075238f23SWenyou Yang #ifdef CONFIG_CMD_USB
15175238f23SWenyou Yang 	board_usb_hw_init();
15275238f23SWenyou Yang #endif
15375238f23SWenyou Yang 
15475238f23SWenyou Yang 	return 0;
15575238f23SWenyou Yang }
15675238f23SWenyou Yang 
dram_init(void)15775238f23SWenyou Yang int dram_init(void)
15875238f23SWenyou Yang {
15975238f23SWenyou Yang 	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
16075238f23SWenyou Yang 				    CONFIG_SYS_SDRAM_SIZE);
16175238f23SWenyou Yang 	return 0;
16275238f23SWenyou Yang }
16375238f23SWenyou Yang 
1640daa2e18SWenyou Yang #ifdef CONFIG_CMD_I2C
set_ethaddr_from_eeprom(void)1650daa2e18SWenyou Yang static int set_ethaddr_from_eeprom(void)
1660daa2e18SWenyou Yang {
1670daa2e18SWenyou Yang 	const int ETH_ADDR_LEN = 6;
1680daa2e18SWenyou Yang 	unsigned char ethaddr[ETH_ADDR_LEN];
1690daa2e18SWenyou Yang 	const char *ETHADDR_NAME = "ethaddr";
1700daa2e18SWenyou Yang 	struct udevice *bus, *dev;
1710daa2e18SWenyou Yang 
172*00caae6dSSimon Glass 	if (env_get(ETHADDR_NAME))
1730daa2e18SWenyou Yang 		return 0;
1740daa2e18SWenyou Yang 
1750daa2e18SWenyou Yang 	if (uclass_get_device_by_seq(UCLASS_I2C, 1, &bus)) {
1760daa2e18SWenyou Yang 		printf("Cannot find I2C bus 1\n");
1770daa2e18SWenyou Yang 		return -1;
1780daa2e18SWenyou Yang 	}
1790daa2e18SWenyou Yang 
1800daa2e18SWenyou Yang 	if (dm_i2c_probe(bus, AT24MAC_ADDR, 0, &dev)) {
1810daa2e18SWenyou Yang 		printf("Failed to probe I2C chip\n");
1820daa2e18SWenyou Yang 		return -1;
1830daa2e18SWenyou Yang 	}
1840daa2e18SWenyou Yang 
1850daa2e18SWenyou Yang 	if (dm_i2c_read(dev, AT24MAC_REG, ethaddr, ETH_ADDR_LEN)) {
1860daa2e18SWenyou Yang 		printf("Failed to read ethernet address from EEPROM\n");
1870daa2e18SWenyou Yang 		return -1;
1880daa2e18SWenyou Yang 	}
1890daa2e18SWenyou Yang 
1900daa2e18SWenyou Yang 	if (!is_valid_ethaddr(ethaddr)) {
1910daa2e18SWenyou Yang 		printf("The ethernet address read from EEPROM is not valid!\n");
1920daa2e18SWenyou Yang 		return -1;
1930daa2e18SWenyou Yang 	}
1940daa2e18SWenyou Yang 
195fd1e959eSSimon Glass 	return eth_env_set_enetaddr(ETHADDR_NAME, ethaddr);
1960daa2e18SWenyou Yang }
1970daa2e18SWenyou Yang #else
set_ethaddr_from_eeprom(void)1980daa2e18SWenyou Yang static int set_ethaddr_from_eeprom(void)
1990daa2e18SWenyou Yang {
2000daa2e18SWenyou Yang 	return 0;
2010daa2e18SWenyou Yang }
2020daa2e18SWenyou Yang #endif
2030daa2e18SWenyou Yang 
2040daa2e18SWenyou Yang #ifdef CONFIG_MISC_INIT_R
misc_init_r(void)2050daa2e18SWenyou Yang int misc_init_r(void)
2060daa2e18SWenyou Yang {
2070daa2e18SWenyou Yang 	set_ethaddr_from_eeprom();
2080daa2e18SWenyou Yang 
2090daa2e18SWenyou Yang 	return 0;
2100daa2e18SWenyou Yang }
2110daa2e18SWenyou Yang #endif
2120daa2e18SWenyou Yang 
21337dadbcaSWenyou Yang /* SPL */
21437dadbcaSWenyou Yang #ifdef CONFIG_SPL_BUILD
spl_board_init(void)21537dadbcaSWenyou Yang void spl_board_init(void)
21637dadbcaSWenyou Yang {
21737dadbcaSWenyou Yang }
21837dadbcaSWenyou Yang 
ddrc_conf(struct atmel_mpddrc_config * ddrc)21937dadbcaSWenyou Yang static void ddrc_conf(struct atmel_mpddrc_config *ddrc)
22037dadbcaSWenyou Yang {
22137dadbcaSWenyou Yang 	ddrc->md = (ATMEL_MPDDRC_MD_DBW_32_BITS | ATMEL_MPDDRC_MD_DDR3_SDRAM);
22237dadbcaSWenyou Yang 
22337dadbcaSWenyou Yang 	ddrc->cr = (ATMEL_MPDDRC_CR_NC_COL_10 |
22437dadbcaSWenyou Yang 		    ATMEL_MPDDRC_CR_NR_ROW_14 |
22537dadbcaSWenyou Yang 		    ATMEL_MPDDRC_CR_CAS_DDR_CAS5 |
22637dadbcaSWenyou Yang 		    ATMEL_MPDDRC_CR_DIC_DS |
22737dadbcaSWenyou Yang 		    ATMEL_MPDDRC_CR_DIS_DLL |
22837dadbcaSWenyou Yang 		    ATMEL_MPDDRC_CR_NB_8BANKS |
22937dadbcaSWenyou Yang 		    ATMEL_MPDDRC_CR_DECOD_INTERLEAVED |
23037dadbcaSWenyou Yang 		    ATMEL_MPDDRC_CR_UNAL_SUPPORTED);
23137dadbcaSWenyou Yang 
23237dadbcaSWenyou Yang 	ddrc->rtr = 0x511;
23337dadbcaSWenyou Yang 
23437dadbcaSWenyou Yang 	ddrc->tpr0 = (6 << ATMEL_MPDDRC_TPR0_TRAS_OFFSET |
23537dadbcaSWenyou Yang 		      3 << ATMEL_MPDDRC_TPR0_TRCD_OFFSET |
23637dadbcaSWenyou Yang 		      4 << ATMEL_MPDDRC_TPR0_TWR_OFFSET |
23737dadbcaSWenyou Yang 		      9 << ATMEL_MPDDRC_TPR0_TRC_OFFSET |
23837dadbcaSWenyou Yang 		      3 << ATMEL_MPDDRC_TPR0_TRP_OFFSET |
23937dadbcaSWenyou Yang 		      4 << ATMEL_MPDDRC_TPR0_TRRD_OFFSET |
24037dadbcaSWenyou Yang 		      4 << ATMEL_MPDDRC_TPR0_TWTR_OFFSET |
24137dadbcaSWenyou Yang 		      4 << ATMEL_MPDDRC_TPR0_TMRD_OFFSET);
24237dadbcaSWenyou Yang 
24337dadbcaSWenyou Yang 	ddrc->tpr1 = (27 << ATMEL_MPDDRC_TPR1_TRFC_OFFSET |
24437dadbcaSWenyou Yang 		      29 << ATMEL_MPDDRC_TPR1_TXSNR_OFFSET |
24537dadbcaSWenyou Yang 		      0 << ATMEL_MPDDRC_TPR1_TXSRD_OFFSET |
24637dadbcaSWenyou Yang 		      3 << ATMEL_MPDDRC_TPR1_TXP_OFFSET);
24737dadbcaSWenyou Yang 
24837dadbcaSWenyou Yang 	ddrc->tpr2 = (0 << ATMEL_MPDDRC_TPR2_TXARD_OFFSET |
24937dadbcaSWenyou Yang 		      0 << ATMEL_MPDDRC_TPR2_TXARDS_OFFSET |
25037dadbcaSWenyou Yang 		      0 << ATMEL_MPDDRC_TPR2_TRPA_OFFSET |
25137dadbcaSWenyou Yang 		      4 << ATMEL_MPDDRC_TPR2_TRTP_OFFSET |
25237dadbcaSWenyou Yang 		      7 << ATMEL_MPDDRC_TPR2_TFAW_OFFSET);
25337dadbcaSWenyou Yang }
25437dadbcaSWenyou Yang 
mem_init(void)25537dadbcaSWenyou Yang void mem_init(void)
25637dadbcaSWenyou Yang {
25737dadbcaSWenyou Yang 	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
25837dadbcaSWenyou Yang 	struct atmel_mpddr *mpddrc = (struct atmel_mpddr *)ATMEL_BASE_MPDDRC;
25937dadbcaSWenyou Yang 	struct atmel_mpddrc_config ddrc_config;
26037dadbcaSWenyou Yang 	u32 reg;
26137dadbcaSWenyou Yang 
26237dadbcaSWenyou Yang 	ddrc_conf(&ddrc_config);
26337dadbcaSWenyou Yang 
26437dadbcaSWenyou Yang 	at91_periph_clk_enable(ATMEL_ID_MPDDRC);
26537dadbcaSWenyou Yang 	writel(AT91_PMC_DDR, &pmc->scer);
26637dadbcaSWenyou Yang 
26737dadbcaSWenyou Yang 	reg = readl(&mpddrc->io_calibr);
26837dadbcaSWenyou Yang 	reg &= ~ATMEL_MPDDRC_IO_CALIBR_RDIV;
26937dadbcaSWenyou Yang 	reg |= ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_55;
27037dadbcaSWenyou Yang 	reg &= ~ATMEL_MPDDRC_IO_CALIBR_TZQIO;
27137dadbcaSWenyou Yang 	reg |= ATMEL_MPDDRC_IO_CALIBR_TZQIO_(100);
27237dadbcaSWenyou Yang 	writel(reg, &mpddrc->io_calibr);
27337dadbcaSWenyou Yang 
27437dadbcaSWenyou Yang 	writel(ATMEL_MPDDRC_RD_DATA_PATH_SHIFT_TWO_CYCLE,
27537dadbcaSWenyou Yang 	       &mpddrc->rd_data_path);
27637dadbcaSWenyou Yang 
27737dadbcaSWenyou Yang 	ddr3_init(ATMEL_BASE_MPDDRC, ATMEL_BASE_DDRCS, &ddrc_config);
27837dadbcaSWenyou Yang 
27937dadbcaSWenyou Yang 	writel(0x3, &mpddrc->cal_mr4);
28037dadbcaSWenyou Yang 	writel(64, &mpddrc->tim_cal);
28137dadbcaSWenyou Yang }
28237dadbcaSWenyou Yang 
at91_pmc_init(void)28337dadbcaSWenyou Yang void at91_pmc_init(void)
28437dadbcaSWenyou Yang {
28537dadbcaSWenyou Yang 	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
28637dadbcaSWenyou Yang 	u32 tmp;
28737dadbcaSWenyou Yang 
28837dadbcaSWenyou Yang 	tmp = AT91_PMC_PLLAR_29 |
28937dadbcaSWenyou Yang 	      AT91_PMC_PLLXR_PLLCOUNT(0x3f) |
29037dadbcaSWenyou Yang 	      AT91_PMC_PLLXR_MUL(82) |
29137dadbcaSWenyou Yang 	      AT91_PMC_PLLXR_DIV(1);
29237dadbcaSWenyou Yang 	at91_plla_init(tmp);
29337dadbcaSWenyou Yang 
29437dadbcaSWenyou Yang 	writel(0x0 << 8, &pmc->pllicpr);
29537dadbcaSWenyou Yang 
29637dadbcaSWenyou Yang 	tmp = AT91_PMC_MCKR_H32MXDIV |
29737dadbcaSWenyou Yang 	      AT91_PMC_MCKR_PLLADIV_2 |
29837dadbcaSWenyou Yang 	      AT91_PMC_MCKR_MDIV_3 |
29937dadbcaSWenyou Yang 	      AT91_PMC_MCKR_CSS_PLLA;
30037dadbcaSWenyou Yang 	at91_mck_init(tmp);
30137dadbcaSWenyou Yang }
30237dadbcaSWenyou Yang #endif
303