/c2ctl

Intel Core and Core 2 frequency and voltage modification utility.

Primary LanguagePascalGNU General Public License v3.0GPL-3.0

0. Warning
==========

USE THIS PROGRAM AT YOU OWN RISK. IT MAY DAMAGE YOUR HARDWARE.


1. What the program can do
==========================
* It is intended for Intel Core and Core 2 CPU's, but it also may work 
  with other processors (namely processors with Intel SpeedStep)
* It runs under Linux
* It can change the processor frequency and voltage;
* enable SpeedStep (e.g. if it was disabled by the BIOS due to 
  overclocking);
* read out frequency and voltage information


2. Requirements
===============
* A Linux kernel with MSR support (Processor type and features --> 
  /dev/cpu/*/msr - Model-specific register support) and write access to 
  /dev/cpu/*/msr
* Libraries: none (linked statically)
* For Compiling: Freepascal compiler (http://www.freepascal.org)


3. Usage
========

c2ctl <cpu>[-<cpun>]
    Print some information about CPU(s) <cpu>(-<cpun>)
    
c2ctl <cpu>[-<cpun>] <fid> <vid>
    Set fid and vid for CPU(s) <cpu>(-<cpun>) and enable EIST if 
    necessary.

c2ctl <cpu>[-<cpun>] -e
    Enable EIST for CPU(s) <cpu>(-<cpun>)
    
c2ctl <cpu> -a
    Print DSDT template for CPU <cpu> using the current settings

c2ctl -h
    Help


4. Meaning of the fid and vid
=============================
The frequency ID (fid) is the multiplier for the reference clock (e.g.
the FSB clock). The voltage ID (vid) is processor specific.
Unfortunately Intel publishes no information about the meaning
of this value but the conversion formula for Core CPU's seems to be

  UCpu = 700 mV + vid*12.5 mV

and for Core 2 CPU's it seems to be

  UCpu = 800 mV + vid*12.5 mV .


5. Examples
===========

c2ctl 0-3 8 32
    Set fid=8 and vid=32 for CPUs 0-3
    
c2ctl 0 -a
    Print a DSDT template for CPU 0


6. Modifying core frequency and voltage
=======================================

1. Make sure, that the core voltage can be adjusted by the CPU. (E.g.
   set BIOS setting to "Normal" or "Auto".)

2. Read out the current and minimum / maximum settings using
 
   # c2ctl 0-3      (assuming you have 4 cores)

   in order to get a reference. The fid usually is the frequency 
   multiplier. Higher vid's mean higher voltages. Unfortunately Intel 
   publishes no formulas or tables for converting vid's to voltages.

3. Modify core frequency and voltage as desired. For example,
   
   # c2ctl 0-3 8 32

   sets fid=8 and vid=32 to the first 4 cores.
    

7. Enabling Enhanced Intel SpeedStep
====================================

If SpeedStep is disabled (for example due to overclocking) it can be 
enabled simply using e.g.

#  c2ctl <cpu>[-<cpun>] -e

But in order to use automatic performance scaling (using cpufreq) you 
need to inform the kernel about working fid-vid pairs. The most elegant
way to do this is to modify the DSDT:

1. Find stable fid-vid pairs by repeating steps 1-3 of Section 4.

2. Modify the DSDT as described in [1,2]. You need to add one _PCT 
   object, one _PSS object and one _PPC object to every Processor 
   object as described in [3, Section 8.4.4], see also [4]. The _PSS
   object defines the so called P-States. Each P-State contains one
   fid-vid pair. The P-States are ordered, the fastest P-State is the
   first one. As a helper for the DSDT modification the command 

   # c2ctl <cpu> -a
   
   can be used to create a DSDT template.

3. Include the new DSDT into the kernel as described in [1]. The 
   acpi-cpufreq driver should be loaded now. To get it working you need
   to enable SpeedStep using

   # c2ctl <cpu>[-<cpun>] -e

An example section of a DSDT, which defines 3 P-States for a Q9450 
Core 2 Quad Processor running with a FSB frequency of 388 MHz is listed
below.


8. References
=============

[1]  Overriding a DSDT, 
     http://www.lesswatts.org/projects/acpi/overridingDSDT.php
[2]  HOWTO: Fix Common ACPI Problems (DSDT, ECDT, etc.),
     http://gentoo-wiki.com/HOWTO_Fix_Common_ACPI_Problems
[3]  ACPI Specification, http://www.acpi.info/DOWNLOADS/ACPIspec30a.pdf
[4]  Intel and IA-32 Architectures Software Developer's Manual
     Volume 3B, Appendix B
     http://www.intel.com/products/processor/manuals


9. DSDT Example
===============

Scope (\_PR)
{
    Processor (\_PR.CPU0, 0x00, 0x00000410, 0x06) {

        Name (_PPC, 0x00)

        Name (_PCT, Package (0x02)
        {
            ResourceTemplate ()
            {
                Register (FFixedHW, 		// PERF_CTL
                    0x10,              		// Bit Width
                    0x00,               	// Bit Offset
                    0x0000000000000199, 	// Address
                    ,)
            }, 

            ResourceTemplate ()
            {
                Register (FFixedHW, 		// PERF_STATUS
                    0x10,	               	// Bit Width
                    0x00,    			// Bit Offset
                    0x0000000000000198, 	// Address
                    ,)
            }
        })

        Name (_PSS, Package (0x03)
        {
            Package (0x06)		// P-State 0
            {
                3104, 			// f in MHz
                75000, 			// P in mW
                10, 			// Transition latency in us
                10, 			// Bus Master latency in us
                0x00000820, 		// value written to PERF_CTL; fid=8, vid=32
                0x00000820		// value of PERF_STATE after successful transition; fid=8, vid=32
            }, 

            Package (0x06)		// P-State 1
            {
                2716, 			// f in MHz
                65000, 			// P in mW
                10, 			// Transition latency in us
                10, 			// Bus Master latency in us
                0x0000071C,	 	// value written to PERF_CTL; fid=7, vid=28
                0x0000071C		// value of PERF_STATE after successful transition; fid=7, vid=28
            }, 

            Package (0x06)		// P-State 2
            {
                2328, 			// f in MHz
                60000, 			// P in mW
                10, 			// Transition latency in us
                10, 			// Bus Master latency in us
                0x0000061A, 		// value written to PERF_CTL; fid=6, vid=26
                0x0000061A		// value of PERF_STATE after successful transition; fid=6, vid=26
            }, 
        })											
    }

    Processor (\_PR.CPU1, 0x01, 0x00000410, 0x06) {

        Name (_PPC, 0x00)

        Name (_PCT, Package (0x02)
        {
            ResourceTemplate ()
            {
                Register (FFixedHW, 		// PERF_CTL
                    0x10,              		// Bit Width
                    0x00,               	// Bit Offset
                    0x0000000000000199, 	// Address
                    ,)
            }, 

            ResourceTemplate ()
            {
                Register (FFixedHW, 		// PERF_STATUS
                    0x10,	               	// Bit Width
                    0x00,    			// Bit Offset
                    0x0000000000000198, 	// Address
                    ,)
            }
        })

        Name (_PSS, Package (0x03)
        {
            Package (0x06)		// P-State 0
            {
                3104, 			// f in MHz
                75000, 			// P in mW
                10, 			// Transition latency in us
                10, 			// Bus Master latency in us
                0x00000820, 		// value written to PERF_CTL; fid=8, vid=32
                0x00000820		// value of PERF_STATE after successful transition; fid=8, vid=32
            }, 

            Package (0x06)		// P-State 1
            {
                2716, 			// f in MHz
                65000, 			// P in mW
                10, 			// Transition latency in us
                10, 			// Bus Master latency in us
                0x0000071C,	 	// value written to PERF_CTL; fid=7, vid=28
                0x0000071C		// value of PERF_STATE after successful transition; fid=7, vid=28
            }, 

            Package (0x06)		// P-State 2
            {
                2328, 			// f in MHz
                60000, 			// P in mW
                10, 			// Transition latency in us
                10, 			// Bus Master latency in us
                0x0000061A, 		// value written to PERF_CTL; fid=6, vid=26
                0x0000061A		// value of PERF_STATE after successful transition; fid=6, vid=26
            }, 
        })											
    }

	
    Processor (\_PR.CPU2, 0x02, 0x00000410, 0x06) {

        Name (_PPC, 0x00)

        Name (_PCT, Package (0x02)
        {
            ResourceTemplate ()
            {
                Register (FFixedHW, 		// PERF_CTL
                    0x10,              		// Bit Width
                    0x00,               	// Bit Offset
                    0x0000000000000199, 	// Address
                    ,)
            }, 

            ResourceTemplate ()
            {
                Register (FFixedHW, 		// PERF_STATUS
                    0x10,	               	// Bit Width
                    0x00,    			// Bit Offset
                    0x0000000000000198, 	// Address
                    ,)
            }
        })

        Name (_PSS, Package (0x03)
        {
            Package (0x06)		// P-State 0
            {
                3104, 			// f in MHz
                75000, 			// P in mW
                10, 			// Transition latency in us
                10, 			// Bus Master latency in us
                0x00000820, 		// value written to PERF_CTL; fid=8, vid=32
                0x00000820		// value of PERF_STATE after successful transition; fid=8, vid=32
            }, 

            Package (0x06)		// P-State 1
            {
                2716, 			// f in MHz
                65000, 			// P in mW
                10, 			// Transition latency in us
                10, 			// Bus Master latency in us
                0x0000071C,	 	// value written to PERF_CTL; fid=7, vid=28
                0x0000071C		// value of PERF_STATE after successful transition; fid=7, vid=28
            }, 

            Package (0x06)		// P-State 2
            {
                2328, 			// f in MHz
                60000, 			// P in mW
                10, 			// Transition latency in us
                10, 			// Bus Master latency in us
                0x0000061A, 		// value written to PERF_CTL; fid=6, vid=26
                0x0000061A		// value of PERF_STATE after successful transition; fid=6, vid=26
            }, 
        })											
    }


    Processor (\_PR.CPU3, 0x03, 0x00000410, 0x06) {

        Name (_PPC, 0x00)

        Name (_PCT, Package (0x02)
        {
            ResourceTemplate ()
            {
                Register (FFixedHW, 		// PERF_CTL
                    0x10,              		// Bit Width
                    0x00,               	// Bit Offset
                    0x0000000000000199, 	// Address
                    ,)
            }, 

            ResourceTemplate ()
            {
                Register (FFixedHW, 		// PERF_STATUS
                    0x10,	               	// Bit Width
                    0x00,    			// Bit Offset
                    0x0000000000000198, 	// Address
                    ,)
            }
        })

        Name (_PSS, Package (0x03)
        {
            Package (0x06)		// P-State 0
            {
                3104, 			// f in MHz
                75000, 			// P in mW
                10, 			// Transition latency in us
                10, 			// Bus Master latency in us
                0x00000820, 		// value written to PERF_CTL; fid=8, vid=32
                0x00000820		// value of PERF_STATE after successful transition; fid=8, vid=32
            }, 

            Package (0x06)		// P-State 1
            {
                2716, 			// f in MHz
                65000, 			// P in mW
                10, 			// Transition latency in us
                10, 			// Bus Master latency in us
                0x0000071C,	 	// value written to PERF_CTL; fid=7, vid=28
                0x0000071C		// value of PERF_STATE after successful transition; fid=7, vid=28
            }, 

            Package (0x06)		// P-State 2
            {
                2328, 			// f in MHz
                60000, 			// P in mW
                10, 			// Transition latency in us
                10, 			// Bus Master latency in us
                0x0000061A, 		// value written to PERF_CTL; fid=6, vid=26
                0x0000061A		// value of PERF_STATE after successful transition; fid=6, vid=26
            }, 
        })											
    }

}