/*
 *	sc520_freq.c: cpufreq driver for the AMD Elan sc520
 *
 *	Copyright (C) 2005 Sean Young <sean@mess.org>
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License
 *	as published by the Free Software Foundation; either version
 *	2 of the License, or (at your option) any later version.
 *
 *	Based on elanfreq.c
 *
 *	2005-03-30: - initial revision
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>

#include <linux/delay.h>
#include <linux/cpufreq.h>

#include <asm/msr.h>
#include <asm/timex.h>
#include <asm/io.h>

#define MMCR_BASE	0xfffef000	/* The default base address */
#define OFFS_CPUCTL	0x2   /* CPU Control Register */

static __u8 __iomem *cpuctl;

#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "sc520_freq", msg)

static struct cpufreq_frequency_table sc520_freq_table[] = {
	{0x01,	100000},
	{0x02,	133000},
	{0,	CPUFREQ_TABLE_END},
};

static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu)
{
	u8 clockspeed_reg = *cpuctl;

	switch (clockspeed_reg & 0x03) {
	default:
		printk(KERN_ERR "sc520_freq: error: cpuctl register has unexpected value %02x\n", clockspeed_reg);
	case 0x01:
		return 100000;
	case 0x02:
		return 133000;
	}
}

static void sc520_freq_set_cpu_state (unsigned int state)
{

	struct cpufreq_freqs	freqs;
	u8 clockspeed_reg;

	freqs.old = sc520_freq_get_cpu_frequency(0);
	freqs.new = sc520_freq_table[state].frequency;
	freqs.cpu = 0; /* AMD Elan is UP */

	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);

	dprintk("attempting to set frequency to %i kHz\n",
			sc520_freq_table[state].frequency);

	local_irq_disable();

	clockspeed_reg = *cpuctl & ~0x03;
	*cpuctl = clockspeed_reg | sc520_freq_table[state].index;

	local_irq_enable();

	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
};

static int sc520_freq_verify (struct cpufreq_policy *policy)
{
	return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]);
}

static int sc520_freq_target (struct cpufreq_policy *policy,
			    unsigned int target_freq,
			    unsigned int relation)
{
	unsigned int newstate = 0;

	if (cpufreq_frequency_table_target(policy, sc520_freq_table, target_freq, relation, &newstate))
		return -EINVAL;

	sc520_freq_set_cpu_state(newstate);

	return 0;
}


/*
 *	Module init and exit code
 */

static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
{
	struct cpuinfo_x86 *c = &cpu_data(0);
	int result;

	/* capability check */
	if (c->x86_vendor != X86_VENDOR_AMD ||
	    c->x86 != 4 || c->x86_model != 9)
		return -ENODEV;

	/* cpuinfo and default policy values */
	policy->cpuinfo.transition_latency = 1000000; /* 1ms */
	policy->cur = sc520_freq_get_cpu_frequency(0);

	result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table);
	if (result)
		return (result);

	cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu);

	return 0;
}


static int sc520_freq_cpu_exit(struct cpufreq_policy *policy)
{
	cpufreq_frequency_table_put_attr(policy->cpu);
	return 0;
}


static struct freq_attr* sc520_freq_attr[] = {
	&cpufreq_freq_attr_scaling_available_freqs,
	NULL,
};


static struct cpufreq_driver sc520_freq_driver = {
	.get	= sc520_freq_get_cpu_frequency,
	.verify	= sc520_freq_verify,
	.target	= sc520_freq_target,
	.init	= sc520_freq_cpu_init,
	.exit	= sc520_freq_cpu_exit,
	.name	= "sc520_freq",
	.owner	= THIS_MODULE,
	.attr	= sc520_freq_attr,
};


static int __init sc520_freq_init(void)
{
	struct cpuinfo_x86 *c = &cpu_data(0);
	int err;

	/* Test if we have the right hardware */
	if(c->x86_vendor != X86_VENDOR_AMD ||
				c->x86 != 4 || c->x86_model != 9) {
		dprintk("no Elan SC520 processor found!\n");
		return -ENODEV;
	}
	cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1);
	if(!cpuctl) {
		printk(KERN_ERR "sc520_freq: error: failed to remap memory\n");
		return -ENOMEM;
	}

	err = cpufreq_register_driver(&sc520_freq_driver);
	if (err)
		iounmap(cpuctl);

	return err;
}


static void __exit sc520_freq_exit(void)
{
	cpufreq_unregister_driver(&sc520_freq_driver);
	iounmap(cpuctl);
}


MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sean Young <sean@mess.org>");
MODULE_DESCRIPTION("cpufreq driver for AMD's Elan sc520 CPU");

module_init(sc520_freq_init);
module_exit(sc520_freq_exit);

