]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/sparc64/sparc64/jbusppm.c
Upgrade Unbound to 1.6.5. More to follow.
[FreeBSD/FreeBSD.git] / sys / sparc64 / sparc64 / jbusppm.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2008 Marius Strobl <marius@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/resource.h>
38 #include <sys/rman.h>
39
40 #include <dev/ofw/ofw_bus.h>
41
42 #include <machine/bus.h>
43 #include <machine/resource.h>
44
45 #if 1
46 #include <sparc64/pci/ofw_pci.h>
47 #endif
48
49 #define JBUSPPM_NREG    2
50
51 #define JBUSPPM_DEVID   0
52 #define JBUSPPM_ESTAR   1
53
54 #define JBUSPPM_DEVID_JID               0x00
55 #define JBUSPPM_DEVID_JID_MASTER        0x00040000
56
57 #define JBUSPPM_ESTAR_CTRL              0x00
58 #define JBUSPPM_ESTAR_CTRL_1            0x00000001
59 #define JBUSPPM_ESTAR_CTRL_2            0x00000002
60 #define JBUSPPM_ESTAR_CTRL_32           0x00000020
61 #define JBUSPPM_ESTAR_CTRL_MASK                                         \
62         (JBUSPPM_ESTAR_CTRL_1 | JBUSPPM_ESTAR_CTRL_2 | JBUSPPM_ESTAR_CTRL_32)
63 #define JBUSPPM_ESTAR_JCHNG             0x08
64 #define JBUSPPM_ESTAR_JCHNG_DELAY_MASK  0x00000007
65 #define JBUSPPM_ESTAR_JCHNG_START       0x00000010
66 #define JBUSPPM_ESTAR_JCHNG_OCCURED     0x00000018
67
68 struct jbusppm_softc {
69         struct resource         *sc_res[JBUSPPM_NREG];
70         bus_space_tag_t         sc_bt[JBUSPPM_NREG];
71         bus_space_handle_t      sc_bh[JBUSPPM_NREG];
72 };
73
74 #define JBUSPPM_READ(sc, reg, off)                                      \
75         bus_space_read_8((sc)->sc_bt[(reg)], (sc)->sc_bh[(reg)], (off))
76 #define JBUSPPM_WRITE(sc, reg, off, val)                                \
77         bus_space_write_8((sc)->sc_bt[(reg)], (sc)->sc_bh[(reg)], (off), (val))
78
79 static device_probe_t jbusppm_probe;
80 static device_attach_t jbusppm_attach;
81
82 static device_method_t jbusppm_methods[] = {
83         /* Device interface */
84         DEVMETHOD(device_probe,         jbusppm_probe),
85         DEVMETHOD(device_attach,        jbusppm_attach),
86
87         DEVMETHOD_END
88 };
89
90 static devclass_t jbusppm_devclass;
91
92 DEFINE_CLASS_0(jbusppm, jbusppm_driver, jbusppm_methods,
93     sizeof(struct jbusppm_softc));
94 DRIVER_MODULE(jbusppm, nexus, jbusppm_driver, jbusppm_devclass, 0, 0);
95
96 static int
97 jbusppm_probe(device_t dev)
98 {
99         const char* compat;
100
101         compat = ofw_bus_get_compat(dev);
102         if (compat != NULL && strcmp(ofw_bus_get_name(dev), "ppm") == 0 &&
103             strcmp(compat, "jbus-ppm") == 0) {
104                 device_set_desc(dev, "JBus power management");
105                 return (BUS_PROBE_DEFAULT);
106         }
107         return (ENXIO);
108 }
109
110 static int
111 jbusppm_attach(device_t dev)
112 {
113         struct jbusppm_softc *sc;
114         int i, rid;
115 #if 1
116         device_t *children, tomatillo;
117         u_long tcount, tstart, jcount, jstart;
118         int j, nchildren;
119 #endif
120
121         sc = device_get_softc(dev);
122         for (i = JBUSPPM_DEVID; i <= JBUSPPM_ESTAR; i++) {
123                 rid = i;
124                 /*
125                  * The JBUSPPM_ESTAR resources is shared with that of the
126                  * Tomatillo bus A controller configuration register bank.
127                  */
128 #if 0
129                 sc->sc_res[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
130                     &rid, (i == JBUSPPM_ESTAR ? RF_SHAREABLE : 0) | RF_ACTIVE);
131                 if (sc->sc_res[i] == NULL) {
132                         device_printf(dev,
133                             "could not allocate resource %d\n", i);
134                         goto fail;
135                 }
136                 sc->sc_bt[i] = rman_get_bustag(sc->sc_res[i]);
137                 sc->sc_bh[i] = rman_get_bushandle(sc->sc_res[i]);
138 #else
139                 /*
140                  * Workaround for the fact that rman(9) only allows to
141                  * share resources of the same size.
142                  */
143                 if (i == JBUSPPM_ESTAR) {
144                         if (bus_get_resource(dev, SYS_RES_MEMORY, i, &jstart,
145                             &jcount) != 0) {
146                                 device_printf(dev,
147                                     "could not determine Estar resource\n");
148                                 goto fail;
149                         }
150                         if (device_get_children(device_get_parent(dev),
151                             &children, &nchildren) != 0) {
152                                 device_printf(dev, "could not get children\n");
153                                 goto fail;
154                         }
155                         tomatillo = NULL;
156                         for (j = 0; j < nchildren; j++) {
157                                 if (ofw_bus_get_type(children[j]) != NULL &&
158                                     strcmp(ofw_bus_get_type(children[j]),
159                                     OFW_TYPE_PCI) == 0 &&
160                                     ofw_bus_get_compat(children[j]) != NULL &&
161                                     strcmp(ofw_bus_get_compat(children[j]),
162                                     "pci108e,a801") == 0 &&
163                                     ((bus_get_resource_start(children[j],
164                                     SYS_RES_MEMORY, 0) >> 20) & 1) == 0) {
165                                         tomatillo = children[j];
166                                         break;
167                                 }
168                         }
169                         free(children, M_TEMP);
170                         if (tomatillo == NULL) {
171                                 device_printf(dev,
172                                     "could not find Tomatillo\n");
173                                 goto fail;
174                         }
175                         if (bus_get_resource(tomatillo, SYS_RES_MEMORY, 1,
176                             &tstart, &tcount) != 0) {
177                                 device_printf(dev,
178                                     "could not determine Tomatillo "
179                                     "resource\n");
180                                 goto fail;
181                         }
182                         sc->sc_res[i] = bus_alloc_resource(dev, SYS_RES_MEMORY,
183                             &rid, tstart, tstart + tcount - 1, tcount,
184                             RF_SHAREABLE | RF_ACTIVE);
185                 } else
186                         sc->sc_res[i] = bus_alloc_resource_any(dev,
187                             SYS_RES_MEMORY, &rid, RF_ACTIVE);
188                 if (sc->sc_res[i] == NULL) {
189                         device_printf(dev,
190                             "could not allocate resource %d\n", i);
191                         goto fail;
192                 }
193                 sc->sc_bt[i] = rman_get_bustag(sc->sc_res[i]);
194                 sc->sc_bh[i] = rman_get_bushandle(sc->sc_res[i]);
195                 if (i == JBUSPPM_ESTAR)
196                         bus_space_subregion(sc->sc_bt[i], sc->sc_bh[i],
197                             jstart - tstart, jcount, &sc->sc_bh[i]);
198 #endif
199         }
200
201         if (bootverbose) {
202                 if ((JBUSPPM_READ(sc, JBUSPPM_DEVID, JBUSPPM_DEVID_JID) &
203                     JBUSPPM_DEVID_JID_MASTER) != 0)
204                         device_printf(dev, "master I/O bridge\n");
205                 device_printf(dev, "running at ");
206                 switch (JBUSPPM_READ(sc, JBUSPPM_ESTAR, JBUSPPM_ESTAR_CTRL) &
207                     JBUSPPM_ESTAR_CTRL_MASK) {
208                 case JBUSPPM_ESTAR_CTRL_1:
209                         printf("full");
210                         break;
211                 case JBUSPPM_ESTAR_CTRL_2:
212                         printf("half");
213                         break;
214                 case JBUSPPM_ESTAR_CTRL_32:
215                         printf("1/32");
216                         break;
217                 default:
218                         printf("unknown");
219                         break;
220                 }
221                 printf(" speed\n");
222         }
223
224         return (0);
225
226  fail:
227         for (i = JBUSPPM_DEVID; i <= JBUSPPM_ESTAR && sc->sc_res[i] != NULL;
228             i++)
229                 bus_release_resource(dev, SYS_RES_MEMORY,
230                     rman_get_rid(sc->sc_res[i]), sc->sc_res[i]);
231         return (ENXIO);
232 }