sdram-nokia.c 6.2 KB

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