xref: /freebsd/sys/arm/mv/armada38x/pmsu.c (revision fdafd315ad0d0f28a11b9fb4476a9ab059c62b92)
1ec22b42aSZbigniew Bodek /*-
2ec22b42aSZbigniew Bodek  * Copyright (c) 2015 Semihalf.
3ec22b42aSZbigniew Bodek  * Copyright (c) 2015 Stormshield.
4ec22b42aSZbigniew Bodek  * All rights reserved.
5ec22b42aSZbigniew Bodek  *
6ec22b42aSZbigniew Bodek  * Redistribution and use in source and binary forms, with or without
7ec22b42aSZbigniew Bodek  * modification, are permitted provided that the following conditions
8ec22b42aSZbigniew Bodek  * are met:
9ec22b42aSZbigniew Bodek  * 1. Redistributions of source code must retain the above copyright
10ec22b42aSZbigniew Bodek  *    notice, this list of conditions and the following disclaimer.
11ec22b42aSZbigniew Bodek  * 2. Redistributions in binary form must reproduce the above copyright
12ec22b42aSZbigniew Bodek  *    notice, this list of conditions and the following disclaimer in the
13ec22b42aSZbigniew Bodek  *    documentation and/or other materials provided with the distribution.
14ec22b42aSZbigniew Bodek  *
15ec22b42aSZbigniew Bodek  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16ec22b42aSZbigniew Bodek  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17ec22b42aSZbigniew Bodek  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ec22b42aSZbigniew Bodek  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19ec22b42aSZbigniew Bodek  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20ec22b42aSZbigniew Bodek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21ec22b42aSZbigniew Bodek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22ec22b42aSZbigniew Bodek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23ec22b42aSZbigniew Bodek  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24ec22b42aSZbigniew Bodek  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25ec22b42aSZbigniew Bodek  * SUCH DAMAGE.
26ec22b42aSZbigniew Bodek  */
27ec22b42aSZbigniew Bodek 
28ec22b42aSZbigniew Bodek #include <sys/param.h>
29ec22b42aSZbigniew Bodek #include <sys/bus.h>
30ec22b42aSZbigniew Bodek #include <sys/conf.h>
31ec22b42aSZbigniew Bodek #include <sys/rman.h>
32ec22b42aSZbigniew Bodek #include <sys/types.h>
33ec22b42aSZbigniew Bodek #include <sys/kernel.h>
34ec22b42aSZbigniew Bodek #include <sys/module.h>
35ec22b42aSZbigniew Bodek #include <sys/resource.h>
36a89156f5SMichal Meloun #include <sys/systm.h>
37ec22b42aSZbigniew Bodek 
38ec22b42aSZbigniew Bodek #include <vm/vm.h>
39ec22b42aSZbigniew Bodek #include <vm/pmap.h>
40ec22b42aSZbigniew Bodek 
41a89156f5SMichal Meloun #include <machine/cpu.h>
42ec22b42aSZbigniew Bodek #include <machine/fdt.h>
43ec22b42aSZbigniew Bodek #include <machine/smp.h>
44ec22b42aSZbigniew Bodek 
45ec22b42aSZbigniew Bodek #include <dev/ofw/ofw_bus_subr.h>
46ec22b42aSZbigniew Bodek 
47ec22b42aSZbigniew Bodek #include <arm/mv/mvreg.h>
48ec22b42aSZbigniew Bodek 
49ec22b42aSZbigniew Bodek #include "pmsu.h"
50ec22b42aSZbigniew Bodek 
51ec22b42aSZbigniew Bodek static struct resource_spec pmsu_spec[] = {
52ec22b42aSZbigniew Bodek 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
53ec22b42aSZbigniew Bodek 	{ -1, 0 }
54ec22b42aSZbigniew Bodek };
55ec22b42aSZbigniew Bodek 
56ec22b42aSZbigniew Bodek struct pmsu_softc {
57ec22b42aSZbigniew Bodek 	device_t	dev;
58ec22b42aSZbigniew Bodek 	struct resource	*res;
59ec22b42aSZbigniew Bodek };
60ec22b42aSZbigniew Bodek 
61ec22b42aSZbigniew Bodek static int pmsu_probe(device_t dev);
62ec22b42aSZbigniew Bodek static int pmsu_attach(device_t dev);
63ec22b42aSZbigniew Bodek static int pmsu_detach(device_t dev);
64ec22b42aSZbigniew Bodek 
65ec22b42aSZbigniew Bodek static device_method_t pmsu_methods[] = {
66ec22b42aSZbigniew Bodek 	DEVMETHOD(device_probe,		pmsu_probe),
67ec22b42aSZbigniew Bodek 	DEVMETHOD(device_attach,	pmsu_attach),
68ec22b42aSZbigniew Bodek 	DEVMETHOD(device_detach,	pmsu_detach),
69ec22b42aSZbigniew Bodek 	{ 0, 0 }
70ec22b42aSZbigniew Bodek };
71ec22b42aSZbigniew Bodek 
72ec22b42aSZbigniew Bodek static driver_t pmsu_driver = {
73ec22b42aSZbigniew Bodek 	"pmsu",
74ec22b42aSZbigniew Bodek 	pmsu_methods,
75ec22b42aSZbigniew Bodek 	sizeof(struct pmsu_softc)
76ec22b42aSZbigniew Bodek };
77ec22b42aSZbigniew Bodek 
78*a3b866cbSJohn Baldwin DRIVER_MODULE(pmsu, simplebus, pmsu_driver, 0, 0);
79*a3b866cbSJohn Baldwin DRIVER_MODULE(pmsu, ofwbus, pmsu_driver, 0, 0);
80ec22b42aSZbigniew Bodek 
81ec22b42aSZbigniew Bodek static int
pmsu_probe(device_t dev)82ec22b42aSZbigniew Bodek pmsu_probe(device_t dev)
83ec22b42aSZbigniew Bodek {
84ec22b42aSZbigniew Bodek 
85ec22b42aSZbigniew Bodek 	if (!ofw_bus_status_okay(dev))
86ec22b42aSZbigniew Bodek 		return (ENXIO);
87ec22b42aSZbigniew Bodek 
88ec22b42aSZbigniew Bodek 	if (!ofw_bus_is_compatible(dev, "marvell,armada-380-pmsu"))
89ec22b42aSZbigniew Bodek 		return (ENXIO);
90ec22b42aSZbigniew Bodek 
91ec22b42aSZbigniew Bodek 	device_set_desc(dev, "Power Management Service Unit");
92ec22b42aSZbigniew Bodek 
93ec22b42aSZbigniew Bodek 	return (BUS_PROBE_DEFAULT);
94ec22b42aSZbigniew Bodek }
95ec22b42aSZbigniew Bodek 
96ec22b42aSZbigniew Bodek static int
pmsu_attach(device_t dev)97ec22b42aSZbigniew Bodek pmsu_attach(device_t dev)
98ec22b42aSZbigniew Bodek {
99ec22b42aSZbigniew Bodek 	struct pmsu_softc *sc;
100ec22b42aSZbigniew Bodek 	int err;
101ec22b42aSZbigniew Bodek 
102ec22b42aSZbigniew Bodek 	sc = device_get_softc(dev);
103ec22b42aSZbigniew Bodek 	sc->dev = dev;
104ec22b42aSZbigniew Bodek 
105ec22b42aSZbigniew Bodek 	err = bus_alloc_resources(dev, pmsu_spec, &sc->res);
106ec22b42aSZbigniew Bodek 	if (err != 0) {
107ec22b42aSZbigniew Bodek 		device_printf(dev, "could not allocate resources\n");
108ec22b42aSZbigniew Bodek 		return (ENXIO);
109ec22b42aSZbigniew Bodek 	}
110ec22b42aSZbigniew Bodek 
111ec22b42aSZbigniew Bodek 	return (0);
112ec22b42aSZbigniew Bodek }
113ec22b42aSZbigniew Bodek 
114ec22b42aSZbigniew Bodek static int
pmsu_detach(device_t dev)115ec22b42aSZbigniew Bodek pmsu_detach(device_t dev)
116ec22b42aSZbigniew Bodek {
117ec22b42aSZbigniew Bodek 	struct pmsu_softc *sc;
118ec22b42aSZbigniew Bodek 
119ec22b42aSZbigniew Bodek 	sc = device_get_softc(dev);
120ec22b42aSZbigniew Bodek 
121ec22b42aSZbigniew Bodek 	bus_release_resources(dev, pmsu_spec, &sc->res);
122ec22b42aSZbigniew Bodek 
123ec22b42aSZbigniew Bodek 	return (0);
124ec22b42aSZbigniew Bodek }
125ec22b42aSZbigniew Bodek 
126ec22b42aSZbigniew Bodek #ifdef SMP
127ec22b42aSZbigniew Bodek int
pmsu_boot_secondary_cpu(void)128ec22b42aSZbigniew Bodek pmsu_boot_secondary_cpu(void)
129ec22b42aSZbigniew Bodek {
130ec22b42aSZbigniew Bodek 	bus_space_handle_t vaddr;
131ec22b42aSZbigniew Bodek 	int rv;
132ec22b42aSZbigniew Bodek 
133ec22b42aSZbigniew Bodek 	rv = bus_space_map(fdtbus_bs_tag, (bus_addr_t)MV_PMSU_BASE, MV_PMSU_REGS_LEN,
134ec22b42aSZbigniew Bodek 	    0, &vaddr);
135ec22b42aSZbigniew Bodek 	if (rv != 0)
136ec22b42aSZbigniew Bodek 		return (rv);
137ec22b42aSZbigniew Bodek 
138ec22b42aSZbigniew Bodek 	/* Boot cpu1 */
139ec22b42aSZbigniew Bodek 	bus_space_write_4(fdtbus_bs_tag, vaddr, PMSU_BOOT_ADDR_REDIRECT_OFFSET(1),
140ec22b42aSZbigniew Bodek 	    pmap_kextract((vm_offset_t)mpentry));
141ec22b42aSZbigniew Bodek 
142a89156f5SMichal Meloun 	dcache_wbinv_poc_all();
1437cc70732SMichal Meloun 	dsb();
1447cc70732SMichal Meloun 	sev();
145ec22b42aSZbigniew Bodek 
146ec22b42aSZbigniew Bodek 	bus_space_unmap(fdtbus_bs_tag, vaddr, MV_PMSU_REGS_LEN);
147ec22b42aSZbigniew Bodek 
148ec22b42aSZbigniew Bodek 	return (0);
149ec22b42aSZbigniew Bodek }
150ec22b42aSZbigniew Bodek #endif
151