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