]>
Commit | Line | Data |
---|---|---|
5b845b66 | 1 | /* |
5da627a4 WD |
2 | * (C) Copyright 2003 |
3 | * Steven Scholz, imc Measurement & Control, steven.scholz@imc-berlin.de | |
4 | * | |
5b845b66 WD |
5 | * (C) Copyright 2002 |
6 | * Rich Ireland, Enterasys Networks, rireland@enterasys.com. | |
7 | * | |
1a459660 | 8 | * SPDX-License-Identifier: GPL-2.0+ |
5b845b66 WD |
9 | */ |
10 | ||
5b845b66 WD |
11 | /* |
12 | * Altera FPGA support | |
13 | */ | |
14 | #include <common.h> | |
fda915a4 | 15 | #include <errno.h> |
5da627a4 | 16 | #include <ACEX1K.h> |
3c735e74 | 17 | #include <stratixII.h> |
5b845b66 | 18 | |
0ae16cbb MV |
19 | /* Define FPGA_DEBUG to 1 to get debug printf's */ |
20 | #define FPGA_DEBUG 0 | |
5b845b66 | 21 | |
2012f238 MV |
22 | static const struct altera_fpga { |
23 | enum altera_family family; | |
24 | const char *name; | |
25 | int (*load)(Altera_desc *, const void *, size_t); | |
26 | int (*dump)(Altera_desc *, const void *, size_t); | |
27 | int (*info)(Altera_desc *); | |
28 | } altera_fpga[] = { | |
29 | #if defined(CONFIG_FPGA_ACEX1K) | |
30 | { Altera_ACEX1K, "ACEX1K", ACEX1K_load, ACEX1K_dump, ACEX1K_info }, | |
31 | { Altera_CYC2, "ACEX1K", ACEX1K_load, ACEX1K_dump, ACEX1K_info }, | |
32 | #elif defined(CONFIG_FPGA_CYCLON2) | |
33 | { Altera_ACEX1K, "CycloneII", CYC2_load, CYC2_dump, CYC2_info }, | |
34 | { Altera_CYC2, "CycloneII", CYC2_load, CYC2_dump, CYC2_info }, | |
35 | #endif | |
36 | #if defined(CONFIG_FPGA_STRATIX_II) | |
37 | { Altera_StratixII, "StratixII", StratixII_load, | |
38 | StratixII_dump, StratixII_info }, | |
39 | #endif | |
ff9c4c53 SR |
40 | #if defined(CONFIG_FPGA_STRATIX_V) |
41 | { Altera_StratixV, "StratixV", stratixv_load, NULL, NULL }, | |
42 | #endif | |
230fe9b2 PM |
43 | #if defined(CONFIG_FPGA_SOCFPGA) |
44 | { Altera_SoCFPGA, "SoC FPGA", socfpga_load, NULL, NULL }, | |
45 | #endif | |
2012f238 MV |
46 | }; |
47 | ||
54c96b18 MV |
48 | static int altera_validate(Altera_desc *desc, const char *fn) |
49 | { | |
50 | if (!desc) { | |
51 | printf("%s: NULL descriptor!\n", fn); | |
fda915a4 | 52 | return -EINVAL; |
54c96b18 MV |
53 | } |
54 | ||
55 | if ((desc->family < min_altera_type) || | |
56 | (desc->family > max_altera_type)) { | |
57 | printf("%s: Invalid family type, %d\n", fn, desc->family); | |
fda915a4 | 58 | return -EINVAL; |
54c96b18 MV |
59 | } |
60 | ||
61 | if ((desc->iface < min_altera_iface_type) || | |
62 | (desc->iface > max_altera_iface_type)) { | |
63 | printf("%s: Invalid Interface type, %d\n", fn, desc->iface); | |
fda915a4 | 64 | return -EINVAL; |
54c96b18 MV |
65 | } |
66 | ||
67 | if (!desc->size) { | |
68 | printf("%s: NULL part size\n", fn); | |
fda915a4 | 69 | return -EINVAL; |
54c96b18 MV |
70 | } |
71 | ||
fda915a4 | 72 | return 0; |
54c96b18 | 73 | } |
5da627a4 | 74 | |
2012f238 MV |
75 | static const struct altera_fpga * |
76 | altera_desc_to_fpga(Altera_desc *desc, const char *fn) | |
5b845b66 | 77 | { |
2012f238 | 78 | int i; |
5da627a4 | 79 | |
2012f238 MV |
80 | if (altera_validate(desc, fn)) { |
81 | printf("%s: Invalid device descriptor\n", fn); | |
82 | return NULL; | |
4a4c0a5e MV |
83 | } |
84 | ||
2012f238 MV |
85 | for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) { |
86 | if (desc->family == altera_fpga[i].family) | |
87 | break; | |
88 | } | |
5da627a4 | 89 | |
2012f238 MV |
90 | if (i == ARRAY_SIZE(altera_fpga)) { |
91 | printf("%s: Unsupported family type, %d\n", fn, desc->family); | |
92 | return NULL; | |
5da627a4 WD |
93 | } |
94 | ||
2012f238 | 95 | return &altera_fpga[i]; |
5b845b66 WD |
96 | } |
97 | ||
2012f238 | 98 | int altera_load(Altera_desc *desc, const void *buf, size_t bsize) |
5b845b66 | 99 | { |
2012f238 | 100 | const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__); |
5da627a4 | 101 | |
2012f238 | 102 | if (!fpga) |
4a4c0a5e | 103 | return FPGA_FAIL; |
4a4c0a5e | 104 | |
2012f238 MV |
105 | debug_cond(FPGA_DEBUG, "%s: Launching the %s Loader...\n", |
106 | __func__, fpga->name); | |
107 | if (fpga->load) | |
108 | return fpga->load(desc, buf, bsize); | |
109 | return 0; | |
110 | } | |
5da627a4 | 111 | |
2012f238 MV |
112 | int altera_dump(Altera_desc *desc, const void *buf, size_t bsize) |
113 | { | |
114 | const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__); | |
5da627a4 | 115 | |
2012f238 MV |
116 | if (!fpga) |
117 | return FPGA_FAIL; | |
118 | ||
119 | debug_cond(FPGA_DEBUG, "%s: Launching the %s Reader...\n", | |
120 | __func__, fpga->name); | |
121 | if (fpga->dump) | |
122 | return fpga->dump(desc, buf, bsize); | |
123 | return 0; | |
5b845b66 WD |
124 | } |
125 | ||
4a4c0a5e | 126 | int altera_info(Altera_desc *desc) |
5b845b66 | 127 | { |
2012f238 | 128 | const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__); |
5da627a4 | 129 | |
2012f238 | 130 | if (!fpga) |
4a4c0a5e | 131 | return FPGA_FAIL; |
5da627a4 | 132 | |
2012f238 | 133 | printf("Family: \t%s\n", fpga->name); |
5da627a4 | 134 | |
4a4c0a5e MV |
135 | printf("Interface type:\t"); |
136 | switch (desc->iface) { | |
137 | case passive_serial: | |
138 | printf("Passive Serial (PS)\n"); | |
139 | break; | |
140 | case passive_parallel_synchronous: | |
141 | printf("Passive Parallel Synchronous (PPS)\n"); | |
142 | break; | |
143 | case passive_parallel_asynchronous: | |
144 | printf("Passive Parallel Asynchronous (PPA)\n"); | |
145 | break; | |
146 | case passive_serial_asynchronous: | |
147 | printf("Passive Serial Asynchronous (PSA)\n"); | |
148 | break; | |
149 | case altera_jtag_mode: /* Not used */ | |
150 | printf("JTAG Mode\n"); | |
151 | break; | |
152 | case fast_passive_parallel: | |
153 | printf("Fast Passive Parallel (FPP)\n"); | |
154 | break; | |
155 | case fast_passive_parallel_security: | |
156 | printf("Fast Passive Parallel with Security (FPPS)\n"); | |
157 | break; | |
158 | /* Add new interface types here */ | |
159 | default: | |
160 | printf("Unsupported interface type, %d\n", desc->iface); | |
161 | } | |
162 | ||
163 | printf("Device Size: \t%zd bytes\n" | |
164 | "Cookie: \t0x%x (%d)\n", | |
165 | desc->size, desc->cookie, desc->cookie); | |
5da627a4 | 166 | |
4a4c0a5e MV |
167 | if (desc->iface_fns) { |
168 | printf("Device Function Table @ 0x%p\n", desc->iface_fns); | |
2012f238 MV |
169 | if (fpga->info) |
170 | fpga->info(desc); | |
5da627a4 | 171 | } else { |
4a4c0a5e | 172 | printf("No Device Function Table.\n"); |
5da627a4 WD |
173 | } |
174 | ||
2012f238 | 175 | return FPGA_SUCCESS; |
5da627a4 | 176 | } |