1/* 2 * SDRC register values for RX51 3 * 4 * Copyright (C) 2008 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 <plat/io.h> 21#include <plat/common.h> 22#include <plat/clock.h> 23#include <plat/sdrc.h> 24 25 26/* In picoseconds, except for tREF (ns), tXP, tCKE, tWTR (clks) */ 27struct sdram_timings { 28 u32 casl; 29 u32 tDAL; 30 u32 tDPL; 31 u32 tRRD; 32 u32 tRCD; 33 u32 tRP; 34 u32 tRAS; 35 u32 tRC; 36 u32 tRFC; 37 u32 tXSR; 38 39 u32 tREF; /* in ns */ 40 41 u32 tXP; 42 u32 tCKE; 43 u32 tWTR; 44}; 45 46struct omap_sdrc_params rx51_sdrc_params[4]; 47 48static const struct sdram_timings rx51_timings[] = { 49 { 50 .casl = 3, 51 .tDAL = 33000, 52 .tDPL = 15000, 53 .tRRD = 12000, 54 .tRCD = 22500, 55 .tRP = 18000, 56 .tRAS = 42000, 57 .tRC = 66000, 58 .tRFC = 138000, 59 .tXSR = 200000, 60 61 .tREF = 7800, 62 63 .tXP = 2, 64 .tCKE = 2, 65 .tWTR = 2 66 }, 67}; 68 69static unsigned long sdrc_get_fclk_period(long rate) 70{ 71 /* In picoseconds */ 72 return 1000000000 / rate; 73} 74 75static unsigned int sdrc_ps_to_ticks(unsigned int time_ps, long rate) 76{ 77 unsigned long tick_ps; 78 79 /* Calculate in picosecs to yield more exact results */ 80 tick_ps = sdrc_get_fclk_period(rate); 81 82 return (time_ps + tick_ps - 1) / tick_ps; 83} 84#undef DEBUG 85#ifdef DEBUG 86static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit, 87 int ticks, long rate, const char *name) 88#else 89static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit, 90 int ticks) 91#endif 92{ 93 int mask, nr_bits; 94 95 nr_bits = end_bit - st_bit + 1; 96 if (ticks >= 1 << nr_bits) 97 return -1; 98 mask = (1 << nr_bits) - 1; 99 *regval &= ~(mask << st_bit); 100 *regval |= ticks << st_bit; 101#ifdef DEBUG 102 printk(KERN_INFO "SDRC %s: %i ticks %i ns\n", name, ticks, 103 (unsigned int)sdrc_get_fclk_period(rate) * ticks / 104 1000); 105#endif 106 107 return 0; 108} 109 110#ifdef DEBUG 111#define SDRC_SET_ONE(reg, st, end, field, rate) \ 112 if (set_sdrc_timing_regval((reg), (st), (end), \ 113 rx51_timings->field, (rate), #field) < 0) \ 114 err = -1; 115#else 116#define SDRC_SET_ONE(reg, st, end, field, rate) \ 117 if (set_sdrc_timing_regval((reg), (st), (end), \ 118 rx51_timings->field) < 0) \ 119 err = -1; 120#endif 121 122#ifdef DEBUG 123static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit, 124 int time, long rate, const char *name) 125#else 126static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit, 127 int time, long rate) 128#endif 129{ 130 int ticks, ret; 131 ret = 0; 132 133 if (time == 0) 134 ticks = 0; 135 else 136 ticks = sdrc_ps_to_ticks(time, rate); 137 138#ifdef DEBUG 139 ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks, 140 rate, name); 141#else 142 ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks); 143#endif 144 145 return ret; 146} 147 148#ifdef DEBUG 149#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \ 150 if (set_sdrc_timing_regval_ps((reg), (st), (end), \ 151 rx51_timings->field, \ 152 (rate), #field) < 0) \ 153 err = -1; 154 155#else 156#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \ 157 if (set_sdrc_timing_regval_ps((reg), (st), (end), \ 158 rx51_timings->field, (rate)) < 0) \ 159 err = -1; 160#endif 161 162static int sdrc_timings(int id, long rate) 163{ 164 u32 ticks_per_ms; 165 u32 rfr, l; 166 u32 actim_ctrla = 0, actim_ctrlb = 0; 167 u32 rfr_ctrl; 168 int err = 0; 169 long l3_rate = rate / 1000; 170 171 SDRC_SET_ONE_PS(&actim_ctrla, 0, 4, tDAL, l3_rate); 172 SDRC_SET_ONE_PS(&actim_ctrla, 6, 8, tDPL, l3_rate); 173 SDRC_SET_ONE_PS(&actim_ctrla, 9, 11, tRRD, l3_rate); 174 SDRC_SET_ONE_PS(&actim_ctrla, 12, 14, tRCD, l3_rate); 175 SDRC_SET_ONE_PS(&actim_ctrla, 15, 17, tRP, l3_rate); 176 SDRC_SET_ONE_PS(&actim_ctrla, 18, 21, tRAS, l3_rate); 177 SDRC_SET_ONE_PS(&actim_ctrla, 22, 26, tRC, l3_rate); 178 SDRC_SET_ONE_PS(&actim_ctrla, 27, 31, tRFC, l3_rate); 179 180 SDRC_SET_ONE_PS(&actim_ctrlb, 0, 7, tXSR, l3_rate); 181 182 SDRC_SET_ONE(&actim_ctrlb, 8, 10, tXP, l3_rate); 183 SDRC_SET_ONE(&actim_ctrlb, 12, 14, tCKE, l3_rate); 184 SDRC_SET_ONE(&actim_ctrlb, 16, 17, tWTR, l3_rate); 185 186 ticks_per_ms = l3_rate; 187 rfr = rx51_timings[0].tREF * ticks_per_ms / 1000000; 188 if (rfr > 65535 + 50) 189 rfr = 65535; 190 else 191 rfr -= 50; 192 193#ifdef DEBUG 194 printk(KERN_INFO "SDRC tREF: %i ticks\n", rfr); 195#endif 196 197 l = rfr << 8; 198 rfr_ctrl = l | 0x1; /* autorefresh, reload counter with 1xARCV */ 199 200 rx51_sdrc_params[id].rate = rate; 201 rx51_sdrc_params[id].actim_ctrla = actim_ctrla; 202 rx51_sdrc_params[id].actim_ctrlb = actim_ctrlb; 203 rx51_sdrc_params[id].rfr_ctrl = rfr_ctrl; 204 rx51_sdrc_params[id].mr = 0x32; 205 206 rx51_sdrc_params[id + 1].rate = 0; 207 208 return err; 209} 210 211struct omap_sdrc_params *rx51_get_sdram_timings(void) 212{ 213 int err; 214 215 err = sdrc_timings(0, 41500000); 216 err |= sdrc_timings(1, 83000000); 217 err |= sdrc_timings(2, 166000000); 218 219 return &rx51_sdrc_params[0]; 220} 221