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>