xref: /openbsd-src/sys/dev/fdt/amlreset.c (revision 9fdf0c627b1fec102f212f847a6f7676c1829e65)
1*9fdf0c62Smpi /*	$OpenBSD: amlreset.c,v 1.2 2021/10/24 17:52:26 mpi Exp $	*/
24350d62eSkettenis /*
34350d62eSkettenis  * Copyright (c) 2019 Mark Kettenis <kettenis@openbsd.org>
44350d62eSkettenis  *
54350d62eSkettenis  * Permission to use, copy, modify, and distribute this software for any
64350d62eSkettenis  * purpose with or without fee is hereby granted, provided that the above
74350d62eSkettenis  * copyright notice and this permission notice appear in all copies.
84350d62eSkettenis  *
94350d62eSkettenis  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
104350d62eSkettenis  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
114350d62eSkettenis  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
124350d62eSkettenis  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
134350d62eSkettenis  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
144350d62eSkettenis  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
154350d62eSkettenis  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
164350d62eSkettenis  */
174350d62eSkettenis 
184350d62eSkettenis #include <sys/param.h>
194350d62eSkettenis #include <sys/systm.h>
204350d62eSkettenis #include <sys/device.h>
214350d62eSkettenis 
224350d62eSkettenis #include <machine/intr.h>
234350d62eSkettenis #include <machine/bus.h>
244350d62eSkettenis #include <machine/fdt.h>
254350d62eSkettenis 
264350d62eSkettenis #include <dev/ofw/openfirm.h>
274350d62eSkettenis #include <dev/ofw/ofw_clock.h>
284350d62eSkettenis #include <dev/ofw/ofw_misc.h>
294350d62eSkettenis #include <dev/ofw/fdt.h>
304350d62eSkettenis 
314350d62eSkettenis #define RESET0_REGISTER		0x0000
324350d62eSkettenis #define RESET0_MASK		0x003c
334350d62eSkettenis #define RESET0_LEVEL		0x007c
344350d62eSkettenis 
354350d62eSkettenis #define HREAD4(sc, reg)							\
364350d62eSkettenis 	(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
374350d62eSkettenis #define HWRITE4(sc, reg, val)						\
384350d62eSkettenis 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
394350d62eSkettenis #define HSET4(sc, reg, bits)						\
404350d62eSkettenis 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
414350d62eSkettenis #define HCLR4(sc, reg, bits)						\
424350d62eSkettenis 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
434350d62eSkettenis 
444350d62eSkettenis struct amlreset_softc {
454350d62eSkettenis 	struct device		sc_dev;
464350d62eSkettenis 	bus_space_tag_t		sc_iot;
474350d62eSkettenis 	bus_space_handle_t	sc_ioh;
484350d62eSkettenis 
494350d62eSkettenis 	struct reset_device	sc_rd;
504350d62eSkettenis };
514350d62eSkettenis 
524350d62eSkettenis int amlreset_match(struct device *, void *, void *);
534350d62eSkettenis void amlreset_attach(struct device *, struct device *, void *);
544350d62eSkettenis 
55*9fdf0c62Smpi const struct cfattach	amlreset_ca = {
564350d62eSkettenis 	sizeof (struct amlreset_softc), amlreset_match, amlreset_attach
574350d62eSkettenis };
584350d62eSkettenis 
594350d62eSkettenis struct cfdriver amlreset_cd = {
604350d62eSkettenis 	NULL, "amlreset", DV_DULL
614350d62eSkettenis };
624350d62eSkettenis 
634350d62eSkettenis void	amlreset_reset(void *, uint32_t *, int);
644350d62eSkettenis 
654350d62eSkettenis int
amlreset_match(struct device * parent,void * match,void * aux)664350d62eSkettenis amlreset_match(struct device *parent, void *match, void *aux)
674350d62eSkettenis {
684350d62eSkettenis 	struct fdt_attach_args *faa = aux;
694350d62eSkettenis 
704350d62eSkettenis 	return OF_is_compatible(faa->fa_node, "amlogic,meson-axg-reset");
714350d62eSkettenis }
724350d62eSkettenis 
734350d62eSkettenis void
amlreset_attach(struct device * parent,struct device * self,void * aux)744350d62eSkettenis amlreset_attach(struct device *parent, struct device *self, void *aux)
754350d62eSkettenis {
764350d62eSkettenis 	struct amlreset_softc *sc = (struct amlreset_softc *)self;
774350d62eSkettenis 	struct fdt_attach_args *faa = aux;
784350d62eSkettenis 
794350d62eSkettenis 	if (faa->fa_nreg < 1) {
804350d62eSkettenis 		printf(": no registers\n");
814350d62eSkettenis 		return;
824350d62eSkettenis 	}
834350d62eSkettenis 
844350d62eSkettenis 	sc->sc_iot = faa->fa_iot;
854350d62eSkettenis 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
864350d62eSkettenis 	    faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
874350d62eSkettenis 		printf(": can't map registers\n");
884350d62eSkettenis 		return;
894350d62eSkettenis 	}
904350d62eSkettenis 
914350d62eSkettenis 	printf("\n");
924350d62eSkettenis 
934350d62eSkettenis 	sc->sc_rd.rd_node = faa->fa_node;
944350d62eSkettenis 	sc->sc_rd.rd_cookie = sc;
954350d62eSkettenis 	sc->sc_rd.rd_reset = amlreset_reset;
964350d62eSkettenis 	reset_register(&sc->sc_rd);
974350d62eSkettenis }
984350d62eSkettenis 
994350d62eSkettenis void
amlreset_reset(void * cookie,uint32_t * cells,int assert)1004350d62eSkettenis amlreset_reset(void *cookie, uint32_t *cells, int assert)
1014350d62eSkettenis {
1024350d62eSkettenis 	struct amlreset_softc *sc = cookie;
1034350d62eSkettenis 	uint32_t bank = cells[0] / 32;
1044350d62eSkettenis 	uint32_t bit = cells[0] % 32;
1054350d62eSkettenis 
1064350d62eSkettenis 	if (assert)
1074350d62eSkettenis 		HCLR4(sc, RESET0_LEVEL + bank * 4, (1 << bit));
1084350d62eSkettenis 	else
1094350d62eSkettenis 		HSET4(sc, RESET0_LEVEL + bank * 4, (1 << bit));
1104350d62eSkettenis }
111