configs: Resync with savedefconfig
[platform/kernel/u-boot.git] / drivers / fpga / cyclon2.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2006
4  * Heiko Schocher, hs@denx.de
5  * Based on ACE1XK.c
6  */
7
8 #define LOG_CATEGORY UCLASS_FPGA
9
10 #include <common.h>             /* core U-Boot definitions */
11 #include <log.h>
12 #include <altera.h>
13 #include <ACEX1K.h>             /* ACEX device family */
14 #include <linux/delay.h>
15
16 /* Note: The assumption is that we cannot possibly run fast enough to
17  * overrun the device (the Slave Parallel mode can free run at 50MHz).
18  * If there is a need to operate slower, define CFG_FPGA_DELAY in
19  * the board config file to slow things down.
20  */
21 #ifndef CFG_FPGA_DELAY
22 #define CFG_FPGA_DELAY()
23 #endif
24
25 #ifndef CFG_SYS_FPGA_WAIT
26 #define CFG_SYS_FPGA_WAIT CONFIG_SYS_HZ / 10            /* 100 ms */
27 #endif
28
29 static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize);
30 static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize);
31 /* static int CYC2_ps_info( Altera_desc *desc ); */
32
33 /* ------------------------------------------------------------------------- */
34 /* CYCLON2 Generic Implementation */
35 int CYC2_load(Altera_desc *desc, const void *buf, size_t bsize)
36 {
37         int ret_val = FPGA_FAIL;
38
39         switch (desc->iface) {
40         case passive_serial:
41                 log_debug("Launching Passive Serial Loader\n");
42                 ret_val = CYC2_ps_load(desc, buf, bsize);
43                 break;
44
45         case fast_passive_parallel:
46                 /* Fast Passive Parallel (FPP) and PS only differ in what is
47                  * done in the write() callback. Use the existing PS load
48                  * function for FPP, too.
49                  */
50                 log_debug("Launching Fast Passive Parallel Loader\n");
51                 ret_val = CYC2_ps_load(desc, buf, bsize);
52                 break;
53
54                 /* Add new interface types here */
55
56         default:
57                 printf("%s: Unsupported interface type, %d\n",
58                        __func__, desc->iface);
59         }
60
61         return ret_val;
62 }
63
64 int CYC2_dump(Altera_desc *desc, const void *buf, size_t bsize)
65 {
66         int ret_val = FPGA_FAIL;
67
68         switch (desc->iface) {
69         case passive_serial:
70                 log_debug("Launching Passive Serial Dump\n");
71                 ret_val = CYC2_ps_dump(desc, buf, bsize);
72                 break;
73
74                 /* Add new interface types here */
75
76         default:
77                 printf("%s: Unsupported interface type, %d\n",
78                        __func__, desc->iface);
79         }
80
81         return ret_val;
82 }
83
84 int CYC2_info(Altera_desc *desc)
85 {
86         return FPGA_SUCCESS;
87 }
88
89 /* ------------------------------------------------------------------------- */
90 /* CYCLON2 Passive Serial Generic Implementation                             */
91 static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize)
92 {
93         int ret_val = FPGA_FAIL;        /* assume the worst */
94         Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns;
95         int     ret = 0;
96
97         log_debug("start with interface functions @ 0x%p\n", fn);
98
99         if (fn) {
100                 int cookie = desc->cookie;      /* make a local copy */
101                 unsigned long ts;               /* timestamp */
102
103                 log_debug("Function Table:\n"
104                           "ptr:\t0x%p\n"
105                           "struct: 0x%p\n"
106                           "config:\t0x%p\n"
107                           "status:\t0x%p\n"
108                           "write:\t0x%p\n"
109                           "done:\t0x%p\n\n",
110                           &fn, fn, fn->config, fn->status,
111                           fn->write, fn->done);
112 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
113                 printf("Loading FPGA Device %d...", cookie);
114 #endif
115
116                 /*
117                  * Run the pre configuration function if there is one.
118                  */
119                 if (*fn->pre)
120                         (*fn->pre) (cookie);
121
122                 /* Establish the initial state */
123                 (*fn->config) (false, true, cookie);    /* De-assert nCONFIG */
124                 udelay(100);
125                 (*fn->config) (true, true, cookie);     /* Assert nCONFIG */
126
127                 udelay(2);              /* T_cfg > 2us  */
128
129                 /* Wait for nSTATUS to be asserted */
130                 ts = get_timer(0);              /* get current time */
131                 do {
132                         CFG_FPGA_DELAY();
133                         if (get_timer(ts) > CFG_SYS_FPGA_WAIT) {
134                                 /* check the time */
135                                 puts("** Timeout waiting for STATUS to go high.\n");
136                                 (*fn->abort) (cookie);
137                                 return FPGA_FAIL;
138                         }
139                 } while (!(*fn->status) (cookie));
140
141                 /* Get ready for the burn */
142                 CFG_FPGA_DELAY();
143
144                 ret = (*fn->write) (buf, bsize, true, cookie);
145                 if (ret) {
146                         puts("** Write failed.\n");
147                         (*fn->abort) (cookie);
148                         return FPGA_FAIL;
149                 }
150 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
151                 puts(" OK? ...");
152 #endif
153
154                 CFG_FPGA_DELAY();
155
156 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
157                 putc(' ');                      /* terminate the dotted line */
158 #endif
159
160                 /*
161                  * Checking FPGA's CONF_DONE signal - correctly booted ?
162                  */
163
164                 if (!(*fn->done) (cookie)) {
165                         puts("** Booting failed! CONF_DONE is still deasserted.\n");
166                         (*fn->abort) (cookie);
167                         return FPGA_FAIL;
168                 }
169 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
170                 puts(" OK\n");
171 #endif
172
173                 ret_val = FPGA_SUCCESS;
174
175 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
176                 if (ret_val == FPGA_SUCCESS)
177                         puts("Done.\n");
178                 else
179                         puts("Fail.\n");
180 #endif
181
182                 /*
183                  * Run the post configuration function if there is one.
184                  */
185                 if (*fn->post)
186                         (*fn->post) (cookie);
187         } else {
188                 printf("%s: NULL Interface function table!\n", __func__);
189         }
190
191         return ret_val;
192 }
193
194 static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize)
195 {
196         /* Readback is only available through the Slave Parallel and         */
197         /* boundary-scan interfaces.                                         */
198         printf("%s: Passive Serial Dumping is unavailable\n", __func__);
199         return FPGA_FAIL;
200 }