Make an attempt at taking over existing streams on Qualcomm machines. Some
authorpatrick <patrick@openbsd.org>
Sun, 11 Sep 2022 10:18:54 +0000 (10:18 +0000)
committerpatrick <patrick@openbsd.org>
Sun, 11 Sep 2022 10:18:54 +0000 (10:18 +0000)
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
sys/arch/arm64/dev/smmureg.h
sys/arch/arm64/dev/smmuvar.h

index e8f103a..37b6d79 100644 (file)
@@ -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 <drahn@dalerahn.com>
  * Copyright (c) 2021 Patrick Wildt <patrick@blueri.se>
@@ -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;
                }
index 926d2d9..3b1962f 100644 (file)
@@ -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 <patrick@blueri.se>
  *
 #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)
index e7d97fd..c01e105 100644 (file)
@@ -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 <patrick@blueri.se>
  *
@@ -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 {