2 * SDRC register values for the Samsung K4X1G323PC
4 * Copyright (C) 2008 Nokia Corporation
6 * Lauri Leukkunen <lauri.leukkunen@nokia.com>
8 * Original code by Juha Yrjölä <juha.yrjola@solidboot.com>
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.
15 #include <linux/kernel.h>
16 #include <linux/clk.h>
17 #include <linux/err.h>
21 #include <plat/common.h>
22 #include <plat/clock.h>
23 #include <plat/sdrc.h>
26 /* In picoseconds, except for tREF */
27 struct sdram_timings
{
47 struct omap_sdrc_params rx51_sdrc_params
[2];
49 static const struct sdram_timings rx51_timings
[] = {
52 .tDAL
= 15000 + 18000,
66 static const struct sdram_info rx51_info
= {
70 #define CM_BASE 0x48004000
72 #define CM_CLKSEL_CORE 0x0a40
73 #define CM_CLKSEL1_PLL 0x0d40
75 #define PRM_CLKSEL 0x48306d40
76 #define PRM_CLKSRC_CTRL 0x48307270
78 static u32 cm_base
= CM_BASE
;
80 static inline u32
cm_read_reg(int idx
)
82 return *(u32
*)OMAP2_L4_IO_ADDRESS(cm_base
+ idx
);
85 static const unsigned long sys_clk_rate_table
[] = {
86 12000, 13000, 19200, 26000, 38400, 16800
89 static unsigned long get_sys_clk_rate(void)
93 rate
= sys_clk_rate_table
[*(u32
*)OMAP2_L4_IO_ADDRESS(PRM_CLKSEL
) & 0x07];
94 if (((*(u32
*)OMAP2_L4_IO_ADDRESS(PRM_CLKSRC_CTRL
) >> 6) & 0x03) == 0x02)
99 static unsigned long get_core_rate(void)
104 l
= cm_read_reg(CM_CLKSEL1_PLL
);
105 rate
= get_sys_clk_rate();
106 rate
*= ((l
>> 16) & 0x7ff);
107 rate
/= ((l
>> 8) & 0x7f) + 1;
108 rate
/= (l
>> 27) & 0x1f;
113 static unsigned long get_l3_rate(void)
117 l
= cm_read_reg(CM_CLKSEL_CORE
);
118 return get_core_rate() / (l
& 0x03);
123 static unsigned long sdrc_get_fclk_period(void)
126 return 1000000000 / get_l3_rate();
129 static unsigned int sdrc_ps_to_ticks(unsigned int time_ps
)
131 unsigned long tick_ps
;
133 /* Calculate in picosecs to yield more exact results */
134 tick_ps
= sdrc_get_fclk_period();
136 return (time_ps
+ tick_ps
- 1) / tick_ps
;
140 static int set_sdrc_timing_regval(u32
*regval
, int st_bit
, int end_bit
,
141 int time
, const char *name
)
143 static int set_sdrc_timing_regval(u32
*regval
, int st_bit
, int end_bit
,
147 int ticks
, mask
, nr_bits
;
152 ticks
= sdrc_ps_to_ticks(time
);
153 nr_bits
= end_bit
- st_bit
+ 1;
154 if (ticks
>= 1 << nr_bits
)
156 mask
= (1 << nr_bits
) - 1;
157 *regval
&= ~(mask
<< st_bit
);
158 *regval
|= ticks
<< st_bit
;
160 printk("SDRC %s: %i ticks %i ns\n", name
, ticks
,
161 (unsigned int)sdrc_get_fclk_period() * ticks
/ 1000);
168 #define SDRC_SET_ONE(reg, st, end, field) \
169 if (set_sdrc_timing_regval((reg), (st), (end), rx51_timings->field, #field) < 0) \
172 #define SDRC_SET_ONE(reg, st, end, field) \
173 if (set_sdrc_timing_regval((reg), (st), (end), rx51_timings->field) < 0) \
177 struct omap_sdrc_params
*rx51_get_sdram_timings(void)
181 u32 actim_ctrla
, actim_ctrlb
;
185 SDRC_SET_ONE(&actim_ctrla
, 0, 4, tDAL
);
186 SDRC_SET_ONE(&actim_ctrla
, 6, 8, tDPL
);
187 SDRC_SET_ONE(&actim_ctrla
, 9, 11, tRRD
);
188 SDRC_SET_ONE(&actim_ctrla
, 12, 14, tRCD
);
189 SDRC_SET_ONE(&actim_ctrla
, 15, 17, tRP
);
190 SDRC_SET_ONE(&actim_ctrla
, 18, 21, tRAS
);
191 SDRC_SET_ONE(&actim_ctrla
, 22, 26, tRC
);
192 SDRC_SET_ONE(&actim_ctrla
, 27, 31, tRFC
);
194 SDRC_SET_ONE(&actim_ctrlb
, 0, 7, tXSR
);
196 ticks_per_ms
= sdrc_ps_to_ticks(1000000000);
197 rfr
= rx51_timings
[0].tREF
* ticks_per_ms
/ (1 << rx51_info
.row_lines
);
198 if (rfr
> 65535 + 50)
204 rfr_ctrl
= l
| 0x3; /* autorefresh, reload counter with 8xARCV */
206 rx51_sdrc_params
[0].rate
= 133333333;
207 rx51_sdrc_params
[0].actim_ctrla
= actim_ctrla
;
208 rx51_sdrc_params
[0].actim_ctrlb
= actim_ctrlb
;
209 rx51_sdrc_params
[0].rfr_ctrl
= rfr_ctrl
;
210 rx51_sdrc_params
[0].mr
= 0x32;
212 rx51_sdrc_params
[1].rate
= 0;
217 return &rx51_sdrc_params
[0];