drivers/gpu/drm/nouveau/dispnv04/dfp.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/dispnv04/dfp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/nouveau/dispnv04/dfp.c- Extension
.c- Size
- 24731 bytes
- Lines
- 725
- 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.
- 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
drm/drm_fourcc.hdrm/drm_modeset_helper_vtables.hnouveau_drv.hnouveau_reg.hnouveau_encoder.hnouveau_connector.hnouveau_crtc.hhw.hnvreg.hdispnv04/i2c/sil164.hsubdev/i2c.h
Detected Declarations
function filesfunction nv04_dfp_get_bound_headfunction nv04_dfp_bind_headfunction nv04_dfp_disablefunction nv04_dfp_update_fp_controlfunction list_for_each_entryfunction nv04_dfp_mode_fixupfunction nv04_dfp_prepare_sel_clkfunction nv04_dfp_preparefunction nv04_dfp_mode_setfunction nv04_dfp_commitfunction nv04_dfp_update_backlightfunction is_powersaving_dpmsfunction nv04_lvds_dpmsfunction nv04_tmds_dpmsfunction nv04_dfp_savefunction nv04_dfp_restorefunction nv04_dfp_destroyfunction nv04_tmds_slave_initfunction nv04_dfp_create
Annotated Snippet
if (is_fpc_off(*fpc)) {
/* using saved value is ok, as (is_digital && dpms_on &&
* fp_control==OFF) is (at present) *only* true when
* fpc's most recent change was by below "off" code
*/
*fpc = nv_crtc->dpms_saved_fp_control;
}
nv_crtc->fp_users |= 1 << nouveau_encoder(encoder)->dcb->index;
NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_FP_TG_CONTROL, *fpc);
} else {
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
nv_crtc = nouveau_crtc(crtc);
fpc = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index].fp_control;
nv_crtc->fp_users &= ~(1 << nouveau_encoder(encoder)->dcb->index);
if (!is_fpc_off(*fpc) && !nv_crtc->fp_users) {
nv_crtc->dpms_saved_fp_control = *fpc;
/* cut the FP output */
*fpc &= ~FP_TG_CONTROL_ON;
*fpc |= FP_TG_CONTROL_OFF;
NVWriteRAMDAC(dev, nv_crtc->index,
NV_PRAMDAC_FP_TG_CONTROL, *fpc);
}
}
}
}
static struct drm_encoder *get_tmds_slave(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct dcb_output *dcb = nouveau_encoder(encoder)->dcb;
struct drm_encoder *slave;
if (dcb->type != DCB_OUTPUT_TMDS || dcb->location == DCB_LOC_ON_CHIP)
return NULL;
/* Some BIOSes (e.g. the one in a Quadro FX1000) report several
* TMDS transmitters at the same I2C address, in the same I2C
* bus. This can still work because in that case one of them is
* always hard-wired to a reasonable configuration using straps,
* and the other one needs to be programmed.
*
* I don't think there's a way to know which is which, even the
* blob programs the one exposed via I2C for *both* heads, so
* let's do the same.
*/
list_for_each_entry(slave, &dev->mode_config.encoder_list, head) {
struct dcb_output *slave_dcb = nouveau_encoder(slave)->dcb;
if (slave_dcb->type == DCB_OUTPUT_TMDS && get_encoder_i2c_funcs(slave) &&
slave_dcb->tmdsconf.slave_addr == dcb->tmdsconf.slave_addr)
return slave;
}
return NULL;
}
static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nouveau_connector *nv_connector =
nv04_encoder_get_connector(nv_encoder);
if (!nv_connector->native_mode ||
nv_connector->scaling_mode == DRM_MODE_SCALE_NONE ||
mode->hdisplay > nv_connector->native_mode->hdisplay ||
mode->vdisplay > nv_connector->native_mode->vdisplay) {
nv_encoder->mode = *adjusted_mode;
} else {
nv_encoder->mode = *nv_connector->native_mode;
adjusted_mode->clock = nv_connector->native_mode->clock;
}
return true;
}
static void nv04_dfp_prepare_sel_clk(struct drm_device *dev,
struct nouveau_encoder *nv_encoder, int head)
{
struct nv04_mode_state *state = &nv04_display(dev)->mode_reg;
uint32_t bits1618 = nv_encoder->dcb->or & DCB_OUTPUT_A ? 0x10000 : 0x40000;
if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP)
return;
/* SEL_CLK is only used on the primary ramdac
Annotation
- Immediate include surface: `drm/drm_fourcc.h`, `drm/drm_modeset_helper_vtables.h`, `nouveau_drv.h`, `nouveau_reg.h`, `nouveau_encoder.h`, `nouveau_connector.h`, `nouveau_crtc.h`, `hw.h`.
- Detected declarations: `function files`, `function nv04_dfp_get_bound_head`, `function nv04_dfp_bind_head`, `function nv04_dfp_disable`, `function nv04_dfp_update_fp_control`, `function list_for_each_entry`, `function nv04_dfp_mode_fixup`, `function nv04_dfp_prepare_sel_clk`, `function nv04_dfp_prepare`, `function nv04_dfp_mode_set`.
- Atlas domain: Driver Families / drivers/gpu.
- 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.