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