drivers/gpu/drm/nouveau/dispnv50/head.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/dispnv50/head.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/nouveau/dispnv50/head.c- Extension
.c- Size
- 19062 bytes
- Lines
- 639
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
head.hbase.hcore.hcurs.hovly.hcrc.hnvif/class.hnvif/event.hnvif/cl0046.hdrm/drm_atomic.hdrm/drm_atomic_helper.hdrm/drm_edid.hdrm/drm_vblank.hnouveau_connector.h
Detected Declarations
function filesfunction nv50_head_flush_set_wndwfunction nv50_head_flush_setfunction nv50_head_atomic_check_procampfunction nv50_head_atomic_check_ditherfunction nv50_head_atomic_check_viewfunction nv50_head_atomic_check_lutfunction nv50_head_atomic_check_modefunction nv50_head_atomic_checkfunction nv50_head_atomic_destroy_statefunction nv50_head_atomic_duplicate_statefunction nv50_head_resetfunction nv50_head_late_registerfunction nv50_head_destroyfunction nv50_head_vblank_handlerfunction nv50_head_create
Annotated Snippet
if (asyc->dither.mode == DITHERING_MODE_AUTO) {
if (asyh->base.depth > asyh->or.bpc * 3)
mode = DITHERING_MODE_DYNAMIC2X2;
} else {
mode = asyc->dither.mode;
}
if (asyc->dither.depth == DITHERING_DEPTH_AUTO) {
if (asyh->or.bpc >= 8)
mode |= DITHERING_DEPTH_8BPC;
} else {
mode |= asyc->dither.depth;
}
}
asyh->dither.enable = NVVAL_GET(mode, NV507D, HEAD_SET_DITHER_CONTROL, ENABLE);
asyh->dither.bits = NVVAL_GET(mode, NV507D, HEAD_SET_DITHER_CONTROL, BITS);
asyh->dither.mode = NVVAL_GET(mode, NV507D, HEAD_SET_DITHER_CONTROL, MODE);
asyh->set.dither = true;
}
static void
nv50_head_atomic_check_view(struct nv50_head_atom *armh,
struct nv50_head_atom *asyh,
struct nouveau_conn_atom *asyc)
{
struct drm_connector *connector = asyc->state.connector;
struct drm_display_mode *omode = &asyh->state.adjusted_mode;
struct drm_display_mode *umode = &asyh->state.mode;
int mode = asyc->scaler.mode;
int umode_vdisplay, omode_hdisplay, omode_vdisplay;
if (!asyc->scaler.full) {
if (mode == DRM_MODE_SCALE_NONE)
omode = umode;
} else {
/* Non-EDID LVDS/eDP mode. */
mode = DRM_MODE_SCALE_FULLSCREEN;
}
/* For the user-specified mode, we must ignore doublescan and
* the like, but honor frame packing.
*/
umode_vdisplay = umode->vdisplay;
if ((umode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING)
umode_vdisplay += umode->vtotal;
asyh->view.iW = umode->hdisplay;
asyh->view.iH = umode_vdisplay;
/* For the output mode, we can just use the stock helper. */
drm_mode_get_hv_timing(omode, &omode_hdisplay, &omode_vdisplay);
asyh->view.oW = omode_hdisplay;
asyh->view.oH = omode_vdisplay;
/* Add overscan compensation if necessary, will keep the aspect
* ratio the same as the backend mode unless overridden by the
* user setting both hborder and vborder properties.
*/
if ((asyc->scaler.underscan.mode == UNDERSCAN_ON ||
(asyc->scaler.underscan.mode == UNDERSCAN_AUTO &&
connector->display_info.is_hdmi))) {
u32 bX = asyc->scaler.underscan.hborder;
u32 bY = asyc->scaler.underscan.vborder;
u32 r = (asyh->view.oH << 19) / asyh->view.oW;
if (bX) {
asyh->view.oW -= (bX * 2);
if (bY) asyh->view.oH -= (bY * 2);
else asyh->view.oH = ((asyh->view.oW * r) + (r / 2)) >> 19;
} else {
asyh->view.oW -= (asyh->view.oW >> 4) + 32;
if (bY) asyh->view.oH -= (bY * 2);
else asyh->view.oH = ((asyh->view.oW * r) + (r / 2)) >> 19;
}
}
/* Handle CENTER/ASPECT scaling, taking into account the areas
* removed already for overscan compensation.
*/
switch (mode) {
case DRM_MODE_SCALE_CENTER:
/* NOTE: This will cause scaling when the input is
* larger than the output.
*/
asyh->view.oW = min(asyh->view.iW, asyh->view.oW);
asyh->view.oH = min(asyh->view.iH, asyh->view.oH);
break;
case DRM_MODE_SCALE_ASPECT:
/* Determine whether the scaling should be on width or on
* height. This is done by comparing the aspect ratios of the
* sizes. If the output AR is larger than input AR, that means
Annotation
- Immediate include surface: `head.h`, `base.h`, `core.h`, `curs.h`, `ovly.h`, `crc.h`, `nvif/class.h`, `nvif/event.h`.
- Detected declarations: `function files`, `function nv50_head_flush_set_wndw`, `function nv50_head_flush_set`, `function nv50_head_atomic_check_procamp`, `function nv50_head_atomic_check_dither`, `function nv50_head_atomic_check_view`, `function nv50_head_atomic_check_lut`, `function nv50_head_atomic_check_mode`, `function nv50_head_atomic_check`, `function nv50_head_atomic_destroy_state`.
- 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.
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.