blob: fc69d371319e2ccd85f5266280898c9d8949a236 [file] [log] [blame]
Barry Wardellf43e50d2007-04-22 12:03:17 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Barry Wardellf43e50d2007-04-22 12:03:17 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
Barry Wardellf43e50d2007-04-22 12:03:17 +000021#include "system.h"
Barry Wardellf43e50d2007-04-22 12:03:17 +000022
Barry Wardellf43e50d2007-04-22 12:03:17 +000023#ifndef BOOTLOADER
24extern void TIMER1(void);
25extern void TIMER2(void);
Jens Arnoldffb121c2007-07-29 08:03:21 +000026extern void ipod_3g_button_int(void);
Jens Arnold4e8b1712007-07-30 23:48:03 +000027extern void ipod_2g_adc_int(void);
Barry Wardellf43e50d2007-04-22 12:03:17 +000028
29void irq(void)
30{
31 if(CURRENT_CORE == CPU)
32 {
33 if (CPU_INT_STAT & TIMER1_MASK)
34 TIMER1();
35 else if (CPU_INT_STAT & TIMER2_MASK)
36 TIMER2();
Jens Arnoldffb121c2007-07-29 08:03:21 +000037 else if (CPU_INT_STAT & GPIO_MASK)
Jens Arnold4e8b1712007-07-30 23:48:03 +000038 {
39 if (GPIOA_INT_STAT)
40 ipod_3g_button_int();
41#ifdef IPOD_1G2G
42 if (GPIOB_INT_STAT & 0x04)
43 ipod_2g_adc_int();
44#endif
45 }
46 }
47 else
48 {
Michael Sevakisa8b388f2007-11-27 01:20:26 +000049 if (COP_INT_STAT & TIMER2_MASK)
Barry Wardellf43e50d2007-04-22 12:03:17 +000050 TIMER2();
51 }
52}
53
54#endif
55
Barry Wardellf43e50d2007-04-22 12:03:17 +000056/* TODO: The following two function have been lifted straight from IPL, and
57 hence have a lot of numeric addresses used straight. I'd like to use
58 #defines for these, but don't know what most of them are for or even what
59 they should be named. Because of this I also have no way of knowing how
60 to extend the funtions to do alternate cache configurations and/or
61 some other CPU frequency scaling. */
62
63#ifndef BOOTLOADER
Michael Sevakisa8b388f2007-11-27 01:20:26 +000064void flush_icache(void) ICODE_ATTR;
65void flush_icache(void)
Barry Wardellf43e50d2007-04-22 12:03:17 +000066{
Michael Sevakisa8b388f2007-11-27 01:20:26 +000067 intptr_t b, e;
Barry Wardellf43e50d2007-04-22 12:03:17 +000068
Michael Sevakisa8b388f2007-11-27 01:20:26 +000069 for (b = (intptr_t)&CACHE_FLUSH_BASE, e = b + CACHE_SIZE;
70 b < e; b += 16) {
71 outl(0x0, b);
72 }
73}
Barry Wardellf43e50d2007-04-22 12:03:17 +000074
Michael Sevakisa8b388f2007-11-27 01:20:26 +000075void invalidate_icache(void) ICODE_ATTR;
76void invalidate_icache(void)
77{
78 intptr_t b, e;
79
80 /* Flush */
81 for (b = (intptr_t)&CACHE_FLUSH_BASE, e = b + CACHE_SIZE;
82 b < e; b += 16) {
83 outl(0x0, b);
Barry Wardellf43e50d2007-04-22 12:03:17 +000084 }
85
Michael Sevakisa8b388f2007-11-27 01:20:26 +000086 /* Invalidate */
87 for (b = (intptr_t)&CACHE_INVALIDATE_BASE, e = b + CACHE_SIZE;
88 b < e; b += 16) {
89 outl(0x0, b);
90 }
91}
Barry Wardellf43e50d2007-04-22 12:03:17 +000092
Michael Sevakisa8b388f2007-11-27 01:20:26 +000093static void ipod_init_cache(void)
94{
95 intptr_t b, e;
96
97/* Initialising the cache in the iPod bootloader prevents Rockbox from starting */
98 PROC_STAT &= ~0x700;
99 outl(0x4000, 0xcf004020);
100
101 CACHE_CTL = CACHE_INIT;
102
103 for (b = (intptr_t)&CACHE_INVALIDATE_BASE, e = b + CACHE_SIZE;
104 b < e; b += 16) {
105 outl(0x0, b);
106 }
107
108 /* Cache if (addr & mask) >> 16 == (mask & match) >> 16:
109 * yes: 0x00000000 - 0x03ffffff
110 * no: 0x04000000 - 0x1fffffff
111 * yes: 0x20000000 - 0x23ffffff
112 * no: 0x24000000 - 0x3fffffff <= range containing uncached alias
113 */
114 CACHE_MASK = 0x00001c00;
115 CACHE_OPERATION = 0x3fc0;
116
117 CACHE_CTL = CACHE_INIT | CACHE_RUN;
Barry Wardellf43e50d2007-04-22 12:03:17 +0000118}
119
Barry Wardellf43e50d2007-04-22 12:03:17 +0000120#ifdef HAVE_ADJUSTABLE_CPU_FREQ
121void set_cpu_frequency(long frequency)
Jens Arnold1bc3b7f2007-07-31 10:56:50 +0000122#else
123static void pp_set_cpu_frequency(long frequency)
Barry Wardellf43e50d2007-04-22 12:03:17 +0000124#endif
Jens Arnold1bc3b7f2007-07-31 10:56:50 +0000125{
126 cpu_frequency = frequency;
127
128 PLL_CONTROL |= 0x6000; /* make sure some enable bits are set */
129 CLOCK_ENABLE = 0x01; /* select source #1 */
130
131 switch (frequency)
132 {
133 case CPUFREQ_MAX:
134 PLL_UNLOCK = 0xd19b; /* unlock frequencies > 66MHz */
135 CLOCK_SOURCE = 0xa9; /* source #1: 24 Mhz, source #2..#4: PLL */
136 PLL_CONTROL = 0xe000; /* PLL enabled */
137 PLL_DIV = 3; /* 10/3 * 24MHz */
138 PLL_MULT = 10;
139 udelay(200); /* wait for relock */
140 break;
141
142 case CPUFREQ_NORMAL:
143 CLOCK_SOURCE = 0xa9; /* source #1: 24 Mhz, source #2..#4: PLL */
144 PLL_CONTROL = 0xe000; /* PLL enabled */
145 PLL_DIV = 4; /* 5/4 * 24MHz */
146 PLL_MULT = 5;
147 udelay(200); /* wait for relock */
148 break;
149
150 case CPUFREQ_SLEEP:
151 CLOCK_SOURCE = 0x51; /* source #2: 32kHz, #1, #2, #4: 24MHz */
152 PLL_CONTROL = 0x6000; /* PLL disabled */
153 udelay(10000); /* let 32kHz source stabilize? */
154 break;
155
156 default:
157 CLOCK_SOURCE = 0x55; /* source #1..#4: 24 Mhz */
158 PLL_CONTROL = 0x6000; /* PLL disabled */
159 cpu_frequency = CPUFREQ_DEFAULT;
160 break;
161 }
162 CLOCK_ENABLE = 0x02; /* select source #2 */
163}
164#endif /* !BOOTLOADER */
Barry Wardellf43e50d2007-04-22 12:03:17 +0000165
166void system_init(void)
167{
168#ifndef BOOTLOADER
169 if (CURRENT_CORE == CPU)
170 {
Michael Sevakisa8b388f2007-11-27 01:20:26 +0000171 /* Remap the flash ROM on CPU, keep hidden from COP:
172 * 0x00000000-0x03ffffff = 0x20000000-0x23ffffff */
173 MMAP1_LOGICAL = 0x20003c00;
174 MMAP1_PHYSICAL = 0x00003f84;
Barry Wardellf43e50d2007-04-22 12:03:17 +0000175
Jens Arnold1fbcead2007-08-06 17:26:28 +0000176#if defined(IPOD_1G2G) || defined(IPOD_3G)
177 DEV_EN = 0x0b9f; /* don't clock unused PP5002 hardware components */
178 outl(0x0035, 0xcf005004); /* DEV_EN2 ? */
179#endif
180
Jens Arnold604e44d2007-07-29 07:50:34 +0000181 INT_FORCED_CLR = -1;
Michael Sevakis191320c2008-06-03 05:08:24 +0000182 CPU_INT_DIS = -1;
183 COP_INT_DIS = -1;
Jens Arnold604e44d2007-07-29 07:50:34 +0000184
185 GPIOA_INT_EN = 0;
186 GPIOB_INT_EN = 0;
187 GPIOC_INT_EN = 0;
188 GPIOD_INT_EN = 0;
189
Michael Sevakisa8b388f2007-11-27 01:20:26 +0000190#ifdef HAVE_ADJUSTABLE_CPU_FREQ
191#if NUM_CORES > 1
192 cpu_boost_init();
193#endif
194#else
Jens Arnold1bc3b7f2007-07-31 10:56:50 +0000195 pp_set_cpu_frequency(CPUFREQ_MAX);
Barry Wardellf43e50d2007-04-22 12:03:17 +0000196#endif
197 }
198 ipod_init_cache();
199#endif
200}
201
202void system_reboot(void)
203{
Jens Arnold1bc3b7f2007-07-31 10:56:50 +0000204 DEV_RS |= 4;
Barry Wardellf43e50d2007-04-22 12:03:17 +0000205}
206
207int system_memory_guard(int newmode)
208{
209 (void)newmode;
210 return 0;
211}