drivers/gpu/drm/nouveau/dispnv04/crtc.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/dispnv04/crtc.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/dispnv04/crtc.c
Extension
.c
Size
42285 bytes
Lines
1335
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct rgb { uint8_t r, g, b; } __attribute__((packed)) *rgbs;
	u16 *r, *g, *b;
	int i;

	rgbs = (struct rgb *)nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index].DAC;
	r = crtc->gamma_store;
	g = r + crtc->gamma_size;
	b = g + crtc->gamma_size;

	for (i = 0; i < 256; i++) {
		rgbs[i].r = *r++ >> 8;
		rgbs[i].g = *g++ >> 8;
		rgbs[i].b = *b++ >> 8;
	}

	nouveau_hw_load_state_palette(dev, nv_crtc->index, &nv04_display(dev)->mode_reg);
}

static void
nv_crtc_disable(struct drm_crtc *crtc)
{
	struct nv04_display *disp = nv04_display(crtc->dev);
	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);

	if (disp->image[nv_crtc->index]) {
		struct nouveau_bo *bo = disp->image[nv_crtc->index];

		nouveau_bo_unpin(bo);
		drm_gem_object_put(&bo->bo.base);
		disp->image[nv_crtc->index] = NULL;
	}
}

static int
nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
		  uint32_t size,
		  struct drm_modeset_acquire_ctx *ctx)
{
	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);

	/* We need to know the depth before we upload, but it's possible to
	 * get called before a framebuffer is bound.  If this is the case,
	 * mark the lut values as dirty by setting depth==0, and it'll be
	 * uploaded on the first mode_set_base()
	 */
	if (!nv_crtc->base.primary->fb) {
		nv_crtc->lut.depth = 0;
		return 0;
	}

	nv_crtc_gamma_load(crtc);

	return 0;
}

static int
nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
			   struct drm_framebuffer *passed_fb,
			   int x, int y)
{
	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
	struct drm_device *dev = crtc->dev;
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index];
	struct nouveau_bo *nvbo;
	struct drm_framebuffer *drm_fb;
	int arb_burst, arb_lwm;

	NV_DEBUG(drm, "index %d\n", nv_crtc->index);

	/* no fb bound */
	if (!crtc->primary->fb) {
		NV_DEBUG(drm, "No FB bound\n");
		return 0;
	}

	drm_fb = crtc->primary->fb;

	nvbo = nouveau_gem_object(drm_fb->obj[0]);
	nv_crtc->fb.offset = nvbo->offset;

	if (nv_crtc->lut.depth != drm_fb->format->depth) {
		nv_crtc->lut.depth = drm_fb->format->depth;
		nv_crtc_gamma_load(crtc);
	}

	/* Update the framebuffer format. */
	regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] &= ~3;
	regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (drm_fb->format->depth + 1) / 8;
	regp->ramdac_gen_ctrl &= ~NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL;

Annotation

Implementation Notes