| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- /*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /*******************************************************************************
- *
- * Filename:
- * ---------
- * AudDrv_devtree_parser.c
- *
- * Project:
- * --------
- *
- *
- * Description:
- * ------------
- * AudDrv_devtree_parser
- *
- * Author:
- * -------
- * Chipeng Chang (mtk02308)
- *
- *------------------------------------------------------------------------------
- *
- *
- *******************************************************************************/
- #include <mt-plat/aee.h>
- #include "auddrv_underflow_mach.h"
- #define UnderflowrecordNumber (20)
- static bool bEnableDump;
- /* default setting for samplerate and interrupt count */
- static unsigned int mDlSamplerate = 44100;
- static const unsigned int DlSampleRateUpperBound = 192000;
- static unsigned int InterruptSample = 1024;
- static const unsigned int InterruptSampleUpperBound = 192000;
- /* static bool bDumpInit = false; */
- static unsigned int mDL1InterruptInterval;
- static unsigned int mDL1_Interrupt_Interval_Limit;
- static unsigned int mDl1Numerator = 8; /* 1.6 */
- static unsigned int mDl1denominator = 5;
- static unsigned long long Irq_time_t1 = 0, Irq_time_t2;
- static bool bAudioInterruptChange;
- static unsigned long long UnderflowTime[UnderflowrecordNumber] = { 0 };
- static unsigned int UnderflowCounter;
- static unsigned int UnderflowThreshold = 3;
- static void ClearInterruptTiming(void);
- static void DumpUnderFlowTime(void);
- static void ClearUnderFlowTime(void);
- void SetUnderFlowThreshold(unsigned int Threshold)
- {
- UnderflowThreshold = Threshold;
- }
- /* base on devtree name to pares dev tree. */
- void Auddrv_Aee_Dump(void)
- {
- pr_debug("+%s\n", __func__);
- if (bEnableDump == true) {
- #ifdef _GIT318_READY
- aee_kernel_exception_api(__FILE__, __LINE__, DB_OPT_FTRACE, "Audio is blocked",
- "audio blocked dump ftrace");
- #endif
- }
- Auddrv_Reset_Dump_State();
- pr_debug("-%s\n", __func__);
- }
- /*
- / dump underflow time in kernel
- */
- static void DumpUnderFlowTime(void)
- {
- int i = 0;
- pr_debug("%s\n", __func__);
- for (i = 0; i < UnderflowrecordNumber; i++)
- pr_debug("UnderflowTime[%d] = %llu\n", i, UnderflowTime[i]);
- }
- /*
- / when pcm playback is close , need to call this function to clear record.
- */
- void Auddrv_Set_UnderFlow(void)
- {
- unsigned long long underflow_time = sched_clock(); /* in ns (10^9) */
- pr_debug("%s UnderflowCounter = %d\n", __func__, UnderflowCounter);
- UnderflowTime[UnderflowCounter] = underflow_time;
- UnderflowCounter++;
- UnderflowCounter %= UnderflowrecordNumber;
- if (UnderflowCounter > UnderflowThreshold) {
- DumpUnderFlowTime();
- Auddrv_Aee_Dump();
- }
- }
- /*
- / dump underflow time in kernel
- */
- static void ClearUnderFlowTime(void)
- {
- int i = 0;
- for (i = 0; i < UnderflowrecordNumber; i++)
- UnderflowTime[i] = 0;
- UnderflowCounter = 0;
- }
- /*
- / when InterruptSample or mDlSamplerate is change , nned to refine mDL1InterruptInterval
- */
- void Auddrv_Set_Interrupt_Changed(bool bChange)
- {
- bAudioInterruptChange = bChange;
- }
- /*
- / when pcm playback is close , need to call this function to clear record.
- */
- void Auddrv_Reset_Dump_State(void)
- {
- ClearUnderFlowTime();
- Auddrv_Set_Interrupt_Changed(false);
- ClearInterruptTiming();
- }
- /*
- / when in interrupt , call this function to check irq timing
- */
- void Auddrv_CheckInterruptTiming(void)
- {
- if (Irq_time_t1 == 0) {
- Irq_time_t1 = sched_clock(); /* in ns (10^9) */
- } else {
- Irq_time_t2 = Irq_time_t1;
- Irq_time_t1 = sched_clock(); /* in ns (10^9) */
- if (bAudioInterruptChange == true) {
- /* for Audio Interrupt is change , so this interrupt interval may not clear.clearqueue */
- ClearInterruptTiming();
- return;
- }
- if ((Irq_time_t1 > Irq_time_t2) && mDL1_Interrupt_Interval_Limit) {
- pr_debug
- ("%s Irq_time_t2 = %llu Irq_time_t1 = %llu t1 - t2 = %llu Interval_Limit = %d\n",
- __func__, Irq_time_t2, Irq_time_t1, Irq_time_t1 - Irq_time_t2,
- mDL1_Interrupt_Interval_Limit);
- Irq_time_t2 = Irq_time_t1 - Irq_time_t2;
- if (Irq_time_t2 > mDL1_Interrupt_Interval_Limit * 1000000) {
- pr_debug
- ("%s interrupt may be blocked Irq_time_t2 = %llu Interval_Limit = %d\n",
- __func__, Irq_time_t2, mDL1_Interrupt_Interval_Limit);
- }
- }
- }
- }
- static void ClearInterruptTiming(void)
- {
- pr_debug("%s\n", __func__);
- Irq_time_t1 = 0;
- Irq_time_t2 = 0;
- }
- /*
- / when InterruptSample or mDlSamplerate is change , nned to refine mDL1InterruptInterval
- */
- void RefineInterrruptInterval(void)
- {
- mDL1InterruptInterval = ((InterruptSample * 1000) / mDlSamplerate) + 1;
- mDL1_Interrupt_Interval_Limit = mDL1InterruptInterval * mDl1Numerator / mDl1denominator;
- pr_debug("%s mDL1InterruptInterval = %d mDL1_Interrupt_Interval_Limit = %d\n",
- __func__, mDL1InterruptInterval, mDL1_Interrupt_Interval_Limit);
- }
- /*
- / function to set DL sampleRate
- */
- bool Auddrv_Set_DlSamplerate(unsigned int Samplerate)
- {
- pr_debug("%s Samplerate = %d\n", __func__, Samplerate);
- if (Samplerate < DlSampleRateUpperBound) {
- mDlSamplerate = Samplerate;
- RefineInterrruptInterval();
- }
- return true;
- }
- bool Auddrv_Set_InterruptSample(unsigned int count)
- {
- pr_debug("%s count = %d\n", __func__, count);
- if (count < InterruptSampleUpperBound) {
- InterruptSample = count;
- RefineInterrruptInterval();
- Auddrv_Set_Interrupt_Changed(true);
- }
- return true;
- }
- /*
- / function to enable / disable dump , only enable will arised aee
- */
- bool Auddrv_Enable_dump(bool bEnable)
- {
- pr_debug("%s bEnable = %d\n", __func__, bEnable);
- bEnableDump = bEnable;
- return true;
- }
|