KT24-1110_65E-HA-651B/cpu/br25/clock_manager.c
2024-11-10 18:44:17 +08:00

415 lines
10 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "system/includes.h"
#include "app_config.h"
#include "clock_cfg.h"
#include "asm/dac.h"
struct clock_type {
u8 type;
u32 clock;
const char *name;
};
/*****
idle clk : 模式里面的空闲时钟
时钟通过idle clk 加上每一种解码或者运算的时钟
累加总和来设置需要的时钟
模式空闲时钟设置
void clock_idle(u32 type)
把时钟设置加入到ext中但是不是立刻设置时钟
需要最后调用clock_set_cur来最后设置时钟
用于连续地方设置时钟
用完后必须把时钟remove
void clock_add(u32 type)
void clock_remove(u32 type)
void clock_set_cur(void)
把时钟设置加入到ext中立刻设置时钟
需要立刻添加时钟
用完后必须把时钟remove
void clock_add_set(u32 type)
void clock_remove_set(u32 type)
*****/
//// 如果clock_fix 为0 就按照配置设置时钟,如果有值就固定频率
#if (TCFG_MIC_EFFECT_ENABLE)
#define CLOCK_FIX 192
#else
#define CLOCK_FIX 0
#endif
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_FRONT_LR_REAR_LR) && TCFG_EQ_DIVIDE_ENABLE
#define EQ4_CLK (24)
#else
#define EQ4_CLK (0)
#endif
#if TCFG_EQ_ONLINE_ENABLE
#define EQ_ONLINE_CLK (64)
#else
#define EQ_ONLINE_CLK (0)
#endif
#define MIX_SRC_CLK (24)//src
DEFINE_SPINLOCK(clock_lock);
const struct clock_type clock_enum[] = {
{ BT_IDLE_CLOCK , (32), " BT_IDLE_CLOCK " },
#ifndef CONFIG_SOUNDBOX_FLASH_256K
{ MUSIC_IDLE_CLOCK , (24), " MUSIC_IDLE_CLOCK " },
{ FM_IDLE_CLOCK , (12), " FM_IDLE_CLOCK " },
{ LINEIN_IDLE_CLOCK , (96), " LINEIN_IDLE_CLOCK " },
{ PC_IDLE_CLOCK , (120), " PC_IDLE_CLOCK " },
{ REC_IDLE_CLOCK , (12), " REC_IDLE_CLOCK " },
{ RTC_IDLE_CLOCK , (12), " RTC_IDLE_CLOCK " },
{ SPDIF_IDLE_CLOCK , (12), " SPDIF_IDLE_CLOCK " },
{ BOX_IDLE_CLOCK , (24), " BOX_IDLE_CLOCK " },
{ DEC_SBC_CLK , (32), "DEC_SBC_CLK " },
{ DEC_AAC_CLK , (32), "DEC_AAC_CLK " },
#endif
{ DEC_MSBC_CLK , (12), "DEC_MSBC_CLK " },
{ DEC_CVSD_CLK , (8), "DEC_CVSD_CLK " },
{ AEC8K_CLK , (10), "AEC8K_CLK " },
{ AEC8K_ADV_CLK , (50), "AEC8K_ADV_CLK " },
{ AEC16K_CLK , (10), "AEC16K_CLK " },
{ AEC16K_ADV_CLK, (50), "AEC16K_ADV_CLK " },
{ AEC8K_SPX_CLK , (10), "AEC8K_SPX_CLK " },
{ AEC16K_SPX_CLK, (10), "AEC16K_SPX_CLK " },
{ DEC_TONE_CLK , (24 + 32), "DEC_TONE_CLK " },
{ DEC_G729_CLK , (24), "DEC_G729_CLK " },
{ DEC_PCM_CLK , (24), "DEC_PCM_CLK " },
#ifndef CONFIG_SOUNDBOX_FLASH_256K
{ DEC_MP3_CLK , (80), "DEC_MP3_CLK " },
{ DEC_WAV_CLK , (48), "DEC_WAV_CLK " },
{ DEC_G726_CLK , (24), "DEC_G726_CLK " },
{ DEC_MTY_CLK , (24), "DEC_MTY_CLK " },
{ DEC_WMA_CLK , (48), "DEC_WMA_CLK " },
{ DEC_APE_CLK , (160), "DEC_APE_CLK "},
{ DEC_FLAC_CLK , (96), "DEC_FLAC_CLK "},
{ DEC_AMR_CLK , (96), "DEC_AMR_CLK "},
{ DEC_DTS_CLK , (120), "DEC_DTS_CLK " },
{ DEC_M4A_CLK , (48), "DEC_M4A_CLK "},
{ DEC_ALAC_CLK , (48), "DEC_ALAC_CLK "},
{ DEC_FM_CLK , (12), "DEC_FM_CLK " },
{ DEC_LINE_CLK , (24), "DEC_LINE_CLK " },
{ DEC_TWS_SBC_CLK, (32), "DEC_TWS_SBC_CLK" },
{ SPDIF_CLK , (120), "SPDIF_CLK " },
{ ENC_RECODE_CLK, (64), "ENC_RECODE_CLK " },
{ ENC_SBC_CLK , (64), "ENC_SBC_CLK " },
{ ENC_WAV_CLK , (96), "ENC_WAV_CLK " },
{ ENC_G726_CLK, (64), "ENC_G726_CLK " },
{ ENC_MP3_CLK , (120), "ENC_MP3_CLK " },
{ ENC_TWS_SBC_CLK, (48), "ENC_TWS_SBC_CLK" },
#endif
{ ENC_MSBC_CLK , (12), "ENC_MSBC_CLK " },
{ ENC_CVSD_CLK , (8), "ENC_CVSD_CLK " },
{ SYNC_CLK , (4), "SYNC_CLK " },
{ AUTOMUTE_CLK , (16), "AUTOMUTE_CLK" },
#ifndef CONFIG_SOUNDBOX_FLASH_256K
{ FINDF_CLK , (120), "FINDF_CLK " },
{ FM_INSIDE_CLK , (96), "FM_INSIDE_CLK " },
#endif
#if TCFG_DEC2TWS_ENABLE
{ BT_CONN_CLK , (48), "BT_CONN_CLK " },
#else
{ BT_CONN_CLK , (16), "BT_CONN_CLK " },
#endif
{ EQ_CLK , (24 + EQ_ONLINE_CLK + EQ4_CLK), " EQ_CLK " },
{ EQ_DRC_CLK , (60), " EQ_DRC_CLK " },
/* { EQ_ONLINE_CLK, (120), " EQ_ONLINE_CLK " }, */
#ifndef CONFIG_SOUNDBOX_FLASH_256K
{ REVERB_CLK , (64), " REVERB_CLK " },
{ REVERB_HOWLING_CLK , (32), " REVERB_HOWLING_CLK " },
{ REVERB_PITCH_CLK , (24), " REVERB_PITCH_CLK " },
{ DEC_MP3PICK_CLK, (8), "DEC_MP3PICK_CLK" },
{ DEC_WMAPICK_CLK, (8), "DEC_WMAICK_CLK" },
{ DEC_M4APICK_CLK, (8), "DEC_M4AICK_CLK" },
#endif
{ DEC_MIX_CLK, (6 + MIX_SRC_CLK), "DEC_MIX_CLK" },
{ DEC_UI_CLK, (8), "DEC_UI_CLK" },
#ifndef CONFIG_SOUNDBOX_FLASH_256K
{ DEC_IIS_CLK, (64), "DEC_IIS_CLK" },
//midi音色文件跳转读取频繁外挂flash baud 调到6000000L, midi_clk 80M就够
{ DEC_MIDI_CLK, (110), "DEC_MIDI_CLK" },
/* { DEC_MIDI_CLK, (80), "DEC_MIDI_CLK" }, */
{ DEC_3D_CLK, (24), "DEC_3D_CLK" },
{ DEC_VBASS_CLK, (24), "DEC_VBASS_CLK" },
{ DEC_LOUDNES_CLK, (108), "DEC_LOUDNES_CLK"},
{ DONGLE_ENC_CLK, (48), "DONGLE_ENC_CLK" },
#endif
{ SCAN_DISK_CLK, (120), "SCAN_DISK_CLK" },//提高扫盘速度
#if TCFG_DEC2TWS_ENABLE
{ LOCALTWS_CLK, (24), "LOCALTWS_CLK" },
#endif
{SPECTRUM_CLK, (5), "SPECTRUM_CLK" },
{AI_SPEECH_CLK, (120), "AI_SPEECH_CLK" },
{SMARTBOX_ACTION_CLK, (160), "SMARTBOX_ACTION_CLK" },
#ifdef CONFIG_ADAPTER_ENABLE
{ADAPTER_PROCESS_CLK, (64), "ADAPTER_PROCESS_CLK" },
#endif
};
const u8 clock_tb[] = {
24,
32,
48,
60,
80,
96,
120,
160,
192,
};
static u8 ext_clk_tb[10];
static u32 idle_type = 0;
static void clock_ext_dump()
{
u8 i, j;
for (i = 0; i < ARRAY_SIZE(clock_enum); i++) {
if (idle_type == clock_enum[i].type) {
y_printf("--- %d %s \n", clock_enum[i].clock, clock_enum[i].name);
break;
}
}
for (i = 0; i < ARRAY_SIZE(ext_clk_tb); i++) {
if (ext_clk_tb[i]) {
for (j = 0; j < ARRAY_SIZE(clock_enum); j++) {
if (ext_clk_tb[i] == clock_enum[j].type) {
y_printf("--- %d %s \n", clock_enum[j].clock, clock_enum[j].name);
continue;
}
}
}
}
}
u8 clock_idle_selet(u32 type)
{
u8 i;
#if (CLOCK_FIX )
return CLOCK_FIX;
#endif
for (i = 0; i < ARRAY_SIZE(clock_enum); i++) {
if (type == clock_enum[i].type) {
/* y_printf("--- %d %s \n", clock_enum[i].clock, clock_enum[i].name); */
return clock_enum[i].clock;
}
}
return 24;
}
u8 clock_ext_push(u8 ext_type)
{
u8 i;
for (i = 0; i < ARRAY_SIZE(ext_clk_tb); i++) {
if (ext_type == ext_clk_tb[i]) {
return 0;
}
}
for (i = 0; i < ARRAY_SIZE(ext_clk_tb); i++) {
if (!ext_clk_tb[i]) {
ext_clk_tb[i] = ext_type;
return 1;
}
}
y_printf("clock ext over!!! \n");
return 0;
}
u8 clock_ext_pop(u8 ext_type)
{
u8 i;
for (i = 0; i < ARRAY_SIZE(ext_clk_tb); i++) {
if (ext_type == ext_clk_tb[i]) {
ext_clk_tb[i] = 0;
return 1;
}
}
return 0;
}
u16 clock_match(u16 clk)
{
u8 i;
for (i = 0; i < ARRAY_SIZE(clock_tb); i++) {
if (clk <= clock_tb[i]) {
return clock_tb[i];
}
}
y_printf("clock overlimit!!! %d\n", clock_tb[ARRAY_SIZE(clock_tb) - 1]);
return clock_tb[ARRAY_SIZE(clock_tb) - 1];
}
u16 clock_ext_cal()
{
u32 ext_clk = 0 ;
u8 i, j;
for (i = 0; i < ARRAY_SIZE(ext_clk_tb); i++) {
if (ext_clk_tb[i]) {
for (j = 0; j < ARRAY_SIZE(clock_enum); j++) {
if (ext_clk_tb[i] == clock_enum[j].type) {
/* y_printf("--- %d %s \n", clock_enum[j].clock, clock_enum[j].name); */
ext_clk += clock_enum[j].clock;
continue;
}
}
}
}
return ext_clk;
}
u32 clock_cur_cal()
{
u32 idle_clk, cur_clk, ext_clk;
#if (CLOCK_FIX )
return CLOCK_FIX;
#endif
local_irq_disable();
idle_clk = clock_idle_selet(idle_type);
ext_clk = clock_ext_cal();
cur_clk = idle_clk + ext_clk;
cur_clk = clock_match(cur_clk);
local_irq_enable();
return cur_clk ;
}
void clock_pause_play(u8 mode)
{
u32 idle_clk, cur_clk ;
spin_lock(&clock_lock);
if (mode) {
idle_clk = clock_idle_selet(idle_type);
clk_set("sys", idle_clk * 1000000L);
} else {
clock_ext_dump();
cur_clk = clock_cur_cal();
clk_set("sys", cur_clk * 1000000L);
}
spin_unlock(&clock_lock);
}
void clock_idle(u32 type)
{
u32 cur_clk;
spin_lock(&clock_lock);
local_irq_disable();
idle_type = type;
cur_clk = clock_cur_cal();
local_irq_enable();
clock_ext_dump();
clk_set("sys", cur_clk * 1000000L);
spin_unlock(&clock_lock);
}
//////把时钟设置加入到ext中但是不是立刻设置时钟
void clock_add(u32 type)
{
u32 cur_clk ;
spin_lock(&clock_lock);
u8 resoult = clock_ext_push(type);
spin_unlock(&clock_lock);
if (!resoult) {
return;
}
}
void clock_remove(u32 type)
{
u32 cur_clk ;
spin_lock(&clock_lock);
u8 resoult = clock_ext_pop(type);
spin_unlock(&clock_lock);
if (!resoult) {
return;
}
}
void clock_set_cur(void)
{
u32 cur_clk ;
spin_lock(&clock_lock);
clock_ext_dump();
cur_clk = clock_cur_cal();
clk_set("sys", cur_clk * 1000000L);
spin_unlock(&clock_lock);
}
//////把时钟设置加入到ext中立刻设置时钟
void clock_add_set(u32 type)
{
u32 cur_clk ;
spin_lock(&clock_lock);
u8 resoult = clock_ext_push(type);
if (!resoult) {
spin_unlock(&clock_lock);
return;
}
clock_ext_dump();
cur_clk = clock_cur_cal();
clk_set("sys", cur_clk * 1000000L);
spin_unlock(&clock_lock);
}
void clock_remove_set(u32 type)
{
u32 cur_clk ;
spin_lock(&clock_lock);
u8 resoult = clock_ext_pop(type);
if (!resoult) {
spin_unlock(&clock_lock);
return;
}
clock_ext_dump();
cur_clk = clock_cur_cal();
clk_set("sys", cur_clk * 1000000L);
spin_unlock(&clock_lock);
}