]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
6b0071c1 PST |
2 | /* |
3 | * Copyright 2017 General Electric Company | |
4 | * | |
5 | * Based on board/freescale/mx53loco/mx53loco.c: | |
6 | * | |
7 | * Copyright (C) 2011 Freescale Semiconductor, Inc. | |
8 | * Jason Liu <[email protected]> | |
6b0071c1 PST |
9 | */ |
10 | ||
11 | #include <common.h> | |
5255932f | 12 | #include <init.h> |
6b0071c1 PST |
13 | #include <asm/io.h> |
14 | #include <asm/arch/imx-regs.h> | |
15 | #include <asm/arch/sys_proto.h> | |
16 | #include <asm/arch/crm_regs.h> | |
17 | #include <asm/arch/clock.h> | |
18 | #include <asm/arch/iomux-mx53.h> | |
19 | #include <asm/arch/clock.h> | |
9fb625ce | 20 | #include <env.h> |
6b0071c1 | 21 | #include <linux/errno.h> |
61c4c2bf | 22 | #include <linux/libfdt.h> |
6b0071c1 PST |
23 | #include <asm/mach-imx/mxc_i2c.h> |
24 | #include <asm/mach-imx/mx5_video.h> | |
25 | #include <netdev.h> | |
26 | #include <i2c.h> | |
27 | #include <mmc.h> | |
e37ac717 | 28 | #include <fsl_esdhc_imx.h> |
6b0071c1 PST |
29 | #include <asm/gpio.h> |
30 | #include <power/pmic.h> | |
31 | #include <dialog_pmic.h> | |
32 | #include <fsl_pmic.h> | |
33 | #include <linux/fb.h> | |
34 | #include <ipu_pixfmt.h> | |
61c4c2bf | 35 | #include <version.h> |
6b0071c1 PST |
36 | #include <watchdog.h> |
37 | #include "ppd_gpio.h" | |
38 | #include <stdlib.h> | |
36e3e7de | 39 | #include "../../ge/common/ge_rtc.h" |
6b0071c1 | 40 | #include "../../ge/common/vpd_reader.h" |
6b0071c1 | 41 | |
6b0071c1 PST |
42 | DECLARE_GLOBAL_DATA_PTR; |
43 | ||
6b0071c1 PST |
44 | static u32 mx53_dram_size[2]; |
45 | ||
46 | phys_size_t get_effective_memsize(void) | |
47 | { | |
48 | /* | |
49 | * WARNING: We must override get_effective_memsize() function here | |
50 | * to report only the size of the first DRAM bank. This is to make | |
51 | * U-Boot relocator place U-Boot into valid memory, that is, at the | |
52 | * end of the first DRAM bank. If we did not override this function | |
53 | * like so, U-Boot would be placed at the address of the first DRAM | |
54 | * bank + total DRAM size - sizeof(uboot), which in the setup where | |
55 | * each DRAM bank contains 512MiB of DRAM would result in placing | |
56 | * U-Boot into invalid memory area close to the end of the first | |
57 | * DRAM bank. | |
58 | */ | |
59 | return mx53_dram_size[0]; | |
60 | } | |
61 | ||
62 | int dram_init(void) | |
63 | { | |
64 | mx53_dram_size[0] = get_ram_size((void *)PHYS_SDRAM_1, 1 << 30); | |
65 | mx53_dram_size[1] = get_ram_size((void *)PHYS_SDRAM_2, 1 << 30); | |
66 | ||
67 | gd->ram_size = mx53_dram_size[0] + mx53_dram_size[1]; | |
68 | ||
69 | return 0; | |
70 | } | |
71 | ||
72 | int dram_init_banksize(void) | |
73 | { | |
74 | gd->bd->bi_dram[0].start = PHYS_SDRAM_1; | |
75 | gd->bd->bi_dram[0].size = mx53_dram_size[0]; | |
76 | ||
77 | gd->bd->bi_dram[1].start = PHYS_SDRAM_2; | |
78 | gd->bd->bi_dram[1].size = mx53_dram_size[1]; | |
79 | ||
80 | return 0; | |
81 | } | |
82 | ||
83 | u32 get_board_rev(void) | |
84 | { | |
85 | return get_cpu_rev() & ~(0xF << 8); | |
86 | } | |
87 | ||
6b0071c1 PST |
88 | #ifdef CONFIG_USB_EHCI_MX5 |
89 | int board_ehci_hcd_init(int port) | |
90 | { | |
91 | /* request VBUS power enable pin, GPIO7_8 */ | |
92 | imx_iomux_v3_setup_pad(MX53_PAD_PATA_DA_2__GPIO7_8); | |
93 | gpio_direction_output(IMX_GPIO_NR(7, 8), 1); | |
94 | return 0; | |
95 | } | |
96 | #endif | |
97 | ||
6b0071c1 PST |
98 | static int clock_1GHz(void) |
99 | { | |
100 | int ret; | |
101 | u32 ref_clk = MXC_HCLK; | |
102 | /* | |
103 | * After increasing voltage to 1.25V, we can switch | |
104 | * CPU clock to 1GHz and DDR to 400MHz safely | |
105 | */ | |
106 | ret = mxc_set_clock(ref_clk, 1000, MXC_ARM_CLK); | |
107 | if (ret) { | |
108 | printf("CPU: Switch CPU clock to 1GHZ failed\n"); | |
109 | return -1; | |
110 | } | |
111 | ||
112 | ret = mxc_set_clock(ref_clk, 400, MXC_PERIPH_CLK); | |
113 | ret |= mxc_set_clock(ref_clk, 400, MXC_DDR_CLK); | |
114 | if (ret) { | |
115 | printf("CPU: Switch DDR clock to 400MHz failed\n"); | |
116 | return -1; | |
117 | } | |
118 | ||
119 | return 0; | |
120 | } | |
121 | ||
122 | void ppd_gpio_init(void) | |
123 | { | |
124 | int i; | |
125 | ||
126 | imx_iomux_v3_setup_multiple_pads(ppd_pads, ARRAY_SIZE(ppd_pads)); | |
1dec7fa7 RB |
127 | for (i = 0; i < ARRAY_SIZE(ppd_gpios); ++i) { |
128 | gpio_request(ppd_gpios[i].gpio, "request"); | |
6b0071c1 | 129 | gpio_direction_output(ppd_gpios[i].gpio, ppd_gpios[i].value); |
1dec7fa7 | 130 | } |
6b0071c1 PST |
131 | } |
132 | ||
133 | int board_early_init_f(void) | |
134 | { | |
6b0071c1 PST |
135 | ppd_gpio_init(); |
136 | ||
137 | return 0; | |
138 | } | |
139 | ||
140 | /* | |
141 | * Do not overwrite the console | |
142 | * Use always serial for U-Boot console | |
143 | */ | |
144 | int overwrite_console(void) | |
145 | { | |
146 | return 1; | |
147 | } | |
148 | ||
149 | #define VPD_TYPE_INVALID 0x00 | |
150 | #define VPD_BLOCK_NETWORK 0x20 | |
151 | #define VPD_BLOCK_HWID 0x44 | |
152 | #define VPD_PRODUCT_PPD 4 | |
153 | #define VPD_HAS_MAC1 0x1 | |
154 | #define VPD_MAC_ADDRESS_LENGTH 6 | |
155 | ||
156 | struct vpd_cache { | |
157 | u8 product_id; | |
158 | u8 has; | |
159 | unsigned char mac1[VPD_MAC_ADDRESS_LENGTH]; | |
160 | }; | |
161 | ||
162 | /* | |
163 | * Extracts MAC and product information from the VPD. | |
164 | */ | |
f026c1d9 PF |
165 | static int vpd_callback(struct vpd_cache *userdata, u8 id, u8 version, |
166 | u8 type, size_t size, u8 const *data) | |
6b0071c1 | 167 | { |
f026c1d9 | 168 | struct vpd_cache *vpd = userdata; |
6b0071c1 PST |
169 | |
170 | if (id == VPD_BLOCK_HWID && version == 1 && type != VPD_TYPE_INVALID && | |
171 | size >= 1) { | |
172 | vpd->product_id = data[0]; | |
173 | ||
174 | } else if (id == VPD_BLOCK_NETWORK && version == 1 && | |
175 | type != VPD_TYPE_INVALID) { | |
176 | if (size >= 6) { | |
177 | vpd->has |= VPD_HAS_MAC1; | |
178 | memcpy(vpd->mac1, data, VPD_MAC_ADDRESS_LENGTH); | |
179 | } | |
180 | } | |
181 | ||
182 | return 0; | |
183 | } | |
184 | ||
185 | static void process_vpd(struct vpd_cache *vpd) | |
186 | { | |
187 | int fec_index = -1; | |
188 | ||
189 | if (vpd->product_id == VPD_PRODUCT_PPD) | |
190 | fec_index = 0; | |
191 | ||
192 | if (fec_index >= 0 && (vpd->has & VPD_HAS_MAC1)) | |
193 | eth_env_set_enetaddr("ethaddr", vpd->mac1); | |
194 | } | |
195 | ||
6b0071c1 PST |
196 | int board_init(void) |
197 | { | |
198 | gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; | |
199 | ||
200 | mxc_set_sata_internal_clock(); | |
6b0071c1 PST |
201 | |
202 | return 0; | |
203 | } | |
204 | ||
205 | int misc_init_r(void) | |
206 | { | |
207 | const char *cause; | |
208 | ||
209 | /* We care about WDOG only, treating everything else as | |
210 | * a power-on-reset. | |
211 | */ | |
212 | if (get_imx_reset_cause() & 0x0010) | |
213 | cause = "WDOG"; | |
214 | else | |
215 | cause = "POR"; | |
216 | ||
217 | env_set("bootcause", cause); | |
218 | ||
219 | return 0; | |
220 | } | |
221 | ||
222 | int board_late_init(void) | |
223 | { | |
224 | int res; | |
4dcbccf7 | 225 | struct vpd_cache vpd; |
6b0071c1 | 226 | |
4dcbccf7 DZ |
227 | memset(&vpd, 0, sizeof(vpd)); |
228 | res = read_vpd(&vpd, vpd_callback); | |
229 | if (!res) | |
230 | process_vpd(&vpd); | |
231 | else | |
232 | printf("Can't read VPD"); | |
6b0071c1 PST |
233 | |
234 | res = clock_1GHz(); | |
235 | if (res != 0) | |
236 | return res; | |
237 | ||
238 | print_cpuinfo(); | |
6b0071c1 PST |
239 | |
240 | check_time(); | |
241 | ||
242 | return 0; | |
243 | } | |
244 | ||
245 | int checkboard(void) | |
246 | { | |
247 | puts("Board: GE PPD\n"); | |
248 | ||
249 | return 0; | |
250 | } | |
61c4c2bf IR |
251 | |
252 | #ifdef CONFIG_OF_BOARD_SETUP | |
b75d8dc5 | 253 | int ft_board_setup(void *blob, struct bd_info *bd) |
61c4c2bf | 254 | { |
b186cfa1 IR |
255 | char *rtc_status = env_get("rtc_status"); |
256 | ||
61c4c2bf | 257 | fdt_setprop(blob, 0, "ge,boot-ver", version_string, |
b186cfa1 IR |
258 | strlen(version_string) + 1); |
259 | ||
260 | fdt_setprop(blob, 0, "ge,rtc-status", rtc_status, | |
261 | strlen(rtc_status) + 1); | |
61c4c2bf IR |
262 | return 0; |
263 | } | |
264 | #endif |