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