mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-26 06:30:39 +00:00
227 lines
4.7 KiB
C
227 lines
4.7 KiB
C
/*
|
|
* U-boot - cpu.c CPU specific functions
|
|
*
|
|
* Copyright (c) 2005-2007 Analog Devices Inc.
|
|
*
|
|
* (C) Copyright 2000-2004
|
|
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
|
*
|
|
* See file CREDITS for list of people who contributed to this
|
|
* project.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
|
* MA 02110-1301 USA
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <asm/blackfin.h>
|
|
#include <command.h>
|
|
#include <asm/entry.h>
|
|
#include <asm/cplb.h>
|
|
#include <asm/io.h>
|
|
|
|
#define CACHE_ON 1
|
|
#define CACHE_OFF 0
|
|
|
|
extern unsigned int icplb_table[page_descriptor_table_size][2];
|
|
extern unsigned int dcplb_table[page_descriptor_table_size][2];
|
|
|
|
int do_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
{
|
|
__asm__ __volatile__("cli r3;" "P0 = %0;" "JUMP (P0);"::"r"(L1_ISRAM)
|
|
);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* These functions are just used to satisfy the linker */
|
|
int cpu_init(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int cleanup_before_linux(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void icache_enable(void)
|
|
{
|
|
unsigned int *I0, *I1;
|
|
int i, j = 0;
|
|
|
|
if ((*pCHIPID >> 28) < 2)
|
|
return;
|
|
|
|
/* Before enable icache, disable it first */
|
|
icache_disable();
|
|
I0 = (unsigned int *)ICPLB_ADDR0;
|
|
I1 = (unsigned int *)ICPLB_DATA0;
|
|
|
|
/* make sure the locked ones go in first */
|
|
for (i = 0; i < page_descriptor_table_size; i++) {
|
|
if (CPLB_LOCK & icplb_table[i][1]) {
|
|
debug("adding %02i %02i 0x%08x 0x%08x\n", i, j,
|
|
icplb_table[i][0], icplb_table[i][1]);
|
|
*I0++ = icplb_table[i][0];
|
|
*I1++ = icplb_table[i][1];
|
|
j++;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < page_descriptor_table_size; i++) {
|
|
if (!(CPLB_LOCK & icplb_table[i][1])) {
|
|
debug("adding %02i %02i 0x%08x 0x%08x\n", i, j,
|
|
icplb_table[i][0], icplb_table[i][1]);
|
|
*I0++ = icplb_table[i][0];
|
|
*I1++ = icplb_table[i][1];
|
|
j++;
|
|
if (j == 16) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Fill the rest with invalid entry */
|
|
if (j <= 15) {
|
|
for (; j < 16; j++) {
|
|
debug("filling %i with 0", j);
|
|
*I1++ = 0x0;
|
|
}
|
|
|
|
}
|
|
|
|
cli();
|
|
sync();
|
|
asm(" .align 8; ");
|
|
*(unsigned int *)IMEM_CONTROL = IMC | ENICPLB;
|
|
sync();
|
|
sti();
|
|
}
|
|
|
|
void icache_disable(void)
|
|
{
|
|
if ((*pCHIPID >> 28) < 2)
|
|
return;
|
|
cli();
|
|
sync();
|
|
asm(" .align 8; ");
|
|
*(unsigned int *)IMEM_CONTROL &= ~(IMC | ENICPLB);
|
|
sync();
|
|
sti();
|
|
}
|
|
|
|
int icache_status(void)
|
|
{
|
|
unsigned int value;
|
|
value = *(unsigned int *)IMEM_CONTROL;
|
|
|
|
if (value & (IMC | ENICPLB))
|
|
return CACHE_ON;
|
|
else
|
|
return CACHE_OFF;
|
|
}
|
|
|
|
void dcache_enable(void)
|
|
{
|
|
unsigned int *I0, *I1;
|
|
unsigned int temp;
|
|
int i, j = 0;
|
|
|
|
/* Before enable dcache, disable it first */
|
|
dcache_disable();
|
|
I0 = (unsigned int *)DCPLB_ADDR0;
|
|
I1 = (unsigned int *)DCPLB_DATA0;
|
|
|
|
/* make sure the locked ones go in first */
|
|
for (i = 0; i < page_descriptor_table_size; i++) {
|
|
if (CPLB_LOCK & dcplb_table[i][1]) {
|
|
debug("adding %02i %02i 0x%08x 0x%08x\n", i, j,
|
|
dcplb_table[i][0], dcplb_table[i][1]);
|
|
*I0++ = dcplb_table[i][0];
|
|
*I1++ = dcplb_table[i][1];
|
|
j++;
|
|
} else {
|
|
debug("skip %02i %02i 0x%08x 0x%08x\n", i, j,
|
|
dcplb_table[i][0], dcplb_table[i][1]);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < page_descriptor_table_size; i++) {
|
|
if (!(CPLB_LOCK & dcplb_table[i][1])) {
|
|
debug("adding %02i %02i 0x%08x 0x%08x\n", i, j,
|
|
dcplb_table[i][0], dcplb_table[i][1]);
|
|
*I0++ = dcplb_table[i][0];
|
|
*I1++ = dcplb_table[i][1];
|
|
j++;
|
|
if (j == 16) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Fill the rest with invalid entry */
|
|
if (j <= 15) {
|
|
for (; j < 16; j++) {
|
|
debug("filling %i with 0", j);
|
|
*I1++ = 0x0;
|
|
}
|
|
}
|
|
|
|
cli();
|
|
temp = *(unsigned int *)DMEM_CONTROL;
|
|
sync();
|
|
asm(" .align 8; ");
|
|
*(unsigned int *)DMEM_CONTROL =
|
|
ACACHE_BCACHE | ENDCPLB | PORT_PREF0 | temp;
|
|
sync();
|
|
sti();
|
|
}
|
|
|
|
void dcache_disable(void)
|
|
{
|
|
unsigned int *I0, *I1;
|
|
int i;
|
|
|
|
cli();
|
|
sync();
|
|
asm(" .align 8; ");
|
|
*(unsigned int *)DMEM_CONTROL &=
|
|
~(ACACHE_BCACHE | ENDCPLB | PORT_PREF0);
|
|
sync();
|
|
sti();
|
|
|
|
/* after disable dcache,
|
|
* clear it so we don't confuse the next application
|
|
*/
|
|
I0 = (unsigned int *)DCPLB_ADDR0;
|
|
I1 = (unsigned int *)DCPLB_DATA0;
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
*I0++ = 0x0;
|
|
*I1++ = 0x0;
|
|
}
|
|
}
|
|
|
|
int dcache_status(void)
|
|
{
|
|
unsigned int value;
|
|
value = *(unsigned int *)DMEM_CONTROL;
|
|
|
|
if (value & (ENDCPLB))
|
|
return CACHE_ON;
|
|
else
|
|
return CACHE_OFF;
|
|
}
|