drivers/gpu/drm/udl/udl_modeset.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/udl/udl_modeset.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/udl/udl_modeset.c
Extension
.c
Size
15699 bytes
Lines
548
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

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2012 Red Hat
 *
 * based in parts on udlfb.c:
 * Copyright (C) 2009 Roberto De Ioris <roberto@unbit.it>
 * Copyright (C) 2009 Jaya Kumar <jayakumar.lkml@gmail.com>
 * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com>
 */

#include <linux/bitfield.h>

#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_edid.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>

#include "udl_drv.h"
#include "udl_edid.h"
#include "udl_proto.h"

/*
 * All DisplayLink bulk operations start with 0xaf (UDL_MSG_BULK), followed by
 * a specific command code. All operations are written to a command buffer, which
 * the driver sends to the device.
 */
static char *udl_set_register(char *buf, u8 reg, u8 val)
{
	*buf++ = UDL_MSG_BULK;
	*buf++ = UDL_CMD_WRITEREG;
	*buf++ = reg;
	*buf++ = val;

	return buf;
}

static char *udl_vidreg_lock(char *buf)
{
	return udl_set_register(buf, UDL_REG_VIDREG, UDL_VIDREG_LOCK);
}

static char *udl_vidreg_unlock(char *buf)
{
	return udl_set_register(buf, UDL_REG_VIDREG, UDL_VIDREG_UNLOCK);
}

static char *udl_set_blank_mode(char *buf, u8 mode)
{
	return udl_set_register(buf, UDL_REG_BLANKMODE, mode);
}

static char *udl_set_color_depth(char *buf, u8 selection)
{
	return udl_set_register(buf, UDL_REG_COLORDEPTH, selection);
}

static char *udl_set_base16bpp(char *buf, u32 base)
{
	/* the base pointer is 24 bits wide, 0x20 is hi byte. */
	u8 reg20 = FIELD_GET(UDL_BASE_ADDR2_MASK, base);
	u8 reg21 = FIELD_GET(UDL_BASE_ADDR1_MASK, base);
	u8 reg22 = FIELD_GET(UDL_BASE_ADDR0_MASK, base);

	buf = udl_set_register(buf, UDL_REG_BASE16BPP_ADDR2, reg20);
	buf = udl_set_register(buf, UDL_REG_BASE16BPP_ADDR1, reg21);
	buf = udl_set_register(buf, UDL_REG_BASE16BPP_ADDR0, reg22);

	return buf;
}

/*
 * DisplayLink HW has separate 16bpp and 8bpp framebuffers.
 * In 24bpp modes, the low 323 RGB bits go in the 8bpp framebuffer
 */
static char *udl_set_base8bpp(char *buf, u32 base)
{
	/* the base pointer is 24 bits wide, 0x26 is hi byte. */
	u8 reg26 = FIELD_GET(UDL_BASE_ADDR2_MASK, base);
	u8 reg27 = FIELD_GET(UDL_BASE_ADDR1_MASK, base);
	u8 reg28 = FIELD_GET(UDL_BASE_ADDR0_MASK, base);

Annotation

Implementation Notes