void cpu_initclocks(void) { struct s3c24x0_softc *sc = (struct s3c24x0_softc *)s3c2xx0_softc; long tc; struct resource *irq; int rid = 0; void *ihl; int err, prescaler; int pclk = s3c2xx0_softc->sc_pclk; bus_space_tag_t iot = sc->sc_sx.sc_iot; bus_space_handle_t ioh = sc->sc_timer_ioh; uint32_t reg; device_t dev = timer_softc.dev; /* We have already been initialized */ if (timer4_reload_value != 0) return; #define time_constant(hz) (TIMER_FREQUENCY(pclk) /(hz)/ prescaler) #define calc_time_constant(hz) \ do { \ prescaler = 1; \ do { \ ++prescaler; \ tc = time_constant(hz); \ } while( tc > 65536 ); \ } while(0) /* Use the channels 4 and 3 for hardclock and statclock, respectively */ /* stop all timers */ bus_space_write_4(iot, ioh, TIMER_TCON, 0); /* calc suitable prescaler value */ calc_time_constant(hz); timer4_prescaler = prescaler; timer4_reload_value = TIMER_FREQUENCY(pclk) / hz / prescaler; timer4_mseccount = TIMER_FREQUENCY(pclk)/timer4_prescaler/1000 ; bus_space_write_4(iot, ioh, TIMER_TCNTB(4), ((prescaler - 1) << 16) | (timer4_reload_value - 1)); printf("clock: hz=%d PCLK=%d prescaler=%d tc=%ld\n", hz, pclk, prescaler, tc); irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, S3C24X0_INT_TIMER4, S3C24X0_INT_TIMER4, 1, RF_ACTIVE); if (!irq) panic("Unable to allocate the clock irq handler.\n"); err = bus_setup_intr(dev, irq, INTR_TYPE_CLK, clock_intr, NULL, NULL, &ihl); if (err != 0) panic("Unable to setup the clock irq handler.\n"); /* set prescaler1 */ reg = bus_space_read_4(iot, ioh, TIMER_TCFG0); bus_space_write_4(iot, ioh, TIMER_TCFG0, (reg & ~0xff00) | ((prescaler-1) << 8)); /* divider 1/16 for ch #4 */ reg = bus_space_read_4(iot, ioh, TIMER_TCFG1); bus_space_write_4(iot, ioh, TIMER_TCFG1, (reg & ~(TCFG1_MUX_MASK(4))) | (TCFG1_MUX_DIV16 << TCFG1_MUX_SHIFT(4)) ); /* start timers */ reg = bus_space_read_4(iot, ioh, TIMER_TCON); reg &= ~(TCON_MASK(4)); /* load the time constant */ bus_space_write_4(iot, ioh, TIMER_TCON, reg | TCON_MANUALUPDATE(4)); /* set auto reload and start */ bus_space_write_4(iot, ioh, TIMER_TCON, reg | TCON_AUTORELOAD(4) | TCON_START(4) ); s3c24x0_timer_timecounter.tc_frequency = TIMER_FREQUENCY(pclk) / timer4_prescaler; tc_init(&s3c24x0_timer_timecounter); }
void s5p6818_timer_count(virtual_addr_t virt, int ch, u32_t cnt) { write32(virt + TIMER_TCNTB(ch), cnt); write32(virt + TIMER_TCMPB(ch), cnt); }