xref: /rk3399_rockchip-uboot/board/armadeus/apf27/fpga.c (revision 05d134b084590684bcf4d832c0035952727b7cd9)
1b5e7f1bcStrem /*
2b5e7f1bcStrem  * (C) Copyright 2002-2013
3b5e7f1bcStrem  * Eric Jarrige <eric.jarrige@armadeus.org>
4b5e7f1bcStrem  *
5b5e7f1bcStrem  * based on the files by
6b5e7f1bcStrem  * Rich Ireland, Enterasys Networks, rireland@enterasys.com
7b5e7f1bcStrem  * and
8b5e7f1bcStrem  * Keith Outwater, keith_outwater@mvis.com
9b5e7f1bcStrem  *
10b5e7f1bcStrem  * SPDX-License-Identifier:     GPL-2.0+
11b5e7f1bcStrem  */
12b5e7f1bcStrem #include <common.h>
13b5e7f1bcStrem 
14b5e7f1bcStrem #include <asm/arch/imx-regs.h>
15b5e7f1bcStrem #include <asm/gpio.h>
16b5e7f1bcStrem #include <asm/io.h>
17b5e7f1bcStrem #include <command.h>
18b5e7f1bcStrem #include <config.h>
19b5e7f1bcStrem #include "fpga.h"
20b5e7f1bcStrem #include <spartan3.h>
21b5e7f1bcStrem #include "apf27.h"
22b5e7f1bcStrem 
23b5e7f1bcStrem /*
24b5e7f1bcStrem  * Note that these are pointers to code that is in Flash.  They will be
25b5e7f1bcStrem  * relocated at runtime.
26b5e7f1bcStrem  * Spartan2 code is used to download our Spartan 3 :) code is compatible.
27b5e7f1bcStrem  * Just take care about the file size
28b5e7f1bcStrem  */
292a6e3869SMichal Simek xilinx_spartan3_slave_parallel_fns fpga_fns = {
30b5e7f1bcStrem 	fpga_pre_fn,
31b5e7f1bcStrem 	fpga_pgm_fn,
32b5e7f1bcStrem 	fpga_init_fn,
33b5e7f1bcStrem 	NULL,
34b5e7f1bcStrem 	fpga_done_fn,
35b5e7f1bcStrem 	fpga_clk_fn,
36b5e7f1bcStrem 	fpga_cs_fn,
37b5e7f1bcStrem 	fpga_wr_fn,
38b5e7f1bcStrem 	fpga_rdata_fn,
39b5e7f1bcStrem 	fpga_wdata_fn,
40b5e7f1bcStrem 	fpga_busy_fn,
41b5e7f1bcStrem 	fpga_abort_fn,
42b5e7f1bcStrem 	fpga_post_fn,
43b5e7f1bcStrem };
44b5e7f1bcStrem 
45f8c1be98SMichal Simek xilinx_desc fpga[CONFIG_FPGA_COUNT] = {
462a6e3869SMichal Simek 	{xilinx_spartan3,
47b5e7f1bcStrem 	 slave_parallel,
48b5e7f1bcStrem 	 1196128l/8,
49b5e7f1bcStrem 	 (void *)&fpga_fns,
50b5e7f1bcStrem 	 0,
51*14cfc4f3SMichal Simek 	 &spartan3_op,
52b5e7f1bcStrem 	 "3s200aft256"}
53b5e7f1bcStrem };
54b5e7f1bcStrem 
55b5e7f1bcStrem /*
56b5e7f1bcStrem  * Initialize GPIO port B before download
57b5e7f1bcStrem  */
fpga_pre_fn(int cookie)58b5e7f1bcStrem int fpga_pre_fn(int cookie)
59b5e7f1bcStrem {
60b5e7f1bcStrem 	/* Initialize GPIO pins */
61b5e7f1bcStrem 	gpio_set_value(ACFG_FPGA_PWR, 1);
62b5e7f1bcStrem 	imx_gpio_mode(ACFG_FPGA_INIT | GPIO_IN | GPIO_PUEN | GPIO_GPIO);
63b5e7f1bcStrem 	imx_gpio_mode(ACFG_FPGA_DONE | GPIO_IN | GPIO_PUEN | GPIO_GPIO);
64b5e7f1bcStrem 	imx_gpio_mode(ACFG_FPGA_PRG | GPIO_OUT | GPIO_PUEN | GPIO_GPIO);
65b5e7f1bcStrem 	imx_gpio_mode(ACFG_FPGA_CLK | GPIO_OUT | GPIO_PUEN | GPIO_GPIO);
66b5e7f1bcStrem 	imx_gpio_mode(ACFG_FPGA_RW | GPIO_OUT | GPIO_PUEN | GPIO_GPIO);
67b5e7f1bcStrem 	imx_gpio_mode(ACFG_FPGA_CS | GPIO_OUT | GPIO_PUEN | GPIO_GPIO);
68b5e7f1bcStrem 	imx_gpio_mode(ACFG_FPGA_SUSPEND|GPIO_OUT|GPIO_PUEN|GPIO_GPIO);
69b5e7f1bcStrem 	gpio_set_value(ACFG_FPGA_RESET, 1);
70b5e7f1bcStrem 	imx_gpio_mode(ACFG_FPGA_RESET | GPIO_OUT | GPIO_PUEN | GPIO_GPIO);
71b5e7f1bcStrem 	imx_gpio_mode(ACFG_FPGA_PWR | GPIO_OUT | GPIO_PUEN | GPIO_GPIO);
72b5e7f1bcStrem 	gpio_set_value(ACFG_FPGA_PRG, 1);
73b5e7f1bcStrem 	gpio_set_value(ACFG_FPGA_CLK, 1);
74b5e7f1bcStrem 	gpio_set_value(ACFG_FPGA_RW, 1);
75b5e7f1bcStrem 	gpio_set_value(ACFG_FPGA_CS, 1);
76b5e7f1bcStrem 	gpio_set_value(ACFG_FPGA_SUSPEND, 0);
77b5e7f1bcStrem 	gpio_set_value(ACFG_FPGA_PWR, 0);
78b5e7f1bcStrem 	udelay(30000); /*wait until supply started*/
79b5e7f1bcStrem 
80b5e7f1bcStrem 	return cookie;
81b5e7f1bcStrem }
82b5e7f1bcStrem 
83b5e7f1bcStrem /*
84b5e7f1bcStrem  * Set the FPGA's active-low program line to the specified level
85b5e7f1bcStrem  */
fpga_pgm_fn(int assert,int flush,int cookie)86b5e7f1bcStrem int fpga_pgm_fn(int assert, int flush, int cookie)
87b5e7f1bcStrem {
88b5e7f1bcStrem 	debug("%s:%d: FPGA PROGRAM %s", __func__, __LINE__,
89b5e7f1bcStrem 	      assert ? "high" : "low");
90b5e7f1bcStrem 	gpio_set_value(ACFG_FPGA_PRG, !assert);
91b5e7f1bcStrem 	return assert;
92b5e7f1bcStrem }
93b5e7f1bcStrem 
94b5e7f1bcStrem /*
95b5e7f1bcStrem  * Set the FPGA's active-high clock line to the specified level
96b5e7f1bcStrem  */
fpga_clk_fn(int assert_clk,int flush,int cookie)97b5e7f1bcStrem int fpga_clk_fn(int assert_clk, int flush, int cookie)
98b5e7f1bcStrem {
99b5e7f1bcStrem 	debug("%s:%d: FPGA CLOCK %s", __func__, __LINE__,
100b5e7f1bcStrem 	      assert_clk ? "high" : "low");
101b5e7f1bcStrem 	gpio_set_value(ACFG_FPGA_CLK, !assert_clk);
102b5e7f1bcStrem 	return assert_clk;
103b5e7f1bcStrem }
104b5e7f1bcStrem 
105b5e7f1bcStrem /*
106b5e7f1bcStrem  * Test the state of the active-low FPGA INIT line.  Return 1 on INIT
107b5e7f1bcStrem  * asserted (low).
108b5e7f1bcStrem  */
fpga_init_fn(int cookie)109b5e7f1bcStrem int fpga_init_fn(int cookie)
110b5e7f1bcStrem {
111b5e7f1bcStrem 	int value;
112b5e7f1bcStrem 	debug("%s:%d: INIT check... ", __func__, __LINE__);
113b5e7f1bcStrem 	value = gpio_get_value(ACFG_FPGA_INIT);
114b5e7f1bcStrem 	/* printf("init value read %x",value); */
115b5e7f1bcStrem #ifdef CONFIG_SYS_FPGA_IS_PROTO
116b5e7f1bcStrem 	return value;
117b5e7f1bcStrem #else
118b5e7f1bcStrem 	return !value;
119b5e7f1bcStrem #endif
120b5e7f1bcStrem }
121b5e7f1bcStrem 
122b5e7f1bcStrem /*
123b5e7f1bcStrem  * Test the state of the active-high FPGA DONE pin
124b5e7f1bcStrem  */
fpga_done_fn(int cookie)125b5e7f1bcStrem int fpga_done_fn(int cookie)
126b5e7f1bcStrem {
127b5e7f1bcStrem 	debug("%s:%d: DONE check... %s", __func__, __LINE__,
128b5e7f1bcStrem 	      gpio_get_value(ACFG_FPGA_DONE) ? "high" : "low");
129b5e7f1bcStrem 	return gpio_get_value(ACFG_FPGA_DONE) ? FPGA_SUCCESS : FPGA_FAIL;
130b5e7f1bcStrem }
131b5e7f1bcStrem 
132b5e7f1bcStrem /*
133b5e7f1bcStrem  * Set the FPGA's wr line to the specified level
134b5e7f1bcStrem  */
fpga_wr_fn(int assert_write,int flush,int cookie)135b5e7f1bcStrem int fpga_wr_fn(int assert_write, int flush, int cookie)
136b5e7f1bcStrem {
137b5e7f1bcStrem 	debug("%s:%d: FPGA RW... %s ", __func__, __LINE__,
138b5e7f1bcStrem 	      assert_write ? "high" : "low");
139b5e7f1bcStrem 	gpio_set_value(ACFG_FPGA_RW, !assert_write);
140b5e7f1bcStrem 	return assert_write;
141b5e7f1bcStrem }
142b5e7f1bcStrem 
fpga_cs_fn(int assert_cs,int flush,int cookie)143b5e7f1bcStrem int fpga_cs_fn(int assert_cs, int flush, int cookie)
144b5e7f1bcStrem {
145b5e7f1bcStrem 	debug("%s:%d: FPGA CS %s ", __func__, __LINE__,
146b5e7f1bcStrem 	      assert_cs ? "high" : "low");
147b5e7f1bcStrem 	gpio_set_value(ACFG_FPGA_CS, !assert_cs);
148b5e7f1bcStrem 	return assert_cs;
149b5e7f1bcStrem }
150b5e7f1bcStrem 
fpga_rdata_fn(unsigned char * data,int cookie)151b5e7f1bcStrem int fpga_rdata_fn(unsigned char *data, int cookie)
152b5e7f1bcStrem {
153b5e7f1bcStrem 	debug("%s:%d: FPGA READ DATA %02X ", __func__, __LINE__,
154b5e7f1bcStrem 	      *((char *)ACFG_FPGA_RDATA));
155b5e7f1bcStrem 	*data = (unsigned char)
156b5e7f1bcStrem 		((*((unsigned short *)ACFG_FPGA_RDATA))&0x00FF);
157b5e7f1bcStrem 	return *data;
158b5e7f1bcStrem }
159b5e7f1bcStrem 
fpga_wdata_fn(unsigned char data,int flush,int cookie)160b5e7f1bcStrem int fpga_wdata_fn(unsigned char data, int flush, int cookie)
161b5e7f1bcStrem {
162b5e7f1bcStrem 	debug("%s:%d: FPGA WRITE DATA %02X ", __func__, __LINE__,
163b5e7f1bcStrem 	      data);
164b5e7f1bcStrem 	*((unsigned short *)ACFG_FPGA_WDATA) = data;
165b5e7f1bcStrem 	return data;
166b5e7f1bcStrem }
167b5e7f1bcStrem 
fpga_abort_fn(int cookie)168b5e7f1bcStrem int fpga_abort_fn(int cookie)
169b5e7f1bcStrem {
170b5e7f1bcStrem 	return fpga_post_fn(cookie);
171b5e7f1bcStrem }
172b5e7f1bcStrem 
173b5e7f1bcStrem 
fpga_busy_fn(int cookie)174b5e7f1bcStrem int fpga_busy_fn(int cookie)
175b5e7f1bcStrem {
176b5e7f1bcStrem 	return 1;
177b5e7f1bcStrem }
178b5e7f1bcStrem 
fpga_post_fn(int cookie)179b5e7f1bcStrem int fpga_post_fn(int cookie)
180b5e7f1bcStrem {
181b5e7f1bcStrem 	debug("%s:%d: FPGA POST ", __func__, __LINE__);
182b5e7f1bcStrem 
183b5e7f1bcStrem 	imx_gpio_mode(ACFG_FPGA_RW | GPIO_PF | GPIO_PUEN);
184b5e7f1bcStrem 	imx_gpio_mode(ACFG_FPGA_CS | GPIO_PF | GPIO_PUEN);
185b5e7f1bcStrem 	imx_gpio_mode(ACFG_FPGA_CLK | GPIO_PF | GPIO_PUEN);
186b5e7f1bcStrem 	gpio_set_value(ACFG_FPGA_PRG, 1);
187b5e7f1bcStrem 	gpio_set_value(ACFG_FPGA_RESET, 0);
188b5e7f1bcStrem 	imx_gpio_mode(ACFG_FPGA_RESET | GPIO_OUT | GPIO_PUEN | GPIO_GPIO);
189b5e7f1bcStrem 	return cookie;
190b5e7f1bcStrem }
191b5e7f1bcStrem 
apf27_fpga_setup(void)192b5e7f1bcStrem void apf27_fpga_setup(void)
193b5e7f1bcStrem {
194b5e7f1bcStrem 	struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE;
195b5e7f1bcStrem 	struct system_control_regs *system =
196b5e7f1bcStrem 		(struct system_control_regs *)IMX_SYSTEM_CTL_BASE;
197b5e7f1bcStrem 
198b5e7f1bcStrem 	/* Configure FPGA CLKO */
199b5e7f1bcStrem 	writel(ACFG_CCSR_VAL, &pll->ccsr);
200b5e7f1bcStrem 
201b5e7f1bcStrem 	/* Configure strentgh for FPGA */
202b5e7f1bcStrem 	writel(ACFG_DSCR10_VAL, &system->dscr10);
203b5e7f1bcStrem 	writel(ACFG_DSCR3_VAL, &system->dscr3);
204b5e7f1bcStrem 	writel(ACFG_DSCR7_VAL, &system->dscr7);
205b5e7f1bcStrem 	writel(ACFG_DSCR2_VAL, &system->dscr2);
206b5e7f1bcStrem }
207b5e7f1bcStrem 
208b5e7f1bcStrem /*
209b5e7f1bcStrem  * Initialize the fpga.  Return 1 on success, 0 on failure.
210b5e7f1bcStrem  */
APF27_init_fpga(void)211b5e7f1bcStrem void APF27_init_fpga(void)
212b5e7f1bcStrem {
213b5e7f1bcStrem 	int i;
214b5e7f1bcStrem 
215b5e7f1bcStrem 	apf27_fpga_setup();
216b5e7f1bcStrem 
217b5e7f1bcStrem 	fpga_init();
218b5e7f1bcStrem 
219b5e7f1bcStrem 	for (i = 0; i < CONFIG_FPGA_COUNT; i++) {
220b5e7f1bcStrem 		debug("%s:%d: Adding fpga %d\n", __func__, __LINE__, i);
221b5e7f1bcStrem 		fpga_add(fpga_xilinx, &fpga[i]);
222b5e7f1bcStrem 	}
223b5e7f1bcStrem 
224b5e7f1bcStrem 	return;
225b5e7f1bcStrem }
226