Merge branch 'u-boot-samsung/master' into 'u-boot-arm/master'

master
Albert ARIBAUD 10 years ago
commit b653516769
  1. 4
      arch/arm/cpu/armv7/exynos/Kconfig
  2. 83
      arch/arm/cpu/armv7/exynos/clock.c
  3. 3
      arch/arm/cpu/armv7/exynos/clock_init.h
  4. 13
      arch/arm/cpu/armv7/exynos/clock_init_exynos5.c
  5. 2
      arch/arm/cpu/armv7/exynos/exynos5_setup.h
  6. 4
      arch/arm/cpu/armv7/exynos/pinmux.c
  7. 7
      arch/arm/cpu/armv7/exynos/power.c
  8. 7
      arch/arm/cpu/armv7/exynos/spl_boot.c
  9. 3
      arch/arm/dts/Makefile
  10. 70
      arch/arm/dts/exynos4412-odroid.dts
  11. 30
      arch/arm/dts/exynos5420-peach-pit.dts
  12. 10
      arch/arm/dts/exynos54xx.dtsi
  13. 1
      arch/arm/include/asm/arch-exynos/clk.h
  14. 1
      arch/arm/include/asm/arch-exynos/gpio.h
  15. 21
      arch/arm/include/asm/arch-exynos/power.h
  16. 17
      arch/arm/include/asm/arch-exynos/spl.h
  17. 4
      arch/arm/include/asm/arch-exynos/system.h
  18. 6
      arch/arm/lib/reset.c
  19. 2
      board/samsung/arndale/MAINTAINERS
  20. 69
      board/samsung/common/board.c
  21. 57
      board/samsung/common/misc.c
  22. 15
      board/samsung/odroid/Kconfig
  23. 6
      board/samsung/odroid/MAINTAINERS
  24. 8
      board/samsung/odroid/Makefile
  25. 470
      board/samsung/odroid/odroid.c
  26. 255
      board/samsung/odroid/setup.h
  27. 129
      board/samsung/smdk5420/smdk5420.c
  28. 3
      configs/odroid_defconfig
  29. 143
      doc/README.odroid
  30. 6
      doc/device-tree-bindings/video/exynos-fb.txt
  31. 1
      drivers/video/Makefile
  32. 18
      drivers/video/exynos_fb.c
  33. 43
      drivers/video/exynos_fimd.c
  34. 220
      drivers/video/parade.c
  35. 1
      include/common.h
  36. 2
      include/configs/exynos5250-dt.h
  37. 216
      include/configs/odroid.h
  38. 10
      include/configs/peach-pit.h
  39. 3
      include/configs/s5pc210_universal.h
  40. 3
      include/configs/trats.h
  41. 3
      include/configs/trats2.h
  42. 2
      include/fdtdec.h
  43. 10
      include/samsung/misc.h
  44. 2
      lib/fdtdec.c

@ -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"

@ -82,7 +82,8 @@ static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
* VPLL_CON: MIDV [24:16]
* BPLL_CON: MIDV [25:16]: Exynos5
*/
if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL)
if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL ||
pllreg == SPLL)
mask = 0x3ff;
else
mask = 0x1ff;
@ -391,6 +392,9 @@ static unsigned long exynos5420_get_pll_clk(int pllreg)
r = readl(&clk->rpll_con0);
k = readl(&clk->rpll_con1);
break;
case SPLL:
r = readl(&clk->spll_con0);
break;
default:
printf("Unsupported PLL (%d)\n", pllreg);
return 0;
@ -1027,6 +1031,40 @@ static unsigned long exynos5_get_lcd_clk(void)
return pclk;
}
static unsigned long exynos5420_get_lcd_clk(void)
{
struct exynos5420_clock *clk =
(struct exynos5420_clock *)samsung_get_base_clock();
unsigned long pclk, sclk;
unsigned int sel;
unsigned int ratio;
/*
* CLK_SRC_DISP10
* FIMD1_SEL [4]
* 0: SCLK_RPLL
* 1: SCLK_SPLL
*/
sel = readl(&clk->src_disp10);
sel &= (1 << 4);
if (sel)
sclk = get_pll_clk(SPLL);
else
sclk = get_pll_clk(RPLL);
/*
* CLK_DIV_DISP10
* FIMD1_RATIO [3:0]
*/
ratio = readl(&clk->div_disp10);
ratio = ratio & 0xf;
pclk = sclk / (ratio + 1);
return pclk;
}
void exynos4_set_lcd_clk(void)
{
struct exynos4_clock *clk =
@ -1131,6 +1169,33 @@ void exynos5_set_lcd_clk(void)
clrsetbits_le32(&clk->div_disp1_0, 0xf, 0x0);
}
void exynos5420_set_lcd_clk(void)
{
struct exynos5420_clock *clk =
(struct exynos5420_clock *)samsung_get_base_clock();
unsigned int cfg;
/*
* CLK_SRC_DISP10
* FIMD1_SEL [4]
* 0: SCLK_RPLL
* 1: SCLK_SPLL
*/
cfg = readl(&clk->src_disp10);
cfg &= ~(0x1 << 4);
cfg |= (0 << 4);
writel(cfg, &clk->src_disp10);
/*
* CLK_DIV_DISP10
* FIMD1_RATIO [3:0]
*/
cfg = readl(&clk->div_disp10);
cfg &= ~(0xf << 0);
cfg |= (0 << 0);
writel(cfg, &clk->div_disp10);
}
void exynos4_set_mipi_clk(void)
{
struct exynos4_clock *clk =
@ -1602,16 +1667,24 @@ unsigned long get_lcd_clk(void)
{
if (cpu_is_exynos4())
return exynos4_get_lcd_clk();
else
return exynos5_get_lcd_clk();
else {
if (proid_is_exynos5420())
return exynos5420_get_lcd_clk();
else
return exynos5_get_lcd_clk();
}
}
void set_lcd_clk(void)
{
if (cpu_is_exynos4())
exynos4_set_lcd_clk();
else
exynos5_set_lcd_clk();
else {
if (proid_is_exynos5250())
exynos5_set_lcd_clk();
else if (proid_is_exynos5420())
exynos5420_set_lcd_clk();
}
}
void set_mipi_clk(void)

@ -75,6 +75,9 @@ struct mem_timings {
unsigned spll_mdiv;
unsigned spll_pdiv;
unsigned spll_sdiv;
unsigned rpll_mdiv;
unsigned rpll_pdiv;
unsigned rpll_sdiv;
unsigned pclk_cdrex_ratio;
unsigned direct_cmd_msr[MEM_TIMINGS_MSR_COUNT];

@ -179,6 +179,10 @@ struct mem_timings mem_timings[] = {
.spll_mdiv = 0xc8,
.spll_pdiv = 0x3,
.spll_sdiv = 0x2,
/* RPLL @70.5Mhz */
.rpll_mdiv = 0x5E,
.rpll_pdiv = 0x2,
.rpll_sdiv = 0x4,
.direct_cmd_msr = {
0x00020018, 0x00030000, 0x00010046, 0x00000d70,
@ -800,6 +804,7 @@ static void exynos5420_system_clock_init(void)
writel(mem->ipll_pdiv * PLL_LOCK_FACTOR, &clk->ipll_lock);
writel(mem->spll_pdiv * PLL_LOCK_FACTOR, &clk->spll_lock);
writel(mem->kpll_pdiv * PLL_LOCK_FACTOR, &clk->kpll_lock);
writel(mem->rpll_pdiv * PLL_X_LOCK_FACTOR, &clk->rpll_lock);
setbits_le32(&clk->src_cpu, MUX_HPM_SEL_MASK);
@ -898,6 +903,14 @@ static void exynos5420_system_clock_init(void)
while ((readl(&clk->spll_con0) & PLL_LOCKED) == 0)
;
/* Set RPLL */
writel(RPLL_CON2_VAL, &clk->rpll_con2);
writel(RPLL_CON1_VAL, &clk->rpll_con1);
val = set_pll(mem->rpll_mdiv, mem->rpll_pdiv, mem->rpll_sdiv);
writel(val, &clk->rpll_con0);
while ((readl(&clk->rpll_con0) & PLL_LOCKED) == 0)
;
writel(CLK_DIV_CDREX0_VAL, &clk->div_cdrex0);
writel(CLK_DIV_CDREX1_VAL, &clk->div_cdrex1);

@ -783,7 +783,7 @@
#define CLK_SRC_TOP2_VAL 0x11101000
#define CLK_SRC_TOP3_VAL 0x11111111
#define CLK_SRC_TOP4_VAL 0x11110111
#define CLK_SRC_TOP5_VAL 0x11111100
#define CLK_SRC_TOP5_VAL 0x11111101
#define CLK_SRC_TOP6_VAL 0x11110111
#define CLK_SRC_TOP7_VAL 0x00022200

@ -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;

@ -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;
}

@ -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);

@ -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 \

@ -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>;
};
};

@ -63,6 +63,11 @@
reg = <0x20>;
compatible = "maxim,max98090-codec";
};
edp-lvds-bridge@48 {
compatible = "parade,ps8625";
reg = <0x48>;
};
};
sound@3830000 {
@ -124,4 +129,29 @@
xhci@12400000 {
samsung,vbus-gpio = <&gpio 0x41 0>; /* H01 */
};
fimd@14400000 {
samsung,vl-freq = <60>;
samsung,vl-col = <1366>;
samsung,vl-row = <768>;
samsung,vl-width = <1366>;
samsung,vl-height = <768>;
samsung,vl-clkp;
samsung,vl-dp;
samsung,vl-bpix = <4>;
samsung,vl-hspw = <32>;
samsung,vl-hbpd = <40>;
samsung,vl-hfpd = <40>;
samsung,vl-vspw = <6>;
samsung,vl-vbpd = <10>;
samsung,vl-vfpd = <12>;
samsung,vl-cmd-allow-len = <0xf>;
samsung,winid = <3>;
samsung,interface-mode = <1>;
samsung,dp-enabled = <1>;
samsung,dual-lcd-enabled = <0>;
};
};

@ -113,6 +113,16 @@
status = "disabled";
};
fimdm0_sysmmu@0x14640000 {
compatible = "samsung,sysmmu-v3.3";
reg = <0x14640000 0x100>;
};
fimdm1_sysmmu@0x14680000 {
compatible = "samsung,sysmmu-v3.3";
reg = <0x14680000 0x100>;
};
fimd@14400000 {
/* sysmmu is not used in U-Boot */
samsung,disable-sysmmu;

@ -15,6 +15,7 @@
#define VPLL 4
#define BPLL 5
#define RPLL 6
#define SPLL 7
#define MASK_PRE_RATIO(x) (0xff << ((x << 4) + 8))
#define MASK_RATIO(x) (0xf << (x << 4))

@ -1504,6 +1504,7 @@ static const struct gpio_name_num_table exynos5420_gpio_table[] = {
void gpio_cfg_pin(int gpio, int cfg);
void gpio_set_pull(int gpio, int mode);
void gpio_set_drv(int gpio, int mode);
int gpio_direction_input(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);
int gpio_set_value(unsigned gpio, int value);
int gpio_get_value(unsigned gpio);

@ -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)

@ -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 */

@ -39,5 +39,9 @@ struct exynos5_sysreg {
void set_usbhost_mode(unsigned int mode);
void set_system_display_ctrl(void);
int exynos_lcd_early_init(const void *blob);
/* Initialize the Parade dP<->LVDS bridge if present */
int parade_init(const void *blob);
#endif /* _EXYNOS4_SYSTEM_H */

@ -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*/

@ -1,5 +1,5 @@
ARNDALE BOARD
M: Inderpal Singh <inderpal.singh@linaro.org>
M: Chander Kashyap <k.chander@samsung.com>
S: Maintained
F: board/samsung/arndale/
F: include/configs/arndale.h

@ -20,6 +20,7 @@
#include <asm/arch/mmc.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/power.h>
#include <asm/arch/system.h>
#include <power/pmic.h>
#include <asm/arch/sromc.h>
#include <lcd.h>
@ -137,7 +138,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");
@ -148,6 +151,20 @@ int board_early_init_f(void)
board_i2c_init(gd->fdt_blob);
#endif
#if defined(CONFIG_OF_CONTROL) && defined(CONFIG_EXYNOS_FB)
/*
* board_init_f(arch/arm/lib/board.c) calls lcd_setmem() which needs
* panel_info.vl_col, panel_info.vl_row and panel_info.vl_bpix, to reserve
* FB memory at a very early stage. So, we need to fill panel_info.vl_col,
* panel_info.vl_row and panel_info.vl_bpix before lcd_setmem() is called.
*/
err = exynos_lcd_early_init(gd->fdt_blob);
if (err) {
debug("LCD early init failed\n");
return err;
}
#endif
return exynos_early_init_f();
}
#endif
@ -240,22 +257,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
@ -263,11 +297,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
@ -307,6 +345,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

@ -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,13 +22,53 @@
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)
{
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);
@ -38,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
}

@ -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__ */

@ -10,11 +10,14 @@
#include <i2c.h>
#include <lcd.h>
#include <spi.h>
#include <errno.h>
#include <asm/arch/board.h>
#include <asm/arch/cpu.h>
#include <asm/arch/gpio.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/system.h>
#include <asm/arch/dp_info.h>
#include <power/tps65090_pmic.h>
DECLARE_GLOBAL_DATA_PTR;
@ -40,95 +43,57 @@ int exynos_init(void)
}
#ifdef CONFIG_LCD
void cfg_lcd_gpio(void)
static int has_edp_bridge(void)
{
/* For Backlight */
gpio_cfg_pin(EXYNOS5420_GPIO_B20, S5P_GPIO_OUTPUT);
gpio_set_value(EXYNOS5420_GPIO_B20, 1);
int node;
node = fdtdec_next_compatible(gd->fdt_blob, 0, COMPAT_PARADE_PS8625);
/* LCD power on */
gpio_cfg_pin(EXYNOS5420_GPIO_X15, S5P_GPIO_OUTPUT);
gpio_set_value(EXYNOS5420_GPIO_X15, 1);
/* No node for bridge in device tree. */
if (node <= 0)
return 0;
/* Set Hotplug detect for DP */
gpio_cfg_pin(EXYNOS5420_GPIO_X07, S5P_GPIO_FUNC(0x3));
/* Default is with bridge ic */
return 1;
}
vidinfo_t panel_info = {
.vl_freq = 60,
.vl_col = 2560,
.vl_row = 1600,
.vl_width = 2560,
.vl_height = 1600,
.vl_clkp = CONFIG_SYS_LOW,
.vl_hsp = CONFIG_SYS_LOW,
.vl_vsp = CONFIG_SYS_LOW,
.vl_dp = CONFIG_SYS_LOW,
.vl_bpix = 4, /* LCD_BPP = 2^4, for output conosle on LCD */
/* wDP panel timing infomation */
.vl_hspw = 32,
.vl_hbpd = 80,
.vl_hfpd = 48,
.vl_vspw = 6,
.vl_vbpd = 37,
.vl_vfpd = 3,
.vl_cmd_allow_len = 0xf,
.win_id = 3,
.cfg_gpio = cfg_lcd_gpio,
.backlight_on = NULL,
.lcd_power_on = NULL,
.reset_lcd = NULL,
.dual_lcd_enabled = 0,
.init_delay = 0,
.power_on_delay = 0,
.reset_delay = 0,
.interface_mode = FIMD_RGB_INTERFACE,
.dp_enabled = 1,
};
static struct edp_device_info edp_info = {
.disp_info = {
.h_res = 2560,
.h_sync_width = 32,
.h_back_porch = 80,
.h_front_porch = 48,
.v_res = 1600,
.v_sync_width = 6,
.v_back_porch = 37,
.v_front_porch = 3,
.v_sync_rate = 60,
},
.lt_info = {
.lt_status = DP_LT_NONE,
},
.video_info = {
.master_mode = 0,
.bist_mode = DP_DISABLE,
.bist_pattern = NO_PATTERN,
.h_sync_polarity = 0,
.v_sync_polarity = 0,
.interlaced = 0,
.color_space = COLOR_RGB,
.dynamic_range = VESA,
.ycbcr_coeff = COLOR_YCBCR601,
.color_depth = COLOR_8,
},
};
static struct exynos_dp_platform_data dp_platform_data = {
.phy_enable = set_dp_phy_ctrl,
.edp_dev_info = &edp_info,
};
void init_panel_info(vidinfo_t *vid)
void exynos_lcd_power_on(void)
{
vid->rgb_mode = MODE_RGB_P;
int ret;
#ifdef CONFIG_POWER_TPS65090
ret = tps65090_init();
if (ret < 0) {
printf("%s: tps65090_init() failed\n", __func__);
return;
}
tps65090_fet_enable(6);
#endif
mdelay(5);
/* TODO(ajaykumar.rs@samsung.com): Use device tree */
gpio_direction_output(EXYNOS5420_GPIO_X35, 1); /* EDP_SLP# */
mdelay(10);
gpio_direction_output(EXYNOS5420_GPIO_Y77, 1); /* EDP_RST# */
gpio_direction_input(EXYNOS5420_GPIO_X26); /* EDP_HPD */
gpio_set_pull(EXYNOS5420_GPIO_X26, S5P_GPIO_PULL_NONE);
exynos_set_dp_platform_data(&dp_platform_data);
if (has_edp_bridge())
if (parade_init(gd->fdt_blob))
printf("%s: ps8625_init() failed\n", __func__);
}
void exynos_backlight_on(unsigned int onoff)
{
/* For PWM */
gpio_cfg_pin(EXYNOS5420_GPIO_B20, S5P_GPIO_FUNC(0x1));
gpio_set_value(EXYNOS5420_GPIO_B20, 1);
#ifdef CONFIG_POWER_TPS65090
tps65090_fet_enable(1);
#endif
}
#endif

@ -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

@ -55,6 +55,12 @@ Board(panel specific):
samsung,pclk-name: parent clock identifier: 1(MPLL), 2(EPLL), 3(VPLL)
samsung,sclk-div: parent_clock/source_clock ratio
samsung,dual-lcd-enabled: 1 if you support two LCD, else 0
samsung,disable-sysmmu: Define this if you want to disable FIMD sysmmu.
(needed for Exynos5420 and newer versions)
Add the required FIMD sysmmu nodes to be
disabled with compatible string
"samsung,sysmmu-v3.3", with a "reg" property
holding the register address of FIMD sysmmu.
Example:
SOC specific part:

@ -42,3 +42,4 @@ obj-$(CONFIG_VIDEO_TEGRA) += tegra.o
obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
obj-$(CONFIG_FORMIKE) += formike.o
obj-$(CONFIG_AM335X_LCD) += am335x-fb.o
obj-$(CONFIG_VIDEO_PARADE) += parade.o

@ -27,17 +27,13 @@ DECLARE_GLOBAL_DATA_PTR;
static unsigned int panel_width, panel_height;
/*
* board_init_f(arch/arm/lib/board.c) calls lcd_setmem() which needs
* panel_info.vl_col, panel_info.vl_row and panel_info.vl_bpix to reserve
* FB memory at a very early stage, i.e even before exynos_fimd_parse_dt()
* is called. So, we are forced to statically assign it.
*/
#ifdef CONFIG_OF_CONTROL
vidinfo_t panel_info = {
.vl_col = LCD_XRES,
.vl_row = LCD_YRES,
.vl_bpix = LCD_COLOR16,
/*
* Insert a value here so that we don't end up in the BSS
* Reference: drivers/video/tegra.c
*/
.vl_col = -1,
};
#endif
@ -141,7 +137,7 @@ static void lcd_panel_on(vidinfo_t *vid)
}
#ifdef CONFIG_OF_CONTROL
int exynos_fimd_parse_dt(const void *blob)
int exynos_lcd_early_init(const void *blob)
{
unsigned int node;
node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS_FIMD);
@ -286,8 +282,6 @@ void lcd_ctrl_init(void *lcdbase)
set_lcd_clk();
#ifdef CONFIG_OF_CONTROL
if (exynos_fimd_parse_dt(gd->fdt_blob))
debug("Can't get proper panel info\n");
#ifdef CONFIG_EXYNOS_MIPI_DSIM
exynos_init_dsim_platform_data(&panel_info);
#endif

@ -251,6 +251,45 @@ void exynos_fimd_window_off(unsigned int win_id)
writel(cfg, &fimd_ctrl->winshmap);
}
#ifdef CONFIG_OF_CONTROL
/*
* The reset value for FIMD SYSMMU register MMU_CTRL is 3
* on Exynos5420 and newer versions.
* This means FIMD SYSMMU is on by default on Exynos5420
* and newer versions.
* Since in u-boot we don't use SYSMMU, we should disable
* those FIMD SYSMMU.
* Note that there are 2 SYSMMU for FIMD: m0 and m1.
* m0 handles windows 0 and 4, and m1 handles windows 1, 2 and 3.
* We disable both of them here.
*/
void exynos_fimd_disable_sysmmu(void)
{
u32 *sysmmufimd;
unsigned int node;
int node_list[2];
int count;
int i;
count = fdtdec_find_aliases_for_id(gd->fdt_blob, "fimd",
COMPAT_SAMSUNG_EXYNOS_SYSMMU, node_list, 2);
for (i = 0; i < count; i++) {
node = node_list[i];
if (node <= 0) {
debug("Can't get device node for fimd sysmmu\n");
return;
}
sysmmufimd = (u32 *)fdtdec_get_addr(gd->fdt_blob, node, "reg");
if (!sysmmufimd) {
debug("Can't get base address for sysmmu fimdm0");
return;
}
writel(0x0, sysmmufimd);
}
}
#endif
void exynos_fimd_lcd_init(vidinfo_t *vid)
{
@ -268,6 +307,10 @@ void exynos_fimd_lcd_init(vidinfo_t *vid)
node, "reg");
if (fimd_ctrl == NULL)
debug("Can't get the FIMD base address\n");
if (fdtdec_get_bool(gd->fdt_blob, node, "samsung,disable-sysmmu"))
exynos_fimd_disable_sysmmu();
#else
fimd_ctrl = (struct exynos_fb *)samsung_get_base_fimd();
#endif

@ -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;
}

@ -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);

@ -61,8 +61,6 @@
#ifdef CONFIG_LCD
#define CONFIG_EXYNOS_FB
#define CONFIG_EXYNOS_DP
#define LCD_XRES 2560
#define LCD_YRES 1600
#define LCD_BPP LCD_COLOR16
#endif

@ -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 */

@ -22,4 +22,14 @@
#define CONFIG_SYS_PROMPT "Peach # "
#define CONFIG_IDENT_STRING " for Peach"
#define CONFIG_VIDEO_PARADE
/* Display */
#define CONFIG_LCD
#ifdef CONFIG_LCD
#define CONFIG_EXYNOS_FB
#define CONFIG_EXYNOS_DP
#define LCD_BPP LCD_COLOR16
#endif
#endif /* __CONFIG_PEACH_PIT_H */

@ -247,7 +247,4 @@ int universal_spi_read(void);
#define CONFIG_VIDEO_BMP_GZIP
#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE ((500 * 160 * 4) + 54)
#define LCD_XRES 480
#define LCD_YRES 800
#endif /* __CONFIG_H */

@ -261,7 +261,4 @@
#define CONFIG_VIDEO_BMP_GZIP
#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE ((500 * 160 * 4) + 54)
#define LCD_XRES 720
#define LCD_YRES 1280
#endif /* __CONFIG_H */

@ -241,7 +241,4 @@ int get_soft_i2c_sda_pin(void);
#define CONFIG_VIDEO_BMP_GZIP
#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE ((500 * 160 * 4) + 54)
#define LCD_XRES 720
#define LCD_YRES 1280
#endif /* __CONFIG_H */

@ -94,6 +94,8 @@ enum fdt_compat_id {
COMPAT_SANDBOX_LCD_SDL, /* Sandbox LCD emulation with SDL */
COMPAT_TI_TPS65090, /* Texas Instrument TPS65090 */
COMPAT_NXP_PTN3460, /* NXP PTN3460 DP/LVDS bridge */
COMPAT_SAMSUNG_EXYNOS_SYSMMU, /* Exynos sysmmu */
COMPAT_PARADE_PS8625, /* Parade PS8622 EDP->LVDS bridge */
COMPAT_COUNT,
};

@ -28,4 +28,14 @@ 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
#ifdef CONFIG_BOARD_TYPES
void set_board_type(void);
const char *get_board_type(void);
#endif
#endif /* __SAMSUNG_MISC_COMMON_H__ */

@ -70,6 +70,8 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(SANDBOX_LCD_SDL, "sandbox,lcd-sdl"),
COMPAT(TI_TPS65090, "ti,tps65090"),
COMPAT(COMPAT_NXP_PTN3460, "nxp,ptn3460"),
COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"),
COMPAT(PARADE_PS8625, "parade,ps8625"),
};
const char *fdtdec_get_compatible(enum fdt_compat_id id)

Loading…
Cancel
Save