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 if (cr
& ATMEL_MPDDRC_CR_DECOD_INTERLEAVED
)
29 int ddr2_init(const unsigned int ram_address
,
30 const struct atmel_mpddr
*mpddr_value
)
32 struct atmel_mpddr
*mpddr
= (struct atmel_mpddr
*)ATMEL_BASE_MPDDRC
;
35 /* Compute bank offset according to NC in configuration register */
36 ba_off
= (mpddr_value
->cr
& ATMEL_MPDDRC_CR_NC_MASK
) + 9;
37 if (ddr2_decodtype_is_seq(mpddr_value
->cr
))
38 ba_off
+= ((mpddr_value
->cr
& ATMEL_MPDDRC_CR_NR_MASK
) >> 2) + 11;
40 ba_off
+= (mpddr_value
->md
& ATMEL_MPDDRC_MD_DBW_MASK
) ? 1 : 2;
42 /* Program the memory device type into the memory device register */
43 writel(mpddr_value
->md
, &mpddr
->md
);
45 /* Program the configuration register */
46 writel(mpddr_value
->cr
, &mpddr
->cr
);
48 /* Program the timing register */
49 writel(mpddr_value
->tpr0
, &mpddr
->tpr0
);
50 writel(mpddr_value
->tpr1
, &mpddr
->tpr1
);
51 writel(mpddr_value
->tpr2
, &mpddr
->tpr2
);
53 /* Issue a NOP command */
54 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_NOP_CMD
, ram_address
);
56 /* A 200 us is provided to precede any signal toggle */
59 /* Issue a NOP command */
60 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_NOP_CMD
, ram_address
);
62 /* Issue an all banks precharge command */
63 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD
, ram_address
);
65 /* Issue an extended mode register set(EMRS2) to choose operation */
66 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD
,
67 ram_address
+ (0x2 << ba_off
));
69 /* Issue an extended mode register set(EMRS3) to set EMSR to 0 */
70 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD
,
71 ram_address
+ (0x3 << ba_off
));
74 * Issue an extended mode register set(EMRS1) to enable DLL and
75 * program D.I.C (output driver impedance control)
77 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD
,
78 ram_address
+ (0x1 << ba_off
));
80 /* Enable DLL reset */
81 cr
= readl(&mpddr
->cr
);
82 writel(cr
| ATMEL_MPDDRC_CR_DLL_RESET_ENABLED
, &mpddr
->cr
);
84 /* A mode register set(MRS) cycle is issued to reset DLL */
85 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_LMR_CMD
, ram_address
);
87 /* Issue an all banks precharge command */
88 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD
, ram_address
);
90 /* Two auto-refresh (CBR) cycles are provided */
91 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_RFSH_CMD
, ram_address
);
92 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_RFSH_CMD
, ram_address
);
94 /* Disable DLL reset */
95 cr
= readl(&mpddr
->cr
);
96 writel(cr
& (~ATMEL_MPDDRC_CR_DLL_RESET_ENABLED
), &mpddr
->cr
);
98 /* A mode register set (MRS) cycle is issued to disable DLL reset */
99 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_LMR_CMD
, ram_address
);
101 /* Set OCD calibration in default state */
102 cr
= readl(&mpddr
->cr
);
103 writel(cr
| ATMEL_MPDDRC_CR_OCD_DEFAULT
, &mpddr
->cr
);
106 * An extended mode register set (EMRS1) cycle is issued
107 * to OCD default value
109 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD
,
110 ram_address
+ (0x1 << ba_off
));
112 /* OCD calibration mode exit */
113 cr
= readl(&mpddr
->cr
);
114 writel(cr
& (~ATMEL_MPDDRC_CR_OCD_DEFAULT
), &mpddr
->cr
);
117 * An extended mode register set (EMRS1) cycle is issued
120 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD
,
121 ram_address
+ (0x1 << ba_off
));
123 /* A nornal mode command is provided */
124 atmel_mpddr_op(ATMEL_MPDDRC_MR_MODE_NORMAL_CMD
, ram_address
);
126 /* Perform a write access to any DDR2-SDRAM address */
127 writel(0, ram_address
);
129 /* Write the refresh rate */
130 writel(mpddr_value
->rtr
, &mpddr
->rtr
);