]>
Commit | Line | Data |
---|---|---|
14d5aeff IO |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * Copyright 2020 Toradex | |
4 | */ | |
5 | ||
6 | #include <common.h> | |
09140113 | 7 | #include <command.h> |
4d72caa5 | 8 | #include <image.h> |
691d719d | 9 | #include <init.h> |
14d5aeff IO |
10 | #include <asm/arch/clock.h> |
11 | #include <asm/arch/ddr.h> | |
12 | #include <asm/arch/imx8mm_pins.h> | |
13 | #include <asm/arch/sys_proto.h> | |
14 | #include <asm/io.h> | |
15 | #include <asm/mach-imx/boot_mode.h> | |
16 | #include <asm/mach-imx/iomux-v3.h> | |
17 | #include <cpu_func.h> | |
18 | #include <dm/device.h> | |
19 | #include <dm/device-internal.h> | |
20 | #include <dm/uclass.h> | |
21 | #include <dm/uclass-internal.h> | |
22 | #include <hang.h> | |
23 | #include <power/bd71837.h> | |
24 | #include <power/pmic.h> | |
25 | #include <spl.h> | |
26 | ||
27 | DECLARE_GLOBAL_DATA_PTR; | |
28 | ||
29 | int spl_board_boot_device(enum boot_device boot_dev_spl) | |
30 | { | |
31 | switch (boot_dev_spl) { | |
32 | case MMC1_BOOT: | |
33 | return BOOT_DEVICE_MMC1; | |
34 | case SD2_BOOT: | |
35 | case MMC2_BOOT: | |
36 | return BOOT_DEVICE_MMC2; | |
37 | case SD3_BOOT: | |
38 | case MMC3_BOOT: | |
39 | return BOOT_DEVICE_MMC1; | |
40 | case USB_BOOT: | |
41 | return BOOT_DEVICE_BOARD; | |
42 | default: | |
43 | return BOOT_DEVICE_NONE; | |
44 | } | |
45 | } | |
46 | ||
47 | void spl_dram_init(void) | |
48 | { | |
49 | ddr_init(&dram_timing); | |
50 | } | |
51 | ||
52 | void spl_board_init(void) | |
53 | { | |
54 | /* Serial download mode */ | |
55 | if (is_usb_boot()) { | |
56 | puts("Back to ROM, SDP\n"); | |
57 | restore_boot_params(); | |
58 | } | |
59 | puts("Normal Boot\n"); | |
60 | } | |
61 | ||
62 | #ifdef CONFIG_SPL_LOAD_FIT | |
63 | int board_fit_config_name_match(const char *name) | |
64 | { | |
65 | /* Just empty function now - can't decide what to choose */ | |
66 | debug("%s: %s\n", __func__, name); | |
67 | ||
68 | return 0; | |
69 | } | |
70 | #endif | |
71 | ||
72 | #define UART_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_PE | PAD_CTL_DSE4) | |
73 | #define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE) | |
74 | ||
75 | /* Verdin UART_3, Console/Debug UART */ | |
76 | static iomux_v3_cfg_t const uart_pads[] = { | |
77 | IMX8MM_PAD_SAI2_RXFS_UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), | |
78 | IMX8MM_PAD_SAI2_RXC_UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), | |
79 | }; | |
80 | ||
81 | static iomux_v3_cfg_t const wdog_pads[] = { | |
82 | IMX8MM_PAD_GPIO1_IO02_WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL), | |
83 | }; | |
84 | ||
85 | int board_early_init_f(void) | |
86 | { | |
87 | struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; | |
88 | ||
89 | imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads)); | |
90 | ||
91 | set_wdog_reset(wdog); | |
92 | ||
93 | imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads)); | |
94 | ||
95 | return 0; | |
96 | } | |
97 | ||
98 | int power_init_board(void) | |
99 | { | |
100 | struct udevice *dev; | |
101 | int ret; | |
102 | ||
103 | ret = pmic_get("pmic@4b", &dev); | |
104 | if (ret == -ENODEV) { | |
105 | puts("No pmic\n"); | |
106 | return 0; | |
107 | } | |
108 | if (ret != 0) | |
109 | return ret; | |
110 | ||
111 | /* decrease RESET key long push time from the default 10s to 10ms */ | |
112 | pmic_reg_write(dev, BD718XX_PWRONCONFIG1, 0x0); | |
113 | ||
114 | /* unlock the PMIC regs */ | |
115 | pmic_reg_write(dev, BD718XX_REGLOCK, 0x1); | |
116 | ||
117 | /* increase VDD_SOC to typical value 0.85v before first DRAM access */ | |
118 | pmic_reg_write(dev, BD718XX_BUCK1_VOLT_RUN, 0x0f); | |
119 | ||
120 | /* increase VDD_DRAM to 0.975v for 3Ghz DDR */ | |
121 | pmic_reg_write(dev, BD718XX_1ST_NODVS_BUCK_VOLT, 0x83); | |
122 | ||
123 | #ifndef CONFIG_IMX8M_LPDDR4 | |
124 | /* increase NVCC_DRAM_1V2 to 1.2v for DDR4 */ | |
125 | pmic_reg_write(dev, BD718XX_4TH_NODVS_BUCK_VOLT, 0x28); | |
126 | #endif | |
127 | ||
128 | /* lock the PMIC regs */ | |
129 | pmic_reg_write(dev, BD718XX_REGLOCK, 0x11); | |
130 | ||
131 | return 0; | |
132 | } | |
133 | ||
134 | void board_init_f(ulong dummy) | |
135 | { | |
136 | struct udevice *dev; | |
137 | int ret; | |
138 | ||
139 | arch_cpu_init(); | |
140 | ||
141 | init_uart_clk(0); | |
142 | ||
143 | board_early_init_f(); | |
144 | ||
145 | timer_init(); | |
146 | ||
147 | preloader_console_init(); | |
148 | ||
149 | /* Clear the BSS. */ | |
150 | memset(__bss_start, 0, __bss_end - __bss_start); | |
151 | ||
152 | ret = spl_early_init(); | |
153 | if (ret) { | |
154 | debug("spl_early_init() failed: %d\n", ret); | |
155 | hang(); | |
156 | } | |
157 | ||
158 | ret = uclass_get_device_by_name(UCLASS_CLK, | |
159 | "clock-controller@30380000", | |
160 | &dev); | |
161 | if (ret < 0) { | |
162 | printf("Failed to find clock node. Check device tree\n"); | |
163 | hang(); | |
164 | } | |
165 | ||
166 | enable_tzc380(); | |
167 | ||
168 | power_init_board(); | |
169 | ||
170 | /* DDR initialization */ | |
171 | spl_dram_init(); | |
172 | ||
173 | board_init_r(NULL, 0); | |
174 | } |