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