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_char stat;
00396 int vb = 0;
00397 int promcode;
00398
00399 int last_width = 1;
00400 int last_hblank = 0;
00401
00402
00403 if (pdv_p)
00404 {
00405 unit = pdv_p->unit_no;
00406
00407 promcode = edt_x_prom_detect(pdv_p, &stat);
00408 edt_x_get_fname(pdv_p, oldname);
00409
00410
00411 if ((trunc = strchr(oldname, '-')) != NULL)
00412 *trunc = '\0';
00413
00414 if (!quiet)
00415 printf("Current firmware is %s\n", oldname);
00416
00417 if (load || (strncmp(oldname,"camlkla", 7) != 0))
00418 {
00419 char cmd[80];
00420 int retval;
00421
00422 FILE *f = fopen("pciload.y","w");
00423 if (f == NULL) {
00424 edt_msg_perror(EDTLIB_MSG_FATAL, "Couldn't open file pciload.y for writing");
00425 return -1;
00426 }
00427 fprintf(f,"\n");
00428 fclose(f);
00429 if (!quiet)
00430 {
00431 printf("\n*********************************\n");
00432
00433 printf("Loading PCI firmware camlkla - this takes about 20 sec\n");
00434 }
00435
00436 sprintf(cmd, "pciload -u %d -q camlkla < pciload.y > pciload.out", unit);
00437 retval = system(cmd);
00438
00439 #ifdef __sun
00440 if (WEXITSTATUS(retval) != 0) {
00441 #else
00442 if (retval != 0) {
00443 #endif
00444 edt_msg(EDTLIB_MSG_FATAL, "ERROR: 'pciload camlkla' failed. Run it with -v for more info.\n");
00445 return -1;
00446 }
00447
00448 edt_reboot_pci(pdv_p, verbose);
00449 edt_reboot_pci(pdv_p, verbose);
00450 if (!quiet)
00451 printf("*********************************\n");
00452
00453
00454 }
00455
00456
00457 edt_set_rtimeout(pdv_p, timeout);
00458
00459 if (outfilename && outfilename[0])
00460 {
00461 outfile = fopen(outfilename, "wb");
00462 }
00463
00464 if (pdv_p)
00465 {
00466
00467
00468 edt_reg_write(pdv_p, PDV_CMD, 0x80);
00469
00470 edt_msleep(50);
00471
00472 clsp->pixel_clock = edt_intfc_read(pdv_p, 4) |
00473 (edt_intfc_read(pdv_p, 5) << 8) |
00474 (edt_intfc_read(pdv_p, 6) << 16);
00475
00476 clsp->pixel_clock *= 100;
00477
00478
00479 edt_reg_write(pdv_p, PDV_CFG, (~clsp->testmask >> 12) & 0xf);
00480
00481 edt_reg_write(pdv_p, PDV_CMD, 2);
00482 }
00483
00484 edt_configure_ring_buffers(pdv_p, clsp->bufsize, clsp->numbufs, EDT_READ, NULL);
00485
00486 edt_start_buffers(pdv_p, clsp->numbufs);
00487 }
00488
00489 buffer = (unsigned short *) edt_alloc(2 * clsp->bufsize);
00490
00491 offset = 0;
00492
00493 if (!quiet)
00494 {
00495 printf("\n*********************************\n");
00496 printf("Sampling transition data from the camera\n");
00497 printf("*********************************\n");
00498 }
00499
00500 while (clsp->nframes < (int) loops &&
00501 ((r = get_next_logic_buffer(buffer, clsp->bufsize, pdv_p, f)) > 0))
00502 {
00503 if (pdv_p)
00504 {
00505 if ((max_timeouts != 0) && (edt_timeouts(pdv_p) > max_timeouts))
00506 {
00507 break;
00508 }
00509 }
00510 if (outfile)
00511 fwrite(buffer,clsp->bufsize,1,outfile);
00512
00513 for (i = 0; i < (int) r; i++)
00514 {
00515
00516 if (lastflags != FLAGS(buffer[i], clsp->testmask))
00517 {
00518 if (FV(lastflags) != FV(buffer[i]))
00519 {
00520 if (FV(buffer[i]))
00521 {
00522 frame_gap = clocks;
00523
00524
00525 if (LV(buffer[i]))
00526 {
00527 start_h_gap = 0;
00528 }
00529 else
00530 {
00531 start_h_gap = CLOCKS(buffer[i]);
00532 }
00533
00534 if (fv_state > 1)
00535 {
00536
00537 cl_logic_stat_add(&clsp->start_hblank, start_h_gap);
00538 if (clocks)
00539 {
00540 cl_logic_stat_add(&clsp->frame_gap, clocks);
00541 lastframegap = clocks;
00542 }
00543
00544 }
00545
00546 inframe = 1;
00547 }
00548 else
00549 {
00550
00551 if (LV(lastflags))
00552 {
00553 end_h_gap = 0;
00554 }
00555 else
00556 {
00557 end_h_gap = CLOCKS(lastval);
00558 }
00559
00560 if (fv_state > 1)
00561 {
00562 cl_logic_stat_add(&clsp->end_hblank, end_h_gap);
00563
00564 cl_logic_stat_add(&clsp->height, lines);
00565
00566 cl_logic_stat_add(&clsp->frameclocks, frameclocks);
00567 cl_logic_stat_add(&clsp->totalframeclocks, frameclocks + lastframegap);
00568
00569 cl_logic_summary_add_frame(clsp, last_width, lines, last_hblank, frame_gap/last_width);
00570
00571 }
00572
00573 if (verbose && fv_state > 1)
00574 printf("%5d: F gap = %6d frame = %d total = %d width = %d height = %6d hblank = %d\n",
00575 clsp->frame_gap.n, frame_gap, frameclocks, frame_gap + frameclocks, last_width, lines,
00576 clsp->hblank_frame.mean);
00577
00578
00579 lines = 0;
00580 frameclocks = 0;
00581 inframe = 0;
00582 cl_logic_stat_clear(&clsp->hblank_frame);
00583 fv_state++;
00584
00585
00586 }
00587 }
00588
00589 if (inframe && fv_state > 1)
00590 {
00591 if (LV(buffer[i]))
00592 {
00593 lineclocks = CLOCKS(buffer[i]);
00594 if (lines > 0)
00595 {
00596 cl_logic_stat_add(&clsp->hblank, CLOCKS(lastval));
00597 cl_logic_stat_add(&clsp->hblank_frame, CLOCKS(lastval));
00598 cl_logic_stat_add(&clsp->totallineclocks, CLOCKS(lastval) + lineclocks);
00599 }
00600
00601 last_hblank = CLOCKS(lastval);
00602 last_width = lineclocks;
00603
00604 cl_logic_stat_add(&clsp->width, lineclocks);
00605 cl_logic_stat_add(&clsp->line_stats[lines], lineclocks);
00606
00607 lines++;
00608 }
00609 }
00610
00611 lastflags = FLAGS(buffer[i],clsp->testmask);
00612 lastval = buffer[i];
00613
00614 if (inframe)
00615 clocks = 0;
00616
00617 }
00618 clocks += CLOCKS(buffer[i]);
00619 if (inframe)
00620 frameclocks += clocks;
00621 if (clsp->height.n >= loops)
00622 {
00623
00624 break;
00625
00626 }
00627 }
00628
00629 offset += r;
00630 }
00631
00632
00633 if (outfile)
00634 fclose(outfile);
00635
00636 if (pdv_p)
00637 {
00638 if (load)
00639 {
00640 char cmd[80];
00641
00642 if (!quiet)
00643 {
00644 printf("\n*********************************\n");
00645
00646 printf("Loading PCI firmware %s - this takes about 20 sec\n", oldname);
00647 }
00648 sprintf(cmd, "pciload -u %d -q %s < pciload.y > pciload.out", unit, oldname);
00649 system(cmd);
00650
00651 edt_reboot_pci(pdv_p, verbose);
00652 edt_reboot_pci(pdv_p, verbose);
00653 if (!quiet)
00654 printf("*********************************\n");
00655
00656 }
00657
00658 }
00659
00660 return 0;
00661
00662 }