static void jz_clockevent_init(struct jz_timerevent *evt_dev) { struct clock_event_device *cd = &evt_dev->clkevt; struct clk *ext_clk = clk_get(NULL,"ext1"); spin_lock_init(&evt_dev->lock); evt_dev->rate = clk_get_rate(ext_clk) / CLKEVENT_DIV; clk_put(ext_clk); stoptimer(); tcu_writel(CH_TCSR(CLKEVENT_CH),CSRDIV(CLKEVENT_DIV) | CSR_EXT_EN); evt_dev->evt_action.handler = jz_timer_interrupt; evt_dev->evt_action.thread_fn = NULL; evt_dev->evt_action.flags = IRQF_DISABLED | IRQF_TIMER; evt_dev->evt_action.name = "jz-timerirq"; evt_dev->evt_action.dev_id = (void*)evt_dev; if(setup_irq(IRQ_TCU1, &evt_dev->evt_action) < 0) { pr_err("timer request irq error\n"); BUG(); } memset(cd,0,sizeof(struct clock_event_device)); cd->name = "jz-clockenvent"; cd->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC; cd->shift = 10; cd->rating = 400; cd->set_mode = jz_set_mode; cd->set_next_event = jz_set_next_event; cd->irq = IRQ_TCU1; cd->cpumask = cpumask_of(0); clockevents_config_and_register(cd,evt_dev->rate,4,65536); printk("clockevents_config_and_register success.\n"); }
/* * @fn: request a tcu channel. * @tcu_chan: channel to request. * */ void tcu_timer_request(int tcu_chan) { tcu_channel = tcu_chan; REG32(CPM_IOBASE + CPM_CLKGR0) &= ~(1<<30); tcu_dump_reg(); tcu_save(); /* stop clear */ tcu_writel(TCU_TSCR,(1 << tcu_channel)); tcu_writel(TCU_TECR,(1 << tcu_channel)); tcu_writel(TCU_TMSR,(1 << tcu_channel)|(1 << (tcu_channel + 16))); tcu_writel(TCU_TFCR, (1 << tcu_channel) | (1 << (tcu_channel + 16))); tcu_writel(CH_TDHR(tcu_channel), 1); /* Mask interrupt */ /* RTC CLK, 32768 * DIV: 64. * TCOUNT: 1: 1.953125ms * */ tcu_writel(CH_TCSR(tcu_channel),CSRDIV(CLK_DIV) | CSR_RTC_EN); tcu_dump_reg(); }
void __cpuinit jz_clocksource_init(void) { struct clk *ext_clk = clk_get(NULL, "ext1"); tmr_src.cs.mult = clocksource_hz2mult(clk_get_rate(ext_clk) / CLKSOURCE_DIV, tmr_src.cs.shift); clk_put(ext_clk); clocksource_register(&tmr_src.cs); tmr_src.clk_gate = clk_get(NULL, "tcu"); if (IS_ERR(tmr_src.clk_gate)) { tmr_src.clk_gate = NULL; printk("warning: tcu clk get fail!\n"); } if (tmr_src.clk_gate) clk_enable(tmr_src.clk_gate); tmr_src.channel = CLKSOURCE_CH; tcu_writel(TCU_TSCR, 1 << CLKSOURCE_CH); apbost_writel(OST_CNTL, 0); apbost_writel(OST_CNTH, 0); apbost_writel(OST_DR, 0); tcu_writel(TCU_TFCR, TFR_OSTF); tcu_writel(TCU_TMSR, TMR_OSTM); apbost_writel(OST_CSR, OSTCSR_CNT_MD | CSRDIV(CLKSOURCE_DIV) | CSR_EXT_EN); // 16 prescale ext clk }
void __cpuinit jz_clocksource_init(void) { struct clk *ext_clk = clk_get(NULL,"ext1"); ost_writel(OST_CNTL, 0); ost_writel(OST_CNTH, 0); ost_writel(OST_DR, 0); ost_writel(OST_TFCR, TFR_OSTF); ost_writel(OST_TMSR, TMR_OSTM); ost_writel(OST_TSCR, TSR_OSTS); ost_writel(OST_CSR, OSTCSR_CNT_MD); ost_writel(OST_TCSR, CSRDIV(CLKSOURCE_DIV)); ost_writel(OST_TESR, OST_EN); clocksource_jz.mult = clocksource_hz2mult(clk_get_rate(ext_clk) / CLKSOURCE_DIV, clocksource_jz.shift); clk_put(ext_clk); clocksource_register(&clocksource_jz); }
/* static int broadcast_cpuhp_notify(struct notifier_block *n, unsigned long action, void *hcpu){ int hotcpu = (unsigned long)hcpu; struct jz_timerevent *evt = &per_cpu(jzclockevent, hotcpu); if(hotcpu != 0) { switch(action & 0xf) { case CPU_DEAD: jz_set_mode(CLOCK_EVT_MODE_SHUTDOWN,&evt->clkevt); break; case CPU_ONLINE: jz_set_mode(CLOCK_EVT_MODE_RESUME,&evt->clkevt); break; } } return NOTIFY_OK; } */ static void jz_clockevent_init(struct jz_timerevent *evt_dev,int cpu) { struct clock_event_device *cd = &evt_dev->clkevt; struct clk *ext_clk = clk_get(NULL,"ext1"); spin_lock_init(&evt_dev->lock); evt_dev->rate = clk_get_rate(ext_clk) / CLKEVENT_DIV; clk_put(ext_clk); stoptimer(evt_dev); outl((1 << evt_dev->ch),evt_dev->ctrl_addr + TCU_TMCR); outl(CSRDIV(CLKEVENT_DIV) | CSR_EXT_EN,evt_dev->config_addr); if(evt_dev->requestirq == 0){ evt_dev->evt_action.handler = jz_timer_interrupt; evt_dev->evt_action.thread_fn = NULL; evt_dev->evt_action.flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER; evt_dev->evt_action.name = "jz-timerirq"; evt_dev->evt_action.dev_id = (void*)evt_dev; if(setup_irq(evt_dev->irq, &evt_dev->evt_action) < 0) { pr_err("timer request irq error\n"); BUG(); } evt_dev->requestirq = 1; } memset(cd,0,sizeof(struct clock_event_device)); cd->name = "jz-clockenvent"; cd->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC; cd->shift = 10; cd->rating = 400; cd->set_mode = jz_set_mode; cd->set_next_event = jz_set_next_event; cd->irq = evt_dev->irq; cd->cpumask = cpumask_of(cpu); clockevents_config_and_register(cd,evt_dev->rate,4,65536); /* evt_dev->cpu_notify.notifier_call = broadcast_cpuhp_notify; if(cpu == 0){ register_cpu_notifier(&evt_dev->cpu_notify); } */ }
void __cpuinit jz_clocksource_init(void) { struct clk *ext_clk = clk_get(NULL,"ext1"); tcu_writel(TCU_TSCR, TSR_OSTS); apbost_writel(OST_CNTL, 0); apbost_writel(OST_CNTH, 0); apbost_writel(OST_DR, 0); tcu_writel(TCU_TFCR, TFR_OSTF); tcu_writel(TCU_TMSR, TMR_OSTM); apbost_writel(OST_CSR, OSTCSR_CNT_MD | CSRDIV(CLKSOURCE_DIV) | CSR_EXT_EN); // 16 prescale ext clk tcu_writel(TCU_TESR, (1 << CLKSOURCE_CH)); // tcu enable ost channel(15) clocksource_jz.mult = clocksource_hz2mult(clk_get_rate(ext_clk) / CLKSOURCE_DIV, clocksource_jz.shift); clk_put(ext_clk); clocksource_register(&clocksource_jz); }