forked from xboot/xfel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fel.h
135 lines (117 loc) · 3.68 KB
/
fel.h
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
128
129
130
131
132
133
134
135
#ifndef __FEL_H__
#define __FEL_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <x.h>
#include <misc.h>
#include <progress.h>
struct xfel_ctx_t;
struct chip_t;
struct xfel_ctx_t {
libusb_device_handle * hdl;
int epout;
int epin;
struct {
char magic[8];
uint32_t id;
uint32_t firmware;
uint16_t protocol;
uint8_t dflag;
uint8_t dlength;
uint32_t scratchpad;
uint8_t pad[8];
} version;
struct chip_t * chip;
};
struct chip_t {
char * name;
int (*detect)(struct xfel_ctx_t * ctx, uint32_t id);
int (*reset)(struct xfel_ctx_t * ctx);
int (*sid)(struct xfel_ctx_t * ctx, char * sid);
int (*jtag)(struct xfel_ctx_t * ctx);
int (*ddr)(struct xfel_ctx_t * ctx, const char * type);
int (*spi_init)(struct xfel_ctx_t * ctx, uint32_t * swapbuf, uint32_t * swaplen, uint32_t * cmdlen);
int (*spi_run)(struct xfel_ctx_t * ctx, uint8_t * cbuf, uint32_t clen);
int (*extra)(struct xfel_ctx_t * ctx, int argc, char * argv[]);
};
enum {
SPI_CMD_END = 0x00,
SPI_CMD_INIT = 0x01,
SPI_CMD_SELECT = 0x02,
SPI_CMD_DESELECT = 0x03,
SPI_CMD_FAST = 0x04,
SPI_CMD_TXBUF = 0x05,
SPI_CMD_RXBUF = 0x06,
SPI_CMD_SPINOR_WAIT = 0x07,
SPI_CMD_SPINAND_WAIT = 0x08,
};
/*
* This R32 and W32 macro can only be used for byte access address, Don't used for address
* that can only support word access. Because the fel protocol can only support
* byte operation, VERY IMPORTANT !!!
*/
#define R32(reg) fel_read32(ctx, reg)
#define W32(reg, val) fel_write32(ctx, reg, val)
static inline int fel_chip_detect(struct xfel_ctx_t * ctx, uint32_t id)
{
if(ctx->chip->detect)
return ctx->chip->detect(ctx, id);
return 0;
}
static inline int fel_chip_reset(struct xfel_ctx_t * ctx)
{
if(ctx->chip->reset)
return ctx->chip->reset(ctx);
return 0;
}
static inline int fel_chip_sid(struct xfel_ctx_t * ctx, char * sid)
{
if(ctx->chip->sid)
return ctx->chip->sid(ctx, sid);
return 0;
}
static inline int fel_chip_jtag(struct xfel_ctx_t * ctx)
{
if(ctx->chip->jtag)
return ctx->chip->jtag(ctx);
return 0;
}
static inline int fel_chip_ddr(struct xfel_ctx_t * ctx, const char * type)
{
if(ctx->chip->ddr)
return ctx->chip->ddr(ctx, type);
return 0;
}
static inline int fel_chip_spi_init(struct xfel_ctx_t * ctx, uint32_t * swapbuf, uint32_t * swaplen, uint32_t * cmdlen)
{
if(ctx->chip->spi_init)
return ctx->chip->spi_init(ctx, swapbuf, swaplen, cmdlen);
return 0;
}
static inline int fel_chip_spi_run(struct xfel_ctx_t * ctx, uint8_t * cbuf, uint32_t clen)
{
if(ctx->chip->spi_run)
return ctx->chip->spi_run(ctx, cbuf, clen);
return 0;
}
static inline int fel_chip_extra(struct xfel_ctx_t * ctx, int argc, char * argv[])
{
if(ctx->chip->extra)
return ctx->chip->extra(ctx, argc, argv);
return 0;
}
int fel_init(struct xfel_ctx_t * ctx);
void fel_exec(struct xfel_ctx_t * ctx, uint32_t addr);
uint32_t fel_read32(struct xfel_ctx_t * ctx, uint32_t addr);
void fel_write32(struct xfel_ctx_t * ctx, uint32_t addr, uint32_t val);
void fel_read(struct xfel_ctx_t * ctx, uint32_t addr, void * buf, size_t len);
void fel_write(struct xfel_ctx_t * ctx, uint32_t addr, void * buf, size_t len);
void fel_read_progress(struct xfel_ctx_t * ctx, uint32_t addr, void * buf, size_t len);
void fel_write_progress(struct xfel_ctx_t * ctx, uint32_t addr, void * buf, size_t len);
int fel_spi_init(struct xfel_ctx_t * ctx, uint32_t * swapbuf, uint32_t * swaplen, uint32_t * cmdlen);
int fel_spi_xfer(struct xfel_ctx_t * ctx, uint32_t swapbuf, uint32_t swaplen, uint32_t cmdlen, void * txbuf, uint32_t txlen, void * rxbuf, uint32_t rxlen);
#ifdef __cplusplus
}
#endif
#endif /* __FEL_H__ */