Niranjan Yadla | 19336af | 2018-04-19 12:19:27 -0700 | [diff] [blame] | 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 */ |
| 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 */ |
| 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 */ |
| 122 | static inline int xf_time_after(u32 a, u32 b) |
| 123 | { |
| 124 | return ((s32)(a - b) > 0); |
| 125 | } |
| 126 | |
| 127 | /* ...compare timstamps */ |
| 128 | static inline int xf_time_before(u32 a, u32 b) |
| 129 | { |
| 130 | return ((s32)(a - b) < 0); |
| 131 | } |
| 132 | |