xref: /openbsd-src/sys/dev/pci/psp_pci.c (revision 8f8d81e9b254f612ef7c357cfa10fbf427cc140c)
1*8f8d81e9Sbluhm /*	$OpenBSD: psp_pci.c,v 1.2 2024/11/08 17:34:22 bluhm Exp $	*/
238923a19Sbluhm 
338923a19Sbluhm /*
438923a19Sbluhm  * Copyright (c) 2023-2024 Hans-Joerg Hoexer <hshoexer@genua.de>
538923a19Sbluhm  * Copyright (c) 2024 Alexander Bluhm <bluhm@openbsd.org>
638923a19Sbluhm  *
738923a19Sbluhm  * Permission to use, copy, modify, and distribute this software for any
838923a19Sbluhm  * purpose with or without fee is hereby granted, provided that the above
938923a19Sbluhm  * copyright notice and this permission notice appear in all copies.
1038923a19Sbluhm  *
1138923a19Sbluhm  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1238923a19Sbluhm  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1338923a19Sbluhm  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1438923a19Sbluhm  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1538923a19Sbluhm  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1638923a19Sbluhm  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1738923a19Sbluhm  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1838923a19Sbluhm  */
1938923a19Sbluhm 
2038923a19Sbluhm #include <sys/param.h>
2138923a19Sbluhm #include <sys/systm.h>
2238923a19Sbluhm #include <sys/device.h>
2338923a19Sbluhm 
2438923a19Sbluhm #include <machine/bus.h>
2538923a19Sbluhm 
2638923a19Sbluhm #include <dev/pci/pcidevs.h>
2738923a19Sbluhm #include <dev/pci/pcivar.h>
2838923a19Sbluhm 
2938923a19Sbluhm #include <dev/ic/ccpvar.h>
3038923a19Sbluhm #include <dev/ic/pspvar.h>
3138923a19Sbluhm 
3238923a19Sbluhm static const struct pci_matchid psp_pci_devices[] = {
3338923a19Sbluhm 	{ PCI_VENDOR_AMD,	PCI_PRODUCT_AMD_17_CCP_1 },
3438923a19Sbluhm 	{ PCI_VENDOR_AMD,	PCI_PRODUCT_AMD_17_3X_CCP },
3538923a19Sbluhm 	{ PCI_VENDOR_AMD,	PCI_PRODUCT_AMD_19_1X_PSP },
3638923a19Sbluhm };
3738923a19Sbluhm 
3838923a19Sbluhm int
3938923a19Sbluhm psp_pci_match(struct ccp_softc *sc, struct pci_attach_args *pa)
4038923a19Sbluhm {
4138923a19Sbluhm 	bus_size_t reg_capabilities;
4238923a19Sbluhm 	uint32_t capabilities;
4338923a19Sbluhm 
4438923a19Sbluhm 	if (!pci_matchbyid(pa, psp_pci_devices, nitems(psp_pci_devices)))
4538923a19Sbluhm 		return (0);
4638923a19Sbluhm 
4738923a19Sbluhm 	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_17_CCP_1)
4838923a19Sbluhm 		reg_capabilities = PSPV1_REG_CAPABILITIES;
4938923a19Sbluhm 	else
5038923a19Sbluhm 		reg_capabilities = PSP_REG_CAPABILITIES;
5138923a19Sbluhm 	capabilities = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
5238923a19Sbluhm 	    reg_capabilities);
5338923a19Sbluhm 	if (!ISSET(capabilities, PSP_CAP_SEV))
5438923a19Sbluhm 		return (0);
5538923a19Sbluhm 
5638923a19Sbluhm 	return (1);
5738923a19Sbluhm }
5838923a19Sbluhm 
5938923a19Sbluhm void
6038923a19Sbluhm psp_pci_intr_map(struct ccp_softc *sc, struct pci_attach_args *pa)
6138923a19Sbluhm {
6238923a19Sbluhm 	pci_intr_handle_t ih;
6338923a19Sbluhm 	const char *intrstr = NULL;
6438923a19Sbluhm 	bus_size_t reg_inten, reg_intsts;
6538923a19Sbluhm 
6638923a19Sbluhm 	/* clear and disable interrupts */
6738923a19Sbluhm 	if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_17_CCP_1) {
6838923a19Sbluhm 		reg_inten = PSPV1_REG_INTEN;
6938923a19Sbluhm 		reg_intsts = PSPV1_REG_INTSTS;
7038923a19Sbluhm 	} else {
7138923a19Sbluhm 		reg_inten = PSP_REG_INTEN;
7238923a19Sbluhm 		reg_intsts = PSP_REG_INTSTS;
7338923a19Sbluhm 	}
7438923a19Sbluhm 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg_inten, 0);
7538923a19Sbluhm 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg_intsts, -1);
7638923a19Sbluhm 
7738923a19Sbluhm 	if (pci_intr_map_msix(pa, 0, &ih) != 0 &&
7838923a19Sbluhm 	    pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) {
7938923a19Sbluhm 		printf(": couldn't map interrupt\n");
8038923a19Sbluhm 		return;
8138923a19Sbluhm 	}
8238923a19Sbluhm 
8338923a19Sbluhm 	intrstr = pci_intr_string(pa->pa_pc, ih);
84*8f8d81e9Sbluhm 	sc->sc_irqh = pci_intr_establish(pa->pa_pc, ih, IPL_BIO | IPL_MPSAFE,
85*8f8d81e9Sbluhm 	    psp_sev_intr, sc, sc->sc_dev.dv_xname);
8638923a19Sbluhm 	if (sc->sc_irqh != NULL)
8738923a19Sbluhm 		printf(": %s", intrstr);
8838923a19Sbluhm }
8938923a19Sbluhm 
9038923a19Sbluhm void
9138923a19Sbluhm psp_pci_attach(struct ccp_softc *sc, struct pci_attach_args *pa)
9238923a19Sbluhm {
9338923a19Sbluhm 	struct psp_attach_args arg;
9438923a19Sbluhm 	struct device *self = (struct device *)sc;
9538923a19Sbluhm 	bus_size_t reg_capabilities;
9638923a19Sbluhm 
9738923a19Sbluhm 	memset(&arg, 0, sizeof(arg));
9838923a19Sbluhm 	arg.iot = sc->sc_iot;
9938923a19Sbluhm 	arg.ioh = sc->sc_ioh;
10038923a19Sbluhm 	arg.dmat = pa->pa_dmat;
10138923a19Sbluhm 	switch (PCI_PRODUCT(pa->pa_id)) {
10238923a19Sbluhm 	case PCI_PRODUCT_AMD_17_CCP_1:
10338923a19Sbluhm 		arg.version = 1;
10438923a19Sbluhm 		reg_capabilities = PSPV1_REG_CAPABILITIES;
10538923a19Sbluhm 		break;
10638923a19Sbluhm 	case PCI_PRODUCT_AMD_17_3X_CCP:
10738923a19Sbluhm 		arg.version = 2;
10838923a19Sbluhm 		reg_capabilities = PSP_REG_CAPABILITIES;
10938923a19Sbluhm 		break;
11038923a19Sbluhm 	case PCI_PRODUCT_AMD_19_1X_PSP:
11138923a19Sbluhm 		arg.version = 4;
11238923a19Sbluhm 		reg_capabilities = PSP_REG_CAPABILITIES;
11338923a19Sbluhm 		break;
11438923a19Sbluhm 	default:
11538923a19Sbluhm 		reg_capabilities = PSP_REG_CAPABILITIES;
11638923a19Sbluhm 		break;
11738923a19Sbluhm 	}
11838923a19Sbluhm 	arg.capabilities = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
11938923a19Sbluhm 	    reg_capabilities);
12038923a19Sbluhm 
12138923a19Sbluhm 	sc->sc_psp = config_found_sm(self, &arg, pspprint, pspsubmatch);
12238923a19Sbluhm 	if (sc->sc_psp == NULL) {
12338923a19Sbluhm 		pci_intr_disestablish(pa->pa_pc, sc->sc_irqh);
12438923a19Sbluhm 		return;
12538923a19Sbluhm 	}
12638923a19Sbluhm }
127