1*8aeeb314SThomas Zimmermann // SPDX-License-Identifier: GPL-2.0-only
2*8aeeb314SThomas Zimmermann 
3*8aeeb314SThomas Zimmermann #include <linux/delay.h>
4*8aeeb314SThomas Zimmermann 
5*8aeeb314SThomas Zimmermann #include "mgag200_drv.h"
6*8aeeb314SThomas Zimmermann 
mgag200_bmc_disable_vidrst(struct mga_device * mdev)7*8aeeb314SThomas Zimmermann void mgag200_bmc_disable_vidrst(struct mga_device *mdev)
8*8aeeb314SThomas Zimmermann {
9*8aeeb314SThomas Zimmermann 	u8 tmp;
10*8aeeb314SThomas Zimmermann 	int iter_max;
11*8aeeb314SThomas Zimmermann 
12*8aeeb314SThomas Zimmermann 	/*
13*8aeeb314SThomas Zimmermann 	 * 1 - The first step is to inform the BMC of an upcoming mode
14*8aeeb314SThomas Zimmermann 	 * change. We are putting the misc<0> to output.
15*8aeeb314SThomas Zimmermann 	 */
16*8aeeb314SThomas Zimmermann 
17*8aeeb314SThomas Zimmermann 	WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL);
18*8aeeb314SThomas Zimmermann 	tmp = RREG8(DAC_DATA);
19*8aeeb314SThomas Zimmermann 	tmp |= 0x10;
20*8aeeb314SThomas Zimmermann 	WREG_DAC(MGA1064_GEN_IO_CTL, tmp);
21*8aeeb314SThomas Zimmermann 
22*8aeeb314SThomas Zimmermann 	/* we are putting a 1 on the misc<0> line */
23*8aeeb314SThomas Zimmermann 	WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
24*8aeeb314SThomas Zimmermann 	tmp = RREG8(DAC_DATA);
25*8aeeb314SThomas Zimmermann 	tmp |= 0x10;
26*8aeeb314SThomas Zimmermann 	WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
27*8aeeb314SThomas Zimmermann 
28*8aeeb314SThomas Zimmermann 	/*
29*8aeeb314SThomas Zimmermann 	 * 2- Second step to mask any further scan request. This is
30*8aeeb314SThomas Zimmermann 	 * done by asserting the remfreqmsk bit (XSPAREREG<7>)
31*8aeeb314SThomas Zimmermann 	 */
32*8aeeb314SThomas Zimmermann 
33*8aeeb314SThomas Zimmermann 	WREG8(DAC_INDEX, MGA1064_SPAREREG);
34*8aeeb314SThomas Zimmermann 	tmp = RREG8(DAC_DATA);
35*8aeeb314SThomas Zimmermann 	tmp |= 0x80;
36*8aeeb314SThomas Zimmermann 	WREG_DAC(MGA1064_SPAREREG, tmp);
37*8aeeb314SThomas Zimmermann 
38*8aeeb314SThomas Zimmermann 	/*
39*8aeeb314SThomas Zimmermann 	 * 3a- The third step is to verify if there is an active scan.
40*8aeeb314SThomas Zimmermann 	 * We are waiting for a 0 on remhsyncsts <XSPAREREG<0>).
41*8aeeb314SThomas Zimmermann 	 */
42*8aeeb314SThomas Zimmermann 	iter_max = 300;
43*8aeeb314SThomas Zimmermann 	while (!(tmp & 0x1) && iter_max) {
44*8aeeb314SThomas Zimmermann 		WREG8(DAC_INDEX, MGA1064_SPAREREG);
45*8aeeb314SThomas Zimmermann 		tmp = RREG8(DAC_DATA);
46*8aeeb314SThomas Zimmermann 		udelay(1000);
47*8aeeb314SThomas Zimmermann 		iter_max--;
48*8aeeb314SThomas Zimmermann 	}
49*8aeeb314SThomas Zimmermann 
50*8aeeb314SThomas Zimmermann 	/*
51*8aeeb314SThomas Zimmermann 	 * 3b- This step occurs only if the remove is actually
52*8aeeb314SThomas Zimmermann 	 * scanning. We are waiting for the end of the frame which is
53*8aeeb314SThomas Zimmermann 	 * a 1 on remvsyncsts (XSPAREREG<1>)
54*8aeeb314SThomas Zimmermann 	 */
55*8aeeb314SThomas Zimmermann 	if (iter_max) {
56*8aeeb314SThomas Zimmermann 		iter_max = 300;
57*8aeeb314SThomas Zimmermann 		while ((tmp & 0x2) && iter_max) {
58*8aeeb314SThomas Zimmermann 			WREG8(DAC_INDEX, MGA1064_SPAREREG);
59*8aeeb314SThomas Zimmermann 			tmp = RREG8(DAC_DATA);
60*8aeeb314SThomas Zimmermann 			udelay(1000);
61*8aeeb314SThomas Zimmermann 			iter_max--;
62*8aeeb314SThomas Zimmermann 		}
63*8aeeb314SThomas Zimmermann 	}
64*8aeeb314SThomas Zimmermann }
65*8aeeb314SThomas Zimmermann 
mgag200_bmc_enable_vidrst(struct mga_device * mdev)66*8aeeb314SThomas Zimmermann void mgag200_bmc_enable_vidrst(struct mga_device *mdev)
67*8aeeb314SThomas Zimmermann {
68*8aeeb314SThomas Zimmermann 	u8 tmp;
69*8aeeb314SThomas Zimmermann 
70*8aeeb314SThomas Zimmermann 	/* Ensure that the vrsten and hrsten are set */
71*8aeeb314SThomas Zimmermann 	WREG8(MGAREG_CRTCEXT_INDEX, 1);
72*8aeeb314SThomas Zimmermann 	tmp = RREG8(MGAREG_CRTCEXT_DATA);
73*8aeeb314SThomas Zimmermann 	WREG8(MGAREG_CRTCEXT_DATA, tmp | 0x88);
74*8aeeb314SThomas Zimmermann 
75*8aeeb314SThomas Zimmermann 	/* Assert rstlvl2 */
76*8aeeb314SThomas Zimmermann 	WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
77*8aeeb314SThomas Zimmermann 	tmp = RREG8(DAC_DATA);
78*8aeeb314SThomas Zimmermann 	tmp |= 0x8;
79*8aeeb314SThomas Zimmermann 	WREG8(DAC_DATA, tmp);
80*8aeeb314SThomas Zimmermann 
81*8aeeb314SThomas Zimmermann 	udelay(10);
82*8aeeb314SThomas Zimmermann 
83*8aeeb314SThomas Zimmermann 	/* Deassert rstlvl2 */
84*8aeeb314SThomas Zimmermann 	tmp &= ~0x08;
85*8aeeb314SThomas Zimmermann 	WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
86*8aeeb314SThomas Zimmermann 	WREG8(DAC_DATA, tmp);
87*8aeeb314SThomas Zimmermann 
88*8aeeb314SThomas Zimmermann 	/* Remove mask of scan request */
89*8aeeb314SThomas Zimmermann 	WREG8(DAC_INDEX, MGA1064_SPAREREG);
90*8aeeb314SThomas Zimmermann 	tmp = RREG8(DAC_DATA);
91*8aeeb314SThomas Zimmermann 	tmp &= ~0x80;
92*8aeeb314SThomas Zimmermann 	WREG8(DAC_DATA, tmp);
93*8aeeb314SThomas Zimmermann 
94*8aeeb314SThomas Zimmermann 	/* Put back a 0 on the misc<0> line */
95*8aeeb314SThomas Zimmermann 	WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
96*8aeeb314SThomas Zimmermann 	tmp = RREG8(DAC_DATA);
97*8aeeb314SThomas Zimmermann 	tmp &= ~0x10;
98*8aeeb314SThomas Zimmermann 	WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
99*8aeeb314SThomas Zimmermann }
100