File: /usr/src/linux/drivers/isdn/eicon/fpga.c

1     
2     /*
3      *
4      * Copyright (C) Eicon Technology Corporation, 2000.
5      *
6      * Eicon File Revision :    1.2  
7      *
8      * This program is free software; you can redistribute it and/or modify
9      * it under the terms of the GNU General Public License as published by
10      * the Free Software Foundation; either version 2, or (at your option)
11      * any later version.
12      *
13      * This program is distributed in the hope that it will be useful,
14      * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
15      * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
16      * See the GNU General Public License for more details.
17      *
18      * You should have received a copy of the GNU General Public License
19      * along with this program; if not, write to the Free Software
20      * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21      *
22      */
23     
24     
25     #include "sys.h"
26     #include "idi.h"
27     #include "uxio.h"
28     
29     #define FPGA_PORT		0x6E
30     #define FPGA_DLOAD_BUFLEN   	256
31     #define NAME_OFFSET         	0x10
32     #define NAME_MAXLEN         	12
33     #define DATE_OFFSET         	0x2c
34     #define DATE_MAXLEN         	10
35     
36     word UxCardPortIoInW(ux_diva_card_t *card, byte *base, int offset);
37     void UxCardPortIoOutW(ux_diva_card_t *card, byte *base, int offset, word);
38     void UxPause(long int);
39     
40     /*-------------------------------------------------------------------------*/
41     /* Loads the FPGA configuration file onto the hardware.                    */
42     /* Function returns 0 on success, else an error number.                    */
43     /* On success, an identifier string is returned in the buffer              */
44     /*                                                                         */
45     /* A buffer of FPGA_BUFSIZE, a handle to the already opened bitstream      */
46     /* file and a file read function has to be provided by the operating       */
47     /* system part.                                                            */
48     /* ----------------------------------------------------------------------- */
49     int FPGA_Download( word      cardtype,
50                             dword     RegBase,
51                             byte *strbuf,
52                             byte FPGA_SRC[],
53     			int FPGA_LEN
54                           )
55     {
56       word        i, j, k;
57       word        baseval, Mask_PROGRAM, Mask_DONE, Mask_CCLK, Mask_DIN;
58       dword       addr;
59       byte        *pFPGA;
60     
61       //--- check for legal cardtype
62       switch (cardtype)
63       {
64         case IDI_ADAPTER_MAESTRAQ:
65           addr          = RegBase ; // address where to access FPGA
66           Mask_PROGRAM  = 0x0001;         // FPGA pins at address
67           Mask_DONE     = 0x0002;
68           Mask_CCLK     = 0x0100;
69           Mask_DIN      = 0x0400;
70           baseval       = 0x000d;         // PROGRAM hi, CCLK lo, DIN lo by default
71         break;
72           
73         default:
74     	
75       	DPRINTF(("divas: FPGA Download ,Illegal Card"));
76           	return -1; // illegal card 
77       }
78     
79       //--- generate id string from file content
80       for (j=NAME_OFFSET, k=0; j<(NAME_OFFSET+NAME_MAXLEN); j++, k++) //name
81       {
82         if (!FPGA_SRC[j]) break;
83         strbuf[k] = FPGA_SRC[j];
84       } 
85       strbuf[k++] = ' ';
86       for (j=DATE_OFFSET; j<(DATE_OFFSET+DATE_MAXLEN); j++, k++) // date
87       {
88         if (!FPGA_SRC[j]) break;
89         strbuf[k] = FPGA_SRC[j];
90       } 
91       strbuf[k] = 0;
92     
93       DPRINTF(("divas: FPGA Download - %s", strbuf));
94     
95       //--- prepare download, Pulse PROGRAM pin down.
96       UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval &~Mask_PROGRAM);  // PROGRAM low pulse
97       UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval);                 // release
98       UxPause(50);  // wait until FPGA finised internal memory clear
99       
100       //--- check done pin, must be low
101       if (UxCardPortIoInW(NULL, (byte *) addr, FPGA_PORT) &Mask_DONE) 
102       {
103         DPRINTF(("divas: FPGA_ERR_DONE_WRONG_LEVEL"));
104         return -1;
105       }
106     
107       pFPGA = FPGA_SRC;
108     
109       i = 0; 
110       /* Move past the header */
111       while ((FPGA_SRC[i] != 0xFF) && (i < FPGA_LEN)) 
112       {
113         i++;
114       }
115     
116       // We've hit the 0xFF so move on to the next byte
117       // i++;
118       DPRINTF(("divas: FPGA Code starts at offset %d", i));
119     
120       //--- put data onto the FPGA
121       for (;i<FPGA_LEN; i++)
122       {
123         //--- put byte onto FPGA
124         for (j=0; j<8; j++)
125         {
126           if (FPGA_SRC[i] &(0x80>>j)) baseval |= Mask_DIN; // write a hi
127           else                      baseval &=~Mask_DIN; // write a lo
128           UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval);
129           UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval | Mask_CCLK);     // set CCLK hi
130           UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval);                 // set CCLK lo
131         }
132       }
133     
134       //--- add some additional startup clock cycles and check done pin
135       for (i=0; i<5; i++) 
136       {
137         UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval | Mask_CCLK);     // set CCLK hi
138         UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval);                 // set CCLK lo
139       }
140     
141       UxPause(100);
142     
143       if (UxCardPortIoInW(NULL, (byte *) addr, FPGA_PORT) &Mask_DONE) 
144       {
145         DPRINTF(("divas: FPGA download successful"));
146       }
147       else
148       {
149         DPRINTF(("divas: FPGA download failed - 0x%x", UxCardPortIoInW(NULL, (byte *) addr, FPGA_PORT)));
150     	return -1;
151       }
152     
153     return 0;
154     }
155     
156