1 #include <sunxi_hal_common.h>
2 #include <sunxi_hal_avs.h>
3 #include <interrupt.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 
7 static hal_sunxi_avs hal_avs[AVS_NUM];
8 
hal_avs_continue(hal_avs_id_t id)9 int hal_avs_continue(hal_avs_id_t id)
10 {
11     u32 val;
12     hal_sunxi_avs *avs;
13 
14     if (id >= AVS_NUM)
15     {
16         AVS_ERR("avs id is too big!!!\n");
17         return -1;
18     }
19     avs = &hal_avs[id];
20 
21     val = hal_readl(avs->base + AVS_CNT_CTRL_REG);
22     val &= ~(1 << (id + 8));
23     hal_writel(val, avs->base + AVS_CNT_CTRL_REG);
24     return 0;
25 }
26 
hal_avs_pause(hal_avs_id_t id)27 int hal_avs_pause(hal_avs_id_t id)
28 {
29     u32 val;
30     hal_sunxi_avs *avs;
31 
32     if (id >= AVS_NUM)
33     {
34         AVS_ERR("avs id is too big!!!\n");
35         return -1;
36     }
37     avs = &hal_avs[id];
38 
39     val = hal_readl(avs->base + AVS_CNT_CTRL_REG);
40     val |= (1 << (id + 8));
41     hal_writel(val, avs->base + AVS_CNT_CTRL_REG);
42     return 0;
43 }
44 
hal_avs_disable(hal_avs_id_t id)45 int hal_avs_disable(hal_avs_id_t id)
46 {
47     u32 val;
48     hal_sunxi_avs *avs;
49 
50     if (id >= AVS_NUM)
51     {
52         AVS_ERR("avs id is too big!!!\n");
53         return -1;
54     }
55     avs = &hal_avs[id];
56 
57     val = hal_readl(avs->base + AVS_CNT_CTRL_REG);
58     val &= ~(1 << id);
59     hal_writel(val, avs->base + AVS_CNT_CTRL_REG);
60     return 0;
61 }
62 
hal_avs_enable(hal_avs_id_t id)63 int hal_avs_enable(hal_avs_id_t id)
64 {
65     u32 val;
66     hal_sunxi_avs *avs;
67 
68     if (id >= AVS_NUM)
69     {
70         AVS_ERR("avs id is too big!!!\n");
71         return -1;
72     }
73     avs = &hal_avs[id];
74 
75     val = hal_readl(avs->base + AVS_CNT_CTRL_REG);
76     val |= (1 << id);
77     hal_writel(val, avs->base + AVS_CNT_CTRL_REG);
78     return 0;
79 }
80 
hal_avs_get_counter(hal_avs_id_t id,u32 * counter)81 int hal_avs_get_counter(hal_avs_id_t id, u32 *counter)
82 {
83     hal_sunxi_avs *avs;
84 
85     if (id >= AVS_NUM)
86     {
87         AVS_ERR("avs id is too big!!!\n");
88         return -1;
89     }
90 
91     avs = &hal_avs[id];
92     *counter = hal_readl(avs->base + AVS_CNT_REG(id));
93     return 0;
94 }
95 
hal_avs_set_counter(hal_avs_id_t id,u32 counter)96 int hal_avs_set_counter(hal_avs_id_t id, u32 counter)
97 {
98     hal_sunxi_avs *avs;
99 
100     if (id >= AVS_NUM)
101     {
102         AVS_ERR("avs id is too big!!!\n");
103         return -1;
104     }
105 
106     avs = &hal_avs[id];
107 
108     hal_writel(counter, avs->base + AVS_CNT_REG(id));
109 
110     return 0;
111 }
112 
hal_avs_set_cnt_div(hal_avs_id_t id,u32 div)113 int hal_avs_set_cnt_div(hal_avs_id_t id, u32 div)
114 {
115     u32 val;
116     hal_sunxi_avs *avs;
117 
118     if (id >= AVS_NUM)
119     {
120         AVS_ERR("avs id is too big!!!\n");
121         return -1;
122     }
123 
124     avs = &hal_avs[id];
125 
126     val = hal_readl(avs->base + AVS_CNT_DIV_REG);
127     val &= ~(AVS_DIV_MASK << (16 * id));
128     div &= AVS_DIV_MASK;
129     val |= (div << (16 * id));
130     hal_writel(val, avs->base + AVS_CNT_DIV_REG);
131 
132     return 0;
133 }
134 
hal_avs_init(hal_avs_id_t id)135 int hal_avs_init(hal_avs_id_t id)
136 {
137     hal_sunxi_avs *avs;
138 
139     if (id >= AVS_NUM)
140     {
141         AVS_ERR("avs id is too big!!!\n");
142         return -1;
143     }
144 
145     avs = &hal_avs[id];
146     avs->id = id;
147     avs->base = SUNXI_TMR_PBASE;
148     avs->enable = 1;
149     avs->clk = hal_clock_get(SUNXI_AVS_CLK_TYPE, SUNXI_AVS_CLK);
150 
151     AVS_INFO("avs_clk:%d", avs->clk);
152     hal_clock_enable(avs->clk);
153 
154     return 0;
155 }
156 
hal_avs_uninit(hal_avs_id_t id)157 int hal_avs_uninit(hal_avs_id_t id)
158 {
159     hal_sunxi_avs *avs;
160     hal_avs_id_t i;
161 
162     if (id >= AVS_NUM)
163     {
164         AVS_ERR("avs id is too big!!!\n");
165         return -1;
166     }
167 
168     avs = &hal_avs[id];
169     avs->enable = 0;
170 
171     for (i = 0; i < AVS_NUM; i++)
172     {
173         if (hal_avs[i].enable)
174         {
175             break;
176         }
177     }
178 
179     if (i == AVS_NUM)
180     {
181         hal_clock_disable(avs->clk);
182     }
183 
184     return 0;
185 }
186 
hal_avs_control(hal_avs_id_t id,hal_avs_cmd_t cmd,void * arg)187 int hal_avs_control(hal_avs_id_t id, hal_avs_cmd_t cmd, void *arg)
188 {
189     hal_sunxi_avs *avs;
190     u32 *counter, *div;
191 
192 
193     if (id >= AVS_NUM)
194     {
195         AVS_ERR("avs id is too big!!!\n");
196         return -1;
197     }
198 
199     avs = &hal_avs[id];
200 
201     switch (cmd)
202     {
203         case AVS_ENABLE:
204             return hal_avs_enable(id);
205         case AVS_DISABLE:
206             return hal_avs_disable(id);
207         case AVS_PAUSE:
208             return hal_avs_pause(id);
209         case AVS_CONTINUE:
210             return hal_avs_continue(id);
211         case AVS_SET_COUNTER:
212             counter = (u32 *)arg;
213             return hal_avs_set_counter(id, *counter);
214         case AVS_GET_COUNTER:
215             counter = (u32 *)arg;
216             return hal_avs_get_counter(id, counter);
217         case AVS_SET_DIV:
218             div = (u32 *)arg;
219             return hal_avs_set_cnt_div(id, *div);
220         default:
221             return -1;
222     }
223 
224     return 0;
225 }
226