Commit 581fe424 authored by Mikhail Karpenko's avatar Mikhail Karpenko
Browse files

Add multichannel support to quantization_tables.c, fix formatting

parent aca0c9b9
Loading
Loading
Loading
Loading
+11 −11
Original line number Original line Diff line number Diff line
@@ -95,14 +95,14 @@ int init_ccam_dma_buf_ptr(struct platform_device *pdev)
	if (pElphel_buf != NULL) {
	if (pElphel_buf != NULL) {
		ccam_dma_buf_ptr = pElphel_buf->vaddr;
		ccam_dma_buf_ptr = pElphel_buf->vaddr;
		dma_handle = pElphel_buf->paddr;
		dma_handle = pElphel_buf->paddr;
		dev_info(dev, "using %d bytes of DMA memory from pElphel_buf at address 0x%08p", pElphel_buf->size * PAGE_SIZE, dma_handle);
		dev_info(dev, "using %lu bytes of DMA memory from pElphel_buf at address 0x%08x", pElphel_buf->size * PAGE_SIZE, dma_handle);
	} else {
	} else {
		ccam_dma_buf_ptr = dmam_alloc_coherent(dev, dma_size, &dma_handle, GFP_KERNEL);
		ccam_dma_buf_ptr = dmam_alloc_coherent(dev, dma_size, &dma_handle, GFP_KERNEL);
		if (!ccam_dma_buf_ptr) {
		if (!ccam_dma_buf_ptr) {
			dev_err(dev, "unable to allocate DMA buffer\n");
			dev_err(dev, "unable to allocate DMA buffer\n");
			return -ENOMEM;
			return -ENOMEM;
		} else {
		} else {
			dev_info(dev, "%d bytes of DMA memory allocated at address 0x%08p", dma_size , dma_handle);
			dev_info(dev, "%d bytes of DMA memory allocated at address 0x%08x", dma_size , dma_handle);
		}
		}
	}
	}


@@ -263,7 +263,7 @@ unsigned int circbuf_all_poll (struct file *file, poll_table *wait)
int circbuf_open(struct inode *inode, struct file *filp)
int circbuf_open(struct inode *inode, struct file *filp)
{
{
	inode->i_size = CCAM_DMA_SIZE;
	inode->i_size = CCAM_DMA_SIZE;
	dev_dbg(g_dev_ptr, "inode->i_size = 0x%x\n");
	dev_dbg(g_dev_ptr, "inode->i_size = 0x%x\n", inode->i_size);


	return 0;
	return 0;
}
}
@@ -286,7 +286,7 @@ unsigned long get_image_length(int byte_offset, unsigned int chn, int *last_chun
		last_image_chunk += CCAM_DMA_SIZE;
		last_image_chunk += CCAM_DMA_SIZE;
	len32 = circbuf_priv[chn].buf_ptr[BYTE2DW(last_image_chunk + (CHUNK_SIZE - CCAM_MMAP_META_LENGTH))];
	len32 = circbuf_priv[chn].buf_ptr[BYTE2DW(last_image_chunk + (CHUNK_SIZE - CCAM_MMAP_META_LENGTH))];


	dev_dbg(g_dev_ptr, "got len32 = 0x%x at 0x%x\n", len32, last_image_chunk + (CHUNK_SIZE - CCAM_MMAP_META_LENGTH));
	dev_dbg(g_dev_ptr, "got len32 = 0x%lx at 0x%x\n", len32, last_image_chunk + (CHUNK_SIZE - CCAM_MMAP_META_LENGTH));


	if (last_chunk_offset != NULL)
	if (last_chunk_offset != NULL)
		*last_chunk_offset = last_image_chunk;
		*last_chunk_offset = last_image_chunk;
@@ -481,13 +481,13 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
				file->f_pos = img_start;
				file->f_pos = img_start;
				break;
				break;
			case LSEEK_CIRC_NEXT:
			case LSEEK_CIRC_NEXT:
				dev_dbg(g_dev_ptr, "LSEEK_CIRC_NEXT: file->f_pos = 0x%x, fvld = %d, fp->len32 = 0x%x\n", file->f_pos, fvld, fp->frame_length);
				dev_dbg(g_dev_ptr, "LSEEK_CIRC_NEXT: file->f_pos = 0x%lx, fvld = %d, fp->len32 = 0x%lx\n", file->f_pos, fvld, fp->frame_length);
				if (fvld <= 0)
				if (fvld <= 0)
					return -EOVERFLOW; //! no frames after current
					return -EOVERFLOW; //! no frames after current
				// calculate the full length of current frame and advance file pointer by this value
				// calculate the full length of current frame and advance file pointer by this value
				padded_frame = fp->frame_length + INSERTED_BYTES(fp->frame_length) + CHUNK_SIZE + CCAM_MMAP_META;
				padded_frame = fp->frame_length + INSERTED_BYTES(fp->frame_length) + CHUNK_SIZE + CCAM_MMAP_META;
				file->f_pos = X393_BUFFADD(file->f_pos, padded_frame); // do it even if the next frame does not yet exist
				file->f_pos = X393_BUFFADD(file->f_pos, padded_frame); // do it even if the next frame does not yet exist
				dev_dbg(g_dev_ptr, "LSEEK_CIRC_NEXT: moving file->f_pos to 0x%x\n", file->f_pos);
				dev_dbg(g_dev_ptr, "LSEEK_CIRC_NEXT: moving file->f_pos to 0x%llx\n", file->f_pos);
				break;
				break;
			case LSEEK_CIRC_FIRST:
			case LSEEK_CIRC_FIRST:
			case LSEEK_CIRC_SCND:
			case LSEEK_CIRC_SCND:
@@ -503,7 +503,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
					nf++;
					nf++;
					preprev_p = prev_p; // second known good (at least first one)
					preprev_p = prev_p; // second known good (at least first one)
					prev_p=rp;          // now - current, known good
					prev_p=rp;          // now - current, known good
					len32 = get_image_length(DW2BYTE(rp), chn, last_image_chunk);
					len32 = get_image_length(DW2BYTE(rp), chn, &last_image_chunk);
					dev_dbg(g_dev_ptr, "LSEEK_CIRC_FIRST or LSEEK_CIRC_SCND: number of frames = %d, rp = 0x%x, fvld = %d, len32 = 0x%x", nf, rp, fvld, len32);
					dev_dbg(g_dev_ptr, "LSEEK_CIRC_FIRST or LSEEK_CIRC_SCND: number of frames = %d, rp = 0x%x, fvld = %d, len32 = 0x%x", nf, rp, fvld, len32);
					if ((len32 & MARKER_FF) != MARKER_FF ) break;  //! no frames before rp (==prev_p)
					if ((len32 & MARKER_FF) != MARKER_FF ) break;  //! no frames before rp (==prev_p)
					//! move rp to the previous frame
					//! move rp to the previous frame
@@ -519,7 +519,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
				break;
				break;
			}
			}
			case LSEEK_CIRC_SETP:
			case LSEEK_CIRC_SETP:
				dev_dbg(g_dev_ptr, "LSEK_CIRC_SETP: Setting jpeg_rp for channel %d to file->f_pos = 0x%x\n", chn, file->f_pos);
				dev_dbg(g_dev_ptr, "LSEK_CIRC_SETP: Setting jpeg_rp for channel %d to file->f_pos = 0x%llx\n", chn, file->f_pos);
				camseq_set_jpeg_rp(chn, file->f_pos >> 2);
				camseq_set_jpeg_rp(chn, file->f_pos >> 2);
				break;
				break;
			case LSEEK_CIRC_VALID:
			case LSEEK_CIRC_VALID:
@@ -569,7 +569,7 @@ ssize_t circbuf_write(struct file *file, const char *buf, size_t count, loff_t *
	unsigned long p;
	unsigned long p;
	unsigned int minor = MINOR(file->f_inode->i_rdev);
	unsigned int minor = MINOR(file->f_inode->i_rdev);
	unsigned int chn = minor_to_chn(minor, NULL);
	unsigned int chn = minor_to_chn(minor, NULL);
	dev_dbg(g_dev_ptr, "minor = 0x%x, count = 0x%x, off = 0x%x", minor, count, off);
	dev_dbg(g_dev_ptr, "minor = 0x%x, count = 0x%x, off = 0x%llx", minor, count, off);


	/* debug code follows*/
	/* debug code follows*/
	switch (buf[0] - 0x30) {
	switch (buf[0] - 0x30) {
@@ -609,7 +609,7 @@ ssize_t circbuf_read(struct file *file, char *buf, size_t count, loff_t *off)
	unsigned long p;
	unsigned long p;
	unsigned int minor = MINOR(file->f_inode->i_rdev);
	unsigned int minor = MINOR(file->f_inode->i_rdev);
	unsigned int chn = minor_to_chn(minor, NULL);
	unsigned int chn = minor_to_chn(minor, NULL);
	dev_dbg(g_dev_ptr, "minor = 0x%x, count = 0x%x, off = 0x%x", minor, count, off);
	dev_dbg(g_dev_ptr, "minor = 0x%x, count = 0x%x, off = 0x%llx", minor, count, off);


	p = *off;
	p = *off;
	if (p >= CCAM_DMA_SIZE)
	if (p >= CCAM_DMA_SIZE)
@@ -674,7 +674,7 @@ unsigned int circbuf_poll (struct file *file, poll_table *wait)
	rslt = circbuf_valid_ptr(file->f_pos, &fp, chn);
	rslt = circbuf_valid_ptr(file->f_pos, &fp, chn);
	if (rslt < 0) {
	if (rslt < 0) {
		// not a valid read pointer, probable buffer overrun
		// not a valid read pointer, probable buffer overrun
		dev_dbg(g_dev_ptr, "invalid pointer file->f_pos = 0x%x\n", file->f_pos);
		dev_dbg(g_dev_ptr, "invalid pointer file->f_pos = 0x%llx\n", file->f_pos);
		return  POLLHUP ;
		return  POLLHUP ;
	} else if (rslt > 0) {
	} else if (rslt > 0) {
		return POLLIN | POLLRDNORM; //! there was frame already available
		return POLLIN | POLLRDNORM; //! there was frame already available
+20 −6
Original line number Original line Diff line number Diff line
@@ -104,12 +104,13 @@ static struct jpeghead_priv_t {
 * @brief Copy two quantization tables for the current frame (for the RTP streamer)
 * @brief Copy two quantization tables for the current frame (for the RTP streamer)
 * @param[in]   params   pointer to an array of parameters stored for the frame
 * @param[in]   params   pointer to an array of parameters stored for the frame
 * @param[out]  buf      buffer to put the header to
 * @param[out]  buf      buffer to put the header to
 * @param[in]   chn      compressor channel number
 * @return      header length if successful, < 0 - error
 * @return      header length if successful, < 0 - error
 */
 */
int qtables_create(struct interframe_params_t *params, unsigned char *buf)
int qtables_create(struct interframe_params_t *params, unsigned char *buf, unsigned int chn)
{
{
	dev_dbg(g_dev_ptr, "params->quality2 = 0x%x\n", params->quality2);
	dev_dbg(g_dev_ptr, "params->quality2 = 0x%x\n", params->quality2);
	int rslt = get_qtable(params->quality2, &buf[0], &buf[64]); /// will copy both quantization tables
	int rslt = get_qtable(params->quality2, &buf[0], &buf[64], chn); /// will copy both quantization tables
	if (rslt < 0) return rslt; /// bad quality table
	if (rslt < 0) return rslt; /// bad quality table
	return 128;
	return 128;
}
}
@@ -192,16 +193,16 @@ int jpegheader_create(struct interframe_params_t *params, unsigned char *buf, un
			0x07, 0x11};
			0x07, 0x11};


	struct huff_tables_t *huff_tables = &jpeghead_priv[chn].huff_tables;
	struct huff_tables_t *huff_tables = &jpeghead_priv[chn].huff_tables;
	unsigned char *p = (unsigned char *)params;


	if (buf==NULL) return -1; /// buffer is not provided
	if (buf==NULL) return -1; /// buffer is not provided


	unsigned char *p = (char *)params;
	dev_dbg(g_dev_ptr, "list of parameters:\n");
	dev_dbg(g_dev_ptr, "list of parameters:\n");
	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p, 32);
	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p, 32);


	memcpy((void *) &buf[0],                 (void *) jfif1, sizeof (jfif1)); /// including DQT0 header
	memcpy((void *) &buf[0],                 (void *) jfif1, sizeof (jfif1)); /// including DQT0 header
	memcpy((void *) &buf[header_cqtable_hd], (void *) jfif2, sizeof (jfif2)); /// DQT1 header
	memcpy((void *) &buf[header_cqtable_hd], (void *) jfif2, sizeof (jfif2)); /// DQT1 header
	rslt=get_qtable(params->quality2, &buf[header_yqtable], &buf[header_cqtable]); /// will copy both quantization tables
	rslt=get_qtable(params->quality2, &buf[header_yqtable], &buf[header_cqtable], chn); /// will copy both quantization tables
	if (rslt <0) return rslt; /// bad quality table
	if (rslt <0) return rslt; /// bad quality table
	bp=header_sof;
	bp=header_sof;
	buf[bp++]=0xff; buf[bp++]=0xc0;
	buf[bp++]=0xff; buf[bp++]=0xc0;
@@ -364,7 +365,7 @@ loff_t jpeghead_lseek(struct file *file, loff_t offset, int orig,
			if ((fp->signffff != MARKER_FFFF) || // signature is overwritten
			if ((fp->signffff != MARKER_FFFF) || // signature is overwritten
					((fp->timestamp_sec) & X313_LENGTH_MASK)) return -EINVAL; //! acquisition of this frame is not done yet - length word high byte is non-zero
					((fp->timestamp_sec) & X313_LENGTH_MASK)) return -EINVAL; //! acquisition of this frame is not done yet - length word high byte is non-zero
			if ((offset & 0x1f) == 0x2)
			if ((offset & 0x1f) == 0x2)
				jpeghead_priv[chn].jpeg_h_sz = qtables_create(fp, jpeghead_priv[chn].header);  /// just qunatization tables (128 bytes) - for the streamer
				jpeghead_priv[chn].jpeg_h_sz = qtables_create(fp, jpeghead_priv[chn].header, chn);  /// just qunatization tables (128 bytes) - for the streamer
			else
			else
				jpeghead_priv[chn].jpeg_h_sz = jpegheader_create(fp, jpeghead_priv[chn].header, chn); /// full JPEG header
				jpeghead_priv[chn].jpeg_h_sz = jpegheader_create(fp, jpeghead_priv[chn].header, chn); /// full JPEG header
			if (jpeghead_priv[chn].jpeg_h_sz < 0) {
			if (jpeghead_priv[chn].jpeg_h_sz < 0) {
@@ -669,20 +670,23 @@ int jpeg_htable_is_programmed(unsigned int chn)
/**
/**
 * @brief program FPGA Huffman table (fram static array)
 * @brief program FPGA Huffman table (fram static array)
 * @param[in]   chn   compressor channel number
 * @param[in]   chn   compressor channel number
 * return none
 * @return none
 */
 */
void jpeg_htable_fpga_pgm(unsigned int chn)
void jpeg_htable_fpga_pgm(unsigned int chn)
{
{
	int i;
	int i;
	unsigned long flags;
	x393_cmprs_table_addr_t table_addr;
	x393_cmprs_table_addr_t table_addr;
	struct huff_tables_t *huff_tables = &jpeghead_priv[chn].huff_tables;
	struct huff_tables_t *huff_tables = &jpeghead_priv[chn].huff_tables;


	table_addr.addr32 = 0;
	table_addr.addr32 = 0;
	table_addr.type = 3;
	table_addr.type = 3;
	local_irq_save(flags);
	x393_cmprs_tables_address(table_addr, chn);
	x393_cmprs_tables_address(table_addr, chn);
	for (i = 0; i < sizeof(huff_tables->fpga_huffman_table); i++) {
	for (i = 0; i < sizeof(huff_tables->fpga_huffman_table); i++) {
		x393_cmprs_tables_data((u32)huff_tables->fpga_huffman_table[i], chn);
		x393_cmprs_tables_data((u32)huff_tables->fpga_huffman_table[i], chn);
	}
	}
	local_irq_restore(flags);
	jpeghead_priv[chn].fpga_programmed = 1;
	jpeghead_priv[chn].fpga_programmed = 1;
}
}


@@ -749,5 +753,15 @@ int jpeghead_init(struct platform_device *pdev)
		jpeg_htable_init(i);
		jpeg_htable_init(i);
	}
	}


	qt_init(pdev);
	dev_dbg(g_dev_ptr, "reset quantization tables\n");
	// force initialization at next access
	if (get_cache_policy() == COMMON_CACHE) {
		reset_qtables(0);
	} else if (get_cache_policy() == PER_CHN_CACHE) {
		for (i = 0; i < IMAGE_CHN_NUM; i++)
			reset_qtables(i);
	}

	return 0;
	return 0;
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -9,7 +9,7 @@ struct huffman_fpga_code_t {
  unsigned short value;       /// code value
  unsigned short value;       /// code value
  unsigned short length;      /// code length
  unsigned short length;      /// code length
};
};
int     qtables_create  (struct interframe_params_t * params, unsigned char * buf);
int     qtables_create  (struct interframe_params_t * params, unsigned char * buf, unsigned int chn);
int     jpegheader_create(struct interframe_params_t * params, unsigned char * buf, unsigned int chn);
int     jpegheader_create(struct interframe_params_t * params, unsigned char * buf, unsigned int chn);
int     jpeghead_open   (struct inode *inode, struct file *filp); // set filesize
int     jpeghead_open   (struct inode *inode, struct file *filp); // set filesize
loff_t  jpeghead_lseek  (struct file * file, loff_t offset, int orig, struct interframe_params_t *fp);
loff_t  jpeghead_lseek  (struct file * file, loff_t offset, int orig, struct interframe_params_t *fp);
Loading