1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2012 Stefan Roese <sr@denx.de>
4  */
5 
6 #include <common.h>
7 #include <log.h>
8 #include <spartan3.h>
9 #include <command.h>
10 #include <asm/gpio.h>
11 #include <asm/io.h>
12 #include <asm/arch/hardware.h>
13 #include <asm/arch/spr_misc.h>
14 #include <asm/arch/spr_ssp.h>
15 #include <linux/delay.h>
16 
17 /*
18  * FPGA program pin configuration on X600:
19  *
20  * Only PROG and DONE are connected to GPIOs. INIT is not connected to the
21  * SoC at all. And CLOCK and DATA are connected to the SSP2 port. We use
22  * 16bit serial writes via this SSP port to write the data bits into the
23  * FPGA.
24  */
25 #define CONFIG_SYS_FPGA_PROG		2
26 #define CONFIG_SYS_FPGA_DONE		3
27 
28 /*
29  * Set the active-low FPGA reset signal.
30  */
fpga_reset(int assert)31 static void fpga_reset(int assert)
32 {
33 	/*
34 	 * On x600 we have no means to toggle the FPGA reset signal
35 	 */
36 	debug("%s:%d: RESET (%d)\n", __func__, __LINE__, assert);
37 }
38 
39 /*
40  * Set the FPGA's active-low SelectMap program line to the specified level
41  */
fpga_pgm_fn(int assert,int flush,int cookie)42 static int fpga_pgm_fn(int assert, int flush, int cookie)
43 {
44 	debug("%s:%d: FPGA PROG (%d)\n", __func__, __LINE__, assert);
45 
46 	gpio_set_value(CONFIG_SYS_FPGA_PROG, assert);
47 
48 	return assert;
49 }
50 
51 /*
52  * Test the state of the active-low FPGA INIT line.  Return 1 on INIT
53  * asserted (low).
54  */
fpga_init_fn(int cookie)55 static int fpga_init_fn(int cookie)
56 {
57 	static int state;
58 
59 	debug("%s:%d: init (state=%d)\n", __func__, __LINE__, state);
60 
61 	/*
62 	 * On x600, the FPGA INIT signal is not connected to the SoC.
63 	 * We can't read the INIT status. Let's return the "correct"
64 	 * INIT signal state generated via a local state-machine.
65 	 */
66 	if (++state == 1) {
67 		return 1;
68 	} else {
69 		state = 0;
70 		return 0;
71 	}
72 }
73 
74 /*
75  * Test the state of the active-high FPGA DONE pin
76  */
fpga_done_fn(int cookie)77 static int fpga_done_fn(int cookie)
78 {
79 	struct ssp_regs *ssp = (struct ssp_regs *)CONFIG_SSP2_BASE;
80 
81 	/*
82 	 * Wait for Tx-FIFO to become empty before looking for DONE
83 	 */
84 	while (!(readl(&ssp->sspsr) & SSPSR_TFE))
85 		;
86 
87 	if (gpio_get_value(CONFIG_SYS_FPGA_DONE))
88 		return 1;
89 	else
90 		return 0;
91 }
92 
93 /*
94  * FPGA pre-configuration function. Just make sure that
95  * FPGA reset is asserted to keep the FPGA from starting up after
96  * configuration.
97  */
fpga_pre_config_fn(int cookie)98 static int fpga_pre_config_fn(int cookie)
99 {
100 	debug("%s:%d: FPGA pre-configuration\n", __func__, __LINE__);
101 	fpga_reset(true);
102 
103 	return 0;
104 }
105 
106 /*
107  * FPGA post configuration function. Blip the FPGA reset line and then see if
108  * the FPGA appears to be running.
109  */
fpga_post_config_fn(int cookie)110 static int fpga_post_config_fn(int cookie)
111 {
112 	int rc = 0;
113 
114 	debug("%s:%d: FPGA post configuration\n", __func__, __LINE__);
115 
116 	fpga_reset(true);
117 	udelay(100);
118 	fpga_reset(false);
119 	udelay(100);
120 
121 	return rc;
122 }
123 
fpga_clk_fn(int assert_clk,int flush,int cookie)124 static int fpga_clk_fn(int assert_clk, int flush, int cookie)
125 {
126 	/*
127 	 * No dedicated clock signal on x600 (data & clock generated)
128 	 * in SSP interface. So we don't have to do anything here.
129 	 */
130 	return assert_clk;
131 }
132 
fpga_wr_fn(int assert_write,int flush,int cookie)133 static int fpga_wr_fn(int assert_write, int flush, int cookie)
134 {
135 	struct ssp_regs *ssp = (struct ssp_regs *)CONFIG_SSP2_BASE;
136 	static int count;
137 	static u16 data;
138 
139 	/*
140 	 * First collect 16 bits of data
141 	 */
142 	data = data << 1;
143 	if (assert_write)
144 		data |= 1;
145 
146 	/*
147 	 * If 16 bits are not available, return for more bits
148 	 */
149 	count++;
150 	if (count != 16)
151 		return assert_write;
152 
153 	count = 0;
154 
155 	/*
156 	 * Wait for Tx-FIFO to become ready
157 	 */
158 	while (!(readl(&ssp->sspsr) & SSPSR_TNF))
159 		;
160 
161 	/* Send 16 bits to FPGA via SSP bus */
162 	writel(data, &ssp->sspdr);
163 
164 	return assert_write;
165 }
166 
167 static xilinx_spartan3_slave_serial_fns x600_fpga_fns = {
168 	fpga_pre_config_fn,
169 	fpga_pgm_fn,
170 	fpga_clk_fn,
171 	fpga_init_fn,
172 	fpga_done_fn,
173 	fpga_wr_fn,
174 	fpga_post_config_fn,
175 };
176 
177 static xilinx_desc fpga[CONFIG_FPGA_COUNT] = {
178 	XILINX_XC3S1200E_DESC(slave_serial, &x600_fpga_fns, 0)
179 };
180 
181 /*
182  * Initialize the SelectMap interface.  We assume that the mode and the
183  * initial state of all of the port pins have already been set!
184  */
fpga_serialslave_init(void)185 static void fpga_serialslave_init(void)
186 {
187 	debug("%s:%d: Initialize serial slave interface\n", __func__, __LINE__);
188 	fpga_pgm_fn(false, false, 0);	/* make sure program pin is inactive */
189 }
190 
expi_setup(int freq)191 static int expi_setup(int freq)
192 {
193 	struct misc_regs *misc = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
194 	int pll2_m, pll2_n, pll2_p, expi_x, expi_y;
195 
196 	pll2_m = (freq * 2) / 1000;
197 	pll2_n = 15;
198 	pll2_p = 1;
199 	expi_x = 1;
200 	expi_y = 2;
201 
202 	/*
203 	 * Disable reset, Low compression, Disable retiming, Enable Expi,
204 	 * Enable soft reset, DMA, PLL2, Internal
205 	 */
206 	writel(EXPI_CLK_CFG_LOW_COMPR | EXPI_CLK_CFG_CLK_EN | EXPI_CLK_CFG_RST |
207 	       EXPI_CLK_SYNT_EN | EXPI_CLK_CFG_SEL_PLL2 |
208 	       EXPI_CLK_CFG_INT_CLK_EN | (expi_y << 16) | (expi_x << 24),
209 	       &misc->expi_clk_cfg);
210 
211 	/*
212 	 * 6 uA, Internal feedback, 1st order, Non-dithered, Sample Parameters,
213 	 * Enable PLL2, Disable reset
214 	 */
215 	writel((pll2_m << 24) | (pll2_p << 8) | (pll2_n), &misc->pll2_frq);
216 	writel(PLL2_CNTL_6UA | PLL2_CNTL_SAMPLE | PLL2_CNTL_ENABLE |
217 	       PLL2_CNTL_RESETN | PLL2_CNTL_LOCK, &misc->pll2_cntl);
218 
219 	/*
220 	 * Disable soft reset
221 	 */
222 	clrbits_le32(&misc->expi_clk_cfg, EXPI_CLK_CFG_RST);
223 
224 	return 0;
225 }
226 
227 /*
228  * Initialize the fpga
229  */
x600_init_fpga(void)230 int x600_init_fpga(void)
231 {
232 	struct ssp_regs *ssp = (struct ssp_regs *)CONFIG_SSP2_BASE;
233 	struct misc_regs *misc = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
234 
235 	/* Enable SSP2 clock */
236 	writel(readl(&misc->periph1_clken) | MISC_SSP2ENB | MISC_GPIO4ENB,
237 	       &misc->periph1_clken);
238 
239 	/* Set EXPI clock to 45 MHz */
240 	expi_setup(45000);
241 
242 	/* Configure GPIO directions */
243 	gpio_direction_output(CONFIG_SYS_FPGA_PROG, 0);
244 	gpio_direction_input(CONFIG_SYS_FPGA_DONE);
245 
246 	writel(SSPCR0_DSS_16BITS, &ssp->sspcr0);
247 	writel(SSPCR1_SSE, &ssp->sspcr1);
248 
249 	/*
250 	 * Set lowest prescale divisor value (CPSDVSR) of 2 for max download
251 	 * speed.
252 	 *
253 	 * Actual data clock rate is: 80MHz / (CPSDVSR * (SCR + 1))
254 	 * With CPSDVSR at 2 and SCR at 0, the maximume clock rate is 40MHz.
255 	 */
256 	writel(2, &ssp->sspcpsr);
257 
258 	fpga_init();
259 	fpga_serialslave_init();
260 
261 	debug("%s:%d: Adding fpga 0\n", __func__, __LINE__);
262 	fpga_add(fpga_xilinx, &fpga[0]);
263 
264 	return 0;
265 }
266