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