示例#1
0
/*
 * 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;
}
示例#2
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;
}
示例#3
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;
}
示例#4
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;
}
示例#5
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;
}