/* output BAM_TEST_BUS_REG with specified TEST_BUS_SEL */ void print_bam_test_bus_reg(void *base, u32 tb_sel) { u32 i; u32 test_bus_selection[] = {0x1, 0x2, 0x3, 0x4, 0xD, 0x10, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}; u32 size = sizeof(test_bus_selection) / sizeof(u32); if ((base == NULL) || (tb_sel == 0)) return; SPS_INFO("\nsps:Specified TEST_BUS_SEL value: 0x%x\n", tb_sel); bam_write_reg_field(base, TEST_BUS_SEL, BAM_TESTBUS_SEL, tb_sel); SPS_INFO("sps:BAM_TEST_BUS_REG: 0x%x when TEST_BUS_SEL: 0x%x\n\n", bam_read_reg(base, TEST_BUS_REG), bam_read_reg_field(base, TEST_BUS_SEL, BAM_TESTBUS_SEL)); /* output other selections */ for (i = 0; i < size; i++) { bam_write_reg_field(base, TEST_BUS_SEL, BAM_TESTBUS_SEL, test_bus_selection[i]); SPS_INFO("sps:bam 0x%x(va);TEST_BUS_REG:0x%x;TEST_BUS_SEL:0x%x", (u32) base, bam_read_reg(base, TEST_BUS_REG), bam_read_reg_field(base, TEST_BUS_SEL, BAM_TESTBUS_SEL)); } }
/** * Set BAM global execution environment * * @base - BAM virtual base address * * @ee - BAM execution environment index * * @vmid - virtual master identifier * * @reset - enable/disable BAM global software reset */ static void bam_set_ee(void *base, u32 ee, u32 vmid, enum bam_nonsecure_reset reset) { bam_write_reg_field(base, TRUST_REG, BAM_EE, ee); bam_write_reg_field(base, TRUST_REG, BAM_VMID, vmid); bam_write_reg_field(base, TRUST_REG, BAM_RST_BLOCK, reset); }
/** * Configure inactivity timer count for a BAM pipe * */ void bam_pipe_timer_config(void *base, u32 pipe, enum bam_pipe_timer_mode mode, u32 timeout_count) { bam_write_reg_field(base, P_TIMER_CTRL(pipe), P_TIMER_MODE, mode); bam_write_reg_field(base, P_TIMER_CTRL(pipe), P_TIMER_TRSHLD, timeout_count); }
void bam_pipe_timer_reset(void *base, u32 pipe) { bam_write_reg_field(base, P_TIMER_CTRL(pipe), P_TIMER_RST, 0); bam_write_reg_field(base, P_TIMER_CTRL(pipe), P_TIMER_RST, 1); }
/** * Reset inactivity timer for a BAM pipe * */ void bam_pipe_timer_reset(void *base, u32 pipe) { /* reset */ bam_write_reg_field(base, P_TIMER_CTRL(pipe), P_TIMER_RST, 0); /* active */ bam_write_reg_field(base, P_TIMER_CTRL(pipe), P_TIMER_RST, 1); }
/** * Configure a BAM pipe for satellite MTI use * */ void bam_pipe_satellite_mti(void *base, u32 pipe, u32 irq_gen_addr, u32 ee) { bam_write_reg(base, P_IRQ_EN(pipe), 0); bam_write_reg(base, P_IRQ_DEST_ADDR(pipe), irq_gen_addr); bam_write_reg_field(base, IRQ_SIC_SEL, (1 << pipe), 1); bam_write_reg_field(base, IRQ_SRCS_MSK, (1 << pipe), 1); }
/** * Disable a BAM device * */ void bam_exit(void *base, u32 ee) { bam_write_reg_field(base, IRQ_SRCS_MSK_EE(ee), BAM_IRQ, 0); bam_write_reg(base, IRQ_EN, 0); /* Disable the BAM */ bam_write_reg_field(base, CTRL, BAM_EN, 0); }
/** * Configure a BAM pipe for satellite MTI use * */ void bam_pipe_satellite_mti(void *base, u32 pipe, u32 irq_gen_addr, u32 ee) { bam_write_reg(base, P_IRQ_EN(pipe), 0); #ifndef CONFIG_SPS_SUPPORT_NDP_BAM bam_write_reg(base, P_IRQ_DEST_ADDR(pipe), irq_gen_addr); bam_write_reg_field(base, IRQ_SIC_SEL, (1 << pipe), 1); #endif bam_write_reg_field(base, IRQ_SRCS_MSK, (1 << pipe), 1); }
/** * Reset the BAM pipe * */ void bam_pipe_exit(void *base, u32 pipe, u32 ee) { bam_write_reg(base, P_IRQ_EN(pipe), 0); /* Disable the Pipe Interrupt at the BAM level */ bam_write_reg_field(base, IRQ_SRCS_MSK_EE(ee), (1 << pipe), 0); /* Pipe Disable */ bam_write_reg_field(base, P_CTRL(pipe), P_EN, 0); }
/** * Disable a BAM device * */ void bam_exit(void *base, u32 ee) { SPS_DBG2("sps:%s:bam=0x%x(va).ee=%d.", __func__, (u32) base, ee); bam_write_reg_field(base, IRQ_SRCS_MSK_EE(ee), BAM_IRQ, 0); bam_write_reg(base, IRQ_EN, 0); /* Disable the BAM */ bam_write_reg_field(base, CTRL, BAM_EN, 0); }
/** * Reset the BAM pipe * */ void bam_pipe_exit(void *base, u32 pipe, u32 ee) { SPS_DBG2("sps:%s:bam=0x%x(va).pipe=%d.", __func__, (u32) base, pipe); bam_write_reg(base, P_IRQ_EN(pipe), 0); /* Disable the Pipe Interrupt at the BAM level */ bam_write_reg_field(base, IRQ_SRCS_MSK_EE(ee), (1 << pipe), 0); /* Pipe Disable */ bam_write_reg_field(base, P_CTRL(pipe), P_EN, 0); }
void bam_pipe_exit(void *base, u32 pipe, u32 ee) { SPS_DBG2("sps:%s:bam=0x%x(va).pipe=%d.", __func__, (u32) base, pipe); bam_write_reg(base, P_IRQ_EN(pipe), 0); bam_write_reg_field(base, IRQ_SRCS_MSK_EE(ee), (1 << pipe), 0); bam_write_reg_field(base, P_CTRL(pipe), P_EN, 0); }
/** * Initialize a BAM device * */ int bam_init(void *base, u32 ee, u16 summing_threshold, u32 irq_mask, u32 *version, u32 *num_pipes) { /* disable bit#11 because of HW bug */ u32 cfg_bits = 0xffffffff & ~(1 << 11); u32 ver = 0; ver = bam_read_reg_field(base, REVISION, BAM_REVISION); if ((ver < BAM_MIN_VERSION) || (ver > BAM_MAX_VERSION)) { SPS_ERR("sps:bam 0x%x(va) Invalid BAM REVISION 0x%x.\n", (u32) base, ver); return -ENODEV; } else SPS_INFO("sps:REVISION of BAM 0x%x is 0x%x.\n", (u32) base, ver); if (summing_threshold == 0) { summing_threshold = 4; SPS_ERR("sps:bam 0x%x(va) summing_threshold is zero , " "use default 4.\n", (u32) base); } bam_write_reg_field(base, CTRL, BAM_SW_RST, 1); /* No delay needed */ bam_write_reg_field(base, CTRL, BAM_SW_RST, 0); bam_write_reg_field(base, CTRL, BAM_EN, 1); bam_write_reg(base, DESC_CNT_TRSHLD, summing_threshold); bam_write_reg(base, CNFG_BITS, cfg_bits); /* * Enable Global BAM Interrupt - for error reasons , * filter with mask. * Note: Pipes interrupts are disabled until BAM_P_IRQ_enn is set */ bam_write_reg_field(base, IRQ_SRCS_MSK_EE(ee), BAM_IRQ, 1); bam_write_reg(base, IRQ_EN, irq_mask); *num_pipes = bam_read_reg_field(base, NUM_PIPES, BAM_NUM_PIPES); *version = ver; return 0; }
/** * Output BAM register content * including the TEST_BUS register content under * different TEST_BUS_SEL values. */ static void bam_output_register_content(void *base) { u32 num_pipes; u32 test_bus_selection[] = {0x1, 0x2, 0x3, 0x4, 0xD, 0x10, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}; u32 i; u32 size = sizeof(test_bus_selection) / sizeof(u32); for (i = 0; i < size; i++) { bam_write_reg_field(base, TEST_BUS_SEL, BAM_TESTBUS_SEL, test_bus_selection[i]); SPS_INFO("sps:bam 0x%x(va);BAM_TEST_BUS_REG is" "0x%x when BAM_TEST_BUS_SEL is 0x%x.", (u32) base, bam_read_reg(base, TEST_BUS_REG), bam_read_reg_field(base, TEST_BUS_SEL, BAM_TESTBUS_SEL)); } print_bam_reg(base); num_pipes = bam_read_reg_field(base, NUM_PIPES, BAM_NUM_PIPES); SPS_INFO("sps:bam 0x%x(va) has %d pipes.", (u32) base, num_pipes); for (i = 0; i < num_pipes; i++) print_bam_pipe_reg(base, i); }
/** * Configure interrupt for a BAM pipe * */ void bam_pipe_set_irq(void *base, u32 pipe, enum bam_enable irq_en, u32 src_mask, u32 ee) { SPS_DBG2("sps:%s:bam=0x%x(va).pipe=%d.", __func__, (u32) base, pipe); bam_write_reg(base, P_IRQ_EN(pipe), src_mask); bam_write_reg_field(base, IRQ_SRCS_MSK_EE(ee), (1 << pipe), irq_en); }
/** * Set write offset for a BAM pipe * */ void bam_pipe_set_desc_write_offset(void *base, u32 pipe, u32 next_write) { /* * It is not necessary to perform a read-modify-write masking to write * the P_DESC_FIFO_PEER_OFST value, since the other field in the * register (P_BYTES_CONSUMED) is read-only. */ bam_write_reg_field(base, P_EVNT_REG(pipe), P_DESC_FIFO_PEER_OFST, next_write); }
/** * Configure inactivity timer count for a BAM pipe * */ void bam_pipe_timer_config(void *base, u32 pipe, enum bam_pipe_timer_mode mode, u32 timeout_count) { u32 for_all_pipes = 0; #ifdef CONFIG_SPS_SUPPORT_NDP_BAM for_all_pipes = bam_read_reg_field(base, REVISION, BAM_NUM_INACTIV_TMRS); #endif if (for_all_pipes) { #ifdef CONFIG_SPS_SUPPORT_NDP_BAM bam_write_reg_field(base, TIMER_CTRL, TIMER_MODE, mode); bam_write_reg_field(base, TIMER_CTRL, TIMER_TRSHLD, timeout_count); #endif } else { bam_write_reg_field(base, P_TIMER_CTRL(pipe), P_TIMER_MODE, mode); bam_write_reg_field(base, P_TIMER_CTRL(pipe), P_TIMER_TRSHLD, timeout_count); } }
/** * Reset inactivity timer for a BAM pipe * */ void bam_pipe_timer_reset(void *base, u32 pipe) { u32 for_all_pipes = 0; #ifdef CONFIG_SPS_SUPPORT_NDP_BAM for_all_pipes = bam_read_reg_field(base, REVISION, BAM_NUM_INACTIV_TMRS); #endif if (for_all_pipes) { #ifdef CONFIG_SPS_SUPPORT_NDP_BAM /* reset */ bam_write_reg_field(base, TIMER_CTRL, TIMER_RST, 0); /* active */ bam_write_reg_field(base, TIMER_CTRL, TIMER_RST, 1); #endif } else { /* reset */ bam_write_reg_field(base, P_TIMER_CTRL(pipe), P_TIMER_RST, 0); /* active */ bam_write_reg_field(base, P_TIMER_CTRL(pipe), P_TIMER_RST, 1); } }
/** * Initialize a BAM pipe */ int bam_pipe_init(void *base, u32 pipe, struct bam_pipe_parameters *param, u32 ee) { /* Reset the BAM pipe */ bam_write_reg(base, P_RST(pipe), 1); /* No delay needed */ bam_write_reg(base, P_RST(pipe), 0); /* Enable the Pipe Interrupt at the BAM level */ bam_write_reg_field(base, IRQ_SRCS_MSK_EE(ee), (1 << pipe), 1); bam_write_reg(base, P_IRQ_EN(pipe), param->pipe_irq_mask); bam_write_reg_field(base, P_CTRL(pipe), P_DIRECTION, param->dir); bam_write_reg_field(base, P_CTRL(pipe), P_SYS_MODE, param->mode); bam_write_reg(base, P_EVNT_GEN_TRSHLD(pipe), param->event_threshold); bam_write_reg(base, P_DESC_FIFO_ADDR(pipe), param->desc_base); bam_write_reg_field(base, P_FIFO_SIZES(pipe), P_DESC_FIFO_SIZE, param->desc_size); bam_write_reg_field(base, P_CTRL(pipe), P_SYS_STRM, param->stream_mode); if (param->mode == BAM_PIPE_MODE_BAM2BAM) { u32 peer_dest_addr = param->peer_phys_addr + P_EVNT_REG(param->peer_pipe); bam_write_reg(base, P_DATA_FIFO_ADDR(pipe), param->data_base); bam_write_reg_field(base, P_FIFO_SIZES(pipe), P_DATA_FIFO_SIZE, param->data_size); bam_write_reg(base, P_EVNT_DEST_ADDR(pipe), peer_dest_addr); SPS_DBG2("sps:bam=0x%x(va).pipe=%d.peer_bam=0x%x." "peer_pipe=%d.\n", (u32) base, pipe, (u32) param->peer_phys_addr, param->peer_pipe); } /* Pipe Enable - at last */ bam_write_reg_field(base, P_CTRL(pipe), P_EN, 1); return 0; }
int bam_init(void *base, u32 ee, u16 summing_threshold, u32 irq_mask, u32 *version, u32 *num_pipes) { u32 cfg_bits = 0xffffffff & ~(1 << 11); u32 ver = 0; SPS_DBG2("sps:%s:bam=0x%x(va).ee=%d.", __func__, (u32) base, ee); ver = bam_read_reg_field(base, REVISION, BAM_REVISION); if ((ver < BAM_MIN_VERSION) || (ver > BAM_MAX_VERSION)) { SPS_ERR("sps:bam 0x%x(va) Invalid BAM REVISION 0x%x.\n", (u32) base, ver); return -ENODEV; } else SPS_INFO("sps:REVISION of BAM 0x%x is 0x%x.\n", (u32) base, ver); if (summing_threshold == 0) { summing_threshold = 4; SPS_ERR("sps:bam 0x%x(va) summing_threshold is zero , " "use default 4.\n", (u32) base); } bam_write_reg_field(base, CTRL, BAM_SW_RST, 1); bam_write_reg_field(base, CTRL, BAM_SW_RST, 0); bam_write_reg_field(base, CTRL, BAM_EN, 1); #ifdef CONFIG_SPS_SUPPORT_NDP_BAM bam_write_reg_field(base, CTRL, CACHE_MISS_ERR_RESP_EN, 1); bam_write_reg_field(base, CTRL, LOCAL_CLK_GATING, 1); #endif bam_write_reg(base, DESC_CNT_TRSHLD, summing_threshold); bam_write_reg(base, CNFG_BITS, cfg_bits); bam_write_reg_field(base, IRQ_SRCS_MSK_EE(ee), BAM_IRQ, 1); bam_write_reg(base, IRQ_EN, irq_mask); *num_pipes = bam_read_reg_field(base, NUM_PIPES, BAM_NUM_PIPES); *version = ver; return 0; }
void bam_pipe_set_desc_write_offset(void *base, u32 pipe, u32 next_write) { bam_write_reg_field(base, P_EVNT_REG(pipe), P_DESC_FIFO_PEER_OFST, next_write); }
/** * Initialize a BAM pipe */ int bam_pipe_init(void *base, u32 pipe, struct bam_pipe_parameters *param, u32 ee) { SPS_DBG2("sps:%s:bam=0x%x(va).pipe=%d.", __func__, (u32) base, pipe); /* Reset the BAM pipe */ bam_write_reg(base, P_RST(pipe), 1); /* No delay needed */ bam_write_reg(base, P_RST(pipe), 0); /* Enable the Pipe Interrupt at the BAM level */ bam_write_reg_field(base, IRQ_SRCS_MSK_EE(ee), (1 << pipe), 1); bam_write_reg(base, P_IRQ_EN(pipe), param->pipe_irq_mask); bam_write_reg_field(base, P_CTRL(pipe), P_DIRECTION, param->dir); bam_write_reg_field(base, P_CTRL(pipe), P_SYS_MODE, param->mode); bam_write_reg(base, P_EVNT_GEN_TRSHLD(pipe), param->event_threshold); bam_write_reg(base, P_DESC_FIFO_ADDR(pipe), param->desc_base); bam_write_reg_field(base, P_FIFO_SIZES(pipe), P_DESC_FIFO_SIZE, param->desc_size); bam_write_reg_field(base, P_CTRL(pipe), P_SYS_STRM, param->stream_mode); #ifdef CONFIG_SPS_SUPPORT_NDP_BAM bam_write_reg_field(base, P_CTRL(pipe), P_LOCK_GROUP, param->lock_group); SPS_DBG("sps:bam=0x%x(va).pipe=%d.lock_group=%d.\n", (u32) base, pipe, param->lock_group); #endif if (param->mode == BAM_PIPE_MODE_BAM2BAM) { u32 peer_dest_addr = param->peer_phys_addr + P_EVNT_REG(param->peer_pipe); bam_write_reg(base, P_DATA_FIFO_ADDR(pipe), param->data_base); bam_write_reg_field(base, P_FIFO_SIZES(pipe), P_DATA_FIFO_SIZE, param->data_size); bam_write_reg(base, P_EVNT_DEST_ADDR(pipe), peer_dest_addr); SPS_DBG2("sps:bam=0x%x(va).pipe=%d.peer_bam=0x%x." "peer_pipe=%d.\n", (u32) base, pipe, (u32) param->peer_phys_addr, param->peer_pipe); #ifdef CONFIG_SPS_SUPPORT_NDP_BAM bam_write_reg_field(base, P_CTRL(pipe), P_WRITE_NWD, param->write_nwd); SPS_DBG("sps:%s WRITE_NWD bit for this bam2bam pipe.", param->write_nwd ? "Set" : "Do not set"); #endif } /* Pipe Enable - at last */ bam_write_reg_field(base, P_CTRL(pipe), P_EN, 1); return 0; }
/** * Configure interrupt for a BAM pipe * */ void bam_pipe_set_irq(void *base, u32 pipe, enum bam_enable irq_en, u32 src_mask, u32 ee) { bam_write_reg(base, P_IRQ_EN(pipe), src_mask); bam_write_reg_field(base, IRQ_SRCS_MSK_EE(ee), (1 << pipe), irq_en); }
/** * Diasble a BAM pipe * */ void bam_pipe_disable(void *base, u32 pipe) { bam_write_reg_field(base, P_CTRL(pipe), P_EN, 0); }
/** * Diasble a BAM pipe * */ void bam_pipe_disable(void *base, u32 pipe) { SPS_DBG2("sps:%s:bam=0x%x(va).pipe=%d.", __func__, (u32) base, pipe); bam_write_reg_field(base, P_CTRL(pipe), P_EN, 0); }
/** * Initialize a BAM device * */ int bam_init(void *base, u32 ee, u16 summing_threshold, u32 irq_mask, u32 *version, u32 *num_pipes, u32 p_rst) { u32 cfg_bits; u32 ver = 0; SPS_DBG2("sps:%s:bam=0x%x(va).ee=%d.", __func__, (u32) base, ee); ver = bam_read_reg_field(base, REVISION, BAM_REVISION); if ((ver < BAM_MIN_VERSION) || (ver > BAM_MAX_VERSION)) { SPS_ERR("sps:bam 0x%x(va) Invalid BAM REVISION 0x%x.\n", (u32) base, ver); return -ENODEV; } else SPS_DBG2("sps:REVISION of BAM 0x%x is 0x%x.\n", (u32) base, ver); if (summing_threshold == 0) { summing_threshold = 4; SPS_ERR("sps:bam 0x%x(va) summing_threshold is zero , " "use default 4.\n", (u32) base); } if (p_rst) cfg_bits = 0xffffffff & ~(3 << 11); else cfg_bits = 0xffffffff & ~(1 << 11); bam_write_reg_field(base, CTRL, BAM_SW_RST, 1); /* No delay needed */ bam_write_reg_field(base, CTRL, BAM_SW_RST, 0); bam_write_reg_field(base, CTRL, BAM_EN, 1); #ifdef CONFIG_SPS_SUPPORT_NDP_BAM bam_write_reg_field(base, CTRL, CACHE_MISS_ERR_RESP_EN, 1); bam_write_reg_field(base, CTRL, LOCAL_CLK_GATING, 1); #endif bam_write_reg(base, DESC_CNT_TRSHLD, summing_threshold); bam_write_reg(base, CNFG_BITS, cfg_bits); /* * Enable Global BAM Interrupt - for error reasons , * filter with mask. * Note: Pipes interrupts are disabled until BAM_P_IRQ_enn is set */ bam_write_reg_field(base, IRQ_SRCS_MSK_EE(ee), BAM_IRQ, 1); bam_write_reg(base, IRQ_EN, irq_mask); *num_pipes = bam_read_reg_field(base, NUM_PIPES, BAM_NUM_PIPES); *version = ver; return 0; }
/** * Set the pipe execution environment * * @base - BAM virtual base address * * @pipe - pipe index * * @ee - BAM execution environment index * * @vmid - virtual master identifier */ static void bam_pipe_set_ee(void *base, u32 pipe, u32 ee, u32 vmid) { bam_write_reg_field(base, P_TRUST_REG(pipe), BAM_P_EE, ee); bam_write_reg_field(base, P_TRUST_REG(pipe), BAM_P_VMID, vmid); }