blob: 1ceb89bd16a5b0a6593211852c726f533c12566f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006 by Linus Nielsen Feltzing
*
* 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "cpu.h"
#include "kernel.h"
#include "system.h"
#include "power.h"
#include "timer.h"
#include "pcf50606.h"
/* Settings for all possible clock frequencies (with properly working timers)
* NOTE: Some 5249 chips don't like having PLLDIV set to 0. We must avoid that!
*
* xxx_REFRESH_TIMER below
* system.h, CPUFREQ_xxx_MULT |
* | |
* V V
* PLLCR & Refreshtim. IDECONFIG1/IDECONFIG2
* CPUCLK/Hz MULT ~0x70400000 16MB 32MB CSCR0 CSCR1 CSCR3 CS2Pre CS2Post CS2Wait
* ---------------------------------------------------------------------------------------
* 11289600 1 0x00800200 4 1 0x0180 0x0180 0x0180 1 1 0
* 22579200 2 0x0589e025 10 4 0x0180 0x0180 0x0180 1 1 0
* 33868800 3 0x0388e025 15 7 0x0180 0x0180 0x0180 1 1 0
* 45158400 4 0x0589e021 21 10 0x0580 0x0180 0x0580 1 1 0
* 56448000 5 0x0289e025 26 12 0x0580 0x0580 0x0980 2 1 0
* 67737600 6 0x0388e021 32 15 0x0980 0x0980 0x0d80 2 1 0
* 79027200 7 0x038a6021 37 18 0x0980 0x0d80 0x1180 2 1 0
* 90316800 8 0x038be021 43 21 0x0d80 0x0d80 0x1580 2 1 0
* 101606400 9 0x01892025 48 23 0x0d80 0x1180 0x1980 2 1 0
* 112896000 10 0x0189e025 54 26 0x1180 0x1580 0x1d80 3 1 0
* 124185600 11 0x018ae025 59 29 0x1180 0x1580 0x2180 3 1 1
*/
#if MEMORYSIZE < 32
#define MAX_REFRESH_TIMER 59
#define NORMAL_REFRESH_TIMER 21
#define DEFAULT_REFRESH_TIMER 4
#else
#define MAX_REFRESH_TIMER 29
#define NORMAL_REFRESH_TIMER 10
#define DEFAULT_REFRESH_TIMER 1
#endif
#ifdef IRIVER_H300_SERIES
#define RECALC_DELAYS(f) \
pcf50606_i2c_recalc_delay(f)
#else
#define RECALC_DELAYS(f)
#endif
#ifdef HAVE_SERIAL
#define BAUD_RATE 57600
#define BAUDRATE_DIV_DEFAULT (CPUFREQ_DEFAULT/(BAUD_RATE*32*2))
#define BAUDRATE_DIV_NORMAL (CPUFREQ_NORMAL/(BAUD_RATE*32*2))
#define BAUDRATE_DIV_MAX (CPUFREQ_MAX/(BAUD_RATE*32*2))
#endif
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
void set_cpu_frequency (long) __attribute__ ((section (".icode")));
void set_cpu_frequency(long frequency)
#else
void cf_set_cpu_frequency (long) __attribute__ ((section (".icode")));
void cf_set_cpu_frequency(long frequency)
#endif
{
switch(frequency)
{
case CPUFREQ_MAX:
DCR = (0x8200 | DEFAULT_REFRESH_TIMER);
/* Refresh timer for bypass frequency */
PLLCR &= ~1; /* Bypass mode */
timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, false);
RECALC_DELAYS(CPUFREQ_MAX);
PLLCR = 0x018ae025 | (PLLCR & 0x70400000);
CSCR0 = 0x00001180; /* Flash: 4 wait states */
CSCR1 = 0x00001580; /* LCD: 5 wait states */
#if CONFIG_USBOTG == USBOTG_ISP1362
CSCR3 = 0x00002180; /* USBOTG: 8 wait states */
#endif
while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked.
This may take up to 10ms! */
timers_adjust_prescale(CPUFREQ_MAX_MULT, true);
DCR = (0x8200 | MAX_REFRESH_TIMER); /* Refresh timer */
cpu_frequency = CPUFREQ_MAX;
IDECONFIG1 = 0x10100000 | (1 << 13) | (3 << 10);
/* SRE active on write (H300 USBOTG) | BUFEN2 enable | CS2Post | CS2Pre */
IDECONFIG2 = 0x40000 | (1 << 8); /* TA enable + CS2wait */
#ifdef HAVE_SERIAL
UBG10 = BAUDRATE_DIV_MAX >> 8;
UBG20 = BAUDRATE_DIV_MAX & 0xff;
#endif
break;
case CPUFREQ_NORMAL:
DCR = (DCR & ~0x01ff) | DEFAULT_REFRESH_TIMER;
/* Refresh timer for bypass frequency */
PLLCR &= ~1; /* Bypass mode */
timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, false);
RECALC_DELAYS(CPUFREQ_NORMAL);
PLLCR = 0x0589e021 | (PLLCR & 0x70400000);
CSCR0 = 0x00000580; /* Flash: 1 wait state */
CSCR1 = 0x00000180; /* LCD: 0 wait states */
#if CONFIG_USBOTG == USBOTG_ISP1362
CSCR3 = 0x00000580; /* USBOTG: 1 wait state */
#endif
while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked.
This may take up to 10ms! */
timers_adjust_prescale(CPUFREQ_NORMAL_MULT, true);
DCR = (0x8000 | NORMAL_REFRESH_TIMER); /* Refresh timer */
cpu_frequency = CPUFREQ_NORMAL;
IDECONFIG1 = 0x10100000 | (1 << 13) | (1 << 10);
/* SRE active on write (H300 USBOTG) | BUFEN2 enable | CS2Post | CS2Pre */
IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */
#ifdef HAVE_SERIAL
UBG10 = BAUDRATE_DIV_NORMAL >> 8;
UBG20 = BAUDRATE_DIV_NORMAL & 0xff;
#endif
break;
default:
DCR = (DCR & ~0x01ff) | DEFAULT_REFRESH_TIMER;
/* Refresh timer for bypass frequency */
PLLCR &= ~1; /* Bypass mode */
timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, true);
RECALC_DELAYS(CPUFREQ_DEFAULT);
/* Power down PLL, but keep CRSEL and CLSEL */
PLLCR = 0x00800200 | (PLLCR & 0x70400000);
CSCR0 = 0x00000180; /* Flash: 0 wait states */
CSCR1 = 0x00000180; /* LCD: 0 wait states */
#if CONFIG_USBOTG == USBOTG_ISP1362
CSCR3 = 0x00000180; /* USBOTG: 0 wait states */
#endif
DCR = (0x8000 | DEFAULT_REFRESH_TIMER); /* Refresh timer */
cpu_frequency = CPUFREQ_DEFAULT;
IDECONFIG1 = 0x10100000 | (1 << 13) | (1 << 10);
/* SRE active on write (H300 USBOTG) | BUFEN2 enable | CS2Post | CS2Pre */
IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */
#ifdef HAVE_SERIAL
UBG10 = BAUDRATE_DIV_DEFAULT >> 8;
UBG20 = BAUDRATE_DIV_DEFAULT & 0xff;
#endif
break;
}
}
|