drivers/staging/media/meson/vdec/esparser.c
Source file repositories/reference/linux-study-clean/drivers/staging/media/meson/vdec/esparser.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/staging/media/meson/vdec/esparser.c- Extension
.c- Size
- 12759 bytes
- Lines
- 458
- Domain
- Driver Families
- Bucket
- drivers/staging
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/init.hlinux/ioctl.hlinux/list.hlinux/module.hlinux/reset.hlinux/interrupt.hmedia/videobuf2-dma-contig.hmedia/v4l2-mem2mem.hdos_regs.hesparser.hvdec_helpers.h
Detected Declarations
function esparser_isrfunction vp9_update_headerfunction esparser_pad_start_codefunction esparser_write_datafunction esparser_vififo_get_free_spacefunction esparser_queue_eosfunction esparser_get_offsetfunction esparser_queuefunction esparser_queue_all_srcfunction esparser_power_upfunction esparser_init
Annotated Snippet
if (!old_header) {
/* nothing */
} else if (old_header > fdata + 16 + framesize) {
dev_dbg(core->dev, "%s: data has gaps, setting to 0\n",
__func__);
memset(fdata + 16 + framesize, 0,
(old_header - fdata + 16 + framesize));
} else if (old_header < fdata + 16 + framesize) {
dev_err(core->dev, "%s: data overwritten\n", __func__);
}
old_header = fdata;
}
return new_frame_size;
}
/* Pad the packet to at least 4KiB bytes otherwise the VDEC unit won't trigger
* ISRs.
* Also append a start code 000001ff at the end to trigger
* the ESPARSER interrupt.
*/
static u32 esparser_pad_start_code(struct amvdec_core *core,
struct vb2_buffer *vb,
u32 payload_size)
{
u32 pad_size = 0;
u8 *vaddr = vb2_plane_vaddr(vb, 0);
if (payload_size < ESPARSER_MIN_PACKET_SIZE) {
pad_size = ESPARSER_MIN_PACKET_SIZE - payload_size;
memset(vaddr + payload_size, 0, pad_size);
}
if ((payload_size + pad_size + SEARCH_PATTERN_LEN) >
vb2_plane_size(vb, 0)) {
dev_warn(core->dev, "%s: unable to pad start code\n", __func__);
return pad_size;
}
memset(vaddr + payload_size + pad_size, 0, SEARCH_PATTERN_LEN);
vaddr[payload_size + pad_size] = 0x00;
vaddr[payload_size + pad_size + 1] = 0x00;
vaddr[payload_size + pad_size + 2] = 0x01;
vaddr[payload_size + pad_size + 3] = 0xff;
return pad_size;
}
static int
esparser_write_data(struct amvdec_core *core, dma_addr_t addr, u32 size)
{
amvdec_write_parser(core, PFIFO_RD_PTR, 0);
amvdec_write_parser(core, PFIFO_WR_PTR, 0);
amvdec_write_parser(core, PARSER_CONTROL,
ES_WRITE |
ES_PARSER_START |
ES_SEARCH |
(size << ES_PACK_SIZE_BIT));
amvdec_write_parser(core, PARSER_FETCH_ADDR, addr);
amvdec_write_parser(core, PARSER_FETCH_CMD,
(7 << FETCH_ENDIAN_BIT) |
(size + SEARCH_PATTERN_LEN));
search_done = 0;
return wait_event_interruptible_timeout(wq, search_done, (HZ / 5));
}
static u32 esparser_vififo_get_free_space(struct amvdec_session *sess)
{
u32 vififo_usage;
struct amvdec_ops *vdec_ops = sess->fmt_out->vdec_ops;
struct amvdec_core *core = sess->core;
vififo_usage = vdec_ops->vififo_level(sess);
vififo_usage += amvdec_read_parser(core, PARSER_VIDEO_HOLE);
vififo_usage += (6 * SZ_1K); // 6 KiB internal fifo
if (vififo_usage > sess->vififo_size) {
dev_warn(sess->core->dev,
"VIFIFO usage (%u) > VIFIFO size (%u)\n",
vififo_usage, sess->vififo_size);
return 0;
}
return sess->vififo_size - vififo_usage;
}
int esparser_queue_eos(struct amvdec_core *core, const u8 *data, u32 len)
{
Annotation
- Immediate include surface: `linux/init.h`, `linux/ioctl.h`, `linux/list.h`, `linux/module.h`, `linux/reset.h`, `linux/interrupt.h`, `media/videobuf2-dma-contig.h`, `media/v4l2-mem2mem.h`.
- Detected declarations: `function esparser_isr`, `function vp9_update_header`, `function esparser_pad_start_code`, `function esparser_write_data`, `function esparser_vififo_get_free_space`, `function esparser_queue_eos`, `function esparser_get_offset`, `function esparser_queue`, `function esparser_queue_all_src`, `function esparser_power_up`.
- Atlas domain: Driver Families / drivers/staging.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.