1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/stage1/board-nanonote.c Sun Jun 07 23:06:08 2015 +0200
1.3 @@ -0,0 +1,210 @@
1.4 +/*
1.5 + * Ben NanoNote board initialisation, based on uboot-xburst and xburst-tools.
1.6 + *
1.7 + * Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
1.8 + * Copyright (C) Xiangfu Liu <xiangfu.z@gmail.com>
1.9 + * Copyright (C) 2006 Ingenic Semiconductor, <jlwei@ingenic.cn>
1.10 + * Copyright (C) 2000-2009 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
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 +#include "jz4740.h"
1.27 +#include "configs.h"
1.28 +#include "nanonote.h"
1.29 +#include "usb_boot_defines.h"
1.30 +
1.31 +/* These arguments are initialised by usbboot and are defined in...
1.32 + /etc/xburst-tools/usbboot.cfg. */
1.33 +
1.34 +struct fw_args *fw_args;
1.35 +volatile u32 CPU_ID;
1.36 +volatile u8 SDRAM_BW16;
1.37 +volatile u8 SDRAM_BANK4;
1.38 +volatile u8 SDRAM_ROW;
1.39 +volatile u8 SDRAM_COL;
1.40 +volatile u8 CONFIG_MOBILE_SDRAM;
1.41 +volatile u8 IS_SHARE;
1.42 +
1.43 +void load_args(void)
1.44 +{
1.45 + /* Get the fw args from memory. See head1.S for the memory layout. */
1.46 +
1.47 + fw_args = (struct fw_args *)0x80002008;
1.48 + CPU_ID = fw_args->cpu_id ;
1.49 + SDRAM_BW16 = fw_args->bus_width;
1.50 + SDRAM_BANK4 = fw_args->bank_num;
1.51 + SDRAM_ROW = fw_args->row_addr;
1.52 + SDRAM_COL = fw_args->col_addr;
1.53 + CONFIG_MOBILE_SDRAM = fw_args->is_mobile;
1.54 + IS_SHARE = fw_args->is_busshare;
1.55 +}
1.56 +
1.57 +/* Initialisation functions. */
1.58 +
1.59 +void gpio_init(void)
1.60 +{
1.61 + /*
1.62 + * Initialize NAND Flash Pins
1.63 + */
1.64 + __gpio_as_nand();
1.65 +
1.66 + /*
1.67 + * Initialize SDRAM pins
1.68 + */
1.69 + __gpio_as_sdram_16bit_4720();
1.70 +}
1.71 +
1.72 +void pll_init(void)
1.73 +{
1.74 + register unsigned int cfcr, plcr1;
1.75 + int nf, pllout2;
1.76 +
1.77 + /* See CPCCR (Clock Control Register).
1.78 + * 0 == same frequency; 2 == f/3
1.79 + */
1.80 +
1.81 + cfcr = CPM_CPCCR_CLKOEN |
1.82 + CPM_CPCCR_PCS |
1.83 + (0 << CPM_CPCCR_CDIV_BIT) |
1.84 + (2 << CPM_CPCCR_HDIV_BIT) |
1.85 + (2 << CPM_CPCCR_PDIV_BIT) |
1.86 + (2 << CPM_CPCCR_MDIV_BIT) |
1.87 + (2 << CPM_CPCCR_LDIV_BIT);
1.88 +
1.89 + /* Determine the divider clock output based on the PCS bit. */
1.90 +
1.91 + pllout2 = (cfcr & CPM_CPCCR_PCS) ? CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2);
1.92 +
1.93 + /* Init USB Host clock.
1.94 + * Divisor == UHCCDR + 1
1.95 + * Desired frequency == 48MHz
1.96 + */
1.97 +
1.98 + REG_CPM_UHCCDR = pllout2 / 48000000 - 1;
1.99 +
1.100 + nf = CONFIG_SYS_CPU_SPEED * 2 / CONFIG_SYS_EXTAL;
1.101 + plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
1.102 + (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
1.103 + (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
1.104 + CPM_CPPCR_PLLEN; /* enable PLL */
1.105 +
1.106 + /* Update PLL and wait. */
1.107 +
1.108 + REG_CPM_CPCCR = cfcr;
1.109 + REG_CPM_CPPCR = plcr1;
1.110 + while (!__cpm_pll_is_on());
1.111 +}
1.112 +
1.113 +void sdram_init(void)
1.114 +{
1.115 + register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;
1.116 + unsigned int pllout = __cpm_get_pllout();
1.117 +
1.118 + unsigned int cas_latency_sdmr[2] = {
1.119 + EMC_SDMR_CAS_2,
1.120 + EMC_SDMR_CAS_3,
1.121 + };
1.122 +
1.123 + unsigned int cas_latency_dmcr[2] = {
1.124 + 1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */
1.125 + 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */
1.126 + };
1.127 +
1.128 + /* Divisors for CPCCR values. */
1.129 +
1.130 + int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
1.131 +
1.132 + cpu_clk = pllout / div[__cpm_get_cdiv()];
1.133 + mem_clk = pllout / div[__cpm_get_mdiv()];
1.134 +
1.135 + REG_EMC_BCR = 0; /* Disable bus release */
1.136 + REG_EMC_RTCSR = 0; /* Disable clock for counting */
1.137 +
1.138 + /* Fault DMCR value for mode register setting*/
1.139 +#define SDRAM_ROW0 11
1.140 +#define SDRAM_COL0 8
1.141 +#define SDRAM_BANK40 0
1.142 +
1.143 + dmcr0 = ((SDRAM_ROW0-11)<<EMC_DMCR_RA_BIT) |
1.144 + ((SDRAM_COL0-8)<<EMC_DMCR_CA_BIT) |
1.145 + (SDRAM_BANK40<<EMC_DMCR_BA_BIT) |
1.146 + (SDRAM_BW16<<EMC_DMCR_BW_BIT) |
1.147 + EMC_DMCR_EPIN |
1.148 + cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
1.149 +
1.150 + /* Basic DMCR value */
1.151 + dmcr = ((SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) |
1.152 + ((SDRAM_COL-8)<<EMC_DMCR_CA_BIT) |
1.153 + (SDRAM_BANK4<<EMC_DMCR_BA_BIT) |
1.154 + (SDRAM_BW16<<EMC_DMCR_BW_BIT) |
1.155 + EMC_DMCR_EPIN |
1.156 + cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
1.157 +
1.158 + /* SDRAM timimg */
1.159 + ns = 1000000000 / mem_clk;
1.160 + tmp = SDRAM_TRAS/ns;
1.161 + if (tmp < 4) tmp = 4;
1.162 + if (tmp > 11) tmp = 11;
1.163 + dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT);
1.164 + tmp = SDRAM_RCD/ns;
1.165 + if (tmp > 3) tmp = 3;
1.166 + dmcr |= (tmp << EMC_DMCR_RCD_BIT);
1.167 + tmp = SDRAM_TPC/ns;
1.168 + if (tmp > 7) tmp = 7;
1.169 + dmcr |= (tmp << EMC_DMCR_TPC_BIT);
1.170 + tmp = SDRAM_TRWL/ns;
1.171 + if (tmp > 3) tmp = 3;
1.172 + dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
1.173 + tmp = (SDRAM_TRAS + SDRAM_TPC)/ns;
1.174 + if (tmp > 14) tmp = 14;
1.175 + dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);
1.176 +
1.177 + /* SDRAM mode value */
1.178 + sdmode = EMC_SDMR_BT_SEQ |
1.179 + EMC_SDMR_OM_NORMAL |
1.180 + EMC_SDMR_BL_4 |
1.181 + cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
1.182 +
1.183 + /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
1.184 + REG_EMC_DMCR = dmcr;
1.185 + REG8(EMC_SDMR0|sdmode) = 0;
1.186 +
1.187 + /* Wait for precharge, > 200us */
1.188 + tmp = (cpu_clk / 1000000) * 1000;
1.189 + while (tmp--);
1.190 +
1.191 + /* Stage 2. Enable auto-refresh */
1.192 + REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH;
1.193 +
1.194 + tmp = SDRAM_TREF/ns;
1.195 + tmp = tmp/64 + 1;
1.196 + if (tmp > 0xff) tmp = 0xff;
1.197 + REG_EMC_RTCOR = tmp;
1.198 + REG_EMC_RTCNT = 0;
1.199 + REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */
1.200 +
1.201 + /* Wait for number of auto-refresh cycles */
1.202 + tmp = (cpu_clk / 1000000) * 1000;
1.203 + while (tmp--);
1.204 +
1.205 + /* Stage 3. Mode Register Set */
1.206 + REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
1.207 + REG8(EMC_SDMR0|sdmode) = 0;
1.208 +
1.209 + /* Set back to basic DMCR value */
1.210 + REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
1.211 +
1.212 + /* everything is ok now */
1.213 +}