1769ba05f2899d4d83b74ff16c06809c368cfe6b
[oweals/u-boot.git] / arch / arm / mach-stm32mp / cmd_stm32prog / cmd_stm32prog.c
1 // 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>
9 #include <asm/arch/stm32prog.h>
10 #include "stm32prog.h"
11
12 struct stm32prog_data *stm32prog_data;
13
14 static int do_stm32prog(cmd_tbl_t *cmdtp, int flag, int argc,
15                         char * const argv[])
16 {
17         ulong   addr, size;
18         int dev, ret;
19         enum stm32prog_link_t link = LINK_UNDEFINED;
20         bool reset = false;
21         struct stm32prog_data *data;
22
23         if (argc < 3 ||  argc > 5)
24                 return CMD_RET_USAGE;
25
26         if (!strcmp(argv[1], "usb"))
27                 link = LINK_USB;
28         else if (!strcmp(argv[1], "serial"))
29                 link = LINK_SERIAL;
30
31         if (link == LINK_UNDEFINED) {
32                 pr_err("not supported link=%s\n", argv[1]);
33                 return CMD_RET_USAGE;
34         }
35
36         dev = (int)simple_strtoul(argv[2], NULL, 10);
37
38         addr = STM32_DDR_BASE;
39         size = 0;
40         if (argc > 3) {
41                 addr = simple_strtoul(argv[3], NULL, 16);
42                 if (!addr)
43                         return CMD_RET_FAILURE;
44         }
45         if (argc > 4)
46                 size = simple_strtoul(argv[4], NULL, 16);
47
48         data = (struct stm32prog_data *)malloc(sizeof(*data));
49
50         if (!data) {
51                 pr_err("Alloc failed.");
52                 return CMD_RET_FAILURE;
53         }
54         stm32prog_data = data;
55
56         ret = stm32prog_init(data, addr, size);
57         if (ret)
58                 printf("Invalid or missing layout file.");
59
60         /* prepare DFU for device read/write */
61         ret = stm32prog_dfu_init(data);
62         if (ret)
63                 goto cleanup;
64
65         switch (link) {
66         case LINK_SERIAL:
67                 ret = stm32prog_serial_init(data, dev);
68                 if (ret)
69                         goto cleanup;
70                 reset = stm32prog_serial_loop(data);
71                 break;
72         case LINK_USB:
73                 reset = stm32prog_usb_loop(data, dev);
74                 break;
75         default:
76                 goto cleanup;
77         }
78
79         stm32prog_clean(data);
80         free(stm32prog_data);
81         stm32prog_data = NULL;
82
83         puts("Download done\n");
84         if (reset) {
85                 puts("Reset...\n");
86                 run_command("reset", 0);
87         }
88
89         return CMD_RET_SUCCESS;
90
91 cleanup:
92         stm32prog_clean(data);
93         free(stm32prog_data);
94         stm32prog_data = NULL;
95
96         return CMD_RET_FAILURE;
97 }
98
99 U_BOOT_CMD(stm32prog, 5, 0, do_stm32prog,
100            "<link> <dev> [<addr>] [<size>]\n"
101            "start communication with tools STM32Cubeprogrammer on <link> with Flashlayout at <addr>",
102            "<link> = serial|usb\n"
103            "<dev>  = device instance\n"
104            "<addr> = address of flashlayout\n"
105            "<size> = size of flashlayout\n"
106 );
107
108 bool stm32prog_get_tee_partitions(void)
109 {
110         if (stm32prog_data)
111                 return stm32prog_data->tee_detected;
112
113         return false;
114 }
115
116 bool stm32prog_get_fsbl_nor(void)
117 {
118         if (stm32prog_data)
119                 return stm32prog_data->fsbl_nor_detected;
120
121         return false;
122 }