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