ch9294.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. * Chrontel
  3. * CH9294 Dual Enhanced Graphics Clock Generator.
  4. */
  5. #include <u.h>
  6. #include <libc.h>
  7. #include <bio.h>
  8. #include "pci.h"
  9. #include "vga.h"
  10. typedef struct {
  11. char* name[2];
  12. ulong frequency[16];
  13. } Pattern;
  14. static Pattern patterns[] = {
  15. { "e", "E", /* Tseng */
  16. 50350000, 56644000, 65000000, 72000000, 80000000, 89800000, 63000000, 75000000,
  17. VgaFreq0, VgaFreq1, 31500000, 36000000, 40000000, 44900000, 50000000, 65000000,
  18. },
  19. { "g", "G", /* S3, IIT */
  20. VgaFreq0, VgaFreq1, 40000000, 72000000, 50000000, 77000000, 36000000, 44900000,
  21. 130000000, 120000000, 80000000, 31500000, 110000000, 65000000, 75000000, 94500000,
  22. },
  23. { "k", "K", /* Avance Logic */
  24. 50350000, 56644000, 89800000, 72000000, 75000000, 65000000, 63000000, 80000000,
  25. 57272000, 85000000, 94000000, 96000000, 100000000, 108000000, 110000000, 77000000,
  26. },
  27. { 0,
  28. },
  29. };
  30. static void
  31. init(Vga* vga, Ctlr* ctlr)
  32. {
  33. Pattern *pattern;
  34. char *p;
  35. int f, fmin, index, divisor, maxdivisor;
  36. if(ctlr->flag & Finit)
  37. return;
  38. if(vga->f[0] == 0)
  39. vga->f[0] = vga->mode->frequency;
  40. if((p = strchr(ctlr->name, '-')) == 0)
  41. error("%s: unknown pattern\n", ctlr->name);
  42. p++;
  43. for(pattern = patterns; pattern->name[0]; pattern++){
  44. if(strcmp(pattern->name[0], p) == 0)
  45. break;
  46. if(pattern->name[1] && strcmp(pattern->name[1], p) == 0)
  47. break;
  48. }
  49. if(pattern->name[0] == 0)
  50. error("%s: unknown pattern\n", ctlr->name);
  51. maxdivisor = 1;
  52. if(vga->ctlr && (vga->ctlr->flag & Hclkdiv))
  53. maxdivisor = 8;
  54. fmin = vga->f[0];
  55. for(index = 0; index < 16; index++){
  56. for(divisor = 1; divisor <= maxdivisor; divisor <<= 1){
  57. f = vga->f[0] - pattern->frequency[index]/divisor;
  58. if(f < 0)
  59. f = -f;
  60. if(f < fmin){
  61. /*vga->f = pattern->frequency[index];*/
  62. fmin = f;
  63. vga->d[0] = divisor;
  64. vga->i[0] = index;
  65. }
  66. }
  67. }
  68. if(fmin > (vga->f[0]*5)/100)
  69. error("%s: can't find frequency %ld\n", ctlr->name, vga->f[0]);
  70. ctlr->flag |= Finit;
  71. }
  72. Ctlr ch9294 = {
  73. "ch9294", /* name */
  74. 0, /* snarf */
  75. 0, /* options */
  76. init, /* init */
  77. 0, /* load */
  78. 0, /* dump */
  79. };