889 lines
27 KiB
C
889 lines
27 KiB
C
/**
|
|
* @file sdrv_xtrg.c
|
|
* @brief Semidrive XTRG driver source file.
|
|
*
|
|
* @copyright Copyright (c) 2021 Semidrive Semiconductor.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#include <debug.h>
|
|
#include <param.h>
|
|
#include <string.h>
|
|
#include <types.h>
|
|
|
|
#include "sdrv_xtrg.h"
|
|
|
|
#include "irq.h"
|
|
|
|
/* Xtrg interrupt bit mask. */
|
|
#define SDRV_XTRG_TMUX7_DONE (1 << 23U)
|
|
#define SDRV_XTRG_TMUX6_DONE (1 << 22U)
|
|
#define SDRV_XTRG_TMUX5_DONE (1 << 21U)
|
|
#define SDRV_XTRG_TMUX4_DONE (1 << 20U)
|
|
#define SDRV_XTRG_TMUX3_DONE (1 << 19U)
|
|
#define SDRV_XTRG_TMUX2_DONE (1 << 18U)
|
|
#define SDRV_XTRG_TMUX1_DONE (1 << 17U)
|
|
#define SDRV_XTRG_TMUX0_DONE (1 << 16U)
|
|
#define SDRV_XTRG_FAULT_EVENT 1
|
|
|
|
/**
|
|
* @brief xTRG interrupt event structure.
|
|
*/
|
|
struct xtrg_intr_event {
|
|
uint32_t intr_mask;
|
|
sdrv_xtrg_irq_status_e event;
|
|
};
|
|
|
|
static const struct xtrg_intr_event xtrg_intr_events[] = {
|
|
{SDRV_XTRG_FAULT_EVENT, SDRV_FAULT_EVENT},
|
|
{SDRV_XTRG_TMUX0_DONE, SDRV_TMUX0_DONE_EVENT},
|
|
{SDRV_XTRG_TMUX1_DONE, SDRV_TMUX1_DONE_EVENT},
|
|
{SDRV_XTRG_TMUX2_DONE, SDRV_TMUX2_DONE_EVENT},
|
|
{SDRV_XTRG_TMUX3_DONE, SDRV_TMUX3_DONE_EVENT},
|
|
{SDRV_XTRG_TMUX4_DONE, SDRV_TMUX4_DONE_EVENT},
|
|
{SDRV_XTRG_TMUX5_DONE, SDRV_TMUX5_DONE_EVENT},
|
|
{SDRV_XTRG_TMUX6_DONE, SDRV_TMUX6_DONE_EVENT},
|
|
{SDRV_XTRG_TMUX7_DONE, SDRV_TMUX7_DONE_EVENT},
|
|
};
|
|
|
|
/* {S,C,T,P} values */
|
|
static const uint32_t sctp[] = {
|
|
[SDRV_XTRG_SWT_EVENT_SET] = 0x8,
|
|
[SDRV_XTRG_SWT_EVENT_CLEAR] = 0x4,
|
|
[SDRV_XTRG_SWT_EVENT_TRIGGER] = 0x2,
|
|
[SDRV_XTRG_SWT_EVENT_PULSE] = 0x1,
|
|
};
|
|
#if (CONFIG_E3L)
|
|
static sdrv_xtrg_sig_group_t sdrv_xtrg_sig_groups[] = {
|
|
[SDRV_XTRG_SWT_i_GROUP] =
|
|
{
|
|
.sig_nr = SWT_i_NR,
|
|
.sse_idx = 0,
|
|
.smon_idx = 0,
|
|
.syncmux_idx = 0,
|
|
},
|
|
[SDRV_XTRG_TRG_i_GROUP] =
|
|
{
|
|
.sig_nr = TRG_i_NR,
|
|
.sse_idx = 8,
|
|
.smux_idx = 54,
|
|
.smon_idx = 72,
|
|
.sync_dis_off = TRG_SYNC_DIS,
|
|
},
|
|
[SDRV_XTRG_SIG_i_GROUP] =
|
|
{
|
|
.sig_nr = SIG_i_NR,
|
|
.sse_idx = 12,
|
|
.smux_idx = 16,
|
|
.smon_idx = 34,
|
|
.sync_dis_off = SIG_SYNC_DIS,
|
|
},
|
|
[SDRV_XTRG_SYNC_i_GROUP] =
|
|
{
|
|
.sig_nr = SYNC_i_NR,
|
|
.sse_idx = 50,
|
|
.smon_idx = 24,
|
|
.syncmux_idx = 24,
|
|
.sync_dis_off = SYNC_SYNC_DIS,
|
|
},
|
|
[SDRV_XTRG_IO_i_GROUP] =
|
|
{
|
|
.sig_nr = IO_i_NR,
|
|
.sse_idx = 60,
|
|
.smux_idx = 58,
|
|
.smon_idx = 76,
|
|
.sync_dis_off = IO_SYNC_DIS,
|
|
},
|
|
[SDRV_XTRG_TID_i_GROUP] =
|
|
{
|
|
.sig_nr = TID_i_NR,
|
|
},
|
|
[SDRV_XTRG_SIG_o_GROUP] =
|
|
{
|
|
.sig_nr = SIG_o_NR,
|
|
.smon_idx = 10,
|
|
},
|
|
[SDRV_XTRG_IO_o_GROUP] =
|
|
{
|
|
.sig_nr = IO_o_NR,
|
|
.smon_idx = 50,
|
|
},
|
|
[SDRV_XTRG_SYNC_o_GROUP] =
|
|
{
|
|
.sig_nr = SYNC_o_NR,
|
|
.smon_idx = 0,
|
|
},
|
|
[SDRV_XTRG_SSIG_GROUP] =
|
|
{
|
|
.sig_nr = SSIG_NR,
|
|
.smux_idx = 0,
|
|
.smon_idx = 8,
|
|
.syncmux_idx = 8,
|
|
},
|
|
};
|
|
#else
|
|
static sdrv_xtrg_sig_group_t sdrv_xtrg_sig_groups[] = {
|
|
[SDRV_XTRG_SWT_i_GROUP] =
|
|
{
|
|
.sig_nr = SWT_i_NR,
|
|
.sse_idx = 0,
|
|
.smon_idx = 0,
|
|
.syncmux_idx = 0,
|
|
},
|
|
[SDRV_XTRG_TRG_i_GROUP] =
|
|
{
|
|
.sig_nr = TRG_i_NR,
|
|
.sse_idx = 8,
|
|
.smux_idx = 84,
|
|
.smon_idx = 112,
|
|
.sync_dis_off = TRG_SYNC_DIS,
|
|
},
|
|
[SDRV_XTRG_SIG_i_GROUP] =
|
|
{
|
|
.sig_nr = SIG_i_NR,
|
|
.sse_idx = 16,
|
|
.smux_idx = 16,
|
|
.smon_idx = 44,
|
|
.sync_dis_off = SIG_SYNC_DIS,
|
|
},
|
|
[SDRV_XTRG_SYNC_i_GROUP] =
|
|
{
|
|
.sig_nr = SYNC_i_NR,
|
|
.sse_idx = 84,
|
|
.smon_idx = 24,
|
|
.syncmux_idx = 24,
|
|
.sync_dis_off = SYNC_SYNC_DIS,
|
|
},
|
|
[SDRV_XTRG_IO_i_GROUP] =
|
|
{
|
|
.sig_nr = IO_i_NR,
|
|
.sse_idx = 104,
|
|
.smux_idx = 92,
|
|
.smon_idx = 120,
|
|
.sync_dis_off = IO_SYNC_DIS,
|
|
},
|
|
[SDRV_XTRG_TID_i_GROUP] =
|
|
{
|
|
.sig_nr = TID_i_NR,
|
|
},
|
|
[SDRV_XTRG_SIG_o_GROUP] =
|
|
{
|
|
.sig_nr = SIG_o_NR,
|
|
.smon_idx = 20,
|
|
},
|
|
[SDRV_XTRG_IO_o_GROUP] =
|
|
{
|
|
.sig_nr = IO_o_NR,
|
|
.smon_idx = 96,
|
|
},
|
|
[SDRV_XTRG_SYNC_o_GROUP] =
|
|
{
|
|
.sig_nr = SYNC_o_NR,
|
|
.smon_idx = 0,
|
|
},
|
|
[SDRV_XTRG_SSIG_GROUP] =
|
|
{
|
|
.sig_nr = SSIG_NR,
|
|
.smux_idx = 0,
|
|
.smon_idx = 8,
|
|
.syncmux_idx = 8,
|
|
},
|
|
};
|
|
#endif
|
|
|
|
/**
|
|
* @brief sdrv xtrg write reg.
|
|
*
|
|
* @param[in] base reg base
|
|
* @param[in] val reg val
|
|
* @param[in] reg reg offset
|
|
*/
|
|
static inline void sdrv_xtrg_writel(paddr_t base, uint32_t reg, uint32_t val)
|
|
{
|
|
writel(val, base + reg);
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv xtrg read reg.
|
|
*
|
|
* @param[in] base reg base
|
|
* @param[in] reg reg offset
|
|
*/
|
|
static inline uint32_t sdrv_xtrg_readl(paddr_t base, uint32_t reg)
|
|
{
|
|
return readl(base + reg);
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv xtrg modify reg.
|
|
*
|
|
* @param[in] base reg base
|
|
* @param[in] reg reg offset
|
|
* @param[in] start start bit
|
|
* @param[in] width width
|
|
* @param[in] val reg val
|
|
*/
|
|
static inline void sdrv_xtrg_modifyl(paddr_t base, uint32_t reg, uint32_t start,
|
|
uint32_t width, uint32_t val)
|
|
{
|
|
RMWREG32(base + reg, start, width, val);
|
|
}
|
|
|
|
/**
|
|
* @brief XTRG irp handler.
|
|
*
|
|
* @param[in] irq sdrv xtrg irq.
|
|
* @param[in] ctrl sdrv xtrg controller
|
|
*/
|
|
int sdrv_xtrg_irq_handler(uint32_t irq, void *ctrl)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
sdrv_xtrg_t *irq_ctrl = (sdrv_xtrg_t *)ctrl;
|
|
ASSERT(irq_ctrl->base > 0U);
|
|
|
|
uint32_t status = sdrv_xtrg_readl(irq_ctrl->base, FUNC_INT_STA);
|
|
|
|
if (irq_ctrl->cb != NULL) {
|
|
for (uint8_t i = 0; i < ARRAY_SIZE(xtrg_intr_events); i++) {
|
|
if (status & xtrg_intr_events[i].intr_mask) {
|
|
irq_ctrl->cb(irq_ctrl, xtrg_intr_events[i].event,
|
|
irq_ctrl->para);
|
|
}
|
|
}
|
|
}
|
|
|
|
sdrv_xtrg_writel(irq_ctrl->base, FUNC_INT_STA, status);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Init XTRG.
|
|
*
|
|
* @param[in] ctrl sdrv XTRG controller.
|
|
*/
|
|
void sdrv_xtrg_init(sdrv_xtrg_t *ctrl, xtrg_callback_t callback, void *para)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
ASSERT(ctrl->base > 0U);
|
|
|
|
ctrl->cb = callback;
|
|
ctrl->para = para;
|
|
|
|
if (ctrl->irq > 0U) {
|
|
irq_attach(ctrl->irq, sdrv_xtrg_irq_handler, ctrl);
|
|
irq_enable(ctrl->irq);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Deinit XTRG.
|
|
*
|
|
* @param[in] ctrl sdrv XTRG controller.
|
|
*/
|
|
void sdrv_xtrg_deinit(sdrv_xtrg_t *ctrl)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
|
|
if (ctrl->irq > 0) {
|
|
irq_disable(ctrl->irq);
|
|
irq_detach(ctrl->irq);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv xtrg int enable.
|
|
*
|
|
* @param[in] ctrl xtrg controller
|
|
* @param[in] int_id int id
|
|
*/
|
|
void sdrv_xtrg_int_enable(sdrv_xtrg_t *ctrl, sdrv_xtrg_irq_status_e int_id)
|
|
{
|
|
uint32_t sta_en, sig_en;
|
|
|
|
sta_en = sdrv_xtrg_readl(ctrl->base, FUNC_INT_STA_EN);
|
|
sta_en |= 1 << int_id;
|
|
sdrv_xtrg_writel(ctrl->base, FUNC_INT_STA_EN, sta_en);
|
|
|
|
sig_en = sdrv_xtrg_readl(ctrl->base, FUNC_INT_SIG_EN);
|
|
sig_en |= 1 << int_id;
|
|
sdrv_xtrg_writel(ctrl->base, FUNC_INT_SIG_EN, sig_en);
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv xtrg int disable.
|
|
*
|
|
* @param[in] ctrl xtrg dev
|
|
* @param[in] int_id int id
|
|
*/
|
|
void sdrv_xtrg_int_disable(sdrv_xtrg_t *ctrl, sdrv_xtrg_irq_status_e int_id)
|
|
{
|
|
uint32_t sta_en, sig_en;
|
|
|
|
sta_en = sdrv_xtrg_readl(ctrl->base, FUNC_INT_STA_EN);
|
|
sta_en &= ~(1 << int_id);
|
|
sdrv_xtrg_writel(ctrl->base, FUNC_INT_STA_EN, sta_en);
|
|
|
|
sig_en = sdrv_xtrg_readl(ctrl->base, FUNC_INT_SIG_EN);
|
|
sig_en &= ~(1 << int_id);
|
|
sdrv_xtrg_writel(ctrl->base, FUNC_INT_SIG_EN, sig_en);
|
|
}
|
|
|
|
/**
|
|
* @brief Enable or disable input signal synchronization.
|
|
*
|
|
* SIG_i, TRG_i, SYNC_i and IO_i signals are synchronized to timer clock domain
|
|
* by default. This function enable or disable signal synchronizations.
|
|
*
|
|
* @param[in] ctrl xTRG controller.
|
|
* @param[in] cfg xTRG configuration.
|
|
* @param[in] enable Enable or disable synchronization.
|
|
*/
|
|
void sdrv_xtrg_sync_config(sdrv_xtrg_t *ctrl, const sdrv_xtrg_config_t *cfg,
|
|
bool enable)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
ASSERT(cfg != NULL);
|
|
|
|
sdrv_xtrg_i_group_e group_id = XTRG_i_GROUP(cfg->sig);
|
|
sdrv_xtrg_sig_group_t *group = &sdrv_xtrg_sig_groups[group_id];
|
|
uint32_t i = XTRG_i_SIG(cfg->sig);
|
|
|
|
sdrv_xtrg_modifyl(ctrl->base, group->sync_dis_off + i / 32, i % 32, 1,
|
|
!enable);
|
|
}
|
|
|
|
/**
|
|
* @brief Configure I/O filters.
|
|
*
|
|
* @param[in] ctrl xTRG controller.
|
|
* @param[in] cfg The input signal to enable or disable debouncing
|
|
* @param[in] io_filter_cfg I/O filter configuration.
|
|
*/
|
|
void sdrv_xtrg_io_filter_config(
|
|
sdrv_xtrg_t *ctrl, const sdrv_xtrg_io_filter_config_t *io_filter_cfg,
|
|
bool enable)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
ASSERT(io_filter_cfg != NULL);
|
|
|
|
uint32_t val = 0;
|
|
|
|
val = ((io_filter_cfg->sampling_intvl - 1) << 12) |
|
|
((io_filter_cfg->neg_edge_intvl - 2) << 8) |
|
|
((io_filter_cfg->pos_edge_intvl - 2) << 4) |
|
|
(io_filter_cfg->edge << 1) | enable;
|
|
|
|
sdrv_xtrg_writel(ctrl->base, IO_FLAT(XTRG_i_SIG(io_filter_cfg->sig)), val);
|
|
}
|
|
|
|
/**
|
|
* @brief Config SWT (software trigger).
|
|
*
|
|
* @param[in] ctrl xTRG controller.
|
|
* @param[in] swt_cfg swt configuration.
|
|
*/
|
|
int sdrv_xtrg_swt_config(sdrv_xtrg_t *ctrl,
|
|
const sdrv_xtrg_swt_config_t *swt_cfg)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
ASSERT(swt_cfg != NULL);
|
|
int ret = 0;
|
|
uint32_t cnt = 0;
|
|
sdrv_xtrg_modifyl(ctrl->base, SW_TRG_PULSE_WIDTH(XTRG_i_SIG(swt_cfg->swt)),
|
|
16 * (XTRG_i_SIG(swt_cfg->swt) % 2), 16,
|
|
swt_cfg->width & 0x0000FFFFul);
|
|
|
|
while (sdrv_xtrg_readl(ctrl->base, SW_TRG_CTRL) != 0 && (cnt < 200000)) {
|
|
cnt++;
|
|
}
|
|
|
|
if (cnt >= 200000) {
|
|
ret = -1;
|
|
} else {
|
|
sdrv_xtrg_modifyl(ctrl->base, SW_TRG_CTRL, 4 * XTRG_i_SIG(swt_cfg->swt),
|
|
4, sctp[swt_cfg->event]);
|
|
ret = 0;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Enable or disable SSE5.
|
|
*ctrl
|
|
* @param[in] ctrl xTRG controller.
|
|
* @param[in] sse5_cfg xTRG sse configuration.
|
|
* @param[in] enable Enable or disable sse5.
|
|
*/
|
|
void sdrv_xtrg_sse5_config(sdrv_xtrg_t *ctrl,
|
|
const sdrv_xtrg_sse5_config_t *sse5_cfg, bool enable)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
ASSERT(sse5_cfg != NULL);
|
|
|
|
uint32_t sel03 = 0, sel4 = 0;
|
|
uint32_t ctrl_reg = 0;
|
|
|
|
for (int i = 0; i < 5; i++) {
|
|
sdrv_xtrg_i_group_e group_id = XTRG_i_GROUP(sse5_cfg->in[i].sig);
|
|
uint32_t idx = XTRG_i_SIG(sse5_cfg->in[i].sig);
|
|
|
|
if (i < 4) {
|
|
sel03 |= (sdrv_xtrg_sig_groups[group_id].sse_idx + idx) << (i * 8);
|
|
} else {
|
|
sel4 = sdrv_xtrg_sig_groups[group_id].sse_idx + idx;
|
|
}
|
|
|
|
ctrl_reg |= (sse5_cfg->in[i].edge_detect << (1 + i)) |
|
|
(sse5_cfg->in[i].edge << (6 + 2 * i));
|
|
}
|
|
|
|
sdrv_xtrg_writel(ctrl->base, SSE_IN_0_3_SEL(sse5_cfg->ssm_sel), sel03);
|
|
sdrv_xtrg_writel(ctrl->base, SSE_IN_4_SEL(sse5_cfg->ssm_sel), sel4);
|
|
sdrv_xtrg_writel(ctrl->base, SSE_REG(sse5_cfg->ssm_sel),
|
|
sse5_cfg->synthesis_val);
|
|
sdrv_xtrg_modifyl(ctrl->base, SSE_CTRL(sse5_cfg->ssm_sel), 0, 16, ctrl_reg);
|
|
|
|
sdrv_xtrg_modifyl(ctrl->base, SSE_CTRL(sse5_cfg->ssm_sel), 0, 1,
|
|
(uint32_t)enable);
|
|
}
|
|
|
|
/**
|
|
* @brief Configure signal mux, muxing input signals to SIG_o or IO_o.
|
|
*
|
|
* The smux module muxes SSIG, TRG_i, SIG_i, and I/O inputs to SIG_o
|
|
* and I/O outputs.
|
|
*
|
|
* @param[in] ctrl xTRG controller.
|
|
* @param[in] cfg xTRG configuration.
|
|
*/
|
|
void sdrv_xtrg_smux_config(sdrv_xtrg_t *ctrl, const sdrv_xtrg_config_t *cfg)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
ASSERT(cfg != NULL);
|
|
|
|
if (SDRV_XTRG_SIG_o_GROUP == XTRG_i_GROUP(cfg->sig_o)) {
|
|
sdrv_xtrg_writel(
|
|
ctrl->base, SIG_O_SEL(XTRG_i_SIG(cfg->sig_o)),
|
|
sdrv_xtrg_sig_groups[XTRG_i_GROUP(cfg->sig_i)].smux_idx +
|
|
XTRG_i_SIG(cfg->sig_i));
|
|
} else if (SDRV_XTRG_IO_o_GROUP == XTRG_i_GROUP(cfg->sig_o)) {
|
|
sdrv_xtrg_writel(
|
|
ctrl->base, IO_O_SEL(XTRG_i_SIG(cfg->sig_o)),
|
|
sdrv_xtrg_sig_groups[XTRG_i_GROUP(cfg->sig_i)].smux_idx +
|
|
XTRG_i_SIG(cfg->sig_i));
|
|
sdrv_xtrg_modifyl(ctrl->base, IO_OUT_EN(XTRG_i_SIG(cfg->sig_o)),
|
|
XTRG_i_SIG(cfg->sig_o) % 32, 1, 1);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Configure IO output, muxing SSIG_i,TRG_i,SIG_i,IO_i to IO_o.
|
|
*
|
|
* @param[in] ctrl xTRG controler.
|
|
* @param[in] cfg xTRG configuration.
|
|
* @param[in] enable Enable or disable io out.
|
|
*/
|
|
void sdrv_xtrg_io_out_config(sdrv_xtrg_t *ctrl, const sdrv_xtrg_config_t *cfg,
|
|
bool enable)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
ASSERT(cfg != NULL);
|
|
|
|
sdrv_xtrg_writel(ctrl->base, IO_O_SEL(XTRG_i_SIG(cfg->sig_o)),
|
|
sdrv_xtrg_sig_groups[XTRG_i_GROUP(cfg->sig_i)].smux_idx +
|
|
XTRG_i_SIG(cfg->sig_i));
|
|
|
|
sdrv_xtrg_modifyl(ctrl->base, IO_OUT_EN(XTRG_i_SIG(cfg->sig_o)),
|
|
XTRG_i_SIG(cfg->sig_o) % 32, 1, (uint32_t)enable);
|
|
}
|
|
|
|
/**
|
|
* @brief Configure syncmux, muxing input sync signals to SYNC_o.
|
|
*
|
|
* The syncmux module muxes SWT_i, SSIG and SYNC_i inputs to SYNC_o outputs.
|
|
*
|
|
* @param[in] ctrl xTRG controller.
|
|
* @param[in] cfg xTRG configuration.
|
|
*/
|
|
void sdrv_xtrg_syncmux_config(sdrv_xtrg_t *ctrl, const sdrv_xtrg_config_t *cfg)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
ASSERT(cfg != NULL);
|
|
|
|
sdrv_xtrg_writel(
|
|
ctrl->base, SYNC_O_SEL(XTRG_i_SIG(cfg->sig_o)),
|
|
sdrv_xtrg_sig_groups[XTRG_i_GROUP(cfg->sig_i)].syncmux_idx +
|
|
XTRG_i_SIG(cfg->sig_i));
|
|
}
|
|
|
|
/**
|
|
* @brief Configure syncmux, muxing input sync signals to SYNC_o.
|
|
*
|
|
* The syncmux module muxes SWT_i, SSIG and SYNC_i inputs to SYNC_o outputs.
|
|
*
|
|
* @param[in] ctrl xTRG controller.
|
|
* @param[in] tmux_drt_cfg xTRG tmux direct configuration.
|
|
*/
|
|
void sdrv_xtrg_tmux0_drt_config(sdrv_xtrg_t *ctrl,
|
|
const sdrv_xtrg_tmux_drt_config_t *tmux_drt_cfg)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
ASSERT(tmux_drt_cfg != NULL);
|
|
|
|
uint32_t trg_sel, tid_sel;
|
|
uint32_t decode_sel[2] = {0};
|
|
|
|
/* Input order is TRG_i, then SSIG. */
|
|
if (SDRV_XTRG_TRG_i_GROUP == XTRG_i_GROUP(tmux_drt_cfg->trigger_sig))
|
|
trg_sel = XTRG_i_SIG(tmux_drt_cfg->trigger_sig);
|
|
else
|
|
trg_sel = TRG_i_NR + XTRG_i_SIG(tmux_drt_cfg->trigger_sig);
|
|
|
|
tid_sel = XTRG_i_SIG(tmux_drt_cfg->tid);
|
|
|
|
sdrv_xtrg_writel(ctrl->base, TMUX0_DRT_CTRL(tmux_drt_cfg->tmux0_drt_sel),
|
|
(trg_sel << 3) + tid_sel);
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
if (i < 4) {
|
|
decode_sel[0] |= tmux_drt_cfg->target_lut[i] << (i * 8);
|
|
} else {
|
|
decode_sel[1] |= tmux_drt_cfg->target_lut[i] << ((i - 4) * 8);
|
|
}
|
|
}
|
|
|
|
sdrv_xtrg_writel(ctrl->base,
|
|
TMUX0_DRT_DECODE_SEL(tmux_drt_cfg->tmux0_drt_sel, 1),
|
|
decode_sel[0]);
|
|
sdrv_xtrg_writel(ctrl->base,
|
|
TMUX0_DRT_DECODE_SEL(tmux_drt_cfg->tmux0_drt_sel, 2),
|
|
decode_sel[1]);
|
|
sdrv_xtrg_modifyl(ctrl->base, TMUX_DEC_EN, tmux_drt_cfg->tmux0_drt_sel, 1,
|
|
1); // TMUX_DEC_EN
|
|
}
|
|
|
|
/**
|
|
* @brief Configure the Trigger Mux (tmux) indrt modules..
|
|
*
|
|
* The tmux muxes TRG_i, SSIG signals to ADC and ACMP modules, with specified
|
|
* TID. There are 8 "drt" decoders, whose TID comes from TID_i, and 8
|
|
* "indrt" decoders, whose TID comes from xTRG internel TID pool.
|
|
*
|
|
* @param[in] ctrl xTRG controller.
|
|
* @param[in] tmux_indrt xTRG tmux indirect configuration.
|
|
*/
|
|
void sdrv_xtrg_tmux0_indrt_config(
|
|
sdrv_xtrg_t *ctrl, const sdrv_xtrg_tmux_indrt_config_t *tmux_indrt_cfg)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
ASSERT(tmux_indrt_cfg != NULL);
|
|
|
|
uint32_t trg_sel;
|
|
uint32_t decode_sel[2] = {0};
|
|
|
|
/* Input order is TRG_i, then SSIG. */
|
|
if (SDRV_XTRG_TRG_i_GROUP == XTRG_i_GROUP(tmux_indrt_cfg->trigger_sig))
|
|
trg_sel = XTRG_i_SIG(tmux_indrt_cfg->trigger_sig);
|
|
else
|
|
trg_sel = TRG_i_NR + XTRG_i_SIG(tmux_indrt_cfg->trigger_sig);
|
|
|
|
sdrv_xtrg_writel(ctrl->base,
|
|
TMUX0_INDRT_CTRL(tmux_indrt_cfg->tmux0_indrt_sel),
|
|
(tmux_indrt_cfg->term_tid << 16) | (trg_sel << 3) |
|
|
tmux_indrt_cfg->term_val);
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
if (i < 4) {
|
|
decode_sel[0] |= tmux_indrt_cfg->target_lut[i] << (i * 8);
|
|
} else {
|
|
decode_sel[1] |= tmux_indrt_cfg->target_lut[i] << ((i - 4) * 8);
|
|
}
|
|
}
|
|
|
|
sdrv_xtrg_writel(ctrl->base,
|
|
TMUX0_INDRT_DECODE_SEL(tmux_indrt_cfg->tmux0_indrt_sel, 1),
|
|
decode_sel[0]);
|
|
sdrv_xtrg_writel(ctrl->base,
|
|
TMUX0_INDRT_DECODE_SEL(tmux_indrt_cfg->tmux0_indrt_sel, 2),
|
|
decode_sel[1]);
|
|
|
|
sdrv_xtrg_writel(ctrl->base,
|
|
TMUX0_INDRT_TID_POOL(tmux_indrt_cfg->tmux0_indrt_sel, 1),
|
|
tmux_indrt_cfg->tid_pool[0]);
|
|
sdrv_xtrg_writel(ctrl->base,
|
|
TMUX0_INDRT_TID_POOL(tmux_indrt_cfg->tmux0_indrt_sel, 2),
|
|
tmux_indrt_cfg->tid_pool[1]);
|
|
sdrv_xtrg_modifyl(ctrl->base, TMUX_DEC_EN,
|
|
tmux_indrt_cfg->tmux0_indrt_sel + 8, 1,
|
|
1); // TMUX_DEC_EN
|
|
}
|
|
|
|
/**
|
|
* @brief Configure SMON (Signal Monitor).
|
|
* The SMON monitors the input and output signal groups
|
|
* First level select 32 input signals and 32 output signals.
|
|
* Second level select inputs from output of 1st level
|
|
*
|
|
* @param[in] ctrl xTRG controller.
|
|
* @param[in] smon_cfg smon configuration.
|
|
* @param[in] enable Enable or disable smon.
|
|
*/
|
|
void sdrv_xtrg_smon_config(sdrv_xtrg_t *ctrl,
|
|
const sdrv_xtrg_smon_config_t *smon_cfg, bool enable)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
ASSERT(smon_cfg != NULL);
|
|
|
|
sdrv_xtrg_i_group_e sig_in_group = XTRG_i_GROUP(smon_cfg->sig_in_sel);
|
|
sdrv_xtrg_i_group_e sig_out_group = XTRG_i_GROUP(smon_cfg->sig_out_sel);
|
|
|
|
uint32_t sig_in_idx = sdrv_xtrg_sig_groups[sig_in_group].smon_idx +
|
|
XTRG_i_SIG(smon_cfg->sig_in_sel);
|
|
uint32_t sig_out_idx = sdrv_xtrg_sig_groups[sig_out_group].smon_idx +
|
|
XTRG_i_SIG(smon_cfg->sig_out_sel);
|
|
|
|
sdrv_xtrg_writel(ctrl->base, SMON_FIRST_MUX_SELECT(smon_cfg->smon_sel),
|
|
(sig_out_idx << 8) | sig_in_idx);
|
|
|
|
sdrv_xtrg_writel(ctrl->base, SMON_SECOND_MUX_SELECT(smon_cfg->smon_sel),
|
|
(smon_cfg->change_pol_in0 << 15) |
|
|
(smon_cfg->sig_input1_sel << 8) |
|
|
smon_cfg->sig_input0_sel);
|
|
|
|
sdrv_xtrg_modifyl(ctrl->base, SMON_EN, smon_cfg->smon_sel, 1,
|
|
(uint32_t)enable);
|
|
}
|
|
|
|
/**
|
|
* @brief Configure SWDT Pulse Check.(Signal Watch Dog Timer).
|
|
*
|
|
* @param[in] ctrl xTRG controller.
|
|
* @param[in] swdt_cfg swdt configuration.
|
|
* @param[in] enable Enable or disable swdt.
|
|
*/
|
|
void sdrv_xtrg_swdt_config(sdrv_xtrg_t *ctrl,
|
|
const sdrv_xtrg_swdt_config_t *swdt_cfg, bool enable)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
ASSERT(swdt_cfg != NULL);
|
|
ASSERT((SDRV_XTRG_SWDT_PULSE_CHECK == swdt_cfg->xtrg_swdt_check_mode) ||
|
|
(SDRV_XTRG_SWDT_EVENT_CHECK == swdt_cfg->xtrg_swdt_check_mode));
|
|
|
|
if (SDRV_XTRG_SWDT_PULSE_CHECK == swdt_cfg->xtrg_swdt_check_mode) {
|
|
sdrv_xtrg_writel(
|
|
ctrl->base,
|
|
SWDT_IN_SEL(swdt_cfg->xtrg_swdt_pulse_check_config.swdt_sel),
|
|
swdt_cfg->xtrg_swdt_pulse_check_config.swdt_sig_sel);
|
|
sdrv_xtrg_modifyl(
|
|
ctrl->base,
|
|
SWDT_PULSE_CHECK(swdt_cfg->xtrg_swdt_pulse_check_config.swdt_sel),
|
|
1, 1, swdt_cfg->xtrg_swdt_pulse_check_config.swdt_pulse_check_edge);
|
|
sdrv_xtrg_modifyl(
|
|
ctrl->base,
|
|
SWDT_PULSE_CHECK(swdt_cfg->xtrg_swdt_pulse_check_config.swdt_sel),
|
|
2, 1, swdt_cfg->xtrg_swdt_pulse_check_config.swdt_pulse_check_mode);
|
|
sdrv_xtrg_modifyl(
|
|
ctrl->base,
|
|
SWDT_PULSE_CHECK_WINDOW(
|
|
swdt_cfg->xtrg_swdt_pulse_check_config.swdt_sel),
|
|
16, 16,
|
|
swdt_cfg->xtrg_swdt_pulse_check_config.swdt_max_check_window);
|
|
sdrv_xtrg_modifyl(
|
|
ctrl->base,
|
|
SWDT_PULSE_CHECK_WINDOW(
|
|
swdt_cfg->xtrg_swdt_pulse_check_config.swdt_sel),
|
|
0, 16,
|
|
swdt_cfg->xtrg_swdt_pulse_check_config.swdt_min_check_window);
|
|
|
|
sdrv_xtrg_modifyl(
|
|
ctrl->base,
|
|
SWDT_PULSE_CHECK(swdt_cfg->xtrg_swdt_pulse_check_config.swdt_sel),
|
|
0, 1, (uint32_t)enable);
|
|
} else {
|
|
sdrv_xtrg_writel(
|
|
ctrl->base,
|
|
SWDT_IN_SEL(swdt_cfg->xtrg_swdt_event_check_config.swdt_sel),
|
|
swdt_cfg->xtrg_swdt_event_check_config.swdt_sig_sel);
|
|
sdrv_xtrg_modifyl(
|
|
ctrl->base,
|
|
SWDT_EVENT_CHECK(swdt_cfg->xtrg_swdt_event_check_config.swdt_sel),
|
|
16, 16,
|
|
swdt_cfg->xtrg_swdt_event_check_config.swdt_event_check_window);
|
|
sdrv_xtrg_modifyl(
|
|
ctrl->base,
|
|
SWDT_EVENT_CHECK(swdt_cfg->xtrg_swdt_event_check_config.swdt_sel),
|
|
1, 3, swdt_cfg->xtrg_swdt_event_check_config.event_trg_mode);
|
|
|
|
sdrv_xtrg_modifyl(
|
|
ctrl->base,
|
|
SWDT_EVENT_CHECK(swdt_cfg->xtrg_swdt_event_check_config.swdt_sel),
|
|
0, 1, (uint32_t)enable);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Enable or disable DMA0/1.
|
|
*
|
|
* @param[in] ctrl xTRG controller.
|
|
* @param[in] config xTRG dma configuration.
|
|
* @param[in] enable Enable or disable dma.
|
|
*/
|
|
void sdrv_xtrg_dma_config(sdrv_xtrg_t *ctrl,
|
|
const sdrv_xtrg_dma_config_t *config, bool enable)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
ASSERT(config != NULL);
|
|
ASSERT((SDRV_XTRG_DMA0 == config->dma_sel) ||
|
|
(SDRV_XTRG_DMA1 == config->dma_sel));
|
|
|
|
if (SDRV_XTRG_DMA0 == config->dma_sel) {
|
|
sdrv_xtrg_writel(ctrl->base, DMAC0_CTRL,
|
|
(config->ssm_sel << 2) | (config->ssig_mode << 1));
|
|
sdrv_xtrg_modifyl(ctrl->base, DMAC0_CTRL, 0, 1, (uint32_t)enable);
|
|
|
|
} else {
|
|
sdrv_xtrg_writel(ctrl->base, DMAC1_CTRL,
|
|
(config->ssm_sel << 2) | (config->ssig_mode << 1));
|
|
sdrv_xtrg_modifyl(ctrl->base, DMAC1_CTRL, 0, 1, (uint32_t)enable);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Read tmux adc result.
|
|
*
|
|
* @param[in] ctrl xTRG controller.
|
|
* @param[in] tmux_id xTRG tmux index.
|
|
* @param[in] adc_id xTRG adc index.
|
|
*
|
|
* @return adc result
|
|
*/
|
|
uint32_t sdrv_xtrg_adc_rslt(sdrv_xtrg_t *ctrl, sdrv_xtrg_tmux_sel_e tmux_id,
|
|
sdrv_xtrg_adc_sel_e adc_id)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
|
|
return sdrv_xtrg_readl(ctrl->base, TMUX_ADC_RSLT(adc_id, tmux_id));
|
|
}
|
|
|
|
/**
|
|
* @brief Read tmux acmp result.
|
|
*
|
|
* @param[in] ctrl xTRG controller.
|
|
* @param[in] tmux_id xTRG tmux index.
|
|
* @param[in] acmp_id xTRG acmp index.
|
|
*
|
|
* @return acmp result
|
|
*/
|
|
uint32_t sdrv_xtrg_acmp_rslt(sdrv_xtrg_t *ctrl, sdrv_xtrg_tmux_sel_e tmux_id,
|
|
sdrv_xtrg_acmp_sel_e acmp_id)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
|
|
return sdrv_xtrg_readl(ctrl->base, TMUX_ACMP_RSLT(acmp_id, tmux_id));
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv xtrg fault source enable.
|
|
*
|
|
* @param[in] xtrg dev base.
|
|
* @param[in] fault_id xtrg fault source id.
|
|
*/
|
|
void sdrv_xtrg_fault_source_config(sdrv_xtrg_t *ctrl, uint32_t fault_id,
|
|
bool enable)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
|
|
sdrv_xtrg_modifyl(ctrl->base, FAULT_SOURCE_EN(fault_id), fault_id % 32, 1,
|
|
(uint32_t)enable);
|
|
}
|
|
|
|
/**
|
|
* @brief Smon cmp err config.
|
|
*
|
|
* @param[in] ctrl xTRG controller.
|
|
* @param[in] xtrg_smon_cmp_err_config Smon cmp err config.
|
|
* @param[in] enable Enable or disable err signal.
|
|
*/
|
|
void sdrv_xtrg_smon_cmp_err_config(
|
|
sdrv_xtrg_t *ctrl,
|
|
sdrv_xtrg_smon_cmp_err_config_t *xtrg_smon_cmp_err_config, bool enable)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
ASSERT(xtrg_smon_cmp_err_config != NULL);
|
|
|
|
uint32_t sta_en, sig_en;
|
|
|
|
sta_en = sdrv_xtrg_readl(ctrl->base, FUNC_SMON_CMP_ERR_INT_STA_EN);
|
|
|
|
if (enable) {
|
|
|
|
sta_en |= (1 << xtrg_smon_cmp_err_config->smon_cmp_err);
|
|
|
|
if (SDRV_SMON_COR_ERROR == xtrg_smon_cmp_err_config->err_sel) {
|
|
sig_en =
|
|
sdrv_xtrg_readl(ctrl->base, FUNC_SMON_CMP_COR_ERR_INT_SIG_EN);
|
|
sig_en |= (1 << xtrg_smon_cmp_err_config->smon_cmp_err);
|
|
sdrv_xtrg_writel(ctrl->base, FUNC_SMON_CMP_COR_ERR_INT_SIG_EN,
|
|
sig_en);
|
|
|
|
} else if (SDRV_SMON_UNC_ERROR == xtrg_smon_cmp_err_config->err_sel) {
|
|
sig_en =
|
|
sdrv_xtrg_readl(ctrl->base, FUNC_SMON_CMP_UNC_ERR_INT_SIG_EN);
|
|
sig_en |= (1 << xtrg_smon_cmp_err_config->smon_cmp_err);
|
|
sdrv_xtrg_writel(ctrl->base, FUNC_SMON_CMP_UNC_ERR_INT_SIG_EN,
|
|
sig_en);
|
|
}
|
|
|
|
} else {
|
|
|
|
sta_en &= ~(1 << xtrg_smon_cmp_err_config->smon_cmp_err);
|
|
|
|
if (SDRV_SMON_COR_ERROR == xtrg_smon_cmp_err_config->err_sel) {
|
|
|
|
sig_en =
|
|
sdrv_xtrg_readl(ctrl->base, FUNC_SMON_CMP_COR_ERR_INT_SIG_EN);
|
|
sig_en &= ~(1 << xtrg_smon_cmp_err_config->smon_cmp_err);
|
|
sdrv_xtrg_writel(ctrl->base, FUNC_SMON_CMP_COR_ERR_INT_SIG_EN,
|
|
sig_en);
|
|
|
|
} else if (SDRV_SMON_UNC_ERROR == xtrg_smon_cmp_err_config->err_sel) {
|
|
|
|
sig_en =
|
|
sdrv_xtrg_readl(ctrl->base, FUNC_SMON_CMP_UNC_ERR_INT_SIG_EN);
|
|
sig_en &= ~(1 << xtrg_smon_cmp_err_config->smon_cmp_err);
|
|
sdrv_xtrg_writel(ctrl->base, FUNC_SMON_CMP_UNC_ERR_INT_SIG_EN,
|
|
sig_en);
|
|
}
|
|
}
|
|
|
|
sdrv_xtrg_writel(ctrl->base, FUNC_SMON_CMP_ERR_INT_STA_EN, sta_en);
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv xtrg read fault status.
|
|
*
|
|
* @param[in] xtrg dev base.
|
|
*/
|
|
uint32_t sdrv_xtrg_read_smon_cmp_err_status(sdrv_xtrg_t *ctrl)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
|
|
uint32_t reg_val = 0;
|
|
|
|
reg_val = sdrv_xtrg_readl(ctrl->base, FUNC_SMON_CMP_ERR_INT_STA);
|
|
return reg_val;
|
|
}
|
|
|
|
/**
|
|
* @brief sdrv set up timeout value from ADC
|
|
*
|
|
* @param[in] xtrg dev base.
|
|
*/
|
|
void sdrv_xtrg_tmux_done_monitor_cnt_config(sdrv_xtrg_t *ctrl, uint8_t timeOutValue)
|
|
{
|
|
ASSERT(ctrl != NULL);
|
|
sdrv_xtrg_writel(ctrl->base, TUMX_DONE_MONITOR_CNT, timeOutValue);
|
|
}
|