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
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 #include <linux/module.h>
00114 #include <linux/mm.h>
00115 #include <linux/sched.h>
00116 #include <linux/slab.h>
00117 #include <linux/errno.h>
00118 #include <linux/kernel.h>
00119 #include <linux/fs.h>
00120 #include <linux/string.h>
00121 #include <linux/init.h>
00122 #include <linux/autoconf.h>
00123 #include <linux/time.h>
00124
00125 #include <asm/system.h>
00126 #include <asm/arch/memmap.h>
00127 #include <asm/io.h>
00128
00129 #include <asm/arch/dma.h>
00130 #include <asm/arch/hwregs/dma_defs.h>
00131 #include <asm/arch/hwregs/dma.h>
00132 #include <asm/arch/hwregs/reg_map.h>
00133 #include <asm/arch/hwregs/bif_dma_defs.h>
00134
00135
00136 #include <asm/irq.h>
00137 #include <asm/atomic.h>
00138
00139 #include <asm/delay.h>
00140 #include <asm/uaccess.h>
00141 #include <asm/arch/cache.h>
00142
00143 #include <asm/elphel/c313a.h>
00144
00145 #include "fpgactrl.h"
00146
00147 #include "x3x3.h"
00148 #include "cc3x3.h"
00149 #include "cxdma.h"
00150 #include "circbuf.h"
00151 #include "exif.h"
00152
00153 #if ELPHEL_DEBUG
00154 #define MD1(x) printk("%s:%d:",__FILE__,__LINE__);x
00155 #define MD12(x) printk("%s:%d:",__FILE__,__LINE__);x
00156
00157 #define MD13(x) printk("%s:%d:",__FILE__,__LINE__);x
00158
00159 #else
00160 #define MD1(x)
00161 #define MD12(x)
00162 #define MD13(x)
00163 #endif
00164
00165
00166
00167 #define D(x)
00168 #define D1(x)
00169
00170
00171 #define MD2(x) printk("%s:%d:",__FILE__,__LINE__);x
00172
00173
00174
00175 #define MD5(x)
00176
00177 #define MD6(x)
00178
00179 #define MD7(x)
00180
00181
00182 #define D0(x)
00183
00184
00185 #define MD8(x)
00186
00187 #define MD9(x)
00188
00189 #define MD10(x)
00191 //#define MD11(x) printk("%s:%d:",__FILE__,__LINE__);x
00192 #define MD11(x)
00193
00194
00195
00196
00197
00198 #ifdef CONFIG_ETRAX_ELPHEL353
00199 #define EXT_DMA_0_START \
00200 do { reg_bif_dma_rw_ch3_start c = {.run=1};\
00201 REG_WR(bif_dma, regi_bif_dma, rw_ch3_start, (reg_bif_dma_rw_ch3_start) c); } while( 0 )
00202 #define EXT_DMA_0_STOP \
00203 do { reg_bif_dma_rw_ch3_start c = {.run=0};\
00204 REG_WR(bif_dma, regi_bif_dma, rw_ch3_start, (reg_bif_dma_rw_ch3_start) c); } while( 0 )
00205 #else
00206 #define EXT_DMA_0_START \
00207 *R_EXT_DMA_0_CMD = (extdma0_cmd_shadow |= IO_STATE( R_EXT_DMA_0_CMD, run, start ) )
00208 #define EXT_DMA_0_STOP \
00209 *R_EXT_DMA_0_CMD = (extdma0_cmd_shadow &= ~IO_MASK( R_EXT_DMA_0_CMD, run ) )
00210 #endif
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 #define TRAILER_SIZE 0x02
00239 #define HEADER_YQTABLE 0x19
00240 #define HEADER_CQTABLE 0x5e
00241
00242 #define HEADER_HEIGHT 0xa3
00243 #define HEADER_WIDTH 0xa5
00244
00245
00246
00254 extern struct frame_params_t frame_params;
00255
00256
00257
00258 #ifdef CONFIG_ETRAX_ELPHEL353
00259 #define DMA_CHUNK 0x4000 // 32-bit words - may increase??
00260
00261 #define CCAM_DESCR_DATA_NUM (( CCAM_DMA_SIZE / DMA_CHUNK) +1 ) // number of data descriptors
00262 static dma_descr_data ccam_dma_descr_data [CCAM_DESCR_DATA_NUM] __attribute__ ((__aligned__(16)));
00263 static dma_descr_context ccam_dma_descr_context __attribute__ ((__aligned__(32)));
00264
00265 #else
00266 #define DMA_CHUNK 0x4000 // 32-bit words
00267
00268 #define CCAM_DESCR_DATA_NUM (( CCAM_DMA_SIZE / DMA_CHUNK) +1 ) // number of data descriptors
00269 static etrax_dma_descr ccam_dma_descr_data[CCAM_DESCR_DATA_NUM];
00270 static unsigned long extdma0_cmd_shadow=0;
00271
00272 #endif
00273 static unsigned char jpeg_header_sbuffer [JPEG_HEADER_SIZE];
00274 unsigned char *jpeg_header_sbuffer_ptr = NULL;
00275 static unsigned char trailer[TRAILER_SIZE] = {0xff,0xd9};
00276 static unsigned long DMABufferLength;
00277
00278
00279 unsigned long ccam_dma_length = CCAM_DMA_SIZE << 2;
00280
00281
00282
00283 static int use_header=1;
00284 static int JPEG_ctrl= 0x2ff;
00285
00286 int jpeg_quality= -1;
00287
00289 int FPGA_quality=-1;
00291 int JPEG_header_quality=-1;
00292
00293
00294
00295
00296 int soft_rp;
00297 static int save_rp=-1;
00298 static int save_wp=-1;
00299
00300
00301
00302 void x313_dma_reset_jpeg(void);
00303 int x313_dma_forget_jpeg(void);
00304
00305
00306
00307 int x313_dma_catchup_jpeg(void);
00308
00309 void update_JPEG_quality (int quality);
00310 int x313_setDMABuffer(void);
00311 unsigned long x313_DMA_size (void);
00312
00313 void x313_dma_update_jpeg_header(void);
00314
00315 void x313_JPEG_dump (void);
00316 int X313_dma_update(int latest);
00317 void x313_dma_reset_chain(void);
00318 int x313_dma_save_jpeg(void);
00319 int x313_dma_restore_jpeg(void);
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 int x313_JPEG_ctrl(int cmd) {
00336 JPEG_ctrl= cmd & 0xffff;
00337 use_header = ((cmd & 0x10000) == 0);
00338 return 0;
00339 }
00340
00341 int x313_get_JPEG_ctrl(void) {
00342 return JPEG_ctrl;
00343 }
00344
00345 void prof_msg(const char *msg) {
00346 struct timeval tv;
00347 do_gettimeofday(&tv);
00348 printk("at %d:%06d: %s\n", (int)tv.tv_sec, (int)tv.tv_usec, msg);
00349 }
00350
00351 int x313_JPEG_cmd(int cmd) {
00352 MD5(printk ("JPEG_cmd %x: aq=%x,rd=%x, ry=%x\n", cmd, acq_index, read_index, ready_index));
00353 MD6(printk ("JPEG_cmd %x\r\n", cmd));
00354 MD8(printk ("JPEG_cmd %x\r\n", cmd));
00355 MD11(printk ("JPEG_cmd %x, rp=0x%x, wp=0x%x\r\n", cmd,camSeqGetJPEG_rp(),camSeqGetJPEG_wp() ));
00356 switch(cmd) {
00357
00358 case JPEG_CMD_GET: {
00359 prof_msg("JPEG_CMD_GET\n");
00360 camSeqStop();
00361 x313_dma_update_jpeg_header();
00362 return camSeqStartClip(0, 0);
00363 }
00364 case JPEG_CMD_ACQUIRE: {
00365 prof_msg("JPEG_CMD_ACQUIRE\n");
00366 x313_dma_update_jpeg_header();
00367 return camSeqStartClip(1, -1);
00368 }
00369 case JPEG_CMD_RESET0:
00370 case JPEG_CMD_RESET: {
00371 prof_msg("JPEG_CMD_RESET\n");
00372 x313_setDMABuffer();
00373 x313_dma_reset_jpeg ();
00374 return 0;
00375 }
00376 case JPEG_CMD_FORGET: {
00377 prof_msg("JPEG_CMD_FORGET\n");
00378 return x313_dma_forget_jpeg();
00379 }
00380 case JPEG_CMD_CATCHUP: {
00381 prof_msg("JPEG_CMD_CATCHUP\n");
00382 return x313_dma_catchup_jpeg();
00383 }
00384 case JPEG_CMD_DUMP: {
00385 prof_msg("JPEG_CMD_DUMP\n");
00386 x313_JPEG_dump();
00387 return 0;
00388 }
00389 case JPEG_CMD_SAVE_RP:
00390 prof_msg("JPEG_CMD_SAVE_RP\n");
00391 return x313_dma_save_jpeg();
00392 case JPEG_CMD_RESTORE_RP:
00393 prof_msg("JPEG_CMD_RESTORE_RP\n");
00394 return x313_dma_restore_jpeg();
00395
00396
00397 case JPEG_CMD_START: {
00398 prof_msg("JPEG_CMD_START\n");
00399 x313_dma_update_jpeg_header();
00400 return camSeqStartClip(0, -1);
00401 }
00402 case JPEG_CMD_STOP: {
00403 prof_msg(" JPEG_CMD_STOP\n");
00404 x313_dma_update_jpeg_header();
00405 return camSeqStartClip(-1, 0);
00406 }
00407 case JPEG_CMD_JUST_STOP: {
00408 prof_msg("JPEG_CMD_JUST_STOP\n");
00409 return camSeqStartClip(-2, 0);
00410 }
00411 case JPEG_CMD_FRAMES: {
00412 prof_msg("JPEG_CMD_FRAMES\n");
00413 return X313_dma_update(-1);
00414 }
00415 default:
00416 return -1;
00417 }
00418 }
00419
00420
00421
00423 #if 0
00424 #define X313_CHAIN_SIGNATURE 0xffffffff
00425 #define X313_CHAIN_SIGNATURE4 0xffff0000
00426
00427 #define X313_LENGTH_MASK 0xff000000
00428
00429 #define X313_PADDED_FRAME(x)((((x)+67+CCAM_MMAP_META ) >>2) & 0xfffffff8)
00430 #define X313_BUFFSUB(x,y) (((x)>=(y))? ((x)-(y)) : ((x)+ (CCAM_DMA_SIZE-(y))))
00431 #define X313_BUFFADD(x,y) ((((x) + (y))<=CCAM_DMA_SIZE)? ((x) + (y)) : ((x) - (CCAM_DMA_SIZE-(y))))
00432 #endif
00433
00445 int x313_dma_save_jpeg(void) {
00446 save_rp = camSeqGetJPEG_rp();
00447 save_wp = camSeqGetJPEG_wp();
00448 return 0;
00449 }
00450
00451 int x313_dma_restore_jpeg(void) {
00452 if(save_wp == camSeqGetJPEG_wp()) {
00453 camSeqSetJPEG_rp(save_rp);
00454 soft_rp = X313_BUFFSUB(save_rp, 2);
00455 return 0;
00456 }
00457 return -1;
00458 }
00462 void x313_dma_reset_chain(void) {
00463 soft_rp = CCAM_DMA_SIZE - 2;
00464 ccam_dma_buf_ptr[soft_rp] |= X313_CHAIN_SIGNATURE4;
00465 ccam_dma_buf_ptr[soft_rp + 1] = X313_CHAIN_SIGNATURE;
00466 save_rp = -1;
00467 save_wp = -1;
00468 }
00469
00475 void x313_dma_reset_jpeg(void) {
00476 camSeqStop();
00477 camSeqStop();
00478 x313_dma_reset_chain();
00479 }
00480
00481 int x313_dma_forget_jpeg(void) {
00482 int i = 0;
00483 unsigned long rp;
00484 if(((ccam_dma_buf_ptr[soft_rp] & X313_CHAIN_SIGNATURE4)!= X313_CHAIN_SIGNATURE4) || (ccam_dma_buf_ptr[soft_rp + 1] == X313_CHAIN_SIGNATURE))
00485 i = X313_dma_update(0);
00486 if(i == 0) {
00487 soft_rp += X313_PADDED_FRAME(ccam_dma_buf_ptr[soft_rp + 1]);
00488 if(soft_rp >= CCAM_DMA_SIZE)
00489 soft_rp -= CCAM_DMA_SIZE;
00490 rp = X313_BUFFADD(soft_rp, 2);
00491 camSeqSetJPEG_rp(rp);
00492 return rp;
00493 }
00494 return -1;
00495 }
00496
00497
00498 int x313_dma_catchup_jpeg(void) {
00499 int i;
00500 i = X313_dma_update(1);
00501 if(i == 0)
00502 return 0;
00503 return -1;
00504 }
00505
00506
00507
00520
00521
00522 int X313_dma_update(int latest) {
00523 int rp,p,p1;
00524 int nz=1;
00525 int nf=0;
00526 int rebuild=(latest<0);
00527 unsigned long l;
00528 unsigned long prev_l=0;
00529 MD1(printk("*** X313_dma_update(latest=%d) - modifies global RP, may interfere with imgsrv or other apps\n",latest));
00530
00531 if(rebuild)
00532 rp = -1;
00533 else {
00534 rp = camSeqGetJPEG_rp();
00535 rebuild = (rp < 0);
00536 if ((rebuild == 0) && (!latest)) {
00537 soft_rp=X313_BUFFSUB(rp, 2);
00538 if(((ccam_dma_buf_ptr[soft_rp] & X313_CHAIN_SIGNATURE4) == X313_CHAIN_SIGNATURE4) &&
00539 (ccam_dma_buf_ptr[soft_rp + 1] != X313_CHAIN_SIGNATURE))
00540 return 0;
00541 }
00542 }
00543
00544 if((p = camSeqGetJPEG_wp()) == rp)
00545 return -1;
00546
00547
00548 camSeqSetJPEG_rp(p);
00549 soft_rp = X313_BUFFSUB(p, 2);
00550 MD2(printk("p=0x%x, rp=0x%x, soft_rp=0x%x\n",p,rp,soft_rp));
00551 while(1) {
00552 l = (ccam_dma_buf_ptr[X313_BUFFSUB(p, 9)] ^ X313_LENGTH_MASK);
00553 if (!prev_l) {
00554 if((l & X313_LENGTH_MASK) == 0) {
00555 p = X313_BUFFSUB(p, X313_PADDED_FRAME(l));
00556 prev_l = l;
00557 } else return rebuild?0:-1;
00558 } else {
00559 if ((ccam_dma_buf_ptr[X313_BUFFSUB(p, 2)] & X313_CHAIN_SIGNATURE4) == X313_CHAIN_SIGNATURE4) {
00560 camSeqSetJPEG_rp(p);
00561 soft_rp = X313_BUFFSUB(p, 2);
00562 nf++;
00563 if((latest > 0) ||
00564 (p == rp))
00565 return 0;
00566 if((l & X313_LENGTH_MASK) == 0) {
00567 p1 = p;
00568 p = X313_BUFFSUB(p, X313_PADDED_FRAME(l));
00569 if(p >= p1) {
00570 if((nz--) <= 0) {
00571 printk(" X313_dma_update: twice went through zero - overwritten p=%x, p1=%x\n", p, p1);
00572 return rebuild ? nf : -1;
00573 }
00574 }
00575 prev_l = l;
00576 } else {
00577 return rebuild ? nf : (nf? 0 :-1);
00578 }
00579 } else {
00580 return rebuild? nf : (nf? 0:-2);
00581 }
00582 }
00583 }
00584 }
00585
00586
00587
00588
00589 unsigned long t_sign = 0;
00590
00591
00592 unsigned long x313_DMA_size(void) {
00593 int i = 0;
00594
00595
00596 if((camSeqGetJPEG_rp() == camSeqGetJPEG_wp()) || ((ccam_dma_buf_ptr[soft_rp] & X313_CHAIN_SIGNATURE4) != X313_CHAIN_SIGNATURE4) || (ccam_dma_buf_ptr[soft_rp + 1] == X313_CHAIN_SIGNATURE))
00597 i = X313_dma_update(0);
00598
00599 if((i >= 0) && (ccam_dma_buf_ptr[soft_rp + 1] != X313_CHAIN_SIGNATURE)) {
00600 t_sign = ccam_dma_buf_ptr[soft_rp + 1] + 0xFF000000;
00601 return ccam_dma_buf_ptr[soft_rp + 1];
00602 }
00603
00604 return 0;
00605 }
00606
00607 int x313_dma_stop(void) {
00608 MD12(printk("==========x313_dma_stop\n"));
00609 port_csp0_addr[X313_WA_DMACR] = 0;
00610 EXT_DMA_0_STOP ;
00611 udelay(10) ;
00612 DMA_RESET( regi_dma9 );
00613
00614 return 0;
00615 }
00616
00617 void x313_dma_start(void) {
00618 unsigned long dai;
00619 int i = 0;
00620
00621
00622
00623
00624 MD12(printk("----------x313_dma_start\n"));
00625
00626 DMA_RESET(regi_dma9);
00627
00628 for(dai = 0; dai < CCAM_DMA_SIZE; dai += DMA_CHUNK) {
00629 if(dai + DMA_CHUNK >= CCAM_DMA_SIZE)
00630 ccam_dma_descr_data[i].after = (char *)virt_to_phys(&ccam_dma_buf_ptr[CCAM_DMA_SIZE]);
00631 else
00632 ccam_dma_descr_data[i].after = (char *)virt_to_phys(&ccam_dma_buf_ptr[dai + DMA_CHUNK]);
00634
00635 flush_dma_descr( & ccam_dma_descr_data[i], 0);
00636
00637 i++;
00638 }
00639 DMA_ENABLE(regi_dma9);
00640 port_csp0_addr[X313_WA_DMACR] = 0;
00641
00642 DMA_WR_CMD(regi_dma9, regk_dma_set_w_size4);
00643
00644 ccam_dma_descr_context.saved_data = (dma_descr_data*)virt_to_phys(&ccam_dma_descr_data[0]);
00645 ccam_dma_descr_context.saved_data_buf = ccam_dma_descr_data[0].buf;
00647 flush_dma_descr((dma_descr_data*) & ccam_dma_descr_context, 0);
00648
00649 DMA_START_CONTEXT(regi_dma9, virt_to_phys(&ccam_dma_descr_context));
00650 EXT_DMA_0_START ;
00651 port_csp0_addr[X313_WA_DMACR] = 0x30000;
00652
00653 }
00654
00655
00656 unsigned long x313_dma_init(void) {
00657 int rslt;
00659 jpeg_header_sbuffer_ptr = &jpeg_header_sbuffer[0];
00660 reg_dma_rw_cfg cfg = {.en = regk_dma_yes};
00661 reg_bif_dma_rw_ch3_ctrl exdma_ctrl = {
00662 .bw = regk_bif_dma_bw32,
00663 .burst_len = regk_bif_dma_burst8,
00664 .cont = 1,
00665 .end_discard = 0,
00666 .cnt = 0,
00667 .dreq_pin = 0,
00668 .dreq_mode = regk_bif_dma_norm,
00669 .tc_in_pin = 0,
00670 .tc_in_mode = 0,
00671 .bus_mode = regk_bif_dma_master,
00672 .rate_en = 0
00673 };
00674 reg_bif_dma_rw_ch3_addr exdma_addr = {.addr = MEM_CSR0_START | MEM_NON_CACHEABLE};
00675 reg_bif_dma_rw_pin0_cfg exdma_pin0 = {
00676 .master_ch = 0,
00677 .master_mode = regk_bif_dma_off,
00678 .slave_ch = 0,
00679 .slave_mode = regk_bif_dma_off
00680 };
00681 reg_bif_dma_rw_pin1_cfg exdma_pin1 = {
00682 .master_ch = 3,
00683 .master_mode = regk_bif_dma_dack,
00684 .slave_ch = 3,
00685 .slave_mode = regk_bif_dma_off
00686 };
00687
00688
00689 crisv32_free_dma(EXTDMA3_RX_DMA_NBR);
00690 printk("Initializing DMA registers for EXTDMA3 - ");
00691 MD7(printk("x313_dma_init(void)"));
00692
00693 D0(printk ("before crisv32_request_dma\n");
00694 udelay (500000));
00695 rslt = crisv32_request_dma(EXTDMA3_RX_DMA_NBR,
00696 "compressed data in from fpga",
00697 DMA_VERBOSE_ON_ERROR,
00698 0,
00699 dma_ext3);
00700 D0(printk ("after crisv32_request_dma - result=%d\n",rslt);
00701 udelay(500000));
00702
00703 if(rslt) {
00704 printk("failed\n");
00705 crisv32_free_dma(EXTDMA3_RX_DMA_NBR);
00706 printk(KERN_CRIT "Can't allocate external dma port for compressed data in from fpga");
00707 } else {
00708
00709 REG_WR(bif_dma, regi_bif_dma, rw_pin0_cfg, exdma_pin0);
00710 REG_WR(bif_dma, regi_bif_dma, rw_pin1_cfg, exdma_pin1);
00711
00712 REG_WR(bif_dma, regi_bif_dma, rw_ch3_ctrl, exdma_ctrl);
00713 REG_WR(bif_dma, regi_bif_dma, rw_ch3_addr, exdma_addr);
00714 REG_WR(dma, regi_dma9, rw_cfg, cfg);
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729 }
00730 DMABufferLength = 0;
00731 x313_setDMABuffer();
00732 x313_dma_reset_jpeg();
00733 return ((unsigned long)virt_to_phys(ccam_dma_buf_ptr)) | 0x80000000;
00734 }
00735
00736 int x313_setDMABuffer(void) {
00737 unsigned long dai;
00738 int i = 0;
00739
00740 EXT_DMA_0_STOP;
00741
00742 for(dai = 0; dai < CCAM_DMA_SIZE; dai += DMA_CHUNK) {
00743 ccam_dma_descr_data[i].buf = (char *)virt_to_phys(&ccam_dma_buf_ptr[dai]);
00744
00745 ccam_dma_descr_data[i].intr = 0;
00746 ccam_dma_descr_data[i].wait = 0;
00747 ccam_dma_descr_data[i].eol = 0;
00748 if(dai + DMA_CHUNK >= CCAM_DMA_SIZE) {
00749 ccam_dma_descr_data[i].after = (char *)virt_to_phys(&ccam_dma_buf_ptr[CCAM_DMA_SIZE]);
00750 ccam_dma_descr_data[i].next = (dma_descr_data*)virt_to_phys(&ccam_dma_descr_data[0]);
00751 } else {
00752 ccam_dma_descr_data[i].after = (char *)virt_to_phys(&ccam_dma_buf_ptr[dai + DMA_CHUNK]);
00753 ccam_dma_descr_data[i].next = (dma_descr_data*)virt_to_phys(&ccam_dma_descr_data[i + 1]);
00754
00755 }
00756 flush_dma_descr( & ccam_dma_descr_data[i], 0);
00757 i++;
00758 }
00759 set_imageParamsR(P_CIRCBUFSIZE,CCAM_DMA_SIZE<<2);
00760
00761
00762
00763
00764 MD8(printk ("filling DMA buffer with natural numbers - just test \n"));
00765 for(dai = 0; dai < CCAM_DMA_SIZE; dai++)
00766 ccam_dma_buf_ptr[dai] = dai;
00767 return 0;
00768 }
00769
00770 void x313_JPEG_dump(void) {
00771
00772 printk("port_csp0_addr[X313__RA__STATUS] = 0x%x\n", (int)port_csp0_addr[X313__RA__STATUS]);
00773 #if 0
00774 printk ("(*R_DMA_CH5_HWSW)=0x%x\n", (int) *R_DMA_CH5_HWSW);
00775 printk ("(*R_DMA_CH5_DESCR)=0x%x\n", (int) *R_DMA_CH5_DESCR);
00776 printk ("(*R_DMA_CH5_NEXT)=0x%x\n", (int) *R_DMA_CH5_NEXT);
00777 printk ("(*R_DMA_CH5_BUF)=0x%x\n", (int) *R_DMA_CH5_BUF);
00778 printk ("(*R_DMA_CH5_FIRST)=0x%x\n", (int) *R_DMA_CH5_FIRST);
00779 printk ("(*R_DMA_CH5_CMD)=0x%x\n", (int) *R_DMA_CH5_CMD);
00780 printk ("(*R_DMA_CH5_STATUS)=0x%x\n", (int) *R_DMA_CH5_STATUS);
00781 #endif
00782 #if 0
00783 typedef struct dma_descr_data {
00784 struct dma_descr_data *next;
00785 char *buf;
00786 unsigned eol : 1;
00787 unsigned : 2;
00788 unsigned out_eop : 1;
00789 unsigned intr : 1;
00790 unsigned wait : 1;
00791 unsigned : 2;
00792 unsigned : 3;
00793 unsigned in_eop : 1;
00794 unsigned : 4;
00795 unsigned md : 16;
00796 char *after;
00797 } dma_descr_data;
00798 #endif
00799 #if 0
00800 printk("\nDMA desriptor table (buf,after,next\n");
00801 for(i=0; i < CCAM_DESCR_DATA_NUM; i++)
00802 printk("%3x: %8x %8x %8x\n", i, (int)ccam_dma_descr_data[i].buf,
00803 (int)ccam_dma_descr_data[i].after,
00804 (int)ccam_dma_descr_data[i].next);
00805 #endif
00806 printk(" use_header= %x\n", use_header);
00807 printk(" JPEG_ctrl= %x\n", JPEG_ctrl);
00808 printk(" jpeg_quality=%x\n", jpeg_quality);
00809 printk(" soft_rp= %x\n", soft_rp);
00810 printk(" ccam_dma_buf_ptr[soft_rp]= %lx\n", ccam_dma_buf_ptr[soft_rp]);
00811 printk(" ccam_dma_buf_ptr[soft_rp+1]= %lx\n", ccam_dma_buf_ptr[soft_rp + 1]);
00812 }
00813
00814
00815
00816 int cmoscam_open_dma(struct inode *inode, struct file *filp) {
00817 int exif_len = exif_header_length();
00818 int exif_off = exif_len - EXIF_OFFSET;
00819 int header_size = JPEG_HEADER_SIZE + exif_off;
00820 int l;
00821
00822 l = x313_DMA_size();
00823
00824 if((l > 0) && use_header)
00825 l += (header_size + TRAILER_SIZE);
00826 inode->i_size = l;
00827
00828
00829
00830 return 0;
00831 }
00832
00833 loff_t x313_dma_lseek(struct file * file, loff_t offset, int orig) {
00834
00835
00836
00837
00838 int exif_len = exif_header_length();
00839 int exif_off = exif_len - EXIF_OFFSET;
00840 int header_size = JPEG_HEADER_SIZE + exif_off;
00841
00842 int l;
00843 l = x313_DMA_size();
00844
00845
00846 if((l > 0) && use_header)
00847 l += (header_size + TRAILER_SIZE);
00848
00849 switch(orig) {
00850 case 0:
00851 file->f_pos = offset;
00852 break;
00853 case 1:
00854 file->f_pos += offset;
00855 break;
00856 case 2:
00857 file->f_pos = l + offset;
00858 break;
00859 default:
00860 return -EINVAL;
00861 }
00862
00863
00864 if(file->f_pos < 0) {
00865 printk("x313_dma_lseek: file->fpose - negative! l=%d\n",l);
00866 printk("x313_dma_lseek orig=%d\n",orig);
00867 file->f_pos = 0;
00868 return(-EOVERFLOW);
00869 }
00870
00871 if(file->f_pos > l) {
00872 file->f_pos = l;
00873 }
00874 return( file->f_pos );
00875 }
00876
00877 unsigned long cpu_to_le(unsigned long in) {
00878 unsigned long r = (in & 0xFF) << 24;
00879 r += (in & 0xFF00) << 8;
00880 r += (in & 0xFF0000) >> 8;
00881 r += (in & 0xFF00) >> 24;
00882 return r;
00883 }
00884
00885 void get_image_exp(unsigned long *e) {
00886 *e = get_imageParamsR(P_EXPOS);
00887
00888
00889
00890 }
00891
00892 static unsigned char ext_mjpeg_header[PAGE_SIZE] __attribute__ ((aligned (PAGE_SIZE)));
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907 unsigned long ext_make_jpeg_header(void);
00908
00909 void ext_fill_jpeg_mmap_desc(struct ext_jpeg_mmap_desc_t *mdesc) {
00910
00911
00912 mdesc->jpeg_addr = ((X313_BUFFADD(soft_rp, 2)) << 2);
00913
00914
00915
00916 mdesc->jpeg_length = x313_DMA_size();
00917 mdesc->exif_length = ext_make_jpeg_header();
00918 mdesc->mmap_start = 0;
00919 mdesc->mmap_exif_length = PAGE_SIZE;
00920 mdesc->mmap_jpeg_length = CCAM_DMA_SIZE << 2;
00921
00922 }
00923
00924 void ext_fill_jpeg_mmap_desc_(struct _ext_jpeg_mmap_desc_t *mdesc) {
00925 mdesc->exif_start = (void *)&ext_mjpeg_header[0];
00926 mdesc->exif_length = PAGE_SIZE;
00927 mdesc->jpeg_start = (unsigned long *) ccam_dma_buf_ptr;
00928 mdesc->jpeg_length = CCAM_DMA_SIZE << 2;
00929
00930 }
00931
00932
00933 unsigned long ext_make_jpeg_header(void) {
00934 unsigned char *jpeg_header = ext_mjpeg_header;
00935 int exif_len = exif_header_length();
00936 int exif_off = exif_len - EXIF_OFFSET;
00937
00938 int header_size = JPEG_HEADER_SIZE + exif_off;
00939
00940 unsigned long ne_exp[2];
00941
00942
00943 memcpy(jpeg_header + exif_off, jpeg_header_sbuffer, JPEG_HEADER_SIZE);
00944 memcpy(jpeg_header, exif_header, exif_len);
00945 unsigned char *exif = jpeg_header;
00946
00947 memcpy(exif + EXIF_FIRMWARE, exif_desc.firmware, EXIF_FIRMWARE_LEN);
00948 memcpy(exif + EXIF_ARTIST, exif_desc.artist, EXIF_ARTIST_LEN);
00949 memcpy(exif + EXIF_DATE_TIME, exif_desc.date_time, EXIF_DATE_TIME_LEN);
00950 memcpy(exif + EXIF_DATE_TIME_OR, exif_desc.date_time_or, EXIF_DATE_TIME_OR_LEN);
00951 memcpy(exif + EXIF_SUBSEC_OR, exif_desc.subsec, EXIF_SUBSEC_OR_LEN);
00952 get_image_exp(&exif_desc.exp[0]);
00953 ne_exp[0] = cpu_to_le(exif_desc.exp[0]);
00954 ne_exp[1] = cpu_to_le(exif_desc.exp[1]);
00955 memcpy(exif + EXIF_EXP, ne_exp, EXIF_EXP_LEN);
00956
00957 return header_size;
00958 }
00959
00960 #ifdef EXIF
00961 ssize_t x313_dma_read(struct file * file, char * buf, size_t count, loff_t *off) {
00962 unsigned long p, l, i, left, l1;
00963 int rp;
00964 char *bp = buf;
00965
00966 unsigned char jpeg_header[2048];
00967 int exif_len = exif_header_length();
00968 int exif_off = exif_len - EXIF_OFFSET;
00969 int header_size = JPEG_HEADER_SIZE + exif_off;
00970
00971
00972 D(printk("x313_dma_read\n"));
00973
00974
00975 p = *off;
00976
00977
00978 if((p + count) > ((l = x313_DMA_size()) + (use_header ? (header_size + TRAILER_SIZE) : 0))) {
00979 count = l + (use_header ? (header_size + TRAILER_SIZE) : 0) - p;
00980 }
00981 left = count;
00982
00983 if(use_header) {
00984 unsigned long ne_exp[2];
00985
00986
00987 memcpy(jpeg_header + exif_off, jpeg_header_sbuffer, JPEG_HEADER_SIZE);
00988 memcpy(jpeg_header, exif_header, exif_len);
00989 unsigned char *exif = jpeg_header;
00990
00991 memcpy(exif + EXIF_FIRMWARE, exif_desc.firmware, EXIF_FIRMWARE_LEN);
00992 memcpy(exif + EXIF_ARTIST, exif_desc.artist, EXIF_ARTIST_LEN);
00993 memcpy(exif + EXIF_DATE_TIME, exif_desc.date_time, EXIF_DATE_TIME_LEN);
00994 memcpy(exif + EXIF_DATE_TIME_OR, exif_desc.date_time_or, EXIF_DATE_TIME_OR_LEN);
00995 memcpy(exif + EXIF_SUBSEC_OR, exif_desc.subsec, EXIF_SUBSEC_OR_LEN);
00996 get_image_exp(&exif_desc.exp[0]);
00997 ne_exp[0] = cpu_to_le(exif_desc.exp[0]);
00998 ne_exp[1] = cpu_to_le(exif_desc.exp[1]);
00999 memcpy(exif + EXIF_EXP, ne_exp, EXIF_EXP_LEN);
01000
01001 if(p < header_size) {
01002 i = left;
01003 if(i > (header_size - p))
01004 i = header_size - p;
01005 if(i && (copy_to_user(bp, &jpeg_header[p], i))) {
01006 printk("copy_to_user1 (0x%x) error\n",( int)i);
01007 return -EFAULT;
01008 }
01009 bp += i;
01010 left -= i;
01011 p = 0;
01012 } else
01013 p -= header_size;
01014 }
01015
01016 if(left == 0) {
01017 *off += count;
01018 return count;
01019 }
01020
01021
01022 if(p < l) {
01023
01024 rp = X313_BUFFADD(soft_rp, 2);
01025 MD9(printk("rp == 0x%08X; rp << 2 == 0x%08X\r\n", rp, rp << 2));
01026
01027 l1 = ((CCAM_DMA_SIZE - rp) << 2);
01028 if(l1 > l)
01029 l1 = l;
01030 if(p < l1) {
01031 i = left;
01032 if(i > (l1 - p))
01033 i = l1 - p;
01034 if(i && (copy_to_user(bp, ((char *) ccam_dma_buf_ptr) + (rp << 2)+ p, i))) {
01035 printk("copy_to_user2 (0x%x) error\n",(int) i);
01036 return -EFAULT;
01037 }
01038
01039 bp += i;
01040 left -= i;
01041 p = 0;
01042 } else
01043 p -= l1;
01044
01045 l -= l1;
01046 if(p < l) {
01047 i = left;
01048 if(i > (l - p))
01049 i = l - p;
01050
01051 if(i && (copy_to_user(bp, ((char *)ccam_dma_buf_ptr) + p, i))) {
01052 printk("copy_to_user3 (0x%x) error\n", (int)i);
01053 printk("soft_rp=0x%x\n", (int)soft_rp);
01054 printk("*off=0x%x\n", (int) *off);
01055 printk("count=0x%x, left=0x%x, l=0x%x, i=0x%x, p=0x%x\n", (int)count, (int)left, (int)l, (int)i, (int)p);
01056 return -EFAULT;
01057 }
01058 bp += i;
01059 left -= i;
01060 p = 0;
01061 } else
01062 p -= l;
01063 } else
01064 p -= l;
01065
01066 if(left > 0) {
01067 i = left;
01068
01069 if(i > TRAILER_SIZE)
01070 i = TRAILER_SIZE;
01071 if(i && (copy_to_user(bp, &trailer[p], i))) {
01072
01073 printk("copy_to_user4 (0x%x) error\n", (int)i);
01074 printk("soft_rp=0x%x\n", (int)soft_rp);
01075 printk("*off=0x%x\n", (int)*off);
01076 printk("count=0x%x, left=0x%x, l=0x%x, i=0x%x, p=0x%x\n", (int)count, (int)left, (int)l, (int)i, (int)p);
01077 return -EFAULT;
01078 }
01079 }
01080
01081 *off += count;
01082 return count;
01083 }
01084
01085 #else
01086
01087 ssize_t x313_dma_read(struct file * file, char * buf, size_t count, loff_t *off) {
01088 unsigned long p, l, i, left, l1;
01089 int rp;
01090 char *bp = buf;
01091
01092 MD9(printk("x313_dma_read\n"));
01093
01094
01095 p = *off;
01096 if((p + count) > ((l = x313_DMA_size()) + (use_header ? (JPEG_HEADER_SIZE + TRAILER_SIZE) : 0))) {
01097 count = l + (use_header ? (JPEG_HEADER_SIZE + TRAILER_SIZE) : 0) - p;
01098 }
01099 left = count;
01100
01101 if (use_header) {
01102 if (p < JPEG_HEADER_SIZE) {
01103 i=left;
01104 if (i>(JPEG_HEADER_SIZE-p)) i= JPEG_HEADER_SIZE-p;
01105 if (i && (copy_to_user(bp, &jpeg_header_sbuffer[p], i)))
01106 {printk("copy_to_user1 (0x%x) error\n",(int) i);return -EFAULT;}
01107 bp+=i;
01108 left-=i;
01109 p=0;
01110 } else p-=JPEG_HEADER_SIZE;
01111 }
01112
01113 if(left == 0) {
01114 *off += count;
01115 return count;
01116 }
01117
01118
01119 if(p < l) {
01120
01121 rp = X313_BUFFADD(soft_rp, 2);
01122 MD9(printk("rp == 0x%08X; rp << 2 == 0x%08X\r\n", rp, rp << 2));
01123
01124 l1 = ((CCAM_DMA_SIZE - rp) << 2);
01125 if(l1 > l)
01126 l1 = l;
01127 if(p < l1) {
01128 i = left;
01129 if(i > (l1 - p))
01130 i = l1 - p;
01131 if(i && (copy_to_user(bp, ((char *) ccam_dma_buf_ptr) + (rp << 2)+ p, i))) {
01132 printk("copy_to_user2 (0x%x) error\n",(int) i);
01133 return -EFAULT;
01134 }
01135 bp += i;
01136 left -= i;
01137 p = 0;
01138 } else
01139 p -= l1;
01140
01141 l -= l1;
01142 if(p < l) {
01143 i = left;
01144 if(i > (l - p))
01145 i = l - p;
01146 if(i && (copy_to_user(bp, ((char *)ccam_dma_buf_ptr) + p, i))) {
01147 printk("copy_to_user3 (0x%x) error\n", (int)i);
01148 printk("soft_rp=0x%x\n", (int)soft_rp);
01149 printk("*off=0x%x\n", (int) *off);
01150 printk("count=0x%x, left=0x%x, l=0x%x, i=0x%x, p=0x%x\n", (int)count, (int)left, (int)l, (int)i, (int)p);
01151 return -EFAULT;
01152 }
01153 bp += i;
01154 left -= i;
01155 p = 0;
01156 } else
01157 p -= l;
01158 } else
01159 p -= l;
01160
01161 if(left > 0) {
01162 i = left;
01163
01164 if(i > TRAILER_SIZE)
01165 i = TRAILER_SIZE;
01166 if(i && (copy_to_user(bp, &trailer[p], i))) {
01167
01168 printk("copy_to_user4 (0x%x) error\n", (int)i);
01169 printk("soft_rp=0x%x\n", (int)soft_rp);
01170 printk("*off=0x%x\n", (int)*off);
01171 printk("count=0x%x, left=0x%x, l=0x%x, i=0x%x, p=0x%x\n", (int)count, (int)left, (int)l, (int)i, (int)p);
01172 return -EFAULT;
01173 }
01174 }
01175
01176 *off += count;
01177 return count;
01178 }
01179
01180 #endif
01181 ssize_t x313_dma_write(struct file * file, const char * buf, size_t count, loff_t *off) {
01182 unsigned long p;
01183
01184 D(printk("x313_dma_write\n"));
01185
01186 p = *off;
01187 if (p >= JPEG_HEADER_SIZE) p = JPEG_HEADER_SIZE;
01188 if( (p + count) > JPEG_HEADER_SIZE) {
01189 count = JPEG_HEADER_SIZE - p;
01190 }
01191 if (count) {
01192 if (copy_from_user(&jpeg_header_sbuffer[p],buf, count)) return -EFAULT;
01193
01194 *off+=count;
01195 }
01196 return count;
01197 }
01198 #if 0
01200 int FPGA_quality=-1;
01202 int JPEG_header_quality=-1;
01203 int JPEG_header_width=-1;
01204 int JPEG_header_height-1;
01205 #endif
01206
01209 void setJPEGHeader (int quality, int width, int height) {
01210 MD9(printk("setJPEGHeader(quality=%d,width=%d, height=%d)\n",quality, width, height));
01211 jpeg_header_sbuffer[HEADER_HEIGHT ] = (height >> 8) & 0xff;
01212 jpeg_header_sbuffer[HEADER_HEIGHT + 1] = height & 0xff;
01213 jpeg_header_sbuffer[HEADER_WIDTH ] = (width >> 8) & 0xff;
01214 jpeg_header_sbuffer[HEADER_WIDTH + 1 ] = width & 0xff;
01215
01216 if (quality != JPEG_header_quality) jpeg_set_quality(quality, QTABLES_EXIF, NULL);
01217 }
01218
01219 void x313_dma_update_jpeg_header(void) {
01220 int x, y;
01221 MD8(printk("x313_dma_update_jpeg_header W(P_QUALITY)=%d,R(P_QUALITY)=%d\n",(int)get_imageParamsW(P_QUALITY),(int)get_imageParamsR(P_QUALITY)));
01222 update_JPEG_quality(get_imageParamsW(P_QUALITY));
01223
01224
01225
01226
01227 y = ((port_csp0_addr[X313_WA_SDCH2_CTL2] & 0x0ff0) >> 4) + 1;
01228 x = ((port_csp0_addr[X313_WA_SDCH2_CTL1] & 0x1ff0) >> 4) + 1;
01229 MD6(printk("x313_dma_update_jpeg_header x=0x%x, y=0x%x\r\n",x,y));
01230 MD13(printk("x313_dma_update_jpeg_header x=0x%x, y=0x%x (used SDRAM CHN2)\r\n",x,y));
01231
01232 jpeg_header_sbuffer[HEADER_HEIGHT ] = (y >> 4) & 0xff;
01233 jpeg_header_sbuffer[HEADER_HEIGHT + 1] = (y << 4) & 0xff;
01234 jpeg_header_sbuffer[HEADER_WIDTH ] = (x >> 4) & 0xff;
01235 jpeg_header_sbuffer[HEADER_WIDTH + 1 ] = (x << 4) & 0xff;
01236 }
01237
01238
01239 #define DCTSIZE2 64
01240 void update_JPEG_quality(int quality) {
01241 if((quality != get_imageParamsR(P_QUALITY)) || (quality != jpeg_quality)) {
01242 set_imageParamsR(P_QUALITY, quality);
01243
01244 jpeg_set_quality(quality, QTABLES_FPGA | QTABLES_EXIF, NULL);
01245 jpeg_quality = quality;
01246 frame_params.quality=quality;
01247 }
01248 }
01261
01262
01263 void jpeg_set_quality (int quality, int target, void *table){
01264
01265
01266
01267
01268 int i, temp;
01269 int prev = 0;
01270 unsigned char *qtable = NULL;
01271
01272 if((target & QTABLES_FPGA) && quality == FPGA_quality)
01273 target &= ~QTABLES_FPGA;
01274 if((target & QTABLES_EXIF) && quality == JPEG_header_quality)
01275 target &= ~QTABLES_EXIF;
01276 if(target & QTABLES_TABLE) {
01277 if(table == NULL)
01278 target &= ~QTABLES_TABLE;
01279 else
01280 qtable = (unsigned char *)table;
01281 }
01282 if(target == 0)
01283 return;
01284
01285
01286 const unsigned int zig_zag[DCTSIZE2] = {
01287 0, 1, 5, 6,14,15,27,28,
01288 2, 4, 7,13,16,26,29,42,
01289 3, 8,12,17,25,30,41,43,
01290 9,11,18,24,31,40,44,53,
01291 10,19,23,32,39,45,52,54,
01292 20,22,33,38,46,51,55,60,
01293 21,34,37,47,50,56,59,61,
01294 35,36,48,49,57,58,62,63
01295 };
01296
01297 const unsigned int std_quant_tbls[2 * DCTSIZE2] = {
01298
01299 16, 11, 10, 16, 24, 40, 51, 61,
01300 12, 12, 14, 19, 26, 58, 60, 55,
01301 14, 13, 16, 24, 40, 57, 69, 56,
01302 14, 17, 22, 29, 51, 87, 80, 62,
01303 18, 22, 37, 56, 68, 109, 103, 77,
01304 24, 35, 55, 64, 81, 104, 113, 92,
01305 49, 64, 78, 87, 103, 121, 120, 101,
01306 72, 92, 95, 98, 112, 100, 103, 99,
01307
01308 17, 18, 24, 47, 99, 99, 99, 99,
01309 18, 21, 26, 66, 99, 99, 99, 99,
01310 24, 26, 56, 99, 99, 99, 99, 99,
01311 47, 66, 99, 99, 99, 99, 99, 99,
01312 99, 99, 99, 99, 99, 99, 99, 99,
01313 99, 99, 99, 99, 99, 99, 99, 99,
01314 99, 99, 99, 99, 99, 99, 99, 99,
01315 99, 99, 99, 99, 99, 99, 99, 99
01316 };
01317
01318
01319
01320
01321
01322
01323 if(quality <= 0)
01324 quality = 1;
01325 if(quality > 100)
01326 quality = 100;
01327
01328
01329
01330
01331
01332
01333
01334 if(quality < 50)
01335 quality = 5000 / quality;
01336 else
01337 quality = 200 - quality * 2;
01338
01339
01340
01341
01342
01343 #ifdef PRINTQTAB
01344 printk ("writing quantization table to FPGA\n");
01345 #endif
01346 MD13(printk ("writing quantization table, target=%x (FPGA=%x,EXIF=%x)\n", (int) target, (int)QTABLES_FPGA, (int) QTABLES_EXIF));
01348 unsigned long flags;
01349 local_irq_save(flags);
01350 if(target & QTABLES_FPGA) port_csp0_addr[X313_WA_COMP_TA] = 0x0;
01351 for(i = 0; i < 2 * DCTSIZE2; i++) {
01352 temp = (std_quant_tbls[i] * quality + 50) / 100;
01353
01354 if(temp <= 0) temp = 1;
01355 if(temp > 255) temp = 255;
01356
01357 temp = ((8192/temp) + 1) >> 1;
01358 if(temp > 4095) temp = 4095;
01359 if(i & 1) {
01360
01361 if(target & QTABLES_FPGA) port_csp0_addr[X313_WA_COMP_TD] = (temp << 16) | prev;
01362 #ifdef PRINTQTAB
01363 printk ("%08x ",(temp << 16) | prev);
01364 if((i & 0x07) == 0x07) printk ("\n");
01365 #endif
01366 } else
01367 prev = temp;
01368 temp = ((8192 / temp) + 1) >> 1;
01369 if(target & QTABLES_EXIF)
01370 jpeg_header_sbuffer[((i < DCTSIZE2) ? HEADER_YQTABLE : HEADER_CQTABLE) + zig_zag[i & 0x3f]] = temp;
01371 if(target & QTABLES_TABLE)
01372 qtable[((i < DCTSIZE2) ? 0 : 64) + zig_zag[i & 0x3F]] = temp;
01373 }
01374 local_irq_restore(flags);
01375
01376 if(target & QTABLES_EXIF)
01377 JPEG_header_quality = quality;
01378 if(target & QTABLES_FPGA)
01379 FPGA_quality = quality;
01380
01381
01382 }