blob: 472be72c92b272c968d4bd6f99629d831cba9d19
1 | /* |
2 | * drivers/amlogic/media/frame_sync/timestamp.c |
3 | * |
4 | * Copyright (C) 2017 Amlogic, Inc. All rights reserved. |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, but WITHOUT |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
14 | * more details. |
15 | * |
16 | */ |
17 | |
18 | #define DEBUG |
19 | #include <linux/module.h> |
20 | #include <linux/amlogic/media/frame_sync/tsync.h> |
21 | #include <linux/amlogic/media/frame_sync/tsync_pcr.h> |
22 | #include <linux/amlogic/media/utils/vdec_reg.h> |
23 | #include <linux/amlogic/media/registers/register.h> |
24 | #include <linux/amlogic/media/vout/vout_notify.h> |
25 | |
26 | |
27 | u32 acc_apts_inc; |
28 | u32 acc_apts_dec; |
29 | u32 acc_pcrscr_inc; |
30 | u32 acc_pcrscr_dec; |
31 | |
32 | static s32 system_time_inc_adj; |
33 | static u32 system_time; |
34 | static u32 system_time_up; |
35 | static u32 audio_pts_up; |
36 | static u32 audio_pts_started; |
37 | static u32 first_vpts; |
38 | static u32 first_checkin_vpts; |
39 | static u32 first_checkin_apts; |
40 | static u32 first_apts; |
41 | static u32 pcrscr_lantcy = 200*90; |
42 | static u32 video_pts; |
43 | static u32 audio_pts; |
44 | |
45 | static u32 system_time_scale_base = 1; |
46 | static u32 system_time_scale_remainder; |
47 | |
48 | #ifdef MODIFY_TIMESTAMP_INC_WITH_PLL |
49 | #define PLL_FACTOR 10000 |
50 | static u32 timestamp_inc_factor = PLL_FACTOR; |
51 | void set_timestamp_inc_factor(u32 factor) |
52 | { |
53 | timestamp_inc_factor = factor; |
54 | } |
55 | #endif |
56 | |
57 | u32 timestamp_vpts_get(void) |
58 | { |
59 | return video_pts; |
60 | } |
61 | EXPORT_SYMBOL(timestamp_vpts_get); |
62 | |
63 | void timestamp_vpts_set(u32 pts) |
64 | { |
65 | video_pts = pts; |
66 | } |
67 | EXPORT_SYMBOL(timestamp_vpts_set); |
68 | |
69 | void timestamp_vpts_inc(s32 val) |
70 | { |
71 | video_pts += val; |
72 | } |
73 | EXPORT_SYMBOL(timestamp_vpts_inc); |
74 | |
75 | u32 timestamp_apts_get(void) |
76 | { |
77 | return audio_pts; |
78 | } |
79 | EXPORT_SYMBOL(timestamp_apts_get); |
80 | |
81 | void timestamp_apts_set(u32 pts) |
82 | { |
83 | audio_pts = pts; |
84 | } |
85 | EXPORT_SYMBOL(timestamp_apts_set); |
86 | |
87 | void timestamp_apts_inc(s32 inc) |
88 | { |
89 | if (audio_pts_up) { |
90 | #ifdef MODIFY_TIMESTAMP_INC_WITH_PLL |
91 | inc = inc * timestamp_inc_factor / PLL_FACTOR; |
92 | #endif |
93 | audio_pts += inc; |
94 | } |
95 | } |
96 | EXPORT_SYMBOL(timestamp_apts_inc); |
97 | |
98 | void timestamp_apts_enable(u32 enable) |
99 | { |
100 | audio_pts_up = enable; |
101 | pr_info("timestamp_apts_enable enable:%x,\n", enable); |
102 | } |
103 | EXPORT_SYMBOL(timestamp_apts_enable); |
104 | |
105 | void timestamp_apts_start(u32 enable) |
106 | { |
107 | audio_pts_started = enable; |
108 | pr_info("audio pts started::::::: %d\n", enable); |
109 | } |
110 | EXPORT_SYMBOL(timestamp_apts_start); |
111 | |
112 | u32 timestamp_apts_started(void) |
113 | { |
114 | return audio_pts_started; |
115 | } |
116 | EXPORT_SYMBOL(timestamp_apts_started); |
117 | |
118 | u32 timestamp_pcrscr_get(void) |
119 | { |
120 | if (tsync_get_mode() == TSYNC_MODE_AMASTER) |
121 | return system_time; |
122 | |
123 | if (tsdemux_pcrscr_valid_cb && tsdemux_pcrscr_valid_cb()) { |
124 | if (tsync_pcr_demux_pcr_used() == 0) { |
125 | return system_time; |
126 | } |
127 | else { |
128 | if (tsdemux_pcrscr_get_cb) |
129 | return tsdemux_pcrscr_get_cb()-pcrscr_lantcy; |
130 | else |
131 | return system_time; |
132 | } |
133 | } else |
134 | return system_time; |
135 | } |
136 | EXPORT_SYMBOL(timestamp_pcrscr_get); |
137 | |
138 | u32 timestamp_tsdemux_pcr_get(void) |
139 | { |
140 | if (tsdemux_pcrscr_get_cb) |
141 | return tsdemux_pcrscr_get_cb(); |
142 | |
143 | return (u32)-1; |
144 | } |
145 | EXPORT_SYMBOL(timestamp_tsdemux_pcr_get); |
146 | |
147 | void timestamp_pcrscr_set(u32 pts) |
148 | { |
149 | /*pr_info("timestamp_pcrscr_set system time = %x\n", pts);*/ |
150 | system_time = pts; |
151 | } |
152 | EXPORT_SYMBOL(timestamp_pcrscr_set); |
153 | |
154 | void timestamp_firstvpts_set(u32 pts) |
155 | { |
156 | first_vpts = pts; |
157 | pr_info("video first pts = %x\n", first_vpts); |
158 | } |
159 | EXPORT_SYMBOL(timestamp_firstvpts_set); |
160 | |
161 | u32 timestamp_firstvpts_get(void) |
162 | { |
163 | return first_vpts; |
164 | } |
165 | EXPORT_SYMBOL(timestamp_firstvpts_get); |
166 | |
167 | void timestamp_checkin_firstvpts_set(u32 pts) |
168 | { |
169 | first_checkin_vpts = pts; |
170 | pr_info("video first checkin pts = %x\n", first_checkin_vpts); |
171 | } |
172 | EXPORT_SYMBOL(timestamp_checkin_firstvpts_set); |
173 | |
174 | void timestamp_checkin_firstapts_set(u32 pts) |
175 | { |
176 | first_checkin_apts = pts; |
177 | pr_info("audio first checkin pts =%x\n", first_checkin_apts); |
178 | } |
179 | EXPORT_SYMBOL(timestamp_checkin_firstapts_set); |
180 | |
181 | u32 timestamp_checkin_firstvpts_get(void) |
182 | { |
183 | return first_checkin_vpts; |
184 | } |
185 | EXPORT_SYMBOL(timestamp_checkin_firstvpts_get); |
186 | |
187 | u32 timestamp_checkin_firstapts_get(void) |
188 | { |
189 | return first_checkin_apts; |
190 | } |
191 | EXPORT_SYMBOL(timestamp_checkin_firstapts_get); |
192 | |
193 | void timestamp_firstapts_set(u32 pts) |
194 | { |
195 | first_apts = pts; |
196 | pr_info("audio first pts = %x\n", first_apts); |
197 | } |
198 | EXPORT_SYMBOL(timestamp_firstapts_set); |
199 | |
200 | u32 timestamp_firstapts_get(void) |
201 | { |
202 | return first_apts; |
203 | } |
204 | EXPORT_SYMBOL(timestamp_firstapts_get); |
205 | |
206 | void timestamp_pcrscr_inc(s32 inc) |
207 | { |
208 | if (system_time_up) { |
209 | #ifdef MODIFY_TIMESTAMP_INC_WITH_PLL |
210 | inc = inc * timestamp_inc_factor / PLL_FACTOR; |
211 | #endif |
212 | system_time += inc + system_time_inc_adj; |
213 | } |
214 | } |
215 | EXPORT_SYMBOL(timestamp_pcrscr_inc); |
216 | |
217 | void timestamp_pcrscr_inc_scale(s32 inc, u32 base) |
218 | { |
219 | if (system_time_scale_base != base) { |
220 | system_time_scale_remainder = |
221 | system_time_scale_remainder * |
222 | base / system_time_scale_base; |
223 | system_time_scale_base = base; |
224 | } |
225 | |
226 | if (system_time_up) { |
227 | u32 r; |
228 | |
229 | system_time += |
230 | div_u64_rem(90000ULL * inc, base, &r) + |
231 | system_time_inc_adj; |
232 | system_time_scale_remainder += r; |
233 | if (system_time_scale_remainder >= system_time_scale_base) { |
234 | system_time++; |
235 | system_time_scale_remainder -= system_time_scale_base; |
236 | } |
237 | } |
238 | } |
239 | EXPORT_SYMBOL(timestamp_pcrscr_inc_scale); |
240 | |
241 | void timestamp_pcrscr_set_adj(s32 inc) |
242 | { |
243 | system_time_inc_adj = inc; |
244 | } |
245 | EXPORT_SYMBOL(timestamp_pcrscr_set_adj); |
246 | |
247 | void timestamp_pcrscr_set_adj_pcr(s32 inc) |
248 | { |
249 | const struct vinfo_s *info = get_current_vinfo(); |
250 | |
251 | if (inc != 0) { |
252 | system_time_inc_adj = |
253 | 900 * info->sync_duration_den / |
254 | (info->sync_duration_num*inc); |
255 | } else |
256 | system_time_inc_adj = 0; |
257 | } |
258 | EXPORT_SYMBOL(timestamp_pcrscr_set_adj_pcr); |
259 | |
260 | void timestamp_pcrscr_enable(u32 enable) |
261 | { |
262 | system_time_up = enable; |
263 | } |
264 | EXPORT_SYMBOL(timestamp_pcrscr_enable); |
265 | |
266 | u32 timestamp_pcrscr_enable_state(void) |
267 | { |
268 | return system_time_up; |
269 | } |
270 | EXPORT_SYMBOL(timestamp_pcrscr_enable_state); |
271 | |
272 | MODULE_DESCRIPTION("AMLOGIC time sync management driver"); |
273 | MODULE_LICENSE("GPL"); |
274 | MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>"); |
275 |