drivers/gpu/drm/sun4i/sun4i_frontend.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/sun4i/sun4i_frontend.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/sun4i/sun4i_frontend.c
Extension
.c
Size
20628 bytes
Lines
733
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (fb->format->num_planes > 1) {
			strides[1] =
				SUN4I_FRONTEND_LINESTRD_TILED(fb->pitches[1]);

			regmap_write(frontend->regs, SUN4I_FRONTEND_TB_OFF1_REG,
				     SUN4I_FRONTEND_TB_OFF_X1(offset));
		}

		if (fb->format->num_planes > 2) {
			strides[2] =
				SUN4I_FRONTEND_LINESTRD_TILED(fb->pitches[2]);

			regmap_write(frontend->regs, SUN4I_FRONTEND_TB_OFF2_REG,
				     SUN4I_FRONTEND_TB_OFF_X1(offset));
		}
	} else {
		strides[0] = fb->pitches[0];

		if (fb->format->num_planes > 1)
			strides[1] = fb->pitches[1];

		if (fb->format->num_planes > 2)
			strides[2] = fb->pitches[2];
	}

	/* Set the line width */
	DRM_DEBUG_DRIVER("Frontend stride: %d bytes\n", fb->pitches[0]);
	regmap_write(frontend->regs, SUN4I_FRONTEND_LINESTRD0_REG,
		     strides[0]);

	if (fb->format->num_planes > 1)
		regmap_write(frontend->regs, SUN4I_FRONTEND_LINESTRD1_REG,
			     strides[1]);

	if (fb->format->num_planes > 2)
		regmap_write(frontend->regs, SUN4I_FRONTEND_LINESTRD2_REG,
			     strides[2]);

	/* Some planar formats require chroma channel swapping by hand. */
	swap = sun4i_frontend_format_chroma_requires_swap(fb->format->format);

	/* Set the physical address of the buffer in memory */
	dma_addr = drm_fb_dma_get_gem_addr(fb, state, 0);
	DRM_DEBUG_DRIVER("Setting buffer #0 address to %pad\n", &dma_addr);
	regmap_write(frontend->regs, SUN4I_FRONTEND_BUF_ADDR0_REG, dma_addr);

	if (fb->format->num_planes > 1) {
		dma_addr = drm_fb_dma_get_gem_addr(fb, state, swap ? 2 : 1);
		DRM_DEBUG_DRIVER("Setting buffer #1 address to %pad\n",
				 &dma_addr);
		regmap_write(frontend->regs, SUN4I_FRONTEND_BUF_ADDR1_REG,
			     dma_addr);
	}

	if (fb->format->num_planes > 2) {
		dma_addr = drm_fb_dma_get_gem_addr(fb, state, swap ? 1 : 2);
		DRM_DEBUG_DRIVER("Setting buffer #2 address to %pad\n",
				 &dma_addr);
		regmap_write(frontend->regs, SUN4I_FRONTEND_BUF_ADDR2_REG,
			     dma_addr);
	}
}
EXPORT_SYMBOL(sun4i_frontend_update_buffer);

static int
sun4i_frontend_drm_format_to_input_fmt(const struct drm_format_info *format,
				       u32 *val)
{
	if (!format->is_yuv)
		*val = SUN4I_FRONTEND_INPUT_FMT_DATA_FMT_RGB;
	else if (drm_format_info_is_yuv_sampling_411(format))
		*val = SUN4I_FRONTEND_INPUT_FMT_DATA_FMT_YUV411;
	else if (drm_format_info_is_yuv_sampling_420(format))
		*val = SUN4I_FRONTEND_INPUT_FMT_DATA_FMT_YUV420;
	else if (drm_format_info_is_yuv_sampling_422(format))
		*val = SUN4I_FRONTEND_INPUT_FMT_DATA_FMT_YUV422;
	else if (drm_format_info_is_yuv_sampling_444(format))
		*val = SUN4I_FRONTEND_INPUT_FMT_DATA_FMT_YUV444;
	else
		return -EINVAL;

	return 0;
}

static int
sun4i_frontend_drm_format_to_input_mode(const struct drm_format_info *format,
					uint64_t modifier, u32 *val)
{
	bool tiled = (modifier == DRM_FORMAT_MOD_ALLWINNER_TILED);

Annotation

Implementation Notes