Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Aug 2014 01:36:48 GMT
From:      astarasikov@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r271977 - soc2014/astarasikov/head/sys/arm/goldfish
Message-ID:  <201408060136.s761amQY015527@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: astarasikov
Date: Wed Aug  6 01:36:48 2014
New Revision: 271977
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=271977

Log:
  [goldfish]: working timer (finally, fixes random & init)
  

Modified:
  soc2014/astarasikov/head/sys/arm/goldfish/goldfish_timer.c

Modified: soc2014/astarasikov/head/sys/arm/goldfish/goldfish_timer.c
==============================================================================
--- soc2014/astarasikov/head/sys/arm/goldfish/goldfish_timer.c	Wed Aug  6 01:36:05 2014	(r271976)
+++ soc2014/astarasikov/head/sys/arm/goldfish/goldfish_timer.c	Wed Aug  6 01:36:48 2014	(r271977)
@@ -59,12 +59,7 @@
 	GOLDFISH_TIMER_CLEAR_ALARM = 0x14,
 };
 
-#define CLOCK_TICK_RATE ((50 * 1000 * 1000) / 16)
-
-#define	DEFAULT_FREQUENCY	1000000
-
-#define	DEFAULT_DIVISOR		16
-#define	DEFAULT_CONTROL_DIV	TIMER_CONTROL_DIV16
+#define CLOCK_TICK_RATE (1000 * 1000 * 1000)
 
 struct goldfish_timer_softc {
 	struct resource*	mem_res;
@@ -78,6 +73,9 @@
 	struct eventtimer	et;
 };
 
+static int goldfish_timer_initialized;
+static struct goldfish_timer_softc *goldfish_timer_sc;
+
 #define goldfish_timer_tc_read_4(reg)		\
 	bus_space_read_4(sc->bst, sc->bsh, reg)
 
@@ -98,7 +96,7 @@
 static unsigned
 goldfish_timer_tc_get_timecount(struct timecounter *tc)
 {
-	return (unsigned)goldfish_timer_read_counter64(tc);
+	return (unsigned)(goldfish_timer_read_counter64(tc));
 }
 
 static int
@@ -109,15 +107,15 @@
 
 	if (first != 0) {
 		sc->et_enabled = 1;
-
 		count = ((uint64_t)et->et_frequency * first);
-
 		goldfish_timer_tc_write_4(GOLDFISH_TIMER_ALARM_HIGH, count >> 32);
 		goldfish_timer_tc_write_4(GOLDFISH_TIMER_ALARM_LOW, count & 0xffffffff);
-		printf("setting timer to %llu\n", count);
-
 		return (0);
 	} 
+	else {
+		goldfish_timer_tc_write_4(GOLDFISH_TIMER_ALARM_HIGH, 0);
+		goldfish_timer_tc_write_4(GOLDFISH_TIMER_ALARM_LOW, 0);
+	}
 
 	if (period != 0) {
 		panic("period");
@@ -141,7 +139,7 @@
 goldfish_timer_intr(void *arg)
 {
 	struct goldfish_timer_softc *sc = arg;
-	//goldfish_timer_tc_write_4(GOLDFISH_TIMER_CLEAR_INTERRUPT, 1);
+	goldfish_timer_tc_write_4(GOLDFISH_TIMER_CLEAR_INTERRUPT, 1);
 
 	if (sc->et_enabled && sc->et.et_active)
 		sc->et.et_event_cb(&sc->et, sc->et.et_arg);
@@ -166,26 +164,29 @@
 {
 	struct goldfish_timer_softc *sc = device_get_softc(dev);
 	int mem_rid = 0, irq_rid = 0;
-	
+
 	/* TODO: get frequency from FDT */
-	sc->sysclk_freq = CLOCK_TICK_RATE * 16;
+	sc->sysclk_freq = CLOCK_TICK_RATE;
 
 	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &mem_rid, RF_ACTIVE);
-	if (sc->mem_res == NULL)
+	if (sc->mem_res == NULL) {
 		goto fail;
+	}
 
 	sc->bst = rman_get_bustag(sc->mem_res);
 	sc->bsh = rman_get_bushandle(sc->mem_res);
 	/* Request the IRQ resources */
 	sc->irq_res =  bus_alloc_resource_any(dev, SYS_RES_IRQ, &irq_rid, RF_ACTIVE);
-	if (sc->irq_res == NULL)
+	if (sc->irq_res == NULL) {
 		goto fail;
+	}
 
 	/* Setup and enable the timer */
 	if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CLK,
-			goldfish_timer_intr, NULL, sc,
-			&sc->intr_hl) != 0)
+			goldfish_timer_intr, NULL, sc, &sc->intr_hl) != 0)
+	{
 		goto fail;
+	}
 
 	/*
 	 * Timer 1, timecounter
@@ -198,25 +199,33 @@
 	sc->tc.tc_quality = 200;
 	sc->tc.tc_priv = sc;
 
-	goldfish_timer_tc_write_4(GOLDFISH_TIMER_CLEAR_ALARM, 1);
-	goldfish_timer_tc_write_4(GOLDFISH_TIMER_CLEAR_INTERRUPT, 1);
-
-	tc_init(&sc->tc);
-
 	/* 
 	 * Timer 2, event timer
 	 */
 	sc->et_enabled = 0;
 	sc->et.et_name = "Goldfish Event Timer";
-	sc->et.et_flags = /*ET_FLAGS_PERIODIC |*/ ET_FLAGS_ONESHOT;
+	sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
 	sc->et.et_frequency = CLOCK_TICK_RATE;
 	sc->et.et_quality = 200;
-	sc->et.et_min_period = (0x00000001LLU << 32) / sc->et.et_frequency;
-	sc->et.et_max_period = (0xffffffffLLU << 32) / sc->et.et_frequency;
+	sc->et.et_min_period = (0x00000002LLU << 32) / sc->et.et_frequency;
+	sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
 	sc->et.et_start = goldfish_timer_start;
 	sc->et.et_stop = goldfish_timer_stop;
 	sc->et.et_priv = sc;
+
+	goldfish_timer_tc_write_4(GOLDFISH_TIMER_CLEAR_ALARM, 1);
+	goldfish_timer_tc_write_4(GOLDFISH_TIMER_CLEAR_INTERRUPT, 1);
+
 	et_register(&sc->et);
+	tc_init(&sc->tc);
+
+	/* keep a global reference to sc to avoid lookup during DELAY */
+	goldfish_timer_sc = sc;
+	goldfish_timer_initialized = 1;
+
+	/* trigger an interrupt */
+	goldfish_timer_tc_write_4(GOLDFISH_TIMER_ALARM_HIGH, 0);
+	goldfish_timer_tc_write_4(GOLDFISH_TIMER_ALARM_LOW, 0);
 
 	return (0);
 
@@ -233,7 +242,7 @@
 static device_method_t goldfish_timer_methods[] = {
 	DEVMETHOD(device_probe,		goldfish_timer_probe),
 	DEVMETHOD(device_attach,	goldfish_timer_attach),
-	{ 0, 0 }
+	DEVMETHOD_END,
 };
 
 static driver_t goldfish_timer_driver = {
@@ -251,12 +260,9 @@
 {
 	uint64_t counts;
 	uint64_t now, end;
-	device_t timer_dev;
-	struct goldfish_timer_softc *sc;
-
-	timer_dev = devclass_get_device(goldfish_timer_devclass, 0);
 
-	if (timer_dev == NULL) {
+	/* Let us uncomment this as soon as rootfs mounts and init starts */
+	if (!goldfish_timer_initialized || !goldfish_timer_sc) {
 		/*
 		 * Timer is not initialized yet
 		 */
@@ -267,20 +273,19 @@
 		return;
 	}
 
-	sc = device_get_softc(timer_dev);
-
 	/* Get the number of times to count */
-	counts = usec * ((sc->tc.tc_frequency / 1000000) + 1);
+	counts = usec * ((goldfish_timer_sc->tc.tc_frequency / 1000000) + 1);
 
-	now = goldfish_timer_read_counter64(&sc->tc);
+	now = goldfish_timer_read_counter64(&goldfish_timer_sc->tc);
 	end = now + counts;
 
 	while (now < end) {
-		now = goldfish_timer_read_counter64(&sc->tc);
+		now = goldfish_timer_read_counter64(&goldfish_timer_sc->tc);
 	}
 }
 
 void
 cpu_initclocks(void)
 {
+	cpu_initclocks_bsp();
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408060136.s761amQY015527>