ARM: 7199/2: only look for TCM on ARMv5 and later
authorLinus Walleij <linus.walleij@linaro.org>
Mon, 12 Dec 2011 08:24:40 +0000 (09:24 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 13 Dec 2011 08:52:02 +0000 (08:52 +0000)
The Integrator AP/CP can have a varying set of core modules, some
(like ARM920T) are so old that trying to read the TCM status register
with CP15 will make them hang. So we need to make sure that we are
running on v5 or later in order to be able to activate this for
the Integrator. (The Integrator with CM926EJ-S has 32+32 kb of TCM
memory.)

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/kernel/tcm.c

index 30e302d..01ec453 100644 (file)
@@ -180,9 +180,9 @@ static int __init setup_tcm_bank(u8 type, u8 bank, u8 banks,
  */
 void __init tcm_init(void)
 {
-       u32 tcm_status = read_cpuid_tcmstatus();
-       u8 dtcm_banks = (tcm_status >> 16) & 0x03;
-       u8 itcm_banks = (tcm_status & 0x03);
+       u32 tcm_status;
+       u8 dtcm_banks;
+       u8 itcm_banks;
        size_t dtcm_code_sz = &__edtcm_data - &__sdtcm_data;
        size_t itcm_code_sz = &__eitcm_text - &__sitcm_text;
        char *start;
@@ -191,6 +191,22 @@ void __init tcm_init(void)
        int ret;
        int i;
 
+       /*
+        * Prior to ARMv5 there is no TCM, and trying to read the status
+        * register will hang the processor.
+        */
+       if (cpu_architecture() < CPU_ARCH_ARMv5) {
+               if (dtcm_code_sz || itcm_code_sz)
+                       pr_info("CPU TCM: %u bytes of DTCM and %u bytes of "
+                               "ITCM code compiled in, but no TCM present "
+                               "in pre-v5 CPU\n", dtcm_code_sz, itcm_code_sz);
+               return;
+       }
+
+       tcm_status = read_cpuid_tcmstatus();
+       dtcm_banks = (tcm_status >> 16) & 0x03;
+       itcm_banks = (tcm_status & 0x03);
+
        /* Values greater than 2 for D/ITCM banks are "reserved" */
        if (dtcm_banks > 2)
                dtcm_banks = 0;