Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Sep 2008 02:48:02 +0200
From:      "fluffles.net" <bsd@fluffles.net>
To:        "G .Otsuji" <annona2@gmail.com>
Cc:        Poul-Henning Kamp <phk@phk.freebsd.dk>, FreeBSD Current <freebsd-current@freebsd.org>
Subject:   Re: AMD Family 10h cpufreq driver
Message-ID:  <48D98E42.5040801@fluffles.net>
In-Reply-To: <200809232307.m8NN79th001888@softbank219001162114.bbtec.net>
References:  <200809232121.m8NLLnig001691@softbank219001162114.bbtec.net>	<26111.1222205043@critter.freebsd.dk> <200809232307.m8NN79th001888@softbank219001162114.bbtec.net>

next in thread | previous in thread | raw e-mail | index | archive | help
G .Otsuji wrote:
> Could you please try following patch to isolate the problem ,
>   

Hi G. Otsuji,

Thanks for the tip. One thing though, you forgot to alter the setting
for 9350e in your patch:

+      } else if (strstr(cpu_model, "9350e")) {
+        sc->mof_id = 25;  /* 2.5 GHz */


should be:

+      } else if (strstr(cpu_model, "9350e")) {
+        sc->mof_id = 20;  /* 2.0 GHz */


Else it'll try to run your cpu at 2.5GHz which i'm not sure it will like. :)
For a complete addition of all Phenom models, i created the following list:

+    if (strstr(cpu_model, "Phenom")) {
+      if (strstr(cpu_model, "9100")) {
+        sc->mof_id = 18;  /* 1.8 GHz */
+      } else if (strstr(cpu_model, "9150e")) {
+        sc->mof_id = 18;  /* 1.8 GHz */
+      } else if (strstr(cpu_model, "9300e")) {
+        sc->mof_id = 20;  /* 2.0 GHz */
+      } else if (strstr(cpu_model, "9350e")) {
+        sc->mof_id = 20;  /* 2.0 GHz */
+      } else if (strstr(cpu_model, "9500")) {
+        sc->mof_id = 22;  /* 2.2 GHz */
+      } else if (strstr(cpu_model, "9550")) {
+        sc->mof_id = 22;  /* 2.2 GHz */
+      } else if (strstr(cpu_model, "9600")) {
+        sc->mof_id = 23;  /* 2.3 GHz */
+      } else if (strstr(cpu_model, "9650")) {
+        sc->mof_id = 23;  /* 2.3 GHz */
+      } else if (strstr(cpu_model, "9700")) {
+        sc->mof_id = 24;  /* 2.4 GHz */
+      } else if (strstr(cpu_model, "9750")) {
+        sc->mof_id = 24;  /* 2.4 GHz */
+      } else if (strstr(cpu_model, "9800")) {
+        sc->mof_id = 25;  /* 2.5 GHz */
+      } else if (strstr(cpu_model, "9850")) {
+        sc->mof_id = 25;  /* 2.5 GHz */
+      } else if (strstr(cpu_model, "9900")) {
+        sc->mof_id = 26;  /* 2.6 GHz */
+      } else if (strstr(cpu_model, "9950")) {
+        sc->mof_id = 26;  /* 2.6 GHz */
+      } else if (strstr(cpu_model, "8250e")) {
+        sc->mof_id = 19;  /* 1.9 GHz */
+      } else if (strstr(cpu_model, "8400")) {
+        sc->mof_id = 21;  /* 2.1 GHz */
+      } else if (strstr(cpu_model, "8450")) {
+        sc->mof_id = 21;  /* 2.1 GHz */
+      } else if (strstr(cpu_model, "8450e")) {
+        sc->mof_id = 21;  /* 2.1 GHz */
+      } else if (strstr(cpu_model, "8600")) {
+        sc->mof_id = 23;  /* 2.3 GHz */
+      } else if (strstr(cpu_model, "8650")) {
+        sc->mof_id = 23;  /* 2.3 GHz */
+      } else if (strstr(cpu_model, "8700")) {
+        sc->mof_id = 24;  /* 2.4 GHz */
+      } else if (strstr(cpu_model, "8750")) {
+        sc->mof_id = 24;  /* 2.4 GHz */
+      } else if (strstr(cpu_model, "8400")) {
+        sc->mof_id = 26;  /* 2.6 GHz */
+      } else if (strstr(cpu_model, "8450")) {
+        sc->mof_id = 26;  /* 2.6 GHz */
+      } else if (strstr(cpu_model, "6400")) {
+        sc->mof_id = 19;  /* 1.9 GHz */
+      } else if (strstr(cpu_model, "6500")) {
+        sc->mof_id = 21;  /* 2.1 GHz */
+      } else if (strstr(cpu_model, "6600")) {
+        sc->mof_id = 23;  /* 2.3 GHz */
+      }
+    }

 
The 9000-series are Quadcore, the 8000-series are Tripe-core, the 6000-series are Dualcore. Source:
http://en.wikipedia.org/wiki/List_of_AMD_Phenom_microprocessors

Good luck with your driver!

Kind Regards,
Veronica




> voltage regulation is wrong or not, or
> swithching between p0 and p1 state is wrong or not .
> I added the comment and changed the vid_list to be mild voltage down-regulation.
> /**
>  * vid list:  1550 - 25 * listvid is the [mV] .
>  * change will be needed. I think.
>  * pstate_vid_list[25] means 2.5GHz's listvid. and so on.
>  * ( by the way limitation of 3.2 GHz . 3.3 GHz will be over flow ! 
>  * but there is no 3.3GHz over i think. )
>  */
> static const int pstate_vid_list[33] = {
> 	18, 18, 18, 18, 18, 18, 17, 17, 16, 16, 15, 15, 14, 14, 13, 13, 12,
> 	12, 11, 11, 10, 10,  9,  9,  8,  8,  7,  7,  6,  6,  5
> };
>
> from the comment , understanding is easier I think. sorry for few comment in the source.
> please try to change the vidlist if it goes wrong at the point which is threshold.
> here's pstate.c patch with /dev/null.
>
> --- /dev/null	2008-09-24 07:47:01.000000000 +0900
> +++ pstate.c	2008-09-24 07:44:43.000000000 +0900
> @@ -0,0 +1,448 @@
> +/*-
> + * Copyright (c) 2008 Gen Otsuji
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted providing that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR``AS IS'' AND ANY EXPRESS OR
> + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
> + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
> + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
> + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> + * POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +/*
> + * Reference: Rev 3.06 - March 26, 2008 AMD Family 10h Processor BKDG
> + */
> +
> +#include <sys/cdefs.h>
> +__FBSDID("$FreeBSD$");
> +
> +#include <sys/param.h>
> +#include <sys/bus.h>
> +#include <sys/cpu.h>
> +#include <sys/kernel.h>
> +#include <sys/module.h>
> +#include <sys/proc.h>
> +#include <sys/sysctl.h>
> +#include <sys/systm.h>
> +#include <sys/types.h>
> +
> +#include <dev/pci/pcivar.h>
> +#include <machine/md_var.h>
> +
> +#include <contrib/dev/acpica/acpi.h>
> +#include <dev/acpica/acpivar.h>
> +
> +#include "acpi_if.h"
> +#include "cpufreq_if.h"
> +
> +#define MSR_PSTATE_LIMIT    0xc0010061
> +#define MSR_PSTATE_CONTROL  0xc0010062
> +#define MSR_PSTATE_STATUS   0xc0010063
> +#define MSR_PSTATE_CONFIG   0xc0010064
> +#define MSR_PSTATE_COFVID   0xc0010071
> +
> +#define MSR_PSTATE_MOF(msr)                 (((uint64_t)(msr)>>49)&0x3F)
> +#define MSR_PSTATE_CUR_VID(msr)             (((msr) >> 9) & 0x3F)
> +#define MSR_PSTATE_CUR_DID(msr)             (((msr) >> 6) & 0x07)
> +#define MSR_PSTATE_CUR_FID(msr)             ((msr) & 0x3F)
> +#define PSTATE_LISTVID_TO_VID(listvid,mult) ((listvid) * (mult))
> +#define PSTATE_VID_TO_LISTVID(vid,mult)     ((vid) / (mult))
> +#define PSTATE_LISTVID_TO_VOLTS(listvid)    (1550 - 25 * (listvid))
> +#define PSTATE_VID_TO_VOLTS(vid,mult)       (1550 - 250 * (vid) / (mult) /10)
> +#define PSTATE_MK_PSTATE(msr,listvid,mult)                       \
> +  (((msr) & 0xFFFFFFFFFFFF0000) |                          \
> +   (((PSTATE_LISTVID_TO_VID(listvid,mult)) & 0x7F) << 9) | \
> +   ((pstate_did_list[id] & 0x07) << 6) |                   \
> +   ((pstate_fid_list[id] & 0x3F)))
> +
> +/**
> + * vid list:  1550 - 25 * listvid is the [mV] .
> + * change will be needed. I think.
> + * pstate_vid_list[25] means 2.5GHz's listvid. and so on.
> + * ( by the way limitation of 3.2 GHz . 3.3 GHz will be over flow ! 
> + * but there is no 3.3GHz over i think. )
> + */
> +static const int pstate_vid_list[33] = {
> +	18, 18, 18, 18, 18, 18, 17, 17, 16, 16, 15, 15, 14, 14, 13, 13, 12,
> +	12, 11, 11, 10, 10,  9,  9,  8,  8,  7,  7,  6,  6,  5
> +};
> +static const int pstate_fid_list[33] = {
> +  0, 0, 0, 0, 4, 8, 12, 0, 2, 4, 6, 8, 10, 12, 14, 0, 1,
> +  2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17
> +};
> +static const int pstate_did_list[33] = {
> +  2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
> +};
> +static const int pstate_did_to_div[] = {
> +  1, 2, 4, 8, 16, 16, 16, 16
> +};
> +#define PSTATE_MAX_STATES  64
> +
> +struct pstate_setting {
> +  int    freq;  /* CPU clock in Mhz or 100ths of a percent. */
> +  int    volts;  /* Voltage in mV. */
> +  int    power;  /* Power consumed in mW. */
> +  int    lat;  /* Transition latency in us. */
> +  device_t  dev;  /* Driver providing this setting. */
> +};
> +
> +struct pstate_softc {
> +  device_t  dev;
> +  struct pstate_setting pstate_settings[PSTATE_MAX_STATES];
> +  int    cfnum;
> +  int    mof_id;  /* Maximum Operating Frequency / 100 */
> +  int    mult;  /* 2(in svi mode) 1(in pvi mode) */
> +  uint64_t  backup [5];
> +  device_t  F3;
> +};
> +
> +static void  pstate_identify(driver_t * driver, device_t parent);
> +static int  pstate_probe(device_t dev);
> +static int  pstate_attach(device_t dev);
> +static int  pstate_detach(device_t dev);
> +static int  pstate_set(device_t dev, const struct cf_setting *cf);
> +static int  pstate_get(device_t dev, struct cf_setting *cf);
> +static int  pstate_settings(device_t dev, struct cf_setting *sets, int *count);
> +static int  pstate_type(device_t dev, int *type);
> +static int  pstate_shutdown(device_t dev);
> +static int  pstate_features(driver_t * driver, u_int * features);
> +
> +static device_method_t pstate_methods[] = {
> +  /* Device interface */
> +  DEVMETHOD(device_identify, pstate_identify),
> +  DEVMETHOD(device_probe, pstate_probe),
> +  DEVMETHOD(device_attach, pstate_attach),
> +  DEVMETHOD(device_detach, pstate_detach),
> +  DEVMETHOD(device_shutdown, pstate_shutdown),
> +
> +  /* cpufreq interface */
> +  DEVMETHOD(cpufreq_drv_set, pstate_set),
> +  DEVMETHOD(cpufreq_drv_get, pstate_get),
> +  DEVMETHOD(cpufreq_drv_settings, pstate_settings),
> +  DEVMETHOD(cpufreq_drv_type, pstate_type),
> +
> +  /* ACPI interface */
> +  DEVMETHOD(acpi_get_features, pstate_features),
> +
> +  {0, 0}
> +};
> +
> +static devclass_t pstate_devclass;
> +static driver_t  pstate_driver = {
> +  "pstate",
> +  pstate_methods,
> +  sizeof(struct pstate_softc),
> +};
> +DRIVER_MODULE(pstate, cpu, pstate_driver, pstate_devclass, 0, 0);
> +
> +static int
> +pstate_cur_cpu_freq(void)
> +{
> +  uint64_t  msr;
> +  int did, fid;
> +  msr = rdmsr(MSR_PSTATE_COFVID);
> +  did = MSR_PSTATE_CUR_DID(msr);
> +  fid = MSR_PSTATE_CUR_FID(msr);
> +  if (bootverbose)
> +    printf("pstate: DID=%d,FID=%d\n", did, fid);
> +  return (100 * (fid + 16) / pstate_did_to_div[did]);
> +}
> +
> +static int
> +pstate_cur_cpu_volts(int mult)
> +{
> +  uint64_t  msr;
> +  int  vid;
> +  msr = rdmsr(MSR_PSTATE_COFVID);
> +  vid = MSR_PSTATE_CUR_VID(msr);
> +  if (bootverbose)
> +    printf("pstate: VID=%d\n", vid);
> +  return (PSTATE_VID_TO_VOLTS(vid, mult));
> +}
> +
> +static int
> +pstate_set(device_t dev, const struct cf_setting *cf)
> +{
> +  struct pstate_softc *sc;
> +  struct pstate_setting *ps;
> +  uint64_t  msr;
> +  int i, id, setfreq, curfreq, curvolts;
> +  if (cf == NULL)
> +    return (EINVAL);
> +  msr = rdmsr(MSR_PSTATE_CONFIG + 1);
> +  if (!(msr & 0x8000000000000000)) {
> +    if (bootverbose)
> +      device_printf(dev, "P1 not supported by hardware.\n");
> +    return (ENODEV);
> +  }
> +  sc = device_get_softc(dev);
> +  ps = sc->pstate_settings;
> +  for (i = 0; i < sc->cfnum; i++, ps++)
> +    if (cf->freq == ps->freq) {
> +      break;
> +    }
> +  setfreq = ps->freq;
> +  if (i == sc->cfnum) {
> +    if (bootverbose)
> +      device_printf(dev, "%d MHz is not supported.\n",
> +              cf->freq);
> +    return (EINVAL);
> +  }
> +  /* go to P0 */
> +  wrmsr(MSR_PSTATE_CONTROL, 0);
> +  DELAY(3000);
> +  if (setfreq / 100 == sc->mof_id) {
> +    if (bootverbose)
> +      device_printf(dev, "going back to default setting.\n");
> +    for (i = 1; i < 5; i++)
> +      wrmsr(MSR_PSTATE_CONFIG + i, sc->backup[i]);
> +    return (0);
> +  }
> +  /* copy config val from P0 to P1 */
> +  msr = rdmsr(MSR_PSTATE_CONFIG);
> +  wrmsr(MSR_PSTATE_CONFIG + 1, msr);
> +  /* make pstate */
> +  id = sc->mof_id - i - 1;
> +  msr = PSTATE_MK_PSTATE(msr, pstate_vid_list[id], sc->mult);
> +  wrmsr(MSR_PSTATE_CONFIG + 1, msr);
> +  if (bootverbose)
> +    device_printf(dev, "going to %dMHz\n", setfreq);
> +  /* go to P1 */
> +  wrmsr(MSR_PSTATE_CONTROL, 1);
> +  for (i = 0; i < 1000; i++) {
> +    DELAY(3000);
> +    curfreq = pstate_cur_cpu_freq();
> +    curvolts = pstate_cur_cpu_volts(sc->mult);
> +    if (setfreq == curfreq)
> +      break;
> +  }
> +  if (setfreq != curfreq && bootverbose) {
> +    device_printf(dev, "current %dMHz and set %dMHz differ.\n",
> +            curfreq, setfreq);
> +    return (0);
> +  }
> +  if (bootverbose)
> +    device_printf(dev, "Now: %d MHz %d mV\n", curfreq, curvolts);
> +
> +  msr = rdmsr(MSR_PSTATE_STATUS);
> +  if (msr != 1 && bootverbose)
> +    device_printf(dev, "P1 is not enabled.\n");
> +  return (0);
> +}
> +
> +static int
> +pstate_get(device_t dev, struct cf_setting *cf)
> +{
> +  struct pstate_softc *sc;
> +  sc = device_get_softc(dev);
> +  if (cf == NULL)
> +    return (EINVAL);
> +  cf->freq = pstate_cur_cpu_freq();
> +  cf->volts = pstate_cur_cpu_volts(sc->mult);
> +  cf->power = CPUFREQ_VAL_UNKNOWN;
> +  cf->lat = 16;
> +  cf->dev = dev;
> +  return (0);
> +}
> +
> +static int
> +pstate_settings(device_t dev, struct cf_setting *sets, int *count)
> +{
> +  struct pstate_softc *sc;
> +  int    i;
> +  if (sets == NULL || count == NULL)
> +    return (EINVAL);
> +  sc = device_get_softc(dev);
> +  if (*count < sc->cfnum)
> +    return (E2BIG);
> +  for (i = 0; i < sc->cfnum; i++, sets++) {
> +    sets->freq = sc->pstate_settings[i].freq;
> +    sets->volts = sc->pstate_settings[i].volts;
> +    sets->power = sc->pstate_settings[i].power;
> +    sets->lat = sc->pstate_settings[i].lat;
> +    sets->dev = sc->pstate_settings[i].dev;
> +  }
> +  *count = sc->cfnum;
> +  return (0);
> +}
> +
> +static int
> +pstate_type(device_t dev, int *type)
> +{
> +
> +  if (type == NULL)
> +    return (EINVAL);
> +  *type = CPUFREQ_TYPE_ABSOLUTE;
> +  return (0);
> +}
> +
> +static int
> +pstate_is_capable(void)
> +{
> +  u_int  regs[4];
> +  if (strcmp(cpu_vendor, "AuthenticAMD") != 0 ||
> +      cpu_exthigh < 0x80000007)
> +    return (FALSE);
> +  switch (cpu_id) {
> +  case 0x100f2A:
> +  case 0x100f22:
> +  case 0x100f23:
> +    break;
> +  default:
> +    return (FALSE);
> +  }
> +  do_cpuid(0x80000007, regs);
> +  if (regs[3] & 0x80) {
> +    return (TRUE);
> +  }
> +  return (FALSE);
> +}
> +
> +static void
> +pstate_identify(driver_t * driver, device_t parent)
> +{
> +  device_t  child;
> +  if (device_find_child(parent, "pstate", -1) != NULL)
> +    return;
> +  if (pstate_is_capable() == FALSE)
> +    return;
> +  if ((child = BUS_ADD_CHILD(parent, 10, "pstate", -1)) == NULL)
> +    device_printf(parent, "pstate: add child failed\n");
> +}
> +
> +static int
> +pstate_probe(device_t dev)
> +{
> +  device_t  perf_dev;
> +  int error, type;
> +  if (resource_disabled("pstate", 0))
> +    return (ENXIO);
> +
> +  perf_dev = device_find_child(device_get_parent(dev), "acpi_perf", -1);
> +  if (perf_dev && device_is_attached(perf_dev)) {
> +    error = CPUFREQ_DRV_TYPE(perf_dev, &type);
> +    if (error == 0 && (type & CPUFREQ_FLAG_INFO_ONLY) == 0)
> +      return (ENXIO);
> +  }
> +  device_set_desc(dev, "Cool`n'Quiet 2.0");
> +  return (0);
> +}
> +
> +static int
> +pstate_attach(device_t dev)
> +{
> +  struct pstate_softc *sc;
> +  uint64_t  msr;
> +  uint32_t  cfg;
> +  int i , j, listvid;
> +  u_int regs[4], reg;
> +  char cpu_model[48], *p = cpu_model;
> +  sc = device_get_softc(dev);
> +  for (i = 0; i < 5; i++)
> +    sc->backup[i] = rdmsr(MSR_PSTATE_CONFIG + i);
> +  msr = rdmsr(MSR_PSTATE_COFVID);
> +  sc->mof_id = MSR_PSTATE_MOF(msr) / 100;
> +  if (sc->mof_id == 0) {
> +    for (i = 0; i < 3; i++) {
> +      do_cpuid(0x80000002 + i, regs);
> +      for (j = 0; j < 4; j++) {
> +        reg = regs[j];
> +        *p++ = (char)(reg & 0xff);
> +        *p++ = (char)((reg >> 8) & 0xff);
> +        *p++ = (char)((reg >> 16) & 0xff);
> +        *p++ = (char)((reg >> 24) & 0xff);
> +      }
> +    }
> +    if (strstr(cpu_model, "Phenom")) {
> +      if (strstr(cpu_model, "9600")) {
> +        sc->mof_id = 23;  /* 2.3 GHz */
> +      } else if (strstr(cpu_model, "9850")) {
> +        sc->mof_id = 25;  /* 2.5 GHz */
> +      } else if (strstr(cpu_model, "9350e")) {
> +        sc->mof_id = 25;  /* 2.5 GHz */
> +      } else if (strstr(cpu_model, "9950")) {
> +        sc->mof_id = 26;  /* 2.6 GHz */
> +      }
> +    }
> +    if (sc->mof_id == 0) {
> +			device_printf(dev,"msr = %x\n",msr);
> +			device_printf(dev,"cpu = %s\n",cpu_model);
> +			device_printf(dev,"no limit of max freq.\n");
> +			device_printf(dev,"change lines near the \"Phenom\" ,sorry :)\n");
> +      return (ENODEV);
> +    }
> +  }
> +  /* if 2500,..600,500,400 MHz => sc->mof_id=25; sc->cfnum=22; */
> +  sc->cfnum = sc->mof_id - 3;
> +  /**
> +   * following 24 means the 1st cpu. 25-31 instead of 24 is MP system.
> +   * I don't have MP system :-< .
> +	 * But only for reading , so MP system will work?
> +   */
> +  sc->F3 = pci_find_bsf(0, 24, 3);
> +  cfg = pci_read_config(sc->F3, 0xA0, 4);
> +  if (cfg & 0x10)    /* PVI mode */
> +    sc->mult = 1;
> +  else      /* SVI mode */
> +    sc->mult = 2;
> +  for (i = 0; i < sc->cfnum; i++) {
> +    sc->pstate_settings[i].freq = 100 * (sc->mof_id - i);
> +    listvid = pstate_vid_list[sc->mof_id - i];
> +    sc->pstate_settings[i].volts = PSTATE_LISTVID_TO_VOLTS(listvid);
> +    sc->pstate_settings[i].power = CPUFREQ_VAL_UNKNOWN;
> +    sc->pstate_settings[i].lat = 16;
> +    sc->pstate_settings[i].dev = dev;
> +  }
> +  cpufreq_register(dev);
> +  return (0);
> +}
> +
> +static int
> +pstate_detach(device_t dev)
> +{
> +  struct pstate_softc *sc;
> +  int    new;
> +  sc = device_get_softc(dev);
> +  new = sc->mof_id * 100;
> +  if (new != 0)
> +    kernel_sysctlbyname(&thread0, "dev.cpu.0.freq",
> +            0, 0, &new, sizeof(new), NULL, 0);
> +  return (cpufreq_unregister(dev));
> +}
> +
> +static int
> +pstate_shutdown(device_t dev)
> +{
> +  struct pstate_softc *sc;
> +  int    new;
> +  sc = device_get_softc(dev);
> +  new = sc->mof_id * 100;
> +  if (new != 0)
> +    kernel_sysctlbyname(&thread0, "dev.cpu.0.freq",
> +            0, 0, &new, sizeof(new), NULL, 0);
> +  return (0);
> +}
> +
> +static int
> +pstate_features(driver_t * driver, u_int * features)
> +{
> +
> +  *features = ACPI_CAP_PERF_MSRS;
> +  return (0);
> +}
>
> Regards,
> G. Otsuji<annona2@gmail.com>
>
> _______________________________________________
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscribe@freebsd.org"
>
>   




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?48D98E42.5040801>