mgag200_bmc.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <linux/delay.h>
  3. #include <linux/iopoll.h>
  4. #include <drm/drm_atomic_helper.h>
  5. #include <drm/drm_edid.h>
  6. #include <drm/drm_managed.h>
  7. #include <drm/drm_probe_helper.h>
  8. #include "mgag200_drv.h"
  9. void mgag200_bmc_stop_scanout(struct mga_device *mdev)
  10. {
  11. u8 tmp;
  12. int ret;
  13. /*
  14. * 1 - The first step is to inform the BMC of an upcoming mode
  15. * change. We are putting the misc<0> to output.
  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. /* we are putting a 1 on the misc<0> line */
  22. WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
  23. tmp = RREG8(DAC_DATA);
  24. tmp |= 0x10;
  25. WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
  26. /*
  27. * 2- Second step to mask any further scan request. This is
  28. * done by asserting the remfreqmsk bit (XSPAREREG<7>)
  29. */
  30. WREG8(DAC_INDEX, MGA1064_SPAREREG);
  31. tmp = RREG8(DAC_DATA);
  32. tmp |= 0x80;
  33. WREG_DAC(MGA1064_SPAREREG, tmp);
  34. /*
  35. * 3a- The third step is to verify if there is an active scan.
  36. * We are waiting for a 0 on remhsyncsts (<XSPAREREG<0>).
  37. */
  38. ret = read_poll_timeout(RREG_DAC, tmp, !(tmp & 0x1),
  39. 1000, 300000, false,
  40. MGA1064_SPAREREG);
  41. if (ret == -ETIMEDOUT)
  42. return;
  43. /*
  44. * 3b- This step occurs only if the remote BMC is actually
  45. * scanning. We are waiting for the end of the frame which is
  46. * a 1 on remvsyncsts (XSPAREREG<1>)
  47. */
  48. (void)read_poll_timeout(RREG_DAC, tmp, (tmp & 0x2),
  49. 1000, 300000, false,
  50. MGA1064_SPAREREG);
  51. }
  52. void mgag200_bmc_start_scanout(struct mga_device *mdev)
  53. {
  54. u8 tmp;
  55. /* Assert rstlvl2 */
  56. WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
  57. tmp = RREG8(DAC_DATA);
  58. tmp |= 0x8;
  59. WREG8(DAC_DATA, tmp);
  60. udelay(10);
  61. /* Deassert rstlvl2 */
  62. tmp &= ~0x08;
  63. WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
  64. WREG8(DAC_DATA, tmp);
  65. /* Remove mask of scan request */
  66. WREG8(DAC_INDEX, MGA1064_SPAREREG);
  67. tmp = RREG8(DAC_DATA);
  68. tmp &= ~0x80;
  69. WREG8(DAC_DATA, tmp);
  70. /* Put back a 0 on the misc<0> line */
  71. WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
  72. tmp = RREG8(DAC_DATA);
  73. tmp &= ~0x10;
  74. WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
  75. }