NanoPayload

Annotated stage2/board.c

217:44fcbb779a70
2017-06-28 Paul Boddie Replaced u8, u16 and u32 with uint8_t, uint16_t and uint32_t respectively.
paul@33 1
/*
paul@33 2
 * Common routines supporting board initialisation.
paul@33 3
 *
paul@33 4
 * Copyright (C) 2005-2006 Ingenic Semiconductor, <jlwei@ingenic.cn>
paul@33 5
 * Copyright (C) Xiangfu Liu <xiangfu.z@gmail.com>
paul@217 6
 * Copyright (C) 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
paul@33 7
 *
paul@63 8
 * This program is free software: you can redistribute it and/or modify
paul@63 9
 * it under the terms of the GNU General Public License as published by
paul@63 10
 * the Free Software Foundation, either version 3 of the License, or
paul@63 11
 * (at your option) any later version.
paul@33 12
 *
paul@63 13
 * This program is distributed in the hope that it will be useful,
paul@63 14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
paul@63 15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
paul@63 16
 * GNU General Public License for more details.
paul@33 17
 *
paul@63 18
 * You should have received a copy of the GNU General Public License
paul@63 19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
paul@33 20
 */
paul@33 21
paul@33 22
#include "sdram.h"
paul@33 23
#include "board.h"
paul@33 24
paul@195 25
unsigned long get_memory_size()
paul@33 26
{
paul@33 27
	unsigned int dmcr;
paul@33 28
	unsigned int rows, cols, dw, banks;
paul@33 29
	unsigned long size;
paul@33 30
paul@33 31
	dmcr = REG_EMC_DMCR;
paul@33 32
	rows = SDRAM_ROW0 + ((dmcr & EMC_DMCR_RA_MASK) >> EMC_DMCR_RA_BIT);
paul@33 33
	cols = SDRAM_COL0 + ((dmcr & EMC_DMCR_CA_MASK) >> EMC_DMCR_CA_BIT);
paul@33 34
	dw = (dmcr & EMC_DMCR_BW) ? 2 : 4;
paul@33 35
	banks = (dmcr & EMC_DMCR_BA) ? 4 : 2;
paul@33 36
paul@33 37
	size = (1 << (rows + cols)) * dw * banks;
paul@33 38
paul@33 39
	return size;
paul@33 40
}
paul@33 41
paul@33 42
/* Timer routines. */
paul@33 43
paul@33 44
extern unsigned long timestamp;
paul@33 45
extern unsigned long lastdec;
paul@33 46
paul@195 47
unsigned long get_timer_masked()
paul@33 48
{
paul@33 49
	unsigned long now = READ_TIMER;
paul@33 50
paul@33 51
	if (lastdec <= now) {
paul@33 52
		/* normal mode */
paul@33 53
		timestamp += (now - lastdec);
paul@33 54
	} else {
paul@33 55
		/* we have an overflow ... */
paul@33 56
		timestamp += TIMER_FDATA + now - lastdec;
paul@33 57
	}
paul@33 58
	lastdec = now;
paul@33 59
paul@33 60
	return timestamp;
paul@33 61
}
paul@33 62
paul@195 63
void reset_timer_masked()
paul@33 64
{
paul@33 65
	/* reset time */
paul@33 66
	lastdec = READ_TIMER;
paul@33 67
	timestamp = 0;
paul@33 68
}
paul@33 69
paul@195 70
void reset_timer()
paul@33 71
{
paul@33 72
	reset_timer_masked ();
paul@33 73
}
paul@33 74
paul@33 75
unsigned long get_timer(unsigned long base)
paul@33 76
{
paul@33 77
	return get_timer_masked () - base;
paul@33 78
}
paul@33 79
paul@33 80
void set_timer(unsigned long t)
paul@33 81
{
paul@33 82
	timestamp = t;
paul@33 83
}
paul@33 84
paul@197 85
void udelay(unsigned long usec)
paul@33 86
{
paul@33 87
	unsigned long tmo,tmp;
paul@33 88
paul@33 89
	/* normalize */
paul@33 90
	if (usec >= 1000) {
paul@33 91
		tmo = usec / 1000;
paul@33 92
		tmo *= TIMER_HZ;
paul@33 93
		tmo /= 1000;
paul@33 94
	}
paul@33 95
	else {
paul@33 96
		if (usec >= 1) {
paul@33 97
			tmo = usec * TIMER_HZ;
paul@33 98
			tmo /= (1000*1000);
paul@33 99
		}
paul@33 100
		else
paul@33 101
			tmo = 1;
paul@33 102
	}
paul@33 103
paul@33 104
	/* check for rollover during this delay */
paul@33 105
	tmp = get_timer (0);
paul@33 106
	if ((tmp + tmo) < tmp )
paul@33 107
		reset_timer_masked();  /* timer would roll over */
paul@33 108
	else
paul@33 109
		tmo += tmp;
paul@33 110
paul@33 111
	while (get_timer_masked () < tmo);
paul@33 112
}
paul@33 113
paul@197 114
void udelay_masked(unsigned long usec)
paul@33 115
{
paul@33 116
	unsigned long tmo;
paul@33 117
	unsigned long endtime;
paul@33 118
	signed long diff;
paul@33 119
paul@33 120
	/* normalize */
paul@33 121
	if (usec >= 1000) {
paul@33 122
		tmo = usec / 1000;
paul@33 123
		tmo *= TIMER_HZ;
paul@33 124
		tmo /= 1000;
paul@33 125
	} else {
paul@33 126
		if (usec > 1) {
paul@33 127
			tmo = usec * TIMER_HZ;
paul@33 128
			tmo /= (1000*1000);
paul@33 129
		} else {
paul@33 130
			tmo = 1;
paul@33 131
		}
paul@33 132
	}
paul@33 133
paul@33 134
	endtime = get_timer_masked () + tmo;
paul@33 135
paul@33 136
	do {
paul@33 137
		unsigned long now = get_timer_masked ();
paul@33 138
		diff = endtime - now;
paul@33 139
	} while (diff >= 0);
paul@33 140
}
paul@33 141
paul@33 142
/*
paul@33 143
 * This function is derived from PowerPC code (read timebase as long long).
paul@33 144
 * On MIPS it just returns the timer value.
paul@33 145
 */
paul@195 146
unsigned long long get_ticks()
paul@33 147
{
paul@33 148
	return get_timer(0);
paul@33 149
}
paul@33 150
paul@33 151
/*
paul@33 152
 * This function is derived from PowerPC code (timebase clock frequency).
paul@33 153
 * On MIPS it returns the number of timer ticks per second.
paul@33 154
 */
paul@195 155
unsigned long get_tbclk()
paul@33 156
{
paul@33 157
	return TIMER_HZ;
paul@33 158
}
paul@197 159
paul@197 160
/* GPIO interrupt administration. */
paul@197 161
paul@217 162
void gpio_clear(uint8_t gpio)
paul@197 163
{
paul@197 164
	/* Clear interrupt status. */
paul@197 165
paul@197 166
	__gpio_ack_irq(gpio);
paul@197 167
	__intc_ack_irq(GPIO_IRQ);
paul@197 168
}
paul@197 169
paul@197 170
/* Miscellaneous interrupt administration. */
paul@197 171
paul@197 172
void irq_clear()
paul@197 173
{
paul@217 174
	uint8_t i;
paul@197 175
paul@197 176
	for (i = 0; i < 32; i++) {
paul@197 177
		if (REG_INTC_IPR & (1 << i))
paul@197 178
			__intc_ack_irq(i);
paul@197 179
	}
paul@197 180
}