cci: Wait before reading status register
authorRoberto Vargas <[email protected]>
Wed, 18 Jul 2018 10:14:20 +0000 (11:14 +0100)
committerRoberto Vargas <[email protected]>
Thu, 19 Jul 2018 11:51:52 +0000 (12:51 +0100)
The functions cci_enable_snoop_dvm_reqs and cci_disable_snoop_dvm_reqs write
in the SNOOP_CTRL_REGISTER of the slave interface and it polls the status
register to be sure that the operation is finished before leaving the
functions. If the write in SNOOP_CTRL_REGISTER is reordered after the first
read in the status register then these functions can finish before
enabling/disabling snoops and DVM messages.

The CCI500 TRM specifies:

Wait for the completion of the write to the Snoop Control Register
before testing the change_pending bit.

Change-Id: Idc7685963f412be1c16bcd3c6e3cca826e2fdf38
Signed-off-by: Roberto Vargas <[email protected]>
drivers/arm/cci/cci.c

index 81808b9f70de316ce6c66d057f1a7eac55a82e02..71b65f42ce2abaab44d2eea1f1ed5b1049a7c1ab 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <arch.h>
+#include <arch_helpers.h>
 #include <assert.h>
 #include <cci.h>
 #include <debug.h>
@@ -142,6 +143,12 @@ void cci_enable_snoop_dvm_reqs(unsigned int master_id)
                      SLAVE_IFACE_OFFSET(slave_if_id) + SNOOP_CTRL_REG,
                      DVM_EN_BIT | SNOOP_EN_BIT);
 
+       /*
+        * Wait for the completion of the write to the Snoop Control Register
+        * before testing the change_pending bit
+        */
+       dmbish();
+
        /* Wait for the dust to settle down */
        while (mmio_read_32(cci_base + STATUS_REG) & CHANGE_PENDING_BIT)
                ;
@@ -163,6 +170,12 @@ void cci_disable_snoop_dvm_reqs(unsigned int master_id)
                      SLAVE_IFACE_OFFSET(slave_if_id) + SNOOP_CTRL_REG,
                      ~(DVM_EN_BIT | SNOOP_EN_BIT));
 
+       /*
+        * Wait for the completion of the write to the Snoop Control Register
+        * before testing the change_pending bit
+        */
+       dmbish();
+
        /* Wait for the dust to settle down */
        while (mmio_read_32(cci_base + STATUS_REG) & CHANGE_PENDING_BIT)
                ;