board.c 6.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * (C) Copyright 2012-2013 Henrik Nordstrom <henrik@henriknordstrom.net>
 * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
 *
 * (C) Copyright 2007-2011
 * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
 * Tom Cubie <tangliang@allwinnertech.com>
 *
 * Some board init for the Allwinner A10-evb board.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
15
#include <mmc.h>
H
Hans de Goede 已提交
16 17 18
#ifdef CONFIG_AXP152_POWER
#include <axp152.h>
#endif
19 20 21
#ifdef CONFIG_AXP209_POWER
#include <axp209.h>
#endif
O
Oliver Schinagl 已提交
22 23 24
#ifdef CONFIG_AXP221_POWER
#include <axp221.h>
#endif
25
#include <asm/arch/clock.h>
26
#include <asm/arch/cpu.h>
L
Luc Verhaegen 已提交
27
#include <asm/arch/display.h>
28
#include <asm/arch/dram.h>
I
Ian Campbell 已提交
29 30
#include <asm/arch/gpio.h>
#include <asm/arch/mmc.h>
31
#include <asm/arch/usbc.h>
32
#include <asm/io.h>
33
#include <linux/usb/musb.h>
34
#include <net.h>
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

DECLARE_GLOBAL_DATA_PTR;

/* add board specific code here */
int board_init(void)
{
	int id_pfr1;

	gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100);

	asm volatile("mrc p15, 0, %0, c0, c1, 1" : "=r"(id_pfr1));
	debug("id_pfr1: 0x%08x\n", id_pfr1);
	/* Generic Timer Extension available? */
	if ((id_pfr1 >> 16) & 0xf) {
		debug("Setting CNTFRQ\n");
		/* CNTFRQ == 24 MHz */
		asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r"(24000000));
	}

	return 0;
}

int dram_init(void)
{
	gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE);

	return 0;
}

I
Ian Campbell 已提交
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
#ifdef CONFIG_GENERIC_MMC
static void mmc_pinmux_setup(int sdc)
{
	unsigned int pin;

	switch (sdc) {
	case 0:
		/* D1-PF0, D0-PF1, CLK-PF2, CMD-PF3, D3-PF4, D4-PF5 */
		for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) {
			sunxi_gpio_set_cfgpin(pin, SUNXI_GPF0_SDC0);
			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
			sunxi_gpio_set_drv(pin, 2);
		}
		break;

	case 1:
80 81 82
		/* CMD-PG3, CLK-PG4, D0~D3-PG5-8 */
		for (pin = SUNXI_GPG(3); pin <= SUNXI_GPG(8); pin++) {
			sunxi_gpio_set_cfgpin(pin, SUN5I_GPG3_SDC1);
I
Ian Campbell 已提交
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
			sunxi_gpio_set_drv(pin, 2);
		}
		break;

	case 2:
		/* CMD-PC6, CLK-PC7, D0-PC8, D1-PC9, D2-PC10, D3-PC11 */
		for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(11); pin++) {
			sunxi_gpio_set_cfgpin(pin, SUNXI_GPC6_SDC2);
			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
			sunxi_gpio_set_drv(pin, 2);
		}
		break;

	case 3:
		/* CMD-PI4, CLK-PI5, D0~D3-PI6~9 : 2 */
		for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) {
			sunxi_gpio_set_cfgpin(pin, SUN4I_GPI4_SDC3);
			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
			sunxi_gpio_set_drv(pin, 2);
		}
		break;

	default:
		printf("sunxi: invalid MMC slot %d for pinmux setup\n", sdc);
		break;
	}
}

int board_mmc_init(bd_t *bis)
{
114 115 116
	__maybe_unused struct mmc *mmc0, *mmc1;
	__maybe_unused char buf[512];

I
Ian Campbell 已提交
117
	mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
118 119 120 121
	mmc0 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
	if (!mmc0)
		return -1;

122
#if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
I
Ian Campbell 已提交
123
	mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
	mmc1 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
	if (!mmc1)
		return -1;
#endif

#if CONFIG_MMC_SUNXI_SLOT == 0 && CONFIG_MMC_SUNXI_SLOT_EXTRA == 2
	/*
	 * Both mmc0 and mmc2 are bootable, figure out where we're booting
	 * from. Try mmc0 first, just like the brom does.
	 */
	if (mmc_getcd(mmc0) && mmc_init(mmc0) == 0 &&
	    mmc0->block_dev.block_read(0, 16, 1, buf) == 1) {
		buf[12] = 0;
		if (strcmp(&buf[4], "eGON.BT0") == 0)
			return 0;
	}

	/* no bootable card in mmc0, so we must be booting from mmc2, swap */
	mmc0->block_dev.dev = 1;
	mmc1->block_dev.dev = 0;
I
Ian Campbell 已提交
144 145 146 147 148 149
#endif

	return 0;
}
#endif

H
Hans de Goede 已提交
150 151 152 153 154 155 156
void i2c_init_board(void)
{
	sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUNXI_GPB0_TWI0);
	sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUNXI_GPB0_TWI0);
	clock_twi_onoff(0, 1);
}

157 158 159
#ifdef CONFIG_SPL_BUILD
void sunxi_board_init(void)
{
160
	int power_failed = 0;
161 162
	unsigned long ramsize;

H
Hans de Goede 已提交
163 164 165 166 167 168 169
#ifdef CONFIG_AXP152_POWER
	power_failed = axp152_init();
	power_failed |= axp152_set_dcdc2(1400);
	power_failed |= axp152_set_dcdc3(1500);
	power_failed |= axp152_set_dcdc4(1250);
	power_failed |= axp152_set_ldo2(3000);
#endif
170 171 172 173 174 175 176
#ifdef CONFIG_AXP209_POWER
	power_failed |= axp209_init();
	power_failed |= axp209_set_dcdc2(1400);
	power_failed |= axp209_set_dcdc3(1250);
	power_failed |= axp209_set_ldo2(3000);
	power_failed |= axp209_set_ldo3(2800);
	power_failed |= axp209_set_ldo4(2800);
O
Oliver Schinagl 已提交
177 178 179
#endif
#ifdef CONFIG_AXP221_POWER
	power_failed = axp221_init();
180
	power_failed |= axp221_set_dcdc1(CONFIG_AXP221_DCDC1_VOLT);
181 182 183 184 185 186 187 188
	power_failed |= axp221_set_dcdc2(1200); /* A31:VDD-GPU, A23:VDD-SYS */
	power_failed |= axp221_set_dcdc3(1200); /* VDD-CPU */
#ifdef CONFIG_MACH_SUN6I
	power_failed |= axp221_set_dcdc4(1200); /* A31:VDD-SYS */
#else
	power_failed |= axp221_set_dcdc4(0);    /* A23:unused */
#endif
	power_failed |= axp221_set_dcdc5(1500); /* VCC-DRAM */
O
Oliver Schinagl 已提交
189 190 191 192 193
	power_failed |= axp221_set_dldo1(CONFIG_AXP221_DLDO1_VOLT);
	power_failed |= axp221_set_dldo4(CONFIG_AXP221_DLDO4_VOLT);
	power_failed |= axp221_set_aldo1(CONFIG_AXP221_ALDO1_VOLT);
	power_failed |= axp221_set_aldo2(CONFIG_AXP221_ALDO2_VOLT);
	power_failed |= axp221_set_aldo3(CONFIG_AXP221_ALDO3_VOLT);
194
	power_failed |= axp221_set_eldo(3, CONFIG_AXP221_ELDO3_VOLT);
195 196
#endif

197 198 199 200 201
	printf("DRAM:");
	ramsize = sunxi_dram_init();
	printf(" %lu MiB\n", ramsize >> 20);
	if (!ramsize)
		hang();
202 203 204 205 206 207 208 209 210

	/*
	 * Only clock up the CPU to full speed if we are reasonably
	 * assured it's being powered with suitable core voltage
	 */
	if (!power_failed)
		clock_set_pll1(CONFIG_CLK_FULL_SPEED);
	else
		printf("Failed to set core voltage! Can't set CPU frequency\n");
211 212
}
#endif
213

214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET)
static struct musb_hdrc_config musb_config = {
	.multipoint     = 1,
	.dyn_fifo       = 1,
	.num_eps        = 6,
	.ram_bits       = 11,
};

static struct musb_hdrc_platform_data musb_plat = {
#if defined(CONFIG_MUSB_HOST)
	.mode           = MUSB_HOST,
#else
	.mode		= MUSB_PERIPHERAL,
#endif
	.config         = &musb_config,
	.power          = 250,
	.platform_ops	= &sunxi_musb_ops,
};
#endif

234 235 236
#ifdef CONFIG_MISC_INIT_R
int misc_init_r(void)
{
237
	unsigned int sid[4];
238

239 240 241
	if (!getenv("ethaddr") && sunxi_get_sid(sid) == 0 &&
			sid[0] != 0 && sid[3] != 0) {
		uint8_t mac_addr[6];
242

243 244 245 246 247 248
		mac_addr[0] = 0x02; /* Non OUI / registered MAC address */
		mac_addr[1] = (sid[0] >>  0) & 0xff;
		mac_addr[2] = (sid[3] >> 24) & 0xff;
		mac_addr[3] = (sid[3] >> 16) & 0xff;
		mac_addr[4] = (sid[3] >>  8) & 0xff;
		mac_addr[5] = (sid[3] >>  0) & 0xff;
249

250
		eth_setenv_enetaddr("ethaddr", mac_addr);
251 252
	}

253 254 255
#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET)
	musb_register(&musb_plat, NULL, (void *)SUNXI_USB0_BASE);
#endif
256 257 258
	return 0;
}
#endif
L
Luc Verhaegen 已提交
259 260 261 262 263 264 265 266 267

#ifdef CONFIG_OF_BOARD_SETUP
int ft_board_setup(void *blob, bd_t *bd)
{
#ifdef CONFIG_VIDEO_DT_SIMPLEFB
	return sunxi_simplefb_setup(blob);
#endif
}
#endif /* CONFIG_OF_BOARD_SETUP */