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

Add multichannel support to quantization_tables.c, fix formatting

parent aca0c9b9
...@@ -95,14 +95,14 @@ int init_ccam_dma_buf_ptr(struct platform_device *pdev) ...@@ -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) ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 * ...@@ -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) ...@@ -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) ...@@ -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
......
...@@ -104,12 +104,13 @@ static struct jpeghead_priv_t { ...@@ -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 ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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;
} }
...@@ -9,7 +9,7 @@ struct huffman_fpga_code_t { ...@@ -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);
......
This diff is collapsed.
/// @file quantization_tables.h /// @file quantization_tables.h
#ifndef _QUANTIZATION_TABLES_H #ifndef _QUANTIZATION_TABLES_H
#define _QUANTIZATION_TABLES_H #define _QUANTIZATION_TABLES_H
/** @brief Quantization tables cache usage policy */
enum {
// @brief Use common cache for all compressors
COMMON_CACHE = 0,
// @brief Use separate cache for each compressor
PER_CHN_CACHE
};
/** /**
* @brief initialization of quantization tables (direct - JPEG header ones) cache * @brief initialization of quantization tables (direct - JPEG header ones) cache
* \n TODO: add \b init_qtable_head_cache to module initialization * \n TODO: add \b init_qtable_head_cache to module initialization
*
* used in quantization_tables.c only
*/ */
void init_qtable_head_cache(void); void init_qtable_head_cache(unsigned int chn);
/** /**
* @brief calculates a pair of direct (JPEG header) tables for the specified quality (2-bytes ) * @brief calculates a pair of direct (JPEG header) tables for the specified quality (2-bytes )
* @param quality2 single byte (standard) or a pair of bytes (see file header description) * @param quality2 single byte (standard) or a pair of bytes (see file header description)
* @param y_tab caller-provided pointer to a 64-byte Y (intensity) quantization table (NULL - don't copy) * @param y_tab caller-provided pointer to a 64-byte Y (intensity) quantization table (NULL - don't copy)
* @param c_tab caller-provided pointer to a 64-byte C (color) quantization table (NULL - don't copy) * @param c_tab caller-provided pointer to a 64-byte C (color) quantization table (NULL - don't copy)
* @return 0 - cache hit, 1 - cache miss (recalculated), -1 - invalid quality * @return 0 - cache hit, 1 - cache miss (recalculated), -1 - invalid quality
*
* used in quantization_tables.c and jpeghead.c
*/ */
int get_qtable(int quality2, unsigned char *y_tab, unsigned char *c_tab); int get_qtable(int quality2, unsigned char *y_tab, unsigned char *c_tab, unsigned int chn);
/** /**
* @brief initialization of quantization tables (reverse, for the FPGA) cache * @brief initialization of quantization tables (reverse, for the FPGA) cache
* \n TODO: add \b init_qtable_fpga to module initialization * \n TODO: add \b init_qtable_fpga to module initialization
*
* used in quantization_tables.c only
*/ */
void init_qtable_fpga(void); void init_qtable_fpga(unsigned int chn);
/** /**
* @brief Finds an already programmed FPGA page or calculates (an programms FPGA with) a new one * @brief Finds an already programmed FPGA page or calculates (an programms FPGA with) a new one
* @param quality2 single byte (standard) or a pair of bytes (see file header description) * @param quality2 single byte (standard) or a pair of bytes (see file header description)
* @return table page number used (0..7) or -1 - invalid q * @return table page number used (0..7) or -1 - invalid q
*
* used in quantization_table.c and pgm_functions.c
*/ */
int set_qtable_fpga(int quality2); int set_qtable_fpga(int quality2, unsigned int chn);
/** /**
* @brief Temporary function to directly set one of the coring LUTs (currently 100 0.0 to 9.9 with 0.1 step) * @brief Temporary function to directly set one of the coring LUTs (currently 100 0.0 to 9.9 with 0.1 step)
...@@ -32,10 +49,14 @@ int set_qtable_fpga(int quality2); ...@@ -32,10 +49,14 @@ int set_qtable_fpga(int quality2);
* @param coring_number 0..99 - function number * @param coring_number 0..99 - function number
* @param fpga_number 0.. 15 - fpga table number * @param fpga_number 0.. 15 - fpga table number
* @return table page number used (0..7) or -1 - invalid q * @return table page number used (0..7) or -1 - invalid q
*
* used in quantization_table.c and pgm_functions.c
*/ */
void set_coring_fpga(int coring_number, int fpga_number); void set_coring_fpga(unsigned int coring_number, int fpga_number, unsigned int chn);
void reset_qtables(unsigned int chn);
void reset_qtables(void); int get_cache_policy(void);
void set_cache_policy(int policy);
void qt_init(struct platform_device *pdev);
#endif #endif
...@@ -764,8 +764,6 @@ int image_acq_init(struct platform_device *pdev) ...@@ -764,8 +764,6 @@ int image_acq_init(struct platform_device *pdev)
//MDD1(printk("init_pgm_proc ()\n")); //MDD1(printk("init_pgm_proc ()\n"));
//init_pgm_proc (); /// setup pointers to functions (not sensor-specific) //init_pgm_proc (); /// setup pointers to functions (not sensor-specific)
//MDD1(printk("reset_qtables()\n")); //MDD1(printk("reset_qtables()\n"));
dev_dbg(dev, "reset quantization tables\n");
reset_qtables(); /// force initialization at next access
return 0; return 0;
} }
......
...@@ -41,6 +41,10 @@ ...@@ -41,6 +41,10 @@
#define X393_BUFFSUB(x, y) (((x) >= (y)) ? ((x)-(y)) : ((x) + (CCAM_DMA_SIZE -(y)))) #define X393_BUFFSUB(x, y) (((x) >= (y)) ? ((x)-(y)) : ((x) + (CCAM_DMA_SIZE -(y))))
#define X393_BUFFADD(x, y) ((((x) + (y)) <= CCAM_DMA_SIZE) ? ((x) + (y)) : ((x) - (CCAM_DMA_SIZE -(y)))) #define X393_BUFFADD(x, y) ((((x) + (y)) <= CCAM_DMA_SIZE) ? ((x) + (y)) : ((x) - (CCAM_DMA_SIZE -(y))))
#define TABLE_TYPE_QUANT 0
#define TABLE_TYPE_CORING 1
#define TABLE_TYPE_FOCUS 2
#define TABLE_TYPE_HUFFMAN 3
/** /**
* @brief Converts file minor number to image compressor channel. * @brief Converts file minor number to image compressor channel.
* *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment