drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
Extension
.c
Size
7906 bytes
Lines
290
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

if (!obj) {
			DRM_DEBUG_KMS("Failed to lookup GEM object\n");
			return -ENOENT;
		}
		fb->obj[i] = obj;

		block_h = drm_format_info_block_height(info, i);
		if ((fb->pitches[i] * block_h) % mdev->chip.bus_width) {
			DRM_DEBUG_KMS("Pitch[%d]: 0x%x doesn't align to 0x%x\n",
				      i, fb->pitches[i], mdev->chip.bus_width);
			return -EINVAL;
		}

		min_size = komeda_fb_get_pixel_addr(kfb, 0, fb->height, i)
			 - to_drm_gem_dma_obj(obj)->dma_addr;
		if (obj->size < min_size) {
			DRM_DEBUG_KMS("The fb->obj[%d] size: 0x%zx lower than the minimum requirement: 0x%llx.\n",
				      i, obj->size, min_size);
			return -EINVAL;
		}
	}

	if (fb->format->num_planes == 3) {
		if (fb->pitches[1] != fb->pitches[2]) {
			DRM_DEBUG_KMS("The pitch[1] and [2] are not same\n");
			return -EINVAL;
		}
	}

	return 0;
}

struct drm_framebuffer *
komeda_fb_create(struct drm_device *dev, struct drm_file *file,
		 const struct drm_format_info *info,
		 const struct drm_mode_fb_cmd2 *mode_cmd)
{
	struct komeda_dev *mdev = dev->dev_private;
	struct komeda_fb *kfb;
	int ret = 0, i;

	kfb = kzalloc_obj(*kfb);
	if (!kfb)
		return ERR_PTR(-ENOMEM);

	kfb->format_caps = komeda_get_format_caps(&mdev->fmt_tbl,
						  mode_cmd->pixel_format,
						  mode_cmd->modifier[0]);
	if (!kfb->format_caps) {
		DRM_DEBUG_KMS("FMT %x is not supported.\n",
			      mode_cmd->pixel_format);
		kfree(kfb);
		return ERR_PTR(-EINVAL);
	}

	drm_helper_mode_fill_fb_struct(dev, &kfb->base, info, mode_cmd);

	if (kfb->base.modifier)
		ret = komeda_fb_afbc_size_check(kfb, file, mode_cmd);
	else
		ret = komeda_fb_none_afbc_size_check(mdev, kfb, file, mode_cmd);
	if (ret < 0)
		goto err_cleanup;

	ret = drm_framebuffer_init(dev, &kfb->base, &komeda_fb_funcs);
	if (ret < 0) {
		DRM_DEBUG_KMS("failed to initialize fb\n");

		goto err_cleanup;
	}

	kfb->is_va = mdev->iommu ? true : false;

	return &kfb->base;

err_cleanup:
	for (i = 0; i < kfb->base.format->num_planes; i++)
		drm_gem_object_put(kfb->base.obj[i]);

	kfree(kfb);
	return ERR_PTR(ret);
}

int komeda_fb_check_src_coords(const struct komeda_fb *kfb,
			       u32 src_x, u32 src_y, u32 src_w, u32 src_h)
{
	const struct drm_framebuffer *fb = &kfb->base;
	const struct drm_format_info *info = fb->format;
	u32 block_w = drm_format_info_block_width(fb->format, 0);
	u32 block_h = drm_format_info_block_height(fb->format, 0);

Annotation

Implementation Notes