1 /*!***************************************************************************
2 *!
3 *! FILE NAME  : vertex.c
4 *!
5 *! DESCRIPTION: Implements an interface towards virtex FPGA (mounted on one of our
6 *!              evaluation boards) from userspace using ioctl()'s
7 *!
8 *!              The FPGA can be programmed by copying the bit-file to /dev/fpga.
9 *!
10 *!                cat fpga.bit > /dev/fpga
11 *!
12 *!                Kernel log should look like:
13 *!                  69900 bytes written
14 *!                  FPGA-configuration completed, no errors
15 *!
16 *!              Number of bytes written depends on the FPGA
17 *!
18 *!                From Xilinx data sheet:
19 *!                XCV50    559,200 bits
20 *!                XCV100   781,216 bits
21 *!                XCV800 4,715,616 bits
22 *!
23 *!              Accepted file type is the design.bit generated by Alliance
24 *!              Design Manager.
25 *!              This software just sends the bitfile into the device without
26 *!              checking device type etc.
27 *!
28 *!              Sync-header 0xff 0xff 0xff 0xff defines the start for the
29 *!              byte stream, everything from that position is written to the FPGA.
30 *!
31 *!
32 *! Jul 19 2002  Stefan Lundberg    Initial version.
33 *! $Log: virtex.c,v $
34 *! Revision 1.2  2003/02/24 07:50:30  fredriko
35 *! Bugfixes and cleanups.
36 *!
37 *! Revision 1.1  2002/06/25 09:58:58  stefanl
38 *! New FPGA driver for Platoon
39 *!
40 *!
41 *! ---------------------------------------------------------------------------
42 *!
43 *! (C) Copyright 2002 Axis Communications AB, LUND, SWEDEN
44 *!
45 *!***************************************************************************/
46 /* $Id: virtex.c,v 1.2 2003/02/24 07:50:30 fredriko Exp $ */
47 /****************** INCLUDE FILES SECTION ***********************************/
48 
49 #include <linux/module.h>
50 #include <linux/sched.h>
51 #include <linux/slab.h>
52 #include <linux/errno.h>
53 #include <linux/major.h>
54 #include <linux/kernel.h>
55 #include <linux/fs.h>
56 #include <linux/string.h>
57 #include <linux/init.h>
58 #include <linux/config.h>
59 
60 #include <linux/hdreg.h>
61 #include <linux/mm.h>
62 
63 #include <asm/etraxvirtex.h>
64 
65 #include <asm/system.h>
66 #include <asm/svinto.h>
67 #include <asm/uaccess.h>
68 #include <asm/io.h>
69 #include <asm/delay.h>
70 
71 #include "virtex.h"
72 
73 /******************* VIRTEX DEFINITION SECTION **************************/
74 
75 #define VIRTEX_DEBUG(x)
76 
77 #define VIRTEX_MAJOR 246  /* EXPERIMENTAL */
78 
79 static const char virtex_name[] = "virtex";
80 
81 /****************** FUNCTION DEFINITION SECTION *************************/
82 
83 
84 
85 //
86 // Read register interface for FPGA programming:
87 //
88 //   FPGA_DONE is connected to S1CD_N G28
89 //   FPGA_INIT_N is connected to S1IO_N G27
90 //
91 
92 // Write register interface for FPGA programming:
93 //
94 //  Bit:       15         14      13    12      9   8   7   0
95 //        ____________________________________________________
96 //       | fpga_write | program | cclk | reserved | cs | data |
97 //       |____________|_________|______|__________|____|______|
98 //
99 
100 
101 // csp0 = cs_fpga1 = FPGA programming interface
102 // csr0 = cs_fpga2 = register interface towards FPGA construction
103 
104 static volatile short *port_csp0_word_addr;
105 static volatile short *port_csr0_word_addr;
106 
107 static volatile unsigned char open_count;
108 static volatile unsigned char bytes_written;
109 static volatile unsigned long bytes_written_cnt;
110 static volatile unsigned char sync_found;
111 static volatile unsigned char sync_count;
112 static volatile unsigned char sync_ff_count;
113 
114 #define WRITE_FPGA_PROG_REG(data) *port_csp0_word_addr=(data)
115 #define SET_PROGRAM_BIT(data) (data)|(1<<14)
116 
117 #define SET_WRITE_BIT(data) (data)|(1<<15)
118 #define CLR_WRITE_BIT(data) (data)&(~(1<<15))
119 
120 #define SET_CS_BIT(data) (data)|(1<<8)
121 #define CLR_CS_BIT(data) (data)&(~(1<<8))
122 
123 #define SET_CCLK_BIT(data) (data)|(1<<13)
124 #define CLR_CCLK_BIT(data) (data)&(~(1<<13))
125 
126 // Bit in read port G (always inputs)
127 #define READ_INIT  (*R_PORT_G_DATA)&(1<<27)
128 #define READ_DONE  (*R_PORT_G_DATA)&(1<<28)
129 
130 
start_virtex_program(void)131 void start_virtex_program(void)
132 {
133   volatile unsigned int i=0;
134   unsigned short reg_data=0;
135 
136   printk("Start writing to FPGA\n");
137   reg_data = SET_CS_BIT(reg_data); // FPGA unselected, PROGRAM bit not set
138   WRITE_FPGA_PROG_REG(reg_data);
139 
140   for(i=0;i<10;i++) { } // at least 300 ns loop
141 
142   reg_data = SET_PROGRAM_BIT(reg_data);
143   WRITE_FPGA_PROG_REG(reg_data);
144 
145   for(i=0;i<10;i++) { } // at least 300 ns loop
146 
147   while(!READ_INIT); // Wait for init
148 
149   reg_data = SET_WRITE_BIT(reg_data);
150   WRITE_FPGA_PROG_REG(reg_data);
151 
152   reg_data = CLR_CS_BIT(reg_data); // FPGA selected, CS is active low
153   WRITE_FPGA_PROG_REG(reg_data);
154   return;
155 }
156 
157 // According to datasheet, bytes should be reversed, it is unknown to me why.
bit_reverse(unsigned char data)158 unsigned char bit_reverse(unsigned char data)
159 {
160   unsigned char in=data;
161   unsigned short out=0;
162   unsigned int i=0;
163 
164   for(i=0;i<8;i++) {
165     if(in&0x1) {
166       out|=0x1;
167     }
168     in=in>>1;
169     out=out<<1;
170   }
171 
172   return(out>>1);
173 
174 }
175 
virtex_program(char * ptr,size_t count)176 void virtex_program(char* ptr,size_t count)
177 {
178   int c;
179   char *p;
180   unsigned char data;
181   unsigned short reg_data=0;
182 //  short tmp_cnt;
183 
184   c=count;
185   p=ptr;
186 
187   if(!sync_found) {
188     c=count;
189     p=ptr;
190     while(c--) {
191       data=(unsigned char)*p++;
192       sync_count++;
193 
194       if(sync_count>=256) {
195         printk("Sync not found, aborting\n");
196         return;
197       }
198 
199       if(data==0xff) {
200         sync_ff_count++;
201       } else {
202         sync_ff_count=0;
203       }
204       if(sync_ff_count==4) {
205         sync_found=1;
206         VIRTEX_DEBUG(printk("Sync found at offset %d\n",sync_count));
207         p--;p--;p--;p--;
208         c++;c++;c++;c++;
209         break;
210       }
211     }
212   }
213 
214   if(sync_found) {
215     if(bytes_written==0) {
216       start_virtex_program();
217     }
218     bytes_written=1;
219 
220     reg_data = SET_PROGRAM_BIT(reg_data);
221     reg_data = SET_WRITE_BIT(reg_data);
222     reg_data = CLR_CS_BIT(reg_data);
223 
224 //    tmp_cnt=0;
225 
226     printk("*");
227     while(c--) {
228       data=(unsigned char)*p++;
229       data=bit_reverse(data);
230 
231 /* debug
232       tmp_cnt++;
233       if(tmp_cnt<=32 || c<=32 ) {
234         printk("0x%x ",data);
235       }
236       if(tmp_cnt==32 || c==0 ) {
237         printk("\n");
238       }
239 */
240       bytes_written_cnt++;
241       reg_data = CLR_CCLK_BIT(reg_data);
242       WRITE_FPGA_PROG_REG(reg_data|(data&0xff));
243       reg_data = SET_CCLK_BIT(reg_data);
244       WRITE_FPGA_PROG_REG(reg_data|(data&0xff));
245       reg_data = CLR_CCLK_BIT(reg_data);
246       WRITE_FPGA_PROG_REG(reg_data|(data&0xff));
247 
248     }
249   }
250 
251   return;
252 }
253 
stop_virtex_program(void)254 void stop_virtex_program(void)
255 {
256   unsigned short reg_data=0;
257 
258   reg_data = SET_PROGRAM_BIT(reg_data);
259   reg_data = SET_WRITE_BIT(reg_data);
260   reg_data = CLR_CCLK_BIT(reg_data);
261 
262   reg_data = SET_CS_BIT(reg_data); // release CS
263   WRITE_FPGA_PROG_REG(reg_data);
264 
265   reg_data = CLR_WRITE_BIT(reg_data); // release write, important to do!
266   WRITE_FPGA_PROG_REG(reg_data);
267   printk("%d bytes written\n",bytes_written_cnt);
268   if(READ_DONE) {
269     printk("FPGA-configuration completed, no errors\n");
270   } else {
271     printk("Error, FPGA-configuration failed\n");
272   }
273   return;
274 }
275 
276 static int
virtex_open(struct inode * inode,struct file * filp)277 virtex_open(struct inode *inode, struct file *filp)
278 {
279   port_csp0_word_addr = port_csp0_addr;
280   if(open_count>=1) {
281     printk("FPGA Device busy, aborting\n");
282     return(-EBUSY);
283   }
284   open_count++;
285   bytes_written=0;
286   sync_found=0;
287   sync_count=0;
288   sync_ff_count=0;
289   bytes_written_cnt=0;
290   return(0);
291 }
292 
293 static int
virtex_release(struct inode * inode,struct file * filp)294 virtex_release(struct inode *inode, struct file *filp)
295 {
296   open_count--;
297   if(bytes_written!=0)stop_virtex_program();
298   return 0;
299 }
300 
301 // FPGA programming interface
302 
virtex_write(struct file * file,const char * buf,size_t count,loff_t * ppos)303 static ssize_t virtex_write(struct file * file, const char * buf,
304                                  size_t count, loff_t *ppos)
305 {
306   char *ptr;
307   VIRTEX_DEBUG(printk("Write FPGA count %d\n", count));
308 
309   ptr=kmalloc(count, GFP_KERNEL);
310   if(!ptr) {
311     printk("FPGA device, kernel malloc failed (%d) bytes\n",count);
312     return -EFAULT;
313   }
314   if(copy_from_user(ptr, buf, count)) {
315     printk("copy_from_user failed\n");
316     kfree(ptr);
317     return -EFAULT;
318   }
319 
320   virtex_program(ptr,count);
321 
322   kfree(ptr);
323   return count;
324 }
325 
326 /* Main device API. ioctl's to write or read to/from registers.
327  */
328 
virtex_writereg(unsigned short theReg,unsigned short theValue)329 int virtex_writereg(unsigned short theReg, unsigned short theValue)
330 {
331   port_csr0_word_addr[theReg]=theValue;
332   return(0);
333 }
334 
virtex_readreg(unsigned short theReg)335 unsigned short virtex_readreg(unsigned short theReg)
336 {
337   return(port_csr0_word_addr[theReg]);
338 }
339 
340 
341 static int
virtex_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)342 virtex_ioctl(struct inode *inode, struct file *file,
343 	  unsigned int cmd, unsigned long arg)
344 {
345   if(_IOC_TYPE(cmd) != ETRAXVIRTEX_FPGA_IOCTYPE) {
346     return -EINVAL;
347   }
348 
349   switch (_IOC_NR(cmd)) {
350     case VIRTEX_FPGA_WRITEREG:
351       /* write to an FPGA register */
352       VIRTEX_DEBUG(printk("virtex wr 0x%x = 0x%x\n",
353                VIRTEX_FPGA_ARGREG(arg),
354                VIRTEX_FPGA_ARGVALUE(arg)));
355 
356       return virtex_writereg(VIRTEX_FPGA_ARGREG(arg),
357                              VIRTEX_FPGA_ARGVALUE(arg));
358     case VIRTEX_FPGA_READREG:
359     {
360       unsigned short val;
361       /* read from an FPGA register */
362       VIRTEX_DEBUG(printk("virtex rd 0x%x ",
363               VIRTEX_FPGA_ARGREG(arg)));
364       val = virtex_readreg(VIRTEX_FPGA_ARGREG(arg));
365       VIRTEX_DEBUG(printk("= 0x%x\n", val));
366       return val;
367     }
368     default:
369       return -EINVAL;
370     }
371 
372 return 0;
373 }
374 
375 static struct file_operations virtex_fops = {
376 	owner:    THIS_MODULE,
377 	ioctl:    virtex_ioctl,
378 	open:     virtex_open,
379         write:    virtex_write,
380 	release:  virtex_release,
381 };
382 
383 static int __init
virtex_init(void)384 virtex_init(void)
385 {
386   int res;
387 
388   /* register char device */
389   res = register_chrdev(VIRTEX_MAJOR, virtex_name, &virtex_fops);
390   if(res < 0) {
391           printk(KERN_ERR "virtex: couldn't get a major number.\n");
392           return res;
393   }
394 
395   port_csr0_word_addr = (volatile unsigned short *)
396                         ioremap((unsigned long)(MEM_CSR0_START |
397                                                 MEM_NON_CACHEABLE), 16);
398 
399 // see ~/platoon/rel2/platoon/os/linux/arch/cris/mm/init.c
400 //              port_csp0_addr = (volatile unsigned long *)
401 //                 ioremap((unsigned long)(MEM_CSP0_START |
402 //                                         MEM_NON_CACHEABLE), 16);
403 
404   open_count=0;
405 
406   printk("VIRTEX(TM) FPGA driver v1.0, (c) 2002 Axis Communications AB\n");
407 
408   return 0;
409 }
410 
411 /* this makes sure that virtex_init is called during boot */
412 
413 module_init(virtex_init);
414 
415 /****************** END OF FILE virtex.c ********************************/
416