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