예제 #1
0
파일: apic_timer.c 프로젝트: 0ida/coreboot
void timer_monotonic_get(struct mono_time *mt)
{
	uint32_t current_tick;
	uint32_t usecs_elapsed;
	uint32_t timer_fsb;

	if (!mono_counter.initialized) {
		init_timer();
		timer_fsb = get_timer_fsb();
		/* An FSB frequency of 200Mhz provides a 20 second polling
		 * interval between timer_monotonic_get() calls before wrap
		 * around occurs. */
		if (timer_fsb > 200)
			printk(BIOS_WARNING,
			       "apic timer freq (%d) may be too fast.\n",
			       timer_fsb);
		mono_counter.last_value = lapic_read(LAPIC_TMCCT);
		mono_counter.initialized = 1;
	}

	timer_fsb = get_timer_fsb();
	current_tick = lapic_read(LAPIC_TMCCT);
	/* Note that the APIC timer counts down. */
	usecs_elapsed = (mono_counter.last_value - current_tick) / timer_fsb;

	/* Update current time and tick values only if a full tick occurred. */
	if (usecs_elapsed) {
		mono_time_add_usecs(&mono_counter.time, usecs_elapsed);
		mono_counter.last_value = current_tick;
	}

	/* Save result. */
	*mt = mono_counter.time;
}
예제 #2
0
파일: delay_tsc.c 프로젝트: 0ida/coreboot
void timer_monotonic_get(struct mono_time *mt)
{
	uint64_t current_tick;
	uint64_t ticks_elapsed;

	if (!mono_counter.initialized) {
		init_timer();
		mono_counter.last_value = rdtscll();
		mono_counter.initialized = 1;
	}

	current_tick = rdtscll();
	ticks_elapsed = current_tick - mono_counter.last_value;

	/* Update current time and tick values only if a full tick occurred. */
	if (ticks_elapsed >= clocks_per_usec) {
		uint64_t usecs_elapsed;

		usecs_elapsed = ticks_elapsed / clocks_per_usec;
		mono_time_add_usecs(&mono_counter.time, (long)usecs_elapsed);
		mono_counter.last_value = current_tick;
	}

	/* Save result. */
	*mt = mono_counter.time;
}
예제 #3
0
파일: delay_tsc.c 프로젝트: siro20/coreboot
void timer_monotonic_get(struct mono_time *mt)
{
	uint64_t current_tick;
	uint64_t ticks_elapsed;
	unsigned long ticks_per_usec;
	struct monotonic_counter *mono_counter;

	mono_counter = get_monotonic_context();
	if (!mono_counter->initialized) {
		init_timer();
		mono_counter->last_value = rdtscll();
		mono_counter->initialized = 1;
	}

	current_tick = rdtscll();
	ticks_elapsed = current_tick - mono_counter->last_value;
	ticks_per_usec = get_clocks_per_usec();

	/* Update current time and tick values only if a full tick occurred. */
	if (ticks_elapsed >= ticks_per_usec) {
		uint64_t usecs_elapsed;

		usecs_elapsed = ticks_elapsed / ticks_per_usec;
		mono_time_add_usecs(&mono_counter->time, (long)usecs_elapsed);
		mono_counter->last_value = current_tick;
	}

	/* Save result. */
	*mt = mono_counter->time;
}
예제 #4
0
파일: fb.c 프로젝트: 0ida/coreboot
/*
 * Configure DP in slave mode and wait for video stream.
 *
 * param dp		pointer to main s5p-dp structure
 * param video_info	pointer to main video_info structure.
 * return		status
 */
static int s5p_dp_config_video(struct s5p_dp_device *dp,
			       struct video_info *video_info)
{
	int timeout = 0;
	struct exynos5_dp *base = dp->base;
	struct mono_time start, current, end;
	s5p_dp_config_video_slave_mode(dp, video_info);

	s5p_dp_set_video_color_format(dp, video_info->color_depth,
				      video_info->color_space,
				      video_info->dynamic_range,
				      video_info->ycbcr_coeff);

	if (s5p_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
		printk(BIOS_DEBUG, "PLL is not locked yet.\n");
		return -ERR_PLL_NOT_UNLOCKED;
	}

	timer_monotonic_get(&start);
	end = current = start;
	mono_time_add_usecs(&end, STREAM_ON_TIMEOUT * USECS_PER_MSEC);
	do {
		if (s5p_dp_is_slave_video_stream_clock_on(dp) == 0) {
			timeout++;
			break;
		}
		timer_monotonic_get(&current);
	} while (mono_time_before(&current, &end));

	if (!timeout) {
		printk(BIOS_ERR, "Video Clock Not ok after %ldus.\n",
				mono_time_diff_microseconds(&start, &end));
		return -ERR_VIDEO_CLOCK_BAD;
	}

	/* Set to use the register calculated M/N video */
	s5p_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);

	clrbits_le32(&base->video_ctl_10, FORMAT_SEL);

	/* Disable video mute */
	clrbits_le32(&base->video_ctl_1, HDCP_VIDEO_MUTE);

	/* Configure video slave mode */
	s5p_dp_enable_video_master(dp);

	/* Enable video */
	setbits_le32(&base->video_ctl_1, VIDEO_EN);
	timeout = s5p_dp_is_video_stream_on(dp);

	if (timeout) {
		printk(BIOS_DEBUG, "Video Stream Not on\n");
		return -ERR_VIDEO_STREAM_BAD;
	}

	return 0;
}
예제 #5
0
파일: timer.c 프로젝트: 0ida/coreboot
/* delay x useconds */
void udelay(unsigned usec)
{
	struct mono_time current, end;

	if (!thread_yield_microseconds(usec))
		return;

	timer_monotonic_get(&current);
	end = current;
	mono_time_add_usecs(&end, usec);

	if (mono_time_after(&current, &end)) {
		printk(BIOS_EMERG, "udelay: 0x%08x is impossibly large\n",
				usec);
		/* There's not much we can do if usec is too big. Use a long,
		 * paranoid delay value and hope for the best... */
		end = current;
		mono_time_add_usecs(&end, USECS_PER_SEC);
	}

	while (mono_time_before(&current, &end))
		timer_monotonic_get(&current);
}
예제 #6
0
void timer_monotonic_get(struct mono_time *mt)
{
	uint32_t current_tick;
	uint32_t usecs_elapsed;

	if (!mono_counter.initialized) {
		mono_counter.last_value = read_counter_msr();
		mono_counter.initialized = 1;
	}

	current_tick = read_counter_msr();
	usecs_elapsed = (current_tick - mono_counter.last_value) / 24;

	/* Update current time and tick values only if a full tick occurred. */
	if (usecs_elapsed) {
		mono_time_add_usecs(&mono_counter.time, usecs_elapsed);
		mono_counter.last_value = current_tick;
	}

	/* Save result. */
	*mt = mono_counter.time;
}