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