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
|
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2021 David Jander, Protonic Holland
// SPDX-FileCopyrightText: 2021 Oleksij Rempel, Pengutronix
#include <bootsource.h>
#include <common.h>
#include <init.h>
#include <mach/bbu.h>
#include <of_device.h>
/* board specific flags */
#define PRT_STM32_BOOTSRC_SD BIT(2)
#define PRT_STM32_BOOTSRC_EMMC BIT(1)
#define PRT_STM32_BOOTSRC_SPI_NOR BIT(0)
struct prt_stm32_machine_data {
u32 flags;
};
struct prt_stm32_boot_dev {
char *name;
char *env;
char *dev;
int flags;
int boot_idx;
enum bootsource boot_src;
};
static const struct prt_stm32_boot_dev prt_stm32_boot_devs[] = {
{
.name = "emmc",
.env = "/chosen/environment-emmc",
.dev = "/dev/mmc1.ssbl",
.flags = PRT_STM32_BOOTSRC_EMMC,
.boot_src = BOOTSOURCE_MMC,
.boot_idx = 1,
}, {
.name = "qspi",
.env = "/chosen/environment-qspi",
.dev = "/dev/flash.ssbl",
.flags = PRT_STM32_BOOTSRC_SPI_NOR,
.boot_src = BOOTSOURCE_SPI_NOR,
.boot_idx = -1,
}, {
/* SD is optional boot source and should be last device in the
* list. */
.name = "sd",
.env = "/chosen/environment-sd",
.dev = "/dev/mmc0.ssbl",
.flags = PRT_STM32_BOOTSRC_SD,
.boot_src = BOOTSOURCE_MMC,
.boot_idx = 0,
},
};
static int prt_stm32_probe(struct device_d *dev)
{
const struct prt_stm32_machine_data *dcfg;
char *env_path_back = NULL, *env_path = NULL;
int ret, i;
dcfg = of_device_get_match_data(dev);
if (!dcfg) {
ret = -EINVAL;
goto exit_get_dcfg;
}
for (i = 0; i < ARRAY_SIZE(prt_stm32_boot_devs); i++) {
const struct prt_stm32_boot_dev *bd = &prt_stm32_boot_devs[i];
int bbu_flags = 0;
/* skip not supported boot sources */
if (!(bd->flags & dcfg->flags))
continue;
/* first device is build-in device */
if (!env_path_back)
env_path_back = bd->env;
if (bd->boot_src == bootsource_get() && (bd->boot_idx == -1 ||
bd->boot_idx == bootsource_get_instance())) {
bbu_flags = BBU_HANDLER_FLAG_DEFAULT;
env_path = bd->env;
}
ret = stm32mp_bbu_mmc_register_handler(bd->name, bd->dev,
bbu_flags);
if (ret < 0)
dev_warn(dev, "Failed to enable %s bbu (%pe)\n",
bd->name, ERR_PTR(ret));
}
if (!env_path)
env_path = env_path_back;
ret = of_device_enable_path(env_path);
if (ret < 0)
dev_warn(dev, "Failed to enable environment partition '%s' (%pe)\n",
env_path, ERR_PTR(ret));
return 0;
exit_get_dcfg:
dev_err(dev, "Failed to get dcfg: %pe\n", ERR_PTR(ret));
return ret;
}
static const struct prt_stm32_machine_data prt_stm32_prtt1a = {
.flags = PRT_STM32_BOOTSRC_SD | PRT_STM32_BOOTSRC_SPI_NOR,
};
static const struct prt_stm32_machine_data prt_stm32_prtt1c = {
.flags = PRT_STM32_BOOTSRC_SD | PRT_STM32_BOOTSRC_EMMC,
};
static const struct of_device_id prt_stm32_of_match[] = {
{ .compatible = "prt,prtt1a", .data = &prt_stm32_prtt1a },
{ .compatible = "prt,prtt1c", .data = &prt_stm32_prtt1c },
{ .compatible = "prt,prtt1s", .data = &prt_stm32_prtt1a },
{ /* sentinel */ },
};
static struct driver_d prt_stm32_board_driver = {
.name = "board-protonic-stm32",
.probe = prt_stm32_probe,
.of_compatible = prt_stm32_of_match,
};
postcore_platform_driver(prt_stm32_board_driver);
|