#ifdef SUPPORT_GYRO_SERVICE
SORT(*libgyro*.a:*.o*) (.data .data* .sdata .sdata*)
#endif
-#ifdef BOARD_LEINIAO
- SORT(*libthunderbird_toys*.a:*.o*) (.data .data* .sdata .sdata*)
-#endif
#ifdef CUSTOM_ZHIHUI
SORT(*libaiMediaService*.a:*.o*) (.data .data* .sdata .sdata*)
SORT(*libzhihui_websocket*.a:*.o*) (.data .data* .sdata .sdata*)
SORT(*libcustom_utils*.a:*.o*) (.data .data* .sdata .sdata*)
#endif
SORT(*libace_adapt.a:*.o*) (.data .data* .sdata .sdata*)
+ SORT(*libace_ext.a:*.o*) (.data .data* .sdata .sdata*)
+ SORT(*libace_ble*.a:*.o*) (.data .data* .sdata .sdata*)
SORT(*libace_http*.a:*.o*) (.data .data* .sdata .sdata*)
+ SORT(*libace_websocket*.a:*.o*) (.data .data* .sdata .sdata*)
SORT(*libnetstack_http*.a:*.o*) (.data .data* .sdata .sdata*)
SORT(*libwebsocket*.a:*.o*) (.data .data* .sdata .sdata*)
SORT(*libjerryscript*.a:*.o*) (.data .data* .sdata .sdata*)
#ifdef SUPPORT_GYRO_SERVICE
SORT(*libgyro*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
#endif
-#ifdef BOARD_LEINIAO
- SORT(*libthunderbird_toys*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
-#endif
#ifdef CUSTOM_ZHIHUI
SORT(*libaiMediaService*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
SORT(*libzhihui_websocket*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
SORT(*libcustom_utils*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
#endif
SORT(*libace_adapt.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
+ SORT(*libace_ext.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
+ SORT(*libace_ble*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
SORT(*libace_http*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
+ SORT(*libace_websocket*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
SORT(*libnetstack_http*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
SORT(*libwebsocket*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
SORT(*libjerryscript*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
{
__l2m_gpu_text_start = .;
__l2m_gpu_text_load = LOADADDR(.l2m_gpu_text);
- . = ALIGN(8);
- *libdisplay_gfx.a:yuv_to_rgb.c.obj* (.text .text* .rodata .rodata* .srodata .srodata*)
- . = ALIGN(8);
__l2m_gpu_text_end = .;
} > L2M_GPU_PROGRAM AT > FLASH_PROGRAM
__l2m_gpu_text_size = __l2m_gpu_text_end - __l2m_gpu_text_start;
.l2m_gpu_bss :
{
__l2m_gpu_bss_start = .;
- . = ALIGN(8);
- *libdisplay_gfx.a:yuv_to_rgb.c.obj* (.bss .bss* .sbss .sbss* COMMON)
- . = ALIGN(8);
__l2m_gpu_bss_end = .;
} > L2M_GPU_PROGRAM
__l2m_gpu_bss_size = __l2m_gpu_bss_end - __l2m_gpu_bss_start;
{
__l2m_gpu_data_start = .;
__l2m_gpu_data_load = LOADADDR(.l2m_gpu_data);
- . = ALIGN(8);
- *libdisplay_gfx.a:yuv_to_rgb.c.obj* (.data .data* .sdata .sdata*)
- . = ALIGN(8);
__l2m_gpu_data_end = .;
} > L2M_GPU_PROGRAM AT > FLASH_PROGRAM
__l2m_gpu_data_size = __l2m_gpu_data_end - __l2m_gpu_data_start;
*utils/pm*.a:*.o* (.text .text* .rodata .rodata* .srodata .srodata*)
*middleware/chips/brandy/pm*.a:*.o* (.text .text* .rodata .rodata* .srodata .srodata*)
KEEP(*(.text.lcd_get_status));
+ KEEP(*(.text.uapi_is_lcd_connect));
/* In particular, memcpy_s and memset_s must be placed in itcm. */
SORT(*libsec.a:*.o*) (.text .text* .rodata .rodata* .srodata .srodata*)
SORT(*libcsysdeps.a:*.o*) (.text .text* .rodata .rodata* .srodata .srodata*)
SORT(*platform/testsuite/test_dhry*.a:*.o*) (.text .text* .rodata .rodata* .srodata .srodata*)
#endif
SORT(*systemview.a:*.o*) (.text .text* .rodata .rodata* .srodata .srodata*)
+ *libdisplay_gfx.a:yuv_to_rgb.c.obj* (.text .text* .rodata .rodata* .srodata .srodata*)
. = ALIGN(8);
__init_array_start = .;
KEEP(*(.ctors .init_array*))
SORT(*test/platform/testsuite*.a:*.o*) (.data .data*)
#endif
SORT(*systemview.a:*.o*) (.data .data*)
+ *libdisplay_gfx.a:yuv_to_rgb.c.obj* (.data .data*)
*(.data)
*(.data*)
*(.got)
SORT(*test/common/testsuite*.a:*.o*) (.sdata .sdata*)
SORT(*test/platform/testsuite*.a:*.o*) (.sdata .sdata*)
#endif
+ *libdisplay_gfx.a:yuv_to_rgb.c.obj* (.sdata .sdata*)
*(.sdata)
*(.sdata*)
. = ALIGN(0x4);
SORT(*test/platform/testsuite*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
#endif
SORT(*systemview.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
+ *libdisplay_gfx.a:yuv_to_rgb.c.obj* (.bss .bss* .sbss .sbss* COMMON)
*(.bss)
*(.bss*)
*(.sbss)
#define OPUS_ENC_BIT_RATE 16000 // opus编码码率
#define MP3_ENC_BIT_RATE 16000 // mp3编码码率
+
+// volume
+#define DEFAULTE_AI_VOL_DB_INTERGER 24 // 默认的AI的音量值整数部分,单位DB
/**
* @}
*/
#define OPUS_ENC_BIT_RATE 16000 // opus编码码率
#define MP3_ENC_BIT_RATE 16000 // mp3编码码率
+
+// volume
+#define DEFAULTE_AI_VOL_DB_INTERGER 24 // 默认的AI的音量值整数部分,单位DB
/**
* @}
*/
#include "hal_xip.h"
#endif
+void mmc_set_sd_bus_clk_div(uint32_t freq_div);
+
#if defined(BUILD_APPLICATION_STANDARD) || defined(TEST_SUITE)
static system_clocks_config_t g_current_system_clock_config = CLOCKS_CONFIG_MAX;
void clocks_system_init(void)
for (i = 0; i < length; i++) {
hal_clocks_app_perips_config(mcu_perip_clks[i].perip, mcu_perip_clks[i].on);
}
+
+ mmc_set_sd_bus_clk_div(0x1);
}
#else
return clocks_get_ccrg_clk_freq(CLOCKS_CCRG_MODULE_MCU_CORE);
}
+uint32_t clocks_get_spi_frequency(void)
+{
+ return clocks_get_ccrg_clk_freq(CLOCKS_CCRG_MODULE_MCU_PERP_SPI);
+}
+
uint32_t clocks_get_tcxo_clock(void)
{
return TCXO_1X_CLK;
{CLOCKS_CLK_SRC_TCXO, CLOCK_DIV_1}, // CLOCKS_CCRG_MODULE_MCU_PERP_UART\r
{CLOCKS_CLK_SRC_TCXO, CLOCK_DIV_1}, // CLOCKS_CCRG_MODULE_MCU_PERP_SPI\r
{CLOCKS_CLK_SRC_TCXO, CLOCK_DIV_1}, // CLOCKS_CCRG_MODULE_COM_BUS\r
- {CLOCKS_CLK_SRC_PLL, CLOCK_DIV_3}, // CLOCKS_CCRG_MODULE_SDIOM\r
+ {CLOCKS_CLK_SRC_PLL, CLOCK_DIV_9}, // CLOCKS_CCRG_MODULE_SDIOM\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_8}, // CLOCKS_CCRG_MODULE_MEM_BUS\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_4}, // CLOCKS_CCRG_MODULE_XIP_OPI\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_5}, // CLOCKS_CCRG_MODULE_XIP_QSPI\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_4}, // CLOCKS_CCRG_MODULE_MCU_CORE\r
{CLOCKS_CLK_SRC_TCXO, CLOCK_DIV_1}, // CLOCKS_CCRG_MODULE_MCU_PERP_LS\r
{CLOCKS_CLK_SRC_TCXO, CLOCK_DIV_1}, // CLOCKS_CCRG_MODULE_MCU_PERP_UART\r
- {CLOCKS_CLK_SRC_PLL, CLOCK_DIV_10}, // CLOCKS_CCRG_MODULE_MCU_PERP_SPI\r
+ {CLOCKS_CLK_SRC_TCXO, CLOCK_DIV_1}, // CLOCKS_CCRG_MODULE_MCU_PERP_SPI\r
{CLOCKS_CLK_SRC_TCXO, CLOCK_DIV_1}, // CLOCKS_CCRG_MODULE_COM_BUS\r
- {CLOCKS_CLK_SRC_PLL, CLOCK_DIV_3}, // CLOCKS_CCRG_MODULE_SDIOM\r
+ {CLOCKS_CLK_SRC_PLL, CLOCK_DIV_9}, // CLOCKS_CCRG_MODULE_SDIOM\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_5}, // CLOCKS_CCRG_MODULE_MEM_BUS\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_3}, // CLOCKS_CCRG_MODULE_XIP_OPI\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_5}, // CLOCKS_CCRG_MODULE_XIP_QSPI\r
{CLOCKS_CLK_SRC_TCXO_2X, CLOCK_DIV_1}, // sdiom: 64M\r
#endif\r
{CLOCKS_CLK_SRC_TCXO_2X, CLOCK_DIV_1}, // gpu: 64M\r
- {CLOCKS_CLK_SRC_TCXO_2X, CLOCK_DIV_1}, // spi: 64M\r
+ {CLOCKS_CLK_SRC_TCXO, CLOCK_DIV_1}, // spi: 32M\r
},\r
{ // CLOCKS_M_H0\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_8}, // mcu_clk:110M\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_4}, // psram_clk:225M\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_8}, // membus:110M\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_5}, // flash: norflash & nandflash: 176M\r
- {CLOCKS_CLK_SRC_PLL, CLOCK_DIV_3}, // sdiom:295M\r
+ {CLOCKS_CLK_SRC_PLL, CLOCK_DIV_9}, // sdiom:98M\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_6}, // gpu:147M\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_9}, // spi:98M\r
},\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_3}, // psram_clk:295M\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_5}, // membus:177M\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_5}, // flash: norflash & nandflash:177M\r
- {CLOCKS_CLK_SRC_PLL, CLOCK_DIV_3}, // sdiom:295M\r
+ {CLOCKS_CLK_SRC_PLL, CLOCK_DIV_9}, // sdiom:98M\r
{CLOCKS_CLK_SRC_PLL, CLOCK_DIV_6}, // gpu:147M\r
- {CLOCKS_CLK_SRC_PLL, CLOCK_DIV_10}, // spi:88M\r
+ {CLOCKS_CLK_SRC_TCXO, CLOCK_DIV_1}, // spi:32M\r
},\r
};\r
\r
{CLOCKS_CLK_SRC_TCXO, CLOCK_DIV_1}, // 32M\r
{CLOCKS_CLK_SRC_RC, CLOCK_DIV_1}, // 50M\r
{CLOCKS_CLK_SRC_TCXO_2X, CLOCK_DIV_1}, // 64M\r
- {CLOCKS_CLK_SRC_PLL, CLOCK_DIV_3}, // 294.912M\r
+ {CLOCKS_CLK_SRC_PLL, CLOCK_DIV_9}, // 98M\r
};\r
\r
/************************** MCU core all perips clock Config *********************/\r
if (div_en == 0) {\r
return CLK_DIV_1;\r
} else {\r
- uint8_t div = reg16_getbits(reg_addr, COMM_CLK_DIV_NUM_POS, COMM_CLK_SRC_LEN);\r
+ uint8_t div = reg16_getbits(reg_addr, COMM_CLK_DIV_NUM_POS, COMM_CLK_NUM_LEN);\r
if (div == 0) {\r
div = 1;\r
}\r
#ifdef BRANDY_PROT
return LOS_MemAlloc(m_aucSysMem0, size);
#else
- return osal_kmalloc(size, 0);
+ return malloc(size);
#endif
}
#ifdef BRANDY_PROT
LOS_MemFree(m_aucSysMem0, addr);
#else
- osal_kfree(addr);
+ free(addr);
#endif
}
oml_pf_log_print4(LOG_ACORE_PLT_BSP_DRIVER_IPC, LOG_NUM_DEBUG, LOG_LEVEL_ERROR,
"ipc error, core=%d current pc=0x%x, lr=0x%x, sp=0x%x", dst, pc, lr, sp);
#endif
- PRINT("%d => %d ipc error, get pc=0x%x, lr=0x%x sp=0x%X", CORE, dst, pc, lr, sp);
+ PRINT("%d => %d ipc action=%d error, get pc=0x%x, lr=0x%x sp=0x%x\r\n", CORE, dst, action, pc, lr, sp);
}
#endif
IPC_ACTION_DSP_POWER_STATE = 42, // !< Used by DSP core to inform App core POWER state
IPC_ACTION_BT_READ_NV_CUSTOMIZE = 43, // !< Used by BT core to inform app core bt needs to load customized nv.
IPC_ACTION_APP_LOAD_NV_CUSTOMIZE = 44, // !< Used by APP core to inform bt core customized nv exist or not.
+ IPC_ACTION_UART_AGENT_TX = 48, // !< Used by APP core to send data to BT core.
+ IPC_ACTION_UART_AGENT_RX = 49, // !< Used by APP core to rcv data to BT core.
IPC_ACTION_GNSS_START = 50, // !< [50:] is used by gnss.
IPC_ACTION_GNSS_LOG_INFO = IPC_ACTION_GNSS_START + 0,
IPC_ACTION_GNSS_MSG = IPC_ACTION_GNSS_START + 1,
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
-
#include "soc_mmc.h"
#include "hci.h"
#include "sdhci.h"
#define XO_DLL2_CLK_VALUE 64000000
#define PLL_CLK_VALUE 884736000
+#define PMU2_CMU_CLK_EN_CFG_REG (PMU2_CMU_CTL_RB_BASE + 0x20)
+#define PMU2_CMU_PLL_CLK_EN_BIT 0
+#define PMU2_CMU_PLL_LOCK_STS_REG (PMU2_CMU_CTL_RB_BASE + 0x2d8)
+#define PMU2_CMU_PLL_LOCK_STS_BIT 0
+
#ifndef SDHCI_ERR_INT_STAT_EN
#define SDHCI_ERR_INT_STAT_EN 0x36
#endif
uint32_t g_sdiom_cfg_clk[MAX_MMC_NUM] = {0, 0};
system_sdio_freq_t g_sdiom_mmc_sel[MAX_MMC_NUM] = {CLOCKS_SDIO_FREQ_MAX, CLOCKS_SDIO_FREQ_MAX};
system_sdio_freq_t g_sdiom_cur_sel = CLOCKS_SDIO_FREQ_MAX;
-
+uint32_t g_pll_lock_fail[MAX_MMC_NUM] = {0, 0};
+uint32_t g_mmc_lock_fail[MAX_MMC_NUM] = {0, 0};
static mmc_save_info_t g_mmc_cur_info[MAX_MMC_NUM] = { {0}, {0} };
bool g_mmc_sleep_inited = false;
return g_mmc_sleep_inited;
}
+static void mmc_sdhci_reg_save(struct hci_softc *sc)
+{
+ int i = sc->num;
+
+ reg16_setbit(g_clk_div1_reg[i], 0); // clk en
+ g_mmc_cur_info[i].timing = regw_getbits(sc->base, SDHCI_HOST_CONTROL2, 0x0, LEN_3BIT); // for speed mode
+ g_mmc_cur_info[i].at_ctrl = hci_readl(sc, SDHCI_AUTO_TUNING_CTRL);
+ g_mmc_cur_info[i].at_stat = regw_getbits(sc->base, SDHCI_AUTO_TUNING_STATUS, 0x0, LEN_8BIT); // for phase
+ if (reg8_getbit(sc->base + SDHCI_HOST_CONTROL, EXT_DAT_XFER_BIT) == 1) {
+ g_mmc_cur_info[i].bus_width = EMMC_SAVE_BUS_WIDTH_8BIT;
+ } else {
+ if (reg8_getbit(sc->base + SDHCI_HOST_CONTROL, 0x1) == 1) {
+ g_mmc_cur_info[i].bus_width = EMMC_SAVE_BUS_WIDTH_4BIT;
+ } else {
+ g_mmc_cur_info[i].bus_width = EMMC_SAVE_BUS_WIDTH_1BIT;
+ }
+ }
+
+ g_mmc_cur_info[i].mbiu_ctrl = hci_readw(sc, SDHCI_MBIU_CTRL);
+ g_mmc_cur_info[i].clk_ctrl = hci_readw(sc, SDHCI_CLOCK_CONTROL);
+ g_mmc_cur_info[i].power_ctrl = hci_readb(sc, SDHCI_POWER_CONTROL);
+ g_mmc_cur_info[i].host_ctrl1 = hci_readb(sc, SDHCI_HOST_CONTROL);
+ g_mmc_cur_info[i].host_ctrl2 = hci_readw(sc, SDHCI_HOST_CONTROL2);
+ g_mmc_cur_info[i].int_en = hci_readl(sc, SDHCI_INT_ENABLE);
+ g_mmc_cur_info[i].int_sig_en = hci_readl(sc, SDHCI_SIGNAL_ENABLE);
+ reg16_clrbit(g_clk_div1_reg[i], 0); // clk disable
+}
+
+static void mmc_sdhci_suspend_debug(struct hci_softc *sc)
+{
+#if MMC_BOARD_DEBUG_ON
+ int i = sc->num;
+ PRINT("mmc%d save sdiom=0x%x, clk_div1=0x%x, clk_div2=0x%x, timing=%d, phase=%d, bus_width=%d\r\n",
+ i, g_mmc_cur_info[i].sdiom_clk_reg, g_mmc_cur_info[i].clk_div1_reg, g_mmc_cur_info[i].clk_div2_reg,
+ g_mmc_cur_info[i].timing, g_mmc_cur_info[i].at_stat, g_mmc_cur_info[i].bus_width);
+ PRINT("mmc%d save clk_ctrl=0x%x, power_ctrl=0x%x, host_ctrl1=0x%x, host_ctrl2=0x%x\r\n",
+ i, g_mmc_cur_info[i].clk_ctrl, g_mmc_cur_info[i].power_ctrl, g_mmc_cur_info[i].host_ctrl1,
+ g_mmc_cur_info[i].host_ctrl2);
+ PRINT("mmc%d save int_en=0x%x, sig_en=0x%x\r\n", i, g_mmc_cur_info[i].int_en, g_mmc_cur_info[i].int_sig_en);
+#endif
+}
/*
* 函 数 名 : mmc_sdhci_suspend
* 功能描述 : 低功耗suspend接口, 保存所有mmc slot工作必须的寄存器
int32_t i;
struct hci_softc *sc = NULL;
+ // soc reg save
for (i = 0; i < MAX_MMC_NUM; i++) {
sc = get_mmc_resource(i);
if (sc == NULL || sc->slot == NULL || ((struct sdhci_slot*)sc->slot)->dev == NULL) {
continue;
}
-
- reg16_setbit(g_clk_div1_reg[i], 0); // clk en
- g_mmc_cur_info[i].timing = regw_getbits(sc->base, SDHCI_HOST_CONTROL2, 0x0, LEN_3BIT); // for speed mode
- g_mmc_cur_info[i].at_ctrl = hci_readl(sc, SDHCI_AUTO_TUNING_CTRL);
- g_mmc_cur_info[i].at_stat = regw_getbits(sc->base, SDHCI_AUTO_TUNING_STATUS, 0x0, LEN_8BIT); // for phase
- if (reg8_getbit(sc->base + SDHCI_HOST_CONTROL, EXT_DAT_XFER_BIT) == 1) {
- g_mmc_cur_info[i].bus_width = EMMC_SAVE_BUS_WIDTH_8BIT;
- } else {
- if (reg8_getbit(sc->base + SDHCI_HOST_CONTROL, 0x1) == 1) {
- g_mmc_cur_info[i].bus_width = EMMC_SAVE_BUS_WIDTH_4BIT;
- } else {
- g_mmc_cur_info[i].bus_width = EMMC_SAVE_BUS_WIDTH_1BIT;
- }
- }
g_mmc_cur_info[i].sdiom_clk_reg = readw(SDIOM_CR_REG);
g_mmc_cur_info[i].clk_div1_reg = readw(g_clk_div1_reg[i]);
g_mmc_cur_info[i].clk_div2_reg = readw(g_clk_div2_reg[i]);
g_mmc_cur_info[i].sd_bus_reg = readw(SDIO_BUS_CGDIV_REG);
- g_mmc_cur_info[i].mbiu_ctrl = hci_readw(sc, SDHCI_MBIU_CTRL);
- g_mmc_cur_info[i].clk_ctrl = hci_readw(sc, SDHCI_CLOCK_CONTROL);
- g_mmc_cur_info[i].power_ctrl = hci_readb(sc, SDHCI_POWER_CONTROL);
- g_mmc_cur_info[i].host_ctrl1 = hci_readb(sc, SDHCI_HOST_CONTROL);
- g_mmc_cur_info[i].host_ctrl2 = hci_readw(sc, SDHCI_HOST_CONTROL2);
- g_mmc_cur_info[i].int_en = hci_readl(sc, SDHCI_INT_ENABLE);
- g_mmc_cur_info[i].int_sig_en = hci_readl(sc, SDHCI_SIGNAL_ENABLE);
-#if MMC_BOARD_DEBUG_ON
- PRINT("mmc%d save sdiom=0x%x, clk_div1=0x%x, clk_div2=0x%x, timing=%d, phase=%d, bus_width=%d\r\n",
- i, g_mmc_cur_info[i].sdiom_clk_reg, g_mmc_cur_info[i].clk_div1_reg, g_mmc_cur_info[i].clk_div2_reg,
- g_mmc_cur_info[i].timing, g_mmc_cur_info[i].at_stat, g_mmc_cur_info[i].bus_width);
- PRINT("mmc%d save clk_ctrl=0x%x, power_ctrl=0x%x, host_ctrl1=0x%x, host_ctrl2=0x%x\r\n",
- i, g_mmc_cur_info[i].clk_ctrl, g_mmc_cur_info[i].power_ctrl, g_mmc_cur_info[i].host_ctrl1,
- g_mmc_cur_info[i].host_ctrl2);
- PRINT("mmc%d save int_en=0x%x, sig_en=0x%x\r\n", i, g_mmc_cur_info[i].int_en, g_mmc_cur_info[i].int_sig_en);
-#endif
- reg16_clrbit(g_clk_div1_reg[i], 0); // clk disable
+ }
+
+ // sdhci reg save
+ for (i = 0; i < MAX_MMC_NUM; i++) {
+ sc = get_mmc_resource(i);
+ if (sc == NULL || sc->slot == NULL || ((struct sdhci_slot*)sc->slot)->dev == NULL) {
+ continue;
+ }
+
+ // 检查pll时钟是否失锁
+ if (g_sdiom_cur_sel == CLOCKS_SDIO_FREQ_H) {
+ if (((readw(PMU2_CMU_CLK_EN_CFG_REG) & 0x1) == 0) || ((readw(PMU2_CMU_PLL_LOCK_STS_REG) & 0x1) == 0)) {
+ g_pll_lock_fail[i]++;
+ }
+ // 切换sdiom时钟到32M XO时钟
+ reg16_clrbit(g_clk_div1_reg[i], 0); // clk dis en
+ writew(SDIOM_CR_REG, SDIOM_CR_CTRL_XO_32M_CLK_EN);
+ reg16_setbit(g_clk_div1_reg[i], 0); // clk en
+ }
+
+ mmc_sdhci_reg_save(sc);
+
+ mmc_sdhci_suspend_debug(sc);
}
mmc_set_sleep_init_flag(false);
}
{
int32_t i;
struct hci_softc *sc;
+ uint32_t timeout;
for (i = 0; i < MAX_MMC_NUM; i++) {
sc = get_mmc_resource(i);
#endif
writew(SDIOM_CR_REG, g_mmc_cur_info[i].sdiom_clk_reg);
writew(g_clk_div1_reg[i], g_mmc_cur_info[i].clk_div1_reg);
+ reg16_setbit(g_clk_div1_reg[i], 0); // clk en
writew(g_clk_div2_reg[i], g_mmc_cur_info[i].clk_div2_reg);
writew(SDIO_BUS_CGDIV_REG, g_mmc_cur_info[i].sd_bus_reg);
reg16_setbit(sc->base + SDHCI_CLOCK_CONTROL, 0x0); // offset:2c bit0 internal clk en
reg16_setbit(sc->base + SDHCI_CLOCK_CONTROL, 0x3); // offset:2c bit3 pll enable
reg16_setbit(sc->base + SDHCI_CLOCK_CONTROL, 0x2); // offset:2c bit2 sd clk enable
- while (reg16_getbit(sc->base + SDHCI_CLOCK_CONTROL, 0x1) != 1) { ; } // wait clock is stability
+ /* Wait up to 1000 ms until it stabilize. */
+ timeout = 1000;
+ while (reg16_getbit(sc->base + SDHCI_CLOCK_CONTROL, 0x1) != 1) {
+ if (timeout == 0) {
+ PRINT("mmc%d resume wait clk stable timeout\r\n", i);
+ g_mmc_lock_fail[i]++;
+ break;
+ }
+ timeout--;
+ osal_udelay(1000); // delay 1000us
+ }
hci_writeb(sc, SDHCI_TIMEOUT_CONTROL, 0xe);
hci_writew(sc, SDHCI_CLOCK_CONTROL, g_mmc_cur_info[i].clk_ctrl);
mmc_set_sleep_init_flag(true);
}
+void mmc_sdhci_clock_info(void)
+{
+ int32_t i;
+ struct hci_softc *sc;
+
+ for (i = 0; i < MAX_MMC_NUM; i++) {
+ sc = get_mmc_resource(i);
+ if (sc == NULL || sc->slot == NULL || ((struct sdhci_slot*)sc->slot)->dev == NULL) {
+ continue;
+ }
+ PRINT("mmc%d:clk_src=%d,sdiom_div=%d,bus_div=%d,div1=%d,div2=%d,pll_lockfail=%d,sdhci_lockfail=%d\r\n", i,
+ regw_getbits(SDIOM_CR_REG, 0, 0x1, 0x3), regw_getbits(SDIOM_CR_REG, 0, 0x5, 0x4),
+ regw_getbits(SDIO_BUS_CGDIV_REG, 0, 0x3, 0x5), regw_getbits(g_clk_div1_reg[i], 0, 0x4, 0x8),
+ regw_getbits(g_clk_div2_reg[i], 0, 0x1, 0x3), g_pll_lock_fail[i], g_mmc_lock_fail[i]);
+ }
+}
#ifdef CFG_DRIVERS_SDIO
/*
* 函 数 名 : mmc_sdhci_sdio_reset
div2 = regw_getbits(g_clk_div1_reg[id], 0, 0x4, 0x8);
}
if (reg16_getbit(g_clk_div2_reg[id], 0x0) == 1) {
- div3 = regw_getbits(g_clk_div2_reg[id], 0, 0x4, 0x3);
+ div3 = regw_getbits(g_clk_div2_reg[id], 0, 0x1, 0x3);
}
#if MMC_BOARD_DEBUG_ON
- PRINT("clk_flag=%d, value=%lu, div1=%d div2=%d, div3=%d\r\n", clk_flag, source_clk_val, div1, div2, div3);
+ PRINT("clk_flag=%d,value=%lu,div1=%d,div2=%d,div3=%d\r\n", clk_flag, source_clk_val, div1, div2, div3);
#endif
return (source_clk_val / div1 / div2 / div3);
}
return 0;
}
-static void mmc_set_sd_bus_clk_div(uint32_t div_reg, uint32_t freq_div)
+void mmc_set_sd_bus_clk_div(uint32_t freq_div)
{
uint16_t value;
- value = DPAL_GET_UINT16(div_reg);
+ value = DPAL_GET_UINT16(SDIO_BUS_CGDIV_REG);
value &= ~SD_BUS_LOAD_DIV_EN;
- DPAL_WRITE_UINT16(value, div_reg);
+ DPAL_WRITE_UINT16(value, SDIO_BUS_CGDIV_REG);
value &= ~SD_BUS_DIV_NUM_MASK;
value |= (uint16_t)(freq_div << SD_BUS_DIV_NUM_POST_SHIFT);
- DPAL_WRITE_UINT16(value, div_reg);
+ DPAL_WRITE_UINT16(value, SDIO_BUS_CGDIV_REG);
value |= SD_BUS_LOAD_DIV_EN;
- DPAL_WRITE_UINT16(value, div_reg);
+ DPAL_WRITE_UINT16(value, SDIO_BUS_CGDIV_REG);
}
static void mmc_calc_sdiom_clk_div(system_sdio_freq_t freq_level, uint32_t cfg_clock,
uint32_t *freq_div, uint32_t *second_freq_div)
{
uint32_t sdiom_freq_val[CLOCKS_SDIO_FREQ_MAX] = {
- SDIOM_SRC_CLK_LOW_FREQ_VAL, SDIOM_SRC_CLK_FREQ_LVL_50M_VAL,
+ SDIOM_SRC_CLK_LOW_FREQ_VAL, SDIOM_SRC_CLK_FREQ_LVL_49M_VAL,
SDIOM_SRC_CLK_FREQ_LVL_64M_VAL, SDIOM_SRC_CLK_HIGH_FREQ_LVL_VAL
};
- if (freq_level == CLOCKS_SDIO_FREQ_H && cfg_clock <= SDIOM_SRC_CLK_FREQ_LVL_98M_VAL) {
- *second_freq_div = 3; // 3:选PLL时钟频率经过3分频到98Mhz,二级分频才能满足低频要求,如400Khz的探卡频率
- } else {
- *second_freq_div = 1;
- }
-
+ *second_freq_div = 1;
if (cfg_clock <= sdiom_freq_val[freq_level]) {
*freq_div = sdiom_freq_val[freq_level] / (cfg_clock * (*second_freq_div));
- if (freq_level == CLOCKS_SDIO_FREQ_32M || freq_level == CLOCKS_SDIO_FREQ_H) {
- if (sdiom_freq_val[freq_level] % (cfg_clock * (*second_freq_div)) != 0) { *freq_div += 1; }
+ if (sdiom_freq_val[freq_level] % (cfg_clock * (*second_freq_div)) != 0) {
+ *freq_div += 1;
}
} else {
*freq_div = 1;
#endif
}
g_sdiom_cur_sel = sdiom_freq_level;
- mmc_set_sd_bus_clk_div(SDIO_BUS_CGDIV_REG, 1);
return 0;
}
#define SDIOM_SRC_CLK_FREQ_LVL_64M_VAL 64000000 // 64MHz
#define SDIOM_SRC_CLK_FREQ_LVL_49M_VAL 49000000
#define SDIOM_SRC_CLK_FREQ_LVL_98M_VAL 98000000 // 98MHz
-#define SDIOM_SRC_CLK_HIGH_FREQ_LVL_VAL 294000000 // 294MHz
+#define SDIOM_SRC_CLK_HIGH_FREQ_LVL_VAL SDIOM_SRC_CLK_FREQ_LVL_98M_VAL
#define SDHCI_CMD_CONFLIT_CHECK 0x01
bool mmc_get_first_init_flag(void);
void mmc_set_sleep_init_flag(bool flag);
bool mmc_get_sleep_init_flag(void);
-
+void mmc_sdhci_clock_info(void);
#ifdef __cplusplus
#if __cplusplus
}
} nandflash_trans_type_t;\r
\r
typedef enum nandflash_trans_speed {\r
- SPEED_HIGH = 8,\r
+ SPEED_HIGH = 12,\r
SPEED_MID = 12,\r
SPEED_SLOW = 16,\r
} nandflash_speed_type_t;\r
if (spi_get_attr_tmod(bus) == HAL_SPI_TRANS_MODE_RX) {
return spi_read_by_writeread(bus, data, timeout);
}
-
- errcode_t ret = spi_read_dma(bus, data, timeout);
- if (g_hal_funcs->ctrl(bus, SPI_CTRL_CHECK_FIFO_BUSY, (uintptr_t)SPI_TX_FIFO_BUSY_TIMEOUT) != ERRCODE_SUCC) {
- return ERRCODE_SPI_TIMEOUT;
- }
- return ret;
+ return spi_read_dma(bus, data, timeout);
}
#endif /* NOT CONFIG_SPI_SUPPORT_POLL_AND_DMA_AUTO_SWITCH */
#endif /* CONFIG_SPI_SUPPORT_DMA */
uint32_t irq_sts = spi_porting_lock(bus);
ret = g_hal_funcs->read(bus, (hal_spi_xfer_data_t *)data, timeout_tmp);
- if (g_hal_funcs->ctrl(bus, SPI_CTRL_CHECK_FIFO_BUSY, timeout_tmp) != ERRCODE_SUCC) {
- spi_porting_unlock(bus, irq_sts);
- spi_mutex_unlock(bus);
- return ERRCODE_SPI_TIMEOUT;
- }
spi_porting_unlock(bus, irq_sts);
spi_mutex_unlock(bus);
data->tx_bytes > CONFIG_SPI_AUTO_SWITCH_DMA_THRESHOLD) {
uapi_spi_set_dma_mode(bus, true, NULL);
ret = spi_writeread_dma(bus, data, timeout_tmp);
- if (g_hal_funcs->ctrl(bus, SPI_CTRL_CHECK_FIFO_BUSY, (uintptr_t)SPI_TX_FIFO_BUSY_TIMEOUT) != ERRCODE_SUCC) {
- spi_mutex_unlock(bus);
- return ERRCODE_SPI_TIMEOUT;
- }
spi_mutex_unlock(bus);
return ret;
}
#if defined(CONFIG_SPI_SUPPORT_DMA) && (CONFIG_SPI_SUPPORT_DMA == 1)
if (g_dma_trans_tx[bus].is_enable && g_dma_trans_rx[bus].is_enable) {
ret = spi_writeread_dma(bus, data, timeout_tmp);
- if (g_hal_funcs->ctrl(bus, SPI_CTRL_CHECK_FIFO_BUSY, (uintptr_t)SPI_TX_FIFO_BUSY_TIMEOUT) != ERRCODE_SUCC) {
- spi_mutex_unlock(bus);
- return ERRCODE_SPI_TIMEOUT;
- }
spi_mutex_unlock(bus);
return ret;
}
uint32_t irq_sts = spi_porting_lock(bus);
ret = g_hal_funcs->writeread(bus, (hal_spi_xfer_data_t *)data, timeout_tmp);
- if (g_hal_funcs->ctrl(bus, SPI_CTRL_CHECK_FIFO_BUSY, timeout_tmp) != ERRCODE_SUCC) {
- spi_porting_unlock(bus, irq_sts);
- spi_mutex_unlock(bus);
- return ERRCODE_SPI_TIMEOUT;
- }
+
spi_porting_unlock(bus, irq_sts);
spi_mutex_unlock(bus);
if (data->tx_bytes > CONFIG_SPI_AUTO_SWITCH_DMA_THRESHOLD) {
uapi_spi_set_dma_mode(bus, true, NULL);
ret = spi_write_dma(bus, data, timeout_tmp);
- if (g_hal_funcs->ctrl(bus, SPI_CTRL_CHECK_FIFO_BUSY, (uintptr_t)SPI_TX_FIFO_BUSY_TIMEOUT) != ERRCODE_SUCC) {
- spi_mutex_unlock(bus);
- return ERRCODE_SPI_TIMEOUT;
- }
spi_mutex_unlock(bus);
return ret;
}
#if defined(CONFIG_SPI_SUPPORT_DMA) && (CONFIG_SPI_SUPPORT_DMA == 1)
if (g_dma_trans_tx[bus].is_enable) {
ret = spi_write_dma(bus, data, timeout_tmp);
- if (g_hal_funcs->ctrl(bus, SPI_CTRL_CHECK_FIFO_BUSY, (uintptr_t)SPI_TX_FIFO_BUSY_TIMEOUT) != ERRCODE_SUCC) {
- spi_mutex_unlock(bus);
- return ERRCODE_SPI_TIMEOUT;
- }
spi_mutex_unlock(bus);
return ret;
}
uint32_t irq_sts = spi_porting_lock(bus);
ret = g_hal_funcs->write(bus, (hal_spi_xfer_data_t *)data, timeout_tmp);
- if (g_hal_funcs->ctrl(bus, SPI_CTRL_CHECK_FIFO_BUSY, timeout_tmp) != ERRCODE_SUCC) {
- spi_porting_unlock(bus, irq_sts);
- spi_mutex_unlock(bus);
- return ERRCODE_SPI_TIMEOUT;
- }
+
spi_porting_unlock(bus, irq_sts);
spi_mutex_unlock(bus);
if (data->rx_bytes > CONFIG_SPI_AUTO_SWITCH_DMA_THRESHOLD) {
uapi_spi_set_dma_mode(bus, true, NULL);
ret = spi_read_dma(bus, data, timeout_tmp);
- if (g_hal_funcs->ctrl(bus, SPI_CTRL_CHECK_FIFO_BUSY, (uintptr_t)SPI_TX_FIFO_BUSY_TIMEOUT) != ERRCODE_SUCC) {
- spi_mutex_unlock(bus);
- return ERRCODE_SPI_TIMEOUT;
- }
spi_mutex_unlock(bus);
return ret;
}
#if defined(CONFIG_SPI_SUPPORT_DMA) && (CONFIG_SPI_SUPPORT_DMA == 1)
if (g_dma_trans_rx[bus].is_enable) {
ret = spi_read_dma(bus, data, timeout_tmp);
- if (g_hal_funcs->ctrl(bus, SPI_CTRL_CHECK_FIFO_BUSY, (uintptr_t)SPI_TX_FIFO_BUSY_TIMEOUT) != ERRCODE_SUCC) {
- spi_mutex_unlock(bus);
- return ERRCODE_SPI_TIMEOUT;
- }
spi_mutex_unlock(bus);
return ret;
}
uint32_t irq_sts = spi_porting_lock(bus);
ret = g_hal_funcs->read(bus, (hal_spi_xfer_data_t *)data, timeout_tmp);
- if (g_hal_funcs->ctrl(bus, SPI_CTRL_CHECK_FIFO_BUSY, timeout_tmp) != ERRCODE_SUCC) {
- spi_porting_unlock(bus, irq_sts);
- spi_mutex_unlock(bus);
- return ERRCODE_SPI_TIMEOUT;
- }
+
spi_porting_unlock(bus, irq_sts);
spi_mutex_unlock(bus);
uint32_t bus_clk; /*!< @if Eng Provide ssi_clk for clock freq division calculation.
@else 用于计算SPI的时钟分频系数。 @endif */
- uint32_t freq_mhz; /*!< @if Eng Indicates the frequency of SPI.
- @else SPI的工作频率。 @endif */
-
+ uint32_t freq_mhz; /*!< @if Eng Indicates the frequency of SPI in MHz.
+ Only one of freq_mhz or freq_hz can be non-zero and effective.
+ @else SPI的工作频率(MHz)。
+ freq_mhz和freq_hz只能有一个非零且有效。 @endif */
+#ifdef CONFIG_SPI_SUPPORT_HZ
+ uint32_t freq_hz; /*!< @if Eng Indicates the frequency of SPI in Hz.
+ Only one of freq_mhz or freq_hz can be non-zero and effective.
+ @else SPI的工作频率(Hz)。
+ freq_mhz和freq_hz只能有一个非零且有效。 @endif */
+#endif
uint32_t clk_polarity; /*!< @if Eng Indicates the clock polarity of SPI.
For details, see @ref hal_spi_cfg_clk_cpol_t
@else SPI的时钟极性。参考 @ref hal_spi_cfg_clk_cpol_t @endif */
#define SPI_MINUMUM_CLOCK_IN_MHZ 1
#define SPI_MAXIMUM_CLOCK_IN_MHZ 48
+#define SPI_MINUMUM_CLOCK_IN_HZ 10000
+#define SPI_MAXIMUM_CLOCK_IN_HZ 48000000
#define QSPI_MINUMUM_CLOCK_IN_MHZ 1
#define QSPI_MAXIMUM_CLOCK_IN_MHZ 96
return ((*trans_time > timeout) ? true : false);
}
-static bool hal_spi_is_attr_freq_valid(const uint32_t clk_in_mhz, const hal_spi_frame_format_t spi_frame_format)
+static bool hal_spi_is_attr_freq_valid(const hal_spi_attr_t *attr, const hal_spi_frame_format_t spi_frame_format)
{
- if (spi_frame_format == HAL_SPI_FRAME_FORMAT_STANDARD) {
- if ((clk_in_mhz < SPI_MINUMUM_CLOCK_IN_MHZ) || (clk_in_mhz > SPI_MAXIMUM_CLOCK_IN_MHZ)) {
+#ifdef CONFIG_SPI_SUPPORT_HZ
+ if ((attr->freq_hz == 0 && attr->freq_mhz == 0) ||
+ (attr->freq_hz != 0 && attr->freq_mhz != 0)) {
+ return false;
+ }
+ if (attr->freq_hz != 0) {
+ if (spi_frame_format == HAL_SPI_FRAME_FORMAT_STANDARD) {
+ if ((attr->freq_hz < SPI_MINUMUM_CLOCK_IN_HZ) || (attr->freq_hz > SPI_MAXIMUM_CLOCK_IN_HZ)) {
+ return false;
+ }
+ } else {
return false;
}
- } else {
- if ((clk_in_mhz < QSPI_MINUMUM_CLOCK_IN_MHZ) || (clk_in_mhz > QSPI_MAXIMUM_CLOCK_IN_MHZ)) {
- return false;
+ return true;
+ }
+#endif
+ if (attr->freq_mhz != 0) {
+ if (spi_frame_format == HAL_SPI_FRAME_FORMAT_STANDARD) {
+ if ((attr->freq_mhz < SPI_MINUMUM_CLOCK_IN_MHZ) || (attr->freq_mhz > SPI_MAXIMUM_CLOCK_IN_MHZ)) {
+ return false;
+ }
+ } else {
+ if ((attr->freq_mhz < QSPI_MINUMUM_CLOCK_IN_MHZ) || (attr->freq_mhz > QSPI_MAXIMUM_CLOCK_IN_MHZ)) {
+ return false;
+ }
}
+ return true;
}
- return true;
+ return false;
}
static bool hal_spi_is_attr_valid(spi_bus_t bus, const hal_spi_attr_t *attr, const hal_spi_extra_attr_t *extra_attr)
if (attr->slave_num > spi_porting_max_slave_select_get(bus) + 1) {
return false;
}
- if (hal_spi_is_attr_freq_valid(attr->freq_mhz, spi_frame_format) != true) {
+ if (hal_spi_is_attr_freq_valid(attr, spi_frame_format) != true) {
return false;
}
}
}
}
-static void hal_spi_init_config_freq(spi_bus_t bus, uint32_t bus_clk, uint32_t clk_in_mhz)
+static void hal_spi_init_config_freq(spi_bus_t bus, const hal_spi_attr_t *attr)
{
- uint32_t clk_div;
- clk_div = (uint32_t)(bus_clk / spi_mhz_to_hz(clk_in_mhz));
- if (clk_div < SPI_MINUMUM_CLK_DIV) {
- clk_div = SPI_MINUMUM_CLK_DIV;
+ uint32_t clk_div = SPI_MINUMUM_CLK_DIV;
+#ifdef CONFIG_SPI_SUPPORT_HZ
+ if (attr->freq_hz != 0) {
+ clk_div = (uint32_t)(attr->bus_clk / attr->freq_hz);
+ if (clk_div < SPI_MINUMUM_CLK_DIV) {
+ clk_div = SPI_MINUMUM_CLK_DIV;
+ }
+ }
+#endif
+ if (attr->freq_mhz != 0) {
+ clk_div = (uint32_t)(attr->bus_clk / spi_mhz_to_hz(attr->freq_mhz));
+ if (clk_div < SPI_MINUMUM_CLK_DIV) {
+ clk_div = SPI_MINUMUM_CLK_DIV;
+ }
}
hal_spi_v100_baudr_set_sckdv(bus, clk_div);
/* Config slave info and freq in master mode. */
if (attr->is_slave == 0) {
hal_spi_v100_ser_set_ser(bus, (attr->slave_num == 0) ? 0 : bit(attr->slave_num - 1));
- hal_spi_init_config_freq(bus, attr->bus_clk, attr->freq_mhz);
+ hal_spi_init_config_freq(bus, attr);
if ((hal_spi_frame_format_t)attr->spi_frame_format == HAL_SPI_FRAME_FORMAT_QUAD) {
hal_spi_config_qspi(bus, &extra_attr->qspi_param);
}
/* Config slave info and freq in master mode. */
if (attr->is_slave == 0) {
hal_spi_v100_ser_set_ser(bus, (attr->slave_num == 0) ? 0 : bit(attr->slave_num - 1));
- hal_spi_init_config_freq(bus, attr->bus_clk, attr->freq_mhz);
+ hal_spi_init_config_freq(bus, attr);
}
/* Config slave select toggle enable. */