drivers/gpu/drm/tve200/tve200_display.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/tve200/tve200_display.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/tve200/tve200_display.c- Extension
.c- Size
- 10247 bytes
- Lines
- 359
- 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/dma-buf.hlinux/of_graph.hlinux/delay.hdrm/drm_fb_dma_helper.hdrm/drm_fourcc.hdrm/drm_framebuffer.hdrm/drm_gem_atomic_helper.hdrm/drm_gem_dma_helper.hdrm/drm_panel.hdrm/drm_print.hdrm/drm_vblank.htve200_drm.h
Detected Declarations
function Copyrightfunction imagefunction tve200_display_checkfunction tve200_display_enablefunction readlfunction tve200_display_disablefunction tve200_display_updatefunction tve200_display_enable_vblankfunction tve200_display_disable_vblankfunction tve200_display_init
Annotated Snippet
if (!(val & TVE200_VSTSTYPE_BITS)) {
drm_crtc_handle_vblank(&priv->pipe.crtc);
/* Toggle trigger to start of active image */
val |= TVE200_VSTSTYPE_VAI;
} else {
/* Toggle trigger back to start of vsync */
val &= ~TVE200_VSTSTYPE_BITS;
}
writel(val, priv->regs + TVE200_CTRL);
} else
dev_err(priv->drm->dev, "stray IRQ %08x\n", stat);
/* Clear the interrupt once done */
writel(stat, priv->regs + TVE200_INT_CLR);
return IRQ_HANDLED;
}
static int tve200_display_check(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *pstate,
struct drm_crtc_state *cstate)
{
const struct drm_display_mode *mode = &cstate->mode;
struct drm_framebuffer *old_fb = pipe->plane.state->fb;
struct drm_framebuffer *fb = pstate->fb;
/*
* We support these specific resolutions and nothing else.
*/
if (!(mode->hdisplay == 352 && mode->vdisplay == 240) && /* SIF(525) */
!(mode->hdisplay == 352 && mode->vdisplay == 288) && /* CIF(625) */
!(mode->hdisplay == 640 && mode->vdisplay == 480) && /* VGA */
!(mode->hdisplay == 720 && mode->vdisplay == 480) && /* D1 */
!(mode->hdisplay == 720 && mode->vdisplay == 576)) { /* D1 */
DRM_DEBUG_KMS("unsupported display mode (%u x %u)\n",
mode->hdisplay, mode->vdisplay);
return -EINVAL;
}
if (fb) {
u32 offset = drm_fb_dma_get_gem_addr(fb, pstate, 0);
/* FB base address must be dword aligned. */
if (offset & 3) {
DRM_DEBUG_KMS("FB not 32-bit aligned\n");
return -EINVAL;
}
/*
* There's no pitch register, the mode's hdisplay
* controls this.
*/
if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0]) {
DRM_DEBUG_KMS("can't handle pitches\n");
return -EINVAL;
}
/*
* We can't change the FB format in a flicker-free
* manner (and only update it during CRTC enable).
*/
if (old_fb && old_fb->format != fb->format)
cstate->mode_changed = true;
}
return 0;
}
static void tve200_display_enable(struct drm_simple_display_pipe *pipe,
struct drm_crtc_state *cstate,
struct drm_plane_state *plane_state)
{
struct drm_crtc *crtc = &pipe->crtc;
struct drm_plane *plane = &pipe->plane;
struct drm_device *drm = crtc->dev;
struct tve200_drm_dev_private *priv = drm->dev_private;
const struct drm_display_mode *mode = &cstate->mode;
struct drm_framebuffer *fb = plane->state->fb;
struct drm_connector *connector = priv->connector;
u32 format = fb->format->format;
u32 ctrl1 = 0;
int retries;
clk_prepare_enable(priv->clk);
/* Reset the TVE200 and wait for it to come back online */
writel(TVE200_CTRL_4_RESET, priv->regs + TVE200_CTRL_4);
for (retries = 0; retries < 5; retries++) {
usleep_range(30000, 50000);
if (readl(priv->regs + TVE200_CTRL_4) & TVE200_CTRL_4_RESET)
Annotation
- Immediate include surface: `linux/clk.h`, `linux/dma-buf.h`, `linux/of_graph.h`, `linux/delay.h`, `drm/drm_fb_dma_helper.h`, `drm/drm_fourcc.h`, `drm/drm_framebuffer.h`, `drm/drm_gem_atomic_helper.h`.
- Detected declarations: `function Copyright`, `function image`, `function tve200_display_check`, `function tve200_display_enable`, `function readl`, `function tve200_display_disable`, `function tve200_display_update`, `function tve200_display_enable_vblank`, `function tve200_display_disable_vblank`, `function tve200_display_init`.
- 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.