blob: 49dd25b28f486af4f4b5506063930061b4d75ca9 [file] [log] [blame]
Patrick Delaunay7daa91d2020-03-18 09:24:49 +01001// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2/*
3 * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
4 */
5
6#include <common.h>
7#include <command.h>
8#include <dfu.h>
Patrick Delaunayc2fdd572020-03-18 09:25:02 +01009#include <image.h>
Patrick Delaunayc5112242020-03-18 09:24:55 +010010#include <asm/arch/stm32prog.h>
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010011#include "stm32prog.h"
12
13struct stm32prog_data *stm32prog_data;
14
Patrick Delaunay8610f222020-03-18 09:25:01 +010015static void enable_vidconsole(void)
16{
Patrick Delaunay8610f222020-03-18 09:25:01 +010017 char *stdname;
18 char buf[64];
19
20 stdname = env_get("stdout");
21 if (!stdname || !strstr(stdname, "vidconsole")) {
22 if (!stdname)
23 snprintf(buf, sizeof(buf), "serial,vidconsole");
24 else
25 snprintf(buf, sizeof(buf), "%s,vidconsole", stdname);
26 env_set("stdout", buf);
27 }
28
29 stdname = env_get("stderr");
30 if (!stdname || !strstr(stdname, "vidconsole")) {
31 if (!stdname)
32 snprintf(buf, sizeof(buf), "serial,vidconsole");
33 else
34 snprintf(buf, sizeof(buf), "%s,vidconsole", stdname);
35 env_set("stderr", buf);
36 }
Patrick Delaunay8610f222020-03-18 09:25:01 +010037}
38
Simon Glassed38aef2020-05-10 11:40:03 -060039static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc,
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010040 char * const argv[])
41{
42 ulong addr, size;
43 int dev, ret;
44 enum stm32prog_link_t link = LINK_UNDEFINED;
45 bool reset = false;
Patrick Delaunayc2fdd572020-03-18 09:25:02 +010046 struct image_header_s header;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010047 struct stm32prog_data *data;
Patrick Delaunay41e6ace2020-03-18 09:25:03 +010048 u32 uimage, dtb;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010049
50 if (argc < 3 || argc > 5)
51 return CMD_RET_USAGE;
52
53 if (!strcmp(argv[1], "usb"))
54 link = LINK_USB;
Patrick Delaunayb823d992020-03-18 09:25:00 +010055 else if (!strcmp(argv[1], "serial"))
56 link = LINK_SERIAL;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010057
58 if (link == LINK_UNDEFINED) {
59 pr_err("not supported link=%s\n", argv[1]);
60 return CMD_RET_USAGE;
61 }
Patrick Delaunayb823d992020-03-18 09:25:00 +010062
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010063 dev = (int)simple_strtoul(argv[2], NULL, 10);
64
65 addr = STM32_DDR_BASE;
66 size = 0;
67 if (argc > 3) {
68 addr = simple_strtoul(argv[3], NULL, 16);
69 if (!addr)
70 return CMD_RET_FAILURE;
71 }
72 if (argc > 4)
73 size = simple_strtoul(argv[4], NULL, 16);
74
Patrick Delaunayc2fdd572020-03-18 09:25:02 +010075 /* check STM32IMAGE presence */
76 if (size == 0 &&
77 !stm32prog_header_check((struct raw_header_s *)addr, &header)) {
78 size = header.image_length + BL_HEADER_SIZE;
79
80 /* uImage detected in STM32IMAGE, execute the script */
81 if (IMAGE_FORMAT_LEGACY ==
82 genimg_get_format((void *)(addr + BL_HEADER_SIZE)))
83 return image_source_script(addr + BL_HEADER_SIZE,
84 "script@1");
85 }
86
Patrick Delaunay8040da12020-07-31 16:31:52 +020087 if (IS_ENABLED(CONFIG_DM_VIDEO))
88 enable_vidconsole();
Patrick Delaunay8610f222020-03-18 09:25:01 +010089
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010090 data = (struct stm32prog_data *)malloc(sizeof(*data));
91
92 if (!data) {
93 pr_err("Alloc failed.");
94 return CMD_RET_FAILURE;
95 }
96 stm32prog_data = data;
97
98 ret = stm32prog_init(data, addr, size);
99 if (ret)
100 printf("Invalid or missing layout file.");
101
102 /* prepare DFU for device read/write */
103 ret = stm32prog_dfu_init(data);
104 if (ret)
105 goto cleanup;
106
107 switch (link) {
Patrick Delaunayb823d992020-03-18 09:25:00 +0100108 case LINK_SERIAL:
109 ret = stm32prog_serial_init(data, dev);
110 if (ret)
111 goto cleanup;
112 reset = stm32prog_serial_loop(data);
113 break;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100114 case LINK_USB:
115 reset = stm32prog_usb_loop(data, dev);
116 break;
117 default:
118 goto cleanup;
119 }
120
Patrick Delaunay41e6ace2020-03-18 09:25:03 +0100121 uimage = data->uimage;
122 dtb = data->dtb;
123
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100124 stm32prog_clean(data);
125 free(stm32prog_data);
126 stm32prog_data = NULL;
127
128 puts("Download done\n");
Patrick Delaunay41e6ace2020-03-18 09:25:03 +0100129
130 if (uimage) {
131 char boot_addr_start[20];
132 char dtb_addr[20];
133 char *bootm_argv[5] = {
134 "bootm", boot_addr_start, "-", dtb_addr, NULL
135 };
136 if (!dtb)
137 bootm_argv[3] = env_get("fdtcontroladdr");
138 else
139 snprintf(dtb_addr, sizeof(dtb_addr) - 1,
140 "0x%x", dtb);
141
142 snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
143 "0x%x", uimage);
144 printf("Booting kernel at %s - %s...\n\n\n",
145 boot_addr_start, bootm_argv[3]);
146 /* Try bootm for legacy and FIT format image */
147 if (genimg_get_format((void *)uimage) != IMAGE_FORMAT_INVALID)
148 do_bootm(cmdtp, 0, 4, bootm_argv);
Bin Mengd0d1df62020-07-08 00:19:22 -0700149 else if (CONFIG_IS_ENABLED(CMD_BOOTZ))
Patrick Delaunay41e6ace2020-03-18 09:25:03 +0100150 do_bootz(cmdtp, 0, 4, bootm_argv);
151 }
152
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100153 if (reset) {
154 puts("Reset...\n");
155 run_command("reset", 0);
156 }
157
158 return CMD_RET_SUCCESS;
159
160cleanup:
161 stm32prog_clean(data);
162 free(stm32prog_data);
163 stm32prog_data = NULL;
164
165 return CMD_RET_FAILURE;
166}
167
168U_BOOT_CMD(stm32prog, 5, 0, do_stm32prog,
169 "<link> <dev> [<addr>] [<size>]\n"
170 "start communication with tools STM32Cubeprogrammer on <link> with Flashlayout at <addr>",
Patrick Delaunayb823d992020-03-18 09:25:00 +0100171 "<link> = serial|usb\n"
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100172 "<dev> = device instance\n"
173 "<addr> = address of flashlayout\n"
174 "<size> = size of flashlayout\n"
175);
Patrick Delaunayc5112242020-03-18 09:24:55 +0100176
177bool stm32prog_get_tee_partitions(void)
178{
179 if (stm32prog_data)
180 return stm32prog_data->tee_detected;
181
182 return false;
183}
184
185bool stm32prog_get_fsbl_nor(void)
186{
187 if (stm32prog_data)
188 return stm32prog_data->fsbl_nor_detected;
189
190 return false;
191}