/* * This function is called to initialize a buffer for logical IPU channel. * * @param channel Input parameter for the logical channel ID. * * @param type Input parameter which buffer to initialize. * * @param pixel_fmt Input parameter for pixel format of buffer. * Pixel format is a FOURCC ASCII code. * * @param width Input parameter for width of buffer in pixels. * * @param height Input parameter for height of buffer in pixels. * * @param stride Input parameter for stride length of buffer * in pixels. * * @param phyaddr_0 Input parameter buffer 0 physical address. * * @param phyaddr_1 Input parameter buffer 1 physical address. * Setting this to a value other than NULL enables * double buffering mode. * * @param u private u offset for additional cropping, * zero if not used. * * @param v private v offset for additional cropping, * zero if not used. * * @return Returns 0 on success or negative error code on fail */ int32_t ipu_init_channel_buffer(ipu_channel_t channel, ipu_buffer_t type, uint32_t pixel_fmt, uint16_t width, uint16_t height, uint32_t stride, dma_addr_t phyaddr_0, dma_addr_t phyaddr_1, uint32_t u, uint32_t v) { uint32_t reg; uint32_t dma_chan; dma_chan = channel_2_dma(channel, type); if (!idma_is_valid(dma_chan)) return -EINVAL; if (stride < width * bytes_per_pixel(pixel_fmt)) stride = width * bytes_per_pixel(pixel_fmt); if (stride % 4) { printf( "Stride not 32-bit aligned, stride = %d\n", stride); return -EINVAL; } /* Build parameter memory data for DMA channel */ ipu_ch_param_init(dma_chan, pixel_fmt, width, height, stride, u, v, 0, phyaddr_0, phyaddr_1); if (ipu_is_dmfc_chan(dma_chan)) { ipu_dmfc_set_wait4eot(dma_chan, width); } if (idma_is_set(IDMAC_CHA_PRI, dma_chan)) ipu_ch_param_set_high_priority(dma_chan); ipu_ch_param_dump(dma_chan); reg = __raw_readl(IPU_CHA_DB_MODE_SEL(dma_chan)); if (phyaddr_1) reg |= idma_mask(dma_chan); else reg &= ~idma_mask(dma_chan); __raw_writel(reg, IPU_CHA_DB_MODE_SEL(dma_chan)); /* Reset to buffer 0 */ __raw_writel(idma_mask(dma_chan), IPU_CHA_CUR_BUF(dma_chan)); return 0; }
/* * This function is called to initialize a buffer for logical IPU channel. * * @param channel Input parameter for the logical channel ID. * * @param type Input parameter which buffer to initialize. * * @param pixel_fmt Input parameter for pixel format of buffer. * Pixel format is a FOURCC ASCII code. * * @param width Input parameter for width of buffer in pixels. * * @param height Input parameter for height of buffer in pixels. * * @param stride Input parameter for stride length of buffer * in pixels. * * @param phyaddr_0 Input parameter buffer 0 physical address. * * @param phyaddr_1 Input parameter buffer 1 physical address. * Setting this to a value other than NULL enables * double buffering mode. * * @param u private u offset for additional cropping, * zero if not used. * * @param v private v offset for additional cropping, * zero if not used. * * @return Returns 0 on success or negative error code on fail */ int32_t ipu_init_channel_buffer(ipu_channel_t channel, ipu_buffer_t type, uint32_t pixel_fmt, uint16_t width, uint16_t height, uint32_t stride, dma_addr_t phyaddr_0, dma_addr_t phyaddr_1, uint32_t u, uint32_t v) { uint32_t reg; uint32_t dma_chan; uint32_t burst_size; static int once = 0; if(IPU_CHAN_ID(channel) == 19){ if (once == 0){ once++; }else{ printf("ipu_init_channel_buffer fake reinit\n"); return 0; } } //printf("ipu_init_channel_buffer: channel: %d, type: %d, pixel_fmt: 0x%x, width: %d, height: %d, stride: %d, phyaddr_0: 0x%x, phyaddr_1: 0x%x, u: 0x%x, v: 0x%x\r\n", // IPU_CHAN_ID(channel), type, pixel_fmt, width, height,stride, phyaddr_0, phyaddr_1, u,v); dma_chan = channel_2_dma(channel, type); if (!idma_is_valid(dma_chan)) return -EINVAL; if (stride < width * bytes_per_pixel(pixel_fmt)){ stride = width * bytes_per_pixel(pixel_fmt); // printf("stride is update with bpp: 0x%x\n", bytes_per_pixel(pixel_fmt)); } if (stride % 4) { printf( "Stride not 32-bit aligned, stride = %d\n", stride); return -EINVAL; } /* Build parameter memory data for DMA channel */ ipu_ch_param_init(dma_chan, pixel_fmt, width, height, stride, u, v, 0, phyaddr_0, phyaddr_1); if (ipu_is_dmfc_chan(dma_chan)) { burst_size = _ipu_ch_param_get_burst_size(dma_chan); //printf("burst_size: 0x%x\n", burst_size); ipu_dmfc_set_wait4eot(dma_chan, width); ipu_dmfc_set_burst_size(dma_chan, burst_size); } /* IC and ROT channels have restriction of 8 or 16 pix burst length */ if (_ipu_is_ic_chan(dma_chan)) { if ((width % 16) == 0) _ipu_ch_param_set_burst_size(dma_chan, 16); else _ipu_ch_param_set_burst_size(dma_chan, 8); } if (_ipu_is_ic_chan(dma_chan) ) { burst_size = _ipu_ch_param_get_burst_size(dma_chan); _ipu_ic_idma_init(dma_chan, width, height, burst_size); } else if (_ipu_is_smfc_chan(dma_chan)) { burst_size = _ipu_ch_param_get_burst_size(dma_chan); if ((pixel_fmt == IPU_PIX_FMT_GENERIC) && ((_ipu_ch_param_get_bpp(dma_chan) == 5) || (_ipu_ch_param_get_bpp(dma_chan) == 3))) burst_size = burst_size >> 4; else burst_size = burst_size >> 2; _ipu_smfc_set_burst_size(channel, burst_size-1); }