aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
blob: 1769ba05f2899d4d83b74ff16c06809c368cfe6b (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
// 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 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);

	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;
}