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