drivers/media/platform/arm/mali-c55/mali-c55-tpg.c
Source file repositories/reference/linux-study-clean/drivers/media/platform/arm/mali-c55/mali-c55-tpg.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/platform/arm/mali-c55/mali-c55-tpg.c- Extension
.c- Size
- 12783 bytes
- Lines
- 439
- Domain
- Driver Families
- Bucket
- drivers/media
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/minmax.hlinux/pm_runtime.hlinux/string.hmedia/media-entity.hmedia/v4l2-ctrls.hmedia/v4l2-event.hmedia/v4l2-subdev.hmali-c55-common.hmali-c55-registers.h
Detected Declarations
function mali_c55_tpg_update_vblankfunction mali_c55_tpg_s_ctrlfunction mali_c55_tpg_configurefunction mali_c55_tpg_enum_mbus_codefunction mali_c55_tpg_enum_frame_sizefunction mali_c55_tpg_set_fmtfunction mali_c55_tpg_enable_streamsfunction mali_c55_tpg_disable_streamsfunction mali_c55_tpg_init_statefunction mali_c55_tpg_init_controlsfunction mali_c55_register_tpgfunction mali_c55_unregister_tpg
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0
/*
* ARM Mali-C55 ISP Driver - Test pattern generator
*
* Copyright (C) 2025 Ideas on Board Oy
*/
#include <linux/minmax.h>
#include <linux/pm_runtime.h>
#include <linux/string.h>
#include <media/media-entity.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
#include <media/v4l2-subdev.h>
#include "mali-c55-common.h"
#include "mali-c55-registers.h"
#define MALI_C55_TPG_SRC_PAD 0
#define MALI_C55_TPG_FIXED_HBLANK 0x20
#define MALI_C55_TPG_DEFAULT_MIN_VBLANK 66
#define MALI_C55_TPG_DEFAULT_DEF_VBLANK 626
#define MALI_C55_TPG_MAX_VBLANK 0xffff
#define MALI_C55_TPG_PIXEL_RATE 100000000
static const char * const mali_c55_tpg_test_pattern_menu[] = {
"Flat field",
"Horizontal gradient",
"Vertical gradient",
"Vertical bars",
"Arbitrary rectangle",
"White frame on black field"
};
static const u32 mali_c55_tpg_mbus_codes[] = {
MEDIA_BUS_FMT_SRGGB20_1X20,
MEDIA_BUS_FMT_RGB202020_1X60,
};
static void mali_c55_tpg_update_vblank(struct mali_c55_tpg *tpg,
struct v4l2_mbus_framefmt *format)
{
unsigned int def_vblank;
unsigned int min_vblank;
unsigned int hts;
int tgt_fps;
hts = format->width + MALI_C55_TPG_FIXED_HBLANK;
/*
* The ISP has minimum vertical blanking requirements that must be
* adhered to by the TPG. The minimum is a function of the Iridix blocks
* clocking requirements and the width of the image and horizontal
* blanking, but if we assume the worst case iVariance and sVariance
* values then it boils down to the below (plus one to the numerator to
* ensure the answer is rounded up).
*/
min_vblank = 15 + (120501 / hts);
/*
* We need to set a sensible default vblank for whatever format height
* we happen to be given from set_fmt(). This function just targets
* an even multiple of 15fps. If we can't get 15fps, let's target 5fps.
* If we can't get 5fps we'll take whatever the minimum vblank gives us.
*/
tgt_fps = MALI_C55_TPG_PIXEL_RATE / hts / (format->height + min_vblank);
if (tgt_fps < 5)
def_vblank = min_vblank;
else
def_vblank = (MALI_C55_TPG_PIXEL_RATE / hts
/ max(rounddown(tgt_fps, 15), 5)) - format->height;
def_vblank = ALIGN_DOWN(def_vblank, 2);
__v4l2_ctrl_modify_range(tpg->ctrls.vblank, min_vblank,
MALI_C55_TPG_MAX_VBLANK, 1, def_vblank);
__v4l2_ctrl_s_ctrl(tpg->ctrls.vblank, def_vblank);
}
static int mali_c55_tpg_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct mali_c55_tpg *tpg = container_of(ctrl->handler,
struct mali_c55_tpg,
ctrls.handler);
struct mali_c55 *mali_c55 = container_of(tpg, struct mali_c55, tpg);
int ret = 0;
if (!pm_runtime_get_if_in_use(mali_c55->dev))
Annotation
- Immediate include surface: `linux/minmax.h`, `linux/pm_runtime.h`, `linux/string.h`, `media/media-entity.h`, `media/v4l2-ctrls.h`, `media/v4l2-event.h`, `media/v4l2-subdev.h`, `mali-c55-common.h`.
- Detected declarations: `function mali_c55_tpg_update_vblank`, `function mali_c55_tpg_s_ctrl`, `function mali_c55_tpg_configure`, `function mali_c55_tpg_enum_mbus_code`, `function mali_c55_tpg_enum_frame_size`, `function mali_c55_tpg_set_fmt`, `function mali_c55_tpg_enable_streams`, `function mali_c55_tpg_disable_streams`, `function mali_c55_tpg_init_state`, `function mali_c55_tpg_init_controls`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: source implementation candidate.
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.