/*
 * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 *
 *  Library for common functions for Intel SpeedStep v.1 and v.2 support
 *
 *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/slab.h>

#include <asm/msr.h>
#include "speedstep-lib.h"

#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-lib", msg)

#ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
static int relaxed_check = 0;
#else
#define relaxed_check 0
#endif

/*********************************************************************
 *                   GET PROCESSOR CORE SPEED IN KHZ                 *
 *********************************************************************/

static unsigned int pentium3_get_frequency (unsigned int processor)
{
        /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */
	struct {
		unsigned int ratio;	/* Frequency Multiplier (x10) */
		u8 bitmap;		/* power on configuration bits
					[27, 25:22] (in MSR 0x2a) */
	} msr_decode_mult [] = {
		{ 30, 0x01 },
		{ 35, 0x05 },
		{ 40, 0x02 },
		{ 45, 0x06 },
		{ 50, 0x00 },
		{ 55, 0x04 },
		{ 60, 0x0b },
		{ 65, 0x0f },
		{ 70, 0x09 },
		{ 75, 0x0d },
		{ 80, 0x0a },
		{ 85, 0x26 },
		{ 90, 0x20 },
		{ 100, 0x2b },
		{ 0, 0xff }     /* error or unknown value */
	};

	/* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */
	struct {
		unsigned int value;	/* Front Side Bus speed in MHz */
		u8 bitmap;		/* power on configuration bits [18: 19]
					(in MSR 0x2a) */
	} msr_decode_fsb [] = {
		{  66, 0x0 },
		{ 100, 0x2 },
		{ 133, 0x1 },
		{   0, 0xff}
	};

	u32 msr_lo, msr_tmp;
	int i = 0, j = 0;

	/* read MSR 0x2a - we only need the low 32 bits */
	rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
	dprintk("P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
	msr_tmp = msr_lo;

	/* decode the FSB */
	msr_tmp &= 0x00c0000;
	msr_tmp >>= 18;
	while (msr_tmp != msr_decode_fsb[i].bitmap) {
		if (msr_decode_fsb[i].bitmap == 0xff)
			return 0;
		i++;
	}

	/* decode the multiplier */
	if (processor == SPEEDSTEP_PROCESSOR_PIII_C_EARLY) {
		dprintk("workaround for early PIIIs\n");
		msr_lo &= 0x03c00000;
	} else
		msr_lo &= 0x0bc00000;
	msr_lo >>= 22;
	while (msr_lo != msr_decode_mult[j].bitmap) {
		if (msr_decode_mult[j].bitmap == 0xff)
			return 0;
		j++;
	}

	dprintk("speed is %u\n", (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100));

	return (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100);
}


static unsigned int pentiumM_get_frequency(void)
{
	u32 msr_lo, msr_tmp;

	rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
	dprintk("PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);

	/* see table B-2 of 24547212.pdf */
	if (msr_lo & 0x00040000) {
		printk(KERN_DEBUG "speedstep-lib: PM - invalid FSB: 0x%x 0x%x\n", msr_lo, msr_tmp);
		return 0;
	}

	msr_tmp = (msr_lo >> 22) & 0x1f;
	dprintk("bits 22-26 are 0x%x, speed is %u\n", msr_tmp, (msr_tmp * 100 * 1000));

	return (msr_tmp * 100 * 1000);
}

static unsigned int pentium_core_get_frequency(void)
{
	u32 fsb = 0;
	u32 msr_lo, msr_tmp;

	rdmsr(MSR_FSB_FREQ, msr_lo, msr_tmp);
	/* see table B-2 of 25366920.pdf */
	switch (msr_lo & 0x07) {
	case 5:
		fsb = 100000;
		break;
	case 1:
		fsb = 133333;
		break;
	case 3:
		fsb = 166667;
		break;
	default:
		printk(KERN_ERR "PCORE - MSR_FSB_FREQ undefined value");
	}

	rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
	dprintk("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);

	msr_tmp = (msr_lo >> 22) & 0x1f;
	dprintk("bits 22-26 are 0x%x, speed is %u\n", msr_tmp, (msr_tmp * fsb));

	return (msr_tmp * fsb);
}


static unsigned int pentium4_get_frequency(void)
{
	struct cpuinfo_x86 *c = &boot_cpu_data;
	u32 msr_lo, msr_hi, mult;
	unsigned int fsb = 0;

	rdmsr(0x2c, msr_lo, msr_hi);

	dprintk("P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi);

	/* decode the FSB: see IA-32 Intel (C) Architecture Software
	 * Developer's Manual, Volume 3: System Prgramming Guide,
	 * revision #12 in Table B-1: MSRs in the Pentium 4 and
	 * Intel Xeon Processors, on page B-4 and B-5.
	 */
	if (c->x86_model < 2)
		fsb = 100 * 1000;
	else {
		u8 fsb_code = (msr_lo >> 16) & 0x7;
		switch (fsb_code) {
		case 0:
			fsb = 100 * 1000;
			break;
		case 1:
			fsb = 13333 * 10;
			break;
		case 2:
			fsb = 200 * 1000;
			break;
		}
	}

	if (!fsb)
		printk(KERN_DEBUG "speedstep-lib: couldn't detect FSB speed. Please send an e-mail to <linux@brodo.de>\n");

	/* Multiplier. */
	if (c->x86_model < 2)
		mult = msr_lo >> 27;
	else
		mult = msr_lo >> 24;

	dprintk("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n", fsb, mult, (fsb * mult));

	return (fsb * mult);
}


unsigned int speedstep_get_processor_frequency(unsigned int processor)
{
	switch (processor) {
	case SPEEDSTEP_PROCESSOR_PCORE:
		return pentium_core_get_frequency();
	case SPEEDSTEP_PROCESSOR_PM:
		return pentiumM_get_frequency();
	case SPEEDSTEP_PROCESSOR_P4D:
	case SPEEDSTEP_PROCESSOR_P4M:
		return pentium4_get_frequency();
	case SPEEDSTEP_PROCESSOR_PIII_T:
	case SPEEDSTEP_PROCESSOR_PIII_C:
	case SPEEDSTEP_PROCESSOR_PIII_C_EARLY:
		return pentium3_get_frequency(processor);
	default:
		return 0;
	};
	return 0;
}
EXPORT_SYMBOL_GPL(speedstep_get_processor_frequency);


/*********************************************************************
 *                 DETECT SPEEDSTEP-CAPABLE PROCESSOR                *
 *********************************************************************/

unsigned int speedstep_detect_processor (void)
{
	struct cpuinfo_x86 *c = &cpu_data(0);
	u32 ebx, msr_lo, msr_hi;

	dprintk("x86: %x, model: %x\n", c->x86, c->x86_model);

	if ((c->x86_vendor != X86_VENDOR_INTEL) ||
	    ((c->x86 != 6) && (c->x86 != 0xF)))
		return 0;

	if (c->x86 == 0xF) {
		/* Intel Mobile Pentium 4-M
		 * or Intel Mobile Pentium 4 with 533 MHz FSB */
		if (c->x86_model != 2)
			return 0;

		ebx = cpuid_ebx(0x00000001);
		ebx &= 0x000000FF;

		dprintk("ebx value is %x, x86_mask is %x\n", ebx, c->x86_mask);

		switch (c->x86_mask) {
		case 4:
			/*
			 * B-stepping [M-P4-M]
			 * sample has ebx = 0x0f, production has 0x0e.
			 */
			if ((ebx == 0x0e) || (ebx == 0x0f))
				return SPEEDSTEP_PROCESSOR_P4M;
			break;
		case 7:
			/*
			 * C-stepping [M-P4-M]
			 * needs to have ebx=0x0e, else it's a celeron:
			 * cf. 25130917.pdf / page 7, footnote 5 even
			 * though 25072120.pdf / page 7 doesn't say
			 * samples are only of B-stepping...
			 */
			if (ebx == 0x0e)
				return SPEEDSTEP_PROCESSOR_P4M;
			break;
		case 9:
			/*
			 * D-stepping [M-P4-M or M-P4/533]
			 *
			 * this is totally strange: CPUID 0x0F29 is
			 * used by M-P4-M, M-P4/533 and(!) Celeron CPUs.
			 * The latter need to be sorted out as they don't
			 * support speedstep.
			 * Celerons with CPUID 0x0F29 may have either
			 * ebx=0x8 or 0xf -- 25130917.pdf doesn't say anything
			 * specific.
			 * M-P4-Ms may have either ebx=0xe or 0xf [see above]
			 * M-P4/533 have either ebx=0xe or 0xf. [25317607.pdf]
			 * also, M-P4M HTs have ebx=0x8, too
			 * For now, they are distinguished by the model_id string
			 */
			if ((ebx == 0x0e) || (strstr(c->x86_model_id,"Mobile Intel(R) Pentium(R) 4") != NULL))
				return SPEEDSTEP_PROCESSOR_P4M;
			break;
		default:
			break;
		}
		return 0;
	}

	switch (c->x86_model) {
	case 0x0B: /* Intel PIII [Tualatin] */
		/* cpuid_ebx(1) is 0x04 for desktop PIII, 0x06 for mobile PIII-M */
		ebx = cpuid_ebx(0x00000001);
		dprintk("ebx is %x\n", ebx);

		ebx &= 0x000000FF;

		if (ebx != 0x06)
			return 0;

		/* So far all PIII-M processors support SpeedStep. See
		 * Intel's 24540640.pdf of June 2003
		 */
		return SPEEDSTEP_PROCESSOR_PIII_T;

	case 0x08: /* Intel PIII [Coppermine] */

		/* all mobile PIII Coppermines have FSB 100 MHz
		 * ==> sort out a few desktop PIIIs. */
		rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi);
		dprintk("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n", msr_lo, msr_hi);
		msr_lo &= 0x00c0000;
		if (msr_lo != 0x0080000)
			return 0;

		/*
		 * If the processor is a mobile version,
		 * platform ID has bit 50 set
		 * it has SpeedStep technology if either
		 * bit 56 or 57 is set
		 */
		rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi);
		dprintk("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n", msr_lo, msr_hi);
		if ((msr_hi & (1<<18)) && (relaxed_check ? 1 : (msr_hi & (3<<24)))) {
			if (c->x86_mask == 0x01) {
				dprintk("early PIII version\n");
				return SPEEDSTEP_PROCESSOR_PIII_C_EARLY;
			} else
				return SPEEDSTEP_PROCESSOR_PIII_C;
		}

	default:
		return 0;
	}
}
EXPORT_SYMBOL_GPL(speedstep_detect_processor);


/*********************************************************************
 *                     DETECT SPEEDSTEP SPEEDS                       *
 *********************************************************************/

unsigned int speedstep_get_freqs(unsigned int processor,
				  unsigned int *low_speed,
				  unsigned int *high_speed,
				  unsigned int *transition_latency,
				  void (*set_state) (unsigned int state))
{
	unsigned int prev_speed;
	unsigned int ret = 0;
	unsigned long flags;
	struct timeval tv1, tv2;

	if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))
		return -EINVAL;

	dprintk("trying to determine both speeds\n");

	/* get current speed */
	prev_speed = speedstep_get_processor_frequency(processor);
	if (!prev_speed)
		return -EIO;

	dprintk("previous speed is %u\n", prev_speed);

	local_irq_save(flags);

	/* switch to low state */
	set_state(SPEEDSTEP_LOW);
	*low_speed = speedstep_get_processor_frequency(processor);
	if (!*low_speed) {
		ret = -EIO;
		goto out;
	}

	dprintk("low speed is %u\n", *low_speed);

	/* start latency measurement */
	if (transition_latency)
		do_gettimeofday(&tv1);

	/* switch to high state */
	set_state(SPEEDSTEP_HIGH);

	/* end latency measurement */
	if (transition_latency)
		do_gettimeofday(&tv2);

	*high_speed = speedstep_get_processor_frequency(processor);
	if (!*high_speed) {
		ret = -EIO;
		goto out;
	}

	dprintk("high speed is %u\n", *high_speed);

	if (*low_speed == *high_speed) {
		ret = -ENODEV;
		goto out;
	}

	/* switch to previous state, if necessary */
	if (*high_speed != prev_speed)
		set_state(SPEEDSTEP_LOW);

	if (transition_latency) {
		*transition_latency = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC +
			tv2.tv_usec - tv1.tv_usec;
		dprintk("transition latency is %u uSec\n", *transition_latency);

		/* convert uSec to nSec and add 20% for safety reasons */
		*transition_latency *= 1200;

		/* check if the latency measurement is too high or too low
		 * and set it to a safe value (500uSec) in that case
		 */
		if (*transition_latency > 10000000 || *transition_latency < 50000) {
			printk (KERN_WARNING "speedstep: frequency transition measured seems out of "
					"range (%u nSec), falling back to a safe one of %u nSec.\n",
					*transition_latency, 500000);
			*transition_latency = 500000;
		}
	}

out:
	local_irq_restore(flags);
	return (ret);
}
EXPORT_SYMBOL_GPL(speedstep_get_freqs);

#ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
module_param(relaxed_check, int, 0444);
MODULE_PARM_DESC(relaxed_check, "Don't do all checks for speedstep capability.");
#endif

MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
MODULE_DESCRIPTION ("Library for Intel SpeedStep 1 or 2 cpufreq drivers.");
MODULE_LICENSE ("GPL");
