]> git.ipfire.org Git - thirdparty/u-boot.git/blame - arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
[thirdparty/u-boot.git] / arch / arm / mach-stm32mp / cmd_stm32prog / cmd_stm32prog.c
CommitLineData
954bd1a9
PD
1// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2/*
3 * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
4 */
5
d678a59d 6#include <common.h>
e4cee649 7#include <bootm.h>
954bd1a9
PD
8#include <command.h>
9#include <dfu.h>
d0686c69 10#include <image.h>
8f035f7b 11#include <asm/arch/stm32prog.h>
1e94b46f 12#include <linux/printk.h>
954bd1a9
PD
13#include "stm32prog.h"
14
15struct stm32prog_data *stm32prog_data;
16
99d643cb
PD
17static void enable_vidconsole(void)
18{
99d643cb
PD
19 char *stdname;
20 char buf[64];
21
22 stdname = env_get("stdout");
23 if (!stdname || !strstr(stdname, "vidconsole")) {
24 if (!stdname)
25 snprintf(buf, sizeof(buf), "serial,vidconsole");
26 else
27 snprintf(buf, sizeof(buf), "%s,vidconsole", stdname);
28 env_set("stdout", buf);
29 }
30
31 stdname = env_get("stderr");
32 if (!stdname || !strstr(stdname, "vidconsole")) {
33 if (!stdname)
34 snprintf(buf, sizeof(buf), "serial,vidconsole");
35 else
36 snprintf(buf, sizeof(buf), "%s,vidconsole", stdname);
37 env_set("stderr", buf);
38 }
99d643cb
PD
39}
40
09140113 41static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
954bd1a9
PD
42 char * const argv[])
43{
44 ulong addr, size;
45 int dev, ret;
46 enum stm32prog_link_t link = LINK_UNDEFINED;
47 bool reset = false;
d0686c69 48 struct image_header_s header;
954bd1a9
PD
49 struct stm32prog_data *data;
50
51 if (argc < 3 || argc > 5)
52 return CMD_RET_USAGE;
53
5a05af87 54 if (IS_ENABLED(CONFIG_CMD_STM32PROG_USB) && !strcmp(argv[1], "usb"))
954bd1a9 55 link = LINK_USB;
5a05af87 56 else if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL) && !strcmp(argv[1], "serial"))
468f0508 57 link = LINK_SERIAL;
954bd1a9
PD
58
59 if (link == LINK_UNDEFINED) {
711b5bc0 60 log_err("not supported link=%s\n", argv[1]);
954bd1a9
PD
61 return CMD_RET_USAGE;
62 }
468f0508 63
0b1284eb 64 dev = (int)dectoul(argv[2], NULL);
954bd1a9 65
ada8fe0c 66 addr = CONFIG_SYS_LOAD_ADDR;
954bd1a9
PD
67 size = 0;
68 if (argc > 3) {
7e5f460e 69 addr = hextoul(argv[3], NULL);
954bd1a9
PD
70 if (!addr)
71 return CMD_RET_FAILURE;
72 }
73 if (argc > 4)
7e5f460e 74 size = hextoul(argv[4], NULL);
954bd1a9 75
d0686c69 76 /* check STM32IMAGE presence */
4fb7b3e1 77 if (size == 0) {
49d0ecb1 78 stm32prog_header_check(addr, &header);
4fb7b3e1 79 if (header.type == HEADER_STM32IMAGE) {
49d0ecb1 80 size = header.image_length + header.length;
4fb7b3e1 81 }
d0686c69
PD
82 }
83
b86986c7 84 if (IS_ENABLED(CONFIG_VIDEO))
9a2b0540 85 enable_vidconsole();
99d643cb 86
954bd1a9
PD
87 data = (struct stm32prog_data *)malloc(sizeof(*data));
88
89 if (!data) {
711b5bc0 90 log_err("Alloc failed.");
954bd1a9
PD
91 return CMD_RET_FAILURE;
92 }
93 stm32prog_data = data;
94
95 ret = stm32prog_init(data, addr, size);
96 if (ret)
d4cb4025 97 log_debug("Invalid or missing layout file at 0x%lx.\n", addr);
954bd1a9
PD
98
99 /* prepare DFU for device read/write */
100 ret = stm32prog_dfu_init(data);
101 if (ret)
102 goto cleanup;
103
104 switch (link) {
468f0508
PD
105 case LINK_SERIAL:
106 ret = stm32prog_serial_init(data, dev);
107 if (ret)
108 goto cleanup;
109 reset = stm32prog_serial_loop(data);
110 break;
954bd1a9
PD
111 case LINK_USB:
112 reset = stm32prog_usb_loop(data, dev);
113 break;
114 default:
115 goto cleanup;
116 }
117
118 stm32prog_clean(data);
119 free(stm32prog_data);
120 stm32prog_data = NULL;
121
122 puts("Download done\n");
306a5cf2 123
d68e53b2 124 if (data->uimage) {
306a5cf2
PD
125 char boot_addr_start[20];
126 char dtb_addr[20];
d68e53b2 127 char initrd_addr[40];
6b50aff1 128 char *fdt_arg, *initrd_arg;
3df19b8b
PD
129 const void *uimage = (void *)data->uimage;
130 const void *dtb = (void *)data->dtb;
131 const void *initrd = (void *)data->initrd;
e4cee649 132 struct bootm_info bmi;
d68e53b2 133
6b50aff1 134 fdt_arg = dtb_addr;
306a5cf2 135 if (!dtb)
6b50aff1 136 fdt_arg = env_get("fdtcontroladdr");
306a5cf2 137 else
6b50aff1 138 snprintf(dtb_addr, sizeof(dtb_addr) - 1, "0x%p", dtb);
306a5cf2
PD
139
140 snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
3df19b8b 141 "0x%p", uimage);
d68e53b2 142
e4cee649 143 initrd_arg = NULL;
d68e53b2 144 if (initrd) {
6b50aff1
SG
145 snprintf(initrd_addr, sizeof(initrd_addr) - 1,
146 "0x%p:0x%zx", initrd, data->initrd_size);
147 initrd_arg = initrd_addr;
d68e53b2
PD
148 }
149
6b50aff1 150 printf("Booting kernel at %s %s %s...\n\n\n", boot_addr_start,
e4cee649
SG
151 initrd_arg ?: "-", fdt_arg);
152
153 bootm_init(&bmi);
154 bmi.addr_img = boot_addr_start;
155 bmi.conf_ramdisk = initrd_arg;
156 bmi.conf_fdt = fdt_arg;
6b50aff1 157
306a5cf2 158 /* Try bootm for legacy and FIT format image */
3df19b8b 159 if (genimg_get_format(uimage) != IMAGE_FORMAT_INVALID)
e4cee649 160 bootm_run(&bmi);
38223fb2 161 else if (IS_ENABLED(CONFIG_CMD_BOOTZ))
e4cee649 162 bootz_run(&bmi);
306a5cf2 163 }
152576a5 164 if (data->script)
30f3333d 165 cmd_source_script(data->script, NULL, NULL);
306a5cf2 166
954bd1a9
PD
167 if (reset) {
168 puts("Reset...\n");
169 run_command("reset", 0);
170 }
171
172 return CMD_RET_SUCCESS;
173
174cleanup:
175 stm32prog_clean(data);
176 free(stm32prog_data);
177 stm32prog_data = NULL;
178
179 return CMD_RET_FAILURE;
180}
181
182U_BOOT_CMD(stm32prog, 5, 0, do_stm32prog,
edca8c3f 183 "start communication with tools STM32Cubeprogrammer",
954bd1a9 184 "<link> <dev> [<addr>] [<size>]\n"
edca8c3f
PD
185 " <link> = serial|usb\n"
186 " <dev> = device instance\n"
187 " <addr> = address of flashlayout\n"
188 " <size> = size of flashlayout (optional for image with STM32 header)\n"
954bd1a9 189);
8f035f7b 190
8f035f7b
PD
191
192bool stm32prog_get_fsbl_nor(void)
193{
194 if (stm32prog_data)
195 return stm32prog_data->fsbl_nor_detected;
196
197 return false;
198}