static int test_scan_context(struct hwtest_ctx *ctx) { nva_wr32(ctx->cnum, 0x4006a4, 0x0f000111); TEST_BITSCAN(0x400600, 0x3fffffff, 0); TEST_BITSCAN(0x400604, 0xff, 0); TEST_BITSCAN(0x400608, 0x3fffffff, 0); TEST_BITSCAN(0x40060c, 0xff, 0); TEST_BITSCAN(0x400610, 0xffffffff, 0); TEST_BITSCAN(0x400614, 0xffffffff, 0); TEST_BITSCAN(0x400618, 3, 0); TEST_BITSCAN(0x40061c, 0x7fffffff, 0); TEST_BITSCAN(0x400620, 0x7fffffff, 0); TEST_BITSCAN(0x400624, 0xff, 0); TEST_BITSCAN(0x400628, 0x7fffffff, 0); TEST_BITSCAN(0x40062c, 0x7fffffff, 0); TEST_BITSCAN(0x400680, 0x0000ffff, 0); TEST_BITSCAN(0x400684, 0x0011ffff, 0); int i; for (i = 0; i < 1000; i++) { uint32_t orig = jrand48(ctx->rand48); nva_wr32(ctx->cnum, 0x400630, orig); uint32_t exp = orig & 0x7f800000; if (orig & 0x80000000) exp = 0; uint32_t real = nva_rd32(ctx->cnum, 0x400630); if (real != exp) { printf("BETA scan mismatch: orig %08x expected %08x real %08x\n", orig, exp, real); return HWTEST_RES_FAIL; } } return HWTEST_RES_PASS; }
static int threshold_gen_intr_dir(struct hwtest_ctx *ctx, struct therm_threshold *thrs, int dir) { int temp, lower_thrs, higher_thrs, tmp; temp = nva_rd32(ctx->cnum, 0x20014) & 0xffff; lower_thrs = temp - 0x100; higher_thrs = temp + 0x100; if (lower_thrs < 0) lower_thrs = 0; if (dir > 0) tmp = lower_thrs; else tmp = higher_thrs; threshold_set(ctx, thrs, tmp); /* enable the IRQs */ nva_wr32(ctx->cnum, 0x1140, 0x70000); /* ACK any IRQ */ nva_wr32(ctx->cnum, 0x1100, 0xffffffff); /* ack pbus' IRQs */ /* Generate an IRQ */ if (dir > 0) tmp = higher_thrs; else tmp = lower_thrs; threshold_set(ctx, thrs, tmp); /* necessary */ usleep(1); return HWTEST_RES_PASS; }
static void threshold_reset(struct hwtest_ctx *ctx) { nva_wr32(ctx->cnum, 0x20000, 0); nva_wr32(ctx->cnum, 0x20004, 0); nva_wr32(ctx->cnum, 0x20010, 0x3fff); nva_wr32(ctx->cnum, 0x2001c, 0x3fff0000); }
static int test_scan_clip(struct hwtest_ctx *ctx) { int i; nva_wr32(ctx->cnum, 0x4006a4, 0x0f000111); TEST_BITSCAN(0x400450, 0x0003ffff, 0); TEST_BITSCAN(0x400454, 0x0003ffff, 0); for (i = 0; i < 1000; i++) { int idx = jrand48(ctx->rand48) & 1; uint32_t v0 = jrand48(ctx->rand48); uint32_t v1 = jrand48(ctx->rand48); uint32_t v2 = jrand48(ctx->rand48); nva_wr32(ctx->cnum, 0x400460 + idx * 8, v0); nva_wr32(ctx->cnum, 0x400464 + idx * 8, v1); v0 &= 0x3ffff; v1 &= 0x3ffff; TEST_READ(0x400460 + idx * 8, v0, "v0 %08x v1 %08x", v0, v1); TEST_READ(0x400464 + idx * 8, v1, "v0 %08x v1 %08x", v0, v1); if (jrand48(ctx->rand48) & 1) { nva_wr32(ctx->cnum, 0x400460 + idx * 8, v2); } else { nva_wr32(ctx->cnum, 0x400464 + idx * 8, v2); } v2 &= 0x3ffff; TEST_READ(0x400460 + idx * 8, v1, "v0 %08x v1 %08x v2 %08x", v0, v1, v2); TEST_READ(0x400464 + idx * 8, v2, "v0 %08x v1 %08x v2 %08x", v0, v1, v2); } return HWTEST_RES_PASS; }
uint32_t xt_rd32(int cnum, uint32_t addr) { nva_wr32(cnum, 0x700004, addr); nva_wr32(cnum, 0x70000, 1); while (nva_rd32(cnum, 0x70000)); nva_wr32(cnum, 0x700000, 1); while (nva_rd32(cnum, 0x700000)); return nva_rd32(cnum, 0x700004); }
uint32_t xt_rsr(int cnum, uint32_t sr, uint32_t *status) { nva_wr32(cnum, 0x700004, sr); nva_wr32(cnum, 0x70000, 1); while (nva_rd32(cnum, 0x70000)); nva_wr32(cnum, 0x700000, 3); while (nva_rd32(cnum, 0x700000)); *status = nva_rd32(cnum, 0x70000c); return nva_rd32(cnum, 0x700004); }
void host_xt_wr32(int cnum, uint32_t xt_addr, uint32_t val) { uint32_t host_addr = pbsp_get_host_addr(xt_addr); uint32_t index = pbsp_get_host_index(xt_addr); // printf("0x%x -> 0x%x i 0x%x\n", xt_addr, host_addr, index); nva_wr32(cnum, HOST_XTENSA_INDEX, index); nva_wr32(cnum, host_addr, val); }
void find_ptimer_b12(int cnum) { uint8_t signals_ref_timer[0x100 * 8]; uint8_t signals_tmp[0x100 * 8]; struct signals_comparaison diffs; int i; uint32_t r_9210, r_9400; printf("<PTIMER_B12>\n"); r_9210 = nva_rd32(cnum, 0x9210); r_9400 = nva_rd32(cnum, 0x9400); /* stop the time */ nva_wr32(cnum, 0x9210, 0); nva_wr32(cnum, 0x9400, 0); poll_signals(cnum, signals_ref_timer); nva_wr32(cnum, 0x9400, 0x20000); poll_signals(cnum, signals_tmp); /* restore ptimer */ nva_wr32(cnum, 0x9400, r_9400); nva_wr32(cnum, 0x9210, r_9210); diffs = signals_compare(signals_ref_timer, signals_tmp); if (diffs.diff_count >= 1) { for (i = 0; i < diffs.diff_count; i++) { uint8_t set, signal; set = diffs.differences[i].set; signal = diffs.differences[i].signal; if (diffs.differences[i].set == 0) { if (diffs.differences[i].change == ZERO_TO_ONE) printf("PTIMER_B12: Set %u, signal 0x%.2x\n", set, signal); } else { printf("Unexpected difference: "); print_difference(diffs.differences[i]); } } } else printf("Not found.\n"); signals_comparaison_free(diffs); printf("</PTIMER_B12>\n\n"); }
void time_pcounter_nv84(unsigned int cnum) { printf ("Perf counters:\n"); int i; for (i = 0; i < 8; i++) { nva_wr32(cnum, 0xa7c0 + i * 4, 1); nva_wr32(cnum, 0xa420 + i * 4, 0xffff); } sleep(1); for (i = 0; i < 8; i++) nva_wr32(cnum, 0xa420 + i * 4, 0xffff); for (i = 0; i < 8; i++) printf ("Set %d: %u Hz\n", i, nva_rd32(cnum, 0xa600 + i * 4)); }
uint32_t vram_rd32(int card, uint64_t addr) { if (nva_cards[card].card_type < 3) { return nva_rd32(card, 0x1000000 + addr); } else if (nva_cards[card].card_type < 0x30) { return nva_grd32(nva_cards[card].bar1, addr); } else if (nva_cards[card].card_type < 0x50) { nva_wr32(card, 0x1570, addr); return nva_rd32(card, 0x1574); } else { uint32_t old = nva_rd32(card, 0x1700); nva_wr32(card, 0x1700, addr >> 16); uint32_t res = nva_rd32(card, 0x700000 | (addr & 0xffff)); nva_wr32(card, 0x1700, old); return res; } }
static int test_temperature_enable_state(struct hwtest_ctx *ctx) { uint32_t r010 = nva_mask(ctx->cnum, 0x20010, 0x40000000, 0x40000000); uint32_t temp_disabled, temp_enabled; temp_disabled = nva_rd32(ctx->cnum, 0x20014) & 0x3fff; nva_wr32(ctx->cnum, 0x20010, 0); usleep(20000); temp_enabled = nva_rd32(ctx->cnum, 0x20014) & 0x3fff; nva_wr32(ctx->cnum, 0x20010, r010); if (temp_disabled == 0 && temp_enabled) return HWTEST_RES_PASS; else return HWTEST_RES_FAIL; }
static int test_scan_canvas(struct hwtest_ctx *ctx) { nva_wr32(ctx->cnum, 0x4006a4, 0x0f000111); TEST_BITSCAN(0x400634, 0x01111011, 0); nva_wr32(ctx->cnum, 0x400688, 0x7fff7fff); if(nva_rd32(ctx->cnum, 0x400688) != 0x7fff7fff) { return HWTEST_RES_FAIL; } TEST_BITSCAN(0x400688, 0xffffffff, 0); TEST_BITSCAN(0x40068c, 0x0fff0fff, 0); TEST_BITSCAN(0x400690, 0x0fff0fff, 0); TEST_BITSCAN(0x400694, 0x0fff0fff, 0); TEST_BITSCAN(0x400698, 0x0fff0fff, 0); TEST_BITSCAN(0x40069c, 0x0fff0fff, 0); TEST_BITSCAN(0x4006a0, 0x113, 0); return HWTEST_RES_PASS; }
static int test_scan_debug(struct hwtest_ctx *ctx) { nva_wr32(ctx->cnum, 0x4006a4, 0x0f000111); TEST_BITSCAN(0x400080, 0x11111110, 0); TEST_BITSCAN(0x400084, 0x31111101, 0); TEST_BITSCAN(0x400088, 0x11111111, 0); return HWTEST_RES_PASS; }
uint32_t host_xt_rd32(int cnum, uint32_t xt_addr) { uint32_t host_addr = pbsp_get_host_addr(xt_addr); uint32_t index = pbsp_get_host_index(xt_addr); nva_wr32(cnum, HOST_XTENSA_INDEX, index); return nva_rd32(cnum, host_addr); }
int main(int argc, char **argv) { if (nva_init()) { fprintf (stderr, "PCI init failure!\n"); return 1; } int c; int cnum =0; while ((c = getopt (argc, argv, "c:")) != -1) switch (c) { case 'c': sscanf(optarg, "%d", &cnum); break; } if (cnum >= nva_cardsnum) { if (nva_cardsnum) fprintf (stderr, "No such card.\n"); else fprintf (stderr, "No cards found.\n"); return 1; } int32_t a, b = 4, v = 0, i; if (optind >= argc) { fprintf (stderr, "No address specified.\n"); return 1; } sscanf (argv[optind], "%x", &a); if (optind + 1 < argc) sscanf (argv[optind + 1], "%x", &b); if (optind + 2 < argc) sscanf (argv[optind + 2], "%x", &v); for (i = 0; i < b; i += 4) { nva_wr32(cnum, a+i, v+i); } return 0; }
static void clear_data(void) { #if 0 // Crashes int i, j; for (i = 0; i < sizeof(((struct snap*)0)->bsp); i += 4) nva_wr32(cnum, BSP_OFS(i), 0); for (i = 0; i < 0x40; ++i) { nva_wr32(cnum, PVP(0xffc), i); for (j = 0; j < 0x40; j += 4) nva_wr32(cnum, VUC(j), 0); } nva_wr32(cnum, PVP(0xffc), 0); for (i = 0; i < sizeof(((struct snap*)0)->pvp); i += 4) nva_wr32(cnum, PVP_OFS(i), 0); #endif }
static int test_scan_control(struct hwtest_ctx *ctx) { nva_wr32(ctx->cnum, 0x4006a4, 0x0f000111); TEST_BITSCAN(0x400140, 0x11111111, 0); TEST_BITSCAN(0x400144, 0x00011111, 0); TEST_BITSCAN(0x400180, 0x807fffff, 0); TEST_BITSCAN(0x400190, 0x11010103, 0); return HWTEST_RES_PASS; }
/* vbios should at least be NV_PROM_SIZE bytes long */ int vbios_extract_prom(int cnum, uint8_t *vbios, int *length) { uint32_t pci_cfg_50 = 0; uint32_t ret = EUNK; int i; fprintf(stderr, "Attempt to extract the vbios from card %i (nv%02x) using PROM\n", cnum, nva_cards[cnum].chipset); int32_t prom_offset; int32_t prom_size; int32_t pbus_offset = 0; if (nva_cards[cnum].chipset < 0x03) { prom_offset = 0x610000; prom_size = NV01_PROM_SIZE; } else if (nva_cards[cnum].chipset < 0x04) { prom_offset = 0x110000; prom_size = NV03_PROM_SIZE; } else { if (nva_cards[cnum].chipset < 0x40) pbus_offset = 0x1800; else pbus_offset = 0x88000; prom_offset = 0x300000; prom_size = NV_PROM_SIZE; pci_cfg_50 = nva_rd32(cnum, pbus_offset + 0x50); nva_wr32(cnum, pbus_offset + 0x50, 0); } /* on some 6600GT/6800LE prom reads are messed up. nvclock alleges a * a good read may be obtained by waiting or re-reading (cargocult: 5x) * each byte. we'll hope pramin has something usable instead */ for (i = 0; i < prom_size; i++) vbios[i] = nva_rd8(cnum, prom_offset + i); ret = nv_ckbios(vbios, length); if (nva_cards[cnum].chipset >= 0x04) { nva_wr32(cnum, pbus_offset + 0x50, pci_cfg_50); } return ret; }
/* clock gating */ static int clock_gating_reset(struct hwtest_ctx *ctx) { int i; for (i = 0x20060; i <= 0x20074; i+=4) nva_wr32(ctx->cnum, i, 0); threshold_reset(ctx); return HWTEST_RES_PASS; }
int main(int argc, char **argv) { if (nva_init()) { fprintf (stderr, "PCI init failure!\n"); return 1; } int c; int cnum =0; while ((c = getopt (argc, argv, "c:")) != -1) switch (c) { case 'c': sscanf(optarg, "%d", &cnum); break; } if (cnum >= nva_cardsnum) { if (nva_cardsnum) fprintf (stderr, "No such card.\n"); else fprintf (stderr, "No cards found.\n"); return 1; } uint32_t m, d, ctrl; if (optind + 3 > argc) { fprintf (stderr, "%s: <channel> <method> <data>\n", argv[0]); return 1; } sscanf (argv[optind + 0], "%d", &c); sscanf (argv[optind + 1], "%x", &m); sscanf (argv[optind + 2], "%x", &d); if (nva_cards[cnum].chipset >= 0xd0) { ctrl = nva_rd32(cnum, 0x610700 + (c * 8)); nva_wr32(cnum, 0x610700 + (c * 8), ctrl | 1); nva_wr32(cnum, 0x610704 + (c * 8), d); nva_wr32(cnum, 0x610700 + (c * 8), 0x80000001 | m); while (nva_rd32(cnum, 0x610700 + (c * 8)) & 0x80000000); nva_wr32(cnum, 0x610700 + (c * 8), ctrl); } else if (nva_cards[cnum].chipset == 0x50 || nva_cards[cnum].chipset >= 0x84) { ctrl = nva_rd32(cnum, 0x610300 + (c * 8)); nva_wr32(cnum, 0x610300 + (c * 8), ctrl | 1); nva_wr32(cnum, 0x610304 + (c * 8), d); nva_wr32(cnum, 0x610300 + (c * 8), 0x80000001 | m); while (nva_rd32(cnum, 0x610300 + (c * 8)) & 0x80000000); nva_wr32(cnum, 0x610300 + (c * 8), ctrl); } else { fprintf (stderr, "unsupported chipset\n"); return 1; } return 0; }
static int test_scan_vtx(struct hwtest_ctx *ctx) { int i; nva_wr32(ctx->cnum, 0x4006a4, 0x0f000111); for (i = 0 ; i < 18; i++) { TEST_BITSCAN(0x400400 + i * 4, 0xffffffff, 0); TEST_BITSCAN(0x400480 + i * 4, 0xffffffff, 0); if (i < 14) TEST_BITSCAN(0x400700 + i * 4, 0x01ffffff, 0); } return HWTEST_RES_PASS; }
static int test_clock_gating_force_div_pwm(struct hwtest_ctx *ctx) { int i; clock_gating_reset(ctx); for (i = 0; i < 0x100; i++) { nva_wr32(ctx->cnum, 0x20064, (i << 8) | 2); TEST_READ_MASK(0x20048, 0x2200 | i, 0xffff, "iteration %i/255 failed", i); } return HWTEST_RES_PASS; }
static int test_clock_gating_force_div_only(struct hwtest_ctx *ctx) { int i; clock_gating_reset(ctx); for (i = 1; i < 4; i++) { nva_wr32(ctx->cnum, 0x20064, i); TEST_READ_MASK(0x20048, (i << 12) | 0x200, 0xffff, "iteration %i/4 failed", i); } return HWTEST_RES_PASS; }
static int test_scan_vstate(struct hwtest_ctx *ctx) { nva_wr32(ctx->cnum, 0x4006a4, 0x0f000111); TEST_BITSCAN(0x400640, 0xf1ff11ff, 0); TEST_BITSCAN(0x400644, 0x03177331, 0); TEST_BITSCAN(0x400648, 0x30ffffff, 0); TEST_BITSCAN(0x40064c, 0x30ffffff, 0); TEST_BITSCAN(0x400650, 0x111ff1ff, 0); TEST_BITSCAN(0x400654, 0xffffffff, 0); TEST_BITSCAN(0x400658, 0xffff00ff, 0); TEST_BITSCAN(0x40065c, 0xffff0113, 0); return HWTEST_RES_PASS; }
static ptime_t pms_launch(int cnum, struct pms_ucode* pms, ptime_t *wall_time) { u32 pbus1098; u32 pms_data, pms_kick; ptime_t ptimer_start, ptimer_end; struct timeval wall_start, wall_end; int i; if (nva_cards[cnum].chipset < 0x90) { pms_data = 0x001400; pms_kick = 0x00000003; } else { pms_data = 0x080000; pms_kick = 0x00000001; } /* upload ucode */ pbus1098 = nva_mask(cnum, 0x001098, 0x00000008, 0x00000000); nva_wr32(cnum, 0x001304, 0x00000000); for (i = 0; i < pms->len / 4; i++) nva_wr32(cnum, pms_data + (i * 4), pms->ptr.u32[i]); nva_wr32(cnum, 0x001098, pbus1098 | 0x18); /* and run it! */ gettimeofday(&wall_start, NULL); ptimer_start = get_time(cnum); nva_wr32(cnum, 0x00130c, pms_kick); /* Wait for completion */ while (nva_rd32(cnum, 0x001308) & 0x100); ptimer_end = get_time(cnum); gettimeofday(&wall_end, NULL); if (wall_time) *wall_time = time_diff_us(wall_start, wall_end); return ptimer_end - ptimer_start - (get_time(cnum) - get_time(cnum)); }
void time_pwm_nv50(unsigned int cnum) { int i; for (i = 0; i < 2; i++) { uint32_t a = 0xe114 + i * 8; uint32_t b = a + 4; uint32_t save0 = nva_rd32(cnum, a); uint32_t save1 = nva_rd32(cnum, b); struct timeval start, end; nva_wr32(cnum, a, 0x200000); nva_wr32(cnum, b, 0x80080000); while (nva_rd32(cnum, b) & 0x80000000); nva_wr32(cnum, b, 0x80080000); while (nva_rd32(cnum, b) & 0x80000000); gettimeofday(&start, NULL); nva_wr32(cnum, b, 0x80080000); while (nva_rd32(cnum, b) & 0x80000000); gettimeofday(&end, NULL); uint64_t td = (time_diff_us(start, end)); printf("PWM %d: %dHz\n", i, (int)(1000000ll * 0x200000 / td)); nva_wr32(cnum, a, save0); nva_wr32(cnum, b, 0x80000000 | save1); } }
void nv50_graph_reset() { nva_wr32(cnum, 0x200, 0xffffefff); nva_wr32(cnum, 0x200, 0xffffffff); nva_wr32(cnum, 0x400040, -1); nva_wr32(cnum, 0x400040, 0); nva_wr32(cnum, 0x400080, 0x3083c2); nva_wr32(cnum, 0x400088, 0x6fe7); }
int main(int argc, char **argv) { int c, cnum = 0; if (nva_init()) { fprintf (stderr, "PCI init failure!\n"); return 1; } /* Arguments parsing */ while ((c = getopt (argc, argv, "c:")) != -1) switch (c) { case 'c': sscanf(optarg, "%d", &cnum); break; } if (cnum >= nva_cardsnum) { if (nva_cardsnum) fprintf (stderr, "No such card.\n"); else fprintf (stderr, "No cards found.\n"); return 1; } if (nva_cards[cnum].chipset < 0x10 || nva_cards[cnum].chipset >= 0xc0) { fprintf(stderr, "The chipset nv%x isn't currently supported\n", nva_cards[cnum].chipset); return 1; } /* Init */ nva_wr32(cnum, 0x200, 0xffffffff); printf("Chipset nv%x:\n\n", nva_cards[cnum].chipset); poll_signals(cnum, signals_ref); find_counter_noise(cnum); find_ptimer_b12(cnum); find_host_mem_read_write(cnum); find_mmio_read_write(cnum, 0x200, "MMIO"); find_mmio_read_write(cnum, 0x2210, "MMIO_PFIFO"); find_mmio_read_write(cnum, 0x610384, "MMIO_PDISPLAY"); find_mmio_read_write(cnum, 0x6666, "MMIO_INVALID"); find_pgraphIdle_and_interrupt(cnum); find_ctxCtlFlags(cnum); return 0; }
int main(int argc, char **argv) { if (nva_init()) { fprintf (stderr, "PCI init failure!\n"); return 1; } int c; int cnum =0; while ((c = getopt (argc, argv, "c:")) != -1) switch (c) { case 'c': sscanf(optarg, "%d", &cnum); break; } if (cnum >= nva_cardsnum) { if (nva_cardsnum) fprintf (stderr, "No such card.\n"); else fprintf (stderr, "No cards found.\n"); return 1; } int32_t a, b = 4, i; if (optind >= argc) { fprintf (stderr, "No address specified.\n"); return 1; } sscanf (argv[optind], "%x", &a); if (optind + 1 < argc) sscanf (argv[optind + 1], "%x", &b); nva_wr32(cnum, 0x1700, 0x30); int ls = 1; while (b > 0) { uint32_t z[4]; int s = 0; for (i = 0; i < 16 && i < b; i+=4) if ((z[i/4] = xt_rd32(cnum, a+i))) s = 1; if (s) { ls = 1; printf ("%08x:", a); for (i = 0; i < 16 && i < b; i+=4) { printf (" %08x", z[i/4]); } printf ("\n"); } else { if (ls) printf ("...\n"), ls = 0; } a+=16; b-=16; } return 0; }
void time_pcounter_nv40(unsigned int cnum) { printf ("Perf counters:\n"); int i; uint32_t debug1 = nva_rd32(cnum, 0x400084); for (i = 0; i < 8; i++) { nva_wr32(cnum, 0xa7c0 + i * 4, 0x1); nva_wr32(cnum, 0xa460 + i * 4, 0); nva_wr32(cnum, 0xa4a0 + i * 4, 0); nva_wr32(cnum, 0xa4e0 + i * 4, 0); nva_wr32(cnum, 0xa500 + i * 4, 0); nva_wr32(cnum, 0xa520 + i * 4, 0); nva_wr32(cnum, 0xa420 + i * 4, 0xffff); nva_wr32(cnum, 0x400084, debug1 | 0x20); sleep(1); nva_wr32(cnum, 0x400084, debug1 | 0x20); printf ("Set %d: %u Hz\n", i, nva_rd32(cnum, 0xa600 + i * 4)); } }