Loading src/drivers/elphel/circbuf.c +11 −11 Original line number Diff line number Diff line Loading @@ -95,14 +95,14 @@ int init_ccam_dma_buf_ptr(struct platform_device *pdev) if (pElphel_buf != NULL) { ccam_dma_buf_ptr = pElphel_buf->vaddr; 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 { ccam_dma_buf_ptr = dmam_alloc_coherent(dev, dma_size, &dma_handle, GFP_KERNEL); if (!ccam_dma_buf_ptr) { dev_err(dev, "unable to allocate DMA buffer\n"); return -ENOMEM; } 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); } } Loading Loading @@ -263,7 +263,7 @@ unsigned int circbuf_all_poll (struct file *file, poll_table *wait) int circbuf_open(struct inode *inode, struct file *filp) { 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; } Loading @@ -286,7 +286,7 @@ unsigned long get_image_length(int byte_offset, unsigned int chn, int *last_chun last_image_chunk += CCAM_DMA_SIZE; 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) *last_chunk_offset = last_image_chunk; Loading Loading @@ -481,13 +481,13 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig) file->f_pos = img_start; break; 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) return -EOVERFLOW; //! no frames after current // 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; 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; case LSEEK_CIRC_FIRST: case LSEEK_CIRC_SCND: Loading @@ -503,7 +503,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig) nf++; preprev_p = prev_p; // second known good (at least first one) 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); if ((len32 & MARKER_FF) != MARKER_FF ) break; //! no frames before rp (==prev_p) //! move rp to the previous frame Loading @@ -519,7 +519,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig) break; } 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); break; case LSEEK_CIRC_VALID: Loading Loading @@ -569,7 +569,7 @@ ssize_t circbuf_write(struct file *file, const char *buf, size_t count, loff_t * unsigned long p; unsigned int minor = MINOR(file->f_inode->i_rdev); 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*/ switch (buf[0] - 0x30) { Loading Loading @@ -609,7 +609,7 @@ ssize_t circbuf_read(struct file *file, char *buf, size_t count, loff_t *off) unsigned long p; unsigned int minor = MINOR(file->f_inode->i_rdev); 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; if (p >= CCAM_DMA_SIZE) Loading Loading @@ -674,7 +674,7 @@ unsigned int circbuf_poll (struct file *file, poll_table *wait) rslt = circbuf_valid_ptr(file->f_pos, &fp, chn); if (rslt < 0) { // 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 ; } else if (rslt > 0) { return POLLIN | POLLRDNORM; //! there was frame already available Loading src/drivers/elphel/jpeghead.c +20 −6 Original line number Diff line number Diff line Loading @@ -104,12 +104,13 @@ static struct jpeghead_priv_t { * @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[out] buf buffer to put the header to * @param[in] chn compressor channel number * @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); 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 return 128; } Loading Loading @@ -192,16 +193,16 @@ int jpegheader_create(struct interframe_params_t *params, unsigned char *buf, un 0x07, 0x11}; 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 unsigned char *p = (char *)params; dev_dbg(g_dev_ptr, "list of parameters:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p, 32); memcpy((void *) &buf[0], (void *) jfif1, sizeof (jfif1)); /// including DQT0 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 bp=header_sof; buf[bp++]=0xff; buf[bp++]=0xc0; Loading Loading @@ -364,7 +365,7 @@ loff_t jpeghead_lseek(struct file *file, loff_t offset, int orig, 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 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 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) { Loading Loading @@ -669,20 +670,23 @@ int jpeg_htable_is_programmed(unsigned int chn) /** * @brief program FPGA Huffman table (fram static array) * @param[in] chn compressor channel number * return none * @return none */ void jpeg_htable_fpga_pgm(unsigned int chn) { int i; unsigned long flags; x393_cmprs_table_addr_t table_addr; struct huff_tables_t *huff_tables = &jpeghead_priv[chn].huff_tables; table_addr.addr32 = 0; table_addr.type = 3; local_irq_save(flags); x393_cmprs_tables_address(table_addr, chn); for (i = 0; i < sizeof(huff_tables->fpga_huffman_table); i++) { x393_cmprs_tables_data((u32)huff_tables->fpga_huffman_table[i], chn); } local_irq_restore(flags); jpeghead_priv[chn].fpga_programmed = 1; } Loading Loading @@ -749,5 +753,15 @@ int jpeghead_init(struct platform_device *pdev) 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; } src/drivers/elphel/jpeghead.h +1 −1 Original line number Diff line number Diff line Loading @@ -9,7 +9,7 @@ struct huffman_fpga_code_t { unsigned short value; /// code value 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 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); Loading Loading
src/drivers/elphel/circbuf.c +11 −11 Original line number Diff line number Diff line Loading @@ -95,14 +95,14 @@ int init_ccam_dma_buf_ptr(struct platform_device *pdev) if (pElphel_buf != NULL) { ccam_dma_buf_ptr = pElphel_buf->vaddr; 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 { ccam_dma_buf_ptr = dmam_alloc_coherent(dev, dma_size, &dma_handle, GFP_KERNEL); if (!ccam_dma_buf_ptr) { dev_err(dev, "unable to allocate DMA buffer\n"); return -ENOMEM; } 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); } } Loading Loading @@ -263,7 +263,7 @@ unsigned int circbuf_all_poll (struct file *file, poll_table *wait) int circbuf_open(struct inode *inode, struct file *filp) { 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; } Loading @@ -286,7 +286,7 @@ unsigned long get_image_length(int byte_offset, unsigned int chn, int *last_chun last_image_chunk += CCAM_DMA_SIZE; 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) *last_chunk_offset = last_image_chunk; Loading Loading @@ -481,13 +481,13 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig) file->f_pos = img_start; break; 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) return -EOVERFLOW; //! no frames after current // 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; 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; case LSEEK_CIRC_FIRST: case LSEEK_CIRC_SCND: Loading @@ -503,7 +503,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig) nf++; preprev_p = prev_p; // second known good (at least first one) 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); if ((len32 & MARKER_FF) != MARKER_FF ) break; //! no frames before rp (==prev_p) //! move rp to the previous frame Loading @@ -519,7 +519,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig) break; } 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); break; case LSEEK_CIRC_VALID: Loading Loading @@ -569,7 +569,7 @@ ssize_t circbuf_write(struct file *file, const char *buf, size_t count, loff_t * unsigned long p; unsigned int minor = MINOR(file->f_inode->i_rdev); 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*/ switch (buf[0] - 0x30) { Loading Loading @@ -609,7 +609,7 @@ ssize_t circbuf_read(struct file *file, char *buf, size_t count, loff_t *off) unsigned long p; unsigned int minor = MINOR(file->f_inode->i_rdev); 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; if (p >= CCAM_DMA_SIZE) Loading Loading @@ -674,7 +674,7 @@ unsigned int circbuf_poll (struct file *file, poll_table *wait) rslt = circbuf_valid_ptr(file->f_pos, &fp, chn); if (rslt < 0) { // 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 ; } else if (rslt > 0) { return POLLIN | POLLRDNORM; //! there was frame already available Loading
src/drivers/elphel/jpeghead.c +20 −6 Original line number Diff line number Diff line Loading @@ -104,12 +104,13 @@ static struct jpeghead_priv_t { * @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[out] buf buffer to put the header to * @param[in] chn compressor channel number * @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); 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 return 128; } Loading Loading @@ -192,16 +193,16 @@ int jpegheader_create(struct interframe_params_t *params, unsigned char *buf, un 0x07, 0x11}; 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 unsigned char *p = (char *)params; dev_dbg(g_dev_ptr, "list of parameters:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p, 32); memcpy((void *) &buf[0], (void *) jfif1, sizeof (jfif1)); /// including DQT0 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 bp=header_sof; buf[bp++]=0xff; buf[bp++]=0xc0; Loading Loading @@ -364,7 +365,7 @@ loff_t jpeghead_lseek(struct file *file, loff_t offset, int orig, 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 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 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) { Loading Loading @@ -669,20 +670,23 @@ int jpeg_htable_is_programmed(unsigned int chn) /** * @brief program FPGA Huffman table (fram static array) * @param[in] chn compressor channel number * return none * @return none */ void jpeg_htable_fpga_pgm(unsigned int chn) { int i; unsigned long flags; x393_cmprs_table_addr_t table_addr; struct huff_tables_t *huff_tables = &jpeghead_priv[chn].huff_tables; table_addr.addr32 = 0; table_addr.type = 3; local_irq_save(flags); x393_cmprs_tables_address(table_addr, chn); for (i = 0; i < sizeof(huff_tables->fpga_huffman_table); i++) { x393_cmprs_tables_data((u32)huff_tables->fpga_huffman_table[i], chn); } local_irq_restore(flags); jpeghead_priv[chn].fpga_programmed = 1; } Loading Loading @@ -749,5 +753,15 @@ int jpeghead_init(struct platform_device *pdev) 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; }
src/drivers/elphel/jpeghead.h +1 −1 Original line number Diff line number Diff line Loading @@ -9,7 +9,7 @@ struct huffman_fpga_code_t { unsigned short value; /// code value 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 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); Loading