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