1 /*
2 * linux/arch/arm/mach-sa1100/cpu-sa1110.c
3 *
4 * Copyright (C) 2001 Russell King
5 *
6 * $Id: cpu-sa1110.c,v 1.6 2001/10/22 11:53:47 rmk Exp $
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * Note: there are two erratas that apply to the SA1110 here:
13 * 7 - SDRAM auto-power-up failure (rev A0)
14 * 13 - Corruption of internal register reads/writes following
15 * SDRAM reads (rev A0, B0, B1)
16 *
17 * We ignore rev. A0 and B0 devices; I don't think they're worth supporting.
18 */
19 #include <linux/types.h>
20 #include <linux/kernel.h>
21 #include <linux/sched.h>
22 #include <linux/cpufreq.h>
23 #include <linux/delay.h>
24 #include <linux/init.h>
25
26 #include <asm/hardware.h>
27 #include <asm/io.h>
28 #include <asm/system.h>
29
30 #undef DEBUG
31
32 extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
33 extern unsigned int sa11x0_validatespeed(unsigned int khz);
34
35 struct sdram_params {
36 u_char rows; /* bits */
37 u_char cas_latency; /* cycles */
38 u_char tck; /* clock cycle time (ns) */
39 u_char trcd; /* activate to r/w (ns) */
40 u_char trp; /* precharge to activate (ns) */
41 u_char twr; /* write recovery time (ns) */
42 u_short refresh; /* refresh time for array (us) */
43 };
44
45 struct sdram_info {
46 u_int mdcnfg;
47 u_int mdrefr;
48 u_int mdcas[3];
49 };
50
51 static struct sdram_params tc59sm716_cl2_params __initdata = {
52 .rows = 12,
53 .tck = 10,
54 .trcd = 20,
55 .trp = 20,
56 .twr = 10,
57 .refresh = 64000,
58 .cas_latency = 2,
59 };
60
61 static struct sdram_params tc59sm716_cl3_params __initdata = {
62 .rows = 12,
63 .tck = 8,
64 .trcd = 20,
65 .trp = 20,
66 .twr = 8,
67 .refresh = 64000,
68 .cas_latency = 3,
69 };
70
71 static struct sdram_params samsung_k4s641632d_tc75 __initdata = {
72 .rows = 14,
73 .tck = 9,
74 .trcd = 27,
75 .trp = 20,
76 .twr = 9,
77 .refresh = 64000,
78 .cas_latency = 3,
79 };
80
81 static struct sdram_params sdram_params;
82
83 /*
84 * Given a period in ns and frequency in khz, calculate the number of
85 * cycles of frequency in period. Note that we round up to the next
86 * cycle, even if we are only slightly over.
87 */
ns_to_cycles(u_int ns,u_int khz)88 static inline u_int ns_to_cycles(u_int ns, u_int khz)
89 {
90 return (ns * khz + 999999) / 1000000;
91 }
92
93 /*
94 * Create the MDCAS register bit pattern.
95 */
set_mdcas(u_int * mdcas,int delayed,u_int rcd)96 static inline void set_mdcas(u_int *mdcas, int delayed, u_int rcd)
97 {
98 u_int shift;
99
100 rcd = 2 * rcd - 1;
101 shift = delayed + 1 + rcd;
102
103 mdcas[0] = (1 << rcd) - 1;
104 mdcas[0] |= 0x55555555 << shift;
105 mdcas[1] = mdcas[2] = 0x55555555 << (shift & 1);
106 }
107
108 static void
sdram_calculate_timing(struct sdram_info * sd,u_int cpu_khz,struct sdram_params * sdram)109 sdram_calculate_timing(struct sdram_info *sd, u_int cpu_khz,
110 struct sdram_params *sdram)
111 {
112 u_int mem_khz, sd_khz, trp, twr;
113
114 mem_khz = cpu_khz / 2;
115 sd_khz = mem_khz;
116
117 /*
118 * If SDCLK would invalidate the SDRAM timings,
119 * run SDCLK at half speed.
120 *
121 * CPU steppings prior to B2 must either run the memory at
122 * half speed or use delayed read latching (errata 13).
123 */
124 if ((ns_to_cycles(sdram->tck, sd_khz) > 1) ||
125 (CPU_REVISION < CPU_SA1110_B2 && sd_khz < 62000))
126 sd_khz /= 2;
127
128 sd->mdcnfg = MDCNFG & 0x007f007f;
129
130 twr = ns_to_cycles(sdram->twr, mem_khz);
131
132 /* trp should always be >1 */
133 trp = ns_to_cycles(sdram->trp, mem_khz) - 1;
134 if (trp < 1)
135 trp = 1;
136
137 sd->mdcnfg |= trp << 8;
138 sd->mdcnfg |= trp << 24;
139 sd->mdcnfg |= sdram->cas_latency << 12;
140 sd->mdcnfg |= sdram->cas_latency << 28;
141 sd->mdcnfg |= twr << 14;
142 sd->mdcnfg |= twr << 30;
143
144 sd->mdrefr = MDREFR & 0xffbffff0;
145 sd->mdrefr |= 7;
146
147 if (sd_khz != mem_khz)
148 sd->mdrefr |= MDREFR_K1DB2;
149
150 /* initial number of '1's in MDCAS + 1 */
151 set_mdcas(sd->mdcas, sd_khz >= 62000, ns_to_cycles(sdram->trcd, mem_khz));
152
153 #ifdef DEBUG
154 printk("MDCNFG: %08x MDREFR: %08x MDCAS0: %08x MDCAS1: %08x MDCAS2: %08x\n",
155 sd->mdcnfg, sd->mdrefr, sd->mdcas[0], sd->mdcas[1], sd->mdcas[2]);
156 #endif
157 }
158
159 /*
160 * Set the SDRAM refresh rate.
161 */
sdram_set_refresh(u_int dri)162 static inline void sdram_set_refresh(u_int dri)
163 {
164 MDREFR = (MDREFR & 0xffff000f) | (dri << 4);
165 (void) MDREFR;
166 }
167
168 /*
169 * Update the refresh period. We do this such that we always refresh
170 * the SDRAMs within their permissible period. The refresh period is
171 * always a multiple of the memory clock (fixed at cpu_clock / 2).
172 *
173 * FIXME: we don't currently take account of burst accesses here,
174 * but neither do Intels DM nor Angel.
175 */
176 static void
sdram_update_refresh(u_int cpu_khz,struct sdram_params * sdram)177 sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
178 {
179 u_int ns_row = (sdram->refresh * 1000) >> sdram->rows;
180 u_int dri = ns_to_cycles(ns_row, cpu_khz / 2) / 32;
181
182 #ifdef DEBUG
183 mdelay(250);
184 printk("new dri value = %d\n", dri);
185 #endif
186
187 sdram_set_refresh(dri);
188 }
189
190 /*
191 * Ok, set the CPU frequency. Since we've done the validation
192 * above, we can match for an exact frequency. If we don't find
193 * an exact match, we will to set the lowest frequency to be safe.
194 */
sa1110_setspeed(unsigned int khz)195 static void sa1110_setspeed(unsigned int khz)
196 {
197 struct sdram_params *sdram = &sdram_params;
198 struct sdram_info sd;
199 unsigned long flags;
200 unsigned int ppcr, unused;
201
202 ppcr = sa11x0_freq_to_ppcr(khz);
203 sdram_calculate_timing(&sd, khz, sdram);
204
205 #if 0
206 /*
207 * These values are wrong according to the SA1110 documentation
208 * and errata, but they seem to work. Need to get a storage
209 * scope on to the SDRAM signals to work out why.
210 */
211 if (khz < 147500) {
212 sd.mdrefr |= MDREFR_K1DB2;
213 sd.mdcas[0] = 0xaaaaaa7f;
214 } else {
215 sd.mdrefr &= ~MDREFR_K1DB2;
216 sd.mdcas[0] = 0xaaaaaa9f;
217 }
218 sd.mdcas[1] = 0xaaaaaaaa;
219 sd.mdcas[2] = 0xaaaaaaaa;
220 #endif
221 /*
222 * The clock could be going away for some time. Set the SDRAMs
223 * to refresh rapidly (every 64 memory clock cycles). To get
224 * through the whole array, we need to wait 262144 mclk cycles.
225 * We wait 20ms to be safe.
226 */
227 sdram_set_refresh(2);
228 set_current_state(TASK_UNINTERRUPTIBLE);
229 schedule_timeout(20 * HZ / 1000);
230
231 /*
232 * Reprogram the DRAM timings with interrupts disabled, and
233 * ensure that we are doing this within a complete cache line.
234 * This means that we won't access SDRAM for the duration of
235 * the programming.
236 */
237 local_irq_save(flags);
238 asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
239 udelay(10);
240 __asm__ __volatile__(" \n\
241 b 2f \n\
242 .align 5 \n\
243 1: str %3, [%1, #0] @ MDCNFG \n\
244 str %4, [%1, #28] @ MDREFR \n\
245 str %5, [%1, #4] @ MDCAS0 \n\
246 str %6, [%1, #8] @ MDCAS1 \n\
247 str %7, [%1, #12] @ MDCAS2 \n\
248 str %8, [%2, #0] @ PPCR \n\
249 ldr %0, [%1, #0] \n\
250 b 3f \n\
251 2: b 1b \n\
252 3: nop \n\
253 nop"
254 : "=&r" (unused)
255 : "r" (&MDCNFG), "r" (&PPCR), "0" (sd.mdcnfg),
256 "r" (sd.mdrefr), "r" (sd.mdcas[0]),
257 "r" (sd.mdcas[1]), "r" (sd.mdcas[2]), "r" (ppcr));
258 local_irq_restore(flags);
259
260 /*
261 * Now, return the SDRAM refresh back to normal.
262 */
263 sdram_update_refresh(khz, sdram);
264 }
265
sa1110_clk_init(void)266 static int __init sa1110_clk_init(void)
267 {
268 struct sdram_params *sdram = NULL;
269
270 if (machine_is_assabet())
271 sdram = &tc59sm716_cl3_params;
272
273 if (machine_is_pt_system3())
274 sdram = &samsung_k4s641632d_tc75;
275
276 if (sdram) {
277 printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d"
278 " twr: %d refresh: %d cas_latency: %d\n",
279 sdram->tck, sdram->trcd, sdram->trp,
280 sdram->twr, sdram->refresh, sdram->cas_latency);
281
282 memcpy(&sdram_params, sdram, sizeof(sdram_params));
283
284 sa1110_setspeed(cpufreq_get(0));
285 cpufreq_setfunctions(sa11x0_validatespeed, sa1110_setspeed);
286 }
287
288 return 0;
289 }
290
291 __initcall(sa1110_clk_init);
292