162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#include <linux/delay.h> 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include "mgag200_drv.h" 662306a36Sopenharmony_ci 762306a36Sopenharmony_civoid mgag200_bmc_disable_vidrst(struct mga_device *mdev) 862306a36Sopenharmony_ci{ 962306a36Sopenharmony_ci u8 tmp; 1062306a36Sopenharmony_ci int iter_max; 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci /* 1362306a36Sopenharmony_ci * 1 - The first step is to inform the BMC of an upcoming mode 1462306a36Sopenharmony_ci * change. We are putting the misc<0> to output. 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL); 1862306a36Sopenharmony_ci tmp = RREG8(DAC_DATA); 1962306a36Sopenharmony_ci tmp |= 0x10; 2062306a36Sopenharmony_ci WREG_DAC(MGA1064_GEN_IO_CTL, tmp); 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci /* we are putting a 1 on the misc<0> line */ 2362306a36Sopenharmony_ci WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA); 2462306a36Sopenharmony_ci tmp = RREG8(DAC_DATA); 2562306a36Sopenharmony_ci tmp |= 0x10; 2662306a36Sopenharmony_ci WREG_DAC(MGA1064_GEN_IO_DATA, tmp); 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci /* 2962306a36Sopenharmony_ci * 2- Second step to mask any further scan request. This is 3062306a36Sopenharmony_ci * done by asserting the remfreqmsk bit (XSPAREREG<7>) 3162306a36Sopenharmony_ci */ 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci WREG8(DAC_INDEX, MGA1064_SPAREREG); 3462306a36Sopenharmony_ci tmp = RREG8(DAC_DATA); 3562306a36Sopenharmony_ci tmp |= 0x80; 3662306a36Sopenharmony_ci WREG_DAC(MGA1064_SPAREREG, tmp); 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci /* 3962306a36Sopenharmony_ci * 3a- The third step is to verify if there is an active scan. 4062306a36Sopenharmony_ci * We are waiting for a 0 on remhsyncsts <XSPAREREG<0>). 4162306a36Sopenharmony_ci */ 4262306a36Sopenharmony_ci iter_max = 300; 4362306a36Sopenharmony_ci while (!(tmp & 0x1) && iter_max) { 4462306a36Sopenharmony_ci WREG8(DAC_INDEX, MGA1064_SPAREREG); 4562306a36Sopenharmony_ci tmp = RREG8(DAC_DATA); 4662306a36Sopenharmony_ci udelay(1000); 4762306a36Sopenharmony_ci iter_max--; 4862306a36Sopenharmony_ci } 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci /* 5162306a36Sopenharmony_ci * 3b- This step occurs only if the remove is actually 5262306a36Sopenharmony_ci * scanning. We are waiting for the end of the frame which is 5362306a36Sopenharmony_ci * a 1 on remvsyncsts (XSPAREREG<1>) 5462306a36Sopenharmony_ci */ 5562306a36Sopenharmony_ci if (iter_max) { 5662306a36Sopenharmony_ci iter_max = 300; 5762306a36Sopenharmony_ci while ((tmp & 0x2) && iter_max) { 5862306a36Sopenharmony_ci WREG8(DAC_INDEX, MGA1064_SPAREREG); 5962306a36Sopenharmony_ci tmp = RREG8(DAC_DATA); 6062306a36Sopenharmony_ci udelay(1000); 6162306a36Sopenharmony_ci iter_max--; 6262306a36Sopenharmony_ci } 6362306a36Sopenharmony_ci } 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_civoid mgag200_bmc_enable_vidrst(struct mga_device *mdev) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci u8 tmp; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci /* Ensure that the vrsten and hrsten are set */ 7162306a36Sopenharmony_ci WREG8(MGAREG_CRTCEXT_INDEX, 1); 7262306a36Sopenharmony_ci tmp = RREG8(MGAREG_CRTCEXT_DATA); 7362306a36Sopenharmony_ci WREG8(MGAREG_CRTCEXT_DATA, tmp | 0x88); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci /* Assert rstlvl2 */ 7662306a36Sopenharmony_ci WREG8(DAC_INDEX, MGA1064_REMHEADCTL2); 7762306a36Sopenharmony_ci tmp = RREG8(DAC_DATA); 7862306a36Sopenharmony_ci tmp |= 0x8; 7962306a36Sopenharmony_ci WREG8(DAC_DATA, tmp); 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci udelay(10); 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci /* Deassert rstlvl2 */ 8462306a36Sopenharmony_ci tmp &= ~0x08; 8562306a36Sopenharmony_ci WREG8(DAC_INDEX, MGA1064_REMHEADCTL2); 8662306a36Sopenharmony_ci WREG8(DAC_DATA, tmp); 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci /* Remove mask of scan request */ 8962306a36Sopenharmony_ci WREG8(DAC_INDEX, MGA1064_SPAREREG); 9062306a36Sopenharmony_ci tmp = RREG8(DAC_DATA); 9162306a36Sopenharmony_ci tmp &= ~0x80; 9262306a36Sopenharmony_ci WREG8(DAC_DATA, tmp); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci /* Put back a 0 on the misc<0> line */ 9562306a36Sopenharmony_ci WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA); 9662306a36Sopenharmony_ci tmp = RREG8(DAC_DATA); 9762306a36Sopenharmony_ci tmp &= ~0x10; 9862306a36Sopenharmony_ci WREG_DAC(MGA1064_GEN_IO_DATA, tmp); 9962306a36Sopenharmony_ci} 100