Beispiel #1
0
static void
obio_setup_cpufreq(device_t dev)
{
    struct obio_softc *sc = device_private(dev);
    int ret;

    ret = cpufreq_register(&sc->sc_cf);
    if (ret != 0)
        aprint_error_dev(sc->sc_dev, "cpufreq_register() failed, error %d\n", ret);
}
Beispiel #2
0
static int
ichss_attach(device_t dev)
{
	struct ichss_softc *sc;
	uint16_t ss_en;

	sc = device_get_softc(dev);
	sc->dev = dev;

	sc->bm_rid = 0;
	sc->bm_reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->bm_rid,
	    RF_ACTIVE);
	if (sc->bm_reg == NULL) {
		device_printf(dev, "failed to alloc BM arb register\n");
		return (ENXIO);
	}
	sc->ctrl_rid = 1;
	sc->ctrl_reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
	    &sc->ctrl_rid, RF_ACTIVE);
	if (sc->ctrl_reg == NULL) {
		device_printf(dev, "failed to alloc control register\n");
		bus_release_resource(dev, SYS_RES_IOPORT, sc->bm_rid,
		    sc->bm_reg);
		return (ENXIO);
	}

	/* Activate SpeedStep control if not already enabled. */
	ss_en = pci_read_config(ich_device, ICHSS_PMCFG_OFFSET, sizeof(ss_en));
	if ((ss_en & ICHSS_ENABLE) == 0) {
		device_printf(dev, "enabling SpeedStep support\n");
		pci_write_config(ich_device, ICHSS_PMCFG_OFFSET,
		    ss_en | ICHSS_ENABLE, sizeof(ss_en));
	}

	/* Setup some defaults for our exported settings. */
	sc->sets[0].freq = CPUFREQ_VAL_UNKNOWN;
	sc->sets[0].volts = CPUFREQ_VAL_UNKNOWN;
	sc->sets[0].power = CPUFREQ_VAL_UNKNOWN;
	sc->sets[0].lat = 1000;
	sc->sets[0].dev = dev;
	sc->sets[1] = sc->sets[0];
	cpufreq_register(dev);

	return (0);
}
Beispiel #3
0
/**
 * longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver
 *
 * Initializes the LongRun support.
 */
static int __init longrun_init(void)
{
	int                     result;
	struct cpufreq_driver   *driver;
	struct cpuinfo_x86 *c = cpu_data;

	if (c->x86_vendor != X86_VENDOR_TRANSMETA || 
	    !cpu_has(c, X86_FEATURE_LONGRUN))
		return 0;

	/* initialization of main "cpufreq" code*/
	driver = kmalloc(sizeof(struct cpufreq_driver) + 
			 NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
	if (!driver)
		return -ENOMEM;

	driver->policy = (struct cpufreq_policy *) (driver + 1);

	if (longrun_determine_freqs(&longrun_low_freq, &longrun_high_freq)) {
		kfree(driver);
		return -EIO;
	}
	driver->policy[0].cpuinfo.min_freq = longrun_low_freq;
	driver->policy[0].cpuinfo.max_freq = longrun_high_freq;
	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;

	longrun_get_policy(&driver->policy[0]);

#ifdef CONFIG_CPU_FREQ_24_API
	driver->cpu_cur_freq[0] = longrun_high_freq; /* dummy value */
#endif

	driver->verify         = &longrun_verify_policy;
	driver->setpolicy      = &longrun_set_policy;

	longrun_driver = driver;

	result = cpufreq_register(driver);
	if (result) {
		longrun_driver = NULL;
		kfree(driver);
	}

	return result;
}
Beispiel #4
0
static int
dfs_attach(device_t dev)
{
	struct dfs_softc *sc;
	uint16_t vers;

	sc = device_get_softc(dev);
	sc->dev = dev;
	sc->dfs4 = 0;
	vers = mfpvr() >> 16;

	/* The 7448 supports divide-by-four as well */
	if (vers == MPC7448)
		sc->dfs4 = 1;

	cpufreq_register(dev);
	return (0);
}
Beispiel #5
0
static int
acpi_perf_attach(device_t dev)
{
	struct acpi_perf_softc *sc;

	sc = device_get_softc(dev);
	sc->dev = dev;
	sc->handle = acpi_get_handle(dev);
	sc->px_max_avail = 0;
	sc->px_curr_state = CPUFREQ_VAL_UNKNOWN;
	if (acpi_perf_evaluate(dev) != 0)
		return (ENXIO);
	AcpiOsExecute(OSL_NOTIFY_HANDLER, acpi_px_startup, NULL);
	if (!sc->info_only)
		cpufreq_register(dev);

	return (0);
}
Beispiel #6
0
static int
pn_attach(device_t dev)
{
	int rv;
	device_t child;

	child = device_find_child(device_get_parent(dev), "acpi_perf", -1);
	if (child) {
		rv = pn_decode_acpi(dev, child);
		if (rv)
			rv = pn_decode_pst(dev);
	} else
		rv = pn_decode_pst(dev);

	if (rv != 0)
		return (ENXIO);
	cpufreq_register(dev);
	return (0);
}
Beispiel #7
0
static int
mpc85xx_jog_attach(device_t dev)
{
	struct ofw_compat_data *compat;
	struct mpc85xx_jog_softc *sc;
	struct mpc85xx_constraints *constraints;
	phandle_t cpu;
	uint32_t reg;

	sc = device_get_softc(dev);
	sc->dev = dev;

	compat = mpc85xx_jog_devcompat();
	constraints = (struct mpc85xx_constraints *)compat->ocd_data;
	cpu = ofw_bus_get_node(device_get_parent(dev));

	if (cpu <= 0) {
		device_printf(dev,"No CPU device tree node!\n");
		return (ENXIO);
	}

	OF_getencprop(cpu, "reg", &sc->cpu, sizeof(sc->cpu));

	reg = ccsr_read4(GUTS_PORPLLSR);
	
	/*
	 * Assume power-on PLL is the highest PLL config supported on the
	 * board.
	 */
	sc->high = PMJCR_GET_CORE_MULT(reg, sc->cpu);
	sc->min_freq = constraints->threshold;
	sc->low = constraints->min_mult;

	cpufreq_register(dev);
	return (0);
}
Beispiel #8
0
static int
hwpstate_attach(device_t dev)
{

	return (cpufreq_register(dev));
}
static void
acpicpu_start(device_t self)
{
	struct acpicpu_softc *sc = device_private(self);
	static uint32_t count = 0;
	struct cpufreq cf;
	uint32_t i;

	/*
	 * Run the state-specific initialization routines. These
	 * must run only once, after interrupts have been enabled,
	 * all CPUs are running, and all ACPI CPUs have attached.
	 */
	if (++count != acpicpu_count || acpicpu_count != sc->sc_ncpus) {
		sc->sc_cold = false;
		return;
	}

	/*
	 * Set the last ACPI CPU as non-cold
	 * only after C-states are enabled.
	 */
	if ((sc->sc_flags & ACPICPU_FLAG_C) != 0)
		acpicpu_cstate_start(self);

	sc->sc_cold = false;

	if ((sc->sc_flags & ACPICPU_FLAG_P) != 0)
		acpicpu_pstate_start(self);

	if ((sc->sc_flags & ACPICPU_FLAG_T) != 0)
		acpicpu_tstate_start(self);

	acpicpu_sysctl(self);
	aprint_debug_dev(self, "ACPI CPUs started\n");

	/*
	 * Register with cpufreq(9).
	 */
	if ((sc->sc_flags & ACPICPU_FLAG_P) != 0) {

		(void)memset(&cf, 0, sizeof(struct cpufreq));

		cf.cf_mp = false;
		cf.cf_cookie = NULL;
		cf.cf_get_freq = acpicpu_pstate_get;
		cf.cf_set_freq = acpicpu_pstate_set;
		cf.cf_state_count = sc->sc_pstate_count;

		(void)strlcpy(cf.cf_name, "acpicpu", sizeof(cf.cf_name));

		for (i = 0; i < sc->sc_pstate_count; i++) {

			if (sc->sc_pstate[i].ps_freq == 0)
				continue;

			cf.cf_state[i].cfs_freq = sc->sc_pstate[i].ps_freq;
			cf.cf_state[i].cfs_power = sc->sc_pstate[i].ps_power;
		}

		if (cpufreq_register(&cf) != 0)
			aprint_error_dev(self, "failed to register cpufreq\n");
	}
}
Beispiel #10
0
static int
bcm2835_cpufreq_attach(device_t dev)
{
	struct bcm2835_cpufreq_softc *sc;
	struct sysctl_oid *oid;

	/* set self dev */
	sc = device_get_softc(dev);
	sc->dev = dev;

	/* initial values */
	sc->arm_max_freq = -1;
	sc->arm_min_freq = -1;
	sc->core_max_freq = -1;
	sc->core_min_freq = -1;
	sc->sdram_max_freq = -1;
	sc->sdram_min_freq = -1;
	sc->max_voltage_core = 0;
	sc->min_voltage_core = 0;

	/* setup sysctl at first device */
	if (device_get_unit(dev) == 0) {
		sysctl_ctx_init(&bcm2835_sysctl_ctx);
		/* create node for hw.cpufreq */
		oid = SYSCTL_ADD_NODE(&bcm2835_sysctl_ctx,
		    SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "cpufreq",
		    CTLFLAG_RD, NULL, "");

		/* Frequency (Hz) */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "arm_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_arm_freq, "IU",
		    "ARM frequency (Hz)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "core_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_core_freq, "IU",
		    "Core frequency (Hz)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "sdram_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_sdram_freq, "IU",
		    "SDRAM frequency (Hz)");

		/* Turbo state */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "turbo", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_turbo, "IU",
		    "Disables dynamic clocking");

		/* Voltage (offset from 1.2V in units of 0.025V) */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_core", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_voltage_core, "I",
		    "ARM/GPU core voltage"
		    "(offset from 1.2V in units of 0.025V)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_sdram", CTLTYPE_INT | CTLFLAG_WR, sc,
		    0, sysctl_bcm2835_cpufreq_voltage_sdram, "I",
		    "SDRAM voltage (offset from 1.2V in units of 0.025V)");

		/* Voltage individual SDRAM */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_sdram_c", CTLTYPE_INT | CTLFLAG_RW, sc,
		    0, sysctl_bcm2835_cpufreq_voltage_sdram_c, "I",
		    "SDRAM controller voltage"
		    "(offset from 1.2V in units of 0.025V)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_sdram_i", CTLTYPE_INT | CTLFLAG_RW, sc,
		    0, sysctl_bcm2835_cpufreq_voltage_sdram_i, "I",
		    "SDRAM I/O voltage (offset from 1.2V in units of 0.025V)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_sdram_p", CTLTYPE_INT | CTLFLAG_RW, sc,
		    0, sysctl_bcm2835_cpufreq_voltage_sdram_p, "I",
		    "SDRAM phy voltage (offset from 1.2V in units of 0.025V)");

		/* Temperature */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
		    sysctl_bcm2835_cpufreq_temperature, "I",
		    "SoC temperature (thousandths of a degree C)");
	}

	/* ARM->VC lock */
	sema_init(&vc_sema, 1, "vcsema");

	/* register callback for using mbox when interrupts are enabled */
	sc->init_hook.ich_func = bcm2835_cpufreq_init;
	sc->init_hook.ich_arg = sc;

	if (config_intrhook_establish(&sc->init_hook) != 0) {
		device_printf(dev, "config_intrhook_establish failed\n");
		return (ENOMEM);
	}

	/* this device is controlled by cpufreq(4) */
	cpufreq_register(dev);

	return (0);
}
Beispiel #11
0
static int
bcm2835_cpufreq_attach(device_t dev)
{
	struct bcm2835_cpufreq_softc *sc;
	struct sysctl_oid *oid;
	int err;

	/* set self dev */
	sc = device_get_softc(dev);
	sc->dev = dev;

	/* initial values */
	sc->arm_max_freq = -1;
	sc->arm_min_freq = -1;
	sc->core_max_freq = -1;
	sc->core_min_freq = -1;
	sc->sdram_max_freq = -1;
	sc->sdram_min_freq = -1;
	sc->max_voltage_core = 0;
	sc->min_voltage_core = 0;

	/* create VC mbox buffer */
	sc->dma_size = PAGE_SIZE;
	err = bus_dma_tag_create(
	    bus_get_dma_tag(sc->dev),
	    PAGE_SIZE, 0,		/* alignment, boundary */
	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
	    BUS_SPACE_MAXADDR,		/* highaddr */
	    NULL, NULL,			/* filter, filterarg */
	    sc->dma_size, 1,		/* maxsize, nsegments */
	    sc->dma_size, 0,		/* maxsegsize, flags */
	    NULL, NULL,			/* lockfunc, lockarg */
	    &sc->dma_tag);
	if (err) {
		device_printf(dev, "can't create DMA tag\n");
		return (ENXIO);
	}

	err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->dma_buf, 0,
	    &sc->dma_map);
	if (err) {
		bus_dma_tag_destroy(sc->dma_tag);
		device_printf(dev, "can't allocate dmamem\n");
		return (ENXIO);
	}

	err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->dma_buf,
	    sc->dma_size, bcm2835_cpufreq_cb, &sc->dma_phys, 0);
	if (err) {
		bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
		bus_dma_tag_destroy(sc->dma_tag);
		device_printf(dev, "can't load DMA map\n");
		return (ENXIO);
	}
	/* OK, ready to use VC buffer */

	/* setup sysctl at first device */
	if (device_get_unit(dev) == 0) {
		sysctl_ctx_init(&bcm2835_sysctl_ctx);
		/* create node for hw.cpufreq */
		oid = SYSCTL_ADD_NODE(&bcm2835_sysctl_ctx,
		    SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "cpufreq",
		    CTLFLAG_RD, NULL, "");

		/* Frequency (Hz) */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "arm_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_arm_freq, "IU",
		    "ARM frequency (Hz)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "core_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_core_freq, "IU",
		    "Core frequency (Hz)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "sdram_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_sdram_freq, "IU",
		    "SDRAM frequency (Hz)");

		/* Turbo state */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "turbo", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_turbo, "IU",
		    "Disables dynamic clocking");

		/* Voltage (offset from 1.2V in units of 0.025V) */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_core", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_voltage_core, "I",
		    "ARM/GPU core voltage"
		    "(offset from 1.2V in units of 0.025V)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_sdram", CTLTYPE_INT | CTLFLAG_WR, sc,
		    0, sysctl_bcm2835_cpufreq_voltage_sdram, "I",
		    "SDRAM voltage (offset from 1.2V in units of 0.025V)");

		/* Voltage individual SDRAM */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_sdram_c", CTLTYPE_INT | CTLFLAG_RW, sc,
		    0, sysctl_bcm2835_cpufreq_voltage_sdram_c, "I",
		    "SDRAM controller voltage"
		    "(offset from 1.2V in units of 0.025V)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_sdram_i", CTLTYPE_INT | CTLFLAG_RW, sc,
		    0, sysctl_bcm2835_cpufreq_voltage_sdram_i, "I",
		    "SDRAM I/O voltage (offset from 1.2V in units of 0.025V)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_sdram_p", CTLTYPE_INT | CTLFLAG_RW, sc,
		    0, sysctl_bcm2835_cpufreq_voltage_sdram_p, "I",
		    "SDRAM phy voltage (offset from 1.2V in units of 0.025V)");

		/* Temperature */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
		    sysctl_bcm2835_cpufreq_temperature, "I",
		    "SoC temperature (thousandths of a degree C)");
	}

	/* ARM->VC lock */
	sema_init(&vc_sema, 1, "vcsema");

	/* register callback for using mbox when interrupts are enabled */
	sc->init_hook.ich_func = bcm2835_cpufreq_init;
	sc->init_hook.ich_arg = sc;

	if (config_intrhook_establish(&sc->init_hook) != 0) {
		bus_dmamap_unload(sc->dma_tag, sc->dma_map);
		bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
		bus_dma_tag_destroy(sc->dma_tag);
		device_printf(dev, "config_intrhook_establish failed\n");
		return (ENOMEM);
	}

	/* this device is controlled by cpufreq(4) */
	cpufreq_register(dev);

	return (0);
}