--- zzzz-none-000/linux-2.6.39.4/arch/x86/kernel/tsc.c 2011-08-03 19:43:28.000000000 +0000 +++ puma6-arm-6490-729/linux-2.6.39.4/arch/x86/kernel/tsc.c 2021-11-10 13:23:10.000000000 +0000 @@ -20,6 +20,13 @@ #include #include +/****************************************************************** + + Includes Intel Corporation's changes/modifications dated: 07/2011. + Changed/modified portions - Copyright(c) 2011, Intel Corporation. + +******************************************************************/ + unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */ EXPORT_SYMBOL(cpu_khz); @@ -217,6 +224,41 @@ pitcnt = 0; tscmax = 0; tscmin = ULONG_MAX; + +#ifdef CONFIG_ARCH_GEN3 +/* + * The following code is for Intel Media SOC Gen3 B0 and B1 workaround. +*/ + +/* + * The 8254 timer flop has an issue between the reset and set pin of a flop. + * This causes a race condition to happen and the value can change based on + * clock sku. The workaround for this silicon issue uses a polling method which + * is not affected by race condition. If this workaround is not applied, then the + * cpu MHz entry in /proc/cpuinfo may show the wrong information. This workaround + * is for errata number 22 in Errata - A Step. +*/ + { + u8 count1; + u8 count2; + outb(0x80, 0x43); + count1 = inb(0x42); + count2 = inb(0x42); + while (count1 >= 0x20 || count2 != 0) { + t2 = get_cycles(); + delta = t2 - tsc; + tsc = t2; + if ((unsigned long) delta < tscmin) + tscmin = (unsigned int) delta; + if ((unsigned long) delta > tscmax) + tscmax = (unsigned int) delta; + pitcnt++; + outb(0x80, 0x43); + count1 = inb(0x42); + count2 = inb(0x42); + } + } +#else while ((inb(0x61) & 0x20) == 0) { t2 = get_cycles(); delta = t2 - tsc; @@ -227,7 +269,7 @@ tscmax = (unsigned int) delta; pitcnt++; } - +#endif /* * Sanity checks: *