drivers/gpu/drm/ast/ast_dp.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/ast/ast_dp.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/ast/ast_dp.c
Extension
.c
Size
15588 bytes
Lines
577
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 ast_astdp_mode_index_table_entry {
	unsigned int hdisplay;
	unsigned int vdisplay;
	unsigned int mode_index;
};

/* FIXME: Do refresh rate and flags actually matter? */
static const struct ast_astdp_mode_index_table_entry ast_astdp_mode_index_table[] = {
	{  320,  240, ASTDP_320x240_60 },
	{  400,  300, ASTDP_400x300_60 },
	{  512,  384, ASTDP_512x384_60 },
	{  640,  480, ASTDP_640x480_60 },
	{  800,  600, ASTDP_800x600_56 },
	{ 1024,  768, ASTDP_1024x768_60 },
	{ 1152,  864, ASTDP_1152x864_75 },
	{ 1280,  800, ASTDP_1280x800_60_RB },
	{ 1280, 1024, ASTDP_1280x1024_60 },
	{ 1360,  768, ASTDP_1366x768_60 }, // same as 1366x786
	{ 1366,  768, ASTDP_1366x768_60 },
	{ 1440,  900, ASTDP_1440x900_60_RB },
	{ 1600,  900, ASTDP_1600x900_60_RB },
	{ 1600, 1200, ASTDP_1600x1200_60 },
	{ 1680, 1050, ASTDP_1680x1050_60_RB },
	{ 1920, 1080, ASTDP_1920x1080_60 },
	{ 1920, 1200, ASTDP_1920x1200_60 },
	{ 0 }
};

struct ast_astdp_connector_state {
	struct drm_connector_state base;

	int mode_index;
};

static struct ast_astdp_connector_state *
to_ast_astdp_connector_state(const struct drm_connector_state *state)
{
	return container_of(state, struct ast_astdp_connector_state, base);
}

static int ast_astdp_get_mode_index(unsigned int hdisplay, unsigned int vdisplay)
{
	const struct ast_astdp_mode_index_table_entry *entry = ast_astdp_mode_index_table;

	while (entry->hdisplay && entry->vdisplay) {
		if (entry->hdisplay == hdisplay && entry->vdisplay == vdisplay)
			return entry->mode_index;
		++entry;
	}

	return -EINVAL;
}

static bool ast_astdp_is_connected(struct ast_device *ast)
{
	if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, AST_IO_VGACRDF_HPD))
		return false;
	/*
	 * HPD might be set even if no monitor is connected, so also check that
	 * the link training was successful.
	 */
	if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, AST_IO_VGACRDC_LINK_SUCCESS))
		return false;
	return true;
}

static int ast_astdp_read_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
{
	struct ast_device *ast = data;
	size_t rdlen = round_up(len, 4);
	int ret = 0;
	unsigned int i;

	if (block > 0)
		return -EIO; /* extension headers not supported */

	/*
	 * Protect access to I/O registers from concurrent modesetting
	 * by acquiring the I/O-register lock.
	 */
	mutex_lock(&ast->modeset_lock);

	/* Start reading EDID data */
	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xe5, (u8)~AST_IO_VGACRE5_EDID_READ_DONE, 0x00);

	for (i = 0; i < rdlen; i += 4) {
		unsigned int offset;
		unsigned int j;
		u8 ediddata[4];
		u8 vgacre4;

Annotation

Implementation Notes