drivers/gpu/drm/kmb/kmb_drv.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/kmb/kmb_drv.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/kmb/kmb_drv.c- Extension
.c- Size
- 16921 bytes
- Lines
- 638
- Domain
- Driver Families
- Bucket
- drivers/gpu
- 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/clk.hlinux/module.hlinux/of_graph.hlinux/of_platform.hlinux/of_reserved_mem.hlinux/mfd/syscon.hlinux/platform_device.hlinux/pm_runtime.hlinux/regmap.hdrm/clients/drm_client_setup.hdrm/drm_atomic_helper.hdrm/drm_drv.hdrm/drm_fbdev_dma.hdrm/drm_gem_dma_helper.hdrm/drm_gem_framebuffer_helper.hdrm/drm_module.hdrm/drm_print.hdrm/drm_probe_helper.hdrm/drm_vblank.hkmb_drv.hkmb_dsi.hkmb_regs.h
Detected Declarations
function kmb_display_clk_enablefunction kmb_initialize_clocksfunction kmb_display_clk_disablefunction kmb_hw_initfunction kmb_setup_mode_configfunction handle_lcd_irqfunction kmb_isrfunction kmb_irq_resetfunction kmb_irq_installfunction kmb_irq_uninstallfunction kmb_removefunction kmb_probefunction kmb_pm_suspendfunction kmb_pm_resume
Annotated Snippet
if (kmb->plane_status[plane_id].disable) {
kmb_clr_bitmask_lcd(kmb,
LCD_LAYERn_DMA_CFG
(plane_id),
LCD_DMA_LAYER_ENABLE);
kmb_clr_bitmask_lcd(kmb, LCD_CONTROL,
kmb->plane_status[plane_id].ctrl);
ctrl = kmb_read_lcd(kmb, LCD_CONTROL);
if (!(ctrl & (LCD_CTRL_VL1_ENABLE |
LCD_CTRL_VL2_ENABLE |
LCD_CTRL_GL1_ENABLE |
LCD_CTRL_GL2_ENABLE))) {
/* If no LCD layers are using DMA,
* then disable DMA pipelined AXI read
* transactions.
*/
kmb_clr_bitmask_lcd(kmb, LCD_CONTROL,
LCD_CTRL_PIPELINE_DMA);
}
kmb->plane_status[plane_id].disable = false;
}
}
if (kmb->kmb_under_flow) {
/* DMA Recovery after underflow */
dma0_state = (kmb->layer_no == 0) ?
LCD_VIDEO0_DMA0_STATE : LCD_VIDEO1_DMA0_STATE;
dma1_state = (kmb->layer_no == 0) ?
LCD_VIDEO0_DMA1_STATE : LCD_VIDEO1_DMA1_STATE;
do {
kmb_write_lcd(kmb, LCD_FIFO_FLUSH, 1);
val = kmb_read_lcd(kmb, dma0_state)
& LCD_DMA_STATE_ACTIVE;
val1 = kmb_read_lcd(kmb, dma1_state)
& LCD_DMA_STATE_ACTIVE;
} while ((val || val1));
/* disable dma */
kmb_clr_bitmask_lcd(kmb,
LCD_LAYERn_DMA_CFG(kmb->layer_no),
LCD_DMA_LAYER_ENABLE);
kmb_write_lcd(kmb, LCD_FIFO_FLUSH, 1);
kmb->kmb_flush_done = 1;
kmb->kmb_under_flow = 0;
}
}
if (status & LCD_INT_LINE_CMP) {
/* clear line compare interrupt */
kmb_write_lcd(kmb, LCD_INT_CLEAR, LCD_INT_LINE_CMP);
}
if (status & LCD_INT_VERT_COMP) {
/* Read VSTATUS */
val = kmb_read_lcd(kmb, LCD_VSTATUS);
val = (val & LCD_VSTATUS_VERTICAL_STATUS_MASK);
switch (val) {
case LCD_VSTATUS_COMPARE_VSYNC:
/* Clear vertical compare interrupt */
kmb_write_lcd(kmb, LCD_INT_CLEAR, LCD_INT_VERT_COMP);
if (kmb->kmb_flush_done) {
kmb_set_bitmask_lcd(kmb,
LCD_LAYERn_DMA_CFG
(kmb->layer_no),
LCD_DMA_LAYER_ENABLE);
kmb->kmb_flush_done = 0;
}
drm_crtc_handle_vblank(&kmb->crtc);
break;
case LCD_VSTATUS_COMPARE_BACKPORCH:
case LCD_VSTATUS_COMPARE_ACTIVE:
case LCD_VSTATUS_COMPARE_FRONT_PORCH:
kmb_write_lcd(kmb, LCD_INT_CLEAR, LCD_INT_VERT_COMP);
break;
}
}
if (status & LCD_INT_DMA_ERR) {
val =
(status & LCD_INT_DMA_ERR &
kmb_read_lcd(kmb, LCD_INT_ENABLE));
/* LAYER0 - VL0 */
if (val & (LAYER0_DMA_FIFO_UNDERFLOW |
LAYER0_DMA_CB_FIFO_UNDERFLOW |
LAYER0_DMA_CR_FIFO_UNDERFLOW)) {
kmb->kmb_under_flow++;
drm_info(&kmb->drm,
"!LAYER0:VL0 DMA UNDERFLOW val = 0x%lx,under_flow=%d",
val, kmb->kmb_under_flow);
Annotation
- Immediate include surface: `linux/clk.h`, `linux/module.h`, `linux/of_graph.h`, `linux/of_platform.h`, `linux/of_reserved_mem.h`, `linux/mfd/syscon.h`, `linux/platform_device.h`, `linux/pm_runtime.h`.
- Detected declarations: `function kmb_display_clk_enable`, `function kmb_initialize_clocks`, `function kmb_display_clk_disable`, `function kmb_hw_init`, `function kmb_setup_mode_config`, `function handle_lcd_irq`, `function kmb_isr`, `function kmb_irq_reset`, `function kmb_irq_install`, `function kmb_irq_uninstall`.
- Atlas domain: Driver Families / drivers/gpu.
- 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.