100 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2 3#include <linux/delay.h>4 5#include <drm/drm_atomic_helper.h>6#include <drm/drm_edid.h>7#include <drm/drm_managed.h>8#include <drm/drm_probe_helper.h>9 10#include "mgag200_drv.h"11 12void mgag200_bmc_stop_scanout(struct mga_device *mdev)13{14 u8 tmp;15 int iter_max;16 17 /*18 * 1 - The first step is to inform the BMC of an upcoming mode19 * change. We are putting the misc<0> to output.20 */21 22 WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL);23 tmp = RREG8(DAC_DATA);24 tmp |= 0x10;25 WREG_DAC(MGA1064_GEN_IO_CTL, tmp);26 27 /* we are putting a 1 on the misc<0> line */28 WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);29 tmp = RREG8(DAC_DATA);30 tmp |= 0x10;31 WREG_DAC(MGA1064_GEN_IO_DATA, tmp);32 33 /*34 * 2- Second step to mask any further scan request. This is35 * done by asserting the remfreqmsk bit (XSPAREREG<7>)36 */37 38 WREG8(DAC_INDEX, MGA1064_SPAREREG);39 tmp = RREG8(DAC_DATA);40 tmp |= 0x80;41 WREG_DAC(MGA1064_SPAREREG, tmp);42 43 /*44 * 3a- The third step is to verify if there is an active scan.45 * We are waiting for a 0 on remhsyncsts <XSPAREREG<0>).46 */47 iter_max = 300;48 while (!(tmp & 0x1) && iter_max) {49 WREG8(DAC_INDEX, MGA1064_SPAREREG);50 tmp = RREG8(DAC_DATA);51 udelay(1000);52 iter_max--;53 }54 55 /*56 * 3b- This step occurs only if the remove is actually57 * scanning. We are waiting for the end of the frame which is58 * a 1 on remvsyncsts (XSPAREREG<1>)59 */60 if (iter_max) {61 iter_max = 300;62 while ((tmp & 0x2) && iter_max) {63 WREG8(DAC_INDEX, MGA1064_SPAREREG);64 tmp = RREG8(DAC_DATA);65 udelay(1000);66 iter_max--;67 }68 }69}70 71void mgag200_bmc_start_scanout(struct mga_device *mdev)72{73 u8 tmp;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