00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <linux/module.h>
00040 #include <linux/sched.h>
00041 #include <linux/slab.h>
00042 #include <linux/errno.h>
00043 #include <linux/kernel.h>
00044 #include <linux/fs.h>
00045 #include <linux/string.h>
00046 #include <linux/init.h>
00047 #include <linux/autoconf.h>
00048
00049 #include <asm/system.h>
00050
00051 #include <asm/io.h>
00052
00053 #include <asm/irq.h>
00054
00055 #include <asm/delay.h>
00056 #include <asm/uaccess.h>
00057 #include <asm/elphel/fpgactrl.h>
00058
00059 #include "fpgactrl.h"
00060 #include "fpga_sdram.h"
00061 #include "x3x3.h"
00062
00063 #define D(x)
00064 #define DEBUG_MODE1
00065 static int sdbuf[128];
00066 static char * sdbytebuf= (char *) sdbuf;
00067
00068
00069 void fpga_initSDRAM(void) {
00070 #if 0 // forced init - checks outside
00071
00072 if (X313_IS_SDRAM_ON) {
00073 D(printk ("SDRAM already initialized\n"));
00074 return;
00075 }
00076 #endif
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 X313_SDRAM_OFF;
00095
00096 udelay (100);
00097 port_csp0_addr[X313_WA_SD_MANCMD] = 0x17fff;
00098 udelay (1);
00099
00100 port_csp0_addr[X313_WA_SD_MANCMD] = 0x02002;
00101 udelay (1);
00102 port_csp0_addr[X313_WA_SD_MANCMD] = 0x00163;
00103 udelay (1);
00104 port_csp0_addr[X313_WA_SD_MANCMD] = 0x8000;
00105 udelay (1);
00106 port_csp0_addr[X313_WA_SD_MANCMD] = 0x8000;
00107 udelay (1);
00108 port_csp0_addr[X313_WA_SD_MANCMD] = 0x00063;
00109 udelay (1);
00110 X313_SDRAM_ON;
00111 D(printk("fpga_initSDRAM\n"));
00112 }
00113
00114
00115 int fsdram_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) {
00116 return 0;
00117 }
00118
00119 ssize_t fsdram_read(struct file * file, char * buf, size_t count, loff_t *off) {
00120 unsigned long p,sa,left,i,j,nb,ibp;
00121 char * bp=buf;
00122
00123 D(printk("fsdram_read from 0x%x\n", (int) *off));
00124 if (!X313_IS_SDRAM_ON) return -EFAULT;
00125
00126 p = *off;
00127 if (p >= X313_SDRAM_SIZE) return -EINVAL;
00128 if( (p + count) > X313_SDRAM_SIZE) {
00129 count = X313_SDRAM_SIZE - p;
00130 }
00131 left=count;
00132 if (left==0) return 0;
00133
00134 sa=(p>>1) & 0x01ffff00;
00135
00136 #ifdef DEBUG_MODE1
00137 if (port_csp0_addr[0x2b] & 1){ X313_INIT_SDCHAN( 3, 1, 0, 0, sa , 0x3ff, 0xfff); }
00138 else { X313_INIT_SDCHAN( 3, 0, 0, 0, sa , 0x3ff, 0xfff); }
00139 #else
00140 X313_INIT_SDCHAN( 3, 0, 0, 0, sa , 0x3ff, 0xfff);
00141 #endif
00142
00143 X313_CHN_EN(3);
00144 while (left >0) {
00145
00146 j=10000;
00147 while (((j--)>0) && !X313_SR(PIORDY));
00148 if (j==0) return -EFAULT;
00149
00150 i=port_csp4_addr[X313_WA_SD_PIOWIN];
00151 for (i=0;i<128;i++) sdbuf[i]=port_csp4_addr[X313_WA_SD_PIOWIN];
00152 port_csp0_addr[X313_WA_SDPIO_NEXT]=0;
00153
00154 ibp=p-(sa<<1);
00155 nb=left;
00156 if ((ibp+nb)>512) nb=512-ibp;
00157
00158 if (copy_to_user(bp, &sdbytebuf[ibp], nb)) return -EFAULT;
00159 left -=nb;
00160 bp+=nb;
00161 p+=nb;
00162 sa+=256;
00163 }
00164
00165 *off+=count;
00166 D(printk("count= 0x%x, pos= 0x%x\n", (int) count, (int)*off));
00167 return count;
00168 }
00169 int read_page_to_buffer(unsigned long sa) {
00170 unsigned long i;
00171 X313_INIT_SDCHAN( 3, 0, 0, 0, sa , 0x3ff, 0xfff);
00172
00173 X313_CHN_EN(3);
00174
00175 i=10000;
00176 while (((i--)>0) && !X313_SR(PIORDY));
00177 D(printk("ready, i=%d\n",(int) i));
00178 if (i==0) return -EFAULT;
00179
00180 X313_CHN_DIS(3);
00181 i=port_csp4_addr[X313_WA_SD_PIOWIN];
00182 for (i=0;i<128;i++){
00183 sdbuf[i]=port_csp4_addr[X313_WA_SD_PIOWIN];
00184 }
00185 return 0;
00186 }
00187
00188 ssize_t fsdram_write(struct file * file, const char * buf, size_t count, loff_t *off) {
00189
00190 unsigned long p,sa,left,i,nb,ibp;
00191 const char * bp=buf;
00192 int fp=1;
00193 D(printk("fsdram_write to 0x%x\n", (int) *off));
00194 if (!X313_IS_SDRAM_ON) return -EFAULT;
00195
00196 p = *off;
00197 if (p >= X313_SDRAM_SIZE) return -EINVAL;
00198 if( (p + count) > X313_SDRAM_SIZE) {
00199 count = X313_SDRAM_SIZE - p;
00200 }
00201 left=count;
00202 if (left==0) return 0;
00203
00204 D(printk ("p=%x, left=%x\n", (int) p, (int) left));
00205 if ((p & 0x1ff) || (left<0x200)) {
00206 sa=(p>>1) & 0x01ffff00;
00207 if (read_page_to_buffer(sa)<0) return -EFAULT;
00208 }
00209
00210 while (left >0) {
00211
00212 sa=(p>>1) & 0x01ffff00;
00213
00214 if (!fp) {
00215 i=1000;
00216 while (((i--)>0) && !X313_SR(PIOWEMPTY)) udelay(1);
00217 if (i==0) return -EFAULT;
00218
00219 if ((left<0x200) && (read_page_to_buffer(sa)<0)) return -EFAULT;
00220 }
00221
00222 X313_INIT_SDCHAN( 3, 0, 1, 0, sa , 0x3ff, 0xfff);
00223
00224 X313_CHN_EN(3);
00225 while ((left>0) && ((left>=512) || fp)) {
00226
00227 ibp=p-(sa<<1);
00228 nb=left;
00229 if ((ibp+nb)>512) nb=512-ibp;
00230 if (copy_from_user(&sdbytebuf[ibp], bp, nb)) return -EFAULT;
00231 bp+=nb;
00232
00233 i=10000;
00234 while (((i--)>0) && !X313_SR(PIORDY));
00235 if (i==0) return -EFAULT;
00236
00237 for (i=0;i<128;i++) port_csp0_addr[X313_WA_SD_PIOWIN]=sdbuf[i];
00238 port_csp0_addr[X313_WA_SDPIO_NEXT]=0;
00239 left -=nb;
00240 p+=nb;
00241 sa+=256;
00242 fp=0;
00243 }
00244 }
00245 i=1000;
00246 while (((i--)>0) && !X313_SR(PIOWEMPTY)) udelay(1);
00247 if (i==0) return -EFAULT;
00248
00249 *off+=count;
00250 D(printk("count= 0x%x, pos= 0x%x\n", (int) count, (int) *off));
00251 return count;
00252 }
00253
00254
00255 loff_t fsdram_lseek(struct file * file, loff_t offset, int orig)
00256 {
00257
00258
00259
00260
00261
00262 D(printk("fsdram_lseek\n"));
00263
00264 switch (orig)
00265 {
00266 case 0:
00267 file->f_pos = offset;
00268 break;
00269 case 1:
00270 file->f_pos += offset;
00271 break;
00272 case 2:
00273 file->f_pos = X313_SDRAM_SIZE + offset;
00274 break;
00275 default:
00276 return -EINVAL;
00277 }
00278
00279
00280 if (file->f_pos < 0) {
00281 file->f_pos = 0;
00282 return(-EOVERFLOW);
00283 }
00284
00285 if (file->f_pos >= X313_SDRAM_SIZE) {
00286 file->f_pos = X313_SDRAM_SIZE - 1;
00287 return(-EOVERFLOW);
00288 }
00289 return ( file->f_pos );
00290 }
00291
00292 int fsdram_open(struct inode *inode, struct file *filp) {
00293
00294 if (!X313_IS_SDRAM_ON) {
00295 fpga_initSDRAM();
00296 D(printk("fpga_initSDRAM\n"));
00297 }
00298
00299 D(printk("fsdram_open\n"));
00300
00301 inode->i_size=X313_SDRAM_SIZE;
00302 return 0;
00303 }
00304 int fsdram_release (void){
00305 D(printk("fsdram_release\n"));
00306 return 0;
00307 }
00308
00309
00310
00311
00312
00313
00314
00315