00001
00007 #include <stdio.h>
00008 #include <string.h>
00009
00010 #include "edtinc.h"
00011
00012 #include "cl_logic_lib.h"
00013
00014 #if defined(__sun) || defined(__linux__) || defined(__APPLE__)
00015 #include <sys/wait.h>
00016 #endif
00017
00018 #include "pciload.h"
00019
00020
00021
00022 #define FLAGS(v, testmask) (v & testmask)
00023 #define CLOCKS(v) (((v) & CLOCK_MASK)+1)
00024
00025 #define FV(v) (v & FV_MASK)
00026 #define DV(v) (v & DV_MASK)
00027 #define LV(v) (v & LV_MASK)
00028
00029
00030
00031 static int default_numbufs = 8;
00032 static int default_bufsize = CL_LOGIC_DEFAULT_BUFSIZE;
00033 static double default_pixel_clock = 20000000;
00034
00035
00036
00037 static int default_testmask = FV_MASK | LV_MASK;
00038 static int default_timeout = 0;
00039
00040
00041
00042
00043
00044
00045
00046
00047 void
00048 cl_logic_summary_init(ClLogicSummary * cls_p,
00049 int testmask,
00050 int numbufs,
00051 int bufsize,
00052 int timeout,
00053 double pixel_clock)
00054
00055 {
00056 memset(cls_p, 0, sizeof(ClLogicSummary));
00057
00058 if (testmask)
00059 cls_p->testmask = testmask;
00060 else
00061 cls_p->testmask = default_testmask;
00062
00063 if (numbufs)
00064 cls_p->numbufs = numbufs;
00065 else
00066 cls_p->numbufs = default_numbufs;
00067
00068 if (bufsize)
00069 cls_p->bufsize = bufsize;
00070 else
00071 cls_p->bufsize = default_bufsize;
00072
00073 if (timeout)
00074 cls_p->timeout = timeout;
00075 else
00076 cls_p->timeout = default_timeout;
00077
00078 if (pixel_clock)
00079 cls_p->pixel_clock = pixel_clock;
00080 else
00081 cls_p->pixel_clock = default_pixel_clock;
00082
00083 }
00084
00085 cl_logic_stat_clear(ClLogicStat *clp)
00086
00087 {
00088 memset(clp, 0, sizeof(ClLogicStat));
00089
00090 }
00091
00092
00093
00094
00095
00096
00097
00098 void
00099 cl_logic_stat_add(ClLogicStat * clp, int value)
00100
00101 {
00102
00103 if (clp->n > 0)
00104 {
00105 if (clp->high < value)
00106 clp->high = value;
00107 if (clp->low > value)
00108 clp->low = value;
00109
00110 }
00111 else
00112 {
00113 clp->high = clp->low = value;
00114
00115 }
00116
00117 clp->sum += value;
00118 clp->n++;
00119
00120 clp->mean = (int) (clp->sum / clp->n);
00121
00122 }
00123
00124
00125
00126 void
00127 cl_logic_stat_print(char *label, ClLogicStat * clp, double clockspeed, int verbose)
00128
00129 {
00130 if (verbose)
00131 printf("%-30s: %8d (%8d - %-8d) %8d\n", label,
00132 clp->mean, clp->low, clp->high, clp->n);
00133 else
00134 {
00135 printf("%-30s: %8d clocks %10g ms", label,
00136 clp->mean, (clp->mean * 1000.0) / clockspeed );
00137
00138 if (clp->low != clp->high)
00139 printf(" (%8d - %8d)\n", clp->low, clp->high);
00140 else
00141 printf("\n");
00142 }
00143
00144 }
00145
00146 int
00147 cl_logic_stats_neq(ClLogicStat * clp1, ClLogicStat * clp2)
00148
00149 {
00150 return (clp1->high != clp2->high ||
00151 clp1->low != clp2->low ||
00152 clp1->mean != clp2->mean ||
00153 clp1->n != clp2->n);
00154 }
00155
00156
00157 u_int
00158 edt_read_pci_config(EdtDev * edt_p, int addr)
00159 {
00160 int ret;
00161 edt_buf buf;
00162
00163 buf.desc = addr;
00164 if ((addr < 0) || (addr > 0x3c))
00165 {
00166 printf("pr_cfg: addr out of range\n");
00167 return (0);
00168 }
00169 ret = edt_ioctl(edt_p, EDTG_CONFIG, &buf);
00170 if (ret < 0)
00171 {
00172 perror("EDTG_CONFIG");
00173 }
00174 return (u_int) (buf.value);
00175 }
00176
00177 void
00178 edt_write_pci_config(EdtDev * edt_p, int addr, int value)
00179 {
00180 int ret;
00181 edt_buf buf;
00182
00183 buf.desc = addr;
00184 if ((addr < 0) || (addr > 0x3c))
00185 {
00186 printf("pw_cfg: addr out of range\n");
00187 return;
00188 }
00189 buf.value = value;
00190 ret = edt_ioctl(edt_p, EDTS_CONFIG, &buf);
00191 if (ret < 0)
00192 {
00193 perror("EDTS_CONFIG");
00194 }
00195 }
00196
00197 void
00198 edt_reboot_pci(EdtDev * edt_p, int verbose)
00199
00200 {
00201
00202 int addr, data;
00203 int buf[0x40];
00204 int old, copy, new_one;
00205 FILE *fd2;
00206
00207 if ((fd2 = fopen("./pdb_reboot.cfg", "wb")) == NULL)
00208 {
00209 fprintf(stderr, "cfgr: Couldn't write to ./pdb_reboot.cfg\n");
00210 return;
00211
00212 }
00213
00214 for (addr = 0; addr <= 0x3c; addr += 4)
00215 {
00216 data = edt_read_pci_config(edt_p, addr);
00217 buf[addr] = data;
00218 putc(data, fd2);
00219 putc(data >> 8, fd2);
00220 putc(data >> 16, fd2);
00221 putc(data >> 24, fd2);
00222
00223 }
00224 fclose(fd2);
00225
00226 printf("Wrote config space state out to ./pdb_reboot.cfg\n");
00227
00228 edt_reg_write(edt_p, 0x01000085, 0x40);
00229
00230 edt_msleep(500);
00231
00232 if (verbose)
00233 printf(" old copy new\n");
00234
00235 for (addr = 0; addr <= 0x3c; addr += 4)
00236 {
00237 old = edt_read_pci_config(edt_p, addr);
00238 copy = buf[addr];
00239 edt_write_pci_config(edt_p, addr, copy);
00240
00241 new_one = edt_read_pci_config(edt_p, addr);
00242
00243 if (verbose)
00244 {
00245 printf("%02x: %08x %08x %08x ", addr, old, copy, new_one);
00246
00247 if (copy != new_one)
00248 printf("ERROR\n");
00249 else if (old != new_one)
00250 printf("changed\n");
00251 else
00252 printf("\n");
00253
00254 }
00255
00256 }
00257
00258 printf("PCI firmware reconfigured...\n");
00259
00260 edt_msleep(2000);
00261
00262 }
00263
00264
00265
00266
00267
00268
00269
00270 size_t
00271 get_buffer_file(unsigned short *buffer, int size, FILE * f)
00272
00273 {
00274 size_t r = fread(buffer, 2, size, f);
00275
00276 return r;
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286 size_t
00287 get_buffer_card(unsigned short *buffer, int size, PdvDev * f)
00288
00289 {
00290 unsigned short *b;
00291
00292 int done = f->donecount;
00293
00294 b = (unsigned short *) edt_wait_for_buffers(f, 1);
00295
00296 memcpy(buffer, b, size);
00297
00298 edt_start_buffers(f, 1);
00299
00300 return (size_t) size / 2;
00301
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311 size_t
00312 get_next_logic_buffer(unsigned short *buffer, int size, PdvDev * pdv_p, FILE * f)
00313
00314 {
00315 if (pdv_p)
00316 return get_buffer_card(buffer, size, pdv_p);
00317 else
00318 return get_buffer_file(buffer, size, f);
00319
00320 }
00321
00322
00323 #define CL_LOGIC_FRAME_GRAN 256
00324
00325 void
00326 cl_logic_summary_add_frame(ClLogicSummary *clp, int width, int height, int hblank, int vblank)
00327
00328 {
00329 if (clp->nframes + 1 > clp->nframesallocated)
00330 {
00331 int newsize = clp->nframesallocated + CL_LOGIC_FRAME_GRAN;
00332
00333 if (clp->nframesallocated == 0)
00334 {
00335
00336 clp->frames = (ClFrameSummary *) calloc(newsize, sizeof(ClFrameSummary));
00337
00338 }
00339 else
00340 {
00341
00342
00343 clp->frames = (ClFrameSummary *) realloc(clp->frames, newsize * sizeof(ClFrameSummary));
00344
00345 }
00346
00347 clp->nframesallocated = newsize;
00348
00349 }
00350
00351 clp->frames[clp->nframes].width = width;
00352 clp->frames[clp->nframes].height = height;
00353 clp->frames[clp->nframes].line_blank = hblank;
00354 clp->frames[clp->nframes].frame_blank = vblank;
00355
00356 clp->nframes ++;
00357
00358 }
00359
00360 int
00361 pdv_cl_logic_sample(PdvDev *pdv_p,
00362 FILE *f,
00363 ClLogicSummary *clsp,
00364 int verbose,
00365 int quiet,
00366 int load,
00367 char *outfilename,
00368 unsigned int loops,
00369 int timeout,
00370 int max_timeouts)
00371
00372 {
00373 FILE *outfile = NULL;
00374 size_t r, offset;
00375 int i;
00376 int clocks = 0;
00377 int lastflags = 0;
00378 int lastval = 0;
00379 int start_h_gap;
00380 int end_h_gap;
00381
00382 int frame_gap = 0;
00383 int lastframegap = 0;
00384
00385 int lines = 0;
00386 int inframe = 0;
00387 int frameclocks = 0;
00388 int lineclocks = 0;
00389 int fv_state = -1;
00390
00391 unsigned short * buffer;
00392 int unit = 0;
00393 char oldname[MAX_STRING+1];
00394 char *trunc;
00395 u_short stat;
00396 int vb = 0;
00397 int promcode;
00398
00399 int last_width = 1;
00400 int last_hblank = 0;
00401 int ret = 0;
00402
00403
00404 if (pdv_p)
00405 {
00406 unit = pdv_p->unit_no;
00407
00408 promcode = edt_flash_prom_detect(pdv_p, &stat);
00409 edt_flash_get_fname(pdv_p, oldname);
00410
00411
00412 if ((trunc = strchr(oldname, '-')) != NULL)
00413 *trunc = '\0';
00414
00415 if (!quiet)
00416 printf("Current firmware is %s\n", oldname);
00417
00418 if (load || (strncmp(oldname,"camlkla", 7) != 0))
00419 {
00420 char cmd[80];
00421 int retval;
00422
00423 FILE *f = fopen("pciload.y","w");
00424 if (f == NULL) {
00425 edt_msg_perror(EDTLIB_MSG_FATAL, "Couldn't open file pciload.y for writing");
00426 return -1;
00427 }
00428 fprintf(f,"\n");
00429 fclose(f);
00430 if (!quiet)
00431 {
00432 printf("\n*********************************\n");
00433
00434 printf("Loading PCI firmware camlkla - this takes about 20 sec\n");
00435 }
00436
00437 sprintf(cmd, "pciload -u %d -q camlkla < pciload.y > pciload.out", unit);
00438 retval = system(cmd);
00439
00440 #ifdef __sun
00441 if (WEXITSTATUS(retval) != 0) {
00442 #else
00443 if (retval != 0) {
00444 #endif
00445 edt_msg(EDTLIB_MSG_FATAL, "ERROR: 'pciload camlkla' failed. Run it with -v for more info.\n");
00446 return -1;
00447 }
00448
00449 edt_reboot_pci(pdv_p, verbose);
00450 edt_reboot_pci(pdv_p, verbose);
00451 if (!quiet)
00452 printf("*********************************\n");
00453
00454
00455 }
00456
00457
00458 edt_set_rtimeout(pdv_p, timeout);
00459
00460 if (outfilename && outfilename[0])
00461 {
00462 outfile = fopen(outfilename, "wb");
00463 }
00464
00465 if (pdv_p)
00466 {
00467
00468
00469 edt_reg_write(pdv_p, PDV_CMD, 0x80);
00470
00471 edt_msleep(50);
00472
00473 clsp->pixel_clock = edt_intfc_read(pdv_p, 4) |
00474 (edt_intfc_read(pdv_p, 5) << 8) |
00475 (edt_intfc_read(pdv_p, 6) << 16);
00476
00477 clsp->pixel_clock *= 100;
00478
00479
00480 edt_reg_write(pdv_p, PDV_CFG, (~clsp->testmask >> 12) & 0xf);
00481
00482 edt_reg_write(pdv_p, PDV_CMD, 2);
00483 }
00484
00485 edt_configure_ring_buffers(pdv_p, clsp->bufsize, clsp->numbufs, EDT_READ, NULL);
00486
00487 edt_start_buffers(pdv_p, clsp->numbufs);
00488 }
00489
00490 buffer = (unsigned short *) edt_alloc(2 * clsp->bufsize);
00491
00492 offset = 0;
00493
00494 if (!quiet)
00495 {
00496 printf("\n*********************************\n");
00497 printf("Sampling transition data from the camera\n");
00498 printf("*********************************\n");
00499 }
00500
00501 while (clsp->nframes < (int) loops &&
00502 ((r = get_next_logic_buffer(buffer, clsp->bufsize, pdv_p, f)) > 0))
00503 {
00504 if (pdv_p)
00505 {
00506 if ((max_timeouts != 0) && (edt_timeouts(pdv_p) > max_timeouts))
00507 {
00508 break;
00509 }
00510 }
00511 if (outfile)
00512 fwrite(buffer,clsp->bufsize,1,outfile);
00513
00514 for (i = 0; i < (int) r; i++)
00515 {
00516
00517 if (lastflags != FLAGS(buffer[i], clsp->testmask))
00518 {
00519 if (FV(lastflags) != FV(buffer[i]))
00520 {
00521 if (FV(buffer[i]))
00522 {
00523 frame_gap = clocks;
00524
00525
00526 if (LV(buffer[i]))
00527 {
00528 start_h_gap = 0;
00529 }
00530 else
00531 {
00532 start_h_gap = CLOCKS(buffer[i]);
00533 }
00534
00535 if (fv_state > 1)
00536 {
00537
00538 cl_logic_stat_add(&clsp->start_hblank, start_h_gap);
00539 if (clocks)
00540 {
00541 cl_logic_stat_add(&clsp->frame_gap, clocks);
00542 lastframegap = clocks;
00543 }
00544
00545 }
00546
00547 inframe = 1;
00548 }
00549 else
00550 {
00551
00552 if (LV(lastflags))
00553 {
00554 end_h_gap = 0;
00555 }
00556 else
00557 {
00558 end_h_gap = CLOCKS(lastval);
00559 }
00560
00561 if (fv_state > 1)
00562 {
00563 cl_logic_stat_add(&clsp->end_hblank, end_h_gap);
00564
00565 cl_logic_stat_add(&clsp->height, lines);
00566
00567 cl_logic_stat_add(&clsp->frameclocks, frameclocks);
00568 cl_logic_stat_add(&clsp->totalframeclocks, frameclocks + lastframegap);
00569
00570 cl_logic_summary_add_frame(clsp, last_width, lines, last_hblank, frame_gap/last_width);
00571
00572 }
00573
00574 if (verbose && fv_state > 1)
00575 printf("%5d: F gap = %6d frame = %d total = %d width = %d height = %6d hblank = %d\n",
00576 clsp->frame_gap.n, frame_gap, frameclocks, frame_gap + frameclocks, last_width, lines,
00577 clsp->hblank_frame.mean);
00578
00579
00580 lines = 0;
00581 frameclocks = 0;
00582 inframe = 0;
00583 cl_logic_stat_clear(&clsp->hblank_frame);
00584 fv_state++;
00585
00586
00587 }
00588 }
00589
00590 if (inframe && fv_state > 1)
00591 {
00592 if (LV(buffer[i]))
00593 {
00594 lineclocks = CLOCKS(buffer[i]);
00595 if (lines > 0)
00596 {
00597 cl_logic_stat_add(&clsp->hblank, CLOCKS(lastval));
00598 cl_logic_stat_add(&clsp->hblank_frame, CLOCKS(lastval));
00599 cl_logic_stat_add(&clsp->totallineclocks, CLOCKS(lastval) + lineclocks);
00600 }
00601
00602 last_hblank = CLOCKS(lastval);
00603 last_width = lineclocks;
00604
00605 cl_logic_stat_add(&clsp->width, lineclocks);
00606 cl_logic_stat_add(&clsp->line_stats[lines], lineclocks);
00607
00608 lines++;
00609 }
00610 }
00611
00612 lastflags = FLAGS(buffer[i],clsp->testmask);
00613 lastval = buffer[i];
00614
00615 if (inframe)
00616 clocks = 0;
00617
00618 }
00619 clocks += CLOCKS(buffer[i]);
00620 if (inframe)
00621 frameclocks += clocks;
00622 if (clsp->height.n >= loops)
00623 {
00624
00625 break;
00626
00627 }
00628 }
00629
00630 offset += r;
00631 }
00632
00633
00634 if (outfile)
00635 fclose(outfile);
00636
00637 if (pdv_p)
00638 {
00639 if (load)
00640 {
00641 char cmd[80];
00642
00643 if (!quiet)
00644 {
00645 printf("\n*********************************\n");
00646
00647 printf("Loading PCI firmware %s - this takes about 20 sec\n", oldname);
00648 }
00649 sprintf(cmd, "pciload -u %d -q %s < pciload.y > pciload.out", unit, oldname);
00650 ret = system(cmd);
00651
00652 edt_reboot_pci(pdv_p, verbose);
00653 edt_reboot_pci(pdv_p, verbose);
00654 if (!quiet)
00655 printf("*********************************\n");
00656
00657 }
00658
00659 }
00660
00661 return 0;
00662
00663 }