drivers/gpu/drm/mgag200/mgag200_bmc.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/mgag200/mgag200_bmc.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/mgag200/mgag200_bmc.c
Extension
.c
Size
2103 bytes
Lines
93
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

#include <linux/delay.h>
#include <linux/iopoll.h>

#include <drm/drm_atomic_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_managed.h>
#include <drm/drm_probe_helper.h>

#include "mgag200_drv.h"

void mgag200_bmc_stop_scanout(struct mga_device *mdev)
{
	u8 tmp;
	int ret;

	/*
	 * 1 - The first step is to inform the BMC of an upcoming mode
	 * change. We are putting the misc<0> to output.
	 */

	WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL);
	tmp = RREG8(DAC_DATA);
	tmp |= 0x10;
	WREG_DAC(MGA1064_GEN_IO_CTL, tmp);

	/* we are putting a 1 on the misc<0> line */
	WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
	tmp = RREG8(DAC_DATA);
	tmp |= 0x10;
	WREG_DAC(MGA1064_GEN_IO_DATA, tmp);

	/*
	 * 2- Second step to mask any further scan request. This is
	 * done by asserting the remfreqmsk bit (XSPAREREG<7>)
	 */

	WREG8(DAC_INDEX, MGA1064_SPAREREG);
	tmp = RREG8(DAC_DATA);
	tmp |= 0x80;
	WREG_DAC(MGA1064_SPAREREG, tmp);

	/*
	 * 3a- The third step is to verify if there is an active scan.
	 * We are waiting for a 0 on remhsyncsts (<XSPAREREG<0>).
	 */
	ret = read_poll_timeout(RREG_DAC, tmp, !(tmp & 0x1),
				1000, 300000, false,
				MGA1064_SPAREREG);
	if (ret == -ETIMEDOUT)
		return;

	/*
	 * 3b- This step occurs only if the remote BMC is actually
	 * scanning. We are waiting for the end of the frame which is
	 * a 1 on remvsyncsts (XSPAREREG<1>)
	 */
	(void)read_poll_timeout(RREG_DAC, tmp, (tmp & 0x2),
				1000, 300000, false,
				MGA1064_SPAREREG);
}

void mgag200_bmc_start_scanout(struct mga_device *mdev)
{
	u8 tmp;

	/* Assert rstlvl2 */
	WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
	tmp = RREG8(DAC_DATA);
	tmp |= 0x8;
	WREG8(DAC_DATA, tmp);

	udelay(10);

	/* Deassert rstlvl2 */
	tmp &= ~0x08;
	WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
	WREG8(DAC_DATA, tmp);

	/* Remove mask of scan request */
	WREG8(DAC_INDEX, MGA1064_SPAREREG);
	tmp = RREG8(DAC_DATA);
	tmp &= ~0x80;
	WREG8(DAC_DATA, tmp);

	/* Put back a 0 on the misc<0> line */
	WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
	tmp = RREG8(DAC_DATA);
	tmp &= ~0x10;

Annotation

Implementation Notes