summaryrefslogtreecommitdiff
path: root/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
blob: 15bbdc2cb6565fe31ee28d4b9b88ab2895624451 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
 * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
 */

#include <common.h>
#include <command.h>
#include <dfu.h>
#include <asm/arch/stm32prog.h>
#include "stm32prog.h"

struct stm32prog_data *stm32prog_data;

static void enable_vidconsole(void)
{
#ifdef CONFIG_DM_VIDEO
	char *stdname;
	char buf[64];

	stdname = env_get("stdout");
	if (!stdname || !strstr(stdname, "vidconsole")) {
		if (!stdname)
			snprintf(buf, sizeof(buf), "serial,vidconsole");
		else
			snprintf(buf, sizeof(buf), "%s,vidconsole", stdname);
		env_set("stdout", buf);
	}

	stdname = env_get("stderr");
	if (!stdname || !strstr(stdname, "vidconsole")) {
		if (!stdname)
			snprintf(buf, sizeof(buf), "serial,vidconsole");
		else
			snprintf(buf, sizeof(buf), "%s,vidconsole", stdname);
		env_set("stderr", buf);
	}
#endif
}

static int do_stm32prog(cmd_tbl_t *cmdtp, int flag, int argc,
			char * const argv[])
{
	ulong	addr, size;
	int dev, ret;
	enum stm32prog_link_t link = LINK_UNDEFINED;
	bool reset = false;
	struct stm32prog_data *data;

	if (argc < 3 ||  argc > 5)
		return CMD_RET_USAGE;

	if (!strcmp(argv[1], "usb"))
		link = LINK_USB;
	else if (!strcmp(argv[1], "serial"))
		link = LINK_SERIAL;

	if (link == LINK_UNDEFINED) {
		pr_err("not supported link=%s\n", argv[1]);
		return CMD_RET_USAGE;
	}

	dev = (int)simple_strtoul(argv[2], NULL, 10);

	addr = STM32_DDR_BASE;
	size = 0;
	if (argc > 3) {
		addr = simple_strtoul(argv[3], NULL, 16);
		if (!addr)
			return CMD_RET_FAILURE;
	}
	if (argc > 4)
		size = simple_strtoul(argv[4], NULL, 16);

	enable_vidconsole();

	data = (struct stm32prog_data *)malloc(sizeof(*data));

	if (!data) {
		pr_err("Alloc failed.");
		return CMD_RET_FAILURE;
	}
	stm32prog_data = data;

	ret = stm32prog_init(data, addr, size);
	if (ret)
		printf("Invalid or missing layout file.");

	/* prepare DFU for device read/write */
	ret = stm32prog_dfu_init(data);
	if (ret)
		goto cleanup;

	switch (link) {
	case LINK_SERIAL:
		ret = stm32prog_serial_init(data, dev);
		if (ret)
			goto cleanup;
		reset = stm32prog_serial_loop(data);
		break;
	case LINK_USB:
		reset = stm32prog_usb_loop(data, dev);
		break;
	default:
		goto cleanup;
	}

	stm32prog_clean(data);
	free(stm32prog_data);
	stm32prog_data = NULL;

	puts("Download done\n");
	if (reset) {
		puts("Reset...\n");
		run_command("reset", 0);
	}

	return CMD_RET_SUCCESS;

cleanup:
	stm32prog_clean(data);
	free(stm32prog_data);
	stm32prog_data = NULL;

	return CMD_RET_FAILURE;
}

U_BOOT_CMD(stm32prog, 5, 0, do_stm32prog,
	   "<link> <dev> [<addr>] [<size>]\n"
	   "start communication with tools STM32Cubeprogrammer on <link> with Flashlayout at <addr>",
	   "<link> = serial|usb\n"
	   "<dev>  = device instance\n"
	   "<addr> = address of flashlayout\n"
	   "<size> = size of flashlayout\n"
);

bool stm32prog_get_tee_partitions(void)
{
	if (stm32prog_data)
		return stm32prog_data->tee_detected;

	return false;
}

bool stm32prog_get_fsbl_nor(void)
{
	if (stm32prog_data)
		return stm32prog_data->fsbl_nor_detected;

	return false;
}