2 * Copyright (C) 2013 Atmel Corporation
3 * Bo Shen <voice.shen@atmel.com>
5 * SPDX-License-Identifier: GPL-2.0+
10 #include <asm/arch/atmel_mpddrc.h>
12 static inline void atmel_mpddr_op(int mode
, u32 ram_address
)
14 struct atmel_mpddr
*mpddr
= (struct atmel_mpddr
*)ATMEL_BASE_MPDDRC
;
16 writel(mode
, &mpddr
->mr
);
17 writel(0, ram_address
);
20 static int ddr2_decodtype_is_seq(u32 cr
)
22 #if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) || \
23 defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAM9N12)
24 if (cr
& ATMEL_MPDDRC_CR_DECOD_INTERLEAVED
)
30 int ddr2_init(const unsigned int ram_address
,
31 const struct atmel_mpddr
*mpddr_value
)
33 struct atmel_mpddr
*mpddr
= (struct atmel_mpddr
*)ATMEL_BASE_MPDDRC
;
36 /* Compute bank offset according to NC in configuration register */
37 ba_off
= (mpddr_value
->cr
& ATMEL_MPDDRC_CR_NC_MASK
) + 9;
38 if (ddr2_decodtype_is_seq(mpddr_value
->cr
))
39 ba_off
+= ((mpddr_value
->cr
& ATMEL_MPDDRC_CR_NR_MASK
) >> 2) + 11;
41 ba_off
+= (mpddr_value
->md
& ATMEL_MPDDRC_MD_DBW_MASK
) ? 1 : 2;
43 /* Program the memory device type into the memory device register */
44 writel(mpddr_value
->md
, &mpddr
->md
);
46 /* Program the configuration register */
47 writel(mpddr_value
->cr
, &mpddr
->cr
);
49 /* Program the timing register */
50 writel(mpddr_value
->tpr0
, &mpddr
->tpr0
);
51 writel(mpddr_value
->tpr1
, &mpddr
->tpr1
);
52 writel(mpddr_value
->tpr2
, &mpddr
->tpr2
);
54 /* Issue a NOP command */
55 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_NOP_CMD
, ram_address
);
57 /* A 200 us is provided to precede any signal toggle */
60 /* Issue a NOP command */
61 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_NOP_CMD
, ram_address
);
63 /* Issue an all banks precharge command */
64 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD
, ram_address
);
66 /* Issue an extended mode register set(EMRS2) to choose operation */
67 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD
,
68 ram_address
+ (0x2 << ba_off
));
70 /* Issue an extended mode register set(EMRS3) to set EMSR to 0 */
71 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD
,
72 ram_address
+ (0x3 << ba_off
));
75 * Issue an extended mode register set(EMRS1) to enable DLL and
76 * program D.I.C (output driver impedance control)
78 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD
,
79 ram_address
+ (0x1 << ba_off
));
81 /* Enable DLL reset */
82 cr
= readl(&mpddr
->cr
);
83 writel(cr
| ATMEL_MPDDRC_CR_DLL_RESET_ENABLED
, &mpddr
->cr
);
85 /* A mode register set(MRS) cycle is issued to reset DLL */
86 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_LMR_CMD
, ram_address
);
88 /* Issue an all banks precharge command */
89 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD
, ram_address
);
91 /* Two auto-refresh (CBR) cycles are provided */
92 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_RFSH_CMD
, ram_address
);
93 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_RFSH_CMD
, ram_address
);
95 /* Disable DLL reset */
96 cr
= readl(&mpddr
->cr
);
97 writel(cr
& (~ATMEL_MPDDRC_CR_DLL_RESET_ENABLED
), &mpddr
->cr
);
99 /* A mode register set (MRS) cycle is issued to disable DLL reset */
100 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_LMR_CMD
, ram_address
);
102 /* Set OCD calibration in default state */
103 cr
= readl(&mpddr
->cr
);
104 writel(cr
| ATMEL_MPDDRC_CR_OCD_DEFAULT
, &mpddr
->cr
);
107 * An extended mode register set (EMRS1) cycle is issued
108 * to OCD default value
110 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD
,
111 ram_address
+ (0x1 << ba_off
));
113 /* OCD calibration mode exit */
114 cr
= readl(&mpddr
->cr
);
115 writel(cr
& (~ATMEL_MPDDRC_CR_OCD_DEFAULT
), &mpddr
->cr
);
118 * An extended mode register set (EMRS1) cycle is issued
121 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD
,
122 ram_address
+ (0x1 << ba_off
));
124 /* A nornal mode command is provided */
125 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_NORMAL_CMD
, ram_address
);
127 /* Perform a write access to any DDR2-SDRAM address */
128 writel(0, ram_address
);
130 /* Write the refresh rate */
131 writel(mpddr_value
->rtr
, &mpddr
->rtr
);