1 // SPDX-License-Identifier: GPL-2.0-only
2
3 #include <linux/delay.h>
4
5 #include "mgag200_drv.h"
6
mgag200_bmc_disable_vidrst(struct mga_device * mdev)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
mgag200_bmc_enable_vidrst(struct mga_device * mdev)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