From a68d7a250eca5e22a3b02a78b12bfb70a49afe7f Mon Sep 17 00:00:00 2001 From: patrick Date: Sun, 11 Sep 2022 10:18:54 +0000 Subject: [PATCH] Make an attempt at taking over existing streams on Qualcomm machines. Some of the stream mappings on the Lenovo x13s match on a single stream id, and others use a mask to match on multiple stream ids. For now we only care about the single ones, which is enough to capture e.g. the xhci(4) nodes. --- sys/arch/arm64/dev/smmu.c | 21 ++++++++++++++++++++- sys/arch/arm64/dev/smmureg.h | 7 +++++-- sys/arch/arm64/dev/smmuvar.h | 7 ++++--- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/sys/arch/arm64/dev/smmu.c b/sys/arch/arm64/dev/smmu.c index e8f103add8c..37b6d79ee5d 100644 --- a/sys/arch/arm64/dev/smmu.c +++ b/sys/arch/arm64/dev/smmu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smmu.c,v 1.19 2022/08/10 17:02:37 patrick Exp $ */ +/* $OpenBSD: smmu.c,v 1.20 2022/09/11 10:18:54 patrick Exp $ */ /* * Copyright (c) 2008-2009,2014-2016 Dale Rahn * Copyright (c) 2021 Patrick Wildt @@ -260,6 +260,8 @@ smmu_attach(struct smmu_softc *sc) */ sc->sc_cb[sc->sc_num_context_banks - 1] = malloc(sizeof(struct smmu_cb), M_DEVBUF, M_WAITOK | M_ZERO); + smmu_cb_write_4(sc, sc->sc_num_context_banks - 1, + SMMU_CB_SCTLR, 0); smmu_gr1_write_4(sc, SMMU_CBAR(sc->sc_num_context_banks - 1), SMMU_CBAR_TYPE_S1_TRANS_S2_BYPASS); } @@ -272,8 +274,13 @@ smmu_attach(struct smmu_softc *sc) /* On QCOM HW we need to keep current streams running. */ if (sc->sc_is_qcom && sc->sc_smr && smmu_gr0_read_4(sc, SMMU_SMR(i)) & SMMU_SMR_VALID) { + reg = smmu_gr0_read_4(sc, SMMU_SMR(i)); sc->sc_smr[i] = malloc(sizeof(struct smmu_smr), M_DEVBUF, M_WAITOK | M_ZERO); + sc->sc_smr[i]->ss_id = (reg >> SMMU_SMR_ID_SHIFT) & + SMMU_SMR_ID_MASK; + sc->sc_smr[i]->ss_mask = (reg >> SMMU_SMR_MASK_SHIFT) & + SMMU_SMR_MASK_MASK; if (sc->sc_bypass_quirk) { smmu_gr0_write_4(sc, SMMU_S2CR(i), SMMU_S2CR_TYPE_TRANS | @@ -603,10 +610,22 @@ smmu_domain_create(struct smmu_softc *sc, uint32_t sid) /* Stream mapping is a bit more effort */ if (sc->sc_smr) { for (i = 0; i < sc->sc_num_streams; i++) { + /* Take over QCOM SMRs */ + if (sc->sc_is_qcom && sc->sc_smr[i] != NULL && + sc->sc_smr[i]->ss_dom == NULL && + sc->sc_smr[i]->ss_id == sid && + sc->sc_smr[i]->ss_mask == 0) { + free(sc->sc_smr[i], M_DEVBUF, + sizeof(struct smmu_smr)); + sc->sc_smr[i] = NULL; + } if (sc->sc_smr[i] != NULL) continue; sc->sc_smr[i] = malloc(sizeof(struct smmu_smr), M_DEVBUF, M_WAITOK | M_ZERO); + sc->sc_smr[i]->ss_dom = dom; + sc->sc_smr[i]->ss_id = sid; + sc->sc_smr[i]->ss_mask = 0; dom->sd_smr_idx = i; break; } diff --git a/sys/arch/arm64/dev/smmureg.h b/sys/arch/arm64/dev/smmureg.h index 926d2d9ae8b..3b1962f021b 100644 --- a/sys/arch/arm64/dev/smmureg.h +++ b/sys/arch/arm64/dev/smmureg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smmureg.h,v 1.1 2021/02/28 21:39:31 patrick Exp $ */ +/* $OpenBSD: smmureg.h,v 1.2 2022/09/11 10:18:54 patrick Exp $ */ /* * Copyright (c) 2021 Patrick Wildt * @@ -122,8 +122,11 @@ #define SMMU_STLBGSTATUS 0x074 #define SMMU_STLBGSTATUS_GSACTIVE (1 << 0) #define SMMU_SMR(x) (0x800 + (x) * 0x4) /* 0 - 127 */ +#define SMMU_SMR_ID_SHIFT 0 +#define SMMU_SMR_ID_MASK 0x7fff +#define SMMU_SMR_MASK_SHIFT 16 +#define SMMU_SMR_MASK_MASK 0x7fff #define SMMU_SMR_VALID (1U << 31) -#define SMMU_SMR_MASK (0x7fff << 16) #define SMMU_S2CR(x) (0xc00 + (x) * 0x4) /* 0 - 127 */ #define SMMU_S2CR_EXIDVALID (1 << 10) #define SMMU_S2CR_TYPE_TRANS (0 << 16) diff --git a/sys/arch/arm64/dev/smmuvar.h b/sys/arch/arm64/dev/smmuvar.h index e7d97fddc4d..c01e10518ee 100644 --- a/sys/arch/arm64/dev/smmuvar.h +++ b/sys/arch/arm64/dev/smmuvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smmuvar.h,v 1.7 2022/08/10 17:02:37 patrick Exp $ */ +/* $OpenBSD: smmuvar.h,v 1.8 2022/09/11 10:18:54 patrick Exp $ */ /* * Copyright (c) 2021 Patrick Wildt * @@ -44,8 +44,9 @@ struct smmu_cb_irq { }; struct smmu_smr { - uint16_t mask; - uint16_t id; + struct smmu_domain *ss_dom; + uint16_t ss_id; + uint16_t ss_mask; }; struct smmu_softc { -- 2.20.1