1bf1ae442SVikas Manocha /* 2bf1ae442SVikas Manocha * (C) Copyright 2017 3bf1ae442SVikas Manocha * Vikas Manocha, <vikas.manocha@st.com> 4bf1ae442SVikas Manocha * 5bf1ae442SVikas Manocha * SPDX-License-Identifier: GPL-2.0+ 6bf1ae442SVikas Manocha */ 7bf1ae442SVikas Manocha 8bf1ae442SVikas Manocha #include <common.h> 9*d0b24c1aSVikas Manocha #include <clk.h> 10910a52edSVikas Manocha #include <dm.h> 11910a52edSVikas Manocha #include <ram.h> 12bf1ae442SVikas Manocha #include <asm/io.h> 13bf1ae442SVikas Manocha #include <asm/arch/fmc.h> 14bf1ae442SVikas Manocha #include <asm/arch/stm32.h> 15bf1ae442SVikas Manocha 16bf1ae442SVikas Manocha static inline u32 _ns2clk(u32 ns, u32 freq) 17bf1ae442SVikas Manocha { 18bf1ae442SVikas Manocha u32 tmp = freq/1000000; 19bf1ae442SVikas Manocha return (tmp * ns) / 1000; 20bf1ae442SVikas Manocha } 21bf1ae442SVikas Manocha 22bf1ae442SVikas Manocha #define NS2CLK(ns) (_ns2clk(ns, freq)) 23bf1ae442SVikas Manocha 24bf1ae442SVikas Manocha /* 25bf1ae442SVikas Manocha * Following are timings for IS42S16400J, from corresponding datasheet 26bf1ae442SVikas Manocha */ 27bf1ae442SVikas Manocha #define SDRAM_CAS 3 /* 3 cycles */ 28bf1ae442SVikas Manocha #define SDRAM_NB 1 /* Number of banks */ 29bf1ae442SVikas Manocha #define SDRAM_MWID 1 /* 16 bit memory */ 30bf1ae442SVikas Manocha 31bf1ae442SVikas Manocha #define SDRAM_NR 0x1 /* 12-bit row */ 32bf1ae442SVikas Manocha #define SDRAM_NC 0x0 /* 8-bit col */ 33bf1ae442SVikas Manocha #define SDRAM_RBURST 0x1 /* Single read requests always as bursts */ 34bf1ae442SVikas Manocha #define SDRAM_RPIPE 0x0 /* No HCLK clock cycle delay */ 35bf1ae442SVikas Manocha 36bf1ae442SVikas Manocha #define SDRAM_TRRD NS2CLK(12) 37bf1ae442SVikas Manocha #define SDRAM_TRCD NS2CLK(18) 38bf1ae442SVikas Manocha #define SDRAM_TRP NS2CLK(18) 39bf1ae442SVikas Manocha #define SDRAM_TRAS NS2CLK(42) 40bf1ae442SVikas Manocha #define SDRAM_TRC NS2CLK(60) 41bf1ae442SVikas Manocha #define SDRAM_TRFC NS2CLK(60) 42bf1ae442SVikas Manocha #define SDRAM_TCDL (1 - 1) 43bf1ae442SVikas Manocha #define SDRAM_TRDL NS2CLK(12) 44bf1ae442SVikas Manocha #define SDRAM_TBDL (1 - 1) 45bf1ae442SVikas Manocha #define SDRAM_TREF (NS2CLK(64000000 / 8192) - 20) 46bf1ae442SVikas Manocha #define SDRAM_TCCD (1 - 1) 47bf1ae442SVikas Manocha 48bf1ae442SVikas Manocha #define SDRAM_TXSR SDRAM_TRFC /* Row cycle time after precharge */ 49bf1ae442SVikas Manocha #define SDRAM_TMRD 1 /* Page 10, Mode Register Set */ 50bf1ae442SVikas Manocha 51bf1ae442SVikas Manocha 52bf1ae442SVikas Manocha /* Last data in to row precharge, need also comply ineq on page 1648 */ 53bf1ae442SVikas Manocha #define SDRAM_TWR max(\ 54bf1ae442SVikas Manocha (int)max((int)SDRAM_TRDL, (int)(SDRAM_TRAS - SDRAM_TRCD)), \ 55bf1ae442SVikas Manocha (int)(SDRAM_TRC - SDRAM_TRCD - SDRAM_TRP)\ 56bf1ae442SVikas Manocha ) 57bf1ae442SVikas Manocha 58bf1ae442SVikas Manocha 59bf1ae442SVikas Manocha #define SDRAM_MODE_BL_SHIFT 0 60bf1ae442SVikas Manocha #define SDRAM_MODE_CAS_SHIFT 4 61bf1ae442SVikas Manocha #define SDRAM_MODE_BL 0 62bf1ae442SVikas Manocha #define SDRAM_MODE_CAS SDRAM_CAS 63bf1ae442SVikas Manocha 64bf1ae442SVikas Manocha int stm32_sdram_init(void) 65bf1ae442SVikas Manocha { 66bf1ae442SVikas Manocha u32 freq; 67bf1ae442SVikas Manocha 68bf1ae442SVikas Manocha /* 69bf1ae442SVikas Manocha * Get frequency for NS2CLK calculation. 70bf1ae442SVikas Manocha */ 71bf1ae442SVikas Manocha freq = clock_get(CLOCK_AHB) / CONFIG_SYS_RAM_FREQ_DIV; 72bf1ae442SVikas Manocha 73bf1ae442SVikas Manocha writel(CONFIG_SYS_RAM_FREQ_DIV << FMC_SDCR_SDCLK_SHIFT 74bf1ae442SVikas Manocha | SDRAM_CAS << FMC_SDCR_CAS_SHIFT 75bf1ae442SVikas Manocha | SDRAM_NB << FMC_SDCR_NB_SHIFT 76bf1ae442SVikas Manocha | SDRAM_MWID << FMC_SDCR_MWID_SHIFT 77bf1ae442SVikas Manocha | SDRAM_NR << FMC_SDCR_NR_SHIFT 78bf1ae442SVikas Manocha | SDRAM_NC << FMC_SDCR_NC_SHIFT 79bf1ae442SVikas Manocha | SDRAM_RPIPE << FMC_SDCR_RPIPE_SHIFT 80bf1ae442SVikas Manocha | SDRAM_RBURST << FMC_SDCR_RBURST_SHIFT, 81bf1ae442SVikas Manocha &STM32_SDRAM_FMC->sdcr1); 82bf1ae442SVikas Manocha 83bf1ae442SVikas Manocha writel(SDRAM_TRCD << FMC_SDTR_TRCD_SHIFT 84bf1ae442SVikas Manocha | SDRAM_TRP << FMC_SDTR_TRP_SHIFT 85bf1ae442SVikas Manocha | SDRAM_TWR << FMC_SDTR_TWR_SHIFT 86bf1ae442SVikas Manocha | SDRAM_TRC << FMC_SDTR_TRC_SHIFT 87bf1ae442SVikas Manocha | SDRAM_TRAS << FMC_SDTR_TRAS_SHIFT 88bf1ae442SVikas Manocha | SDRAM_TXSR << FMC_SDTR_TXSR_SHIFT 89bf1ae442SVikas Manocha | SDRAM_TMRD << FMC_SDTR_TMRD_SHIFT, 90bf1ae442SVikas Manocha &STM32_SDRAM_FMC->sdtr1); 91bf1ae442SVikas Manocha 92bf1ae442SVikas Manocha writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_START_CLOCK, 93bf1ae442SVikas Manocha &STM32_SDRAM_FMC->sdcmr); 94bf1ae442SVikas Manocha udelay(200); /* 200 us delay, page 10, "Power-Up" */ 95bf1ae442SVikas Manocha FMC_BUSY_WAIT(); 96bf1ae442SVikas Manocha 97bf1ae442SVikas Manocha writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_PRECHARGE, 98bf1ae442SVikas Manocha &STM32_SDRAM_FMC->sdcmr); 99bf1ae442SVikas Manocha udelay(100); 100bf1ae442SVikas Manocha FMC_BUSY_WAIT(); 101bf1ae442SVikas Manocha 102bf1ae442SVikas Manocha writel((FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_AUTOREFRESH 103bf1ae442SVikas Manocha | 7 << FMC_SDCMR_NRFS_SHIFT), &STM32_SDRAM_FMC->sdcmr); 104bf1ae442SVikas Manocha udelay(100); 105bf1ae442SVikas Manocha FMC_BUSY_WAIT(); 106bf1ae442SVikas Manocha 107bf1ae442SVikas Manocha writel(FMC_SDCMR_BANK_1 | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT 108bf1ae442SVikas Manocha | SDRAM_MODE_CAS << SDRAM_MODE_CAS_SHIFT) 109bf1ae442SVikas Manocha << FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE, 110bf1ae442SVikas Manocha &STM32_SDRAM_FMC->sdcmr); 111bf1ae442SVikas Manocha udelay(100); 112bf1ae442SVikas Manocha FMC_BUSY_WAIT(); 113bf1ae442SVikas Manocha 114bf1ae442SVikas Manocha writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_NORMAL, 115bf1ae442SVikas Manocha &STM32_SDRAM_FMC->sdcmr); 116bf1ae442SVikas Manocha FMC_BUSY_WAIT(); 117bf1ae442SVikas Manocha 118bf1ae442SVikas Manocha /* Refresh timer */ 119bf1ae442SVikas Manocha writel(SDRAM_TREF, &STM32_SDRAM_FMC->sdrtr); 120bf1ae442SVikas Manocha 121bf1ae442SVikas Manocha return 0; 122bf1ae442SVikas Manocha } 123910a52edSVikas Manocha 124910a52edSVikas Manocha static int stm32_fmc_probe(struct udevice *dev) 125910a52edSVikas Manocha { 126*d0b24c1aSVikas Manocha #ifdef CONFIG_CLK 127*d0b24c1aSVikas Manocha int ret; 128*d0b24c1aSVikas Manocha struct clk clk; 129*d0b24c1aSVikas Manocha ret = clk_get_by_index(dev, 0, &clk); 130*d0b24c1aSVikas Manocha if (ret < 0) 131*d0b24c1aSVikas Manocha return ret; 132*d0b24c1aSVikas Manocha 133*d0b24c1aSVikas Manocha ret = clk_enable(&clk); 134*d0b24c1aSVikas Manocha 135*d0b24c1aSVikas Manocha if (ret) { 136*d0b24c1aSVikas Manocha dev_err(dev, "failed to enable clock\n"); 137*d0b24c1aSVikas Manocha return ret; 138*d0b24c1aSVikas Manocha } 139*d0b24c1aSVikas Manocha #endif 140910a52edSVikas Manocha stm32_sdram_init(); 141910a52edSVikas Manocha return 0; 142910a52edSVikas Manocha } 143910a52edSVikas Manocha 144910a52edSVikas Manocha static int stm32_fmc_get_info(struct udevice *dev, struct ram_info *info) 145910a52edSVikas Manocha { 146910a52edSVikas Manocha info->size = CONFIG_SYS_RAM_SIZE; 147910a52edSVikas Manocha return 0; 148910a52edSVikas Manocha } 149910a52edSVikas Manocha 150910a52edSVikas Manocha static struct ram_ops stm32_fmc_ops = { 151910a52edSVikas Manocha .get_info = stm32_fmc_get_info, 152910a52edSVikas Manocha }; 153910a52edSVikas Manocha 154910a52edSVikas Manocha static const struct udevice_id stm32_fmc_ids[] = { 155910a52edSVikas Manocha { .compatible = "st,stm32-fmc" }, 156910a52edSVikas Manocha { } 157910a52edSVikas Manocha }; 158910a52edSVikas Manocha 159910a52edSVikas Manocha U_BOOT_DRIVER(stm32_fmc) = { 160910a52edSVikas Manocha .name = "stm32_fmc", 161910a52edSVikas Manocha .id = UCLASS_RAM, 162910a52edSVikas Manocha .of_match = stm32_fmc_ids, 163910a52edSVikas Manocha .ops = &stm32_fmc_ops, 164910a52edSVikas Manocha .probe = stm32_fmc_probe, 165910a52edSVikas Manocha }; 166