blob: 1af909a9a55cb85f87f08f9a5911184bc21b34ae [file] [log] [blame]
wdenkc0218802003-03-27 12:09:35 +00001/*
2 * (C) Copyright 2003
3 * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
4 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
wdenkc0218802003-03-27 12:09:35 +00006 */
7
8#include <common.h>
9#include <command.h>
Shinya Kuribayashi5dfb3ee2008-10-19 12:08:50 +090010#include <netdev.h>
wdenk5da627a2003-10-09 20:09:04 +000011#include <asm/mipsregs.h>
Shinya Kuribayashiccf8f822008-03-25 21:30:06 +090012#include <asm/cacheops.h>
Shinya Kuribayashib0c66af2008-03-25 21:30:07 +090013#include <asm/reboot.h>
Shinya Kuribayashiccf8f822008-03-25 21:30:06 +090014
Shinya Kuribayashib0c66af2008-03-25 21:30:07 +090015void __attribute__((weak)) _machine_restart(void)
16{
17}
18
Wolfgang Denk54841ab2010-06-28 22:00:46 +020019int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
wdenkc0218802003-03-27 12:09:35 +000020{
Shinya Kuribayashib0c66af2008-03-25 21:30:07 +090021 _machine_restart();
wdenk3e386912003-04-05 00:53:31 +000022
wdenkc0218802003-03-27 12:09:35 +000023 fprintf(stderr, "*** reset failed ***\n");
24 return 0;
25}
26
Paul Burtonfa476f72013-11-08 11:18:42 +000027#ifdef CONFIG_SYS_CACHELINE_SIZE
28
29static inline unsigned long icache_line_size(void)
30{
31 return CONFIG_SYS_CACHELINE_SIZE;
32}
33
34static inline unsigned long dcache_line_size(void)
35{
36 return CONFIG_SYS_CACHELINE_SIZE;
37}
38
39#else /* !CONFIG_SYS_CACHELINE_SIZE */
40
41static inline unsigned long icache_line_size(void)
42{
43 unsigned long conf1, il;
44 conf1 = read_c0_config1();
45 il = (conf1 & MIPS_CONF1_IL) >> MIPS_CONF1_IL_SHIFT;
46 if (!il)
47 return 0;
48 return 2 << il;
49}
50
51static inline unsigned long dcache_line_size(void)
52{
53 unsigned long conf1, dl;
54 conf1 = read_c0_config1();
55 dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHIFT;
56 if (!dl)
57 return 0;
58 return 2 << dl;
59}
60
61#endif /* !CONFIG_SYS_CACHELINE_SIZE */
62
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +090063void flush_cache(ulong start_addr, ulong size)
wdenkc0218802003-03-27 12:09:35 +000064{
Paul Burtonfa476f72013-11-08 11:18:42 +000065 unsigned long ilsize = icache_line_size();
66 unsigned long dlsize = dcache_line_size();
Paul Burton2b8bcc52015-01-29 01:27:56 +000067 const void *addr, *aend;
Shinya Kuribayashiccf8f822008-03-25 21:30:06 +090068
Yao Chengdc344582011-08-10 15:11:16 +080069 /* aend will be miscalculated when size is zero, so we return here */
70 if (size == 0)
71 return;
72
Paul Burton2b8bcc52015-01-29 01:27:56 +000073 addr = (const void *)(start_addr & ~(dlsize - 1));
74 aend = (const void *)((start_addr + size - 1) & ~(dlsize - 1));
Paul Burtonfa476f72013-11-08 11:18:42 +000075
76 if (ilsize == dlsize) {
77 /* flush I-cache & D-cache simultaneously */
78 while (1) {
Paul Burton2b8bcc52015-01-29 01:27:56 +000079 mips_cache(HIT_WRITEBACK_INV_D, addr);
80 mips_cache(HIT_INVALIDATE_I, addr);
Paul Burtonfa476f72013-11-08 11:18:42 +000081 if (addr == aend)
82 break;
83 addr += dlsize;
84 }
85 return;
86 }
87
88 /* flush D-cache */
Shinya Kuribayashiccf8f822008-03-25 21:30:06 +090089 while (1) {
Paul Burton2b8bcc52015-01-29 01:27:56 +000090 mips_cache(HIT_WRITEBACK_INV_D, addr);
Paul Burtonfa476f72013-11-08 11:18:42 +000091 if (addr == aend)
92 break;
93 addr += dlsize;
94 }
95
96 /* flush I-cache */
Paul Burton2b8bcc52015-01-29 01:27:56 +000097 addr = (const void *)(start_addr & ~(ilsize - 1));
98 aend = (const void *)((start_addr + size - 1) & ~(ilsize - 1));
Paul Burtonfa476f72013-11-08 11:18:42 +000099 while (1) {
Paul Burton2b8bcc52015-01-29 01:27:56 +0000100 mips_cache(HIT_INVALIDATE_I, addr);
Shinya Kuribayashiccf8f822008-03-25 21:30:06 +0900101 if (addr == aend)
102 break;
Paul Burtonfa476f72013-11-08 11:18:42 +0000103 addr += ilsize;
Shinya Kuribayashiccf8f822008-03-25 21:30:06 +0900104 }
wdenkc0218802003-03-27 12:09:35 +0000105}
wdenk5da627a2003-10-09 20:09:04 +0000106
Stefan Roese03d3bfb2009-01-21 17:20:20 +0100107void flush_dcache_range(ulong start_addr, ulong stop)
108{
Paul Burtonfa476f72013-11-08 11:18:42 +0000109 unsigned long lsize = dcache_line_size();
Paul Burton2b8bcc52015-01-29 01:27:56 +0000110 const void *addr = (const void *)(start_addr & ~(lsize - 1));
111 const void *aend = (const void *)((stop - 1) & ~(lsize - 1));
Stefan Roese03d3bfb2009-01-21 17:20:20 +0100112
113 while (1) {
Paul Burton2b8bcc52015-01-29 01:27:56 +0000114 mips_cache(HIT_WRITEBACK_INV_D, addr);
Stefan Roese03d3bfb2009-01-21 17:20:20 +0100115 if (addr == aend)
116 break;
117 addr += lsize;
118 }
119}
120
121void invalidate_dcache_range(ulong start_addr, ulong stop)
122{
Paul Burtonfa476f72013-11-08 11:18:42 +0000123 unsigned long lsize = dcache_line_size();
Paul Burton2b8bcc52015-01-29 01:27:56 +0000124 const void *addr = (const void *)(start_addr & ~(lsize - 1));
125 const void *aend = (const void *)((stop - 1) & ~(lsize - 1));
Stefan Roese03d3bfb2009-01-21 17:20:20 +0100126
127 while (1) {
Paul Burton2b8bcc52015-01-29 01:27:56 +0000128 mips_cache(HIT_INVALIDATE_D, addr);
Stefan Roese03d3bfb2009-01-21 17:20:20 +0100129 if (addr == aend)
130 break;
131 addr += lsize;
132 }
133}
134
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900135void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
136{
Shinya Kuribayashie2ad8422008-05-30 00:53:38 +0900137 write_c0_entrylo0(low0);
138 write_c0_pagemask(pagemask);
139 write_c0_entrylo1(low1);
140 write_c0_entryhi(hi);
141 write_c0_index(index);
wdenk5da627a2003-10-09 20:09:04 +0000142 tlb_write_indexed();
143}
Shinya Kuribayashi5dfb3ee2008-10-19 12:08:50 +0900144
145int cpu_eth_init(bd_t *bis)
146{
147#ifdef CONFIG_SOC_AU1X00
148 au1x00_enet_initialize(bis);
149#endif
150 return 0;
151}