xref: /openbmc/u-boot/include/dfu.h (revision 1f92c074cbb53debc7ad31073dc7895d8a2aa44e)
183d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */
2f22b11c1SLukasz Majewski /*
3f22b11c1SLukasz Majewski  * dfu.h - DFU flashable area description
4f22b11c1SLukasz Majewski  *
5f22b11c1SLukasz Majewski  * Copyright (C) 2012 Samsung Electronics
6f22b11c1SLukasz Majewski  * authors: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
7f22b11c1SLukasz Majewski  *	    Lukasz Majewski <l.majewski@samsung.com>
8f22b11c1SLukasz Majewski  */
9f22b11c1SLukasz Majewski 
10f22b11c1SLukasz Majewski #ifndef __DFU_ENTITY_H_
11f22b11c1SLukasz Majewski #define __DFU_ENTITY_H_
12f22b11c1SLukasz Majewski 
13f22b11c1SLukasz Majewski #include <common.h>
14f22b11c1SLukasz Majewski #include <linux/list.h>
15f22b11c1SLukasz Majewski #include <mmc.h>
166f12ebf6SStephen Warren #include <spi_flash.h>
17a6921adcSLukasz Majewski #include <linux/usb/composite.h>
18f22b11c1SLukasz Majewski 
19f22b11c1SLukasz Majewski enum dfu_device_type {
20f22b11c1SLukasz Majewski 	DFU_DEV_MMC = 1,
21f22b11c1SLukasz Majewski 	DFU_DEV_ONENAND,
22f22b11c1SLukasz Majewski 	DFU_DEV_NAND,
23a9479f04SAfzal Mohammed 	DFU_DEV_RAM,
246f12ebf6SStephen Warren 	DFU_DEV_SF,
25f22b11c1SLukasz Majewski };
26f22b11c1SLukasz Majewski 
27f22b11c1SLukasz Majewski enum dfu_layout {
28f22b11c1SLukasz Majewski 	DFU_RAW_ADDR = 1,
29f22b11c1SLukasz Majewski 	DFU_FS_FAT,
30f22b11c1SLukasz Majewski 	DFU_FS_EXT2,
31f22b11c1SLukasz Majewski 	DFU_FS_EXT3,
32f22b11c1SLukasz Majewski 	DFU_FS_EXT4,
33a9479f04SAfzal Mohammed 	DFU_RAM_ADDR,
34f22b11c1SLukasz Majewski };
35f22b11c1SLukasz Majewski 
365a127c84SAfzal Mohammed enum dfu_op {
375a127c84SAfzal Mohammed 	DFU_OP_READ = 1,
385a127c84SAfzal Mohammed 	DFU_OP_WRITE,
390e285b50SStephen Warren 	DFU_OP_SIZE,
405a127c84SAfzal Mohammed };
415a127c84SAfzal Mohammed 
42f22b11c1SLukasz Majewski struct mmc_internal_data {
43dd64827eSStephen Warren 	int dev_num;
44dd64827eSStephen Warren 
45f22b11c1SLukasz Majewski 	/* RAW programming */
46f22b11c1SLukasz Majewski 	unsigned int lba_start;
47f22b11c1SLukasz Majewski 	unsigned int lba_size;
48f22b11c1SLukasz Majewski 	unsigned int lba_blk_size;
49f22b11c1SLukasz Majewski 
50c8151b4aSLukasz Majewski 	/* eMMC HW partition access */
51c8151b4aSLukasz Majewski 	int hw_partition;
52c8151b4aSLukasz Majewski 
53f22b11c1SLukasz Majewski 	/* FAT/EXT */
54f22b11c1SLukasz Majewski 	unsigned int dev;
55f22b11c1SLukasz Majewski 	unsigned int part;
56f22b11c1SLukasz Majewski };
57f22b11c1SLukasz Majewski 
58c6631764SPantelis Antoniou struct nand_internal_data {
59c6631764SPantelis Antoniou 	/* RAW programming */
60c6631764SPantelis Antoniou 	u64 start;
61c6631764SPantelis Antoniou 	u64 size;
62c6631764SPantelis Antoniou 
63c6631764SPantelis Antoniou 	unsigned int dev;
64c6631764SPantelis Antoniou 	unsigned int part;
65815c30b2SHeiko Schocher 	/* for nand/ubi use */
66815c30b2SHeiko Schocher 	unsigned int ubi;
67c6631764SPantelis Antoniou };
68c6631764SPantelis Antoniou 
69a9479f04SAfzal Mohammed struct ram_internal_data {
70a9479f04SAfzal Mohammed 	void		*start;
71a9479f04SAfzal Mohammed 	unsigned int	size;
72a9479f04SAfzal Mohammed };
73a9479f04SAfzal Mohammed 
746f12ebf6SStephen Warren struct sf_internal_data {
756f12ebf6SStephen Warren 	struct spi_flash *dev;
766f12ebf6SStephen Warren 
776f12ebf6SStephen Warren 	/* RAW programming */
786f12ebf6SStephen Warren 	u64 start;
796f12ebf6SStephen Warren 	u64 size;
806f12ebf6SStephen Warren };
816f12ebf6SStephen Warren 
82f22b11c1SLukasz Majewski #define DFU_NAME_SIZE			32
83e7e75c70SHeiko Schocher #ifndef CONFIG_SYS_DFU_DATA_BUF_SIZE
84e7e75c70SHeiko Schocher #define CONFIG_SYS_DFU_DATA_BUF_SIZE		(1024*1024*8)	/* 8 MiB */
85e7e75c70SHeiko Schocher #endif
86ea2453d5SPantelis Antoniou #ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE
877a813d5bSLukasz Majewski #define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE
88ea2453d5SPantelis Antoniou #endif
8933fac4a6SLukasz Majewski #ifndef DFU_DEFAULT_POLL_TIMEOUT
9033fac4a6SLukasz Majewski #define DFU_DEFAULT_POLL_TIMEOUT 0
9133fac4a6SLukasz Majewski #endif
92001a8319SHeiko Schocher #ifndef DFU_MANIFEST_POLL_TIMEOUT
93001a8319SHeiko Schocher #define DFU_MANIFEST_POLL_TIMEOUT	DFU_DEFAULT_POLL_TIMEOUT
94001a8319SHeiko Schocher #endif
95f22b11c1SLukasz Majewski 
96f22b11c1SLukasz Majewski struct dfu_entity {
97f22b11c1SLukasz Majewski 	char			name[DFU_NAME_SIZE];
98f22b11c1SLukasz Majewski 	int                     alt;
99f22b11c1SLukasz Majewski 	void                    *dev_private;
100f22b11c1SLukasz Majewski 	enum dfu_device_type    dev_type;
101f22b11c1SLukasz Majewski 	enum dfu_layout         layout;
1027ac1b410SStephen Warren 	unsigned long           max_buf_size;
103f22b11c1SLukasz Majewski 
104f22b11c1SLukasz Majewski 	union {
105f22b11c1SLukasz Majewski 		struct mmc_internal_data mmc;
106c6631764SPantelis Antoniou 		struct nand_internal_data nand;
107a9479f04SAfzal Mohammed 		struct ram_internal_data ram;
1086f12ebf6SStephen Warren 		struct sf_internal_data sf;
109f22b11c1SLukasz Majewski 	} data;
110f22b11c1SLukasz Majewski 
11115970d87SPatrick Delaunay 	int (*get_medium_size)(struct dfu_entity *dfu, u64 *size);
1120e285b50SStephen Warren 
113ea2453d5SPantelis Antoniou 	int (*read_medium)(struct dfu_entity *dfu,
114ea2453d5SPantelis Antoniou 			u64 offset, void *buf, long *len);
115ea2453d5SPantelis Antoniou 
116ea2453d5SPantelis Antoniou 	int (*write_medium)(struct dfu_entity *dfu,
117ea2453d5SPantelis Antoniou 			u64 offset, void *buf, long *len);
118ea2453d5SPantelis Antoniou 
119ea2453d5SPantelis Antoniou 	int (*flush_medium)(struct dfu_entity *dfu);
120fc25fa27SHeiko Schocher 	unsigned int (*poll_timeout)(struct dfu_entity *dfu);
121f22b11c1SLukasz Majewski 
122cb7bd2e0SStephen Warren 	void (*free_entity)(struct dfu_entity *dfu);
123cb7bd2e0SStephen Warren 
124f22b11c1SLukasz Majewski 	struct list_head list;
125ea2453d5SPantelis Antoniou 
126ea2453d5SPantelis Antoniou 	/* on the fly state */
127ea2453d5SPantelis Antoniou 	u32 crc;
128ea2453d5SPantelis Antoniou 	u64 offset;
129ea2453d5SPantelis Antoniou 	int i_blk_seq_num;
130ea2453d5SPantelis Antoniou 	u8 *i_buf;
131ea2453d5SPantelis Antoniou 	u8 *i_buf_start;
132ea2453d5SPantelis Antoniou 	u8 *i_buf_end;
13315970d87SPatrick Delaunay 	u64 r_left;
134ea2453d5SPantelis Antoniou 	long b_left;
135ea2453d5SPantelis Antoniou 
136c6631764SPantelis Antoniou 	u32 bad_skip;	/* for nand use */
137c6631764SPantelis Antoniou 
138ea2453d5SPantelis Antoniou 	unsigned int inited:1;
139f22b11c1SLukasz Majewski };
140f22b11c1SLukasz Majewski 
141899a5282SPrzemyslaw Marczak #ifdef CONFIG_SET_DFU_ALT_INFO
142899a5282SPrzemyslaw Marczak void set_dfu_alt_info(char *interface, char *devstr);
143899a5282SPrzemyslaw Marczak #endif
144dd64827eSStephen Warren int dfu_config_entities(char *s, char *interface, char *devstr);
145f22b11c1SLukasz Majewski void dfu_free_entities(void);
146f22b11c1SLukasz Majewski void dfu_show_entities(void);
147f22b11c1SLukasz Majewski int dfu_get_alt_number(void);
148f22b11c1SLukasz Majewski const char *dfu_get_dev_type(enum dfu_device_type t);
149f22b11c1SLukasz Majewski const char *dfu_get_layout(enum dfu_layout l);
150f22b11c1SLukasz Majewski struct dfu_entity *dfu_get_entity(int alt);
151f22b11c1SLukasz Majewski char *dfu_extract_token(char** e, int *n);
1526bed7ce5SLukasz Majewski void dfu_trigger_reset(void);
153fed936edSLukasz Majewski int dfu_get_alt(char *name);
154dd64827eSStephen Warren int dfu_init_env_entities(char *interface, char *devstr);
1557ac1b410SStephen Warren unsigned char *dfu_get_buf(struct dfu_entity *dfu);
156d4278263SLukasz Majewski unsigned char *dfu_free_buf(void);
1574fb12789SLukasz Majewski unsigned long dfu_get_buf_size(void);
1581cc03c5cSLukasz Majewski bool dfu_usb_get_reset(void);
159f22b11c1SLukasz Majewski 
160f22b11c1SLukasz Majewski int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
161f22b11c1SLukasz Majewski int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
162a2199afeSHeiko Schocher int dfu_flush(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
1632092e461SLukasz Majewski 
164fc18f8d1SLukasz Majewski /*
165fc18f8d1SLukasz Majewski  * dfu_defer_flush - pointer to store dfu_entity for deferred flashing.
166fc18f8d1SLukasz Majewski  *		     It should be NULL when not used.
167fc18f8d1SLukasz Majewski  */
168fc18f8d1SLukasz Majewski extern struct dfu_entity *dfu_defer_flush;
169fc18f8d1SLukasz Majewski /**
170fc18f8d1SLukasz Majewski  * dfu_get_defer_flush - get current value of dfu_defer_flush pointer
171fc18f8d1SLukasz Majewski  *
172fc18f8d1SLukasz Majewski  * @return - value of the dfu_defer_flush pointer
173fc18f8d1SLukasz Majewski  */
dfu_get_defer_flush(void)174fc18f8d1SLukasz Majewski static inline struct dfu_entity *dfu_get_defer_flush(void)
175fc18f8d1SLukasz Majewski {
176fc18f8d1SLukasz Majewski 	return dfu_defer_flush;
177fc18f8d1SLukasz Majewski }
178fc18f8d1SLukasz Majewski 
179fc18f8d1SLukasz Majewski /**
180fc18f8d1SLukasz Majewski  * dfu_set_defer_flush - set the dfu_defer_flush pointer
181fc18f8d1SLukasz Majewski  *
182fc18f8d1SLukasz Majewski  * @param dfu - pointer to the dfu_entity, which should be written
183fc18f8d1SLukasz Majewski  */
dfu_set_defer_flush(struct dfu_entity * dfu)184fc18f8d1SLukasz Majewski static inline void dfu_set_defer_flush(struct dfu_entity *dfu)
185fc18f8d1SLukasz Majewski {
186fc18f8d1SLukasz Majewski 	dfu_defer_flush = dfu;
187fc18f8d1SLukasz Majewski }
188fc18f8d1SLukasz Majewski 
1892092e461SLukasz Majewski /**
1902092e461SLukasz Majewski  * dfu_write_from_mem_addr - write data from memory to DFU managed medium
1912092e461SLukasz Majewski  *
1922092e461SLukasz Majewski  * This function adds support for writing data starting from fixed memory
1932092e461SLukasz Majewski  * address (like $loadaddr) to dfu managed medium (e.g. NAND, MMC, file system)
1942092e461SLukasz Majewski  *
1952092e461SLukasz Majewski  * @param dfu - dfu entity to which we want to store data
1962092e461SLukasz Majewski  * @param buf - fixed memory addres from where data starts
1972092e461SLukasz Majewski  * @param size - number of bytes to write
1982092e461SLukasz Majewski  *
1992092e461SLukasz Majewski  * @return - 0 on success, other value on failure
2002092e461SLukasz Majewski  */
2012092e461SLukasz Majewski int dfu_write_from_mem_addr(struct dfu_entity *dfu, void *buf, int size);
2022092e461SLukasz Majewski 
203f22b11c1SLukasz Majewski /* Device specific */
204*2d59ec84SAndrew F. Davis #if CONFIG_IS_ENABLED(DFU_MMC)
205dd64827eSStephen Warren extern int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s);
206f22b11c1SLukasz Majewski #else
dfu_fill_entity_mmc(struct dfu_entity * dfu,char * devstr,char * s)207dd64827eSStephen Warren static inline int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr,
208dd64827eSStephen Warren 				      char *s)
209f22b11c1SLukasz Majewski {
210f22b11c1SLukasz Majewski 	puts("MMC support not available!\n");
211f22b11c1SLukasz Majewski 	return -1;
212f22b11c1SLukasz Majewski }
213f22b11c1SLukasz Majewski #endif
214c6631764SPantelis Antoniou 
215*2d59ec84SAndrew F. Davis #if CONFIG_IS_ENABLED(DFU_NAND)
216dd64827eSStephen Warren extern int dfu_fill_entity_nand(struct dfu_entity *dfu, char *devstr, char *s);
217c6631764SPantelis Antoniou #else
dfu_fill_entity_nand(struct dfu_entity * dfu,char * devstr,char * s)218dd64827eSStephen Warren static inline int dfu_fill_entity_nand(struct dfu_entity *dfu, char *devstr,
219dd64827eSStephen Warren 				       char *s)
220c6631764SPantelis Antoniou {
221c6631764SPantelis Antoniou 	puts("NAND support not available!\n");
222c6631764SPantelis Antoniou 	return -1;
223c6631764SPantelis Antoniou }
224c6631764SPantelis Antoniou #endif
225c6631764SPantelis Antoniou 
226*2d59ec84SAndrew F. Davis #if CONFIG_IS_ENABLED(DFU_RAM)
227dd64827eSStephen Warren extern int dfu_fill_entity_ram(struct dfu_entity *dfu, char *devstr, char *s);
228a9479f04SAfzal Mohammed #else
dfu_fill_entity_ram(struct dfu_entity * dfu,char * devstr,char * s)229dd64827eSStephen Warren static inline int dfu_fill_entity_ram(struct dfu_entity *dfu, char *devstr,
230dd64827eSStephen Warren 				      char *s)
231a9479f04SAfzal Mohammed {
232a9479f04SAfzal Mohammed 	puts("RAM support not available!\n");
233a9479f04SAfzal Mohammed 	return -1;
234a9479f04SAfzal Mohammed }
235a9479f04SAfzal Mohammed #endif
236a9479f04SAfzal Mohammed 
237*2d59ec84SAndrew F. Davis #if CONFIG_IS_ENABLED(DFU_SF)
2386f12ebf6SStephen Warren extern int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr, char *s);
2396f12ebf6SStephen Warren #else
dfu_fill_entity_sf(struct dfu_entity * dfu,char * devstr,char * s)2406f12ebf6SStephen Warren static inline int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr,
2416f12ebf6SStephen Warren 				     char *s)
2426f12ebf6SStephen Warren {
2436f12ebf6SStephen Warren 	puts("SF support not available!\n");
2446f12ebf6SStephen Warren 	return -1;
2456f12ebf6SStephen Warren }
2466f12ebf6SStephen Warren #endif
2476f12ebf6SStephen Warren 
2482d50d68aSLukasz Majewski /**
2492d50d68aSLukasz Majewski  * dfu_tftp_write - Write TFTP data to DFU medium
2502d50d68aSLukasz Majewski  *
2512d50d68aSLukasz Majewski  * This function is storing data received via TFTP on DFU supported medium.
2522d50d68aSLukasz Majewski  *
2532d50d68aSLukasz Majewski  * @param dfu_entity_name - name of DFU entity to write
2542d50d68aSLukasz Majewski  * @param addr - address of data buffer to write
2552d50d68aSLukasz Majewski  * @param len - number of bytes
2562d50d68aSLukasz Majewski  * @param interface - destination DFU medium (e.g. "mmc")
2572d50d68aSLukasz Majewski  * @param devstring - instance number of destination DFU medium (e.g. "1")
2582d50d68aSLukasz Majewski  *
2592d50d68aSLukasz Majewski  * @return 0 on success, otherwise error code
2602d50d68aSLukasz Majewski  */
261*2d59ec84SAndrew F. Davis #if CONFIG_IS_ENABLED(DFU_TFTP)
2622d50d68aSLukasz Majewski int dfu_tftp_write(char *dfu_entity_name, unsigned int addr, unsigned int len,
2632d50d68aSLukasz Majewski 		   char *interface, char *devstring);
2642d50d68aSLukasz Majewski #else
dfu_tftp_write(char * dfu_entity_name,unsigned int addr,unsigned int len,char * interface,char * devstring)2652d50d68aSLukasz Majewski static inline int dfu_tftp_write(char *dfu_entity_name, unsigned int addr,
2662d50d68aSLukasz Majewski 				 unsigned int len, char *interface,
2672d50d68aSLukasz Majewski 				 char *devstring)
2682d50d68aSLukasz Majewski {
2692d50d68aSLukasz Majewski 	puts("TFTP write support for DFU not available!\n");
2702d50d68aSLukasz Majewski 	return -ENOSYS;
2712d50d68aSLukasz Majewski }
2722d50d68aSLukasz Majewski #endif
2732d50d68aSLukasz Majewski 
274a6921adcSLukasz Majewski int dfu_add(struct usb_configuration *c);
275f22b11c1SLukasz Majewski #endif /* __DFU_ENTITY_H_ */
276