1f196044dSBo Shen /*
2f196044dSBo Shen * Copyright (C) 2014 Atmel
3f196044dSBo Shen * Bo Shen <voice.shen@atmel.com>
4f196044dSBo Shen *
5f196044dSBo Shen * SPDX-License-Identifier: GPL-2.0+
6f196044dSBo Shen */
7f196044dSBo Shen
8f196044dSBo Shen #include <common.h>
9f196044dSBo Shen #include <asm/io.h>
10f196044dSBo Shen #include <asm/arch/at91_common.h>
11f196044dSBo Shen #include <asm/arch/at91_rstc.h>
120b2a9824SBo Shen #include <asm/arch/atmel_mpddrc.h>
13f196044dSBo Shen #include <asm/arch/gpio.h>
14f196044dSBo Shen #include <asm/arch/clk.h>
15f196044dSBo Shen #include <asm/arch/sama5d3_smc.h>
16f196044dSBo Shen #include <asm/arch/sama5d4.h>
1777d5b407SBo Shen #include <atmel_hlcdc.h>
18334794f5SWenyou Yang #include <debug_uart.h>
19f196044dSBo Shen #include <lcd.h>
20f196044dSBo Shen #include <nand.h>
2102fc64d1SWu, Josh #include <version.h>
22f196044dSBo Shen
23f196044dSBo Shen DECLARE_GLOBAL_DATA_PTR;
24f196044dSBo Shen
25f196044dSBo Shen #ifdef CONFIG_NAND_ATMEL
sama5d4_xplained_nand_hw_init(void)26f196044dSBo Shen static void sama5d4_xplained_nand_hw_init(void)
27f196044dSBo Shen {
28f196044dSBo Shen struct at91_smc *smc = (struct at91_smc *)ATMEL_BASE_SMC;
29f196044dSBo Shen
30f196044dSBo Shen at91_periph_clk_enable(ATMEL_ID_SMC);
31f196044dSBo Shen
32f196044dSBo Shen /* Configure SMC CS3 for NAND */
33f196044dSBo Shen writel(AT91_SMC_SETUP_NWE(1) | AT91_SMC_SETUP_NCS_WR(1) |
34f196044dSBo Shen AT91_SMC_SETUP_NRD(1) | AT91_SMC_SETUP_NCS_RD(1),
35f196044dSBo Shen &smc->cs[3].setup);
36f196044dSBo Shen writel(AT91_SMC_PULSE_NWE(2) | AT91_SMC_PULSE_NCS_WR(3) |
37f196044dSBo Shen AT91_SMC_PULSE_NRD(2) | AT91_SMC_PULSE_NCS_RD(3),
38f196044dSBo Shen &smc->cs[3].pulse);
39f196044dSBo Shen writel(AT91_SMC_CYCLE_NWE(5) | AT91_SMC_CYCLE_NRD(5),
40f196044dSBo Shen &smc->cs[3].cycle);
41f196044dSBo Shen writel(AT91_SMC_TIMINGS_TCLR(2) | AT91_SMC_TIMINGS_TADL(7) |
42f196044dSBo Shen AT91_SMC_TIMINGS_TAR(2) | AT91_SMC_TIMINGS_TRR(3) |
43f196044dSBo Shen AT91_SMC_TIMINGS_TWB(7) | AT91_SMC_TIMINGS_RBNSEL(3)|
44f196044dSBo Shen AT91_SMC_TIMINGS_NFSEL(1), &smc->cs[3].timings);
45f196044dSBo Shen writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_WM_NWE |
46f196044dSBo Shen AT91_SMC_MODE_EXNW_DISABLE |
47f196044dSBo Shen AT91_SMC_MODE_DBW_8 |
48f196044dSBo Shen AT91_SMC_MODE_TDF_CYCLE(3),
49f196044dSBo Shen &smc->cs[3].mode);
50f196044dSBo Shen
512dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTC, 5, 0); /* D0 */
522dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTC, 6, 0); /* D1 */
532dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTC, 7, 0); /* D2 */
542dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTC, 8, 0); /* D3 */
552dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTC, 9, 0); /* D4 */
562dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTC, 10, 0); /* D5 */
572dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTC, 11, 0); /* D6 */
582dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTC, 12, 0); /* D7 */
592dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTC, 13, 0); /* RE */
602dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTC, 14, 0); /* WE */
612dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTC, 15, 1); /* NCS */
622dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTC, 16, 1); /* RDY */
632dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTC, 17, 1); /* ALE */
642dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTC, 18, 1); /* CLE */
65f196044dSBo Shen }
66f196044dSBo Shen #endif
67f196044dSBo Shen
68f196044dSBo Shen #ifdef CONFIG_CMD_USB
sama5d4_xplained_usb_hw_init(void)69f196044dSBo Shen static void sama5d4_xplained_usb_hw_init(void)
70f196044dSBo Shen {
71f196044dSBo Shen at91_set_pio_output(AT91_PIO_PORTE, 11, 1);
72f196044dSBo Shen at91_set_pio_output(AT91_PIO_PORTE, 14, 1);
73f196044dSBo Shen }
74f196044dSBo Shen #endif
75f196044dSBo Shen
76f196044dSBo Shen #ifdef CONFIG_LCD
77f196044dSBo Shen vidinfo_t panel_info = {
78f196044dSBo Shen .vl_col = 480,
79f196044dSBo Shen .vl_row = 272,
8077d5b407SBo Shen .vl_clk = 9000000,
81f196044dSBo Shen .vl_bpix = LCD_BPP,
82f196044dSBo Shen .vl_tft = 1,
83f196044dSBo Shen .vl_hsync_len = 41,
84f196044dSBo Shen .vl_left_margin = 2,
85f196044dSBo Shen .vl_right_margin = 2,
86f196044dSBo Shen .vl_vsync_len = 11,
87f196044dSBo Shen .vl_upper_margin = 2,
88f196044dSBo Shen .vl_lower_margin = 2,
89f196044dSBo Shen .mmio = ATMEL_BASE_LCDC,
90f196044dSBo Shen };
91f196044dSBo Shen
92f196044dSBo Shen /* No power up/down pin for the LCD pannel */
lcd_enable(void)93f196044dSBo Shen void lcd_enable(void) { /* Empty! */ }
lcd_disable(void)94f196044dSBo Shen void lcd_disable(void) { /* Empty! */ }
95f196044dSBo Shen
has_lcdc(void)96f196044dSBo Shen unsigned int has_lcdc(void)
97f196044dSBo Shen {
98f196044dSBo Shen return 1;
99f196044dSBo Shen }
100f196044dSBo Shen
sama5d4_xplained_lcd_hw_init(void)101f196044dSBo Shen static void sama5d4_xplained_lcd_hw_init(void)
102f196044dSBo Shen {
1032dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 24, 0); /* LCDPWM */
1042dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 25, 0); /* LCDDISP */
1052dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 26, 0); /* LCDVSYNC */
1062dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 27, 0); /* LCDHSYNC */
1072dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 28, 0); /* LCDDOTCK */
1082dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 29, 0); /* LCDDEN */
109f196044dSBo Shen
1102dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 0, 0); /* LCDD0 */
1112dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 1, 0); /* LCDD1 */
1122dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 2, 0); /* LCDD2 */
1132dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 3, 0); /* LCDD3 */
1142dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 4, 0); /* LCDD4 */
1152dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 5, 0); /* LCDD5 */
1162dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 6, 0); /* LCDD6 */
1172dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 7, 0); /* LCDD7 */
118f196044dSBo Shen
1192dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 8, 0); /* LCDD9 */
1202dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 9, 0); /* LCDD8 */
1212dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 10, 0); /* LCDD10 */
1222dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 11, 0); /* LCDD11 */
1232dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 12, 0); /* LCDD12 */
1242dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 13, 0); /* LCDD13 */
1252dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 14, 0); /* LCDD14 */
1262dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 15, 0); /* LCDD15 */
127f196044dSBo Shen
1282dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 16, 0); /* LCDD16 */
1292dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 17, 0); /* LCDD17 */
1302dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 18, 0); /* LCDD18 */
1312dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 19, 0); /* LCDD19 */
1322dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 20, 0); /* LCDD20 */
1332dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 21, 0); /* LCDD21 */
1342dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 22, 0); /* LCDD22 */
1352dc63f73SWenyou Yang at91_pio3_set_a_periph(AT91_PIO_PORTA, 23, 0); /* LCDD23 */
136f196044dSBo Shen
137f196044dSBo Shen /* Enable clock */
138f196044dSBo Shen at91_periph_clk_enable(ATMEL_ID_LCDC);
139f196044dSBo Shen }
140f196044dSBo Shen
141f196044dSBo Shen #ifdef CONFIG_LCD_INFO
lcd_show_board_info(void)142f196044dSBo Shen void lcd_show_board_info(void)
143f196044dSBo Shen {
144f196044dSBo Shen ulong dram_size, nand_size;
145f196044dSBo Shen int i;
146f196044dSBo Shen char temp[32];
147f196044dSBo Shen
14802fc64d1SWu, Josh lcd_printf("%s\n", U_BOOT_VERSION);
149f196044dSBo Shen lcd_printf("2014 ATMEL Corp\n");
150f196044dSBo Shen lcd_printf("%s CPU at %s MHz\n", get_cpu_name(),
151f196044dSBo Shen strmhz(temp, get_cpu_clk_rate()));
152f196044dSBo Shen
153f196044dSBo Shen dram_size = 0;
154f196044dSBo Shen for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
155f196044dSBo Shen dram_size += gd->bd->bi_dram[i].size;
156f196044dSBo Shen
157f196044dSBo Shen nand_size = 0;
158f196044dSBo Shen #ifdef CONFIG_NAND_ATMEL
159f196044dSBo Shen for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)
160*31f8d39eSGrygorii Strashko nand_size += get_nand_dev_by_index(i)->size;
161f196044dSBo Shen #endif
162f196044dSBo Shen lcd_printf("%ld MB SDRAM, %ld MB NAND\n",
163f196044dSBo Shen dram_size >> 20, nand_size >> 20);
164f196044dSBo Shen }
165f196044dSBo Shen #endif /* CONFIG_LCD_INFO */
166f196044dSBo Shen
167f196044dSBo Shen #endif /* CONFIG_LCD */
168f196044dSBo Shen
169334794f5SWenyou Yang #ifdef CONFIG_DEBUG_UART_BOARD_INIT
sama5d4_xplained_serial3_hw_init(void)170f196044dSBo Shen static void sama5d4_xplained_serial3_hw_init(void)
171f196044dSBo Shen {
1722dc63f73SWenyou Yang at91_pio3_set_b_periph(AT91_PIO_PORTE, 17, 1); /* TXD3 */
1732dc63f73SWenyou Yang at91_pio3_set_b_periph(AT91_PIO_PORTE, 16, 0); /* RXD3 */
174f196044dSBo Shen
175f196044dSBo Shen /* Enable clock */
176f196044dSBo Shen at91_periph_clk_enable(ATMEL_ID_USART3);
177f196044dSBo Shen }
178f196044dSBo Shen
board_debug_uart_init(void)179334794f5SWenyou Yang void board_debug_uart_init(void)
180f196044dSBo Shen {
181f196044dSBo Shen sama5d4_xplained_serial3_hw_init();
182334794f5SWenyou Yang }
183334794f5SWenyou Yang #endif
184f196044dSBo Shen
185334794f5SWenyou Yang #ifdef CONFIG_BOARD_EARLY_INIT_F
board_early_init_f(void)186334794f5SWenyou Yang int board_early_init_f(void)
187334794f5SWenyou Yang {
188334794f5SWenyou Yang #ifdef CONFIG_DEBUG_UART
189334794f5SWenyou Yang debug_uart_init();
190334794f5SWenyou Yang #endif
191f196044dSBo Shen return 0;
192f196044dSBo Shen }
193334794f5SWenyou Yang #endif
194f196044dSBo Shen
board_init(void)195f196044dSBo Shen int board_init(void)
196f196044dSBo Shen {
197f196044dSBo Shen /* adress of boot parameters */
198f196044dSBo Shen gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
199f196044dSBo Shen
200f196044dSBo Shen #ifdef CONFIG_NAND_ATMEL
201f196044dSBo Shen sama5d4_xplained_nand_hw_init();
202f196044dSBo Shen #endif
203f196044dSBo Shen #ifdef CONFIG_LCD
204f196044dSBo Shen sama5d4_xplained_lcd_hw_init();
205f196044dSBo Shen #endif
206f196044dSBo Shen #ifdef CONFIG_CMD_USB
207f196044dSBo Shen sama5d4_xplained_usb_hw_init();
208f196044dSBo Shen #endif
209f196044dSBo Shen
210f196044dSBo Shen return 0;
211f196044dSBo Shen }
212f196044dSBo Shen
dram_init(void)213f196044dSBo Shen int dram_init(void)
214f196044dSBo Shen {
215f196044dSBo Shen gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
216f196044dSBo Shen CONFIG_SYS_SDRAM_SIZE);
217f196044dSBo Shen return 0;
218f196044dSBo Shen }
219f196044dSBo Shen
2200b2a9824SBo Shen /* SPL */
2210b2a9824SBo Shen #ifdef CONFIG_SPL_BUILD
spl_board_init(void)2220b2a9824SBo Shen void spl_board_init(void)
2230b2a9824SBo Shen {
2243b93f852SWenyou Yang #if CONFIG_SYS_USE_NANDFLASH
2250b2a9824SBo Shen sama5d4_xplained_nand_hw_init();
2260b2a9824SBo Shen #endif
2270b2a9824SBo Shen }
2280b2a9824SBo Shen
ddr2_conf(struct atmel_mpddrc_config * ddr2)2297e8702a0SWenyou Yang static void ddr2_conf(struct atmel_mpddrc_config *ddr2)
2300b2a9824SBo Shen {
2310b2a9824SBo Shen ddr2->md = (ATMEL_MPDDRC_MD_DBW_32_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM);
2320b2a9824SBo Shen
2330b2a9824SBo Shen ddr2->cr = (ATMEL_MPDDRC_CR_NC_COL_10 |
2340b2a9824SBo Shen ATMEL_MPDDRC_CR_NR_ROW_14 |
2350b2a9824SBo Shen ATMEL_MPDDRC_CR_CAS_DDR_CAS3 |
2360b2a9824SBo Shen ATMEL_MPDDRC_CR_NB_8BANKS |
2370b2a9824SBo Shen ATMEL_MPDDRC_CR_NDQS_DISABLED |
2380b2a9824SBo Shen ATMEL_MPDDRC_CR_DECOD_INTERLEAVED |
2390b2a9824SBo Shen ATMEL_MPDDRC_CR_UNAL_SUPPORTED);
2400b2a9824SBo Shen
2410b2a9824SBo Shen ddr2->rtr = 0x2b0;
2420b2a9824SBo Shen
2430b2a9824SBo Shen ddr2->tpr0 = (8 << ATMEL_MPDDRC_TPR0_TRAS_OFFSET |
2440b2a9824SBo Shen 3 << ATMEL_MPDDRC_TPR0_TRCD_OFFSET |
2450b2a9824SBo Shen 3 << ATMEL_MPDDRC_TPR0_TWR_OFFSET |
2460b2a9824SBo Shen 10 << ATMEL_MPDDRC_TPR0_TRC_OFFSET |
2470b2a9824SBo Shen 3 << ATMEL_MPDDRC_TPR0_TRP_OFFSET |
2480b2a9824SBo Shen 2 << ATMEL_MPDDRC_TPR0_TRRD_OFFSET |
2490b2a9824SBo Shen 2 << ATMEL_MPDDRC_TPR0_TWTR_OFFSET |
2500b2a9824SBo Shen 2 << ATMEL_MPDDRC_TPR0_TMRD_OFFSET);
2510b2a9824SBo Shen
2520b2a9824SBo Shen ddr2->tpr1 = (2 << ATMEL_MPDDRC_TPR1_TXP_OFFSET |
2530b2a9824SBo Shen 200 << ATMEL_MPDDRC_TPR1_TXSRD_OFFSET |
2540b2a9824SBo Shen 25 << ATMEL_MPDDRC_TPR1_TXSNR_OFFSET |
2550b2a9824SBo Shen 23 << ATMEL_MPDDRC_TPR1_TRFC_OFFSET);
2560b2a9824SBo Shen
2570b2a9824SBo Shen ddr2->tpr2 = (7 << ATMEL_MPDDRC_TPR2_TFAW_OFFSET |
2580b2a9824SBo Shen 2 << ATMEL_MPDDRC_TPR2_TRTP_OFFSET |
2590b2a9824SBo Shen 3 << ATMEL_MPDDRC_TPR2_TRPA_OFFSET |
2600b2a9824SBo Shen 2 << ATMEL_MPDDRC_TPR2_TXARDS_OFFSET |
2610b2a9824SBo Shen 8 << ATMEL_MPDDRC_TPR2_TXARD_OFFSET);
2620b2a9824SBo Shen }
2630b2a9824SBo Shen
mem_init(void)2640b2a9824SBo Shen void mem_init(void)
2650b2a9824SBo Shen {
2667e8702a0SWenyou Yang struct atmel_mpddrc_config ddr2;
2670b2a9824SBo Shen
2680b2a9824SBo Shen ddr2_conf(&ddr2);
2690b2a9824SBo Shen
27070341e2eSWenyou Yang /* Enable MPDDR clock */
2710b2a9824SBo Shen at91_periph_clk_enable(ATMEL_ID_MPDDRC);
27270341e2eSWenyou Yang at91_system_clk_enable(AT91_PMC_DDR);
2730b2a9824SBo Shen
2740b2a9824SBo Shen /* DDRAM2 Controller initialize */
2750c01c3e8SErik van Luijk ddr2_init(ATMEL_BASE_MPDDRC, ATMEL_BASE_DDRCS, &ddr2);
2760b2a9824SBo Shen }
2770b2a9824SBo Shen
at91_pmc_init(void)2780b2a9824SBo Shen void at91_pmc_init(void)
2790b2a9824SBo Shen {
2800b2a9824SBo Shen u32 tmp;
2810b2a9824SBo Shen
2820b2a9824SBo Shen tmp = AT91_PMC_PLLAR_29 |
2830b2a9824SBo Shen AT91_PMC_PLLXR_PLLCOUNT(0x3f) |
2840b2a9824SBo Shen AT91_PMC_PLLXR_MUL(87) |
2850b2a9824SBo Shen AT91_PMC_PLLXR_DIV(1);
2860b2a9824SBo Shen at91_plla_init(tmp);
2870b2a9824SBo Shen
288ede86ed2SWenyou Yang at91_pllicpr_init(AT91_PMC_IPLL_PLLA(0x0));
2890b2a9824SBo Shen
2900b2a9824SBo Shen tmp = AT91_PMC_MCKR_H32MXDIV |
2910b2a9824SBo Shen AT91_PMC_MCKR_PLLADIV_2 |
2920b2a9824SBo Shen AT91_PMC_MCKR_MDIV_3 |
2930b2a9824SBo Shen AT91_PMC_MCKR_CSS_PLLA;
2940b2a9824SBo Shen at91_mck_init(tmp);
2950b2a9824SBo Shen }
2960b2a9824SBo Shen #endif
297