commit
b653516769
@ -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>; |
||||
}; |
||||
}; |
@ -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 |
@ -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 |
@ -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
|
@ -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 880MHz */ |
||||
set = SDIV(0) | PDIV(3) | MDIV(110) | 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 = 880 MHz |
||||
* MOUTdphy = 880 MHz |
||||
* |
||||
* aclk_acp = MOUTdmc / (ratio + 1) = 220 (3) |
||||
* pclk_acp = aclk_acp / (ratio + 1) = 110 (1) |
||||
* sclk_dphy = MOUTdphy / (ratio + 1) = 440 (1) |
||||
* sclk_dmc = MOUTdmc / (ratio + 1) = 440 (1) |
||||
* aclk_dmcd = sclk_dmc / (ratio + 1) = 220 (1) |
||||
* aclk_dmcp = aclk_dmcd / (ratio + 1) = 110 (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 = 880 MHz |
||||
* MOUTc2c = 880 Mhz |
||||
* MOUTpwi = 108 MHz |
||||
* |
||||
* sclk_g2d_acp = MOUTg2d / (ratio + 1) = 440 (1) |
||||
* sclk_c2c = MOUTc2c / (ratio + 1) = 440 (1) |
||||
* aclk_c2c = sclk_c2c / (ratio + 1) = 220 (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: 880MHz |
||||
* |
||||
* SCLK_UARTx = MOUTuartX / (ratio + 1) = 110 (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 = 880 MHz (MPLL) |
||||
* |
||||
* DOUTmmc1 = MOUTmmc1 / (ratio + 1) = 110 (7) |
||||
* sclk_mmc1 = DOUTmmc1 / (ratio + 1) = 60 (1) |
||||
* DOUTmmc0 = MOUTmmc0 / (ratio + 1) = 110 (7) |
||||
* sclk_mmc0 = DOUTmmc0 / (ratio + 1) = 60 (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 = 880 MHz (MPLL) |
||||
* |
||||
* DOUTmmc3 = MOUTmmc3 / (ratio + 1) = 110 (7) |
||||
* sclk_mmc3 = DOUTmmc3 / (ratio + 1) = 60 (1) |
||||
* DOUTmmc2 = MOUTmmc2 / (ratio + 1) = 110 (7) |
||||
* sclk_mmc2 = DOUTmmc2 / (ratio + 1) = 60 (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 = 880 MHz (MPLL) |
||||
* |
||||
* DOUTmmc4 = MOUTmmc4 / (ratio + 1) = 110 (7) |
||||
* sclk_mmc4 = DOUTmmc4 / (ratio + 1) = 110 (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); |
||||
} |
@ -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__ */ |
@ -0,0 +1,3 @@ |
||||
CONFIG_ARM=y |
||||
CONFIG_ARCH_EXYNOS=y |
||||
CONFIG_TARGET_ODROID=y |
@ -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&value=boot.tar.gz |
||||
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 |
@ -0,0 +1,220 @@ |
||||
/*
|
||||
* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
/*
|
||||
* This file is a driver for Parade dP<->LVDS bridges. The original submission |
||||
* is for the ps8625 chip. |
||||
*/ |
||||
#include <config.h> |
||||
#include <common.h> |
||||
#include <i2c.h> |
||||
#include <fdtdec.h> |
||||
|
||||
/*
|
||||
* Initialization of the chip is a process of writing certaing values into |
||||
* certain registers over i2c bus. The chip in fact responds to a range of |
||||
* addresses on the i2c bus, so for each written value three parameters are |
||||
* required: i2c address, register address and the actual value. |
||||
* |
||||
* The base address is derived from the device tree, only address offset is |
||||
* stored in the table below. |
||||
*/ |
||||
/**
|
||||
* struct reg_data() - data for a parade register write |
||||
* |
||||
* @addr_off offset from the i2c base address for parade |
||||
* @reg_addr register address to write |
||||
* @value value to be written |
||||
*/ |
||||
struct reg_data { |
||||
uint8_t addr_off; |
||||
uint8_t reg; |
||||
uint8_t value; |
||||
} _packed; |
||||
|
||||
#define END_OF_TABLE 0xff /* Ficticious offset */ |
||||
|
||||
static const struct reg_data parade_values[] = { |
||||
{0x02, 0xa1, 0x01}, /* HPD low */ |
||||
/*
|
||||
* SW setting |
||||
* [1:0] SW output 1.2V voltage is lower to 96% |
||||
*/ |
||||
{0x04, 0x14, 0x01}, |
||||
/*
|
||||
* RCO SS setting |
||||
* [5:4] = b01 0.5%, b10 1%, b11 1.5% |
||||
*/ |
||||
{0x04, 0xe3, 0x20}, |
||||
{0x04, 0xe2, 0x80}, /* [7] RCO SS enable */ |
||||
/*
|
||||
* RPHY Setting |
||||
* [3:2] CDR tune wait cycle before |
||||
* measure for fine tune b00: 1us, |
||||
* 01: 0.5us, 10:2us, 11:4us. |
||||
*/ |
||||
{0x04, 0x8a, 0x0c}, |
||||
{0x04, 0x89, 0x08}, /* [3] RFD always on */ |
||||
/*
|
||||
* CTN lock in/out: |
||||
* 20000ppm/80000ppm. Lock out 2 |
||||
* times. |
||||
*/ |
||||
{0x04, 0x71, 0x2d}, |
||||
/*
|
||||
* 2.7G CDR settings |
||||
* NOF=40LSB for HBR CDR setting |
||||
*/ |
||||
{0x04, 0x7d, 0x07}, |
||||
{0x04, 0x7b, 0x00}, /* [1:0] Fmin=+4bands */ |
||||
{0x04, 0x7a, 0xfd}, /* [7:5] DCO_FTRNG=+-40% */ |
||||
/*
|
||||
* 1.62G CDR settings |
||||
* [5:2]NOF=64LSB [1:0]DCO scale is 2/5 |
||||
*/ |
||||
{0x04, 0xc0, 0x12}, |
||||
{0x04, 0xc1, 0x92}, /* Gitune=-37% */ |
||||
{0x04, 0xc2, 0x1c}, /* Fbstep=100% */ |
||||
{0x04, 0x32, 0x80}, /* [7] LOS signal disable */ |
||||
/*
|
||||
* RPIO Setting |
||||
* [7:4] LVDS driver bias current : |
||||
* 75% (250mV swing) |
||||
*/ |
||||
{0x04, 0x00, 0xb0}, |
||||
/*
|
||||
* [7:6] Right-bar GPIO output strength is 8mA |
||||
*/ |
||||
{0x04, 0x15, 0x40}, |
||||
/* EQ Training State Machine Setting */ |
||||
{0x04, 0x54, 0x10}, /* RCO calibration start */ |
||||
/* [4:0] MAX_LANE_COUNT set to one lane */ |
||||
{0x01, 0x02, 0x81}, |
||||
/* [4:0] LANE_COUNT_SET set to one lane */ |
||||
{0x01, 0x21, 0x81}, |
||||
{0x00, 0x52, 0x20}, |
||||
{0x00, 0xf1, 0x03}, /* HPD CP toggle enable */ |
||||
{0x00, 0x62, 0x41}, |
||||
/* Counter number, add 1ms counter delay */ |
||||
{0x00, 0xf6, 0x01}, |
||||
/*
|
||||
* [6]PWM function control by |
||||
* DPCD0040f[7], default is PWM |
||||
* block always works. |
||||
*/ |
||||
{0x00, 0x77, 0x06}, |
||||
/*
|
||||
* 04h Adjust VTotal tolerance to |
||||
* fix the 30Hz no display issue |
||||
*/ |
||||
{0x00, 0x4c, 0x04}, |
||||
/* DPCD00400='h00, Parade OUI = 'h001cf8 */ |
||||
{0x01, 0xc0, 0x00}, |
||||
{0x01, 0xc1, 0x1c}, /* DPCD00401='h1c */ |
||||
{0x01, 0xc2, 0xf8}, /* DPCD00402='hf8 */ |
||||
/*
|
||||
* DPCD403~408 = ASCII code |
||||
* D2SLV5='h4432534c5635 |
||||
*/ |
||||
{0x01, 0xc3, 0x44}, |
||||
{0x01, 0xc4, 0x32}, /* DPCD404 */ |
||||
{0x01, 0xc5, 0x53}, /* DPCD405 */ |
||||
{0x01, 0xc6, 0x4c}, /* DPCD406 */ |
||||
{0x01, 0xc7, 0x56}, /* DPCD407 */ |
||||
{0x01, 0xc8, 0x35}, /* DPCD408 */ |
||||
/*
|
||||
* DPCD40A, Initial Code major revision |
||||
* '01' |
||||
*/ |
||||
{0x01, 0xca, 0x01}, |
||||
/* DPCD40B, Initial Code minor revision '05' */ |
||||
{0x01, 0xcb, 0x05}, |
||||
/* DPCD720, Select internal PWM */ |
||||
{0x01, 0xa5, 0xa0}, |
||||
/*
|
||||
* FFh for 100% PWM of brightness, 0h for 0% |
||||
* brightness |
||||
*/ |
||||
{0x01, 0xa7, 0xff}, |
||||
/*
|
||||
* Set LVDS output as 6bit-VESA mapping, |
||||
* single LVDS channel |
||||
*/ |
||||
{0x01, 0xcc, 0x13}, |
||||
/* Enable SSC set by register */ |
||||
{0x02, 0xb1, 0x20}, |
||||
/*
|
||||
* Set SSC enabled and +/-1% central |
||||
* spreading |
||||
*/ |
||||
{0x04, 0x10, 0x16}, |
||||
/* MPU Clock source: LC => RCO */ |
||||
{0x04, 0x59, 0x60}, |
||||
{0x04, 0x54, 0x14}, /* LC -> RCO */ |
||||
{0x02, 0xa1, 0x91}, /* HPD high */ |
||||
{END_OF_TABLE} |
||||
}; |
||||
|
||||
/**
|
||||
* Write values table into the Parade eDP bridge |
||||
* |
||||
* @return 0 on success, non-0 on failure |
||||
*/ |
||||
|
||||
static int parade_write_regs(int base_addr, const struct reg_data *table) |
||||
{ |
||||
int ret = 0; |
||||
|
||||
while (!ret && (table->addr_off != END_OF_TABLE)) { |
||||
ret = i2c_write(base_addr + table->addr_off, |
||||
table->reg, 1, |
||||
(uint8_t *)&table->value, |
||||
sizeof(table->value)); |
||||
table++; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
int parade_init(const void *blob) |
||||
{ |
||||
int bus, old_bus; |
||||
int parent; |
||||
int node; |
||||
int addr; |
||||
int ret; |
||||
|
||||
node = fdtdec_next_compatible(blob, 0, COMPAT_PARADE_PS8625); |
||||
if (node < 0) |
||||
return 0; |
||||
|
||||
parent = fdt_parent_offset(blob, node); |
||||
if (parent < 0) { |
||||
debug("%s: Could not find parent i2c node\n", __func__); |
||||
return -1; |
||||
} |
||||
addr = fdtdec_get_int(blob, node, "reg", -1); |
||||
if (addr < 0) { |
||||
debug("%s: Could not find i2c address\n", __func__); |
||||
return -1; |
||||
} |
||||
|
||||
bus = i2c_get_bus_num_fdt(parent); |
||||
old_bus = i2c_get_bus_num(); |
||||
|
||||
debug("%s: Using i2c bus %d\n", __func__, bus); |
||||
|
||||
/*
|
||||
* TODO(sjg@chromium.org): Hmmm we seem to need some sort of delay |
||||
* here. |
||||
*/ |
||||
mdelay(40); |
||||
i2c_set_bus_num(bus); |
||||
ret = parade_write_regs(addr, parade_values); |
||||
|
||||
i2c_set_bus_num(old_bus); |
||||
|
||||
return ret; |
||||
} |
@ -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 */ |
Loading…
Reference in new issue