1316370Sgonzo/*
2316370Sgonzo * Copyright (c) 2017 Oleksandr Tymoshenko <gonzo@freebsd.org>
3316370Sgonzo * All rights reserved.
4316370Sgonzo *
5316370Sgonzo * Redistribution and use in source and binary forms, with or without
6316370Sgonzo * modification, are permitted provided that the following conditions
7316370Sgonzo * are met:
8316370Sgonzo * 1. Redistributions of source code must retain the above copyright
9316370Sgonzo *    notice, this list of conditions and the following disclaimer.
10316370Sgonzo * 2. Redistributions in binary form must reproduce the above copyright
11316370Sgonzo *    notice, this list of conditions and the following disclaimer in the
12316370Sgonzo *    documentation and/or other materials provided with the distribution.
13316370Sgonzo * 3. All advertising materials mentioning features or use of this software
14316370Sgonzo *    must display the following acknowledgement:
15316370Sgonzo *	This product includes software developed by Ben Gray.
16316370Sgonzo * 4. The name of the company nor the name of the author may be used to
17316370Sgonzo *    endorse or promote products derived from this software without specific
18316370Sgonzo *    prior written permission.
19316370Sgonzo *
20316370Sgonzo * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``AS IS'' AND ANY EXPRESS OR
21316370Sgonzo * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22316370Sgonzo * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23316370Sgonzo * IN NO EVENT SHALL BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24316370Sgonzo * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25316370Sgonzo * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26316370Sgonzo * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27316370Sgonzo * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28316370Sgonzo * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29316370Sgonzo * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30316370Sgonzo */
31316370Sgonzo
32316370Sgonzo/*
33316370Sgonzo * SCM - System Control Module
34316370Sgonzo */
35316370Sgonzo#include <sys/cdefs.h>
36316370Sgonzo__FBSDID("$FreeBSD: stable/11/sys/arm/versatile/versatile_scm.c 331402 2018-03-23 01:37:31Z gonzo $");
37316370Sgonzo
38316370Sgonzo#include <sys/param.h>
39316370Sgonzo#include <sys/systm.h>
40316370Sgonzo#include <sys/kernel.h>
41316370Sgonzo#include <sys/module.h>
42316370Sgonzo#include <sys/bus.h>
43316370Sgonzo#include <sys/resource.h>
44316370Sgonzo#include <sys/rman.h>
45316370Sgonzo#include <sys/lock.h>
46316370Sgonzo#include <sys/mutex.h>
47316370Sgonzo
48316370Sgonzo#include <machine/bus.h>
49316370Sgonzo#include <machine/resource.h>
50316370Sgonzo
51316370Sgonzo#include <dev/ofw/openfirm.h>
52316370Sgonzo#include <dev/ofw/ofw_bus.h>
53316370Sgonzo#include <dev/ofw/ofw_bus_subr.h>
54316370Sgonzo
55316370Sgonzo#include "versatile_scm.h"
56316370Sgonzo
57316370Sgonzostruct versatile_scm_softc {
58316370Sgonzo	device_t		sc_dev;
59316370Sgonzo	struct resource *	sc_mem_res;
60316370Sgonzo};
61316370Sgonzo
62316370Sgonzostatic struct versatile_scm_softc *versatile_scm_sc;
63316370Sgonzo
64316370Sgonzo#define	versatile_scm_read_4(sc, reg)		\
65316370Sgonzo    bus_read_4((sc)->sc_mem_res, (reg))
66316370Sgonzo#define	versatile_scm_write_4(sc, reg, val)		\
67316370Sgonzo    bus_write_4((sc)->sc_mem_res, (reg), (val))
68316370Sgonzo
69316370Sgonzostatic int
70316370Sgonzoversatile_scm_probe(device_t dev)
71316370Sgonzo{
72316370Sgonzo	if (!ofw_bus_status_okay(dev))
73316370Sgonzo		return (ENXIO);
74316370Sgonzo
75316370Sgonzo	if (!ofw_bus_is_compatible(dev, "syscon"))
76316370Sgonzo		return (ENXIO);
77316370Sgonzo
78316370Sgonzo	if (versatile_scm_sc) {
79316370Sgonzo		return (EEXIST);
80316370Sgonzo	}
81316370Sgonzo
82316370Sgonzo	device_set_desc(dev, "Versatile Control Module");
83316370Sgonzo	return (BUS_PROBE_DEFAULT);
84316370Sgonzo}
85316370Sgonzo
86316370Sgonzostatic int
87316370Sgonzoversatile_scm_attach(device_t dev)
88316370Sgonzo{
89316370Sgonzo	struct versatile_scm_softc *sc;
90316370Sgonzo	int rid;
91316370Sgonzo
92316370Sgonzo	sc = device_get_softc(dev);
93316370Sgonzo	sc->sc_dev = dev;
94316370Sgonzo
95316370Sgonzo	rid = 0;
96316370Sgonzo	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
97316370Sgonzo
98316370Sgonzo	if (sc->sc_mem_res == NULL) {
99316370Sgonzo		device_printf(dev, "could not allocate memory resources\n");
100316370Sgonzo		return (ENXIO);
101316370Sgonzo	}
102316370Sgonzo
103316370Sgonzo	versatile_scm_sc = sc;
104316370Sgonzo
105316370Sgonzo	return (0);
106316370Sgonzo}
107316370Sgonzo
108316370Sgonzoint
109316370Sgonzoversatile_scm_reg_read_4(uint32_t reg, uint32_t *val)
110316370Sgonzo{
111316370Sgonzo	if (!versatile_scm_sc)
112316370Sgonzo		return (ENXIO);
113316370Sgonzo
114316370Sgonzo	*val = versatile_scm_read_4(versatile_scm_sc, reg);
115316370Sgonzo	return (0);
116316370Sgonzo}
117316370Sgonzo
118316370Sgonzoint
119316370Sgonzoversatile_scm_reg_write_4(uint32_t reg, uint32_t val)
120316370Sgonzo{
121316370Sgonzo	if (!versatile_scm_sc)
122316370Sgonzo		return (ENXIO);
123316370Sgonzo
124316370Sgonzo	versatile_scm_write_4(versatile_scm_sc, reg, val);
125316370Sgonzo	return (0);
126316370Sgonzo}
127316370Sgonzo
128316370Sgonzostatic device_method_t versatile_scm_methods[] = {
129316370Sgonzo	DEVMETHOD(device_probe,		versatile_scm_probe),
130316370Sgonzo	DEVMETHOD(device_attach,	versatile_scm_attach),
131316370Sgonzo
132316370Sgonzo	DEVMETHOD_END
133316370Sgonzo};
134316370Sgonzo
135316370Sgonzostatic driver_t versatile_scm_driver = {
136316370Sgonzo	"scm",
137316370Sgonzo	versatile_scm_methods,
138316370Sgonzo	sizeof(struct versatile_scm_softc),
139316370Sgonzo};
140316370Sgonzo
141316370Sgonzostatic devclass_t versatile_scm_devclass;
142316370Sgonzo
143316370SgonzoEARLY_DRIVER_MODULE(versatile_scm, simplebus, versatile_scm_driver, versatile_scm_devclass, 0, 0,
144316370Sgonzo    BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
145