162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#include <linux/delay.h>
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include "mgag200_drv.h"
662306a36Sopenharmony_ci
762306a36Sopenharmony_civoid mgag200_bmc_disable_vidrst(struct mga_device *mdev)
862306a36Sopenharmony_ci{
962306a36Sopenharmony_ci	u8 tmp;
1062306a36Sopenharmony_ci	int iter_max;
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci	/*
1362306a36Sopenharmony_ci	 * 1 - The first step is to inform the BMC of an upcoming mode
1462306a36Sopenharmony_ci	 * change. We are putting the misc<0> to output.
1562306a36Sopenharmony_ci	 */
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci	WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL);
1862306a36Sopenharmony_ci	tmp = RREG8(DAC_DATA);
1962306a36Sopenharmony_ci	tmp |= 0x10;
2062306a36Sopenharmony_ci	WREG_DAC(MGA1064_GEN_IO_CTL, tmp);
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci	/* we are putting a 1 on the misc<0> line */
2362306a36Sopenharmony_ci	WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
2462306a36Sopenharmony_ci	tmp = RREG8(DAC_DATA);
2562306a36Sopenharmony_ci	tmp |= 0x10;
2662306a36Sopenharmony_ci	WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci	/*
2962306a36Sopenharmony_ci	 * 2- Second step to mask any further scan request. This is
3062306a36Sopenharmony_ci	 * done by asserting the remfreqmsk bit (XSPAREREG<7>)
3162306a36Sopenharmony_ci	 */
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	WREG8(DAC_INDEX, MGA1064_SPAREREG);
3462306a36Sopenharmony_ci	tmp = RREG8(DAC_DATA);
3562306a36Sopenharmony_ci	tmp |= 0x80;
3662306a36Sopenharmony_ci	WREG_DAC(MGA1064_SPAREREG, tmp);
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	/*
3962306a36Sopenharmony_ci	 * 3a- The third step is to verify if there is an active scan.
4062306a36Sopenharmony_ci	 * We are waiting for a 0 on remhsyncsts <XSPAREREG<0>).
4162306a36Sopenharmony_ci	 */
4262306a36Sopenharmony_ci	iter_max = 300;
4362306a36Sopenharmony_ci	while (!(tmp & 0x1) && iter_max) {
4462306a36Sopenharmony_ci		WREG8(DAC_INDEX, MGA1064_SPAREREG);
4562306a36Sopenharmony_ci		tmp = RREG8(DAC_DATA);
4662306a36Sopenharmony_ci		udelay(1000);
4762306a36Sopenharmony_ci		iter_max--;
4862306a36Sopenharmony_ci	}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	/*
5162306a36Sopenharmony_ci	 * 3b- This step occurs only if the remove is actually
5262306a36Sopenharmony_ci	 * scanning. We are waiting for the end of the frame which is
5362306a36Sopenharmony_ci	 * a 1 on remvsyncsts (XSPAREREG<1>)
5462306a36Sopenharmony_ci	 */
5562306a36Sopenharmony_ci	if (iter_max) {
5662306a36Sopenharmony_ci		iter_max = 300;
5762306a36Sopenharmony_ci		while ((tmp & 0x2) && iter_max) {
5862306a36Sopenharmony_ci			WREG8(DAC_INDEX, MGA1064_SPAREREG);
5962306a36Sopenharmony_ci			tmp = RREG8(DAC_DATA);
6062306a36Sopenharmony_ci			udelay(1000);
6162306a36Sopenharmony_ci			iter_max--;
6262306a36Sopenharmony_ci		}
6362306a36Sopenharmony_ci	}
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_civoid mgag200_bmc_enable_vidrst(struct mga_device *mdev)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	u8 tmp;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	/* Ensure that the vrsten and hrsten are set */
7162306a36Sopenharmony_ci	WREG8(MGAREG_CRTCEXT_INDEX, 1);
7262306a36Sopenharmony_ci	tmp = RREG8(MGAREG_CRTCEXT_DATA);
7362306a36Sopenharmony_ci	WREG8(MGAREG_CRTCEXT_DATA, tmp | 0x88);
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	/* Assert rstlvl2 */
7662306a36Sopenharmony_ci	WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
7762306a36Sopenharmony_ci	tmp = RREG8(DAC_DATA);
7862306a36Sopenharmony_ci	tmp |= 0x8;
7962306a36Sopenharmony_ci	WREG8(DAC_DATA, tmp);
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	udelay(10);
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	/* Deassert rstlvl2 */
8462306a36Sopenharmony_ci	tmp &= ~0x08;
8562306a36Sopenharmony_ci	WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
8662306a36Sopenharmony_ci	WREG8(DAC_DATA, tmp);
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	/* Remove mask of scan request */
8962306a36Sopenharmony_ci	WREG8(DAC_INDEX, MGA1064_SPAREREG);
9062306a36Sopenharmony_ci	tmp = RREG8(DAC_DATA);
9162306a36Sopenharmony_ci	tmp &= ~0x80;
9262306a36Sopenharmony_ci	WREG8(DAC_DATA, tmp);
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	/* Put back a 0 on the misc<0> line */
9562306a36Sopenharmony_ci	WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
9662306a36Sopenharmony_ci	tmp = RREG8(DAC_DATA);
9762306a36Sopenharmony_ci	tmp &= ~0x10;
9862306a36Sopenharmony_ci	WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
9962306a36Sopenharmony_ci}
100