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