xref: /openbsd-src/sys/arch/armv7/vexpress/sysreg.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: sysreg.c,v 1.1 2015/06/08 06:33:16 jsg Exp $	*/
2 
3 /*
4  * Copyright (c) 2015 Jonathan Gray <jsg@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/device.h>
22 #include <machine/bus.h>
23 #include <armv7/armv7/armv7var.h>
24 
25 #define SYS_ID			0x00
26 #define SYS_PROCID0		0x84
27 #define SYS_PROCID1		0x88
28 #define SYS_CFGDATA		0xa0
29 #define SYS_CFGCTRL		0xa4
30 #define SYS_CFGSTAT		0xa8
31 
32 #define SYS_CFG_WRITE		(1 << 30)
33 #define SYS_CFG_START		(1U << 31)
34 
35 #define SYS_CFG_RESET		5
36 #define SYS_CFG_SHUTDOWN	8
37 #define SYS_CFG_REBOOT		9
38 
39 #define SYS_CFGSTAT_COMPLETE	(1 << 0)
40 #define SYS_CFGSTAT_ERROR	(1 << 1)
41 
42 struct sysreg_softc {
43 	struct device		sc_dev;
44 	bus_space_tag_t		sc_iot;
45 	bus_space_handle_t	sc_ioh;
46 };
47 
48 struct sysreg_softc *sysreg_sc;
49 
50 void sysreg_attach(struct device *, struct device *, void *);
51 void sysreg_reset(void);
52 
53 struct cfattach sysreg_ca = {
54 	sizeof (struct sysreg_softc), NULL, sysreg_attach
55 };
56 
57 struct cfdriver sysreg_cd = {
58 	NULL, "sysreg", DV_DULL
59 };
60 
61 void
62 sysreg_attach(struct device *parent, struct device *self, void *args)
63 {
64 	struct armv7_attach_args *aa = args;
65 	struct sysreg_softc *sc = (struct sysreg_softc *)self;
66 	uint32_t id;
67 
68 	sc->sc_iot = aa->aa_iot;
69 	if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr,
70 	    aa->aa_dev->mem[0].size, 0, &sc->sc_ioh))
71 		panic(": bus_space_map failed!");
72 	sysreg_sc = sc;
73 
74 	id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SYS_ID);
75 	printf(": ID 0x%x", id);
76 
77 	id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SYS_PROCID0);
78 	printf(" PROCID0 0x%x\n", id);
79 }
80 
81 void
82 sysconf_function(struct sysreg_softc *sc, int function)
83 {
84 	int dcc, site, position, device;
85 
86 	dcc = 0;
87 	site = 0;
88 	position = 0;
89 	device = 0;
90 
91 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SYS_CFGSTAT, 0);
92 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, SYS_CFGCTRL,
93 	    SYS_CFG_START | SYS_CFG_WRITE |
94 	    (dcc << 26) | (function << 20) | (site << 16) |
95 	    (position << 12) | device);
96 
97 	while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SYS_CFGSTAT) &
98 	    SYS_CFGSTAT_COMPLETE) == 0);
99 
100 	if (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SYS_CFGSTAT) &
101 	    SYS_CFGSTAT_ERROR)
102 		printf("SYS_CFGSTAT error\n");
103 }
104 
105 void
106 sysconf_reboot(void)
107 {
108 	struct sysreg_softc *sc = sysreg_sc;
109 
110 	if (sc == NULL)
111 		return;
112 
113 	sysconf_function(sc, SYS_CFG_REBOOT);
114 }
115 
116 void
117 sysconf_shutdown(void)
118 {
119 	struct sysreg_softc *sc = sysreg_sc;
120 
121 	if (sc == NULL)
122 		return;
123 
124 	sysconf_function(sc, SYS_CFG_SHUTDOWN);
125 }
126