--- zzzz-none-000/linux-3.10.107/arch/arm/mach-mvebu/coherency_ll.S 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/arm/mach-mvebu/coherency_ll.S 2021-02-04 17:41:59.000000000 +0000 @@ -20,36 +20,147 @@ #define ARMADA_XP_CFB_CTL_REG_OFFSET 0x0 #define ARMADA_XP_CFB_CFG_REG_OFFSET 0x4 +#include +#include + .text /* - * r0: Coherency fabric base register address - * r1: HW CPU id + * Returns the coherency base address in r1 (r0 is untouched), or 0 if + * the coherency fabric is not enabled. */ -ENTRY(ll_set_cpu_coherent) - /* Create bit by cpu index */ - mov r3, #(1 << 24) - lsl r1, r3, r1 +ENTRY(ll_get_coherency_base) + mrc p15, 0, r1, c1, c0, 0 + tst r1, #CR_M @ Check MMU bit enabled + bne 1f - /* Add CPU to SMP group - Atomic */ - add r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET + /* + * MMU is disabled, use the physical address of the coherency + * base address. However, if the coherency fabric isn't mapped + * (i.e its virtual address is zero), it means coherency is + * not enabled, so we return 0. + */ + ldr r1, =coherency_base + cmp r1, #0 + beq 2f + adr r1, 3f + ldr r3, [r1] + ldr r1, [r1, r3] + b 2f 1: - ldrex r2, [r3] - orr r2, r2, r1 - strex r0, r2, [r3] - cmp r0, #0 - bne 1b + /* + * MMU is enabled, use the virtual address of the coherency + * base address. + */ + ldr r1, =coherency_base + ldr r1, [r1] +2: + ret lr +ENDPROC(ll_get_coherency_base) + +/* + * Returns the coherency CPU mask in r3 (r0 is untouched). This + * coherency CPU mask can be used with the coherency fabric + * configuration and control registers. Note that the mask is already + * endian-swapped as appropriate so that the calling functions do not + * have to care about endianness issues while accessing the coherency + * fabric registers + */ +ENTRY(ll_get_coherency_cpumask) + mrc 15, 0, r3, cr0, cr0, 5 + and r3, r3, #15 + mov r2, #(1 << 24) + lsl r3, r2, r3 +ARM_BE8(rev r3, r3) + ret lr +ENDPROC(ll_get_coherency_cpumask) + +/* + * ll_add_cpu_to_smp_group(), ll_enable_coherency() and + * ll_disable_coherency() use the strex/ldrex instructions while the + * MMU can be disabled. The Armada XP SoC has an exclusive monitor + * that tracks transactions to Device and/or SO memory and thanks to + * that, exclusive transactions are functional even when the MMU is + * disabled. + */ - /* Enable coherency on CPU - Atomic */ - add r3, r3, #ARMADA_XP_CFB_CFG_REG_OFFSET +ENTRY(ll_add_cpu_to_smp_group) + /* + * As r0 is not modified by ll_get_coherency_base() and + * ll_get_coherency_cpumask(), we use it to temporarly save lr + * and avoid it being modified by the branch and link + * calls. This function is used very early in the secondary + * CPU boot, and no stack is available at this point. + */ + mov r0, lr + bl ll_get_coherency_base + /* Bail out if the coherency is not enabled */ + cmp r1, #0 + reteq r0 + bl ll_get_coherency_cpumask + mov lr, r0 + add r0, r1, #ARMADA_XP_CFB_CFG_REG_OFFSET 1: - ldrex r2, [r3] - orr r2, r2, r1 - strex r0, r2, [r3] - cmp r0, #0 - bne 1b + ldrex r2, [r0] + orr r2, r2, r3 + strex r1, r2, [r0] + cmp r1, #0 + bne 1b + ret lr +ENDPROC(ll_add_cpu_to_smp_group) +ENTRY(ll_enable_coherency) + /* + * As r0 is not modified by ll_get_coherency_base() and + * ll_get_coherency_cpumask(), we use it to temporarly save lr + * and avoid it being modified by the branch and link + * calls. This function is used very early in the secondary + * CPU boot, and no stack is available at this point. + */ + mov r0, lr + bl ll_get_coherency_base + /* Bail out if the coherency is not enabled */ + cmp r1, #0 + reteq r0 + bl ll_get_coherency_cpumask + mov lr, r0 + add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET +1: + ldrex r2, [r0] + orr r2, r2, r3 + strex r1, r2, [r0] + cmp r1, #0 + bne 1b dsb - mov r0, #0 - mov pc, lr -ENDPROC(ll_set_cpu_coherent) + ret lr +ENDPROC(ll_enable_coherency) + +ENTRY(ll_disable_coherency) + /* + * As r0 is not modified by ll_get_coherency_base() and + * ll_get_coherency_cpumask(), we use it to temporarly save lr + * and avoid it being modified by the branch and link + * calls. This function is used very early in the secondary + * CPU boot, and no stack is available at this point. + */ + mov r0, lr + bl ll_get_coherency_base + /* Bail out if the coherency is not enabled */ + cmp r1, #0 + reteq r0 + bl ll_get_coherency_cpumask + mov lr, r0 + add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET +1: + ldrex r2, [r0] + bic r2, r2, r3 + strex r1, r2, [r0] + cmp r1, #0 + bne 1b + dsb + ret lr +ENDPROC(ll_disable_coherency) + + .align 2 +3: + .long coherency_phys_base - .