/* * This function disables a logical channel. * * @param channel Input parameter for the logical channel ID. * * @param wait_for_stop Flag to set whether to wait for channel end * of frame or return immediately. * * @return This function returns 0 on success or negative error code on * fail. */ int32_t ipu_disable_channel(ipu_channel_t channel) { uint32_t reg; uint32_t in_dma; uint32_t out_dma; if ((g_channel_enable_mask & (1L << IPU_CHAN_ID(channel))) == 0) { debug("Channel already disabled %d\n", IPU_CHAN_ID(channel)); return 0; } /* Get input and output dma channels */ out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER); in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER); if ((idma_is_valid(in_dma) && !idma_is_set(IDMAC_CHA_EN, in_dma)) && (idma_is_valid(out_dma) && !idma_is_set(IDMAC_CHA_EN, out_dma))) return -EINVAL; if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) || (channel == MEM_DC_SYNC)) { ipu_dp_dc_disable(channel, 0); } /* Disable DMA channel(s) */ if (idma_is_valid(in_dma)) { reg = __raw_readl(IDMAC_CHA_EN(in_dma)); __raw_writel(reg & ~idma_mask(in_dma), IDMAC_CHA_EN(in_dma)); __raw_writel(idma_mask(in_dma), IPU_CHA_CUR_BUF(in_dma)); } if (idma_is_valid(out_dma)) { reg = __raw_readl(IDMAC_CHA_EN(out_dma)); __raw_writel(reg & ~idma_mask(out_dma), IDMAC_CHA_EN(out_dma)); __raw_writel(idma_mask(out_dma), IPU_CHA_CUR_BUF(out_dma)); } g_channel_enable_mask &= ~(1L << IPU_CHAN_ID(channel)); /* Set channel buffers NOT to be ready */ if (idma_is_valid(in_dma)) { ipu_clear_buffer_ready(channel, IPU_VIDEO_IN_BUFFER, 0); ipu_clear_buffer_ready(channel, IPU_VIDEO_IN_BUFFER, 1); } if (idma_is_valid(out_dma)) { ipu_clear_buffer_ready(channel, IPU_OUTPUT_BUFFER, 0); ipu_clear_buffer_ready(channel, IPU_OUTPUT_BUFFER, 1); } return 0; }
/*! * function to update physical buffer address for encorder IDMA channel * * @param eba physical buffer address for encorder IDMA channel * @param buffer_num int buffer 0 or buffer 1 * * @return status */ static int prp_enc_eba_update(dma_addr_t eba, int *buffer_num) { int err = 0; pr_debug("eba %x\n", eba); if (grotation >= IPU_ROTATE_90_RIGHT) { err = ipu_update_channel_buffer(MEM_ROT_ENC_MEM, IPU_OUTPUT_BUFFER, *buffer_num, eba); } else { err = ipu_update_channel_buffer(CSI_PRP_ENC_MEM, IPU_OUTPUT_BUFFER, *buffer_num, eba); } if (err != 0) { if (grotation >= IPU_ROTATE_90_RIGHT) { ipu_clear_buffer_ready(MEM_ROT_ENC_MEM, IPU_OUTPUT_BUFFER, *buffer_num); err = ipu_update_channel_buffer(MEM_ROT_ENC_MEM, IPU_OUTPUT_BUFFER, *buffer_num, eba); } else { ipu_clear_buffer_ready(CSI_PRP_ENC_MEM, IPU_OUTPUT_BUFFER, *buffer_num); err = ipu_update_channel_buffer(CSI_PRP_ENC_MEM, IPU_OUTPUT_BUFFER, *buffer_num, eba); } if (err != 0) { pr_err("ERROR: v4l2 capture: fail to update " "buf%d\n", *buffer_num); return err; } } if (grotation >= IPU_ROTATE_90_RIGHT) { ipu_select_buffer(MEM_ROT_ENC_MEM, IPU_OUTPUT_BUFFER, *buffer_num); } else { ipu_select_buffer(CSI_PRP_ENC_MEM, IPU_OUTPUT_BUFFER, *buffer_num); } *buffer_num = (*buffer_num == 0) ? 1 : 0; return 0; }
/*! * function to update physical buffer address for encorder IDMA channel * * @param eba physical buffer address for encorder IDMA channel * @param buffer_num int buffer 0 or buffer 1 * * @return status */ static int csi_enc_eba_update(struct ipu_soc *ipu, dma_addr_t eba, int *buffer_num) { int err = 0; pr_debug("eba %x\n", eba); err = ipu_update_channel_buffer(ipu, CSI_MEM, IPU_OUTPUT_BUFFER, *buffer_num, eba); if (err != 0) { ipu_clear_buffer_ready(ipu, CSI_MEM, IPU_OUTPUT_BUFFER, *buffer_num); err = ipu_update_channel_buffer(ipu, CSI_MEM, IPU_OUTPUT_BUFFER, *buffer_num, eba); if (err != 0) { pr_err("ERROR: v4l2 capture: fail to update " "buf%d\n", *buffer_num); return err; } } ipu_select_buffer(ipu, CSI_MEM, IPU_OUTPUT_BUFFER, *buffer_num); *buffer_num = (*buffer_num == 0) ? 1 : 0; return 0; }
/*! * function to update physical buffer address for encorder IDMA channel * * @param eba physical buffer address for encorder IDMA channel * @param buffer_num int buffer 0 or buffer 1 * * @return status */ static int csi_enc_eba_update(dma_addr_t eba, int *buffer_num) { int err = 0; pr_debug("eba %x\n", eba); err = ipu_update_channel_buffer(CSI_MEM, IPU_OUTPUT_BUFFER, *buffer_num, eba); if (err != 0) { ipu_clear_buffer_ready(CSI_MEM, IPU_OUTPUT_BUFFER, *buffer_num); printk(KERN_ERR "err %d buffer_num %d\n", err, *buffer_num); return err; } ipu_select_buffer(CSI_MEM, IPU_OUTPUT_BUFFER, *buffer_num); *buffer_num = (*buffer_num == 0) ? 1 : 0; return 0; }
/*! * function to update physical buffer address for encorder IDMA channel * * @param eba physical buffer address for encorder IDMA channel * @param buffer_num int buffer 0 or buffer 1 * * @return status */ static int csi_enc_eba_update(dma_addr_t eba, int *buffer_num) { int err = 0; //printf("csi_enc_eba_update, addr: 0x%x, buffer_num: %d\n", eba, *buffer_num); err = ipu_update_channel_buffer(CSI_MEM, IPU_OUTPUT_BUFFER, *buffer_num, eba); if (err != 0) { ipu_clear_buffer_ready(CSI_MEM, IPU_OUTPUT_BUFFER, *buffer_num); err = ipu_update_channel_buffer(CSI_MEM, IPU_OUTPUT_BUFFER, *buffer_num, eba); if (err != 0) { printf("ERROR: v4l2 capture: fail to update buf %d\n", *buffer_num); return err; } } ipu_select_buffer(CSI_MEM, IPU_OUTPUT_BUFFER, *buffer_num); *buffer_num = (*buffer_num == 0) ? 1 : 0; return 0; }