[U-Boot] [PATCH v5 00/12] Add support to Odroid U3/X2

This patch set introduces changes to common Samsung code as a preparation of new board support: - boot device check - code cleanup - automatic init order of mmc drivers - automatic setting of dfu entities which depends on boot device - pre reset function call for board own implementation - setting board info environment for multi board support
New board config: - odroid_config - Odroid U3/X2 support
V5 main changes: - fix kernel crash - decrease mem size by 1MB - ramdisk support - OTG fix for Odroid U3+ - some code cleanup
Przemyslaw Marczak (12): samsung: misc: fix soc revision setting in the set_board_info() exynos: pinmux: fix the gpio names for exynos4x12 mmc arch:exynos: boot mode: add get_boot_mode(), code cleanup board:samsung: check the boot device and init the right mmc driver. samsung: misc: add function for setting $dfu_alt_info samsung:board: misc_init_r: call set_dfu_alt_info() arm:reset: call the reset_misc() before the cpu reset samsung: board: enable support of multiple board types samsung: misc: use board specific functions to set env board info odroid: add board file for Odroid X2/U3 based on Samsung Exynos4412 odroid: add odroid U3/X2 device tree description odroid: add odroid_config
arch/arm/cpu/armv7/exynos/pinmux.c | 4 +- arch/arm/cpu/armv7/exynos/power.c | 7 + arch/arm/cpu/armv7/exynos/spl_boot.c | 5 +- arch/arm/dts/Makefile | 3 +- arch/arm/dts/exynos4412-odroid.dts | 70 +++++ arch/arm/include/asm/arch-exynos/power.h | 21 ++ arch/arm/include/asm/arch-exynos/spl.h | 17 +- arch/arm/lib/reset.c | 6 + board/samsung/common/board.c | 55 +++- board/samsung/common/misc.c | 57 +++- board/samsung/odroid/Makefile | 8 + board/samsung/odroid/odroid.c | 470 +++++++++++++++++++++++++++++++ board/samsung/odroid/setup.h | 255 +++++++++++++++++ boards.cfg | 1 + doc/README.odroid | 143 ++++++++++ include/common.h | 1 + include/configs/odroid.h | 216 ++++++++++++++ include/samsung/misc.h | 10 + 18 files changed, 1309 insertions(+), 40 deletions(-) create mode 100644 arch/arm/dts/exynos4412-odroid.dts create mode 100644 board/samsung/odroid/Makefile create mode 100644 board/samsung/odroid/odroid.c create mode 100644 board/samsung/odroid/setup.h create mode 100644 doc/README.odroid create mode 100644 include/configs/odroid.h

The byte order of soc revision was inverted, now it is fixed.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Piotr Wilczek p.wilczek@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com --- board/samsung/common/misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index 03106fd..a453a82 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -26,8 +26,8 @@ void set_board_info(void) { char info[64];
- snprintf(info, ARRAY_SIZE(info), "%d.%d", s5p_cpu_rev & 0x0f, - (s5p_cpu_rev & 0xf0) >> 0x04); + snprintf(info, ARRAY_SIZE(info), "%u.%u", (s5p_cpu_rev & 0xf0) >> 4, + s5p_cpu_rev & 0xf); setenv("soc_rev", info);
snprintf(info, ARRAY_SIZE(info), "%x", s5p_cpu_id);

This change fixes the bad gpio configuration for the exynos dwmmc.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Beomho Seo beomho.seo@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Jaehoon Chung jh80.chung@samsung.com --- arch/arm/cpu/armv7/exynos/pinmux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index 86a0c75..b929486 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -704,8 +704,8 @@ static int exynos4x12_mmc_config(int peripheral, int flags) ext_func = S5P_GPIO_FUNC(0x3); break; case PERIPH_ID_SDMMC4: - start = EXYNOS4_GPIO_K00; - start_ext = EXYNOS4_GPIO_K13; + start = EXYNOS4X12_GPIO_K00; + start_ext = EXYNOS4X12_GPIO_K13; func = S5P_GPIO_FUNC(0x3); ext_func = S5P_GPIO_FUNC(0x4); break;

This patch introduces code clean-up for exynos boot mode check. It includes: - removal of typedef: boot_mode - move the boot mode enum to arch-exynos/power.h - add bootmode for sequence: eMMC 4.4 ch4 / SD ch2 - add new function: get_boot_mode() for OM[5:1] pin check - update spl boot code
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com
Changes v5: - exynos: boot mode: add missing bootmode (1st:EMMC 4.4 / 2nd:SD ch2) --- arch/arm/cpu/armv7/exynos/power.c | 7 +++++++ arch/arm/cpu/armv7/exynos/spl_boot.c | 5 ++--- arch/arm/include/asm/arch-exynos/power.h | 21 +++++++++++++++++++++ arch/arm/include/asm/arch-exynos/spl.h | 17 ++--------------- 4 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c index 638ee0b..e1ab3d6 100644 --- a/arch/arm/cpu/armv7/exynos/power.c +++ b/arch/arm/cpu/armv7/exynos/power.c @@ -202,3 +202,10 @@ void power_exit_wakeup(void) else exynos4_power_exit_wakeup(); } + +unsigned int get_boot_mode(void) +{ + unsigned int om_pin = samsung_get_base_power(); + + return readl(om_pin) & OM_PIN_MASK; +} diff --git a/arch/arm/cpu/armv7/exynos/spl_boot.c b/arch/arm/cpu/armv7/exynos/spl_boot.c index 7916630..87f9214 100644 --- a/arch/arm/cpu/armv7/exynos/spl_boot.c +++ b/arch/arm/cpu/armv7/exynos/spl_boot.c @@ -20,7 +20,6 @@ #include "clock_init.h"
DECLARE_GLOBAL_DATA_PTR; -#define OM_STAT (0x1f << 1)
/* Index into irom ptr table */ enum index { @@ -184,7 +183,7 @@ static void exynos_spi_copy(unsigned int uboot_size, unsigned int uboot_addr) */ void copy_uboot_to_ram(void) { - enum boot_mode bootmode = BOOT_MODE_OM; + u32 bootmode = BOOT_MODE_OM;
u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst) = NULL; u32 offset = 0, size = 0; @@ -207,7 +206,7 @@ void copy_uboot_to_ram(void) #endif
if (bootmode == BOOT_MODE_OM) - bootmode = readl(samsung_get_base_power()) & OM_STAT; + bootmode = get_boot_mode();
switch (bootmode) { #ifdef CONFIG_SPI_BOOTING diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h index 4f2447b..1c0f144 100644 --- a/arch/arm/include/asm/arch-exynos/power.h +++ b/arch/arm/include/asm/arch-exynos/power.h @@ -1670,6 +1670,27 @@ struct exynos5420_power { }; #endif /* __ASSEMBLY__ */
+#define OM_PIN_BITS 0x1f +#define OM_PIN_SHIFT 0x1 +#define OM_PIN_MASK (OM_PIN_BITS << OM_PIN_SHIFT) + +enum { + /* + * Assign the OM pin values for respective boot modes. + * Exynos4 does not support spi boot and the mmc boot OM + * pin values are the same across Exynos4 and Exynos5. + */ + BOOT_MODE_MMC = 4, /* SD_CH2 | USB */ + BOOT_MODE_EMMC = 8, /* EMMC4.4 | USB */ + BOOT_MODE_EMMC_SD = 40, /* EMMC4.4 | SD_CH2 */ + BOOT_MODE_SERIAL = 20, + /* Boot based on Operating Mode pin settings */ + BOOT_MODE_OM = 32, + BOOT_MODE_USB, /* Boot using USB download */ +}; + +unsigned int get_boot_mode(void); + void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable);
#define EXYNOS_MIPI_PHY_ENABLE (1 << 0) diff --git a/arch/arm/include/asm/arch-exynos/spl.h b/arch/arm/include/asm/arch-exynos/spl.h index b1d68c3..cdcb2bc 100644 --- a/arch/arm/include/asm/arch-exynos/spl.h +++ b/arch/arm/include/asm/arch-exynos/spl.h @@ -8,20 +8,7 @@ #define __ASM_ARCH_EXYNOS_SPL_H__
#include <asm/arch-exynos/dmc.h> - -enum boot_mode { - /* - * Assign the OM pin values for respective boot modes. - * Exynos4 does not support spi boot and the mmc boot OM - * pin values are the same across Exynos4 and Exynos5. - */ - BOOT_MODE_MMC = 4, - BOOT_MODE_EMMC = 8, /* EMMC4.4 */ - BOOT_MODE_SERIAL = 20, - /* Boot based on Operating Mode pin settings */ - BOOT_MODE_OM = 32, - BOOT_MODE_USB, /* Boot using USB download */ -}; +#include <asm/arch/power.h>
#ifndef __ASSEMBLY__ /* Parameters of early board initialization in SPL */ @@ -62,7 +49,7 @@ struct spl_machine_param { * table only for mmc boot. */ u32 uboot_size; - enum boot_mode boot_source; /* Boot device */ + unsigned boot_source; /* Boot device */ unsigned frequency_mhz; /* Frequency of memory in MHz */ unsigned arm_freq_mhz; /* ARM Frequency in MHz */ u32 serial_base; /* Serial base address */

It is possible to boot device using a micro SD or eMMC slots. In this situation, boot device should be registered as a block device 0 in the MMC framework, because CONFIG_SYS_MMC_ENV_DEV is usually set to "0" in the most config cases.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com --- Changes V3: - separate two changes into two commits
Changes V4: - board.c: add functions: init_mmc() and init_dwmmc() - board_mmc_init(): call get_boot_mode() --- board/samsung/common/board.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index 9dc7c83..4d3f216 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -240,22 +240,39 @@ int board_eth_init(bd_t *bis) }
#ifdef CONFIG_GENERIC_MMC -int board_mmc_init(bd_t *bis) +static int init_mmc(void) +{ +#ifdef CONFIG_SDHCI + return exynos_mmc_init(gd->fdt_blob); +#else + return 0; +#endif +} + +static int init_dwmmc(void) { - int ret; #ifdef CONFIG_DWMMC - /* dwmmc initializattion for available channels */ - ret = exynos_dwmmc_init(gd->fdt_blob); - if (ret) - debug("dwmmc init failed\n"); + return exynos_dwmmc_init(gd->fdt_blob); +#else + return 0; #endif +} + +int board_mmc_init(bd_t *bis) +{ + int ret; + + if (get_boot_mode() == BOOT_MODE_MMC) { + ret = init_mmc(); + ret |= init_dwmmc(); + } else { + ret = init_dwmmc(); + ret |= init_mmc(); + }
-#ifdef CONFIG_SDHCI - /* mmc initializattion for available channels */ - ret = exynos_mmc_init(gd->fdt_blob); if (ret) debug("mmc init failed\n"); -#endif + return ret; } #endif

This change introduces new common function: - set_dfu_alt_info() - put dfu system and bootloader setting into $dfu_alt_info. functions declaration: - char *get_dfu_alt_system(void) - char *get_dfu_alt_boot(void) - void set_dfu_alt_info(void) and new config: - CONFIG_SET_DFU_ALT_INFO
This function can be used for auto setting dfu configuration on boot. Such feature is useful for multi board support by one u-boot binary. Each board should define two functions: - get_dfu_alt_system() - get_dfu_alt_boot()
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Piotr Wilczek p.wilczek@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v2: - change config names: CONFIG_SET_DFU_BOOT_ALT to CONFIG_DFU_ALT_BOOTLOADER and CONFIG_DFU_BOOT_ALT_* to CONFIG_DFU_ALT_BOOT_* - change function name: set_dfu_boot_alt() to set_dfu_alt_boot() - remove superfluous ifdefs
Changes v3: - set $dfu_alt_info at every boot - new config: CONFIG_SET_DFU_ALT_INFO - update commit msg
Changes v4: - set_dfu_alt_info(): add checking the pointer returned by malloc
Changes v5: - set_dfu_alt_info(): remove malloc and declare cache aligned buffer - set_dfu_alt_info(): introduce CONFIG_SET_DFU_ALT_BUF_LEN --- board/samsung/common/misc.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/samsung/misc.h | 6 ++++++ 2 files changed, 47 insertions(+)
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index a453a82..9e52452 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -11,6 +11,7 @@ #include <samsung/misc.h> #include <errno.h> #include <version.h> +#include <malloc.h> #include <linux/sizes.h> #include <asm/arch/cpu.h> #include <asm/arch/gpio.h> @@ -21,6 +22,46 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_SET_DFU_ALT_INFO +void set_dfu_alt_info(void) +{ + size_t buf_size = CONFIG_SET_DFU_ALT_BUF_LEN; + ALLOC_CACHE_ALIGN_BUFFER(char, buf, buf_size); + char *alt_info = "Settings not found!"; + char *status = "error!\n"; + char *alt_setting; + char *alt_sep; + int offset = 0; + + puts("DFU alt info setting: "); + + alt_setting = get_dfu_alt_boot(); + if (alt_setting) { + setenv("dfu_alt_boot", alt_setting); + offset = snprintf(buf, buf_size, "%s", alt_setting); + } + + alt_setting = get_dfu_alt_system(); + if (alt_setting) { + if (offset) + alt_sep = ";"; + else + alt_sep = ""; + + offset += snprintf(buf + offset, buf_size - offset, + "%s%s", alt_sep, alt_setting); + } + + if (offset) { + alt_info = buf; + status = "done\n"; + } + + setenv("dfu_alt_info", alt_info); + puts(status); +} +#endif + #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG void set_board_info(void) { diff --git a/include/samsung/misc.h b/include/samsung/misc.h index 10653a1..e82bf32 100644 --- a/include/samsung/misc.h +++ b/include/samsung/misc.h @@ -28,4 +28,10 @@ void check_boot_mode(void); void draw_logo(void); #endif
+#ifdef CONFIG_SET_DFU_ALT_INFO +char *get_dfu_alt_system(void); +char *get_dfu_alt_boot(void); +void set_dfu_alt_info(void); +#endif + #endif /* __SAMSUNG_MISC_COMMON_H__ */

This change enable automatic setting of dfu alt info on every boot. This is useful in case of booting one u-boot binary from multiple media.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com --- board/samsung/common/board.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index 4d3f216..a46e87b 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -324,6 +324,9 @@ int arch_early_init_r(void) #ifdef CONFIG_MISC_INIT_R int misc_init_r(void) { +#ifdef CONFIG_SET_DFU_ALT_INFO + set_dfu_alt_info(); +#endif #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG set_board_info(); #endif

On an Odroid U3 board, the SOC is unable to reset the eMMC card in the DWMMC mode by the cpu software reset. Manual reset of the card by switching proper gpio pin - fixes this issue.
Such solution needs to add a call to pre reset function. This is done by the reset_misc() function, which is called before reset_cpu(). The function reset_misc() is a weak function.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Jean-Christophe PLAGNIOL-VILLARD plagnioj@jcrosoft.com Cc: Albert ARIBAUD albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com
Changes v4: - arch/arm/reset: fix weak function attribute to proper style --- arch/arm/lib/reset.c | 6 ++++++ include/common.h | 1 + 2 files changed, 7 insertions(+)
diff --git a/arch/arm/lib/reset.c b/arch/arm/lib/reset.c index 7a03580..9a95f08 100644 --- a/arch/arm/lib/reset.c +++ b/arch/arm/lib/reset.c @@ -23,6 +23,10 @@
#include <common.h>
+__weak void reset_misc(void) +{ +} + int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { puts ("resetting ...\n"); @@ -30,6 +34,8 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) udelay (50000); /* wait 50 ms */
disable_interrupts(); + + reset_misc(); reset_cpu(0);
/*NOTREACHED*/ diff --git a/include/common.h b/include/common.h index 82c0a5a..48e4cbd 100644 --- a/include/common.h +++ b/include/common.h @@ -619,6 +619,7 @@ int checkicache (void); int checkdcache (void); void upmconfig (unsigned int, unsigned int *, unsigned int); ulong get_tbclk (void); +void reset_misc (void); void reset_cpu (ulong addr); #if defined (CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP) void ft_cpu_setup(void *blob, bd_t *bd);

This change adds declaration of functions: - set_board_type() - called at board_early_init_f() - get_board_type() - called at checkboard()
For supporting multiple board types in a one config - it is welcome to display the current board model. This is what get_board_type() should return.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Piotr Wilczek p.wilczek@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v3: - change the commit order - include/samsung/misc.h: add new functions declaration - update a commit message
Changes v4: - checkboard(): remove redundant variable
Changes v5: - board.c: move call to set_board_type() into board_early_init_f() - misc.h: remove get_board_name() function declaration --- board/samsung/common/board.c | 15 ++++++++++----- include/samsung/misc.h | 4 ++++ 2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index a46e87b..3de828a 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -137,7 +137,9 @@ static int board_uart_init(void) int board_early_init_f(void) { int err; - +#ifdef CONFIG_BOARD_TYPES + set_board_type(); +#endif err = board_uart_init(); if (err) { debug("UART init failed\n"); @@ -147,7 +149,6 @@ int board_early_init_f(void) #ifdef CONFIG_SYS_I2C_INIT_BOARD board_i2c_init(gd->fdt_blob); #endif - return exynos_early_init_f(); } #endif @@ -280,11 +281,15 @@ int board_mmc_init(bd_t *bis) #ifdef CONFIG_DISPLAY_BOARDINFO int checkboard(void) { - const char *board_name; + const char *board_info;
- board_name = fdt_getprop(gd->fdt_blob, 0, "model", NULL); - printf("Board: %s\n", board_name ? board_name : "unknown"); + board_info = fdt_getprop(gd->fdt_blob, 0, "model", NULL); + printf("Board: %s\n", board_info ? board_info : "unknown"); +#ifdef CONFIG_BOARD_TYPES + board_info = get_board_type();
+ printf("Model: %s\n", board_info ? board_info : "unknown"); +#endif return 0; } #endif diff --git a/include/samsung/misc.h b/include/samsung/misc.h index e82bf32..607e8d4 100644 --- a/include/samsung/misc.h +++ b/include/samsung/misc.h @@ -33,5 +33,9 @@ char *get_dfu_alt_system(void); char *get_dfu_alt_boot(void); void set_dfu_alt_info(void); #endif +#ifdef CONFIG_BOARD_TYPES +void set_board_type(void); +const char *get_board_type(void); +#endif
#endif /* __SAMSUNG_MISC_COMMON_H__ */

This change adds setup of environmental board info using get_board_name() and get_board_type() functions for config CONFIG_BOARD_TYPES.
This is useful in case of running many boards with just one config.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Piotr Wilczek p.wilczek@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v2: - set_board_info: move the bdtype pointer to avoid unused pointer compilation warning
Changes v3: - samsung: misc: change get_board_type_fdt() to get_board_type() - samsung: misc: set env $boardname using get_board_* functions for CONFIG_BOARD_TYPES - update commit msg
Changes v5: - misc.c: set_bard_info(): remove a call to get_board_name() --- board/samsung/common/misc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index 9e52452..8766f0c 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -79,8 +79,16 @@ void set_board_info(void) setenv("board_rev", info); #endif #ifdef CONFIG_OF_LIBFDT - snprintf(info, ARRAY_SIZE(info), "%s%x-%s.dtb", - CONFIG_SYS_SOC, s5p_cpu_id, CONFIG_SYS_BOARD); + const char *bdtype = ""; + const char *bdname = CONFIG_SYS_BOARD; + +#ifdef CONFIG_BOARD_TYPES + bdtype = get_board_type(); + sprintf(info, "%s%s", bdname, bdtype); + setenv("boardname", info); +#endif + snprintf(info, ARRAY_SIZE(info), "%s%x-%s%s.dtb", + CONFIG_SYS_SOC, s5p_cpu_id, bdname, bdtype); setenv("fdtfile", info); #endif }

This board file supports standard features of Odroid X2 and U3 boards: - Exynos4412 core clock set to 1000MHz and MPLL peripherial clock set to 800MHz, - MAX77686 power regulator, - USB PHY, - enable XCL205 - power for board peripherials - check board type: U3 or X2. - enable Odroid U3 FAN cooler
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Tom Rini trini@ti.com
--- Changes v2: - enable fan on odroid U3
Changes v3: - odroid.c: clean up board name related code - odroid.c: remove static from set_board_type() - odroid.c: add implementation of functions: get_dfu_alt_* - odroid.c: include misc.h
Changes v4: - odroid.c: dfu_get_alt_boot: add call get_boot_mode()
Changes v5: - odroid.c: set_board_type: change mdelay to sdelay, define XCL205 GPIO config - odroid.c: board_gpio_init(): fix OTG for Odroid U3+ - odroid.c: reserve the last 1 MB of dram for secure firmware - odroid.c: board_clock_init(): code cleanup - odroid.c: get_dfu_alt_boot(): remove setenv() - odroid.c: remove get_board_name() function definition - odroid.c: add enum ODROID_TYPES --- board/samsung/odroid/Makefile | 8 + board/samsung/odroid/odroid.c | 470 ++++++++++++++++++++++++++++++++++++++++++ board/samsung/odroid/setup.h | 255 +++++++++++++++++++++++ 3 files changed, 733 insertions(+) create mode 100644 board/samsung/odroid/Makefile create mode 100644 board/samsung/odroid/odroid.c create mode 100644 board/samsung/odroid/setup.h
diff --git a/board/samsung/odroid/Makefile b/board/samsung/odroid/Makefile new file mode 100644 index 0000000..b98aaeb --- /dev/null +++ b/board/samsung/odroid/Makefile @@ -0,0 +1,8 @@ +# +# Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved. +# Przemyslaw Marczak p.marczak@samsung.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := odroid.o diff --git a/board/samsung/odroid/odroid.c b/board/samsung/odroid/odroid.c new file mode 100644 index 0000000..2c5c107 --- /dev/null +++ b/board/samsung/odroid/odroid.c @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * Przemyslaw Marczak p.marczak@samsung.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/power.h> +#include <asm/arch/clock.h> +#include <asm/arch/gpio.h> +#include <asm/gpio.h> +#include <asm/arch/cpu.h> +#include <power/pmic.h> +#include <power/max77686_pmic.h> +#include <errno.h> +#include <usb.h> +#include <usb/s3c_udc.h> +#include <samsung/misc.h> +#include "setup.h" + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_BOARD_TYPES +/* Odroid board types */ +enum { + ODROID_TYPE_U3, + ODROID_TYPE_X2, + ODROID_TYPES, +}; + +void set_board_type(void) +{ + /* Set GPA1 pin 1 to HI - enable XCL205 output */ + writel(XCL205_EN_GPIO_CON_CFG, XCL205_EN_GPIO_CON); + writel(XCL205_EN_GPIO_DAT_CFG, XCL205_EN_GPIO_CON + 0x4); + writel(XCL205_EN_GPIO_PUD_CFG, XCL205_EN_GPIO_CON + 0x8); + writel(XCL205_EN_GPIO_DRV_CFG, XCL205_EN_GPIO_CON + 0xc); + + /* Set GPC1 pin 2 to IN - check XCL205 output state */ + writel(XCL205_STATE_GPIO_CON_CFG, XCL205_STATE_GPIO_CON); + writel(XCL205_STATE_GPIO_PUD_CFG, XCL205_STATE_GPIO_CON + 0x8); + + /* XCL205 - needs some latch time */ + sdelay(200000); + + /* Check GPC1 pin2 - LED supplied by XCL205 - X2 only */ + if (readl(XCL205_STATE_GPIO_DAT) & (1 << XCL205_STATE_GPIO_PIN)) + gd->board_type = ODROID_TYPE_X2; + else + gd->board_type = ODROID_TYPE_U3; +} + +const char *get_board_type(void) +{ + const char *board_type[] = {"u3", "x2"}; + + return board_type[gd->board_type]; +} +#endif + +#ifdef CONFIG_SET_DFU_ALT_INFO +char *get_dfu_alt_system(void) +{ + return getenv("dfu_alt_system"); +} + +char *get_dfu_alt_boot(void) +{ + char *alt_boot; + + switch (get_boot_mode()) { + case BOOT_MODE_MMC: + alt_boot = CONFIG_DFU_ALT_BOOT_SD; + break; + case BOOT_MODE_EMMC: + case BOOT_MODE_EMMC_SD: + alt_boot = CONFIG_DFU_ALT_BOOT_EMMC; + break; + default: + alt_boot = NULL; + break; + } + return alt_boot; +} +#endif + +static void board_clock_init(void) +{ + unsigned int set, clr, clr_src_cpu, clr_pll_con0, clr_src_dmc; + struct exynos4x12_clock *clk = (struct exynos4x12_clock *) + samsung_get_base_clock(); + + /* + * CMU_CPU clocks src to MPLL + * Bit values: 0 ; 1 + * MUX_APLL_SEL: FIN_PLL ; FOUT_APLL + * MUX_CORE_SEL: MOUT_APLL ; SCLK_MPLL + * MUX_HPM_SEL: MOUT_APLL ; SCLK_MPLL_USER_C + * MUX_MPLL_USER_SEL_C: FIN_PLL ; SCLK_MPLL + */ + clr_src_cpu = MUX_APLL_SEL(1) | MUX_CORE_SEL(1) | + MUX_HPM_SEL(1) | MUX_MPLL_USER_SEL_C(1); + set = MUX_APLL_SEL(0) | MUX_CORE_SEL(1) | MUX_HPM_SEL(1) | + MUX_MPLL_USER_SEL_C(1); + + clrsetbits_le32(&clk->src_cpu, clr_src_cpu, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_cpu) & MUX_STAT_CPU_CHANGING) + continue; + + /* Set APLL to 1000MHz */ + clr_pll_con0 = SDIV(7) | PDIV(63) | MDIV(1023) | FSEL(1); + set = SDIV(0) | PDIV(3) | MDIV(125) | FSEL(1); + + clrsetbits_le32(&clk->apll_con0, clr_pll_con0, set); + + /* Wait for PLL to be locked */ + while (!(readl(&clk->apll_con0) & PLL_LOCKED_BIT)) + continue; + + /* Set CMU_CPU clocks src to APLL */ + set = MUX_APLL_SEL(1) | MUX_CORE_SEL(0) | MUX_HPM_SEL(0) | + MUX_MPLL_USER_SEL_C(1); + clrsetbits_le32(&clk->src_cpu, clr_src_cpu, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_cpu) & MUX_STAT_CPU_CHANGING) + continue; + + set = CORE_RATIO(0) | COREM0_RATIO(2) | COREM1_RATIO(5) | + PERIPH_RATIO(0) | ATB_RATIO(4) | PCLK_DBG_RATIO(1) | + APLL_RATIO(0) | CORE2_RATIO(0); + /* + * Set dividers for MOUTcore = 1000 MHz + * coreout = MOUT / (ratio + 1) = 1000 MHz (0) + * corem0 = armclk / (ratio + 1) = 333 MHz (2) + * corem1 = armclk / (ratio + 1) = 166 MHz (5) + * periph = armclk / (ratio + 1) = 1000 MHz (0) + * atbout = MOUT / (ratio + 1) = 200 MHz (4) + * pclkdbgout = atbout / (ratio + 1) = 100 MHz (1) + * sclkapll = MOUTapll / (ratio + 1) = 1000 MHz (0) + * core2out = core_out / (ratio + 1) = 1000 MHz (0) (armclk) + */ + clr = CORE_RATIO(7) | COREM0_RATIO(7) | COREM1_RATIO(7) | + PERIPH_RATIO(7) | ATB_RATIO(7) | PCLK_DBG_RATIO(7) | + APLL_RATIO(7) | CORE2_RATIO(7); + + clrsetbits_le32(&clk->div_cpu0, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_cpu0) & DIV_STAT_CPU0_CHANGING) + continue; + + /* + * For MOUThpm = 1000 MHz (MOUTapll) + * doutcopy = MOUThpm / (ratio + 1) = 200 (4) + * sclkhpm = doutcopy / (ratio + 1) = 200 (4) + * cores_out = armclk / (ratio + 1) = 1000 (0) + */ + clr = COPY_RATIO(7) | HPM_RATIO(7) | CORES_RATIO(7); + set = COPY_RATIO(4) | HPM_RATIO(4) | CORES_RATIO(0); + + clrsetbits_le32(&clk->div_cpu1, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_cpu1) & DIV_STAT_CPU1_CHANGING) + continue; + + /* + * Set CMU_DMC clocks src to APLL + * Bit values: 0 ; 1 + * MUX_C2C_SEL: SCLKMPLL ; SCLKAPLL + * MUX_DMC_BUS_SEL: SCLKMPLL ; SCLKAPLL + * MUX_DPHY_SEL: SCLKMPLL ; SCLKAPLL + * MUX_MPLL_SEL: FINPLL ; MOUT_MPLL_FOUT + * MUX_PWI_SEL: 0110 (MPLL); 0111 (EPLL); 1000 (VPLL); 0(XXTI) + * MUX_G2D_ACP0_SEL: SCLKMPLL ; SCLKAPLL + * MUX_G2D_ACP1_SEL: SCLKEPLL ; SCLKVPLL + * MUX_G2D_ACP_SEL: OUT_ACP0 ; OUT_ACP1 + */ + clr_src_dmc = MUX_C2C_SEL(1) | MUX_DMC_BUS_SEL(1) | + MUX_DPHY_SEL(1) | MUX_MPLL_SEL(1) | + MUX_PWI_SEL(15) | MUX_G2D_ACP0_SEL(1) | + MUX_G2D_ACP1_SEL(1) | MUX_G2D_ACP_SEL(1); + set = MUX_C2C_SEL(1) | MUX_DMC_BUS_SEL(1) | MUX_DPHY_SEL(1) | + MUX_MPLL_SEL(0) | MUX_PWI_SEL(0) | MUX_G2D_ACP0_SEL(1) | + MUX_G2D_ACP1_SEL(1) | MUX_G2D_ACP_SEL(1); + + clrsetbits_le32(&clk->src_dmc, clr_src_dmc, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_dmc) & MUX_STAT_DMC_CHANGING) + continue; + + /* Set MPLL to 800MHz */ + set = SDIV(0) | PDIV(3) | MDIV(100) | FSEL(0) | PLL_ENABLE(1); + + clrsetbits_le32(&clk->mpll_con0, clr_pll_con0, set); + + /* Wait for PLL to be locked */ + while (!(readl(&clk->mpll_con0) & PLL_LOCKED_BIT)) + continue; + + /* Switch back CMU_DMC mux */ + set = MUX_C2C_SEL(0) | MUX_DMC_BUS_SEL(0) | MUX_DPHY_SEL(0) | + MUX_MPLL_SEL(1) | MUX_PWI_SEL(8) | MUX_G2D_ACP0_SEL(0) | + MUX_G2D_ACP1_SEL(0) | MUX_G2D_ACP_SEL(0); + + clrsetbits_le32(&clk->src_dmc, clr_src_dmc, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_dmc) & MUX_STAT_DMC_CHANGING) + continue; + + /* CLK_DIV_DMC0 */ + clr = ACP_RATIO(7) | ACP_PCLK_RATIO(7) | DPHY_RATIO(7) | + DMC_RATIO(7) | DMCD_RATIO(7) | DMCP_RATIO(7); + /* + * For: + * MOUTdmc = 800 MHz + * MOUTdphy = 800 MHz + * + * aclk_acp = MOUTdmc / (ratio + 1) = 200 (3) + * pclk_acp = aclk_acp / (ratio + 1) = 100 (1) + * sclk_dphy = MOUTdphy / (ratio + 1) = 400 (1) + * sclk_dmc = MOUTdmc / (ratio + 1) = 400 (1) + * aclk_dmcd = sclk_dmc / (ratio + 1) = 200 (1) + * aclk_dmcp = aclk_dmcd / (ratio + 1) = 100 (1) + */ + set = ACP_RATIO(3) | ACP_PCLK_RATIO(1) | DPHY_RATIO(1) | + DMC_RATIO(1) | DMCD_RATIO(1) | DMCP_RATIO(1); + + clrsetbits_le32(&clk->div_dmc0, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_dmc0) & DIV_STAT_DMC0_CHANGING) + continue; + + /* CLK_DIV_DMC1 */ + clr = G2D_ACP_RATIO(15) | C2C_RATIO(7) | PWI_RATIO(15) | + C2C_ACLK_RATIO(7) | DVSEM_RATIO(127) | DPM_RATIO(127); + /* + * For: + * MOUTg2d = 800 MHz + * MOUTc2c = 800 Mhz + * MOUTpwi = 108 MHz + * + * sclk_g2d_acp = MOUTg2d / (ratio + 1) = 400 (1) + * sclk_c2c = MOUTc2c / (ratio + 1) = 400 (1) + * aclk_c2c = sclk_c2c / (ratio + 1) = 200 (1) + * sclk_pwi = MOUTpwi / (ratio + 1) = 18 (5) + */ + set = G2D_ACP_RATIO(1) | C2C_RATIO(1) | PWI_RATIO(5) | + C2C_ACLK_RATIO(1) | DVSEM_RATIO(1) | DPM_RATIO(1); + + clrsetbits_le32(&clk->div_dmc1, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_dmc1) & DIV_STAT_DMC1_CHANGING) + continue; + + /* CLK_SRC_PERIL0 */ + clr = UART0_SEL(15) | UART1_SEL(15) | UART2_SEL(15) | + UART3_SEL(15) | UART4_SEL(15); + /* + * Set CLK_SRC_PERIL0 clocks src to MPLL + * src values: 0(XXTI); 1(XusbXTI); 2(SCLK_HDMI24M); 3(SCLK_USBPHY0); + * 5(SCLK_HDMIPHY); 6(SCLK_MPLL_USER_T); 7(SCLK_EPLL); + * 8(SCLK_VPLL) + * + * Set all to SCLK_MPLL_USER_T + */ + set = UART0_SEL(6) | UART1_SEL(6) | UART2_SEL(6) | UART3_SEL(6) | + UART4_SEL(6); + + clrsetbits_le32(&clk->src_peril0, clr, set); + + /* CLK_DIV_PERIL0 */ + clr = UART0_RATIO(15) | UART1_RATIO(15) | UART2_RATIO(15) | + UART3_RATIO(15) | UART4_RATIO(15); + /* + * For MOUTuart0-4: 800MHz + * + * SCLK_UARTx = MOUTuartX / (ratio + 1) = 100 (7) + */ + set = UART0_RATIO(7) | UART1_RATIO(7) | UART2_RATIO(7) | + UART3_RATIO(7) | UART4_RATIO(7); + + clrsetbits_le32(&clk->div_peril0, clr, set); + + while (readl(&clk->div_stat_peril0) & DIV_STAT_PERIL0_CHANGING) + continue; + + /* CLK_DIV_FSYS1 */ + clr = MMC0_RATIO(15) | MMC0_PRE_RATIO(255) | MMC1_RATIO(15) | + MMC1_PRE_RATIO(255); + /* + * For MOUTmmc0-3 = 800 MHz (MPLL) + * + * DOUTmmc1 = MOUTmmc1 / (ratio + 1) = 100 (7) + * sclk_mmc1 = DOUTmmc1 / (ratio + 1) = 50 (1) + * DOUTmmc0 = MOUTmmc0 / (ratio + 1) = 100 (7) + * sclk_mmc0 = DOUTmmc0 / (ratio + 1) = 50 (1) + */ + set = MMC0_RATIO(7) | MMC0_PRE_RATIO(1) | MMC1_RATIO(7) | + MMC1_PRE_RATIO(1); + + clrsetbits_le32(&clk->div_fsys1, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_fsys1) & DIV_STAT_FSYS1_CHANGING) + continue; + + /* CLK_DIV_FSYS2 */ + clr = MMC2_RATIO(15) | MMC2_PRE_RATIO(255) | MMC3_RATIO(15) | + MMC3_PRE_RATIO(255); + /* + * For MOUTmmc0-3 = 800 MHz (MPLL) + * + * DOUTmmc3 = MOUTmmc3 / (ratio + 1) = 100 (7) + * sclk_mmc3 = DOUTmmc3 / (ratio + 1) = 50 (1) + * DOUTmmc2 = MOUTmmc2 / (ratio + 1) = 100 (7) + * sclk_mmc2 = DOUTmmc2 / (ratio + 1) = 50 (1) + */ + set = MMC2_RATIO(7) | MMC2_PRE_RATIO(1) | MMC3_RATIO(7) | + MMC3_PRE_RATIO(1); + + clrsetbits_le32(&clk->div_fsys2, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_fsys2) & DIV_STAT_FSYS2_CHANGING) + continue; + + /* CLK_DIV_FSYS3 */ + clr = MMC4_RATIO(15) | MMC4_PRE_RATIO(255); + /* + * For MOUTmmc4 = 800 MHz (MPLL) + * + * DOUTmmc4 = MOUTmmc4 / (ratio + 1) = 100 (7) + * sclk_mmc4 = DOUTmmc4 / (ratio + 1) = 100 (0) + */ + set = MMC4_RATIO(7) | MMC4_PRE_RATIO(0); + + clrsetbits_le32(&clk->div_fsys3, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_fsys3) & DIV_STAT_FSYS3_CHANGING) + continue; + + return; +} + +static void board_gpio_init(void) +{ + /* eMMC Reset Pin */ + gpio_cfg_pin(EXYNOS4X12_GPIO_K12, S5P_GPIO_FUNC(0x1)); + gpio_set_pull(EXYNOS4X12_GPIO_K12, S5P_GPIO_PULL_NONE); + gpio_set_drv(EXYNOS4X12_GPIO_K12, S5P_GPIO_DRV_4X); + + /* Enable FAN (Odroid U3) */ + gpio_set_pull(EXYNOS4X12_GPIO_D00, S5P_GPIO_PULL_UP); + gpio_set_drv(EXYNOS4X12_GPIO_D00, S5P_GPIO_DRV_4X); + gpio_direction_output(EXYNOS4X12_GPIO_D00, 1); + + /* OTG Vbus output (Odroid U3+) */ + gpio_set_pull(EXYNOS4X12_GPIO_L20, S5P_GPIO_PULL_NONE); + gpio_set_drv(EXYNOS4X12_GPIO_L20, S5P_GPIO_DRV_4X); + gpio_direction_output(EXYNOS4X12_GPIO_L20, 0); + + /* OTG INT (Odroid U3+) */ + gpio_set_pull(EXYNOS4X12_GPIO_X31, S5P_GPIO_PULL_UP); + gpio_set_drv(EXYNOS4X12_GPIO_X31, S5P_GPIO_DRV_4X); + gpio_direction_input(EXYNOS4X12_GPIO_X31); +} + +static int pmic_init_max77686(void) +{ + struct pmic *p = pmic_get("MAX77686_PMIC"); + + if (pmic_probe(p)) + return -ENODEV; + + /* Set LDO Voltage */ + max77686_set_ldo_voltage(p, 20, 1800000); /* LDO20 eMMC */ + max77686_set_ldo_voltage(p, 21, 2800000); /* LDO21 SD */ + max77686_set_ldo_voltage(p, 22, 2800000); /* LDO22 eMMC */ + + return 0; +} + +#ifdef CONFIG_SYS_I2C_INIT_BOARD +static void board_init_i2c(void) +{ + /* I2C_0 */ + if (exynos_pinmux_config(PERIPH_ID_I2C0, PINMUX_FLAG_NONE)) + debug("I2C%d not configured\n", (I2C_0)); +} +#endif + +int exynos_early_init_f(void) +{ + board_clock_init(); + board_gpio_init(); + + return 0; +} + +int exynos_init(void) +{ + /* The last MB of memory is reserved for secure firmware */ + gd->ram_size -= SZ_1M; + gd->bd->bi_dram[CONFIG_NR_DRAM_BANKS - 1].size -= SZ_1M; + + return 0; +} + +int exynos_power_init(void) +{ +#ifdef CONFIG_SYS_I2C_INIT_BOARD + board_init_i2c(); +#endif + pmic_init(I2C_0); + pmic_init_max77686(); + + return 0; +} + +#ifdef CONFIG_USB_GADGET +static int s5pc210_phy_control(int on) +{ + struct pmic *p_pmic; + + p_pmic = pmic_get("MAX77686_PMIC"); + if (!p_pmic) + return -ENODEV; + + if (pmic_probe(p_pmic)) + return -1; + + if (on) + return max77686_set_ldo_mode(p_pmic, 12, OPMODE_ON); + else + return max77686_set_ldo_mode(p_pmic, 12, OPMODE_LPM); +} + +struct s3c_plat_otg_data s5pc210_otg_data = { + .phy_control = s5pc210_phy_control, + .regs_phy = EXYNOS4X12_USBPHY_BASE, + .regs_otg = EXYNOS4X12_USBOTG_BASE, + .usb_phy_ctrl = EXYNOS4X12_USBPHY_CONTROL, + .usb_flags = PHY0_SLEEP, +}; + +int board_usb_init(int index, enum usb_init_type init) +{ + debug("USB_udc_probe\n"); + return s3c_udc_probe(&s5pc210_otg_data); +} +#endif + +void reset_misc(void) +{ + /* Reset eMMC*/ + gpio_set_value(EXYNOS4X12_GPIO_K12, 0); + mdelay(10); + gpio_set_value(EXYNOS4X12_GPIO_K12, 1); +} diff --git a/board/samsung/odroid/setup.h b/board/samsung/odroid/setup.h new file mode 100644 index 0000000..f6acbff --- /dev/null +++ b/board/samsung/odroid/setup.h @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * Przemyslaw Marczak p.marczak@samsung.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ODROIDU3_SETUP__ +#define __ODROIDU3_SETUP__ + +/* A/M PLL_CON0 */ +#define SDIV(x) (x & 0x7) +#define PDIV(x) ((x & 0x3f) << 8) +#define MDIV(x) ((x & 0x3ff) << 16) +#define FSEL(x) ((x & 0x1) << 27) +#define PLL_LOCKED_BIT (0x1 << 29) +#define PLL_ENABLE(x) ((x & 0x1) << 31) + +/* CLK_SRC_CPU */ +#define MUX_APLL_SEL(x) (x & 0x1) +#define MUX_CORE_SEL(x) ((x & 0x1) << 16) +#define MUX_HPM_SEL(x) ((x & 0x1) << 20) +#define MUX_MPLL_USER_SEL_C(x) ((x & 0x1) << 24) + +#define MUX_STAT_CHANGING 0x100 + +/* CLK_MUX_STAT_CPU */ +#define APLL_SEL(x) (x & 0x7) +#define CORE_SEL(x) ((x & 0x7) << 16) +#define HPM_SEL(x) ((x & 0x7) << 20) +#define MPLL_USER_SEL_C(x) ((x & 0x7) << 24) +#define MUX_STAT_CPU_CHANGING (APLL_SEL(MUX_STAT_CHANGING) | \ + CORE_SEL(MUX_STAT_CHANGING) | \ + HPM_SEL(MUX_STAT_CHANGING) | \ + MPLL_USER_SEL_C(MUX_STAT_CHANGING)) + +/* CLK_DIV_CPU0 */ +#define CORE_RATIO(x) (x & 0x7) +#define COREM0_RATIO(x) ((x & 0x7) << 4) +#define COREM1_RATIO(x) ((x & 0x7) << 8) +#define PERIPH_RATIO(x) ((x & 0x7) << 12) +#define ATB_RATIO(x) ((x & 0x7) << 16) +#define PCLK_DBG_RATIO(x) ((x & 0x7) << 20) +#define APLL_RATIO(x) ((x & 0x7) << 24) +#define CORE2_RATIO(x) ((x & 0x7) << 28) + +/* CLK_DIV_STAT_CPU0 */ +#define DIV_CORE(x) (x & 0x1) +#define DIV_COREM0(x) ((x & 0x1) << 4) +#define DIV_COREM1(x) ((x & 0x1) << 8) +#define DIV_PERIPH(x) ((x & 0x1) << 12) +#define DIV_ATB(x) ((x & 0x1) << 16) +#define DIV_PCLK_DBG(x) ((x & 0x1) << 20) +#define DIV_APLL(x) ((x & 0x1) << 24) +#define DIV_CORE2(x) ((x & 0x1) << 28) + +#define DIV_STAT_CHANGING 0x1 +#define DIV_STAT_CPU0_CHANGING (DIV_CORE(DIV_STAT_CHANGING) | \ + DIV_COREM0(DIV_STAT_CHANGING) | \ + DIV_COREM1(DIV_STAT_CHANGING) | \ + DIV_PERIPH(DIV_STAT_CHANGING) | \ + DIV_ATB(DIV_STAT_CHANGING) | \ + DIV_PCLK_DBG(DIV_STAT_CHANGING) | \ + DIV_APLL(DIV_STAT_CHANGING) | \ + DIV_CORE2(DIV_STAT_CHANGING)) + +/* CLK_DIV_CPU1 */ +#define COPY_RATIO(x) (x & 0x7) +#define HPM_RATIO(x) ((x & 0x7) << 4) +#define CORES_RATIO(x) ((x & 0x7) << 8) + +/* CLK_DIV_STAT_CPU1 */ +#define DIV_COPY(x) (x & 0x7) +#define DIV_HPM(x) ((x & 0x1) << 4) +#define DIV_CORES(x) ((x & 0x1) << 8) + +#define DIV_STAT_CPU1_CHANGING (DIV_COPY(DIV_STAT_CHANGING) | \ + DIV_HPM(DIV_STAT_CHANGING) | \ + DIV_CORES(DIV_STAT_CHANGING)) + +/* CLK_SRC_DMC */ +#define MUX_C2C_SEL(x) (x & 0x1) +#define MUX_DMC_BUS_SEL(x) ((x & 0x1) << 4) +#define MUX_DPHY_SEL(x) ((x & 0x1) << 8) +#define MUX_MPLL_SEL(x) ((x & 0x1) << 12) +#define MUX_PWI_SEL(x) ((x & 0xf) << 16) +#define MUX_G2D_ACP0_SEL(x) ((x & 0x1) << 20) +#define MUX_G2D_ACP1_SEL(x) ((x & 0x1) << 24) +#define MUX_G2D_ACP_SEL(x) ((x & 0x1) << 28) + +/* CLK_MUX_STAT_DMC */ +#define C2C_SEL(x) ((x) & 0x7) +#define DMC_BUS_SEL(x) ((x & 0x7) << 4) +#define DPHY_SEL(x) ((x & 0x7) << 8) +#define MPLL_SEL(x) ((x & 0x7) << 12) +/* #define PWI_SEL(x) ((x & 0xf) << 16) - Reserved */ +#define G2D_ACP0_SEL(x) ((x & 0x7) << 20) +#define G2D_ACP1_SEL(x) ((x & 0x7) << 24) +#define G2D_ACP_SEL(x) ((x & 0x7) << 28) + +#define MUX_STAT_DMC_CHANGING (C2C_SEL(MUX_STAT_CHANGING) | \ + DMC_BUS_SEL(MUX_STAT_CHANGING) | \ + DPHY_SEL(MUX_STAT_CHANGING) | \ + MPLL_SEL(MUX_STAT_CHANGING) |\ + G2D_ACP0_SEL(MUX_STAT_CHANGING) | \ + G2D_ACP1_SEL(MUX_STAT_CHANGING) | \ + G2D_ACP_SEL(MUX_STAT_CHANGING)) + +/* CLK_DIV_DMC0 */ +#define ACP_RATIO(x) (x & 0x7) +#define ACP_PCLK_RATIO(x) ((x & 0x7) << 4) +#define DPHY_RATIO(x) ((x & 0x7) << 8) +#define DMC_RATIO(x) ((x & 0x7) << 12) +#define DMCD_RATIO(x) ((x & 0x7) << 16) +#define DMCP_RATIO(x) ((x & 0x7) << 20) + +/* CLK_DIV_STAT_DMC0 */ +#define DIV_ACP(x) (x & 0x1) +#define DIV_ACP_PCLK(x) ((x & 0x1) << 4) +#define DIV_DPHY(x) ((x & 0x1) << 8) +#define DIV_DMC(x) ((x & 0x1) << 12) +#define DIV_DMCD(x) ((x & 0x1) << 16) +#define DIV_DMCP(x) ((x & 0x1) << 20) + +#define DIV_STAT_DMC0_CHANGING (DIV_ACP(DIV_STAT_CHANGING) | \ + DIV_ACP_PCLK(DIV_STAT_CHANGING) | \ + DIV_DPHY(DIV_STAT_CHANGING) | \ + DIV_DMC(DIV_STAT_CHANGING) | \ + DIV_DMCD(DIV_STAT_CHANGING) | \ + DIV_DMCP(DIV_STAT_CHANGING)) + +/* CLK_DIV_DMC1 */ +#define G2D_ACP_RATIO(x) (x & 0xf) +#define C2C_RATIO(x) ((x & 0x7) << 4) +#define PWI_RATIO(x) ((x & 0xf) << 8) +#define C2C_ACLK_RATIO(x) ((x & 0x7) << 12) +#define DVSEM_RATIO(x) ((x & 0x7f) << 16) +#define DPM_RATIO(x) ((x & 0x7f) << 24) + +/* CLK_DIV_STAT_DMC1 */ +#define DIV_G2D_ACP(x) (x & 0x1) +#define DIV_C2C(x) ((x & 0x1) << 4) +#define DIV_PWI(x) ((x & 0x1) << 8) +#define DIV_C2C_ACLK(x) ((x & 0x1) << 12) +#define DIV_DVSEM(x) ((x & 0x1) << 16) +#define DIV_DPM(x) ((x & 0x1) << 24) + +#define DIV_STAT_DMC1_CHANGING (DIV_G2D_ACP(DIV_STAT_CHANGING) | \ + DIV_C2C(DIV_STAT_CHANGING) | \ + DIV_PWI(DIV_STAT_CHANGING) | \ + DIV_C2C_ACLK(DIV_STAT_CHANGING) | \ + DIV_DVSEM(DIV_STAT_CHANGING) | \ + DIV_DPM(DIV_STAT_CHANGING)) + +/* Set CLK_SRC_PERIL0 */ +#define UART4_SEL(x) ((x & 0xf) << 16) +#define UART3_SEL(x) ((x & 0xf) << 12) +#define UART2_SEL(x) ((x & 0xf) << 8) +#define UART1_SEL(x) ((x & 0xf) << 4) +#define UART0_SEL(x) ((x) & 0xf) + +/* Set CLK_DIV_PERIL0 */ +#define UART4_RATIO(x) ((x & 0xf) << 16) +#define UART3_RATIO(x) ((x & 0xf) << 12) +#define UART2_RATIO(x) ((x & 0xf) << 8) +#define UART1_RATIO(x) ((x & 0xf) << 4) +#define UART0_RATIO(x) ((x) & 0xf) + +/* Set CLK_DIV_STAT_PERIL0 */ +#define DIV_UART4(x) ((x & 0x1) << 16) +#define DIV_UART3(x) ((x & 0x1) << 12) +#define DIV_UART2(x) ((x & 0x1) << 8) +#define DIV_UART1(x) ((x & 0x1) << 4) +#define DIV_UART0(x) ((x) & 0x1) + +#define DIV_STAT_PERIL0_CHANGING (DIV_UART4(DIV_STAT_CHANGING) | \ + DIV_UART3(DIV_STAT_CHANGING) | \ + DIV_UART2(DIV_STAT_CHANGING) | \ + DIV_UART1(DIV_STAT_CHANGING) | \ + DIV_UART0(DIV_STAT_CHANGING)) + +/* CLK_DIV_FSYS1 */ +#define MMC0_RATIO(x) ((x) & 0xf) +#define MMC0_PRE_RATIO(x) ((x & 0xff) << 8) +#define MMC1_RATIO(x) ((x & 0xf) << 16) +#define MMC1_PRE_RATIO(x) ((x & 0xff) << 24) + +/* CLK_DIV_STAT_FSYS1 */ +#define DIV_MMC0(x) ((x) & 1) +#define DIV_MMC0_PRE(x) ((x & 1) << 8) +#define DIV_MMC1(x) ((x & 1) << 16) +#define DIV_MMC1_PRE(x) ((x & 1) << 24) + +#define DIV_STAT_FSYS1_CHANGING (DIV_MMC0(DIV_STAT_CHANGING) | \ + DIV_MMC0_PRE(DIV_STAT_CHANGING) | \ + DIV_MMC1(DIV_STAT_CHANGING) | \ + DIV_MMC1_PRE(DIV_STAT_CHANGING)) + +/* CLK_DIV_FSYS2 */ +#define MMC2_RATIO(x) (x & 0xf) +#define MMC2_PRE_RATIO(x) ((x & 0xff) << 8) +#define MMC3_RATIO(x) ((x & 0xf) << 16) +#define MMC3_PRE_RATIO(x) ((x & 0xff) << 24) + +/* CLK_DIV_STAT_FSYS2 */ +#define DIV_MMC2(x) (x & 0x1) +#define DIV_MMC2_PRE(x) ((x & 0x1) << 8) +#define DIV_MMC3(x) ((x & 0x1) << 16) +#define DIV_MMC3_PRE(x) ((x & 0x1) << 24) + +#define DIV_STAT_FSYS2_CHANGING (DIV_MMC2(DIV_STAT_CHANGING) | \ + DIV_MMC2_PRE(DIV_STAT_CHANGING) | \ + DIV_MMC3(DIV_STAT_CHANGING) | \ + DIV_MMC3_PRE(DIV_STAT_CHANGING)) + +/* CLK_DIV_FSYS3 */ +#define MMC4_RATIO(x) (x & 0x7) +#define MMC4_PRE_RATIO(x) ((x & 0xff) << 8) + +/* CLK_DIV_STAT_FSYS3 */ +#define DIV_MMC4(x) (x & 0x1) +#define DIV_MMC4_PRE(x) ((x & 0x1) << 8) + +#define DIV_STAT_FSYS3_CHANGING (DIV_MMC4(DIV_STAT_CHANGING) | \ + DIV_MMC4_PRE(DIV_STAT_CHANGING)) + +/* XCL205 GPIO config - Odroid U3 */ +#define XCL205_GPIO_BASE EXYNOS4X12_GPIO_PART1_BASE +#define XCL205_EN_GPIO_OFFSET 0x20 /* GPA1 */ +#define XCL205_EN_GPIO_PIN 1 +#define XCL205_EN_GPIO_CON (XCL205_GPIO_BASE + \ + XCL205_EN_GPIO_OFFSET) +#define XCL205_EN_GPIO_CON_CFG (S5P_GPIO_OUTPUT << \ + 4 * XCL205_EN_GPIO_PIN) +#define XCL205_EN_GPIO_DAT_CFG (0x1 << XCL205_EN_GPIO_PIN) +#define XCL205_EN_GPIO_PUD_CFG (S5P_GPIO_PULL_UP << \ + 2 * XCL205_EN_GPIO_PIN) +#define XCL205_EN_GPIO_DRV_CFG (S5P_GPIO_DRV_4X << \ + 2 * XCL205_EN_GPIO_PIN) + +#define XCL205_STATE_GPIO_OFFSET 0x80 /* GPC1 */ +#define XCL205_STATE_GPIO_PIN 2 +#define XCL205_STATE_GPIO_CON (XCL205_GPIO_BASE + \ + XCL205_STATE_GPIO_OFFSET) +#define XCL205_STATE_GPIO_DAT XCL205_STATE_GPIO_CON + 0x4 +#define XCL205_STATE_GPIO_CON_CFG (S5P_GPIO_INPUT << \ + 4 * XCL205_STATE_GPIO_PIN) +#define XCL205_STATE_GPIO_PUD_CFG (S5P_GPIO_PULL_NONE << \ + 2 * XCL205_STATE_GPIO_PIN) + +#ifdef CONFIG_BOARD_TYPES +extern void sdelay(unsigned long); +#endif + +#endif /*__ODROIDU3_SETUP__ */

This is a standard description for Odroid boards.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Tom Rini trini@ti.com --- arch/arm/dts/Makefile | 3 +- arch/arm/dts/exynos4412-odroid.dts | 70 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/exynos4412-odroid.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 6e2e313..8bcc69c 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1,7 +1,8 @@ dtb-$(CONFIG_EXYNOS4) += exynos4210-origen.dtb \ exynos4210-universal_c210.dtb \ exynos4210-trats.dtb \ - exynos4412-trats2.dtb + exynos4412-trats2.dtb \ + exynos4412-odroid.dtb
dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \ exynos5250-snow.dtb \ diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts new file mode 100644 index 0000000..24d0bf1 --- /dev/null +++ b/arch/arm/dts/exynos4412-odroid.dts @@ -0,0 +1,70 @@ +/* + * Odroid-U3/X2 board device tree source + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; +/include/ "exynos4.dtsi" + +/ { + model = "Odroid based on Exynos4412"; + compatible = "samsung,odroid", "samsung,exynos4412"; + + aliases { + i2c0 = "/i2c@13860000"; + serial0 = "/serial@13800000"; + console = "/serial@13810000"; + mmc2 = "sdhci@12530000"; + mmc4 = "dwmmc@12550000"; + }; + + i2c@13860000 { + samsung,i2c-sda-delay = <100>; + samsung,i2c-slave-addr = <0x10>; + samsung,i2c-max-bus-freq = <100000>; + status = "okay"; + + max77686_pmic@09 { + compatible = "maxim,max77686_pmic"; + interrupts = <7 0>; + reg = <0x09 0 0>; + #clock-cells = <1>; + }; + }; + + serial@13810000 { + status = "okay"; + }; + + sdhci@12510000 { + status = "disabled"; + }; + + sdhci@12520000 { + status = "disabled"; + }; + + sdhci@12530000 { + samsung,bus-width = <4>; + samsung,timing = <1 2 3>; + cd-gpios = <&gpio 0xC2 0>; + }; + + sdhci@12540000 { + status = "disabled"; + }; + + dwmmc@12550000 { + samsung,bus-width = <8>; + samsung,timing = <2 1 0>; + samsung,removable = <0>; + fifoth_val = <0x203f0040>; + bus_hz = <400000000>; + div = <0x3>; + index = <4>; + }; +};

This config is valid for two devices: - Odroid X2, - Odroid U3.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Tom Rini trini@ti.com
--- Changes v2: - odroid config: add CONFIG_DFU_ALT_BOOTLOADER - odroid config: change name of CONFIG_DFU_BOOT_ALT_* to CONFIG_DFU_ALT_BOOT_*
Changes v3: - odroid.h: update CONFIG_DFU_ALT_BOOT_** with required bootloader binaries - odroid.h: add multi image support (CONFIG_FIT) - odroid.h: add "autoboot" script for multi boot options - odroid.h: change env name: dfu_alt_info -> dfu_alt_system - odroid.h: update config name: CONFIG_SET_DFU_ALT_INFO - odroid.h: reduce boot delay to 0 seconds - update: doc/README.odroid
Changes v5: - odroid.h: default environment cleanup - odroid.h: remove unused definitions - odroid.h: dfu_alt_system update - odroid.h: define CONFIG_SET_DFU_ALT_BUF_LEN to 1k - odroid.h: add init ramdisk support - update: doc/README.odroid --- boards.cfg | 1 + doc/README.odroid | 143 +++++++++++++++++++++++++++++++ include/configs/odroid.h | 216 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 360 insertions(+) create mode 100644 doc/README.odroid create mode 100644 include/configs/odroid.h
diff --git a/boards.cfg b/boards.cfg index 1ba2081..da16ec2 100644 --- a/boards.cfg +++ b/boards.cfg @@ -298,6 +298,7 @@ Active arm armv7 exynos samsung smdk5420 Active arm armv7 exynos samsung smdkv310 smdkv310 - Chander Kashyap k.chander@samsung.com Active arm armv7 exynos samsung trats trats - Lukasz Majewski l.majewski@samsung.com Active arm armv7 exynos samsung trats2 trats2 - Piotr Wilczek p.wilczek@samsung.com +Active arm armv7 exynos samsung odroid odroid - Przemyslaw Marczak p.marczak@samsung.com Active arm armv7 exynos samsung universal_c210 s5pc210_universal - Przemyslaw Marczak p.marczak@samsung.com Active arm armv7 highbank - highbank highbank - Rob Herring robh@kernel.org Active arm armv7 keystone ti k2hk_evm k2hk_evm - Vitaly Andrianov vitalya@ti.com diff --git a/doc/README.odroid b/doc/README.odroid new file mode 100644 index 0000000..528bb95 --- /dev/null +++ b/doc/README.odroid @@ -0,0 +1,143 @@ + U-boot for Odroid X2/U3 +======================== + +1. Summary +========== +This is a quick instruction for setup Odroid boards based on Exynos4412. +Board config: odroid_config + +2. Supported devices +==================== +This U-BOOT config can be used on two boards: +- Odroid U3 +- Odroid X2 +with CPU Exynos 4412 rev 2.0 and 2GB of RAM + +3. Boot sequence +================ +iROM->BL1->(BL2 + TrustZone)->U-BOOT + +This version of U-BOOT doesn't implement SPL but it is required(BL2) +and can be found in "boot.tar.gz" from here: +http://dev.odroid.com/projects/4412boot/wiki/FrontPage?action=download&v... +or here: +http://odroid.in/guides/ubuntu-lfs/boot.tar.gz + +4. Boot media layout +==================== +The table below shows SD/eMMC cards layout for U-boot. +The block offset is starting from 0 and the block size is 512B. + ------------------------------------- +| Binary | Block offset| part type | +| name | SD | eMMC |(eMMC only)| + ------------------------------------- +| Bl1 | 1 | 0 | 1 (boot) | +| Bl2 | 31 | 30 | 1 (boot) | +| U-boot | 63 | 62 | 1 (boot) | +| Tzsw | 2111 | 2110 | 1 (boot) | +| Uboot Env | 2500 | 2500 | 0 (user) | + ------------------------------------- + +5. Prepare the SD boot card - with SD card reader +================================================= +To prepare bootable media you need boot binaries provided by hardkernel. +File "boot.tar.gz" (link in point 3.) contains: +- E4412_S.bl1.HardKernel.bin +- E4412_S.tzsw.signed.bin +- bl2.signed.bin +- sd_fusing.sh +- u-boot.bin + +This is all you need to boot this board. But if you want to use your custom +u-boot then you need to change u-boot.bin with your own u-boot binary* +and run the script "sd_fusing.sh" - this script is valid only for SD card. + +*note: +The proper binary file of current U-boot is u-boot-dtb.bin. + +quick steps for Linux: +- extract boot.tar.gz +- put any SD card into the SD reader +- check the device with "dmesg" +- run ./sd_fusing.sh /dev/sdX - where X is SD card device (but not a partition) +Check if Hardkernel U-boot is booting, and next do the same with your U-boot. + +6. Prepare the eMMC boot card + with a eMMC card reader (boot from eMMC card slot) +===================================================== +To boot the device from the eMMC slot you should use a special card reader +which supports eMMC partiion switch. All of the boot binaries are stored +on the eMMC boot partition which is normally hidden. + +The "sd_fusing.sh" script can be used after updating offsets of binaries +according to the table from point 4. Be sure that you are working on the right +eMMC partition - its size is usually very small, about 1-4 MiB. + +7. Prepare the eMMC boot card + with a SD card reader (boot from SD card slot) +================================================= +If you have an eMMC->microSD adapter you can prepare the card as in point 5. +But then the device can boot only from the SD card slot. + +8. Prepare the boot media using Hardkernel U-boot +================================================= +You can update the U-boot to the custom one if you have an working bootloader +delivered with the board on a eMMC/SD card. Then follow the steps: +- install the android fastboot tool +- connect a micro usb cable to the board +- on the U-boot prompt, run command: fastboot (as a root) +- on the host, run command: "fastboot flash bootloader u-boot-dtb.bin" +- the custom U-boot should start after the board resets. + +9. Partition layout +==================== +Default U-boot environment is setup for fixed partiion layout. + +Partition table: MSDOS. Disk layout and files as listed in the table below. + ----- ------ ------ ------ -------- --------------------------------- +| Num | Name | FS | Size | Offset | Reguired files | +| | | Type | MiB | MiB | | + ----- ------ ------ ------ -------- --------------------------------- +| 1 | BOOT | fat | 100 | 2 | kernel, fdt** | +| 2 | ROOT | ext4 | - | | any Linux system | + ----- ------ ------ ------ -------- --------------------------------- + +**note: +Supported fdt files are: +- exynos4412-odroidx2.dtb +- exynos4412-odroidu3.dtb + +Supported kernel files are: +- Image.itb +- zImage +- uImage + +The default environmental variable "dfu_alt_info" is set* for above layout. +Each partition size is just an example, dfu_alt_info tries init two partitions. +The size of each is not important. + +*note: +$dfu_alt_info is set on a boot time and it is concatenated using two variables: +- $dfu_alt_boot(set dynamically) +- $dfu_alt_system(from current env). + +To add any changes to dfu_alt_info - please modify $dfu_alt_system only. +Changes are visible after board reset. + +10. The environment and booting the kernel +========================================== +There are three macros defined in config for various boot options: +Two for both, kernel with device tree support and also without it: +- boot_uimg - load uImage +- boot_zimg - load zImage +If proper fdt file exists then it will be automatically loaded, +so for old kernel types, please remove fdt file from boot partition. + +The third boot option for multi image support (more info: doc/uImage.FIT/) +- boot_fit - for binary file: "Image.itb" + +Default boot command: "autoboot" +And the boot sequence is: +- boot_fit - if "Image.itb" exists +- boot_zimg - if "zImage" exists +- boot_uimg - if "uImage" exists diff --git a/include/configs/odroid.h b/include/configs/odroid.h new file mode 100644 index 0000000..c0d4157 --- /dev/null +++ b/include/configs/odroid.h @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * Sanghee Kim sh0130.kim@samsung.com + * Piotr Wilczek p.wilczek@samsung.com + * Przemyslaw Marczak p.marczak@samsung.com + * + * Configuation settings for the Odroid-U3 (EXYNOS4412) board. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_ODROID_U3_H +#define __CONFIG_ODROID_U3_H + +#include <configs/exynos4-dt.h> + +#define CONFIG_SYS_PROMPT "Odroid # " /* Monitor Command Prompt */ + +#undef CONFIG_DEFAULT_DEVICE_TREE +#define CONFIG_DEFAULT_DEVICE_TREE exynos4412-odroid + +#define CONFIG_SYS_L2CACHE_OFF +#ifndef CONFIG_SYS_L2CACHE_OFF +#define CONFIG_SYS_L2_PL310 +#define CONFIG_SYS_PL310_BASE 0x10502000 +#endif + +#define CONFIG_MACH_TYPE 4289 + +#define CONFIG_NR_DRAM_BANKS 8 +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define SDRAM_BANK_SIZE (256 << 20) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE + +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x3E00000) +#define CONFIG_SYS_TEXT_BASE 0x43e00000 + +#include <linux/sizes.h> +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (80 * SZ_1M)) + +/* select serial console configuration */ +#define CONFIG_SERIAL1 +#define CONFIG_BAUDRATE 115200 + +/* Console configuration */ +#define CONFIG_SYS_CONSOLE_INFO_QUIET +#define CONFIG_SYS_CONSOLE_IS_IN_ENV + +#define CONFIG_CMD_BOOTZ +#define CONFIG_FIT +#define CONFIG_FIT_VERBOSE +#define CONFIG_BOOTARGS "Please use defined boot" +#define CONFIG_BOOTCOMMAND "run autoboot" +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR \ + - GENERATED_GBL_DATA_SIZE) + +#define CONFIG_SYS_MEM_TOP_HIDE (SZ_1M) /* ram console */ + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV CONFIG_MMC_DEFAULT_DEV +#define CONFIG_ENV_SIZE 4096 +#define CONFIG_ENV_OFFSET (SZ_1K * 1280) /* 1.25 MiB offset */ +#define CONFIG_ENV_OVERWRITE + +/* Partitions name */ +#define PARTS_BOOT "boot" +#define PARTS_ROOT "platform" + +#define CONFIG_DFU_ALT \ + "uImage fat 0 1;" \ + "zImage fat 0 1;" \ + "Image.itb fat 0 1;" \ + "uInitrd fat 0 1;" \ + "exynos4412-odroidu3.dtb fat 0 1;" \ + "exynos4412-odroidx2.dtb fat 0 1;" \ + ""PARTS_BOOT" part 0 1;" \ + ""PARTS_ROOT" part 0 2\0" \ + +#define CONFIG_SET_DFU_ALT_INFO +#define CONFIG_SET_DFU_ALT_BUF_LEN (SZ_1K) + +#define CONFIG_DFU_ALT_BOOT_EMMC \ + "u-boot raw 0x3e 0x800 mmcpart 1;" \ + "bl1 raw 0x0 0x1e mmcpart 1;" \ + "bl2 raw 0x1e 0x1d mmcpart 1;" \ + "tzsw raw 0x83e 0x138 mmcpart 1\0" + +#define CONFIG_DFU_ALT_BOOT_SD \ + "u-boot raw 0x3f 0x800;" \ + "bl1 raw 0x1 0x1e;" \ + "bl2 raw 0x1f 0x1d;" \ + "tzsw raw 0x83f 0x138\0" + +/* + * Bootable media layout: + * dev: SD eMMC(part boot) + * BL1 1 0 + * BL2 31 30 + * UBOOT 63 62 + * TZSW 2111 2110 + * ENV 2560 2560(part user) + * + * MBR Primary partiions: + * Num Name Size Offset + * 1. BOOT: 100MiB 2MiB + * 2. ROOT: - +*/ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "loadkernel=fatload mmc ${mmcbootdev}:${mmcbootpart} ${kerneladdr} " \ + "${kernelname}\0" \ + "loadinitrd=fatload mmc ${mmcbootdev}:${mmcbootpart} ${initrdaddr} " \ + "${initrdname}\0" \ + "loaddtb=fatload mmc ${mmcbootdev}:${mmcbootpart} ${fdtaddr} " \ + "${fdtfile}\0" \ + "check_ramdisk=" \ + "if run loadinitrd; then " \ + "setenv ramdisk_addr ${initrdaddr};" \ + "else " \ + "setenv ramdisk_addr;" \ + "fi;\0" \ + "check_dtb=" \ + "if run loaddtb; then " \ + "setenv image_addr ${kerneladdr} - ${fdtaddr};" \ + "else " \ + "setenv image_addr ${kerneladdr};" \ + "fi;\0" \ + "kernel_args=" \ + "setenv bootargs root=/dev/mmcblk${mmcrootdev}p${mmcrootpart}" \ + " rootwait ${console} ${opts}\0" \ + "boot_fit=" \ + "setenv kerneladdr 0x42000000;" \ + "setenv kernelname Image.itb;" \ + "run loadkernel;" \ + "run kernel_args;" \ + "bootm ${kerneladdr}#${boardname}\0" \ + "boot_uimg=" \ + "setenv kerneladdr 0x40007FC0;" \ + "setenv kernelname uImage;" \ + "run check_dtb;" \ + "run check_ramdisk;" \ + "run loadkernel;" \ + "run kernel_args;" \ + "bootm ${image_addr} ${ramdisk_addr};\0" \ + "boot_zimg=" \ + "setenv kerneladdr 0x40007FC0;" \ + "setenv kernelname zImage;" \ + "run check_dtb;" \ + "run check_ramdisk;" \ + "run loadkernel;" \ + "run kernel_args;" \ + "bootz ${image_addr} ${ramdisk_addr};\0" \ + "autoboot=" \ + "if test -e mmc 0 Image.itb; then; " \ + "run boot_fit;" \ + "elif test -e mmc 0 zImage; then; " \ + "run boot_zimg;" \ + "elif test -e mmc 0 uImage; then; " \ + "run boot_uimg;" \ + "fi;\0" \ + "console=" CONFIG_DEFAULT_CONSOLE \ + "mmcbootdev=0\0" \ + "mmcbootpart=1\0" \ + "mmcrootdev=0\0" \ + "mmcrootpart=2\0" \ + "bootdelay=0\0" \ + "dfu_alt_system="CONFIG_DFU_ALT \ + "dfu_alt_info=Please reset the board\0" \ + "consoleon=set console console=ttySAC1,115200n8; save; reset\0" \ + "consoleoff=set console console=ram; save; reset\0" \ + "initrdname=uInitrd\0" \ + "initrdaddr=42000000\0" \ + "fdtaddr=40800000\0" + +/* I2C */ +#define CONFIG_CMD_I2C +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_S3C24X0 +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 +#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0 +#define CONFIG_MAX_I2C_NUM 8 +#define CONFIG_SYS_I2C_INIT_BOARD + +/* POWER */ +#define CONFIG_POWER +#define CONFIG_POWER_I2C +#define CONFIG_POWER_MAX77686 + +/* GPT */ +#define CONFIG_RANDOM_UUID + +/* Security subsystem - enable hw_rand() */ +#define CONFIG_EXYNOS_ACE_SHA +#define CONFIG_LIB_HW_RAND + +#define CONFIG_CMD_GPIO + +/* + * Supported Odroid boards: X3, U3 + * TODO: Add Odroid X support + */ +#define CONFIG_MISC_COMMON +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +#define CONFIG_BOARD_TYPES +#define CONFIG_MISC_INIT_R + +#undef CONFIG_REVISION_TAG + +#endif /* __CONFIG_H */

This patch set introduces changes to common Samsung code as a preparation of new board support: - boot device check - code cleanup - automatic init order of mmc drivers - automatic setting of dfu entities which depends on boot device - pre reset function call for board own implementation - setting board info environment for multi board support
New board config: - odroid_config - Odroid U3/X2 support
V6 change: - fix ramdisk load issue
Przemyslaw Marczak (12): samsung: misc: fix soc revision setting in the set_board_info() exynos: pinmux: fix the gpio names for exynos4x12 mmc arch:exynos: boot mode: add get_boot_mode(), code cleanup board:samsung: check the boot device and init the right mmc driver. samsung: misc: add function for setting $dfu_alt_info samsung:board: misc_init_r: call set_dfu_alt_info() arm:reset: call the reset_misc() before the cpu reset samsung: board: enable support of multiple board types samsung: misc: use board specific functions to set env board info odroid: add board file for Odroid X2/U3 based on Samsung Exynos4412 odroid: add odroid U3/X2 device tree description odroid: add odroid_config
arch/arm/cpu/armv7/exynos/pinmux.c | 4 +- arch/arm/cpu/armv7/exynos/power.c | 7 + arch/arm/cpu/armv7/exynos/spl_boot.c | 5 +- arch/arm/dts/Makefile | 3 +- arch/arm/dts/exynos4412-odroid.dts | 70 +++++ arch/arm/include/asm/arch-exynos/power.h | 21 ++ arch/arm/include/asm/arch-exynos/spl.h | 17 +- arch/arm/lib/reset.c | 6 + board/samsung/common/board.c | 55 +++- board/samsung/common/misc.c | 57 +++- board/samsung/odroid/Makefile | 8 + board/samsung/odroid/odroid.c | 470 +++++++++++++++++++++++++++++++ board/samsung/odroid/setup.h | 255 +++++++++++++++++ boards.cfg | 1 + doc/README.odroid | 143 ++++++++++ include/common.h | 1 + include/configs/odroid.h | 216 ++++++++++++++ include/samsung/misc.h | 10 + 18 files changed, 1309 insertions(+), 40 deletions(-) create mode 100644 arch/arm/dts/exynos4412-odroid.dts create mode 100644 board/samsung/odroid/Makefile create mode 100644 board/samsung/odroid/odroid.c create mode 100644 board/samsung/odroid/setup.h create mode 100644 doc/README.odroid create mode 100644 include/configs/odroid.h

The byte order of soc revision was inverted, now it is fixed.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Piotr Wilczek p.wilczek@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com --- board/samsung/common/misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index 03106fd..a453a82 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -26,8 +26,8 @@ void set_board_info(void) { char info[64];
- snprintf(info, ARRAY_SIZE(info), "%d.%d", s5p_cpu_rev & 0x0f, - (s5p_cpu_rev & 0xf0) >> 0x04); + snprintf(info, ARRAY_SIZE(info), "%u.%u", (s5p_cpu_rev & 0xf0) >> 4, + s5p_cpu_rev & 0xf); setenv("soc_rev", info);
snprintf(info, ARRAY_SIZE(info), "%x", s5p_cpu_id);

This change fixes the bad gpio configuration for the exynos dwmmc.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Beomho Seo beomho.seo@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Jaehoon Chung jh80.chung@samsung.com --- arch/arm/cpu/armv7/exynos/pinmux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index 86a0c75..b929486 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -704,8 +704,8 @@ static int exynos4x12_mmc_config(int peripheral, int flags) ext_func = S5P_GPIO_FUNC(0x3); break; case PERIPH_ID_SDMMC4: - start = EXYNOS4_GPIO_K00; - start_ext = EXYNOS4_GPIO_K13; + start = EXYNOS4X12_GPIO_K00; + start_ext = EXYNOS4X12_GPIO_K13; func = S5P_GPIO_FUNC(0x3); ext_func = S5P_GPIO_FUNC(0x4); break;

This patch introduces code clean-up for exynos boot mode check. It includes: - removal of typedef: boot_mode - move the boot mode enum to arch-exynos/power.h - add bootmode for sequence: eMMC 4.4 ch4 / SD ch2 - add new function: get_boot_mode() for OM[5:1] pin check - update spl boot code
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com
Changes v5: - exynos: boot mode: add missing bootmode (1st:EMMC 4.4 / 2nd:SD ch2) --- arch/arm/cpu/armv7/exynos/power.c | 7 +++++++ arch/arm/cpu/armv7/exynos/spl_boot.c | 5 ++--- arch/arm/include/asm/arch-exynos/power.h | 21 +++++++++++++++++++++ arch/arm/include/asm/arch-exynos/spl.h | 17 ++--------------- 4 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c index 638ee0b..e1ab3d6 100644 --- a/arch/arm/cpu/armv7/exynos/power.c +++ b/arch/arm/cpu/armv7/exynos/power.c @@ -202,3 +202,10 @@ void power_exit_wakeup(void) else exynos4_power_exit_wakeup(); } + +unsigned int get_boot_mode(void) +{ + unsigned int om_pin = samsung_get_base_power(); + + return readl(om_pin) & OM_PIN_MASK; +} diff --git a/arch/arm/cpu/armv7/exynos/spl_boot.c b/arch/arm/cpu/armv7/exynos/spl_boot.c index 7916630..87f9214 100644 --- a/arch/arm/cpu/armv7/exynos/spl_boot.c +++ b/arch/arm/cpu/armv7/exynos/spl_boot.c @@ -20,7 +20,6 @@ #include "clock_init.h"
DECLARE_GLOBAL_DATA_PTR; -#define OM_STAT (0x1f << 1)
/* Index into irom ptr table */ enum index { @@ -184,7 +183,7 @@ static void exynos_spi_copy(unsigned int uboot_size, unsigned int uboot_addr) */ void copy_uboot_to_ram(void) { - enum boot_mode bootmode = BOOT_MODE_OM; + u32 bootmode = BOOT_MODE_OM;
u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst) = NULL; u32 offset = 0, size = 0; @@ -207,7 +206,7 @@ void copy_uboot_to_ram(void) #endif
if (bootmode == BOOT_MODE_OM) - bootmode = readl(samsung_get_base_power()) & OM_STAT; + bootmode = get_boot_mode();
switch (bootmode) { #ifdef CONFIG_SPI_BOOTING diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h index 4f2447b..1c0f144 100644 --- a/arch/arm/include/asm/arch-exynos/power.h +++ b/arch/arm/include/asm/arch-exynos/power.h @@ -1670,6 +1670,27 @@ struct exynos5420_power { }; #endif /* __ASSEMBLY__ */
+#define OM_PIN_BITS 0x1f +#define OM_PIN_SHIFT 0x1 +#define OM_PIN_MASK (OM_PIN_BITS << OM_PIN_SHIFT) + +enum { + /* + * Assign the OM pin values for respective boot modes. + * Exynos4 does not support spi boot and the mmc boot OM + * pin values are the same across Exynos4 and Exynos5. + */ + BOOT_MODE_MMC = 4, /* SD_CH2 | USB */ + BOOT_MODE_EMMC = 8, /* EMMC4.4 | USB */ + BOOT_MODE_EMMC_SD = 40, /* EMMC4.4 | SD_CH2 */ + BOOT_MODE_SERIAL = 20, + /* Boot based on Operating Mode pin settings */ + BOOT_MODE_OM = 32, + BOOT_MODE_USB, /* Boot using USB download */ +}; + +unsigned int get_boot_mode(void); + void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable);
#define EXYNOS_MIPI_PHY_ENABLE (1 << 0) diff --git a/arch/arm/include/asm/arch-exynos/spl.h b/arch/arm/include/asm/arch-exynos/spl.h index b1d68c3..cdcb2bc 100644 --- a/arch/arm/include/asm/arch-exynos/spl.h +++ b/arch/arm/include/asm/arch-exynos/spl.h @@ -8,20 +8,7 @@ #define __ASM_ARCH_EXYNOS_SPL_H__
#include <asm/arch-exynos/dmc.h> - -enum boot_mode { - /* - * Assign the OM pin values for respective boot modes. - * Exynos4 does not support spi boot and the mmc boot OM - * pin values are the same across Exynos4 and Exynos5. - */ - BOOT_MODE_MMC = 4, - BOOT_MODE_EMMC = 8, /* EMMC4.4 */ - BOOT_MODE_SERIAL = 20, - /* Boot based on Operating Mode pin settings */ - BOOT_MODE_OM = 32, - BOOT_MODE_USB, /* Boot using USB download */ -}; +#include <asm/arch/power.h>
#ifndef __ASSEMBLY__ /* Parameters of early board initialization in SPL */ @@ -62,7 +49,7 @@ struct spl_machine_param { * table only for mmc boot. */ u32 uboot_size; - enum boot_mode boot_source; /* Boot device */ + unsigned boot_source; /* Boot device */ unsigned frequency_mhz; /* Frequency of memory in MHz */ unsigned arm_freq_mhz; /* ARM Frequency in MHz */ u32 serial_base; /* Serial base address */

Hi, Przemyslaw.
On 07/19/2014 12:29 AM, Przemyslaw Marczak wrote:
This patch introduces code clean-up for exynos boot mode check. It includes:
- removal of typedef: boot_mode
- move the boot mode enum to arch-exynos/power.h
- add bootmode for sequence: eMMC 4.4 ch4 / SD ch2
- add new function: get_boot_mode() for OM[5:1] pin check
- update spl boot code
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com
Changes v5:
- exynos: boot mode: add missing bootmode (1st:EMMC 4.4 / 2nd:SD ch2)
arch/arm/cpu/armv7/exynos/power.c | 7 +++++++ arch/arm/cpu/armv7/exynos/spl_boot.c | 5 ++--- arch/arm/include/asm/arch-exynos/power.h | 21 +++++++++++++++++++++ arch/arm/include/asm/arch-exynos/spl.h | 17 ++--------------- 4 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c index 638ee0b..e1ab3d6 100644 --- a/arch/arm/cpu/armv7/exynos/power.c +++ b/arch/arm/cpu/armv7/exynos/power.c @@ -202,3 +202,10 @@ void power_exit_wakeup(void) else exynos4_power_exit_wakeup(); }
+unsigned int get_boot_mode(void) +{
- unsigned int om_pin = samsung_get_base_power();
- return readl(om_pin) & OM_PIN_MASK;
+} diff --git a/arch/arm/cpu/armv7/exynos/spl_boot.c b/arch/arm/cpu/armv7/exynos/spl_boot.c index 7916630..87f9214 100644 --- a/arch/arm/cpu/armv7/exynos/spl_boot.c +++ b/arch/arm/cpu/armv7/exynos/spl_boot.c @@ -20,7 +20,6 @@ #include "clock_init.h"
DECLARE_GLOBAL_DATA_PTR; -#define OM_STAT (0x1f << 1)
/* Index into irom ptr table */ enum index { @@ -184,7 +183,7 @@ static void exynos_spi_copy(unsigned int uboot_size, unsigned int uboot_addr) */ void copy_uboot_to_ram(void) {
- enum boot_mode bootmode = BOOT_MODE_OM;
- u32 bootmode = BOOT_MODE_OM;
Need to use "u32"?
u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst) = NULL; u32 offset = 0, size = 0; @@ -207,7 +206,7 @@ void copy_uboot_to_ram(void) #endif
if (bootmode == BOOT_MODE_OM)
bootmode = readl(samsung_get_base_power()) & OM_STAT;
bootmode = get_boot_mode();
switch (bootmode) {
#ifdef CONFIG_SPI_BOOTING diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h index 4f2447b..1c0f144 100644 --- a/arch/arm/include/asm/arch-exynos/power.h +++ b/arch/arm/include/asm/arch-exynos/power.h @@ -1670,6 +1670,27 @@ struct exynos5420_power { }; #endif /* __ASSEMBLY__ */
+#define OM_PIN_BITS 0x1f +#define OM_PIN_SHIFT 0x1 +#define OM_PIN_MASK (OM_PIN_BITS << OM_PIN_SHIFT)
+enum {
- /*
* Assign the OM pin values for respective boot modes.
* Exynos4 does not support spi boot and the mmc boot OM
* pin values are the same across Exynos4 and Exynos5.
*/
- BOOT_MODE_MMC = 4, /* SD_CH2 | USB */
I think good that use "BOOT_MODE_SD" instead of "BOOT_MODE_MMC".
Best Regards, Jaehoon Chung
- BOOT_MODE_EMMC = 8, /* EMMC4.4 | USB */
- BOOT_MODE_EMMC_SD = 40, /* EMMC4.4 | SD_CH2 */
- BOOT_MODE_SERIAL = 20,
- /* Boot based on Operating Mode pin settings */
- BOOT_MODE_OM = 32,
- BOOT_MODE_USB, /* Boot using USB download */
+};
+unsigned int get_boot_mode(void);
void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable);
#define EXYNOS_MIPI_PHY_ENABLE (1 << 0) diff --git a/arch/arm/include/asm/arch-exynos/spl.h b/arch/arm/include/asm/arch-exynos/spl.h index b1d68c3..cdcb2bc 100644 --- a/arch/arm/include/asm/arch-exynos/spl.h +++ b/arch/arm/include/asm/arch-exynos/spl.h @@ -8,20 +8,7 @@ #define __ASM_ARCH_EXYNOS_SPL_H__
#include <asm/arch-exynos/dmc.h>
-enum boot_mode {
- /*
* Assign the OM pin values for respective boot modes.
* Exynos4 does not support spi boot and the mmc boot OM
* pin values are the same across Exynos4 and Exynos5.
*/
- BOOT_MODE_MMC = 4,
- BOOT_MODE_EMMC = 8, /* EMMC4.4 */
- BOOT_MODE_SERIAL = 20,
- /* Boot based on Operating Mode pin settings */
- BOOT_MODE_OM = 32,
- BOOT_MODE_USB, /* Boot using USB download */
-}; +#include <asm/arch/power.h>
#ifndef __ASSEMBLY__ /* Parameters of early board initialization in SPL */ @@ -62,7 +49,7 @@ struct spl_machine_param { * table only for mmc boot. */ u32 uboot_size;
- enum boot_mode boot_source; /* Boot device */
- unsigned boot_source; /* Boot device */ unsigned frequency_mhz; /* Frequency of memory in MHz */ unsigned arm_freq_mhz; /* ARM Frequency in MHz */ u32 serial_base; /* Serial base address */

Hello Jaehoon,
On 07/28/2014 07:10 AM, Jaehoon Chung wrote:
Hi, Przemyslaw.
On 07/19/2014 12:29 AM, Przemyslaw Marczak wrote:
This patch introduces code clean-up for exynos boot mode check. It includes:
- removal of typedef: boot_mode
- move the boot mode enum to arch-exynos/power.h
- add bootmode for sequence: eMMC 4.4 ch4 / SD ch2
- add new function: get_boot_mode() for OM[5:1] pin check
- update spl boot code
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com
Changes v5:
- exynos: boot mode: add missing bootmode (1st:EMMC 4.4 / 2nd:SD ch2)
arch/arm/cpu/armv7/exynos/power.c | 7 +++++++ arch/arm/cpu/armv7/exynos/spl_boot.c | 5 ++--- arch/arm/include/asm/arch-exynos/power.h | 21 +++++++++++++++++++++ arch/arm/include/asm/arch-exynos/spl.h | 17 ++--------------- 4 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c index 638ee0b..e1ab3d6 100644 --- a/arch/arm/cpu/armv7/exynos/power.c +++ b/arch/arm/cpu/armv7/exynos/power.c @@ -202,3 +202,10 @@ void power_exit_wakeup(void) else exynos4_power_exit_wakeup(); }
+unsigned int get_boot_mode(void) +{
- unsigned int om_pin = samsung_get_base_power();
- return readl(om_pin) & OM_PIN_MASK;
+} diff --git a/arch/arm/cpu/armv7/exynos/spl_boot.c b/arch/arm/cpu/armv7/exynos/spl_boot.c index 7916630..87f9214 100644 --- a/arch/arm/cpu/armv7/exynos/spl_boot.c +++ b/arch/arm/cpu/armv7/exynos/spl_boot.c @@ -20,7 +20,6 @@ #include "clock_init.h"
DECLARE_GLOBAL_DATA_PTR; -#define OM_STAT (0x1f << 1)
/* Index into irom ptr table */ enum index { @@ -184,7 +183,7 @@ static void exynos_spi_copy(unsigned int uboot_size, unsigned int uboot_addr) */ void copy_uboot_to_ram(void) {
- enum boot_mode bootmode = BOOT_MODE_OM;
- u32 bootmode = BOOT_MODE_OM;
Need to use "u32"?
Ok, will change to "unsigned int".
u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst) = NULL; u32 offset = 0, size = 0; @@ -207,7 +206,7 @@ void copy_uboot_to_ram(void) #endif
if (bootmode == BOOT_MODE_OM)
bootmode = readl(samsung_get_base_power()) & OM_STAT;
bootmode = get_boot_mode();
switch (bootmode) { #ifdef CONFIG_SPI_BOOTING
diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h index 4f2447b..1c0f144 100644 --- a/arch/arm/include/asm/arch-exynos/power.h +++ b/arch/arm/include/asm/arch-exynos/power.h @@ -1670,6 +1670,27 @@ struct exynos5420_power { }; #endif /* __ASSEMBLY__ */
+#define OM_PIN_BITS 0x1f +#define OM_PIN_SHIFT 0x1 +#define OM_PIN_MASK (OM_PIN_BITS << OM_PIN_SHIFT)
+enum {
- /*
* Assign the OM pin values for respective boot modes.
* Exynos4 does not support spi boot and the mmc boot OM
* pin values are the same across Exynos4 and Exynos5.
*/
- BOOT_MODE_MMC = 4, /* SD_CH2 | USB */
I think good that use "BOOT_MODE_SD" instead of "BOOT_MODE_MMC".
Best Regards, Jaehoon Chung
Ok, I can change this.
- BOOT_MODE_EMMC = 8, /* EMMC4.4 | USB */
- BOOT_MODE_EMMC_SD = 40, /* EMMC4.4 | SD_CH2 */
- BOOT_MODE_SERIAL = 20,
- /* Boot based on Operating Mode pin settings */
- BOOT_MODE_OM = 32,
- BOOT_MODE_USB, /* Boot using USB download */
+};
+unsigned int get_boot_mode(void);
void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable);
#define EXYNOS_MIPI_PHY_ENABLE (1 << 0)
diff --git a/arch/arm/include/asm/arch-exynos/spl.h b/arch/arm/include/asm/arch-exynos/spl.h index b1d68c3..cdcb2bc 100644 --- a/arch/arm/include/asm/arch-exynos/spl.h +++ b/arch/arm/include/asm/arch-exynos/spl.h @@ -8,20 +8,7 @@ #define __ASM_ARCH_EXYNOS_SPL_H__
#include <asm/arch-exynos/dmc.h>
-enum boot_mode {
- /*
* Assign the OM pin values for respective boot modes.
* Exynos4 does not support spi boot and the mmc boot OM
* pin values are the same across Exynos4 and Exynos5.
*/
- BOOT_MODE_MMC = 4,
- BOOT_MODE_EMMC = 8, /* EMMC4.4 */
- BOOT_MODE_SERIAL = 20,
- /* Boot based on Operating Mode pin settings */
- BOOT_MODE_OM = 32,
- BOOT_MODE_USB, /* Boot using USB download */
-}; +#include <asm/arch/power.h>
#ifndef __ASSEMBLY__ /* Parameters of early board initialization in SPL */ @@ -62,7 +49,7 @@ struct spl_machine_param { * table only for mmc boot. */ u32 uboot_size;
- enum boot_mode boot_source; /* Boot device */
- unsigned boot_source; /* Boot device */ unsigned frequency_mhz; /* Frequency of memory in MHz */ unsigned arm_freq_mhz; /* ARM Frequency in MHz */ u32 serial_base; /* Serial base address */
Thanks,

It is possible to boot device using a micro SD or eMMC slots. In this situation, boot device should be registered as a block device 0 in the MMC framework, because CONFIG_SYS_MMC_ENV_DEV is usually set to "0" in the most config cases.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com --- Changes V3: - separate two changes into two commits
Changes V4: - board.c: add functions: init_mmc() and init_dwmmc() - board_mmc_init(): call get_boot_mode() --- board/samsung/common/board.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index 9dc7c83..4d3f216 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -240,22 +240,39 @@ int board_eth_init(bd_t *bis) }
#ifdef CONFIG_GENERIC_MMC -int board_mmc_init(bd_t *bis) +static int init_mmc(void) +{ +#ifdef CONFIG_SDHCI + return exynos_mmc_init(gd->fdt_blob); +#else + return 0; +#endif +} + +static int init_dwmmc(void) { - int ret; #ifdef CONFIG_DWMMC - /* dwmmc initializattion for available channels */ - ret = exynos_dwmmc_init(gd->fdt_blob); - if (ret) - debug("dwmmc init failed\n"); + return exynos_dwmmc_init(gd->fdt_blob); +#else + return 0; #endif +} + +int board_mmc_init(bd_t *bis) +{ + int ret; + + if (get_boot_mode() == BOOT_MODE_MMC) { + ret = init_mmc(); + ret |= init_dwmmc(); + } else { + ret = init_dwmmc(); + ret |= init_mmc(); + }
-#ifdef CONFIG_SDHCI - /* mmc initializattion for available channels */ - ret = exynos_mmc_init(gd->fdt_blob); if (ret) debug("mmc init failed\n"); -#endif + return ret; } #endif

This change introduces new common function: - set_dfu_alt_info() - put dfu system and bootloader setting into $dfu_alt_info. functions declaration: - char *get_dfu_alt_system(void) - char *get_dfu_alt_boot(void) - void set_dfu_alt_info(void) and new config: - CONFIG_SET_DFU_ALT_INFO
This function can be used for auto setting dfu configuration on boot. Such feature is useful for multi board support by one u-boot binary. Each board should define two functions: - get_dfu_alt_system() - get_dfu_alt_boot()
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Piotr Wilczek p.wilczek@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v2: - change config names: CONFIG_SET_DFU_BOOT_ALT to CONFIG_DFU_ALT_BOOTLOADER and CONFIG_DFU_BOOT_ALT_* to CONFIG_DFU_ALT_BOOT_* - change function name: set_dfu_boot_alt() to set_dfu_alt_boot() - remove superfluous ifdefs
Changes v3: - set $dfu_alt_info at every boot - new config: CONFIG_SET_DFU_ALT_INFO - update commit msg
Changes v4: - set_dfu_alt_info(): add checking the pointer returned by malloc
Changes v5: - set_dfu_alt_info(): remove malloc and declare cache aligned buffer - set_dfu_alt_info(): introduce CONFIG_SET_DFU_ALT_BUF_LEN --- board/samsung/common/misc.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/samsung/misc.h | 6 ++++++ 2 files changed, 47 insertions(+)
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index a453a82..9e52452 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -11,6 +11,7 @@ #include <samsung/misc.h> #include <errno.h> #include <version.h> +#include <malloc.h> #include <linux/sizes.h> #include <asm/arch/cpu.h> #include <asm/arch/gpio.h> @@ -21,6 +22,46 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_SET_DFU_ALT_INFO +void set_dfu_alt_info(void) +{ + size_t buf_size = CONFIG_SET_DFU_ALT_BUF_LEN; + ALLOC_CACHE_ALIGN_BUFFER(char, buf, buf_size); + char *alt_info = "Settings not found!"; + char *status = "error!\n"; + char *alt_setting; + char *alt_sep; + int offset = 0; + + puts("DFU alt info setting: "); + + alt_setting = get_dfu_alt_boot(); + if (alt_setting) { + setenv("dfu_alt_boot", alt_setting); + offset = snprintf(buf, buf_size, "%s", alt_setting); + } + + alt_setting = get_dfu_alt_system(); + if (alt_setting) { + if (offset) + alt_sep = ";"; + else + alt_sep = ""; + + offset += snprintf(buf + offset, buf_size - offset, + "%s%s", alt_sep, alt_setting); + } + + if (offset) { + alt_info = buf; + status = "done\n"; + } + + setenv("dfu_alt_info", alt_info); + puts(status); +} +#endif + #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG void set_board_info(void) { diff --git a/include/samsung/misc.h b/include/samsung/misc.h index 10653a1..e82bf32 100644 --- a/include/samsung/misc.h +++ b/include/samsung/misc.h @@ -28,4 +28,10 @@ void check_boot_mode(void); void draw_logo(void); #endif
+#ifdef CONFIG_SET_DFU_ALT_INFO +char *get_dfu_alt_system(void); +char *get_dfu_alt_boot(void); +void set_dfu_alt_info(void); +#endif + #endif /* __SAMSUNG_MISC_COMMON_H__ */

This change enable automatic setting of dfu alt info on every boot. This is useful in case of booting one u-boot binary from multiple media.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com --- board/samsung/common/board.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index 4d3f216..a46e87b 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -324,6 +324,9 @@ int arch_early_init_r(void) #ifdef CONFIG_MISC_INIT_R int misc_init_r(void) { +#ifdef CONFIG_SET_DFU_ALT_INFO + set_dfu_alt_info(); +#endif #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG set_board_info(); #endif

On an Odroid U3 board, the SOC is unable to reset the eMMC card in the DWMMC mode by the cpu software reset. Manual reset of the card by switching proper gpio pin - fixes this issue.
Such solution needs to add a call to pre reset function. This is done by the reset_misc() function, which is called before reset_cpu(). The function reset_misc() is a weak function.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Jean-Christophe PLAGNIOL-VILLARD plagnioj@jcrosoft.com Cc: Albert ARIBAUD albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com
Changes v4: - arch/arm/reset: fix weak function attribute to proper style --- arch/arm/lib/reset.c | 6 ++++++ include/common.h | 1 + 2 files changed, 7 insertions(+)
diff --git a/arch/arm/lib/reset.c b/arch/arm/lib/reset.c index 7a03580..9a95f08 100644 --- a/arch/arm/lib/reset.c +++ b/arch/arm/lib/reset.c @@ -23,6 +23,10 @@
#include <common.h>
+__weak void reset_misc(void) +{ +} + int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { puts ("resetting ...\n"); @@ -30,6 +34,8 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) udelay (50000); /* wait 50 ms */
disable_interrupts(); + + reset_misc(); reset_cpu(0);
/*NOTREACHED*/ diff --git a/include/common.h b/include/common.h index 82c0a5a..48e4cbd 100644 --- a/include/common.h +++ b/include/common.h @@ -619,6 +619,7 @@ int checkicache (void); int checkdcache (void); void upmconfig (unsigned int, unsigned int *, unsigned int); ulong get_tbclk (void); +void reset_misc (void); void reset_cpu (ulong addr); #if defined (CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP) void ft_cpu_setup(void *blob, bd_t *bd);

This change adds declaration of functions: - set_board_type() - called at board_early_init_f() - get_board_type() - called at checkboard()
For supporting multiple board types in a one config - it is welcome to display the current board model. This is what get_board_type() should return.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Piotr Wilczek p.wilczek@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v3: - change the commit order - include/samsung/misc.h: add new functions declaration - update a commit message
Changes v4: - checkboard(): remove redundant variable
Changes v5: - board.c: move call to set_board_type() into board_early_init_f() - misc.h: remove get_board_name() function declaration --- board/samsung/common/board.c | 15 ++++++++++----- include/samsung/misc.h | 4 ++++ 2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index a46e87b..3de828a 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -137,7 +137,9 @@ static int board_uart_init(void) int board_early_init_f(void) { int err; - +#ifdef CONFIG_BOARD_TYPES + set_board_type(); +#endif err = board_uart_init(); if (err) { debug("UART init failed\n"); @@ -147,7 +149,6 @@ int board_early_init_f(void) #ifdef CONFIG_SYS_I2C_INIT_BOARD board_i2c_init(gd->fdt_blob); #endif - return exynos_early_init_f(); } #endif @@ -280,11 +281,15 @@ int board_mmc_init(bd_t *bis) #ifdef CONFIG_DISPLAY_BOARDINFO int checkboard(void) { - const char *board_name; + const char *board_info;
- board_name = fdt_getprop(gd->fdt_blob, 0, "model", NULL); - printf("Board: %s\n", board_name ? board_name : "unknown"); + board_info = fdt_getprop(gd->fdt_blob, 0, "model", NULL); + printf("Board: %s\n", board_info ? board_info : "unknown"); +#ifdef CONFIG_BOARD_TYPES + board_info = get_board_type();
+ printf("Model: %s\n", board_info ? board_info : "unknown"); +#endif return 0; } #endif diff --git a/include/samsung/misc.h b/include/samsung/misc.h index e82bf32..607e8d4 100644 --- a/include/samsung/misc.h +++ b/include/samsung/misc.h @@ -33,5 +33,9 @@ char *get_dfu_alt_system(void); char *get_dfu_alt_boot(void); void set_dfu_alt_info(void); #endif +#ifdef CONFIG_BOARD_TYPES +void set_board_type(void); +const char *get_board_type(void); +#endif
#endif /* __SAMSUNG_MISC_COMMON_H__ */

This change adds setup of environmental board info using get_board_name() and get_board_type() functions for config CONFIG_BOARD_TYPES.
This is useful in case of running many boards with just one config.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Piotr Wilczek p.wilczek@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v2: - set_board_info: move the bdtype pointer to avoid unused pointer compilation warning
Changes v3: - samsung: misc: change get_board_type_fdt() to get_board_type() - samsung: misc: set env $boardname using get_board_* functions for CONFIG_BOARD_TYPES - update commit msg
Changes v5: - misc.c: set_bard_info(): remove a call to get_board_name() --- board/samsung/common/misc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index 9e52452..8766f0c 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -79,8 +79,16 @@ void set_board_info(void) setenv("board_rev", info); #endif #ifdef CONFIG_OF_LIBFDT - snprintf(info, ARRAY_SIZE(info), "%s%x-%s.dtb", - CONFIG_SYS_SOC, s5p_cpu_id, CONFIG_SYS_BOARD); + const char *bdtype = ""; + const char *bdname = CONFIG_SYS_BOARD; + +#ifdef CONFIG_BOARD_TYPES + bdtype = get_board_type(); + sprintf(info, "%s%s", bdname, bdtype); + setenv("boardname", info); +#endif + snprintf(info, ARRAY_SIZE(info), "%s%x-%s%s.dtb", + CONFIG_SYS_SOC, s5p_cpu_id, bdname, bdtype); setenv("fdtfile", info); #endif }

This board file supports standard features of Odroid X2 and U3 boards: - Exynos4412 core clock set to 1000MHz and MPLL peripherial clock set to 800MHz, - MAX77686 power regulator, - USB PHY, - enable XCL205 - power for board peripherials - check board type: U3 or X2. - enable Odroid U3 FAN cooler
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Tom Rini trini@ti.com
--- Changes v2: - enable fan on odroid U3
Changes v3: - odroid.c: clean up board name related code - odroid.c: remove static from set_board_type() - odroid.c: add implementation of functions: get_dfu_alt_* - odroid.c: include misc.h
Changes v4: - odroid.c: dfu_get_alt_boot: add call get_boot_mode()
Changes v5: - odroid.c: set_board_type: change mdelay to sdelay, define XCL205 GPIO config - odroid.c: board_gpio_init(): fix OTG for Odroid U3+ - odroid.c: reserve the last 1 MB of dram for secure firmware - odroid.c: board_clock_init(): code cleanup - odroid.c: get_dfu_alt_boot(): remove setenv() - odroid.c: remove get_board_name() function definition - odroid.c: add enum ODROID_TYPES --- board/samsung/odroid/Makefile | 8 + board/samsung/odroid/odroid.c | 470 ++++++++++++++++++++++++++++++++++++++++++ board/samsung/odroid/setup.h | 255 +++++++++++++++++++++++ 3 files changed, 733 insertions(+) create mode 100644 board/samsung/odroid/Makefile create mode 100644 board/samsung/odroid/odroid.c create mode 100644 board/samsung/odroid/setup.h
diff --git a/board/samsung/odroid/Makefile b/board/samsung/odroid/Makefile new file mode 100644 index 0000000..b98aaeb --- /dev/null +++ b/board/samsung/odroid/Makefile @@ -0,0 +1,8 @@ +# +# Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved. +# Przemyslaw Marczak p.marczak@samsung.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := odroid.o diff --git a/board/samsung/odroid/odroid.c b/board/samsung/odroid/odroid.c new file mode 100644 index 0000000..2c5c107 --- /dev/null +++ b/board/samsung/odroid/odroid.c @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * Przemyslaw Marczak p.marczak@samsung.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/power.h> +#include <asm/arch/clock.h> +#include <asm/arch/gpio.h> +#include <asm/gpio.h> +#include <asm/arch/cpu.h> +#include <power/pmic.h> +#include <power/max77686_pmic.h> +#include <errno.h> +#include <usb.h> +#include <usb/s3c_udc.h> +#include <samsung/misc.h> +#include "setup.h" + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_BOARD_TYPES +/* Odroid board types */ +enum { + ODROID_TYPE_U3, + ODROID_TYPE_X2, + ODROID_TYPES, +}; + +void set_board_type(void) +{ + /* Set GPA1 pin 1 to HI - enable XCL205 output */ + writel(XCL205_EN_GPIO_CON_CFG, XCL205_EN_GPIO_CON); + writel(XCL205_EN_GPIO_DAT_CFG, XCL205_EN_GPIO_CON + 0x4); + writel(XCL205_EN_GPIO_PUD_CFG, XCL205_EN_GPIO_CON + 0x8); + writel(XCL205_EN_GPIO_DRV_CFG, XCL205_EN_GPIO_CON + 0xc); + + /* Set GPC1 pin 2 to IN - check XCL205 output state */ + writel(XCL205_STATE_GPIO_CON_CFG, XCL205_STATE_GPIO_CON); + writel(XCL205_STATE_GPIO_PUD_CFG, XCL205_STATE_GPIO_CON + 0x8); + + /* XCL205 - needs some latch time */ + sdelay(200000); + + /* Check GPC1 pin2 - LED supplied by XCL205 - X2 only */ + if (readl(XCL205_STATE_GPIO_DAT) & (1 << XCL205_STATE_GPIO_PIN)) + gd->board_type = ODROID_TYPE_X2; + else + gd->board_type = ODROID_TYPE_U3; +} + +const char *get_board_type(void) +{ + const char *board_type[] = {"u3", "x2"}; + + return board_type[gd->board_type]; +} +#endif + +#ifdef CONFIG_SET_DFU_ALT_INFO +char *get_dfu_alt_system(void) +{ + return getenv("dfu_alt_system"); +} + +char *get_dfu_alt_boot(void) +{ + char *alt_boot; + + switch (get_boot_mode()) { + case BOOT_MODE_MMC: + alt_boot = CONFIG_DFU_ALT_BOOT_SD; + break; + case BOOT_MODE_EMMC: + case BOOT_MODE_EMMC_SD: + alt_boot = CONFIG_DFU_ALT_BOOT_EMMC; + break; + default: + alt_boot = NULL; + break; + } + return alt_boot; +} +#endif + +static void board_clock_init(void) +{ + unsigned int set, clr, clr_src_cpu, clr_pll_con0, clr_src_dmc; + struct exynos4x12_clock *clk = (struct exynos4x12_clock *) + samsung_get_base_clock(); + + /* + * CMU_CPU clocks src to MPLL + * Bit values: 0 ; 1 + * MUX_APLL_SEL: FIN_PLL ; FOUT_APLL + * MUX_CORE_SEL: MOUT_APLL ; SCLK_MPLL + * MUX_HPM_SEL: MOUT_APLL ; SCLK_MPLL_USER_C + * MUX_MPLL_USER_SEL_C: FIN_PLL ; SCLK_MPLL + */ + clr_src_cpu = MUX_APLL_SEL(1) | MUX_CORE_SEL(1) | + MUX_HPM_SEL(1) | MUX_MPLL_USER_SEL_C(1); + set = MUX_APLL_SEL(0) | MUX_CORE_SEL(1) | MUX_HPM_SEL(1) | + MUX_MPLL_USER_SEL_C(1); + + clrsetbits_le32(&clk->src_cpu, clr_src_cpu, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_cpu) & MUX_STAT_CPU_CHANGING) + continue; + + /* Set APLL to 1000MHz */ + clr_pll_con0 = SDIV(7) | PDIV(63) | MDIV(1023) | FSEL(1); + set = SDIV(0) | PDIV(3) | MDIV(125) | FSEL(1); + + clrsetbits_le32(&clk->apll_con0, clr_pll_con0, set); + + /* Wait for PLL to be locked */ + while (!(readl(&clk->apll_con0) & PLL_LOCKED_BIT)) + continue; + + /* Set CMU_CPU clocks src to APLL */ + set = MUX_APLL_SEL(1) | MUX_CORE_SEL(0) | MUX_HPM_SEL(0) | + MUX_MPLL_USER_SEL_C(1); + clrsetbits_le32(&clk->src_cpu, clr_src_cpu, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_cpu) & MUX_STAT_CPU_CHANGING) + continue; + + set = CORE_RATIO(0) | COREM0_RATIO(2) | COREM1_RATIO(5) | + PERIPH_RATIO(0) | ATB_RATIO(4) | PCLK_DBG_RATIO(1) | + APLL_RATIO(0) | CORE2_RATIO(0); + /* + * Set dividers for MOUTcore = 1000 MHz + * coreout = MOUT / (ratio + 1) = 1000 MHz (0) + * corem0 = armclk / (ratio + 1) = 333 MHz (2) + * corem1 = armclk / (ratio + 1) = 166 MHz (5) + * periph = armclk / (ratio + 1) = 1000 MHz (0) + * atbout = MOUT / (ratio + 1) = 200 MHz (4) + * pclkdbgout = atbout / (ratio + 1) = 100 MHz (1) + * sclkapll = MOUTapll / (ratio + 1) = 1000 MHz (0) + * core2out = core_out / (ratio + 1) = 1000 MHz (0) (armclk) + */ + clr = CORE_RATIO(7) | COREM0_RATIO(7) | COREM1_RATIO(7) | + PERIPH_RATIO(7) | ATB_RATIO(7) | PCLK_DBG_RATIO(7) | + APLL_RATIO(7) | CORE2_RATIO(7); + + clrsetbits_le32(&clk->div_cpu0, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_cpu0) & DIV_STAT_CPU0_CHANGING) + continue; + + /* + * For MOUThpm = 1000 MHz (MOUTapll) + * doutcopy = MOUThpm / (ratio + 1) = 200 (4) + * sclkhpm = doutcopy / (ratio + 1) = 200 (4) + * cores_out = armclk / (ratio + 1) = 1000 (0) + */ + clr = COPY_RATIO(7) | HPM_RATIO(7) | CORES_RATIO(7); + set = COPY_RATIO(4) | HPM_RATIO(4) | CORES_RATIO(0); + + clrsetbits_le32(&clk->div_cpu1, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_cpu1) & DIV_STAT_CPU1_CHANGING) + continue; + + /* + * Set CMU_DMC clocks src to APLL + * Bit values: 0 ; 1 + * MUX_C2C_SEL: SCLKMPLL ; SCLKAPLL + * MUX_DMC_BUS_SEL: SCLKMPLL ; SCLKAPLL + * MUX_DPHY_SEL: SCLKMPLL ; SCLKAPLL + * MUX_MPLL_SEL: FINPLL ; MOUT_MPLL_FOUT + * MUX_PWI_SEL: 0110 (MPLL); 0111 (EPLL); 1000 (VPLL); 0(XXTI) + * MUX_G2D_ACP0_SEL: SCLKMPLL ; SCLKAPLL + * MUX_G2D_ACP1_SEL: SCLKEPLL ; SCLKVPLL + * MUX_G2D_ACP_SEL: OUT_ACP0 ; OUT_ACP1 + */ + clr_src_dmc = MUX_C2C_SEL(1) | MUX_DMC_BUS_SEL(1) | + MUX_DPHY_SEL(1) | MUX_MPLL_SEL(1) | + MUX_PWI_SEL(15) | MUX_G2D_ACP0_SEL(1) | + MUX_G2D_ACP1_SEL(1) | MUX_G2D_ACP_SEL(1); + set = MUX_C2C_SEL(1) | MUX_DMC_BUS_SEL(1) | MUX_DPHY_SEL(1) | + MUX_MPLL_SEL(0) | MUX_PWI_SEL(0) | MUX_G2D_ACP0_SEL(1) | + MUX_G2D_ACP1_SEL(1) | MUX_G2D_ACP_SEL(1); + + clrsetbits_le32(&clk->src_dmc, clr_src_dmc, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_dmc) & MUX_STAT_DMC_CHANGING) + continue; + + /* Set MPLL to 800MHz */ + set = SDIV(0) | PDIV(3) | MDIV(100) | FSEL(0) | PLL_ENABLE(1); + + clrsetbits_le32(&clk->mpll_con0, clr_pll_con0, set); + + /* Wait for PLL to be locked */ + while (!(readl(&clk->mpll_con0) & PLL_LOCKED_BIT)) + continue; + + /* Switch back CMU_DMC mux */ + set = MUX_C2C_SEL(0) | MUX_DMC_BUS_SEL(0) | MUX_DPHY_SEL(0) | + MUX_MPLL_SEL(1) | MUX_PWI_SEL(8) | MUX_G2D_ACP0_SEL(0) | + MUX_G2D_ACP1_SEL(0) | MUX_G2D_ACP_SEL(0); + + clrsetbits_le32(&clk->src_dmc, clr_src_dmc, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_dmc) & MUX_STAT_DMC_CHANGING) + continue; + + /* CLK_DIV_DMC0 */ + clr = ACP_RATIO(7) | ACP_PCLK_RATIO(7) | DPHY_RATIO(7) | + DMC_RATIO(7) | DMCD_RATIO(7) | DMCP_RATIO(7); + /* + * For: + * MOUTdmc = 800 MHz + * MOUTdphy = 800 MHz + * + * aclk_acp = MOUTdmc / (ratio + 1) = 200 (3) + * pclk_acp = aclk_acp / (ratio + 1) = 100 (1) + * sclk_dphy = MOUTdphy / (ratio + 1) = 400 (1) + * sclk_dmc = MOUTdmc / (ratio + 1) = 400 (1) + * aclk_dmcd = sclk_dmc / (ratio + 1) = 200 (1) + * aclk_dmcp = aclk_dmcd / (ratio + 1) = 100 (1) + */ + set = ACP_RATIO(3) | ACP_PCLK_RATIO(1) | DPHY_RATIO(1) | + DMC_RATIO(1) | DMCD_RATIO(1) | DMCP_RATIO(1); + + clrsetbits_le32(&clk->div_dmc0, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_dmc0) & DIV_STAT_DMC0_CHANGING) + continue; + + /* CLK_DIV_DMC1 */ + clr = G2D_ACP_RATIO(15) | C2C_RATIO(7) | PWI_RATIO(15) | + C2C_ACLK_RATIO(7) | DVSEM_RATIO(127) | DPM_RATIO(127); + /* + * For: + * MOUTg2d = 800 MHz + * MOUTc2c = 800 Mhz + * MOUTpwi = 108 MHz + * + * sclk_g2d_acp = MOUTg2d / (ratio + 1) = 400 (1) + * sclk_c2c = MOUTc2c / (ratio + 1) = 400 (1) + * aclk_c2c = sclk_c2c / (ratio + 1) = 200 (1) + * sclk_pwi = MOUTpwi / (ratio + 1) = 18 (5) + */ + set = G2D_ACP_RATIO(1) | C2C_RATIO(1) | PWI_RATIO(5) | + C2C_ACLK_RATIO(1) | DVSEM_RATIO(1) | DPM_RATIO(1); + + clrsetbits_le32(&clk->div_dmc1, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_dmc1) & DIV_STAT_DMC1_CHANGING) + continue; + + /* CLK_SRC_PERIL0 */ + clr = UART0_SEL(15) | UART1_SEL(15) | UART2_SEL(15) | + UART3_SEL(15) | UART4_SEL(15); + /* + * Set CLK_SRC_PERIL0 clocks src to MPLL + * src values: 0(XXTI); 1(XusbXTI); 2(SCLK_HDMI24M); 3(SCLK_USBPHY0); + * 5(SCLK_HDMIPHY); 6(SCLK_MPLL_USER_T); 7(SCLK_EPLL); + * 8(SCLK_VPLL) + * + * Set all to SCLK_MPLL_USER_T + */ + set = UART0_SEL(6) | UART1_SEL(6) | UART2_SEL(6) | UART3_SEL(6) | + UART4_SEL(6); + + clrsetbits_le32(&clk->src_peril0, clr, set); + + /* CLK_DIV_PERIL0 */ + clr = UART0_RATIO(15) | UART1_RATIO(15) | UART2_RATIO(15) | + UART3_RATIO(15) | UART4_RATIO(15); + /* + * For MOUTuart0-4: 800MHz + * + * SCLK_UARTx = MOUTuartX / (ratio + 1) = 100 (7) + */ + set = UART0_RATIO(7) | UART1_RATIO(7) | UART2_RATIO(7) | + UART3_RATIO(7) | UART4_RATIO(7); + + clrsetbits_le32(&clk->div_peril0, clr, set); + + while (readl(&clk->div_stat_peril0) & DIV_STAT_PERIL0_CHANGING) + continue; + + /* CLK_DIV_FSYS1 */ + clr = MMC0_RATIO(15) | MMC0_PRE_RATIO(255) | MMC1_RATIO(15) | + MMC1_PRE_RATIO(255); + /* + * For MOUTmmc0-3 = 800 MHz (MPLL) + * + * DOUTmmc1 = MOUTmmc1 / (ratio + 1) = 100 (7) + * sclk_mmc1 = DOUTmmc1 / (ratio + 1) = 50 (1) + * DOUTmmc0 = MOUTmmc0 / (ratio + 1) = 100 (7) + * sclk_mmc0 = DOUTmmc0 / (ratio + 1) = 50 (1) + */ + set = MMC0_RATIO(7) | MMC0_PRE_RATIO(1) | MMC1_RATIO(7) | + MMC1_PRE_RATIO(1); + + clrsetbits_le32(&clk->div_fsys1, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_fsys1) & DIV_STAT_FSYS1_CHANGING) + continue; + + /* CLK_DIV_FSYS2 */ + clr = MMC2_RATIO(15) | MMC2_PRE_RATIO(255) | MMC3_RATIO(15) | + MMC3_PRE_RATIO(255); + /* + * For MOUTmmc0-3 = 800 MHz (MPLL) + * + * DOUTmmc3 = MOUTmmc3 / (ratio + 1) = 100 (7) + * sclk_mmc3 = DOUTmmc3 / (ratio + 1) = 50 (1) + * DOUTmmc2 = MOUTmmc2 / (ratio + 1) = 100 (7) + * sclk_mmc2 = DOUTmmc2 / (ratio + 1) = 50 (1) + */ + set = MMC2_RATIO(7) | MMC2_PRE_RATIO(1) | MMC3_RATIO(7) | + MMC3_PRE_RATIO(1); + + clrsetbits_le32(&clk->div_fsys2, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_fsys2) & DIV_STAT_FSYS2_CHANGING) + continue; + + /* CLK_DIV_FSYS3 */ + clr = MMC4_RATIO(15) | MMC4_PRE_RATIO(255); + /* + * For MOUTmmc4 = 800 MHz (MPLL) + * + * DOUTmmc4 = MOUTmmc4 / (ratio + 1) = 100 (7) + * sclk_mmc4 = DOUTmmc4 / (ratio + 1) = 100 (0) + */ + set = MMC4_RATIO(7) | MMC4_PRE_RATIO(0); + + clrsetbits_le32(&clk->div_fsys3, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_fsys3) & DIV_STAT_FSYS3_CHANGING) + continue; + + return; +} + +static void board_gpio_init(void) +{ + /* eMMC Reset Pin */ + gpio_cfg_pin(EXYNOS4X12_GPIO_K12, S5P_GPIO_FUNC(0x1)); + gpio_set_pull(EXYNOS4X12_GPIO_K12, S5P_GPIO_PULL_NONE); + gpio_set_drv(EXYNOS4X12_GPIO_K12, S5P_GPIO_DRV_4X); + + /* Enable FAN (Odroid U3) */ + gpio_set_pull(EXYNOS4X12_GPIO_D00, S5P_GPIO_PULL_UP); + gpio_set_drv(EXYNOS4X12_GPIO_D00, S5P_GPIO_DRV_4X); + gpio_direction_output(EXYNOS4X12_GPIO_D00, 1); + + /* OTG Vbus output (Odroid U3+) */ + gpio_set_pull(EXYNOS4X12_GPIO_L20, S5P_GPIO_PULL_NONE); + gpio_set_drv(EXYNOS4X12_GPIO_L20, S5P_GPIO_DRV_4X); + gpio_direction_output(EXYNOS4X12_GPIO_L20, 0); + + /* OTG INT (Odroid U3+) */ + gpio_set_pull(EXYNOS4X12_GPIO_X31, S5P_GPIO_PULL_UP); + gpio_set_drv(EXYNOS4X12_GPIO_X31, S5P_GPIO_DRV_4X); + gpio_direction_input(EXYNOS4X12_GPIO_X31); +} + +static int pmic_init_max77686(void) +{ + struct pmic *p = pmic_get("MAX77686_PMIC"); + + if (pmic_probe(p)) + return -ENODEV; + + /* Set LDO Voltage */ + max77686_set_ldo_voltage(p, 20, 1800000); /* LDO20 eMMC */ + max77686_set_ldo_voltage(p, 21, 2800000); /* LDO21 SD */ + max77686_set_ldo_voltage(p, 22, 2800000); /* LDO22 eMMC */ + + return 0; +} + +#ifdef CONFIG_SYS_I2C_INIT_BOARD +static void board_init_i2c(void) +{ + /* I2C_0 */ + if (exynos_pinmux_config(PERIPH_ID_I2C0, PINMUX_FLAG_NONE)) + debug("I2C%d not configured\n", (I2C_0)); +} +#endif + +int exynos_early_init_f(void) +{ + board_clock_init(); + board_gpio_init(); + + return 0; +} + +int exynos_init(void) +{ + /* The last MB of memory is reserved for secure firmware */ + gd->ram_size -= SZ_1M; + gd->bd->bi_dram[CONFIG_NR_DRAM_BANKS - 1].size -= SZ_1M; + + return 0; +} + +int exynos_power_init(void) +{ +#ifdef CONFIG_SYS_I2C_INIT_BOARD + board_init_i2c(); +#endif + pmic_init(I2C_0); + pmic_init_max77686(); + + return 0; +} + +#ifdef CONFIG_USB_GADGET +static int s5pc210_phy_control(int on) +{ + struct pmic *p_pmic; + + p_pmic = pmic_get("MAX77686_PMIC"); + if (!p_pmic) + return -ENODEV; + + if (pmic_probe(p_pmic)) + return -1; + + if (on) + return max77686_set_ldo_mode(p_pmic, 12, OPMODE_ON); + else + return max77686_set_ldo_mode(p_pmic, 12, OPMODE_LPM); +} + +struct s3c_plat_otg_data s5pc210_otg_data = { + .phy_control = s5pc210_phy_control, + .regs_phy = EXYNOS4X12_USBPHY_BASE, + .regs_otg = EXYNOS4X12_USBOTG_BASE, + .usb_phy_ctrl = EXYNOS4X12_USBPHY_CONTROL, + .usb_flags = PHY0_SLEEP, +}; + +int board_usb_init(int index, enum usb_init_type init) +{ + debug("USB_udc_probe\n"); + return s3c_udc_probe(&s5pc210_otg_data); +} +#endif + +void reset_misc(void) +{ + /* Reset eMMC*/ + gpio_set_value(EXYNOS4X12_GPIO_K12, 0); + mdelay(10); + gpio_set_value(EXYNOS4X12_GPIO_K12, 1); +} diff --git a/board/samsung/odroid/setup.h b/board/samsung/odroid/setup.h new file mode 100644 index 0000000..f6acbff --- /dev/null +++ b/board/samsung/odroid/setup.h @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * Przemyslaw Marczak p.marczak@samsung.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ODROIDU3_SETUP__ +#define __ODROIDU3_SETUP__ + +/* A/M PLL_CON0 */ +#define SDIV(x) (x & 0x7) +#define PDIV(x) ((x & 0x3f) << 8) +#define MDIV(x) ((x & 0x3ff) << 16) +#define FSEL(x) ((x & 0x1) << 27) +#define PLL_LOCKED_BIT (0x1 << 29) +#define PLL_ENABLE(x) ((x & 0x1) << 31) + +/* CLK_SRC_CPU */ +#define MUX_APLL_SEL(x) (x & 0x1) +#define MUX_CORE_SEL(x) ((x & 0x1) << 16) +#define MUX_HPM_SEL(x) ((x & 0x1) << 20) +#define MUX_MPLL_USER_SEL_C(x) ((x & 0x1) << 24) + +#define MUX_STAT_CHANGING 0x100 + +/* CLK_MUX_STAT_CPU */ +#define APLL_SEL(x) (x & 0x7) +#define CORE_SEL(x) ((x & 0x7) << 16) +#define HPM_SEL(x) ((x & 0x7) << 20) +#define MPLL_USER_SEL_C(x) ((x & 0x7) << 24) +#define MUX_STAT_CPU_CHANGING (APLL_SEL(MUX_STAT_CHANGING) | \ + CORE_SEL(MUX_STAT_CHANGING) | \ + HPM_SEL(MUX_STAT_CHANGING) | \ + MPLL_USER_SEL_C(MUX_STAT_CHANGING)) + +/* CLK_DIV_CPU0 */ +#define CORE_RATIO(x) (x & 0x7) +#define COREM0_RATIO(x) ((x & 0x7) << 4) +#define COREM1_RATIO(x) ((x & 0x7) << 8) +#define PERIPH_RATIO(x) ((x & 0x7) << 12) +#define ATB_RATIO(x) ((x & 0x7) << 16) +#define PCLK_DBG_RATIO(x) ((x & 0x7) << 20) +#define APLL_RATIO(x) ((x & 0x7) << 24) +#define CORE2_RATIO(x) ((x & 0x7) << 28) + +/* CLK_DIV_STAT_CPU0 */ +#define DIV_CORE(x) (x & 0x1) +#define DIV_COREM0(x) ((x & 0x1) << 4) +#define DIV_COREM1(x) ((x & 0x1) << 8) +#define DIV_PERIPH(x) ((x & 0x1) << 12) +#define DIV_ATB(x) ((x & 0x1) << 16) +#define DIV_PCLK_DBG(x) ((x & 0x1) << 20) +#define DIV_APLL(x) ((x & 0x1) << 24) +#define DIV_CORE2(x) ((x & 0x1) << 28) + +#define DIV_STAT_CHANGING 0x1 +#define DIV_STAT_CPU0_CHANGING (DIV_CORE(DIV_STAT_CHANGING) | \ + DIV_COREM0(DIV_STAT_CHANGING) | \ + DIV_COREM1(DIV_STAT_CHANGING) | \ + DIV_PERIPH(DIV_STAT_CHANGING) | \ + DIV_ATB(DIV_STAT_CHANGING) | \ + DIV_PCLK_DBG(DIV_STAT_CHANGING) | \ + DIV_APLL(DIV_STAT_CHANGING) | \ + DIV_CORE2(DIV_STAT_CHANGING)) + +/* CLK_DIV_CPU1 */ +#define COPY_RATIO(x) (x & 0x7) +#define HPM_RATIO(x) ((x & 0x7) << 4) +#define CORES_RATIO(x) ((x & 0x7) << 8) + +/* CLK_DIV_STAT_CPU1 */ +#define DIV_COPY(x) (x & 0x7) +#define DIV_HPM(x) ((x & 0x1) << 4) +#define DIV_CORES(x) ((x & 0x1) << 8) + +#define DIV_STAT_CPU1_CHANGING (DIV_COPY(DIV_STAT_CHANGING) | \ + DIV_HPM(DIV_STAT_CHANGING) | \ + DIV_CORES(DIV_STAT_CHANGING)) + +/* CLK_SRC_DMC */ +#define MUX_C2C_SEL(x) (x & 0x1) +#define MUX_DMC_BUS_SEL(x) ((x & 0x1) << 4) +#define MUX_DPHY_SEL(x) ((x & 0x1) << 8) +#define MUX_MPLL_SEL(x) ((x & 0x1) << 12) +#define MUX_PWI_SEL(x) ((x & 0xf) << 16) +#define MUX_G2D_ACP0_SEL(x) ((x & 0x1) << 20) +#define MUX_G2D_ACP1_SEL(x) ((x & 0x1) << 24) +#define MUX_G2D_ACP_SEL(x) ((x & 0x1) << 28) + +/* CLK_MUX_STAT_DMC */ +#define C2C_SEL(x) ((x) & 0x7) +#define DMC_BUS_SEL(x) ((x & 0x7) << 4) +#define DPHY_SEL(x) ((x & 0x7) << 8) +#define MPLL_SEL(x) ((x & 0x7) << 12) +/* #define PWI_SEL(x) ((x & 0xf) << 16) - Reserved */ +#define G2D_ACP0_SEL(x) ((x & 0x7) << 20) +#define G2D_ACP1_SEL(x) ((x & 0x7) << 24) +#define G2D_ACP_SEL(x) ((x & 0x7) << 28) + +#define MUX_STAT_DMC_CHANGING (C2C_SEL(MUX_STAT_CHANGING) | \ + DMC_BUS_SEL(MUX_STAT_CHANGING) | \ + DPHY_SEL(MUX_STAT_CHANGING) | \ + MPLL_SEL(MUX_STAT_CHANGING) |\ + G2D_ACP0_SEL(MUX_STAT_CHANGING) | \ + G2D_ACP1_SEL(MUX_STAT_CHANGING) | \ + G2D_ACP_SEL(MUX_STAT_CHANGING)) + +/* CLK_DIV_DMC0 */ +#define ACP_RATIO(x) (x & 0x7) +#define ACP_PCLK_RATIO(x) ((x & 0x7) << 4) +#define DPHY_RATIO(x) ((x & 0x7) << 8) +#define DMC_RATIO(x) ((x & 0x7) << 12) +#define DMCD_RATIO(x) ((x & 0x7) << 16) +#define DMCP_RATIO(x) ((x & 0x7) << 20) + +/* CLK_DIV_STAT_DMC0 */ +#define DIV_ACP(x) (x & 0x1) +#define DIV_ACP_PCLK(x) ((x & 0x1) << 4) +#define DIV_DPHY(x) ((x & 0x1) << 8) +#define DIV_DMC(x) ((x & 0x1) << 12) +#define DIV_DMCD(x) ((x & 0x1) << 16) +#define DIV_DMCP(x) ((x & 0x1) << 20) + +#define DIV_STAT_DMC0_CHANGING (DIV_ACP(DIV_STAT_CHANGING) | \ + DIV_ACP_PCLK(DIV_STAT_CHANGING) | \ + DIV_DPHY(DIV_STAT_CHANGING) | \ + DIV_DMC(DIV_STAT_CHANGING) | \ + DIV_DMCD(DIV_STAT_CHANGING) | \ + DIV_DMCP(DIV_STAT_CHANGING)) + +/* CLK_DIV_DMC1 */ +#define G2D_ACP_RATIO(x) (x & 0xf) +#define C2C_RATIO(x) ((x & 0x7) << 4) +#define PWI_RATIO(x) ((x & 0xf) << 8) +#define C2C_ACLK_RATIO(x) ((x & 0x7) << 12) +#define DVSEM_RATIO(x) ((x & 0x7f) << 16) +#define DPM_RATIO(x) ((x & 0x7f) << 24) + +/* CLK_DIV_STAT_DMC1 */ +#define DIV_G2D_ACP(x) (x & 0x1) +#define DIV_C2C(x) ((x & 0x1) << 4) +#define DIV_PWI(x) ((x & 0x1) << 8) +#define DIV_C2C_ACLK(x) ((x & 0x1) << 12) +#define DIV_DVSEM(x) ((x & 0x1) << 16) +#define DIV_DPM(x) ((x & 0x1) << 24) + +#define DIV_STAT_DMC1_CHANGING (DIV_G2D_ACP(DIV_STAT_CHANGING) | \ + DIV_C2C(DIV_STAT_CHANGING) | \ + DIV_PWI(DIV_STAT_CHANGING) | \ + DIV_C2C_ACLK(DIV_STAT_CHANGING) | \ + DIV_DVSEM(DIV_STAT_CHANGING) | \ + DIV_DPM(DIV_STAT_CHANGING)) + +/* Set CLK_SRC_PERIL0 */ +#define UART4_SEL(x) ((x & 0xf) << 16) +#define UART3_SEL(x) ((x & 0xf) << 12) +#define UART2_SEL(x) ((x & 0xf) << 8) +#define UART1_SEL(x) ((x & 0xf) << 4) +#define UART0_SEL(x) ((x) & 0xf) + +/* Set CLK_DIV_PERIL0 */ +#define UART4_RATIO(x) ((x & 0xf) << 16) +#define UART3_RATIO(x) ((x & 0xf) << 12) +#define UART2_RATIO(x) ((x & 0xf) << 8) +#define UART1_RATIO(x) ((x & 0xf) << 4) +#define UART0_RATIO(x) ((x) & 0xf) + +/* Set CLK_DIV_STAT_PERIL0 */ +#define DIV_UART4(x) ((x & 0x1) << 16) +#define DIV_UART3(x) ((x & 0x1) << 12) +#define DIV_UART2(x) ((x & 0x1) << 8) +#define DIV_UART1(x) ((x & 0x1) << 4) +#define DIV_UART0(x) ((x) & 0x1) + +#define DIV_STAT_PERIL0_CHANGING (DIV_UART4(DIV_STAT_CHANGING) | \ + DIV_UART3(DIV_STAT_CHANGING) | \ + DIV_UART2(DIV_STAT_CHANGING) | \ + DIV_UART1(DIV_STAT_CHANGING) | \ + DIV_UART0(DIV_STAT_CHANGING)) + +/* CLK_DIV_FSYS1 */ +#define MMC0_RATIO(x) ((x) & 0xf) +#define MMC0_PRE_RATIO(x) ((x & 0xff) << 8) +#define MMC1_RATIO(x) ((x & 0xf) << 16) +#define MMC1_PRE_RATIO(x) ((x & 0xff) << 24) + +/* CLK_DIV_STAT_FSYS1 */ +#define DIV_MMC0(x) ((x) & 1) +#define DIV_MMC0_PRE(x) ((x & 1) << 8) +#define DIV_MMC1(x) ((x & 1) << 16) +#define DIV_MMC1_PRE(x) ((x & 1) << 24) + +#define DIV_STAT_FSYS1_CHANGING (DIV_MMC0(DIV_STAT_CHANGING) | \ + DIV_MMC0_PRE(DIV_STAT_CHANGING) | \ + DIV_MMC1(DIV_STAT_CHANGING) | \ + DIV_MMC1_PRE(DIV_STAT_CHANGING)) + +/* CLK_DIV_FSYS2 */ +#define MMC2_RATIO(x) (x & 0xf) +#define MMC2_PRE_RATIO(x) ((x & 0xff) << 8) +#define MMC3_RATIO(x) ((x & 0xf) << 16) +#define MMC3_PRE_RATIO(x) ((x & 0xff) << 24) + +/* CLK_DIV_STAT_FSYS2 */ +#define DIV_MMC2(x) (x & 0x1) +#define DIV_MMC2_PRE(x) ((x & 0x1) << 8) +#define DIV_MMC3(x) ((x & 0x1) << 16) +#define DIV_MMC3_PRE(x) ((x & 0x1) << 24) + +#define DIV_STAT_FSYS2_CHANGING (DIV_MMC2(DIV_STAT_CHANGING) | \ + DIV_MMC2_PRE(DIV_STAT_CHANGING) | \ + DIV_MMC3(DIV_STAT_CHANGING) | \ + DIV_MMC3_PRE(DIV_STAT_CHANGING)) + +/* CLK_DIV_FSYS3 */ +#define MMC4_RATIO(x) (x & 0x7) +#define MMC4_PRE_RATIO(x) ((x & 0xff) << 8) + +/* CLK_DIV_STAT_FSYS3 */ +#define DIV_MMC4(x) (x & 0x1) +#define DIV_MMC4_PRE(x) ((x & 0x1) << 8) + +#define DIV_STAT_FSYS3_CHANGING (DIV_MMC4(DIV_STAT_CHANGING) | \ + DIV_MMC4_PRE(DIV_STAT_CHANGING)) + +/* XCL205 GPIO config - Odroid U3 */ +#define XCL205_GPIO_BASE EXYNOS4X12_GPIO_PART1_BASE +#define XCL205_EN_GPIO_OFFSET 0x20 /* GPA1 */ +#define XCL205_EN_GPIO_PIN 1 +#define XCL205_EN_GPIO_CON (XCL205_GPIO_BASE + \ + XCL205_EN_GPIO_OFFSET) +#define XCL205_EN_GPIO_CON_CFG (S5P_GPIO_OUTPUT << \ + 4 * XCL205_EN_GPIO_PIN) +#define XCL205_EN_GPIO_DAT_CFG (0x1 << XCL205_EN_GPIO_PIN) +#define XCL205_EN_GPIO_PUD_CFG (S5P_GPIO_PULL_UP << \ + 2 * XCL205_EN_GPIO_PIN) +#define XCL205_EN_GPIO_DRV_CFG (S5P_GPIO_DRV_4X << \ + 2 * XCL205_EN_GPIO_PIN) + +#define XCL205_STATE_GPIO_OFFSET 0x80 /* GPC1 */ +#define XCL205_STATE_GPIO_PIN 2 +#define XCL205_STATE_GPIO_CON (XCL205_GPIO_BASE + \ + XCL205_STATE_GPIO_OFFSET) +#define XCL205_STATE_GPIO_DAT XCL205_STATE_GPIO_CON + 0x4 +#define XCL205_STATE_GPIO_CON_CFG (S5P_GPIO_INPUT << \ + 4 * XCL205_STATE_GPIO_PIN) +#define XCL205_STATE_GPIO_PUD_CFG (S5P_GPIO_PULL_NONE << \ + 2 * XCL205_STATE_GPIO_PIN) + +#ifdef CONFIG_BOARD_TYPES +extern void sdelay(unsigned long); +#endif + +#endif /*__ODROIDU3_SETUP__ */

Dear Przemyslaw Marczak,
On 19 July 2014 00:29, Przemyslaw Marczak p.marczak@samsung.com wrote:
This board file supports standard features of Odroid X2 and U3 boards:
- Exynos4412 core clock set to 1000MHz and MPLL peripherial clock set to
800MHz,
- MAX77686 power regulator,
- USB PHY,
- enable XCL205 - power for board peripherials
- check board type: U3 or X2.
- enable Odroid U3 FAN cooler
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Tom Rini trini@ti.com
Changes v2:
- enable fan on odroid U3
Changes v3:
- odroid.c: clean up board name related code
- odroid.c: remove static from set_board_type()
- odroid.c: add implementation of functions: get_dfu_alt_*
- odroid.c: include misc.h
Changes v4:
- odroid.c: dfu_get_alt_boot: add call get_boot_mode()
Changes v5:
- odroid.c: set_board_type: change mdelay to sdelay, define XCL205 GPIO
config
- odroid.c: board_gpio_init(): fix OTG for Odroid U3+
- odroid.c: reserve the last 1 MB of dram for secure firmware
- odroid.c: board_clock_init(): code cleanup
- odroid.c: get_dfu_alt_boot(): remove setenv()
- odroid.c: remove get_board_name() function definition
- odroid.c: add enum ODROID_TYPES
board/samsung/odroid/Makefile | 8 + board/samsung/odroid/odroid.c | 470 ++++++++++++++++++++++++++++++++++++++++++ board/samsung/odroid/setup.h | 255 +++++++++++++++++++++++ 3 files changed, 733 insertions(+) create mode 100644 board/samsung/odroid/Makefile create mode 100644 board/samsung/odroid/odroid.c create mode 100644 board/samsung/odroid/setup.h
diff --git a/board/samsung/odroid/setup.h b/board/samsung/odroid/setup.h new file mode 100644 index 0000000..f6acbff --- /dev/null +++ b/board/samsung/odroid/setup.h @@ -0,0 +1,255 @@ +/*
- Copyright (C) 2014 Samsung Electronics
- Przemyslaw Marczak p.marczak@samsung.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef __ODROIDU3_SETUP__ +#define __ODROIDU3_SETUP__
+/* A/M PLL_CON0 */ +#define SDIV(x) (x & 0x7)
In this file, x should be wrapped with (). Please fix it.
+#define PDIV(x) ((x & 0x3f) << 8) +#define MDIV(x) ((x & 0x3ff) << 16) +#define FSEL(x) ((x & 0x1) << 27) +#define PLL_LOCKED_BIT (0x1 << 29) +#define PLL_ENABLE(x) ((x & 0x1) << 31)
+/* CLK_SRC_CPU */ +#define MUX_APLL_SEL(x) (x & 0x1) +#define MUX_CORE_SEL(x) ((x & 0x1) << 16) +#define MUX_HPM_SEL(x) ((x & 0x1) << 20) +#define MUX_MPLL_USER_SEL_C(x) ((x & 0x1) << 24)
Others are looks good to me.
Thanks, Minkyu Kang.

Hello Minkyu,
On 07/26/2014 11:07 AM, Minkyu Kang wrote:
Dear Przemyslaw Marczak,
On 19 July 2014 00:29, Przemyslaw Marczak <p.marczak@samsung.com mailto:p.marczak@samsung.com> wrote:
This board file supports standard features of Odroid X2 and U3 boards: - Exynos4412 core clock set to 1000MHz and MPLL peripherial clock set to 800MHz, - MAX77686 power regulator, - USB PHY, - enable XCL205 - power for board peripherials - check board type: U3 or X2. - enable Odroid U3 FAN cooler Signed-off-by: Przemyslaw Marczak <p.marczak@samsung.com <mailto:p.marczak@samsung.com>> Cc: Minkyu Kang <mk7.kang@samsung.com <mailto:mk7.kang@samsung.com>> Cc: Tom Rini <trini@ti.com <mailto:trini@ti.com>> --- Changes v2: - enable fan on odroid U3 Changes v3: - odroid.c: clean up board name related code - odroid.c: remove static from set_board_type() - odroid.c: add implementation of functions: get_dfu_alt_* - odroid.c: include misc.h Changes v4: - odroid.c: dfu_get_alt_boot: add call get_boot_mode() Changes v5: - odroid.c: set_board_type: change mdelay to sdelay, define XCL205 GPIO config - odroid.c: board_gpio_init(): fix OTG for Odroid U3+ - odroid.c: reserve the last 1 MB of dram for secure firmware - odroid.c: board_clock_init(): code cleanup - odroid.c: get_dfu_alt_boot(): remove setenv() - odroid.c: remove get_board_name() function definition - odroid.c: add enum ODROID_TYPES --- board/samsung/odroid/Makefile | 8 + board/samsung/odroid/odroid.c | 470 ++++++++++++++++++++++++++++++++++++++++++ board/samsung/odroid/setup.h | 255 +++++++++++++++++++++++ 3 files changed, 733 insertions(+) create mode 100644 board/samsung/odroid/Makefile create mode 100644 board/samsung/odroid/odroid.c create mode 100644 board/samsung/odroid/setup.h diff --git a/board/samsung/odroid/setup.h b/board/samsung/odroid/setup.h new file mode 100644 index 0000000..f6acbff --- /dev/null +++ b/board/samsung/odroid/setup.h @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * Przemyslaw Marczak <p.marczak@samsung.com <mailto:p.marczak@samsung.com>> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ODROIDU3_SETUP__ +#define __ODROIDU3_SETUP__ + +/* A/M PLL_CON0 */ +#define SDIV(x) (x & 0x7)
In this file, x should be wrapped with (). Please fix it.
Ok, I will fix this.
+#define PDIV(x) ((x & 0x3f) << 8) +#define MDIV(x) ((x & 0x3ff) << 16) +#define FSEL(x) ((x & 0x1) << 27) +#define PLL_LOCKED_BIT (0x1 << 29) +#define PLL_ENABLE(x) ((x & 0x1) << 31) + +/* CLK_SRC_CPU */ +#define MUX_APLL_SEL(x) (x & 0x1) +#define MUX_CORE_SEL(x) ((x & 0x1) << 16) +#define MUX_HPM_SEL(x) ((x & 0x1) << 20) +#define MUX_MPLL_USER_SEL_C(x) ((x & 0x1) << 24) +
Others are looks good to me.
Thanks, Minkyu Kang.
-- from. prom. www.promsoft.net http://www.promsoft.net
Thank you,

This is a standard description for Odroid boards.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Tom Rini trini@ti.com --- arch/arm/dts/Makefile | 3 +- arch/arm/dts/exynos4412-odroid.dts | 70 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/exynos4412-odroid.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 6e2e313..8bcc69c 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1,7 +1,8 @@ dtb-$(CONFIG_EXYNOS4) += exynos4210-origen.dtb \ exynos4210-universal_c210.dtb \ exynos4210-trats.dtb \ - exynos4412-trats2.dtb + exynos4412-trats2.dtb \ + exynos4412-odroid.dtb
dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \ exynos5250-snow.dtb \ diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts new file mode 100644 index 0000000..24d0bf1 --- /dev/null +++ b/arch/arm/dts/exynos4412-odroid.dts @@ -0,0 +1,70 @@ +/* + * Odroid-U3/X2 board device tree source + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; +/include/ "exynos4.dtsi" + +/ { + model = "Odroid based on Exynos4412"; + compatible = "samsung,odroid", "samsung,exynos4412"; + + aliases { + i2c0 = "/i2c@13860000"; + serial0 = "/serial@13800000"; + console = "/serial@13810000"; + mmc2 = "sdhci@12530000"; + mmc4 = "dwmmc@12550000"; + }; + + i2c@13860000 { + samsung,i2c-sda-delay = <100>; + samsung,i2c-slave-addr = <0x10>; + samsung,i2c-max-bus-freq = <100000>; + status = "okay"; + + max77686_pmic@09 { + compatible = "maxim,max77686_pmic"; + interrupts = <7 0>; + reg = <0x09 0 0>; + #clock-cells = <1>; + }; + }; + + serial@13810000 { + status = "okay"; + }; + + sdhci@12510000 { + status = "disabled"; + }; + + sdhci@12520000 { + status = "disabled"; + }; + + sdhci@12530000 { + samsung,bus-width = <4>; + samsung,timing = <1 2 3>; + cd-gpios = <&gpio 0xC2 0>; + }; + + sdhci@12540000 { + status = "disabled"; + }; + + dwmmc@12550000 { + samsung,bus-width = <8>; + samsung,timing = <2 1 0>; + samsung,removable = <0>; + fifoth_val = <0x203f0040>; + bus_hz = <400000000>; + div = <0x3>; + index = <4>; + }; +};

This config is valid for two devices: - Odroid X2, - Odroid U3.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Tom Rini trini@ti.com
--- Changes v2: - odroid config: add CONFIG_DFU_ALT_BOOTLOADER - odroid config: change name of CONFIG_DFU_BOOT_ALT_* to CONFIG_DFU_ALT_BOOT_*
Changes v3: - odroid.h: update CONFIG_DFU_ALT_BOOT_** with required bootloader binaries - odroid.h: add multi image support (CONFIG_FIT) - odroid.h: add "autoboot" script for multi boot options - odroid.h: change env name: dfu_alt_info -> dfu_alt_system - odroid.h: update config name: CONFIG_SET_DFU_ALT_INFO - odroid.h: reduce boot delay to 0 seconds - update: doc/README.odroid
Changes v5: - odroid.h: default environment cleanup - odroid.h: remove unused definitions - odroid.h: dfu_alt_system update - odroid.h: define CONFIG_SET_DFU_ALT_BUF_LEN to 1k - odroid.h: add init ramdisk support - update: doc/README.odroid
Changes v6: - odroid.h: fix ramdisk load issue --- boards.cfg | 1 + doc/README.odroid | 143 +++++++++++++++++++++++++++++++ include/configs/odroid.h | 216 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 360 insertions(+) create mode 100644 doc/README.odroid create mode 100644 include/configs/odroid.h
diff --git a/boards.cfg b/boards.cfg index 1ba2081..da16ec2 100644 --- a/boards.cfg +++ b/boards.cfg @@ -298,6 +298,7 @@ Active arm armv7 exynos samsung smdk5420 Active arm armv7 exynos samsung smdkv310 smdkv310 - Chander Kashyap k.chander@samsung.com Active arm armv7 exynos samsung trats trats - Lukasz Majewski l.majewski@samsung.com Active arm armv7 exynos samsung trats2 trats2 - Piotr Wilczek p.wilczek@samsung.com +Active arm armv7 exynos samsung odroid odroid - Przemyslaw Marczak p.marczak@samsung.com Active arm armv7 exynos samsung universal_c210 s5pc210_universal - Przemyslaw Marczak p.marczak@samsung.com Active arm armv7 highbank - highbank highbank - Rob Herring robh@kernel.org Active arm armv7 keystone ti k2hk_evm k2hk_evm - Vitaly Andrianov vitalya@ti.com diff --git a/doc/README.odroid b/doc/README.odroid new file mode 100644 index 0000000..528bb95 --- /dev/null +++ b/doc/README.odroid @@ -0,0 +1,143 @@ + U-boot for Odroid X2/U3 +======================== + +1. Summary +========== +This is a quick instruction for setup Odroid boards based on Exynos4412. +Board config: odroid_config + +2. Supported devices +==================== +This U-BOOT config can be used on two boards: +- Odroid U3 +- Odroid X2 +with CPU Exynos 4412 rev 2.0 and 2GB of RAM + +3. Boot sequence +================ +iROM->BL1->(BL2 + TrustZone)->U-BOOT + +This version of U-BOOT doesn't implement SPL but it is required(BL2) +and can be found in "boot.tar.gz" from here: +http://dev.odroid.com/projects/4412boot/wiki/FrontPage?action=download&v... +or here: +http://odroid.in/guides/ubuntu-lfs/boot.tar.gz + +4. Boot media layout +==================== +The table below shows SD/eMMC cards layout for U-boot. +The block offset is starting from 0 and the block size is 512B. + ------------------------------------- +| Binary | Block offset| part type | +| name | SD | eMMC |(eMMC only)| + ------------------------------------- +| Bl1 | 1 | 0 | 1 (boot) | +| Bl2 | 31 | 30 | 1 (boot) | +| U-boot | 63 | 62 | 1 (boot) | +| Tzsw | 2111 | 2110 | 1 (boot) | +| Uboot Env | 2500 | 2500 | 0 (user) | + ------------------------------------- + +5. Prepare the SD boot card - with SD card reader +================================================= +To prepare bootable media you need boot binaries provided by hardkernel. +File "boot.tar.gz" (link in point 3.) contains: +- E4412_S.bl1.HardKernel.bin +- E4412_S.tzsw.signed.bin +- bl2.signed.bin +- sd_fusing.sh +- u-boot.bin + +This is all you need to boot this board. But if you want to use your custom +u-boot then you need to change u-boot.bin with your own u-boot binary* +and run the script "sd_fusing.sh" - this script is valid only for SD card. + +*note: +The proper binary file of current U-boot is u-boot-dtb.bin. + +quick steps for Linux: +- extract boot.tar.gz +- put any SD card into the SD reader +- check the device with "dmesg" +- run ./sd_fusing.sh /dev/sdX - where X is SD card device (but not a partition) +Check if Hardkernel U-boot is booting, and next do the same with your U-boot. + +6. Prepare the eMMC boot card + with a eMMC card reader (boot from eMMC card slot) +===================================================== +To boot the device from the eMMC slot you should use a special card reader +which supports eMMC partiion switch. All of the boot binaries are stored +on the eMMC boot partition which is normally hidden. + +The "sd_fusing.sh" script can be used after updating offsets of binaries +according to the table from point 4. Be sure that you are working on the right +eMMC partition - its size is usually very small, about 1-4 MiB. + +7. Prepare the eMMC boot card + with a SD card reader (boot from SD card slot) +================================================= +If you have an eMMC->microSD adapter you can prepare the card as in point 5. +But then the device can boot only from the SD card slot. + +8. Prepare the boot media using Hardkernel U-boot +================================================= +You can update the U-boot to the custom one if you have an working bootloader +delivered with the board on a eMMC/SD card. Then follow the steps: +- install the android fastboot tool +- connect a micro usb cable to the board +- on the U-boot prompt, run command: fastboot (as a root) +- on the host, run command: "fastboot flash bootloader u-boot-dtb.bin" +- the custom U-boot should start after the board resets. + +9. Partition layout +==================== +Default U-boot environment is setup for fixed partiion layout. + +Partition table: MSDOS. Disk layout and files as listed in the table below. + ----- ------ ------ ------ -------- --------------------------------- +| Num | Name | FS | Size | Offset | Reguired files | +| | | Type | MiB | MiB | | + ----- ------ ------ ------ -------- --------------------------------- +| 1 | BOOT | fat | 100 | 2 | kernel, fdt** | +| 2 | ROOT | ext4 | - | | any Linux system | + ----- ------ ------ ------ -------- --------------------------------- + +**note: +Supported fdt files are: +- exynos4412-odroidx2.dtb +- exynos4412-odroidu3.dtb + +Supported kernel files are: +- Image.itb +- zImage +- uImage + +The default environmental variable "dfu_alt_info" is set* for above layout. +Each partition size is just an example, dfu_alt_info tries init two partitions. +The size of each is not important. + +*note: +$dfu_alt_info is set on a boot time and it is concatenated using two variables: +- $dfu_alt_boot(set dynamically) +- $dfu_alt_system(from current env). + +To add any changes to dfu_alt_info - please modify $dfu_alt_system only. +Changes are visible after board reset. + +10. The environment and booting the kernel +========================================== +There are three macros defined in config for various boot options: +Two for both, kernel with device tree support and also without it: +- boot_uimg - load uImage +- boot_zimg - load zImage +If proper fdt file exists then it will be automatically loaded, +so for old kernel types, please remove fdt file from boot partition. + +The third boot option for multi image support (more info: doc/uImage.FIT/) +- boot_fit - for binary file: "Image.itb" + +Default boot command: "autoboot" +And the boot sequence is: +- boot_fit - if "Image.itb" exists +- boot_zimg - if "zImage" exists +- boot_uimg - if "uImage" exists diff --git a/include/configs/odroid.h b/include/configs/odroid.h new file mode 100644 index 0000000..29dcc4a --- /dev/null +++ b/include/configs/odroid.h @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * Sanghee Kim sh0130.kim@samsung.com + * Piotr Wilczek p.wilczek@samsung.com + * Przemyslaw Marczak p.marczak@samsung.com + * + * Configuation settings for the Odroid-U3 (EXYNOS4412) board. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_ODROID_U3_H +#define __CONFIG_ODROID_U3_H + +#include <configs/exynos4-dt.h> + +#define CONFIG_SYS_PROMPT "Odroid # " /* Monitor Command Prompt */ + +#undef CONFIG_DEFAULT_DEVICE_TREE +#define CONFIG_DEFAULT_DEVICE_TREE exynos4412-odroid + +#define CONFIG_SYS_L2CACHE_OFF +#ifndef CONFIG_SYS_L2CACHE_OFF +#define CONFIG_SYS_L2_PL310 +#define CONFIG_SYS_PL310_BASE 0x10502000 +#endif + +#define CONFIG_MACH_TYPE 4289 + +#define CONFIG_NR_DRAM_BANKS 8 +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define SDRAM_BANK_SIZE (256 << 20) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE + +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x3E00000) +#define CONFIG_SYS_TEXT_BASE 0x43e00000 + +#include <linux/sizes.h> +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (80 * SZ_1M)) + +/* select serial console configuration */ +#define CONFIG_SERIAL1 +#define CONFIG_BAUDRATE 115200 + +/* Console configuration */ +#define CONFIG_SYS_CONSOLE_INFO_QUIET +#define CONFIG_SYS_CONSOLE_IS_IN_ENV + +#define CONFIG_CMD_BOOTZ +#define CONFIG_FIT +#define CONFIG_FIT_VERBOSE +#define CONFIG_BOOTARGS "Please use defined boot" +#define CONFIG_BOOTCOMMAND "run autoboot" +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR \ + - GENERATED_GBL_DATA_SIZE) + +#define CONFIG_SYS_MEM_TOP_HIDE (SZ_1M) /* ram console */ + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV CONFIG_MMC_DEFAULT_DEV +#define CONFIG_ENV_SIZE 4096 +#define CONFIG_ENV_OFFSET (SZ_1K * 1280) /* 1.25 MiB offset */ +#define CONFIG_ENV_OVERWRITE + +/* Partitions name */ +#define PARTS_BOOT "boot" +#define PARTS_ROOT "platform" + +#define CONFIG_DFU_ALT \ + "uImage fat 0 1;" \ + "zImage fat 0 1;" \ + "Image.itb fat 0 1;" \ + "uInitrd fat 0 1;" \ + "exynos4412-odroidu3.dtb fat 0 1;" \ + "exynos4412-odroidx2.dtb fat 0 1;" \ + ""PARTS_BOOT" part 0 1;" \ + ""PARTS_ROOT" part 0 2\0" \ + +#define CONFIG_SET_DFU_ALT_INFO +#define CONFIG_SET_DFU_ALT_BUF_LEN (SZ_1K) + +#define CONFIG_DFU_ALT_BOOT_EMMC \ + "u-boot raw 0x3e 0x800 mmcpart 1;" \ + "bl1 raw 0x0 0x1e mmcpart 1;" \ + "bl2 raw 0x1e 0x1d mmcpart 1;" \ + "tzsw raw 0x83e 0x138 mmcpart 1\0" + +#define CONFIG_DFU_ALT_BOOT_SD \ + "u-boot raw 0x3f 0x800;" \ + "bl1 raw 0x1 0x1e;" \ + "bl2 raw 0x1f 0x1d;" \ + "tzsw raw 0x83f 0x138\0" + +/* + * Bootable media layout: + * dev: SD eMMC(part boot) + * BL1 1 0 + * BL2 31 30 + * UBOOT 63 62 + * TZSW 2111 2110 + * ENV 2560 2560(part user) + * + * MBR Primary partiions: + * Num Name Size Offset + * 1. BOOT: 100MiB 2MiB + * 2. ROOT: - +*/ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "loadkernel=fatload mmc ${mmcbootdev}:${mmcbootpart} ${kerneladdr} " \ + "${kernelname}\0" \ + "loadinitrd=fatload mmc ${mmcbootdev}:${mmcbootpart} ${initrdaddr} " \ + "${initrdname}\0" \ + "loaddtb=fatload mmc ${mmcbootdev}:${mmcbootpart} ${fdtaddr} " \ + "${fdtfile}\0" \ + "check_ramdisk=" \ + "if run loadinitrd; then " \ + "setenv initrd_addr ${initrdaddr};" \ + "else " \ + "setenv initrd_addr -;" \ + "fi;\0" \ + "check_dtb=" \ + "if run loaddtb; then " \ + "setenv fdt_addr ${fdtaddr};" \ + "else " \ + "setenv fdt_addr;" \ + "fi;\0" \ + "kernel_args=" \ + "setenv bootargs root=/dev/mmcblk${mmcrootdev}p${mmcrootpart}" \ + " rootwait ${console} ${opts}\0" \ + "boot_fit=" \ + "setenv kerneladdr 0x42000000;" \ + "setenv kernelname Image.itb;" \ + "run loadkernel;" \ + "run kernel_args;" \ + "bootm ${kerneladdr}#${boardname}\0" \ + "boot_uimg=" \ + "setenv kerneladdr 0x40007FC0;" \ + "setenv kernelname uImage;" \ + "run check_dtb;" \ + "run check_ramdisk;" \ + "run loadkernel;" \ + "run kernel_args;" \ + "bootm ${kerneladdr} ${initrd_addr} ${fdt_addr};\0" \ + "boot_zimg=" \ + "setenv kerneladdr 0x40007FC0;" \ + "setenv kernelname zImage;" \ + "run check_dtb;" \ + "run check_ramdisk;" \ + "run loadkernel;" \ + "run kernel_args;" \ + "bootz ${kerneladdr} ${initrd_addr} ${fdt_addr};\0" \ + "autoboot=" \ + "if test -e mmc 0 Image.itb; then; " \ + "run boot_fit;" \ + "elif test -e mmc 0 zImage; then; " \ + "run boot_zimg;" \ + "elif test -e mmc 0 uImage; then; " \ + "run boot_uimg;" \ + "fi;\0" \ + "console=" CONFIG_DEFAULT_CONSOLE \ + "mmcbootdev=0\0" \ + "mmcbootpart=1\0" \ + "mmcrootdev=0\0" \ + "mmcrootpart=2\0" \ + "bootdelay=0\0" \ + "dfu_alt_system="CONFIG_DFU_ALT \ + "dfu_alt_info=Please reset the board\0" \ + "consoleon=set console console=ttySAC1,115200n8; save; reset\0" \ + "consoleoff=set console console=ram; save; reset\0" \ + "initrdname=uInitrd\0" \ + "initrdaddr=42000000\0" \ + "fdtaddr=40800000\0" + +/* I2C */ +#define CONFIG_CMD_I2C +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_S3C24X0 +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 +#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0 +#define CONFIG_MAX_I2C_NUM 8 +#define CONFIG_SYS_I2C_INIT_BOARD + +/* POWER */ +#define CONFIG_POWER +#define CONFIG_POWER_I2C +#define CONFIG_POWER_MAX77686 + +/* GPT */ +#define CONFIG_RANDOM_UUID + +/* Security subsystem - enable hw_rand() */ +#define CONFIG_EXYNOS_ACE_SHA +#define CONFIG_LIB_HW_RAND + +#define CONFIG_CMD_GPIO + +/* + * Supported Odroid boards: X3, U3 + * TODO: Add Odroid X support + */ +#define CONFIG_MISC_COMMON +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +#define CONFIG_BOARD_TYPES +#define CONFIG_MISC_INIT_R + +#undef CONFIG_REVISION_TAG + +#endif /* __CONFIG_H */

This patch set introduces changes to common Samsung code as a preparation of new board support: - boot device check - code cleanup - automatic init order of mmc drivers - automatic setting of dfu entities which depends on boot device - pre reset function call for board own implementation - setting board info environment for multi board support
New board config: - odroid_config - Odroid U3/X2 support
V7 changes: - some code cleanup
Przemyslaw Marczak (12): samsung: misc: fix soc revision setting in the set_board_info() exynos: pinmux: fix the gpio names for exynos4x12 mmc arch:exynos: boot mode: add get_boot_mode(), code cleanup board:samsung: check the boot device and init the right mmc driver. samsung: misc: add function for setting $dfu_alt_info samsung:board: misc_init_r: call set_dfu_alt_info() arm:reset: call the reset_misc() before the cpu reset samsung: board: enable support of multiple board types samsung: misc: use board specific functions to set env board info odroid: add board file for Odroid X2/U3 based on Samsung Exynos4412 odroid: add odroid U3/X2 device tree description odroid: add odroid_config
arch/arm/cpu/armv7/exynos/pinmux.c | 4 +- arch/arm/cpu/armv7/exynos/power.c | 7 + arch/arm/cpu/armv7/exynos/spl_boot.c | 7 +- arch/arm/dts/Makefile | 3 +- arch/arm/dts/exynos4412-odroid.dts | 70 +++++ arch/arm/include/asm/arch-exynos/power.h | 21 ++ arch/arm/include/asm/arch-exynos/spl.h | 17 +- arch/arm/lib/reset.c | 6 + board/samsung/common/board.c | 55 +++- board/samsung/common/misc.c | 57 +++- board/samsung/odroid/Makefile | 8 + board/samsung/odroid/odroid.c | 470 +++++++++++++++++++++++++++++++ board/samsung/odroid/setup.h | 255 +++++++++++++++++ boards.cfg | 1 + doc/README.odroid | 143 ++++++++++ include/common.h | 1 + include/configs/odroid.h | 216 ++++++++++++++ include/samsung/misc.h | 10 + 18 files changed, 1310 insertions(+), 41 deletions(-) create mode 100644 arch/arm/dts/exynos4412-odroid.dts create mode 100644 board/samsung/odroid/Makefile create mode 100644 board/samsung/odroid/odroid.c create mode 100644 board/samsung/odroid/setup.h create mode 100644 doc/README.odroid create mode 100644 include/configs/odroid.h

The byte order of soc revision was inverted, now it is fixed.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Piotr Wilczek p.wilczek@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com --- board/samsung/common/misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index 03106fd..a453a82 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -26,8 +26,8 @@ void set_board_info(void) { char info[64];
- snprintf(info, ARRAY_SIZE(info), "%d.%d", s5p_cpu_rev & 0x0f, - (s5p_cpu_rev & 0xf0) >> 0x04); + snprintf(info, ARRAY_SIZE(info), "%u.%u", (s5p_cpu_rev & 0xf0) >> 4, + s5p_cpu_rev & 0xf); setenv("soc_rev", info);
snprintf(info, ARRAY_SIZE(info), "%x", s5p_cpu_id);

This change fixes the bad gpio configuration for the exynos dwmmc.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Beomho Seo beomho.seo@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Jaehoon Chung jh80.chung@samsung.com --- arch/arm/cpu/armv7/exynos/pinmux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index 86a0c75..b929486 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -704,8 +704,8 @@ static int exynos4x12_mmc_config(int peripheral, int flags) ext_func = S5P_GPIO_FUNC(0x3); break; case PERIPH_ID_SDMMC4: - start = EXYNOS4_GPIO_K00; - start_ext = EXYNOS4_GPIO_K13; + start = EXYNOS4X12_GPIO_K00; + start_ext = EXYNOS4X12_GPIO_K13; func = S5P_GPIO_FUNC(0x3); ext_func = S5P_GPIO_FUNC(0x4); break;

This patch introduces code clean-up for exynos boot mode check. It includes: - removal of typedef: boot_mode - move the boot mode enum to arch-exynos/power.h - add bootmode for sequence: eMMC 4.4 ch4 / SD ch2 - add new function: get_boot_mode() for OM[5:1] pin check - update spl boot code
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com
Changes v5: - exynos: boot mode: add missing bootmode (1st:EMMC 4.4 / 2nd:SD ch2)
Changes v6: - none
changes v7: - change boot mode name: BOOT_MODE_MMC to BOOT_MODE_SD --- arch/arm/cpu/armv7/exynos/power.c | 7 +++++++ arch/arm/cpu/armv7/exynos/spl_boot.c | 7 +++---- arch/arm/include/asm/arch-exynos/power.h | 21 +++++++++++++++++++++ arch/arm/include/asm/arch-exynos/spl.h | 17 ++--------------- 4 files changed, 33 insertions(+), 19 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c index 638ee0b..e1ab3d6 100644 --- a/arch/arm/cpu/armv7/exynos/power.c +++ b/arch/arm/cpu/armv7/exynos/power.c @@ -202,3 +202,10 @@ void power_exit_wakeup(void) else exynos4_power_exit_wakeup(); } + +unsigned int get_boot_mode(void) +{ + unsigned int om_pin = samsung_get_base_power(); + + return readl(om_pin) & OM_PIN_MASK; +} diff --git a/arch/arm/cpu/armv7/exynos/spl_boot.c b/arch/arm/cpu/armv7/exynos/spl_boot.c index 7916630..658e4cb 100644 --- a/arch/arm/cpu/armv7/exynos/spl_boot.c +++ b/arch/arm/cpu/armv7/exynos/spl_boot.c @@ -20,7 +20,6 @@ #include "clock_init.h"
DECLARE_GLOBAL_DATA_PTR; -#define OM_STAT (0x1f << 1)
/* Index into irom ptr table */ enum index { @@ -184,7 +183,7 @@ static void exynos_spi_copy(unsigned int uboot_size, unsigned int uboot_addr) */ void copy_uboot_to_ram(void) { - enum boot_mode bootmode = BOOT_MODE_OM; + unsigned int bootmode = BOOT_MODE_OM;
u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst) = NULL; u32 offset = 0, size = 0; @@ -207,7 +206,7 @@ void copy_uboot_to_ram(void) #endif
if (bootmode == BOOT_MODE_OM) - bootmode = readl(samsung_get_base_power()) & OM_STAT; + bootmode = get_boot_mode();
switch (bootmode) { #ifdef CONFIG_SPI_BOOTING @@ -216,7 +215,7 @@ void copy_uboot_to_ram(void) exynos_spi_copy(param->uboot_size, CONFIG_SYS_TEXT_BASE); break; #endif - case BOOT_MODE_MMC: + case BOOT_MODE_SD: offset = BL2_START_OFFSET; size = BL2_SIZE_BLOC_COUNT; copy_bl2 = get_irom_func(MMC_INDEX); diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h index 4f2447b..e8a98a5 100644 --- a/arch/arm/include/asm/arch-exynos/power.h +++ b/arch/arm/include/asm/arch-exynos/power.h @@ -1670,6 +1670,27 @@ struct exynos5420_power { }; #endif /* __ASSEMBLY__ */
+#define OM_PIN_BITS 0x1f +#define OM_PIN_SHIFT 0x1 +#define OM_PIN_MASK (OM_PIN_BITS << OM_PIN_SHIFT) + +enum { + /* + * Assign the OM pin values for respective boot modes. + * Exynos4 does not support spi boot and the mmc boot OM + * pin values are the same across Exynos4 and Exynos5. + */ + BOOT_MODE_SD = 4, /* SD_CH2 | USB */ + BOOT_MODE_EMMC = 8, /* EMMC4.4 | USB */ + BOOT_MODE_EMMC_SD = 40, /* EMMC4.4 | SD_CH2 */ + BOOT_MODE_SERIAL = 20, + /* Boot based on Operating Mode pin settings */ + BOOT_MODE_OM = 32, + BOOT_MODE_USB, /* Boot using USB download */ +}; + +unsigned int get_boot_mode(void); + void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable);
#define EXYNOS_MIPI_PHY_ENABLE (1 << 0) diff --git a/arch/arm/include/asm/arch-exynos/spl.h b/arch/arm/include/asm/arch-exynos/spl.h index b1d68c3..cdcb2bc 100644 --- a/arch/arm/include/asm/arch-exynos/spl.h +++ b/arch/arm/include/asm/arch-exynos/spl.h @@ -8,20 +8,7 @@ #define __ASM_ARCH_EXYNOS_SPL_H__
#include <asm/arch-exynos/dmc.h> - -enum boot_mode { - /* - * Assign the OM pin values for respective boot modes. - * Exynos4 does not support spi boot and the mmc boot OM - * pin values are the same across Exynos4 and Exynos5. - */ - BOOT_MODE_MMC = 4, - BOOT_MODE_EMMC = 8, /* EMMC4.4 */ - BOOT_MODE_SERIAL = 20, - /* Boot based on Operating Mode pin settings */ - BOOT_MODE_OM = 32, - BOOT_MODE_USB, /* Boot using USB download */ -}; +#include <asm/arch/power.h>
#ifndef __ASSEMBLY__ /* Parameters of early board initialization in SPL */ @@ -62,7 +49,7 @@ struct spl_machine_param { * table only for mmc boot. */ u32 uboot_size; - enum boot_mode boot_source; /* Boot device */ + unsigned boot_source; /* Boot device */ unsigned frequency_mhz; /* Frequency of memory in MHz */ unsigned arm_freq_mhz; /* ARM Frequency in MHz */ u32 serial_base; /* Serial base address */

It is possible to boot device using a micro SD or eMMC slots. In this situation, boot device should be registered as a block device 0 in the MMC framework, because CONFIG_SYS_MMC_ENV_DEV is usually set to "0" in the most config cases.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com --- Changes V3: - separate two changes into two commits
Changes V4: - board.c: add functions: init_mmc() and init_dwmmc() - board_mmc_init(): call get_boot_mode()
Changes V5: - none
Changes V6: - update boot mode name --- board/samsung/common/board.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index 9dc7c83..1fa0e51 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -240,22 +240,39 @@ int board_eth_init(bd_t *bis) }
#ifdef CONFIG_GENERIC_MMC -int board_mmc_init(bd_t *bis) +static int init_mmc(void) +{ +#ifdef CONFIG_SDHCI + return exynos_mmc_init(gd->fdt_blob); +#else + return 0; +#endif +} + +static int init_dwmmc(void) { - int ret; #ifdef CONFIG_DWMMC - /* dwmmc initializattion for available channels */ - ret = exynos_dwmmc_init(gd->fdt_blob); - if (ret) - debug("dwmmc init failed\n"); + return exynos_dwmmc_init(gd->fdt_blob); +#else + return 0; #endif +} + +int board_mmc_init(bd_t *bis) +{ + int ret; + + if (get_boot_mode() == BOOT_MODE_SD) { + ret = init_mmc(); + ret |= init_dwmmc(); + } else { + ret = init_dwmmc(); + ret |= init_mmc(); + }
-#ifdef CONFIG_SDHCI - /* mmc initializattion for available channels */ - ret = exynos_mmc_init(gd->fdt_blob); if (ret) debug("mmc init failed\n"); -#endif + return ret; } #endif

This change introduces new common function: - set_dfu_alt_info() - put dfu system and bootloader setting into $dfu_alt_info. functions declaration: - char *get_dfu_alt_system(void) - char *get_dfu_alt_boot(void) - void set_dfu_alt_info(void) and new config: - CONFIG_SET_DFU_ALT_INFO
This function can be used for auto setting dfu configuration on boot. Such feature is useful for multi board support by one u-boot binary. Each board should define two functions: - get_dfu_alt_system() - get_dfu_alt_boot()
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Piotr Wilczek p.wilczek@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v2: - change config names: CONFIG_SET_DFU_BOOT_ALT to CONFIG_DFU_ALT_BOOTLOADER and CONFIG_DFU_BOOT_ALT_* to CONFIG_DFU_ALT_BOOT_* - change function name: set_dfu_boot_alt() to set_dfu_alt_boot() - remove superfluous ifdefs
Changes v3: - set $dfu_alt_info at every boot - new config: CONFIG_SET_DFU_ALT_INFO - update commit msg
Changes v4: - set_dfu_alt_info(): add checking the pointer returned by malloc
Changes v5: - set_dfu_alt_info(): remove malloc and declare cache aligned buffer - set_dfu_alt_info(): introduce CONFIG_SET_DFU_ALT_BUF_LEN --- board/samsung/common/misc.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/samsung/misc.h | 6 ++++++ 2 files changed, 47 insertions(+)
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index a453a82..9e52452 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -11,6 +11,7 @@ #include <samsung/misc.h> #include <errno.h> #include <version.h> +#include <malloc.h> #include <linux/sizes.h> #include <asm/arch/cpu.h> #include <asm/arch/gpio.h> @@ -21,6 +22,46 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_SET_DFU_ALT_INFO +void set_dfu_alt_info(void) +{ + size_t buf_size = CONFIG_SET_DFU_ALT_BUF_LEN; + ALLOC_CACHE_ALIGN_BUFFER(char, buf, buf_size); + char *alt_info = "Settings not found!"; + char *status = "error!\n"; + char *alt_setting; + char *alt_sep; + int offset = 0; + + puts("DFU alt info setting: "); + + alt_setting = get_dfu_alt_boot(); + if (alt_setting) { + setenv("dfu_alt_boot", alt_setting); + offset = snprintf(buf, buf_size, "%s", alt_setting); + } + + alt_setting = get_dfu_alt_system(); + if (alt_setting) { + if (offset) + alt_sep = ";"; + else + alt_sep = ""; + + offset += snprintf(buf + offset, buf_size - offset, + "%s%s", alt_sep, alt_setting); + } + + if (offset) { + alt_info = buf; + status = "done\n"; + } + + setenv("dfu_alt_info", alt_info); + puts(status); +} +#endif + #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG void set_board_info(void) { diff --git a/include/samsung/misc.h b/include/samsung/misc.h index 10653a1..e82bf32 100644 --- a/include/samsung/misc.h +++ b/include/samsung/misc.h @@ -28,4 +28,10 @@ void check_boot_mode(void); void draw_logo(void); #endif
+#ifdef CONFIG_SET_DFU_ALT_INFO +char *get_dfu_alt_system(void); +char *get_dfu_alt_boot(void); +void set_dfu_alt_info(void); +#endif + #endif /* __SAMSUNG_MISC_COMMON_H__ */

This change enable automatic setting of dfu alt info on every boot. This is useful in case of booting one u-boot binary from multiple media.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com --- board/samsung/common/board.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index 1fa0e51..5693813 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -324,6 +324,9 @@ int arch_early_init_r(void) #ifdef CONFIG_MISC_INIT_R int misc_init_r(void) { +#ifdef CONFIG_SET_DFU_ALT_INFO + set_dfu_alt_info(); +#endif #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG set_board_info(); #endif

On an Odroid U3 board, the SOC is unable to reset the eMMC card in the DWMMC mode by the cpu software reset. Manual reset of the card by switching proper gpio pin - fixes this issue.
Such solution needs to add a call to pre reset function. This is done by the reset_misc() function, which is called before reset_cpu(). The function reset_misc() is a weak function.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Jean-Christophe PLAGNIOL-VILLARD plagnioj@jcrosoft.com Cc: Albert ARIBAUD albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com
Changes v4: - arch/arm/reset: fix weak function attribute to proper style --- arch/arm/lib/reset.c | 6 ++++++ include/common.h | 1 + 2 files changed, 7 insertions(+)
diff --git a/arch/arm/lib/reset.c b/arch/arm/lib/reset.c index 7a03580..9a95f08 100644 --- a/arch/arm/lib/reset.c +++ b/arch/arm/lib/reset.c @@ -23,6 +23,10 @@
#include <common.h>
+__weak void reset_misc(void) +{ +} + int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { puts ("resetting ...\n"); @@ -30,6 +34,8 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) udelay (50000); /* wait 50 ms */
disable_interrupts(); + + reset_misc(); reset_cpu(0);
/*NOTREACHED*/ diff --git a/include/common.h b/include/common.h index cc74633..557893a 100644 --- a/include/common.h +++ b/include/common.h @@ -623,6 +623,7 @@ int checkicache (void); int checkdcache (void); void upmconfig (unsigned int, unsigned int *, unsigned int); ulong get_tbclk (void); +void reset_misc (void); void reset_cpu (ulong addr); #if defined (CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP) void ft_cpu_setup(void *blob, bd_t *bd);

This change adds declaration of functions: - set_board_type() - called at board_early_init_f() - get_board_type() - called at checkboard()
For supporting multiple board types in a one config - it is welcome to display the current board model. This is what get_board_type() should return.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Piotr Wilczek p.wilczek@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v3: - change the commit order - include/samsung/misc.h: add new functions declaration - update a commit message
Changes v4: - checkboard(): remove redundant variable
Changes v5: - board.c: move call to set_board_type() into board_early_init_f() - misc.h: remove get_board_name() function declaration --- board/samsung/common/board.c | 15 ++++++++++----- include/samsung/misc.h | 4 ++++ 2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index 5693813..3d1cf43 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -137,7 +137,9 @@ static int board_uart_init(void) int board_early_init_f(void) { int err; - +#ifdef CONFIG_BOARD_TYPES + set_board_type(); +#endif err = board_uart_init(); if (err) { debug("UART init failed\n"); @@ -147,7 +149,6 @@ int board_early_init_f(void) #ifdef CONFIG_SYS_I2C_INIT_BOARD board_i2c_init(gd->fdt_blob); #endif - return exynos_early_init_f(); } #endif @@ -280,11 +281,15 @@ int board_mmc_init(bd_t *bis) #ifdef CONFIG_DISPLAY_BOARDINFO int checkboard(void) { - const char *board_name; + const char *board_info;
- board_name = fdt_getprop(gd->fdt_blob, 0, "model", NULL); - printf("Board: %s\n", board_name ? board_name : "unknown"); + board_info = fdt_getprop(gd->fdt_blob, 0, "model", NULL); + printf("Board: %s\n", board_info ? board_info : "unknown"); +#ifdef CONFIG_BOARD_TYPES + board_info = get_board_type();
+ printf("Model: %s\n", board_info ? board_info : "unknown"); +#endif return 0; } #endif diff --git a/include/samsung/misc.h b/include/samsung/misc.h index e82bf32..607e8d4 100644 --- a/include/samsung/misc.h +++ b/include/samsung/misc.h @@ -33,5 +33,9 @@ char *get_dfu_alt_system(void); char *get_dfu_alt_boot(void); void set_dfu_alt_info(void); #endif +#ifdef CONFIG_BOARD_TYPES +void set_board_type(void); +const char *get_board_type(void); +#endif
#endif /* __SAMSUNG_MISC_COMMON_H__ */

This change adds setup of environmental board info using get_board_name() and get_board_type() functions for config CONFIG_BOARD_TYPES.
This is useful in case of running many boards with just one config.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Piotr Wilczek p.wilczek@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v2: - set_board_info: move the bdtype pointer to avoid unused pointer compilation warning
Changes v3: - samsung: misc: change get_board_type_fdt() to get_board_type() - samsung: misc: set env $boardname using get_board_* functions for CONFIG_BOARD_TYPES - update commit msg
Changes v5: - misc.c: set_bard_info(): remove a call to get_board_name() --- board/samsung/common/misc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index 9e52452..8766f0c 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -79,8 +79,16 @@ void set_board_info(void) setenv("board_rev", info); #endif #ifdef CONFIG_OF_LIBFDT - snprintf(info, ARRAY_SIZE(info), "%s%x-%s.dtb", - CONFIG_SYS_SOC, s5p_cpu_id, CONFIG_SYS_BOARD); + const char *bdtype = ""; + const char *bdname = CONFIG_SYS_BOARD; + +#ifdef CONFIG_BOARD_TYPES + bdtype = get_board_type(); + sprintf(info, "%s%s", bdname, bdtype); + setenv("boardname", info); +#endif + snprintf(info, ARRAY_SIZE(info), "%s%x-%s%s.dtb", + CONFIG_SYS_SOC, s5p_cpu_id, bdname, bdtype); setenv("fdtfile", info); #endif }

This board file supports standard features of Odroid X2 and U3 boards: - Exynos4412 core clock set to 1000MHz and MPLL peripherial clock set to 800MHz, - MAX77686 power regulator, - USB PHY, - enable XCL205 - power for board peripherials - check board type: U3 or X2. - enable Odroid U3 FAN cooler
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Tom Rini trini@ti.com
--- Changes v2: - enable fan on odroid U3
Changes v3: - odroid.c: clean up board name related code - odroid.c: remove static from set_board_type() - odroid.c: add implementation of functions: get_dfu_alt_* - odroid.c: include misc.h
Changes v4: - odroid.c: dfu_get_alt_boot: add call get_boot_mode()
Changes v5: - odroid.c: set_board_type: change mdelay to sdelay, define XCL205 GPIO config - odroid.c: board_gpio_init(): fix OTG for Odroid U3+ - odroid.c: reserve the last 1 MB of dram for secure firmware - odroid.c: board_clock_init(): code cleanup - odroid.c: get_dfu_alt_boot(): remove setenv() - odroid.c: remove get_board_name() function definition - odroid.c: add enum ODROID_TYPES --- board/samsung/odroid/Makefile | 8 + board/samsung/odroid/odroid.c | 470 ++++++++++++++++++++++++++++++++++++++++++ board/samsung/odroid/setup.h | 255 +++++++++++++++++++++++ 3 files changed, 733 insertions(+) create mode 100644 board/samsung/odroid/Makefile create mode 100644 board/samsung/odroid/odroid.c create mode 100644 board/samsung/odroid/setup.h
diff --git a/board/samsung/odroid/Makefile b/board/samsung/odroid/Makefile new file mode 100644 index 0000000..b98aaeb --- /dev/null +++ b/board/samsung/odroid/Makefile @@ -0,0 +1,8 @@ +# +# Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved. +# Przemyslaw Marczak p.marczak@samsung.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := odroid.o diff --git a/board/samsung/odroid/odroid.c b/board/samsung/odroid/odroid.c new file mode 100644 index 0000000..ac19527 --- /dev/null +++ b/board/samsung/odroid/odroid.c @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * Przemyslaw Marczak p.marczak@samsung.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/power.h> +#include <asm/arch/clock.h> +#include <asm/arch/gpio.h> +#include <asm/gpio.h> +#include <asm/arch/cpu.h> +#include <power/pmic.h> +#include <power/max77686_pmic.h> +#include <errno.h> +#include <usb.h> +#include <usb/s3c_udc.h> +#include <samsung/misc.h> +#include "setup.h" + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_BOARD_TYPES +/* Odroid board types */ +enum { + ODROID_TYPE_U3, + ODROID_TYPE_X2, + ODROID_TYPES, +}; + +void set_board_type(void) +{ + /* Set GPA1 pin 1 to HI - enable XCL205 output */ + writel(XCL205_EN_GPIO_CON_CFG, XCL205_EN_GPIO_CON); + writel(XCL205_EN_GPIO_DAT_CFG, XCL205_EN_GPIO_CON + 0x4); + writel(XCL205_EN_GPIO_PUD_CFG, XCL205_EN_GPIO_CON + 0x8); + writel(XCL205_EN_GPIO_DRV_CFG, XCL205_EN_GPIO_CON + 0xc); + + /* Set GPC1 pin 2 to IN - check XCL205 output state */ + writel(XCL205_STATE_GPIO_CON_CFG, XCL205_STATE_GPIO_CON); + writel(XCL205_STATE_GPIO_PUD_CFG, XCL205_STATE_GPIO_CON + 0x8); + + /* XCL205 - needs some latch time */ + sdelay(200000); + + /* Check GPC1 pin2 - LED supplied by XCL205 - X2 only */ + if (readl(XCL205_STATE_GPIO_DAT) & (1 << XCL205_STATE_GPIO_PIN)) + gd->board_type = ODROID_TYPE_X2; + else + gd->board_type = ODROID_TYPE_U3; +} + +const char *get_board_type(void) +{ + const char *board_type[] = {"u3", "x2"}; + + return board_type[gd->board_type]; +} +#endif + +#ifdef CONFIG_SET_DFU_ALT_INFO +char *get_dfu_alt_system(void) +{ + return getenv("dfu_alt_system"); +} + +char *get_dfu_alt_boot(void) +{ + char *alt_boot; + + switch (get_boot_mode()) { + case BOOT_MODE_SD: + alt_boot = CONFIG_DFU_ALT_BOOT_SD; + break; + case BOOT_MODE_EMMC: + case BOOT_MODE_EMMC_SD: + alt_boot = CONFIG_DFU_ALT_BOOT_EMMC; + break; + default: + alt_boot = NULL; + break; + } + return alt_boot; +} +#endif + +static void board_clock_init(void) +{ + unsigned int set, clr, clr_src_cpu, clr_pll_con0, clr_src_dmc; + struct exynos4x12_clock *clk = (struct exynos4x12_clock *) + samsung_get_base_clock(); + + /* + * CMU_CPU clocks src to MPLL + * Bit values: 0 ; 1 + * MUX_APLL_SEL: FIN_PLL ; FOUT_APLL + * MUX_CORE_SEL: MOUT_APLL ; SCLK_MPLL + * MUX_HPM_SEL: MOUT_APLL ; SCLK_MPLL_USER_C + * MUX_MPLL_USER_SEL_C: FIN_PLL ; SCLK_MPLL + */ + clr_src_cpu = MUX_APLL_SEL(1) | MUX_CORE_SEL(1) | + MUX_HPM_SEL(1) | MUX_MPLL_USER_SEL_C(1); + set = MUX_APLL_SEL(0) | MUX_CORE_SEL(1) | MUX_HPM_SEL(1) | + MUX_MPLL_USER_SEL_C(1); + + clrsetbits_le32(&clk->src_cpu, clr_src_cpu, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_cpu) & MUX_STAT_CPU_CHANGING) + continue; + + /* Set APLL to 1000MHz */ + clr_pll_con0 = SDIV(7) | PDIV(63) | MDIV(1023) | FSEL(1); + set = SDIV(0) | PDIV(3) | MDIV(125) | FSEL(1); + + clrsetbits_le32(&clk->apll_con0, clr_pll_con0, set); + + /* Wait for PLL to be locked */ + while (!(readl(&clk->apll_con0) & PLL_LOCKED_BIT)) + continue; + + /* Set CMU_CPU clocks src to APLL */ + set = MUX_APLL_SEL(1) | MUX_CORE_SEL(0) | MUX_HPM_SEL(0) | + MUX_MPLL_USER_SEL_C(1); + clrsetbits_le32(&clk->src_cpu, clr_src_cpu, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_cpu) & MUX_STAT_CPU_CHANGING) + continue; + + set = CORE_RATIO(0) | COREM0_RATIO(2) | COREM1_RATIO(5) | + PERIPH_RATIO(0) | ATB_RATIO(4) | PCLK_DBG_RATIO(1) | + APLL_RATIO(0) | CORE2_RATIO(0); + /* + * Set dividers for MOUTcore = 1000 MHz + * coreout = MOUT / (ratio + 1) = 1000 MHz (0) + * corem0 = armclk / (ratio + 1) = 333 MHz (2) + * corem1 = armclk / (ratio + 1) = 166 MHz (5) + * periph = armclk / (ratio + 1) = 1000 MHz (0) + * atbout = MOUT / (ratio + 1) = 200 MHz (4) + * pclkdbgout = atbout / (ratio + 1) = 100 MHz (1) + * sclkapll = MOUTapll / (ratio + 1) = 1000 MHz (0) + * core2out = core_out / (ratio + 1) = 1000 MHz (0) (armclk) + */ + clr = CORE_RATIO(7) | COREM0_RATIO(7) | COREM1_RATIO(7) | + PERIPH_RATIO(7) | ATB_RATIO(7) | PCLK_DBG_RATIO(7) | + APLL_RATIO(7) | CORE2_RATIO(7); + + clrsetbits_le32(&clk->div_cpu0, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_cpu0) & DIV_STAT_CPU0_CHANGING) + continue; + + /* + * For MOUThpm = 1000 MHz (MOUTapll) + * doutcopy = MOUThpm / (ratio + 1) = 200 (4) + * sclkhpm = doutcopy / (ratio + 1) = 200 (4) + * cores_out = armclk / (ratio + 1) = 1000 (0) + */ + clr = COPY_RATIO(7) | HPM_RATIO(7) | CORES_RATIO(7); + set = COPY_RATIO(4) | HPM_RATIO(4) | CORES_RATIO(0); + + clrsetbits_le32(&clk->div_cpu1, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_cpu1) & DIV_STAT_CPU1_CHANGING) + continue; + + /* + * Set CMU_DMC clocks src to APLL + * Bit values: 0 ; 1 + * MUX_C2C_SEL: SCLKMPLL ; SCLKAPLL + * MUX_DMC_BUS_SEL: SCLKMPLL ; SCLKAPLL + * MUX_DPHY_SEL: SCLKMPLL ; SCLKAPLL + * MUX_MPLL_SEL: FINPLL ; MOUT_MPLL_FOUT + * MUX_PWI_SEL: 0110 (MPLL); 0111 (EPLL); 1000 (VPLL); 0(XXTI) + * MUX_G2D_ACP0_SEL: SCLKMPLL ; SCLKAPLL + * MUX_G2D_ACP1_SEL: SCLKEPLL ; SCLKVPLL + * MUX_G2D_ACP_SEL: OUT_ACP0 ; OUT_ACP1 + */ + clr_src_dmc = MUX_C2C_SEL(1) | MUX_DMC_BUS_SEL(1) | + MUX_DPHY_SEL(1) | MUX_MPLL_SEL(1) | + MUX_PWI_SEL(15) | MUX_G2D_ACP0_SEL(1) | + MUX_G2D_ACP1_SEL(1) | MUX_G2D_ACP_SEL(1); + set = MUX_C2C_SEL(1) | MUX_DMC_BUS_SEL(1) | MUX_DPHY_SEL(1) | + MUX_MPLL_SEL(0) | MUX_PWI_SEL(0) | MUX_G2D_ACP0_SEL(1) | + MUX_G2D_ACP1_SEL(1) | MUX_G2D_ACP_SEL(1); + + clrsetbits_le32(&clk->src_dmc, clr_src_dmc, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_dmc) & MUX_STAT_DMC_CHANGING) + continue; + + /* Set MPLL to 800MHz */ + set = SDIV(0) | PDIV(3) | MDIV(100) | FSEL(0) | PLL_ENABLE(1); + + clrsetbits_le32(&clk->mpll_con0, clr_pll_con0, set); + + /* Wait for PLL to be locked */ + while (!(readl(&clk->mpll_con0) & PLL_LOCKED_BIT)) + continue; + + /* Switch back CMU_DMC mux */ + set = MUX_C2C_SEL(0) | MUX_DMC_BUS_SEL(0) | MUX_DPHY_SEL(0) | + MUX_MPLL_SEL(1) | MUX_PWI_SEL(8) | MUX_G2D_ACP0_SEL(0) | + MUX_G2D_ACP1_SEL(0) | MUX_G2D_ACP_SEL(0); + + clrsetbits_le32(&clk->src_dmc, clr_src_dmc, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_dmc) & MUX_STAT_DMC_CHANGING) + continue; + + /* CLK_DIV_DMC0 */ + clr = ACP_RATIO(7) | ACP_PCLK_RATIO(7) | DPHY_RATIO(7) | + DMC_RATIO(7) | DMCD_RATIO(7) | DMCP_RATIO(7); + /* + * For: + * MOUTdmc = 800 MHz + * MOUTdphy = 800 MHz + * + * aclk_acp = MOUTdmc / (ratio + 1) = 200 (3) + * pclk_acp = aclk_acp / (ratio + 1) = 100 (1) + * sclk_dphy = MOUTdphy / (ratio + 1) = 400 (1) + * sclk_dmc = MOUTdmc / (ratio + 1) = 400 (1) + * aclk_dmcd = sclk_dmc / (ratio + 1) = 200 (1) + * aclk_dmcp = aclk_dmcd / (ratio + 1) = 100 (1) + */ + set = ACP_RATIO(3) | ACP_PCLK_RATIO(1) | DPHY_RATIO(1) | + DMC_RATIO(1) | DMCD_RATIO(1) | DMCP_RATIO(1); + + clrsetbits_le32(&clk->div_dmc0, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_dmc0) & DIV_STAT_DMC0_CHANGING) + continue; + + /* CLK_DIV_DMC1 */ + clr = G2D_ACP_RATIO(15) | C2C_RATIO(7) | PWI_RATIO(15) | + C2C_ACLK_RATIO(7) | DVSEM_RATIO(127) | DPM_RATIO(127); + /* + * For: + * MOUTg2d = 800 MHz + * MOUTc2c = 800 Mhz + * MOUTpwi = 108 MHz + * + * sclk_g2d_acp = MOUTg2d / (ratio + 1) = 400 (1) + * sclk_c2c = MOUTc2c / (ratio + 1) = 400 (1) + * aclk_c2c = sclk_c2c / (ratio + 1) = 200 (1) + * sclk_pwi = MOUTpwi / (ratio + 1) = 18 (5) + */ + set = G2D_ACP_RATIO(1) | C2C_RATIO(1) | PWI_RATIO(5) | + C2C_ACLK_RATIO(1) | DVSEM_RATIO(1) | DPM_RATIO(1); + + clrsetbits_le32(&clk->div_dmc1, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_dmc1) & DIV_STAT_DMC1_CHANGING) + continue; + + /* CLK_SRC_PERIL0 */ + clr = UART0_SEL(15) | UART1_SEL(15) | UART2_SEL(15) | + UART3_SEL(15) | UART4_SEL(15); + /* + * Set CLK_SRC_PERIL0 clocks src to MPLL + * src values: 0(XXTI); 1(XusbXTI); 2(SCLK_HDMI24M); 3(SCLK_USBPHY0); + * 5(SCLK_HDMIPHY); 6(SCLK_MPLL_USER_T); 7(SCLK_EPLL); + * 8(SCLK_VPLL) + * + * Set all to SCLK_MPLL_USER_T + */ + set = UART0_SEL(6) | UART1_SEL(6) | UART2_SEL(6) | UART3_SEL(6) | + UART4_SEL(6); + + clrsetbits_le32(&clk->src_peril0, clr, set); + + /* CLK_DIV_PERIL0 */ + clr = UART0_RATIO(15) | UART1_RATIO(15) | UART2_RATIO(15) | + UART3_RATIO(15) | UART4_RATIO(15); + /* + * For MOUTuart0-4: 800MHz + * + * SCLK_UARTx = MOUTuartX / (ratio + 1) = 100 (7) + */ + set = UART0_RATIO(7) | UART1_RATIO(7) | UART2_RATIO(7) | + UART3_RATIO(7) | UART4_RATIO(7); + + clrsetbits_le32(&clk->div_peril0, clr, set); + + while (readl(&clk->div_stat_peril0) & DIV_STAT_PERIL0_CHANGING) + continue; + + /* CLK_DIV_FSYS1 */ + clr = MMC0_RATIO(15) | MMC0_PRE_RATIO(255) | MMC1_RATIO(15) | + MMC1_PRE_RATIO(255); + /* + * For MOUTmmc0-3 = 800 MHz (MPLL) + * + * DOUTmmc1 = MOUTmmc1 / (ratio + 1) = 100 (7) + * sclk_mmc1 = DOUTmmc1 / (ratio + 1) = 50 (1) + * DOUTmmc0 = MOUTmmc0 / (ratio + 1) = 100 (7) + * sclk_mmc0 = DOUTmmc0 / (ratio + 1) = 50 (1) + */ + set = MMC0_RATIO(7) | MMC0_PRE_RATIO(1) | MMC1_RATIO(7) | + MMC1_PRE_RATIO(1); + + clrsetbits_le32(&clk->div_fsys1, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_fsys1) & DIV_STAT_FSYS1_CHANGING) + continue; + + /* CLK_DIV_FSYS2 */ + clr = MMC2_RATIO(15) | MMC2_PRE_RATIO(255) | MMC3_RATIO(15) | + MMC3_PRE_RATIO(255); + /* + * For MOUTmmc0-3 = 800 MHz (MPLL) + * + * DOUTmmc3 = MOUTmmc3 / (ratio + 1) = 100 (7) + * sclk_mmc3 = DOUTmmc3 / (ratio + 1) = 50 (1) + * DOUTmmc2 = MOUTmmc2 / (ratio + 1) = 100 (7) + * sclk_mmc2 = DOUTmmc2 / (ratio + 1) = 50 (1) + */ + set = MMC2_RATIO(7) | MMC2_PRE_RATIO(1) | MMC3_RATIO(7) | + MMC3_PRE_RATIO(1); + + clrsetbits_le32(&clk->div_fsys2, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_fsys2) & DIV_STAT_FSYS2_CHANGING) + continue; + + /* CLK_DIV_FSYS3 */ + clr = MMC4_RATIO(15) | MMC4_PRE_RATIO(255); + /* + * For MOUTmmc4 = 800 MHz (MPLL) + * + * DOUTmmc4 = MOUTmmc4 / (ratio + 1) = 100 (7) + * sclk_mmc4 = DOUTmmc4 / (ratio + 1) = 100 (0) + */ + set = MMC4_RATIO(7) | MMC4_PRE_RATIO(0); + + clrsetbits_le32(&clk->div_fsys3, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_fsys3) & DIV_STAT_FSYS3_CHANGING) + continue; + + return; +} + +static void board_gpio_init(void) +{ + /* eMMC Reset Pin */ + gpio_cfg_pin(EXYNOS4X12_GPIO_K12, S5P_GPIO_FUNC(0x1)); + gpio_set_pull(EXYNOS4X12_GPIO_K12, S5P_GPIO_PULL_NONE); + gpio_set_drv(EXYNOS4X12_GPIO_K12, S5P_GPIO_DRV_4X); + + /* Enable FAN (Odroid U3) */ + gpio_set_pull(EXYNOS4X12_GPIO_D00, S5P_GPIO_PULL_UP); + gpio_set_drv(EXYNOS4X12_GPIO_D00, S5P_GPIO_DRV_4X); + gpio_direction_output(EXYNOS4X12_GPIO_D00, 1); + + /* OTG Vbus output (Odroid U3+) */ + gpio_set_pull(EXYNOS4X12_GPIO_L20, S5P_GPIO_PULL_NONE); + gpio_set_drv(EXYNOS4X12_GPIO_L20, S5P_GPIO_DRV_4X); + gpio_direction_output(EXYNOS4X12_GPIO_L20, 0); + + /* OTG INT (Odroid U3+) */ + gpio_set_pull(EXYNOS4X12_GPIO_X31, S5P_GPIO_PULL_UP); + gpio_set_drv(EXYNOS4X12_GPIO_X31, S5P_GPIO_DRV_4X); + gpio_direction_input(EXYNOS4X12_GPIO_X31); +} + +static int pmic_init_max77686(void) +{ + struct pmic *p = pmic_get("MAX77686_PMIC"); + + if (pmic_probe(p)) + return -ENODEV; + + /* Set LDO Voltage */ + max77686_set_ldo_voltage(p, 20, 1800000); /* LDO20 eMMC */ + max77686_set_ldo_voltage(p, 21, 2800000); /* LDO21 SD */ + max77686_set_ldo_voltage(p, 22, 2800000); /* LDO22 eMMC */ + + return 0; +} + +#ifdef CONFIG_SYS_I2C_INIT_BOARD +static void board_init_i2c(void) +{ + /* I2C_0 */ + if (exynos_pinmux_config(PERIPH_ID_I2C0, PINMUX_FLAG_NONE)) + debug("I2C%d not configured\n", (I2C_0)); +} +#endif + +int exynos_early_init_f(void) +{ + board_clock_init(); + board_gpio_init(); + + return 0; +} + +int exynos_init(void) +{ + /* The last MB of memory is reserved for secure firmware */ + gd->ram_size -= SZ_1M; + gd->bd->bi_dram[CONFIG_NR_DRAM_BANKS - 1].size -= SZ_1M; + + return 0; +} + +int exynos_power_init(void) +{ +#ifdef CONFIG_SYS_I2C_INIT_BOARD + board_init_i2c(); +#endif + pmic_init(I2C_0); + pmic_init_max77686(); + + return 0; +} + +#ifdef CONFIG_USB_GADGET +static int s5pc210_phy_control(int on) +{ + struct pmic *p_pmic; + + p_pmic = pmic_get("MAX77686_PMIC"); + if (!p_pmic) + return -ENODEV; + + if (pmic_probe(p_pmic)) + return -1; + + if (on) + return max77686_set_ldo_mode(p_pmic, 12, OPMODE_ON); + else + return max77686_set_ldo_mode(p_pmic, 12, OPMODE_LPM); +} + +struct s3c_plat_otg_data s5pc210_otg_data = { + .phy_control = s5pc210_phy_control, + .regs_phy = EXYNOS4X12_USBPHY_BASE, + .regs_otg = EXYNOS4X12_USBOTG_BASE, + .usb_phy_ctrl = EXYNOS4X12_USBPHY_CONTROL, + .usb_flags = PHY0_SLEEP, +}; + +int board_usb_init(int index, enum usb_init_type init) +{ + debug("USB_udc_probe\n"); + return s3c_udc_probe(&s5pc210_otg_data); +} +#endif + +void reset_misc(void) +{ + /* Reset eMMC*/ + gpio_set_value(EXYNOS4X12_GPIO_K12, 0); + mdelay(10); + gpio_set_value(EXYNOS4X12_GPIO_K12, 1); +} diff --git a/board/samsung/odroid/setup.h b/board/samsung/odroid/setup.h new file mode 100644 index 0000000..3e48dad --- /dev/null +++ b/board/samsung/odroid/setup.h @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * Przemyslaw Marczak p.marczak@samsung.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ODROIDU3_SETUP__ +#define __ODROIDU3_SETUP__ + +/* A/M PLL_CON0 */ +#define SDIV(x) ((x) & 0x7) +#define PDIV(x) (((x) & 0x3f) << 8) +#define MDIV(x) (((x) & 0x3ff) << 16) +#define FSEL(x) (((x) & 0x1) << 27) +#define PLL_LOCKED_BIT (0x1 << 29) +#define PLL_ENABLE(x) (((x) & 0x1) << 31) + +/* CLK_SRC_CPU */ +#define MUX_APLL_SEL(x) ((x) & 0x1) +#define MUX_CORE_SEL(x) (((x) & 0x1) << 16) +#define MUX_HPM_SEL(x) (((x) & 0x1) << 20) +#define MUX_MPLL_USER_SEL_C(x) (((x) & 0x1) << 24) + +#define MUX_STAT_CHANGING 0x100 + +/* CLK_MUX_STAT_CPU */ +#define APLL_SEL(x) ((x) & 0x7) +#define CORE_SEL(x) (((x) & 0x7) << 16) +#define HPM_SEL(x) (((x) & 0x7) << 20) +#define MPLL_USER_SEL_C(x) (((x) & 0x7) << 24) +#define MUX_STAT_CPU_CHANGING (APLL_SEL(MUX_STAT_CHANGING) | \ + CORE_SEL(MUX_STAT_CHANGING) | \ + HPM_SEL(MUX_STAT_CHANGING) | \ + MPLL_USER_SEL_C(MUX_STAT_CHANGING)) + +/* CLK_DIV_CPU0 */ +#define CORE_RATIO(x) ((x) & 0x7) +#define COREM0_RATIO(x) (((x) & 0x7) << 4) +#define COREM1_RATIO(x) (((x) & 0x7) << 8) +#define PERIPH_RATIO(x) (((x) & 0x7) << 12) +#define ATB_RATIO(x) (((x) & 0x7) << 16) +#define PCLK_DBG_RATIO(x) (((x) & 0x7) << 20) +#define APLL_RATIO(x) (((x) & 0x7) << 24) +#define CORE2_RATIO(x) (((x) & 0x7) << 28) + +/* CLK_DIV_STAT_CPU0 */ +#define DIV_CORE(x) ((x) & 0x1) +#define DIV_COREM0(x) (((x) & 0x1) << 4) +#define DIV_COREM1(x) (((x) & 0x1) << 8) +#define DIV_PERIPH(x) (((x) & 0x1) << 12) +#define DIV_ATB(x) (((x) & 0x1) << 16) +#define DIV_PCLK_DBG(x) (((x) & 0x1) << 20) +#define DIV_APLL(x) (((x) & 0x1) << 24) +#define DIV_CORE2(x) (((x) & 0x1) << 28) + +#define DIV_STAT_CHANGING 0x1 +#define DIV_STAT_CPU0_CHANGING (DIV_CORE(DIV_STAT_CHANGING) | \ + DIV_COREM0(DIV_STAT_CHANGING) | \ + DIV_COREM1(DIV_STAT_CHANGING) | \ + DIV_PERIPH(DIV_STAT_CHANGING) | \ + DIV_ATB(DIV_STAT_CHANGING) | \ + DIV_PCLK_DBG(DIV_STAT_CHANGING) | \ + DIV_APLL(DIV_STAT_CHANGING) | \ + DIV_CORE2(DIV_STAT_CHANGING)) + +/* CLK_DIV_CPU1 */ +#define COPY_RATIO(x) ((x) & 0x7) +#define HPM_RATIO(x) (((x) & 0x7) << 4) +#define CORES_RATIO(x) (((x) & 0x7) << 8) + +/* CLK_DIV_STAT_CPU1 */ +#define DIV_COPY(x) ((x) & 0x7) +#define DIV_HPM(x) (((x) & 0x1) << 4) +#define DIV_CORES(x) (((x) & 0x1) << 8) + +#define DIV_STAT_CPU1_CHANGING (DIV_COPY(DIV_STAT_CHANGING) | \ + DIV_HPM(DIV_STAT_CHANGING) | \ + DIV_CORES(DIV_STAT_CHANGING)) + +/* CLK_SRC_DMC */ +#define MUX_C2C_SEL(x) ((x) & 0x1) +#define MUX_DMC_BUS_SEL(x) (((x) & 0x1) << 4) +#define MUX_DPHY_SEL(x) (((x) & 0x1) << 8) +#define MUX_MPLL_SEL(x) (((x) & 0x1) << 12) +#define MUX_PWI_SEL(x) (((x) & 0xf) << 16) +#define MUX_G2D_ACP0_SEL(x) (((x) & 0x1) << 20) +#define MUX_G2D_ACP1_SEL(x) (((x) & 0x1) << 24) +#define MUX_G2D_ACP_SEL(x) (((x) & 0x1) << 28) + +/* CLK_MUX_STAT_DMC */ +#define C2C_SEL(x) (((x)) & 0x7) +#define DMC_BUS_SEL(x) (((x) & 0x7) << 4) +#define DPHY_SEL(x) (((x) & 0x7) << 8) +#define MPLL_SEL(x) (((x) & 0x7) << 12) +/* #define PWI_SEL(x) (((x) & 0xf) << 16) - Reserved */ +#define G2D_ACP0_SEL(x) (((x) & 0x7) << 20) +#define G2D_ACP1_SEL(x) (((x) & 0x7) << 24) +#define G2D_ACP_SEL(x) (((x) & 0x7) << 28) + +#define MUX_STAT_DMC_CHANGING (C2C_SEL(MUX_STAT_CHANGING) | \ + DMC_BUS_SEL(MUX_STAT_CHANGING) | \ + DPHY_SEL(MUX_STAT_CHANGING) | \ + MPLL_SEL(MUX_STAT_CHANGING) |\ + G2D_ACP0_SEL(MUX_STAT_CHANGING) | \ + G2D_ACP1_SEL(MUX_STAT_CHANGING) | \ + G2D_ACP_SEL(MUX_STAT_CHANGING)) + +/* CLK_DIV_DMC0 */ +#define ACP_RATIO(x) ((x) & 0x7) +#define ACP_PCLK_RATIO(x) (((x) & 0x7) << 4) +#define DPHY_RATIO(x) (((x) & 0x7) << 8) +#define DMC_RATIO(x) (((x) & 0x7) << 12) +#define DMCD_RATIO(x) (((x) & 0x7) << 16) +#define DMCP_RATIO(x) (((x) & 0x7) << 20) + +/* CLK_DIV_STAT_DMC0 */ +#define DIV_ACP(x) ((x) & 0x1) +#define DIV_ACP_PCLK(x) (((x) & 0x1) << 4) +#define DIV_DPHY(x) (((x) & 0x1) << 8) +#define DIV_DMC(x) (((x) & 0x1) << 12) +#define DIV_DMCD(x) (((x) & 0x1) << 16) +#define DIV_DMCP(x) (((x) & 0x1) << 20) + +#define DIV_STAT_DMC0_CHANGING (DIV_ACP(DIV_STAT_CHANGING) | \ + DIV_ACP_PCLK(DIV_STAT_CHANGING) | \ + DIV_DPHY(DIV_STAT_CHANGING) | \ + DIV_DMC(DIV_STAT_CHANGING) | \ + DIV_DMCD(DIV_STAT_CHANGING) | \ + DIV_DMCP(DIV_STAT_CHANGING)) + +/* CLK_DIV_DMC1 */ +#define G2D_ACP_RATIO(x) ((x) & 0xf) +#define C2C_RATIO(x) (((x) & 0x7) << 4) +#define PWI_RATIO(x) (((x) & 0xf) << 8) +#define C2C_ACLK_RATIO(x) (((x) & 0x7) << 12) +#define DVSEM_RATIO(x) (((x) & 0x7f) << 16) +#define DPM_RATIO(x) (((x) & 0x7f) << 24) + +/* CLK_DIV_STAT_DMC1 */ +#define DIV_G2D_ACP(x) ((x) & 0x1) +#define DIV_C2C(x) (((x) & 0x1) << 4) +#define DIV_PWI(x) (((x) & 0x1) << 8) +#define DIV_C2C_ACLK(x) (((x) & 0x1) << 12) +#define DIV_DVSEM(x) (((x) & 0x1) << 16) +#define DIV_DPM(x) (((x) & 0x1) << 24) + +#define DIV_STAT_DMC1_CHANGING (DIV_G2D_ACP(DIV_STAT_CHANGING) | \ + DIV_C2C(DIV_STAT_CHANGING) | \ + DIV_PWI(DIV_STAT_CHANGING) | \ + DIV_C2C_ACLK(DIV_STAT_CHANGING) | \ + DIV_DVSEM(DIV_STAT_CHANGING) | \ + DIV_DPM(DIV_STAT_CHANGING)) + +/* Set CLK_SRC_PERIL0 */ +#define UART4_SEL(x) (((x) & 0xf) << 16) +#define UART3_SEL(x) (((x) & 0xf) << 12) +#define UART2_SEL(x) (((x) & 0xf) << 8) +#define UART1_SEL(x) (((x) & 0xf) << 4) +#define UART0_SEL(x) ((x) & 0xf) + +/* Set CLK_DIV_PERIL0 */ +#define UART4_RATIO(x) (((x) & 0xf) << 16) +#define UART3_RATIO(x) (((x) & 0xf) << 12) +#define UART2_RATIO(x) (((x) & 0xf) << 8) +#define UART1_RATIO(x) (((x) & 0xf) << 4) +#define UART0_RATIO(x) ((x) & 0xf) + +/* Set CLK_DIV_STAT_PERIL0 */ +#define DIV_UART4(x) (((x) & 0x1) << 16) +#define DIV_UART3(x) (((x) & 0x1) << 12) +#define DIV_UART2(x) (((x) & 0x1) << 8) +#define DIV_UART1(x) (((x) & 0x1) << 4) +#define DIV_UART0(x) ((x) & 0x1) + +#define DIV_STAT_PERIL0_CHANGING (DIV_UART4(DIV_STAT_CHANGING) | \ + DIV_UART3(DIV_STAT_CHANGING) | \ + DIV_UART2(DIV_STAT_CHANGING) | \ + DIV_UART1(DIV_STAT_CHANGING) | \ + DIV_UART0(DIV_STAT_CHANGING)) + +/* CLK_DIV_FSYS1 */ +#define MMC0_RATIO(x) ((x) & 0xf) +#define MMC0_PRE_RATIO(x) (((x) & 0xff) << 8) +#define MMC1_RATIO(x) (((x) & 0xf) << 16) +#define MMC1_PRE_RATIO(x) (((x) & 0xff) << 24) + +/* CLK_DIV_STAT_FSYS1 */ +#define DIV_MMC0(x) ((x) & 1) +#define DIV_MMC0_PRE(x) (((x) & 1) << 8) +#define DIV_MMC1(x) (((x) & 1) << 16) +#define DIV_MMC1_PRE(x) (((x) & 1) << 24) + +#define DIV_STAT_FSYS1_CHANGING (DIV_MMC0(DIV_STAT_CHANGING) | \ + DIV_MMC0_PRE(DIV_STAT_CHANGING) | \ + DIV_MMC1(DIV_STAT_CHANGING) | \ + DIV_MMC1_PRE(DIV_STAT_CHANGING)) + +/* CLK_DIV_FSYS2 */ +#define MMC2_RATIO(x) ((x) & 0xf) +#define MMC2_PRE_RATIO(x) (((x) & 0xff) << 8) +#define MMC3_RATIO(x) (((x) & 0xf) << 16) +#define MMC3_PRE_RATIO(x) (((x) & 0xff) << 24) + +/* CLK_DIV_STAT_FSYS2 */ +#define DIV_MMC2(x) ((x) & 0x1) +#define DIV_MMC2_PRE(x) (((x) & 0x1) << 8) +#define DIV_MMC3(x) (((x) & 0x1) << 16) +#define DIV_MMC3_PRE(x) (((x) & 0x1) << 24) + +#define DIV_STAT_FSYS2_CHANGING (DIV_MMC2(DIV_STAT_CHANGING) | \ + DIV_MMC2_PRE(DIV_STAT_CHANGING) | \ + DIV_MMC3(DIV_STAT_CHANGING) | \ + DIV_MMC3_PRE(DIV_STAT_CHANGING)) + +/* CLK_DIV_FSYS3 */ +#define MMC4_RATIO(x) ((x) & 0x7) +#define MMC4_PRE_RATIO(x) (((x) & 0xff) << 8) + +/* CLK_DIV_STAT_FSYS3 */ +#define DIV_MMC4(x) ((x) & 0x1) +#define DIV_MMC4_PRE(x) (((x) & 0x1) << 8) + +#define DIV_STAT_FSYS3_CHANGING (DIV_MMC4(DIV_STAT_CHANGING) | \ + DIV_MMC4_PRE(DIV_STAT_CHANGING)) + +/* XCL205 GPIO config - Odroid U3 */ +#define XCL205_GPIO_BASE EXYNOS4X12_GPIO_PART1_BASE +#define XCL205_EN_GPIO_OFFSET 0x20 /* GPA1 */ +#define XCL205_EN_GPIO_PIN 1 +#define XCL205_EN_GPIO_CON (XCL205_GPIO_BASE + \ + XCL205_EN_GPIO_OFFSET) +#define XCL205_EN_GPIO_CON_CFG (S5P_GPIO_OUTPUT << \ + 4 * XCL205_EN_GPIO_PIN) +#define XCL205_EN_GPIO_DAT_CFG (0x1 << XCL205_EN_GPIO_PIN) +#define XCL205_EN_GPIO_PUD_CFG (S5P_GPIO_PULL_UP << \ + 2 * XCL205_EN_GPIO_PIN) +#define XCL205_EN_GPIO_DRV_CFG (S5P_GPIO_DRV_4X << \ + 2 * XCL205_EN_GPIO_PIN) + +#define XCL205_STATE_GPIO_OFFSET 0x80 /* GPC1 */ +#define XCL205_STATE_GPIO_PIN 2 +#define XCL205_STATE_GPIO_CON (XCL205_GPIO_BASE + \ + XCL205_STATE_GPIO_OFFSET) +#define XCL205_STATE_GPIO_DAT XCL205_STATE_GPIO_CON + 0x4 +#define XCL205_STATE_GPIO_CON_CFG (S5P_GPIO_INPUT << \ + 4 * XCL205_STATE_GPIO_PIN) +#define XCL205_STATE_GPIO_PUD_CFG (S5P_GPIO_PULL_NONE << \ + 2 * XCL205_STATE_GPIO_PIN) + +#ifdef CONFIG_BOARD_TYPES +extern void sdelay(unsigned long); +#endif + +#endif /*__ODROIDU3_SETUP__ */

This is a standard description for Odroid boards.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Tom Rini trini@ti.com --- arch/arm/dts/Makefile | 3 +- arch/arm/dts/exynos4412-odroid.dts | 70 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/exynos4412-odroid.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 6e2e313..8bcc69c 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1,7 +1,8 @@ dtb-$(CONFIG_EXYNOS4) += exynos4210-origen.dtb \ exynos4210-universal_c210.dtb \ exynos4210-trats.dtb \ - exynos4412-trats2.dtb + exynos4412-trats2.dtb \ + exynos4412-odroid.dtb
dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \ exynos5250-snow.dtb \ diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts new file mode 100644 index 0000000..24d0bf1 --- /dev/null +++ b/arch/arm/dts/exynos4412-odroid.dts @@ -0,0 +1,70 @@ +/* + * Odroid-U3/X2 board device tree source + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; +/include/ "exynos4.dtsi" + +/ { + model = "Odroid based on Exynos4412"; + compatible = "samsung,odroid", "samsung,exynos4412"; + + aliases { + i2c0 = "/i2c@13860000"; + serial0 = "/serial@13800000"; + console = "/serial@13810000"; + mmc2 = "sdhci@12530000"; + mmc4 = "dwmmc@12550000"; + }; + + i2c@13860000 { + samsung,i2c-sda-delay = <100>; + samsung,i2c-slave-addr = <0x10>; + samsung,i2c-max-bus-freq = <100000>; + status = "okay"; + + max77686_pmic@09 { + compatible = "maxim,max77686_pmic"; + interrupts = <7 0>; + reg = <0x09 0 0>; + #clock-cells = <1>; + }; + }; + + serial@13810000 { + status = "okay"; + }; + + sdhci@12510000 { + status = "disabled"; + }; + + sdhci@12520000 { + status = "disabled"; + }; + + sdhci@12530000 { + samsung,bus-width = <4>; + samsung,timing = <1 2 3>; + cd-gpios = <&gpio 0xC2 0>; + }; + + sdhci@12540000 { + status = "disabled"; + }; + + dwmmc@12550000 { + samsung,bus-width = <8>; + samsung,timing = <2 1 0>; + samsung,removable = <0>; + fifoth_val = <0x203f0040>; + bus_hz = <400000000>; + div = <0x3>; + index = <4>; + }; +};

This config is valid for two devices: - Odroid X2, - Odroid U3.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Tom Rini trini@ti.com
--- Changes v2: - odroid config: add CONFIG_DFU_ALT_BOOTLOADER - odroid config: change name of CONFIG_DFU_BOOT_ALT_* to CONFIG_DFU_ALT_BOOT_*
Changes v3: - odroid.h: update CONFIG_DFU_ALT_BOOT_** with required bootloader binaries - odroid.h: add multi image support (CONFIG_FIT) - odroid.h: add "autoboot" script for multi boot options - odroid.h: change env name: dfu_alt_info -> dfu_alt_system - odroid.h: update config name: CONFIG_SET_DFU_ALT_INFO - odroid.h: reduce boot delay to 0 seconds - update: doc/README.odroid
Changes v5: - odroid.h: default environment cleanup - odroid.h: remove unused definitions - odroid.h: dfu_alt_system update - odroid.h: define CONFIG_SET_DFU_ALT_BUF_LEN to 1k - odroid.h: add init ramdisk support - update: doc/README.odroid
Changes v6: - odroid.h: fix ramdisk load issue --- boards.cfg | 1 + doc/README.odroid | 143 +++++++++++++++++++++++++++++++ include/configs/odroid.h | 216 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 360 insertions(+) create mode 100644 doc/README.odroid create mode 100644 include/configs/odroid.h
diff --git a/boards.cfg b/boards.cfg index 8e2db82..458c500 100644 --- a/boards.cfg +++ b/boards.cfg @@ -293,6 +293,7 @@ Active arm armv7 exynos samsung smdk5420 Active arm armv7 exynos samsung smdkv310 smdkv310 - Chander Kashyap k.chander@samsung.com Active arm armv7 exynos samsung trats trats - Lukasz Majewski l.majewski@samsung.com Active arm armv7 exynos samsung trats2 trats2 - Piotr Wilczek p.wilczek@samsung.com +Active arm armv7 exynos samsung odroid odroid - Przemyslaw Marczak p.marczak@samsung.com Active arm armv7 exynos samsung universal_c210 s5pc210_universal - Przemyslaw Marczak p.marczak@samsung.com Active arm armv7 highbank - highbank highbank - Rob Herring robh@kernel.org Active arm armv7 keystone ti k2hk_evm k2hk_evm - Vitaly Andrianov vitalya@ti.com diff --git a/doc/README.odroid b/doc/README.odroid new file mode 100644 index 0000000..528bb95 --- /dev/null +++ b/doc/README.odroid @@ -0,0 +1,143 @@ + U-boot for Odroid X2/U3 +======================== + +1. Summary +========== +This is a quick instruction for setup Odroid boards based on Exynos4412. +Board config: odroid_config + +2. Supported devices +==================== +This U-BOOT config can be used on two boards: +- Odroid U3 +- Odroid X2 +with CPU Exynos 4412 rev 2.0 and 2GB of RAM + +3. Boot sequence +================ +iROM->BL1->(BL2 + TrustZone)->U-BOOT + +This version of U-BOOT doesn't implement SPL but it is required(BL2) +and can be found in "boot.tar.gz" from here: +http://dev.odroid.com/projects/4412boot/wiki/FrontPage?action=download&v... +or here: +http://odroid.in/guides/ubuntu-lfs/boot.tar.gz + +4. Boot media layout +==================== +The table below shows SD/eMMC cards layout for U-boot. +The block offset is starting from 0 and the block size is 512B. + ------------------------------------- +| Binary | Block offset| part type | +| name | SD | eMMC |(eMMC only)| + ------------------------------------- +| Bl1 | 1 | 0 | 1 (boot) | +| Bl2 | 31 | 30 | 1 (boot) | +| U-boot | 63 | 62 | 1 (boot) | +| Tzsw | 2111 | 2110 | 1 (boot) | +| Uboot Env | 2500 | 2500 | 0 (user) | + ------------------------------------- + +5. Prepare the SD boot card - with SD card reader +================================================= +To prepare bootable media you need boot binaries provided by hardkernel. +File "boot.tar.gz" (link in point 3.) contains: +- E4412_S.bl1.HardKernel.bin +- E4412_S.tzsw.signed.bin +- bl2.signed.bin +- sd_fusing.sh +- u-boot.bin + +This is all you need to boot this board. But if you want to use your custom +u-boot then you need to change u-boot.bin with your own u-boot binary* +and run the script "sd_fusing.sh" - this script is valid only for SD card. + +*note: +The proper binary file of current U-boot is u-boot-dtb.bin. + +quick steps for Linux: +- extract boot.tar.gz +- put any SD card into the SD reader +- check the device with "dmesg" +- run ./sd_fusing.sh /dev/sdX - where X is SD card device (but not a partition) +Check if Hardkernel U-boot is booting, and next do the same with your U-boot. + +6. Prepare the eMMC boot card + with a eMMC card reader (boot from eMMC card slot) +===================================================== +To boot the device from the eMMC slot you should use a special card reader +which supports eMMC partiion switch. All of the boot binaries are stored +on the eMMC boot partition which is normally hidden. + +The "sd_fusing.sh" script can be used after updating offsets of binaries +according to the table from point 4. Be sure that you are working on the right +eMMC partition - its size is usually very small, about 1-4 MiB. + +7. Prepare the eMMC boot card + with a SD card reader (boot from SD card slot) +================================================= +If you have an eMMC->microSD adapter you can prepare the card as in point 5. +But then the device can boot only from the SD card slot. + +8. Prepare the boot media using Hardkernel U-boot +================================================= +You can update the U-boot to the custom one if you have an working bootloader +delivered with the board on a eMMC/SD card. Then follow the steps: +- install the android fastboot tool +- connect a micro usb cable to the board +- on the U-boot prompt, run command: fastboot (as a root) +- on the host, run command: "fastboot flash bootloader u-boot-dtb.bin" +- the custom U-boot should start after the board resets. + +9. Partition layout +==================== +Default U-boot environment is setup for fixed partiion layout. + +Partition table: MSDOS. Disk layout and files as listed in the table below. + ----- ------ ------ ------ -------- --------------------------------- +| Num | Name | FS | Size | Offset | Reguired files | +| | | Type | MiB | MiB | | + ----- ------ ------ ------ -------- --------------------------------- +| 1 | BOOT | fat | 100 | 2 | kernel, fdt** | +| 2 | ROOT | ext4 | - | | any Linux system | + ----- ------ ------ ------ -------- --------------------------------- + +**note: +Supported fdt files are: +- exynos4412-odroidx2.dtb +- exynos4412-odroidu3.dtb + +Supported kernel files are: +- Image.itb +- zImage +- uImage + +The default environmental variable "dfu_alt_info" is set* for above layout. +Each partition size is just an example, dfu_alt_info tries init two partitions. +The size of each is not important. + +*note: +$dfu_alt_info is set on a boot time and it is concatenated using two variables: +- $dfu_alt_boot(set dynamically) +- $dfu_alt_system(from current env). + +To add any changes to dfu_alt_info - please modify $dfu_alt_system only. +Changes are visible after board reset. + +10. The environment and booting the kernel +========================================== +There are three macros defined in config for various boot options: +Two for both, kernel with device tree support and also without it: +- boot_uimg - load uImage +- boot_zimg - load zImage +If proper fdt file exists then it will be automatically loaded, +so for old kernel types, please remove fdt file from boot partition. + +The third boot option for multi image support (more info: doc/uImage.FIT/) +- boot_fit - for binary file: "Image.itb" + +Default boot command: "autoboot" +And the boot sequence is: +- boot_fit - if "Image.itb" exists +- boot_zimg - if "zImage" exists +- boot_uimg - if "uImage" exists diff --git a/include/configs/odroid.h b/include/configs/odroid.h new file mode 100644 index 0000000..29dcc4a --- /dev/null +++ b/include/configs/odroid.h @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * Sanghee Kim sh0130.kim@samsung.com + * Piotr Wilczek p.wilczek@samsung.com + * Przemyslaw Marczak p.marczak@samsung.com + * + * Configuation settings for the Odroid-U3 (EXYNOS4412) board. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_ODROID_U3_H +#define __CONFIG_ODROID_U3_H + +#include <configs/exynos4-dt.h> + +#define CONFIG_SYS_PROMPT "Odroid # " /* Monitor Command Prompt */ + +#undef CONFIG_DEFAULT_DEVICE_TREE +#define CONFIG_DEFAULT_DEVICE_TREE exynos4412-odroid + +#define CONFIG_SYS_L2CACHE_OFF +#ifndef CONFIG_SYS_L2CACHE_OFF +#define CONFIG_SYS_L2_PL310 +#define CONFIG_SYS_PL310_BASE 0x10502000 +#endif + +#define CONFIG_MACH_TYPE 4289 + +#define CONFIG_NR_DRAM_BANKS 8 +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define SDRAM_BANK_SIZE (256 << 20) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE + +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x3E00000) +#define CONFIG_SYS_TEXT_BASE 0x43e00000 + +#include <linux/sizes.h> +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (80 * SZ_1M)) + +/* select serial console configuration */ +#define CONFIG_SERIAL1 +#define CONFIG_BAUDRATE 115200 + +/* Console configuration */ +#define CONFIG_SYS_CONSOLE_INFO_QUIET +#define CONFIG_SYS_CONSOLE_IS_IN_ENV + +#define CONFIG_CMD_BOOTZ +#define CONFIG_FIT +#define CONFIG_FIT_VERBOSE +#define CONFIG_BOOTARGS "Please use defined boot" +#define CONFIG_BOOTCOMMAND "run autoboot" +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR \ + - GENERATED_GBL_DATA_SIZE) + +#define CONFIG_SYS_MEM_TOP_HIDE (SZ_1M) /* ram console */ + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV CONFIG_MMC_DEFAULT_DEV +#define CONFIG_ENV_SIZE 4096 +#define CONFIG_ENV_OFFSET (SZ_1K * 1280) /* 1.25 MiB offset */ +#define CONFIG_ENV_OVERWRITE + +/* Partitions name */ +#define PARTS_BOOT "boot" +#define PARTS_ROOT "platform" + +#define CONFIG_DFU_ALT \ + "uImage fat 0 1;" \ + "zImage fat 0 1;" \ + "Image.itb fat 0 1;" \ + "uInitrd fat 0 1;" \ + "exynos4412-odroidu3.dtb fat 0 1;" \ + "exynos4412-odroidx2.dtb fat 0 1;" \ + ""PARTS_BOOT" part 0 1;" \ + ""PARTS_ROOT" part 0 2\0" \ + +#define CONFIG_SET_DFU_ALT_INFO +#define CONFIG_SET_DFU_ALT_BUF_LEN (SZ_1K) + +#define CONFIG_DFU_ALT_BOOT_EMMC \ + "u-boot raw 0x3e 0x800 mmcpart 1;" \ + "bl1 raw 0x0 0x1e mmcpart 1;" \ + "bl2 raw 0x1e 0x1d mmcpart 1;" \ + "tzsw raw 0x83e 0x138 mmcpart 1\0" + +#define CONFIG_DFU_ALT_BOOT_SD \ + "u-boot raw 0x3f 0x800;" \ + "bl1 raw 0x1 0x1e;" \ + "bl2 raw 0x1f 0x1d;" \ + "tzsw raw 0x83f 0x138\0" + +/* + * Bootable media layout: + * dev: SD eMMC(part boot) + * BL1 1 0 + * BL2 31 30 + * UBOOT 63 62 + * TZSW 2111 2110 + * ENV 2560 2560(part user) + * + * MBR Primary partiions: + * Num Name Size Offset + * 1. BOOT: 100MiB 2MiB + * 2. ROOT: - +*/ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "loadkernel=fatload mmc ${mmcbootdev}:${mmcbootpart} ${kerneladdr} " \ + "${kernelname}\0" \ + "loadinitrd=fatload mmc ${mmcbootdev}:${mmcbootpart} ${initrdaddr} " \ + "${initrdname}\0" \ + "loaddtb=fatload mmc ${mmcbootdev}:${mmcbootpart} ${fdtaddr} " \ + "${fdtfile}\0" \ + "check_ramdisk=" \ + "if run loadinitrd; then " \ + "setenv initrd_addr ${initrdaddr};" \ + "else " \ + "setenv initrd_addr -;" \ + "fi;\0" \ + "check_dtb=" \ + "if run loaddtb; then " \ + "setenv fdt_addr ${fdtaddr};" \ + "else " \ + "setenv fdt_addr;" \ + "fi;\0" \ + "kernel_args=" \ + "setenv bootargs root=/dev/mmcblk${mmcrootdev}p${mmcrootpart}" \ + " rootwait ${console} ${opts}\0" \ + "boot_fit=" \ + "setenv kerneladdr 0x42000000;" \ + "setenv kernelname Image.itb;" \ + "run loadkernel;" \ + "run kernel_args;" \ + "bootm ${kerneladdr}#${boardname}\0" \ + "boot_uimg=" \ + "setenv kerneladdr 0x40007FC0;" \ + "setenv kernelname uImage;" \ + "run check_dtb;" \ + "run check_ramdisk;" \ + "run loadkernel;" \ + "run kernel_args;" \ + "bootm ${kerneladdr} ${initrd_addr} ${fdt_addr};\0" \ + "boot_zimg=" \ + "setenv kerneladdr 0x40007FC0;" \ + "setenv kernelname zImage;" \ + "run check_dtb;" \ + "run check_ramdisk;" \ + "run loadkernel;" \ + "run kernel_args;" \ + "bootz ${kerneladdr} ${initrd_addr} ${fdt_addr};\0" \ + "autoboot=" \ + "if test -e mmc 0 Image.itb; then; " \ + "run boot_fit;" \ + "elif test -e mmc 0 zImage; then; " \ + "run boot_zimg;" \ + "elif test -e mmc 0 uImage; then; " \ + "run boot_uimg;" \ + "fi;\0" \ + "console=" CONFIG_DEFAULT_CONSOLE \ + "mmcbootdev=0\0" \ + "mmcbootpart=1\0" \ + "mmcrootdev=0\0" \ + "mmcrootpart=2\0" \ + "bootdelay=0\0" \ + "dfu_alt_system="CONFIG_DFU_ALT \ + "dfu_alt_info=Please reset the board\0" \ + "consoleon=set console console=ttySAC1,115200n8; save; reset\0" \ + "consoleoff=set console console=ram; save; reset\0" \ + "initrdname=uInitrd\0" \ + "initrdaddr=42000000\0" \ + "fdtaddr=40800000\0" + +/* I2C */ +#define CONFIG_CMD_I2C +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_S3C24X0 +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 +#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0 +#define CONFIG_MAX_I2C_NUM 8 +#define CONFIG_SYS_I2C_INIT_BOARD + +/* POWER */ +#define CONFIG_POWER +#define CONFIG_POWER_I2C +#define CONFIG_POWER_MAX77686 + +/* GPT */ +#define CONFIG_RANDOM_UUID + +/* Security subsystem - enable hw_rand() */ +#define CONFIG_EXYNOS_ACE_SHA +#define CONFIG_LIB_HW_RAND + +#define CONFIG_CMD_GPIO + +/* + * Supported Odroid boards: X3, U3 + * TODO: Add Odroid X support + */ +#define CONFIG_MISC_COMMON +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +#define CONFIG_BOARD_TYPES +#define CONFIG_MISC_INIT_R + +#undef CONFIG_REVISION_TAG + +#endif /* __CONFIG_H */

This patch set introduces changes to common Samsung code as a preparation of new board support: - boot device check - code cleanup - automatic init order of mmc drivers - automatic setting of dfu entities which depends on boot device - pre reset function call for board own implementation - setting board info environment for multi board support
New board config: - odroid_config - Odroid U3/X2 support
V8 changes: - patchset adjust to Kconfig
Przemyslaw Marczak (12): samsung: misc: fix soc revision setting in the set_board_info() exynos: pinmux: fix the gpio names for exynos4x12 mmc arch:exynos: boot mode: add get_boot_mode(), code cleanup board:samsung: check the boot device and init the right mmc driver. samsung: misc: add function for setting $dfu_alt_info samsung:board: misc_init_r: call set_dfu_alt_info() arm:reset: call the reset_misc() before the cpu reset samsung: board: enable support of multiple board types samsung: misc: use board specific functions to set env board info odroid: add board file for Odroid X2/U3 based on Samsung Exynos4412 odroid: add odroid U3/X2 device tree description odroid: kconfig: add odroid_defconfig
arch/arm/cpu/armv7/exynos/Kconfig | 4 + arch/arm/cpu/armv7/exynos/pinmux.c | 4 +- arch/arm/cpu/armv7/exynos/power.c | 7 + arch/arm/cpu/armv7/exynos/spl_boot.c | 7 +- arch/arm/dts/Makefile | 3 +- arch/arm/dts/exynos4412-odroid.dts | 70 +++++ arch/arm/include/asm/arch-exynos/power.h | 21 ++ arch/arm/include/asm/arch-exynos/spl.h | 17 +- arch/arm/lib/reset.c | 6 + board/samsung/common/board.c | 55 +++- board/samsung/common/misc.c | 57 +++- board/samsung/odroid/Kconfig | 15 + board/samsung/odroid/MAINTAINERS | 6 + board/samsung/odroid/Makefile | 8 + board/samsung/odroid/odroid.c | 470 +++++++++++++++++++++++++++++++ board/samsung/odroid/setup.h | 255 +++++++++++++++++ configs/odroid_defconfig | 3 + doc/README.odroid | 143 ++++++++++ include/common.h | 1 + include/configs/odroid.h | 216 ++++++++++++++ include/samsung/misc.h | 10 + 21 files changed, 1337 insertions(+), 41 deletions(-) create mode 100644 arch/arm/dts/exynos4412-odroid.dts create mode 100644 board/samsung/odroid/Kconfig create mode 100644 board/samsung/odroid/MAINTAINERS create mode 100644 board/samsung/odroid/Makefile create mode 100644 board/samsung/odroid/odroid.c create mode 100644 board/samsung/odroid/setup.h create mode 100644 configs/odroid_defconfig create mode 100644 doc/README.odroid create mode 100644 include/configs/odroid.h

The byte order of soc revision was inverted, now it is fixed.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com --- board/samsung/common/misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index 03106fd..a453a82 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -26,8 +26,8 @@ void set_board_info(void) { char info[64];
- snprintf(info, ARRAY_SIZE(info), "%d.%d", s5p_cpu_rev & 0x0f, - (s5p_cpu_rev & 0xf0) >> 0x04); + snprintf(info, ARRAY_SIZE(info), "%u.%u", (s5p_cpu_rev & 0xf0) >> 4, + s5p_cpu_rev & 0xf); setenv("soc_rev", info);
snprintf(info, ARRAY_SIZE(info), "%x", s5p_cpu_id);

This change fixes the bad gpio configuration for the exynos dwmmc.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Beomho Seo beomho.seo@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Jaehoon Chung jh80.chung@samsung.com --- arch/arm/cpu/armv7/exynos/pinmux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index 86a0c75..b929486 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -704,8 +704,8 @@ static int exynos4x12_mmc_config(int peripheral, int flags) ext_func = S5P_GPIO_FUNC(0x3); break; case PERIPH_ID_SDMMC4: - start = EXYNOS4_GPIO_K00; - start_ext = EXYNOS4_GPIO_K13; + start = EXYNOS4X12_GPIO_K00; + start_ext = EXYNOS4X12_GPIO_K13; func = S5P_GPIO_FUNC(0x3); ext_func = S5P_GPIO_FUNC(0x4); break;

This patch introduces code clean-up for exynos boot mode check. It includes: - removal of typedef: boot_mode - move the boot mode enum to arch-exynos/power.h - add bootmode for sequence: eMMC 4.4 ch4 / SD ch2 - add new function: get_boot_mode() for OM[5:1] pin check - update spl boot code
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com
Changes v5: - exynos: boot mode: add missing bootmode (1st:EMMC 4.4 / 2nd:SD ch2)
Changes v6: - none
changes v7: - change boot mode name: BOOT_MODE_MMC to BOOT_MODE_SD --- arch/arm/cpu/armv7/exynos/power.c | 7 +++++++ arch/arm/cpu/armv7/exynos/spl_boot.c | 7 +++---- arch/arm/include/asm/arch-exynos/power.h | 21 +++++++++++++++++++++ arch/arm/include/asm/arch-exynos/spl.h | 17 ++--------------- 4 files changed, 33 insertions(+), 19 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c index 638ee0b..e1ab3d6 100644 --- a/arch/arm/cpu/armv7/exynos/power.c +++ b/arch/arm/cpu/armv7/exynos/power.c @@ -202,3 +202,10 @@ void power_exit_wakeup(void) else exynos4_power_exit_wakeup(); } + +unsigned int get_boot_mode(void) +{ + unsigned int om_pin = samsung_get_base_power(); + + return readl(om_pin) & OM_PIN_MASK; +} diff --git a/arch/arm/cpu/armv7/exynos/spl_boot.c b/arch/arm/cpu/armv7/exynos/spl_boot.c index 7916630..658e4cb 100644 --- a/arch/arm/cpu/armv7/exynos/spl_boot.c +++ b/arch/arm/cpu/armv7/exynos/spl_boot.c @@ -20,7 +20,6 @@ #include "clock_init.h"
DECLARE_GLOBAL_DATA_PTR; -#define OM_STAT (0x1f << 1)
/* Index into irom ptr table */ enum index { @@ -184,7 +183,7 @@ static void exynos_spi_copy(unsigned int uboot_size, unsigned int uboot_addr) */ void copy_uboot_to_ram(void) { - enum boot_mode bootmode = BOOT_MODE_OM; + unsigned int bootmode = BOOT_MODE_OM;
u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst) = NULL; u32 offset = 0, size = 0; @@ -207,7 +206,7 @@ void copy_uboot_to_ram(void) #endif
if (bootmode == BOOT_MODE_OM) - bootmode = readl(samsung_get_base_power()) & OM_STAT; + bootmode = get_boot_mode();
switch (bootmode) { #ifdef CONFIG_SPI_BOOTING @@ -216,7 +215,7 @@ void copy_uboot_to_ram(void) exynos_spi_copy(param->uboot_size, CONFIG_SYS_TEXT_BASE); break; #endif - case BOOT_MODE_MMC: + case BOOT_MODE_SD: offset = BL2_START_OFFSET; size = BL2_SIZE_BLOC_COUNT; copy_bl2 = get_irom_func(MMC_INDEX); diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h index 4f2447b..e8a98a5 100644 --- a/arch/arm/include/asm/arch-exynos/power.h +++ b/arch/arm/include/asm/arch-exynos/power.h @@ -1670,6 +1670,27 @@ struct exynos5420_power { }; #endif /* __ASSEMBLY__ */
+#define OM_PIN_BITS 0x1f +#define OM_PIN_SHIFT 0x1 +#define OM_PIN_MASK (OM_PIN_BITS << OM_PIN_SHIFT) + +enum { + /* + * Assign the OM pin values for respective boot modes. + * Exynos4 does not support spi boot and the mmc boot OM + * pin values are the same across Exynos4 and Exynos5. + */ + BOOT_MODE_SD = 4, /* SD_CH2 | USB */ + BOOT_MODE_EMMC = 8, /* EMMC4.4 | USB */ + BOOT_MODE_EMMC_SD = 40, /* EMMC4.4 | SD_CH2 */ + BOOT_MODE_SERIAL = 20, + /* Boot based on Operating Mode pin settings */ + BOOT_MODE_OM = 32, + BOOT_MODE_USB, /* Boot using USB download */ +}; + +unsigned int get_boot_mode(void); + void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable);
#define EXYNOS_MIPI_PHY_ENABLE (1 << 0) diff --git a/arch/arm/include/asm/arch-exynos/spl.h b/arch/arm/include/asm/arch-exynos/spl.h index b1d68c3..cdcb2bc 100644 --- a/arch/arm/include/asm/arch-exynos/spl.h +++ b/arch/arm/include/asm/arch-exynos/spl.h @@ -8,20 +8,7 @@ #define __ASM_ARCH_EXYNOS_SPL_H__
#include <asm/arch-exynos/dmc.h> - -enum boot_mode { - /* - * Assign the OM pin values for respective boot modes. - * Exynos4 does not support spi boot and the mmc boot OM - * pin values are the same across Exynos4 and Exynos5. - */ - BOOT_MODE_MMC = 4, - BOOT_MODE_EMMC = 8, /* EMMC4.4 */ - BOOT_MODE_SERIAL = 20, - /* Boot based on Operating Mode pin settings */ - BOOT_MODE_OM = 32, - BOOT_MODE_USB, /* Boot using USB download */ -}; +#include <asm/arch/power.h>
#ifndef __ASSEMBLY__ /* Parameters of early board initialization in SPL */ @@ -62,7 +49,7 @@ struct spl_machine_param { * table only for mmc boot. */ u32 uboot_size; - enum boot_mode boot_source; /* Boot device */ + unsigned boot_source; /* Boot device */ unsigned frequency_mhz; /* Frequency of memory in MHz */ unsigned arm_freq_mhz; /* ARM Frequency in MHz */ u32 serial_base; /* Serial base address */

It is possible to boot device using a micro SD or eMMC slots. In this situation, boot device should be registered as a block device 0 in the MMC framework, because CONFIG_SYS_MMC_ENV_DEV is usually set to "0" in the most config cases.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com --- Changes V3: - separate two changes into two commits
Changes V4: - board.c: add functions: init_mmc() and init_dwmmc() - board_mmc_init(): call get_boot_mode()
Changes V5: - none
Changes V6: - update boot mode name --- board/samsung/common/board.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index 9dc7c83..1fa0e51 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -240,22 +240,39 @@ int board_eth_init(bd_t *bis) }
#ifdef CONFIG_GENERIC_MMC -int board_mmc_init(bd_t *bis) +static int init_mmc(void) +{ +#ifdef CONFIG_SDHCI + return exynos_mmc_init(gd->fdt_blob); +#else + return 0; +#endif +} + +static int init_dwmmc(void) { - int ret; #ifdef CONFIG_DWMMC - /* dwmmc initializattion for available channels */ - ret = exynos_dwmmc_init(gd->fdt_blob); - if (ret) - debug("dwmmc init failed\n"); + return exynos_dwmmc_init(gd->fdt_blob); +#else + return 0; #endif +} + +int board_mmc_init(bd_t *bis) +{ + int ret; + + if (get_boot_mode() == BOOT_MODE_SD) { + ret = init_mmc(); + ret |= init_dwmmc(); + } else { + ret = init_dwmmc(); + ret |= init_mmc(); + }
-#ifdef CONFIG_SDHCI - /* mmc initializattion for available channels */ - ret = exynos_mmc_init(gd->fdt_blob); if (ret) debug("mmc init failed\n"); -#endif + return ret; } #endif

This change introduces new common function: - set_dfu_alt_info() - put dfu system and bootloader setting into $dfu_alt_info. functions declaration: - char *get_dfu_alt_system(void) - char *get_dfu_alt_boot(void) - void set_dfu_alt_info(void) and new config: - CONFIG_SET_DFU_ALT_INFO
This function can be used for auto setting dfu configuration on boot. Such feature is useful for multi board support by one u-boot binary. Each board should define two functions: - get_dfu_alt_system() - get_dfu_alt_boot()
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v2: - change config names: CONFIG_SET_DFU_BOOT_ALT to CONFIG_DFU_ALT_BOOTLOADER and CONFIG_DFU_BOOT_ALT_* to CONFIG_DFU_ALT_BOOT_* - change function name: set_dfu_boot_alt() to set_dfu_alt_boot() - remove superfluous ifdefs
Changes v3: - set $dfu_alt_info at every boot - new config: CONFIG_SET_DFU_ALT_INFO - update commit msg
Changes v4: - set_dfu_alt_info(): add checking the pointer returned by malloc
Changes v5: - set_dfu_alt_info(): remove malloc and declare cache aligned buffer - set_dfu_alt_info(): introduce CONFIG_SET_DFU_ALT_BUF_LEN --- board/samsung/common/misc.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/samsung/misc.h | 6 ++++++ 2 files changed, 47 insertions(+)
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index a453a82..9e52452 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -11,6 +11,7 @@ #include <samsung/misc.h> #include <errno.h> #include <version.h> +#include <malloc.h> #include <linux/sizes.h> #include <asm/arch/cpu.h> #include <asm/arch/gpio.h> @@ -21,6 +22,46 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_SET_DFU_ALT_INFO +void set_dfu_alt_info(void) +{ + size_t buf_size = CONFIG_SET_DFU_ALT_BUF_LEN; + ALLOC_CACHE_ALIGN_BUFFER(char, buf, buf_size); + char *alt_info = "Settings not found!"; + char *status = "error!\n"; + char *alt_setting; + char *alt_sep; + int offset = 0; + + puts("DFU alt info setting: "); + + alt_setting = get_dfu_alt_boot(); + if (alt_setting) { + setenv("dfu_alt_boot", alt_setting); + offset = snprintf(buf, buf_size, "%s", alt_setting); + } + + alt_setting = get_dfu_alt_system(); + if (alt_setting) { + if (offset) + alt_sep = ";"; + else + alt_sep = ""; + + offset += snprintf(buf + offset, buf_size - offset, + "%s%s", alt_sep, alt_setting); + } + + if (offset) { + alt_info = buf; + status = "done\n"; + } + + setenv("dfu_alt_info", alt_info); + puts(status); +} +#endif + #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG void set_board_info(void) { diff --git a/include/samsung/misc.h b/include/samsung/misc.h index 10653a1..e82bf32 100644 --- a/include/samsung/misc.h +++ b/include/samsung/misc.h @@ -28,4 +28,10 @@ void check_boot_mode(void); void draw_logo(void); #endif
+#ifdef CONFIG_SET_DFU_ALT_INFO +char *get_dfu_alt_system(void); +char *get_dfu_alt_boot(void); +void set_dfu_alt_info(void); +#endif + #endif /* __SAMSUNG_MISC_COMMON_H__ */

This change enable automatic setting of dfu alt info on every boot. This is useful in case of booting one u-boot binary from multiple media.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com --- board/samsung/common/board.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index 1fa0e51..5693813 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -324,6 +324,9 @@ int arch_early_init_r(void) #ifdef CONFIG_MISC_INIT_R int misc_init_r(void) { +#ifdef CONFIG_SET_DFU_ALT_INFO + set_dfu_alt_info(); +#endif #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG set_board_info(); #endif

On an Odroid U3 board, the SOC is unable to reset the eMMC card in the DWMMC mode by the cpu software reset. Manual reset of the card by switching proper gpio pin - fixes this issue.
Such solution needs to add a call to pre reset function. This is done by the reset_misc() function, which is called before reset_cpu(). The function reset_misc() is a weak function.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Jean-Christophe PLAGNIOL-VILLARD plagnioj@jcrosoft.com Cc: Albert ARIBAUD albert.u.boot@aribaud.net Cc: Tom Rini trini@ti.com
Changes v4: - arch/arm/reset: fix weak function attribute to proper style --- arch/arm/lib/reset.c | 6 ++++++ include/common.h | 1 + 2 files changed, 7 insertions(+)
diff --git a/arch/arm/lib/reset.c b/arch/arm/lib/reset.c index 7a03580..9a95f08 100644 --- a/arch/arm/lib/reset.c +++ b/arch/arm/lib/reset.c @@ -23,6 +23,10 @@
#include <common.h>
+__weak void reset_misc(void) +{ +} + int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { puts ("resetting ...\n"); @@ -30,6 +34,8 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) udelay (50000); /* wait 50 ms */
disable_interrupts(); + + reset_misc(); reset_cpu(0);
/*NOTREACHED*/ diff --git a/include/common.h b/include/common.h index c7e51ca..97c04df 100644 --- a/include/common.h +++ b/include/common.h @@ -616,6 +616,7 @@ int checkicache (void); int checkdcache (void); void upmconfig (unsigned int, unsigned int *, unsigned int); ulong get_tbclk (void); +void reset_misc (void); void reset_cpu (ulong addr); #if defined (CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP) void ft_cpu_setup(void *blob, bd_t *bd);

This change adds declaration of functions: - set_board_type() - called at board_early_init_f() - get_board_type() - called at checkboard()
For supporting multiple board types in a one config - it is welcome to display the current board model. This is what get_board_type() should return.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v3: - change the commit order - include/samsung/misc.h: add new functions declaration - update a commit message
Changes v4: - checkboard(): remove redundant variable
Changes v5: - board.c: move call to set_board_type() into board_early_init_f() - misc.h: remove get_board_name() function declaration --- board/samsung/common/board.c | 15 ++++++++++----- include/samsung/misc.h | 4 ++++ 2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index 5693813..3d1cf43 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -137,7 +137,9 @@ static int board_uart_init(void) int board_early_init_f(void) { int err; - +#ifdef CONFIG_BOARD_TYPES + set_board_type(); +#endif err = board_uart_init(); if (err) { debug("UART init failed\n"); @@ -147,7 +149,6 @@ int board_early_init_f(void) #ifdef CONFIG_SYS_I2C_INIT_BOARD board_i2c_init(gd->fdt_blob); #endif - return exynos_early_init_f(); } #endif @@ -280,11 +281,15 @@ int board_mmc_init(bd_t *bis) #ifdef CONFIG_DISPLAY_BOARDINFO int checkboard(void) { - const char *board_name; + const char *board_info;
- board_name = fdt_getprop(gd->fdt_blob, 0, "model", NULL); - printf("Board: %s\n", board_name ? board_name : "unknown"); + board_info = fdt_getprop(gd->fdt_blob, 0, "model", NULL); + printf("Board: %s\n", board_info ? board_info : "unknown"); +#ifdef CONFIG_BOARD_TYPES + board_info = get_board_type();
+ printf("Model: %s\n", board_info ? board_info : "unknown"); +#endif return 0; } #endif diff --git a/include/samsung/misc.h b/include/samsung/misc.h index e82bf32..607e8d4 100644 --- a/include/samsung/misc.h +++ b/include/samsung/misc.h @@ -33,5 +33,9 @@ char *get_dfu_alt_system(void); char *get_dfu_alt_boot(void); void set_dfu_alt_info(void); #endif +#ifdef CONFIG_BOARD_TYPES +void set_board_type(void); +const char *get_board_type(void); +#endif
#endif /* __SAMSUNG_MISC_COMMON_H__ */

This change adds setup of environmental board info using get_board_name() and get_board_type() functions for config CONFIG_BOARD_TYPES.
This is useful in case of running many boards with just one config.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com
--- Changes v2: - set_board_info: move the bdtype pointer to avoid unused pointer compilation warning
Changes v3: - samsung: misc: change get_board_type_fdt() to get_board_type() - samsung: misc: set env $boardname using get_board_* functions for CONFIG_BOARD_TYPES - update commit msg
Changes v5: - misc.c: set_bard_info(): remove a call to get_board_name() --- board/samsung/common/misc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c index 9e52452..8766f0c 100644 --- a/board/samsung/common/misc.c +++ b/board/samsung/common/misc.c @@ -79,8 +79,16 @@ void set_board_info(void) setenv("board_rev", info); #endif #ifdef CONFIG_OF_LIBFDT - snprintf(info, ARRAY_SIZE(info), "%s%x-%s.dtb", - CONFIG_SYS_SOC, s5p_cpu_id, CONFIG_SYS_BOARD); + const char *bdtype = ""; + const char *bdname = CONFIG_SYS_BOARD; + +#ifdef CONFIG_BOARD_TYPES + bdtype = get_board_type(); + sprintf(info, "%s%s", bdname, bdtype); + setenv("boardname", info); +#endif + snprintf(info, ARRAY_SIZE(info), "%s%x-%s%s.dtb", + CONFIG_SYS_SOC, s5p_cpu_id, bdname, bdtype); setenv("fdtfile", info); #endif }

This board file supports standard features of Odroid X2 and U3 boards: - Exynos4412 core clock set to 1000MHz and MPLL peripherial clock set to 800MHz, - MAX77686 power regulator, - USB PHY, - enable XCL205 - power for board peripherials - check board type: U3 or X2. - enable Odroid U3 FAN cooler
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Tom Rini trini@ti.com
--- Changes v2: - enable fan on odroid U3
Changes v3: - odroid.c: clean up board name related code - odroid.c: remove static from set_board_type() - odroid.c: add implementation of functions: get_dfu_alt_* - odroid.c: include misc.h
Changes v4: - odroid.c: dfu_get_alt_boot: add call get_boot_mode()
Changes v5: - odroid.c: set_board_type: change mdelay to sdelay, define XCL205 GPIO config - odroid.c: board_gpio_init(): fix OTG for Odroid U3+ - odroid.c: reserve the last 1 MB of dram for secure firmware - odroid.c: board_clock_init(): code cleanup - odroid.c: get_dfu_alt_boot(): remove setenv() - odroid.c: remove get_board_name() function definition - odroid.c: add enum ODROID_TYPES --- board/samsung/odroid/Makefile | 8 + board/samsung/odroid/odroid.c | 470 ++++++++++++++++++++++++++++++++++++++++++ board/samsung/odroid/setup.h | 255 +++++++++++++++++++++++ 3 files changed, 733 insertions(+) create mode 100644 board/samsung/odroid/Makefile create mode 100644 board/samsung/odroid/odroid.c create mode 100644 board/samsung/odroid/setup.h
diff --git a/board/samsung/odroid/Makefile b/board/samsung/odroid/Makefile new file mode 100644 index 0000000..b98aaeb --- /dev/null +++ b/board/samsung/odroid/Makefile @@ -0,0 +1,8 @@ +# +# Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved. +# Przemyslaw Marczak p.marczak@samsung.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := odroid.o diff --git a/board/samsung/odroid/odroid.c b/board/samsung/odroid/odroid.c new file mode 100644 index 0000000..ac19527 --- /dev/null +++ b/board/samsung/odroid/odroid.c @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * Przemyslaw Marczak p.marczak@samsung.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/power.h> +#include <asm/arch/clock.h> +#include <asm/arch/gpio.h> +#include <asm/gpio.h> +#include <asm/arch/cpu.h> +#include <power/pmic.h> +#include <power/max77686_pmic.h> +#include <errno.h> +#include <usb.h> +#include <usb/s3c_udc.h> +#include <samsung/misc.h> +#include "setup.h" + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_BOARD_TYPES +/* Odroid board types */ +enum { + ODROID_TYPE_U3, + ODROID_TYPE_X2, + ODROID_TYPES, +}; + +void set_board_type(void) +{ + /* Set GPA1 pin 1 to HI - enable XCL205 output */ + writel(XCL205_EN_GPIO_CON_CFG, XCL205_EN_GPIO_CON); + writel(XCL205_EN_GPIO_DAT_CFG, XCL205_EN_GPIO_CON + 0x4); + writel(XCL205_EN_GPIO_PUD_CFG, XCL205_EN_GPIO_CON + 0x8); + writel(XCL205_EN_GPIO_DRV_CFG, XCL205_EN_GPIO_CON + 0xc); + + /* Set GPC1 pin 2 to IN - check XCL205 output state */ + writel(XCL205_STATE_GPIO_CON_CFG, XCL205_STATE_GPIO_CON); + writel(XCL205_STATE_GPIO_PUD_CFG, XCL205_STATE_GPIO_CON + 0x8); + + /* XCL205 - needs some latch time */ + sdelay(200000); + + /* Check GPC1 pin2 - LED supplied by XCL205 - X2 only */ + if (readl(XCL205_STATE_GPIO_DAT) & (1 << XCL205_STATE_GPIO_PIN)) + gd->board_type = ODROID_TYPE_X2; + else + gd->board_type = ODROID_TYPE_U3; +} + +const char *get_board_type(void) +{ + const char *board_type[] = {"u3", "x2"}; + + return board_type[gd->board_type]; +} +#endif + +#ifdef CONFIG_SET_DFU_ALT_INFO +char *get_dfu_alt_system(void) +{ + return getenv("dfu_alt_system"); +} + +char *get_dfu_alt_boot(void) +{ + char *alt_boot; + + switch (get_boot_mode()) { + case BOOT_MODE_SD: + alt_boot = CONFIG_DFU_ALT_BOOT_SD; + break; + case BOOT_MODE_EMMC: + case BOOT_MODE_EMMC_SD: + alt_boot = CONFIG_DFU_ALT_BOOT_EMMC; + break; + default: + alt_boot = NULL; + break; + } + return alt_boot; +} +#endif + +static void board_clock_init(void) +{ + unsigned int set, clr, clr_src_cpu, clr_pll_con0, clr_src_dmc; + struct exynos4x12_clock *clk = (struct exynos4x12_clock *) + samsung_get_base_clock(); + + /* + * CMU_CPU clocks src to MPLL + * Bit values: 0 ; 1 + * MUX_APLL_SEL: FIN_PLL ; FOUT_APLL + * MUX_CORE_SEL: MOUT_APLL ; SCLK_MPLL + * MUX_HPM_SEL: MOUT_APLL ; SCLK_MPLL_USER_C + * MUX_MPLL_USER_SEL_C: FIN_PLL ; SCLK_MPLL + */ + clr_src_cpu = MUX_APLL_SEL(1) | MUX_CORE_SEL(1) | + MUX_HPM_SEL(1) | MUX_MPLL_USER_SEL_C(1); + set = MUX_APLL_SEL(0) | MUX_CORE_SEL(1) | MUX_HPM_SEL(1) | + MUX_MPLL_USER_SEL_C(1); + + clrsetbits_le32(&clk->src_cpu, clr_src_cpu, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_cpu) & MUX_STAT_CPU_CHANGING) + continue; + + /* Set APLL to 1000MHz */ + clr_pll_con0 = SDIV(7) | PDIV(63) | MDIV(1023) | FSEL(1); + set = SDIV(0) | PDIV(3) | MDIV(125) | FSEL(1); + + clrsetbits_le32(&clk->apll_con0, clr_pll_con0, set); + + /* Wait for PLL to be locked */ + while (!(readl(&clk->apll_con0) & PLL_LOCKED_BIT)) + continue; + + /* Set CMU_CPU clocks src to APLL */ + set = MUX_APLL_SEL(1) | MUX_CORE_SEL(0) | MUX_HPM_SEL(0) | + MUX_MPLL_USER_SEL_C(1); + clrsetbits_le32(&clk->src_cpu, clr_src_cpu, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_cpu) & MUX_STAT_CPU_CHANGING) + continue; + + set = CORE_RATIO(0) | COREM0_RATIO(2) | COREM1_RATIO(5) | + PERIPH_RATIO(0) | ATB_RATIO(4) | PCLK_DBG_RATIO(1) | + APLL_RATIO(0) | CORE2_RATIO(0); + /* + * Set dividers for MOUTcore = 1000 MHz + * coreout = MOUT / (ratio + 1) = 1000 MHz (0) + * corem0 = armclk / (ratio + 1) = 333 MHz (2) + * corem1 = armclk / (ratio + 1) = 166 MHz (5) + * periph = armclk / (ratio + 1) = 1000 MHz (0) + * atbout = MOUT / (ratio + 1) = 200 MHz (4) + * pclkdbgout = atbout / (ratio + 1) = 100 MHz (1) + * sclkapll = MOUTapll / (ratio + 1) = 1000 MHz (0) + * core2out = core_out / (ratio + 1) = 1000 MHz (0) (armclk) + */ + clr = CORE_RATIO(7) | COREM0_RATIO(7) | COREM1_RATIO(7) | + PERIPH_RATIO(7) | ATB_RATIO(7) | PCLK_DBG_RATIO(7) | + APLL_RATIO(7) | CORE2_RATIO(7); + + clrsetbits_le32(&clk->div_cpu0, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_cpu0) & DIV_STAT_CPU0_CHANGING) + continue; + + /* + * For MOUThpm = 1000 MHz (MOUTapll) + * doutcopy = MOUThpm / (ratio + 1) = 200 (4) + * sclkhpm = doutcopy / (ratio + 1) = 200 (4) + * cores_out = armclk / (ratio + 1) = 1000 (0) + */ + clr = COPY_RATIO(7) | HPM_RATIO(7) | CORES_RATIO(7); + set = COPY_RATIO(4) | HPM_RATIO(4) | CORES_RATIO(0); + + clrsetbits_le32(&clk->div_cpu1, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_cpu1) & DIV_STAT_CPU1_CHANGING) + continue; + + /* + * Set CMU_DMC clocks src to APLL + * Bit values: 0 ; 1 + * MUX_C2C_SEL: SCLKMPLL ; SCLKAPLL + * MUX_DMC_BUS_SEL: SCLKMPLL ; SCLKAPLL + * MUX_DPHY_SEL: SCLKMPLL ; SCLKAPLL + * MUX_MPLL_SEL: FINPLL ; MOUT_MPLL_FOUT + * MUX_PWI_SEL: 0110 (MPLL); 0111 (EPLL); 1000 (VPLL); 0(XXTI) + * MUX_G2D_ACP0_SEL: SCLKMPLL ; SCLKAPLL + * MUX_G2D_ACP1_SEL: SCLKEPLL ; SCLKVPLL + * MUX_G2D_ACP_SEL: OUT_ACP0 ; OUT_ACP1 + */ + clr_src_dmc = MUX_C2C_SEL(1) | MUX_DMC_BUS_SEL(1) | + MUX_DPHY_SEL(1) | MUX_MPLL_SEL(1) | + MUX_PWI_SEL(15) | MUX_G2D_ACP0_SEL(1) | + MUX_G2D_ACP1_SEL(1) | MUX_G2D_ACP_SEL(1); + set = MUX_C2C_SEL(1) | MUX_DMC_BUS_SEL(1) | MUX_DPHY_SEL(1) | + MUX_MPLL_SEL(0) | MUX_PWI_SEL(0) | MUX_G2D_ACP0_SEL(1) | + MUX_G2D_ACP1_SEL(1) | MUX_G2D_ACP_SEL(1); + + clrsetbits_le32(&clk->src_dmc, clr_src_dmc, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_dmc) & MUX_STAT_DMC_CHANGING) + continue; + + /* Set MPLL to 800MHz */ + set = SDIV(0) | PDIV(3) | MDIV(100) | FSEL(0) | PLL_ENABLE(1); + + clrsetbits_le32(&clk->mpll_con0, clr_pll_con0, set); + + /* Wait for PLL to be locked */ + while (!(readl(&clk->mpll_con0) & PLL_LOCKED_BIT)) + continue; + + /* Switch back CMU_DMC mux */ + set = MUX_C2C_SEL(0) | MUX_DMC_BUS_SEL(0) | MUX_DPHY_SEL(0) | + MUX_MPLL_SEL(1) | MUX_PWI_SEL(8) | MUX_G2D_ACP0_SEL(0) | + MUX_G2D_ACP1_SEL(0) | MUX_G2D_ACP_SEL(0); + + clrsetbits_le32(&clk->src_dmc, clr_src_dmc, set); + + /* Wait for mux change */ + while (readl(&clk->mux_stat_dmc) & MUX_STAT_DMC_CHANGING) + continue; + + /* CLK_DIV_DMC0 */ + clr = ACP_RATIO(7) | ACP_PCLK_RATIO(7) | DPHY_RATIO(7) | + DMC_RATIO(7) | DMCD_RATIO(7) | DMCP_RATIO(7); + /* + * For: + * MOUTdmc = 800 MHz + * MOUTdphy = 800 MHz + * + * aclk_acp = MOUTdmc / (ratio + 1) = 200 (3) + * pclk_acp = aclk_acp / (ratio + 1) = 100 (1) + * sclk_dphy = MOUTdphy / (ratio + 1) = 400 (1) + * sclk_dmc = MOUTdmc / (ratio + 1) = 400 (1) + * aclk_dmcd = sclk_dmc / (ratio + 1) = 200 (1) + * aclk_dmcp = aclk_dmcd / (ratio + 1) = 100 (1) + */ + set = ACP_RATIO(3) | ACP_PCLK_RATIO(1) | DPHY_RATIO(1) | + DMC_RATIO(1) | DMCD_RATIO(1) | DMCP_RATIO(1); + + clrsetbits_le32(&clk->div_dmc0, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_dmc0) & DIV_STAT_DMC0_CHANGING) + continue; + + /* CLK_DIV_DMC1 */ + clr = G2D_ACP_RATIO(15) | C2C_RATIO(7) | PWI_RATIO(15) | + C2C_ACLK_RATIO(7) | DVSEM_RATIO(127) | DPM_RATIO(127); + /* + * For: + * MOUTg2d = 800 MHz + * MOUTc2c = 800 Mhz + * MOUTpwi = 108 MHz + * + * sclk_g2d_acp = MOUTg2d / (ratio + 1) = 400 (1) + * sclk_c2c = MOUTc2c / (ratio + 1) = 400 (1) + * aclk_c2c = sclk_c2c / (ratio + 1) = 200 (1) + * sclk_pwi = MOUTpwi / (ratio + 1) = 18 (5) + */ + set = G2D_ACP_RATIO(1) | C2C_RATIO(1) | PWI_RATIO(5) | + C2C_ACLK_RATIO(1) | DVSEM_RATIO(1) | DPM_RATIO(1); + + clrsetbits_le32(&clk->div_dmc1, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_dmc1) & DIV_STAT_DMC1_CHANGING) + continue; + + /* CLK_SRC_PERIL0 */ + clr = UART0_SEL(15) | UART1_SEL(15) | UART2_SEL(15) | + UART3_SEL(15) | UART4_SEL(15); + /* + * Set CLK_SRC_PERIL0 clocks src to MPLL + * src values: 0(XXTI); 1(XusbXTI); 2(SCLK_HDMI24M); 3(SCLK_USBPHY0); + * 5(SCLK_HDMIPHY); 6(SCLK_MPLL_USER_T); 7(SCLK_EPLL); + * 8(SCLK_VPLL) + * + * Set all to SCLK_MPLL_USER_T + */ + set = UART0_SEL(6) | UART1_SEL(6) | UART2_SEL(6) | UART3_SEL(6) | + UART4_SEL(6); + + clrsetbits_le32(&clk->src_peril0, clr, set); + + /* CLK_DIV_PERIL0 */ + clr = UART0_RATIO(15) | UART1_RATIO(15) | UART2_RATIO(15) | + UART3_RATIO(15) | UART4_RATIO(15); + /* + * For MOUTuart0-4: 800MHz + * + * SCLK_UARTx = MOUTuartX / (ratio + 1) = 100 (7) + */ + set = UART0_RATIO(7) | UART1_RATIO(7) | UART2_RATIO(7) | + UART3_RATIO(7) | UART4_RATIO(7); + + clrsetbits_le32(&clk->div_peril0, clr, set); + + while (readl(&clk->div_stat_peril0) & DIV_STAT_PERIL0_CHANGING) + continue; + + /* CLK_DIV_FSYS1 */ + clr = MMC0_RATIO(15) | MMC0_PRE_RATIO(255) | MMC1_RATIO(15) | + MMC1_PRE_RATIO(255); + /* + * For MOUTmmc0-3 = 800 MHz (MPLL) + * + * DOUTmmc1 = MOUTmmc1 / (ratio + 1) = 100 (7) + * sclk_mmc1 = DOUTmmc1 / (ratio + 1) = 50 (1) + * DOUTmmc0 = MOUTmmc0 / (ratio + 1) = 100 (7) + * sclk_mmc0 = DOUTmmc0 / (ratio + 1) = 50 (1) + */ + set = MMC0_RATIO(7) | MMC0_PRE_RATIO(1) | MMC1_RATIO(7) | + MMC1_PRE_RATIO(1); + + clrsetbits_le32(&clk->div_fsys1, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_fsys1) & DIV_STAT_FSYS1_CHANGING) + continue; + + /* CLK_DIV_FSYS2 */ + clr = MMC2_RATIO(15) | MMC2_PRE_RATIO(255) | MMC3_RATIO(15) | + MMC3_PRE_RATIO(255); + /* + * For MOUTmmc0-3 = 800 MHz (MPLL) + * + * DOUTmmc3 = MOUTmmc3 / (ratio + 1) = 100 (7) + * sclk_mmc3 = DOUTmmc3 / (ratio + 1) = 50 (1) + * DOUTmmc2 = MOUTmmc2 / (ratio + 1) = 100 (7) + * sclk_mmc2 = DOUTmmc2 / (ratio + 1) = 50 (1) + */ + set = MMC2_RATIO(7) | MMC2_PRE_RATIO(1) | MMC3_RATIO(7) | + MMC3_PRE_RATIO(1); + + clrsetbits_le32(&clk->div_fsys2, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_fsys2) & DIV_STAT_FSYS2_CHANGING) + continue; + + /* CLK_DIV_FSYS3 */ + clr = MMC4_RATIO(15) | MMC4_PRE_RATIO(255); + /* + * For MOUTmmc4 = 800 MHz (MPLL) + * + * DOUTmmc4 = MOUTmmc4 / (ratio + 1) = 100 (7) + * sclk_mmc4 = DOUTmmc4 / (ratio + 1) = 100 (0) + */ + set = MMC4_RATIO(7) | MMC4_PRE_RATIO(0); + + clrsetbits_le32(&clk->div_fsys3, clr, set); + + /* Wait for divider ready status */ + while (readl(&clk->div_stat_fsys3) & DIV_STAT_FSYS3_CHANGING) + continue; + + return; +} + +static void board_gpio_init(void) +{ + /* eMMC Reset Pin */ + gpio_cfg_pin(EXYNOS4X12_GPIO_K12, S5P_GPIO_FUNC(0x1)); + gpio_set_pull(EXYNOS4X12_GPIO_K12, S5P_GPIO_PULL_NONE); + gpio_set_drv(EXYNOS4X12_GPIO_K12, S5P_GPIO_DRV_4X); + + /* Enable FAN (Odroid U3) */ + gpio_set_pull(EXYNOS4X12_GPIO_D00, S5P_GPIO_PULL_UP); + gpio_set_drv(EXYNOS4X12_GPIO_D00, S5P_GPIO_DRV_4X); + gpio_direction_output(EXYNOS4X12_GPIO_D00, 1); + + /* OTG Vbus output (Odroid U3+) */ + gpio_set_pull(EXYNOS4X12_GPIO_L20, S5P_GPIO_PULL_NONE); + gpio_set_drv(EXYNOS4X12_GPIO_L20, S5P_GPIO_DRV_4X); + gpio_direction_output(EXYNOS4X12_GPIO_L20, 0); + + /* OTG INT (Odroid U3+) */ + gpio_set_pull(EXYNOS4X12_GPIO_X31, S5P_GPIO_PULL_UP); + gpio_set_drv(EXYNOS4X12_GPIO_X31, S5P_GPIO_DRV_4X); + gpio_direction_input(EXYNOS4X12_GPIO_X31); +} + +static int pmic_init_max77686(void) +{ + struct pmic *p = pmic_get("MAX77686_PMIC"); + + if (pmic_probe(p)) + return -ENODEV; + + /* Set LDO Voltage */ + max77686_set_ldo_voltage(p, 20, 1800000); /* LDO20 eMMC */ + max77686_set_ldo_voltage(p, 21, 2800000); /* LDO21 SD */ + max77686_set_ldo_voltage(p, 22, 2800000); /* LDO22 eMMC */ + + return 0; +} + +#ifdef CONFIG_SYS_I2C_INIT_BOARD +static void board_init_i2c(void) +{ + /* I2C_0 */ + if (exynos_pinmux_config(PERIPH_ID_I2C0, PINMUX_FLAG_NONE)) + debug("I2C%d not configured\n", (I2C_0)); +} +#endif + +int exynos_early_init_f(void) +{ + board_clock_init(); + board_gpio_init(); + + return 0; +} + +int exynos_init(void) +{ + /* The last MB of memory is reserved for secure firmware */ + gd->ram_size -= SZ_1M; + gd->bd->bi_dram[CONFIG_NR_DRAM_BANKS - 1].size -= SZ_1M; + + return 0; +} + +int exynos_power_init(void) +{ +#ifdef CONFIG_SYS_I2C_INIT_BOARD + board_init_i2c(); +#endif + pmic_init(I2C_0); + pmic_init_max77686(); + + return 0; +} + +#ifdef CONFIG_USB_GADGET +static int s5pc210_phy_control(int on) +{ + struct pmic *p_pmic; + + p_pmic = pmic_get("MAX77686_PMIC"); + if (!p_pmic) + return -ENODEV; + + if (pmic_probe(p_pmic)) + return -1; + + if (on) + return max77686_set_ldo_mode(p_pmic, 12, OPMODE_ON); + else + return max77686_set_ldo_mode(p_pmic, 12, OPMODE_LPM); +} + +struct s3c_plat_otg_data s5pc210_otg_data = { + .phy_control = s5pc210_phy_control, + .regs_phy = EXYNOS4X12_USBPHY_BASE, + .regs_otg = EXYNOS4X12_USBOTG_BASE, + .usb_phy_ctrl = EXYNOS4X12_USBPHY_CONTROL, + .usb_flags = PHY0_SLEEP, +}; + +int board_usb_init(int index, enum usb_init_type init) +{ + debug("USB_udc_probe\n"); + return s3c_udc_probe(&s5pc210_otg_data); +} +#endif + +void reset_misc(void) +{ + /* Reset eMMC*/ + gpio_set_value(EXYNOS4X12_GPIO_K12, 0); + mdelay(10); + gpio_set_value(EXYNOS4X12_GPIO_K12, 1); +} diff --git a/board/samsung/odroid/setup.h b/board/samsung/odroid/setup.h new file mode 100644 index 0000000..3e48dad --- /dev/null +++ b/board/samsung/odroid/setup.h @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * Przemyslaw Marczak p.marczak@samsung.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ODROIDU3_SETUP__ +#define __ODROIDU3_SETUP__ + +/* A/M PLL_CON0 */ +#define SDIV(x) ((x) & 0x7) +#define PDIV(x) (((x) & 0x3f) << 8) +#define MDIV(x) (((x) & 0x3ff) << 16) +#define FSEL(x) (((x) & 0x1) << 27) +#define PLL_LOCKED_BIT (0x1 << 29) +#define PLL_ENABLE(x) (((x) & 0x1) << 31) + +/* CLK_SRC_CPU */ +#define MUX_APLL_SEL(x) ((x) & 0x1) +#define MUX_CORE_SEL(x) (((x) & 0x1) << 16) +#define MUX_HPM_SEL(x) (((x) & 0x1) << 20) +#define MUX_MPLL_USER_SEL_C(x) (((x) & 0x1) << 24) + +#define MUX_STAT_CHANGING 0x100 + +/* CLK_MUX_STAT_CPU */ +#define APLL_SEL(x) ((x) & 0x7) +#define CORE_SEL(x) (((x) & 0x7) << 16) +#define HPM_SEL(x) (((x) & 0x7) << 20) +#define MPLL_USER_SEL_C(x) (((x) & 0x7) << 24) +#define MUX_STAT_CPU_CHANGING (APLL_SEL(MUX_STAT_CHANGING) | \ + CORE_SEL(MUX_STAT_CHANGING) | \ + HPM_SEL(MUX_STAT_CHANGING) | \ + MPLL_USER_SEL_C(MUX_STAT_CHANGING)) + +/* CLK_DIV_CPU0 */ +#define CORE_RATIO(x) ((x) & 0x7) +#define COREM0_RATIO(x) (((x) & 0x7) << 4) +#define COREM1_RATIO(x) (((x) & 0x7) << 8) +#define PERIPH_RATIO(x) (((x) & 0x7) << 12) +#define ATB_RATIO(x) (((x) & 0x7) << 16) +#define PCLK_DBG_RATIO(x) (((x) & 0x7) << 20) +#define APLL_RATIO(x) (((x) & 0x7) << 24) +#define CORE2_RATIO(x) (((x) & 0x7) << 28) + +/* CLK_DIV_STAT_CPU0 */ +#define DIV_CORE(x) ((x) & 0x1) +#define DIV_COREM0(x) (((x) & 0x1) << 4) +#define DIV_COREM1(x) (((x) & 0x1) << 8) +#define DIV_PERIPH(x) (((x) & 0x1) << 12) +#define DIV_ATB(x) (((x) & 0x1) << 16) +#define DIV_PCLK_DBG(x) (((x) & 0x1) << 20) +#define DIV_APLL(x) (((x) & 0x1) << 24) +#define DIV_CORE2(x) (((x) & 0x1) << 28) + +#define DIV_STAT_CHANGING 0x1 +#define DIV_STAT_CPU0_CHANGING (DIV_CORE(DIV_STAT_CHANGING) | \ + DIV_COREM0(DIV_STAT_CHANGING) | \ + DIV_COREM1(DIV_STAT_CHANGING) | \ + DIV_PERIPH(DIV_STAT_CHANGING) | \ + DIV_ATB(DIV_STAT_CHANGING) | \ + DIV_PCLK_DBG(DIV_STAT_CHANGING) | \ + DIV_APLL(DIV_STAT_CHANGING) | \ + DIV_CORE2(DIV_STAT_CHANGING)) + +/* CLK_DIV_CPU1 */ +#define COPY_RATIO(x) ((x) & 0x7) +#define HPM_RATIO(x) (((x) & 0x7) << 4) +#define CORES_RATIO(x) (((x) & 0x7) << 8) + +/* CLK_DIV_STAT_CPU1 */ +#define DIV_COPY(x) ((x) & 0x7) +#define DIV_HPM(x) (((x) & 0x1) << 4) +#define DIV_CORES(x) (((x) & 0x1) << 8) + +#define DIV_STAT_CPU1_CHANGING (DIV_COPY(DIV_STAT_CHANGING) | \ + DIV_HPM(DIV_STAT_CHANGING) | \ + DIV_CORES(DIV_STAT_CHANGING)) + +/* CLK_SRC_DMC */ +#define MUX_C2C_SEL(x) ((x) & 0x1) +#define MUX_DMC_BUS_SEL(x) (((x) & 0x1) << 4) +#define MUX_DPHY_SEL(x) (((x) & 0x1) << 8) +#define MUX_MPLL_SEL(x) (((x) & 0x1) << 12) +#define MUX_PWI_SEL(x) (((x) & 0xf) << 16) +#define MUX_G2D_ACP0_SEL(x) (((x) & 0x1) << 20) +#define MUX_G2D_ACP1_SEL(x) (((x) & 0x1) << 24) +#define MUX_G2D_ACP_SEL(x) (((x) & 0x1) << 28) + +/* CLK_MUX_STAT_DMC */ +#define C2C_SEL(x) (((x)) & 0x7) +#define DMC_BUS_SEL(x) (((x) & 0x7) << 4) +#define DPHY_SEL(x) (((x) & 0x7) << 8) +#define MPLL_SEL(x) (((x) & 0x7) << 12) +/* #define PWI_SEL(x) (((x) & 0xf) << 16) - Reserved */ +#define G2D_ACP0_SEL(x) (((x) & 0x7) << 20) +#define G2D_ACP1_SEL(x) (((x) & 0x7) << 24) +#define G2D_ACP_SEL(x) (((x) & 0x7) << 28) + +#define MUX_STAT_DMC_CHANGING (C2C_SEL(MUX_STAT_CHANGING) | \ + DMC_BUS_SEL(MUX_STAT_CHANGING) | \ + DPHY_SEL(MUX_STAT_CHANGING) | \ + MPLL_SEL(MUX_STAT_CHANGING) |\ + G2D_ACP0_SEL(MUX_STAT_CHANGING) | \ + G2D_ACP1_SEL(MUX_STAT_CHANGING) | \ + G2D_ACP_SEL(MUX_STAT_CHANGING)) + +/* CLK_DIV_DMC0 */ +#define ACP_RATIO(x) ((x) & 0x7) +#define ACP_PCLK_RATIO(x) (((x) & 0x7) << 4) +#define DPHY_RATIO(x) (((x) & 0x7) << 8) +#define DMC_RATIO(x) (((x) & 0x7) << 12) +#define DMCD_RATIO(x) (((x) & 0x7) << 16) +#define DMCP_RATIO(x) (((x) & 0x7) << 20) + +/* CLK_DIV_STAT_DMC0 */ +#define DIV_ACP(x) ((x) & 0x1) +#define DIV_ACP_PCLK(x) (((x) & 0x1) << 4) +#define DIV_DPHY(x) (((x) & 0x1) << 8) +#define DIV_DMC(x) (((x) & 0x1) << 12) +#define DIV_DMCD(x) (((x) & 0x1) << 16) +#define DIV_DMCP(x) (((x) & 0x1) << 20) + +#define DIV_STAT_DMC0_CHANGING (DIV_ACP(DIV_STAT_CHANGING) | \ + DIV_ACP_PCLK(DIV_STAT_CHANGING) | \ + DIV_DPHY(DIV_STAT_CHANGING) | \ + DIV_DMC(DIV_STAT_CHANGING) | \ + DIV_DMCD(DIV_STAT_CHANGING) | \ + DIV_DMCP(DIV_STAT_CHANGING)) + +/* CLK_DIV_DMC1 */ +#define G2D_ACP_RATIO(x) ((x) & 0xf) +#define C2C_RATIO(x) (((x) & 0x7) << 4) +#define PWI_RATIO(x) (((x) & 0xf) << 8) +#define C2C_ACLK_RATIO(x) (((x) & 0x7) << 12) +#define DVSEM_RATIO(x) (((x) & 0x7f) << 16) +#define DPM_RATIO(x) (((x) & 0x7f) << 24) + +/* CLK_DIV_STAT_DMC1 */ +#define DIV_G2D_ACP(x) ((x) & 0x1) +#define DIV_C2C(x) (((x) & 0x1) << 4) +#define DIV_PWI(x) (((x) & 0x1) << 8) +#define DIV_C2C_ACLK(x) (((x) & 0x1) << 12) +#define DIV_DVSEM(x) (((x) & 0x1) << 16) +#define DIV_DPM(x) (((x) & 0x1) << 24) + +#define DIV_STAT_DMC1_CHANGING (DIV_G2D_ACP(DIV_STAT_CHANGING) | \ + DIV_C2C(DIV_STAT_CHANGING) | \ + DIV_PWI(DIV_STAT_CHANGING) | \ + DIV_C2C_ACLK(DIV_STAT_CHANGING) | \ + DIV_DVSEM(DIV_STAT_CHANGING) | \ + DIV_DPM(DIV_STAT_CHANGING)) + +/* Set CLK_SRC_PERIL0 */ +#define UART4_SEL(x) (((x) & 0xf) << 16) +#define UART3_SEL(x) (((x) & 0xf) << 12) +#define UART2_SEL(x) (((x) & 0xf) << 8) +#define UART1_SEL(x) (((x) & 0xf) << 4) +#define UART0_SEL(x) ((x) & 0xf) + +/* Set CLK_DIV_PERIL0 */ +#define UART4_RATIO(x) (((x) & 0xf) << 16) +#define UART3_RATIO(x) (((x) & 0xf) << 12) +#define UART2_RATIO(x) (((x) & 0xf) << 8) +#define UART1_RATIO(x) (((x) & 0xf) << 4) +#define UART0_RATIO(x) ((x) & 0xf) + +/* Set CLK_DIV_STAT_PERIL0 */ +#define DIV_UART4(x) (((x) & 0x1) << 16) +#define DIV_UART3(x) (((x) & 0x1) << 12) +#define DIV_UART2(x) (((x) & 0x1) << 8) +#define DIV_UART1(x) (((x) & 0x1) << 4) +#define DIV_UART0(x) ((x) & 0x1) + +#define DIV_STAT_PERIL0_CHANGING (DIV_UART4(DIV_STAT_CHANGING) | \ + DIV_UART3(DIV_STAT_CHANGING) | \ + DIV_UART2(DIV_STAT_CHANGING) | \ + DIV_UART1(DIV_STAT_CHANGING) | \ + DIV_UART0(DIV_STAT_CHANGING)) + +/* CLK_DIV_FSYS1 */ +#define MMC0_RATIO(x) ((x) & 0xf) +#define MMC0_PRE_RATIO(x) (((x) & 0xff) << 8) +#define MMC1_RATIO(x) (((x) & 0xf) << 16) +#define MMC1_PRE_RATIO(x) (((x) & 0xff) << 24) + +/* CLK_DIV_STAT_FSYS1 */ +#define DIV_MMC0(x) ((x) & 1) +#define DIV_MMC0_PRE(x) (((x) & 1) << 8) +#define DIV_MMC1(x) (((x) & 1) << 16) +#define DIV_MMC1_PRE(x) (((x) & 1) << 24) + +#define DIV_STAT_FSYS1_CHANGING (DIV_MMC0(DIV_STAT_CHANGING) | \ + DIV_MMC0_PRE(DIV_STAT_CHANGING) | \ + DIV_MMC1(DIV_STAT_CHANGING) | \ + DIV_MMC1_PRE(DIV_STAT_CHANGING)) + +/* CLK_DIV_FSYS2 */ +#define MMC2_RATIO(x) ((x) & 0xf) +#define MMC2_PRE_RATIO(x) (((x) & 0xff) << 8) +#define MMC3_RATIO(x) (((x) & 0xf) << 16) +#define MMC3_PRE_RATIO(x) (((x) & 0xff) << 24) + +/* CLK_DIV_STAT_FSYS2 */ +#define DIV_MMC2(x) ((x) & 0x1) +#define DIV_MMC2_PRE(x) (((x) & 0x1) << 8) +#define DIV_MMC3(x) (((x) & 0x1) << 16) +#define DIV_MMC3_PRE(x) (((x) & 0x1) << 24) + +#define DIV_STAT_FSYS2_CHANGING (DIV_MMC2(DIV_STAT_CHANGING) | \ + DIV_MMC2_PRE(DIV_STAT_CHANGING) | \ + DIV_MMC3(DIV_STAT_CHANGING) | \ + DIV_MMC3_PRE(DIV_STAT_CHANGING)) + +/* CLK_DIV_FSYS3 */ +#define MMC4_RATIO(x) ((x) & 0x7) +#define MMC4_PRE_RATIO(x) (((x) & 0xff) << 8) + +/* CLK_DIV_STAT_FSYS3 */ +#define DIV_MMC4(x) ((x) & 0x1) +#define DIV_MMC4_PRE(x) (((x) & 0x1) << 8) + +#define DIV_STAT_FSYS3_CHANGING (DIV_MMC4(DIV_STAT_CHANGING) | \ + DIV_MMC4_PRE(DIV_STAT_CHANGING)) + +/* XCL205 GPIO config - Odroid U3 */ +#define XCL205_GPIO_BASE EXYNOS4X12_GPIO_PART1_BASE +#define XCL205_EN_GPIO_OFFSET 0x20 /* GPA1 */ +#define XCL205_EN_GPIO_PIN 1 +#define XCL205_EN_GPIO_CON (XCL205_GPIO_BASE + \ + XCL205_EN_GPIO_OFFSET) +#define XCL205_EN_GPIO_CON_CFG (S5P_GPIO_OUTPUT << \ + 4 * XCL205_EN_GPIO_PIN) +#define XCL205_EN_GPIO_DAT_CFG (0x1 << XCL205_EN_GPIO_PIN) +#define XCL205_EN_GPIO_PUD_CFG (S5P_GPIO_PULL_UP << \ + 2 * XCL205_EN_GPIO_PIN) +#define XCL205_EN_GPIO_DRV_CFG (S5P_GPIO_DRV_4X << \ + 2 * XCL205_EN_GPIO_PIN) + +#define XCL205_STATE_GPIO_OFFSET 0x80 /* GPC1 */ +#define XCL205_STATE_GPIO_PIN 2 +#define XCL205_STATE_GPIO_CON (XCL205_GPIO_BASE + \ + XCL205_STATE_GPIO_OFFSET) +#define XCL205_STATE_GPIO_DAT XCL205_STATE_GPIO_CON + 0x4 +#define XCL205_STATE_GPIO_CON_CFG (S5P_GPIO_INPUT << \ + 4 * XCL205_STATE_GPIO_PIN) +#define XCL205_STATE_GPIO_PUD_CFG (S5P_GPIO_PULL_NONE << \ + 2 * XCL205_STATE_GPIO_PIN) + +#ifdef CONFIG_BOARD_TYPES +extern void sdelay(unsigned long); +#endif + +#endif /*__ODROIDU3_SETUP__ */

This is a standard description for Odroid boards.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Tom Rini trini@ti.com --- arch/arm/dts/Makefile | 3 +- arch/arm/dts/exynos4412-odroid.dts | 70 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/exynos4412-odroid.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index c46b7be..1ccd827 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1,7 +1,8 @@ dtb-$(CONFIG_EXYNOS4) += exynos4210-origen.dtb \ exynos4210-universal_c210.dtb \ exynos4210-trats.dtb \ - exynos4412-trats2.dtb + exynos4412-trats2.dtb \ + exynos4412-odroid.dtb
dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \ exynos5250-snow.dtb \ diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts new file mode 100644 index 0000000..24d0bf1 --- /dev/null +++ b/arch/arm/dts/exynos4412-odroid.dts @@ -0,0 +1,70 @@ +/* + * Odroid-U3/X2 board device tree source + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; +/include/ "exynos4.dtsi" + +/ { + model = "Odroid based on Exynos4412"; + compatible = "samsung,odroid", "samsung,exynos4412"; + + aliases { + i2c0 = "/i2c@13860000"; + serial0 = "/serial@13800000"; + console = "/serial@13810000"; + mmc2 = "sdhci@12530000"; + mmc4 = "dwmmc@12550000"; + }; + + i2c@13860000 { + samsung,i2c-sda-delay = <100>; + samsung,i2c-slave-addr = <0x10>; + samsung,i2c-max-bus-freq = <100000>; + status = "okay"; + + max77686_pmic@09 { + compatible = "maxim,max77686_pmic"; + interrupts = <7 0>; + reg = <0x09 0 0>; + #clock-cells = <1>; + }; + }; + + serial@13810000 { + status = "okay"; + }; + + sdhci@12510000 { + status = "disabled"; + }; + + sdhci@12520000 { + status = "disabled"; + }; + + sdhci@12530000 { + samsung,bus-width = <4>; + samsung,timing = <1 2 3>; + cd-gpios = <&gpio 0xC2 0>; + }; + + sdhci@12540000 { + status = "disabled"; + }; + + dwmmc@12550000 { + samsung,bus-width = <8>; + samsung,timing = <2 1 0>; + samsung,removable = <0>; + fifoth_val = <0x203f0040>; + bus_hz = <400000000>; + div = <0x3>; + index = <4>; + }; +};

This config is valid for two devices: - Odroid X2, - Odroid U3.
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com Cc: Minkyu Kang mk7.kang@samsung.com Cc: Tom Rini trini@ti.com
--- Changes v2: - odroid config: add CONFIG_DFU_ALT_BOOTLOADER - odroid config: change name of CONFIG_DFU_BOOT_ALT_* to CONFIG_DFU_ALT_BOOT_*
Changes v3: - odroid.h: update CONFIG_DFU_ALT_BOOT_** with required bootloader binaries - odroid.h: add multi image support (CONFIG_FIT) - odroid.h: add "autoboot" script for multi boot options - odroid.h: change env name: dfu_alt_info -> dfu_alt_system - odroid.h: update config name: CONFIG_SET_DFU_ALT_INFO - odroid.h: reduce boot delay to 0 seconds - update: doc/README.odroid
Changes v5: - odroid.h: default environment cleanup - odroid.h: remove unused definitions - odroid.h: dfu_alt_system update - odroid.h: define CONFIG_SET_DFU_ALT_BUF_LEN to 1k - odroid.h: add init ramdisk support - update: doc/README.odroid
Changes v6: - odroid.h: fix ramdisk load issue
Changes v8: - add Kconfig configuration for Odroid --- arch/arm/cpu/armv7/exynos/Kconfig | 4 + board/samsung/odroid/Kconfig | 15 +++ board/samsung/odroid/MAINTAINERS | 6 ++ configs/odroid_defconfig | 3 + doc/README.odroid | 143 +++++++++++++++++++++++++ include/configs/odroid.h | 216 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 387 insertions(+) create mode 100644 board/samsung/odroid/Kconfig create mode 100644 board/samsung/odroid/MAINTAINERS create mode 100644 configs/odroid_defconfig create mode 100644 doc/README.odroid create mode 100644 include/configs/odroid.h
diff --git a/arch/arm/cpu/armv7/exynos/Kconfig b/arch/arm/cpu/armv7/exynos/Kconfig index f1cacdc..b6a558b 100644 --- a/arch/arm/cpu/armv7/exynos/Kconfig +++ b/arch/arm/cpu/armv7/exynos/Kconfig @@ -18,6 +18,9 @@ config TARGET_ORIGEN config TARGET_TRATS2 bool "Exynos4412 Trat2 board"
+config TARGET_ODROID + bool "Exynos4412 Odroid board" + config TARGET_ARNDALE bool "Exynos5250 Arndale board"
@@ -48,6 +51,7 @@ source "board/samsung/trats/Kconfig" source "board/samsung/universal_c210/Kconfig" source "board/samsung/origen/Kconfig" source "board/samsung/trats2/Kconfig" +source "board/samsung/odroid/Kconfig" source "board/samsung/arndale/Kconfig" source "board/samsung/smdk5250/Kconfig" source "board/samsung/smdk5420/Kconfig" diff --git a/board/samsung/odroid/Kconfig b/board/samsung/odroid/Kconfig new file mode 100644 index 0000000..8dcfb48 --- /dev/null +++ b/board/samsung/odroid/Kconfig @@ -0,0 +1,15 @@ +if TARGET_ODROID + +config SYS_BOARD + string + default "odroid" + +config SYS_VENDOR + string + default "samsung" + +config SYS_CONFIG_NAME + string + default "odroid" + +endif diff --git a/board/samsung/odroid/MAINTAINERS b/board/samsung/odroid/MAINTAINERS new file mode 100644 index 0000000..2131d36 --- /dev/null +++ b/board/samsung/odroid/MAINTAINERS @@ -0,0 +1,6 @@ +ODROID BOARD +M: Przemyslaw Marczak p.marczak@samsung.com +S: Maintained +F: board/samsung/odroid/ +F: include/configs/odroid.h +F: configs/odroid_defconfig diff --git a/configs/odroid_defconfig b/configs/odroid_defconfig new file mode 100644 index 0000000..a1c7ac5 --- /dev/null +++ b/configs/odroid_defconfig @@ -0,0 +1,3 @@ +CONFIG_ARM=y +CONFIG_ARCH_EXYNOS=y +CONFIG_TARGET_ODROID=y diff --git a/doc/README.odroid b/doc/README.odroid new file mode 100644 index 0000000..528bb95 --- /dev/null +++ b/doc/README.odroid @@ -0,0 +1,143 @@ + U-boot for Odroid X2/U3 +======================== + +1. Summary +========== +This is a quick instruction for setup Odroid boards based on Exynos4412. +Board config: odroid_config + +2. Supported devices +==================== +This U-BOOT config can be used on two boards: +- Odroid U3 +- Odroid X2 +with CPU Exynos 4412 rev 2.0 and 2GB of RAM + +3. Boot sequence +================ +iROM->BL1->(BL2 + TrustZone)->U-BOOT + +This version of U-BOOT doesn't implement SPL but it is required(BL2) +and can be found in "boot.tar.gz" from here: +http://dev.odroid.com/projects/4412boot/wiki/FrontPage?action=download&v... +or here: +http://odroid.in/guides/ubuntu-lfs/boot.tar.gz + +4. Boot media layout +==================== +The table below shows SD/eMMC cards layout for U-boot. +The block offset is starting from 0 and the block size is 512B. + ------------------------------------- +| Binary | Block offset| part type | +| name | SD | eMMC |(eMMC only)| + ------------------------------------- +| Bl1 | 1 | 0 | 1 (boot) | +| Bl2 | 31 | 30 | 1 (boot) | +| U-boot | 63 | 62 | 1 (boot) | +| Tzsw | 2111 | 2110 | 1 (boot) | +| Uboot Env | 2500 | 2500 | 0 (user) | + ------------------------------------- + +5. Prepare the SD boot card - with SD card reader +================================================= +To prepare bootable media you need boot binaries provided by hardkernel. +File "boot.tar.gz" (link in point 3.) contains: +- E4412_S.bl1.HardKernel.bin +- E4412_S.tzsw.signed.bin +- bl2.signed.bin +- sd_fusing.sh +- u-boot.bin + +This is all you need to boot this board. But if you want to use your custom +u-boot then you need to change u-boot.bin with your own u-boot binary* +and run the script "sd_fusing.sh" - this script is valid only for SD card. + +*note: +The proper binary file of current U-boot is u-boot-dtb.bin. + +quick steps for Linux: +- extract boot.tar.gz +- put any SD card into the SD reader +- check the device with "dmesg" +- run ./sd_fusing.sh /dev/sdX - where X is SD card device (but not a partition) +Check if Hardkernel U-boot is booting, and next do the same with your U-boot. + +6. Prepare the eMMC boot card + with a eMMC card reader (boot from eMMC card slot) +===================================================== +To boot the device from the eMMC slot you should use a special card reader +which supports eMMC partiion switch. All of the boot binaries are stored +on the eMMC boot partition which is normally hidden. + +The "sd_fusing.sh" script can be used after updating offsets of binaries +according to the table from point 4. Be sure that you are working on the right +eMMC partition - its size is usually very small, about 1-4 MiB. + +7. Prepare the eMMC boot card + with a SD card reader (boot from SD card slot) +================================================= +If you have an eMMC->microSD adapter you can prepare the card as in point 5. +But then the device can boot only from the SD card slot. + +8. Prepare the boot media using Hardkernel U-boot +================================================= +You can update the U-boot to the custom one if you have an working bootloader +delivered with the board on a eMMC/SD card. Then follow the steps: +- install the android fastboot tool +- connect a micro usb cable to the board +- on the U-boot prompt, run command: fastboot (as a root) +- on the host, run command: "fastboot flash bootloader u-boot-dtb.bin" +- the custom U-boot should start after the board resets. + +9. Partition layout +==================== +Default U-boot environment is setup for fixed partiion layout. + +Partition table: MSDOS. Disk layout and files as listed in the table below. + ----- ------ ------ ------ -------- --------------------------------- +| Num | Name | FS | Size | Offset | Reguired files | +| | | Type | MiB | MiB | | + ----- ------ ------ ------ -------- --------------------------------- +| 1 | BOOT | fat | 100 | 2 | kernel, fdt** | +| 2 | ROOT | ext4 | - | | any Linux system | + ----- ------ ------ ------ -------- --------------------------------- + +**note: +Supported fdt files are: +- exynos4412-odroidx2.dtb +- exynos4412-odroidu3.dtb + +Supported kernel files are: +- Image.itb +- zImage +- uImage + +The default environmental variable "dfu_alt_info" is set* for above layout. +Each partition size is just an example, dfu_alt_info tries init two partitions. +The size of each is not important. + +*note: +$dfu_alt_info is set on a boot time and it is concatenated using two variables: +- $dfu_alt_boot(set dynamically) +- $dfu_alt_system(from current env). + +To add any changes to dfu_alt_info - please modify $dfu_alt_system only. +Changes are visible after board reset. + +10. The environment and booting the kernel +========================================== +There are three macros defined in config for various boot options: +Two for both, kernel with device tree support and also without it: +- boot_uimg - load uImage +- boot_zimg - load zImage +If proper fdt file exists then it will be automatically loaded, +so for old kernel types, please remove fdt file from boot partition. + +The third boot option for multi image support (more info: doc/uImage.FIT/) +- boot_fit - for binary file: "Image.itb" + +Default boot command: "autoboot" +And the boot sequence is: +- boot_fit - if "Image.itb" exists +- boot_zimg - if "zImage" exists +- boot_uimg - if "uImage" exists diff --git a/include/configs/odroid.h b/include/configs/odroid.h new file mode 100644 index 0000000..29dcc4a --- /dev/null +++ b/include/configs/odroid.h @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * Sanghee Kim sh0130.kim@samsung.com + * Piotr Wilczek p.wilczek@samsung.com + * Przemyslaw Marczak p.marczak@samsung.com + * + * Configuation settings for the Odroid-U3 (EXYNOS4412) board. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_ODROID_U3_H +#define __CONFIG_ODROID_U3_H + +#include <configs/exynos4-dt.h> + +#define CONFIG_SYS_PROMPT "Odroid # " /* Monitor Command Prompt */ + +#undef CONFIG_DEFAULT_DEVICE_TREE +#define CONFIG_DEFAULT_DEVICE_TREE exynos4412-odroid + +#define CONFIG_SYS_L2CACHE_OFF +#ifndef CONFIG_SYS_L2CACHE_OFF +#define CONFIG_SYS_L2_PL310 +#define CONFIG_SYS_PL310_BASE 0x10502000 +#endif + +#define CONFIG_MACH_TYPE 4289 + +#define CONFIG_NR_DRAM_BANKS 8 +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define SDRAM_BANK_SIZE (256 << 20) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE + +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x3E00000) +#define CONFIG_SYS_TEXT_BASE 0x43e00000 + +#include <linux/sizes.h> +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (80 * SZ_1M)) + +/* select serial console configuration */ +#define CONFIG_SERIAL1 +#define CONFIG_BAUDRATE 115200 + +/* Console configuration */ +#define CONFIG_SYS_CONSOLE_INFO_QUIET +#define CONFIG_SYS_CONSOLE_IS_IN_ENV + +#define CONFIG_CMD_BOOTZ +#define CONFIG_FIT +#define CONFIG_FIT_VERBOSE +#define CONFIG_BOOTARGS "Please use defined boot" +#define CONFIG_BOOTCOMMAND "run autoboot" +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR \ + - GENERATED_GBL_DATA_SIZE) + +#define CONFIG_SYS_MEM_TOP_HIDE (SZ_1M) /* ram console */ + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV CONFIG_MMC_DEFAULT_DEV +#define CONFIG_ENV_SIZE 4096 +#define CONFIG_ENV_OFFSET (SZ_1K * 1280) /* 1.25 MiB offset */ +#define CONFIG_ENV_OVERWRITE + +/* Partitions name */ +#define PARTS_BOOT "boot" +#define PARTS_ROOT "platform" + +#define CONFIG_DFU_ALT \ + "uImage fat 0 1;" \ + "zImage fat 0 1;" \ + "Image.itb fat 0 1;" \ + "uInitrd fat 0 1;" \ + "exynos4412-odroidu3.dtb fat 0 1;" \ + "exynos4412-odroidx2.dtb fat 0 1;" \ + ""PARTS_BOOT" part 0 1;" \ + ""PARTS_ROOT" part 0 2\0" \ + +#define CONFIG_SET_DFU_ALT_INFO +#define CONFIG_SET_DFU_ALT_BUF_LEN (SZ_1K) + +#define CONFIG_DFU_ALT_BOOT_EMMC \ + "u-boot raw 0x3e 0x800 mmcpart 1;" \ + "bl1 raw 0x0 0x1e mmcpart 1;" \ + "bl2 raw 0x1e 0x1d mmcpart 1;" \ + "tzsw raw 0x83e 0x138 mmcpart 1\0" + +#define CONFIG_DFU_ALT_BOOT_SD \ + "u-boot raw 0x3f 0x800;" \ + "bl1 raw 0x1 0x1e;" \ + "bl2 raw 0x1f 0x1d;" \ + "tzsw raw 0x83f 0x138\0" + +/* + * Bootable media layout: + * dev: SD eMMC(part boot) + * BL1 1 0 + * BL2 31 30 + * UBOOT 63 62 + * TZSW 2111 2110 + * ENV 2560 2560(part user) + * + * MBR Primary partiions: + * Num Name Size Offset + * 1. BOOT: 100MiB 2MiB + * 2. ROOT: - +*/ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "loadkernel=fatload mmc ${mmcbootdev}:${mmcbootpart} ${kerneladdr} " \ + "${kernelname}\0" \ + "loadinitrd=fatload mmc ${mmcbootdev}:${mmcbootpart} ${initrdaddr} " \ + "${initrdname}\0" \ + "loaddtb=fatload mmc ${mmcbootdev}:${mmcbootpart} ${fdtaddr} " \ + "${fdtfile}\0" \ + "check_ramdisk=" \ + "if run loadinitrd; then " \ + "setenv initrd_addr ${initrdaddr};" \ + "else " \ + "setenv initrd_addr -;" \ + "fi;\0" \ + "check_dtb=" \ + "if run loaddtb; then " \ + "setenv fdt_addr ${fdtaddr};" \ + "else " \ + "setenv fdt_addr;" \ + "fi;\0" \ + "kernel_args=" \ + "setenv bootargs root=/dev/mmcblk${mmcrootdev}p${mmcrootpart}" \ + " rootwait ${console} ${opts}\0" \ + "boot_fit=" \ + "setenv kerneladdr 0x42000000;" \ + "setenv kernelname Image.itb;" \ + "run loadkernel;" \ + "run kernel_args;" \ + "bootm ${kerneladdr}#${boardname}\0" \ + "boot_uimg=" \ + "setenv kerneladdr 0x40007FC0;" \ + "setenv kernelname uImage;" \ + "run check_dtb;" \ + "run check_ramdisk;" \ + "run loadkernel;" \ + "run kernel_args;" \ + "bootm ${kerneladdr} ${initrd_addr} ${fdt_addr};\0" \ + "boot_zimg=" \ + "setenv kerneladdr 0x40007FC0;" \ + "setenv kernelname zImage;" \ + "run check_dtb;" \ + "run check_ramdisk;" \ + "run loadkernel;" \ + "run kernel_args;" \ + "bootz ${kerneladdr} ${initrd_addr} ${fdt_addr};\0" \ + "autoboot=" \ + "if test -e mmc 0 Image.itb; then; " \ + "run boot_fit;" \ + "elif test -e mmc 0 zImage; then; " \ + "run boot_zimg;" \ + "elif test -e mmc 0 uImage; then; " \ + "run boot_uimg;" \ + "fi;\0" \ + "console=" CONFIG_DEFAULT_CONSOLE \ + "mmcbootdev=0\0" \ + "mmcbootpart=1\0" \ + "mmcrootdev=0\0" \ + "mmcrootpart=2\0" \ + "bootdelay=0\0" \ + "dfu_alt_system="CONFIG_DFU_ALT \ + "dfu_alt_info=Please reset the board\0" \ + "consoleon=set console console=ttySAC1,115200n8; save; reset\0" \ + "consoleoff=set console console=ram; save; reset\0" \ + "initrdname=uInitrd\0" \ + "initrdaddr=42000000\0" \ + "fdtaddr=40800000\0" + +/* I2C */ +#define CONFIG_CMD_I2C +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_S3C24X0 +#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 +#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0 +#define CONFIG_MAX_I2C_NUM 8 +#define CONFIG_SYS_I2C_INIT_BOARD + +/* POWER */ +#define CONFIG_POWER +#define CONFIG_POWER_I2C +#define CONFIG_POWER_MAX77686 + +/* GPT */ +#define CONFIG_RANDOM_UUID + +/* Security subsystem - enable hw_rand() */ +#define CONFIG_EXYNOS_ACE_SHA +#define CONFIG_LIB_HW_RAND + +#define CONFIG_CMD_GPIO + +/* + * Supported Odroid boards: X3, U3 + * TODO: Add Odroid X support + */ +#define CONFIG_MISC_COMMON +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +#define CONFIG_BOARD_TYPES +#define CONFIG_MISC_INIT_R + +#undef CONFIG_REVISION_TAG + +#endif /* __CONFIG_H */

Hello Minkyu,
On 09/01/2014 01:50 PM, Przemyslaw Marczak wrote:
This patch set introduces changes to common Samsung code as a preparation of new board support:
- boot device check - code cleanup
- automatic init order of mmc drivers
- automatic setting of dfu entities which depends on boot device
- pre reset function call for board own implementation
- setting board info environment for multi board support
New board config:
- odroid_config - Odroid U3/X2 support
V8 changes:
- patchset adjust to Kconfig
Przemyslaw Marczak (12): samsung: misc: fix soc revision setting in the set_board_info() exynos: pinmux: fix the gpio names for exynos4x12 mmc arch:exynos: boot mode: add get_boot_mode(), code cleanup board:samsung: check the boot device and init the right mmc driver. samsung: misc: add function for setting $dfu_alt_info samsung:board: misc_init_r: call set_dfu_alt_info() arm:reset: call the reset_misc() before the cpu reset samsung: board: enable support of multiple board types samsung: misc: use board specific functions to set env board info odroid: add board file for Odroid X2/U3 based on Samsung Exynos4412 odroid: add odroid U3/X2 device tree description odroid: kconfig: add odroid_defconfig
Can you please merge this patch set as a result of rebase on the top of the last Kconfig changes?
Best Regards,

On 01/09/14 20:50, Przemyslaw Marczak wrote:
This patch set introduces changes to common Samsung code as a preparation of new board support:
- boot device check - code cleanup
- automatic init order of mmc drivers
- automatic setting of dfu entities which depends on boot device
- pre reset function call for board own implementation
- setting board info environment for multi board support
New board config:
- odroid_config - Odroid U3/X2 support
V8 changes:
- patchset adjust to Kconfig
Przemyslaw Marczak (12): samsung: misc: fix soc revision setting in the set_board_info() exynos: pinmux: fix the gpio names for exynos4x12 mmc arch:exynos: boot mode: add get_boot_mode(), code cleanup board:samsung: check the boot device and init the right mmc driver. samsung: misc: add function for setting $dfu_alt_info samsung:board: misc_init_r: call set_dfu_alt_info() arm:reset: call the reset_misc() before the cpu reset samsung: board: enable support of multiple board types samsung: misc: use board specific functions to set env board info odroid: add board file for Odroid X2/U3 based on Samsung Exynos4412 odroid: add odroid U3/X2 device tree description odroid: kconfig: add odroid_defconfig
arch/arm/cpu/armv7/exynos/Kconfig | 4 + arch/arm/cpu/armv7/exynos/pinmux.c | 4 +- arch/arm/cpu/armv7/exynos/power.c | 7 + arch/arm/cpu/armv7/exynos/spl_boot.c | 7 +- arch/arm/dts/Makefile | 3 +- arch/arm/dts/exynos4412-odroid.dts | 70 +++++ arch/arm/include/asm/arch-exynos/power.h | 21 ++ arch/arm/include/asm/arch-exynos/spl.h | 17 +- arch/arm/lib/reset.c | 6 + board/samsung/common/board.c | 55 +++- board/samsung/common/misc.c | 57 +++- board/samsung/odroid/Kconfig | 15 + board/samsung/odroid/MAINTAINERS | 6 + board/samsung/odroid/Makefile | 8 + board/samsung/odroid/odroid.c | 470 +++++++++++++++++++++++++++++++ board/samsung/odroid/setup.h | 255 +++++++++++++++++ configs/odroid_defconfig | 3 + doc/README.odroid | 143 ++++++++++ include/common.h | 1 + include/configs/odroid.h | 216 ++++++++++++++ include/samsung/misc.h | 10 + 21 files changed, 1337 insertions(+), 41 deletions(-) create mode 100644 arch/arm/dts/exynos4412-odroid.dts create mode 100644 board/samsung/odroid/Kconfig create mode 100644 board/samsung/odroid/MAINTAINERS create mode 100644 board/samsung/odroid/Makefile create mode 100644 board/samsung/odroid/odroid.c create mode 100644 board/samsung/odroid/setup.h create mode 100644 configs/odroid_defconfig create mode 100644 doc/README.odroid create mode 100644 include/configs/odroid.h
applied to u-boot-samsung
Thanks, Minkyu Kang.
participants (4)
-
Jaehoon Chung
-
Minkyu Kang
-
Minkyu Kang
-
Przemyslaw Marczak