blob: 3b008facb8c4daeb59aacb0140a15f40b21df18e [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 */
Simon Glassc05ed002020-05-10 11:40:11 -060011#include <linux/delay.h>
Stefan Roesef0ff4692006-08-15 14:15:51 +020012
Stefan Roesef0ff4692006-08-15 14:15:51 +020013/* Define FPGA_DEBUG to get debug printf's */
14#ifdef FPGA_DEBUG
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020015#define PRINTF(fmt, args...) printf(fmt, ##args)
Stefan Roesef0ff4692006-08-15 14:15:51 +020016#else
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020017#define PRINTF(fmt, args...)
Stefan Roesef0ff4692006-08-15 14:15:51 +020018#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
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020029#ifndef CONFIG_SYS_FPGA_WAIT
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020030#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ / 10 /* 100 ms */
Stefan Roesef0ff4692006-08-15 14:15:51 +020031#endif
32
Wolfgang Denke6a857d2011-07-30 13:33:49 +000033static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize);
34static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize);
Stefan Roesef0ff4692006-08-15 14:15:51 +020035/* static int CYC2_ps_info( Altera_desc *desc ); */
Stefan Roesef0ff4692006-08-15 14:15:51 +020036
37/* ------------------------------------------------------------------------- */
38/* CYCLON2 Generic Implementation */
Wolfgang Denke6a857d2011-07-30 13:33:49 +000039int CYC2_load(Altera_desc *desc, const void *buf, size_t bsize)
Stefan Roesef0ff4692006-08-15 14:15:51 +020040{
41 int ret_val = FPGA_FAIL;
42
43 switch (desc->iface) {
44 case passive_serial:
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020045 PRINTF("%s: Launching Passive Serial Loader\n", __func__);
46 ret_val = CYC2_ps_load(desc, buf, bsize);
Stefan Roesef0ff4692006-08-15 14:15:51 +020047 break;
48
Michael Jonesee44fb22011-07-14 23:09:41 +000049 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 */
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020054 PRINTF("%s: Launching Fast Passive Parallel Loader\n",
55 __func__);
Michael Jonesee44fb22011-07-14 23:09:41 +000056 ret_val = CYC2_ps_load(desc, buf, bsize);
57 break;
58
Stefan Roesef0ff4692006-08-15 14:15:51 +020059 /* Add new interface types here */
60
61 default:
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020062 printf("%s: Unsupported interface type, %d\n",
63 __func__, desc->iface);
Stefan Roesef0ff4692006-08-15 14:15:51 +020064 }
65
66 return ret_val;
67}
68
Wolfgang Denke6a857d2011-07-30 13:33:49 +000069int CYC2_dump(Altera_desc *desc, const void *buf, size_t bsize)
Stefan Roesef0ff4692006-08-15 14:15:51 +020070{
71 int ret_val = FPGA_FAIL;
72
73 switch (desc->iface) {
74 case passive_serial:
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020075 PRINTF("%s: Launching Passive Serial Dump\n", __func__);
76 ret_val = CYC2_ps_dump(desc, buf, bsize);
Stefan Roesef0ff4692006-08-15 14:15:51 +020077 break;
78
79 /* Add new interface types here */
80
81 default:
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020082 printf("%s: Unsupported interface type, %d\n",
83 __func__, desc->iface);
Stefan Roesef0ff4692006-08-15 14:15:51 +020084 }
85
86 return ret_val;
87}
88
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020089int CYC2_info(Altera_desc *desc)
Stefan Roesef0ff4692006-08-15 14:15:51 +020090{
91 return FPGA_SUCCESS;
92}
93
Stefan Roesef0ff4692006-08-15 14:15:51 +020094/* ------------------------------------------------------------------------- */
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +020095/* CYCLON2 Passive Serial Generic Implementation */
Wolfgang Denke6a857d2011-07-30 13:33:49 +000096static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize)
Stefan Roesef0ff4692006-08-15 14:15:51 +020097{
98 int ret_val = FPGA_FAIL; /* assume the worst */
99 Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns;
100 int ret = 0;
101
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200102 PRINTF("%s: start with interface functions @ 0x%p\n",
103 __func__, fn);
Stefan Roesef0ff4692006-08-15 14:15:51 +0200104
105 if (fn) {
106 int cookie = desc->cookie; /* make a local copy */
107 unsigned long ts; /* timestamp */
108
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200109 PRINTF("%s: Function Table:\n"
Stefan Roesef0ff4692006-08-15 14:15:51 +0200110 "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",
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200116 __func__, &fn, fn, fn->config, fn->status,
Stefan Roesef0ff4692006-08-15 14:15:51 +0200117 fn->write, fn->done);
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200118#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200119 printf("Loading FPGA Device %d...", cookie);
Stefan Roesef0ff4692006-08-15 14:15:51 +0200120#endif
121
122 /*
123 * Run the pre configuration function if there is one.
124 */
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200125 if (*fn->pre)
Stefan Roesef0ff4692006-08-15 14:15:51 +0200126 (*fn->pre) (cookie);
Stefan Roesef0ff4692006-08-15 14:15:51 +0200127
128 /* Establish the initial state */
York Sun472d5462013-04-01 11:29:11 -0700129 (*fn->config) (false, true, cookie); /* De-assert nCONFIG */
Stephan Gatzkaa99c0402012-10-22 23:11:41 +0000130 udelay(100);
York Sun472d5462013-04-01 11:29:11 -0700131 (*fn->config) (true, true, cookie); /* Assert nCONFIG */
Stefan Roesef0ff4692006-08-15 14:15:51 +0200132
133 udelay(2); /* T_cfg > 2us */
134
135 /* Wait for nSTATUS to be asserted */
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200136 ts = get_timer(0); /* get current time */
Stefan Roesef0ff4692006-08-15 14:15:51 +0200137 do {
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200138 CONFIG_FPGA_DELAY();
139 if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
140 /* check the time */
141 puts("** Timeout waiting for STATUS to go high.\n");
Stefan Roesef0ff4692006-08-15 14:15:51 +0200142 (*fn->abort) (cookie);
143 return FPGA_FAIL;
144 }
145 } while (!(*fn->status) (cookie));
146
147 /* Get ready for the burn */
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200148 CONFIG_FPGA_DELAY();
Stefan Roesef0ff4692006-08-15 14:15:51 +0200149
York Sun472d5462013-04-01 11:29:11 -0700150 ret = (*fn->write) (buf, bsize, true, cookie);
Stefan Roesef0ff4692006-08-15 14:15:51 +0200151 if (ret) {
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200152 puts("** Write failed.\n");
Stefan Roesef0ff4692006-08-15 14:15:51 +0200153 (*fn->abort) (cookie);
154 return FPGA_FAIL;
155 }
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200156#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Stefan Roesef0ff4692006-08-15 14:15:51 +0200157 puts(" OK? ...");
158#endif
159
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200160 CONFIG_FPGA_DELAY();
Stefan Roesef0ff4692006-08-15 14:15:51 +0200161
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200162#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200163 putc(' '); /* terminate the dotted line */
Stefan Roesef0ff4692006-08-15 14:15:51 +0200164#endif
165
Alexander Dahl3911b192019-06-28 14:41:22 +0200166 /*
167 * Checking FPGA's CONF_DONE signal - correctly booted ?
168 */
Stefan Roesef0ff4692006-08-15 14:15:51 +0200169
Alexander Dahl3911b192019-06-28 14:41:22 +0200170 if (!(*fn->done) (cookie)) {
171 puts("** Booting failed! CONF_DONE is still deasserted.\n");
172 (*fn->abort) (cookie);
173 return FPGA_FAIL;
174 }
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200175#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Alexander Dahl3911b192019-06-28 14:41:22 +0200176 puts(" OK\n");
Stefan Roesef0ff4692006-08-15 14:15:51 +0200177#endif
178
Alexander Dahl3911b192019-06-28 14:41:22 +0200179 ret_val = FPGA_SUCCESS;
Stefan Roesef0ff4692006-08-15 14:15:51 +0200180
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200181#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
Alexander Dahl3911b192019-06-28 14:41:22 +0200182 if (ret_val == FPGA_SUCCESS)
183 puts("Done.\n");
184 else
185 puts("Fail.\n");
Stefan Roesef0ff4692006-08-15 14:15:51 +0200186#endif
Stefan Roesef0ff4692006-08-15 14:15:51 +0200187
Alexander Dahlb283d6b2019-06-28 14:41:23 +0200188 /*
189 * Run the post configuration function if there is one.
190 */
191 if (*fn->post)
192 (*fn->post) (cookie);
Stefan Roesef0ff4692006-08-15 14:15:51 +0200193 } else {
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200194 printf("%s: NULL Interface function table!\n", __func__);
Stefan Roesef0ff4692006-08-15 14:15:51 +0200195 }
196
197 return ret_val;
198}
199
Wolfgang Denke6a857d2011-07-30 13:33:49 +0000200static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize)
Stefan Roesef0ff4692006-08-15 14:15:51 +0200201{
202 /* Readback is only available through the Slave Parallel and */
203 /* boundary-scan interfaces. */
Alexander Dahlbb2c0fa2019-06-28 14:41:21 +0200204 printf("%s: Passive Serial Dumping is unavailable\n", __func__);
Stefan Roesef0ff4692006-08-15 14:15:51 +0200205 return FPGA_FAIL;
206}