NanoPayload

Annotated board-nanonote.c

16:9904a4a3b363
2015-06-07 Paul Boddie Split initialisation into separate stage-related files. Fixed the system map file generation in the Makefile. Tidied up the assembly language header sections.
paul@0 1
/*
paul@0 2
 * Ben NanoNote board initialisation, based on uboot-xburst and xburst-tools.
paul@0 3
 *
paul@0 4
 * Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
paul@0 5
 * Copyright (C) Xiangfu Liu <xiangfu.z@gmail.com>
paul@9 6
 * Copyright (C) 2006 Ingenic Semiconductor, <jlwei@ingenic.cn>
paul@14 7
 * Copyright (C) 2000-2009 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
paul@0 8
 *
paul@0 9
 * This program is free software; you can redistribute it and/or modify it under
paul@0 10
 * the terms of the GNU General Public License as published by the Free Software
paul@0 11
 * Foundation; either version 3 of the License, or (at your option) any later
paul@0 12
 * version.
paul@0 13
 *
paul@0 14
 * This program is distributed in the hope that it will be useful, but WITHOUT
paul@0 15
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
paul@0 16
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
paul@0 17
 * details.
paul@0 18
 *
paul@0 19
 * You should have received a copy of the GNU General Public License along with
paul@0 20
 * this program.  If not, see <http://www.gnu.org/licenses/>.
paul@0 21
 */
paul@0 22
paul@0 23
#include "jz4740.h"
paul@0 24
#include "configs.h"
paul@2 25
#include "nanonote.h"
paul@10 26
#include "usb_boot_defines.h"
paul@10 27
paul@10 28
/* These arguments are initialised by usbboot and are defined in...
paul@10 29
   /etc/xburst-tools/usbboot.cfg. */
paul@10 30
paul@10 31
struct fw_args *fw_args;
paul@10 32
volatile u32 CPU_ID;
paul@10 33
volatile u32 UART_BASE;
paul@10 34
volatile u32 CONFIG_BAUDRATE;
paul@10 35
volatile u8 SDRAM_BW16;
paul@10 36
volatile u8 SDRAM_BANK4;
paul@10 37
volatile u8 SDRAM_ROW;
paul@10 38
volatile u8 SDRAM_COL;
paul@10 39
volatile u8 CONFIG_MOBILE_SDRAM;
paul@10 40
volatile u32 CFG_CPU_SPEED;
paul@10 41
volatile u32 CFG_EXTAL;
paul@10 42
volatile u8 PHM_DIV;
paul@10 43
volatile u8 IS_SHARE;
paul@10 44
paul@10 45
void load_args(void)
paul@10 46
{
paul@10 47
	/* Get the fw args from memory. See head.S for the memory layout. */
paul@10 48
paul@10 49
        fw_args = (struct fw_args *)0x80002008;
paul@10 50
        CPU_ID = fw_args->cpu_id ;
paul@10 51
        CFG_EXTAL = (u32)fw_args->ext_clk * 1000000;
paul@10 52
        CFG_CPU_SPEED = (u32)fw_args->cpu_speed * CFG_EXTAL ;
paul@10 53
        if (CFG_EXTAL == 19000000) {
paul@10 54
                CFG_EXTAL = 19200000;
paul@10 55
                CFG_CPU_SPEED = 192000000;
paul@10 56
        }
paul@10 57
        PHM_DIV = fw_args->phm_div;
paul@10 58
        UART_BASE = UART0_BASE + fw_args->use_uart * 0x1000;
paul@10 59
        CONFIG_BAUDRATE = fw_args->boudrate;
paul@10 60
        SDRAM_BW16 = fw_args->bus_width;
paul@10 61
        SDRAM_BANK4 = fw_args->bank_num;
paul@10 62
        SDRAM_ROW = fw_args->row_addr;
paul@10 63
        SDRAM_COL = fw_args->col_addr;
paul@10 64
        CONFIG_MOBILE_SDRAM = fw_args->is_mobile;
paul@10 65
        IS_SHARE = fw_args->is_busshare;
paul@10 66
}
paul@10 67
paul@10 68
/* Initialisation functions. */
paul@0 69
paul@0 70
void gpio_init(void)
paul@0 71
{
paul@0 72
	/*
paul@0 73
	 * Initialize NAND Flash Pins
paul@0 74
	 */
paul@0 75
	__gpio_as_nand();
paul@0 76
paul@0 77
	/*
paul@0 78
	 * Initialize SDRAM pins
paul@0 79
	 */
paul@0 80
	__gpio_as_sdram_32bit();
paul@6 81
}
paul@0 82
paul@0 83
void pll_init(void)
paul@0 84
{
paul@0 85
	register unsigned int cfcr, plcr1;
paul@0 86
	int n2FR[33] = {
paul@0 87
		0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
paul@0 88
		7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
paul@0 89
		9
paul@0 90
	};
paul@0 91
	int nf, pllout2;
paul@0 92
paul@0 93
	cfcr = CPM_CPCCR_CLKOEN |
paul@0 94
		(n2FR[PHM_DIV] << CPM_CPCCR_CDIV_BIT) |
paul@0 95
		(n2FR[PHM_DIV] << CPM_CPCCR_HDIV_BIT) |
paul@0 96
		(n2FR[PHM_DIV] << CPM_CPCCR_PDIV_BIT) |
paul@0 97
		(n2FR[PHM_DIV] << CPM_CPCCR_MDIV_BIT) |
paul@0 98
		(n2FR[PHM_DIV] << CPM_CPCCR_LDIV_BIT);
paul@0 99
paul@0 100
	pllout2 = (cfcr & CPM_CPCCR_PCS) ? CFG_CPU_SPEED : (CFG_CPU_SPEED / 2);
paul@0 101
paul@0 102
	/* Init USB Host clock, pllout2 must be n*48MHz */
paul@0 103
	REG_CPM_UHCCDR = pllout2 / 48000000 - 1;
paul@0 104
paul@0 105
	nf = CFG_CPU_SPEED * 2 / CFG_EXTAL;
paul@0 106
	plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
paul@0 107
		(0 << CPM_CPPCR_PLLN_BIT) |	/* RD=0, NR=2 */
paul@0 108
		(0 << CPM_CPPCR_PLLOD_BIT) |    /* OD=0, NO=1 */
paul@0 109
		(0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
paul@0 110
		CPM_CPPCR_PLLEN;                /* enable PLL */
paul@0 111
paul@0 112
	/* init PLL */
paul@0 113
	REG_CPM_CPCCR = cfcr;
paul@0 114
	REG_CPM_CPPCR = plcr1;
paul@0 115
}
paul@0 116
paul@0 117
void sdram_init(void)
paul@0 118
{
paul@0 119
	register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;
paul@0 120
paul@0 121
	unsigned int cas_latency_sdmr[2] = {
paul@0 122
		EMC_SDMR_CAS_2,
paul@0 123
		EMC_SDMR_CAS_3,
paul@0 124
	};
paul@0 125
paul@0 126
	unsigned int cas_latency_dmcr[2] = {
paul@0 127
		1 << EMC_DMCR_TCL_BIT,	/* CAS latency is 2 */
paul@0 128
		2 << EMC_DMCR_TCL_BIT	/* CAS latency is 3 */
paul@0 129
	};
paul@0 130
paul@0 131
	int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
paul@0 132
paul@0 133
	cpu_clk = CFG_CPU_SPEED;
paul@0 134
	mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
paul@0 135
paul@0 136
	REG_EMC_BCR = 0;	/* Disable bus release */
paul@0 137
	REG_EMC_RTCSR = 0;	/* Disable clock for counting */
paul@0 138
paul@0 139
	/* Fault DMCR value for mode register setting*/
paul@0 140
#define SDRAM_ROW0    11
paul@0 141
#define SDRAM_COL0     8
paul@0 142
#define SDRAM_BANK40   0
paul@0 143
paul@0 144
	dmcr0 = ((SDRAM_ROW0-11)<<EMC_DMCR_RA_BIT) |
paul@0 145
		((SDRAM_COL0-8)<<EMC_DMCR_CA_BIT) |
paul@0 146
		(SDRAM_BANK40<<EMC_DMCR_BA_BIT) |
paul@0 147
		(SDRAM_BW16<<EMC_DMCR_BW_BIT) |
paul@0 148
		EMC_DMCR_EPIN |
paul@0 149
		cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
paul@0 150
paul@0 151
	/* Basic DMCR value */
paul@0 152
	dmcr = ((SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) |
paul@0 153
		((SDRAM_COL-8)<<EMC_DMCR_CA_BIT) |
paul@0 154
		(SDRAM_BANK4<<EMC_DMCR_BA_BIT) |
paul@0 155
		(SDRAM_BW16<<EMC_DMCR_BW_BIT) |
paul@0 156
		EMC_DMCR_EPIN |
paul@0 157
		cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
paul@0 158
paul@0 159
	/* SDRAM timimg */
paul@0 160
	ns = 1000000000 / mem_clk;
paul@0 161
	tmp = SDRAM_TRAS/ns;
paul@0 162
	if (tmp < 4) tmp = 4;
paul@0 163
	if (tmp > 11) tmp = 11;
paul@0 164
	dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT);
paul@0 165
	tmp = SDRAM_RCD/ns;
paul@0 166
	if (tmp > 3) tmp = 3;
paul@0 167
	dmcr |= (tmp << EMC_DMCR_RCD_BIT);
paul@0 168
	tmp = SDRAM_TPC/ns;
paul@0 169
	if (tmp > 7) tmp = 7;
paul@0 170
	dmcr |= (tmp << EMC_DMCR_TPC_BIT);
paul@0 171
	tmp = SDRAM_TRWL/ns;
paul@0 172
	if (tmp > 3) tmp = 3;
paul@0 173
	dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
paul@0 174
	tmp = (SDRAM_TRAS + SDRAM_TPC)/ns;
paul@0 175
	if (tmp > 14) tmp = 14;
paul@0 176
	dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);
paul@0 177
paul@0 178
	/* SDRAM mode value */
paul@0 179
	sdmode = EMC_SDMR_BT_SEQ | 
paul@0 180
		 EMC_SDMR_OM_NORMAL |
paul@0 181
		 EMC_SDMR_BL_4 | 
paul@0 182
		 cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
paul@0 183
paul@0 184
	/* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
paul@0 185
	REG_EMC_DMCR = dmcr;
paul@0 186
	REG8(EMC_SDMR0|sdmode) = 0;
paul@0 187
paul@0 188
	/* Wait for precharge, > 200us */
paul@0 189
	tmp = (cpu_clk / 1000000) * 1000;
paul@0 190
	while (tmp--);
paul@0 191
paul@0 192
	/* Stage 2. Enable auto-refresh */
paul@0 193
	REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH;
paul@0 194
paul@0 195
	tmp = SDRAM_TREF/ns;
paul@0 196
	tmp = tmp/64 + 1;
paul@0 197
	if (tmp > 0xff) tmp = 0xff;
paul@0 198
	REG_EMC_RTCOR = tmp;
paul@0 199
	REG_EMC_RTCNT = 0;
paul@0 200
	REG_EMC_RTCSR = EMC_RTCSR_CKS_64;	/* Divisor is 64, CKO/64 */
paul@0 201
paul@0 202
	/* Wait for number of auto-refresh cycles */
paul@0 203
	tmp = (cpu_clk / 1000000) * 1000;
paul@0 204
	while (tmp--);
paul@0 205
paul@0 206
 	/* Stage 3. Mode Register Set */
paul@0 207
	REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
paul@0 208
	REG8(EMC_SDMR0|sdmode) = 0;
paul@0 209
paul@0 210
        /* Set back to basic DMCR value */
paul@0 211
	REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
paul@0 212
paul@0 213
	/* everything is ok now */
paul@0 214
}