1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2007
4 * Eran Liberty, Extricom , eran.liberty@gmail.com
5 */
6
7 #include <altera.h>
8 #include <stratixII.h>
9 #include <linux/delay.h>
10
11 /****************************************************************/
12 /* Stratix II Generic Implementation */
StratixII_ps_fpp_dump(Altera_desc * desc,const void * buf,size_t bsize)13 int StratixII_ps_fpp_dump(Altera_desc *desc, const void *buf, size_t bsize)
14 {
15 printf("Stratix II Fast Passive Parallel dump is not implemented\n");
16 return FPGA_FAIL;
17 }
18
StratixII_ps_fpp_load(Altera_desc * desc,const void * buf,size_t bsize,int isSerial,int isSecure)19 int StratixII_ps_fpp_load(Altera_desc *desc, const void *buf, size_t bsize,
20 int isSerial, int isSecure)
21 {
22 altera_board_specific_func *fns;
23 int cookie;
24 int ret_val = FPGA_FAIL;
25 int bytecount;
26 const char *buff = buf;
27 int i;
28
29 if (!desc) {
30 log_err("Altera_desc missing\n");
31 return FPGA_FAIL;
32 }
33 if (!buff) {
34 log_err("buffer is missing\n");
35 return FPGA_FAIL;
36 }
37 if (!bsize) {
38 log_err("size is zero\n");
39 return FPGA_FAIL;
40 }
41 if (!desc->iface_fns) {
42 log_err("Altera_desc function interface table is missing\n");
43 return FPGA_FAIL;
44 }
45 fns = (altera_board_specific_func *) (desc->iface_fns);
46 cookie = desc->cookie;
47
48 if (!
49 (fns->config && fns->status && fns->done && fns->data
50 && fns->abort)) {
51 log_err("Missing some function in the function interface table\n");
52 return FPGA_FAIL;
53 }
54
55 /* 1. give board specific a chance to do anything before we start */
56 if (fns->pre) {
57 if ((ret_val = fns->pre (cookie)) < 0) {
58 return ret_val;
59 }
60 }
61
62 /* from this point on we must fail gracfully by calling lower layer abort */
63
64 /* 2. Strat burn cycle by deasserting config for t_CFG and waiting t_CF2CK after reaserted */
65 fns->config (0, 1, cookie);
66 udelay(5); /* nCONFIG low pulse width 2usec */
67 fns->config (1, 1, cookie);
68 udelay(100); /* nCONFIG high to first rising edge on DCLK */
69
70 /* 3. Start the Data cycle with clk deasserted */
71 bytecount = 0;
72 fns->clk (0, 1, cookie);
73
74 printf("loading to fpga ");
75 while (bytecount < bsize) {
76 /* 3.1 check stratix has not signaled us an error */
77 if (fns->status (cookie) != 1) {
78 log_err("\nStratix failed (byte transferred till failure 0x%x)\n",
79 bytecount);
80 fns->abort (cookie);
81 return FPGA_FAIL;
82 }
83 if (isSerial) {
84 int i;
85 uint8_t data = buff[bytecount++];
86 for (i = 0; i < 8; i++) {
87 /* 3.2(ps) put data on the bus */
88 fns->data ((data >> i) & 1, 1, cookie);
89
90 /* 3.3(ps) clock once */
91 fns->clk (1, 1, cookie);
92 fns->clk (0, 1, cookie);
93 }
94 } else {
95 /* 3.2(fpp) put data on the bus */
96 fns->data (buff[bytecount++], 1, cookie);
97
98 /* 3.3(fpp) clock once */
99 fns->clk (1, 1, cookie);
100 fns->clk (0, 1, cookie);
101
102 /* 3.4(fpp) for secure cycle push 3 more clocks */
103 for (i = 0; isSecure && i < 3; i++) {
104 fns->clk (1, 1, cookie);
105 fns->clk (0, 1, cookie);
106 }
107 }
108
109 /* 3.5 while clk is deasserted it is safe to print some progress indication */
110 if ((bytecount % (bsize / 100)) == 0) {
111 printf("\b\b\b%02zu\%%", bytecount * 100 / bsize);
112 }
113 }
114
115 /* 4. Set one last clock and check conf done signal */
116 fns->clk (1, 1, cookie);
117 udelay(100);
118 if (!fns->done (cookie)) {
119 printf(" error!.\n");
120 fns->abort (cookie);
121 return FPGA_FAIL;
122 } else {
123 printf("\b\b\b done.\n");
124 }
125
126 /* 5. call lower layer post configuration */
127 if (fns->post) {
128 if ((ret_val = fns->post (cookie)) < 0) {
129 fns->abort (cookie);
130 return ret_val;
131 }
132 }
133
134 return FPGA_SUCCESS;
135 }
136
StratixII_load(Altera_desc * desc,const void * buf,size_t size)137 int StratixII_load(Altera_desc *desc, const void *buf, size_t size)
138 {
139 int ret_val = FPGA_FAIL;
140
141 switch (desc->iface) {
142 case passive_serial:
143 ret_val = StratixII_ps_fpp_load(desc, buf, size, 1, 0);
144 break;
145 case fast_passive_parallel:
146 ret_val = StratixII_ps_fpp_load(desc, buf, size, 0, 0);
147 break;
148 case fast_passive_parallel_security:
149 ret_val = StratixII_ps_fpp_load(desc, buf, size, 0, 1);
150 break;
151
152 /* Add new interface types here */
153 default:
154 log_err("Unsupported interface type, %d\n", desc->iface);
155 }
156 return ret_val;
157 }
158
StratixII_dump(Altera_desc * desc,const void * buf,size_t bsize)159 int StratixII_dump(Altera_desc *desc, const void *buf, size_t bsize)
160 {
161 int ret_val = FPGA_FAIL;
162
163 switch (desc->iface) {
164 case passive_serial:
165 case fast_passive_parallel:
166 case fast_passive_parallel_security:
167 ret_val = StratixII_ps_fpp_dump(desc, buf, bsize);
168 break;
169 /* Add new interface types here */
170 default:
171 log_err("Unsupported interface type, %d\n", desc->iface);
172 }
173 return ret_val;
174 }
175
StratixII_info(Altera_desc * desc)176 int StratixII_info(Altera_desc *desc)
177 {
178 return FPGA_SUCCESS;
179 }
180