blob: 924952f805c83a4c50bd0a29087383c6883ed569 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0+ */
Lukasz Majewskif22b11c2012-08-06 14:41:07 +02002/*
3 * dfu.h - DFU flashable area description
4 *
5 * Copyright (C) 2012 Samsung Electronics
6 * authors: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
7 * Lukasz Majewski <l.majewski@samsung.com>
Lukasz Majewskif22b11c2012-08-06 14:41:07 +02008 */
9
10#ifndef __DFU_ENTITY_H_
11#define __DFU_ENTITY_H_
12
13#include <common.h>
14#include <linux/list.h>
15#include <mmc.h>
Stephen Warren6f12ebf2014-06-11 16:03:36 -060016#include <spi_flash.h>
Lukasz Majewskia6921ad2013-09-17 15:58:23 +020017#include <linux/usb/composite.h>
Lukasz Majewskif22b11c2012-08-06 14:41:07 +020018
19enum dfu_device_type {
20 DFU_DEV_MMC = 1,
21 DFU_DEV_ONENAND,
22 DFU_DEV_NAND,
Afzal Mohammeda9479f02013-09-18 01:15:24 +053023 DFU_DEV_RAM,
Stephen Warren6f12ebf2014-06-11 16:03:36 -060024 DFU_DEV_SF,
Patrick Delaunay6015af22019-10-14 09:28:04 +020025 DFU_DEV_MTD,
Lukasz Majewskif22b11c2012-08-06 14:41:07 +020026};
27
28enum dfu_layout {
29 DFU_RAW_ADDR = 1,
30 DFU_FS_FAT,
31 DFU_FS_EXT2,
32 DFU_FS_EXT3,
33 DFU_FS_EXT4,
Afzal Mohammeda9479f02013-09-18 01:15:24 +053034 DFU_RAM_ADDR,
Lukasz Majewskif22b11c2012-08-06 14:41:07 +020035};
36
Afzal Mohammed5a127c82013-09-18 01:14:50 +053037enum dfu_op {
38 DFU_OP_READ = 1,
39 DFU_OP_WRITE,
Stephen Warren0e285b52014-06-11 12:47:27 -060040 DFU_OP_SIZE,
Afzal Mohammed5a127c82013-09-18 01:14:50 +053041};
42
Lukasz Majewskif22b11c2012-08-06 14:41:07 +020043struct mmc_internal_data {
Stephen Warrendd648272014-06-11 16:03:33 -060044 int dev_num;
45
Lukasz Majewskif22b11c2012-08-06 14:41:07 +020046 /* RAW programming */
47 unsigned int lba_start;
48 unsigned int lba_size;
49 unsigned int lba_blk_size;
50
Lukasz Majewskic8151b42014-05-09 16:58:15 +020051 /* eMMC HW partition access */
52 int hw_partition;
53
Lukasz Majewskif22b11c2012-08-06 14:41:07 +020054 /* FAT/EXT */
55 unsigned int dev;
56 unsigned int part;
57};
58
Patrick Delaunay6015af22019-10-14 09:28:04 +020059struct mtd_internal_data {
60 struct mtd_info *info;
61
62 /* RAW programming */
63 u64 start;
64 u64 size;
65};
66
Pantelis Antoniouc6631762013-03-14 05:32:52 +000067struct nand_internal_data {
68 /* RAW programming */
69 u64 start;
70 u64 size;
71
72 unsigned int dev;
73 unsigned int part;
Heiko Schocher815c30b2013-07-25 06:43:11 +020074 /* for nand/ubi use */
75 unsigned int ubi;
Pantelis Antoniouc6631762013-03-14 05:32:52 +000076};
77
Afzal Mohammeda9479f02013-09-18 01:15:24 +053078struct ram_internal_data {
79 void *start;
80 unsigned int size;
81};
82
Stephen Warren6f12ebf2014-06-11 16:03:36 -060083struct sf_internal_data {
84 struct spi_flash *dev;
85
86 /* RAW programming */
87 u64 start;
88 u64 size;
Patrick Delaunaycb986ba2019-10-14 09:28:00 +020089 /* for sf/ubi use */
90 unsigned int ubi;
Stephen Warren6f12ebf2014-06-11 16:03:36 -060091};
92
Tom Rinia24c3152013-03-14 05:32:49 +000093#define DFU_NAME_SIZE 32
Heiko Schochere7e75c72013-06-12 06:05:51 +020094#ifndef CONFIG_SYS_DFU_DATA_BUF_SIZE
95#define CONFIG_SYS_DFU_DATA_BUF_SIZE (1024*1024*8) /* 8 MiB */
96#endif
Pantelis Antoniouea2453d2013-03-14 05:32:48 +000097#ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE
Lukasz Majewski7a813d52013-09-10 15:29:23 +020098#define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE
Pantelis Antoniouea2453d2013-03-14 05:32:48 +000099#endif
Lukasz Majewski33fac4a2013-12-09 16:20:14 +0100100#ifndef DFU_DEFAULT_POLL_TIMEOUT
101#define DFU_DEFAULT_POLL_TIMEOUT 0
102#endif
Heiko Schocher001a8312014-03-18 08:09:56 +0100103#ifndef DFU_MANIFEST_POLL_TIMEOUT
104#define DFU_MANIFEST_POLL_TIMEOUT DFU_DEFAULT_POLL_TIMEOUT
105#endif
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200106
107struct dfu_entity {
108 char name[DFU_NAME_SIZE];
109 int alt;
110 void *dev_private;
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200111 enum dfu_device_type dev_type;
112 enum dfu_layout layout;
Stephen Warren7ac1b412014-06-11 16:03:34 -0600113 unsigned long max_buf_size;
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200114
115 union {
116 struct mmc_internal_data mmc;
Patrick Delaunay6015af22019-10-14 09:28:04 +0200117 struct mtd_internal_data mtd;
Pantelis Antoniouc6631762013-03-14 05:32:52 +0000118 struct nand_internal_data nand;
Afzal Mohammeda9479f02013-09-18 01:15:24 +0530119 struct ram_internal_data ram;
Stephen Warren6f12ebf2014-06-11 16:03:36 -0600120 struct sf_internal_data sf;
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200121 } data;
122
Patrick Delaunay15970d82017-07-19 16:39:23 +0200123 int (*get_medium_size)(struct dfu_entity *dfu, u64 *size);
Stephen Warren0e285b52014-06-11 12:47:27 -0600124
Pantelis Antoniouea2453d2013-03-14 05:32:48 +0000125 int (*read_medium)(struct dfu_entity *dfu,
126 u64 offset, void *buf, long *len);
127
128 int (*write_medium)(struct dfu_entity *dfu,
129 u64 offset, void *buf, long *len);
130
131 int (*flush_medium)(struct dfu_entity *dfu);
Heiko Schocherfc25fa22014-04-11 07:59:47 +0200132 unsigned int (*poll_timeout)(struct dfu_entity *dfu);
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200133
Stephen Warrencb7bd2e2014-06-11 16:03:35 -0600134 void (*free_entity)(struct dfu_entity *dfu);
135
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200136 struct list_head list;
Pantelis Antoniouea2453d2013-03-14 05:32:48 +0000137
138 /* on the fly state */
139 u32 crc;
140 u64 offset;
141 int i_blk_seq_num;
142 u8 *i_buf;
143 u8 *i_buf_start;
144 u8 *i_buf_end;
Patrick Delaunay15970d82017-07-19 16:39:23 +0200145 u64 r_left;
Pantelis Antoniouea2453d2013-03-14 05:32:48 +0000146 long b_left;
147
Pantelis Antoniouc6631762013-03-14 05:32:52 +0000148 u32 bad_skip; /* for nand use */
149
Pantelis Antoniouea2453d2013-03-14 05:32:48 +0000150 unsigned int inited:1;
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200151};
152
Przemyslaw Marczak899a5282015-02-17 12:24:11 +0100153#ifdef CONFIG_SET_DFU_ALT_INFO
154void set_dfu_alt_info(char *interface, char *devstr);
155#endif
Patrick Delaunay9ada6832019-10-14 09:28:01 +0200156int dfu_alt_init(int num, struct dfu_entity **dfu);
157int dfu_alt_add(struct dfu_entity *dfu, char *interface, char *devstr, char *s);
Stephen Warrendd648272014-06-11 16:03:33 -0600158int dfu_config_entities(char *s, char *interface, char *devstr);
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200159void dfu_free_entities(void);
160void dfu_show_entities(void);
161int dfu_get_alt_number(void);
162const char *dfu_get_dev_type(enum dfu_device_type t);
163const char *dfu_get_layout(enum dfu_layout l);
164struct dfu_entity *dfu_get_entity(int alt);
165char *dfu_extract_token(char** e, int *n);
Lukasz Majewski6bed7ce2013-07-18 13:19:14 +0200166void dfu_trigger_reset(void);
Lukasz Majewskifed936e2013-10-08 14:30:38 +0200167int dfu_get_alt(char *name);
Stephen Warrendd648272014-06-11 16:03:33 -0600168int dfu_init_env_entities(char *interface, char *devstr);
Stephen Warren7ac1b412014-06-11 16:03:34 -0600169unsigned char *dfu_get_buf(struct dfu_entity *dfu);
Lukasz Majewskid4278262013-10-08 14:30:39 +0200170unsigned char *dfu_free_buf(void);
Lukasz Majewski4fb12782013-12-09 16:20:13 +0100171unsigned long dfu_get_buf_size(void);
Lukasz Majewski1cc03c52014-08-25 11:07:28 +0200172bool dfu_usb_get_reset(void);
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200173
174int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
175int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
Heiko Schochera2199af2014-03-18 08:09:55 +0100176int dfu_flush(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
Lukasz Majewski2092e462015-08-24 00:21:46 +0200177
Lukasz Majewskifc18f8d2016-01-28 16:14:49 +0100178/*
179 * dfu_defer_flush - pointer to store dfu_entity for deferred flashing.
180 * It should be NULL when not used.
181 */
182extern struct dfu_entity *dfu_defer_flush;
183/**
184 * dfu_get_defer_flush - get current value of dfu_defer_flush pointer
185 *
186 * @return - value of the dfu_defer_flush pointer
187 */
188static inline struct dfu_entity *dfu_get_defer_flush(void)
189{
190 return dfu_defer_flush;
191}
192
193/**
194 * dfu_set_defer_flush - set the dfu_defer_flush pointer
195 *
196 * @param dfu - pointer to the dfu_entity, which should be written
197 */
198static inline void dfu_set_defer_flush(struct dfu_entity *dfu)
199{
200 dfu_defer_flush = dfu;
201}
202
Lukasz Majewski2092e462015-08-24 00:21:46 +0200203/**
204 * dfu_write_from_mem_addr - write data from memory to DFU managed medium
205 *
206 * This function adds support for writing data starting from fixed memory
207 * address (like $loadaddr) to dfu managed medium (e.g. NAND, MMC, file system)
208 *
209 * @param dfu - dfu entity to which we want to store data
210 * @param buf - fixed memory addres from where data starts
211 * @param size - number of bytes to write
212 *
213 * @return - 0 on success, other value on failure
214 */
215int dfu_write_from_mem_addr(struct dfu_entity *dfu, void *buf, int size);
216
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200217/* Device specific */
Andrew F. Davis2d59ec82019-01-17 13:43:03 -0600218#if CONFIG_IS_ENABLED(DFU_MMC)
Stephen Warrendd648272014-06-11 16:03:33 -0600219extern int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s);
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200220#else
Stephen Warrendd648272014-06-11 16:03:33 -0600221static inline int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr,
222 char *s)
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200223{
224 puts("MMC support not available!\n");
225 return -1;
226}
227#endif
Pantelis Antoniouc6631762013-03-14 05:32:52 +0000228
Andrew F. Davis2d59ec82019-01-17 13:43:03 -0600229#if CONFIG_IS_ENABLED(DFU_NAND)
Stephen Warrendd648272014-06-11 16:03:33 -0600230extern int dfu_fill_entity_nand(struct dfu_entity *dfu, char *devstr, char *s);
Pantelis Antoniouc6631762013-03-14 05:32:52 +0000231#else
Stephen Warrendd648272014-06-11 16:03:33 -0600232static inline int dfu_fill_entity_nand(struct dfu_entity *dfu, char *devstr,
233 char *s)
Pantelis Antoniouc6631762013-03-14 05:32:52 +0000234{
235 puts("NAND support not available!\n");
236 return -1;
237}
238#endif
239
Andrew F. Davis2d59ec82019-01-17 13:43:03 -0600240#if CONFIG_IS_ENABLED(DFU_RAM)
Stephen Warrendd648272014-06-11 16:03:33 -0600241extern int dfu_fill_entity_ram(struct dfu_entity *dfu, char *devstr, char *s);
Afzal Mohammeda9479f02013-09-18 01:15:24 +0530242#else
Stephen Warrendd648272014-06-11 16:03:33 -0600243static inline int dfu_fill_entity_ram(struct dfu_entity *dfu, char *devstr,
244 char *s)
Afzal Mohammeda9479f02013-09-18 01:15:24 +0530245{
246 puts("RAM support not available!\n");
247 return -1;
248}
249#endif
250
Andrew F. Davis2d59ec82019-01-17 13:43:03 -0600251#if CONFIG_IS_ENABLED(DFU_SF)
Stephen Warren6f12ebf2014-06-11 16:03:36 -0600252extern int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr, char *s);
253#else
254static inline int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr,
255 char *s)
256{
257 puts("SF support not available!\n");
258 return -1;
259}
260#endif
261
Patrick Delaunay6015af22019-10-14 09:28:04 +0200262#if CONFIG_IS_ENABLED(DFU_MTD)
263int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr, char *s);
264#else
265static inline int dfu_fill_entity_mtd(struct dfu_entity *dfu, char *devstr,
266 char *s)
267{
268 puts("MTD support not available!\n");
269 return -1;
270}
271#endif
272
Lukasz Majewski2d50d682015-08-24 00:21:45 +0200273/**
274 * dfu_tftp_write - Write TFTP data to DFU medium
275 *
276 * This function is storing data received via TFTP on DFU supported medium.
277 *
278 * @param dfu_entity_name - name of DFU entity to write
279 * @param addr - address of data buffer to write
280 * @param len - number of bytes
281 * @param interface - destination DFU medium (e.g. "mmc")
282 * @param devstring - instance number of destination DFU medium (e.g. "1")
283 *
284 * @return 0 on success, otherwise error code
285 */
Andrew F. Davis2d59ec82019-01-17 13:43:03 -0600286#if CONFIG_IS_ENABLED(DFU_TFTP)
Lukasz Majewski2d50d682015-08-24 00:21:45 +0200287int dfu_tftp_write(char *dfu_entity_name, unsigned int addr, unsigned int len,
288 char *interface, char *devstring);
289#else
290static inline int dfu_tftp_write(char *dfu_entity_name, unsigned int addr,
291 unsigned int len, char *interface,
292 char *devstring)
293{
294 puts("TFTP write support for DFU not available!\n");
295 return -ENOSYS;
296}
297#endif
298
Lukasz Majewskia6921ad2013-09-17 15:58:23 +0200299int dfu_add(struct usb_configuration *c);
Lukasz Majewskif22b11c2012-08-06 14:41:07 +0200300#endif /* __DFU_ENTITY_H_ */