blob: 654ebe259e0d0869c86ef035a7beddd43de0e3fa [file] [log] [blame]
#include "tests.h"
#include "dump.h"
#include <diags.h>
#include <common.h>
#include <init.h>
#include <asm/io.h>
#include <asm/mmu.h>
#define SCU_BASE_ADDR 0xFFF00000
#define TTB_BASE 0x4000
#define PMD_SEC_TEX2 (1 << 14)
#define COHERENT_SECTION (PMD_SECT_AP_WRITE | PMD_SECT_XN | PMD_SECT_S | PMD_SECT_BUFFERABLE | PMD_SEC_TEX2 | PMD_TYPE_SECT)
#define COHE_TEST_AREA 0x00600000
#define COHE_TEST_LOC 0x00600010
#define A9DP_CPU_RESET 0x904b0078
#define NEON1_RESET 0x8 /* When Set to 1, A9DP NEON1 is in Reset. */
#define CPU1_RESET 0x4 /* When Set to 1, A9DP CPU1 is in Reset. */
#define CPU_SYNC_LOC 0x8300ff04
#define CPU0_SYNC_VAL0 0xdeaddead
#define CPU0_SYNC_VAL1 0xdeadbeef
#define CPU1_SYNC_VAL0 0xbeefbeef
#define CPU0_SYNC_VAL_COHERENT 0xbeefdead
#define CPU0_SYNC_VAL_COHERENT2 0xbeefdddd
#define COHE_PATTERN0 0xa1a1b1b1
#define COHE_PATTERN1 0xaaaabbbb
#define COHE_PATTERN2 0xbbbbcccc
#define COHE_PATTERN3 0xccccdddd
#define DEBUG_LOC 0x8300ff0c
#define PATTERN_TEMP1 0xdead5555
#define PATTERN_TEMP2 0xdead6666
#define PATTERN_PASS 0xdeadaaaa
#define PATTERN_FAIL 0xdeadffff
static unsigned long *ttb;
static inline void set_marker(int mark)
{
writel(mark, 0x8300ff0c);
}
void cpu_reset_1()
{
unsigned int val;
val = readl(A9DP_CPU_RESET);
val &= ~(NEON1_RESET | CPU1_RESET);
writel(val, A9DP_CPU_RESET);
}
void smp_mode_enable(void) {
unsigned long val;
//ENable the coherency bit
asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc");
val |= (1 << 6);
asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" : : "r" (val) : "cc");
}
void enable_SCU(void)
{
unsigned long val;
//Invalidate SCU Tag
val = 0;
writel(val, SCU_BASE_ADDR + 0xC);
//Enable SCU
val = readl(SCU_BASE_ADDR);
val |= 0x1;
writel(val, SCU_BASE_ADDR);
}
static void create_section_entry(unsigned long virt, unsigned long phys, int size_m,
unsigned int flags)
{
int i;
phys >>= 20;
virt >>= 20;
for (i = size_m; i > 0; i--, virt++, phys++)
ttb[virt] = (phys << 20) | flags;
}
static void setup_pagetable(void)
{
ttb = (void *)TTB_BASE;
create_section_entry(0x0, 0x0, 2, PMD_SECT_DEF_UNCACHED);
create_section_entry(COHE_TEST_AREA, COHE_TEST_AREA, 1, COHERENT_SECTION);
//IRAM section
create_section_entry(0x83000000, 0x83000000, 1, PMD_SECT_DEF_UNCACHED);
//SCU register section
create_section_entry(SCU_BASE_ADDR, SCU_BASE_ADDR, 1, PMD_SECT_DEF_UNCACHED);
}
static void mmu_init_minimal(void)
{
int i;
ttb = (void *)TTB_BASE;
/* Set the Domain Access Control Register */
i = 0x3;
asm volatile ("mcr p15,0,%0,c3,c0,0" : : "r"(i) /*:*/);
/* Set the ttb register */
asm volatile ("mcr p15,0,%0,c2,c0,0" : : "r"(ttb) /*:*/);
//MMU Enable
mmu_enable();
}
int Comcerto_dualcore_test (struct diags_test_param *p)
{
unsigned int r = 0;
volatile int *ptr = COHE_TEST_LOC;
*ptr = COHE_PATTERN0;
writel(CPU0_SYNC_VAL0, CPU_SYNC_LOC);
cpu_reset_1();
while(r != CPU1_SYNC_VAL0)
{
r = readl(CPU_SYNC_LOC);
}
writel(CPU0_SYNC_VAL1, CPU_SYNC_LOC);
*(volatile int *)0x90470034 = 0x10;
setup_pagetable();
mmu_init_minimal();
smp_mode_enable();
enable_SCU();
cpu0_coherency_test();
}
void cpu1_test(void)
{
unsigned int r = 0;
writel(CPU1_SYNC_VAL0, CPU_SYNC_LOC);
while(r != CPU0_SYNC_VAL1)
{
r = readl(CPU_SYNC_LOC);
}
#define STACK_BASE_1 0x83005000
#define STACK_SIZE_1 0x1000
/* Setup the stack */
r = STACK_BASE_1 + STACK_SIZE_1 - 16;
__asm__ __volatile__("mov sp, %0" : : "r"(r));
setup_pagetable();
mmu_init_minimal();
smp_mode_enable();
cpu1_coherency_test();
}
void cpu0_coherency_test()
{
int timeout = 0;
volatile int r = 0;
writel(COHE_PATTERN1, COHE_TEST_LOC);
writel(CPU0_SYNC_VAL_COHERENT, CPU_SYNC_LOC);
while(r != CPU0_SYNC_VAL_COHERENT2)
{
r = readl(CPU_SYNC_LOC);
}
r = readl(COHE_TEST_LOC);
if(r == COHE_PATTERN2)
{
set_marker(PATTERN_PASS);
}
else
set_marker(PATTERN_FAIL);
}
void cpu1_coherency_test()
{
volatile int r;
int timeout = 0;
while(r != CPU0_SYNC_VAL_COHERENT)
{
r = readl(CPU_SYNC_LOC);
}
r = readl(COHE_TEST_LOC);
if(r == COHE_PATTERN1)
{
set_marker(PATTERN_PASS);
}
else
set_marker(PATTERN_FAIL);
writel(COHE_PATTERN2, COHE_TEST_LOC);
writel(CPU0_SYNC_VAL_COHERENT2, CPU_SYNC_LOC);
while(1);
}