1 /* 2 * Mem setup common file for different types of DDR present on Exynos boards. 3 * 4 * Copyright (C) 2012 Samsung Electronics 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include <common.h> 10 #include <asm/arch/spl.h> 11 12 #include "clock_init.h" 13 #include "common_setup.h" 14 #include "exynos5_setup.h" 15 16 #define ZQ_INIT_TIMEOUT 10000 17 18 int dmc_config_zq(struct mem_timings *mem, uint32_t *phy0_con16, 19 uint32_t *phy1_con16, uint32_t *phy0_con17, 20 uint32_t *phy1_con17) 21 { 22 unsigned long val = 0; 23 int i; 24 25 /* 26 * ZQ Calibration: 27 * Select Driver Strength, 28 * long calibration for manual calibration 29 */ 30 val = PHY_CON16_RESET_VAL; 31 val |= mem->zq_mode_dds << PHY_CON16_ZQ_MODE_DDS_SHIFT; 32 val |= mem->zq_mode_term << PHY_CON16_ZQ_MODE_TERM_SHIFT; 33 val |= ZQ_CLK_DIV_EN; 34 writel(val, phy0_con16); 35 writel(val, phy1_con16); 36 37 /* Disable termination */ 38 if (mem->zq_mode_noterm) 39 val |= PHY_CON16_ZQ_MODE_NOTERM_MASK; 40 writel(val, phy0_con16); 41 writel(val, phy1_con16); 42 43 /* ZQ_MANUAL_START: Enable */ 44 val |= ZQ_MANUAL_STR; 45 writel(val, phy0_con16); 46 writel(val, phy1_con16); 47 48 /* ZQ_MANUAL_START: Disable */ 49 val &= ~ZQ_MANUAL_STR; 50 51 /* 52 * Since we are manaully calibrating the ZQ values, 53 * we are looping for the ZQ_init to complete. 54 */ 55 i = ZQ_INIT_TIMEOUT; 56 while ((readl(phy0_con17) & ZQ_DONE) != ZQ_DONE && i > 0) { 57 sdelay(100); 58 i--; 59 } 60 if (!i) 61 return -1; 62 writel(val, phy0_con16); 63 64 i = ZQ_INIT_TIMEOUT; 65 while ((readl(phy1_con17) & ZQ_DONE) != ZQ_DONE && i > 0) { 66 sdelay(100); 67 i--; 68 } 69 if (!i) 70 return -1; 71 writel(val, phy1_con16); 72 73 return 0; 74 } 75 76 void update_reset_dll(uint32_t *phycontrol0, enum ddr_mode mode) 77 { 78 unsigned long val; 79 80 if (mode == DDR_MODE_DDR3) { 81 val = MEM_TERM_EN | PHY_TERM_EN | DMC_CTRL_SHGATE; 82 writel(val, phycontrol0); 83 } 84 85 /* Update DLL Information: Force DLL Resyncronization */ 86 val = readl(phycontrol0); 87 val |= FP_RSYNC; 88 writel(val, phycontrol0); 89 90 /* Reset Force DLL Resyncronization */ 91 val = readl(phycontrol0); 92 val &= ~FP_RSYNC; 93 writel(val, phycontrol0); 94 } 95 96 void dmc_config_mrs(struct mem_timings *mem, uint32_t *directcmd) 97 { 98 int channel, chip; 99 100 for (channel = 0; channel < mem->dmc_channels; channel++) { 101 unsigned long mask; 102 103 mask = channel << DIRECT_CMD_CHANNEL_SHIFT; 104 for (chip = 0; chip < mem->chips_to_configure; chip++) { 105 int i; 106 107 mask |= chip << DIRECT_CMD_CHIP_SHIFT; 108 109 /* Sending NOP command */ 110 writel(DIRECT_CMD_NOP | mask, directcmd); 111 112 /* 113 * TODO(alim.akhtar@samsung.com): Do we need these 114 * delays? This one and the next were not there for 115 * DDR3. 116 */ 117 sdelay(0x10000); 118 119 /* Sending EMRS/MRS commands */ 120 for (i = 0; i < MEM_TIMINGS_MSR_COUNT; i++) { 121 writel(mem->direct_cmd_msr[i] | mask, 122 directcmd); 123 sdelay(0x10000); 124 } 125 126 if (mem->send_zq_init) { 127 /* Sending ZQINIT command */ 128 writel(DIRECT_CMD_ZQINIT | mask, 129 directcmd); 130 131 sdelay(10000); 132 } 133 } 134 } 135 } 136 137 void dmc_config_prech(struct mem_timings *mem, uint32_t *directcmd) 138 { 139 int channel, chip; 140 141 for (channel = 0; channel < mem->dmc_channels; channel++) { 142 unsigned long mask; 143 144 mask = channel << DIRECT_CMD_CHANNEL_SHIFT; 145 for (chip = 0; chip < mem->chips_per_channel; chip++) { 146 mask |= chip << DIRECT_CMD_CHIP_SHIFT; 147 148 /* PALL (all banks precharge) CMD */ 149 writel(DIRECT_CMD_PALL | mask, directcmd); 150 sdelay(0x10000); 151 } 152 } 153 } 154 155 void mem_ctrl_init(int reset) 156 { 157 struct spl_machine_param *param = spl_get_machine_params(); 158 struct mem_timings *mem; 159 int ret; 160 161 mem = clock_get_mem_timings(); 162 163 /* If there are any other memory variant, add their init call below */ 164 if (param->mem_type == DDR_MODE_DDR3) { 165 ret = ddr3_mem_ctrl_init(mem, reset); 166 if (ret) { 167 /* will hang if failed to init memory control */ 168 while (1) 169 ; 170 } 171 } else { 172 /* will hang if unknow memory type */ 173 while (1) 174 ; 175 } 176 } 177