1/*
2 * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <autoconf.h>
8#include <camkes.h>
9#include <stdio.h>
10
11#define KZM_EPIT_BASE_ADDR  (unsigned int)mem
12#define KZM_EPIT_CTRL_ADDR  (KZM_EPIT_BASE_ADDR + 0x00)
13#define KZM_EPIT_STAT_ADDR  (KZM_EPIT_BASE_ADDR + 0x04)
14#define KZM_EPIT_LOAD_ADDR  (KZM_EPIT_BASE_ADDR + 0x08)
15#define KZM_EPIT_COMP_ADDR  (KZM_EPIT_BASE_ADDR + 0x0C)
16#define KZM_EPIT_CNT_ADDR   (KZM_EPIT_BASE_ADDR + 0x10)
17
18#define REG_VAL(x)         *((volatile uint32_t *)(x))
19
20#define CTRL_EN       (1 << 0)   /* EPIT enable */
21#define CTRL_ENMOD    (1 << 1)   /* EPIT enable mode */
22#define CTRL_OCIEN    (1 << 2)   /* EPIT interrupt enable */
23#define CTRL_RLD      (1 << 3)   /* Counter reload control */
24#define CTRL_SWR      (1 << 17)  /* Software reset */
25
26#define CTRL_CLKSRC_SHIFT   (24)    /* Clock source */
27#define CTRL_PRESCALE_SHIFT (4)     /* Prescalar */
28
29//#define IPG_CLK_KHZ       (53200)     /* Clock frequency in KHz */
30#define IPG_CLK_KHZ       (66000)     /* Clock frequency in KHz */
31#define CLKSRC_IPG        (0x1)     /* IPG clock */
32#define CLKSRC_IPG_HIGH   (0x2)     /* IPG clock high frequency */
33#define CLKSRC_IPG_32K    (0x3)     /* IPG 32K clock */
34
35void epit_init()
36{
37	printf("EPIT init\n");
38
39	REG_VAL(KZM_EPIT_CTRL_ADDR) = 0;
40
41	/* Disable EPIT and reset. */
42	REG_VAL(KZM_EPIT_CTRL_ADDR) = CTRL_SWR;
43
44	/* Select Clock source */
45	REG_VAL(KZM_EPIT_CTRL_ADDR) = (CLKSRC_IPG << CTRL_CLKSRC_SHIFT);
46
47	/* Reload from load register */
48	REG_VAL(KZM_EPIT_CTRL_ADDR) |= (CTRL_RLD | CTRL_ENMOD);
49
50	/* Enable interrupt */
51	REG_VAL(KZM_EPIT_CTRL_ADDR) |= CTRL_OCIEN;
52
53}
54
55/* Set interrupt interval, in milliseconds. */
56void epit_set_interval(int interval)
57{
58	REG_VAL(KZM_EPIT_LOAD_ADDR) = (IPG_CLK_KHZ * interval) ;
59	REG_VAL(KZM_EPIT_COMP_ADDR) = 0;
60}
61
62void epit_start_timer(void)
63{
64	REG_VAL(KZM_EPIT_STAT_ADDR) = 0x1;
65
66	/* Enable timer */
67	REG_VAL(KZM_EPIT_CTRL_ADDR) |= CTRL_EN;
68}
69
70static int count = 0;
71void irq_handle(void)
72{
73	/* Clear status bit. */
74	REG_VAL(KZM_EPIT_STAT_ADDR) = 0x1;
75	irq_acknowledge();
76
77	printf("EPIT time out...%d\n", count++);
78}
79
80int run(void)
81{
82	epit_init();
83	epit_set_interval(1000);
84
85	epit_start_timer();
86
87	return 0;
88}
89