Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 34358
b: refs/heads/master
c: 179da8e
h: refs/heads/master
v: v3
  • Loading branch information
Rafa� Bilski authored and Dave Jones committed Aug 11, 2006
1 parent c69f70d commit 2a869d5
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 05ca0350e8caa91a5ec9961c585c98005b6934ea
refs/heads/master: 179da8e6e8903a8cdb19bb12672d50dc33f0fde6
86 changes: 64 additions & 22 deletions trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/string.h>

Expand Down Expand Up @@ -60,6 +61,7 @@ static int can_scale_voltage;
static int vrmrev;
static struct acpi_processor *pr = NULL;
static struct acpi_processor_cx *cx = NULL;
static int port22_en = 0;

/* Module parameters */
static int dont_scale_voltage;
Expand Down Expand Up @@ -124,10 +126,9 @@ static int longhaul_get_cpu_mult(void)

/* For processor with BCR2 MSR */

static void do_longhaul1(int cx_address, unsigned int clock_ratio_index)
static void do_longhaul1(unsigned int clock_ratio_index)
{
union msr_bcr2 bcr2;
u32 t;

rdmsrl(MSR_VIA_BCR2, bcr2.val);
/* Enable software clock multiplier */
Expand All @@ -136,13 +137,11 @@ static void do_longhaul1(int cx_address, unsigned int clock_ratio_index)

/* Sync to timer tick */
safe_halt();
ACPI_FLUSH_CPU_CACHE();
/* Change frequency on next halt or sleep */
wrmsrl(MSR_VIA_BCR2, bcr2.val);
/* Invoke C3 */
inb(cx_address);
/* Dummy op - must do something useless after P_LVL3 read */
t = inl(acpi_fadt.xpm_tmr_blk.address);
/* Invoke transition */
ACPI_FLUSH_CPU_CACHE();
halt();

/* Disable software clock multiplier */
local_irq_disable();
Expand All @@ -166,9 +165,9 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)

/* Sync to timer tick */
safe_halt();
ACPI_FLUSH_CPU_CACHE();
/* Change frequency on next halt or sleep */
wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
ACPI_FLUSH_CPU_CACHE();
/* Invoke C3 */
inb(cx_address);
/* Dummy op - must do something useless after P_LVL3 read */
Expand Down Expand Up @@ -227,10 +226,13 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
outb(0xFF,0xA1); /* Overkill */
outb(0xFE,0x21); /* TMR0 only */

/* Disable bus master arbitration */
if (pr->flags.bm_check) {
if (pr->flags.bm_control) {
/* Disable bus master arbitration */
acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1,
ACPI_MTX_DO_NOT_LOCK);
} else if (port22_en) {
/* Disable AGP and PCI arbiters */
outb(3, 0x22);
}

switch (longhaul_version) {
Expand All @@ -244,7 +246,7 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
*/
case TYPE_LONGHAUL_V1:
case TYPE_LONGHAUL_V2:
do_longhaul1(cx->address, clock_ratio_index);
do_longhaul1(clock_ratio_index);
break;

/*
Expand All @@ -259,14 +261,20 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
* to work in practice.
*/
case TYPE_POWERSAVER:
/* Don't allow wakeup */
acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0,
ACPI_MTX_DO_NOT_LOCK);
do_powersaver(cx->address, clock_ratio_index);
break;
}

/* Enable bus master arbitration */
if (pr->flags.bm_check) {
if (pr->flags.bm_control) {
/* Enable bus master arbitration */
acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0,
ACPI_MTX_DO_NOT_LOCK);
} else if (port22_en) {
/* Enable arbiters */
outb(0, 0x22);
}

outb(pic2_mask,0xA1); /* restore mask */
Expand Down Expand Up @@ -540,21 +548,33 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
return 1;
}

/* VIA don't support PM2 reg, but have something similar */
static int enable_arbiter_disable(void)
{
struct pci_dev *dev;
u8 pci_cmd;

/* Find PLE133 host bridge */
dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, NULL);
if (dev != NULL) {
/* Enable access to port 0x22 */
pci_read_config_byte(dev, 0x78, &pci_cmd);
if ( !(pci_cmd & 1<<7) ) {
pci_cmd |= 1<<7;
pci_write_config_byte(dev, 0x78, pci_cmd);
}
return 1;
}
return 0;
}

static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
{
struct cpuinfo_x86 *c = cpu_data;
char *cpuname=NULL;
int ret;

/* Check ACPI support for C3 state */
acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
&longhaul_walk_callback, NULL, (void *)&pr);
if (pr == NULL) goto err_acpi;

cx = &pr->power.states[ACPI_STATE_C3];
if (cx->address == 0 || cx->latency > 1000) goto err_acpi;

/* Now check what we have on this motherboard */
/* Check what we have on this motherboard */
switch (c->x86_model) {
case 6:
cpu_model = CPU_SAMUEL;
Expand Down Expand Up @@ -636,6 +656,28 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
break;
};

/* Find ACPI data for processor */
acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
&longhaul_walk_callback, NULL, (void *)&pr);
if (pr == NULL)
goto err_acpi;

if (longhaul_version == TYPE_POWERSAVER) {
/* Check ACPI support for C3 state */
cx = &pr->power.states[ACPI_STATE_C3];
if (cx->address == 0 || cx->latency > 1000)
goto err_acpi;
} else {
/* Check ACPI support for bus master arbiter disable */
if (!pr->flags.bm_control) {
if (!enable_arbiter_disable()) {
printk(KERN_ERR PFX "No ACPI support. No VT8601 host bridge. Aborting.\n");
return -ENODEV;
} else
port22_en = 1;
}
}

ret = longhaul_get_ranges();
if (ret != 0)
return ret;
Expand Down

0 comments on commit 2a869d5

Please sign in to comment.