att21c498.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include "pci.h"
  5. #include "vga.h"
  6. /*
  7. * ATT21C498 16-Bit Interface RAMDAC
  8. * PrecisionDAC Technology
  9. */
  10. enum {
  11. Cr0 = 0x00, /* Control register 0 */
  12. Midr = 0x01, /* Manufacturer's identification register */
  13. Didr = 0x02, /* Device identification register */
  14. Rtest = 0x03, /* Red signature analysis register */
  15. Gtest = 0x04, /* Green signature analysis register */
  16. Btest = 0x05, /* Blue signature analysis register */
  17. Nir = 0x06, /* number of indirect registers */
  18. };
  19. static void
  20. attdacio(uchar reg)
  21. {
  22. int i;
  23. /*
  24. * Access to the indirect registers is accomplished by reading
  25. * Pixmask 4 times, then subsequent reads cycle through the
  26. * indirect registers. Any I/O write to a direct register resets
  27. * the sequence.
  28. */
  29. inportb(PaddrW);
  30. for(i = 0; i < 4+reg; i++)
  31. inportb(Pixmask);
  32. }
  33. uchar
  34. attdaci(uchar reg)
  35. {
  36. uchar r;
  37. attdacio(reg);
  38. r = inportb(Pixmask);
  39. inportb(PaddrW);
  40. return r;
  41. }
  42. void
  43. attdaco(uchar reg, uchar data)
  44. {
  45. attdacio(reg);
  46. outportb(Pixmask, data);
  47. inportb(PaddrW);
  48. }
  49. static void
  50. options(Vga*, Ctlr* ctlr)
  51. {
  52. ctlr->flag |= Hpclk2x8|Foptions;
  53. }
  54. static void
  55. init(Vga* vga, Ctlr* ctlr)
  56. {
  57. ulong grade, pclk;
  58. char *p;
  59. /*
  60. * Part comes in -170, -130 and -110MHz speed-grades.
  61. * In 8-bit mode the max. PCLK is 80MHz for the -110 part
  62. * and 110MHz for the others. In 2x8-bit mode, the max.
  63. * PCLK is the speed-grade, using the 2x doubler.
  64. * We can use mode 2 (2x8-bit, internal clock doubler)
  65. * if connected to a suitable graphics chip, e.g. the
  66. * S3 Vision864.
  67. * Work out the part speed-grade from name. Name can have,
  68. * e.g. '-135' on the end for 135MHz part.
  69. */
  70. grade = 110000000;
  71. if(p = strrchr(ctlr->name, '-'))
  72. grade = strtoul(p+1, 0, 0) * 1000000;
  73. if(vga->ctlr && ((vga->ctlr->flag & Hpclk2x8) && vga->mode->z == 8))
  74. pclk = grade;
  75. else{
  76. if(grade == 110000000)
  77. pclk = 80000000;
  78. else
  79. pclk = 110000000;
  80. }
  81. /*
  82. * If we don't already have a desired pclk,
  83. * take it from the mode.
  84. * Check it's within range.
  85. */
  86. if(vga->f[0] == 0)
  87. vga->f[0] = vga->mode->frequency;
  88. /*
  89. * Determine whether to use 2x8-bit mode or not.
  90. * If yes and the clock has already been initialised,
  91. * initialise it again.
  92. */
  93. if(vga->ctlr && (vga->ctlr->flag & Hpclk2x8) && vga->mode->z == 8 && vga->f[0] > 80000000){
  94. vga->f[0] /= 2;
  95. resyncinit(vga, ctlr, Upclk2x8, 0);
  96. }
  97. if(vga->f[0] > pclk)
  98. error("%s: invalid pclk - %ld\n", ctlr->name, vga->f[0]);
  99. ctlr->flag |= Finit;
  100. }
  101. static void
  102. load(Vga* vga, Ctlr* ctlr)
  103. {
  104. uchar mode, x;
  105. /*
  106. * Put the chip to sleep.
  107. */
  108. x = attdaci(Cr0);
  109. attdaco(Cr0, x|0x04);
  110. mode = 0x00;
  111. if(ctlr->flag & Upclk2x8)
  112. mode = 0x20;
  113. /*
  114. * Set the mode in the RAMDAC, setting 6/8-bit colour
  115. * as appropriate and waking the chip back up.
  116. */
  117. if(vga->mode->z == 8 && 0)
  118. mode |= 0x02;
  119. attdaco(Cr0, mode);
  120. ctlr->flag |= Fload;
  121. }
  122. static void
  123. dump(Vga*, Ctlr* ctlr)
  124. {
  125. int i;
  126. printitem(ctlr->name, "");
  127. for(i = 0; i < Nir; i++)
  128. printreg(attdaci(i));
  129. }
  130. Ctlr att21c498 = {
  131. "att21c498", /* name */
  132. 0, /* snarf */
  133. options, /* options */
  134. init, /* init */
  135. load, /* load */
  136. dump, /* dump */
  137. };