GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -0,0 +1,12 @@
if TARGET_ARNDALE
config SYS_BOARD
default "arndale"
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "arndale"
endif
@@ -0,0 +1,6 @@
ARNDALE BOARD
M: Krzysztof Kozlowski <krzk@kernel.org>
S: Maintained
F: board/samsung/arndale/
F: include/configs/arndale.h
F: configs/arndale_defconfig
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2013 Samsung Electronics
obj-y += arndale_spl.o
obj-y += arndale.o
@@ -0,0 +1,133 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2013 Samsung Electronics
*/
#include <common.h>
#include <cpu_func.h>
#include <usb.h>
#include <asm/gpio.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/dwmmc.h>
#include <asm/arch/power.h>
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_USB_EHCI_EXYNOS
int board_usb_init(int index, enum usb_init_type init)
{
/* Configure gpios for usb 3503 hub:
* disconnect, toggle reset and connect
*/
gpio_request(EXYNOS5_GPIO_D17, "usb_connect");
gpio_request(EXYNOS5_GPIO_X35, "usb_reset");
gpio_direction_output(EXYNOS5_GPIO_D17, 0);
gpio_direction_output(EXYNOS5_GPIO_X35, 0);
gpio_direction_output(EXYNOS5_GPIO_X35, 1);
gpio_direction_output(EXYNOS5_GPIO_D17, 1);
return 0;
}
#endif
int board_init(void)
{
gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
return 0;
}
int dram_init(void)
{
int i;
u32 addr;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
addr = CONFIG_SYS_SDRAM_BASE + (i * SDRAM_BANK_SIZE);
gd->ram_size += get_ram_size((long *)addr, SDRAM_BANK_SIZE);
}
return 0;
}
int power_init_board(void)
{
set_ps_hold_ctrl();
return 0;
}
int dram_init_banksize(void)
{
int i;
u32 addr, size;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
addr = CONFIG_SYS_SDRAM_BASE + (i * SDRAM_BANK_SIZE);
size = get_ram_size((long *)addr, SDRAM_BANK_SIZE);
gd->bd->bi_dram[i].start = addr;
gd->bd->bi_dram[i].size = size;
}
return 0;
}
#ifdef CONFIG_MMC
int board_mmc_init(bd_t *bis)
{
int ret;
/* dwmmc initializattion for available channels */
ret = exynos_dwmmc_init(gd->fdt_blob);
if (ret)
debug("dwmmc init failed\n");
return ret;
}
#endif
static int board_uart_init(void)
{
int err = 0, uart_id;
for (uart_id = PERIPH_ID_UART0; uart_id <= PERIPH_ID_UART3; uart_id++) {
err = exynos_pinmux_config(uart_id, PINMUX_FLAG_NONE);
if (err) {
debug("UART%d not configured\n",
(uart_id - PERIPH_ID_UART0));
return err;
}
}
return err;
}
#ifdef CONFIG_BOARD_EARLY_INIT_F
int board_early_init_f(void)
{
int err;
err = board_uart_init();
if (err) {
debug("UART init failed\n");
return err;
}
return err;
}
#endif
#ifdef CONFIG_DISPLAY_BOARDINFO
int checkboard(void)
{
printf("\nBoard: Arndale\n");
return 0;
}
#endif
#ifdef CONFIG_S5P_PA_SYSRAM
void smp_set_core_boot_addr(unsigned long addr, int corenr)
{
writel(addr, CONFIG_S5P_PA_SYSRAM);
/* make sure this write is really executed */
__asm__ volatile ("dsb\n");
}
#endif
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2012 The Chromium OS Authors.
*/
#include <common.h>
#include <asm/arch/spl.h>
#define SIGNATURE 0xdeadbeef
/* Parameters of early board initialization in SPL */
static struct spl_machine_param machine_param
__attribute__((section(".machine_param"))) = {
.signature = SIGNATURE,
.version = 1,
.params = "vmubfasirM",
.size = sizeof(machine_param),
.mem_iv_size = 0x1f,
.mem_type = DDR_MODE_DDR3,
/*
* Set uboot_size to 0x100000 bytes.
*
* This is an overly conservative value chosen to accommodate all
* possible U-Boot image. You are advised to set this value to a
* smaller realistic size via scripts that modifies the .machine_param
* section of output U-Boot image.
*/
.uboot_size = 0x100000,
.boot_source = BOOT_MODE_OM,
.frequency_mhz = 800,
.arm_freq_mhz = 1000,
.serial_base = 0x12c30000,
.i2c_base = 0x12c60000,
.mem_manuf = MEM_MANUF_SAMSUNG,
};
struct spl_machine_param *spl_get_machine_params(void)
{
if (machine_param.signature != SIGNATURE) {
/* Will hang if SIGNATURE dont match */
while (1)
;
}
return &machine_param;
}
@@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2012 Samsung Electronics
# Lukasz Majewski <l.majewski@samsung.com>
obj-$(CONFIG_USB_GADGET_DOWNLOAD) += gadget.o
obj-$(CONFIG_MISC_COMMON) += misc.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_BOARD_COMMON) += board.o
ifdef CONFIG_EXYNOS5_DT
obj-y += exynos5-dt.o
obj-$(CONFIG_BOARD_TYPES) += exynos5-dt-types.o
endif
endif
@@ -0,0 +1,361 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2013 SAMSUNG Electronics
* Rajeshwari Shinde <rajeshwari.s@samsung.com>
*/
#include <common.h>
#include <cros_ec.h>
#include <errno.h>
#include <fdtdec.h>
#include <init.h>
#include <spi.h>
#include <tmu.h>
#include <netdev.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/arch/board.h>
#include <asm/arch/cpu.h>
#include <asm/arch/dwmmc.h>
#include <asm/arch/mmc.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/power.h>
#include <asm/arch/system.h>
#include <asm/arch/sromc.h>
#include <lcd.h>
#include <i2c.h>
#include <usb.h>
#include <dwc3-uboot.h>
#include <samsung/misc.h>
#include <dm/pinctrl.h>
#include <dm.h>
DECLARE_GLOBAL_DATA_PTR;
__weak int exynos_early_init_f(void)
{
return 0;
}
__weak int exynos_power_init(void)
{
return 0;
}
#if defined CONFIG_EXYNOS_TMU
/* Boot Time Thermal Analysis for SoC temperature threshold breach */
static void boot_temp_check(void)
{
int temp;
switch (tmu_monitor(&temp)) {
case TMU_STATUS_NORMAL:
break;
case TMU_STATUS_TRIPPED:
/*
* Status TRIPPED ans WARNING means corresponding threshold
* breach
*/
puts("EXYNOS_TMU: TRIPPING! Device power going down ...\n");
set_ps_hold_ctrl();
hang();
break;
case TMU_STATUS_WARNING:
puts("EXYNOS_TMU: WARNING! Temperature very high\n");
break;
case TMU_STATUS_INIT:
/*
* TMU_STATUS_INIT means something is wrong with temperature
* sensing and TMU status was changed back from NORMAL to INIT.
*/
puts("EXYNOS_TMU: WARNING! Temperature sensing not done\n");
break;
default:
debug("EXYNOS_TMU: Unknown TMU state\n");
}
}
#endif
int board_init(void)
{
gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
#if defined CONFIG_EXYNOS_TMU
if (tmu_init(gd->fdt_blob) != TMU_STATUS_NORMAL) {
debug("%s: Failed to init TMU\n", __func__);
return -1;
}
boot_temp_check();
#endif
#ifdef CONFIG_TZSW_RESERVED_DRAM_SIZE
/* The last few MB of memory can be reserved for secure firmware */
ulong size = CONFIG_TZSW_RESERVED_DRAM_SIZE;
gd->ram_size -= size;
gd->bd->bi_dram[CONFIG_NR_DRAM_BANKS - 1].size -= size;
#endif
return exynos_init();
}
int dram_init(void)
{
unsigned int i;
unsigned long addr;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
addr = CONFIG_SYS_SDRAM_BASE + (i * SDRAM_BANK_SIZE);
gd->ram_size += get_ram_size((long *)addr, SDRAM_BANK_SIZE);
}
return 0;
}
int dram_init_banksize(void)
{
unsigned int i;
unsigned long addr, size;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
addr = CONFIG_SYS_SDRAM_BASE + (i * SDRAM_BANK_SIZE);
size = get_ram_size((long *)addr, SDRAM_BANK_SIZE);
gd->bd->bi_dram[i].start = addr;
gd->bd->bi_dram[i].size = size;
}
return 0;
}
static int board_uart_init(void)
{
#ifndef CONFIG_PINCTRL_EXYNOS
int err, uart_id, ret = 0;
for (uart_id = PERIPH_ID_UART0; uart_id <= PERIPH_ID_UART3; uart_id++) {
err = exynos_pinmux_config(uart_id, PINMUX_FLAG_NONE);
if (err) {
debug("UART%d not configured\n",
(uart_id - PERIPH_ID_UART0));
ret |= err;
}
}
return ret;
#else
return 0;
#endif
}
#ifdef CONFIG_BOARD_EARLY_INIT_F
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");
return err;
}
#ifdef CONFIG_SYS_I2C_INIT_BOARD
board_i2c_init(gd->fdt_blob);
#endif
return exynos_early_init_f();
}
#endif
#if defined(CONFIG_POWER) || defined(CONFIG_DM_PMIC)
int power_init_board(void)
{
set_ps_hold_ctrl();
return exynos_power_init();
}
#endif
#ifdef CONFIG_SMC911X
static int decode_sromc(const void *blob, struct fdt_sromc *config)
{
int err;
int node;
node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SROMC);
if (node < 0) {
debug("Could not find SROMC node\n");
return node;
}
config->bank = fdtdec_get_int(blob, node, "bank", 0);
config->width = fdtdec_get_int(blob, node, "width", 2);
err = fdtdec_get_int_array(blob, node, "srom-timing", config->timing,
FDT_SROM_TIMING_COUNT);
if (err < 0) {
debug("Could not decode SROMC configuration Error: %s\n",
fdt_strerror(err));
return -FDT_ERR_NOTFOUND;
}
return 0;
}
#endif
int board_eth_init(bd_t *bis)
{
#ifdef CONFIG_SMC911X
u32 smc_bw_conf, smc_bc_conf;
struct fdt_sromc config;
fdt_addr_t base_addr;
int node;
node = decode_sromc(gd->fdt_blob, &config);
if (node < 0) {
debug("%s: Could not find sromc configuration\n", __func__);
return 0;
}
node = fdtdec_next_compatible(gd->fdt_blob, node, COMPAT_SMSC_LAN9215);
if (node < 0) {
debug("%s: Could not find lan9215 configuration\n", __func__);
return 0;
}
/* We now have a node, so any problems from now on are errors */
base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg");
if (base_addr == FDT_ADDR_T_NONE) {
debug("%s: Could not find lan9215 address\n", __func__);
return -1;
}
/* Ethernet needs data bus width of 16 bits */
if (config.width != 2) {
debug("%s: Unsupported bus width %d\n", __func__,
config.width);
return -1;
}
smc_bw_conf = SROMC_DATA16_WIDTH(config.bank)
| SROMC_BYTE_ENABLE(config.bank);
smc_bc_conf = SROMC_BC_TACS(config.timing[FDT_SROM_TACS]) |
SROMC_BC_TCOS(config.timing[FDT_SROM_TCOS]) |
SROMC_BC_TACC(config.timing[FDT_SROM_TACC]) |
SROMC_BC_TCOH(config.timing[FDT_SROM_TCOH]) |
SROMC_BC_TAH(config.timing[FDT_SROM_TAH]) |
SROMC_BC_TACP(config.timing[FDT_SROM_TACP]) |
SROMC_BC_PMC(config.timing[FDT_SROM_PMC]);
/* Select and configure the SROMC bank */
exynos_pinmux_config(PERIPH_ID_SROMC, config.bank);
s5p_config_sromc(config.bank, smc_bw_conf, smc_bc_conf);
return smc911x_initialize(0, base_addr);
#endif
return 0;
}
#if defined(CONFIG_DISPLAY_BOARDINFO) || defined(CONFIG_DISPLAY_BOARDINFO_LATE)
int checkboard(void)
{
if (IS_ENABLED(CONFIG_BOARD_TYPES)) {
const char *board_info;
if (IS_ENABLED(CONFIG_DISPLAY_BOARDINFO_LATE)) {
/*
* Printing type requires having revision, although
* this will succeed only if done late.
* Otherwise revision will be set in misc_init_r().
*/
set_board_revision();
}
board_info = get_board_type();
if (board_info)
printf("Type: %s\n", board_info);
}
return 0;
}
#endif
#ifdef CONFIG_BOARD_LATE_INIT
int board_late_init(void)
{
struct udevice *dev;
int ret;
stdio_print_current_devices();
ret = uclass_first_device_err(UCLASS_CROS_EC, &dev);
if (ret && ret != -ENODEV) {
/* Force console on */
gd->flags &= ~GD_FLG_SILENT;
printf("cros-ec communications failure %d\n", ret);
puts("\nPlease reset with Power+Refresh\n\n");
panic("Cannot init cros-ec device");
return -1;
}
return 0;
}
#endif
#ifdef CONFIG_MISC_INIT_R
int misc_init_r(void)
{
if (IS_ENABLED(CONFIG_BOARD_TYPES) &&
!IS_ENABLED(CONFIG_DISPLAY_BOARDINFO_LATE)) {
/*
* If revision was not set by late display boardinfo,
* set it here. At this point regulators should be already
* available.
*/
set_board_revision();
}
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
set_board_info();
#endif
#ifdef CONFIG_LCD_MENU
keys_init();
check_boot_mode();
#endif
#ifdef CONFIG_CMD_BMP
if (panel_info.logo_on)
draw_logo();
#endif
return 0;
}
#endif
void reset_misc(void)
{
struct gpio_desc gpio = {};
int node;
node = fdt_node_offset_by_compatible(gd->fdt_blob, 0,
"samsung,emmc-reset");
if (node < 0)
return;
gpio_request_by_name_nodev(offset_to_ofnode(node), "reset-gpio", 0,
&gpio, GPIOD_IS_OUT);
if (dm_gpio_is_valid(&gpio)) {
/*
* Reset eMMC
*
* FIXME: Need to optimize delay time. Minimum 1usec pulse is
* required by 'JEDEC Standard No.84-A441' (eMMC)
* document but real delay time is expected to greater
* than 1usec.
*/
dm_gpio_set_value(&gpio, 0);
mdelay(10);
dm_gpio_set_value(&gpio, 1);
}
}
int board_usb_cleanup(int index, enum usb_init_type init)
{
#ifdef CONFIG_USB_DWC3
dwc3_uboot_exit(index);
#endif
return 0;
}
@@ -0,0 +1,92 @@
# This is an example file to generate boot.scr - a boot script for U-Boot
# Generate boot.scr:
# ./tools/mkimage -c none -A arm -T script -d autoboot.cmd boot.scr
#
# It requires a list of environment variables to be defined before load:
# platform dependent: board_name, fdtfile, console
# system dependent: mmcbootdev, mmcbootpart, mmcrootdev, mmcrootpart, rootfstype
#
setenv fdtaddr "40800000"
setenv initrdname "uInitrd"
setenv initrdaddr "42000000"
setenv loaddtb "load mmc ${mmcbootdev}:${mmcbootpart} ${fdtaddr} ${fdtfile}"
setenv loadinitrd "load mmc ${mmcbootdev}:${mmcbootpart} ${initrdaddr} ${initrdname}"
setenv loadkernel "load mmc ${mmcbootdev}:${mmcbootpart} '${kerneladdr}' '${kernelname}'"
setenv kernel_args "setenv bootargs ${console} root=/dev/mmcblk${mmcrootdev}p${mmcrootpart} rootfstype=${rootfstype} rootwait ${opts}"
#### Routine: check_dtb - check that target.dtb exists on boot partition
setenv check_dtb "
if test -e mmc '${mmcbootdev}':'${mmcbootpart}' '${fdtfile}'; then
run loaddtb;
setenv fdt_addr ${fdtaddr};
else
echo Warning! Booting without DTB: '${fdtfile}'!;
setenv fdt_addr;
fi;"
#### Routine: check_ramdisk - check that uInitrd exists on boot partition
setenv check_ramdisk "
if test -e mmc '${mmcbootdev}':'${mmcbootpart}' '${initrdname}'; then
echo "Found ramdisk image.";
run loadinitrd;
setenv initrd_addr ${initrdaddr};
else
echo Warning! Booting without RAMDISK: '${initrdname}'!;
setenv initrd_addr -;
fi;"
#### Routine: boot_fit - check that env $board_name is set and boot proper config of ITB image
setenv setboot_fit "
if test -e '${board_name}'; then
setenv fdt_addr ;
setenv initrd_addr ;
setenv kerneladdr 0x42000000;
setenv kernelname Image.itb;
setenv itbcfg "\"#${board_name}\"";
setenv imgbootcmd bootm;
else
echo Warning! Variable: \$board_name is undefined!;
fi"
#### Routine: setboot_uimg - prepare env to boot uImage
setenv setboot_uimg "
setenv kerneladdr 0x40007FC0;
setenv kernelname uImage;
setenv itbcfg ;
setenv imgbootcmd bootm;
run check_dtb;
run check_ramdisk;"
#### Routine: setboot_zimg - prepare env to boot zImage
setenv setboot_zimg "
setenv kerneladdr 0x40007FC0;
setenv kernelname zImage;
setenv itbcfg ;
setenv imgbootcmd bootz;
run check_dtb;
run check_ramdisk;"
#### Routine: boot_img - boot the kernel after env setup
setenv boot_img "
run loadkernel;
run kernel_args;
'${imgbootcmd}' '${kerneladdr}${itbcfg}' '${initrd_addr}' '${fdt_addr}';"
#### Routine: autoboot - choose proper boot path
setenv autoboot "
if test -e mmc ${mmcbootdev}:${mmcbootpart} Image.itb; then
echo Found kernel image: Image.itb;
run setboot_fit;
run boot_img;
elif test -e mmc ${mmcbootdev}:${mmcbootpart} zImage; then
echo Found kernel image: zImage;
run setboot_zimg;
run boot_img;
elif test -e mmc ${mmcbootdev}:${mmcbootpart} uImage; then
echo Found kernel image: uImage;
run setboot_uimg;
run boot_img;
fi;"
#### Execute the defined autoboot macro
run autoboot
@@ -0,0 +1,10 @@
setenv kernelname zImage;
setenv boot_kernel "setenv bootargs \"${console} root=/dev/mmcblk${mmcrootdev}p${mmcrootpart} rootfstype=${rootfstype} rootwait ${opts}\";
load mmc ${mmcbootdev}:${mmcbootpart} 0x40007FC0 '${kernelname}';
if load mmc ${mmcbootdev}:${mmcbootpart} 40800000 ${fdtfile}; then
bootz 0x40007FC0 - 40800000;
else
echo Warning! Booting without DTB: '${fdtfile}'!;
bootz 0x40007FC0 -;
fi;"
run boot_kernel;
@@ -0,0 +1,9 @@
mmcboot=setenv bootargs root=/dev/mmcblk${mmcdev}p${mmcrootpart} ${rootfstype} rootwait ${console}; run loaduimage; bootm 0x40007FC0
rootfstype=ext4
loaduimage=ext4load mmc ${mmcdev}:${mmcbootpart} 0x40007FC0 uImage
mmcdev=0
mmcbootpart=2
mmcrootpart=5
console=console=ttySAC2,115200n8
bootcmd=run mmcboot
dfu_alt_info=u-boot mmc 80 800;params.bin mmc 0x38 0x8;uImage ext4 0 2
@@ -0,0 +1,58 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
*
* Copyright (C) 2012 Samsung Electronics
*
* Based on arch/arm/cpu/armv7/omap-common/u-boot-spl.lds
*/
MEMORY { .sram : ORIGIN = IMAGE_TEXT_BASE, \
LENGTH = CONFIG_SPL_MAX_FOOTPRINT }
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
.text :
{
__start = .;
*(.vectors)
arch/arm/cpu/armv7/start.o (.text*)
*(.text*)
} >.sram
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
. = ALIGN(4);
.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
} >.sram
. = ALIGN(4);
.machine_param : { *(.machine_param) } >.sram
. = ALIGN(4);
__image_copy_end = .;
.end :
{
*(.__end)
} >.sram
.bss :
{
. = ALIGN(4);
__bss_start = .;
*(.bss*)
. = ALIGN(4);
__bss_end = .;
} >.sram
}
@@ -0,0 +1,264 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2015 Samsung Electronics
* Przemyslaw Marczak <p.marczak@samsung.com>
*/
#include <common.h>
#include <adc.h>
#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <power/pmic.h>
#include <power/regulator.h>
#include <power/s2mps11.h>
#include <samsung/exynos5-dt-types.h>
#include <samsung/misc.h>
DECLARE_GLOBAL_DATA_PTR;
static const struct udevice_id board_ids[] = {
{ .compatible = "samsung,odroidxu3", .data = EXYNOS5_BOARD_ODROID_XU3 },
{ .compatible = "samsung,exynos5", .data = EXYNOS5_BOARD_GENERIC },
{ },
};
/**
* Odroix XU3/XU4/HC1/HC2 board revisions (from HC1+_HC2_MAIN_REV0.1_20171017.pdf):
* Rev ADCmax Board
* 0.1 0 XU3 0.1
* 0.2 372 XU3 0.2 | XU3L - no DISPLAYPORT (probe I2C0:0x40 / INA231)
* 0.3 1280 XU4 0.1
* 0.4 739 XU4 0.2
* 0.5 1016 XU4+Air0.1 (Passive cooling)
* 0.6 1309 XU4-HC1 0.1
* 0.7 1470 XU4-HC1+ 0.1 (HC2)
* Use +1% for ADC value tolerance in the array below, the code loops until
* the measured ADC value is lower than then ADCmax from the array.
*/
struct odroid_rev_info odroid_info[] = {
{ EXYNOS5_BOARD_ODROID_XU3_REV01, 1, 10, "xu3" },
{ EXYNOS5_BOARD_ODROID_XU3_REV02, 2, 375, "xu3" },
{ EXYNOS5_BOARD_ODROID_XU4_REV01, 1, 1293, "xu4" },
{ EXYNOS5_BOARD_ODROID_HC1_REV01, 1, 1322, "hc1" },
{ EXYNOS5_BOARD_ODROID_HC2_REV01, 1, 1484, "hc1" },
{ EXYNOS5_BOARD_ODROID_UNKNOWN, 0, 4095, "unknown" },
};
static unsigned int odroid_get_rev(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
if (odroid_info[i].board_type == gd->board_type)
return odroid_info[i].board_rev;
}
return 0;
}
/*
* Read ADC at least twice and check the resuls. If regulator providing voltage
* on to measured point was just turned on, first reads might require time
* to stabilize.
*/
static int odroid_get_adc_val(unsigned int *adcval)
{
unsigned int adcval_prev = 0;
int ret, retries = 20;
ret = adc_channel_single_shot("adc", CONFIG_ODROID_REV_AIN,
&adcval_prev);
if (ret)
return ret;
while (retries--) {
mdelay(5);
ret = adc_channel_single_shot("adc", CONFIG_ODROID_REV_AIN,
adcval);
if (ret)
return ret;
/*
* If difference between ADC reads is less than 3%,
* accept the result
*/
if ((100 * abs(*adcval - adcval_prev) / adcval_prev) < 3)
return ret;
adcval_prev = *adcval;
}
return ret;
}
static int odroid_get_board_type(void)
{
unsigned int adcval;
int ret, i;
ret = odroid_get_adc_val(&adcval);
if (ret)
goto rev_default;
for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
/* ADC tolerance: +1% */
if (adcval < odroid_info[i].adc_val)
return odroid_info[i].board_type;
}
rev_default:
return EXYNOS5_BOARD_ODROID_XU3;
}
/**
* odroid_get_type_str - returns pointer to one of the board type string.
* Board types: "xu3", "xu3-lite", "xu4". However the "xu3lite" can be
* detected only when the i2c controller is ready to use. Fortunately,
* XU3 and XU3L are compatible, and the information about board lite
* revision is needed before booting the linux, to set proper environment
* variable: $fdtfile.
*/
static const char *odroid_get_type_str(void)
{
const char *type_xu3l = "xu3-lite";
struct udevice *dev, *chip;
int i, ret;
if (gd->board_type != EXYNOS5_BOARD_ODROID_XU3_REV02)
goto exit;
ret = pmic_get("s2mps11", &dev);
if (ret)
goto exit;
/* Enable LDO26: 3.0V */
ret = pmic_reg_write(dev, S2MPS11_REG_L26CTRL,
S2MPS11_LDO26_ENABLE);
if (ret)
goto exit;
/* Check XU3Lite by probe INA231 I2C0:0x40 */
ret = uclass_get_device(UCLASS_I2C, 0, &dev);
if (ret)
goto exit;
ret = dm_i2c_probe(dev, 0x40, 0x0, &chip);
if (ret)
return type_xu3l;
exit:
for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
if (odroid_info[i].board_type == gd->board_type)
return odroid_info[i].name;
}
return NULL;
}
bool board_is_odroidxu3(void)
{
if (gd->board_type >= EXYNOS5_BOARD_ODROID_XU3 &&
gd->board_type <= EXYNOS5_BOARD_ODROID_XU3_REV02)
return true;
return false;
}
bool board_is_odroidxu4(void)
{
if (gd->board_type == EXYNOS5_BOARD_ODROID_XU4_REV01)
return true;
return false;
}
bool board_is_odroidhc1(void)
{
if (gd->board_type == EXYNOS5_BOARD_ODROID_HC1_REV01)
return true;
return false;
}
bool board_is_odroidhc2(void)
{
if (gd->board_type == EXYNOS5_BOARD_ODROID_HC2_REV01)
return true;
return false;
}
bool board_is_generic(void)
{
if (gd->board_type == EXYNOS5_BOARD_GENERIC)
return true;
return false;
}
/**
* get_board_rev() - return detected board revision.
*
* @return: return board revision number for XU3 or 0 for generic
*/
u32 get_board_rev(void)
{
if (board_is_generic())
return 0;
return odroid_get_rev();
}
/**
* get_board_type() - returns board type string.
*
* @return: return board type string for XU3 or empty string for generic
*/
const char *get_board_type(void)
{
const char *generic = "";
if (board_is_generic())
return generic;
return odroid_get_type_str();
}
/**
* set_board_type() - set board type in gd->board_type.
* As default type set EXYNOS5_BOARD_GENERIC. If Odroid is detected,
* set its proper type based on device tree.
*
* This might be called early when some more specific ways to detect revision
* are not yet available.
*/
void set_board_type(void)
{
const struct udevice_id *of_match = board_ids;
int ret;
gd->board_type = EXYNOS5_BOARD_GENERIC;
while (of_match->compatible) {
ret = fdt_node_check_compatible(gd->fdt_blob, 0,
of_match->compatible);
if (ret)
of_match++;
gd->board_type = of_match->data;
break;
}
}
/**
* set_board_revision() - set detailed board type in gd->board_type.
* Should be called when resources (e.g. regulators) are available
* so ADC can be used to detect the specific revision of a board.
*/
void set_board_revision(void)
{
if (board_is_odroidxu3())
gd->board_type = odroid_get_board_type();
}
@@ -0,0 +1,186 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2012 Samsung Electronics
*/
#include <common.h>
#include <dm.h>
#include <dwc3-uboot.h>
#include <env.h>
#include <fdtdec.h>
#include <asm/io.h>
#include <errno.h>
#include <i2c.h>
#include <mmc.h>
#include <netdev.h>
#include <samsung-usb-phy-uboot.h>
#include <spi.h>
#include <usb.h>
#include <video_bridge.h>
#include <asm/gpio.h>
#include <asm/arch/cpu.h>
#include <asm/arch/dwmmc.h>
#include <asm/arch/mmc.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/power.h>
#include <asm/arch/sromc.h>
#include <power/pmic.h>
#include <power/max77686_pmic.h>
#include <power/regulator.h>
#include <power/s2mps11.h>
#include <power/s5m8767.h>
#include <samsung/exynos5-dt-types.h>
#include <samsung/misc.h>
#include <tmu.h>
DECLARE_GLOBAL_DATA_PTR;
int exynos_init(void)
{
return 0;
}
static int exynos_set_regulator(const char *name, uint uv)
{
struct udevice *dev;
int ret;
ret = regulator_get_by_platname(name, &dev);
if (ret) {
debug("%s: Cannot find regulator %s\n", __func__, name);
return ret;
}
ret = regulator_set_value(dev, uv);
if (ret) {
debug("%s: Cannot set regulator %s\n", __func__, name);
return ret;
}
return 0;
}
int exynos_power_init(void)
{
struct udevice *dev;
int ret;
#ifdef CONFIG_PMIC_S2MPS11
ret = pmic_get("s2mps11_pmic", &dev);
#else
ret = pmic_get("max77686", &dev);
if (!ret) {
/* TODO(sjg@chromium.org): Move into the clock/pmic API */
ret = pmic_clrsetbits(dev, MAX77686_REG_PMIC_32KHZ, 0,
MAX77686_32KHCP_EN);
if (ret)
return ret;
ret = pmic_clrsetbits(dev, MAX77686_REG_PMIC_BBAT, 0,
MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V);
if (ret)
return ret;
} else {
ret = pmic_get("s5m8767-pmic", &dev);
/* TODO(sjg@chromium.org): Use driver model to access clock */
#ifdef CONFIG_PMIC_S5M8767
if (!ret)
s5m8767_enable_32khz_cp(dev);
#endif
}
#endif /* CONFIG_PMIC_S2MPS11 */
if (ret == -ENODEV)
return 0;
ret = regulators_enable_boot_on(false);
if (ret)
return ret;
ret = exynos_set_regulator("vdd_mif", 1100000);
if (ret)
return ret;
ret = exynos_set_regulator("vdd_arm", 1300000);
if (ret)
return ret;
ret = exynos_set_regulator("vdd_int", 1012500);
if (ret)
return ret;
ret = exynos_set_regulator("vdd_g3d", 1200000);
if (ret)
return ret;
return 0;
}
int board_get_revision(void)
{
return 0;
}
#ifdef CONFIG_USB_DWC3
static struct dwc3_device dwc3_device_data = {
.maximum_speed = USB_SPEED_SUPER,
.base = 0x12400000,
.dr_mode = USB_DR_MODE_PERIPHERAL,
.index = 0,
};
int usb_gadget_handle_interrupts(void)
{
dwc3_uboot_handle_interrupt(0);
return 0;
}
int board_usb_init(int index, enum usb_init_type init)
{
struct exynos_usb3_phy *phy = (struct exynos_usb3_phy *)
samsung_get_base_usb3_phy();
if (!phy) {
pr_err("usb3 phy not supported\n");
return -ENODEV;
}
set_usbdrd_phy_ctrl(POWER_USB_DRD_PHY_CTRL_EN);
exynos5_usb3_phy_init(phy);
return dwc3_uboot_init(&dwc3_device_data);
}
#endif
#ifdef CONFIG_SET_DFU_ALT_INFO
char *get_dfu_alt_system(char *interface, char *devstr)
{
char *info = "Not supported!";
if (board_is_odroidxu4() || board_is_odroidhc1() || board_is_odroidhc2())
return info;
return env_get("dfu_alt_system");
}
char *get_dfu_alt_boot(char *interface, char *devstr)
{
char *info = "Not supported!";
struct mmc *mmc;
char *alt_boot;
int dev_num;
if (board_is_odroidxu4() || board_is_odroidhc1() || board_is_odroidhc2())
return info;
dev_num = simple_strtoul(devstr, NULL, 10);
mmc = find_mmc_device(dev_num);
if (!mmc)
return NULL;
if (mmc_init(mmc))
return NULL;
if (IS_SD(mmc))
alt_boot = CONFIG_DFU_ALT_BOOT_SD;
else
alt_boot = CONFIG_DFU_ALT_BOOT_EMMC;
return alt_boot;
}
#endif
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2013 Samsung Electronics
* Lukasz Majewski <l.majewski@samsung.com>
*/
#include <common.h>
#include <linux/usb/ch9.h>
int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
{
if (!strcmp(name, "usb_dnl_thor")) {
put_unaligned(CONFIG_G_DNL_THOR_VENDOR_NUM, &dev->idVendor);
put_unaligned(CONFIG_G_DNL_THOR_PRODUCT_NUM, &dev->idProduct);
} else if (!strcmp(name, "usb_dnl_ums")) {
put_unaligned(CONFIG_G_DNL_UMS_VENDOR_NUM, &dev->idVendor);
put_unaligned(CONFIG_G_DNL_UMS_PRODUCT_NUM, &dev->idProduct);
} else {
put_unaligned(CONFIG_USB_GADGET_VENDOR_NUM, &dev->idVendor);
put_unaligned(CONFIG_USB_GADGET_PRODUCT_NUM, &dev->idProduct);
}
return 0;
}
@@ -0,0 +1,483 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2013 Samsung Electronics
* Przemyslaw Marczak <p.marczak@samsung.com>
*/
#include <common.h>
#include <command.h>
#include <env.h>
#include <lcd.h>
#include <libtizen.h>
#include <samsung/misc.h>
#include <errno.h>
#include <version.h>
#include <malloc.h>
#include <memalign.h>
#include <linux/sizes.h>
#include <asm/arch/cpu.h>
#include <asm/gpio.h>
#include <linux/input.h>
#include <dm.h>
/*
* Use #ifdef to work around conflicting headers while we wait for this to be
* converted to driver model.
*/
#ifdef CONFIG_DM_PMIC_MAX77686
#include <power/max77686_pmic.h>
#endif
#ifdef CONFIG_DM_PMIC_MAX8998
#include <power/max8998_pmic.h>
#endif
#ifdef CONFIG_PMIC_MAX8997
#include <power/max8997_pmic.h>
#endif
#include <power/pmic.h>
#include <mmc.h>
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_SET_DFU_ALT_INFO
void set_dfu_alt_info(char *interface, char *devstr)
{
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(interface, devstr);
if (alt_setting) {
env_set("dfu_alt_boot", alt_setting);
offset = snprintf(buf, buf_size, "%s", alt_setting);
}
alt_setting = get_dfu_alt_system(interface, devstr);
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";
}
env_set("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), "%u.%u", (s5p_cpu_rev & 0xf0) >> 4,
s5p_cpu_rev & 0xf);
env_set("soc_rev", info);
snprintf(info, ARRAY_SIZE(info), "%x", s5p_cpu_id);
env_set("soc_id", info);
#ifdef CONFIG_REVISION_TAG
snprintf(info, ARRAY_SIZE(info), "%x", get_board_rev());
env_set("board_rev", info);
#endif
#ifdef CONFIG_OF_LIBFDT
const char *bdtype = "";
const char *bdname = CONFIG_SYS_BOARD;
#ifdef CONFIG_BOARD_TYPES
bdtype = get_board_type();
if (!bdtype)
bdtype = "";
sprintf(info, "%s%s", bdname, bdtype);
env_set("board_name", info);
#endif
snprintf(info, ARRAY_SIZE(info), "%s%x-%s%s.dtb",
CONFIG_SYS_SOC, s5p_cpu_id, bdname, bdtype);
env_set("fdtfile", info);
#endif
}
#endif /* CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG */
#ifdef CONFIG_LCD_MENU
static int power_key_pressed(u32 reg)
{
#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
struct pmic *pmic;
u32 status;
u32 mask;
pmic = pmic_get(KEY_PWR_PMIC_NAME);
if (!pmic) {
printf("%s: Not found\n", KEY_PWR_PMIC_NAME);
return 0;
}
if (pmic_probe(pmic))
return 0;
if (reg == KEY_PWR_STATUS_REG)
mask = KEY_PWR_STATUS_MASK;
else
mask = KEY_PWR_INTERRUPT_MASK;
if (pmic_reg_read(pmic, reg, &status))
return 0;
return !!(status & mask);
#else
return 0;
#endif
}
static int key_pressed(int key)
{
int value;
switch (key) {
case KEY_POWER:
value = power_key_pressed(KEY_PWR_INTERRUPT_REG);
break;
case KEY_VOLUMEUP:
value = !gpio_get_value(KEY_VOL_UP_GPIO);
break;
case KEY_VOLUMEDOWN:
value = !gpio_get_value(KEY_VOL_DOWN_GPIO);
break;
default:
value = 0;
break;
}
return value;
}
#ifdef CONFIG_LCD
static int check_keys(void)
{
int keys = 0;
if (key_pressed(KEY_POWER))
keys += KEY_POWER;
if (key_pressed(KEY_VOLUMEUP))
keys += KEY_VOLUMEUP;
if (key_pressed(KEY_VOLUMEDOWN))
keys += KEY_VOLUMEDOWN;
return keys;
}
/*
* 0 BOOT_MODE_INFO
* 1 BOOT_MODE_THOR
* 2 BOOT_MODE_UMS
* 3 BOOT_MODE_DFU
* 4 BOOT_MODE_EXIT
*/
static char *
mode_name[BOOT_MODE_EXIT + 1][2] = {
{"DEVICE", ""},
{"THOR", "thor"},
{"UMS", "ums"},
{"DFU", "dfu"},
{"GPT", "gpt"},
{"ENV", "env"},
{"EXIT", ""},
};
static char *
mode_info[BOOT_MODE_EXIT + 1] = {
"info",
"downloader",
"mass storage",
"firmware update",
"restore",
"default",
"and run normal boot"
};
static char *
mode_cmd[BOOT_MODE_EXIT + 1] = {
"",
"thor 0 mmc 0",
"ums 0 mmc 0",
"dfu 0 mmc 0",
"gpt write mmc 0 $partitions",
"env default -a; saveenv",
"",
};
static void display_board_info(void)
{
#ifdef CONFIG_MMC
struct mmc *mmc = find_mmc_device(0);
#endif
vidinfo_t *vid = &panel_info;
lcd_position_cursor(4, 4);
lcd_printf("%s\n\t", U_BOOT_VERSION);
lcd_puts("\n\t\tBoard Info:\n");
#ifdef CONFIG_SYS_BOARD
lcd_printf("\tBoard name: %s\n", CONFIG_SYS_BOARD);
#endif
#ifdef CONFIG_REVISION_TAG
lcd_printf("\tBoard rev: %u\n", get_board_rev());
#endif
lcd_printf("\tDRAM banks: %u\n", CONFIG_NR_DRAM_BANKS);
lcd_printf("\tDRAM size: %u MB\n", gd->ram_size / SZ_1M);
#ifdef CONFIG_MMC
if (mmc) {
if (!mmc->capacity)
mmc_init(mmc);
lcd_printf("\teMMC size: %llu MB\n", mmc->capacity / SZ_1M);
}
#endif
if (vid)
lcd_printf("\tDisplay resolution: %u x % u\n",
vid->vl_col, vid->vl_row);
lcd_printf("\tDisplay BPP: %u\n", 1 << vid->vl_bpix);
}
#endif
static int mode_leave_menu(int mode)
{
#ifdef CONFIG_LCD
char *exit_option;
char *exit_reset = "reset";
char *exit_back = "back";
cmd_tbl_t *cmd;
int cmd_result;
int leave;
lcd_clear();
switch (mode) {
case BOOT_MODE_EXIT:
return 1;
case BOOT_MODE_INFO:
display_board_info();
exit_option = exit_back;
leave = 0;
break;
default:
cmd = find_cmd(mode_name[mode][1]);
if (cmd) {
printf("Enter: %s %s\n", mode_name[mode][0],
mode_info[mode]);
lcd_printf("\n\n\t%s %s\n", mode_name[mode][0],
mode_info[mode]);
lcd_puts("\n\tDo not turn off device before finish!\n");
cmd_result = run_command(mode_cmd[mode], 0);
if (cmd_result == CMD_RET_SUCCESS) {
printf("Command finished\n");
lcd_clear();
lcd_printf("\n\n\t%s finished\n",
mode_name[mode][0]);
exit_option = exit_reset;
leave = 1;
} else {
printf("Command error\n");
lcd_clear();
lcd_printf("\n\n\t%s command error\n",
mode_name[mode][0]);
exit_option = exit_back;
leave = 0;
}
} else {
lcd_puts("\n\n\tThis mode is not supported.\n");
exit_option = exit_back;
leave = 0;
}
}
lcd_printf("\n\n\tPress POWER KEY to %s\n", exit_option);
/* Clear PWR button Rising edge interrupt status flag */
power_key_pressed(KEY_PWR_INTERRUPT_REG);
/* Wait for PWR key */
while (!key_pressed(KEY_POWER))
mdelay(1);
lcd_clear();
return leave;
#else
return 0;
#endif
}
#ifdef CONFIG_LCD
static void display_download_menu(int mode)
{
char *selection[BOOT_MODE_EXIT + 1];
int i;
for (i = 0; i <= BOOT_MODE_EXIT; i++)
selection[i] = "[ ]";
selection[mode] = "[=>]";
lcd_clear();
lcd_printf("\n\n\t\tDownload Mode Menu\n\n");
for (i = 0; i <= BOOT_MODE_EXIT; i++)
lcd_printf("\t%s %s - %s\n\n", selection[i],
mode_name[i][0], mode_info[i]);
}
#endif
static void download_menu(void)
{
#ifdef CONFIG_LCD
int mode = 0;
int last_mode = 0;
int run;
int key = 0;
int timeout = 15; /* sec */
int i;
display_download_menu(mode);
lcd_puts("\n");
/* Start count if no key is pressed */
while (check_keys())
continue;
while (timeout--) {
lcd_printf("\r\tNormal boot will start in: %2.d seconds.",
timeout);
/* about 1000 ms in for loop */
for (i = 0; i < 10; i++) {
mdelay(100);
key = check_keys();
if (key)
break;
}
if (key)
break;
}
if (!key) {
lcd_clear();
return;
}
while (1) {
run = 0;
if (mode != last_mode)
display_download_menu(mode);
last_mode = mode;
mdelay(200);
key = check_keys();
switch (key) {
case KEY_POWER:
run = 1;
break;
case KEY_VOLUMEUP:
if (mode > 0)
mode--;
break;
case KEY_VOLUMEDOWN:
if (mode < BOOT_MODE_EXIT)
mode++;
break;
default:
break;
}
if (run) {
if (mode_leave_menu(mode))
run_command("reset", 0);
display_download_menu(mode);
}
}
lcd_clear();
#endif
}
void check_boot_mode(void)
{
int pwr_key;
pwr_key = power_key_pressed(KEY_PWR_STATUS_REG);
if (!pwr_key)
return;
/* Clear PWR button Rising edge interrupt status flag */
power_key_pressed(KEY_PWR_INTERRUPT_REG);
if (key_pressed(KEY_VOLUMEUP))
download_menu();
else if (key_pressed(KEY_VOLUMEDOWN))
mode_leave_menu(BOOT_MODE_THOR);
}
void keys_init(void)
{
/* Set direction to input */
gpio_request(KEY_VOL_UP_GPIO, "volume-up");
gpio_request(KEY_VOL_DOWN_GPIO, "volume-down");
gpio_direction_input(KEY_VOL_UP_GPIO);
gpio_direction_input(KEY_VOL_DOWN_GPIO);
}
#endif /* CONFIG_LCD_MENU */
#ifdef CONFIG_CMD_BMP
void draw_logo(void)
{
int x, y;
ulong addr;
addr = panel_info.logo_addr;
if (!addr) {
pr_err("There is no logo data.\n");
return;
}
if (panel_info.vl_width >= panel_info.logo_width) {
x = ((panel_info.vl_width - panel_info.logo_width) >> 1);
x += panel_info.logo_x_offset; /* For X center align */
} else {
x = 0;
printf("Warning: image width is bigger than display width\n");
}
if (panel_info.vl_height >= panel_info.logo_height) {
y = ((panel_info.vl_height - panel_info.logo_height) >> 1);
y += panel_info.logo_y_offset; /* For Y center align */
} else {
y = 0;
printf("Warning: image height is bigger than display height\n");
}
bmp_display(addr, x, y);
}
#endif /* CONFIG_CMD_BMP */
@@ -0,0 +1,16 @@
if TARGET_ESPRESSO7420
config SYS_BOARD
default "espresso7420"
help
Espresso7420 is a development/evaluation board for Exynos7420 SoC.
It includes multiple onboard compoments (EMMC/Codec) and various
interconnects (USB/HDMI).
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "espresso7420"
endif
@@ -0,0 +1,6 @@
ESPRESSO7420 Board
M: Thomas Abraham <thomas.ab@samsung.com>
S: Maintained
F: board/samsung/espresso7420/
F: include/configs/espresso7420.h
F: configs/espresso7420_defconfig
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2016 Samsung Electronics
# Thomas Abraham <thomas.ab@samsung.com>
obj-y += espresso7420.o
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Espresso7420 board file
* Copyright (C) 2016 Samsung Electronics
* Thomas Abraham <thomas.ab@samsung.com>
*/
#include <common.h>
int exynos_init(void)
{
return 0;
}
@@ -0,0 +1,15 @@
if TARGET_S5P_GONI
config SYS_BOARD
default "goni"
config SYS_VENDOR
default "samsung"
config SYS_SOC
default "s5pc1xx"
config SYS_CONFIG_NAME
default "s5p_goni"
endif
@@ -0,0 +1,6 @@
GONI BOARD
M: Robert Baldyga <r.baldyga@samsung.com>
S: Maintained
F: board/samsung/goni/
F: include/configs/s5p_goni.h
F: configs/s5p_goni_defconfig
@@ -0,0 +1,10 @@
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2000, 2001, 2002
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# (C) Copyright 2008
# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
obj-y := goni.o onenand.o
obj-y += lowlevel_init.o
@@ -0,0 +1,213 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2008-2009 Samsung Electronics
* Minkyu Kang <mk7.kang@samsung.com>
* Kyungmin Park <kyungmin.park@samsung.com>
*/
#include <common.h>
#include <asm/gpio.h>
#include <asm/arch/mmc.h>
#include <dm.h>
#include <power/pmic.h>
#include <usb/dwc2_udc.h>
#include <asm/arch/cpu.h>
#include <power/max8998_pmic.h>
#include <samsung/misc.h>
#include <usb.h>
#include <usb_mass_storage.h>
#include <asm/mach-types.h>
DECLARE_GLOBAL_DATA_PTR;
u32 get_board_rev(void)
{
return 0;
}
int board_init(void)
{
/* Set Initial global variables */
gd->bd->bi_arch_number = MACH_TYPE_GONI;
gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
return 0;
}
#ifdef CONFIG_SYS_I2C_INIT_BOARD
void i2c_init_board(void)
{
gpio_request(S5PC110_GPIO_J43, "i2c_clk");
gpio_request(S5PC110_GPIO_J40, "i2c_data");
gpio_direction_output(S5PC110_GPIO_J43, 1);
gpio_direction_output(S5PC110_GPIO_J40, 1);
}
#endif
int dram_init(void)
{
gd->ram_size = PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE +
PHYS_SDRAM_3_SIZE;
return 0;
}
int dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
gd->bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;
return 0;
}
#ifdef CONFIG_DISPLAY_BOARDINFO
int checkboard(void)
{
puts("Board:\tGoni\n");
return 0;
}
#endif
#ifdef CONFIG_MMC
int board_mmc_init(bd_t *bis)
{
int i, ret, ret_sd = 0;
/* MASSMEMORY_EN: XMSMDATA7: GPJ2[7] output high */
gpio_request(S5PC110_GPIO_J27, "massmemory_en");
gpio_direction_output(S5PC110_GPIO_J27, 1);
/*
* MMC0 GPIO
* GPG0[0] SD_0_CLK
* GPG0[1] SD_0_CMD
* GPG0[2] SD_0_CDn -> Not used
* GPG0[3:6] SD_0_DATA[0:3]
*/
for (i = S5PC110_GPIO_G00; i < S5PC110_GPIO_G07; i++) {
if (i == S5PC110_GPIO_G02)
continue;
/* GPG0[0:6] special function 2 */
gpio_cfg_pin(i, 0x2);
/* GPG0[0:6] pull disable */
gpio_set_pull(i, S5P_GPIO_PULL_NONE);
/* GPG0[0:6] drv 4x */
gpio_set_drv(i, S5P_GPIO_DRV_4X);
}
ret = s5p_mmc_init(0, 4);
if (ret)
pr_err("MMC: Failed to init MMC:0.\n");
/*
* SD card (T_FLASH) detect and init
* T_FLASH_DETECT: EINT28: GPH3[4] input mode
*/
gpio_request(S5PC110_GPIO_H34, "t_flash_detect");
gpio_cfg_pin(S5PC110_GPIO_H34, S5P_GPIO_INPUT);
gpio_set_pull(S5PC110_GPIO_H34, S5P_GPIO_PULL_UP);
if (!gpio_get_value(S5PC110_GPIO_H34)) {
for (i = S5PC110_GPIO_G20; i < S5PC110_GPIO_G27; i++) {
if (i == S5PC110_GPIO_G22)
continue;
/* GPG2[0:6] special function 2 */
gpio_cfg_pin(i, 0x2);
/* GPG2[0:6] pull disable */
gpio_set_pull(i, S5P_GPIO_PULL_NONE);
/* GPG2[0:6] drv 4x */
gpio_set_drv(i, S5P_GPIO_DRV_4X);
}
ret_sd = s5p_mmc_init(2, 4);
if (ret_sd)
pr_err("MMC: Failed to init SD card (MMC:2).\n");
}
return ret & ret_sd;
}
#endif
#ifdef CONFIG_USB_GADGET
static int s5pc1xx_phy_control(int on)
{
struct udevice *dev;
static int status;
int reg, ret;
ret = pmic_get("max8998-pmic", &dev);
if (ret)
return ret;
if (on && !status) {
reg = pmic_reg_read(dev, MAX8998_REG_ONOFF1);
reg |= MAX8998_LDO3;
ret = pmic_reg_write(dev, MAX8998_REG_ONOFF1, reg);
if (ret) {
puts("MAX8998 LDO setting error!\n");
return -EINVAL;
}
reg = pmic_reg_read(dev, MAX8998_REG_ONOFF2);
reg |= MAX8998_LDO8;
ret = pmic_reg_write(dev, MAX8998_REG_ONOFF2, reg);
if (ret) {
puts("MAX8998 LDO setting error!\n");
return -EINVAL;
}
status = 1;
} else if (!on && status) {
reg = pmic_reg_read(dev, MAX8998_REG_ONOFF1);
reg &= ~MAX8998_LDO3;
ret = pmic_reg_write(dev, MAX8998_REG_ONOFF1, reg);
if (ret) {
puts("MAX8998 LDO setting error!\n");
return -EINVAL;
}
reg = pmic_reg_read(dev, MAX8998_REG_ONOFF2);
reg &= ~MAX8998_LDO8;
ret = pmic_reg_write(dev, MAX8998_REG_ONOFF2, reg);
if (ret) {
puts("MAX8998 LDO setting error!\n");
return -EINVAL;
}
status = 0;
}
udelay(10000);
return 0;
}
struct dwc2_plat_otg_data s5pc110_otg_data = {
.phy_control = s5pc1xx_phy_control,
.regs_phy = S5PC110_PHY_BASE,
.regs_otg = S5PC110_OTG_BASE,
.usb_phy_ctrl = S5PC110_USB_PHY_CONTROL,
};
int board_usb_init(int index, enum usb_init_type init)
{
debug("USB_udc_probe\n");
return dwc2_udc_probe(&s5pc110_otg_data);
}
#endif
#ifdef CONFIG_MISC_INIT_R
int misc_init_r(void)
{
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
set_board_info();
#endif
return 0;
}
#endif
int board_usb_cleanup(int index, enum usb_init_type init)
{
return 0;
}
@@ -0,0 +1,444 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Memory Setup stuff - taken from blob memsetup.S
*
* Copyright (C) 2009 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
*/
#include <config.h>
#include <asm/arch/cpu.h>
#include <asm/arch/clock.h>
#include <asm/arch/power.h>
/*
* Register usages:
*
* r5 has zero always
* r7 has S5PC100 GPIO base, 0xE0300000
* r8 has real GPIO base, 0xE0300000, 0xE0200000 at S5PC100, S5PC110 repectively
* r9 has Mobile DDR size, 1 means 1GiB, 2 means 2GiB and so on
*/
.globl lowlevel_init
lowlevel_init:
mov r11, lr
/* r5 has always zero */
mov r5, #0
ldr r7, =S5PC100_GPIO_BASE
ldr r8, =S5PC100_GPIO_BASE
/* Read CPU ID */
ldr r2, =S5PC110_PRO_ID
ldr r0, [r2]
mov r1, #0x00010000
and r0, r0, r1
cmp r0, r5
beq 100f
ldr r8, =S5PC110_GPIO_BASE
100:
/* Turn on KEY_LED_ON [GPJ4(1)] XMSMWEN */
cmp r7, r8
beq skip_check_didle @ Support C110 only
ldr r0, =S5PC110_RST_STAT
ldr r1, [r0]
and r1, r1, #0x000D0000
cmp r1, #(0x1 << 19) @ DEEPIDLE_WAKEUP
beq didle_wakeup
cmp r7, r8
skip_check_didle:
addeq r0, r8, #0x280 @ S5PC100_GPIO_J4
addne r0, r8, #0x2C0 @ S5PC110_GPIO_J4
ldr r1, [r0, #0x0] @ GPIO_CON_OFFSET
bic r1, r1, #(0xf << 4) @ 1 * 4-bit
orr r1, r1, #(0x1 << 4)
str r1, [r0, #0x0] @ GPIO_CON_OFFSET
ldr r1, [r0, #0x4] @ GPIO_DAT_OFFSET
bic r1, r1, #(1 << 1)
str r1, [r0, #0x4] @ GPIO_DAT_OFFSET
/* Don't setup at s5pc100 */
beq 100f
/*
* Initialize Async Register Setting for EVT1
* Because we are setting EVT1 as the default value of EVT0,
* setting EVT0 as well does not make things worse.
* Thus, for the simplicity, we set for EVT0, too
*
* The "Async Registers" are:
* 0xE0F0_0000
* 0xE1F0_0000
* 0xF180_0000
* 0xF190_0000
* 0xF1A0_0000
* 0xF1B0_0000
* 0xF1C0_0000
* 0xF1D0_0000
* 0xF1E0_0000
* 0xF1F0_0000
* 0xFAF0_0000
*/
ldr r0, =0xe0f00000
ldr r1, [r0]
bic r1, r1, #0x1
str r1, [r0]
ldr r0, =0xe1f00000
ldr r1, [r0]
bic r1, r1, #0x1
str r1, [r0]
ldr r0, =0xf1800000
ldr r1, [r0]
bic r1, r1, #0x1
str r1, [r0]
ldr r0, =0xf1900000
ldr r1, [r0]
bic r1, r1, #0x1
str r1, [r0]
ldr r0, =0xf1a00000
ldr r1, [r0]
bic r1, r1, #0x1
str r1, [r0]
ldr r0, =0xf1b00000
ldr r1, [r0]
bic r1, r1, #0x1
str r1, [r0]
ldr r0, =0xf1c00000
ldr r1, [r0]
bic r1, r1, #0x1
str r1, [r0]
ldr r0, =0xf1d00000
ldr r1, [r0]
bic r1, r1, #0x1
str r1, [r0]
ldr r0, =0xf1e00000
ldr r1, [r0]
bic r1, r1, #0x1
str r1, [r0]
ldr r0, =0xf1f00000
ldr r1, [r0]
bic r1, r1, #0x1
str r1, [r0]
ldr r0, =0xfaf00000
ldr r1, [r0]
bic r1, r1, #0x1
str r1, [r0]
/*
* Diable ABB block to reduce sleep current at low temperature
* Note that it's hidden register setup don't modify it
*/
ldr r0, =0xE010C300
ldr r1, =0x00800000
str r1, [r0]
100:
/* IO retension release */
ldreq r0, =S5PC100_OTHERS @ 0xE0108200
ldrne r0, =S5PC110_OTHERS @ 0xE010E000
ldr r1, [r0]
ldreq r2, =(1 << 31) @ IO_RET_REL
ldrne r2, =((1 << 31) | (1 << 30) | (1 << 29) | (1 << 28))
orr r1, r1, r2
/* Do not release retention here for S5PC110 */
streq r1, [r0]
/* Disable Watchdog */
ldreq r0, =S5PC100_WATCHDOG_BASE @ 0xEA200000
ldrne r0, =S5PC110_WATCHDOG_BASE @ 0xE2700000
str r5, [r0]
/* setting SRAM */
ldreq r0, =S5PC100_SROMC_BASE
ldrne r0, =S5PC110_SROMC_BASE
ldr r1, =0x9
str r1, [r0]
/* S5PC100 has 3 groups of interrupt sources */
ldreq r0, =S5PC100_VIC0_BASE @ 0xE4000000
ldrne r0, =S5PC110_VIC0_BASE @ 0xF2000000
add r1, r0, #0x00100000
add r2, r0, #0x00200000
/* Disable all interrupts (VIC0, VIC1 and VIC2) */
mvn r3, #0x0
str r3, [r0, #0x14] @ INTENCLEAR
str r3, [r1, #0x14] @ INTENCLEAR
str r3, [r2, #0x14] @ INTENCLEAR
/* Set all interrupts as IRQ */
str r5, [r0, #0xc] @ INTSELECT
str r5, [r1, #0xc] @ INTSELECT
str r5, [r2, #0xc] @ INTSELECT
/* Pending Interrupt Clear */
str r5, [r0, #0xf00] @ INTADDRESS
str r5, [r1, #0xf00] @ INTADDRESS
str r5, [r2, #0xf00] @ INTADDRESS
/* for UART */
bl uart_asm_init
bl internal_ram_init
cmp r7, r8
/* Clear wakeup status register */
ldreq r0, =S5PC100_WAKEUP_STAT
ldrne r0, =S5PC110_WAKEUP_STAT
ldr r1, [r0]
str r1, [r0]
/* IO retension release */
ldreq r0, =S5PC100_OTHERS @ 0xE0108200
ldrne r0, =S5PC110_OTHERS @ 0xE010E000
ldr r1, [r0]
ldreq r2, =(1 << 31) @ IO_RET_REL
ldrne r2, =((1 << 31) | (1 << 30) | (1 << 29) | (1 << 28))
orr r1, r1, r2
str r1, [r0]
b 1f
didle_wakeup:
/* Wait when APLL is locked */
ldr r0, =0xE0100100 @ S5PC110_APLL_CON
lockloop:
ldr r1, [r0]
and r1, r1, #(1 << 29)
cmp r1, #(1 << 29)
bne lockloop
ldr r0, =S5PC110_INFORM0
ldr r1, [r0]
mov pc, r1
nop
nop
nop
nop
nop
1:
mov lr, r11
mov pc, lr
/*
* system_clock_init: Initialize core clock and bus clock.
* void system_clock_init(void)
*/
system_clock_init:
ldr r0, =S5PC110_CLOCK_BASE @ 0xE0100000
/* Check S5PC100 */
cmp r7, r8
bne 110f
100:
/* Set Lock Time */
ldr r1, =0xe10 @ Locktime : 0xe10 = 3600
str r1, [r0, #0x000] @ S5PC100_APLL_LOCK
str r1, [r0, #0x004] @ S5PC100_MPLL_LOCK
str r1, [r0, #0x008] @ S5PC100_EPLL_LOCK
str r1, [r0, #0x00C] @ S5PC100_HPLL_LOCK
/* S5P_APLL_CON */
ldr r1, =0x81bc0400 @ SDIV 0, PDIV 4, MDIV 444 (1333MHz)
str r1, [r0, #0x100]
/* S5P_MPLL_CON */
ldr r1, =0x80590201 @ SDIV 1, PDIV 2, MDIV 89 (267MHz)
str r1, [r0, #0x104]
/* S5P_EPLL_CON */
ldr r1, =0x80870303 @ SDIV 3, PDIV 3, MDIV 135 (67.5MHz)
str r1, [r0, #0x108]
/* S5P_HPLL_CON */
ldr r1, =0x80600603 @ SDIV 3, PDIV 6, MDIV 96
str r1, [r0, #0x10C]
ldr r1, [r0, #0x300]
ldr r2, =0x00003fff
bic r1, r1, r2
ldr r2, =0x00011301
orr r1, r1, r2
str r1, [r0, #0x300]
ldr r1, [r0, #0x304]
ldr r2, =0x00011110
orr r1, r1, r2
str r1, [r0, #0x304]
ldr r1, =0x00000001
str r1, [r0, #0x308]
/* Set Source Clock */
ldr r1, =0x00001111 @ A, M, E, HPLL Muxing
str r1, [r0, #0x200] @ S5PC1XX_CLK_SRC0
b 200f
110:
ldr r0, =0xE010C000 @ S5PC110_PWR_CFG
/* Set OSC_FREQ value */
ldr r1, =0xf
str r1, [r0, #0x100] @ S5PC110_OSC_FREQ
/* Set MTC_STABLE value */
ldr r1, =0xffffffff
str r1, [r0, #0x110] @ S5PC110_MTC_STABLE
/* Set CLAMP_STABLE value */
ldr r1, =0x3ff03ff
str r1, [r0, #0x114] @ S5PC110_CLAMP_STABLE
ldr r0, =S5PC110_CLOCK_BASE @ 0xE0100000
/* Set Clock divider */
ldr r1, =0x14131330 @ 1:1:4:4, 1:4:5
str r1, [r0, #0x300]
ldr r1, =0x11110111 @ UART[3210]: MMC[3210]
str r1, [r0, #0x310]
/* Set Lock Time */
ldr r1, =0x2cf @ Locktime : 30us
str r1, [r0, #0x000] @ S5PC110_APLL_LOCK
ldr r1, =0xe10 @ Locktime : 0xe10 = 3600
str r1, [r0, #0x008] @ S5PC110_MPLL_LOCK
str r1, [r0, #0x010] @ S5PC110_EPLL_LOCK
str r1, [r0, #0x020] @ S5PC110_VPLL_LOCK
/* S5PC110_APLL_CON */
ldr r1, =0x80C80601 @ 800MHz
str r1, [r0, #0x100]
/* S5PC110_MPLL_CON */
ldr r1, =0x829B0C01 @ 667MHz
str r1, [r0, #0x108]
/* S5PC110_EPLL_CON */
ldr r1, =0x80600602 @ 96MHz VSEL 0 P 6 M 96 S 2
str r1, [r0, #0x110]
/* S5PC110_VPLL_CON */
ldr r1, =0x806C0603 @ 54MHz
str r1, [r0, #0x120]
/* Set Source Clock */
ldr r1, =0x10001111 @ A, M, E, VPLL Muxing
str r1, [r0, #0x200] @ S5PC1XX_CLK_SRC0
/* OneDRAM(DMC0) clock setting */
ldr r1, =0x01000000 @ ONEDRAM_SEL[25:24] 1 SCLKMPLL
str r1, [r0, #0x218] @ S5PC110_CLK_SRC6
ldr r1, =0x30000000 @ ONEDRAM_RATIO[31:28] 3 + 1
str r1, [r0, #0x318] @ S5PC110_CLK_DIV6
/* XCLKOUT = XUSBXTI 24MHz */
add r2, r0, #0xE000 @ S5PC110_OTHERS
ldr r1, [r2]
orr r1, r1, #(0x3 << 8) @ CLKOUT[9:8] 3 XUSBXTI
str r1, [r2]
/* CLK_IP0 */
ldr r1, =0x8fefeeb @ DMC[1:0] PDMA0[3] IMEM[5]
str r1, [r0, #0x460] @ S5PC110_CLK_IP0
/* CLK_IP1 */
ldr r1, =0xe9fdf0f9 @ FIMD[0] USBOTG[16]
@ NANDXL[24]
str r1, [r0, #0x464] @ S5PC110_CLK_IP1
/* CLK_IP2 */
ldr r1, =0xf75f7fc @ CORESIGHT[8] MODEM[9]
@ HOSTIF[10] HSMMC0[16]
@ HSMMC2[18] VIC[27:24]
str r1, [r0, #0x468] @ S5PC110_CLK_IP2
/* CLK_IP3 */
ldr r1, =0x8eff038c @ I2C[8:6]
@ SYSTIMER[16] UART0[17]
@ UART1[18] UART2[19]
@ UART3[20] WDT[22]
@ PWM[23] GPIO[26] SYSCON[27]
str r1, [r0, #0x46c] @ S5PC110_CLK_IP3
/* CLK_IP4 */
ldr r1, =0xfffffff1 @ CHIP_ID[0] TZPC[8:5]
str r1, [r0, #0x470] @ S5PC110_CLK_IP3
200:
/* wait at least 200us to stablize all clock */
mov r2, #0x10000
1: subs r2, r2, #1
bne 1b
mov pc, lr
internal_ram_init:
ldreq r0, =0xE3800000
ldrne r0, =0xF1500000
ldr r1, =0x0
str r1, [r0]
mov pc, lr
/*
* uart_asm_init: Initialize UART's pins
*/
uart_asm_init:
/* set GPIO to enable UART0-UART4 */
mov r0, r8
ldr r1, =0x22222222
str r1, [r0, #0x0] @ S5PC100_GPIO_A0_OFFSET
ldr r1, =0x00002222
str r1, [r0, #0x20] @ S5PC100_GPIO_A1_OFFSET
/* Check S5PC100 */
cmp r7, r8
bne 110f
/* UART_SEL GPK0[5] at S5PC100 */
add r0, r8, #0x2A0 @ S5PC100_GPIO_K0_OFFSET
ldr r1, [r0, #0x0] @ S5PC1XX_GPIO_CON_OFFSET
bic r1, r1, #(0xf << 20) @ 20 = 5 * 4-bit
orr r1, r1, #(0x1 << 20) @ Output
str r1, [r0, #0x0] @ S5PC1XX_GPIO_CON_OFFSET
ldr r1, [r0, #0x8] @ S5PC1XX_GPIO_PULL_OFFSET
bic r1, r1, #(0x3 << 10) @ 10 = 5 * 2-bit
orr r1, r1, #(0x2 << 10) @ Pull-up enabled
str r1, [r0, #0x8] @ S5PC1XX_GPIO_PULL_OFFSET
ldr r1, [r0, #0x4] @ S5PC1XX_GPIO_DAT_OFFSET
orr r1, r1, #(1 << 5) @ 5 = 5 * 1-bit
str r1, [r0, #0x4] @ S5PC1XX_GPIO_DAT_OFFSET
b 200f
110:
/*
* Note that the following address
* 0xE020'0360 is reserved address at S5PC100
*/
/* UART_SEL MP0_5[7] at S5PC110 */
add r0, r8, #0x360 @ S5PC110_GPIO_MP0_5_OFFSET
ldr r1, [r0, #0x0] @ S5PC1XX_GPIO_CON_OFFSET
bic r1, r1, #(0xf << 28) @ 28 = 7 * 4-bit
orr r1, r1, #(0x1 << 28) @ Output
str r1, [r0, #0x0] @ S5PC1XX_GPIO_CON_OFFSET
ldr r1, [r0, #0x8] @ S5PC1XX_GPIO_PULL_OFFSET
bic r1, r1, #(0x3 << 14) @ 14 = 7 * 2-bit
orr r1, r1, #(0x2 << 14) @ Pull-up enabled
str r1, [r0, #0x8] @ S5PC1XX_GPIO_PULL_OFFSET
ldr r1, [r0, #0x4] @ S5PC1XX_GPIO_DAT_OFFSET
orr r1, r1, #(1 << 7) @ 7 = 7 * 1-bit
str r1, [r0, #0x4] @ S5PC1XX_GPIO_DAT_OFFSET
200:
mov pc, lr
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2008-2009 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
*/
#include <common.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>
#include <linux/mtd/samsung_onenand.h>
#include <onenand_uboot.h>
int onenand_board_init(struct mtd_info *mtd)
{
struct onenand_chip *this = mtd->priv;
this->base = (void *)CONFIG_SYS_ONENAND_BASE;
this->options |= ONENAND_RUNTIME_BADBLOCK_CHECK;
this->chip_probe = s5pc110_chip_probe;
return 0;
}
@@ -0,0 +1,12 @@
if TARGET_ODROID
config SYS_BOARD
default "odroid"
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "odroid"
endif
@@ -0,0 +1,6 @@
ODROID BOARD
M: Jaehoon Chung <jh80.chung@samsung.com>
S: Maintained
F: board/samsung/odroid/
F: include/configs/odroid.h
F: configs/odroid_defconfig
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
# Przemyslaw Marczak <p.marczak@samsung.com>
obj-y := odroid.o
@@ -0,0 +1,538 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2014 Samsung Electronics
* Przemyslaw Marczak <p.marczak@samsung.com>
*/
#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 <dm.h>
#include <env.h>
#include <power/pmic.h>
#include <power/regulator.h>
#include <power/max77686_pmic.h>
#include <errno.h>
#include <mmc.h>
#include <usb.h>
#include <usb/dwc2_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;
}
void set_board_revision(void)
{
/*
* Revision already set by set_board_type() because it can be
* executed early.
*/
}
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(char *interface, char *devstr)
{
return env_get("dfu_alt_system");
}
char *get_dfu_alt_boot(char *interface, char *devstr)
{
struct mmc *mmc;
char *alt_boot;
int dev_num;
dev_num = simple_strtoul(devstr, NULL, 10);
mmc = find_mmc_device(dev_num);
if (!mmc)
return NULL;
if (mmc_init(mmc))
return NULL;
alt_boot = IS_SD(mmc) ? CONFIG_DFU_ALT_BOOT_SD :
CONFIG_DFU_ALT_BOOT_EMMC;
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) = 200 (4)
*/
clr = COPY_RATIO(7) | HPM_RATIO(7) | CORES_RATIO(7);
set = COPY_RATIO(4) | HPM_RATIO(4) | CORES_RATIO(4);
clrsetbits_le32(&clk->div_cpu1, clr, set);
/* Wait for divider ready status */
while (readl(&clk->div_stat_cpu1) & DIV_STAT_CPU1_CHANGING)
continue;
/*
* Set CMU_DMC clocks src to APLL
* Bit values: 0 ; 1
* MUX_C2C_SEL: SCLKMPLL ; SCLKAPLL
* MUX_DMC_BUS_SEL: SCLKMPLL ; SCLKAPLL
* MUX_DPHY_SEL: SCLKMPLL ; SCLKAPLL
* MUX_MPLL_SEL: FINPLL ; MOUT_MPLL_FOUT
* MUX_PWI_SEL: 0110 (MPLL); 0111 (EPLL); 1000 (VPLL); 0(XXTI)
* MUX_G2D_ACP0_SEL: SCLKMPLL ; SCLKAPLL
* MUX_G2D_ACP1_SEL: SCLKEPLL ; SCLKVPLL
* MUX_G2D_ACP_SEL: OUT_ACP0 ; OUT_ACP1
*/
clr_src_dmc = MUX_C2C_SEL(1) | MUX_DMC_BUS_SEL(1) |
MUX_DPHY_SEL(1) | MUX_MPLL_SEL(1) |
MUX_PWI_SEL(15) | MUX_G2D_ACP0_SEL(1) |
MUX_G2D_ACP1_SEL(1) | MUX_G2D_ACP_SEL(1);
set = MUX_C2C_SEL(1) | MUX_DMC_BUS_SEL(1) | MUX_DPHY_SEL(1) |
MUX_MPLL_SEL(0) | MUX_PWI_SEL(0) | MUX_G2D_ACP0_SEL(1) |
MUX_G2D_ACP1_SEL(1) | MUX_G2D_ACP_SEL(1);
clrsetbits_le32(&clk->src_dmc, clr_src_dmc, set);
/* Wait for mux change */
while (readl(&clk->mux_stat_dmc) & MUX_STAT_DMC_CHANGING)
continue;
/* Set MPLL to 800MHz */
set = SDIV(0) | PDIV(3) | MDIV(100) | FSEL(0) | PLL_ENABLE(1);
clrsetbits_le32(&clk->mpll_con0, clr_pll_con0, set);
/* Wait for PLL to be locked */
while (!(readl(&clk->mpll_con0) & PLL_LOCKED_BIT))
continue;
/* Switch back CMU_DMC mux */
set = MUX_C2C_SEL(0) | MUX_DMC_BUS_SEL(0) | MUX_DPHY_SEL(0) |
MUX_MPLL_SEL(1) | MUX_PWI_SEL(8) | MUX_G2D_ACP0_SEL(0) |
MUX_G2D_ACP1_SEL(0) | MUX_G2D_ACP_SEL(0);
clrsetbits_le32(&clk->src_dmc, clr_src_dmc, set);
/* Wait for mux change */
while (readl(&clk->mux_stat_dmc) & MUX_STAT_DMC_CHANGING)
continue;
/* CLK_DIV_DMC0 */
clr = ACP_RATIO(7) | ACP_PCLK_RATIO(7) | DPHY_RATIO(7) |
DMC_RATIO(7) | DMCD_RATIO(7) | DMCP_RATIO(7);
/*
* For:
* MOUTdmc = 800 MHz
* MOUTdphy = 800 MHz
*
* aclk_acp = MOUTdmc / (ratio + 1) = 200 (3)
* pclk_acp = aclk_acp / (ratio + 1) = 100 (1)
* sclk_dphy = MOUTdphy / (ratio + 1) = 400 (1)
* sclk_dmc = MOUTdmc / (ratio + 1) = 400 (1)
* aclk_dmcd = sclk_dmc / (ratio + 1) = 200 (1)
* aclk_dmcp = aclk_dmcd / (ratio + 1) = 100 (1)
*/
set = ACP_RATIO(3) | ACP_PCLK_RATIO(1) | DPHY_RATIO(1) |
DMC_RATIO(1) | DMCD_RATIO(1) | DMCP_RATIO(1);
clrsetbits_le32(&clk->div_dmc0, clr, set);
/* Wait for divider ready status */
while (readl(&clk->div_stat_dmc0) & DIV_STAT_DMC0_CHANGING)
continue;
/* CLK_DIV_DMC1 */
clr = G2D_ACP_RATIO(15) | C2C_RATIO(7) | PWI_RATIO(15) |
C2C_ACLK_RATIO(7) | DVSEM_RATIO(127) | DPM_RATIO(127);
/*
* For:
* MOUTg2d = 800 MHz
* MOUTc2c = 800 Mhz
* MOUTpwi = 108 MHz
*
* sclk_g2d_acp = MOUTg2d / (ratio + 1) = 200 (3)
* sclk_c2c = MOUTc2c / (ratio + 1) = 400 (1)
* aclk_c2c = sclk_c2c / (ratio + 1) = 200 (1)
* sclk_pwi = MOUTpwi / (ratio + 1) = 18 (5)
*/
set = G2D_ACP_RATIO(3) | C2C_RATIO(1) | PWI_RATIO(5) |
C2C_ACLK_RATIO(1) | DVSEM_RATIO(1) | DPM_RATIO(1);
clrsetbits_le32(&clk->div_dmc1, clr, set);
/* Wait for divider ready status */
while (readl(&clk->div_stat_dmc1) & DIV_STAT_DMC1_CHANGING)
continue;
/* CLK_SRC_PERIL0 */
clr = UART0_SEL(15) | UART1_SEL(15) | UART2_SEL(15) |
UART3_SEL(15) | UART4_SEL(15);
/*
* Set CLK_SRC_PERIL0 clocks src to MPLL
* src values: 0(XXTI); 1(XusbXTI); 2(SCLK_HDMI24M); 3(SCLK_USBPHY0);
* 5(SCLK_HDMIPHY); 6(SCLK_MPLL_USER_T); 7(SCLK_EPLL);
* 8(SCLK_VPLL)
*
* Set all to SCLK_MPLL_USER_T
*/
set = UART0_SEL(6) | UART1_SEL(6) | UART2_SEL(6) | UART3_SEL(6) |
UART4_SEL(6);
clrsetbits_le32(&clk->src_peril0, clr, set);
/* CLK_DIV_PERIL0 */
clr = UART0_RATIO(15) | UART1_RATIO(15) | UART2_RATIO(15) |
UART3_RATIO(15) | UART4_RATIO(15);
/*
* For MOUTuart0-4: 800MHz
*
* SCLK_UARTx = MOUTuartX / (ratio + 1) = 100 (7)
*/
set = UART0_RATIO(7) | UART1_RATIO(7) | UART2_RATIO(7) |
UART3_RATIO(7) | UART4_RATIO(7);
clrsetbits_le32(&clk->div_peril0, clr, set);
while (readl(&clk->div_stat_peril0) & DIV_STAT_PERIL0_CHANGING)
continue;
/* CLK_DIV_FSYS1 */
clr = MMC0_RATIO(15) | MMC0_PRE_RATIO(255) | MMC1_RATIO(15) |
MMC1_PRE_RATIO(255);
/*
* For MOUTmmc0-3 = 800 MHz (MPLL)
*
* DOUTmmc1 = MOUTmmc1 / (ratio + 1) = 100 (7)
* sclk_mmc1 = DOUTmmc1 / (ratio + 1) = 50 (1)
* DOUTmmc0 = MOUTmmc0 / (ratio + 1) = 100 (7)
* sclk_mmc0 = DOUTmmc0 / (ratio + 1) = 50 (1)
*/
set = MMC0_RATIO(7) | MMC0_PRE_RATIO(1) | MMC1_RATIO(7) |
MMC1_PRE_RATIO(1);
clrsetbits_le32(&clk->div_fsys1, clr, set);
/* Wait for divider ready status */
while (readl(&clk->div_stat_fsys1) & DIV_STAT_FSYS1_CHANGING)
continue;
/* CLK_DIV_FSYS2 */
clr = MMC2_RATIO(15) | MMC2_PRE_RATIO(255) | MMC3_RATIO(15) |
MMC3_PRE_RATIO(255);
/*
* For MOUTmmc0-3 = 800 MHz (MPLL)
*
* DOUTmmc3 = MOUTmmc3 / (ratio + 1) = 100 (7)
* sclk_mmc3 = DOUTmmc3 / (ratio + 1) = 50 (1)
* DOUTmmc2 = MOUTmmc2 / (ratio + 1) = 100 (7)
* sclk_mmc2 = DOUTmmc2 / (ratio + 1) = 50 (1)
*/
set = MMC2_RATIO(7) | MMC2_PRE_RATIO(1) | MMC3_RATIO(7) |
MMC3_PRE_RATIO(1);
clrsetbits_le32(&clk->div_fsys2, clr, set);
/* Wait for divider ready status */
while (readl(&clk->div_stat_fsys2) & DIV_STAT_FSYS2_CHANGING)
continue;
/* CLK_DIV_FSYS3 */
clr = MMC4_RATIO(15) | MMC4_PRE_RATIO(255);
/*
* For MOUTmmc4 = 800 MHz (MPLL)
*
* DOUTmmc4 = MOUTmmc4 / (ratio + 1) = 100 (7)
* sclk_mmc4 = DOUTmmc4 / (ratio + 1) = 100 (0)
*/
set = MMC4_RATIO(7) | MMC4_PRE_RATIO(0);
clrsetbits_le32(&clk->div_fsys3, clr, set);
/* Wait for divider ready status */
while (readl(&clk->div_stat_fsys3) & DIV_STAT_FSYS3_CHANGING)
continue;
return;
}
static void board_gpio_init(void)
{
/* eMMC Reset Pin */
gpio_request(EXYNOS4X12_GPIO_K12, "eMMC Reset");
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_request(EXYNOS4X12_GPIO_D00, "FAN Control");
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_request(EXYNOS4X12_GPIO_L20, "OTG Vbus");
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_request(EXYNOS4X12_GPIO_X31, "OTG INT");
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);
/* Blue LED (Odroid X2/U2/U3) */
gpio_request(EXYNOS4X12_GPIO_C10, "Blue LED");
gpio_direction_output(EXYNOS4X12_GPIO_C10, 0);
#ifdef CONFIG_CMD_USB
/* USB3503A Reference frequency */
gpio_request(EXYNOS4X12_GPIO_X30, "USB3503A RefFreq");
/* USB3503A Connect */
gpio_request(EXYNOS4X12_GPIO_X34, "USB3503A Connect");
/* USB3503A Reset */
gpio_request(EXYNOS4X12_GPIO_X35, "USB3503A Reset");
#endif
}
int exynos_early_init_f(void)
{
board_clock_init();
return 0;
}
int exynos_init(void)
{
board_gpio_init();
return 0;
}
int exynos_power_init(void)
{
const char *mmc_regulators[] = {
"VDDQ_EMMC_1.8V",
"VDDQ_EMMC_2.8V",
"TFLASH_2.8V",
NULL,
};
if (regulator_list_autoset(mmc_regulators, NULL, true))
pr_err("Unable to init all mmc regulators\n");
return 0;
}
#ifdef CONFIG_USB_GADGET
static int s5pc210_phy_control(int on)
{
struct udevice *dev;
int ret;
ret = regulator_get_by_platname("VDD_UOTG_3.0V", &dev);
if (ret) {
pr_err("Regulator get error: %d\n", ret);
return ret;
}
if (on)
return regulator_set_mode(dev, OPMODE_ON);
else
return regulator_set_mode(dev, OPMODE_LPM);
}
struct dwc2_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,
};
#endif
#if defined(CONFIG_USB_GADGET) || defined(CONFIG_CMD_USB)
static void set_usb3503_ref_clk(void)
{
#ifdef CONFIG_BOARD_TYPES
/*
* gpx3-0 chooses primary (low) or secondary (high) reference clock
* frequencies table. The choice of clock is done through hard-wired
* REF_SEL pins.
* The Odroid Us have reference clock at 24 MHz (00 entry from secondary
* table) and Odroid Xs have it at 26 MHz (01 entry from primary table).
*/
if (gd->board_type == ODROID_TYPE_U3)
gpio_direction_output(EXYNOS4X12_GPIO_X30, 0);
else
gpio_direction_output(EXYNOS4X12_GPIO_X30, 1);
#else
/* Choose Odroid Xs frequency without board types */
gpio_direction_output(EXYNOS4X12_GPIO_X30, 1);
#endif /* CONFIG_BOARD_TYPES */
}
int board_usb_init(int index, enum usb_init_type init)
{
#ifdef CONFIG_CMD_USB
struct udevice *dev;
int ret;
set_usb3503_ref_clk();
/* Disconnect, Reset, Connect */
gpio_direction_output(EXYNOS4X12_GPIO_X34, 0);
gpio_direction_output(EXYNOS4X12_GPIO_X35, 0);
gpio_direction_output(EXYNOS4X12_GPIO_X35, 1);
gpio_direction_output(EXYNOS4X12_GPIO_X34, 1);
/* Power off and on BUCK8 for LAN9730 */
debug("LAN9730 - Turning power buck 8 OFF and ON.\n");
ret = regulator_get_by_platname("VCC_P3V3_2.85V", &dev);
if (ret) {
pr_err("Regulator get error: %d\n", ret);
return ret;
}
ret = regulator_set_enable(dev, true);
if (ret) {
pr_err("Regulator %s enable setting error: %d\n", dev->name, ret);
return ret;
}
ret = regulator_set_value(dev, 750000);
if (ret) {
pr_err("Regulator %s value setting error: %d\n", dev->name, ret);
return ret;
}
ret = regulator_set_value(dev, 3300000);
if (ret) {
pr_err("Regulator %s value setting error: %d\n", dev->name, ret);
return ret;
}
#endif
debug("USB_udc_probe\n");
return dwc2_udc_probe(&s5pc210_otg_data);
}
#endif
@@ -0,0 +1,254 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2014 Samsung Electronics
* Przemyslaw Marczak <p.marczak@samsung.com>
*/
#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,12 @@
if TARGET_ORIGEN
config SYS_BOARD
default "origen"
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "origen"
endif
@@ -0,0 +1,6 @@
ORIGEN BOARD
M: Chander Kashyap <k.chander@samsung.com>
S: Maintained
F: board/samsung/origen/
F: include/configs/origen.h
F: configs/origen_defconfig
@@ -0,0 +1,20 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2011 Samsung Electronics
ifdef CONFIG_SPL_BUILD
# necessary to create built-in.o
obj- := __dummy__.o
hostprogs-y := tools/mkorigenspl
always := $(hostprogs-y)
# omit -O2 option to suppress
# warning: dereferencing type-punned pointer will break strict-aliasing rules
#
# TODO:
# Fix the root cause in tools/mkorigenspl.c and delete the following work-around
$(obj)/tools/mkorigenspl: HOSTCFLAGS:=$(filter-out -O2,$(HOSTCFLAGS))
else
obj-y += origen.o
endif
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2011 Samsung Electronics
*/
#include <common.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/arch/cpu.h>
#include <asm/arch/mmc.h>
#include <asm/arch/periph.h>
#include <asm/arch/pinmux.h>
#include <usb.h>
u32 get_board_rev(void)
{
return 0;
}
int exynos_init(void)
{
return 0;
}
int board_usb_init(int index, enum usb_init_type init)
{
return 0;
}
#ifdef CONFIG_BOARD_EARLY_INIT_F
int exynos_early_init_f(void)
{
return 0;
}
#endif
@@ -0,0 +1,38 @@
if TARGET_SMDK5250
config SYS_BOARD
default "smdk5250"
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "smdk5250"
endif
if TARGET_SNOW
config SYS_BOARD
default "smdk5250"
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "snow"
endif
if TARGET_SPRING
config SYS_BOARD
default "smdk5250"
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "spring"
endif
@@ -0,0 +1,18 @@
SMDK5250 BOARD
M: Chander Kashyap <k.chander@samsung.com>
S: Maintained
F: board/samsung/smdk5250/
F: include/configs/smdk5250.h
F: configs/smdk5250_defconfig
SNOW BOARD
M: Akshay Saraswat <akshay.s@samsung.com>
S: Maintained
F: include/configs/snow.h
F: configs/snow_defconfig
SPRING BOARD
M: Simon Glass <sjg@chromium.org>
S: Maintained
F: include/configs/spring.h
F: configs/spring_defconfig
@@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2012 Samsung Electronics
obj-y += smdk5250_spl.o
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2012 The Chromium OS Authors.
*/
#include <common.h>
#include <asm/arch/cpu.h>
#include <asm/arch/spl.h>
#include <asm/arch/clk.h>
#define SIGNATURE 0xdeadbeef
/* Parameters of early board initialization in SPL */
static struct spl_machine_param machine_param
__attribute__((section(".machine_param"))) = {
.signature = SIGNATURE,
.version = 1,
.params = "vmubfasirM",
.size = sizeof(machine_param),
.mem_iv_size = 0x1f,
.mem_type = DDR_MODE_DDR3,
/*
* Set uboot_size to 0x100000 bytes.
*
* This is an overly conservative value chosen to accommodate all
* possible U-Boot image. You are advised to set this value to a
* smaller realistic size via scripts that modifies the .machine_param
* section of output U-Boot image.
*/
.uboot_size = 0x100000,
.boot_source = BOOT_MODE_OM,
.frequency_mhz = 800,
.arm_freq_mhz = 1700,
.serial_base = 0x12c30000,
.i2c_base = 0x12c60000,
.mem_manuf = MEM_MANUF_SAMSUNG,
};
struct spl_machine_param *spl_get_machine_params(void)
{
if (machine_param.signature != SIGNATURE) {
/* Will hang if SIGNATURE dont match */
while (1)
;
}
return &machine_param;
}
@@ -0,0 +1,51 @@
if TARGET_ODROID_XU3
config SYS_BOARD
default "smdk5420"
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "odroid_xu3"
endif
if TARGET_PEACH_PI
config SYS_BOARD
default "smdk5420"
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "peach-pi"
endif
if TARGET_PEACH_PIT
config SYS_BOARD
default "smdk5420"
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "peach-pit"
endif
if TARGET_SMDK5420
config SYS_BOARD
default "smdk5420"
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "smdk5420"
endif
@@ -0,0 +1,18 @@
SMDK5420 BOARD
M: Akshay Saraswat <akshay.s@samsung.com>
S: Maintained
F: board/samsung/smdk5420/
F: include/configs/peach-pit.h
F: configs/peach-pit_defconfig
F: include/configs/smdk5420.h
F: configs/smdk5420_defconfig
F: include/configs/peach-pi.h
F: configs/peach-pi_defconfig
ODROID-XU3 BOARD
M: Jaehoon Chung <jh80.chung@samsung.com>
M: Lukasz Majewski <lukma@denx.de>
S: Maintained
F: board/samsung/smdk5420/
F: include/configs/odroid_xu3.h
F: configs/odroid-xu3_defconfig
@@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2013 Samsung Electronics
obj-y += smdk5420_spl.o
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2013 The Chromium OS Authors.
*/
#include <common.h>
#include <asm/arch/cpu.h>
#include <asm/arch/spl.h>
#include <asm/arch/clk.h>
#define SIGNATURE 0xdeadbeef
/* Parameters of early board initialization in SPL */
static struct spl_machine_param machine_param
__attribute__((section(".machine_param"))) = {
.signature = SIGNATURE,
.version = 1,
.params = "vmubfasirM",
.size = sizeof(machine_param),
.mem_iv_size = 0x1f,
.mem_type = DDR_MODE_DDR3,
/*
* Set uboot_size to 0x100000 bytes.
*
* This is an overly conservative value chosen to accommodate all
* possible U-Boot image. You are advised to set this value to a
* smaller realistic size via scripts that modifies the .machine_param
* section of output U-Boot image.
*/
.uboot_size = 0x100000,
.boot_source = BOOT_MODE_OM,
.frequency_mhz = 800,
.arm_freq_mhz = 900,
.serial_base = 0x12c30000,
.i2c_base = 0x12c60000,
.mem_manuf = MEM_MANUF_SAMSUNG,
};
struct spl_machine_param *spl_get_machine_params(void)
{
if (machine_param.signature != SIGNATURE) {
/* Will hang if SIGNATURE dont match */
while (1)
;
}
return &machine_param;
}
@@ -0,0 +1,15 @@
if TARGET_SMDKC100
config SYS_BOARD
default "smdkc100"
config SYS_VENDOR
default "samsung"
config SYS_SOC
default "s5pc1xx"
config SYS_CONFIG_NAME
default "smdkc100"
endif
@@ -0,0 +1,6 @@
SMDKC100 BOARD
M: Minkyu Kang <mk7.kang@samsung.com>
S: Maintained
F: board/samsung/smdkc100/
F: include/configs/smdkc100.h
F: configs/smdkc100_defconfig
@@ -0,0 +1,11 @@
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2000, 2001, 2002
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# (C) Copyright 2008
# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
obj-y := smdkc100.o
obj-$(CONFIG_SAMSUNG_ONENAND) += onenand.o
obj-y += lowlevel_init.o
@@ -0,0 +1,152 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2009 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
* Minkyu Kang <mk7.kang@samsung.com>
*/
#include <config.h>
#include <asm/arch/cpu.h>
#include <asm/arch/power.h>
/*
* Register usages:
*
* r5 has zero always
*/
.globl lowlevel_init
lowlevel_init:
mov r9, lr
/* r5 has always zero */
mov r5, #0
ldr r8, =S5PC100_GPIO_BASE
/* Disable Watchdog */
ldr r0, =S5PC100_WATCHDOG_BASE @0xEA200000
orr r0, r0, #0x0
str r5, [r0]
/* setting SRAM */
ldr r0, =S5PC100_SROMC_BASE
ldr r1, =0x9
str r1, [r0]
/* S5PC100 has 3 groups of interrupt sources */
ldr r0, =S5PC100_VIC0_BASE @0xE4000000
ldr r1, =S5PC100_VIC1_BASE @0xE4000000
ldr r2, =S5PC100_VIC2_BASE @0xE4000000
/* Disable all interrupts (VIC0, VIC1 and VIC2) */
mvn r3, #0x0
str r3, [r0, #0x14] @INTENCLEAR
str r3, [r1, #0x14] @INTENCLEAR
str r3, [r2, #0x14] @INTENCLEAR
/* Set all interrupts as IRQ */
str r5, [r0, #0xc] @INTSELECT
str r5, [r1, #0xc] @INTSELECT
str r5, [r2, #0xc] @INTSELECT
/* Pending Interrupt Clear */
str r5, [r0, #0xf00] @INTADDRESS
str r5, [r1, #0xf00] @INTADDRESS
str r5, [r2, #0xf00] @INTADDRESS
/* for UART */
bl uart_asm_init
/* for TZPC */
bl tzpc_asm_init
1:
mov lr, r9
mov pc, lr
/*
* system_clock_init: Initialize core clock and bus clock.
* void system_clock_init(void)
*/
system_clock_init:
ldr r8, =S5PC100_CLOCK_BASE @ 0xE0100000
/* Set Clock divider */
ldr r1, =0x00011110
str r1, [r8, #0x304]
ldr r1, =0x1
str r1, [r8, #0x308]
ldr r1, =0x00011301
str r1, [r8, #0x300]
/* Set Lock Time */
ldr r1, =0xe10 @ Locktime : 0xe10 = 3600
str r1, [r8, #0x000] @ APLL_LOCK
str r1, [r8, #0x004] @ MPLL_LOCK
str r1, [r8, #0x008] @ EPLL_LOCK
str r1, [r8, #0x00C] @ HPLL_LOCK
/* APLL_CON */
ldr r1, =0x81bc0400 @ SDIV 0, PDIV 4, MDIV 444 (1332MHz)
str r1, [r8, #0x100]
/* MPLL_CON */
ldr r1, =0x80590201 @ SDIV 1, PDIV 2, MDIV 89 (267MHz)
str r1, [r8, #0x104]
/* EPLL_CON */
ldr r1, =0x80870303 @ SDIV 3, PDIV 3, MDIV 135 (67.5MHz)
str r1, [r8, #0x108]
/* HPLL_CON */
ldr r1, =0x80600603
str r1, [r8, #0x10C]
/* Set Source Clock */
ldr r1, =0x1111 @ A, M, E, HPLL Muxing
str r1, [r8, #0x200] @ CLK_SRC0
ldr r1, =0x1000001 @ Uart Clock & CLK48M Muxing
str r1, [r8, #0x204] @ CLK_SRC1
ldr r1, =0x9000 @ ARMCLK/4
str r1, [r8, #0x400] @ CLK_OUT
/* wait at least 200us to stablize all clock */
mov r2, #0x10000
1: subs r2, r2, #1
bne 1b
mov pc, lr
/*
* uart_asm_init: Initialize UART's pins
*/
uart_asm_init:
mov r0, r8
ldr r1, =0x22222222
str r1, [r0, #0x0] @ GPA0_CON
ldr r1, =0x00022222
str r1, [r0, #0x20] @ GPA1_CON
mov pc, lr
/*
* tzpc_asm_init: Initialize TZPC
*/
tzpc_asm_init:
ldr r0, =0xE3800000
mov r1, #0x0
str r1, [r0]
mov r1, #0xff
str r1, [r0, #0x804]
str r1, [r0, #0x810]
ldr r0, =0xE2800000
str r1, [r0, #0x804]
str r1, [r0, #0x810]
str r1, [r0, #0x81C]
ldr r0, =0xE2900000
str r1, [r0, #0x804]
str r1, [r0, #0x810]
mov pc, lr
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2008-2009 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
*/
#include <common.h>
#include <linux/compat.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>
#include <linux/mtd/samsung_onenand.h>
#include <onenand_uboot.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
int onenand_board_init(struct mtd_info *mtd)
{
struct onenand_chip *this = mtd->priv;
struct s5pc100_clock *clk =
(struct s5pc100_clock *)samsung_get_base_clock();
struct samsung_onenand *onenand;
int value;
this->base = (void *)S5PC100_ONENAND_BASE;
onenand = (struct samsung_onenand *)this->base;
/* D0 Domain memory clock gating */
value = readl(&clk->gate_d01);
value &= ~(1 << 2); /* CLK_ONENANDC */
value |= (1 << 2);
writel(value, &clk->gate_d01);
value = readl(&clk->src0);
value &= ~(1 << 24); /* MUX_1nand: 0 from HCLKD0 */
value &= ~(1 << 20); /* MUX_HREF: 0 from FIN_27M */
writel(value, &clk->src0);
value = readl(&clk->div1);
value &= ~(3 << 16); /* PCLKD1_RATIO */
value |= (1 << 16);
writel(value, &clk->div1);
writel(ONENAND_MEM_RESET_COLD, &onenand->mem_reset);
while (!(readl(&onenand->int_err_stat) & RST_CMP))
continue;
writel(RST_CMP, &onenand->int_err_ack);
/*
* Access_Clock [2:0]
* 166 MHz, 134 Mhz : 3
* 100 Mhz, 60 Mhz : 2
*/
writel(0x3, &onenand->acc_clock);
writel(INT_ERR_ALL, &onenand->int_err_mask);
writel(1 << 0, &onenand->int_pin_en); /* Enable */
value = readl(&onenand->int_err_mask);
value &= ~RDY_ACT;
writel(value, &onenand->int_err_mask);
s3c_onenand_init(mtd);
return 0;
}
@@ -0,0 +1,77 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2008-2009 Samsung Electronics
* Minkyu Kang <mk7.kang@samsung.com>
* Kyungmin Park <kyungmin.park@samsung.com>
*/
#include <common.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/sromc.h>
#include <netdev.h>
#include <asm/mach-types.h>
DECLARE_GLOBAL_DATA_PTR;
/*
* Miscellaneous platform dependent initialisations
*/
static void smc9115_pre_init(void)
{
u32 smc_bw_conf, smc_bc_conf;
/* gpio configuration GPK0CON */
gpio_cfg_pin(S5PC100_GPIO_K00 + CONFIG_ENV_SROM_BANK, S5P_GPIO_FUNC(2));
/* Ethernet needs bus width of 16 bits */
smc_bw_conf = SMC_DATA16_WIDTH(CONFIG_ENV_SROM_BANK);
smc_bc_conf = SMC_BC_TACS(0x0) | SMC_BC_TCOS(0x4) | SMC_BC_TACC(0xe)
| SMC_BC_TCOH(0x1) | SMC_BC_TAH(0x4)
| SMC_BC_TACP(0x6) | SMC_BC_PMC(0x0);
/* Select and configure the SROMC bank */
s5p_config_sromc(CONFIG_ENV_SROM_BANK, smc_bw_conf, smc_bc_conf);
}
int board_init(void)
{
smc9115_pre_init();
gd->bd->bi_arch_number = MACH_TYPE_SMDKC100;
gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
return 0;
}
int dram_init(void)
{
gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
return 0;
}
int dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
return 0;
}
#ifdef CONFIG_DISPLAY_BOARDINFO
int checkboard(void)
{
printf("Board:\tSMDKC100\n");
return 0;
}
#endif
int board_eth_init(bd_t *bis)
{
int rc = 0;
#ifdef CONFIG_SMC911X
rc = smc911x_initialize(0, CONFIG_SMC911X_BASE);
#endif
return rc;
}
@@ -0,0 +1,12 @@
if TARGET_SMDKV310
config SYS_BOARD
default "smdkv310"
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "smdkv310"
endif
@@ -0,0 +1,6 @@
SMDKV310 BOARD
M: Chander Kashyap <k.chander@samsung.com>
S: Maintained
F: board/samsung/smdkv310/
F: include/configs/smdkv310.h
F: configs/smdkv310_defconfig
@@ -0,0 +1,13 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2011 Samsung Electronics
ifdef CONFIG_SPL_BUILD
# necessary to create built-in.o
obj- := __dummy__.o
hostprogs-y := tools/mksmdkv310spl
always := $(hostprogs-y)
else
obj-y += smdkv310.o
endif
@@ -0,0 +1,165 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2011 Samsung Electronics
*/
#include <common.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <netdev.h>
#include <asm/arch/cpu.h>
#include <asm/arch/mmc.h>
#include <asm/arch/periph.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/sromc.h>
DECLARE_GLOBAL_DATA_PTR;
static void smc9115_pre_init(void)
{
u32 smc_bw_conf, smc_bc_conf;
/* gpio configuration GPK0CON */
gpio_cfg_pin(EXYNOS4_GPIO_Y00 + CONFIG_ENV_SROM_BANK, S5P_GPIO_FUNC(2));
/* Ethernet needs bus width of 16 bits */
smc_bw_conf = SROMC_DATA16_WIDTH(CONFIG_ENV_SROM_BANK);
smc_bc_conf = SROMC_BC_TACS(0x0F) | SROMC_BC_TCOS(0x0F)
| SROMC_BC_TACC(0x0F) | SROMC_BC_TCOH(0x0F)
| SROMC_BC_TAH(0x0F) | SROMC_BC_TACP(0x0F)
| SROMC_BC_PMC(0x0F);
/* Select and configure the SROMC bank */
s5p_config_sromc(CONFIG_ENV_SROM_BANK, smc_bw_conf, smc_bc_conf);
}
int board_init(void)
{
smc9115_pre_init();
gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
return 0;
}
int dram_init(void)
{
gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE)
+ get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE)
+ get_ram_size((long *)PHYS_SDRAM_3, PHYS_SDRAM_3_SIZE)
+ get_ram_size((long *)PHYS_SDRAM_4, PHYS_SDRAM_4_SIZE);
return 0;
}
int dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1,
PHYS_SDRAM_1_SIZE);
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2,
PHYS_SDRAM_2_SIZE);
gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3,
PHYS_SDRAM_3_SIZE);
gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4,
PHYS_SDRAM_4_SIZE);
return 0;
}
int board_eth_init(bd_t *bis)
{
int rc = 0;
#ifdef CONFIG_SMC911X
rc = smc911x_initialize(0, CONFIG_SMC911X_BASE);
#endif
return rc;
}
#ifdef CONFIG_DISPLAY_BOARDINFO
int checkboard(void)
{
printf("\nBoard: SMDKV310\n");
return 0;
}
#endif
#ifdef CONFIG_MMC
int board_mmc_init(bd_t *bis)
{
int i, err;
/*
* MMC2 SD card GPIO:
*
* GPK2[0] SD_2_CLK(2)
* GPK2[1] SD_2_CMD(2)
* GPK2[2] SD_2_CDn
* GPK2[3:6] SD_2_DATA[0:3](2)
*/
for (i = EXYNOS4_GPIO_K20; i < EXYNOS4_GPIO_K27; i++) {
/* GPK2[0:6] special function 2 */
gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2));
/* GPK2[0:6] drv 4x */
gpio_set_drv(i, S5P_GPIO_DRV_4X);
/* GPK2[0:1] pull disable */
if (i == EXYNOS4_GPIO_K20 || i == EXYNOS4_GPIO_K21) {
gpio_set_pull(i, S5P_GPIO_PULL_NONE);
continue;
}
/* GPK2[2:6] pull up */
gpio_set_pull(i, S5P_GPIO_PULL_UP);
}
err = s5p_mmc_init(2, 4);
return err;
}
#endif
static int board_uart_init(void)
{
int err;
err = exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE);
if (err) {
debug("UART0 not configured\n");
return err;
}
err = exynos_pinmux_config(PERIPH_ID_UART1, PINMUX_FLAG_NONE);
if (err) {
debug("UART1 not configured\n");
return err;
}
err = exynos_pinmux_config(PERIPH_ID_UART2, PINMUX_FLAG_NONE);
if (err) {
debug("UART2 not configured\n");
return err;
}
err = exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE);
if (err) {
debug("UART3 not configured\n");
return err;
}
return 0;
}
#ifdef CONFIG_BOARD_EARLY_INIT_F
int board_early_init_f(void)
{
int err;
err = board_uart_init();
if (err) {
debug("UART init failed\n");
return err;
}
return err;
}
#endif
@@ -0,0 +1,12 @@
if TARGET_TRATS
config SYS_BOARD
default "trats"
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "trats"
endif
@@ -0,0 +1,6 @@
TRATS BOARD
M: Jaehoon Chung <jh80.chung@samsung.com>
S: Maintained
F: board/samsung/trats/
F: include/configs/trats.h
F: configs/trats_defconfig
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2011 Samsung Electronics
# Heungjun Kim <riverful.kim@samsung.com>
obj-y += trats.o
@@ -0,0 +1,619 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Machine Specific Values for TRATS board based on EXYNOS4210
*
* Copyright (C) 2011 Samsung Electronics
* Heungjun Kim <riverful.kim@samsung.com>
*/
#ifndef _TRATS_SETUP_H
#define _TRATS_SETUP_H
#include <config.h>
#include <asm/arch/cpu.h>
/* CLK_SRC_CPU: APLL(1), MPLL(1), CORE(0), HPM(0) */
#define MUX_HPM_SEL_MOUTAPLL 0x0
#define MUX_HPM_SEL_SCLKMPLL 0x1
#define MUX_CORE_SEL_MOUTAPLL 0x0
#define MUX_CORE_SEL_SCLKMPLL 0x1
#define MUX_MPLL_SEL_FILPLL 0x0
#define MUX_MPLL_SEL_MOUTMPLLFOUT 0x1
#define MUX_APLL_SEL_FILPLL 0x0
#define MUX_APLL_SEL_MOUTMPLLFOUT 0x1
#define CLK_SRC_CPU_VAL ((MUX_HPM_SEL_MOUTAPLL << 20) \
| (MUX_CORE_SEL_MOUTAPLL << 16) \
| (MUX_MPLL_SEL_MOUTMPLLFOUT << 8)\
| (MUX_APLL_SEL_MOUTMPLLFOUT << 0))
/* CLK_DIV_CPU0 */
#define APLL_RATIO 0x0
#define PCLK_DBG_RATIO 0x1
#define ATB_RATIO 0x3
#define PERIPH_RATIO 0x3
#define COREM1_RATIO 0x7
#define COREM0_RATIO 0x3
#define CORE_RATIO 0x0
#define CLK_DIV_CPU0_VAL ((APLL_RATIO << 24) \
| (PCLK_DBG_RATIO << 20) \
| (ATB_RATIO << 16) \
| (PERIPH_RATIO << 12) \
| (COREM1_RATIO << 8) \
| (COREM0_RATIO << 4) \
| (CORE_RATIO << 0))
/* CLK_DIV_CPU1 */
#define HPM_RATIO 0x0
#define COPY_RATIO 0x3
#define CLK_DIV_CPU1_VAL ((HPM_RATIO << 4) | (COPY_RATIO))
/* CLK_DIV_DMC0 */
#define CORE_TIMERS_RATIO 0x1
#define COPY2_RATIO 0x3
#define DMCP_RATIO 0x1
#define DMCD_RATIO 0x1
#define DMC_RATIO 0x1
#define DPHY_RATIO 0x1
#define ACP_PCLK_RATIO 0x1
#define ACP_RATIO 0x3
#define CLK_DIV_DMC0_VAL ((CORE_TIMERS_RATIO << 28) \
| (COPY2_RATIO << 24) \
| (DMCP_RATIO << 20) \
| (DMCD_RATIO << 16) \
| (DMC_RATIO << 12) \
| (DPHY_RATIO << 8) \
| (ACP_PCLK_RATIO << 4) \
| (ACP_RATIO << 0))
/* CLK_DIV_DMC1 */
#define DPM_RATIO 0x1
#define DVSEM_RATIO 0x1
#define PWI_RATIO 0x1
#define CLK_DIV_DMC1_VAL ((DPM_RATIO << 24) \
| (DVSEM_RATIO << 16) \
| (PWI_RATIO << 8))
/* CLK_SRC_TOP0 */
#define MUX_ONENAND_SEL_ACLK_133 0x0
#define MUX_ONENAND_SEL_ACLK_160 0x1
#define MUX_ACLK_133_SEL_SCLKMPLL 0x0
#define MUX_ACLK_133_SEL_SCLKAPLL 0x1
#define MUX_ACLK_160_SEL_SCLKMPLL 0x0
#define MUX_ACLK_160_SEL_SCLKAPLL 0x1
#define MUX_ACLK_100_SEL_SCLKMPLL 0x0
#define MUX_ACLK_100_SEL_SCLKAPLL 0x1
#define MUX_ACLK_200_SEL_SCLKMPLL 0x0
#define MUX_ACLK_200_SEL_SCLKAPLL 0x1
#define MUX_VPLL_SEL_FINPLL 0x0
#define MUX_VPLL_SEL_FOUTVPLL 0x1
#define MUX_EPLL_SEL_FINPLL 0x0
#define MUX_EPLL_SEL_FOUTEPLL 0x1
#define MUX_ONENAND_1_SEL_MOUTONENAND 0x0
#define MUX_ONENAND_1_SEL_SCLKVPLL 0x1
#define CLK_SRC_TOP0_VAL ((MUX_ONENAND_SEL_ACLK_160 << 28) \
| (MUX_ACLK_133_SEL_SCLKMPLL << 24) \
| (MUX_ACLK_160_SEL_SCLKMPLL << 20) \
| (MUX_ACLK_100_SEL_SCLKMPLL << 16) \
| (MUX_ACLK_200_SEL_SCLKMPLL << 12) \
| (MUX_VPLL_SEL_FOUTVPLL << 8) \
| (MUX_EPLL_SEL_FOUTEPLL << 4) \
| (MUX_ONENAND_1_SEL_MOUTONENAND << 0))
/* CLK_DIV_TOP */
#define ONENAND_RATIO 0x0
#define ACLK_133_RATIO 0x5
#define ACLK_160_RATIO 0x4
#define ACLK_100_RATIO 0x7
#define ACLK_200_RATIO 0x3
#define CLK_DIV_TOP_VAL ((ONENAND_RATIO << 16) \
| (ACLK_133_RATIO << 12)\
| (ACLK_160_RATIO << 8) \
| (ACLK_100_RATIO << 4) \
| (ACLK_200_RATIO << 0))
/* CLK_DIV_LEFTBUS */
#define GPL_RATIO 0x1
#define GDL_RATIO 0x3
#define CLK_DIV_LEFTBUS_VAL ((GPL_RATIO << 4) | (GDL_RATIO))
/* CLK_DIV_RIGHTBUS */
#define GPR_RATIO 0x1
#define GDR_RATIO 0x3
#define CLK_DIV_RIGHTBUS_VAL ((GPR_RATIO << 4) | (GDR_RATIO))
/* CLK_SRS_FSYS: 6 = SCLKMPLL */
#define SATA_SEL_SCLKMPLL 0
#define SATA_SEL_SCLKAPLL 1
#define MMC_SEL_XXTI 0
#define MMC_SEL_XUSBXTI 1
#define MMC_SEL_SCLK_HDMI24M 2
#define MMC_SEL_SCLK_USBPHY0 3
#define MMC_SEL_SCLK_USBPHY1 4
#define MMC_SEL_SCLK_HDMIPHY 5
#define MMC_SEL_SCLKMPLL 6
#define MMC_SEL_SCLKEPLL 7
#define MMC_SEL_SCLKVPLL 8
#define MMCC0_SEL MMC_SEL_SCLKMPLL
#define MMCC1_SEL MMC_SEL_SCLKMPLL
#define MMCC2_SEL MMC_SEL_SCLKMPLL
#define MMCC3_SEL MMC_SEL_SCLKMPLL
#define MMCC4_SEL MMC_SEL_SCLKMPLL
#define CLK_SRC_FSYS_VAL ((SATA_SEL_SCLKMPLL << 24) \
| (MMCC4_SEL << 16) \
| (MMCC3_SEL << 12) \
| (MMCC2_SEL << 8) \
| (MMCC1_SEL << 4) \
| (MMCC0_SEL << 0))
/* SCLK_MMC[0-4] = MOUTMMC[0-4]/(MMC[0-4]_RATIO + 1)/(MMC[0-4]_PRE_RATIO +1) */
/* CLK_DIV_FSYS1: 800(MPLL) / (15 + 1) */
#define MMC0_RATIO 0xF
#define MMC0_PRE_RATIO 0x0
#define MMC1_RATIO 0xF
#define MMC1_PRE_RATIO 0x0
#define CLK_DIV_FSYS1_VAL ((MMC1_PRE_RATIO << 24) \
| (MMC1_RATIO << 16) \
| (MMC0_PRE_RATIO << 8) \
| (MMC0_RATIO << 0))
/* CLK_DIV_FSYS2: 800(MPLL) / (15 + 1) */
#define MMC2_RATIO 0xF
#define MMC2_PRE_RATIO 0x0
#define MMC3_RATIO 0xF
#define MMC3_PRE_RATIO 0x0
#define CLK_DIV_FSYS2_VAL ((MMC3_PRE_RATIO << 24) \
| (MMC3_RATIO << 16) \
| (MMC2_PRE_RATIO << 8) \
| (MMC2_RATIO << 0))
/* CLK_DIV_FSYS3: 800(MPLL) / (15 + 1) */
#define MMC4_RATIO 0xF
#define MMC4_PRE_RATIO 0x0
#define CLK_DIV_FSYS3_VAL ((MMC4_PRE_RATIO << 8) \
| (MMC4_RATIO << 0))
/* CLK_SRC_PERIL0 */
#define UART_SEL_XXTI 0
#define UART_SEL_XUSBXTI 1
#define UART_SEL_SCLK_HDMI24M 2
#define UART_SEL_SCLK_USBPHY0 3
#define UART_SEL_SCLK_USBPHY1 4
#define UART_SEL_SCLK_HDMIPHY 5
#define UART_SEL_SCLKMPLL 6
#define UART_SEL_SCLKEPLL 7
#define UART_SEL_SCLKVPLL 8
#define UART0_SEL UART_SEL_SCLKMPLL
#define UART1_SEL UART_SEL_SCLKMPLL
#define UART2_SEL UART_SEL_SCLKMPLL
#define UART3_SEL UART_SEL_SCLKMPLL
#define UART4_SEL UART_SEL_SCLKMPLL
#define UART5_SEL UART_SEL_SCLKMPLL
#define CLK_SRC_PERIL0_VAL ((UART5_SEL << 16) \
| (UART4_SEL << 12) \
| (UART3_SEL << 12) \
| (UART2_SEL << 8) \
| (UART1_SEL << 4) \
| (UART0_SEL << 0))
/* SCLK_UART[0-4] = MOUTUART[0-4] / (UART[0-4]_RATIO + 1) */
/* CLK_DIV_PERIL0 */
#define UART0_RATIO 7
#define UART1_RATIO 7
#define UART2_RATIO 7
#define UART3_RATIO 4
#define UART4_RATIO 7
#define UART5_RATIO 7
#define CLK_DIV_PERIL0_VAL ((UART5_RATIO << 16) \
| (UART4_RATIO << 12) \
| (UART3_RATIO << 12) \
| (UART2_RATIO << 8) \
| (UART1_RATIO << 4) \
| (UART0_RATIO << 0))
/* CLK_DIV_PERIL3 */
#define SLIMBUS_RATIO 0x0
#define PWM_RATIO 0x8
#define CLK_DIV_PERIL3_VAL ((SLIMBUS_RATIO << 4) \
| (PWM_RATIO << 0))
/* Required period to generate a stable clock output */
/* PLL_LOCK_TIME */
#define PLL_LOCKTIME 0x1C20
/* PLL Values */
#define DISABLE 0
#define ENABLE 1
#define SET_PLL(mdiv, pdiv, sdiv) ((ENABLE << 31)\
| (mdiv << 16) \
| (pdiv << 8) \
| (sdiv << 0))
/* APLL_CON0: 800MHz */
#define APLL_MDIV 0xC8
#define APLL_PDIV 0x6
#define APLL_SDIV 0x1
#define APLL_CON0_VAL SET_PLL(APLL_MDIV, APLL_PDIV, APLL_SDIV)
/* APLL_CON1 */
#define APLL_AFC_ENB 0x1
#define APLL_AFC 0x1C
#define APLL_CON1_VAL ((APLL_AFC_ENB << 31) | (APLL_AFC << 0))
/* MPLL_CON0: 800MHz */
#define MPLL_MDIV 0xC8
#define MPLL_PDIV 0x6
#define MPLL_SDIV 0x1
#define MPLL_CON0_VAL SET_PLL(MPLL_MDIV, MPLL_PDIV, MPLL_SDIV)
/* MPLL_CON1 */
#define MPLL_AFC_ENB 0x1
#define MPLL_AFC 0x1C
#define MPLL_CON1_VAL ((MPLL_AFC_ENB << 31) | (MPLL_AFC << 0))
/* EPLL_CON0: 96MHz */
#define EPLL_MDIV 0x30
#define EPLL_PDIV 0x3
#define EPLL_SDIV 0x2
#define EPLL_CON0_VAL SET_PLL(EPLL_MDIV, EPLL_PDIV, EPLL_SDIV)
/* EPLL_CON1 */
#define EPLL_K 0x0
#define EPLL_CON1_VAL (EPLL_K >> 0)
/* VPLL_CON0: 108MHz */
#define VPLL_MDIV 0x35
#define VPLL_PDIV 0x3
#define VPLL_SDIV 0x2
#define VPLL_CON0_VAL SET_PLL(VPLL_MDIV, VPLL_PDIV, VPLL_SDIV)
/* VPLL_CON1 */
#define VPLL_SSCG_EN DISABLE
#define VPLL_SEL_PF_DN_SPREAD 0x0
#define VPLL_MRR 0x11
#define VPLL_MFR 0x0
#define VPLL_K 0x400
#define VPLL_CON1_VAL ((VPLL_SSCG_EN << 31)\
| (VPLL_SEL_PF_DN_SPREAD << 29) \
| (VPLL_MRR << 24) \
| (VPLL_MFR << 16) \
| (VPLL_K << 0))
/* CLOCK GATE */
#define CLK_DIS 0x0
#define CLK_EN 0x1
#define BIT_CAM_CLK_PIXELASYNCM1 18
#define BIT_CAM_CLK_PIXELASYNCM0 17
#define BIT_CAM_CLK_PPMUCAMIF 16
#define BIT_CAM_CLK_QEFIMC3 15
#define BIT_CAM_CLK_QEFIMC2 14
#define BIT_CAM_CLK_QEFIMC1 13
#define BIT_CAM_CLK_QEFIMC0 12
#define BIT_CAM_CLK_SMMUJPEG 11
#define BIT_CAM_CLK_SMMUFIMC3 10
#define BIT_CAM_CLK_SMMUFIMC2 9
#define BIT_CAM_CLK_SMMUFIMC1 8
#define BIT_CAM_CLK_SMMUFIMC0 7
#define BIT_CAM_CLK_JPEG 6
#define BIT_CAM_CLK_CSIS1 5
#define BIT_CAM_CLK_CSIS0 4
#define BIT_CAM_CLK_FIMC3 3
#define BIT_CAM_CLK_FIMC2 2
#define BIT_CAM_CLK_FIMC1 1
#define BIT_CAM_CLK_FIMC0 0
#define CLK_GATE_IP_CAM_ALL_EN ((CLK_EN << BIT_CAM_CLK_PIXELASYNCM1)\
| (CLK_EN << BIT_CAM_CLK_PIXELASYNCM0)\
| (CLK_EN << BIT_CAM_CLK_PPMUCAMIF)\
| (CLK_EN << BIT_CAM_CLK_QEFIMC3)\
| (CLK_EN << BIT_CAM_CLK_QEFIMC2)\
| (CLK_EN << BIT_CAM_CLK_QEFIMC1)\
| (CLK_EN << BIT_CAM_CLK_QEFIMC0)\
| (CLK_EN << BIT_CAM_CLK_SMMUJPEG)\
| (CLK_EN << BIT_CAM_CLK_SMMUFIMC3)\
| (CLK_EN << BIT_CAM_CLK_SMMUFIMC2)\
| (CLK_EN << BIT_CAM_CLK_SMMUFIMC1)\
| (CLK_EN << BIT_CAM_CLK_SMMUFIMC0)\
| (CLK_EN << BIT_CAM_CLK_JPEG)\
| (CLK_EN << BIT_CAM_CLK_CSIS1)\
| (CLK_EN << BIT_CAM_CLK_CSIS0)\
| (CLK_EN << BIT_CAM_CLK_FIMC3)\
| (CLK_EN << BIT_CAM_CLK_FIMC2)\
| (CLK_EN << BIT_CAM_CLK_FIMC1)\
| (CLK_EN << BIT_CAM_CLK_FIMC0))
#define CLK_GATE_IP_CAM_ALL_DIS ~CLK_GATE_IP_CAM_ALL_EN
#define BIT_VP_CLK_PPMUTV 5
#define BIT_VP_CLK_SMMUTV 4
#define BIT_VP_CLK_HDMI 3
#define BIT_VP_CLK_TVENC 2
#define BIT_VP_CLK_MIXER 1
#define BIT_VP_CLK_VP 0
#define CLK_GATE_IP_VP_ALL_EN ((CLK_EN << BIT_VP_CLK_PPMUTV)\
| (CLK_EN << BIT_VP_CLK_SMMUTV)\
| (CLK_EN << BIT_VP_CLK_HDMI)\
| (CLK_EN << BIT_VP_CLK_TVENC)\
| (CLK_EN << BIT_VP_CLK_MIXER)\
| (CLK_EN << BIT_VP_CLK_VP))
#define CLK_GATE_IP_VP_ALL_DIS ~CLK_GATE_IP_VP_ALL_EN
#define BIT_MFC_CLK_PPMUMFC_R 4
#define BIT_MFC_CLK_PPMUMFC_L 3
#define BIT_MFC_CLK_SMMUMFC_R 2
#define BIT_MFC_CLK_SMMUMFC_L 1
#define BIT_MFC_CLK_MFC 0
#define CLK_GATE_IP_MFC_ALL_EN ((CLK_EN << BIT_MFC_CLK_PPMUMFC_R)\
| (CLK_EN << BIT_MFC_CLK_PPMUMFC_L)\
| (CLK_EN << BIT_MFC_CLK_SMMUMFC_R)\
| (CLK_EN << BIT_MFC_CLK_SMMUMFC_L)\
| (CLK_EN << BIT_MFC_CLK_MFC))
#define CLK_GATE_IP_MFC_ALL_DIS ~CLK_GATE_IP_MFC_ALL_EN
#define BIT_G3D_CLK_QEG3D 2
#define BIT_G3D_CLK_PPMUG3D 1
#define BIT_G3D_CLK_G3D 0
#define CLK_GATE_IP_G3D_ALL_EN ((CLK_EN << BIT_G3D_CLK_QEG3D)\
| (CLK_EN << BIT_G3D_CLK_PPMUG3D)\
| (CLK_EN << BIT_G3D_CLK_G3D))
#define CLK_GATE_IP_G3D_ALL_DIS ~CLK_GATE_IP_G3D_ALL_EN
#define BIT_IMAGE_CLK_PPMUIMAGE 9
#define BIT_IMAGE_CLK_QEMDMA 8
#define BIT_IMAGE_CLK_QEROTATOR 7
#define BIT_IMAGE_CLK_QEG2D 6
#define BIT_IMAGE_CLK_SMMUMDMA 5
#define BIT_IMAGE_CLK_SMMUROTATOR 4
#define BIT_IMAGE_CLK_SMMUG2D 3
#define BIT_IMAGE_CLK_MDMA 2
#define BIT_IMAGE_CLK_ROTATOR 1
#define BIT_IMAGE_CLK_G2D 0
#define CLK_GATE_IP_IMAGE_ALL_EN ((CLK_EN << BIT_IMAGE_CLK_PPMUIMAGE)\
| (CLK_EN << BIT_IMAGE_CLK_QEMDMA)\
| (CLK_EN << BIT_IMAGE_CLK_QEROTATOR)\
| (CLK_EN << BIT_IMAGE_CLK_QEG2D)\
| (CLK_EN << BIT_IMAGE_CLK_SMMUMDMA)\
| (CLK_EN << BIT_IMAGE_CLK_SMMUROTATOR)\
| (CLK_EN << BIT_IMAGE_CLK_SMMUG2D)\
| (CLK_EN << BIT_IMAGE_CLK_MDMA)\
| (CLK_EN << BIT_IMAGE_CLK_ROTATOR)\
| (CLK_EN << BIT_IMAGE_CLK_G2D))
#define CLK_GATE_IP_IMAGE_ALL_DIS ~CLK_GATE_IP_IMAGE_ALL_EN
#define BIT_LCD0_CLK_PPMULCD0 5
#define BIT_LCD0_CLK_SMMUFIMD0 4
#define BIT_LCD0_CLK_DSIM0 3
#define BIT_LCD0_CLK_MDNIE0 2
#define BIT_LCD0_CLK_MIE0 1
#define BIT_LCD0_CLK_FIMD0 0
#define CLK_GATE_IP_LCD0_ALL_EN ((CLK_EN << BIT_LCD0_CLK_PPMULCD0)\
| (CLK_EN << BIT_LCD0_CLK_SMMUFIMD0)\
| (CLK_EN << BIT_LCD0_CLK_DSIM0)\
| (CLK_EN << BIT_LCD0_CLK_MDNIE0)\
| (CLK_EN << BIT_LCD0_CLK_MIE0)\
| (CLK_EN << BIT_LCD0_CLK_FIMD0))
#define CLK_GATE_IP_LCD0_ALL_DIS ~CLK_GATE_IP_LCD0_ALL_EN
#define BIT_LCD1_CLK_PPMULCD1 5
#define BIT_LCD1_CLK_SMMUFIMD1 4
#define BIT_LCD1_CLK_DSIM1 3
#define BIT_LCD1_CLK_MDNIE1 2
#define BIT_LCD1_CLK_MIE1 1
#define BIT_LCD1_CLK_FIMD1 0
#define CLK_GATE_IP_LCD1_ALL_EN ((CLK_EN << BIT_LCD1_CLK_PPMULCD1)\
| (CLK_EN << BIT_LCD1_CLK_SMMUFIMD1)\
| (CLK_EN << BIT_LCD1_CLK_DSIM1)\
| (CLK_EN << BIT_LCD1_CLK_MDNIE1)\
| (CLK_EN << BIT_LCD1_CLK_MIE1)\
| (CLK_EN << BIT_LCD1_CLK_FIMD1))
#define CLK_GATE_IP_LCD1_ALL_DIS ~CLK_GATE_IP_LCD1_ALL_EN
#define BIT_FSYS_CLK_SMMUPCIE 18
#define BIT_FSYS_CLK_PPMUFILE 17
#define BIT_FSYS_CLK_NFCON 16
#define BIT_FSYS_CLK_ONENAND 15
#define BIT_FSYS_CLK_PCIE 14
#define BIT_FSYS_CLK_USBDEVICE 13
#define BIT_FSYS_CLK_USBHOST 12
#define BIT_FSYS_CLK_SROMC 11
#define BIT_FSYS_CLK_SATA 10
#define BIT_FSYS_CLK_SDMMC4 9
#define BIT_FSYS_CLK_SDMMC3 8
#define BIT_FSYS_CLK_SDMMC2 7
#define BIT_FSYS_CLK_SDMMC1 6
#define BIT_FSYS_CLK_SDMMC0 5
#define BIT_FSYS_CLK_TSI 4
#define BIT_FSYS_CLK_SATAPHY 3
#define BIT_FSYS_CLK_PCIEPHY 2
#define BIT_FSYS_CLK_PDMA1 1
#define BIT_FSYS_CLK_PDMA0 0
#define CLK_GATE_IP_FSYS_ALL_EN ((CLK_EN << BIT_FSYS_CLK_SMMUPCIE)\
| (CLK_EN << BIT_FSYS_CLK_PPMUFILE)\
| (CLK_EN << BIT_FSYS_CLK_NFCON)\
| (CLK_EN << BIT_FSYS_CLK_ONENAND)\
| (CLK_EN << BIT_FSYS_CLK_PCIE)\
| (CLK_EN << BIT_FSYS_CLK_USBDEVICE)\
| (CLK_EN << BIT_FSYS_CLK_USBHOST)\
| (CLK_EN << BIT_FSYS_CLK_SROMC)\
| (CLK_EN << BIT_FSYS_CLK_SATA)\
| (CLK_EN << BIT_FSYS_CLK_SDMMC4)\
| (CLK_EN << BIT_FSYS_CLK_SDMMC3)\
| (CLK_EN << BIT_FSYS_CLK_SDMMC2)\
| (CLK_EN << BIT_FSYS_CLK_SDMMC1)\
| (CLK_EN << BIT_FSYS_CLK_SDMMC0)\
| (CLK_EN << BIT_FSYS_CLK_TSI)\
| (CLK_EN << BIT_FSYS_CLK_SATAPHY)\
| (CLK_EN << BIT_FSYS_CLK_PCIEPHY)\
| (CLK_EN << BIT_FSYS_CLK_PDMA1)\
| (CLK_EN << BIT_FSYS_CLK_PDMA0))
#define CLK_GATE_IP_FSYS_ALL_DIS ~CLK_GATE_IP_FSYS_ALL_EN
#define BIT_GPS_CLK_SMMUGPS 1
#define BIT_GPS_CLK_GPS 0
#define CLK_GATE_IP_GPS_ALL_EN ((CLK_EN << BIT_GPS_CLK_SMMUGPS)\
| (CLK_EN << BIT_GPS_CLK_GPS))
#define CLK_GATE_IP_GPS_ALL_DIS ~CLK_GATE_IP_GPS_ALL_EN
#define BIT_PERIL_CLK_MODEMIF 28
#define BIT_PERIL_CLK_AC97 27
#define BIT_PERIL_CLK_SPDIF 26
#define BIT_PERIL_CLK_SLIMBUS 25
#define BIT_PERIL_CLK_PWM 24
#define BIT_PERIL_CLK_PCM2 23
#define BIT_PERIL_CLK_PCM1 22
#define BIT_PERIL_CLK_I2S2 21
#define BIT_PERIL_CLK_I2S1 20
#define BIT_PERIL_CLK_RESERVED0 19
#define BIT_PERIL_CLK_SPI2 18
#define BIT_PERIL_CLK_SPI1 17
#define BIT_PERIL_CLK_SPI0 16
#define BIT_PERIL_CLK_TSADC 15
#define BIT_PERIL_CLK_I2CHDMI 14
#define BIT_PERIL_CLK_I2C7 13
#define BIT_PERIL_CLK_I2C6 12
#define BIT_PERIL_CLK_I2C5 11
#define BIT_PERIL_CLK_I2C4 10
#define BIT_PERIL_CLK_I2C3 9
#define BIT_PERIL_CLK_I2C2 8
#define BIT_PERIL_CLK_I2C1 7
#define BIT_PERIL_CLK_I2C0 6
#define BIT_PERIL_CLK_RESERVED1 5
#define BIT_PERIL_CLK_UART4 4
#define BIT_PERIL_CLK_UART3 3
#define BIT_PERIL_CLK_UART2 2
#define BIT_PERIL_CLK_UART1 1
#define BIT_PERIL_CLK_UART0 0
#define CLK_GATE_IP_PERIL_ALL_EN ((CLK_EN << BIT_PERIL_CLK_MODEMIF)\
| (CLK_EN << BIT_PERIL_CLK_AC97)\
| (CLK_EN << BIT_PERIL_CLK_SPDIF)\
| (CLK_EN << BIT_PERIL_CLK_SLIMBUS)\
| (CLK_EN << BIT_PERIL_CLK_PWM)\
| (CLK_EN << BIT_PERIL_CLK_PCM2)\
| (CLK_EN << BIT_PERIL_CLK_PCM1)\
| (CLK_EN << BIT_PERIL_CLK_I2S2)\
| (CLK_EN << BIT_PERIL_CLK_I2S1)\
| (CLK_EN << BIT_PERIL_CLK_RESERVED0)\
| (CLK_EN << BIT_PERIL_CLK_SPI2)\
| (CLK_EN << BIT_PERIL_CLK_SPI1)\
| (CLK_EN << BIT_PERIL_CLK_SPI0)\
| (CLK_EN << BIT_PERIL_CLK_TSADC)\
| (CLK_EN << BIT_PERIL_CLK_I2CHDMI)\
| (CLK_EN << BIT_PERIL_CLK_I2C7)\
| (CLK_EN << BIT_PERIL_CLK_I2C6)\
| (CLK_EN << BIT_PERIL_CLK_I2C5)\
| (CLK_EN << BIT_PERIL_CLK_I2C4)\
| (CLK_EN << BIT_PERIL_CLK_I2C3)\
| (CLK_EN << BIT_PERIL_CLK_I2C2)\
| (CLK_EN << BIT_PERIL_CLK_I2C1)\
| (CLK_EN << BIT_PERIL_CLK_I2C0)\
| (CLK_EN << BIT_PERIL_CLK_RESERVED1)\
| (CLK_EN << BIT_PERIL_CLK_UART4)\
| (CLK_EN << BIT_PERIL_CLK_UART3)\
| (CLK_EN << BIT_PERIL_CLK_UART2)\
| (CLK_EN << BIT_PERIL_CLK_UART1)\
| (CLK_EN << BIT_PERIL_CLK_UART0))
#define CLK_GATE_IP_PERIL_ALL_DIS ~CLK_GATE_IP_PERIL_ALL_EN
#define BIT_PERIR_CLK_TMU_APBIF 17
#define BIT_PERIR_CLK_KEYIF 16
#define BIT_PERIR_CLK_RTC 15
#define BIT_PERIR_CLK_WDT 14
#define BIT_PERIR_CLK_MCT 13
#define BIT_PERIR_CLK_SECKEY 12
#define BIT_PERIR_CLK_HDMI_CEC 11
#define BIT_PERIR_CLK_TZPC5 10
#define BIT_PERIR_CLK_TZPC4 9
#define BIT_PERIR_CLK_TZPC3 8
#define BIT_PERIR_CLK_TZPC2 7
#define BIT_PERIR_CLK_TZPC1 6
#define BIT_PERIR_CLK_TZPC0 5
#define BIT_PERIR_CLK_CMU_DMCPART 4
#define BIT_PERIR_CLK_RESERVED 3
#define BIT_PERIR_CLK_CMU_APBIF 2
#define BIT_PERIR_CLK_SYSREG 1
#define BIT_PERIR_CLK_CHIP_ID 0
#define CLK_GATE_IP_PERIR_ALL_EN ((CLK_EN << BIT_PERIR_CLK_TMU_APBIF)\
| (CLK_EN << BIT_PERIR_CLK_KEYIF)\
| (CLK_EN << BIT_PERIR_CLK_RTC)\
| (CLK_EN << BIT_PERIR_CLK_WDT)\
| (CLK_EN << BIT_PERIR_CLK_MCT)\
| (CLK_EN << BIT_PERIR_CLK_SECKEY)\
| (CLK_EN << BIT_PERIR_CLK_HDMI_CEC)\
| (CLK_EN << BIT_PERIR_CLK_TZPC5)\
| (CLK_EN << BIT_PERIR_CLK_TZPC4)\
| (CLK_EN << BIT_PERIR_CLK_TZPC3)\
| (CLK_EN << BIT_PERIR_CLK_TZPC2)\
| (CLK_EN << BIT_PERIR_CLK_TZPC1)\
| (CLK_EN << BIT_PERIR_CLK_TZPC0)\
| (CLK_EN << BIT_PERIR_CLK_CMU_DMCPART)\
| (CLK_EN << BIT_PERIR_CLK_RESERVED)\
| (CLK_EN << BIT_PERIR_CLK_CMU_APBIF)\
| (CLK_EN << BIT_PERIR_CLK_SYSREG)\
| (CLK_EN << BIT_PERIR_CLK_CHIP_ID))
#define CLK_GATE_IP_PERIR_ALL_DIS ~CLK_GATE_IP_PERIR_ALL_EN
#define BIT_BLOCK_CLK_GPS 7
#define BIT_BLOCK_CLK_RESERVED 6
#define BIT_BLOCK_CLK_LCD1 5
#define BIT_BLOCK_CLK_LCD0 4
#define BIT_BLOCK_CLK_G3D 3
#define BIT_BLOCK_CLK_MFC 2
#define BIT_BLOCK_CLK_TV 1
#define BIT_BLOCK_CLK_CAM 0
#define CLK_GATE_BLOCK_ALL_EN ((CLK_EN << BIT_BLOCK_CLK_GPS)\
| (CLK_EN << BIT_BLOCK_CLK_RESERVED)\
| (CLK_EN << BIT_BLOCK_CLK_LCD1)\
| (CLK_EN << BIT_BLOCK_CLK_LCD0)\
| (CLK_EN << BIT_BLOCK_CLK_G3D)\
| (CLK_EN << BIT_BLOCK_CLK_MFC)\
| (CLK_EN << BIT_BLOCK_CLK_TV)\
| (CLK_EN << BIT_BLOCK_CLK_CAM))
#define CLK_GATE_BLOCK_ALL_DIS ~CLK_GATE_BLOCK_ALL_EN
/*
* GATE CAM : All block
* GATE VP : All block
* GATE MFC : All block
* GATE G3D : All block
* GATE IMAGE : All block
* GATE LCD0 : All block
* GATE LCD1 : All block
* GATE FSYS : Enable - PDMA0,1, SDMMC0,2, USBHOST, USBDEVICE, PPMUFILE
* GATE GPS : All block
* GATE PERI Left : All Enable, Block - SLIMBUS, SPDIF, AC97
* GATE PERI Right : All Enable, Block - KEYIF
* GATE Block : All block
*/
#define CLK_GATE_IP_CAM_VAL CLK_GATE_IP_CAM_ALL_DIS
#define CLK_GATE_IP_VP_VAL CLK_GATE_IP_VP_ALL_DIS
#define CLK_GATE_IP_MFC_VAL CLK_GATE_IP_MFC_ALL_DIS
#define CLK_GATE_IP_G3D_VAL CLK_GATE_IP_G3D_ALL_DIS
#define CLK_GATE_IP_IMAGE_VAL CLK_GATE_IP_IMAGE_ALL_DIS
#define CLK_GATE_IP_LCD0_VAL CLK_GATE_IP_LCD0_ALL_DIS
#define CLK_GATE_IP_LCD1_VAL CLK_GATE_IP_LCD1_ALL_DIS
#define CLK_GATE_IP_FSYS_VAL (CLK_GATE_IP_FSYS_ALL_DIS \
| (CLK_EN << BIT_FSYS_CLK_PPMUFILE)\
| (CLK_EN << BIT_FSYS_CLK_USBDEVICE)\
| (CLK_EN << BIT_FSYS_CLK_USBHOST)\
| (CLK_EN << BIT_FSYS_CLK_SROMC)\
| (CLK_EN << BIT_FSYS_CLK_SDMMC2)\
| (CLK_EN << BIT_FSYS_CLK_SDMMC0)\
| (CLK_EN << BIT_FSYS_CLK_PDMA1)\
| (CLK_EN << BIT_FSYS_CLK_PDMA0))
#define CLK_GATE_IP_GPS_VAL CLK_GATE_IP_GPS_ALL_DIS
#define CLK_GATE_IP_PERIL_VAL (CLK_GATE_IP_PERIL_ALL_DIS \
| ~((CLK_EN << BIT_PERIL_CLK_AC97)\
| (CLK_EN << BIT_PERIL_CLK_SPDIF)\
| (CLK_EN << BIT_PERIL_CLK_I2C2)\
| (CLK_EN << BIT_PERIL_CLK_SLIMBUS)))
#define CLK_GATE_IP_PERIR_VAL (CLK_GATE_IP_PERIR_ALL_DIS \
| ~((CLK_EN << BIT_PERIR_CLK_KEYIF)))
#define CLK_GATE_BLOCK_VAL CLK_GATE_BLOCK_ALL_DIS
/* PS_HOLD: Data Hight, Output En */
#define BIT_DAT 8
#define BIT_EN 9
#define EXYNOS4_PS_HOLD_CON_VAL (0x1 << BIT_DAT | 0x1 << BIT_EN)
#endif
@@ -0,0 +1,473 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2011 Samsung Electronics
* Heungjun Kim <riverful.kim@samsung.com>
* Kyungmin Park <kyungmin.park@samsung.com>
* Donghwa Lee <dh09.lee@samsung.com>
*/
#include <common.h>
#include <env.h>
#include <lcd.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/arch/cpu.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/clock.h>
#include <asm/arch/mipi_dsim.h>
#include <asm/arch/watchdog.h>
#include <asm/arch/power.h>
#include <power/pmic.h>
#include <usb/dwc2_udc.h>
#include <power/max8997_pmic.h>
#include <power/max8997_muic.h>
#include <power/battery.h>
#include <power/max17042_fg.h>
#include <power/pmic.h>
#include <libtizen.h>
#include <usb.h>
#include <usb_mass_storage.h>
#include "setup.h"
unsigned int board_rev;
#ifdef CONFIG_REVISION_TAG
u32 get_board_rev(void)
{
return board_rev;
}
#endif
static void check_hw_revision(void);
struct dwc2_plat_otg_data s5pc210_otg_data;
int exynos_init(void)
{
check_hw_revision();
printf("HW Revision:\t0x%x\n", board_rev);
return 0;
}
#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
static void trats_low_power_mode(void)
{
struct exynos4_clock *clk =
(struct exynos4_clock *)samsung_get_base_clock();
struct exynos4_power *pwr =
(struct exynos4_power *)samsung_get_base_power();
/* Power down CORE1 */
/* LOCAL_PWR_CFG [1:0] 0x3 EN, 0x0 DIS */
writel(0x0, &pwr->arm_core1_configuration);
/* Change the APLL frequency */
/* ENABLE (1 enable) | LOCKED (1 locked) */
/* [31] | [29] */
/* FSEL | MDIV | PDIV | SDIV */
/* [27] | [25:16] | [13:8] | [2:0] */
writel(0xa0c80604, &clk->apll_con0);
/* Change CPU0 clock divider */
/* CORE2_RATIO | APLL_RATIO | PCLK_DBG_RATIO | ATB_RATIO */
/* [30:28] | [26:24] | [22:20] | [18:16] */
/* PERIPH_RATIO | COREM1_RATIO | COREM0_RATIO | CORE_RATIO */
/* [14:12] | [10:8] | [6:4] | [2:0] */
writel(0x00000100, &clk->div_cpu0);
/* CLK_DIV_STAT_CPU0 - wait until clock gets stable (0 = stable) */
while (readl(&clk->div_stat_cpu0) & 0x1111111)
continue;
/* Change clock divider ratio for DMC */
/* DMCP_RATIO | DMCD_RATIO */
/* [22:20] | [18:16] */
/* DMC_RATIO | DPHY_RATIO | ACP_PCLK_RATIO | ACP_RATIO */
/* [14:12] | [10:8] | [6:4] | [2:0] */
writel(0x13113117, &clk->div_dmc0);
/* CLK_DIV_STAT_DMC0 - wait until clock gets stable (0 = stable) */
while (readl(&clk->div_stat_dmc0) & 0x11111111)
continue;
/* Turn off unnecessary power domains */
writel(0x0, &pwr->xxti_configuration); /* XXTI */
writel(0x0, &pwr->cam_configuration); /* CAM */
writel(0x0, &pwr->tv_configuration); /* TV */
writel(0x0, &pwr->mfc_configuration); /* MFC */
writel(0x0, &pwr->g3d_configuration); /* G3D */
writel(0x0, &pwr->gps_configuration); /* GPS */
writel(0x0, &pwr->gps_alive_configuration); /* GPS_ALIVE */
/* Turn off unnecessary clocks */
writel(0x0, &clk->gate_ip_cam); /* CAM */
writel(0x0, &clk->gate_ip_tv); /* TV */
writel(0x0, &clk->gate_ip_mfc); /* MFC */
writel(0x0, &clk->gate_ip_g3d); /* G3D */
writel(0x0, &clk->gate_ip_image); /* IMAGE */
writel(0x0, &clk->gate_ip_gps); /* GPS */
}
#endif
int exynos_power_init(void)
{
#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
int chrg, ret;
struct power_battery *pb;
struct pmic *p_fg, *p_chrg, *p_muic, *p_bat;
/*
* For PMIC/MUIC the I2C bus is named as I2C5, but it is connected
* to logical I2C adapter 0
*
* The FUEL_GAUGE is marked as I2C9 on the schematic, but connected
* to logical I2C adapter 1
*/
ret = power_fg_init(I2C_9);
ret |= power_muic_init(I2C_5);
ret |= power_bat_init(0);
if (ret)
return ret;
p_fg = pmic_get("MAX17042_FG");
if (!p_fg) {
puts("MAX17042_FG: Not found\n");
return -ENODEV;
}
p_chrg = pmic_get("MAX8997_PMIC");
if (!p_chrg) {
puts("MAX8997_PMIC: Not found\n");
return -ENODEV;
}
p_muic = pmic_get("MAX8997_MUIC");
if (!p_muic) {
puts("MAX8997_MUIC: Not found\n");
return -ENODEV;
}
p_bat = pmic_get("BAT_TRATS");
if (!p_bat) {
puts("BAT_TRATS: Not found\n");
return -ENODEV;
}
p_fg->parent = p_bat;
p_chrg->parent = p_bat;
p_muic->parent = p_bat;
p_bat->low_power_mode = trats_low_power_mode;
p_bat->pbat->battery_init(p_bat, p_fg, p_chrg, p_muic);
pb = p_bat->pbat;
chrg = p_muic->chrg->chrg_type(p_muic);
debug("CHARGER TYPE: %d\n", chrg);
if (!p_chrg->chrg->chrg_bat_present(p_chrg)) {
puts("No battery detected\n");
return 0;
}
p_fg->fg->fg_battery_check(p_fg, p_bat);
if (pb->bat->state == CHARGE && chrg == CHARGER_USB)
puts("CHARGE Battery !\n");
#endif
return 0;
}
static unsigned int get_hw_revision(void)
{
int hwrev = 0;
char str[10];
int i;
/* hw_rev[3:0] == GPE1[3:0] */
for (i = 0; i < 4; i++) {
int pin = i + EXYNOS4_GPIO_E10;
sprintf(str, "hw_rev%d", i);
gpio_request(pin, str);
gpio_cfg_pin(pin, S5P_GPIO_INPUT);
gpio_set_pull(pin, S5P_GPIO_PULL_NONE);
}
udelay(1);
for (i = 0; i < 4; i++)
hwrev |= (gpio_get_value(EXYNOS4_GPIO_E10 + i) << i);
debug("hwrev 0x%x\n", hwrev);
return hwrev;
}
static void check_hw_revision(void)
{
int hwrev;
hwrev = get_hw_revision();
board_rev |= hwrev;
}
#ifdef CONFIG_USB_GADGET
static int s5pc210_phy_control(int on)
{
struct udevice *dev;
int reg, ret;
ret = pmic_get("max8997-pmic", &dev);
if (ret)
return ret;
if (on) {
reg = pmic_reg_read(dev, MAX8997_REG_SAFEOUTCTRL);
reg |= ENSAFEOUT1;
ret = pmic_reg_write(dev, MAX8997_REG_SAFEOUTCTRL, reg);
if (ret) {
puts("MAX8997 setting error!\n");
return ret;
}
reg = pmic_reg_read(dev, MAX8997_REG_LDO3CTRL);
reg |= EN_LDO;
ret = pmic_reg_write(dev, MAX8997_REG_LDO3CTRL, reg);
if (ret) {
puts("MAX8997 setting error!\n");
return ret;
}
reg = pmic_reg_read(dev, MAX8997_REG_LDO8CTRL);
reg |= EN_LDO;
ret = pmic_reg_write(dev, MAX8997_REG_LDO8CTRL, reg);
if (ret) {
puts("MAX8997 setting error!\n");
return ret;
}
} else {
reg = pmic_reg_read(dev, MAX8997_REG_LDO8CTRL);
reg &= DIS_LDO;
ret = pmic_reg_write(dev, MAX8997_REG_LDO8CTRL, reg);
if (ret) {
puts("MAX8997 setting error!\n");
return ret;
}
reg = pmic_reg_read(dev, MAX8997_REG_LDO3CTRL);
reg &= DIS_LDO;
ret = pmic_reg_write(dev, MAX8997_REG_LDO3CTRL, reg);
if (ret) {
puts("MAX8997 setting error!\n");
return ret;
}
reg = pmic_reg_read(dev, MAX8997_REG_SAFEOUTCTRL);
reg &= ~ENSAFEOUT1;
ret = pmic_reg_write(dev, MAX8997_REG_SAFEOUTCTRL, reg);
if (ret) {
puts("MAX8997 setting error!\n");
return ret;
}
}
return 0;
}
struct dwc2_plat_otg_data s5pc210_otg_data = {
.phy_control = s5pc210_phy_control,
.regs_phy = EXYNOS4_USBPHY_BASE,
.regs_otg = EXYNOS4_USBOTG_BASE,
.usb_phy_ctrl = EXYNOS4_USBPHY_CONTROL,
.usb_flags = PHY0_SLEEP,
};
int board_usb_init(int index, enum usb_init_type init)
{
debug("USB_udc_probe\n");
return dwc2_udc_probe(&s5pc210_otg_data);
}
int g_dnl_board_usb_cable_connected(void)
{
#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
struct pmic *muic = pmic_get("MAX8997_MUIC");
if (!muic)
return 0;
return !!muic->chrg->chrg_type(muic);
#else
return false;
#endif
}
#endif
static void pmic_reset(void)
{
gpio_direction_output(EXYNOS4_GPIO_X07, 1);
gpio_set_pull(EXYNOS4_GPIO_X27, S5P_GPIO_PULL_NONE);
}
static void board_clock_init(void)
{
struct exynos4_clock *clk =
(struct exynos4_clock *)samsung_get_base_clock();
writel(CLK_SRC_CPU_VAL, (unsigned int)&clk->src_cpu);
writel(CLK_SRC_TOP0_VAL, (unsigned int)&clk->src_top0);
writel(CLK_SRC_FSYS_VAL, (unsigned int)&clk->src_fsys);
writel(CLK_SRC_PERIL0_VAL, (unsigned int)&clk->src_peril0);
writel(CLK_DIV_CPU0_VAL, (unsigned int)&clk->div_cpu0);
writel(CLK_DIV_CPU1_VAL, (unsigned int)&clk->div_cpu1);
writel(CLK_DIV_DMC0_VAL, (unsigned int)&clk->div_dmc0);
writel(CLK_DIV_DMC1_VAL, (unsigned int)&clk->div_dmc1);
writel(CLK_DIV_LEFTBUS_VAL, (unsigned int)&clk->div_leftbus);
writel(CLK_DIV_RIGHTBUS_VAL, (unsigned int)&clk->div_rightbus);
writel(CLK_DIV_TOP_VAL, (unsigned int)&clk->div_top);
writel(CLK_DIV_FSYS1_VAL, (unsigned int)&clk->div_fsys1);
writel(CLK_DIV_FSYS2_VAL, (unsigned int)&clk->div_fsys2);
writel(CLK_DIV_FSYS3_VAL, (unsigned int)&clk->div_fsys3);
writel(CLK_DIV_PERIL0_VAL, (unsigned int)&clk->div_peril0);
writel(CLK_DIV_PERIL3_VAL, (unsigned int)&clk->div_peril3);
writel(PLL_LOCKTIME, (unsigned int)&clk->apll_lock);
writel(PLL_LOCKTIME, (unsigned int)&clk->mpll_lock);
writel(PLL_LOCKTIME, (unsigned int)&clk->epll_lock);
writel(PLL_LOCKTIME, (unsigned int)&clk->vpll_lock);
writel(APLL_CON1_VAL, (unsigned int)&clk->apll_con1);
writel(APLL_CON0_VAL, (unsigned int)&clk->apll_con0);
writel(MPLL_CON1_VAL, (unsigned int)&clk->mpll_con1);
writel(MPLL_CON0_VAL, (unsigned int)&clk->mpll_con0);
writel(EPLL_CON1_VAL, (unsigned int)&clk->epll_con1);
writel(EPLL_CON0_VAL, (unsigned int)&clk->epll_con0);
writel(VPLL_CON1_VAL, (unsigned int)&clk->vpll_con1);
writel(VPLL_CON0_VAL, (unsigned int)&clk->vpll_con0);
writel(CLK_GATE_IP_CAM_VAL, (unsigned int)&clk->gate_ip_cam);
writel(CLK_GATE_IP_VP_VAL, (unsigned int)&clk->gate_ip_tv);
writel(CLK_GATE_IP_MFC_VAL, (unsigned int)&clk->gate_ip_mfc);
writel(CLK_GATE_IP_G3D_VAL, (unsigned int)&clk->gate_ip_g3d);
writel(CLK_GATE_IP_IMAGE_VAL, (unsigned int)&clk->gate_ip_image);
writel(CLK_GATE_IP_LCD0_VAL, (unsigned int)&clk->gate_ip_lcd0);
writel(CLK_GATE_IP_LCD1_VAL, (unsigned int)&clk->gate_ip_lcd1);
writel(CLK_GATE_IP_FSYS_VAL, (unsigned int)&clk->gate_ip_fsys);
writel(CLK_GATE_IP_GPS_VAL, (unsigned int)&clk->gate_ip_gps);
writel(CLK_GATE_IP_PERIL_VAL, (unsigned int)&clk->gate_ip_peril);
writel(CLK_GATE_IP_PERIR_VAL, (unsigned int)&clk->gate_ip_perir);
writel(CLK_GATE_BLOCK_VAL, (unsigned int)&clk->gate_block);
}
static void board_power_init(void)
{
struct exynos4_power *pwr =
(struct exynos4_power *)samsung_get_base_power();
/* PS HOLD */
writel(EXYNOS4_PS_HOLD_CON_VAL, (unsigned int)&pwr->ps_hold_control);
/* Set power down */
writel(0, (unsigned int)&pwr->cam_configuration);
writel(0, (unsigned int)&pwr->tv_configuration);
writel(0, (unsigned int)&pwr->mfc_configuration);
writel(0, (unsigned int)&pwr->g3d_configuration);
writel(0, (unsigned int)&pwr->lcd1_configuration);
writel(0, (unsigned int)&pwr->gps_configuration);
writel(0, (unsigned int)&pwr->gps_alive_configuration);
/* It is necessary to power down core 1 */
/* to successfully boot CPU1 in kernel */
writel(0, (unsigned int)&pwr->arm_core1_configuration);
}
static void exynos_uart_init(void)
{
/* UART_SEL GPY4[7] (part2) at EXYNOS4 */
gpio_request(EXYNOS4_GPIO_Y47, "uart_sel");
gpio_set_pull(EXYNOS4_GPIO_Y47, S5P_GPIO_PULL_UP);
gpio_direction_output(EXYNOS4_GPIO_Y47, 1);
}
int exynos_early_init_f(void)
{
wdt_stop();
pmic_reset();
board_clock_init();
exynos_uart_init();
board_power_init();
return 0;
}
void exynos_reset_lcd(void)
{
gpio_request(EXYNOS4_GPIO_Y45, "lcd_reset");
gpio_direction_output(EXYNOS4_GPIO_Y45, 1);
udelay(10000);
gpio_direction_output(EXYNOS4_GPIO_Y45, 0);
udelay(10000);
gpio_direction_output(EXYNOS4_GPIO_Y45, 1);
}
int lcd_power(void)
{
#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
int ret = 0;
struct pmic *p = pmic_get("MAX8997_PMIC");
if (!p)
return -ENODEV;
if (pmic_probe(p))
return 0;
/* LDO15 voltage: 2.2v */
ret |= pmic_reg_write(p, MAX8997_REG_LDO15CTRL, 0x1c | EN_LDO);
/* LDO13 voltage: 3.0v */
ret |= pmic_reg_write(p, MAX8997_REG_LDO13CTRL, 0x2c | EN_LDO);
if (ret) {
puts("MAX8997 LDO setting error!\n");
return -1;
}
#endif
return 0;
}
int mipi_power(void)
{
#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
int ret = 0;
struct pmic *p = pmic_get("MAX8997_PMIC");
if (!p)
return -ENODEV;
if (pmic_probe(p))
return 0;
/* LDO3 voltage: 1.1v */
ret |= pmic_reg_write(p, MAX8997_REG_LDO3CTRL, 0x6 | EN_LDO);
/* LDO4 voltage: 1.8v */
ret |= pmic_reg_write(p, MAX8997_REG_LDO4CTRL, 0x14 | EN_LDO);
if (ret) {
puts("MAX8997 LDO setting error!\n");
return -1;
}
#endif
return 0;
}
#ifdef CONFIG_LCD
void exynos_lcd_misc_init(vidinfo_t *vid)
{
#ifdef CONFIG_TIZEN
get_tizen_logo_info(vid);
#endif
#ifdef CONFIG_S6E8AX0
s6e8ax0_init();
env_set("lcdinfo", "lcd=s6e8ax0");
#endif
}
#endif
@@ -0,0 +1,12 @@
if TARGET_TRATS2
config SYS_BOARD
default "trats2"
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "trats2"
endif
@@ -0,0 +1,6 @@
TRATS2 BOARD
M: Jaehoon Chung <jh80.chung@samsung.com>
S: Maintained
F: board/samsung/trats2/
F: include/configs/trats2.h
F: configs/trats2_defconfig
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
# Sanghee Kim <sh0130.kim@samsung.com>
obj-y := trats2.o
@@ -0,0 +1,336 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
* Sanghee Kim <sh0130.kim@samsung.com>
* Piotr Wilczek <p.wilczek@samsung.com>
*/
#include <common.h>
#include <lcd.h>
#include <asm/gpio.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/power.h>
#include <asm/arch/mipi_dsim.h>
#include <power/pmic.h>
#include <power/max77686_pmic.h>
#include <power/battery.h>
#include <power/max77693_pmic.h>
#include <power/max77693_muic.h>
#include <power/max77693_fg.h>
#include <libtizen.h>
#include <errno.h>
#include <usb.h>
#include <usb/dwc2_udc.h>
#include <usb_mass_storage.h>
static unsigned int board_rev = -1;
static inline u32 get_model_rev(void);
static void check_hw_revision(void)
{
int modelrev = 0;
char str[12];
int i;
/*
* GPM1[1:0]: MODEL_REV[1:0]
* Don't set as pull-none for these N/C pin.
* TRM say that it may cause unexcepted state and leakage current.
* and pull-none is only for output function.
*/
for (i = 0; i < 2; i++) {
int pin = i + EXYNOS4X12_GPIO_M10;
sprintf(str, "model_rev%d", i);
gpio_request(pin, str);
gpio_cfg_pin(pin, S5P_GPIO_INPUT);
}
/* GPM1[5:2]: HW_REV[3:0] */
for (i = 0; i < 4; i++) {
int pin = i + EXYNOS4X12_GPIO_M12;
sprintf(str, "hw_rev%d", i);
gpio_request(pin, str);
gpio_cfg_pin(pin, S5P_GPIO_INPUT);
gpio_set_pull(pin, S5P_GPIO_PULL_NONE);
}
/* GPM1[1:0]: MODEL_REV[1:0] */
for (i = 0; i < 2; i++)
modelrev |= (gpio_get_value(EXYNOS4X12_GPIO_M10 + i) << i);
/* board_rev[15:8] = model */
board_rev = modelrev << 8;
}
u32 get_board_rev(void)
{
return board_rev;
}
static inline u32 get_model_rev(void)
{
return (board_rev >> 8) & 0xff;
}
static void board_external_gpio_init(void)
{
/*
* some pins which in alive block are connected with external pull-up
* but it's default setting is pull-down.
* if that pin set as input then that floated
*/
gpio_set_pull(EXYNOS4X12_GPIO_X02, S5P_GPIO_PULL_NONE); /* PS_ALS_INT */
gpio_set_pull(EXYNOS4X12_GPIO_X04, S5P_GPIO_PULL_NONE); /* TSP_nINT */
gpio_set_pull(EXYNOS4X12_GPIO_X07, S5P_GPIO_PULL_NONE); /* AP_PMIC_IRQ*/
gpio_set_pull(EXYNOS4X12_GPIO_X15, S5P_GPIO_PULL_NONE); /* IF_PMIC_IRQ*/
gpio_set_pull(EXYNOS4X12_GPIO_X20, S5P_GPIO_PULL_NONE); /* VOL_UP */
gpio_set_pull(EXYNOS4X12_GPIO_X21, S5P_GPIO_PULL_NONE); /* VOL_DOWN */
gpio_set_pull(EXYNOS4X12_GPIO_X23, S5P_GPIO_PULL_NONE); /* FUEL_ALERT */
gpio_set_pull(EXYNOS4X12_GPIO_X24, S5P_GPIO_PULL_NONE); /* ADC_INT */
gpio_set_pull(EXYNOS4X12_GPIO_X27, S5P_GPIO_PULL_NONE); /* nPOWER */
gpio_set_pull(EXYNOS4X12_GPIO_X30, S5P_GPIO_PULL_NONE); /* WPC_INT */
gpio_set_pull(EXYNOS4X12_GPIO_X35, S5P_GPIO_PULL_NONE); /* OK_KEY */
gpio_set_pull(EXYNOS4X12_GPIO_X37, S5P_GPIO_PULL_NONE); /* HDMI_HPD */
}
int exynos_early_init_f(void)
{
board_external_gpio_init();
return 0;
}
int exynos_init(void)
{
struct exynos4_power *pwr =
(struct exynos4_power *)samsung_get_base_power();
check_hw_revision();
printf("HW Revision:\t0x%04x\n", board_rev);
/*
* First bootloader on the TRATS2 platform uses
* INFORM4 and INFORM5 registers for recovery
*
* To indicate correct boot chain - those two
* registers must be cleared out
*/
writel(0, &pwr->inform4);
writel(0, &pwr->inform5);
return 0;
}
int exynos_power_init(void)
{
#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
int chrg;
struct power_battery *pb;
struct pmic *p_chrg, *p_muic, *p_fg, *p_bat;
pmic_init_max77693(I2C_10); /* I2C adapter 10 - bus name soft1 */
power_muic_init(I2C_10); /* I2C adapter 10 - bus name soft1 */
power_fg_init(I2C_9); /* I2C adapter 9 - bus name soft0 */
power_bat_init(0);
p_chrg = pmic_get("MAX77693_PMIC");
if (!p_chrg) {
puts("MAX77693_PMIC: Not found\n");
return -ENODEV;
}
p_muic = pmic_get("MAX77693_MUIC");
if (!p_muic) {
puts("MAX77693_MUIC: Not found\n");
return -ENODEV;
}
p_fg = pmic_get("MAX77693_FG");
if (!p_fg) {
puts("MAX17042_FG: Not found\n");
return -ENODEV;
}
if (p_chrg->chrg->chrg_bat_present(p_chrg) == 0)
puts("No battery detected\n");
p_bat = pmic_get("BAT_TRATS2");
if (!p_bat) {
puts("BAT_TRATS2: Not found\n");
return -ENODEV;
}
p_fg->parent = p_bat;
p_chrg->parent = p_bat;
p_muic->parent = p_bat;
p_bat->pbat->battery_init(p_bat, p_fg, p_chrg, p_muic);
pb = p_bat->pbat;
chrg = p_muic->chrg->chrg_type(p_muic);
debug("CHARGER TYPE: %d\n", chrg);
if (!p_chrg->chrg->chrg_bat_present(p_chrg)) {
puts("No battery detected\n");
return 0;
}
p_fg->fg->fg_battery_check(p_fg, p_bat);
if (pb->bat->state == CHARGE && chrg == CHARGER_USB)
puts("CHARGE Battery !\n");
#endif
return 0;
}
#ifdef CONFIG_USB_GADGET
static int s5pc210_phy_control(int on)
{
#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
int ret = 0;
unsigned int val;
struct pmic *p, *p_pmic, *p_muic;
p_pmic = pmic_get("MAX77686_PMIC");
if (!p_pmic)
return -ENODEV;
if (pmic_probe(p_pmic))
return -1;
p_muic = pmic_get("MAX77693_MUIC");
if (!p_muic)
return -ENODEV;
if (pmic_probe(p_muic))
return -1;
if (on) {
ret = max77686_set_ldo_mode(p_pmic, 12, OPMODE_ON);
if (ret)
return -1;
p = pmic_get("MAX77693_PMIC");
if (!p)
return -ENODEV;
if (pmic_probe(p))
return -1;
/* SAFEOUT */
ret = pmic_reg_read(p, MAX77693_SAFEOUT, &val);
if (ret)
return -1;
val |= MAX77693_ENSAFEOUT1;
ret = pmic_reg_write(p, MAX77693_SAFEOUT, val);
if (ret)
return -1;
/* PATH: USB */
ret = pmic_reg_write(p_muic, MAX77693_MUIC_CONTROL1,
MAX77693_MUIC_CTRL1_DN1DP2);
} else {
ret = max77686_set_ldo_mode(p_pmic, 12, OPMODE_LPM);
if (ret)
return -1;
/* PATH: UART */
ret = pmic_reg_write(p_muic, MAX77693_MUIC_CONTROL1,
MAX77693_MUIC_CTRL1_UT1UR2);
}
if (ret)
return -1;
#endif
return 0;
}
struct dwc2_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 dwc2_udc_probe(&s5pc210_otg_data);
}
int g_dnl_board_usb_cable_connected(void)
{
#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
struct pmic *muic = pmic_get("MAX77693_MUIC");
if (!muic)
return 0;
return !!muic->chrg->chrg_type(muic);
#else
return false;
#endif
}
#endif
/*
* LCD
*/
#ifdef CONFIG_LCD
int mipi_power(void)
{
#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
struct pmic *p = pmic_get("MAX77686_PMIC");
/* LDO8 VMIPI_1.0V_AP */
max77686_set_ldo_mode(p, 8, OPMODE_ON);
/* LDO10 VMIPI_1.8V_AP */
max77686_set_ldo_mode(p, 10, OPMODE_ON);
#endif
return 0;
}
void exynos_lcd_power_on(void)
{
#ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
struct pmic *p = pmic_get("MAX77686_PMIC");
/* LCD_2.2V_EN: GPC0[1] */
gpio_request(EXYNOS4X12_GPIO_C01, "lcd_2v2_en");
gpio_set_pull(EXYNOS4X12_GPIO_C01, S5P_GPIO_PULL_UP);
gpio_direction_output(EXYNOS4X12_GPIO_C01, 1);
/* LDO25 VCC_3.1V_LCD */
pmic_probe(p);
max77686_set_ldo_voltage(p, 25, 3100000);
max77686_set_ldo_mode(p, 25, OPMODE_LPM);
#endif
}
void exynos_reset_lcd(void)
{
/* reset lcd */
gpio_request(EXYNOS4X12_GPIO_F21, "lcd_reset");
gpio_direction_output(EXYNOS4X12_GPIO_F21, 0);
udelay(10);
gpio_set_value(EXYNOS4X12_GPIO_F21, 1);
}
void exynos_lcd_misc_init(vidinfo_t *vid)
{
#ifdef CONFIG_TIZEN
get_tizen_logo_info(vid);
#endif
#ifdef CONFIG_S6E8AX0
s6e8ax0_init();
#endif
}
#endif /* LCD */
@@ -0,0 +1,12 @@
if TARGET_S5PC210_UNIVERSAL
config SYS_BOARD
default "universal_c210"
config SYS_VENDOR
default "samsung"
config SYS_CONFIG_NAME
default "s5pc210_universal"
endif
@@ -0,0 +1,6 @@
UNIVERSAL_C210 BOARD
M: Jaehoon Chung <jh80.chung@samsung.com>
S: Maintained
F: board/samsung/universal_c210/
F: include/configs/s5pc210_universal.h
F: configs/s5pc210_universal_defconfig
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2010 Samsung Electronics
# Minkyu Kang <mk7.kang@samsung.com>
obj-y := universal.o onenand.o
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2010 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
*/
#include <common.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>
#include <linux/mtd/samsung_onenand.h>
int onenand_board_init(struct mtd_info *mtd)
{
struct onenand_chip *this = mtd->priv;
this->base = (void *)CONFIG_SYS_ONENAND_BASE;
this->options |= ONENAND_RUNTIME_BADBLOCK_CHECK;
this->chip_probe = s5pc210_chip_probe;
return 0;
}
@@ -0,0 +1,402 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2010 Samsung Electronics
* Minkyu Kang <mk7.kang@samsung.com>
* Kyungmin Park <kyungmin.park@samsung.com>
*/
#include <common.h>
#include <env.h>
#include <spi.h>
#include <lcd.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/arch/adc.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/watchdog.h>
#include <ld9040.h>
#include <power/pmic.h>
#include <usb.h>
#include <usb/dwc2_udc.h>
#include <asm/arch/cpu.h>
#include <power/max8998_pmic.h>
#include <libtizen.h>
#include <samsung/misc.h>
#include <usb_mass_storage.h>
#include <asm/mach-types.h>
DECLARE_GLOBAL_DATA_PTR;
unsigned int board_rev;
static int init_pmic_lcd(void);
u32 get_board_rev(void)
{
return board_rev;
}
int exynos_power_init(void)
{
return init_pmic_lcd();
}
static int get_hwrev(void)
{
return board_rev & 0xFF;
}
static unsigned short get_adc_value(int channel)
{
struct s5p_adc *adc = (struct s5p_adc *)samsung_get_base_adc();
unsigned short ret = 0;
unsigned int reg;
unsigned int loop = 0;
writel(channel & 0xF, &adc->adcmux);
writel((1 << 14) | (49 << 6), &adc->adccon);
writel(1000 & 0xffff, &adc->adcdly);
writel(readl(&adc->adccon) | (1 << 16), &adc->adccon); /* 12 bit */
udelay(10);
writel(readl(&adc->adccon) | (1 << 0), &adc->adccon); /* Enable */
udelay(10);
do {
udelay(1);
reg = readl(&adc->adccon);
} while (!(reg & (1 << 15)) && (loop++ < 1000));
ret = readl(&adc->adcdat0) & 0xFFF;
return ret;
}
static int adc_power_control(int on)
{
struct udevice *dev;
int ret;
u8 reg;
ret = pmic_get("max8998-pmic", &dev);
if (ret) {
puts("Failed to get MAX8998!\n");
return ret;
}
reg = pmic_reg_read(dev, MAX8998_REG_ONOFF1);
if (on)
reg |= MAX8998_LDO4;
else
reg &= ~MAX8998_LDO4;
ret = pmic_reg_write(dev, MAX8998_REG_ONOFF1, reg);
if (ret) {
puts("MAX8998 LDO setting error\n");
return -EINVAL;
}
return 0;
}
static unsigned int get_hw_revision(void)
{
int hwrev, mode0, mode1;
adc_power_control(1);
mode0 = get_adc_value(1); /* HWREV_MODE0 */
mode1 = get_adc_value(2); /* HWREV_MODE1 */
/*
* XXX Always set the default hwrev as the latest board
* ADC = (voltage) / 3.3 * 4096
*/
hwrev = 3;
#define IS_RANGE(x, min, max) ((x) > (min) && (x) < (max))
if (IS_RANGE(mode0, 80, 200) && IS_RANGE(mode1, 80, 200))
hwrev = 0x0; /* 0.01V 0.01V */
if (IS_RANGE(mode0, 750, 1000) && IS_RANGE(mode1, 80, 200))
hwrev = 0x1; /* 610mV 0.01V */
if (IS_RANGE(mode0, 1300, 1700) && IS_RANGE(mode1, 80, 200))
hwrev = 0x2; /* 1.16V 0.01V */
if (IS_RANGE(mode0, 2000, 2400) && IS_RANGE(mode1, 80, 200))
hwrev = 0x3; /* 1.79V 0.01V */
#undef IS_RANGE
debug("mode0: %d, mode1: %d, hwrev 0x%x\n", mode0, mode1, hwrev);
adc_power_control(0);
return hwrev;
}
static void check_hw_revision(void)
{
int hwrev;
hwrev = get_hw_revision();
board_rev |= hwrev;
}
#ifdef CONFIG_USB_GADGET
static int s5pc210_phy_control(int on)
{
struct udevice *dev;
int ret;
u8 reg;
ret = pmic_get("max8998-pmic", &dev);
if (ret) {
puts("Failed to get MAX8998!\n");
return ret;
}
if (on) {
reg = pmic_reg_read(dev, MAX8998_REG_BUCK_ACTIVE_DISCHARGE3);
reg |= MAX8998_SAFEOUT1;
ret |= pmic_reg_write(dev,
MAX8998_REG_BUCK_ACTIVE_DISCHARGE3, reg);
reg = pmic_reg_read(dev, MAX8998_REG_ONOFF1);
reg |= MAX8998_LDO3;
ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF1, reg);
reg = pmic_reg_read(dev, MAX8998_REG_ONOFF2);
reg |= MAX8998_LDO8;
ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF2, reg);
} else {
reg = pmic_reg_read(dev, MAX8998_REG_ONOFF2);
reg &= ~MAX8998_LDO8;
ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF2, reg);
reg = pmic_reg_read(dev, MAX8998_REG_ONOFF1);
reg &= ~MAX8998_LDO3;
ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF1, reg);
reg = pmic_reg_read(dev, MAX8998_REG_BUCK_ACTIVE_DISCHARGE3);
reg &= ~MAX8998_SAFEOUT1;
ret |= pmic_reg_write(dev,
MAX8998_REG_BUCK_ACTIVE_DISCHARGE3, reg);
}
if (ret) {
puts("MAX8998 LDO setting error!\n");
return -EINVAL;
}
return 0;
}
struct dwc2_plat_otg_data s5pc210_otg_data = {
.phy_control = s5pc210_phy_control,
.regs_phy = EXYNOS4_USBPHY_BASE,
.regs_otg = EXYNOS4_USBOTG_BASE,
.usb_phy_ctrl = EXYNOS4_USBPHY_CONTROL,
.usb_flags = PHY0_SLEEP,
};
#endif
int board_usb_init(int index, enum usb_init_type init)
{
debug("USB_udc_probe\n");
return dwc2_udc_probe(&s5pc210_otg_data);
}
int exynos_early_init_f(void)
{
wdt_stop();
return 0;
}
static int init_pmic_lcd(void)
{
struct udevice *dev;
unsigned char val;
int ret = 0;
ret = pmic_get("max8998-pmic", &dev);
if (ret) {
puts("Failed to get MAX8998 for init_pmic_lcd()!\n");
return ret;
}
/* LDO7 1.8V */
val = 0x02; /* (1800 - 1600) / 100; */
ret |= pmic_reg_write(dev, MAX8998_REG_LDO7, val);
/* LDO17 3.0V */
val = 0xe; /* (3000 - 1600) / 100; */
ret |= pmic_reg_write(dev, MAX8998_REG_LDO17, val);
/* Disable unneeded regulators */
/*
* ONOFF1
* Buck1 ON, Buck2 OFF, Buck3 ON, Buck4 ON
* LDO2 ON, LDO3 OFF, LDO4 OFF, LDO5 ON
*/
val = 0xB9;
ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF1, val);
/* ONOFF2
* LDO6 OFF, LDO7 ON, LDO8 OFF, LDO9 ON,
* LDO10 OFF, LDO11 OFF, LDO12 OFF, LDO13 OFF
*/
val = 0x50;
ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF2, val);
/* ONOFF3
* LDO14 OFF, LDO15 OFF, LGO16 OFF, LDO17 OFF
* EPWRHOLD OFF, EBATTMON OFF, ELBCNFG2 OFF, ELBCNFG1 OFF
*/
val = 0x00;
ret |= pmic_reg_write(dev, MAX8998_REG_ONOFF3, val);
if (ret) {
puts("LCD pmic initialisation error!\n");
return -EINVAL;
}
return 0;
}
void exynos_cfg_lcd_gpio(void)
{
unsigned int i, f3_end = 4;
for (i = 0; i < 8; i++) {
/* set GPF0,1,2[0:7] for RGB Interface and Data lines (32bit) */
gpio_cfg_pin(EXYNOS4_GPIO_F00 + i, S5P_GPIO_FUNC(2));
gpio_cfg_pin(EXYNOS4_GPIO_F10 + i, S5P_GPIO_FUNC(2));
gpio_cfg_pin(EXYNOS4_GPIO_F20 + i, S5P_GPIO_FUNC(2));
/* pull-up/down disable */
gpio_set_pull(EXYNOS4_GPIO_F00 + i, S5P_GPIO_PULL_NONE);
gpio_set_pull(EXYNOS4_GPIO_F10 + i, S5P_GPIO_PULL_NONE);
gpio_set_pull(EXYNOS4_GPIO_F20 + i, S5P_GPIO_PULL_NONE);
/* drive strength to max (24bit) */
gpio_set_drv(EXYNOS4_GPIO_F00 + i, S5P_GPIO_DRV_4X);
gpio_set_rate(EXYNOS4_GPIO_F00 + i, S5P_GPIO_DRV_SLOW);
gpio_set_drv(EXYNOS4_GPIO_F10 + i, S5P_GPIO_DRV_4X);
gpio_set_rate(EXYNOS4_GPIO_F10 + i, S5P_GPIO_DRV_SLOW);
gpio_set_drv(EXYNOS4_GPIO_F20 + i, S5P_GPIO_DRV_4X);
gpio_set_rate(EXYNOS4_GPIO_F00 + i, S5P_GPIO_DRV_SLOW);
}
for (i = EXYNOS4_GPIO_F30; i < (EXYNOS4_GPIO_F30 + f3_end); i++) {
/* set GPF3[0:3] for RGB Interface and Data lines (32bit) */
gpio_cfg_pin(i, S5P_GPIO_FUNC(2));
/* pull-up/down disable */
gpio_set_pull(i, S5P_GPIO_PULL_NONE);
/* drive strength to max (24bit) */
gpio_set_drv(i, S5P_GPIO_DRV_4X);
gpio_set_rate(i, S5P_GPIO_DRV_SLOW);
}
/* gpio pad configuration for LCD reset. */
gpio_request(EXYNOS4_GPIO_Y45, "lcd_reset");
gpio_cfg_pin(EXYNOS4_GPIO_Y45, S5P_GPIO_OUTPUT);
}
int mipi_power(void)
{
return 0;
}
void exynos_reset_lcd(void)
{
gpio_set_value(EXYNOS4_GPIO_Y45, 1);
udelay(10000);
gpio_set_value(EXYNOS4_GPIO_Y45, 0);
udelay(10000);
gpio_set_value(EXYNOS4_GPIO_Y45, 1);
udelay(100);
}
void exynos_lcd_power_on(void)
{
struct udevice *dev;
int ret;
u8 reg;
ret = pmic_get("max8998-pmic", &dev);
if (ret) {
puts("Failed to get MAX8998!\n");
return;
}
reg = pmic_reg_read(dev, MAX8998_REG_ONOFF3);
reg |= MAX8998_LDO17;
ret = pmic_reg_write(dev, MAX8998_REG_ONOFF3, reg);
if (ret) {
puts("MAX8998 LDO setting error\n");
return;
}
reg = pmic_reg_read(dev, MAX8998_REG_ONOFF2);
reg |= MAX8998_LDO7;
ret = pmic_reg_write(dev, MAX8998_REG_ONOFF2, reg);
if (ret) {
puts("MAX8998 LDO setting error\n");
return;
}
}
void exynos_cfg_ldo(void)
{
ld9040_cfg_ldo();
}
void exynos_enable_ldo(unsigned int onoff)
{
ld9040_enable_ldo(onoff);
}
int exynos_init(void)
{
gd->bd->bi_arch_number = MACH_TYPE_UNIVERSAL_C210;
switch (get_hwrev()) {
case 0:
/*
* Set the low to enable LDO_EN
* But when you use the test board for eMMC booting
* you should set it HIGH since it removes the inverter
*/
/* MASSMEMORY_EN: XMDMDATA_6: GPE3[6] */
gpio_request(EXYNOS4_GPIO_E36, "ldo_en");
gpio_direction_output(EXYNOS4_GPIO_E36, 0);
break;
default:
/*
* Default reset state is High and there's no inverter
* But set it as HIGH to ensure
*/
/* MASSMEMORY_EN: XMDMADDR_3: GPE1[3] */
gpio_request(EXYNOS4_GPIO_E13, "massmemory_en");
gpio_direction_output(EXYNOS4_GPIO_E13, 1);
break;
}
check_hw_revision();
printf("HW Revision:\t0x%x\n", board_rev);
return 0;
}
#ifdef CONFIG_LCD
void exynos_lcd_misc_init(vidinfo_t *vid)
{
#ifdef CONFIG_TIZEN
get_tizen_logo_info(vid);
#endif
/* for LD9040. */
vid->pclk_name = 1; /* MPLL */
vid->sclk_div = 1;
env_set("lcdinfo", "lcd=ld9040");
}
#endif