12000655ee7b44ef2816d565c62ae03de74333204Tero Kristo/* 26c3bc4eb5608665b7330b3d2044fca976cbd1a50Aaro Koskinen * SDRC register values for Nokia boards 32000655ee7b44ef2816d565c62ae03de74333204Tero Kristo * 4ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev * Copyright (C) 2008, 2010-2011 Nokia Corporation 52000655ee7b44ef2816d565c62ae03de74333204Tero Kristo * 62000655ee7b44ef2816d565c62ae03de74333204Tero Kristo * Lauri Leukkunen <lauri.leukkunen@nokia.com> 72000655ee7b44ef2816d565c62ae03de74333204Tero Kristo * 82000655ee7b44ef2816d565c62ae03de74333204Tero Kristo * Original code by Juha Yrjola <juha.yrjola@solidboot.com> 92000655ee7b44ef2816d565c62ae03de74333204Tero Kristo * 102000655ee7b44ef2816d565c62ae03de74333204Tero Kristo * This program is free software; you can redistribute it and/or modify 112000655ee7b44ef2816d565c62ae03de74333204Tero Kristo * it under the terms of the GNU General Public License version 2 as 122000655ee7b44ef2816d565c62ae03de74333204Tero Kristo * published by the Free Software Foundation. 132000655ee7b44ef2816d565c62ae03de74333204Tero Kristo */ 142000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 152000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#include <linux/kernel.h> 162000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#include <linux/clk.h> 172000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#include <linux/err.h> 182000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#include <linux/io.h> 192000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 204e65331c6bb4a777bd61a4dac0daa9fc47777b63Tony Lindgren#include "common.h" 21fcd8d84633902fd1717d80f36a38b8a4305ca3d4Aaro Koskinen#include "sdram-nokia.h" 223e6ece13d966a20a38ee7adfac452a47455ccd7aPaul Walmsley#include "sdrc.h" 232000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 242000655ee7b44ef2816d565c62ae03de74333204Tero Kristo/* In picoseconds, except for tREF (ns), tXP, tCKE, tWTR (clks) */ 252000655ee7b44ef2816d565c62ae03de74333204Tero Kristostruct sdram_timings { 262000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 casl; 272000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 tDAL; 282000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 tDPL; 292000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 tRRD; 302000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 tRCD; 312000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 tRP; 322000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 tRAS; 332000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 tRC; 342000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 tRFC; 352000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 tXSR; 362000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 372000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 tREF; /* in ns */ 382000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 392000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 tXP; 402000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 tCKE; 412000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 tWTR; 422000655ee7b44ef2816d565c62ae03de74333204Tero Kristo}; 432000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 4420dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinenstatic const struct sdram_timings nokia_97dot6mhz_timings[] = { 4520dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen { 4620dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .casl = 3, 4720dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tDAL = 30725, 4820dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tDPL = 15362, 4920dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tRRD = 10241, 5020dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tRCD = 20483, 5120dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tRP = 15362, 5220dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tRAS = 40967, 5320dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tRC = 56330, 5420dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tRFC = 138266, 5520dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tXSR = 204839, 5620dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen 5720dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tREF = 7798, 5820dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen 5920dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tXP = 2, 6020dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tCKE = 4, 6120dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tWTR = 2, 6220dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen }, 6320dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen}; 6420dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen 65fbd208e9772005c193459d1a0575c0787ad52f69Aaro Koskinenstatic const struct sdram_timings nokia_166mhz_timings[] = { 662000655ee7b44ef2816d565c62ae03de74333204Tero Kristo { 672000655ee7b44ef2816d565c62ae03de74333204Tero Kristo .casl = 3, 682000655ee7b44ef2816d565c62ae03de74333204Tero Kristo .tDAL = 33000, 692000655ee7b44ef2816d565c62ae03de74333204Tero Kristo .tDPL = 15000, 702000655ee7b44ef2816d565c62ae03de74333204Tero Kristo .tRRD = 12000, 712000655ee7b44ef2816d565c62ae03de74333204Tero Kristo .tRCD = 22500, 722000655ee7b44ef2816d565c62ae03de74333204Tero Kristo .tRP = 18000, 732000655ee7b44ef2816d565c62ae03de74333204Tero Kristo .tRAS = 42000, 742000655ee7b44ef2816d565c62ae03de74333204Tero Kristo .tRC = 66000, 752000655ee7b44ef2816d565c62ae03de74333204Tero Kristo .tRFC = 138000, 762000655ee7b44ef2816d565c62ae03de74333204Tero Kristo .tXSR = 200000, 772000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 782000655ee7b44ef2816d565c62ae03de74333204Tero Kristo .tREF = 7800, 792000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 802000655ee7b44ef2816d565c62ae03de74333204Tero Kristo .tXP = 2, 812000655ee7b44ef2816d565c62ae03de74333204Tero Kristo .tCKE = 2, 822000655ee7b44ef2816d565c62ae03de74333204Tero Kristo .tWTR = 2 832000655ee7b44ef2816d565c62ae03de74333204Tero Kristo }, 842000655ee7b44ef2816d565c62ae03de74333204Tero Kristo}; 852000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 8620dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinenstatic const struct sdram_timings nokia_195dot2mhz_timings[] = { 8720dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen { 8820dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .casl = 3, 8920dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tDAL = 30725, 9020dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tDPL = 15362, 9120dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tRRD = 10241, 9220dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tRCD = 20483, 9320dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tRP = 15362, 9420dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tRAS = 40967, 9520dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tRC = 56330, 9620dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tRFC = 138266, 9720dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tXSR = 204839, 9820dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen 9920dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tREF = 7752, 10020dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen 10120dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tXP = 2, 10220dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tCKE = 4, 10320dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen .tWTR = 2, 10420dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen }, 10520dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen}; 10620dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen 107ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitrievstatic const struct sdram_timings nokia_200mhz_timings[] = { 108ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev { 109ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev .casl = 3, 110ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev .tDAL = 30000, 111ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev .tDPL = 15000, 112ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev .tRRD = 10000, 113ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev .tRCD = 20000, 114ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev .tRP = 15000, 115ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev .tRAS = 40000, 116ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev .tRC = 55000, 117ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev .tRFC = 140000, 118ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev .tXSR = 200000, 119ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev 120ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev .tREF = 7800, 121ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev 122ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev .tXP = 2, 123ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev .tCKE = 4, 124ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev .tWTR = 2 125ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev }, 126ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev}; 127ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev 128e5f5b5422d064b7a393e39332da31af68e975f91Aaro Koskinenstatic const struct { 129e5f5b5422d064b7a393e39332da31af68e975f91Aaro Koskinen long rate; 130e5f5b5422d064b7a393e39332da31af68e975f91Aaro Koskinen struct sdram_timings const *data; 131e5f5b5422d064b7a393e39332da31af68e975f91Aaro Koskinen} nokia_timings[] = { 132e5f5b5422d064b7a393e39332da31af68e975f91Aaro Koskinen { 83000000, nokia_166mhz_timings }, 13320dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen { 97600000, nokia_97dot6mhz_timings }, 134ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev { 100000000, nokia_200mhz_timings }, 135e5f5b5422d064b7a393e39332da31af68e975f91Aaro Koskinen { 166000000, nokia_166mhz_timings }, 13620dbeb1081327aefaac7044d9908c97bf445858cAaro Koskinen { 195200000, nokia_195dot2mhz_timings }, 137ef211dc626beb47fc11d4aba27a8c1b20a4b3b4aIgor Dmitriev { 200000000, nokia_200mhz_timings }, 138e5f5b5422d064b7a393e39332da31af68e975f91Aaro Koskinen}; 139e5f5b5422d064b7a393e39332da31af68e975f91Aaro Koskinenstatic struct omap_sdrc_params nokia_sdrc_params[ARRAY_SIZE(nokia_timings) + 1]; 140e5f5b5422d064b7a393e39332da31af68e975f91Aaro Koskinen 1412000655ee7b44ef2816d565c62ae03de74333204Tero Kristostatic unsigned long sdrc_get_fclk_period(long rate) 1422000655ee7b44ef2816d565c62ae03de74333204Tero Kristo{ 1432000655ee7b44ef2816d565c62ae03de74333204Tero Kristo /* In picoseconds */ 1442000655ee7b44ef2816d565c62ae03de74333204Tero Kristo return 1000000000 / rate; 1452000655ee7b44ef2816d565c62ae03de74333204Tero Kristo} 1462000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 1472000655ee7b44ef2816d565c62ae03de74333204Tero Kristostatic unsigned int sdrc_ps_to_ticks(unsigned int time_ps, long rate) 1482000655ee7b44ef2816d565c62ae03de74333204Tero Kristo{ 1492000655ee7b44ef2816d565c62ae03de74333204Tero Kristo unsigned long tick_ps; 1502000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 1512000655ee7b44ef2816d565c62ae03de74333204Tero Kristo /* Calculate in picosecs to yield more exact results */ 1522000655ee7b44ef2816d565c62ae03de74333204Tero Kristo tick_ps = sdrc_get_fclk_period(rate); 1532000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 1542000655ee7b44ef2816d565c62ae03de74333204Tero Kristo return (time_ps + tick_ps - 1) / tick_ps; 1552000655ee7b44ef2816d565c62ae03de74333204Tero Kristo} 1562000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#undef DEBUG 1572000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#ifdef DEBUG 1582000655ee7b44ef2816d565c62ae03de74333204Tero Kristostatic int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit, 1592000655ee7b44ef2816d565c62ae03de74333204Tero Kristo int ticks, long rate, const char *name) 1602000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#else 1612000655ee7b44ef2816d565c62ae03de74333204Tero Kristostatic int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit, 1622000655ee7b44ef2816d565c62ae03de74333204Tero Kristo int ticks) 1632000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#endif 1642000655ee7b44ef2816d565c62ae03de74333204Tero Kristo{ 1652000655ee7b44ef2816d565c62ae03de74333204Tero Kristo int mask, nr_bits; 1662000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 1672000655ee7b44ef2816d565c62ae03de74333204Tero Kristo nr_bits = end_bit - st_bit + 1; 1682000655ee7b44ef2816d565c62ae03de74333204Tero Kristo if (ticks >= 1 << nr_bits) 1692000655ee7b44ef2816d565c62ae03de74333204Tero Kristo return -1; 1702000655ee7b44ef2816d565c62ae03de74333204Tero Kristo mask = (1 << nr_bits) - 1; 1712000655ee7b44ef2816d565c62ae03de74333204Tero Kristo *regval &= ~(mask << st_bit); 1722000655ee7b44ef2816d565c62ae03de74333204Tero Kristo *regval |= ticks << st_bit; 1732000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#ifdef DEBUG 1742000655ee7b44ef2816d565c62ae03de74333204Tero Kristo printk(KERN_INFO "SDRC %s: %i ticks %i ns\n", name, ticks, 1752000655ee7b44ef2816d565c62ae03de74333204Tero Kristo (unsigned int)sdrc_get_fclk_period(rate) * ticks / 1762000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 1000); 1772000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#endif 1782000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 1792000655ee7b44ef2816d565c62ae03de74333204Tero Kristo return 0; 1802000655ee7b44ef2816d565c62ae03de74333204Tero Kristo} 1812000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 1822000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#ifdef DEBUG 1832000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#define SDRC_SET_ONE(reg, st, end, field, rate) \ 1842000655ee7b44ef2816d565c62ae03de74333204Tero Kristo if (set_sdrc_timing_regval((reg), (st), (end), \ 1856c3bc4eb5608665b7330b3d2044fca976cbd1a50Aaro Koskinen memory_timings->field, (rate), #field) < 0) \ 1862000655ee7b44ef2816d565c62ae03de74333204Tero Kristo err = -1; 1872000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#else 1882000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#define SDRC_SET_ONE(reg, st, end, field, rate) \ 1892000655ee7b44ef2816d565c62ae03de74333204Tero Kristo if (set_sdrc_timing_regval((reg), (st), (end), \ 1906c3bc4eb5608665b7330b3d2044fca976cbd1a50Aaro Koskinen memory_timings->field) < 0) \ 1912000655ee7b44ef2816d565c62ae03de74333204Tero Kristo err = -1; 1922000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#endif 1932000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 1942000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#ifdef DEBUG 1952000655ee7b44ef2816d565c62ae03de74333204Tero Kristostatic int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit, 1962000655ee7b44ef2816d565c62ae03de74333204Tero Kristo int time, long rate, const char *name) 1972000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#else 1982000655ee7b44ef2816d565c62ae03de74333204Tero Kristostatic int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit, 1992000655ee7b44ef2816d565c62ae03de74333204Tero Kristo int time, long rate) 2002000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#endif 2012000655ee7b44ef2816d565c62ae03de74333204Tero Kristo{ 2022000655ee7b44ef2816d565c62ae03de74333204Tero Kristo int ticks, ret; 2032000655ee7b44ef2816d565c62ae03de74333204Tero Kristo ret = 0; 2042000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2052000655ee7b44ef2816d565c62ae03de74333204Tero Kristo if (time == 0) 2062000655ee7b44ef2816d565c62ae03de74333204Tero Kristo ticks = 0; 2072000655ee7b44ef2816d565c62ae03de74333204Tero Kristo else 2082000655ee7b44ef2816d565c62ae03de74333204Tero Kristo ticks = sdrc_ps_to_ticks(time, rate); 2092000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2102000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#ifdef DEBUG 2112000655ee7b44ef2816d565c62ae03de74333204Tero Kristo ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks, 2122000655ee7b44ef2816d565c62ae03de74333204Tero Kristo rate, name); 2132000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#else 2142000655ee7b44ef2816d565c62ae03de74333204Tero Kristo ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks); 2152000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#endif 2162000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2172000655ee7b44ef2816d565c62ae03de74333204Tero Kristo return ret; 2182000655ee7b44ef2816d565c62ae03de74333204Tero Kristo} 2192000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2202000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#ifdef DEBUG 2212000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \ 2222000655ee7b44ef2816d565c62ae03de74333204Tero Kristo if (set_sdrc_timing_regval_ps((reg), (st), (end), \ 2236c3bc4eb5608665b7330b3d2044fca976cbd1a50Aaro Koskinen memory_timings->field, \ 2242000655ee7b44ef2816d565c62ae03de74333204Tero Kristo (rate), #field) < 0) \ 2252000655ee7b44ef2816d565c62ae03de74333204Tero Kristo err = -1; 2262000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2272000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#else 2282000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \ 2292000655ee7b44ef2816d565c62ae03de74333204Tero Kristo if (set_sdrc_timing_regval_ps((reg), (st), (end), \ 2306c3bc4eb5608665b7330b3d2044fca976cbd1a50Aaro Koskinen memory_timings->field, (rate)) < 0) \ 2312000655ee7b44ef2816d565c62ae03de74333204Tero Kristo err = -1; 2322000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#endif 2332000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 234fbd208e9772005c193459d1a0575c0787ad52f69Aaro Koskinenstatic int sdrc_timings(int id, long rate, 235fbd208e9772005c193459d1a0575c0787ad52f69Aaro Koskinen const struct sdram_timings *memory_timings) 2362000655ee7b44ef2816d565c62ae03de74333204Tero Kristo{ 2372000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 ticks_per_ms; 2382000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 rfr, l; 2392000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 actim_ctrla = 0, actim_ctrlb = 0; 2402000655ee7b44ef2816d565c62ae03de74333204Tero Kristo u32 rfr_ctrl; 2412000655ee7b44ef2816d565c62ae03de74333204Tero Kristo int err = 0; 2422000655ee7b44ef2816d565c62ae03de74333204Tero Kristo long l3_rate = rate / 1000; 2432000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2442000655ee7b44ef2816d565c62ae03de74333204Tero Kristo SDRC_SET_ONE_PS(&actim_ctrla, 0, 4, tDAL, l3_rate); 2452000655ee7b44ef2816d565c62ae03de74333204Tero Kristo SDRC_SET_ONE_PS(&actim_ctrla, 6, 8, tDPL, l3_rate); 2462000655ee7b44ef2816d565c62ae03de74333204Tero Kristo SDRC_SET_ONE_PS(&actim_ctrla, 9, 11, tRRD, l3_rate); 2472000655ee7b44ef2816d565c62ae03de74333204Tero Kristo SDRC_SET_ONE_PS(&actim_ctrla, 12, 14, tRCD, l3_rate); 2482000655ee7b44ef2816d565c62ae03de74333204Tero Kristo SDRC_SET_ONE_PS(&actim_ctrla, 15, 17, tRP, l3_rate); 2492000655ee7b44ef2816d565c62ae03de74333204Tero Kristo SDRC_SET_ONE_PS(&actim_ctrla, 18, 21, tRAS, l3_rate); 2502000655ee7b44ef2816d565c62ae03de74333204Tero Kristo SDRC_SET_ONE_PS(&actim_ctrla, 22, 26, tRC, l3_rate); 2512000655ee7b44ef2816d565c62ae03de74333204Tero Kristo SDRC_SET_ONE_PS(&actim_ctrla, 27, 31, tRFC, l3_rate); 2522000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2532000655ee7b44ef2816d565c62ae03de74333204Tero Kristo SDRC_SET_ONE_PS(&actim_ctrlb, 0, 7, tXSR, l3_rate); 2542000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2552000655ee7b44ef2816d565c62ae03de74333204Tero Kristo SDRC_SET_ONE(&actim_ctrlb, 8, 10, tXP, l3_rate); 2562000655ee7b44ef2816d565c62ae03de74333204Tero Kristo SDRC_SET_ONE(&actim_ctrlb, 12, 14, tCKE, l3_rate); 2572000655ee7b44ef2816d565c62ae03de74333204Tero Kristo SDRC_SET_ONE(&actim_ctrlb, 16, 17, tWTR, l3_rate); 2582000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2592000655ee7b44ef2816d565c62ae03de74333204Tero Kristo ticks_per_ms = l3_rate; 2606c3bc4eb5608665b7330b3d2044fca976cbd1a50Aaro Koskinen rfr = memory_timings[0].tREF * ticks_per_ms / 1000000; 2612000655ee7b44ef2816d565c62ae03de74333204Tero Kristo if (rfr > 65535 + 50) 2622000655ee7b44ef2816d565c62ae03de74333204Tero Kristo rfr = 65535; 2632000655ee7b44ef2816d565c62ae03de74333204Tero Kristo else 2642000655ee7b44ef2816d565c62ae03de74333204Tero Kristo rfr -= 50; 2652000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2662000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#ifdef DEBUG 2672000655ee7b44ef2816d565c62ae03de74333204Tero Kristo printk(KERN_INFO "SDRC tREF: %i ticks\n", rfr); 2682000655ee7b44ef2816d565c62ae03de74333204Tero Kristo#endif 2692000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2702000655ee7b44ef2816d565c62ae03de74333204Tero Kristo l = rfr << 8; 2712000655ee7b44ef2816d565c62ae03de74333204Tero Kristo rfr_ctrl = l | 0x1; /* autorefresh, reload counter with 1xARCV */ 2722000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2736c3bc4eb5608665b7330b3d2044fca976cbd1a50Aaro Koskinen nokia_sdrc_params[id].rate = rate; 2746c3bc4eb5608665b7330b3d2044fca976cbd1a50Aaro Koskinen nokia_sdrc_params[id].actim_ctrla = actim_ctrla; 2756c3bc4eb5608665b7330b3d2044fca976cbd1a50Aaro Koskinen nokia_sdrc_params[id].actim_ctrlb = actim_ctrlb; 2766c3bc4eb5608665b7330b3d2044fca976cbd1a50Aaro Koskinen nokia_sdrc_params[id].rfr_ctrl = rfr_ctrl; 2776c3bc4eb5608665b7330b3d2044fca976cbd1a50Aaro Koskinen nokia_sdrc_params[id].mr = 0x32; 2782000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2796c3bc4eb5608665b7330b3d2044fca976cbd1a50Aaro Koskinen nokia_sdrc_params[id + 1].rate = 0; 2802000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2812000655ee7b44ef2816d565c62ae03de74333204Tero Kristo return err; 2822000655ee7b44ef2816d565c62ae03de74333204Tero Kristo} 2832000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2846c3bc4eb5608665b7330b3d2044fca976cbd1a50Aaro Koskinenstruct omap_sdrc_params *nokia_get_sdram_timings(void) 2852000655ee7b44ef2816d565c62ae03de74333204Tero Kristo{ 286e5f5b5422d064b7a393e39332da31af68e975f91Aaro Koskinen int err = 0; 287e5f5b5422d064b7a393e39332da31af68e975f91Aaro Koskinen int i; 2882000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2892b1af87ace4776f0d0c3513923a79529fc1b5a00Aaro Koskinen for (i = 0; i < ARRAY_SIZE(nokia_timings); i++) { 290e5f5b5422d064b7a393e39332da31af68e975f91Aaro Koskinen err |= sdrc_timings(i, nokia_timings[i].rate, 291e5f5b5422d064b7a393e39332da31af68e975f91Aaro Koskinen nokia_timings[i].data); 2922b1af87ace4776f0d0c3513923a79529fc1b5a00Aaro Koskinen if (err) 2932b1af87ace4776f0d0c3513923a79529fc1b5a00Aaro Koskinen pr_err("%s: error with rate %ld: %d\n", __func__, 2942b1af87ace4776f0d0c3513923a79529fc1b5a00Aaro Koskinen nokia_timings[i].rate, err); 2952b1af87ace4776f0d0c3513923a79529fc1b5a00Aaro Koskinen } 2962000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 2972b1af87ace4776f0d0c3513923a79529fc1b5a00Aaro Koskinen return err ? NULL : nokia_sdrc_params; 2982000655ee7b44ef2816d565c62ae03de74333204Tero Kristo} 2992000655ee7b44ef2816d565c62ae03de74333204Tero Kristo 300