timer.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /**
  2. ******************************************************************************
  3. * @file timer.c
  4. * @author StarFive Technology
  5. * @version V1.0
  6. * @date 07/24/2020
  7. * @brief
  8. ******************************************************************************
  9. * @copy
  10. *
  11. * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  12. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  13. * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
  14. * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  15. * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  16. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  17. *
  18. * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
  19. */
  20. #include <comdef.h>
  21. #include <sys.h>
  22. #include <timer.h>
  23. #include <clkgen_ctrl_macro.h>
  24. #include <uart.h>
  25. #include <div64.h>
  26. #define TIMER_RATE_HZ (TIMER_CLK_HZ /1000)
  27. #if 0
  28. #define VIC_TIMER_NUM 7
  29. #define VIC_TIMER_NUM_MAX 7
  30. #define VIC_SYS_TIMER 0
  31. #define CONFIG_SYS_HZ 1000
  32. #define TIMER_RATE_HZ (CONFIG_SYS_HZ_CLOCK /1000)
  33. #define WDOG_UNKOCK 0x378f0765
  34. u32 interrupt_count = 0;
  35. /*
  36. * variables definition for local use
  37. */
  38. static const u32 timer_clk = CONFIG_SYS_HZ_CLOCK;
  39. static u64 lastdec;//Last decremneter snapshot
  40. static u64 timestamp;//Monotonic incrementing timer
  41. static u64 timer_load_val;
  42. struct timer_regs{
  43. u32 interrupt_status; //0x00
  44. struct time_reg{
  45. u32 control; //0x04+i*0x10
  46. u32 load_reg; //0x08+i*0x10
  47. u32 res0; //0x0c+i*0x10
  48. u32 enable_reg; //0x10+i*0x10
  49. u32 reload_reg; //0x14 + i * 0x10
  50. u32 timer_value; //0x18 + i * 0x10
  51. u32 res1; //0x1c
  52. u32 interrupt_clr; //0x20
  53. u32 interrupt_mask; //0x24
  54. u32 res3[5];
  55. u32 watchdog_lock; //0x3c+i*0x40 watchdog use ONLY
  56. u32 res4; //0x40+i*0x40
  57. }timer[VIC_TIMER_NUM_MAX];
  58. };
  59. struct timer_int_arg{
  60. u32 id;
  61. void (*callback)(void *);
  62. void *arg;
  63. u32 wdog_reset;
  64. };
  65. /*
  66. * local functions
  67. */
  68. struct timer_regs *timer_driver_to_base(struct timer_driver *driver)
  69. {
  70. return (struct timer_regs *)driver->base;
  71. }
  72. static struct timer_driver g_timer_driver;
  73. void timer_int_enable(u32 id)
  74. {
  75. struct timer_driver *driver = &g_timer_driver;
  76. volatile struct timer_regs *base;
  77. base = timer_driver_to_base(driver);
  78. base->timer[id].interrupt_mask = 0;
  79. }
  80. void timer_int_disable(u32 id)
  81. {
  82. struct timer_driver *driver = &g_timer_driver;
  83. volatile struct timer_regs *base;
  84. base = timer_driver_to_base(driver);
  85. base->timer[id].interrupt_mask = 1;
  86. }
  87. void timer_disable(u32 id)
  88. {
  89. struct timer_driver *driver = &g_timer_driver;
  90. volatile struct timer_regs *base;
  91. base = timer_driver_to_base(driver);
  92. base->timer[id].enable_reg = 0;
  93. }
  94. int timer_is_timeout(u32 id)
  95. {
  96. struct timer_driver *driver = &g_timer_driver;
  97. volatile struct timer_regs *base;
  98. base = timer_driver_to_base(driver);
  99. //printf("addr = 0x%x,base[id].raw_int_status = 0x%x\r\n", &(base[id].raw_int_status), base[id].raw_int_status);
  100. return (base->interrupt_status == 1) ? true : false;
  101. }
  102. void timer_set_mode(u32 id,u32 run_mode)
  103. {
  104. struct timer_driver *driver = &g_timer_driver;
  105. volatile struct timer_regs *base;
  106. base = timer_driver_to_base(driver);
  107. base->timer[id].control = run_mode;
  108. }
  109. void timer_set_val(u32 id,u32 val)
  110. {
  111. struct timer_driver *driver = &g_timer_driver;
  112. volatile struct timer_regs *base;
  113. base = timer_driver_to_base(driver);
  114. base->timer[id].load_reg = val;
  115. }
  116. void timer_set_reload_val(u32 id,u32 val)
  117. {
  118. struct timer_driver *driver = &g_timer_driver;
  119. volatile struct timer_regs *base;
  120. base = timer_driver_to_base(driver);
  121. base->timer[id].reload_reg = val;
  122. }
  123. static struct timer_int_arg int_arg[VIC_TIMER_NUM_MAX];
  124. int timer_set(u32 id,struct timer_init_s *init)
  125. {
  126. u32 irq = 0;
  127. timer_disable(id);
  128. timer_set_mode(id,init->run_mode);
  129. timer_set_val(id,init->count);
  130. timer_int_disable(id);
  131. timer_set_reload_val(id, init->count);
  132. timestamp=0;
  133. timer_load_val=init->count;
  134. lastdec=timer_load_val;
  135. //_ENABLE_CLOCK_clk_wdtimer_apb_;
  136. switch (id){
  137. case 0:
  138. _ENABLE_CLOCK_clk_timer0_coreclk_;
  139. break;
  140. case 1:
  141. _ENABLE_CLOCK_clk_timer1_coreclk_;
  142. break;
  143. case 2:
  144. _ENABLE_CLOCK_clk_timer2_coreclk_;
  145. break;
  146. case 3:
  147. _ENABLE_CLOCK_clk_timer3_coreclk_;
  148. break;
  149. case 4:
  150. _ENABLE_CLOCK_clk_timer4_coreclk_;
  151. break;
  152. case 5:
  153. _ENABLE_CLOCK_clk_timer5_coreclk_;
  154. break;
  155. case 6:
  156. _ENABLE_CLOCK_clk_timer6_coreclk_;
  157. break;
  158. }
  159. timer_int_disable(id);
  160. //timer_int_disable(id);
  161. return 0;
  162. }
  163. void timer_enable(u32 id)
  164. {
  165. struct timer_driver *driver = &g_timer_driver;
  166. volatile struct timer_regs *base;
  167. base = timer_driver_to_base(driver);
  168. base->timer[id].enable_reg = 1;
  169. }
  170. /*
  171. * public functions
  172. */
  173. int timer_clr_int_status(u32 id)
  174. {
  175. struct timer_driver *driver = &g_timer_driver;
  176. volatile struct timer_regs *base;
  177. int clr;
  178. //printf("clr timer id = %d\r\n", id);
  179. base = timer_driver_to_base(driver);
  180. base->timer[id].interrupt_clr = 1;
  181. return clr;
  182. }
  183. u32 timer_get_val(u32 id)
  184. {
  185. struct timer_driver *driver = &g_timer_driver;
  186. volatile struct timer_regs *base;
  187. base = timer_driver_to_base(driver);
  188. return base->timer[id].timer_value;
  189. }
  190. int timer_stop(u32 id)
  191. {
  192. int irq;
  193. timer_int_disable(id);
  194. timer_disable(id);
  195. timer_clr_int_status(id);
  196. return 0;
  197. }
  198. int timer_start(u32 id)
  199. {
  200. timer_enable(id);
  201. return 0;
  202. }
  203. int timer_exit(void)
  204. {
  205. return 0;
  206. }
  207. int timer_init(int id)
  208. {
  209. struct timer_driver *driver = &g_timer_driver;
  210. struct timer_init_s timer_init_param;
  211. int reg_value;
  212. /* timer clk use apb clk */
  213. /* reset */
  214. driver->base = (void *)TIMER_BASE_ADDR;
  215. driver->freq = CONFIG_SYS_HZ_CLOCK;
  216. // _ASSERT_RESET_rstn_apb_timer_;
  217. // _CLEAR_RESET_rstn_apb_timer_;
  218. if(id == SOC_SYS_TIMER)/* start timer0 as system delay timer */
  219. {
  220. timer_init_param.int_en = 0;//0:interrupt disable 1:interrupt enable
  221. timer_init_param.run_mode = 0;//0:continuous 1:single
  222. timer_init_param.count = 0xffffffff;
  223. timer_init_param.one_shot = 0;
  224. timer_init_param.callback = NULL;
  225. timer_init_param.arg = NULL;
  226. //_SET_SYSCON_REG_SCFG_misc_ctrl1_timclken1(1);
  227. timer_set(id, &timer_init_param);
  228. timer_start(id);
  229. }
  230. else
  231. {
  232. timer_set(id, &timer_init_param);
  233. timer_start(id);
  234. }
  235. return 0;
  236. }
  237. u32 get_ticks(u32 tick_base)
  238. {
  239. u32 id = SOC_SYS_TIMER;
  240. u32 now = timer_get_val(id);
  241. //printf("time value = 0x%x\r\n",now);
  242. if (lastdec >= now) {
  243. /* normal mode */
  244. timestamp += lastdec - now;
  245. } else {
  246. /* we have an overflow ... */
  247. timestamp += lastdec + timer_load_val - now;
  248. }
  249. lastdec = now;
  250. return (u32)(timestamp-tick_base);
  251. }
  252. #endif
  253. #include "platform.h"
  254. unsigned long long get_ticks(void)
  255. {
  256. return readq(CLINT_CTRL_MTIME);
  257. }
  258. u32 get_timer(unsigned int base)
  259. {
  260. return lldiv(get_ticks(), TIMER_RATE_HZ) - base;
  261. }
  262. #if 0
  263. u32 usec_to_tick(u32 usec)
  264. {
  265. u32 value = usec*(timer_clk/1000000);
  266. //printf("value = 0x%x\r\n", value);
  267. return usec*(timer_clk/1000000);
  268. }
  269. int udelay(u32 usec)
  270. {
  271. UINT64 tmp;
  272. UINT64 tmo;
  273. tmo = usec_to_tick(usec);
  274. tmp = get_ticks(0) + tmo; /* get current timestamp */
  275. while (get_ticks(0) < tmp)/* loop till event */
  276. /*NOP*/
  277. {
  278. }
  279. return 0;
  280. }
  281. #endif
  282. u64 usec_to_tick(u64 usec)
  283. {
  284. u64 value;
  285. value = usec*(TIMER_CLK_HZ/1000)/1000;
  286. return value;
  287. }
  288. /* delay x useconds */
  289. int udelay(unsigned int usec)
  290. {
  291. unsigned long tmp;
  292. tmp = readq((volatile void *)CLINT_CTRL_MTIME) + usec_to_tick(usec); /* get current timestamp */
  293. while (readq((volatile void *)CLINT_CTRL_MTIME) < tmp);
  294. }
  295. void mdelay(unsigned int ms)
  296. {
  297. udelay(1000*ms);
  298. }
  299. void sdelay(unsigned int s)
  300. {
  301. mdelay(1000*s);
  302. }