1 /* 2 * Copyright 2021 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8 /* 9 * Generic driver for Freescale MMDC(Multi Mode DDR Controller). 10 */ 11 12 #include <errno.h> 13 #include <stdint.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 18 #include <common/debug.h> 19 #include "ddr_io.h" 20 #include <drivers/delay_timer.h> 21 #include <fsl_mmdc.h> 22 23 static void set_wait_for_bits_clear(void *ptr, unsigned int value, 24 unsigned int bits) 25 { 26 int timeout = 1000; 27 28 ddr_out32(ptr, value); 29 30 while ((ddr_in32(ptr) & bits) != 0) { 31 udelay(100); 32 timeout--; 33 } 34 if (timeout <= 0) { 35 INFO("Error: %llx", (unsigned long long)ptr); 36 INFO(" wait for clear timeout.\n"); 37 } 38 } 39 40 void mmdc_init(const struct fsl_mmdc_info *priv, uintptr_t nxp_ddr_addr) 41 { 42 struct mmdc_regs *mmdc = (struct mmdc_regs *)nxp_ddr_addr; 43 unsigned int tmp; 44 45 /* 1. set configuration request */ 46 ddr_out32(&mmdc->mdscr, MDSCR_ENABLE_CON_REQ); 47 48 /* 2. configure the desired timing parameters */ 49 ddr_out32(&mmdc->mdotc, priv->mdotc); 50 ddr_out32(&mmdc->mdcfg0, priv->mdcfg0); 51 ddr_out32(&mmdc->mdcfg1, priv->mdcfg1); 52 ddr_out32(&mmdc->mdcfg2, priv->mdcfg2); 53 54 /* 3. configure DDR type and other miscellaneous parameters */ 55 ddr_out32(&mmdc->mdmisc, priv->mdmisc); 56 ddr_out32(&mmdc->mpmur0, MMDC_MPMUR0_FRC_MSR); 57 ddr_out32(&mmdc->mdrwd, priv->mdrwd); 58 ddr_out32(&mmdc->mpodtctrl, priv->mpodtctrl); 59 60 /* 4. configure the required delay while leaving reset */ 61 ddr_out32(&mmdc->mdor, priv->mdor); 62 63 /* 5. configure DDR physical parameters */ 64 /* set row/column address width, burst length, data bus width */ 65 tmp = priv->mdctl & ~(MDCTL_SDE0 | MDCTL_SDE1); 66 ddr_out32(&mmdc->mdctl, tmp); 67 /* configure address space partition */ 68 ddr_out32(&mmdc->mdasp, priv->mdasp); 69 70 /* 6. perform a ZQ calibration - not needed here, doing in #8b */ 71 72 /* 7. enable MMDC with the desired chip select */ 73 #if (DDRC_NUM_CS == 1) 74 ddr_out32(&mmdc->mdctl, tmp | MDCTL_SDE0); 75 #elif (DDRC_NUM_CS == 2) 76 ddr_out32(&mmdc->mdctl, tmp | MDCTL_SDE0 | MDCTL_SDE1); 77 #else 78 #error "Unsupported DDRC_NUM_CS" 79 #endif 80 81 /* 8a. dram init sequence: update MRs for ZQ, ODT, PRE, etc */ 82 ddr_out32(&mmdc->mdscr, CMD_ADDR_LSB_MR_ADDR(8) | 83 MDSCR_ENABLE_CON_REQ | 84 CMD_LOAD_MODE_REG | 85 CMD_BANK_ADDR_2); 86 87 ddr_out32(&mmdc->mdscr, CMD_ADDR_LSB_MR_ADDR(0) | 88 MDSCR_ENABLE_CON_REQ | 89 CMD_LOAD_MODE_REG | 90 CMD_BANK_ADDR_3); 91 92 ddr_out32(&mmdc->mdscr, CMD_ADDR_LSB_MR_ADDR(4) | 93 MDSCR_ENABLE_CON_REQ | 94 CMD_LOAD_MODE_REG | 95 CMD_BANK_ADDR_1); 96 97 ddr_out32(&mmdc->mdscr, CMD_ADDR_MSB_MR_OP(0x19) | 98 CMD_ADDR_LSB_MR_ADDR(0x30) | 99 MDSCR_ENABLE_CON_REQ | 100 CMD_LOAD_MODE_REG | CMD_BANK_ADDR_0); 101 102 /* 8b. ZQ calibration */ 103 ddr_out32(&mmdc->mdscr, CMD_ADDR_MSB_MR_OP(0x4) | 104 MDSCR_ENABLE_CON_REQ | 105 CMD_ZQ_CALIBRATION | CMD_BANK_ADDR_0); 106 107 set_wait_for_bits_clear(&mmdc->mpzqhwctrl, priv->mpzqhwctrl, 108 MPZQHWCTRL_ZQ_HW_FORCE); 109 110 /* 9a. calibrations now, wr lvl */ 111 ddr_out32(&mmdc->mdscr, CMD_ADDR_LSB_MR_ADDR(0x84) | MDSCR_WL_EN | 112 MDSCR_ENABLE_CON_REQ | 113 CMD_LOAD_MODE_REG | CMD_BANK_ADDR_1); 114 115 set_wait_for_bits_clear(&mmdc->mpwlgcr, MPWLGCR_HW_WL_EN, 116 MPWLGCR_HW_WL_EN); 117 118 mdelay(1); 119 120 ddr_out32(&mmdc->mdscr, CMD_ADDR_LSB_MR_ADDR(4) | 121 MDSCR_ENABLE_CON_REQ | 122 CMD_LOAD_MODE_REG | CMD_BANK_ADDR_1); 123 124 ddr_out32(&mmdc->mdscr, MDSCR_ENABLE_CON_REQ); 125 126 mdelay(1); 127 128 /* 9b. read DQS gating calibration */ 129 ddr_out32(&mmdc->mdscr, CMD_ADDR_MSB_MR_OP(4) | MDSCR_ENABLE_CON_REQ | 130 CMD_PRECHARGE_BANK_OPEN | CMD_BANK_ADDR_0); 131 132 ddr_out32(&mmdc->mdscr, CMD_ADDR_LSB_MR_ADDR(4) | MDSCR_ENABLE_CON_REQ | 133 CMD_LOAD_MODE_REG | CMD_BANK_ADDR_3); 134 135 ddr_out32(&mmdc->mppdcmpr2, MPPDCMPR2_MPR_COMPARE_EN); 136 137 /* set absolute read delay offset */ 138 if (priv->mprddlctl != 0) { 139 ddr_out32(&mmdc->mprddlctl, priv->mprddlctl); 140 } else { 141 ddr_out32(&mmdc->mprddlctl, MMDC_MPRDDLCTL_DEFAULT_DELAY); 142 } 143 144 set_wait_for_bits_clear(&mmdc->mpdgctrl0, 145 AUTO_RD_DQS_GATING_CALIBRATION_EN, 146 AUTO_RD_DQS_GATING_CALIBRATION_EN); 147 148 ddr_out32(&mmdc->mdscr, MDSCR_ENABLE_CON_REQ | CMD_LOAD_MODE_REG | 149 CMD_BANK_ADDR_3); 150 151 /* 9c. read calibration */ 152 ddr_out32(&mmdc->mdscr, CMD_ADDR_MSB_MR_OP(4) | MDSCR_ENABLE_CON_REQ | 153 CMD_PRECHARGE_BANK_OPEN | CMD_BANK_ADDR_0); 154 ddr_out32(&mmdc->mdscr, CMD_ADDR_LSB_MR_ADDR(4) | MDSCR_ENABLE_CON_REQ | 155 CMD_LOAD_MODE_REG | CMD_BANK_ADDR_3); 156 ddr_out32(&mmdc->mppdcmpr2, MPPDCMPR2_MPR_COMPARE_EN); 157 set_wait_for_bits_clear(&mmdc->mprddlhwctl, 158 MPRDDLHWCTL_AUTO_RD_CALIBRATION_EN, 159 MPRDDLHWCTL_AUTO_RD_CALIBRATION_EN); 160 161 ddr_out32(&mmdc->mdscr, MDSCR_ENABLE_CON_REQ | CMD_LOAD_MODE_REG | 162 CMD_BANK_ADDR_3); 163 164 /* 10. configure power-down, self-refresh entry, exit parameters */ 165 ddr_out32(&mmdc->mdpdc, priv->mdpdc); 166 ddr_out32(&mmdc->mapsr, MMDC_MAPSR_PWR_SAV_CTRL_STAT); 167 168 /* 11. ZQ config again? do nothing here */ 169 170 /* 12. refresh scheme */ 171 set_wait_for_bits_clear(&mmdc->mdref, priv->mdref, 172 MDREF_START_REFRESH); 173 174 /* 13. disable CON_REQ */ 175 ddr_out32(&mmdc->mdscr, MDSCR_DISABLE_CFG_REQ); 176 } 177