1 /* 2 * Generic board initialisation, based on uboot-xburst and xburst-tools. 3 * 4 * Copyright (C) 2000-2009 Wolfgang Denk, DENX Software Engineering, <wd@denx.de> 5 * Copyright (C) 2005-2006 Ingenic Semiconductor, <jlwei@ingenic.cn> 6 * Copyright (C) 2006 Stefan Roese, DENX Software Engineering, sr@denx.de. 7 * Copyright (C) Xiangfu Liu <xiangfu.z@gmail.com> 8 * Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk> 9 * 10 * This program is free software; you can redistribute it and/or modify it under 11 * the terms of the GNU General Public License as published by the Free Software 12 * Foundation; either version 3 of the License, or (at your option) any later 13 * version. 14 * 15 * This program is distributed in the hope that it will be useful, but WITHOUT 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 18 * details. 19 * 20 * You should have received a copy of the GNU General Public License along with 21 * this program. If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 #ifdef CONFIG_CPU_JZ4730 25 #include "jz4730.h" 26 #include "jz4730_compat.h" 27 #else 28 #include "jz4740.h" 29 #endif 30 31 #include "sdram.h" 32 #include "usb_boot_defines.h" 33 34 /* These arguments are initialised by usbboot and are defined in... 35 /etc/xburst-tools/usbboot.cfg. */ 36 37 struct fw_args *fw_args; 38 volatile u32 FW_CPU_ID; 39 volatile u8 FW_SDRAM_BW16; 40 volatile u8 FW_SDRAM_BANK4; 41 volatile u8 FW_SDRAM_ROW; 42 volatile u8 FW_SDRAM_COL; 43 volatile u8 FW_CONFIG_MOBILE_SDRAM; 44 volatile u8 FW_IS_SHARE; 45 46 void load_args(void) 47 { 48 /* Get the fw args from memory. See head1.S for the memory layout. */ 49 50 fw_args = (struct fw_args *)0x80002008; 51 FW_CPU_ID = fw_args->cpu_id ; 52 53 /* Where the arguments have not been initialised, use the defaults. */ 54 55 FW_SDRAM_BW16 = FW_CPU_ID ? fw_args->bus_width : SDRAM_BW16; 56 FW_SDRAM_BANK4 = FW_CPU_ID ? fw_args->bank_num : SDRAM_BANK4; 57 FW_SDRAM_ROW = FW_CPU_ID ? fw_args->row_addr : SDRAM_ROW; 58 FW_SDRAM_COL = FW_CPU_ID ? fw_args->col_addr : SDRAM_COL; 59 FW_CONFIG_MOBILE_SDRAM = fw_args->is_mobile; 60 FW_IS_SHARE = fw_args->is_busshare; 61 } 62 63 /* Initialisation functions. */ 64 65 void gpio_init(void) 66 { 67 #ifdef CONFIG_CPU_JZ4730 68 /* 69 * Initialize SDRAM pins 70 */ 71 __gpio_as_emc(); 72 #else 73 /* 74 * Initialize NAND Flash Pins 75 */ 76 __gpio_as_nand(); 77 78 /* 79 * Initialize SDRAM pins 80 */ 81 __gpio_as_sdram_16bit_4720(); 82 #endif 83 } 84 85 void pll_init(void) 86 { 87 register unsigned int cfcr, plcr1; 88 int nf, pllout2; 89 90 /* See CPCCR (Clock Control Register). 91 * 0 == same frequency; 2 == f/3 92 */ 93 94 cfcr = CPM_CPCCR_CLKOEN | 95 CPM_CPCCR_PCS | 96 (0 << CPM_CPCCR_CDIV_BIT) | 97 (2 << CPM_CPCCR_HDIV_BIT) | 98 (2 << CPM_CPCCR_PDIV_BIT) | 99 (2 << CPM_CPCCR_MDIV_BIT) | 100 (2 << CPM_CPCCR_LDIV_BIT); 101 102 /* Init USB Host clock. 103 * Desired frequency == 48MHz 104 */ 105 106 #ifdef CONFIG_CPU_JZ4730 107 cfcr |= ((CFG_CPU_SPEED / 48000000 - 1) << 25); 108 #else 109 /* Determine the divider clock output based on the PCS bit. */ 110 pllout2 = (cfcr & CPM_CPCCR_PCS) ? CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2); 111 112 /* Divisor == UHCCDR + 1 */ 113 REG_CPM_UHCCDR = pllout2 / 48000000 - 1; 114 #endif 115 116 nf = CONFIG_SYS_CPU_SPEED * 2 / CONFIG_SYS_EXTAL; 117 plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */ 118 (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */ 119 (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */ 120 CPM_CPPCR_PLLEN; /* enable PLL */ 121 122 /* Update PLL and wait. */ 123 124 REG_CPM_CPCCR = cfcr; 125 REG_CPM_CPPCR = plcr1; 126 while (!__cpm_pll_is_on()); 127 } 128 129 void sdram_init(void) 130 { 131 register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns; 132 unsigned int pllout = __cpm_get_pllout(); 133 134 unsigned int cas_latency_sdmr[2] = { 135 EMC_SDMR_CAS_2, 136 EMC_SDMR_CAS_3, 137 }; 138 139 unsigned int cas_latency_dmcr[2] = { 140 1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */ 141 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */ 142 }; 143 144 /* Divisors for CPCCR values. */ 145 146 int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}; 147 148 cpu_clk = pllout / div[__cpm_get_cdiv()]; 149 mem_clk = pllout / div[__cpm_get_mdiv()]; 150 151 REG_EMC_BCR = 0; /* Disable bus release */ 152 REG_EMC_RTCSR = 0; /* Disable clock for counting */ 153 154 /* Fault DMCR value for mode register setting*/ 155 dmcr0 = (0<<EMC_DMCR_RA_BIT) | 156 (0<<EMC_DMCR_CA_BIT) | 157 (0<<EMC_DMCR_BA_BIT) | 158 (FW_SDRAM_BW16<<EMC_DMCR_BW_BIT) | 159 EMC_DMCR_EPIN | 160 cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]; 161 162 /* Basic DMCR value */ 163 dmcr = ((FW_SDRAM_ROW-SDRAM_ROW0)<<EMC_DMCR_RA_BIT) | 164 ((FW_SDRAM_COL-SDRAM_COL0)<<EMC_DMCR_CA_BIT) | 165 ((FW_SDRAM_BANK4-SDRAM_BANK40)<<EMC_DMCR_BA_BIT) | 166 (FW_SDRAM_BW16<<EMC_DMCR_BW_BIT) | 167 EMC_DMCR_EPIN | 168 cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]; 169 170 /* SDRAM timimg */ 171 ns = 1000000000 / mem_clk; 172 tmp = SDRAM_TRAS/ns; 173 if (tmp < 4) tmp = 4; 174 if (tmp > 11) tmp = 11; 175 dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT); 176 tmp = SDRAM_RCD/ns; 177 if (tmp > 3) tmp = 3; 178 dmcr |= (tmp << EMC_DMCR_RCD_BIT); 179 tmp = SDRAM_TPC/ns; 180 if (tmp > 7) tmp = 7; 181 dmcr |= (tmp << EMC_DMCR_TPC_BIT); 182 tmp = SDRAM_TRWL/ns; 183 if (tmp > 3) tmp = 3; 184 dmcr |= (tmp << EMC_DMCR_TRWL_BIT); 185 tmp = (SDRAM_TRAS + SDRAM_TPC)/ns; 186 if (tmp > 14) tmp = 14; 187 dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT); 188 189 /* SDRAM mode value */ 190 sdmode = EMC_SDMR_BT_SEQ | 191 EMC_SDMR_OM_NORMAL | 192 EMC_SDMR_BL_4 | 193 cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)]; 194 195 /* jz4730 additional measures */ 196 #ifdef CONFIG_CPU_JZ4730 197 if (FW_SDRAM_BW16) 198 sdmode <<= 1; 199 else 200 sdmode <<= 2; 201 #endif 202 203 /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */ 204 REG_EMC_DMCR = dmcr; 205 REG8(EMC_SDMR0|sdmode) = 0; 206 207 /* jz4730 additional measures */ 208 #ifdef CONFIG_CPU_JZ4730 209 REG8(EMC_SDMR1|sdmode) = 0; 210 #endif 211 212 /* Wait for precharge, > 200us */ 213 tmp = (cpu_clk / 1000000) * 1000; 214 while (tmp--); 215 216 /* Stage 2. Enable auto-refresh */ 217 REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH; 218 219 tmp = SDRAM_TREF/ns; 220 tmp = tmp/64 + 1; 221 if (tmp > 0xff) tmp = 0xff; 222 REG_EMC_RTCOR = tmp; 223 REG_EMC_RTCNT = 0; 224 REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */ 225 226 /* Wait for number of auto-refresh cycles */ 227 tmp = (cpu_clk / 1000000) * 1000; 228 while (tmp--); 229 230 /* Stage 3. Mode Register Set */ 231 REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET; 232 REG8(EMC_SDMR0|sdmode) = 0; 233 234 /* jz4730 additional measures */ 235 #ifdef CONFIG_CPU_JZ4730 236 REG8(EMC_SDMR1|sdmode) = 0; 237 #endif 238 239 /* Set back to basic DMCR value */ 240 REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET; 241 242 /* everything is ok now */ 243 }