blob: 261efc8a533eb13be7aacd4a727a55c6f6808535 [file] [log] [blame]
Tero Kristo20006552009-11-22 10:11:36 -08001/*
Aaro Koskinen6c3bc4e2010-12-17 15:13:44 -08002 * SDRC register values for Nokia boards
Tero Kristo20006552009-11-22 10:11:36 -08003 *
Aaro Koskinen6c3bc4e2010-12-17 15:13:44 -08004 * Copyright (C) 2008, 2010 Nokia Corporation
Tero Kristo20006552009-11-22 10:11:36 -08005 *
6 * Lauri Leukkunen <lauri.leukkunen@nokia.com>
7 *
8 * Original code by Juha Yrjola <juha.yrjola@solidboot.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/clk.h>
17#include <linux/err.h>
18#include <linux/io.h>
19
20#include <plat/io.h>
21#include <plat/common.h>
22#include <plat/clock.h>
23#include <plat/sdrc.h>
24
Aaro Koskinenfcd8d8462010-12-17 15:13:44 -080025#include "sdram-nokia.h"
Tero Kristo20006552009-11-22 10:11:36 -080026
27/* In picoseconds, except for tREF (ns), tXP, tCKE, tWTR (clks) */
28struct sdram_timings {
29 u32 casl;
30 u32 tDAL;
31 u32 tDPL;
32 u32 tRRD;
33 u32 tRCD;
34 u32 tRP;
35 u32 tRAS;
36 u32 tRC;
37 u32 tRFC;
38 u32 tXSR;
39
40 u32 tREF; /* in ns */
41
42 u32 tXP;
43 u32 tCKE;
44 u32 tWTR;
45};
46
Aaro Koskinen6c3bc4e2010-12-17 15:13:44 -080047static struct omap_sdrc_params nokia_sdrc_params[4];
Tero Kristo20006552009-11-22 10:11:36 -080048
Aaro Koskinen6c3bc4e2010-12-17 15:13:44 -080049static const struct sdram_timings memory_timings[] = {
Tero Kristo20006552009-11-22 10:11:36 -080050 {
51 .casl = 3,
52 .tDAL = 33000,
53 .tDPL = 15000,
54 .tRRD = 12000,
55 .tRCD = 22500,
56 .tRP = 18000,
57 .tRAS = 42000,
58 .tRC = 66000,
59 .tRFC = 138000,
60 .tXSR = 200000,
61
62 .tREF = 7800,
63
64 .tXP = 2,
65 .tCKE = 2,
66 .tWTR = 2
67 },
68};
69
70static unsigned long sdrc_get_fclk_period(long rate)
71{
72 /* In picoseconds */
73 return 1000000000 / rate;
74}
75
76static unsigned int sdrc_ps_to_ticks(unsigned int time_ps, long rate)
77{
78 unsigned long tick_ps;
79
80 /* Calculate in picosecs to yield more exact results */
81 tick_ps = sdrc_get_fclk_period(rate);
82
83 return (time_ps + tick_ps - 1) / tick_ps;
84}
85#undef DEBUG
86#ifdef DEBUG
87static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit,
88 int ticks, long rate, const char *name)
89#else
90static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit,
91 int ticks)
92#endif
93{
94 int mask, nr_bits;
95
96 nr_bits = end_bit - st_bit + 1;
97 if (ticks >= 1 << nr_bits)
98 return -1;
99 mask = (1 << nr_bits) - 1;
100 *regval &= ~(mask << st_bit);
101 *regval |= ticks << st_bit;
102#ifdef DEBUG
103 printk(KERN_INFO "SDRC %s: %i ticks %i ns\n", name, ticks,
104 (unsigned int)sdrc_get_fclk_period(rate) * ticks /
105 1000);
106#endif
107
108 return 0;
109}
110
111#ifdef DEBUG
112#define SDRC_SET_ONE(reg, st, end, field, rate) \
113 if (set_sdrc_timing_regval((reg), (st), (end), \
Aaro Koskinen6c3bc4e2010-12-17 15:13:44 -0800114 memory_timings->field, (rate), #field) < 0) \
Tero Kristo20006552009-11-22 10:11:36 -0800115 err = -1;
116#else
117#define SDRC_SET_ONE(reg, st, end, field, rate) \
118 if (set_sdrc_timing_regval((reg), (st), (end), \
Aaro Koskinen6c3bc4e2010-12-17 15:13:44 -0800119 memory_timings->field) < 0) \
Tero Kristo20006552009-11-22 10:11:36 -0800120 err = -1;
121#endif
122
123#ifdef DEBUG
124static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit,
125 int time, long rate, const char *name)
126#else
127static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit,
128 int time, long rate)
129#endif
130{
131 int ticks, ret;
132 ret = 0;
133
134 if (time == 0)
135 ticks = 0;
136 else
137 ticks = sdrc_ps_to_ticks(time, rate);
138
139#ifdef DEBUG
140 ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks,
141 rate, name);
142#else
143 ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks);
144#endif
145
146 return ret;
147}
148
149#ifdef DEBUG
150#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \
151 if (set_sdrc_timing_regval_ps((reg), (st), (end), \
Aaro Koskinen6c3bc4e2010-12-17 15:13:44 -0800152 memory_timings->field, \
Tero Kristo20006552009-11-22 10:11:36 -0800153 (rate), #field) < 0) \
154 err = -1;
155
156#else
157#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \
158 if (set_sdrc_timing_regval_ps((reg), (st), (end), \
Aaro Koskinen6c3bc4e2010-12-17 15:13:44 -0800159 memory_timings->field, (rate)) < 0) \
Tero Kristo20006552009-11-22 10:11:36 -0800160 err = -1;
161#endif
162
163static int sdrc_timings(int id, long rate)
164{
165 u32 ticks_per_ms;
166 u32 rfr, l;
167 u32 actim_ctrla = 0, actim_ctrlb = 0;
168 u32 rfr_ctrl;
169 int err = 0;
170 long l3_rate = rate / 1000;
171
172 SDRC_SET_ONE_PS(&actim_ctrla, 0, 4, tDAL, l3_rate);
173 SDRC_SET_ONE_PS(&actim_ctrla, 6, 8, tDPL, l3_rate);
174 SDRC_SET_ONE_PS(&actim_ctrla, 9, 11, tRRD, l3_rate);
175 SDRC_SET_ONE_PS(&actim_ctrla, 12, 14, tRCD, l3_rate);
176 SDRC_SET_ONE_PS(&actim_ctrla, 15, 17, tRP, l3_rate);
177 SDRC_SET_ONE_PS(&actim_ctrla, 18, 21, tRAS, l3_rate);
178 SDRC_SET_ONE_PS(&actim_ctrla, 22, 26, tRC, l3_rate);
179 SDRC_SET_ONE_PS(&actim_ctrla, 27, 31, tRFC, l3_rate);
180
181 SDRC_SET_ONE_PS(&actim_ctrlb, 0, 7, tXSR, l3_rate);
182
183 SDRC_SET_ONE(&actim_ctrlb, 8, 10, tXP, l3_rate);
184 SDRC_SET_ONE(&actim_ctrlb, 12, 14, tCKE, l3_rate);
185 SDRC_SET_ONE(&actim_ctrlb, 16, 17, tWTR, l3_rate);
186
187 ticks_per_ms = l3_rate;
Aaro Koskinen6c3bc4e2010-12-17 15:13:44 -0800188 rfr = memory_timings[0].tREF * ticks_per_ms / 1000000;
Tero Kristo20006552009-11-22 10:11:36 -0800189 if (rfr > 65535 + 50)
190 rfr = 65535;
191 else
192 rfr -= 50;
193
194#ifdef DEBUG
195 printk(KERN_INFO "SDRC tREF: %i ticks\n", rfr);
196#endif
197
198 l = rfr << 8;
199 rfr_ctrl = l | 0x1; /* autorefresh, reload counter with 1xARCV */
200
Aaro Koskinen6c3bc4e2010-12-17 15:13:44 -0800201 nokia_sdrc_params[id].rate = rate;
202 nokia_sdrc_params[id].actim_ctrla = actim_ctrla;
203 nokia_sdrc_params[id].actim_ctrlb = actim_ctrlb;
204 nokia_sdrc_params[id].rfr_ctrl = rfr_ctrl;
205 nokia_sdrc_params[id].mr = 0x32;
Tero Kristo20006552009-11-22 10:11:36 -0800206
Aaro Koskinen6c3bc4e2010-12-17 15:13:44 -0800207 nokia_sdrc_params[id + 1].rate = 0;
Tero Kristo20006552009-11-22 10:11:36 -0800208
209 return err;
210}
211
Aaro Koskinen6c3bc4e2010-12-17 15:13:44 -0800212struct omap_sdrc_params *nokia_get_sdram_timings(void)
Tero Kristo20006552009-11-22 10:11:36 -0800213{
214 int err;
215
216 err = sdrc_timings(0, 41500000);
217 err |= sdrc_timings(1, 83000000);
218 err |= sdrc_timings(2, 166000000);
219
Aaro Koskinen6c3bc4e2010-12-17 15:13:44 -0800220 return &nokia_sdrc_params[0];
Tero Kristo20006552009-11-22 10:11:36 -0800221}
222