Skip to content

Commit 0a19b7b

Browse files
Sahil-Malpekarprashymh
authored andcommitted
fix(smmu): update GBPA.ABORT on SMMU disable
- Added programming of SMMU_GBPA.ABORT during SMMU state transitions. - Clear ABORT when disabling the SMMU to avoid abort responses in bypass mode. Signed-off-by: Sahil Shakil Malpekar <Sahil.ShakilMalpekar@arm.com> Change-Id: Ib9f2f994a5e39a827978c07535dc8ee92350f094
1 parent e68c861 commit 0a19b7b

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

val/driver/smmu_v3/smmu_reg.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/** @file
2-
* Copyright (c) 2020, 2023-2025, Arm Limited or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2023-2026, Arm Limited or its affiliates. All rights reserved.
33
* SPDX-License-Identifier : Apache-2.0
44
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -65,6 +65,12 @@ uint32_t smmu_oas[SMMU_OAS_MAX_IDX] = {32, 36, 40, 42, 44, 48, 52};
6565

6666
#define SMMU_CR0ACK_OFFSET 0x24
6767

68+
#define SMMU_GBPA_OFFSET 0x44
69+
#define SMMU_GBPA_ABORT (1U << 20)
70+
#define SMMU_GBPA_UPDATE (1U << 31)
71+
72+
#define SMMU_SYNC_TIMEOUT 0x1000000ULL
73+
6874
#define SMMU_CR1_OFFSET 0x28
6975
BITFIELD_DECL(uint32_t, CR1_TABLE_SH, 11, 10)
7076
BITFIELD_DECL(uint32_t, CR1_TABLE_OC, 9, 8)

val/driver/smmu_v3/smmu_v3.c

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/** @file
2-
* Copyright (c) 2020, 2022-2025, Arm Limited or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2022-2026, Arm Limited or its affiliates. All rights reserved.
33
* SPDX-License-Identifier : Apache-2.0
44
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -727,11 +727,52 @@ static int smmu_reset(smmu_dev_t *smmu)
727727
return 1;
728728
}
729729

730+
/**
731+
@brief Program SMMU_GBPA using the architected Update procedure
732+
733+
@param smmu - Pointer to the SMMU device structure
734+
@param gbpa_attrs - Desired SMMU_GBPA attribute value with Update bit clear
735+
736+
@return
737+
- 0 : Success
738+
- non-zero: Failure (GBPA update did not complete within timeout)
739+
**/
740+
static int smmu_gbpa_write_sync(smmu_dev_t *smmu, uint32_t gbpa_attrs)
741+
{
742+
uint64_t timeout = SMMU_SYNC_TIMEOUT;
743+
uint32_t gbpa;
744+
745+
/* Must only write when Update == 0 */
746+
while (timeout--) {
747+
gbpa = val_mmio_read(smmu->base + SMMU_GBPA_OFFSET);
748+
if ((gbpa & SMMU_GBPA_UPDATE) == 0)
749+
break;
750+
}
751+
752+
if (gbpa & SMMU_GBPA_UPDATE)
753+
return 1;
754+
755+
/* setting Update=1 simultaneously */
756+
val_mmio_write(smmu->base + SMMU_GBPA_OFFSET,
757+
gbpa_attrs | SMMU_GBPA_UPDATE);
758+
759+
/* Poll until Update clears (update complete) */
760+
timeout = SMMU_SYNC_TIMEOUT;
761+
while (timeout--) {
762+
gbpa = val_mmio_read(smmu->base + SMMU_GBPA_OFFSET);
763+
if ((gbpa & SMMU_GBPA_UPDATE) == 0)
764+
return 0;
765+
}
766+
767+
return 1;
768+
}
769+
730770
static uint32_t smmu_set_state(uint32_t smmu_index, uint32_t en)
731771
{
732772
smmu_dev_t *smmu;
733773
uint32_t cr0_val;
734774
int ret;
775+
uint32_t gbpa;
735776

736777
if (smmu_index >= g_num_smmus)
737778
{
@@ -762,6 +803,19 @@ static uint32_t smmu_set_state(uint32_t smmu_index, uint32_t en)
762803
return ret;
763804
}
764805

806+
/* Clear GBPA.ABORT when disabling SMMU */
807+
if (!en) {
808+
809+
gbpa = val_mmio_read(smmu->base + SMMU_GBPA_OFFSET);
810+
811+
gbpa &= ~SMMU_GBPA_ABORT;
812+
813+
if (smmu_gbpa_write_sync(smmu, gbpa)) {
814+
val_print(ACS_PRINT_ERR, "\n GBPA update sync failed", 0);
815+
return 1;
816+
}
817+
}
818+
765819
return 0;
766820
}
767821

0 commit comments

Comments
 (0)