1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2012, Stefano Babic <sbabic@denx.de> 4 */ 5 6 #include <asm/io.h> 7 #include <linux/errno.h> 8 #include <asm/arch/imx-regs.h> 9 #include <linux/types.h> 10 #include <asm/arch/sys_proto.h> 11 12 #define ESDCTL_DDR2_EMR2 0x04000000 13 #define ESDCTL_DDR2_EMR3 0x06000000 14 #define ESDCTL_PRECHARGE 0x00000400 15 #define ESDCTL_DDR2_EN_DLL 0x02000400 16 #define ESDCTL_DDR2_RESET_DLL 0x00000333 17 #define ESDCTL_DDR2_MR 0x00000233 18 #define ESDCTL_DDR2_OCD_DEFAULT 0x02000780 19 20 enum { 21 SMODE_NORMAL = 0, 22 SMODE_PRECHARGE, 23 SMODE_AUTO_REFRESH, 24 SMODE_LOAD_REG, 25 SMODE_MANUAL_REFRESH 26 }; 27 28 #define set_mode(x, en, m) (x | (en << 31) | (m << 28)) 29 30 static inline void dram_wait(unsigned int count) 31 { 32 volatile unsigned int wait = count; 33 34 while (wait--) 35 ; 36 37 } 38 39 void mx3_setup_sdram_bank(u32 start_address, u32 ddr2_config, 40 u32 row, u32 col, u32 dsize, u32 refresh) 41 { 42 struct esdc_regs *esdc = (struct esdc_regs *)ESDCTL_BASE_ADDR; 43 u32 *cfg_reg, *ctl_reg; 44 u32 val; 45 u32 ctlval; 46 47 switch (start_address) { 48 case CSD0_BASE_ADDR: 49 cfg_reg = &esdc->esdcfg0; 50 ctl_reg = &esdc->esdctl0; 51 break; 52 case CSD1_BASE_ADDR: 53 cfg_reg = &esdc->esdcfg1; 54 ctl_reg = &esdc->esdctl1; 55 break; 56 default: 57 return; 58 } 59 60 /* The MX35 supports 11 up to 14 rows */ 61 if (row < 11 || row > 14 || col < 8 || col > 10) 62 return; 63 ctlval = (row - 11) << 24 | (col - 8) << 20 | (dsize << 16); 64 65 /* Initialize MISC register for DDR2 */ 66 val = ESDC_MISC_RST | ESDC_MISC_MDDR_EN | ESDC_MISC_MDDR_DL_RST | 67 ESDC_MISC_DDR_EN | ESDC_MISC_DDR2_EN; 68 writel(val, &esdc->esdmisc); 69 val &= ~(ESDC_MISC_RST | ESDC_MISC_MDDR_DL_RST); 70 writel(val, &esdc->esdmisc); 71 72 /* 73 * according to DDR2 specs, wait a while before 74 * the PRECHARGE_ALL command 75 */ 76 dram_wait(0x20000); 77 78 /* Load DDR2 config and timing */ 79 writel(ddr2_config, cfg_reg); 80 81 /* Precharge ALL */ 82 writel(set_mode(ctlval, 1, SMODE_PRECHARGE), 83 ctl_reg); 84 writel(0xda, start_address + ESDCTL_PRECHARGE); 85 86 /* Load mode */ 87 writel(set_mode(ctlval, 1, SMODE_LOAD_REG), 88 ctl_reg); 89 writeb(0xda, start_address + ESDCTL_DDR2_EMR2); /* EMRS2 */ 90 writeb(0xda, start_address + ESDCTL_DDR2_EMR3); /* EMRS3 */ 91 writeb(0xda, start_address + ESDCTL_DDR2_EN_DLL); /* Enable DLL */ 92 writeb(0xda, start_address + ESDCTL_DDR2_RESET_DLL); /* Reset DLL */ 93 94 /* Precharge ALL */ 95 writel(set_mode(ctlval, 1, SMODE_PRECHARGE), 96 ctl_reg); 97 writel(0xda, start_address + ESDCTL_PRECHARGE); 98 99 /* Set mode auto refresh : at least two refresh are required */ 100 writel(set_mode(ctlval, 1, SMODE_AUTO_REFRESH), 101 ctl_reg); 102 writel(0xda, start_address); 103 writel(0xda, start_address); 104 105 writel(set_mode(ctlval, 1, SMODE_LOAD_REG), 106 ctl_reg); 107 writeb(0xda, start_address + ESDCTL_DDR2_MR); 108 writeb(0xda, start_address + ESDCTL_DDR2_OCD_DEFAULT); 109 110 /* OCD mode exit */ 111 writeb(0xda, start_address + ESDCTL_DDR2_EN_DLL); /* Enable DLL */ 112 113 /* Set normal mode */ 114 writel(set_mode(ctlval, 1, SMODE_NORMAL) | refresh, 115 ctl_reg); 116 117 dram_wait(0x20000); 118 119 /* Do not set delay lines, only for MDDR */ 120 } 121