1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/stage1/board.c Tue Jun 09 21:36:40 2015 +0200
1.3 @@ -0,0 +1,231 @@
1.4 +/*
1.5 + * Generic board initialisation, based on uboot-xburst and xburst-tools.
1.6 + *
1.7 + * Copyright (C) 2000-2009 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
1.8 + * Copyright (C) 2005-2006 Ingenic Semiconductor, <jlwei@ingenic.cn>
1.9 + * Copyright (C) Xiangfu Liu <xiangfu.z@gmail.com>
1.10 + * Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
1.11 + *
1.12 + * This program is free software; you can redistribute it and/or modify it under
1.13 + * the terms of the GNU General Public License as published by the Free Software
1.14 + * Foundation; either version 3 of the License, or (at your option) any later
1.15 + * version.
1.16 + *
1.17 + * This program is distributed in the hope that it will be useful, but WITHOUT
1.18 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.19 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.20 + * details.
1.21 + *
1.22 + * You should have received a copy of the GNU General Public License along with
1.23 + * this program. If not, see <http://www.gnu.org/licenses/>.
1.24 + */
1.25 +
1.26 +#ifdef CONFIG_CPU_JZ4730
1.27 +#include "jz4730.h"
1.28 +#else
1.29 +#include "jz4740.h"
1.30 +#endif
1.31 +
1.32 +#include "sdram.h"
1.33 +#include "usb_boot_defines.h"
1.34 +
1.35 +/* These arguments are initialised by usbboot and are defined in...
1.36 + /etc/xburst-tools/usbboot.cfg. */
1.37 +
1.38 +struct fw_args *fw_args;
1.39 +volatile u32 FW_CPU_ID;
1.40 +volatile u8 FW_SDRAM_BW16;
1.41 +volatile u8 FW_SDRAM_BANK4;
1.42 +volatile u8 FW_SDRAM_ROW;
1.43 +volatile u8 FW_SDRAM_COL;
1.44 +volatile u8 FW_CONFIG_MOBILE_SDRAM;
1.45 +volatile u8 FW_IS_SHARE;
1.46 +
1.47 +void load_args(void)
1.48 +{
1.49 + /* Get the fw args from memory. See head1.S for the memory layout. */
1.50 +
1.51 + fw_args = (struct fw_args *)0x80002008;
1.52 + FW_CPU_ID = fw_args->cpu_id ;
1.53 + FW_SDRAM_BW16 = fw_args->bus_width;
1.54 + FW_SDRAM_BANK4 = fw_args->bank_num;
1.55 + FW_SDRAM_ROW = fw_args->row_addr;
1.56 + FW_SDRAM_COL = fw_args->col_addr;
1.57 + FW_CONFIG_MOBILE_SDRAM = fw_args->is_mobile;
1.58 + FW_IS_SHARE = fw_args->is_busshare;
1.59 +}
1.60 +
1.61 +/* Initialisation functions. */
1.62 +
1.63 +void gpio_init(void)
1.64 +{
1.65 + /*
1.66 + * Initialize NAND Flash Pins
1.67 + */
1.68 + __gpio_as_nand();
1.69 +
1.70 + /*
1.71 + * Initialize SDRAM pins
1.72 + */
1.73 + __gpio_as_sdram_16bit_4720();
1.74 +}
1.75 +
1.76 +void pll_init(void)
1.77 +{
1.78 + register unsigned int cfcr, plcr1;
1.79 + int nf, pllout2;
1.80 +
1.81 + /* See CPCCR (Clock Control Register).
1.82 + * 0 == same frequency; 2 == f/3
1.83 + */
1.84 +
1.85 + cfcr = CPM_CPCCR_CLKOEN |
1.86 + CPM_CPCCR_PCS |
1.87 + (0 << CPM_CPCCR_CDIV_BIT) |
1.88 + (2 << CPM_CPCCR_HDIV_BIT) |
1.89 + (2 << CPM_CPCCR_PDIV_BIT) |
1.90 + (2 << CPM_CPCCR_MDIV_BIT) |
1.91 + (2 << CPM_CPCCR_LDIV_BIT);
1.92 +
1.93 + /* Init USB Host clock.
1.94 + * Desired frequency == 48MHz
1.95 + */
1.96 +
1.97 +#ifdef CONFIG_CPU_JZ4730
1.98 + cfcr |= ((CFG_CPU_SPEED / 48000000 - 1) << 25);
1.99 +#else
1.100 + /* Determine the divider clock output based on the PCS bit. */
1.101 + pllout2 = (cfcr & CPM_CPCCR_PCS) ? CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2);
1.102 +
1.103 + /* Divisor == UHCCDR + 1 */
1.104 + REG_CPM_UHCCDR = pllout2 / 48000000 - 1;
1.105 +#endif
1.106 +
1.107 + nf = CONFIG_SYS_CPU_SPEED * 2 / CONFIG_SYS_EXTAL;
1.108 + plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
1.109 + (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
1.110 + (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
1.111 + CPM_CPPCR_PLLEN; /* enable PLL */
1.112 +
1.113 + /* Update PLL and wait. */
1.114 +
1.115 + REG_CPM_CPCCR = cfcr;
1.116 + REG_CPM_CPPCR = plcr1;
1.117 + while (!__cpm_pll_is_on());
1.118 +}
1.119 +
1.120 +void sdram_init(void)
1.121 +{
1.122 + register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;
1.123 + unsigned int pllout = __cpm_get_pllout();
1.124 +
1.125 + unsigned int cas_latency_sdmr[2] = {
1.126 + EMC_SDMR_CAS_2,
1.127 + EMC_SDMR_CAS_3,
1.128 + };
1.129 +
1.130 + unsigned int cas_latency_dmcr[2] = {
1.131 + 1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */
1.132 + 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */
1.133 + };
1.134 +
1.135 + /* Divisors for CPCCR values. */
1.136 +
1.137 + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
1.138 +
1.139 + cpu_clk = pllout / div[__cpm_get_cdiv()];
1.140 + mem_clk = pllout / div[__cpm_get_mdiv()];
1.141 +
1.142 + REG_EMC_BCR = 0; /* Disable bus release */
1.143 + REG_EMC_RTCSR = 0; /* Disable clock for counting */
1.144 +
1.145 + /* Fault DMCR value for mode register setting*/
1.146 + dmcr0 = (0<<EMC_DMCR_RA_BIT) |
1.147 + (0<<EMC_DMCR_CA_BIT) |
1.148 + (0<<EMC_DMCR_BA_BIT) |
1.149 + (FW_SDRAM_BW16<<EMC_DMCR_BW_BIT) |
1.150 + EMC_DMCR_EPIN |
1.151 + cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
1.152 +
1.153 + /* Basic DMCR value */
1.154 + dmcr = ((FW_SDRAM_ROW-SDRAM_ROW0)<<EMC_DMCR_RA_BIT) |
1.155 + ((FW_SDRAM_COL-SDRAM_COL0)<<EMC_DMCR_CA_BIT) |
1.156 + ((FW_SDRAM_BANK4-SDRAM_BANK40)<<EMC_DMCR_BA_BIT) |
1.157 + (FW_SDRAM_BW16<<EMC_DMCR_BW_BIT) |
1.158 + EMC_DMCR_EPIN |
1.159 + cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
1.160 +
1.161 + /* SDRAM timimg */
1.162 + ns = 1000000000 / mem_clk;
1.163 + tmp = SDRAM_TRAS/ns;
1.164 + if (tmp < 4) tmp = 4;
1.165 + if (tmp > 11) tmp = 11;
1.166 + dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT);
1.167 + tmp = SDRAM_RCD/ns;
1.168 + if (tmp > 3) tmp = 3;
1.169 + dmcr |= (tmp << EMC_DMCR_RCD_BIT);
1.170 + tmp = SDRAM_TPC/ns;
1.171 + if (tmp > 7) tmp = 7;
1.172 + dmcr |= (tmp << EMC_DMCR_TPC_BIT);
1.173 + tmp = SDRAM_TRWL/ns;
1.174 + if (tmp > 3) tmp = 3;
1.175 + dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
1.176 + tmp = (SDRAM_TRAS + SDRAM_TPC)/ns;
1.177 + if (tmp > 14) tmp = 14;
1.178 + dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);
1.179 +
1.180 + /* SDRAM mode value */
1.181 + sdmode = EMC_SDMR_BT_SEQ |
1.182 + EMC_SDMR_OM_NORMAL |
1.183 + EMC_SDMR_BL_4 |
1.184 + cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
1.185 +
1.186 + /* jz4730 additional measures */
1.187 +#ifdef CONFIG_CPU_JZ4730
1.188 + if (FW_SDRAM_BW16)
1.189 + sdmode <<= 1;
1.190 + else
1.191 + sdmode <<= 2;
1.192 +#endif
1.193 +
1.194 + /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
1.195 + REG_EMC_DMCR = dmcr;
1.196 + REG8(EMC_SDMR0|sdmode) = 0;
1.197 +
1.198 + /* jz4730 additional measures */
1.199 +#ifdef CONFIG_CPU_JZ4730
1.200 + REG8(EMC_SDMR1|sdmode) = 0;
1.201 +#endif
1.202 +
1.203 + /* Wait for precharge, > 200us */
1.204 + tmp = (cpu_clk / 1000000) * 1000;
1.205 + while (tmp--);
1.206 +
1.207 + /* Stage 2. Enable auto-refresh */
1.208 + REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH;
1.209 +
1.210 + tmp = SDRAM_TREF/ns;
1.211 + tmp = tmp/64 + 1;
1.212 + if (tmp > 0xff) tmp = 0xff;
1.213 + REG_EMC_RTCOR = tmp;
1.214 + REG_EMC_RTCNT = 0;
1.215 + REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */
1.216 +
1.217 + /* Wait for number of auto-refresh cycles */
1.218 + tmp = (cpu_clk / 1000000) * 1000;
1.219 + while (tmp--);
1.220 +
1.221 + /* Stage 3. Mode Register Set */
1.222 + REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
1.223 + REG8(EMC_SDMR0|sdmode) = 0;
1.224 +
1.225 + /* jz4730 additional measures */
1.226 +#ifdef CONFIG_CPU_JZ4730
1.227 + REG8(EMC_SDMR1|sdmode) = 0;
1.228 +#endif
1.229 +
1.230 + /* Set back to basic DMCR value */
1.231 + REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
1.232 +
1.233 + /* everything is ok now */
1.234 +}