mgag200_bmc.c 2.1 KB

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