| /* | |
| * (C) Copyright 2007 | |
| * Eran Liberty, Extricom , eran.liberty@gmail.com | |
| * | |
| * SPDX-License-Identifier: GPL-2.0+ | |
| */ | |
| #include <common.h> /* core U-Boot definitions */ | |
| #include <altera.h> | |
| int StratixII_ps_fpp_load (Altera_desc * desc, void *buf, size_t bsize, | |
| int isSerial, int isSecure); | |
| int StratixII_ps_fpp_dump (Altera_desc * desc, void *buf, size_t bsize); | |
| /****************************************************************/ | |
| /* Stratix II Generic Implementation */ | |
| int StratixII_load (Altera_desc * desc, void *buf, size_t bsize) | |
| { | |
| int ret_val = FPGA_FAIL; | |
| switch (desc->iface) { | |
| case passive_serial: | |
| ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 1, 0); | |
| break; | |
| case fast_passive_parallel: | |
| ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 0, 0); | |
| break; | |
| case fast_passive_parallel_security: | |
| ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 0, 1); | |
| break; | |
| /* Add new interface types here */ | |
| default: | |
| printf ("%s: Unsupported interface type, %d\n", __FUNCTION__, | |
| desc->iface); | |
| } | |
| return ret_val; | |
| } | |
| int StratixII_dump (Altera_desc * desc, void *buf, size_t bsize) | |
| { | |
| int ret_val = FPGA_FAIL; | |
| switch (desc->iface) { | |
| case passive_serial: | |
| case fast_passive_parallel: | |
| case fast_passive_parallel_security: | |
| ret_val = StratixII_ps_fpp_dump (desc, buf, bsize); | |
| break; | |
| /* Add new interface types here */ | |
| default: | |
| printf ("%s: Unsupported interface type, %d\n", __FUNCTION__, | |
| desc->iface); | |
| } | |
| return ret_val; | |
| } | |
| int StratixII_info (Altera_desc * desc) | |
| { | |
| return FPGA_SUCCESS; | |
| } | |
| int StratixII_ps_fpp_dump (Altera_desc * desc, void *buf, size_t bsize) | |
| { | |
| printf ("Stratix II Fast Passive Parallel dump is not implemented\n"); | |
| return FPGA_FAIL; | |
| } | |
| int StratixII_ps_fpp_load (Altera_desc * desc, void *buf, size_t bsize, | |
| int isSerial, int isSecure) | |
| { | |
| altera_board_specific_func *fns; | |
| int cookie; | |
| int ret_val = FPGA_FAIL; | |
| int bytecount; | |
| char *buff = buf; | |
| int i; | |
| if (!desc) { | |
| printf ("%s(%d) Altera_desc missing\n", __FUNCTION__, __LINE__); | |
| return FPGA_FAIL; | |
| } | |
| if (!buff) { | |
| printf ("%s(%d) buffer is missing\n", __FUNCTION__, __LINE__); | |
| return FPGA_FAIL; | |
| } | |
| if (!bsize) { | |
| printf ("%s(%d) size is zero\n", __FUNCTION__, __LINE__); | |
| return FPGA_FAIL; | |
| } | |
| if (!desc->iface_fns) { | |
| printf | |
| ("%s(%d) Altera_desc function interface table is missing\n", | |
| __FUNCTION__, __LINE__); | |
| return FPGA_FAIL; | |
| } | |
| fns = (altera_board_specific_func *) (desc->iface_fns); | |
| cookie = desc->cookie; | |
| if (! | |
| (fns->config && fns->status && fns->done && fns->data | |
| && fns->abort)) { | |
| printf | |
| ("%s(%d) Missing some function in the function interface table\n", | |
| __FUNCTION__, __LINE__); | |
| return FPGA_FAIL; | |
| } | |
| /* 1. give board specific a chance to do anything before we start */ | |
| if (fns->pre) { | |
| if ((ret_val = fns->pre (cookie)) < 0) { | |
| return ret_val; | |
| } | |
| } | |
| /* from this point on we must fail gracfully by calling lower layer abort */ | |
| /* 2. Strat burn cycle by deasserting config for t_CFG and waiting t_CF2CK after reaserted */ | |
| fns->config (0, 1, cookie); | |
| udelay (5); /* nCONFIG low pulse width 2usec */ | |
| fns->config (1, 1, cookie); | |
| udelay (100); /* nCONFIG high to first rising edge on DCLK */ | |
| /* 3. Start the Data cycle with clk deasserted */ | |
| bytecount = 0; | |
| fns->clk (0, 1, cookie); | |
| printf ("loading to fpga "); | |
| while (bytecount < bsize) { | |
| /* 3.1 check stratix has not signaled us an error */ | |
| if (fns->status (cookie) != 1) { | |
| printf | |
| ("\n%s(%d) Stratix failed (byte transferred till failure 0x%x)\n", | |
| __FUNCTION__, __LINE__, bytecount); | |
| fns->abort (cookie); | |
| return FPGA_FAIL; | |
| } | |
| if (isSerial) { | |
| int i; | |
| uint8_t data = buff[bytecount++]; | |
| for (i = 0; i < 8; i++) { | |
| /* 3.2(ps) put data on the bus */ | |
| fns->data ((data >> i) & 1, 1, cookie); | |
| /* 3.3(ps) clock once */ | |
| fns->clk (1, 1, cookie); | |
| fns->clk (0, 1, cookie); | |
| } | |
| } else { | |
| /* 3.2(fpp) put data on the bus */ | |
| fns->data (buff[bytecount++], 1, cookie); | |
| /* 3.3(fpp) clock once */ | |
| fns->clk (1, 1, cookie); | |
| fns->clk (0, 1, cookie); | |
| /* 3.4(fpp) for secure cycle push 3 more clocks */ | |
| for (i = 0; isSecure && i < 3; i++) { | |
| fns->clk (1, 1, cookie); | |
| fns->clk (0, 1, cookie); | |
| } | |
| } | |
| /* 3.5 while clk is deasserted it is safe to print some progress indication */ | |
| if ((bytecount % (bsize / 100)) == 0) { | |
| printf ("\b\b\b%02d\%", bytecount * 100 / bsize); | |
| } | |
| } | |
| /* 4. Set one last clock and check conf done signal */ | |
| fns->clk (1, 1, cookie); | |
| udelay (100); | |
| if (!fns->done (cookie)) { | |
| printf (" error!.\n"); | |
| fns->abort (cookie); | |
| return FPGA_FAIL; | |
| } else { | |
| printf ("\b\b\b done.\n"); | |
| } | |
| /* 5. call lower layer post configuration */ | |
| if (fns->post) { | |
| if ((ret_val = fns->post (cookie)) < 0) { | |
| fns->abort (cookie); | |
| return ret_val; | |
| } | |
| } | |
| return FPGA_SUCCESS; | |
| } |