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