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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/dispnv04/overlay.c
Extension
.c
Size
15332 bytes
Lines
520
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 nouveau_plane {
	struct drm_plane base;
	bool flip;
	struct nouveau_bo *cur;

	struct {
		struct drm_property *colorkey;
		struct drm_property *contrast;
		struct drm_property *brightness;
		struct drm_property *hue;
		struct drm_property *saturation;
	} props;

	int colorkey;
	int contrast;
	int brightness;
	int hue;
	int saturation;
	enum drm_color_encoding color_encoding;

	void (*set_params)(struct nouveau_plane *);
};

static uint32_t formats[] = {
	DRM_FORMAT_YUYV,
	DRM_FORMAT_UYVY,
	DRM_FORMAT_NV12,
	DRM_FORMAT_NV21,
};

/* Sine can be approximated with
 * http://en.wikipedia.org/wiki/Bhaskara_I's_sine_approximation_formula
 * sin(x degrees) ~= 4 x (180 - x) / (40500 - x (180 - x) )
 * Note that this only works for the range [0, 180].
 * Also note that sin(x) == -sin(x - 180)
 */
static inline int
sin_mul(int degrees, int factor)
{
	if (degrees > 180) {
		degrees -= 180;
		factor *= -1;
	}
	return factor * 4 * degrees * (180 - degrees) /
		(40500 - degrees * (180 - degrees));
}

/* cos(x) = sin(x + 90) */
static inline int
cos_mul(int degrees, int factor)
{
	return sin_mul((degrees + 90) % 360, factor);
}

static int
verify_scaling(const struct drm_framebuffer *fb, uint8_t shift,
               uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,
               uint32_t crtc_w, uint32_t crtc_h)
{
	if (crtc_w < (src_w >> shift) || crtc_h < (src_h >> shift)) {
		DRM_DEBUG_KMS("Unsuitable framebuffer scaling: %dx%d -> %dx%d\n",
			      src_w, src_h, crtc_w, crtc_h);
		return -ERANGE;
	}

	if (src_x != 0 || src_y != 0) {
		DRM_DEBUG_KMS("Unsuitable framebuffer offset: %d,%d\n",
                              src_x, src_y);
		return -ERANGE;
	}

	return 0;
}

static int
nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
		  struct drm_framebuffer *fb, int crtc_x, int crtc_y,
		  unsigned int crtc_w, unsigned int crtc_h,
		  uint32_t src_x, uint32_t src_y,
		  uint32_t src_w, uint32_t src_h,
		  struct drm_modeset_acquire_ctx *ctx)
{
	struct nouveau_drm *drm = nouveau_drm(plane->dev);
	struct nvif_object *dev = &drm->client.device.object;
	struct nouveau_plane *nv_plane =
		container_of(plane, struct nouveau_plane, base);
	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
	struct nouveau_bo *cur = nv_plane->cur;
	struct nouveau_bo *nvbo;
	bool flip = nv_plane->flip;

Annotation

Implementation Notes