19eb9db93SNathan Whitehorn /*- 29eb9db93SNathan Whitehorn * Copyright (c) 2009 Nathan Whitehorn 39eb9db93SNathan Whitehorn * All rights reserved. 49eb9db93SNathan Whitehorn * 59eb9db93SNathan Whitehorn * Redistribution and use in source and binary forms, with or without 69eb9db93SNathan Whitehorn * modification, are permitted provided that the following conditions 79eb9db93SNathan Whitehorn * are met: 89eb9db93SNathan Whitehorn * 1. Redistributions of source code must retain the above copyright 99eb9db93SNathan Whitehorn * notice, this list of conditions and the following disclaimer. 109eb9db93SNathan Whitehorn * 2. Redistributions in binary form must reproduce the above copyright 119eb9db93SNathan Whitehorn * notice, this list of conditions and the following disclaimer in the 129eb9db93SNathan Whitehorn * documentation and/or other materials provided with the distribution. 139eb9db93SNathan Whitehorn * 149eb9db93SNathan Whitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 159eb9db93SNathan Whitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 169eb9db93SNathan Whitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 179eb9db93SNathan Whitehorn * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 189eb9db93SNathan Whitehorn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 199eb9db93SNathan Whitehorn * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 209eb9db93SNathan Whitehorn * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 219eb9db93SNathan Whitehorn * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 229eb9db93SNathan Whitehorn * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 239eb9db93SNathan Whitehorn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 249eb9db93SNathan Whitehorn * SUCH DAMAGE. 259eb9db93SNathan Whitehorn * 269eb9db93SNathan Whitehorn */ 279eb9db93SNathan Whitehorn 289eb9db93SNathan Whitehorn #include <sys/cdefs.h> 299eb9db93SNathan Whitehorn __FBSDID("$FreeBSD$"); 309eb9db93SNathan Whitehorn 319eb9db93SNathan Whitehorn #include <sys/param.h> 329eb9db93SNathan Whitehorn #include <sys/systm.h> 339eb9db93SNathan Whitehorn #include <sys/module.h> 349eb9db93SNathan Whitehorn #include <sys/bus.h> 359eb9db93SNathan Whitehorn #include <sys/conf.h> 369eb9db93SNathan Whitehorn #include <sys/cpu.h> 379eb9db93SNathan Whitehorn #include <sys/kernel.h> 389eb9db93SNathan Whitehorn #include <sys/sysctl.h> 399eb9db93SNathan Whitehorn 409eb9db93SNathan Whitehorn #include <dev/ofw/ofw_bus.h> 419eb9db93SNathan Whitehorn #include <dev/ofw/openfirm.h> 429eb9db93SNathan Whitehorn 439eb9db93SNathan Whitehorn #include <powerpc/powermac/macgpiovar.h> 449eb9db93SNathan Whitehorn 459eb9db93SNathan Whitehorn static int vcoregpio_probe(device_t); 469eb9db93SNathan Whitehorn static int vcoregpio_attach(device_t); 479eb9db93SNathan Whitehorn static void vcoregpio_pre_change(device_t, const struct cf_level *level); 489eb9db93SNathan Whitehorn static void vcoregpio_post_change(device_t, const struct cf_level *level); 499eb9db93SNathan Whitehorn 509eb9db93SNathan Whitehorn static device_method_t vcoregpio_methods[] = { 519eb9db93SNathan Whitehorn /* Device interface */ 529eb9db93SNathan Whitehorn DEVMETHOD(device_probe, vcoregpio_probe), 539eb9db93SNathan Whitehorn DEVMETHOD(device_attach, vcoregpio_attach), 549eb9db93SNathan Whitehorn { 0, 0 }, 559eb9db93SNathan Whitehorn }; 569eb9db93SNathan Whitehorn 579eb9db93SNathan Whitehorn static driver_t vcoregpio_driver = { 589eb9db93SNathan Whitehorn "vcoregpio", 599eb9db93SNathan Whitehorn vcoregpio_methods, 609eb9db93SNathan Whitehorn 0 619eb9db93SNathan Whitehorn }; 629eb9db93SNathan Whitehorn 639eb9db93SNathan Whitehorn static devclass_t vcoregpio_devclass; 649eb9db93SNathan Whitehorn 659eb9db93SNathan Whitehorn DRIVER_MODULE(vcoregpio, macgpio, vcoregpio_driver, vcoregpio_devclass, 0, 0); 669eb9db93SNathan Whitehorn 679eb9db93SNathan Whitehorn static int 689eb9db93SNathan Whitehorn vcoregpio_probe(device_t dev) 699eb9db93SNathan Whitehorn { 709eb9db93SNathan Whitehorn const char *name = ofw_bus_get_name(dev); 719eb9db93SNathan Whitehorn 729eb9db93SNathan Whitehorn if (strcmp(name, "cpu-vcore-select") != 0) 739eb9db93SNathan Whitehorn return (ENXIO); 749eb9db93SNathan Whitehorn 759eb9db93SNathan Whitehorn device_set_desc(dev, "CPU Core Voltage Control"); 769eb9db93SNathan Whitehorn return (0); 779eb9db93SNathan Whitehorn } 789eb9db93SNathan Whitehorn 799eb9db93SNathan Whitehorn static int 809eb9db93SNathan Whitehorn vcoregpio_attach(device_t dev) 819eb9db93SNathan Whitehorn { 829eb9db93SNathan Whitehorn EVENTHANDLER_REGISTER(cpufreq_pre_change, vcoregpio_pre_change, dev, 839eb9db93SNathan Whitehorn EVENTHANDLER_PRI_ANY); 849eb9db93SNathan Whitehorn EVENTHANDLER_REGISTER(cpufreq_post_change, vcoregpio_post_change, dev, 859eb9db93SNathan Whitehorn EVENTHANDLER_PRI_ANY); 869eb9db93SNathan Whitehorn 879eb9db93SNathan Whitehorn return (0); 889eb9db93SNathan Whitehorn } 899eb9db93SNathan Whitehorn 909eb9db93SNathan Whitehorn static void 919eb9db93SNathan Whitehorn vcoregpio_pre_change(device_t dev, const struct cf_level *level) 929eb9db93SNathan Whitehorn { 939eb9db93SNathan Whitehorn if (level->rel_set[0].freq == 10000 /* max */) { 949eb9db93SNathan Whitehorn /* 959eb9db93SNathan Whitehorn * Make sure the CPU voltage is raised before we raise 969eb9db93SNathan Whitehorn * the clock. 979eb9db93SNathan Whitehorn */ 989eb9db93SNathan Whitehorn macgpio_write(dev, GPIO_DDR_OUTPUT | 1); 999eb9db93SNathan Whitehorn DELAY(1000); 1009eb9db93SNathan Whitehorn } 1019eb9db93SNathan Whitehorn } 1029eb9db93SNathan Whitehorn 1039eb9db93SNathan Whitehorn static void 1049eb9db93SNathan Whitehorn vcoregpio_post_change(device_t dev, const struct cf_level *level) 1059eb9db93SNathan Whitehorn { 1069eb9db93SNathan Whitehorn if (level->rel_set[0].freq < 10000 /* max */) { 1079eb9db93SNathan Whitehorn DELAY(1000); 1089eb9db93SNathan Whitehorn /* We are safe to reduce CPU voltage now */ 1099eb9db93SNathan Whitehorn macgpio_write(dev, GPIO_DDR_OUTPUT | 0); 1109eb9db93SNathan Whitehorn } 1119eb9db93SNathan Whitehorn } 1129eb9db93SNathan Whitehorn 113