blob: c1a9b573de9ec60efe2b8147aef787fd19ca2182
1 | #include <stdio.h> |
2 | #include <string.h> // strcmp |
3 | #include <time.h> // clock |
4 | #include <fcntl.h> |
5 | #include <unistd.h> |
6 | |
7 | #include <sys/mman.h> |
8 | #include <audio-dec.h> |
9 | #include <adec-pts-mgt.h> |
10 | #include <amthreadpool.h> |
11 | |
12 | #include "Amsysfsutils.h" |
13 | #include "amconfigutils.h" |
14 | |
15 | |
16 | #define ASTREAM_DEV "/dev/uio0" |
17 | #define ASTREAM_ADDR "/sys/class/astream/astream-dev/uio0/maps/map0/addr" |
18 | #define ASTREAM_SIZE "/sys/class/astream/astream-dev/uio0/maps/map0/size" |
19 | #define ASTREAM_OFFSET "/sys/class/astream/astream-dev/uio0/maps/map0/offset" |
20 | #define ADDR_OFFSET "/sys/class/astream/addr_offset" |
21 | |
22 | |
23 | #define AIU_AIFIFO_CTRL 0x1580 |
24 | #define AIU_AIFIFO_STATUS 0x1581 |
25 | #define AIU_AIFIFO_GBIT 0x1582 |
26 | #define AIU_AIFIFO_CLB 0x1583 |
27 | #define AIU_MEM_AIFIFO_START_PTR 0x1584 |
28 | #define AIU_MEM_AIFIFO_CURR_PTR 0x1585 |
29 | #define AIU_MEM_AIFIFO_END_PTR 0x1586 |
30 | #define AIU_MEM_AIFIFO_BYTES_AVAIL 0x1587 |
31 | #define AIU_MEM_AIFIFO_CONTROL 0x1588 |
32 | #define AIU_MEM_AIFIFO_MAN_WP 0x1589 |
33 | #define AIU_MEM_AIFIFO_MAN_RP 0x158a |
34 | #define AIU_MEM_AIFIFO_LEVEL 0x158b |
35 | #define AIU_MEM_AIFIFO_BUF_CNTL 0x158c |
36 | #define AIU_MEM_AIFIFO_BUF_WRAP_COUNT 0x158d |
37 | #define AIU_MEM_AIFIFO2_BUF_WRAP_COUNT 0x158e |
38 | #define AIU_MEM_AIFIFO_MEM_CTL 0x158f |
39 | |
40 | volatile unsigned* reg_base = 0; |
41 | #define READ_MPEG_REG(reg) reg_base[reg-AIU_AIFIFO_CTRL] |
42 | #define WRITE_MPEG_REG(reg, val) reg_base[reg-AIU_AIFIFO_CTRL]=val |
43 | #define AIFIFO_READY (((READ_MPEG_REG(AIU_MEM_AIFIFO_CONTROL)&(1<<9)))) |
44 | #define min(x,y) ((x<y)?(x):(y)) |
45 | |
46 | static volatile void *memmap = MAP_FAILED; |
47 | static int phys_size = 0; |
48 | |
49 | static unsigned long get_num_infile(char *file) |
50 | { |
51 | return amsysfs_get_sysfs_ulong(file); |
52 | } |
53 | |
54 | int uio_init(aml_audio_dec_t *audec) |
55 | { |
56 | // int fd = -1; |
57 | int pagesize = getpagesize(); |
58 | int phys_start; |
59 | // int phys_size; |
60 | int phys_offset; |
61 | // volatile unsigned memmap; |
62 | int addr_offset; |
63 | |
64 | |
65 | audec->fd_uio = open(ASTREAM_DEV, O_RDWR); |
66 | if (audec->fd_uio < 0) { |
67 | adec_print("error open UIO 0\n"); |
68 | return -1; |
69 | } |
70 | phys_start = get_num_infile(ASTREAM_ADDR); |
71 | phys_size = get_num_infile(ASTREAM_SIZE); |
72 | phys_offset = get_num_infile(ASTREAM_OFFSET); |
73 | addr_offset = get_num_infile(ADDR_OFFSET); |
74 | |
75 | adec_print("add=%08x, size=%08x, phy_offset=%08x, addr_offset=%d\n", |
76 | phys_start, phys_size, phys_offset, addr_offset); |
77 | |
78 | phys_size = (phys_size + pagesize - 1) & (~(pagesize - 1)); |
79 | memmap = mmap(NULL, phys_size, PROT_READ | PROT_WRITE, MAP_SHARED, audec->fd_uio, 0 * pagesize); |
80 | |
81 | adec_print("memmap = %x , pagesize = %x\n", memmap, pagesize); |
82 | if (memmap == MAP_FAILED) { |
83 | adec_print("map /dev/uio0 failed\n"); |
84 | return -1; |
85 | } |
86 | if (phys_offset == 0) |
87 | phys_offset = ((AIU_AIFIFO_CTRL + addr_offset) << 2) & (pagesize - 1); |
88 | reg_base = memmap + phys_offset; |
89 | return 0; |
90 | } |
91 | |
92 | int uio_deinit(aml_audio_dec_t *audec) |
93 | { |
94 | if (audec->fd_uio >= 0) { |
95 | close(audec->fd_uio); |
96 | } |
97 | audec->fd_uio = -1; |
98 | |
99 | if (memmap != NULL && memmap != MAP_FAILED) { |
100 | munmap(memmap, phys_size); |
101 | } |
102 | adec_print("audio_dec_release done \n"); |
103 | return 0; |
104 | } |
105 | |
106 | |
107 | static inline void waiting_bits(int bits) |
108 | { |
109 | int bytes; |
110 | bytes = READ_MPEG_REG(AIU_MEM_AIFIFO_BYTES_AVAIL); |
111 | while (bytes * 8 < bits) { |
112 | if (amthreadpool_on_requare_exit(0)) { |
113 | break; |
114 | } |
115 | amthreadpool_thread_usleep(1000); |
116 | bytes = READ_MPEG_REG(AIU_MEM_AIFIFO_BYTES_AVAIL); |
117 | } |
118 | } |
119 | |
120 | |
121 | #define EXTRA_DATA_SIZE 128 |
122 | int read_buffer(unsigned char *buffer, int size) |
123 | { |
124 | int bytes; |
125 | int len; |
126 | unsigned char *p = buffer; |
127 | int tmp; |
128 | int space; |
129 | int i; |
130 | int wait_times = 0, fifo_ready_wait = 0; |
131 | |
132 | int iii; |
133 | |
134 | iii = READ_MPEG_REG(AIU_MEM_AIFIFO_LEVEL) - EXTRA_DATA_SIZE; |
135 | // adec_print("read_buffer start iii = %d!!\n", iii); |
136 | |
137 | static int cc = 0; |
138 | len = 0; |
139 | #if 0 |
140 | while (size >= iii) { |
141 | cc++ ; |
142 | amthreadpool_thread_usleep(1000); |
143 | iii = READ_MPEG_REG(AIU_MEM_AIFIFO_LEVEL) - EXTRA_DATA_SIZE; |
144 | if (cc % 2000 == 0) { |
145 | adec_print("read_buffer start in while iii = %d!!exit_decode_thread:%d \n", iii, exit_decode_thread); |
146 | } |
147 | if (exit_decode_thread) { |
148 | goto out; |
149 | } |
150 | } |
151 | #endif |
152 | if ((size >= iii)) { |
153 | return 0; |
154 | } |
155 | |
156 | // adec_print("read_buffer start while iii= %d!!\n", iii); |
157 | for (len = 0; len < size;) { |
158 | space = (size - len); |
159 | bytes = READ_MPEG_REG(AIU_MEM_AIFIFO_BYTES_AVAIL); |
160 | //adec_print("read_buffer start AIU_MEM_AIFIFO_BYTES_AVAIL bytes= %d!!\n", bytes); |
161 | wait_times = 0; |
162 | while (bytes == 0) { |
163 | waiting_bits((space > 128) ? 128 * 8 : (space * 8)); /*wait 32 bytes,if the space is less than 32 bytes,wait the space bits*/ |
164 | bytes = READ_MPEG_REG(AIU_MEM_AIFIFO_BYTES_AVAIL); |
165 | |
166 | adec_print("read_buffer while AIU_MEM_AIFIFO_BYTES_AVAIL = %d!!\n", bytes); |
167 | wait_times++; |
168 | if (wait_times > 10 || amthreadpool_on_requare_exit(0)) { |
169 | adec_print("goto out!!\n"); |
170 | goto out; |
171 | } |
172 | } |
173 | bytes = min(space, bytes); |
174 | |
175 | //adec_print("read_buffer while bytes = %d!!\n", bytes); |
176 | for (i = 0; i < bytes; i++) { |
177 | while (!AIFIFO_READY) { |
178 | fifo_ready_wait++; |
179 | amthreadpool_thread_usleep(1000); |
180 | if (fifo_ready_wait > 100 || amthreadpool_on_requare_exit(0)) { |
181 | adec_print("FATAL err,AIFIFO is not ready,check!!\n"); |
182 | return 0; |
183 | } |
184 | } |
185 | WRITE_MPEG_REG(AIU_AIFIFO_GBIT, 8); |
186 | tmp = READ_MPEG_REG(AIU_AIFIFO_GBIT); |
187 | //adec_print("read_buffer while tmp = %d!!\n", tmp); |
188 | |
189 | *p++ = tmp & 0xff; |
190 | fifo_ready_wait = 0; |
191 | |
192 | } |
193 | len += bytes; |
194 | } |
195 | out: |
196 | //stream_in_offset+=len; |
197 | return len; |
198 | } |
199 | |
200 | |
201 |