From: Jon Medhurst <t...@linaro.org>

The A15xA7 models simulate a Cache Coherent Interconnect (CCI) and this
needs to be initialised correctly for Linux to boot.

To perform this initiation we add the new function configure_from_fdt()
which will look in the fdt for devices to initialise. In this first case
we look for the CCI node and if found then setup this device.

Signed-off-by: Jon Medhurst <t...@linaro.org>
---
 semi_loader.c |   50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/semi_loader.c b/semi_loader.c
index c9750be..ca70633 100644
--- a/semi_loader.c
+++ b/semi_loader.c
@@ -242,6 +242,54 @@ libfdt_error:
        fatal("libfdt: ", fdt_strerror(e), ", while updating device tree\n");
 }
 
+/* For accessing 32-bit device ports */
+#define io32(p) (*(volatile uint32_t *)(p))
+
+static void init_cci(unsigned cci)
+{
+       info("Initialising CCI\n");
+
+       /*
+        * Ideally, the CCI device tree binding would include suitable
+        * information so we can correctly configure the CCI, but for
+        * now we'll just hard-code settings for the present A15xA7
+        * models.
+        */
+
+       /* Turn on CCI snoops and DVM messages */
+       io32(cci+0x4000) = 0x3;   /* A15 cluster */
+       io32(cci+0x5000) = 0x3;   /* A7 cluster */
+
+       /* Wait while change pending bit of status register is set */
+       while(io32(cci+0xc) & 0x1)
+               {}
+}
+
+static void configure_from_fdt(struct loader_info *info)
+{
+       void *fdt = (void *)info->fdt_start;
+       uint32_t const *p;
+       int addrcells, sizecells;
+       int offset, len;
+
+       if(!fdt)
+               return;
+
+       _fdt_address_and_size_cells(fdt, &addrcells, &sizecells);
+
+       /* See if there is a CCI device to initialise */
+       offset = fdt_node_offset_by_compatible(fdt, 0, "arm,cci");
+       if (offset >= 0) {
+               p = fdt_getprop(fdt, offset, "reg", &len);
+               if(len != (addrcells + sizecells) * 4)
+                       info("Failed parsing device-tree node for CCI\n");
+               else
+                       init_cci(fdt32_to_cpu(p[addrcells - 1]));
+       }
+
+       return;
+}
+
 static int is_space(char c)
 {
        return c == ' ';
@@ -598,4 +646,6 @@ args_done:
        atag_append(&atagp, ATAG_NONE, 0, 0);
 
        update_fdt(&phys, info);
+
+       configure_from_fdt(info);
 }
-- 
1.7.10.4


_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to