Commit 391d0feb authored by Joerg Roedel's avatar Joerg Roedel
Browse files

Merge tag 'arm-smmu-updates' of...

Merge tag 'arm-smmu-updates' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux into arm/smmu

Arm SMMU updates for 6.4

- Device-tree binding updates:
  * Allow Qualcomm GPU SMMUs to accept relevant clock properties
  * Document Qualcomm 8550 SoC as implementing an MMU-500
  * Favour new "qcom,smmu-500" binding for Adreno SMMUs

- Fix S2CR quirk detection on non-architectural Qualcomm SMMU
  implementations

- Acknowledge SMMUv3 PRI queue overflow when consuming events

- Document (in a comment) why ATS is disabled for bypass streams
parents e8d018dd ca08b2a6
Loading
Loading
Loading
Loading
+41 −4
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ properties:
              - qcom,sm8250-smmu-500
              - qcom,sm8350-smmu-500
              - qcom,sm8450-smmu-500
              - qcom,sm8550-smmu-500
          - const: qcom,smmu-500
          - const: arm,mmu-500

@@ -75,9 +76,22 @@ properties:
              - qcom,sm8350-smmu-500
              - qcom,sm8450-smmu-500
          - const: arm,mmu-500

      - description: Qcom Adreno GPUs implementing "arm,smmu-500"
      - description: Qcom Adreno GPUs implementing "qcom,smmu-500" and "arm,mmu-500"
        items:
          - enum:
              - qcom,sc7280-smmu-500
              - qcom,sm6115-smmu-500
              - qcom,sm6125-smmu-500
              - qcom,sm8150-smmu-500
              - qcom,sm8250-smmu-500
              - qcom,sm8350-smmu-500
          - const: qcom,adreno-smmu
          - const: qcom,smmu-500
          - const: arm,mmu-500
      - description: Qcom Adreno GPUs implementing "arm,mmu-500" (legacy binding)
        deprecated: true
        items:
          # Do not add additional SoC to this list. Instead use previous list.
          - enum:
              - qcom,sc7280-smmu-500
              - qcom,sm8150-smmu-500
@@ -364,6 +378,30 @@ allOf:
            - description: interface clock required to access smmu's registers
                through the TCU's programming interface.

  - if:
      properties:
        compatible:
          items:
            - enum:
                - qcom,sm6115-smmu-500
                - qcom,sm6125-smmu-500
            - const: qcom,adreno-smmu
            - const: qcom,smmu-500
            - const: arm,mmu-500
    then:
      properties:
        clock-names:
          items:
            - const: mem
            - const: hlos
            - const: iface

        clocks:
          items:
            - description: GPU memory bus clock
            - description: Voter clock required for HLOS SMMU access
            - description: Interface clock required for register access

  # Disallow clocks for all other platforms with specific compatibles
  - if:
      properties:
@@ -383,12 +421,11 @@ allOf:
              - qcom,sdm845-smmu-500
              - qcom,sdx55-smmu-500
              - qcom,sdx65-smmu-500
              - qcom,sm6115-smmu-500
              - qcom,sm6125-smmu-500
              - qcom,sm6350-smmu-500
              - qcom,sm6375-smmu-500
              - qcom,sm8350-smmu-500
              - qcom,sm8450-smmu-500
              - qcom,sm8550-smmu-500
    then:
      properties:
        clock-names: false
+21 −5
Original line number Diff line number Diff line
@@ -152,6 +152,18 @@ static void queue_inc_cons(struct arm_smmu_ll_queue *q)
	q->cons = Q_OVF(q->cons) | Q_WRP(q, cons) | Q_IDX(q, cons);
}

static void queue_sync_cons_ovf(struct arm_smmu_queue *q)
{
	struct arm_smmu_ll_queue *llq = &q->llq;

	if (likely(Q_OVF(llq->prod) == Q_OVF(llq->cons)))
		return;

	llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
		      Q_IDX(llq, llq->cons);
	queue_sync_cons_out(q);
}

static int queue_sync_prod_in(struct arm_smmu_queue *q)
{
	u32 prod;
@@ -1577,8 +1589,7 @@ static irqreturn_t arm_smmu_evtq_thread(int irq, void *dev)
	} while (!queue_empty(llq));

	/* Sync our overflow flag, as we believe we're up to speed */
	llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
		    Q_IDX(llq, llq->cons);
	queue_sync_cons_ovf(q);
	return IRQ_HANDLED;
}

@@ -1636,9 +1647,7 @@ static irqreturn_t arm_smmu_priq_thread(int irq, void *dev)
	} while (!queue_empty(llq));

	/* Sync our overflow flag, as we believe we're up to speed */
	llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
		      Q_IDX(llq, llq->cons);
	queue_sync_cons_out(q);
	queue_sync_cons_ovf(q);
	return IRQ_HANDLED;
}

@@ -2447,6 +2456,13 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)

	master->domain = smmu_domain;

	/*
	 * The SMMU does not support enabling ATS with bypass. When the STE is
	 * in bypass (STE.Config[2:0] == 0b100), ATS Translation Requests and
	 * Translated transactions are denied as though ATS is disabled for the
	 * stream (STE.EATS == 0b00), causing F_BAD_ATS_TREQ and
	 * F_TRANSL_FORBIDDEN events (IHI0070Ea 5.2 Stream Table Entry).
	 */
	if (smmu_domain->stage != ARM_SMMU_DOMAIN_BYPASS)
		master->ats_enabled = arm_smmu_ats_supported(master);

+15 −1
Original line number Diff line number Diff line
@@ -268,12 +268,26 @@ static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,

static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
{
	unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1);
	struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
	unsigned int last_s2cr;
	u32 reg;
	u32 smr;
	int i;

	/*
	 * Some platforms support more than the Arm SMMU architected maximum of
	 * 128 stream matching groups. For unknown reasons, the additional
	 * groups don't exhibit the same behavior as the architected registers,
	 * so limit the groups to 128 until the behavior is fixed for the other
	 * groups.
	 */
	if (smmu->num_mapping_groups > 128) {
		dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n");
		smmu->num_mapping_groups = 128;
	}

	last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1);

	/*
	 * With some firmware versions writes to S2CR of type FAULT are
	 * ignored, and writing BYPASS will end up written as FAULT in the