drivers/gpu/drm/logicvc/logicvc_drm.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/logicvc/logicvc_drm.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/logicvc/logicvc_drm.c
Extension
.c
Size
11717 bytes
Lines
506
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 (IS_ERR(clk)) {
			if (PTR_ERR(clk) == -ENOENT && clocks_map[i].optional)
				continue;

			drm_err(drm_dev, "Missing non-optional clock %s\n",
				clocks_map[i].name);

			ret = PTR_ERR(clk);
			goto error;
		}

		ret = clk_prepare_enable(clk);
		if (ret) {
			drm_err(drm_dev,
				"Failed to prepare and enable clock %s\n",
				clocks_map[i].name);
			goto error;
		}

		*clocks_map[i].clk = clk;
	}

	return 0;

error:
	for (i = 0; i < ARRAY_SIZE(clocks_map); i++) {
		if (!*clocks_map[i].clk)
			continue;

		clk_disable_unprepare(*clocks_map[i].clk);
		*clocks_map[i].clk = NULL;
	}

	return ret;
}

static int logicvc_clocks_unprepare(struct logicvc_drm *logicvc)
{
	struct clk **clocks[] = {
		&logicvc->vclk,
		&logicvc->vclk2,
		&logicvc->lvdsclk,
		&logicvc->lvdsclkn,
	};
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(clocks); i++) {
		if (!*clocks[i])
			continue;

		clk_disable_unprepare(*clocks[i]);
		*clocks[i] = NULL;
	}

	return 0;
}

static const struct logicvc_drm_caps logicvc_drm_caps[] = {
	{
		.major		= 3,
		.layer_address	= false,
	},
	{
		.major		= 4,
		.layer_address	= true,
	},
	{
		.major		= 5,
		.layer_address	= true,
	},
};

static const struct logicvc_drm_caps *
logicvc_drm_caps_match(struct logicvc_drm *logicvc)
{
	struct drm_device *drm_dev = &logicvc->drm_dev;
	const struct logicvc_drm_caps *caps = NULL;
	unsigned int major, minor;
	char level;
	unsigned int i;
	u32 version;

	regmap_read(logicvc->regmap, LOGICVC_IP_VERSION_REG, &version);

	major = FIELD_GET(LOGICVC_IP_VERSION_MAJOR_MASK, version);
	minor = FIELD_GET(LOGICVC_IP_VERSION_MINOR_MASK, version);
	level = FIELD_GET(LOGICVC_IP_VERSION_LEVEL_MASK, version) + 'a';

	for (i = 0; i < ARRAY_SIZE(logicvc_drm_caps); i++) {
		if (logicvc_drm_caps[i].major &&

Annotation

Implementation Notes