1 /* 2 * Copyright (C) 2013 Atmel Corporation 3 * Bo Shen <voice.shen@atmel.com> 4 * 5 * Copyright (C) 2015 Atmel Corporation 6 * Wenyou Yang <wenyou.yang@atmel.com> 7 * 8 * SPDX-License-Identifier: GPL-2.0+ 9 */ 10 11 #include <common.h> 12 #include <asm/io.h> 13 #include <asm/arch/atmel_mpddrc.h> 14 15 static inline void atmel_mpddr_op(const struct atmel_mpddr *mpddr, 16 int mode, 17 u32 ram_address) 18 { 19 writel(mode, &mpddr->mr); 20 writel(0, ram_address); 21 } 22 23 static int ddr2_decodtype_is_seq(u32 cr) 24 { 25 #if defined(CONFIG_SAMA5D3) || defined(CONFIG_SAMA5D4) || \ 26 defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAM9N12) 27 if (cr & ATMEL_MPDDRC_CR_DECOD_INTERLEAVED) 28 return 0; 29 #endif 30 return 1; 31 } 32 33 34 int ddr2_init(const unsigned int base, 35 const unsigned int ram_address, 36 const struct atmel_mpddrc_config *mpddr_value) 37 { 38 const struct atmel_mpddr *mpddr = (struct atmel_mpddr *)base; 39 40 u32 ba_off, cr; 41 42 /* Compute bank offset according to NC in configuration register */ 43 ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9; 44 if (ddr2_decodtype_is_seq(mpddr_value->cr)) 45 ba_off += ((mpddr_value->cr & ATMEL_MPDDRC_CR_NR_MASK) >> 2) + 11; 46 47 ba_off += (mpddr_value->md & ATMEL_MPDDRC_MD_DBW_MASK) ? 1 : 2; 48 49 /* Program the memory device type into the memory device register */ 50 writel(mpddr_value->md, &mpddr->md); 51 52 /* Program the configuration register */ 53 writel(mpddr_value->cr, &mpddr->cr); 54 55 /* Program the timing register */ 56 writel(mpddr_value->tpr0, &mpddr->tpr0); 57 writel(mpddr_value->tpr1, &mpddr->tpr1); 58 writel(mpddr_value->tpr2, &mpddr->tpr2); 59 60 /* Issue a NOP command */ 61 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address); 62 63 /* A 200 us is provided to precede any signal toggle */ 64 udelay(200); 65 66 /* Issue a NOP command */ 67 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address); 68 69 /* Issue an all banks precharge command */ 70 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD, ram_address); 71 72 /* Issue an extended mode register set(EMRS2) to choose operation */ 73 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, 74 ram_address + (0x2 << ba_off)); 75 76 /* Issue an extended mode register set(EMRS3) to set EMSR to 0 */ 77 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, 78 ram_address + (0x3 << ba_off)); 79 80 /* 81 * Issue an extended mode register set(EMRS1) to enable DLL and 82 * program D.I.C (output driver impedance control) 83 */ 84 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, 85 ram_address + (0x1 << ba_off)); 86 87 /* Enable DLL reset */ 88 cr = readl(&mpddr->cr); 89 writel(cr | ATMEL_MPDDRC_CR_DLL_RESET_ENABLED, &mpddr->cr); 90 91 /* A mode register set(MRS) cycle is issued to reset DLL */ 92 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address); 93 94 /* Issue an all banks precharge command */ 95 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD, ram_address); 96 97 /* Two auto-refresh (CBR) cycles are provided */ 98 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_RFSH_CMD, ram_address); 99 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_RFSH_CMD, ram_address); 100 101 /* Disable DLL reset */ 102 cr = readl(&mpddr->cr); 103 writel(cr & (~ATMEL_MPDDRC_CR_DLL_RESET_ENABLED), &mpddr->cr); 104 105 /* A mode register set (MRS) cycle is issued to disable DLL reset */ 106 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address); 107 108 /* Set OCD calibration in default state */ 109 cr = readl(&mpddr->cr); 110 writel(cr | ATMEL_MPDDRC_CR_OCD_DEFAULT, &mpddr->cr); 111 112 /* 113 * An extended mode register set (EMRS1) cycle is issued 114 * to OCD default value 115 */ 116 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, 117 ram_address + (0x1 << ba_off)); 118 119 /* OCD calibration mode exit */ 120 cr = readl(&mpddr->cr); 121 writel(cr & (~ATMEL_MPDDRC_CR_OCD_DEFAULT), &mpddr->cr); 122 123 /* 124 * An extended mode register set (EMRS1) cycle is issued 125 * to enable OCD exit 126 */ 127 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, 128 ram_address + (0x1 << ba_off)); 129 130 /* A nornal mode command is provided */ 131 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NORMAL_CMD, ram_address); 132 133 /* Perform a write access to any DDR2-SDRAM address */ 134 writel(0, ram_address); 135 136 /* Write the refresh rate */ 137 writel(mpddr_value->rtr, &mpddr->rtr); 138 139 return 0; 140 } 141 142 int ddr3_init(const unsigned int base, 143 const unsigned int ram_address, 144 const struct atmel_mpddrc_config *mpddr_value) 145 { 146 struct atmel_mpddr *mpddr = (struct atmel_mpddr *)base; 147 u32 ba_off; 148 149 /* Compute bank offset according to NC in configuration register */ 150 ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9; 151 if (ddr2_decodtype_is_seq(mpddr_value->cr)) 152 ba_off += ((mpddr_value->cr & 153 ATMEL_MPDDRC_CR_NR_MASK) >> 2) + 11; 154 155 ba_off += (mpddr_value->md & ATMEL_MPDDRC_MD_DBW_MASK) ? 1 : 2; 156 157 /* Program the memory device type */ 158 writel(mpddr_value->md, &mpddr->md); 159 160 /* 161 * Program features of the DDR3-SDRAM device and timing parameters 162 */ 163 writel(mpddr_value->cr, &mpddr->cr); 164 165 writel(mpddr_value->tpr0, &mpddr->tpr0); 166 writel(mpddr_value->tpr1, &mpddr->tpr1); 167 writel(mpddr_value->tpr2, &mpddr->tpr2); 168 169 /* A NOP command is issued to the DDR3-SRAM */ 170 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address); 171 172 /* A pause of at least 500us must be observed before a single toggle. */ 173 udelay(500); 174 175 /* A NOP command is issued to the DDR3-SDRAM */ 176 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address); 177 178 /* 179 * An Extended Mode Register Set (EMRS2) cycle is issued to choose 180 * between commercial or high temperature operations. 181 */ 182 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, 183 ram_address + (0x2 << ba_off)); 184 /* 185 * Step 7: An Extended Mode Register Set (EMRS3) cycle is issued to set 186 * the Extended Mode Register to 0. 187 */ 188 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, 189 ram_address + (0x3 << ba_off)); 190 /* 191 * An Extended Mode Register Set (EMRS1) cycle is issued to disable and 192 * to program O.D.S. (Output Driver Strength). 193 */ 194 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD, 195 ram_address + (0x1 << ba_off)); 196 197 /* 198 * Write a one to the DLL bit (enable DLL reset) in the MPDDRC 199 * Configuration Register. 200 */ 201 202 /* A Mode Register Set (MRS) cycle is issued to reset DLL. */ 203 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address); 204 205 udelay(50); 206 207 /* 208 * A Calibration command (MRS) is issued to calibrate RTT and RON 209 * values for the Process Voltage Temperature (PVT). 210 */ 211 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_DEEP_CMD, ram_address); 212 213 /* A Normal Mode command is provided. */ 214 atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NORMAL_CMD, ram_address); 215 216 /* Perform a write access to any DDR3-SDRAM address. */ 217 writel(0, ram_address); 218 219 /* 220 * Write the refresh rate into the COUNT field in the MPDDRC 221 * Refresh Timer Register (MPDDRC_RTR): 222 */ 223 writel(mpddr_value->rtr, &mpddr->rtr); 224 225 return 0; 226 } 227