Annotation of ntddk/src/video/miniport/s3/nnclk.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1990-1993  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     s3.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This module contains the code to set the number nine clock.
        !            12: 
        !            13: Environment:
        !            14: 
        !            15:     Kernel mode
        !            16: 
        !            17: Revision History:
        !            18: 
        !            19: --*/
        !            20: 
        !            21: #include "s3.h"
        !            22: 
        !            23: #define PROM_WRITE_INDEX        0x51
        !            24: #define PROM_WRITE_BIT          0x80
        !            25: #define SSW_READ_ENBL_INDEX     0x55
        !            26: #define SSW_READ_ENBL_BIT       0x04
        !            27: #define SSW_READ_PORT           0x03C8
        !            28: #define SSW_WRITE_INDEX         0x5C
        !            29: #define LOCK_INDEX              0x39
        !            30: #define UNLOCK_PATTERN          0xA0
        !            31: #define LOCK_INDEX2             0x38
        !            32: #define UNLOCK_PATTERN2         0x48
        !            33: #define BIOS_32K_INDEX          0x31
        !            34: #define BIOS_32K_BIT            0x80
        !            35: #define MODE_CTRL_INDEX         0x42
        !            36: 
        !            37: #define GOPA_FLSEL              0x40
        !            38: #define GOPB_ENABLE             0x80
        !            39: #define GOPB_SLED               0x40
        !            40: #define GOPB_FLSEL              0x20
        !            41: #define GOPB_BURN               0x10
        !            42: 
        !            43: 
        !            44: long calc_clock(long, int);
        !            45: long gcd(long, long);
        !            46: VOID set_clock(
        !            47:     PHW_DEVICE_EXTENSION HwDeviceExtension,
        !            48:     LONG clock_value);
        !            49: 
        !            50: 
        !            51: #undef  MIN
        !            52: #define MIN(a, b)               (((a) < (b)) ? (a) : (b))
        !            53: #undef  MAX
        !            54: #define MAX(a, b)               (((a) > (b)) ? (a) : (b))
        !            55: #define CRYSTAL_FREQUENCY       (14318180 * 2)
        !            56: #define MIN_VCO_FREQUENCY       50000000
        !            57: #define MAX_POST_SCALE          285000000
        !            58: #define MAX_NUMERATOR           130
        !            59: #define MAX_DENOMINATOR         MIN(129, CRYSTAL_FREQUENCY / 400000)
        !            60: #define MIN_DENOMINATOR         MAX(3, CRYSTAL_FREQUENCY / 2000000)
        !            61: 
        !            62:   /* Set up the softswitch write value */
        !            63: 
        !            64: #define CLOCK(x) VideoPortWritePortUchar(CRT_DATA_REG, (UCHAR)(iotemp | (x)))
        !            65: #define C_DATA  2
        !            66: #define C_CLK   1
        !            67: #define C_BOTH  3
        !            68: #define C_NONE  0
        !            69: 
        !            70: /* Index register frequency ranges for ICD2061A chip */
        !            71: 
        !            72: static long     vclk_range[16] = {
        !            73:                 0, /* should be MIN_VCO_FREQUENCY, but that causes problems. */
        !            74:          51000000,
        !            75:          53200000,
        !            76:          58500000,
        !            77:          60700000,
        !            78:          64400000,
        !            79:          66800000,
        !            80:          73500000,
        !            81:          75600000,
        !            82:          80900000,
        !            83:          83200000,
        !            84:          91500000,
        !            85:         100000000,
        !            86:         120000000,
        !            87:         MAX_POST_SCALE,
        !            88:                 0,
        !            89:         };
        !            90: 
        !            91: /****************************************************************************
        !            92:  * calc_clock
        !            93:  *
        !            94:  * Usage: clock frequency [set]
        !            95:  *      frequency is specified in MHz
        !            96:  *
        !            97:  ***************************************************************************/
        !            98: long calc_clock(frequency, select)
        !            99: 
        !           100: register long   frequency;               /* in Hz */
        !           101: int select;
        !           102: {
        !           103:   register long         index;
        !           104:   long                  temp;
        !           105:   long                  min_m, min_n, min_diff;
        !           106:   long                  diff;
        !           107: 
        !           108:   int clock_m;
        !           109:   int clock_n;
        !           110:   int clock_p;
        !           111: 
        !           112:   min_diff = 0xFFFFFFF;
        !           113:   min_n = 1;
        !           114:   min_m = 1;
        !           115: 
        !           116:   /* Calculate 18 bit clock value */
        !           117: 
        !           118:   clock_p = 0;
        !           119:   if (frequency < MIN_VCO_FREQUENCY)
        !           120:     clock_p = 1;
        !           121:   if (frequency < MIN_VCO_FREQUENCY / 2)
        !           122:     clock_p = 2;
        !           123:   if (frequency < MIN_VCO_FREQUENCY / 4)
        !           124:     clock_p = 3;
        !           125: 
        !           126:   frequency <<= clock_p;
        !           127: 
        !           128:   for (clock_n = 4; clock_n <= MAX_NUMERATOR; clock_n++)
        !           129:     {
        !           130:       index = CRYSTAL_FREQUENCY / (frequency / clock_n);
        !           131: 
        !           132:       if (index > MAX_DENOMINATOR)
        !           133:         index = MAX_DENOMINATOR;
        !           134:       if (index < MIN_DENOMINATOR)
        !           135:         index = MIN_DENOMINATOR;
        !           136: 
        !           137:       for (clock_m = index - 3; clock_m < index + 4; clock_m++)
        !           138:         if (clock_m >= MIN_DENOMINATOR && clock_m <= MAX_DENOMINATOR)
        !           139:           {
        !           140:             diff = (CRYSTAL_FREQUENCY / clock_m) * clock_n - frequency;
        !           141: 
        !           142:             if (diff < 0)
        !           143:               diff = -diff;
        !           144: 
        !           145:             if (min_m * gcd(clock_m, clock_n) / gcd(min_m, min_n) == clock_m &&
        !           146:               min_n * gcd(clock_m, clock_n) / gcd(min_m, min_n) == clock_n)
        !           147: 
        !           148:             if (diff > min_diff)
        !           149:               diff = min_diff;
        !           150: 
        !           151:             if (diff <= min_diff)
        !           152:               {
        !           153:                 min_diff = diff;
        !           154:                 min_m = clock_m;
        !           155:                 min_n = clock_n;
        !           156:               }
        !           157:           }
        !           158:     }
        !           159: 
        !           160:   clock_m = min_m;
        !           161:   clock_n = min_n;
        !           162: 
        !           163:   /* Calculate the index */
        !           164: 
        !           165:   temp = (((CRYSTAL_FREQUENCY / 2) * clock_n) / clock_m) << 1;
        !           166:   for (index = 0; vclk_range[index + 1] < temp && index < 15; index++)
        !           167:     ;
        !           168: 
        !           169:   /* Pack the clock value for the frequency snthesizer */
        !           170: 
        !           171:   temp = (((long)clock_n - 3) << 11) + ((clock_m - 2) << 1)
        !           172:                 + (clock_p << 8) + (index << 18) + ((long)select << 22);
        !           173: 
        !           174:   return temp;
        !           175: 
        !           176: }
        !           177: 
        !           178: /******************************************************************************
        !           179:  *
        !           180:  *****************************************************************************/
        !           181: VOID set_clock(
        !           182:     PHW_DEVICE_EXTENSION HwDeviceExtension,
        !           183:     LONG clock_value)                   /* 7bits M, 7bits N, 2bits P */
        !           184: {
        !           185:   register long         index;
        !           186:   register char         iotemp;
        !           187:   int select;
        !           188: 
        !           189:   select = (clock_value >> 22) & 3;
        !           190: 
        !           191:   /* Unlock the S3 registers */
        !           192: 
        !           193:   VideoPortWritePortUchar(CRT_ADDRESS_REG, LOCK_INDEX);
        !           194:   VideoPortWritePortUchar(CRT_DATA_REG, UNLOCK_PATTERN);
        !           195: 
        !           196:   /* Shut off screen */
        !           197: 
        !           198:   VideoPortWritePortUchar(SEQ_ADDRESS_REG, 0x01);
        !           199:   iotemp = VideoPortReadPortUchar(SEQ_DATA_REG);
        !           200:   VideoPortWritePortUchar(SEQ_DATA_REG, (UCHAR)(iotemp | 0x20));
        !           201: 
        !           202:   /* set clock input to 11 binary */
        !           203: 
        !           204:   iotemp = VideoPortReadPortUchar(MISC_OUTPUT_REG_READ);
        !           205:   VideoPortWritePortUchar(MISC_OUTPUT_REG_WRITE, (UCHAR)(iotemp | 0x0C));
        !           206: 
        !           207:   VideoPortWritePortUchar(CRT_ADDRESS_REG, SSW_WRITE_INDEX);
        !           208:   VideoPortWritePortUchar(CRT_DATA_REG, 0);
        !           209: 
        !           210:   VideoPortWritePortUchar(CRT_ADDRESS_REG, MODE_CTRL_INDEX);
        !           211:   iotemp = VideoPortReadPortUchar(CRT_DATA_REG) & 0xF0;
        !           212: 
        !           213: 
        !           214:   /* Program the IC Designs 2061A frequency generator */
        !           215: 
        !           216:   CLOCK(C_NONE);
        !           217: 
        !           218:   /* Unlock sequence */
        !           219: 
        !           220:   CLOCK(C_DATA);
        !           221:   for (index = 0; index < 6; index++)
        !           222:     {
        !           223:       CLOCK(C_BOTH);
        !           224:       CLOCK(C_DATA);
        !           225:     }
        !           226:   CLOCK(C_NONE);
        !           227:   CLOCK(C_CLK);
        !           228:   CLOCK(C_NONE);
        !           229:   CLOCK(C_CLK);
        !           230: 
        !           231:   /* Program the 24 bit value into REG0 */
        !           232: 
        !           233:   for (index = 0; index < 24; index++)
        !           234:     {
        !           235:       /* Clock in the next bit */
        !           236:       clock_value >>= 1;
        !           237:       if (clock_value & 1)
        !           238:         {
        !           239:           CLOCK(C_CLK);
        !           240:           CLOCK(C_NONE);
        !           241:           CLOCK(C_DATA);
        !           242:           CLOCK(C_BOTH);
        !           243:         }
        !           244:       else
        !           245:         {
        !           246:           CLOCK(C_BOTH);
        !           247:           CLOCK(C_DATA);
        !           248:           CLOCK(C_NONE);
        !           249:           CLOCK(C_CLK);
        !           250:         }
        !           251:     }
        !           252: 
        !           253:   CLOCK(C_BOTH);
        !           254:   CLOCK(C_DATA);
        !           255:   CLOCK(C_BOTH);
        !           256: 
        !           257:   /* If necessary, reprogram other ICD2061A registers to defaults */
        !           258: 
        !           259:   /* Select the CLOCK in the frequency synthesizer */
        !           260: 
        !           261:   CLOCK(C_NONE | select);
        !           262: 
        !           263:   /* Turn screen back on */
        !           264: 
        !           265:   VideoPortWritePortUchar(SEQ_ADDRESS_REG, 0x01);
        !           266:   iotemp = VideoPortReadPortUchar(SEQ_DATA_REG);
        !           267:   VideoPortWritePortUchar(SEQ_DATA_REG, (UCHAR) (iotemp & 0xDF));
        !           268: 
        !           269: }
        !           270: 
        !           271: /******************************************************************************
        !           272:  * Number theoretic function - GCD (Greatest Common Divisor)
        !           273:  *****************************************************************************/
        !           274: long gcd(a, b)
        !           275: register long a, b;
        !           276: {
        !           277:   register long c = a % b;
        !           278:   while (c)
        !           279:     a = b, b = c, c = a % b;
        !           280:   return b;
        !           281: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.