Home | History | Annotate | Download | only in fpga
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2003
      4  * Steven Scholz, imc Measurement & Control, steven.scholz (at) imc-berlin.de
      5  *
      6  * (C) Copyright 2002
      7  * Rich Ireland, Enterasys Networks, rireland (at) enterasys.com.
      8  */
      9 
     10 /*
     11  *  Altera FPGA support
     12  */
     13 #include <common.h>
     14 #include <errno.h>
     15 #include <ACEX1K.h>
     16 #include <stratixII.h>
     17 
     18 /* Define FPGA_DEBUG to 1 to get debug printf's */
     19 #define FPGA_DEBUG	0
     20 
     21 static const struct altera_fpga {
     22 	enum altera_family	family;
     23 	const char		*name;
     24 	int			(*load)(Altera_desc *, const void *, size_t);
     25 	int			(*dump)(Altera_desc *, const void *, size_t);
     26 	int			(*info)(Altera_desc *);
     27 } altera_fpga[] = {
     28 #if defined(CONFIG_FPGA_ACEX1K)
     29 	{ Altera_ACEX1K, "ACEX1K", ACEX1K_load, ACEX1K_dump, ACEX1K_info },
     30 	{ Altera_CYC2,   "ACEX1K", ACEX1K_load, ACEX1K_dump, ACEX1K_info },
     31 #elif defined(CONFIG_FPGA_CYCLON2)
     32 	{ Altera_ACEX1K, "CycloneII", CYC2_load, CYC2_dump, CYC2_info },
     33 	{ Altera_CYC2,   "CycloneII", CYC2_load, CYC2_dump, CYC2_info },
     34 #endif
     35 #if defined(CONFIG_FPGA_STRATIX_II)
     36 	{ Altera_StratixII, "StratixII", StratixII_load,
     37 	  StratixII_dump, StratixII_info },
     38 #endif
     39 #if defined(CONFIG_FPGA_STRATIX_V)
     40 	{ Altera_StratixV, "StratixV", stratixv_load, NULL, NULL },
     41 #endif
     42 #if defined(CONFIG_FPGA_SOCFPGA)
     43 	{ Altera_SoCFPGA, "SoC FPGA", socfpga_load, NULL, NULL },
     44 #endif
     45 };
     46 
     47 static int altera_validate(Altera_desc *desc, const char *fn)
     48 {
     49 	if (!desc) {
     50 		printf("%s: NULL descriptor!\n", fn);
     51 		return -EINVAL;
     52 	}
     53 
     54 	if ((desc->family < min_altera_type) ||
     55 	    (desc->family > max_altera_type)) {
     56 		printf("%s: Invalid family type, %d\n", fn, desc->family);
     57 		return -EINVAL;
     58 	}
     59 
     60 	if ((desc->iface < min_altera_iface_type) ||
     61 	    (desc->iface > max_altera_iface_type)) {
     62 		printf("%s: Invalid Interface type, %d\n", fn, desc->iface);
     63 		return -EINVAL;
     64 	}
     65 
     66 	if (!desc->size) {
     67 		printf("%s: NULL part size\n", fn);
     68 		return -EINVAL;
     69 	}
     70 
     71 	return 0;
     72 }
     73 
     74 static const struct altera_fpga *
     75 altera_desc_to_fpga(Altera_desc *desc, const char *fn)
     76 {
     77 	int i;
     78 
     79 	if (altera_validate(desc, fn)) {
     80 		printf("%s: Invalid device descriptor\n", fn);
     81 		return NULL;
     82 	}
     83 
     84 	for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) {
     85 		if (desc->family == altera_fpga[i].family)
     86 			break;
     87 	}
     88 
     89 	if (i == ARRAY_SIZE(altera_fpga)) {
     90 		printf("%s: Unsupported family type, %d\n", fn, desc->family);
     91 		return NULL;
     92 	}
     93 
     94 	return &altera_fpga[i];
     95 }
     96 
     97 int altera_load(Altera_desc *desc, const void *buf, size_t bsize)
     98 {
     99 	const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__);
    100 
    101 	if (!fpga)
    102 		return FPGA_FAIL;
    103 
    104 	debug_cond(FPGA_DEBUG, "%s: Launching the %s Loader...\n",
    105 		   __func__, fpga->name);
    106 	if (fpga->load)
    107 		return fpga->load(desc, buf, bsize);
    108 	return 0;
    109 }
    110 
    111 int altera_dump(Altera_desc *desc, const void *buf, size_t bsize)
    112 {
    113 	const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__);
    114 
    115 	if (!fpga)
    116 		return FPGA_FAIL;
    117 
    118 	debug_cond(FPGA_DEBUG, "%s: Launching the %s Reader...\n",
    119 		   __func__, fpga->name);
    120 	if (fpga->dump)
    121 		return fpga->dump(desc, buf, bsize);
    122 	return 0;
    123 }
    124 
    125 int altera_info(Altera_desc *desc)
    126 {
    127 	const struct altera_fpga *fpga = altera_desc_to_fpga(desc, __func__);
    128 
    129 	if (!fpga)
    130 		return FPGA_FAIL;
    131 
    132 	printf("Family:        \t%s\n", fpga->name);
    133 
    134 	printf("Interface type:\t");
    135 	switch (desc->iface) {
    136 	case passive_serial:
    137 		printf("Passive Serial (PS)\n");
    138 		break;
    139 	case passive_parallel_synchronous:
    140 		printf("Passive Parallel Synchronous (PPS)\n");
    141 		break;
    142 	case passive_parallel_asynchronous:
    143 		printf("Passive Parallel Asynchronous (PPA)\n");
    144 		break;
    145 	case passive_serial_asynchronous:
    146 		printf("Passive Serial Asynchronous (PSA)\n");
    147 		break;
    148 	case altera_jtag_mode:		/* Not used */
    149 		printf("JTAG Mode\n");
    150 		break;
    151 	case fast_passive_parallel:
    152 		printf("Fast Passive Parallel (FPP)\n");
    153 		break;
    154 	case fast_passive_parallel_security:
    155 		printf("Fast Passive Parallel with Security (FPPS)\n");
    156 		break;
    157 		/* Add new interface types here */
    158 	default:
    159 		printf("Unsupported interface type, %d\n", desc->iface);
    160 	}
    161 
    162 	printf("Device Size:   \t%zd bytes\n"
    163 	       "Cookie:        \t0x%x (%d)\n",
    164 	       desc->size, desc->cookie, desc->cookie);
    165 
    166 	if (desc->iface_fns) {
    167 		printf("Device Function Table @ 0x%p\n", desc->iface_fns);
    168 		if (fpga->info)
    169 			fpga->info(desc);
    170 	} else {
    171 		printf("No Device Function Table.\n");
    172 	}
    173 
    174 	return FPGA_SUCCESS;
    175 }
    176