1// SPDX-License-Identifier: GPL-2.0-only
2
3#include <linux/delay.h>
4
5#include "mgag200_drv.h"
6
7void 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
66void 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