mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-14 18:38:55 +00:00
182 lines
4.2 KiB
C
182 lines
4.2 KiB
C
/*
|
|
* Copyright (c) 2023, ArtInChip Technology Co., Ltd
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Authors: Hao Xiong <hao.xiong@artinchip.com>
|
|
*/
|
|
|
|
#include <aic_core.h>
|
|
#include <aic_hal.h>
|
|
#include <hal_spienc.h>
|
|
|
|
#define SPIE_REG_CTL 0x00
|
|
#define SPIE_REG_ICR 0x04
|
|
#define SPIE_REG_ISR 0x08
|
|
#define SPIE_REG_KCNT 0x0C
|
|
#define SPIE_REG_OCNT 0x10
|
|
#define SPIE_REG_ADDR 0x14
|
|
#define SPIE_REG_TWEAK 0x18
|
|
#define SPIE_REG_CPOS 0x1C
|
|
#define SPIE_REG_CLEN 0x20
|
|
|
|
#define SPIE_START_OFF 0
|
|
#define SPIE_SPI_SEL_OFF 12
|
|
|
|
#define SPIE_START_MSK (0x1 << SPIE_START_OFF)
|
|
#define SPIE_SPI_SEL_MSK (0x3 << SPIE_SPI_SEL_OFF)
|
|
|
|
#define SPIE_INTR_KEY_GEN_MSK (1 << 0)
|
|
#define SPIE_INTR_ENC_DEC_FIN_MSK (1 << 1)
|
|
#define SPIE_INTR_ALL_EMP_MSK (1 << 2)
|
|
#define SPIE_INTR_HALF_EMP_MSK (1 << 3)
|
|
#define SPIE_INTR_KEY_UDF_MSK (1 << 4)
|
|
#define SPIE_INTR_KEY_OVF_MSK (1 << 5)
|
|
#define SPIE_INTR_ALL_MSK (0x3F)
|
|
|
|
#define SPI_CTLR_0 0
|
|
#define SPI_CTLR_1 1
|
|
#define SPI_CTLR_SE 5
|
|
#define SPI_CTLR_INVAL 0xFF
|
|
|
|
static int bypass = 0;
|
|
static int tweak_sel = AIC_SPIENC_USER_TWEAK;
|
|
|
|
static int hal_spienc_attach_bus(u8 bus)
|
|
{
|
|
u32 val;
|
|
|
|
val = readl(SPI_ENC_BASE + SPIE_REG_CTL);
|
|
val &= ~SPIE_SPI_SEL_MSK;
|
|
|
|
switch (bus) {
|
|
#if defined(AIC_SPIENC_QSPI0)
|
|
case SPI_CTLR_0:
|
|
val |= (1 << SPIE_SPI_SEL_OFF);
|
|
writel(val, (SPI_ENC_BASE + SPIE_REG_CTL));
|
|
break;
|
|
#endif
|
|
#if defined(AIC_SPIENC_QSPI1)
|
|
case SPI_CTLR_1:
|
|
val |= (2 << SPIE_SPI_SEL_OFF);
|
|
writel(val, (SPI_ENC_BASE + SPIE_REG_CTL));
|
|
break;
|
|
#endif
|
|
#if defined(AIC_USING_SE_SPI)
|
|
case SPI_CTLR_SE:
|
|
val |= (1 << SPIE_SPI_SEL_OFF);
|
|
writel(val, (SPI_ENC_BASE + SPIE_REG_CTL));
|
|
break;
|
|
#endif
|
|
case SPI_CTLR_INVAL:
|
|
val |= (0 << SPIE_SPI_SEL_OFF);
|
|
writel(val, (SPI_ENC_BASE + SPIE_REG_CTL));
|
|
break;
|
|
default:
|
|
val |= (0 << SPIE_SPI_SEL_OFF);
|
|
writel(val, (SPI_ENC_BASE + SPIE_REG_CTL));
|
|
hal_log_warn("SPI controller %d not enable spienc\n", bus);
|
|
return -EINVAL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int hal_spienc_init(void)
|
|
{
|
|
int ret = 0;
|
|
|
|
ret = hal_clk_enable(CLK_SPIENC);
|
|
if (ret < 0) {
|
|
hal_log_err("Failed to enable SID clk.\n");
|
|
return -EFAULT;
|
|
}
|
|
|
|
ret = hal_clk_enable_deassertrst(CLK_SPIENC);
|
|
if (ret < 0) {
|
|
hal_log_err("Failed to reset SID deassert.\n");
|
|
return -EFAULT;
|
|
}
|
|
/* Enable Interrupt */
|
|
writel(SPIE_INTR_ALL_MSK, (SPI_ENC_BASE + SPIE_REG_ICR));
|
|
|
|
return 0;
|
|
}
|
|
|
|
void hal_spienc_set_cfg(u32 spi_bus, u32 addr, u32 cpos, u32 clen)
|
|
{
|
|
u32 tweak = 0;
|
|
|
|
if (spi_bus == 0) {
|
|
#if defined(AIC_SPIENC_QSPI0)
|
|
tweak = AIC_SPIENC_QSPI0_TWEAK;
|
|
#endif
|
|
} else if (spi_bus == 1) {
|
|
#if defined(AIC_SPIENC_QSPI1)
|
|
tweak = AIC_SPIENC_QSPI1_TWEAK;
|
|
#endif
|
|
} else if (spi_bus == 5) {
|
|
#if defined(AIC_SPIENC_SE_SPI)
|
|
tweak = AIC_SPIENC_SE_SPI_TWEAK;
|
|
#endif
|
|
} else {
|
|
tweak = 0;
|
|
hal_log_warn("not define spi %d tweak, default(%d).\n", spi_bus, tweak);
|
|
}
|
|
|
|
if (bypass)
|
|
hal_spienc_attach_bus(0xff);
|
|
else
|
|
hal_spienc_attach_bus(spi_bus);
|
|
|
|
if (tweak_sel == AIC_SPIENC_HW_TWEAK)
|
|
tweak = 0;
|
|
|
|
writel(addr, (SPI_ENC_BASE + SPIE_REG_ADDR));
|
|
writel(cpos, (SPI_ENC_BASE + SPIE_REG_CPOS));
|
|
writel(clen, (SPI_ENC_BASE + SPIE_REG_CLEN));
|
|
writel(tweak, (SPI_ENC_BASE + SPIE_REG_TWEAK));
|
|
}
|
|
|
|
void hal_spienc_set_bypass(int status)
|
|
{
|
|
bypass = status;
|
|
}
|
|
|
|
void hal_spienc_select_tweak(int select)
|
|
{
|
|
tweak_sel = select;
|
|
}
|
|
|
|
void hal_spienc_start(void)
|
|
{
|
|
u32 val;
|
|
|
|
writel(SPIE_INTR_ALL_MSK, (SPI_ENC_BASE + SPIE_REG_ISR));
|
|
val = readl((SPI_ENC_BASE + SPIE_REG_CTL));
|
|
val |= SPIE_START_MSK;
|
|
writel(val, (SPI_ENC_BASE + SPIE_REG_CTL));
|
|
}
|
|
|
|
void hal_spienc_stop(void)
|
|
{
|
|
u32 val;
|
|
|
|
val = readl((SPI_ENC_BASE + SPIE_REG_CTL));
|
|
val &= ~SPIE_START_MSK;
|
|
writel(val, (SPI_ENC_BASE + SPIE_REG_CTL));
|
|
}
|
|
|
|
int hal_spienc_check_empty(void)
|
|
{
|
|
u32 val;
|
|
|
|
val = readl((SPI_ENC_BASE + SPIE_REG_ISR));
|
|
writel(val, (SPI_ENC_BASE + SPIE_REG_ISR));
|
|
if (val & SPIE_INTR_ALL_EMP_MSK)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|