drivers/gpu/drm/exynos/exynos_drm_scaler.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/exynos/exynos_drm_scaler.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/exynos/exynos_drm_scaler.c
Extension
.c
Size
19674 bytes
Lines
729
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 scaler_data {
	const char	*clk_name[SCALER_MAX_CLK];
	unsigned int	num_clk;
	const struct exynos_drm_ipp_formats *formats;
	unsigned int	num_formats;
};

struct scaler_context {
	struct exynos_drm_ipp		ipp;
	struct drm_device		*drm_dev;
	void				*dma_priv;
	struct device			*dev;
	void __iomem			*regs;
	struct clk			*clock[SCALER_MAX_CLK];
	struct exynos_drm_ipp_task	*task;
	const struct scaler_data	*scaler_data;
};

struct scaler_format {
	u32	drm_fmt;
	u32	internal_fmt;
	u32	chroma_tile_w;
	u32	chroma_tile_h;
};

static const struct scaler_format scaler_formats[] = {
	{ DRM_FORMAT_NV12, SCALER_YUV420_2P_UV, 8, 8 },
	{ DRM_FORMAT_NV21, SCALER_YUV420_2P_VU, 8, 8 },
	{ DRM_FORMAT_YUV420, SCALER_YUV420_3P, 8, 8 },
	{ DRM_FORMAT_YUYV, SCALER_YUV422_1P_YUYV, 16, 16 },
	{ DRM_FORMAT_UYVY, SCALER_YUV422_1P_UYVY, 16, 16 },
	{ DRM_FORMAT_YVYU, SCALER_YUV422_1P_YVYU, 16, 16 },
	{ DRM_FORMAT_NV16, SCALER_YUV422_2P_UV, 8, 16 },
	{ DRM_FORMAT_NV61, SCALER_YUV422_2P_VU, 8, 16 },
	{ DRM_FORMAT_YUV422, SCALER_YUV422_3P, 8, 16 },
	{ DRM_FORMAT_NV24, SCALER_YUV444_2P_UV, 16, 16 },
	{ DRM_FORMAT_NV42, SCALER_YUV444_2P_VU, 16, 16 },
	{ DRM_FORMAT_YUV444, SCALER_YUV444_3P, 16, 16 },
	{ DRM_FORMAT_RGB565, SCALER_RGB_565, 0, 0 },
	{ DRM_FORMAT_XRGB1555, SCALER_ARGB1555, 0, 0 },
	{ DRM_FORMAT_ARGB1555, SCALER_ARGB1555, 0, 0 },
	{ DRM_FORMAT_XRGB4444, SCALER_ARGB4444, 0, 0 },
	{ DRM_FORMAT_ARGB4444, SCALER_ARGB4444, 0, 0 },
	{ DRM_FORMAT_XRGB8888, SCALER_ARGB8888, 0, 0 },
	{ DRM_FORMAT_ARGB8888, SCALER_ARGB8888, 0, 0 },
	{ DRM_FORMAT_RGBX8888, SCALER_RGBA8888, 0, 0 },
	{ DRM_FORMAT_RGBA8888, SCALER_RGBA8888, 0, 0 },
};

static const struct scaler_format *scaler_get_format(u32 drm_fmt)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(scaler_formats); i++)
		if (scaler_formats[i].drm_fmt == drm_fmt)
			return &scaler_formats[i];

	return NULL;
}

static inline int scaler_reset(struct scaler_context *scaler)
{
	int retry = SCALER_RESET_WAIT_RETRIES;

	scaler_write(SCALER_CFG_SOFT_RESET, SCALER_CFG);
	do {
		cpu_relax();
	} while (--retry > 1 &&
		 scaler_read(SCALER_CFG) & SCALER_CFG_SOFT_RESET);
	do {
		cpu_relax();
		scaler_write(1, SCALER_INT_EN);
	} while (--retry > 0 && scaler_read(SCALER_INT_EN) != 1);

	return retry ? 0 : -EIO;
}

static inline void scaler_enable_int(struct scaler_context *scaler)
{
	u32 val;

	val = SCALER_INT_EN_TIMEOUT |
		SCALER_INT_EN_ILLEGAL_BLEND |
		SCALER_INT_EN_ILLEGAL_RATIO |
		SCALER_INT_EN_ILLEGAL_DST_HEIGHT |
		SCALER_INT_EN_ILLEGAL_DST_WIDTH |
		SCALER_INT_EN_ILLEGAL_DST_V_POS |
		SCALER_INT_EN_ILLEGAL_DST_H_POS |
		SCALER_INT_EN_ILLEGAL_DST_C_SPAN |
		SCALER_INT_EN_ILLEGAL_DST_Y_SPAN |

Annotation

Implementation Notes