blob: bf184c8a8846f571c5750037944b446f5d587751 [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#ifndef _STM32PROG_H_
7#define _STM32PROG_H_
8
Simon Glassbdd5f812023-09-14 18:21:46 -06009#include <linux/printk.h>
10
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010011/* - phase defines ------------------------------------------------*/
12#define PHASE_FLASHLAYOUT 0x00
13#define PHASE_FIRST_USER 0x10
14#define PHASE_LAST_USER 0xF0
15#define PHASE_CMD 0xF1
Patrick Delaunay1d96b182020-03-18 09:24:58 +010016#define PHASE_OTP 0xF2
Patrick Delaunay541c7de2020-03-18 09:24:59 +010017#define PHASE_PMIC 0xF4
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010018#define PHASE_END 0xFE
19#define PHASE_RESET 0xFF
20#define PHASE_DO_RESET 0x1FF
21
22#define DEFAULT_ADDRESS 0xFFFFFFFF
23
Patrick Delaunaybd577492021-07-05 09:39:01 +020024#define CMD_SIZE 512
Patrick Delaunay9a699b72022-09-06 18:53:20 +020025/* SMC is only supported in SPMIN for STM32MP15x */
Patrick Delaunay4c6fcbc2024-01-15 15:05:57 +010026#ifdef CONFIG_STM32MP15X
Patrick Delaunay8da5df92022-03-28 19:25:28 +020027#define OTP_SIZE_SMC 1024
Patrick Delaunay9a699b72022-09-06 18:53:20 +020028#else
29#define OTP_SIZE_SMC 0
30#endif
Patrick Delaunay90946722024-01-15 15:05:52 +010031/* size of the OTP struct in NVMEM PTA */
32#define _OTP_SIZE_TA(otp) (((otp) * 2 + 2) * 4)
Patrick Delaunay4c6fcbc2024-01-15 15:05:57 +010033#if defined(CONFIG_STM32MP13X) || defined(CONFIG_STM32MP15X)
Patrick Delaunay90946722024-01-15 15:05:52 +010034/* STM32MP1 with BSEC2 */
35#define OTP_SIZE_TA _OTP_SIZE_TA(96)
36#else
37/* STM32MP2 with BSEC3 */
38#define OTP_SIZE_TA _OTP_SIZE_TA(368)
39#endif
Patrick Delaunay541c7de2020-03-18 09:24:59 +010040#define PMIC_SIZE 8
Patrick Delaunay1d96b182020-03-18 09:24:58 +010041
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010042enum stm32prog_target {
43 STM32PROG_NONE,
Patrick Delaunay7aae1e32020-03-18 09:24:51 +010044 STM32PROG_MMC,
Patrick Delaunay6ab74962020-03-18 09:24:54 +010045 STM32PROG_NAND,
46 STM32PROG_NOR,
Patrick Delaunay41e6ace2020-03-18 09:25:03 +010047 STM32PROG_SPI_NAND,
48 STM32PROG_RAM
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010049};
50
51enum stm32prog_link_t {
Patrick Delaunayb823d992020-03-18 09:25:00 +010052 LINK_SERIAL,
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010053 LINK_USB,
54 LINK_UNDEFINED,
55};
56
Patrick Delaunay19676ef2021-04-02 14:05:17 +020057enum stm32prog_header_t {
58 HEADER_NONE,
59 HEADER_STM32IMAGE,
Patrick Delaunay953d8bf2022-03-28 19:25:29 +020060 HEADER_STM32IMAGE_V2,
Patrick Delaunay19676ef2021-04-02 14:05:17 +020061 HEADER_FIP,
62};
63
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010064struct image_header_s {
Patrick Delaunay19676ef2021-04-02 14:05:17 +020065 enum stm32prog_header_t type;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010066 u32 image_checksum;
67 u32 image_length;
Patrick Delaunay953d8bf2022-03-28 19:25:29 +020068 u32 length;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010069};
70
Patrick Delaunay953d8bf2022-03-28 19:25:29 +020071struct stm32_header_v1 {
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010072 u32 magic_number;
Patrick Delaunay953d8bf2022-03-28 19:25:29 +020073 u8 image_signature[64];
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010074 u32 image_checksum;
75 u32 header_version;
76 u32 image_length;
77 u32 image_entry_point;
78 u32 reserved1;
79 u32 load_address;
80 u32 reserved2;
81 u32 version_number;
82 u32 option_flags;
83 u32 ecdsa_algorithm;
Patrick Delaunay953d8bf2022-03-28 19:25:29 +020084 u8 ecdsa_public_key[64];
85 u8 padding[83];
86 u8 binary_type;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +010087};
88
Patrick Delaunay953d8bf2022-03-28 19:25:29 +020089struct stm32_header_v2 {
90 u32 magic_number;
91 u8 image_signature[64];
92 u32 image_checksum;
93 u32 header_version;
94 u32 image_length;
95 u32 image_entry_point;
96 u32 reserved1;
97 u32 load_address;
98 u32 reserved2;
99 u32 version_number;
100 u32 extension_flags;
101 u32 extension_headers_length;
102 u32 binary_type;
103 u8 padding[16];
104 u32 extension_header_type;
105 u32 extension_header_length;
106 u8 extension_padding[376];
107};
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100108
Patrick Delaunay0e582be2023-06-08 17:09:55 +0200109/*
110 * partition type in flashlayout file
111 * SYSTEM = linux partition, bootable
112 * FILESYSTEM = linux partition
113 * ESP = EFI system partition
114 */
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100115enum stm32prog_part_type {
116 PART_BINARY,
Patrick Delaunay8dc57682022-03-28 19:25:30 +0200117 PART_FIP,
Patrick Delaunayc203c212023-06-08 17:09:56 +0200118 PART_FWU_MDATA,
Patrick Delaunayb386b9c2023-06-08 17:09:54 +0200119 PART_ENV,
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100120 PART_SYSTEM,
121 PART_FILESYSTEM,
Patrick Delaunay0e582be2023-06-08 17:09:55 +0200122 PART_ESP,
Patrick Delaunay8dc57682022-03-28 19:25:30 +0200123 RAW_IMAGE,
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100124};
125
126/* device information */
127struct stm32prog_dev_t {
128 enum stm32prog_target target;
129 char dev_id;
Patrick Delaunay7aae1e32020-03-18 09:24:51 +0100130 u32 erase_size;
131 struct mmc *mmc;
Patrick Delaunay6ab74962020-03-18 09:24:54 +0100132 struct mtd_info *mtd;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100133 /* list of partition for this device / ordered in offset */
134 struct list_head part_list;
Patrick Delaunay5ce50062020-03-18 09:24:53 +0100135 bool full_update;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100136};
137
138/* partition information build from FlashLayout and device */
139struct stm32prog_part_t {
140 /* FlashLayout information */
141 int option;
142 int id;
143 enum stm32prog_part_type part_type;
144 enum stm32prog_target target;
145 char dev_id;
146
147 /* partition name
148 * (16 char in gpt, + 1 for null terminated string
149 */
150 char name[16 + 1];
151 u64 addr;
152 u64 size;
Patrick Delaunay851d6f32020-03-18 09:24:56 +0100153 enum stm32prog_part_type bin_nb; /* SSBL repeatition */
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100154
155 /* information on associated device */
156 struct stm32prog_dev_t *dev; /* pointer to device */
Patrick Delaunay6915b492020-03-18 09:24:52 +0100157 s16 part_id; /* partition id in device */
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100158 int alt_id; /* alt id in usb/dfu */
159
160 struct list_head list;
161};
162
163#define STM32PROG_MAX_DEV 5
164struct stm32prog_data {
165 /* Layout information */
166 int dev_nb; /* device number*/
167 struct stm32prog_dev_t dev[STM32PROG_MAX_DEV]; /* array of device */
168 int part_nb; /* nb of partition */
169 struct stm32prog_part_t *part_array; /* array of partition */
Patrick Delaunayc5112242020-03-18 09:24:55 +0100170 bool fsbl_nor_detected;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100171
172 /* command internal information */
173 unsigned int phase;
174 u32 offset;
175 char error[255];
176 struct stm32prog_part_t *cur_part;
Patrick Delaunay21ea4ef2022-09-06 18:53:19 +0200177 void *otp_part;
Patrick Delaunay541c7de2020-03-18 09:24:59 +0100178 u8 pmic_part[PMIC_SIZE];
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100179
Patrick Delaunayb823d992020-03-18 09:25:00 +0100180 /* SERIAL information */
181 u32 cursor;
182 u32 packet_number;
Patrick Delaunayb823d992020-03-18 09:25:00 +0100183 u8 *buffer; /* size = USART_RAM_BUFFER_SIZE*/
184 int dfu_seq;
185 u8 read_phase;
Patrick Delaunay41e6ace2020-03-18 09:25:03 +0100186
187 /* bootm information */
Patrick Delaunay21ea4ef2022-09-06 18:53:19 +0200188 uintptr_t uimage;
189 uintptr_t dtb;
190 uintptr_t initrd;
191 size_t initrd_size;
Patrick Delaunay8da5df92022-03-28 19:25:28 +0200192
Patrick Delaunay21ea4ef2022-09-06 18:53:19 +0200193 uintptr_t script;
Patrick Delaunayb9ef46b2022-03-28 19:25:32 +0200194
Patrick Delaunay8da5df92022-03-28 19:25:28 +0200195 /* OPTEE PTA NVMEM */
196 struct udevice *tee;
197 u32 tee_session;
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100198};
199
200extern struct stm32prog_data *stm32prog_data;
201
Patrick Delaunay1d96b182020-03-18 09:24:58 +0100202/* OTP access */
203int stm32prog_otp_write(struct stm32prog_data *data, u32 offset,
204 u8 *buffer, long *size);
205int stm32prog_otp_read(struct stm32prog_data *data, u32 offset,
206 u8 *buffer, long *size);
207int stm32prog_otp_start(struct stm32prog_data *data);
208
Patrick Delaunay541c7de2020-03-18 09:24:59 +0100209/* PMIC access */
210int stm32prog_pmic_write(struct stm32prog_data *data, u32 offset,
211 u8 *buffer, long *size);
212int stm32prog_pmic_read(struct stm32prog_data *data, u32 offset,
213 u8 *buffer, long *size);
214int stm32prog_pmic_start(struct stm32prog_data *data);
215
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100216/* generic part*/
Patrick Delaunay953d8bf2022-03-28 19:25:29 +0200217void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header);
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100218int stm32prog_dfu_init(struct stm32prog_data *data);
219void stm32prog_next_phase(struct stm32prog_data *data);
220void stm32prog_do_reset(struct stm32prog_data *data);
221
222char *stm32prog_get_error(struct stm32prog_data *data);
223
224#define stm32prog_err(args...) {\
225 if (data->phase != PHASE_RESET) { \
226 sprintf(data->error, args); \
227 data->phase = PHASE_RESET; \
Patrick Delaunay2b15af52020-11-06 19:01:30 +0100228 log_err("Error: %s\n", data->error); } \
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100229 }
230
231/* Main function */
Patrick Delaunay21ea4ef2022-09-06 18:53:19 +0200232int stm32prog_init(struct stm32prog_data *data, uintptr_t addr, ulong size);
Patrick Delaunay29b2e2e2021-02-25 13:37:01 +0100233void stm32prog_clean(struct stm32prog_data *data);
234
235#ifdef CONFIG_CMD_STM32PROG_SERIAL
Patrick Delaunayb823d992020-03-18 09:25:00 +0100236int stm32prog_serial_init(struct stm32prog_data *data, int link_dev);
237bool stm32prog_serial_loop(struct stm32prog_data *data);
Patrick Delaunay29b2e2e2021-02-25 13:37:01 +0100238#else
239static inline int stm32prog_serial_init(struct stm32prog_data *data, int link_dev)
240{
241 return -ENOSYS;
242}
243
244static inline bool stm32prog_serial_loop(struct stm32prog_data *data)
245{
246 return false;
247}
248#endif
249
250#ifdef CONFIG_CMD_STM32PROG_USB
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100251bool stm32prog_usb_loop(struct stm32prog_data *data, int dev);
Patrick Delaunay29b2e2e2021-02-25 13:37:01 +0100252#else
253static inline bool stm32prog_usb_loop(struct stm32prog_data *data, int dev)
254{
255 return false;
256}
257#endif
Patrick Delaunay7daa91d2020-03-18 09:24:49 +0100258
259#endif