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