geode.c revision 126349
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: head/sys/i386/i386/geode.c 126349 2004-02-28 13:15:53Z phk $");
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 <dev/pci/pcireg.h>
36#include <dev/pci/pcivar.h>
37
38#include "opt_cpu.h"
39
40static unsigned	cba;
41static unsigned	gpio;
42static unsigned	geode_counter;
43
44#ifdef CPU_SOEKRIS
45
46#include <dev/led/led.h>
47
48static dev_t	errorled;
49
50static void
51err_led(void *unused, int onoff)
52{
53	uint32_t u;
54
55	u = inl(gpio + 4);
56	if (onoff)
57		u |= 1 << 20;
58	else
59		u &= ~(1 << 20);
60	outl(gpio, u);
61}
62#endif
63
64
65static unsigned
66geode_get_timecount(struct timecounter *tc)
67{
68	return (inl(geode_counter));
69}
70
71static struct timecounter geode_timecounter = {
72	geode_get_timecount,
73	NULL,
74	0xffffffff,
75	27000000,
76	"Geode",
77	1000
78};
79
80static int
81geode_probe(device_t self)
82{
83
84	if (pci_get_devid(self) == 0x0515100b) {
85		if (geode_counter == 0) {
86			/*
87			 * The address of the CBA is written to this register
88			 * by the bios, see p161 in data sheet.
89			 */
90			cba = pci_read_config(self, 0x64, 4);
91			printf("Geode CBA@ 0x%x\n", cba);
92			geode_counter = cba + 0x08;
93			outl(cba + 0x0d, 2);
94			printf("Geode rev: %02x %02x\n",
95				inb(cba + 0x3c), inb(cba + 0x3d));
96			tc_init(&geode_timecounter);
97		}
98	} else if (pci_get_devid(self) == 0x0510100b) {
99		gpio = pci_read_config(self, PCIR_BAR(0), 4);
100		gpio &= ~0x1f;
101		printf("Geode GPIO@ = %x\n", gpio);
102#ifdef CPU_SOEKRIS
103		errorled = led_create(err_led, NULL, "error");
104#endif
105	}
106	return (ENXIO);
107}
108
109static int
110geode_attach(device_t self)
111{
112
113	return(ENODEV);
114}
115
116static device_method_t geode_methods[] = {
117	/* Device interface */
118	DEVMETHOD(device_probe,		geode_probe),
119	DEVMETHOD(device_attach,	geode_attach),
120	DEVMETHOD(device_suspend,	bus_generic_suspend),
121	DEVMETHOD(device_resume,	bus_generic_resume),
122	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
123	{0, 0}
124};
125
126static driver_t geode_driver = {
127	"geode",
128	geode_methods,
129	0,
130};
131
132static devclass_t geode_devclass;
133
134DRIVER_MODULE(geode, pci, geode_driver, geode_devclass, 0, 0);
135