timer.c 7.7 KB

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