1 /* 2 * (C) Copyright 2017 3 * Vikas Manocha, <vikas.manocha@st.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <clk.h> 10 #include <dm.h> 11 #include <ram.h> 12 #include <asm/io.h> 13 #include <asm/arch/fmc.h> 14 #include <asm/arch/stm32.h> 15 16 DECLARE_GLOBAL_DATA_PTR; 17 18 struct stm32_sdram_control { 19 u8 no_columns; 20 u8 no_rows; 21 u8 memory_width; 22 u8 no_banks; 23 u8 cas_latency; 24 u8 sdclk; 25 u8 rd_burst; 26 u8 rd_pipe_delay; 27 }; 28 29 struct stm32_sdram_timing { 30 u8 tmrd; 31 u8 txsr; 32 u8 tras; 33 u8 trc; 34 u8 trp; 35 u8 twr; 36 u8 trcd; 37 }; 38 struct stm32_sdram_params { 39 u8 no_sdram_banks; 40 struct stm32_sdram_control sdram_control; 41 struct stm32_sdram_timing sdram_timing; 42 u32 sdram_ref_count; 43 }; 44 45 #define SDRAM_MODE_BL_SHIFT 0 46 #define SDRAM_MODE_CAS_SHIFT 4 47 #define SDRAM_MODE_BL 0 48 49 int stm32_sdram_init(struct udevice *dev) 50 { 51 struct stm32_sdram_params *params = dev_get_platdata(dev); 52 53 writel(params->sdram_control.sdclk << FMC_SDCR_SDCLK_SHIFT 54 | params->sdram_control.cas_latency << FMC_SDCR_CAS_SHIFT 55 | params->sdram_control.no_banks << FMC_SDCR_NB_SHIFT 56 | params->sdram_control.memory_width << FMC_SDCR_MWID_SHIFT 57 | params->sdram_control.no_rows << FMC_SDCR_NR_SHIFT 58 | params->sdram_control.no_columns << FMC_SDCR_NC_SHIFT 59 | params->sdram_control.rd_pipe_delay << FMC_SDCR_RPIPE_SHIFT 60 | params->sdram_control.rd_burst << FMC_SDCR_RBURST_SHIFT, 61 &STM32_SDRAM_FMC->sdcr1); 62 63 writel(params->sdram_timing.trcd << FMC_SDTR_TRCD_SHIFT 64 | params->sdram_timing.trp << FMC_SDTR_TRP_SHIFT 65 | params->sdram_timing.twr << FMC_SDTR_TWR_SHIFT 66 | params->sdram_timing.trc << FMC_SDTR_TRC_SHIFT 67 | params->sdram_timing.tras << FMC_SDTR_TRAS_SHIFT 68 | params->sdram_timing.txsr << FMC_SDTR_TXSR_SHIFT 69 | params->sdram_timing.tmrd << FMC_SDTR_TMRD_SHIFT, 70 &STM32_SDRAM_FMC->sdtr1); 71 72 writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_START_CLOCK, 73 &STM32_SDRAM_FMC->sdcmr); 74 udelay(200); /* 200 us delay, page 10, "Power-Up" */ 75 FMC_BUSY_WAIT(); 76 77 writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_PRECHARGE, 78 &STM32_SDRAM_FMC->sdcmr); 79 udelay(100); 80 FMC_BUSY_WAIT(); 81 82 writel((FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_AUTOREFRESH 83 | 7 << FMC_SDCMR_NRFS_SHIFT), &STM32_SDRAM_FMC->sdcmr); 84 udelay(100); 85 FMC_BUSY_WAIT(); 86 87 writel(FMC_SDCMR_BANK_1 | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT 88 | params->sdram_control.cas_latency << SDRAM_MODE_CAS_SHIFT) 89 << FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE, 90 &STM32_SDRAM_FMC->sdcmr); 91 udelay(100); 92 FMC_BUSY_WAIT(); 93 94 writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_NORMAL, 95 &STM32_SDRAM_FMC->sdcmr); 96 FMC_BUSY_WAIT(); 97 98 /* Refresh timer */ 99 writel((params->sdram_ref_count) << 1, &STM32_SDRAM_FMC->sdrtr); 100 101 return 0; 102 } 103 104 static int stm32_fmc_ofdata_to_platdata(struct udevice *dev) 105 { 106 int ret; 107 int node = dev_of_offset(dev); 108 const void *blob = gd->fdt_blob; 109 struct stm32_sdram_params *params = dev_get_platdata(dev); 110 111 params->no_sdram_banks = fdtdec_get_uint(blob, node, "mr-nbanks", 1); 112 debug("%s, no of banks = %d\n", __func__, params->no_sdram_banks); 113 114 fdt_for_each_subnode(node, blob, node) { 115 ret = fdtdec_get_byte_array(blob, node, "st,sdram-control", 116 (u8 *)¶ms->sdram_control, 117 sizeof(params->sdram_control)); 118 if (ret) 119 return ret; 120 ret = fdtdec_get_byte_array(blob, node, "st,sdram-timing", 121 (u8 *)¶ms->sdram_timing, 122 sizeof(params->sdram_timing)); 123 if (ret) 124 return ret; 125 126 params->sdram_ref_count = fdtdec_get_int(blob, node, 127 "st,sdram-refcount", 8196); 128 } 129 130 return 0; 131 } 132 133 static int stm32_fmc_probe(struct udevice *dev) 134 { 135 #ifdef CONFIG_CLK 136 int ret; 137 struct clk clk; 138 139 ret = clk_get_by_index(dev, 0, &clk); 140 if (ret < 0) 141 return ret; 142 143 ret = clk_enable(&clk); 144 145 if (ret) { 146 dev_err(dev, "failed to enable clock\n"); 147 return ret; 148 } 149 #endif 150 ret = stm32_sdram_init(dev); 151 if (ret) 152 return ret; 153 154 return 0; 155 } 156 157 static int stm32_fmc_get_info(struct udevice *dev, struct ram_info *info) 158 { 159 return 0; 160 } 161 162 static struct ram_ops stm32_fmc_ops = { 163 .get_info = stm32_fmc_get_info, 164 }; 165 166 static const struct udevice_id stm32_fmc_ids[] = { 167 { .compatible = "st,stm32-fmc" }, 168 { } 169 }; 170 171 U_BOOT_DRIVER(stm32_fmc) = { 172 .name = "stm32_fmc", 173 .id = UCLASS_RAM, 174 .of_match = stm32_fmc_ids, 175 .ops = &stm32_fmc_ops, 176 .ofdata_to_platdata = stm32_fmc_ofdata_to_platdata, 177 .probe = stm32_fmc_probe, 178 .platdata_auto_alloc_size = sizeof(struct stm32_sdram_params), 179 }; 180