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