123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2018-11-22 Jesven first version
- */
- #include <rthw.h>
- #include <rtthread.h>
- #include <stdint.h>
- #include <board.h>
- #include "mmu.h"
- #define TICK_PERIOD (g_sys_freq / RT_TICK_PER_SECOND)
- static int g_sys_freq;
- #define IRQ_SECURE_PHY_TIMER 29 /* Secure physical timer event */
- #define IRQ_NOSECURE_PHY_TIMER 30 /* No-Secure physical timer event */
- #define IRQ_SYS_TICK IRQ_SECURE_PHY_TIMER
- /* System Counter */
- struct sctr_regs {
- rt_uint32_t cntcr;
- rt_uint32_t cntsr;
- rt_uint32_t cntcv1;
- rt_uint32_t cntcv2;
- rt_uint32_t resv1[4];
- rt_uint32_t cntfid0;
- rt_uint32_t cntfid1;
- rt_uint32_t cntfid2;
- rt_uint32_t resv2[1001];
- rt_uint32_t counterid[1];
- };
- #define SC_CNTCR_ENABLE (1 << 0)
- #define SC_CNTCR_HDBG (1 << 1)
- #define SC_CNTCR_FREQ0 (1 << 8)
- #define SC_CNTCR_FREQ1 (1 << 9)
- #define isb() __asm__ __volatile__ ("" : : : "memory")
- #define dsb() __asm__ __volatile__ ("" : : : "memory")
- #define dmb() __asm__ __volatile__ ("" : : : "memory")
- static inline void enable_cntp(void)
- {
- rt_uint32_t cntv_ctl;
- cntv_ctl = 1;
- asm volatile ("mcr p15, 0, %0, c14, c2, 1" :: "r"(cntv_ctl)); // write CNTP_CTL
- isb();
- }
- static inline void disable_cntp(void)
- {
- rt_uint32_t cntv_ctl;
- cntv_ctl = 0;
- asm volatile ("mcr p15, 0, %0, c14, c2, 1" :: "r"(cntv_ctl)); // write CNTP_CTL
- isb();
- }
- static inline rt_uint32_t read_cntfrq(void)
- {
- rt_uint32_t val;
- asm volatile ("mrc p15, 0, %0, c14, c0, 0" : "=r"(val));
- return val;
- }
- static inline void write_cntp_tval(rt_uint32_t val)
- {
- asm volatile ("mcr p15, 0, %0, c14, c2, 0" :: "r"(val));
- isb();
- return;
- }
- static inline void write_cntp_cval(rt_uint64_t val)
- {
- asm volatile ("mcrr p15, 2, %Q0, %R0, c14" :: "r" (val));
- isb();
- return;
- }
- static inline rt_uint64_t read_cntp_cval(void)
- {
- rt_uint64_t val;
- asm volatile ("mrrc p15, 2, %Q0, %R0, c14" : "=r" (val));
- return (val);
- }
- volatile unsigned int *CCM_CLPCR;
- static void imx6ull_enable_clk_in_waitmode(void)
- {
- CCM_CLPCR = rt_ioremap((void*)0x20C4054, 4);
- *CCM_CLPCR &= ~((1 << 5) | 0x3);
- }
- static void system_counter_clk_source_init(void)
- {
- /* to do */
- }
- static void system_counter_init(void)
- {
- /* enable system_counter */
- #define SCTR_BASE_ADDR 0x021DC000
- #define CONFIG_SC_TIMER_CLK 8000000
- /* imx6ull, enable system counter */
- struct sctr_regs *sctr = (struct sctr_regs *)rt_ioremap((void*)SCTR_BASE_ADDR, sizeof(struct sctr_regs));
- unsigned long val, freq;
- freq = CONFIG_SC_TIMER_CLK;
- asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
- sctr->cntfid0 = freq;
- /* Enable system counter */
- val = sctr->cntcr;
- val &= ~(SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1);
- val |= SC_CNTCR_FREQ0 | SC_CNTCR_ENABLE | SC_CNTCR_HDBG;
- sctr->cntcr = val;
- imx6ull_enable_clk_in_waitmode();
- }
- static void arch_timer_init(void)
- {
- g_sys_freq = read_cntfrq();
- /* set timeout val */
- disable_cntp();
- write_cntp_tval(TICK_PERIOD);
- /* start timer */
- enable_cntp();
- /* enable irq */
- }
- static void rt_hw_timer_isr(int vector, void *param)
- {
- rt_tick_increase();
- /* setup for next irq */
- /* clear interrupt */
- disable_cntp();
- write_cntp_cval(read_cntp_cval() + TICK_PERIOD);
- enable_cntp();
- }
- int rt_hw_timer_init(void)
- {
- /* Setup Timer for generating irq */
- /* enable timer */
- system_counter_clk_source_init();
- system_counter_init();
- arch_timer_init();
- /* insall irq, enable irq */
- rt_hw_interrupt_install(IRQ_SYS_TICK, rt_hw_timer_isr, RT_NULL, "tick");
- rt_hw_interrupt_umask(IRQ_SYS_TICK);
- return 0;
- }
- INIT_BOARD_EXPORT(rt_hw_timer_init);
|