]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
5b845b66 | 2 | /* |
5da627a4 WD |
3 | * (C) Copyright 2003 |
4 | * Steven Scholz, imc Measurement & Control, [email protected] | |
5 | * | |
5b845b66 WD |
6 | * (C) Copyright 2002 |
7 | * Rich Ireland, Enterasys Networks, [email protected]. | |
5b845b66 WD |
8 | */ |
9 | ||
5b845b66 WD |
10 | /* |
11 | * Altera FPGA support | |
12 | */ | |
13 | #include <common.h> | |
fda915a4 | 14 | #include <errno.h> |
5da627a4 | 15 | #include <ACEX1K.h> |
f7ae49fc | 16 | #include <log.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 | |
d2170168 CHA |
46 | #if defined(CONFIG_FPGA_INTEL_SDM_MAILBOX) |
47 | { Intel_FPGA_SDM_Mailbox, "Intel SDM Mailbox", intel_sdm_mb_load, NULL, | |
48 | NULL }, | |
49 | #endif | |
2012f238 MV |
50 | }; |
51 | ||
54c96b18 MV |
52 | static int altera_validate(Altera_desc *desc, const char *fn) |
53 | { | |
54 | if (!desc) { | |
55 | printf("%s: NULL descriptor!\n", fn); | |
fda915a4 | 56 | return -EINVAL; |
54c96b18 MV |
57 | } |
58 | ||
59 | if ((desc->family < min_altera_type) || | |
60 | (desc->family > max_altera_type)) { | |
61 | printf("%s: Invalid family type, %d\n", fn, desc->family); | |
fda915a4 | 62 | return -EINVAL; |
54c96b18 MV |
63 | } |
64 | ||
65 | if ((desc->iface < min_altera_iface_type) || | |
66 | (desc->iface > max_altera_iface_type)) { | |
67 | printf("%s: Invalid Interface type, %d\n", fn, desc->iface); | |
fda915a4 | 68 | return -EINVAL; |
54c96b18 MV |
69 | } |
70 | ||
71 | if (!desc->size) { | |
72 | printf("%s: NULL part size\n", fn); | |
fda915a4 | 73 | return -EINVAL; |
54c96b18 MV |
74 | } |
75 | ||
fda915a4 | 76 | return 0; |
54c96b18 | 77 | } |
5da627a4 | 78 | |
2012f238 MV |
79 | static const struct altera_fpga * |
80 | altera_desc_to_fpga(Altera_desc *desc, const char *fn) | |
5b845b66 | 81 | { |
2012f238 | 82 | int i; |
5da627a4 | 83 | |
2012f238 MV |
84 | if (altera_validate(desc, fn)) { |
85 | printf("%s: Invalid device descriptor\n", fn); | |
86 | return NULL; | |
4a4c0a5e MV |
87 | } |
88 | ||
2012f238 MV |
89 | for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) { |
90 | if (desc->family == altera_fpga[i].family) | |
91 | break; | |
92 | } | |
5da627a4 | 93 | |
2012f238 MV |
94 | if (i == ARRAY_SIZE(altera_fpga)) { |
95 | printf("%s: Unsupported family type, %d\n", fn, desc->family); | |
96 | return NULL; | |
5da627a4 WD |
97 | } |
98 | ||
2012f238 | 99 | return &altera_fpga[i]; |
5b845b66 WD |
100 | } |
101 | ||
2012f238 | 102 | int altera_load(Altera_desc *desc, const void *buf, size_t bsize) |
5b845b66 | 103 | { |
2012f238 | 104 | const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__); |
5da627a4 | 105 | |
2012f238 | 106 | if (!fpga) |
4a4c0a5e | 107 | return FPGA_FAIL; |
4a4c0a5e | 108 | |
2012f238 MV |
109 | debug_cond(FPGA_DEBUG, "%s: Launching the %s Loader...\n", |
110 | __func__, fpga->name); | |
111 | if (fpga->load) | |
112 | return fpga->load(desc, buf, bsize); | |
113 | return 0; | |
114 | } | |
5da627a4 | 115 | |
2012f238 MV |
116 | int altera_dump(Altera_desc *desc, const void *buf, size_t bsize) |
117 | { | |
118 | const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__); | |
5da627a4 | 119 | |
2012f238 MV |
120 | if (!fpga) |
121 | return FPGA_FAIL; | |
122 | ||
123 | debug_cond(FPGA_DEBUG, "%s: Launching the %s Reader...\n", | |
124 | __func__, fpga->name); | |
125 | if (fpga->dump) | |
126 | return fpga->dump(desc, buf, bsize); | |
127 | return 0; | |
5b845b66 WD |
128 | } |
129 | ||
4a4c0a5e | 130 | int altera_info(Altera_desc *desc) |
5b845b66 | 131 | { |
2012f238 | 132 | const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__); |
5da627a4 | 133 | |
2012f238 | 134 | if (!fpga) |
4a4c0a5e | 135 | return FPGA_FAIL; |
5da627a4 | 136 | |
2012f238 | 137 | printf("Family: \t%s\n", fpga->name); |
5da627a4 | 138 | |
4a4c0a5e MV |
139 | printf("Interface type:\t"); |
140 | switch (desc->iface) { | |
141 | case passive_serial: | |
142 | printf("Passive Serial (PS)\n"); | |
143 | break; | |
144 | case passive_parallel_synchronous: | |
145 | printf("Passive Parallel Synchronous (PPS)\n"); | |
146 | break; | |
147 | case passive_parallel_asynchronous: | |
148 | printf("Passive Parallel Asynchronous (PPA)\n"); | |
149 | break; | |
150 | case passive_serial_asynchronous: | |
151 | printf("Passive Serial Asynchronous (PSA)\n"); | |
152 | break; | |
153 | case altera_jtag_mode: /* Not used */ | |
154 | printf("JTAG Mode\n"); | |
155 | break; | |
156 | case fast_passive_parallel: | |
157 | printf("Fast Passive Parallel (FPP)\n"); | |
158 | break; | |
159 | case fast_passive_parallel_security: | |
160 | printf("Fast Passive Parallel with Security (FPPS)\n"); | |
161 | break; | |
877ec6eb ACH |
162 | case secure_device_manager_mailbox: |
163 | puts("Secure Device Manager (SDM) Mailbox\n"); | |
164 | break; | |
4a4c0a5e MV |
165 | /* Add new interface types here */ |
166 | default: | |
167 | printf("Unsupported interface type, %d\n", desc->iface); | |
168 | } | |
169 | ||
170 | printf("Device Size: \t%zd bytes\n" | |
171 | "Cookie: \t0x%x (%d)\n", | |
172 | desc->size, desc->cookie, desc->cookie); | |
5da627a4 | 173 | |
4a4c0a5e MV |
174 | if (desc->iface_fns) { |
175 | printf("Device Function Table @ 0x%p\n", desc->iface_fns); | |
2012f238 MV |
176 | if (fpga->info) |
177 | fpga->info(desc); | |
5da627a4 | 178 | } else { |
4a4c0a5e | 179 | printf("No Device Function Table.\n"); |
5da627a4 WD |
180 | } |
181 | ||
2012f238 | 182 | return FPGA_SUCCESS; |
5da627a4 | 183 | } |