The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/i386/geode.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2003-2004 Poul-Henning Kamp
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/timetc.h>
   33 #include <sys/bus.h>
   34 #include <sys/kernel.h>
   35 #include <sys/module.h>
   36 #include <sys/watchdog.h>
   37 #include <dev/pci/pcireg.h>
   38 #include <dev/pci/pcivar.h>
   39 #include <dev/led/led.h>
   40 #include <machine/pc/bios.h>
   41 
   42 static unsigned cba;
   43 static unsigned gpio;
   44 static unsigned geode_counter;
   45 
   46 static struct cdev *led1, *led2, *led3;
   47 static int      led1b, led2b, led3b;
   48 
   49 static void
   50 led_func(void *ptr, int onoff)
   51 {
   52         uint32_t u;
   53         int bit;
   54 
   55         bit = *(int *)ptr;
   56         if (bit < 0) {
   57                 bit = -bit;
   58                 onoff = !onoff;
   59         }
   60 
   61         u = inl(gpio + 4);
   62         if (onoff)
   63                 u |= 1 << bit;
   64         else
   65                 u &= ~(1 << bit);
   66         outl(gpio, u);
   67 }
   68 
   69 
   70 static unsigned
   71 geode_get_timecount(struct timecounter *tc)
   72 {
   73         return (inl(geode_counter));
   74 }
   75 
   76 static struct timecounter geode_timecounter = {
   77         geode_get_timecount,
   78         NULL,
   79         0xffffffff,
   80         27000000,
   81         "Geode",
   82         1000
   83 };
   84 
   85 /*
   86  * The GEODE watchdog runs from a 32kHz frequency.  One period of that is
   87  * 31250 nanoseconds which we round down to 2^14 nanoseconds.  The watchdog
   88  * consists of a power-of-two prescaler and a 16 bit counter, so the math
   89  * is quite simple.  The max timeout is 14 + 16 + 13 = 2^43 nsec ~= 2h26m.
   90  */
   91 static void
   92 geode_watchdog(void *foo __unused, u_int cmd, int *error)
   93 {
   94         u_int u, p, r;
   95 
   96         u = cmd & WD_INTERVAL;
   97         if (cmd && u >= 14 && u <= 43) {
   98                 u -= 14;
   99                 if (u > 16) {
  100                         p = u - 16;
  101                         u -= p;
  102                 } else {
  103                         p = 0;
  104                 }
  105                 if (u == 16)
  106                         u = (1 << u) - 1;
  107                 else
  108                         u = 1 << u;
  109                 r = inw(cba + 2) & 0xff00;
  110                 outw(cba + 2, p | 0xf0 | r);
  111                 outw(cba, u);
  112                 *error = 0;
  113         } else {
  114                 outw(cba, 0);
  115         }
  116 }
  117 
  118 static int
  119 geode_probe(device_t self)
  120 {
  121 
  122         if (pci_get_devid(self) == 0x0515100b) {
  123                 if (geode_counter == 0) {
  124                         /*
  125                          * The address of the CBA is written to this register
  126                          * by the bios, see p161 in data sheet.
  127                          */
  128                         cba = pci_read_config(self, 0x64, 4);
  129                         printf("Geode CBA@ 0x%x\n", cba);
  130                         geode_counter = cba + 0x08;
  131                         outl(cba + 0x0d, 2);
  132                         printf("Geode rev: %02x %02x\n",
  133                                 inb(cba + 0x3c), inb(cba + 0x3d));
  134                         tc_init(&geode_timecounter);
  135                         EVENTHANDLER_REGISTER(watchdog_list, geode_watchdog,
  136                             NULL, 0);
  137                 }
  138         } else if (pci_get_devid(self) == 0x0510100b) {
  139                 gpio = pci_read_config(self, PCIR_BAR(0), 4);
  140                 gpio &= ~0x1f;
  141                 printf("Geode GPIO@ = %x\n", gpio);
  142                 if (NULL != 
  143                     bios_string(0xf0000, 0xf0100, "Soekris Engineering", 0)) {
  144                         printf("Soekris Engineering NET4801 platform\n");
  145                         led1b = 20;
  146                         led1 = led_create(led_func, &led1b, "error");
  147                 } else if (NULL !=
  148                     bios_string(0xf9000, 0xf9000, "PC Engines WRAP.1C ", 0)) {
  149                         printf("PC Engines WRAP.1C platfrom\n");
  150                         led1b = -2;
  151                         led2b = -3;
  152                         led3b = -18;
  153                         led1 = led_create(led_func, &led1b, "led1");
  154                         led2 = led_create(led_func, &led2b, "led2");
  155                         led3 = led_create(led_func, &led3b, "led3");
  156                         /*
  157                          * Turn on first LED so we don't make people think
  158                          * their box just died.
  159                          */
  160                         led_func(&led1b, 1);
  161                 }
  162         }
  163         return (ENXIO);
  164 }
  165 
  166 static int
  167 geode_attach(device_t self)
  168 {
  169 
  170         return(ENODEV);
  171 }
  172 
  173 static device_method_t geode_methods[] = {
  174         /* Device interface */
  175         DEVMETHOD(device_probe,         geode_probe),
  176         DEVMETHOD(device_attach,        geode_attach),
  177         DEVMETHOD(device_suspend,       bus_generic_suspend),
  178         DEVMETHOD(device_resume,        bus_generic_resume),
  179         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
  180         {0, 0}
  181 };
  182  
  183 static driver_t geode_driver = {
  184         "geode",
  185         geode_methods,
  186         0,
  187 };
  188 
  189 static devclass_t geode_devclass;
  190 
  191 DRIVER_MODULE(geode, pci, geode_driver, geode_devclass, 0, 0);

Cache object: 487d011bbfc8e06d356fc282bc50f09d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.