1/* 2 * SDRC register values for Nokia boards 3 * 4 * Copyright (C) 2008, 2010-2011 Nokia Corporation 5 * 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 "common.h" 21#include "sdram-nokia.h" 22#include "sdrc.h" 23 24/* In picoseconds, except for tREF (ns), tXP, tCKE, tWTR (clks) */ 25struct sdram_timings { 26 u32 casl; 27 u32 tDAL; 28 u32 tDPL; 29 u32 tRRD; 30 u32 tRCD; 31 u32 tRP; 32 u32 tRAS; 33 u32 tRC; 34 u32 tRFC; 35 u32 tXSR; 36 37 u32 tREF; /* in ns */ 38 39 u32 tXP; 40 u32 tCKE; 41 u32 tWTR; 42}; 43 44static const struct sdram_timings nokia_97dot6mhz_timings[] = { 45 { 46 .casl = 3, 47 .tDAL = 30725, 48 .tDPL = 15362, 49 .tRRD = 10241, 50 .tRCD = 20483, 51 .tRP = 15362, 52 .tRAS = 40967, 53 .tRC = 56330, 54 .tRFC = 138266, 55 .tXSR = 204839, 56 57 .tREF = 7798, 58 59 .tXP = 2, 60 .tCKE = 4, 61 .tWTR = 2, 62 }, 63}; 64 65static const struct sdram_timings nokia_166mhz_timings[] = { 66 { 67 .casl = 3, 68 .tDAL = 33000, 69 .tDPL = 15000, 70 .tRRD = 12000, 71 .tRCD = 22500, 72 .tRP = 18000, 73 .tRAS = 42000, 74 .tRC = 66000, 75 .tRFC = 138000, 76 .tXSR = 200000, 77 78 .tREF = 7800, 79 80 .tXP = 2, 81 .tCKE = 2, 82 .tWTR = 2 83 }, 84}; 85 86static const struct sdram_timings nokia_195dot2mhz_timings[] = { 87 { 88 .casl = 3, 89 .tDAL = 30725, 90 .tDPL = 15362, 91 .tRRD = 10241, 92 .tRCD = 20483, 93 .tRP = 15362, 94 .tRAS = 40967, 95 .tRC = 56330, 96 .tRFC = 138266, 97 .tXSR = 204839, 98 99 .tREF = 7752, 100 101 .tXP = 2, 102 .tCKE = 4, 103 .tWTR = 2, 104 }, 105}; 106 107static const struct sdram_timings nokia_200mhz_timings[] = { 108 { 109 .casl = 3, 110 .tDAL = 30000, 111 .tDPL = 15000, 112 .tRRD = 10000, 113 .tRCD = 20000, 114 .tRP = 15000, 115 .tRAS = 40000, 116 .tRC = 55000, 117 .tRFC = 140000, 118 .tXSR = 200000, 119 120 .tREF = 7800, 121 122 .tXP = 2, 123 .tCKE = 4, 124 .tWTR = 2 125 }, 126}; 127 128static const struct { 129 long rate; 130 struct sdram_timings const *data; 131} nokia_timings[] = { 132 { 83000000, nokia_166mhz_timings }, 133 { 97600000, nokia_97dot6mhz_timings }, 134 { 100000000, nokia_200mhz_timings }, 135 { 166000000, nokia_166mhz_timings }, 136 { 195200000, nokia_195dot2mhz_timings }, 137 { 200000000, nokia_200mhz_timings }, 138}; 139static struct omap_sdrc_params nokia_sdrc_params[ARRAY_SIZE(nokia_timings) + 1]; 140 141static unsigned long sdrc_get_fclk_period(long rate) 142{ 143 /* In picoseconds */ 144 return 1000000000 / rate; 145} 146 147static unsigned int sdrc_ps_to_ticks(unsigned int time_ps, long rate) 148{ 149 unsigned long tick_ps; 150 151 /* Calculate in picosecs to yield more exact results */ 152 tick_ps = sdrc_get_fclk_period(rate); 153 154 return (time_ps + tick_ps - 1) / tick_ps; 155} 156#undef DEBUG 157#ifdef DEBUG 158static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit, 159 int ticks, long rate, const char *name) 160#else 161static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit, 162 int ticks) 163#endif 164{ 165 int mask, nr_bits; 166 167 nr_bits = end_bit - st_bit + 1; 168 if (ticks >= 1 << nr_bits) 169 return -1; 170 mask = (1 << nr_bits) - 1; 171 *regval &= ~(mask << st_bit); 172 *regval |= ticks << st_bit; 173#ifdef DEBUG 174 printk(KERN_INFO "SDRC %s: %i ticks %i ns\n", name, ticks, 175 (unsigned int)sdrc_get_fclk_period(rate) * ticks / 176 1000); 177#endif 178 179 return 0; 180} 181 182#ifdef DEBUG 183#define SDRC_SET_ONE(reg, st, end, field, rate) \ 184 if (set_sdrc_timing_regval((reg), (st), (end), \ 185 memory_timings->field, (rate), #field) < 0) \ 186 err = -1; 187#else 188#define SDRC_SET_ONE(reg, st, end, field, rate) \ 189 if (set_sdrc_timing_regval((reg), (st), (end), \ 190 memory_timings->field) < 0) \ 191 err = -1; 192#endif 193 194#ifdef DEBUG 195static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit, 196 int time, long rate, const char *name) 197#else 198static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit, 199 int time, long rate) 200#endif 201{ 202 int ticks, ret; 203 ret = 0; 204 205 if (time == 0) 206 ticks = 0; 207 else 208 ticks = sdrc_ps_to_ticks(time, rate); 209 210#ifdef DEBUG 211 ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks, 212 rate, name); 213#else 214 ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks); 215#endif 216 217 return ret; 218} 219 220#ifdef DEBUG 221#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \ 222 if (set_sdrc_timing_regval_ps((reg), (st), (end), \ 223 memory_timings->field, \ 224 (rate), #field) < 0) \ 225 err = -1; 226 227#else 228#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \ 229 if (set_sdrc_timing_regval_ps((reg), (st), (end), \ 230 memory_timings->field, (rate)) < 0) \ 231 err = -1; 232#endif 233 234static int sdrc_timings(int id, long rate, 235 const struct sdram_timings *memory_timings) 236{ 237 u32 ticks_per_ms; 238 u32 rfr, l; 239 u32 actim_ctrla = 0, actim_ctrlb = 0; 240 u32 rfr_ctrl; 241 int err = 0; 242 long l3_rate = rate / 1000; 243 244 SDRC_SET_ONE_PS(&actim_ctrla, 0, 4, tDAL, l3_rate); 245 SDRC_SET_ONE_PS(&actim_ctrla, 6, 8, tDPL, l3_rate); 246 SDRC_SET_ONE_PS(&actim_ctrla, 9, 11, tRRD, l3_rate); 247 SDRC_SET_ONE_PS(&actim_ctrla, 12, 14, tRCD, l3_rate); 248 SDRC_SET_ONE_PS(&actim_ctrla, 15, 17, tRP, l3_rate); 249 SDRC_SET_ONE_PS(&actim_ctrla, 18, 21, tRAS, l3_rate); 250 SDRC_SET_ONE_PS(&actim_ctrla, 22, 26, tRC, l3_rate); 251 SDRC_SET_ONE_PS(&actim_ctrla, 27, 31, tRFC, l3_rate); 252 253 SDRC_SET_ONE_PS(&actim_ctrlb, 0, 7, tXSR, l3_rate); 254 255 SDRC_SET_ONE(&actim_ctrlb, 8, 10, tXP, l3_rate); 256 SDRC_SET_ONE(&actim_ctrlb, 12, 14, tCKE, l3_rate); 257 SDRC_SET_ONE(&actim_ctrlb, 16, 17, tWTR, l3_rate); 258 259 ticks_per_ms = l3_rate; 260 rfr = memory_timings[0].tREF * ticks_per_ms / 1000000; 261 if (rfr > 65535 + 50) 262 rfr = 65535; 263 else 264 rfr -= 50; 265 266#ifdef DEBUG 267 printk(KERN_INFO "SDRC tREF: %i ticks\n", rfr); 268#endif 269 270 l = rfr << 8; 271 rfr_ctrl = l | 0x1; /* autorefresh, reload counter with 1xARCV */ 272 273 nokia_sdrc_params[id].rate = rate; 274 nokia_sdrc_params[id].actim_ctrla = actim_ctrla; 275 nokia_sdrc_params[id].actim_ctrlb = actim_ctrlb; 276 nokia_sdrc_params[id].rfr_ctrl = rfr_ctrl; 277 nokia_sdrc_params[id].mr = 0x32; 278 279 nokia_sdrc_params[id + 1].rate = 0; 280 281 return err; 282} 283 284struct omap_sdrc_params *nokia_get_sdram_timings(void) 285{ 286 int err = 0; 287 int i; 288 289 for (i = 0; i < ARRAY_SIZE(nokia_timings); i++) { 290 err |= sdrc_timings(i, nokia_timings[i].rate, 291 nokia_timings[i].data); 292 if (err) 293 pr_err("%s: error with rate %ld: %d\n", __func__, 294 nokia_timings[i].rate, err); 295 } 296 297 return err ? NULL : nokia_sdrc_params; 298} 299 300