/** * @file sdrv_xtrg.c * @brief Semidrive XTRG driver source file. * * @copyright Copyright (c) 2021 Semidrive Semiconductor. * All rights reserved. */ #include #include #include #include #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); }