183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2f196044dSBo Shen /*
3f196044dSBo Shen  * Copyright (C) 2014 Atmel
4f196044dSBo Shen  *		      Bo Shen <voice.shen@atmel.com>
5f196044dSBo Shen  */
6f196044dSBo Shen 
7f196044dSBo Shen #include <common.h>
8f196044dSBo Shen #include <asm/io.h>
9f196044dSBo Shen #include <asm/arch/at91_common.h>
10f196044dSBo Shen #include <asm/arch/at91_rstc.h>
110b2a9824SBo Shen #include <asm/arch/atmel_mpddrc.h>
12f196044dSBo Shen #include <asm/arch/gpio.h>
13f196044dSBo Shen #include <asm/arch/clk.h>
14f196044dSBo Shen #include <asm/arch/sama5d3_smc.h>
15f196044dSBo Shen #include <asm/arch/sama5d4.h>
16334794f5SWenyou Yang #include <debug_uart.h>
17f196044dSBo Shen 
18f196044dSBo Shen DECLARE_GLOBAL_DATA_PTR;
19f196044dSBo Shen 
20*95501d52SEugen Hristev extern void at91_pda_detect(void);
21*95501d52SEugen Hristev 
22f196044dSBo Shen #ifdef CONFIG_NAND_ATMEL
sama5d4_xplained_nand_hw_init(void)23f196044dSBo Shen static void sama5d4_xplained_nand_hw_init(void)
24f196044dSBo Shen {
25f196044dSBo Shen 	struct at91_smc *smc = (struct at91_smc *)ATMEL_BASE_SMC;
26f196044dSBo Shen 
27f196044dSBo Shen 	at91_periph_clk_enable(ATMEL_ID_SMC);
28f196044dSBo Shen 
29f196044dSBo Shen 	/* Configure SMC CS3 for NAND */
30f196044dSBo Shen 	writel(AT91_SMC_SETUP_NWE(1) | AT91_SMC_SETUP_NCS_WR(1) |
31f196044dSBo Shen 	       AT91_SMC_SETUP_NRD(1) | AT91_SMC_SETUP_NCS_RD(1),
32f196044dSBo Shen 	       &smc->cs[3].setup);
33f196044dSBo Shen 	writel(AT91_SMC_PULSE_NWE(2) | AT91_SMC_PULSE_NCS_WR(3) |
34f196044dSBo Shen 	       AT91_SMC_PULSE_NRD(2) | AT91_SMC_PULSE_NCS_RD(3),
35f196044dSBo Shen 	       &smc->cs[3].pulse);
36f196044dSBo Shen 	writel(AT91_SMC_CYCLE_NWE(5) | AT91_SMC_CYCLE_NRD(5),
37f196044dSBo Shen 	       &smc->cs[3].cycle);
38f196044dSBo Shen 	writel(AT91_SMC_TIMINGS_TCLR(2) | AT91_SMC_TIMINGS_TADL(7) |
39f196044dSBo Shen 	       AT91_SMC_TIMINGS_TAR(2)  | AT91_SMC_TIMINGS_TRR(3)   |
40f196044dSBo Shen 	       AT91_SMC_TIMINGS_TWB(7)  | AT91_SMC_TIMINGS_RBNSEL(3)|
41f196044dSBo Shen 	       AT91_SMC_TIMINGS_NFSEL(1), &smc->cs[3].timings);
42f196044dSBo Shen 	writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_WM_NWE |
43f196044dSBo Shen 	       AT91_SMC_MODE_EXNW_DISABLE |
44f196044dSBo Shen 	       AT91_SMC_MODE_DBW_8 |
45f196044dSBo Shen 	       AT91_SMC_MODE_TDF_CYCLE(3),
46f196044dSBo Shen 	       &smc->cs[3].mode);
47f196044dSBo Shen 
482dc63f73SWenyou Yang 	at91_pio3_set_a_periph(AT91_PIO_PORTC, 5, 0);	/* D0 */
492dc63f73SWenyou Yang 	at91_pio3_set_a_periph(AT91_PIO_PORTC, 6, 0);	/* D1 */
502dc63f73SWenyou Yang 	at91_pio3_set_a_periph(AT91_PIO_PORTC, 7, 0);	/* D2 */
512dc63f73SWenyou Yang 	at91_pio3_set_a_periph(AT91_PIO_PORTC, 8, 0);	/* D3 */
522dc63f73SWenyou Yang 	at91_pio3_set_a_periph(AT91_PIO_PORTC, 9, 0);	/* D4 */
532dc63f73SWenyou Yang 	at91_pio3_set_a_periph(AT91_PIO_PORTC, 10, 0);	/* D5 */
542dc63f73SWenyou Yang 	at91_pio3_set_a_periph(AT91_PIO_PORTC, 11, 0);	/* D6 */
552dc63f73SWenyou Yang 	at91_pio3_set_a_periph(AT91_PIO_PORTC, 12, 0);	/* D7 */
562dc63f73SWenyou Yang 	at91_pio3_set_a_periph(AT91_PIO_PORTC, 13, 0);	/* RE */
572dc63f73SWenyou Yang 	at91_pio3_set_a_periph(AT91_PIO_PORTC, 14, 0);	/* WE */
582dc63f73SWenyou Yang 	at91_pio3_set_a_periph(AT91_PIO_PORTC, 15, 1);	/* NCS */
592dc63f73SWenyou Yang 	at91_pio3_set_a_periph(AT91_PIO_PORTC, 16, 1);	/* RDY */
602dc63f73SWenyou Yang 	at91_pio3_set_a_periph(AT91_PIO_PORTC, 17, 1);	/* ALE */
612dc63f73SWenyou Yang 	at91_pio3_set_a_periph(AT91_PIO_PORTC, 18, 1);	/* CLE */
62f196044dSBo Shen }
63f196044dSBo Shen #endif
64f196044dSBo Shen 
65f196044dSBo Shen #ifdef CONFIG_CMD_USB
sama5d4_xplained_usb_hw_init(void)66f196044dSBo Shen static void sama5d4_xplained_usb_hw_init(void)
67f196044dSBo Shen {
68f196044dSBo Shen 	at91_set_pio_output(AT91_PIO_PORTE, 11, 1);
69f196044dSBo Shen 	at91_set_pio_output(AT91_PIO_PORTE, 14, 1);
70f196044dSBo Shen }
71f196044dSBo Shen #endif
72f196044dSBo Shen 
73e974b081SWenyou Yang #ifdef CONFIG_BOARD_LATE_INIT
board_late_init(void)74e974b081SWenyou Yang int board_late_init(void)
75f196044dSBo Shen {
76*95501d52SEugen Hristev 	at91_pda_detect();
77e974b081SWenyou Yang #ifdef CONFIG_DM_VIDEO
78e974b081SWenyou Yang 	at91_video_show_board_info();
79f196044dSBo Shen #endif
80e974b081SWenyou Yang 	return 0;
81f196044dSBo Shen }
82e974b081SWenyou Yang #endif
83f196044dSBo Shen 
84334794f5SWenyou Yang #ifdef CONFIG_DEBUG_UART_BOARD_INIT
sama5d4_xplained_serial3_hw_init(void)85f196044dSBo Shen static void sama5d4_xplained_serial3_hw_init(void)
86f196044dSBo Shen {
872dc63f73SWenyou Yang 	at91_pio3_set_b_periph(AT91_PIO_PORTE, 17, 1);	/* TXD3 */
882dc63f73SWenyou Yang 	at91_pio3_set_b_periph(AT91_PIO_PORTE, 16, 0);	/* RXD3 */
89f196044dSBo Shen 
90f196044dSBo Shen 	/* Enable clock */
91f196044dSBo Shen 	at91_periph_clk_enable(ATMEL_ID_USART3);
92f196044dSBo Shen }
93f196044dSBo Shen 
board_debug_uart_init(void)94334794f5SWenyou Yang void board_debug_uart_init(void)
95f196044dSBo Shen {
96f196044dSBo Shen 	sama5d4_xplained_serial3_hw_init();
97334794f5SWenyou Yang }
98334794f5SWenyou Yang #endif
99f196044dSBo Shen 
100334794f5SWenyou Yang #ifdef CONFIG_BOARD_EARLY_INIT_F
board_early_init_f(void)101334794f5SWenyou Yang int board_early_init_f(void)
102334794f5SWenyou Yang {
103334794f5SWenyou Yang #ifdef CONFIG_DEBUG_UART
104334794f5SWenyou Yang 	debug_uart_init();
105334794f5SWenyou Yang #endif
106f196044dSBo Shen 	return 0;
107f196044dSBo Shen }
108334794f5SWenyou Yang #endif
109f196044dSBo Shen 
110fafa4403SWenyou Yang #define AT24MAC_MAC_OFFSET	0x9a
111fafa4403SWenyou Yang 
112fafa4403SWenyou Yang #ifdef CONFIG_MISC_INIT_R
misc_init_r(void)113fafa4403SWenyou Yang int misc_init_r(void)
114fafa4403SWenyou Yang {
115fafa4403SWenyou Yang #ifdef CONFIG_I2C_EEPROM
116fafa4403SWenyou Yang 	at91_set_ethaddr(AT24MAC_MAC_OFFSET);
117fafa4403SWenyou Yang #endif
118fafa4403SWenyou Yang 	return 0;
119fafa4403SWenyou Yang }
120fafa4403SWenyou Yang #endif
121fafa4403SWenyou Yang 
board_init(void)122f196044dSBo Shen int board_init(void)
123f196044dSBo Shen {
124f196044dSBo Shen 	/* adress of boot parameters */
125f196044dSBo Shen 	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
126f196044dSBo Shen 
127f196044dSBo Shen #ifdef CONFIG_NAND_ATMEL
128f196044dSBo Shen 	sama5d4_xplained_nand_hw_init();
129f196044dSBo Shen #endif
130f196044dSBo Shen #ifdef CONFIG_CMD_USB
131f196044dSBo Shen 	sama5d4_xplained_usb_hw_init();
132f196044dSBo Shen #endif
133f196044dSBo Shen 
134f196044dSBo Shen 	return 0;
135f196044dSBo Shen }
136f196044dSBo Shen 
dram_init(void)137f196044dSBo Shen int dram_init(void)
138f196044dSBo Shen {
139f196044dSBo Shen 	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
140f196044dSBo Shen 				    CONFIG_SYS_SDRAM_SIZE);
141f196044dSBo Shen 	return 0;
142f196044dSBo Shen }
143f196044dSBo Shen 
1440b2a9824SBo Shen /* SPL */
1450b2a9824SBo Shen #ifdef CONFIG_SPL_BUILD
spl_board_init(void)1460b2a9824SBo Shen void spl_board_init(void)
1470b2a9824SBo Shen {
1485541543fSWenyou Yang #if CONFIG_NAND_BOOT
1490b2a9824SBo Shen 	sama5d4_xplained_nand_hw_init();
1500b2a9824SBo Shen #endif
1510b2a9824SBo Shen }
1520b2a9824SBo Shen 
ddr2_conf(struct atmel_mpddrc_config * ddr2)1537e8702a0SWenyou Yang static void ddr2_conf(struct atmel_mpddrc_config *ddr2)
1540b2a9824SBo Shen {
1550b2a9824SBo Shen 	ddr2->md = (ATMEL_MPDDRC_MD_DBW_32_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM);
1560b2a9824SBo Shen 
1570b2a9824SBo Shen 	ddr2->cr = (ATMEL_MPDDRC_CR_NC_COL_10 |
1580b2a9824SBo Shen 		    ATMEL_MPDDRC_CR_NR_ROW_14 |
1590b2a9824SBo Shen 		    ATMEL_MPDDRC_CR_CAS_DDR_CAS3 |
1600b2a9824SBo Shen 		    ATMEL_MPDDRC_CR_NB_8BANKS |
1610b2a9824SBo Shen 		    ATMEL_MPDDRC_CR_NDQS_DISABLED |
1620b2a9824SBo Shen 		    ATMEL_MPDDRC_CR_DECOD_INTERLEAVED |
1630b2a9824SBo Shen 		    ATMEL_MPDDRC_CR_UNAL_SUPPORTED);
1640b2a9824SBo Shen 
1650b2a9824SBo Shen 	ddr2->rtr = 0x2b0;
1660b2a9824SBo Shen 
1670b2a9824SBo Shen 	ddr2->tpr0 = (8 << ATMEL_MPDDRC_TPR0_TRAS_OFFSET |
1680b2a9824SBo Shen 		      3 << ATMEL_MPDDRC_TPR0_TRCD_OFFSET |
1690b2a9824SBo Shen 		      3 << ATMEL_MPDDRC_TPR0_TWR_OFFSET |
1700b2a9824SBo Shen 		      10 << ATMEL_MPDDRC_TPR0_TRC_OFFSET |
1710b2a9824SBo Shen 		      3 << ATMEL_MPDDRC_TPR0_TRP_OFFSET |
1720b2a9824SBo Shen 		      2 << ATMEL_MPDDRC_TPR0_TRRD_OFFSET |
1730b2a9824SBo Shen 		      2 << ATMEL_MPDDRC_TPR0_TWTR_OFFSET |
1740b2a9824SBo Shen 		      2 << ATMEL_MPDDRC_TPR0_TMRD_OFFSET);
1750b2a9824SBo Shen 
1760b2a9824SBo Shen 	ddr2->tpr1 = (2 << ATMEL_MPDDRC_TPR1_TXP_OFFSET |
1770b2a9824SBo Shen 		      200 << ATMEL_MPDDRC_TPR1_TXSRD_OFFSET |
1780b2a9824SBo Shen 		      25 << ATMEL_MPDDRC_TPR1_TXSNR_OFFSET |
1790b2a9824SBo Shen 		      23 << ATMEL_MPDDRC_TPR1_TRFC_OFFSET);
1800b2a9824SBo Shen 
1810b2a9824SBo Shen 	ddr2->tpr2 = (7 << ATMEL_MPDDRC_TPR2_TFAW_OFFSET |
1820b2a9824SBo Shen 		      2 << ATMEL_MPDDRC_TPR2_TRTP_OFFSET |
1830b2a9824SBo Shen 		      3 << ATMEL_MPDDRC_TPR2_TRPA_OFFSET |
1840b2a9824SBo Shen 		      2 << ATMEL_MPDDRC_TPR2_TXARDS_OFFSET |
1850b2a9824SBo Shen 		      8 << ATMEL_MPDDRC_TPR2_TXARD_OFFSET);
1860b2a9824SBo Shen }
1870b2a9824SBo Shen 
mem_init(void)1880b2a9824SBo Shen void mem_init(void)
1890b2a9824SBo Shen {
1907e8702a0SWenyou Yang 	struct atmel_mpddrc_config ddr2;
1910b2a9824SBo Shen 
1920b2a9824SBo Shen 	ddr2_conf(&ddr2);
1930b2a9824SBo Shen 
19470341e2eSWenyou Yang 	/* Enable MPDDR clock */
1950b2a9824SBo Shen 	at91_periph_clk_enable(ATMEL_ID_MPDDRC);
19670341e2eSWenyou Yang 	at91_system_clk_enable(AT91_PMC_DDR);
1970b2a9824SBo Shen 
1980b2a9824SBo Shen 	/* DDRAM2 Controller initialize */
1990c01c3e8SErik van Luijk 	ddr2_init(ATMEL_BASE_MPDDRC, ATMEL_BASE_DDRCS, &ddr2);
2000b2a9824SBo Shen }
2010b2a9824SBo Shen 
at91_pmc_init(void)2020b2a9824SBo Shen void at91_pmc_init(void)
2030b2a9824SBo Shen {
2040b2a9824SBo Shen 	u32 tmp;
2050b2a9824SBo Shen 
2060b2a9824SBo Shen 	tmp = AT91_PMC_PLLAR_29 |
2070b2a9824SBo Shen 	      AT91_PMC_PLLXR_PLLCOUNT(0x3f) |
2080b2a9824SBo Shen 	      AT91_PMC_PLLXR_MUL(87) |
2090b2a9824SBo Shen 	      AT91_PMC_PLLXR_DIV(1);
2100b2a9824SBo Shen 	at91_plla_init(tmp);
2110b2a9824SBo Shen 
212ede86ed2SWenyou Yang 	at91_pllicpr_init(AT91_PMC_IPLL_PLLA(0x0));
2130b2a9824SBo Shen 
2140b2a9824SBo Shen 	tmp = AT91_PMC_MCKR_H32MXDIV |
2150b2a9824SBo Shen 	      AT91_PMC_MCKR_PLLADIV_2 |
2160b2a9824SBo Shen 	      AT91_PMC_MCKR_MDIV_3 |
2170b2a9824SBo Shen 	      AT91_PMC_MCKR_CSS_PLLA;
2180b2a9824SBo Shen 	at91_mck_init(tmp);
2190b2a9824SBo Shen }
2200b2a9824SBo Shen #endif
221