3 * Matthias Fuchs, esd gmbh, matthias.fuchs@esd-electronics.com.
5 * SPDX-License-Identifier: GPL-2.0+
16 DECLARE_GLOBAL_DATA_PTR
;
18 #if defined(CONFIG_FPGA)
23 Xilinx_Spartan3_Slave_Parallel_fns pmc440_fpga_fns
= {
39 Xilinx_Spartan3_Slave_Serial_fns pmc440_fpga_fns
= {
50 Xilinx_Spartan2_Slave_Serial_fns ngcc_fpga_fns
= {
51 ngcc_fpga_pre_config_fn
,
57 ngcc_fpga_post_config_fn
60 Xilinx_desc fpga
[CONFIG_FPGA_COUNT
] = {
61 XILINX_XC3S1200E_DESC(
67 (void *)&pmc440_fpga_fns
,
71 (void *)&ngcc_fpga_fns
,
77 * Set the active-low FPGA reset signal.
79 void fpga_reset(int assert)
81 debug("%s:%d: RESET ", __FUNCTION__
, __LINE__
);
83 out_be32((void*)GPIO1_OR
, in_be32((void*)GPIO1_OR
) & ~GPIO1_FPGA_DATA
);
86 out_be32((void*)GPIO1_OR
, in_be32((void*)GPIO1_OR
) | GPIO1_FPGA_DATA
);
87 debug("deasserted\n");
93 * Initialize the SelectMap interface. We assume that the mode and the
94 * initial state of all of the port pins have already been set!
96 void fpga_serialslave_init(void)
98 debug("%s:%d: Initialize serial slave interface\n", __FUNCTION__
,
100 fpga_pgm_fn(false, false, 0); /* make sure program pin is inactive */
105 * Set the FPGA's active-low SelectMap program line to the specified level
107 int fpga_pgm_fn(int assert, int flush
, int cookie
)
109 debug("%s:%d: FPGA PROGRAM ",
110 __FUNCTION__
, __LINE__
);
113 out_be32((void*)GPIO1_OR
, in_be32((void*)GPIO1_OR
) & ~GPIO1_FPGA_PRG
);
116 out_be32((void*)GPIO1_OR
, in_be32((void*)GPIO1_OR
) | GPIO1_FPGA_PRG
);
117 debug("deasserted\n");
124 * Test the state of the active-low FPGA INIT line. Return 1 on INIT
127 int fpga_init_fn(int cookie
)
129 if (in_be32((void*)GPIO1_IR
) & GPIO1_FPGA_INIT
)
136 int fpga_abort_fn(int cookie
)
142 int fpga_cs_fn(int assert_cs
, int flush
, int cookie
)
148 int fpga_busy_fn(int cookie
)
156 * Test the state of the active-high FPGA DONE pin
158 int fpga_done_fn(int cookie
)
160 if (in_be32((void*)GPIO1_IR
) & GPIO1_FPGA_DONE
)
168 * FPGA pre-configuration function. Just make sure that
169 * FPGA reset is asserted to keep the FPGA from starting up after
172 int fpga_pre_config_fn(int cookie
)
174 debug("%s:%d: FPGA pre-configuration\n", __FUNCTION__
, __LINE__
);
178 out_be32((void*)GPIO0_OR
, in_be32((void*)GPIO0_OR
) | GPIO0_FPGA_FORCEINIT
);
179 /* disable PLD IOs */
180 out_be32((void*)GPIO1_OR
, in_be32((void*)GPIO1_OR
) | GPIO1_IOEN_N
);
186 * FPGA post configuration function. Blip the FPGA reset line and then see if
187 * the FPGA appears to be running.
189 int fpga_post_config_fn(int cookie
)
191 pmc440_fpga_t
*fpga
= (pmc440_fpga_t
*)FPGA_BA
;
195 debug("%s:%d: FPGA post configuration\n", __FUNCTION__
, __LINE__
);
197 /* enable PLD0..7 pins */
198 out_be32((void*)GPIO1_OR
, in_be32((void*)GPIO1_OR
) & ~GPIO1_IOEN_N
);
205 FPGA_OUT32(&fpga
->status
, (gd
->board_type
<< STATUS_HWREV_SHIFT
) & STATUS_HWREV_MASK
);
207 /* NGCC/CANDES only: enable ledlink */
208 if ((s
= getenv("bd_type")) &&
209 ((!strcmp(s
, "ngcc")) || (!strcmp(s
, "candes"))))
210 FPGA_SETBITS(&fpga
->ctrla
, 0x29f8c000);
216 int fpga_clk_fn(int assert_clk
, int flush
, int cookie
)
219 out_be32((void*)GPIO1_OR
, in_be32((void*)GPIO1_OR
) | GPIO1_FPGA_CLK
);
221 out_be32((void*)GPIO1_OR
, in_be32((void*)GPIO1_OR
) & ~GPIO1_FPGA_CLK
);
227 int fpga_wr_fn(int assert_write
, int flush
, int cookie
)
230 out_be32((void*)GPIO1_OR
, in_be32((void*)GPIO1_OR
) | GPIO1_FPGA_DATA
);
232 out_be32((void*)GPIO1_OR
, in_be32((void*)GPIO1_OR
) & ~GPIO1_FPGA_DATA
);
238 int fpga_wdata_fn(uchar data
, int flush
, int cookie
)
241 ulong
or = in_be32((void*)GPIO1_OR
);
246 or = (or & ~GPIO1_FPGA_CLK
) | GPIO1_FPGA_DATA
;
248 or = or & ~(GPIO1_FPGA_CLK
| GPIO1_FPGA_DATA
);
250 out_be32((void*)GPIO1_OR
, or);
252 /* Assert the clock */
253 or |= GPIO1_FPGA_CLK
;
254 out_be32((void*)GPIO1_OR
, or);
259 /* Write last data bit (the 8th clock comes from the sp_load() code */
261 or = (or & ~GPIO1_FPGA_CLK
) | GPIO1_FPGA_DATA
;
263 or = or & ~(GPIO1_FPGA_CLK
| GPIO1_FPGA_DATA
);
265 out_be32((void*)GPIO1_OR
, or);
271 #define NGCC_FPGA_PRG CLOCK_EN
272 #define NGCC_FPGA_DATA RESET_OUT
273 #define NGCC_FPGA_DONE CLOCK_IN
274 #define NGCC_FPGA_INIT IRIGB_R_IN
275 #define NGCC_FPGA_CLK CLOCK_OUT
277 void ngcc_fpga_serialslave_init(void)
279 debug("%s:%d: Initialize serial slave interface\n",
280 __FUNCTION__
, __LINE__
);
282 /* make sure program pin is inactive */
283 ngcc_fpga_pgm_fn(false, false, 0);
287 * Set the active-low FPGA reset signal.
289 void ngcc_fpga_reset(int assert)
291 debug("%s:%d: RESET ", __FUNCTION__
, __LINE__
);
294 FPGA_CLRBITS(NGCC_CTRL_BASE
, NGCC_CTRL_FPGARST_N
);
297 FPGA_SETBITS(NGCC_CTRL_BASE
, NGCC_CTRL_FPGARST_N
);
298 debug("deasserted\n");
304 * Set the FPGA's active-low SelectMap program line to the specified level
306 int ngcc_fpga_pgm_fn(int assert, int flush
, int cookie
)
308 pmc440_fpga_t
*fpga
= (pmc440_fpga_t
*)FPGA_BA
;
310 debug("%s:%d: FPGA PROGRAM ", __FUNCTION__
, __LINE__
);
313 FPGA_CLRBITS(&fpga
->ctrla
, NGCC_FPGA_PRG
);
316 FPGA_SETBITS(&fpga
->ctrla
, NGCC_FPGA_PRG
);
317 debug("deasserted\n");
325 * Test the state of the active-low FPGA INIT line. Return 1 on INIT
328 int ngcc_fpga_init_fn(int cookie
)
330 pmc440_fpga_t
*fpga
= (pmc440_fpga_t
*)FPGA_BA
;
332 debug("%s:%d: INIT check... ", __FUNCTION__
, __LINE__
);
333 if (FPGA_IN32(&fpga
->status
) & NGCC_FPGA_INIT
) {
344 * Test the state of the active-high FPGA DONE pin
346 int ngcc_fpga_done_fn(int cookie
)
348 pmc440_fpga_t
*fpga
= (pmc440_fpga_t
*)FPGA_BA
;
350 debug("%s:%d: DONE check... ", __FUNCTION__
, __LINE__
);
351 if (FPGA_IN32(&fpga
->status
) & NGCC_FPGA_DONE
) {
352 debug("DONE high\n");
362 * FPGA pre-configuration function.
364 int ngcc_fpga_pre_config_fn(int cookie
)
366 pmc440_fpga_t
*fpga
= (pmc440_fpga_t
*)FPGA_BA
;
367 debug("%s:%d: FPGA pre-configuration\n", __FUNCTION__
, __LINE__
);
369 ngcc_fpga_reset(true);
370 FPGA_CLRBITS(&fpga
->ctrla
, 0xfffffe00);
372 ngcc_fpga_reset(true);
378 * FPGA post configuration function. Blip the FPGA reset line and then see if
379 * the FPGA appears to be running.
381 int ngcc_fpga_post_config_fn(int cookie
)
383 pmc440_fpga_t
*fpga
= (pmc440_fpga_t
*)FPGA_BA
;
385 debug("%s:%d: NGCC FPGA post configuration\n", __FUNCTION__
, __LINE__
);
388 ngcc_fpga_reset(false);
390 FPGA_SETBITS(&fpga
->ctrla
, 0x29f8c000);
396 int ngcc_fpga_clk_fn(int assert_clk
, int flush
, int cookie
)
398 pmc440_fpga_t
*fpga
= (pmc440_fpga_t
*)FPGA_BA
;
401 FPGA_SETBITS(&fpga
->ctrla
, NGCC_FPGA_CLK
);
403 FPGA_CLRBITS(&fpga
->ctrla
, NGCC_FPGA_CLK
);
409 int ngcc_fpga_wr_fn(int assert_write
, int flush
, int cookie
)
411 pmc440_fpga_t
*fpga
= (pmc440_fpga_t
*)FPGA_BA
;
414 FPGA_SETBITS(&fpga
->ctrla
, NGCC_FPGA_DATA
);
416 FPGA_CLRBITS(&fpga
->ctrla
, NGCC_FPGA_DATA
);
423 * Initialize the fpga. Return 1 on success, 0 on failure.
425 int pmc440_init_fpga(void)
429 debug("%s:%d: Initialize FPGA interface\n",
430 __FUNCTION__
, __LINE__
);
433 fpga_serialslave_init ();
434 debug("%s:%d: Adding fpga 0\n", __FUNCTION__
, __LINE__
);
435 fpga_add (fpga_xilinx
, &fpga
[0]);
438 if ((s
= getenv("bd_type")) && !strcmp(s
, "ngcc")) {
439 ngcc_fpga_serialslave_init ();
440 debug("%s:%d: Adding fpga 1\n", __FUNCTION__
, __LINE__
);
441 fpga_add (fpga_xilinx
, &fpga
[1]);
446 #endif /* CONFIG_FPGA */