1258057Sbr/*-
2258057Sbr * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
3258057Sbr * All rights reserved.
4258057Sbr *
5258057Sbr * Redistribution and use in source and binary forms, with or without
6258057Sbr * modification, are permitted provided that the following conditions
7258057Sbr * are met:
8258057Sbr * 1. Redistributions of source code must retain the above copyright
9258057Sbr *    notice, this list of conditions and the following disclaimer.
10258057Sbr * 2. Redistributions in binary form must reproduce the above copyright
11258057Sbr *    notice, this list of conditions and the following disclaimer in the
12258057Sbr *    documentation and/or other materials provided with the distribution.
13258057Sbr *
14258057Sbr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15258057Sbr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16258057Sbr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17258057Sbr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18258057Sbr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19258057Sbr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20258057Sbr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21258057Sbr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22258057Sbr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23258057Sbr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24258057Sbr * SUCH DAMAGE.
25258057Sbr */
26258057Sbr
27258057Sbr/*
28258057Sbr * Vybrid Family System Reset Controller (SRC)
29258057Sbr * Chapter 18, Vybrid Reference Manual, Rev. 5, 07/2013
30258057Sbr */
31258057Sbr
32258057Sbr#include <sys/cdefs.h>
33258057Sbr__FBSDID("$FreeBSD: releng/11.0/sys/arm/freescale/vybrid/vf_src.c 281085 2015-04-04 21:34:26Z andrew $");
34258057Sbr
35258057Sbr#include <sys/param.h>
36258057Sbr#include <sys/systm.h>
37258057Sbr#include <sys/bus.h>
38258057Sbr#include <sys/kernel.h>
39258057Sbr#include <sys/module.h>
40258057Sbr#include <sys/malloc.h>
41258057Sbr#include <sys/rman.h>
42258057Sbr#include <sys/timeet.h>
43258057Sbr#include <sys/timetc.h>
44258057Sbr#include <sys/watchdog.h>
45258057Sbr
46258057Sbr#include <dev/fdt/fdt_common.h>
47258057Sbr#include <dev/ofw/openfirm.h>
48258057Sbr#include <dev/ofw/ofw_bus.h>
49258057Sbr#include <dev/ofw/ofw_bus_subr.h>
50258057Sbr
51258057Sbr#include <machine/bus.h>
52258057Sbr#include <machine/cpu.h>
53258057Sbr#include <machine/intr.h>
54258057Sbr
55258057Sbr#include <arm/freescale/vybrid/vf_src.h>
56258057Sbr#include <arm/freescale/vybrid/vf_common.h>
57258057Sbr
58258057Sbr#define	SRC_SCR		0x00	/* SRC Control Register */
59258057Sbr#define	SRC_SBMR1	0x04	/* SRC Boot Mode Register 1 */
60258057Sbr#define	SRC_SRSR	0x08	/* SRC Status Register */
61258057Sbr#define	SRC_SECR	0x0C	/* SRC_SECR */
62258057Sbr#define	SRC_SICR	0x14	/* SRC Reset Interrupt Configuration Register */
63258057Sbr#define	SRC_SIMR	0x18	/* SRC Interrupt Masking Register */
64258057Sbr#define	SRC_SBMR2	0x1C	/* SRC Boot Mode Register 2 */
65258057Sbr#define	SRC_GPR0	0x20	/* General Purpose Register */
66258057Sbr#define	SRC_GPR1	0x24	/* General Purpose Register */
67258057Sbr#define	SRC_GPR2	0x28	/* General Purpose Register */
68258057Sbr#define	SRC_GPR3	0x2C	/* General Purpose Register */
69258057Sbr#define	SRC_GPR4	0x30	/* General Purpose Register */
70258057Sbr#define	SRC_MISC0	0x4C	/* MISC0 */
71258057Sbr#define	SRC_MISC1	0x50	/* MISC1 */
72258057Sbr#define	SRC_MISC2	0x54	/* MISC2 */
73258057Sbr#define	SRC_MISC3	0x58	/* MISC3 */
74258057Sbr
75258057Sbrstruct src_softc {
76258057Sbr	struct resource		*res[1];
77258057Sbr	bus_space_tag_t		bst;
78258057Sbr	bus_space_handle_t	bsh;
79258057Sbr};
80258057Sbr
81258057Sbrstruct src_softc *src_sc;
82258057Sbr
83258057Sbrstatic struct resource_spec src_spec[] = {
84258057Sbr	{ SYS_RES_MEMORY,       0,      RF_ACTIVE },
85258057Sbr	{ -1, 0 }
86258057Sbr};
87258057Sbr
88258057Sbrint
89258057Sbrsrc_swreset(void)
90258057Sbr{
91258057Sbr
92258057Sbr	if (src_sc == NULL)
93258057Sbr		return (1);
94258057Sbr
95258057Sbr	WRITE4(src_sc, SRC_SCR, SW_RST);
96258057Sbr
97258057Sbr	return (0);
98258057Sbr}
99258057Sbr
100258057Sbrstatic int
101258057Sbrsrc_probe(device_t dev)
102258057Sbr{
103258057Sbr
104261410Sian	if (!ofw_bus_status_okay(dev))
105261410Sian		return (ENXIO);
106261410Sian
107258057Sbr	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-src"))
108258057Sbr		return (ENXIO);
109258057Sbr
110258057Sbr	device_set_desc(dev, "Vybrid Family System Reset Controller");
111258057Sbr	return (BUS_PROBE_DEFAULT);
112258057Sbr}
113258057Sbr
114258057Sbrstatic int
115258057Sbrsrc_attach(device_t dev)
116258057Sbr{
117258057Sbr	struct src_softc *sc;
118258057Sbr
119258057Sbr	sc = device_get_softc(dev);
120258057Sbr
121258057Sbr	if (bus_alloc_resources(dev, src_spec, sc->res)) {
122258057Sbr		device_printf(dev, "could not allocate resources\n");
123258057Sbr		return (ENXIO);
124258057Sbr	}
125258057Sbr
126258057Sbr	/* Memory interface */
127258057Sbr	sc->bst = rman_get_bustag(sc->res[0]);
128258057Sbr	sc->bsh = rman_get_bushandle(sc->res[0]);
129258057Sbr
130258057Sbr	src_sc = sc;
131258057Sbr
132258057Sbr	return (0);
133258057Sbr}
134258057Sbr
135258057Sbrstatic device_method_t src_methods[] = {
136258057Sbr	DEVMETHOD(device_probe,		src_probe),
137258057Sbr	DEVMETHOD(device_attach,	src_attach),
138258057Sbr	{ 0, 0 }
139258057Sbr};
140258057Sbr
141258057Sbrstatic driver_t src_driver = {
142258057Sbr	"src",
143258057Sbr	src_methods,
144258057Sbr	sizeof(struct src_softc),
145258057Sbr};
146258057Sbr
147258057Sbrstatic devclass_t src_devclass;
148258057Sbr
149258057SbrDRIVER_MODULE(src, simplebus, src_driver, src_devclass, 0, 0);
150