summaryrefslogtreecommitdiff
path: root/core/arch/arm/plat-sunxi/smp_fixup.S
diff options
context:
space:
mode:
Diffstat (limited to 'core/arch/arm/plat-sunxi/smp_fixup.S')
-rw-r--r--core/arch/arm/plat-sunxi/smp_fixup.S116
1 files changed, 116 insertions, 0 deletions
diff --git a/core/arch/arm/plat-sunxi/smp_fixup.S b/core/arch/arm/plat-sunxi/smp_fixup.S
new file mode 100644
index 0000000..bf533b4
--- /dev/null
+++ b/core/arch/arm/plat-sunxi/smp_fixup.S
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2014, Allwinner Technology Co., Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <asm.S>
+#include <kernel/unwind.h>
+
+#define SLAVE_SNOOPCTL_OFFSET 0
+#define SNOOPCTL_SNOOP_ENABLE (1 << 0)
+#define SNOOPCTL_DVM_ENABLE (1 << 1)
+
+#define CCI_STATUS_OFFSET 0xc
+#define STATUS_CHANGE_PENDING (1 << 0)
+
+#define CCI_SLAVE_OFFSET(n) (0x1000 + 0x1000 * (n))
+
+#define SUNXI_CCI_PHYS_BASE 0x01c90000
+#define SUNXI_CCI_SLAVE_A7 3
+#define SUNXI_CCI_SLAVE_A15 4
+#define SUNXI_CCI_A15_OFFSET CCI_SLAVE_OFFSET(SUNXI_CCI_SLAVE_A15)
+#define SUNXI_CCI_A7_OFFSET CCI_SLAVE_OFFSET(SUNXI_CCI_SLAVE_A7)
+
+#define SUNXI_CCU_PHYS_BASE (0x06000000)
+#define SUNXI_CCU_C0_CFG_OFFSET (0x54)
+#define SUNXI_CCU_C1_CFG_OFFSET (0x58)
+
+FUNC sunxi_secondary_fixup , :
+UNWIND( .fnstart)
+ mrc p15, 0, r0, c0, c0, 5 /* MPIDR */
+ ubfx r0, r0, #8, #4 /* cluster */
+
+ ldr r3, =SUNXI_CCU_PHYS_BASE + SUNXI_CCU_C0_CFG_OFFSET
+ cmp r0, #0 /* A7 cluster? */
+ addne r3, r3, #SUNXI_CCU_C1_CFG_OFFSET - SUNXI_CCU_C0_CFG_OFFSET
+ ldr r1, [r3]
+ bic r1, r1, #(0x3<<8) /* a15 atb div */
+ orr r1, r1, #(0x1<<8) /* div = 2 */
+ bic r1, r1, #(0x7<<0) /* a15 atb div */
+ orr r1, r1, #(0x2<<0) /* div = value + 1 */
+ str r1, [r3] /* set atb div to 2, axi div to 3 */
+ dsb /* Synchronise side-effects of axi config */
+ ldr r1, [r3]
+ bic r1, r1, #(0x3<<8) /* a15 atb div */
+ orr r1, r1, #(0x2<<8) /* div = 4 */
+ bic r1, r1, #(0x7<<0) /* a15 atb div */
+ orr r1, r1, #(0x3<<0) /* div = value + 1 */
+ str r1, [r3] /* set atb div to 4, axi div to 4 */
+ dsb /* Synchronise side-effects of axi config */
+
+ /* Enable CCI snoops. */
+ ldr r3, =SUNXI_CCI_PHYS_BASE + SUNXI_CCI_A7_OFFSET
+ cmp r0, #0 /* A7 cluster? */
+ addne r3, r3, #SUNXI_CCI_A15_OFFSET - SUNXI_CCI_A7_OFFSET
+
+ @ r3 now points to the correct CCI slave register block
+ ldr r1, [r3, #SLAVE_SNOOPCTL_OFFSET]
+ orr r1, r1, #SNOOPCTL_SNOOP_ENABLE
+ orr r1, r1, #SNOOPCTL_DVM_ENABLE
+ str r1, [r3, #SLAVE_SNOOPCTL_OFFSET] /* enable CCI snoops */
+
+ /* Wait for snoop control change to complete */
+ ldr r3, =SUNXI_CCI_PHYS_BASE
+1:
+ ldr r1, [r3, #CCI_STATUS_OFFSET]
+ tst r1, #STATUS_CHANGE_PENDING
+ bne 1b
+ dsb /* Synchronise side-effects of enabling CCI */
+
+ cmp r0, #1 /* A15 cluster ? */
+ bne 2f
+
+ /* a80 platform-specific Cortex-A15 setup */
+ mrc p15, 1, r1, c15, c0, 4 /* ACTLR2 */
+ orr r1, r1, #(0x1<<31) /* Enable CPU regional clock gates */
+ mcr p15, 1, r1, c15, c0, 4
+
+ mrc p15, 1, r1, c15, c0, 0 /* L2ACTLR */
+ orr r1, r1, #(0x1<<26) /* Enables L2, GIC, and Timer regional clock gates */
+ mcr p15, 1, r1, c15, c0, 0
+
+ mrc p15, 1, r1, c15, c0, 0 /* L2ACTLR */
+ orr r1, r1, #(0x1<<3) /* Disables clean/evict from being pushed to external */
+ mcr p15, 1, r1, c15, c0, 0
+
+ mrc p15, 1, r1, c9, c0, 2
+ bic r1, r1, #(0x7<<0) /* L2 data ram latency */
+ orr r1, r1, #(0x3<<0)
+ mcr p15, 1, r1, c9, c0, 2
+
+2:
+ /* a80 platform-specific operations porcess done. */
+ bx lr
+UNWIND( .fnend)
+END_FUNC sunxi_secondary_fixup