summaryrefslogtreecommitdiff
path: root/cpu/bf561/cpu.c
diff options
context:
space:
mode:
authorStefan Roese <sr@denx.de>2007-03-31 13:44:12 +0200
committerStefan Roese <sr@denx.de>2007-03-31 13:44:12 +0200
commit0e7d4916afaf83083b9b70ad779f29f7b57bd8ed (patch)
tree40e9396ee819149a89f520f551d1ed31cb8f5216 /cpu/bf561/cpu.c
parentda6ebc1bc082cbe3b6bbde079cafe09f7ebbad4b (diff)
parent6db7d0af2336c126e4d4b2f248cc23516bdd46a8 (diff)
Merge with git://www.denx.de/git/u-boot.git
Diffstat (limited to 'cpu/bf561/cpu.c')
-rw-r--r--cpu/bf561/cpu.c220
1 files changed, 220 insertions, 0 deletions
diff --git a/cpu/bf561/cpu.c b/cpu/bf561/cpu.c
new file mode 100644
index 00000000000..a7b53d8a2d7
--- /dev/null
+++ b/cpu/bf561/cpu.c
@@ -0,0 +1,220 @@
+/*
+ * U-boot - cpu.c CPU specific functions
+ *
+ * Copyright (c) 2005 blackfin.uclinux.org
+ *
+ * (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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 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;
+
+ /* 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)
+{
+ 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;
+}