Example #1
0
static int threshold_check_state(struct hwtest_ctx *ctx, const struct therm_threshold *thrs) {
	int i, dir, temp, exp_state;

	threshold_reset(ctx);
	nva_mask(ctx->cnum, 0x20010, 0x80000000, 0x80000000);

	i = 1;
	dir = 1;
	while (i > 0) {
		/* set the threshold */
		threshold_set(ctx, thrs, i);

		/* calculate the expected state */
		do {
			temp = nva_rd32(ctx->cnum, 0x20014) & 0x3fff;
			if (thrs->dir_inverted)
				exp_state = (temp < i);
			else
				exp_state = (temp > i);
		} while (temp != (nva_rd32(ctx->cnum, 0x20014) & 0x3fff));

		/* check the state */
		TEST_READ_MASK(thrs->dir_addr, exp_state << thrs->dir_status_bit, 1 << thrs->dir_status_bit,
			       "invalid state at temperature %i: dir (%i), threshold (%i)", temp, dir, i);

		if (i == 0x3fff)
			dir = -1;
		i += dir;
	}

	return HWTEST_RES_PASS;
}
Example #2
0
static int test_threshold_crit_intr_both_disabled(struct hwtest_ctx *ctx) {
	nva_mask(ctx->cnum, 0x20010, 0x80000000, 0x00000000);
	if (threshold_check_intr_both(ctx, &nv50_therm_thresholds[therm_threshold_crit]) == HWTEST_RES_FAIL)
		return HWTEST_RES_PASS;
	else
		return HWTEST_RES_FAIL;
}
Example #3
0
void nv40_stop_monitoring(int cnum, int set, uint8_t *signals, uint32_t *real_signals, uint32_t *cycles)
{
	uint32_t cycles_cnt, s[4];
	uint8_t w_s[4];
	int i;

	/* readout */
	nva_mask(cnum, 0x400084, 0x0, 0x20);

	w_s[0] = nva_rd32(cnum, 0xa400 + set * 4);
	w_s[1] = nva_rd32(cnum, 0xa440 + set * 4);
	w_s[2] = nva_rd32(cnum, 0xa480 + set * 4);
	w_s[3] = nva_rd32(cnum, 0xa4c0 + set * 4);

	cycles_cnt = nva_rd32(cnum, 0xa600 + set * 4);
	s[0] = nva_rd32(cnum, 0xa700 + set * 4);
	s[1] = nva_rd32(cnum, 0xa6c0 + set * 4);
	s[2] = nva_rd32(cnum, 0xa680 + set * 4);
	s[3] = nva_rd32(cnum, 0xa740 + set * 4);

	for (i = 0; i < 4; i++) {
		if (signals)
			SIGNAL_VALUE(signals, set, w_s[i]) = s[i] * 100 / cycles_cnt;
		if (real_signals)
			SIGNAL_VALUE(real_signals, set, w_s[i]) = s[i];
		if (cycles)
			SIGNAL_VALUE(cycles, set, w_s[i]) = cycles_cnt;
	}
}
Example #4
0
void find_ctxCtlFlags(int cnum)
{
	uint8_t signals_ref_ctx[0x100 * 8];
	uint8_t signals_tmp[0x100 * 8];
	struct signals_comparaison diffs;
	int bit, i;
	uint32_t r_400824 = nva_rd32(cnum, 0x400824);

	printf("<CTXCTL FLAGS>\n");

	nva_mask(cnum, 0x400824, 0xf0000000, 0);
	poll_signals(cnum, signals_ref_ctx);

	for (bit = 28; bit < 32; bit++) {
		nva_mask(cnum, 0x400824, 0xf0000000, 1 << bit);

		poll_signals(cnum, signals_tmp);
		diffs = signals_compare(signals_ref_ctx, 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 == 1) {
					if (diffs.differences[i].change == ZERO_TO_ONE)
						printf("CTXCTL flag 0x%.2x: Set %u, signal 0x%.2x\n", bit, set, signal);
				} else {
					printf("Unexpected difference: ");
					print_difference(diffs.differences[i]);
				}
			}
		} else
			printf("Not found. Please re-run when the GPU is idle.\n");

		signals_comparaison_free(diffs);
	}

	nva_wr32(cnum, 0x400824, r_400824);

	printf("</CTXCTL FLAGS>\n\n");
}
Example #5
0
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;

	nva_mask(ctx->cnum, thrs->thrs_addr, thrs->thrs_mask, 
		 (tmp << thrs->thrs_lshift) & thrs->thrs_mask); 
	
	/* 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;
	nva_mask(ctx->cnum, thrs->thrs_addr, thrs->thrs_mask, 
		 (tmp << thrs->thrs_lshift) & thrs->thrs_mask); 

	/* necessary */
	usleep(1);

	return HWTEST_RES_PASS;
}
Example #6
0
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;
}
Example #7
0
static int nv50_threshold_filter(struct hwtest_ctx *ctx, const struct therm_threshold *thrs)
{
	uint8_t div, cycles;
	uint64_t before;
	uint64_t after;


	/* get the data */
	for (div = 0; div < 4; div++) {
		for (cycles = 1; cycles < 3; cycles++) {
			threshold_reset(ctx);
			nva_mask(ctx->cnum, 0x20010, 0x80000000, 0x80000000);

			threshold_filter_set(ctx, thrs, 0, 0);

			threshold_set(ctx, thrs, 0x3fff);

			nva_wr32(ctx->cnum, 0x1100, 0x70000);
			threshold_set_intr_dir(ctx, thrs, 3);
			threshold_filter_set(ctx, thrs, div, (cycles * 0x7f));

			before = get_time(ctx->cnum);

			threshold_set(ctx, thrs, 10);
			while ((nva_rd32(ctx->cnum, 0x1100) & 0x70000) == 0);

			after = get_time(ctx->cnum);


			uint64_t time = after - before;
			double clock_hz = (1000000.0 / (16.0 * pow(16, div)));
			double expected_time = (1.0 / clock_hz) * cycles * 0x7f * 1e9;

			double prediction_error = abs(time - expected_time) * 100.0 / expected_time;

			if (prediction_error > 5.0) {
				printf("div %x => %f, cycles 0x%x: delay %"PRIu64"; expected delay %.0f (prediction_error = %f%%), clock_hz = %f\n",
					div, 32 * pow(16, div), cycles * 0x7f, time, expected_time, prediction_error, clock_hz);
				return HWTEST_RES_FAIL;
			}
		}
	}

	return HWTEST_RES_PASS;
}
Example #8
0
void nv40_start_monitoring(int cnum, int set, int s1, int s2, int s3, int s4)
{
	nva_wr32(cnum, 0xa7c0 + set * 4, 0x1);
	nva_wr32(cnum, 0xa500 + set * 4, 0);
	nva_wr32(cnum, 0xa520 + set * 4, 0);

	nva_wr32(cnum, 0xa400 + set * 4, s1);
	nva_wr32(cnum, 0xa440 + set * 4, s2);
	nva_wr32(cnum, 0xa480 + set * 4, s3);
	nva_wr32(cnum, 0xa4c0 + set * 4, s4);

	nva_wr32(cnum, 0xa420 + set * 4, 0xaaaa);
	nva_wr32(cnum, 0xa460 + set * 4, 0xaaaa);
	nva_wr32(cnum, 0xa4a0 + set * 4, 0xaaaa);
	nva_wr32(cnum, 0xa4e0 + set * 4, 0xaaaa);

	/* reset the counters */
	nva_mask(cnum, 0x400084, 0x20, 0x20);
}
Example #9
0
static int test_clock_gating_thermal_protect_crit(struct hwtest_ctx *ctx) {
	int temp, lower_thrs;
	uint8_t rnd_div = 1 + (rand() % 6);
	uint8_t rnd_pwm = 1 + (rand() % 0xfe);

	clock_gating_reset(ctx);

	temp = nva_rd32(ctx->cnum, 0x20014) & 0x3fff;
	lower_thrs = temp - 0x200; /* just to be sure the threshold is under the current temp */
	if (lower_thrs < 0)
		lower_thrs = 0;

	nva_mask(ctx->cnum, 0x20010, 0x80003fff, 0x80000000 | lower_thrs);
	nva_wr32(ctx->cnum, 0x20060, (rnd_pwm << 8) | rnd_div); /* div = rnd_div */

	TEST_READ_MASK(0x20048, 0x800, 0x800, "THERMAL_PROTECT_DIV_ACTIVE is not active!%s", "");
	TEST_READ_MASK(0x20048, rnd_pwm, 0xff, "PWM isn't %i", rnd_pwm);
	TEST_READ_MASK(0x20048, rnd_div << 12, 0x7000, "divisor isn't %i", rnd_div);

	return HWTEST_RES_PASS;
}
Example #10
0
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));
}
Example #11
0
static int test_threshold_crit_intr_both(struct hwtest_ctx *ctx) {
	threshold_reset(ctx);
	nva_mask(ctx->cnum, 0x20010, 0x80000000, 0x80000000);
	return threshold_check_intr_both(ctx, &nv50_therm_thresholds[therm_threshold_crit]);
}
Example #12
0
/* calibration */
static void start_sensor(struct hwtest_ctx *ctx) {
	nva_mask(ctx->cnum, 0x20010, 0x40000000, 0x0);
	usleep(20000);
}
Example #13
0
static void threshold_filter_set(struct hwtest_ctx *ctx, const struct therm_threshold *thrs, uint8_t div, uint8_t cycles)
{
	uint32_t filter = (div << 8) | cycles;
	nva_mask(ctx->cnum, thrs->thrs_filter_addr, thrs->thrs_filter_mask,
			 (filter << thrs->thrs_filter_lshift) & thrs->thrs_filter_mask);
}
Example #14
0
static void threshold_set(struct hwtest_ctx *ctx, const struct therm_threshold *thrs, uint16_t temp)
{
	/* set the irq threshold */
	nva_mask(ctx->cnum, thrs->thrs_addr, thrs->thrs_mask,
			 (temp << thrs->thrs_lshift) & thrs->thrs_mask);
}
Example #15
0
void find_pgraphIdle_and_interrupt(int cnum)
{
	unsigned char signals_idle[0x100 * 8];
	struct signals_comparaison diffs;
	int i;

	uint32_t r_400500, r_400808, r_40013c;

	printf("<PGRAPH_IDLE/INTERRUPT> /!\\ no drivers should be loaded!\n");

	/* safety check:  */
	if (nva_rd32(cnum, 0x140) == 1) {
		printf("You shouldn't run this tool while a driver is running\n");
		goto error;
	}

	/* reboot PGRAPH */
	nva_mask(cnum, 0x200, 0x00201000, 0x00000000);
	nva_mask(cnum, 0x200, 0x00201000, 0x00201000);

	r_400500 =  nva_rd32(cnum, 0x400500);
	r_400808 = nva_rd32(cnum, 0x400808);
	r_40013c = nva_rd32(cnum, 0x40013c);

	/* generate an illegal method IRQ
	 * that will pull the PGRAP_IDLE signal down and the PGRAPH_INTERRUPT up
	 *
	 * neither nouveau or nvidia should be loaded as they would ack the interrupt
	 * straight away.
	 */
	nva_wr32(cnum, 0x400500, 0x10001);
	nva_wr32(cnum, 0x400808, 0xa00000fc);
	nva_wr32(cnum, 0x40013c, 0xffffffff);

	poll_signals(cnum, signals_idle);
	diffs = signals_compare(signals_ref, signals_idle);

	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 == 1) {
				if (diffs.differences[i].change == ONE_TO_ZERO)
					printf("PGRAPH_IDLE: Set %u, signal 0x%.2x\n", set, signal);
				else if (diffs.differences[i].change == ZERO_TO_ONE)
					printf("PGRAPH_INTERRUPT: Set %u, signal 0x%.2x\n", set, signal);
			} else {
				printf("Unexpected difference: ");
				print_difference(diffs.differences[i]);
			}
		}

		signals_comparaison_free(diffs);
	} else
		printf("Not found. Please re-run when the GPU is idle.\n");

	/* restore our mess */
	nva_wr32(cnum, 0x400500, r_400500);
	nva_wr32(cnum, 0x400808, r_400808);
	nva_wr32(cnum, 0x40013c, r_40013c);

	/* ACK all PGRAPH's interrupts */
	nva_wr32(cnum, 0x400100, 0xffffffff);

error:
	printf("</PGRAPH_IDLE/INTERRUPT>\n\n");
}