xref: /openbsd-src/sys/arch/octeon/dev/octsctl.c (revision a250d81a0eb3c895e9c7c8febf9467db5f4fb4a5)
1*a250d81aSvisa /*	$OpenBSD: octsctl.c,v 1.2 2019/01/12 13:50:52 visa Exp $	*/
21839ace7Svisa 
31839ace7Svisa /*
41839ace7Svisa  * Copyright (c) 2017 Visa Hankala
51839ace7Svisa  *
61839ace7Svisa  * Permission to use, copy, modify, and distribute this software for any
71839ace7Svisa  * purpose with or without fee is hereby granted, provided that the above
81839ace7Svisa  * copyright notice and this permission notice appear in all copies.
91839ace7Svisa  *
101839ace7Svisa  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
111839ace7Svisa  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
121839ace7Svisa  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
131839ace7Svisa  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
141839ace7Svisa  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
151839ace7Svisa  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
161839ace7Svisa  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
171839ace7Svisa  */
181839ace7Svisa 
191839ace7Svisa /*
201839ace7Svisa  * Driver for OCTEON SATA controller bridge.
211839ace7Svisa  */
221839ace7Svisa 
231839ace7Svisa #include <sys/param.h>
241839ace7Svisa #include <sys/systm.h>
251839ace7Svisa #include <sys/device.h>
261839ace7Svisa 
271839ace7Svisa #include <machine/bus.h>
281839ace7Svisa #include <machine/fdt.h>
291839ace7Svisa 
301839ace7Svisa #include <dev/ofw/fdt.h>
311839ace7Svisa #include <dev/ofw/openfirm.h>
321839ace7Svisa 
331839ace7Svisa #define SCTL_SHIM_CFG			0xe8
341839ace7Svisa #define   SCTL_SHIM_CFG_READ_CMD		0x0000000000001000ul
351839ace7Svisa #define   SCTL_SHIM_CFG_DMA_BYTE_SWAP		0x0000000000000300ul
361839ace7Svisa #define   SCTL_SHIM_CFG_DMA_BYTE_SWAP_SHIFT	8
371839ace7Svisa #define   SCTL_SHIM_CFG_CSR_BYTE_SWAP		0x0000000000000003ul
381839ace7Svisa #define   SCTL_SHIM_CFG_CSR_BYTE_SWAP_SHIFT	0
391839ace7Svisa 
401839ace7Svisa struct octsctl_softc {
411839ace7Svisa 	struct device		sc_dev;
421839ace7Svisa 	bus_space_tag_t		sc_iot;
431839ace7Svisa 	bus_space_handle_t	sc_ioh;
441839ace7Svisa };
451839ace7Svisa 
461839ace7Svisa int	octsctl_match(struct device *, void *, void *);
471839ace7Svisa void	octsctl_attach(struct device *, struct device *, void *);
481839ace7Svisa 
491839ace7Svisa const struct cfattach octsctl_ca = {
501839ace7Svisa 	sizeof(struct octsctl_softc), octsctl_match, octsctl_attach
511839ace7Svisa };
521839ace7Svisa 
531839ace7Svisa struct cfdriver octsctl_cd = {
541839ace7Svisa 	NULL, "octsctl", DV_DULL
551839ace7Svisa };
561839ace7Svisa 
571839ace7Svisa int
octsctl_match(struct device * parent,void * match,void * aux)581839ace7Svisa octsctl_match(struct device *parent, void *match, void *aux)
591839ace7Svisa {
601839ace7Svisa 	struct fdt_attach_args *faa = aux;
611839ace7Svisa 
62*a250d81aSvisa 	return OF_is_compatible(faa->fa_node, "cavium,octeon-7130-sata-uctl");
631839ace7Svisa }
641839ace7Svisa 
651839ace7Svisa void
octsctl_attach(struct device * parent,struct device * self,void * aux)661839ace7Svisa octsctl_attach(struct device *parent, struct device *self, void *aux)
671839ace7Svisa {
681839ace7Svisa 	struct fdt_reg child_reg;
691839ace7Svisa 	struct fdt_attach_args child_faa;
701839ace7Svisa 	struct fdt_attach_args *faa = aux;
711839ace7Svisa 	struct octsctl_softc *sc = (struct octsctl_softc *)self;
721839ace7Svisa 	uint64_t val;
731839ace7Svisa 	uint32_t reg[4];
741839ace7Svisa 	int child;
751839ace7Svisa 
76*a250d81aSvisa 	child = OF_child(faa->fa_node);
77*a250d81aSvisa 
78*a250d81aSvisa 	/*
79*a250d81aSvisa 	 * On some machines, the bridge controller node does not have
80*a250d81aSvisa 	 * an AHCI controller node as a child.
81*a250d81aSvisa 	 */
82*a250d81aSvisa 	if (child == 0) {
83*a250d81aSvisa 		printf(": disabled\n");
84*a250d81aSvisa 		return;
85*a250d81aSvisa 	}
86*a250d81aSvisa 
871839ace7Svisa 	if (faa->fa_nreg != 1) {
881839ace7Svisa 		printf(": expected one IO space, got %d\n", faa->fa_nreg);
891839ace7Svisa 		return;
901839ace7Svisa 	}
911839ace7Svisa 
921839ace7Svisa 	if (OF_getpropint(faa->fa_node, "#address-cells", 0) != 2 ||
931839ace7Svisa 	    OF_getpropint(faa->fa_node, "#size-cells", 0) != 2) {
941839ace7Svisa 		printf(": invalid fdt reg cells\n");
951839ace7Svisa 		return;
961839ace7Svisa 	}
971839ace7Svisa 	if (OF_getproplen(child, "reg") != sizeof(reg)) {
981839ace7Svisa 		printf(": invalid child fdt reg\n");
991839ace7Svisa 		return;
1001839ace7Svisa 	}
1011839ace7Svisa 	OF_getpropintarray(child, "reg", reg, sizeof(reg));
1021839ace7Svisa 	child_reg.addr = ((uint64_t)reg[0] << 32) | reg[1];
1031839ace7Svisa 	child_reg.size = ((uint64_t)reg[2] << 32) | reg[3];
1041839ace7Svisa 
1051839ace7Svisa 	sc->sc_iot = faa->fa_iot;
1061839ace7Svisa 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, faa->fa_reg[0].size,
1071839ace7Svisa 	    0, &sc->sc_ioh)) {
1081839ace7Svisa 		printf(": could not map registers\n");
1091839ace7Svisa 		goto error;
1101839ace7Svisa 	}
1111839ace7Svisa 
1121839ace7Svisa 	val = bus_space_read_8(sc->sc_iot, sc->sc_ioh, SCTL_SHIM_CFG);
1131839ace7Svisa 	val &= ~SCTL_SHIM_CFG_CSR_BYTE_SWAP;
1141839ace7Svisa 	val &= ~SCTL_SHIM_CFG_DMA_BYTE_SWAP;
1151839ace7Svisa 	val |= 3ul << SCTL_SHIM_CFG_CSR_BYTE_SWAP_SHIFT;
1161839ace7Svisa 	val |= 1ul << SCTL_SHIM_CFG_DMA_BYTE_SWAP_SHIFT;
1171839ace7Svisa 	val |= SCTL_SHIM_CFG_READ_CMD;
1181839ace7Svisa 	bus_space_write_8(sc->sc_iot, sc->sc_ioh, SCTL_SHIM_CFG, val);
1191839ace7Svisa 	(void)bus_space_read_8(sc->sc_iot, sc->sc_ioh, SCTL_SHIM_CFG);
1201839ace7Svisa 
1211839ace7Svisa 	printf("\n");
1221839ace7Svisa 
1231839ace7Svisa 	memset(&child_faa, 0, sizeof(child_faa));
1241839ace7Svisa 	child_faa.fa_name = "";
1251839ace7Svisa 	child_faa.fa_node = child;
1261839ace7Svisa 	child_faa.fa_iot = faa->fa_iot;
1271839ace7Svisa 	child_faa.fa_dmat = faa->fa_dmat;
1281839ace7Svisa 	child_faa.fa_reg = &child_reg;
1291839ace7Svisa 	child_faa.fa_nreg = 1;
1301839ace7Svisa 	/* child_faa.fa_intr is not utilized. */
1311839ace7Svisa 
1321839ace7Svisa 	config_found(self, &child_faa, NULL);
1331839ace7Svisa 
1341839ace7Svisa 	return;
1351839ace7Svisa 
1361839ace7Svisa error:
1371839ace7Svisa 	if (sc->sc_ioh != 0)
1381839ace7Svisa 		bus_space_unmap(sc->sc_iot, sc->sc_ioh, faa->fa_reg[0].size);
1391839ace7Svisa }
140