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