1 /*******************************************************************************
2 * Copyright (C) 2018 Cadence Design Systems, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to use this Software with Cadence processor cores only and
7 * not with any other processors and platforms, subject to
8 * the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included
11 * in all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
18 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 
21 ******************************************************************************/
22 
23 /*******************************************************************************
24  * xf-timebase.h
25  *
26  * Common timebase for deadline-driven scheduler
27  *
28  *******************************************************************************/
29 
30 #ifndef __XF_H
31 #error "xf-timebase.h mustn't be included directly"
32 #endif
33 
34 /*******************************************************************************
35  * Timebase for deadline-driven scheduler
36  ******************************************************************************/
37 #ifdef XAF_ENABLE_NON_HIKEY
38 /* ...set internal scheduler frequency as a LCM of all supported sample rates;
39  * it is in general not a problem to have large number here, however it should
40  * be noted that maximal-size audio-buffer that we handle, when expressed in
41  * ticks of this virtual frequency, must not exceed 2**31 (for otherwise
42  * scheduler timestamp comparison function will misbehave).
43  */
44 #define XF_TIMEBASE_FREQ           (4 * 3 * 56448000U)
45 /* ...add paranoic check considering maximal audio-buffer duration as 0.1 sec */
46 C_BUG((u32)(XF_TIMEBASE_FREQ / 10) >= (1 << 31));
47 #else
48 /* ...set internal scheduler frequency as a LCM of all supported sample rates */
49 #define XF_TIMEBASE_FREQ           56448000U
50 #endif
51 /* ...supported sampling rates */
52 C_BUG(XF_TIMEBASE_FREQ % 4000);
53 C_BUG(XF_TIMEBASE_FREQ % 8000);
54 C_BUG(XF_TIMEBASE_FREQ % 11025);
55 C_BUG(XF_TIMEBASE_FREQ % 12000);
56 C_BUG(XF_TIMEBASE_FREQ % 16000);
57 C_BUG(XF_TIMEBASE_FREQ % 22050);
58 C_BUG(XF_TIMEBASE_FREQ % 24000);
59 C_BUG(XF_TIMEBASE_FREQ % 32000);
60 C_BUG(XF_TIMEBASE_FREQ % 44100);
61 C_BUG(XF_TIMEBASE_FREQ % 48000);
62 C_BUG(XF_TIMEBASE_FREQ % 64000);
63 C_BUG(XF_TIMEBASE_FREQ % 88200);
64 C_BUG(XF_TIMEBASE_FREQ % 96000);
65 C_BUG(XF_TIMEBASE_FREQ % 128000);
66 C_BUG(XF_TIMEBASE_FREQ % 176400);
67 C_BUG(XF_TIMEBASE_FREQ % 192000);
68 
69 /* ...calculate upsampling factor for given sample rate */
xf_timebase_factor(u32 sample_rate)70 static inline u32 xf_timebase_factor(u32 sample_rate)
71 {
72     /* ...probably we can tolerate single division */
73     switch(sample_rate)
74     {
75     case 4000:
76         return XF_TIMEBASE_FREQ / 4000;
77     case 8000:
78         return XF_TIMEBASE_FREQ / 8000;
79     case 11025:
80         return XF_TIMEBASE_FREQ / 11025;
81     case 12000:
82         return XF_TIMEBASE_FREQ / 11025;
83     case 16000:
84         return XF_TIMEBASE_FREQ / 16000;
85     case 22050:
86         return XF_TIMEBASE_FREQ / 22050;
87     case 24000:
88         return XF_TIMEBASE_FREQ / 24000;
89     case 32000:
90         return XF_TIMEBASE_FREQ / 32000;
91     case 44100:
92         return XF_TIMEBASE_FREQ / 44100;
93     case 48000:
94         return XF_TIMEBASE_FREQ / 48000;
95     case 64000:
96         return XF_TIMEBASE_FREQ / 64000;
97     case 88200:
98         return XF_TIMEBASE_FREQ / 88200;
99     case 96000:
100         return XF_TIMEBASE_FREQ / 96000;
101     case 128000:
102         return XF_TIMEBASE_FREQ / 128000;
103     case 176400:
104         return XF_TIMEBASE_FREQ / 176400;
105     case 192000:
106         return XF_TIMEBASE_FREQ / 192000;
107     default:
108         return 0;
109     }
110 }
111 
112 /* ...core timebase */
xf_core_timebase(u32 core)113 static inline u32 xf_core_timebase(u32 core)
114 {
115     xf_core_data_t     *cd = XF_CORE_DATA(core);
116 
117     /* ...get local scheduler timebase */
118     return xf_sched_timestamp(&cd->sched);
119 }
120 
121 /* ...compare timestamps */
xf_time_after(u32 a,u32 b)122 static inline int xf_time_after(u32 a, u32 b)
123 {
124     return ((s32)(a - b) > 0);
125 }
126 
127 /* ...compare timstamps */
xf_time_before(u32 a,u32 b)128 static inline int xf_time_before(u32 a, u32 b)
129 {
130     return ((s32)(a - b) < 0);
131 }
132 
133