summaryrefslogtreecommitdiff
path: root/board/samsung
diff options
context:
space:
mode:
authorMinkyu Kang <mk7.kang@samsung.com>2011-01-24 15:33:50 +0900
committerAlbert Aribaud <albert.aribaud@free.fr>2011-02-02 00:54:45 +0100
commit9e40808c3fe0237a8d49f10394d3a8e4e29540a6 (patch)
tree0ae51893b24862fd0d2ec32712b2bb963eefed08 /board/samsung
parent008a351a8a6b6dda8cd6d6d5813a44bdd4a455df (diff)
downloadu-boot-imx-9e40808c3fe0237a8d49f10394d3a8e4e29540a6.zip
u-boot-imx-9e40808c3fe0237a8d49f10394d3a8e4e29540a6.tar.gz
u-boot-imx-9e40808c3fe0237a8d49f10394d3a8e4e29540a6.tar.bz2
armv7: add support for s5pc210 universal board
This patch adds support for Samsung s5pc210 universal board Signed-off-by: Minkyu Kang <mk7.kang@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'board/samsung')
-rw-r--r--board/samsung/universal_c210/Makefile51
-rw-r--r--board/samsung/universal_c210/lowlevel_init.S395
-rw-r--r--board/samsung/universal_c210/onenand.c34
-rw-r--r--board/samsung/universal_c210/universal.c250
4 files changed, 730 insertions, 0 deletions
diff --git a/board/samsung/universal_c210/Makefile b/board/samsung/universal_c210/Makefile
new file mode 100644
index 0000000..0200220
--- /dev/null
+++ b/board/samsung/universal_c210/Makefile
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2010 Samsung Electronics
+# Minkyu Kang <mk7.kang@samsung.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).o
+
+COBJS-y := universal.o onenand.o
+SOBJS := lowlevel_init.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(SOBJS) $(OBJS)
+ $(call cmd_link_o_target, $(SOBJS) $(OBJS))
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/samsung/universal_c210/lowlevel_init.S b/board/samsung/universal_c210/lowlevel_init.S
new file mode 100644
index 0000000..67635bb
--- /dev/null
+++ b/board/samsung/universal_c210/lowlevel_init.S
@@ -0,0 +1,395 @@
+/*
+ * Lowlevel setup for universal board based on S5PC210
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <version.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+
+/*
+ * Register usages:
+ *
+ * r5 has zero always
+ * r7 has GPIO part1 base 0x11400000
+ * r6 has GPIO part2 base 0x11000000
+ */
+
+ .globl lowlevel_init
+lowlevel_init:
+ mov r11, lr
+
+ /* r5 has always zero */
+ mov r5, #0
+
+ ldr r7, =S5PC210_GPIO_PART1_BASE
+ ldr r6, =S5PC210_GPIO_PART2_BASE
+
+ /* System Timer */
+ ldr r0, =S5PC210_SYSTIMER_BASE
+ ldr r1, =0x5000
+ str r1, [r0, #0x0]
+ ldr r1, =0xffffffff
+ str r1, [r0, #0x8]
+ ldr r1, =0x49
+ str r1, [r0, #0x4]
+
+ /* PMIC manual reset */
+ /* nPOWER: XEINT_23: GPX2[7] */
+ add r0, r6, #0xC40 @ S5PC210_GPIO_X2_OFFSET
+ ldr r1, [r0, #0x0]
+ bic r1, r1, #(0xf << 28) @ 28 = 7 * 4-bit
+ orr r1, r1, #(0x1 << 28) @ Output
+ str r1, [r0, #0x0]
+
+ ldr r1, [r0, #0x4]
+ orr r1, r1, #(1 << 7) @ 7 = 7 * 1-bit
+ str r1, [r0, #0x4]
+
+ /* init system clock */
+ bl system_clock_init
+
+ /* Disable Watchdog */
+ ldr r0, =S5PC210_WATCHDOG_BASE @0x10060000
+ str r5, [r0]
+
+ /* UART */
+ bl uart_asm_init
+
+ /* PMU init */
+ bl system_power_init
+
+ bl tzpc_init
+
+ mov lr, r11
+ mov pc, lr
+ nop
+ nop
+ nop
+
+/*
+ * uart_asm_init: Initialize UART's pins
+ */
+uart_asm_init:
+ /*
+ * setup UART0-UART4 GPIOs (part1)
+ * GPA1CON[3] = I2C_3_SCL (3)
+ * GPA1CON[2] = I2C_3_SDA (3)
+ */
+ mov r0, r7
+ ldr r1, =0x22222222
+ str r1, [r0, #0x00] @ S5PC210_GPIO_A0_OFFSET
+ ldr r1, =0x00223322
+ str r1, [r0, #0x20] @ S5PC210_GPIO_A1_OFFSET
+
+ /* UART_SEL GPY4[7] (part2) at S5PC210 */
+ add r0, r6, #0x1A0 @ S5PC210_GPIO_Y4_OFFSET
+ ldr r1, [r0, #0x0]
+ bic r1, r1, #(0xf << 28) @ 28 = 7 * 4-bit
+ orr r1, r1, #(0x1 << 28)
+ str r1, [r0, #0x0]
+
+ ldr r1, [r0, #0x8]
+ bic r1, r1, #(0x3 << 14) @ 14 = 7 * 2-bit
+ orr r1, r1, #(0x3 << 14) @ Pull-up enabled
+ str r1, [r0, #0x8]
+
+ ldr r1, [r0, #0x4]
+ orr r1, r1, #(1 << 7) @ 7 = 7 * 1-bit
+ str r1, [r0, #0x4]
+
+ mov pc, lr
+ nop
+ nop
+ nop
+
+system_clock_init:
+ ldr r0, =S5PC210_CLOCK_BASE
+
+ /* APLL(1), MPLL(1), CORE(0), HPM(0) */
+ ldr r1, =0x0101
+ ldr r2, =0x14200 @ CLK_SRC_CPU
+ str r1, [r0, r2]
+
+ /* wait ?us */
+ mov r1, #0x10000
+1: subs r1, r1, #1
+ bne 1b
+
+ /*
+ * CLK_SRC_TOP0
+ * MUX_ONENAND_SEL[28] 0: DOUT133, 1: DOUT166
+ * MUX_VPLL_SEL[8] 0: FINPLL, 1: FOUTVPLL
+ * MUX_EPLL_SEL[4] 0: FINPLL, 1: FOUTEPLL
+ */
+ ldr r1, =0x10000110
+ ldr r2, =0x0C210 @ CLK_SRC_TOP
+ str r1, [r0, r2]
+
+ /* SATA: SCLKMPLL(0), MMC[0:4]: SCLKMPLL(6) */
+ ldr r1, =0x0066666
+ ldr r2, =0x0C240 @ CLK_SRC_FSYS
+ str r1, [r0, r2]
+ /* UART[0:5], PWM: SCLKMPLL(6) */
+ ldr r1, =0x6666666
+ ldr r2, =0x0C250 @ CLK_SRC_PERIL0_OFFSET
+ str r1, [r0, r2]
+
+ /* CPU0: CORE, COREM0, COREM1, PERI, ATB, PCLK_DBG, APLL */
+ ldr r1, =0x0133730
+ ldr r2, =0x14500 @ CLK_DIV_CPU0
+ str r1, [r0, r2]
+ /* CPU1: COPY, HPM */
+ ldr r1, =0x03
+ ldr r2, =0x14504 @ CLK_DIV_CPU1
+ str r1, [r0, r2]
+ /* DMC0: ACP, ACP_PCLK, DPHY, DMC, DMCD, DMCP, COPY2 CORE_TIMER */
+ ldr r1, =0x13111113
+ ldr r2, =0x10500 @ CLK_DIV_DMC0
+ str r1, [r0, r2]
+ /* DMC1: PWI, DVSEM, DPM */
+ ldr r1, =0x01010100
+ ldr r2, =0x10504 @ CLK_DIV_DMC1
+ str r1, [r0, r2]
+ /* LEFTBUS: GDL, GPL */
+ ldr r1, =0x13
+ ldr r2, =0x04500 @ CLK_DIV_LEFTBUS
+ str r1, [r0, r2]
+ /* RIGHHTBUS: GDR, GPR */
+ ldr r1, =0x13
+ ldr r2, =0x08500 @ CLK_DIV_RIGHTBUS
+ str r1, [r0, r2]
+ /*
+ * CLK_DIV_TOP
+ * ONENAND_RATIOD[18:16]: 0 SCLK_ONENAND = MOUTONENAND / (n + 1)
+ * ACLK_200, ACLK_100, ACLK_160, ACLK_133,
+ */
+ ldr r1, =0x00005473
+ ldr r2, =0x0C510 @ CLK_DIV_TOP
+ str r1, [r0, r2]
+ /* MMC[0:1] */
+ ldr r1, =0x000f000f /* 800(MPLL) / (15 + 1) */
+ ldr r2, =0x0C544 @ CLK_DIV_FSYS1
+ str r1, [r0, r2]
+ /* MMC[2:3] */
+ ldr r1, =0x000f000f /* 800(MPLL) / (15 + 1) */
+ ldr r2, =0x0C548 @ CLK_DIV_FSYS2
+ str r1, [r0, r2]
+ /* MMC4 */
+ ldr r1, =0x000f /* 800(MPLL) / (15 + 1) */
+ ldr r2, =0x0C54C @ CLK_DIV_FSYS3
+ str r1, [r0, r2]
+ /* UART[0:5] */
+ ldr r1, =0x774777
+ ldr r2, =0x0C550 @ CLK_DIV_PERIL0
+ str r1, [r0, r2]
+ /* SLIMBUS: ???, PWM */
+ ldr r1, =0x8
+ ldr r2, =0x0C55C @ CLK_DIV_PERIL3
+ str r1, [r0, r2]
+
+ /* PLL Setting */
+ ldr r1, =0x1C20
+ ldr r2, =0x14000 @ APLL_LOCK
+ str r1, [r0, r2]
+ ldr r2, =0x14008 @ MPLL_LOCK
+ str r1, [r0, r2]
+ ldr r2, =0x0C010 @ EPLL_LOCK
+ str r1, [r0, r2]
+ ldr r2, =0x0C020 @ VPLL_LOCK
+ str r1, [r0, r2]
+
+ /* APLL */
+ ldr r1, =0x8000001c
+ ldr r2, =0x14104 @ APLL_CON1
+ str r1, [r0, r2]
+ ldr r1, =0x80c80601 @ 800MHz
+ ldr r2, =0x14100 @ APLL_CON0
+ str r1, [r0, r2]
+ /* MPLL */
+ ldr r1, =0x8000001C
+ ldr r2, =0x1410C @ MPLL_CON1
+ str r1, [r0, r2]
+ ldr r1, =0x80c80601 @ 800MHz
+ ldr r2, =0x14108 @ MPLL_CON0
+ str r1, [r0, r2]
+ /* EPLL */
+ ldr r1, =0x0
+ ldr r2, =0x0C114 @ EPLL_CON1
+ str r1, [r0, r2]
+ ldr r1, =0x80300302 @ 96MHz
+ ldr r2, =0x0C110 @ EPLL_CON0
+ str r1, [r0, r2]
+ /* VPLL */
+ ldr r1, =0x11000400
+ ldr r2, =0x0C124 @ VPLL_CON1
+ str r1, [r0, r2]
+ ldr r1, =0x80350302 @ 108MHz
+ ldr r2, =0x0C120 @ VPLL_CON0
+ str r1, [r0, r2]
+
+ /*
+ * SMMUJPEG[11], JPEG[6], CSIS1[5] : 0111 1001
+ * Turn off all
+ */
+ ldr r1, =0xFFF80000
+ ldr r2, =0x0C920 @ CLK_GATE_IP_CAM
+ str r1, [r0, r2]
+
+ /* Turn off all */
+ ldr r1, =0xFFFFFFC0
+ ldr r2, =0x0C924 @ CLK_GATE_IP_VP
+ str r1, [r0, r2]
+
+ /* Turn off all */
+ ldr r1, =0xFFFFFFE0
+ ldr r2, =0x0C928 @ CLK_GATE_IP_MFC
+ str r1, [r0, r2]
+
+ /* Turn off all */
+ ldr r1, =0xFFFFFFFC
+ ldr r2, =0x0C92C @ CLK_GATE_IP_G3D
+ str r1, [r0, r2]
+
+ /* Turn off all */
+ ldr r1, =0xFFFFFC00
+ ldr r2, =0x0C930 @ CLK_GATE_IP_IMAGE
+ str r1, [r0, r2]
+
+ /* DSIM0[3], MDNIE0[2], MIE0[1] : 0001 */
+ ldr r1, =0xFFFFFFF1
+ ldr r2, =0x0C934 @ CLK_GATE_IP_LCD0
+ str r1, [r0, r2]
+
+ /* Turn off all */
+ ldr r1, =0xFFFFFFC0
+ ldr r2, =0x0C938 @ CLK_GATE_IP_LCD1
+ str r1, [r0, r2]
+
+ /*
+ * SMMUPCIE[18], NFCON[16] : 1111 1010
+ * PCIE[14], SATA[10], SDMMC43[9:8] : 1011 1000
+ * SDMMC1[6], TSI[4], SATAPHY[3], PCIEPHY[2] : 1010 0011
+ */
+ ldr r1, =0xFFFAB8A3
+ ldr r2, =0x0C940 @ CLK_GATE_IP_FSYS
+ str r1, [r0, r2]
+
+ /* Turn off all */
+ ldr r1, =0xFFFFFFFC
+ ldr r2, =0x0C94C @ CLK_GATE_IP_GPS
+ str r1, [r0, r2]
+
+ /*
+ * AC97[27], SPDIF[26], SLIMBUS[25] : 1111 0001
+ * I2C2[8] : 1111 1110
+ */
+ ldr r1, =0xF1FFFEFF
+ ldr r2, =0x0C950 @ CLK_GATE_IP_PERIL
+ str r1, [r0, r2]
+
+ /*
+ * KEYIF[16] : 1111 1110
+ */
+ ldr r1, =0xFFFEFFFF
+ ldr r2, =0x0C960 @ CLK_GATE_IP_PERIR
+ str r1, [r0, r2]
+
+ /* LCD1[5], G3D[3], MFC[2], TV[1] : 1101 0001 */
+ ldr r1, =0xFFFFFFD1
+ ldr r2, =0x0C970 @ CLK_GATE_BLOCK
+ str r1, [r0, r2]
+ mov pc, lr
+ nop
+ nop
+ nop
+
+system_power_init:
+ ldr r0, =S5PC210_POWER_BASE @ 0x10020000
+
+ ldr r2, =0x330C @ PS_HOLD_CONTROL
+ ldr r1, [r0, r2]
+ orr r1, r1, #(0x3 << 8) @ Data High, Output En
+ str r1, [r0, r2]
+
+ /* Power Down */
+ add r2, r0, #0x3000
+ str r5, [r2, #0xC20] @ TV_CONFIGURATION
+ str r5, [r2, #0xC40] @ MFC_CONFIGURATION
+ str r5, [r2, #0xC60] @ G3D_CONFIGURATION
+ str r5, [r2, #0xCA0] @ LCD1_CONFIGURATION
+ str r5, [r2, #0xCE0] @ GPS_CONFIGURATION
+
+ mov pc, lr
+ nop
+ nop
+ nop
+
+tzpc_init:
+ ldr r0, =0x10110000
+ mov r1, #0x0
+ str r1, [r0]
+ mov r1, #0xff
+ str r1, [r0, #0x0804]
+ str r1, [r0, #0x0810]
+ str r1, [r0, #0x081C]
+ str r1, [r0, #0x0828]
+
+ ldr r0, =0x10120000
+ mov r1, #0x0
+ str r1, [r0]
+ mov r1, #0xff
+ str r1, [r0, #0x0804]
+ str r1, [r0, #0x0810]
+ str r1, [r0, #0x081C]
+ str r1, [r0, #0x0828]
+
+ ldr r0, =0x10130000
+ mov r1, #0x0
+ str r1, [r0]
+ mov r1, #0xff
+ str r1, [r0, #0x0804]
+ str r1, [r0, #0x0810]
+ str r1, [r0, #0x081C]
+ str r1, [r0, #0x0828]
+
+ ldr r0, =0x10140000
+ mov r1, #0x0
+ str r1, [r0]
+ mov r1, #0xff
+ str r1, [r0, #0x0804]
+ str r1, [r0, #0x0810]
+ str r1, [r0, #0x081C]
+ str r1, [r0, #0x0828]
+
+ ldr r0, =0x10150000
+ mov r1, #0x0
+ str r1, [r0]
+ mov r1, #0xff
+ str r1, [r0, #0x0804]
+ str r1, [r0, #0x0810]
+ str r1, [r0, #0x081C]
+ str r1, [r0, #0x0828]
+
+ mov pc, lr
diff --git a/board/samsung/universal_c210/onenand.c b/board/samsung/universal_c210/onenand.c
new file mode 100644
index 0000000..20e1dc5
--- /dev/null
+++ b/board/samsung/universal_c210/onenand.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+
+void onenand_board_init(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+
+ this->base = (void *)CONFIG_SYS_ONENAND_BASE;
+ this->options |= ONENAND_RUNTIME_BADBLOCK_CHECK;
+}
diff --git a/board/samsung/universal_c210/universal.c b/board/samsung/universal_c210/universal.c
new file mode 100644
index 0000000..b65bc6e
--- /dev/null
+++ b/board/samsung/universal_c210/universal.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/adc.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mmc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct s5pc210_gpio_part1 *gpio1;
+struct s5pc210_gpio_part2 *gpio2;
+unsigned int board_rev;
+
+u32 get_board_rev(void)
+{
+ return board_rev;
+}
+
+static int get_hwrev(void)
+{
+ return board_rev & 0xFF;
+}
+
+static void check_hw_revision(void);
+
+int board_init(void)
+{
+ gpio1 = (struct s5pc210_gpio_part1 *) S5PC210_GPIO_PART1_BASE;
+ gpio2 = (struct s5pc210_gpio_part2 *) S5PC210_GPIO_PART2_BASE;
+
+ gd->bd->bi_arch_number = MACH_TYPE_UNIVERSAL_C210;
+ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
+
+ check_hw_revision();
+ printf("HW Revision:\t0x%x\n", board_rev);
+
+ return 0;
+}
+
+int dram_init(void)
+{
+ gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) +
+ get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE);
+
+ return 0;
+}
+
+void dram_init_banksize(void)
+{
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+ gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+ gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+}
+
+static unsigned short get_adc_value(int channel)
+{
+ struct s5p_adc *adc = (struct s5p_adc *)samsung_get_base_adc();
+ unsigned short ret = 0;
+ unsigned int reg;
+ unsigned int loop = 0;
+
+ writel(channel & 0xF, &adc->adcmux);
+ writel((1 << 14) | (49 << 6), &adc->adccon);
+ writel(1000 & 0xffff, &adc->adcdly);
+ writel(readl(&adc->adccon) | (1 << 16), &adc->adccon); /* 12 bit */
+ udelay(10);
+ writel(readl(&adc->adccon) | (1 << 0), &adc->adccon); /* Enable */
+ udelay(10);
+
+ do {
+ udelay(1);
+ reg = readl(&adc->adccon);
+ } while (!(reg & (1 << 15)) && (loop++ < 1000));
+
+ ret = readl(&adc->adcdat0) & 0xFFF;
+
+ return ret;
+}
+
+static unsigned int get_hw_revision(void)
+{
+ int hwrev, mode0, mode1;
+
+ mode0 = get_adc_value(1); /* HWREV_MODE0 */
+ mode1 = get_adc_value(2); /* HWREV_MODE1 */
+
+ /*
+ * XXX Always set the default hwrev as the latest board
+ * ADC = (voltage) / 3.3 * 4096
+ */
+ hwrev = 3;
+
+#define IS_RANGE(x, min, max) ((x) > (min) && (x) < (max))
+ if (IS_RANGE(mode0, 80, 200) && IS_RANGE(mode1, 80, 200))
+ hwrev = 0x0; /* 0.01V 0.01V */
+ if (IS_RANGE(mode0, 750, 1000) && IS_RANGE(mode1, 80, 200))
+ hwrev = 0x1; /* 610mV 0.01V */
+ if (IS_RANGE(mode0, 1300, 1700) && IS_RANGE(mode1, 80, 200))
+ hwrev = 0x2; /* 1.16V 0.01V */
+ if (IS_RANGE(mode0, 2000, 2400) && IS_RANGE(mode1, 80, 200))
+ hwrev = 0x3; /* 1.79V 0.01V */
+#undef IS_RANGE
+
+ debug("mode0: %d, mode1: %d, hwrev 0x%x\n", mode0, mode1, hwrev);
+
+ return hwrev;
+}
+
+static void check_hw_revision(void)
+{
+ int hwrev;
+
+ hwrev = get_hw_revision();
+
+ board_rev |= hwrev;
+}
+
+#ifdef CONFIG_DISPLAY_BOARDINFO
+int checkboard(void)
+{
+ puts("Board:\tUniversal C210\n");
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_GENERIC_MMC
+int board_mmc_init(bd_t *bis)
+{
+ int i, err;
+
+ switch (get_hwrev()) {
+ case 0:
+ /*
+ * Set the low to enable LDO_EN
+ * But when you use the test board for eMMC booting
+ * you should set it HIGH since it removes the inverter
+ */
+ /* MASSMEMORY_EN: XMDMDATA_6: GPE3[6] */
+ gpio_direction_output(&gpio1->e3, 6, 0);
+ break;
+ default:
+ /*
+ * Default reset state is High and there's no inverter
+ * But set it as HIGH to ensure
+ */
+ /* MASSMEMORY_EN: XMDMADDR_3: GPE1[3] */
+ gpio_direction_output(&gpio1->e1, 3, 1);
+ break;
+ }
+
+ /*
+ * eMMC GPIO:
+ * SDR 8-bit@48MHz at MMC0
+ * GPK0[0] SD_0_CLK(2)
+ * GPK0[1] SD_0_CMD(2)
+ * GPK0[2] SD_0_CDn -> Not used
+ * GPK0[3:6] SD_0_DATA[0:3](2)
+ * GPK1[3:6] SD_0_DATA[0:3](3)
+ *
+ * DDR 4-bit@26MHz at MMC4
+ * GPK0[0] SD_4_CLK(3)
+ * GPK0[1] SD_4_CMD(3)
+ * GPK0[2] SD_4_CDn -> Not used
+ * GPK0[3:6] SD_4_DATA[0:3](3)
+ * GPK1[3:6] SD_4_DATA[4:7](4)
+ */
+ for (i = 0; i < 7; i++) {
+ if (i == 2)
+ continue;
+ /* GPK0[0:6] special function 2 */
+ gpio_cfg_pin(&gpio2->k0, i, 0x2);
+ /* GPK0[0:6] pull disable */
+ gpio_set_pull(&gpio2->k0, i, GPIO_PULL_NONE);
+ /* GPK0[0:6] drv 4x */
+ gpio_set_drv(&gpio2->k0, i, GPIO_DRV_4X);
+ }
+
+ for (i = 3; i < 7; i++) {
+ /* GPK1[3:6] special function 3 */
+ gpio_cfg_pin(&gpio2->k1, i, 0x3);
+ /* GPK1[3:6] pull disable */
+ gpio_set_pull(&gpio2->k1, i, GPIO_PULL_NONE);
+ /* GPK1[3:6] drv 4x */
+ gpio_set_drv(&gpio2->k1, i, GPIO_DRV_4X);
+ }
+
+ /* T-flash detect */
+ gpio_cfg_pin(&gpio2->x3, 4, 0xf);
+ gpio_set_pull(&gpio2->x3, 4, GPIO_PULL_UP);
+
+ /*
+ * MMC device init
+ * mmc0 : eMMC (8-bit buswidth)
+ * mmc2 : SD card (4-bit buswidth)
+ */
+ err = s5p_mmc_init(0, 8);
+
+ /*
+ * Check the T-flash detect pin
+ * GPX3[4] T-flash detect pin
+ */
+ if (!gpio_get_value(&gpio2->x3, 4)) {
+ /*
+ * SD card GPIO:
+ * GPK2[0] SD_2_CLK(2)
+ * GPK2[1] SD_2_CMD(2)
+ * GPK2[2] SD_2_CDn -> Not used
+ * GPK2[3:6] SD_2_DATA[0:3](2)
+ */
+ for (i = 0; i < 7; i++) {
+ if (i == 2)
+ continue;
+ /* GPK2[0:6] special function 2 */
+ gpio_cfg_pin(&gpio2->k2, i, 0x2);
+ /* GPK2[0:6] pull disable */
+ gpio_set_pull(&gpio2->k2, i, GPIO_PULL_NONE);
+ /* GPK2[0:6] drv 4x */
+ gpio_set_drv(&gpio2->k2, i, GPIO_DRV_4X);
+ }
+ err = s5p_mmc_init(2, 4);
+ }
+
+ return err;
+
+}
+#endif