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