blob: c929cd2cc51863a77323102ddaf9561f2494a8c7 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Stefan Roesef0ff4692006-08-15 14:15:51 +02002/*
3 * (C) Copyright 2006
4 * Heiko Schocher, hs@denx.de
5 * Based on ACE1XK.c
Stefan Roesef0ff4692006-08-15 14:15:51 +02006 */
7
8#include <common.h> /* core U-Boot definitions */
9#include <altera.h>
10#include <ACEX1K.h> /* ACEX device family */
11
Stefan Roesef0ff4692006-08-15 14:15:51 +020012/* Define FPGA_DEBUG to get debug printf's */
13#ifdef FPGA_DEBUG
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020014#define PRINTF(fmt, args...) printf(fmt, ##args)
Stefan Roesef0ff4692006-08-15 14:15:51 +020015#else
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020016#define PRINTF(fmt, args...)
Stefan Roesef0ff4692006-08-15 14:15:51 +020017#endif
18
19/* Note: The assumption is that we cannot possibly run fast enough to
20 * overrun the device (the Slave Parallel mode can free run at 50MHz).
21 * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
22 * the board config file to slow things down.
23 */
24#ifndef CONFIG_FPGA_DELAY
25#define CONFIG_FPGA_DELAY()
26#endif
27
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020028#ifndef CONFIG_SYS_FPGA_WAIT
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020029#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ / 10 /* 100 ms */
Stefan Roesef0ff4692006-08-15 14:15:51 +020030#endif
31
Wolfgang Denke6a857d2011-07-30 13:33:49 +000032static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize);
33static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize);
Stefan Roesef0ff4692006-08-15 14:15:51 +020034/* static int CYC2_ps_info( Altera_desc *desc ); */
Stefan Roesef0ff4692006-08-15 14:15:51 +020035
36/* ------------------------------------------------------------------------- */
37/* CYCLON2 Generic Implementation */
Wolfgang Denke6a857d2011-07-30 13:33:49 +000038int CYC2_load(Altera_desc *desc, const void *buf, size_t bsize)
Stefan Roesef0ff4692006-08-15 14:15:51 +020039{
40 int ret_val = FPGA_FAIL;
41
42 switch (desc->iface) {
43 case passive_serial:
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020044 PRINTF("%s: Launching Passive Serial Loader\n", __func__);
45 ret_val = CYC2_ps_load(desc, buf, bsize);
Stefan Roesef0ff4692006-08-15 14:15:51 +020046 break;
47
Michael Jonesee44fb22011-07-14 23:09:41 +000048 case fast_passive_parallel:
49 /* Fast Passive Parallel (FPP) and PS only differ in what is
50 * done in the write() callback. Use the existing PS load
51 * function for FPP, too.
52 */
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020053 PRINTF("%s: Launching Fast Passive Parallel Loader\n",
54 __func__);
Michael Jonesee44fb22011-07-14 23:09:41 +000055 ret_val = CYC2_ps_load(desc, buf, bsize);
56 break;
57
Stefan Roesef0ff4692006-08-15 14:15:51 +020058 /* Add new interface types here */
59
60 default:
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020061 printf("%s: Unsupported interface type, %d\n",
62 __func__, desc->iface);
Stefan Roesef0ff4692006-08-15 14:15:51 +020063 }
64
65 return ret_val;
66}
67
Wolfgang Denke6a857d2011-07-30 13:33:49 +000068int CYC2_dump(Altera_desc *desc, const void *buf, size_t bsize)
Stefan Roesef0ff4692006-08-15 14:15:51 +020069{
70 int ret_val = FPGA_FAIL;
71
72 switch (desc->iface) {
73 case passive_serial:
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020074 PRINTF("%s: Launching Passive Serial Dump\n", __func__);
75 ret_val = CYC2_ps_dump(desc, buf, bsize);
Stefan Roesef0ff4692006-08-15 14:15:51 +020076 break;
77
78 /* Add new interface types here */
79
80 default:
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020081 printf("%s: Unsupported interface type, %d\n",
82 __func__, desc->iface);
Stefan Roesef0ff4692006-08-15 14:15:51 +020083 }
84
85 return ret_val;
86}
87
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020088int CYC2_info(Altera_desc *desc)
Stefan Roesef0ff4692006-08-15 14:15:51 +020089{
90 return FPGA_SUCCESS;
91}
92
Stefan Roesef0ff4692006-08-15 14:15:51 +020093/* ------------------------------------------------------------------------- */
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020094/* CYCLON2 Passive Serial Generic Implementation */
Wolfgang Denke6a857d2011-07-30 13:33:49 +000095static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize)
Stefan Roesef0ff4692006-08-15 14:15:51 +020096{
97 int ret_val = FPGA_FAIL; /* assume the worst */
98 Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns;
99 int ret = 0;
100
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200101 PRINTF("%s: start with interface functions @ 0x%p\n",
102 __func__, fn);
Stefan Roesef0ff4692006-08-15 14:15:51 +0200103
104 if (fn) {
105 int cookie = desc->cookie; /* make a local copy */
106 unsigned long ts; /* timestamp */
107
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200108 PRINTF("%s: Function Table:\n"
Stefan Roesef0ff4692006-08-15 14:15:51 +0200109 "ptr:\t0x%p\n"
110 "struct: 0x%p\n"
111 "config:\t0x%p\n"
112 "status:\t0x%p\n"
113 "write:\t0x%p\n"
114 "done:\t0x%p\n\n",
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200115 __func__, &fn, fn, fn->config, fn->status,
Stefan Roesef0ff4692006-08-15 14:15:51 +0200116 fn->write, fn->done);
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200117#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200118 printf("Loading FPGA Device %d...", cookie);
Stefan Roesef0ff4692006-08-15 14:15:51 +0200119#endif
120
121 /*
122 * Run the pre configuration function if there is one.
123 */
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200124 if (*fn->pre)
Stefan Roesef0ff4692006-08-15 14:15:51 +0200125 (*fn->pre) (cookie);
Stefan Roesef0ff4692006-08-15 14:15:51 +0200126
127 /* Establish the initial state */
York Sun472d5462013-04-01 11:29:11 -0700128 (*fn->config) (false, true, cookie); /* De-assert nCONFIG */
Stephan Gatzkaa99c0402012-10-22 23:11:41 +0000129 udelay(100);
York Sun472d5462013-04-01 11:29:11 -0700130 (*fn->config) (true, true, cookie); /* Assert nCONFIG */
Stefan Roesef0ff4692006-08-15 14:15:51 +0200131
132 udelay(2); /* T_cfg > 2us */
133
134 /* Wait for nSTATUS to be asserted */
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200135 ts = get_timer(0); /* get current time */
Stefan Roesef0ff4692006-08-15 14:15:51 +0200136 do {
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200137 CONFIG_FPGA_DELAY();
138 if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
139 /* check the time */
140 puts("** Timeout waiting for STATUS to go high.\n");
Stefan Roesef0ff4692006-08-15 14:15:51 +0200141 (*fn->abort) (cookie);
142 return FPGA_FAIL;
143 }
144 } while (!(*fn->status) (cookie));
145
146 /* Get ready for the burn */
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200147 CONFIG_FPGA_DELAY();
Stefan Roesef0ff4692006-08-15 14:15:51 +0200148
York Sun472d5462013-04-01 11:29:11 -0700149 ret = (*fn->write) (buf, bsize, true, cookie);
Stefan Roesef0ff4692006-08-15 14:15:51 +0200150 if (ret) {
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200151 puts("** Write failed.\n");
Stefan Roesef0ff4692006-08-15 14:15:51 +0200152 (*fn->abort) (cookie);
153 return FPGA_FAIL;
154 }
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200155#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Stefan Roesef0ff4692006-08-15 14:15:51 +0200156 puts(" OK? ...");
157#endif
158
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200159 CONFIG_FPGA_DELAY();
Stefan Roesef0ff4692006-08-15 14:15:51 +0200160
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200161#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200162 putc(' '); /* terminate the dotted line */
Stefan Roesef0ff4692006-08-15 14:15:51 +0200163#endif
164
Alexander Dahl3911b192019-06-28 14:41:22 +0200165 /*
166 * Checking FPGA's CONF_DONE signal - correctly booted ?
167 */
Stefan Roesef0ff4692006-08-15 14:15:51 +0200168
Alexander Dahl3911b192019-06-28 14:41:22 +0200169 if (!(*fn->done) (cookie)) {
170 puts("** Booting failed! CONF_DONE is still deasserted.\n");
171 (*fn->abort) (cookie);
172 return FPGA_FAIL;
173 }
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200174#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Alexander Dahl3911b192019-06-28 14:41:22 +0200175 puts(" OK\n");
Stefan Roesef0ff4692006-08-15 14:15:51 +0200176#endif
177
Alexander Dahl3911b192019-06-28 14:41:22 +0200178 ret_val = FPGA_SUCCESS;
Stefan Roesef0ff4692006-08-15 14:15:51 +0200179
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200180#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Alexander Dahl3911b192019-06-28 14:41:22 +0200181 if (ret_val == FPGA_SUCCESS)
182 puts("Done.\n");
183 else
184 puts("Fail.\n");
Stefan Roesef0ff4692006-08-15 14:15:51 +0200185#endif
Stefan Roesef0ff4692006-08-15 14:15:51 +0200186
Alexander Dahlb283d6b2019-06-28 14:41:23 +0200187 /*
188 * Run the post configuration function if there is one.
189 */
190 if (*fn->post)
191 (*fn->post) (cookie);
Stefan Roesef0ff4692006-08-15 14:15:51 +0200192 } else {
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200193 printf("%s: NULL Interface function table!\n", __func__);
Stefan Roesef0ff4692006-08-15 14:15:51 +0200194 }
195
196 return ret_val;
197}
198
Wolfgang Denke6a857d2011-07-30 13:33:49 +0000199static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize)
Stefan Roesef0ff4692006-08-15 14:15:51 +0200200{
201 /* Readback is only available through the Slave Parallel and */
202 /* boundary-scan interfaces. */
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200203 printf("%s: Passive Serial Dumping is unavailable\n", __func__);
Stefan Roesef0ff4692006-08-15 14:15:51 +0200204 return FPGA_FAIL;
205}