xref: /openbsd-src/sys/arch/armv7/xilinx/zqreset.c (revision 5b874c1196a514aa442de1f3320274d89766b2d8)
1*5b874c11Svisa /*	$OpenBSD: zqreset.c,v 1.1 2021/04/30 13:20:14 visa Exp $	*/
2*5b874c11Svisa 
3*5b874c11Svisa /*
4*5b874c11Svisa  * Copyright (c) 2021 Visa Hankala
5*5b874c11Svisa  *
6*5b874c11Svisa  * Permission to use, copy, modify, and/or distribute this software for any
7*5b874c11Svisa  * purpose with or without fee is hereby granted, provided that the above
8*5b874c11Svisa  * copyright notice and this permission notice appear in all copies.
9*5b874c11Svisa  *
10*5b874c11Svisa  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11*5b874c11Svisa  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12*5b874c11Svisa  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13*5b874c11Svisa  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14*5b874c11Svisa  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15*5b874c11Svisa  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16*5b874c11Svisa  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*5b874c11Svisa  */
18*5b874c11Svisa 
19*5b874c11Svisa /*
20*5b874c11Svisa  * Driver for Xilinx Zynq-7000 reset controller.
21*5b874c11Svisa  */
22*5b874c11Svisa 
23*5b874c11Svisa #include <sys/param.h>
24*5b874c11Svisa #include <sys/systm.h>
25*5b874c11Svisa #include <sys/device.h>
26*5b874c11Svisa #include <sys/mutex.h>
27*5b874c11Svisa 
28*5b874c11Svisa #include <machine/bus.h>
29*5b874c11Svisa #include <machine/fdt.h>
30*5b874c11Svisa 
31*5b874c11Svisa #include <dev/ofw/fdt.h>
32*5b874c11Svisa #include <dev/ofw/openfirm.h>
33*5b874c11Svisa #include <dev/ofw/ofw_misc.h>
34*5b874c11Svisa 
35*5b874c11Svisa #include <armv7/xilinx/slcreg.h>
36*5b874c11Svisa 
37*5b874c11Svisa extern void (*cpuresetfn)(void);
38*5b874c11Svisa 
39*5b874c11Svisa struct zqreset_softc {
40*5b874c11Svisa 	struct device		sc_dev;
41*5b874c11Svisa 	struct regmap		*sc_rm;
42*5b874c11Svisa };
43*5b874c11Svisa 
44*5b874c11Svisa int	zqreset_match(struct device *, void *, void *);
45*5b874c11Svisa void	zqreset_attach(struct device *, struct device *, void *);
46*5b874c11Svisa 
47*5b874c11Svisa void	zqreset_cpureset(void);
48*5b874c11Svisa 
49*5b874c11Svisa const struct cfattach zqreset_ca = {
50*5b874c11Svisa 	sizeof(struct zqreset_softc), zqreset_match, zqreset_attach
51*5b874c11Svisa };
52*5b874c11Svisa 
53*5b874c11Svisa struct cfdriver zqreset_cd = {
54*5b874c11Svisa 	NULL, "zqreset", DV_DULL
55*5b874c11Svisa };
56*5b874c11Svisa 
57*5b874c11Svisa struct zqreset_softc	*zqreset_sc;
58*5b874c11Svisa 
59*5b874c11Svisa struct mutex	zynq_slcr_lock = MUTEX_INITIALIZER(IPL_HIGH);
60*5b874c11Svisa 
61*5b874c11Svisa int
zqreset_match(struct device * parent,void * match,void * aux)62*5b874c11Svisa zqreset_match(struct device *parent, void *match, void *aux)
63*5b874c11Svisa {
64*5b874c11Svisa 	struct fdt_attach_args *faa = aux;
65*5b874c11Svisa 
66*5b874c11Svisa 	return OF_is_compatible(faa->fa_node, "xlnx,zynq-reset");
67*5b874c11Svisa }
68*5b874c11Svisa 
69*5b874c11Svisa void
zqreset_attach(struct device * parent,struct device * self,void * aux)70*5b874c11Svisa zqreset_attach(struct device *parent, struct device *self, void *aux)
71*5b874c11Svisa {
72*5b874c11Svisa 	struct fdt_attach_args *faa = aux;
73*5b874c11Svisa 	struct zqreset_softc *sc = (struct zqreset_softc *)self;
74*5b874c11Svisa 
75*5b874c11Svisa 	sc->sc_rm = regmap_bynode(OF_parent(faa->fa_node));
76*5b874c11Svisa 	if (sc->sc_rm == NULL) {
77*5b874c11Svisa 		printf(": can't get regmap\n");
78*5b874c11Svisa 		return;
79*5b874c11Svisa 	}
80*5b874c11Svisa 
81*5b874c11Svisa 	printf("\n");
82*5b874c11Svisa 
83*5b874c11Svisa 	zqreset_sc = sc;
84*5b874c11Svisa 	cpuresetfn = zqreset_cpureset;
85*5b874c11Svisa }
86*5b874c11Svisa 
87*5b874c11Svisa void
zqreset_cpureset(void)88*5b874c11Svisa zqreset_cpureset(void)
89*5b874c11Svisa {
90*5b874c11Svisa 	struct zqreset_softc *sc = zqreset_sc;
91*5b874c11Svisa 
92*5b874c11Svisa 	mtx_enter(&zynq_slcr_lock);
93*5b874c11Svisa 	zynq_slcr_write(sc->sc_rm, SLCR_PSS_RST_CTRL,
94*5b874c11Svisa 	    SLCR_PSS_RST_CTRL_SOFT_RST);
95*5b874c11Svisa 	mtx_leave(&zynq_slcr_lock);
96*5b874c11Svisa }
97*5b874c11Svisa 
98*5b874c11Svisa uint32_t
zynq_slcr_read(struct regmap * rm,uint32_t reg)99*5b874c11Svisa zynq_slcr_read(struct regmap *rm, uint32_t reg)
100*5b874c11Svisa {
101*5b874c11Svisa 	return regmap_read_4(rm, reg);
102*5b874c11Svisa }
103*5b874c11Svisa 
104*5b874c11Svisa void
zynq_slcr_write(struct regmap * rm,uint32_t reg,uint32_t val)105*5b874c11Svisa zynq_slcr_write(struct regmap *rm, uint32_t reg, uint32_t val)
106*5b874c11Svisa {
107*5b874c11Svisa 	MUTEX_ASSERT_LOCKED(&zynq_slcr_lock);
108*5b874c11Svisa 
109*5b874c11Svisa 	regmap_write_4(rm, SLCR_UNLOCK, SLCR_UNLOCK_KEY);
110*5b874c11Svisa 	regmap_write_4(rm, reg, val);
111*5b874c11Svisa 	regmap_write_4(rm, SLCR_LOCK, SLCR_LOCK_KEY);
112*5b874c11Svisa }
113