2
* Memory setup for SMDK5250 board based on EXYNOS5
4
* Copyright (C) 2012 Samsung Electronics
6
* See file CREDITS for list of people who contributed to this
9
* This program is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU General Public License as
11
* published by the Free Software Foundation; either version 2 of
12
* the License, or (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27
#include <asm/arch/dmc.h>
28
#include <asm/arch/clock.h>
29
#include <asm/arch/cpu.h>
33
/* MCLK_CDREX: MCLK_CDREX_533*/
34
/* LPDDR support: LPDDR2 */
35
static void reset_phy_ctrl(void);
36
static void config_zq(struct exynos5_phy_control *,
37
struct exynos5_phy_control *);
38
static void update_reset_dll(struct exynos5_dmc *);
39
static void config_cdrex(void);
40
static void config_mrs(struct exynos5_dmc *);
41
static void sec_sdram_phy_init(struct exynos5_dmc *);
42
static void config_prech(struct exynos5_dmc *);
43
static void config_rdlvl(struct exynos5_dmc *,
44
struct exynos5_phy_control *,
45
struct exynos5_phy_control *);
46
static void config_memory(struct exynos5_dmc *);
48
static void config_offsets(unsigned int,
49
struct exynos5_phy_control *,
50
struct exynos5_phy_control *);
52
static void reset_phy_ctrl(void)
54
struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
56
writel(PHY_RESET_VAL, &clk->lpddr3phy_ctrl);
60
static void config_zq(struct exynos5_phy_control *phy0_ctrl,
61
struct exynos5_phy_control *phy1_ctrl)
63
unsigned long val = 0;
66
* Select Driver Strength,
67
* long calibration for manual calibration
69
val = PHY_CON16_RESET_VAL;
70
SET_ZQ_MODE_DDS_VAL(val);
71
SET_ZQ_MODE_TERM_VAL(val);
73
writel(val, &phy0_ctrl->phy_con16);
74
writel(val, &phy1_ctrl->phy_con16);
76
/* Disable termination */
77
val |= ZQ_MODE_NOTERM;
78
writel(val, &phy0_ctrl->phy_con16);
79
writel(val, &phy1_ctrl->phy_con16);
81
/* ZQ_MANUAL_START: Enable */
83
writel(val, &phy0_ctrl->phy_con16);
84
writel(val, &phy1_ctrl->phy_con16);
87
/* ZQ_MANUAL_START: Disable */
88
val &= ~ZQ_MANUAL_STR;
89
writel(val, &phy0_ctrl->phy_con16);
90
writel(val, &phy1_ctrl->phy_con16);
93
static void update_reset_dll(struct exynos5_dmc *dmc)
97
* Update DLL Information:
98
* Force DLL Resyncronization
100
val = readl(&dmc->phycontrol0);
102
writel(val, &dmc->phycontrol0);
104
/* Reset Force DLL Resyncronization */
105
val = readl(&dmc->phycontrol0);
107
writel(val, &dmc->phycontrol0);
110
static void config_mrs(struct exynos5_dmc *dmc)
112
unsigned long channel, chip, mask = 0, val;
114
for (channel = 0; channel < CONFIG_DMC_CHANNELS; channel++) {
115
SET_CMD_CHANNEL(mask, channel);
116
for (chip = 0; chip < CONFIG_CHIPS_PER_CHANNEL; chip++) {
119
* Assert and hold CKE to logic high level
121
SET_CMD_CHIP(mask, chip);
122
val = DIRECT_CMD_NOP | mask;
123
writel(val, &dmc->directcmd);
126
/* EMRS, MRS Cmds(Mode Reg Settings) Using Direct Cmd */
127
val = DIRECT_CMD_MRS1 | mask;
128
writel(val, &dmc->directcmd);
131
val = DIRECT_CMD_MRS2 | mask;
132
writel(val, &dmc->directcmd);
136
val = DIRECT_CMD_MRS3 | mask;
137
writel(val, &dmc->directcmd);
140
val = DIRECT_CMD_MRS4 | mask;
141
writel(val, &dmc->directcmd);
147
static void config_prech(struct exynos5_dmc *dmc)
149
unsigned long channel, chip, mask = 0, val;
151
for (channel = 0; channel < CONFIG_DMC_CHANNELS; channel++) {
152
SET_CMD_CHANNEL(mask, channel);
153
for (chip = 0; chip < CONFIG_CHIPS_PER_CHANNEL; chip++) {
154
SET_CMD_CHIP(mask, chip);
155
/* PALL (all banks precharge) CMD */
156
val = DIRECT_CMD_PALL | mask;
157
writel(val, &dmc->directcmd);
163
static void sec_sdram_phy_init(struct exynos5_dmc *dmc)
166
val = readl(&dmc->concontrol);
167
val |= DFI_INIT_START;
168
writel(val, &dmc->concontrol);
171
val = readl(&dmc->concontrol);
172
val &= ~DFI_INIT_START;
173
writel(val, &dmc->concontrol);
176
static void config_offsets(unsigned int state,
177
struct exynos5_phy_control *phy0_ctrl,
178
struct exynos5_phy_control *phy1_ctrl)
181
/* Set Offsets to read DQS */
182
val = (state == SET) ? SET_DQS_OFFSET_VAL : RESET_DQS_OFFSET_VAL;
183
writel(val, &phy0_ctrl->phy_con4);
184
writel(val, &phy1_ctrl->phy_con4);
186
/* Set Offsets to read DQ */
187
val = (state == SET) ? SET_DQ_OFFSET_VAL : RESET_DQ_OFFSET_VAL;
188
writel(val, &phy0_ctrl->phy_con6);
189
writel(val, &phy1_ctrl->phy_con6);
192
val = (state == SET) ? SET_DEBUG_OFFSET_VAL : RESET_DEBUG_OFFSET_VAL;
193
writel(val, &phy0_ctrl->phy_con10);
194
writel(val, &phy1_ctrl->phy_con10);
197
static void config_cdrex(void)
199
struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
200
writel(CLK_DIV_CDREX_VAL, &clk->div_cdrex);
201
writel(CLK_SRC_CDREX_VAL, &clk->src_cdrex);
205
static void config_ctrl_dll_on(unsigned int state,
206
unsigned int ctrl_force_val,
207
struct exynos5_phy_control *phy0_ctrl,
208
struct exynos5_phy_control *phy1_ctrl)
211
val = readl(&phy0_ctrl->phy_con12);
212
CONFIG_CTRL_DLL_ON(val, state);
213
SET_CTRL_FORCE_VAL(val, ctrl_force_val);
214
writel(val, &phy0_ctrl->phy_con12);
216
val = readl(&phy1_ctrl->phy_con12);
217
CONFIG_CTRL_DLL_ON(val, state);
218
SET_CTRL_FORCE_VAL(val, ctrl_force_val);
219
writel(val, &phy1_ctrl->phy_con12);
222
static void config_ctrl_start(unsigned int state,
223
struct exynos5_phy_control *phy0_ctrl,
224
struct exynos5_phy_control *phy1_ctrl)
227
val = readl(&phy0_ctrl->phy_con12);
228
CONFIG_CTRL_START(val, state);
229
writel(val, &phy0_ctrl->phy_con12);
231
val = readl(&phy1_ctrl->phy_con12);
232
CONFIG_CTRL_START(val, state);
233
writel(val, &phy1_ctrl->phy_con12);
236
#if defined(CONFIG_RD_LVL)
237
static void config_rdlvl(struct exynos5_dmc *dmc,
238
struct exynos5_phy_control *phy0_ctrl,
239
struct exynos5_phy_control *phy1_ctrl)
243
/* Disable CTRL_DLL_ON and set ctrl_force */
244
config_ctrl_dll_on(RESET, 0x2D, phy0_ctrl, phy1_ctrl);
247
* Set ctrl_gateadj, ctrl_readadj
248
* ctrl_gateduradj, rdlvl_pass_adj
251
val = SET_RDLVL_RDDATAPADJ;
252
writel(val, &phy0_ctrl->phy_con1);
253
writel(val, &phy1_ctrl->phy_con1);
256
writel(LPDDR2_ADDR, &phy0_ctrl->phy_con22);
257
writel(LPDDR2_ADDR, &phy1_ctrl->phy_con22);
259
/* Enable Byte Read Leveling set ctrl_ddr_mode */
260
val = readl(&phy0_ctrl->phy_con0);
261
val |= BYTE_RDLVL_EN;
262
writel(val, &phy0_ctrl->phy_con0);
263
val = readl(&phy1_ctrl->phy_con0);
264
val |= BYTE_RDLVL_EN;
265
writel(val, &phy1_ctrl->phy_con0);
267
/* rdlvl_en: Use levelling offset instead ctrl_shiftc */
268
val = PHY_CON2_RESET_VAL | RDLVL_EN;
269
writel(val, &phy0_ctrl->phy_con2);
270
writel(val, &phy1_ctrl->phy_con2);
273
/* Enable Data Eye Training */
274
val = readl(&dmc->rdlvl_config);
275
val |= CTRL_RDLVL_DATA_EN;
276
writel(val, &dmc->rdlvl_config);
279
/* Disable Data Eye Training */
280
val = readl(&dmc->rdlvl_config);
281
val &= ~CTRL_RDLVL_DATA_EN;
282
writel(val, &dmc->rdlvl_config);
284
/* RdDeSkew_clear: Clear */
285
val = readl(&phy0_ctrl->phy_con2);
286
val |= RDDSKEW_CLEAR;
287
writel(val, &phy0_ctrl->phy_con2);
288
val = readl(&phy1_ctrl->phy_con2);
289
val |= RDDSKEW_CLEAR;
290
writel(val, &phy1_ctrl->phy_con2);
292
/* Enable CTRL_DLL_ON */
293
config_ctrl_dll_on(SET, 0x0, phy0_ctrl, phy1_ctrl);
295
update_reset_dll(dmc);
298
/* ctrl_atgte: ctrl_gate_p*, ctrl_read_p* generated by PHY */
299
val = readl(&phy0_ctrl->phy_con0);
301
writel(val, &phy0_ctrl->phy_con0);
302
val = readl(&phy1_ctrl->phy_con0);
304
writel(val, &phy1_ctrl->phy_con0);
308
static void config_memory(struct exynos5_dmc *dmc)
311
* Memory Configuration Chip 0
312
* Address Mapping: Interleaved
313
* Number of Column address Bits: 10 bits
314
* Number of Rows Address Bits: 14
317
writel(DMC_MEMCONFIG0_VAL, &dmc->memconfig0);
320
* Memory Configuration Chip 1
321
* Address Mapping: Interleaved
322
* Number of Column address Bits: 10 bits
323
* Number of Rows Address Bits: 14
326
writel(DMC_MEMCONFIG1_VAL, &dmc->memconfig1);
330
* AXI Base Address: 0x40000000
331
* AXI Base Address Mask: 0x780
333
writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0);
337
* AXI Base Address: 0x80000000
338
* AXI Base Address Mask: 0x780
340
writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1);
345
struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl;
346
struct exynos5_dmc *dmc;
349
phy0_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY0_BASE;
350
phy1_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY1_BASE;
351
dmc = (struct exynos5_dmc *)EXYNOS5_DMC_CTRL_BASE;
353
/* Reset PHY Controllor: PHY_RESET[0] */
356
/*set Read Latancy and Burst Length for PHY0 and PHY1 */
357
writel(PHY_CON42_VAL, &phy0_ctrl->phy_con42);
358
writel(PHY_CON42_VAL, &phy1_ctrl->phy_con42);
360
/* ZQ Cofiguration */
361
config_zq(phy0_ctrl, phy1_ctrl);
363
/* Operation Mode : LPDDR2 */
364
val = PHY_CON0_RESET_VAL;
365
SET_CTRL_DDR_MODE(val, DDR_MODE_LPDDR2);
366
writel(val, &phy0_ctrl->phy_con0);
367
writel(val, &phy1_ctrl->phy_con0);
369
/* DQS, DQ: Signal, for LPDDR2: Always Set */
370
val = CTRL_PULLD_DQ | CTRL_PULLD_DQS;
371
writel(val, &phy0_ctrl->phy_con14);
372
writel(val, &phy1_ctrl->phy_con14);
374
/* Init SEC SDRAM PHY */
375
sec_sdram_phy_init(dmc);
378
update_reset_dll(dmc);
381
* Dynamic Clock: Always Running
382
* Memory Burst length: 4
384
* Memory Bus width: 32 bit
385
* Memory Type: LPDDR2-S4
386
* Additional Latancy for PLL: 1 Cycle
388
writel(DMC_MEMCONTROL_VAL, &dmc->memcontrol);
392
/* Precharge Configuration */
393
writel(DMC_PRECHCONFIG_VAL, &dmc->prechconfig);
395
/* Power Down mode Configuration */
396
writel(DMC_PWRDNCONFIG_VAL, &dmc->pwrdnconfig);
398
/* Periodic Refrese Interval */
399
writel(DMC_TIMINGREF_VAL, &dmc->timingref);
402
* TimingRow, TimingData, TimingPower Setting:
403
* Values as per Memory AC Parameters
405
writel(DMC_TIMINGROW_VAL, &dmc->timingrow);
407
writel(DMC_TIMINGDATA_VAL, &dmc->timingdata);
409
writel(DMC_TIMINGPOWER_VAL, &dmc->timingpower);
411
/* Memory Channel Inteleaving Size: 128 Bytes */
412
writel(CONFIG_IV_SIZE, &dmc->ivcontrol);
414
/* Set DQS, DQ and DEBUG offsets */
415
config_offsets(SET, phy0_ctrl, phy1_ctrl);
417
/* Disable CTRL_DLL_ON and set ctrl_force */
418
config_ctrl_dll_on(RESET, 0x7F, phy0_ctrl, phy1_ctrl);
421
update_reset_dll(dmc);
423
/* Config MRS(Mode Register Settingg) */
428
/* Reset DQS DQ and DEBUG offsets */
429
config_offsets(RESET, phy0_ctrl, phy1_ctrl);
431
/* Enable CTRL_DLL_ON */
432
config_ctrl_dll_on(SET, 0x0, phy0_ctrl, phy1_ctrl);
434
/* Stop DLL Locking */
435
config_ctrl_start(RESET, phy0_ctrl, phy1_ctrl);
438
/* Start DLL Locking */
439
config_ctrl_start(SET, phy0_ctrl, phy1_ctrl);
442
update_reset_dll(dmc);
444
#if defined(CONFIG_RD_LVL)
445
config_rdlvl(dmc, phy0_ctrl, phy1_ctrl);
450
* Dynamic Clock: Stops During Idle Period
451
* Dynamic Power Down: Enable
452
* Dynamic Self refresh: Enable
454
val = readl(&dmc->memcontrol);
455
val |= CLK_STOP_EN | DPWRDN_EN | DSREF_EN;
456
writel(val, &dmc->memcontrol);
458
/* Start Auto refresh */
459
val = readl(&dmc->concontrol);
461
writel(val, &dmc->concontrol);