pit: Add a "pit" mainboard which is mostly a copy of "snow".
This change adds a pit mainboard which is mostly a copy of snow, except that mentions of the 5250 were replaced with the 5420, and mentions of snow were replaced with pit. Change-Id: I8eb0ce379eb2fa353bb88d5656a0c5e2290afbf0 Signed-off-by: Gabe Black <gabeblack@chromium.org> Reviewed-on: http://review.coreboot.org/3646 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
b2d811aa9e
commit
d3163abd43
|
@ -32,6 +32,8 @@ config BOARD_GOOGLE_LINK
|
|||
bool "Link"
|
||||
config BOARD_GOOGLE_PARROT
|
||||
bool "Parrot"
|
||||
config BOARD_GOOGLE_PIT
|
||||
bool "Pit"
|
||||
config BOARD_GOOGLE_SNOW
|
||||
bool "Snow"
|
||||
config BOARD_GOOGLE_STOUT
|
||||
|
@ -42,6 +44,7 @@ endchoice
|
|||
source "src/mainboard/google/butterfly/Kconfig"
|
||||
source "src/mainboard/google/link/Kconfig"
|
||||
source "src/mainboard/google/parrot/Kconfig"
|
||||
source "src/mainboard/google/pit/Kconfig"
|
||||
source "src/mainboard/google/snow/Kconfig"
|
||||
source "src/mainboard/google/stout/Kconfig"
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
##
|
||||
## This file is part of the coreboot project.
|
||||
##
|
||||
## Copyright 2013 Google Inc.
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; version 2 of the License.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program; if not, write to the Free Software
|
||||
## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
##
|
||||
|
||||
if BOARD_GOOGLE_PIT
|
||||
|
||||
config BOARD_SPECIFIC_OPTIONS # dummy
|
||||
def_bool y
|
||||
select ARCH_ARMV7
|
||||
select CPU_SAMSUNG_EXYNOS5420
|
||||
select HAVE_UART_MEMORY_MAPPED
|
||||
select EC_GOOGLE_CHROMEEC
|
||||
select EC_GOOGLE_CHROMEEC_I2C
|
||||
select BOARD_ROMSIZE_KB_4096
|
||||
select DRIVER_MAXIM_MAX77686
|
||||
select CHROMEOS
|
||||
select DRIVER_TI_TPS65090
|
||||
select MAINBOARD_HAS_NATIVE_VGA_INIT
|
||||
select MAINBOARD_DO_NATIVE_VGA_INIT
|
||||
|
||||
config MAINBOARD_DIR
|
||||
string
|
||||
default google/pit
|
||||
|
||||
config MAINBOARD_PART_NUMBER
|
||||
string
|
||||
default "Pit"
|
||||
|
||||
config MAX_CPUS
|
||||
int
|
||||
default 2
|
||||
|
||||
config DRAM_SIZE_MB
|
||||
int
|
||||
default 2048
|
||||
|
||||
config EC_GOOGLE_CHROMEEC_I2C_BUS
|
||||
hex
|
||||
default 4
|
||||
|
||||
endif # BOARD_GOOGLE_PIT
|
|
@ -0,0 +1,27 @@
|
|||
##
|
||||
## This file is part of the coreboot project.
|
||||
##
|
||||
## Copyright 2012 Google Inc.
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; version 2 of the License.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program; if not, write to the Free Software
|
||||
## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
##
|
||||
|
||||
bootblock-y += wakeup.c
|
||||
|
||||
romstage-y += memory.c
|
||||
romstage-y += romstage.c
|
||||
romstage-y += wakeup.c
|
||||
|
||||
ramstage-y += mainboard.c
|
||||
ramstage-y += chromeos.c
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <boot/coreboot_tables.h>
|
||||
#include <console/console.h>
|
||||
#include <ec/google/chromeec/ec.h>
|
||||
#include <ec/google/chromeec/ec_commands.h>
|
||||
#include <string.h>
|
||||
#include <vendorcode/google/chromeos/chromeos.h>
|
||||
#include <cpu/samsung/exynos5420/cpu.h>
|
||||
#include <cpu/samsung/exynos5420/gpio.h>
|
||||
|
||||
enum {
|
||||
ACTIVE_LOW = 0,
|
||||
ACTIVE_HIGH = 1
|
||||
};
|
||||
|
||||
void fill_lb_gpios(struct lb_gpios *gpios)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
/* Write Protect: active low */
|
||||
gpios->gpios[count].port = EXYNOS5_GPD1;
|
||||
gpios->gpios[count].polarity = ACTIVE_LOW;
|
||||
gpios->gpios[count].value = gpio_get_value(GPIO_D16); // WP_GPIO
|
||||
strncpy((char *)gpios->gpios[count].name, "write protect",
|
||||
GPIO_MAX_NAME_LENGTH);
|
||||
count++;
|
||||
|
||||
/* Recovery: active low */
|
||||
gpios->gpios[count].port = -1;
|
||||
gpios->gpios[count].polarity = ACTIVE_HIGH;
|
||||
gpios->gpios[count].value = get_recovery_mode_switch();
|
||||
strncpy((char *)gpios->gpios[count].name, "recovery",
|
||||
GPIO_MAX_NAME_LENGTH);
|
||||
count++;
|
||||
|
||||
/* Lid: active high */
|
||||
gpios->gpios[count].port = EXYNOS5_GPX3;
|
||||
gpios->gpios[count].polarity = ACTIVE_HIGH;
|
||||
gpios->gpios[count].value = gpio_get_value(GPIO_X35); // LID_GPIO
|
||||
strncpy((char *)gpios->gpios[count].name, "lid", GPIO_MAX_NAME_LENGTH);
|
||||
count++;
|
||||
|
||||
/* Power: virtual GPIO active low */
|
||||
gpios->gpios[count].port = EXYNOS5_GPX1;
|
||||
gpios->gpios[count].polarity = ACTIVE_LOW;
|
||||
gpios->gpios[count].value =
|
||||
gpio_get_value(GPIO_X13); // POWER_GPIO
|
||||
strncpy((char *)gpios->gpios[count].name, "power",
|
||||
GPIO_MAX_NAME_LENGTH);
|
||||
count++;
|
||||
|
||||
/* Developer: virtual GPIO active high */
|
||||
gpios->gpios[count].port = -1;
|
||||
gpios->gpios[count].polarity = ACTIVE_HIGH;
|
||||
gpios->gpios[count].value = get_developer_mode_switch();
|
||||
strncpy((char *)gpios->gpios[count].name, "developer",
|
||||
GPIO_MAX_NAME_LENGTH);
|
||||
count++;
|
||||
|
||||
gpios->size = sizeof(*gpios) + (count * sizeof(struct lb_gpio));
|
||||
gpios->count = count;
|
||||
|
||||
printk(BIOS_ERR, "Added %d GPIOS size %d\n", count, gpios->size);
|
||||
}
|
||||
|
||||
int get_developer_mode_switch(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_recovery_mode_switch(void)
|
||||
{
|
||||
uint32_t ec_events;
|
||||
|
||||
/* The GPIO is active low. */
|
||||
if (!gpio_get_value(GPIO_Y10)) // RECMODE_GPIO
|
||||
return 1;
|
||||
|
||||
ec_events = google_chromeec_get_events_b();
|
||||
return !!(ec_events &
|
||||
EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));
|
||||
}
|
||||
|
||||
int get_recovery_mode_from_vbnv(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
##
|
||||
## This file is part of the coreboot project.
|
||||
##
|
||||
## Copyright 2012 Google Inc.
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; version 2 of the License.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program; if not, write to the Free Software
|
||||
## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
##
|
||||
|
||||
chip cpu/samsung/exynos5420
|
||||
device cpu_cluster 0 on end
|
||||
register "xres" = "1366"
|
||||
register "yres" = "768"
|
||||
register "bpp" = "16"
|
||||
# complex magic timing!
|
||||
register "clkval_f" = "2"
|
||||
register "upper_margin" = "14"
|
||||
register "lower_margin" = "3"
|
||||
register "vsync" = "5"
|
||||
register "left_margin" = "80"
|
||||
register "right_margin" = "48"
|
||||
register "hsync" = "32"
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* I2C */
|
||||
#define I2C_0_SPEED 100000
|
||||
#define I2C_SLAVE 0
|
||||
|
||||
/* Voltages */
|
||||
#define VDD_ARM_MV 1300 // 1.3V
|
||||
#define VDD_INT_UV 1012500 // 1.0125V
|
||||
#define VDD_MIF_MV 1000 // 1.0V
|
||||
#define VDD_G3D_MV 1200 // 1.2V
|
||||
#define VDD_LDO2_MV 1500 // 1.5V
|
||||
#define VDD_LDO3_MV 1800 // 1.8V
|
||||
#define VDD_LDO5_MV 1800 // 1.8V
|
||||
#define VDD_LDO10_MV 1800 // 1.8V
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/i2c.h>
|
||||
#include <drivers/ti/tps65090/tps65090.h>
|
||||
#include <cbmem.h>
|
||||
#include <delay.h>
|
||||
#include <edid.h>
|
||||
#include <vbe.h>
|
||||
#include <boot/coreboot_tables.h>
|
||||
#include <arch/cache.h>
|
||||
#include <arch/exception.h>
|
||||
#include <cpu/samsung/exynos5420/tmu.h>
|
||||
#include <cpu/samsung/exynos5420/clk.h>
|
||||
#include <cpu/samsung/exynos5420/cpu.h>
|
||||
#include <cpu/samsung/exynos5420/gpio.h>
|
||||
#include <cpu/samsung/exynos5420/power.h>
|
||||
#include <cpu/samsung/exynos5420/i2c.h>
|
||||
#include <cpu/samsung/exynos5420/dp-core.h>
|
||||
|
||||
#include "exynos5420.h"
|
||||
|
||||
/* convenient shorthand (in MB) */
|
||||
#define DRAM_START (CONFIG_SYS_SDRAM_BASE >> 20)
|
||||
#define DRAM_SIZE CONFIG_DRAM_SIZE_MB
|
||||
#define DRAM_END (DRAM_START + DRAM_SIZE) /* plus one... */
|
||||
|
||||
static struct edid edid = {
|
||||
.ha = 1366,
|
||||
.va = 768,
|
||||
.bpp = 16,
|
||||
};
|
||||
|
||||
/* TODO: transplanted DP stuff, clean up once we have something that works */
|
||||
static enum exynos5_gpio_pin dp_pd_l = GPIO_Y25; /* active low */
|
||||
static enum exynos5_gpio_pin dp_rst_l = GPIO_X15; /* active low */
|
||||
static enum exynos5_gpio_pin dp_hpd = GPIO_X07; /* active high */
|
||||
|
||||
static void exynos_dp_bridge_setup(void)
|
||||
{
|
||||
exynos_pinmux_config(PERIPH_ID_DPHPD, 0);
|
||||
|
||||
gpio_set_value(dp_pd_l, 1);
|
||||
gpio_cfg_pin(dp_pd_l, GPIO_OUTPUT);
|
||||
gpio_set_pull(dp_pd_l, GPIO_PULL_NONE);
|
||||
|
||||
gpio_set_value(dp_rst_l, 0);
|
||||
gpio_cfg_pin(dp_rst_l, GPIO_OUTPUT);
|
||||
gpio_set_pull(dp_rst_l, GPIO_PULL_NONE);
|
||||
udelay(10);
|
||||
gpio_set_value(dp_rst_l, 1);
|
||||
}
|
||||
|
||||
static void exynos_dp_bridge_init(void)
|
||||
{
|
||||
/* De-assert PD (and possibly RST) to power up the bridge */
|
||||
gpio_set_value(dp_pd_l, 1);
|
||||
gpio_set_value(dp_rst_l, 1);
|
||||
|
||||
/*
|
||||
* We need to wait for 90ms after bringing up the bridge since
|
||||
* there is a phantom "high" on the HPD chip during its
|
||||
* bootup. The phantom high comes within 7ms of de-asserting
|
||||
* PD and persists for at least 15ms. The real high comes
|
||||
* roughly 50ms after PD is de-asserted. The phantom high
|
||||
* makes it hard for us to know when the NXP chip is up.
|
||||
*/
|
||||
udelay(90000);
|
||||
}
|
||||
|
||||
static int exynos_dp_hotplug(void)
|
||||
{
|
||||
/* Check HPD. If it's high, we're all good. */
|
||||
return gpio_get_value(dp_hpd) ? 0 : 1;
|
||||
}
|
||||
|
||||
static void exynos_dp_reset(void)
|
||||
{
|
||||
gpio_set_value(dp_pd_l, 0);
|
||||
gpio_set_value(dp_rst_l, 0);
|
||||
/* paranoid delay period (300ms) */
|
||||
udelay(300 * 1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* This delay is T3 in the LCD timing spec (defined as >200ms). We set
|
||||
* this down to 60ms since that's the approximate maximum amount of time
|
||||
* it'll take a bridge to start outputting LVDS data. The delay of
|
||||
* >200ms is just a conservative value to avoid turning on the backlight
|
||||
* when there's random LCD data on the screen. Shaving 140ms off the
|
||||
* boot is an acceptable trade-off.
|
||||
*/
|
||||
#define LCD_T3_DELAY_MS 60
|
||||
|
||||
#define LCD_T5_DELAY_MS 10
|
||||
#define LCD_T6_DELAY_MS 10
|
||||
|
||||
static void backlight_pwm(void)
|
||||
{
|
||||
/*Configure backlight PWM as a simple output high (100% brightness) */
|
||||
gpio_direction_output(GPIO_B20, 1);
|
||||
udelay(LCD_T6_DELAY_MS * 1000);
|
||||
}
|
||||
|
||||
static void backlight_en(void)
|
||||
{
|
||||
/* Configure GPIO for LCD_BL_EN */
|
||||
gpio_direction_output(GPIO_X30, 1);
|
||||
}
|
||||
|
||||
#define TPS69050_BUS 4 /* Pit-specific */
|
||||
|
||||
#define FET1_CTRL 0x0f
|
||||
#define FET6_CTRL 0x14
|
||||
|
||||
static void lcd_vdd(void)
|
||||
{
|
||||
/* Enable FET6, lcd panel */
|
||||
tps65090_fet_enable(TPS69050_BUS, FET6_CTRL);
|
||||
}
|
||||
|
||||
static void backlight_vdd(void)
|
||||
{
|
||||
/* Enable FET1, backlight */
|
||||
tps65090_fet_enable(TPS69050_BUS, FET1_CTRL);
|
||||
udelay(LCD_T5_DELAY_MS * 1000);
|
||||
}
|
||||
|
||||
//static struct video_info smdk5420_dp_config = {
|
||||
static struct video_info dp_video_info = {
|
||||
/* FIXME: fix video_info struct to use const for name */
|
||||
.name = (char *)"eDP-LVDS NXP PTN3460",
|
||||
|
||||
.h_sync_polarity = 0,
|
||||
.v_sync_polarity = 0,
|
||||
.interlaced = 0,
|
||||
|
||||
.color_space = COLOR_RGB,
|
||||
.dynamic_range = VESA,
|
||||
.ycbcr_coeff = COLOR_YCBCR601,
|
||||
.color_depth = COLOR_8,
|
||||
|
||||
.link_rate = LINK_RATE_2_70GBPS,
|
||||
.lane_count = LANE_COUNT2,
|
||||
};
|
||||
|
||||
/* FIXME: move some place more appropriate */
|
||||
#define EXYNOS5420_DP1_BASE 0x145b0000
|
||||
#define MAX_DP_TRIES 5
|
||||
|
||||
/*
|
||||
* This function disables the USB3.0 PLL to save power
|
||||
*/
|
||||
static void disable_usb30_pll(void)
|
||||
{
|
||||
enum exynos5_gpio_pin usb3_pll_l = GPIO_Y11;
|
||||
|
||||
gpio_direction_output(usb3_pll_l, 0);
|
||||
}
|
||||
|
||||
/* this happens after cpu_init where exynos resources are set */
|
||||
static void mainboard_init(device_t dev)
|
||||
{
|
||||
int dp_tries;
|
||||
struct s5p_dp_device dp_device = {
|
||||
.base = (struct exynos5_dp *)EXYNOS5420_DP1_BASE,
|
||||
.video_info = &dp_video_info,
|
||||
};
|
||||
void *fb_addr;
|
||||
|
||||
i2c_init(TPS69050_BUS, I2C_0_SPEED, I2C_SLAVE);
|
||||
i2c_init(7, I2C_0_SPEED, I2C_SLAVE);
|
||||
|
||||
tmu_init(&exynos5420_tmu_info);
|
||||
|
||||
/* Clock Gating all the unused IP's to save power */
|
||||
clock_gate();
|
||||
|
||||
/* Disable USB3.0 PLL to save 250mW of power */
|
||||
disable_usb30_pll();
|
||||
|
||||
fb_addr = cbmem_find(CBMEM_ID_CONSOLE);
|
||||
set_vbe_mode_info_valid(&edid, (uintptr_t)(fb_addr) + 64*KiB);
|
||||
|
||||
lcd_vdd();
|
||||
do {
|
||||
udelay(50);
|
||||
} while (!exynos_dp_hotplug());
|
||||
|
||||
exynos_dp_bridge_setup();
|
||||
for (dp_tries = 1; dp_tries <= MAX_DP_TRIES; dp_tries++) {
|
||||
exynos_dp_bridge_init();
|
||||
if (exynos_dp_hotplug()) {
|
||||
exynos_dp_reset();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dp_controller_init(&dp_device))
|
||||
continue;
|
||||
|
||||
udelay(LCD_T3_DELAY_MS * 1000);
|
||||
|
||||
backlight_vdd();
|
||||
backlight_pwm();
|
||||
backlight_en();
|
||||
/* if we're here, we're successful */
|
||||
break;
|
||||
}
|
||||
|
||||
if (dp_tries > MAX_DP_TRIES)
|
||||
printk(BIOS_ERR, "%s: Failed to set up displayport\n", __func__);
|
||||
|
||||
gpio_info();
|
||||
}
|
||||
|
||||
static void mainboard_enable(device_t dev)
|
||||
{
|
||||
dev->ops->init = &mainboard_init;
|
||||
|
||||
/* set up coreboot tables */
|
||||
/* FIXME: this should happen somewhere else */
|
||||
high_tables_size = CONFIG_COREBOOT_TABLES_SIZE;
|
||||
high_tables_base = CONFIG_SYS_SDRAM_BASE +
|
||||
((unsigned)CONFIG_DRAM_SIZE_MB << 20ULL) -
|
||||
CONFIG_COREBOOT_TABLES_SIZE;
|
||||
cbmem_init(high_tables_base, high_tables_size);
|
||||
|
||||
/* set up dcache and MMU */
|
||||
/* FIXME: this should happen via resource allocator */
|
||||
exynos5420_config_l2_cache();
|
||||
mmu_init();
|
||||
mmu_config_range(0, DRAM_START, DCACHE_OFF);
|
||||
mmu_config_range(DRAM_START, DRAM_SIZE, DCACHE_WRITEBACK);
|
||||
mmu_config_range(DRAM_END, 4096 - DRAM_END, DCACHE_OFF);
|
||||
dcache_invalidate_all();
|
||||
dcache_mmu_enable();
|
||||
|
||||
/* this is going to move, but we must have it now and we're
|
||||
* not sure where */
|
||||
exception_init();
|
||||
|
||||
const unsigned epll_hz = 192000000;
|
||||
const unsigned sample_rate = 48000;
|
||||
const unsigned lr_frame_size = 256;
|
||||
clock_epll_set_rate(epll_hz);
|
||||
clock_select_i2s_clk_source();
|
||||
clock_set_i2s_clk_prescaler(epll_hz, sample_rate * lr_frame_size);
|
||||
|
||||
power_enable_xclkout();
|
||||
}
|
||||
|
||||
struct chip_operations mainboard_ops = {
|
||||
.name = "Samsung/Google ARM Chromebook",
|
||||
.enable_dev = mainboard_enable,
|
||||
};
|
|
@ -0,0 +1,546 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2012 Samsung Electronics
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <console/console.h>
|
||||
|
||||
#include <cpu/samsung/exynos5420/gpio.h>
|
||||
#include <cpu/samsung/exynos5420/setup.h>
|
||||
#include <cpu/samsung/exynos5420/dmc.h>
|
||||
#include <cpu/samsung/exynos5420/clk.h>
|
||||
|
||||
const struct mem_timings mem_timings[] = {
|
||||
{
|
||||
.mem_manuf = MEM_MANUF_ELPIDA,
|
||||
.mem_type = DDR_MODE_DDR3,
|
||||
.frequency_mhz = 800,
|
||||
.mpll_mdiv = 0x64,
|
||||
.mpll_pdiv = 0x3,
|
||||
.mpll_sdiv = 0x0,
|
||||
.cpll_mdiv = 0xde,
|
||||
.cpll_pdiv = 0x4,
|
||||
.cpll_sdiv = 0x2,
|
||||
.gpll_mdiv = 0x215,
|
||||
.gpll_pdiv = 0xc,
|
||||
.gpll_sdiv = 0x1,
|
||||
.epll_mdiv = 0x60,
|
||||
.epll_pdiv = 0x3,
|
||||
.epll_sdiv = 0x3,
|
||||
.vpll_mdiv = 0x96,
|
||||
.vpll_pdiv = 0x3,
|
||||
.vpll_sdiv = 0x2,
|
||||
|
||||
.bpll_mdiv = 0x64,
|
||||
.bpll_pdiv = 0x3,
|
||||
.bpll_sdiv = 0x0,
|
||||
.use_bpll = 0,
|
||||
.pclk_cdrex_ratio = 0x5,
|
||||
.direct_cmd_msr = {
|
||||
0x00020018, 0x00030000, 0x00010042, 0x00000d70
|
||||
},
|
||||
.timing_ref = 0x000000bb,
|
||||
.timing_row = 0x8c36660f,
|
||||
.timing_data = 0x3630580b,
|
||||
.timing_power = 0x41000a44,
|
||||
.phy0_dqs = 0x08080808,
|
||||
.phy1_dqs = 0x08080808,
|
||||
.phy0_dq = 0x08080808,
|
||||
.phy1_dq = 0x08080808,
|
||||
.phy0_tFS = 0x4,
|
||||
.phy1_tFS = 0x4,
|
||||
.phy0_pulld_dqs = 0xf,
|
||||
.phy1_pulld_dqs = 0xf,
|
||||
|
||||
.lpddr3_ctrl_phy_reset = 0x1,
|
||||
.ctrl_start_point = 0x10,
|
||||
.ctrl_inc = 0x10,
|
||||
.ctrl_start = 0x1,
|
||||
.ctrl_dll_on = 0x1,
|
||||
.ctrl_ref = 0x8,
|
||||
|
||||
.ctrl_force = 0x1a,
|
||||
.ctrl_rdlat = 0x0b,
|
||||
.ctrl_bstlen = 0x08,
|
||||
|
||||
.fp_resync = 0x8,
|
||||
.iv_size = 0x7,
|
||||
.dfi_init_start = 1,
|
||||
.aref_en = 1,
|
||||
|
||||
.rd_fetch = 0x3,
|
||||
|
||||
.zq_mode_dds = 0x7,
|
||||
.zq_mode_term = 0x1,
|
||||
.zq_mode_noterm = 0,
|
||||
|
||||
/*
|
||||
* Dynamic Clock: Always Running
|
||||
* Memory Burst length: 8
|
||||
* Number of chips: 1
|
||||
* Memory Bus width: 32 bit
|
||||
* Memory Type: DDR3
|
||||
* Additional Latancy for PLL: 0 Cycle
|
||||
*/
|
||||
.memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
|
||||
DMC_MEMCONTROL_DPWRDN_DISABLE |
|
||||
DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE |
|
||||
DMC_MEMCONTROL_TP_DISABLE |
|
||||
DMC_MEMCONTROL_DSREF_ENABLE |
|
||||
DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
|
||||
DMC_MEMCONTROL_MEM_TYPE_DDR3 |
|
||||
DMC_MEMCONTROL_MEM_WIDTH_32BIT |
|
||||
DMC_MEMCONTROL_NUM_CHIP_1 |
|
||||
DMC_MEMCONTROL_BL_8 |
|
||||
DMC_MEMCONTROL_PZQ_DISABLE |
|
||||
DMC_MEMCONTROL_MRR_BYTE_7_0,
|
||||
.memconfig = DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED |
|
||||
DMC_MEMCONFIGx_CHIP_COL_10 |
|
||||
DMC_MEMCONFIGx_CHIP_ROW_15 |
|
||||
DMC_MEMCONFIGx_CHIP_BANK_8,
|
||||
.membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
|
||||
.membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
|
||||
.prechconfig_tp_cnt = 0xff,
|
||||
.dpwrdn_cyc = 0xff,
|
||||
.dsref_cyc = 0xffff,
|
||||
.concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE |
|
||||
DMC_CONCONTROL_TIMEOUT_LEVEL0 |
|
||||
DMC_CONCONTROL_RD_FETCH_DISABLE |
|
||||
DMC_CONCONTROL_EMPTY_DISABLE |
|
||||
DMC_CONCONTROL_AREF_EN_DISABLE |
|
||||
DMC_CONCONTROL_IO_PD_CON_DISABLE,
|
||||
.dmc_channels = 2,
|
||||
.chips_per_channel = 2,
|
||||
.chips_to_configure = 1,
|
||||
.send_zq_init = 1,
|
||||
.impedance = IMP_OUTPUT_DRV_30_OHM,
|
||||
.gate_leveling_enable = 0,
|
||||
}, {
|
||||
.mem_manuf = MEM_MANUF_SAMSUNG,
|
||||
.mem_type = DDR_MODE_DDR3,
|
||||
.frequency_mhz = 800,
|
||||
.mpll_mdiv = 0x64,
|
||||
.mpll_pdiv = 0x3,
|
||||
.mpll_sdiv = 0x0,
|
||||
.cpll_mdiv = 0xde,
|
||||
.cpll_pdiv = 0x4,
|
||||
.cpll_sdiv = 0x2,
|
||||
.gpll_mdiv = 0x215,
|
||||
.gpll_pdiv = 0xc,
|
||||
.gpll_sdiv = 0x1,
|
||||
.epll_mdiv = 0x60,
|
||||
.epll_pdiv = 0x3,
|
||||
.epll_sdiv = 0x3,
|
||||
.vpll_mdiv = 0x96,
|
||||
.vpll_pdiv = 0x3,
|
||||
.vpll_sdiv = 0x2,
|
||||
|
||||
.bpll_mdiv = 0x64,
|
||||
.bpll_pdiv = 0x3,
|
||||
.bpll_sdiv = 0x0,
|
||||
.use_bpll = 0,
|
||||
.pclk_cdrex_ratio = 0x5,
|
||||
.direct_cmd_msr = {
|
||||
0x00020018, 0x00030000, 0x00010000, 0x00000d70
|
||||
},
|
||||
.timing_ref = 0x000000bb,
|
||||
.timing_row = 0x8c36660f,
|
||||
.timing_data = 0x3630580b,
|
||||
.timing_power = 0x41000a44,
|
||||
.phy0_dqs = 0x08080808,
|
||||
.phy1_dqs = 0x08080808,
|
||||
.phy0_dq = 0x08080808,
|
||||
.phy1_dq = 0x08080808,
|
||||
.phy0_tFS = 0x8,
|
||||
.phy1_tFS = 0x8,
|
||||
.phy0_pulld_dqs = 0xf,
|
||||
.phy1_pulld_dqs = 0xf,
|
||||
|
||||
.lpddr3_ctrl_phy_reset = 0x1,
|
||||
.ctrl_start_point = 0x10,
|
||||
.ctrl_inc = 0x10,
|
||||
.ctrl_start = 0x1,
|
||||
.ctrl_dll_on = 0x1,
|
||||
.ctrl_ref = 0x8,
|
||||
|
||||
.ctrl_force = 0x1a,
|
||||
.ctrl_rdlat = 0x0b,
|
||||
.ctrl_bstlen = 0x08,
|
||||
|
||||
.fp_resync = 0x8,
|
||||
.iv_size = 0x7,
|
||||
.dfi_init_start = 1,
|
||||
.aref_en = 1,
|
||||
|
||||
.rd_fetch = 0x3,
|
||||
|
||||
.zq_mode_dds = 0x5,
|
||||
.zq_mode_term = 0x1,
|
||||
.zq_mode_noterm = 1,
|
||||
|
||||
/*
|
||||
* Dynamic Clock: Always Running
|
||||
* Memory Burst length: 8
|
||||
* Number of chips: 1
|
||||
* Memory Bus width: 32 bit
|
||||
* Memory Type: DDR3
|
||||
* Additional Latancy for PLL: 0 Cycle
|
||||
*/
|
||||
.memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
|
||||
DMC_MEMCONTROL_DPWRDN_DISABLE |
|
||||
DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE |
|
||||
DMC_MEMCONTROL_TP_DISABLE |
|
||||
DMC_MEMCONTROL_DSREF_ENABLE |
|
||||
DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
|
||||
DMC_MEMCONTROL_MEM_TYPE_DDR3 |
|
||||
DMC_MEMCONTROL_MEM_WIDTH_32BIT |
|
||||
DMC_MEMCONTROL_NUM_CHIP_1 |
|
||||
DMC_MEMCONTROL_BL_8 |
|
||||
DMC_MEMCONTROL_PZQ_DISABLE |
|
||||
DMC_MEMCONTROL_MRR_BYTE_7_0,
|
||||
.memconfig = DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED |
|
||||
DMC_MEMCONFIGx_CHIP_COL_10 |
|
||||
DMC_MEMCONFIGx_CHIP_ROW_15 |
|
||||
DMC_MEMCONFIGx_CHIP_BANK_8,
|
||||
.membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
|
||||
.membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
|
||||
.prechconfig_tp_cnt = 0xff,
|
||||
.dpwrdn_cyc = 0xff,
|
||||
.dsref_cyc = 0xffff,
|
||||
.concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE |
|
||||
DMC_CONCONTROL_TIMEOUT_LEVEL0 |
|
||||
DMC_CONCONTROL_RD_FETCH_DISABLE |
|
||||
DMC_CONCONTROL_EMPTY_DISABLE |
|
||||
DMC_CONCONTROL_AREF_EN_DISABLE |
|
||||
DMC_CONCONTROL_IO_PD_CON_DISABLE,
|
||||
.dmc_channels = 2,
|
||||
.chips_per_channel = 2,
|
||||
.chips_to_configure = 1,
|
||||
.send_zq_init = 1,
|
||||
.impedance = IMP_OUTPUT_DRV_40_OHM,
|
||||
.gate_leveling_enable = 1,
|
||||
},
|
||||
{
|
||||
.mem_manuf = MEM_MANUF_ELPIDA,
|
||||
.mem_type = DDR_MODE_DDR3,
|
||||
.frequency_mhz = 780,
|
||||
.mpll_mdiv = 0x64,
|
||||
.mpll_pdiv = 0x3,
|
||||
.mpll_sdiv = 0x0,
|
||||
.cpll_mdiv = 0xde,
|
||||
.cpll_pdiv = 0x4,
|
||||
.cpll_sdiv = 0x2,
|
||||
.gpll_mdiv = 0x215,
|
||||
.gpll_pdiv = 0xc,
|
||||
.gpll_sdiv = 0x1,
|
||||
.epll_mdiv = 0x60,
|
||||
.epll_pdiv = 0x3,
|
||||
.epll_sdiv = 0x3,
|
||||
.vpll_mdiv = 0x96,
|
||||
.vpll_pdiv = 0x3,
|
||||
.vpll_sdiv = 0x2,
|
||||
|
||||
.bpll_mdiv = 0x82,
|
||||
.bpll_pdiv = 0x4,
|
||||
.bpll_sdiv = 0x0,
|
||||
.use_bpll = 1,
|
||||
.pclk_cdrex_ratio = 0x5,
|
||||
.direct_cmd_msr = {
|
||||
0x00020018, 0x00030000, 0x00010042, 0x00000d70
|
||||
},
|
||||
.timing_ref = 0x000000bb,
|
||||
.timing_row = 0x8c36660f,
|
||||
.timing_data = 0x3630580b,
|
||||
.timing_power = 0x41000a44,
|
||||
.phy0_dqs = 0x08080808,
|
||||
.phy1_dqs = 0x08080808,
|
||||
.phy0_dq = 0x08080808,
|
||||
.phy1_dq = 0x08080808,
|
||||
.phy0_tFS = 0x4,
|
||||
.phy1_tFS = 0x4,
|
||||
.phy0_pulld_dqs = 0xf,
|
||||
.phy1_pulld_dqs = 0xf,
|
||||
|
||||
.lpddr3_ctrl_phy_reset = 0x1,
|
||||
.ctrl_start_point = 0x10,
|
||||
.ctrl_inc = 0x10,
|
||||
.ctrl_start = 0x1,
|
||||
.ctrl_dll_on = 0x1,
|
||||
.ctrl_ref = 0x8,
|
||||
|
||||
.ctrl_force = 0x1a,
|
||||
.ctrl_rdlat = 0x0b,
|
||||
.ctrl_bstlen = 0x08,
|
||||
|
||||
.fp_resync = 0x8,
|
||||
.iv_size = 0x7,
|
||||
.dfi_init_start = 1,
|
||||
.aref_en = 1,
|
||||
|
||||
.rd_fetch = 0x3,
|
||||
|
||||
.zq_mode_dds = 0x7,
|
||||
.zq_mode_term = 0x1,
|
||||
.zq_mode_noterm = 0,
|
||||
|
||||
/*
|
||||
* Dynamic Clock: Always Running
|
||||
* Memory Burst length: 8
|
||||
* Number of chips: 1
|
||||
* Memory Bus width: 32 bit
|
||||
* Memory Type: DDR3
|
||||
* Additional Latancy for PLL: 0 Cycle
|
||||
*/
|
||||
.memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
|
||||
DMC_MEMCONTROL_DPWRDN_DISABLE |
|
||||
DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE |
|
||||
DMC_MEMCONTROL_TP_DISABLE |
|
||||
DMC_MEMCONTROL_DSREF_ENABLE |
|
||||
DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
|
||||
DMC_MEMCONTROL_MEM_TYPE_DDR3 |
|
||||
DMC_MEMCONTROL_MEM_WIDTH_32BIT |
|
||||
DMC_MEMCONTROL_NUM_CHIP_1 |
|
||||
DMC_MEMCONTROL_BL_8 |
|
||||
DMC_MEMCONTROL_PZQ_DISABLE |
|
||||
DMC_MEMCONTROL_MRR_BYTE_7_0,
|
||||
.memconfig = DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED |
|
||||
DMC_MEMCONFIGx_CHIP_COL_10 |
|
||||
DMC_MEMCONFIGx_CHIP_ROW_15 |
|
||||
DMC_MEMCONFIGx_CHIP_BANK_8,
|
||||
.membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
|
||||
.membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
|
||||
.prechconfig_tp_cnt = 0xff,
|
||||
.dpwrdn_cyc = 0xff,
|
||||
.dsref_cyc = 0xffff,
|
||||
.concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE |
|
||||
DMC_CONCONTROL_TIMEOUT_LEVEL0 |
|
||||
DMC_CONCONTROL_RD_FETCH_DISABLE |
|
||||
DMC_CONCONTROL_EMPTY_DISABLE |
|
||||
DMC_CONCONTROL_AREF_EN_DISABLE |
|
||||
DMC_CONCONTROL_IO_PD_CON_DISABLE,
|
||||
.dmc_channels = 2,
|
||||
.chips_per_channel = 2,
|
||||
.chips_to_configure = 1,
|
||||
.send_zq_init = 1,
|
||||
.impedance = IMP_OUTPUT_DRV_30_OHM,
|
||||
.gate_leveling_enable = 0,
|
||||
}, {
|
||||
.mem_manuf = MEM_MANUF_SAMSUNG,
|
||||
.mem_type = DDR_MODE_DDR3,
|
||||
.frequency_mhz = 780,
|
||||
.mpll_mdiv = 0x64,
|
||||
.mpll_pdiv = 0x3,
|
||||
.mpll_sdiv = 0x0,
|
||||
.cpll_mdiv = 0xde,
|
||||
.cpll_pdiv = 0x4,
|
||||
.cpll_sdiv = 0x2,
|
||||
.gpll_mdiv = 0x215,
|
||||
.gpll_pdiv = 0xc,
|
||||
.gpll_sdiv = 0x1,
|
||||
.epll_mdiv = 0x60,
|
||||
.epll_pdiv = 0x3,
|
||||
.epll_sdiv = 0x3,
|
||||
.vpll_mdiv = 0x96,
|
||||
.vpll_pdiv = 0x3,
|
||||
.vpll_sdiv = 0x2,
|
||||
|
||||
.bpll_mdiv = 0x82,
|
||||
.bpll_pdiv = 0x4,
|
||||
.bpll_sdiv = 0x0,
|
||||
.use_bpll = 1,
|
||||
.pclk_cdrex_ratio = 0x5,
|
||||
.direct_cmd_msr = {
|
||||
0x00020018, 0x00030000, 0x00010000, 0x00000d70
|
||||
},
|
||||
.timing_ref = 0x000000bb,
|
||||
.timing_row = 0x8c36660f,
|
||||
.timing_data = 0x3630580b,
|
||||
.timing_power = 0x41000a44,
|
||||
.phy0_dqs = 0x08080808,
|
||||
.phy1_dqs = 0x08080808,
|
||||
.phy0_dq = 0x08080808,
|
||||
.phy1_dq = 0x08080808,
|
||||
.phy0_tFS = 0x8,
|
||||
.phy1_tFS = 0x8,
|
||||
.phy0_pulld_dqs = 0xf,
|
||||
.phy1_pulld_dqs = 0xf,
|
||||
|
||||
.lpddr3_ctrl_phy_reset = 0x1,
|
||||
.ctrl_start_point = 0x10,
|
||||
.ctrl_inc = 0x10,
|
||||
.ctrl_start = 0x1,
|
||||
.ctrl_dll_on = 0x1,
|
||||
.ctrl_ref = 0x8,
|
||||
|
||||
.ctrl_force = 0x1a,
|
||||
.ctrl_rdlat = 0x0b,
|
||||
.ctrl_bstlen = 0x08,
|
||||
|
||||
.fp_resync = 0x8,
|
||||
.iv_size = 0x7,
|
||||
.dfi_init_start = 1,
|
||||
.aref_en = 1,
|
||||
|
||||
.rd_fetch = 0x3,
|
||||
|
||||
.zq_mode_dds = 0x5,
|
||||
.zq_mode_term = 0x1,
|
||||
.zq_mode_noterm = 1,
|
||||
|
||||
/*
|
||||
* Dynamic Clock: Always Running
|
||||
* Memory Burst length: 8
|
||||
* Number of chips: 1
|
||||
* Memory Bus width: 32 bit
|
||||
* Memory Type: DDR3
|
||||
* Additional Latancy for PLL: 0 Cycle
|
||||
*/
|
||||
.memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
|
||||
DMC_MEMCONTROL_DPWRDN_DISABLE |
|
||||
DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE |
|
||||
DMC_MEMCONTROL_TP_DISABLE |
|
||||
DMC_MEMCONTROL_DSREF_ENABLE |
|
||||
DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
|
||||
DMC_MEMCONTROL_MEM_TYPE_DDR3 |
|
||||
DMC_MEMCONTROL_MEM_WIDTH_32BIT |
|
||||
DMC_MEMCONTROL_NUM_CHIP_1 |
|
||||
DMC_MEMCONTROL_BL_8 |
|
||||
DMC_MEMCONTROL_PZQ_DISABLE |
|
||||
DMC_MEMCONTROL_MRR_BYTE_7_0,
|
||||
.memconfig = DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED |
|
||||
DMC_MEMCONFIGx_CHIP_COL_10 |
|
||||
DMC_MEMCONFIGx_CHIP_ROW_15 |
|
||||
DMC_MEMCONFIGx_CHIP_BANK_8,
|
||||
.membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
|
||||
.membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
|
||||
.prechconfig_tp_cnt = 0xff,
|
||||
.dpwrdn_cyc = 0xff,
|
||||
.dsref_cyc = 0xffff,
|
||||
.concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE |
|
||||
DMC_CONCONTROL_TIMEOUT_LEVEL0 |
|
||||
DMC_CONCONTROL_RD_FETCH_DISABLE |
|
||||
DMC_CONCONTROL_EMPTY_DISABLE |
|
||||
DMC_CONCONTROL_AREF_EN_DISABLE |
|
||||
DMC_CONCONTROL_IO_PD_CON_DISABLE,
|
||||
.dmc_channels = 2,
|
||||
.chips_per_channel = 2,
|
||||
.chips_to_configure = 1,
|
||||
.send_zq_init = 1,
|
||||
.impedance = IMP_OUTPUT_DRV_40_OHM,
|
||||
.gate_leveling_enable = 1,
|
||||
}
|
||||
};
|
||||
|
||||
#define BOARD_ID0_GPIO 88 /* GPD0, pin 0 */
|
||||
#define BOARD_ID1_GPIO 89 /* GPD0, pin 1 */
|
||||
|
||||
enum board_config {
|
||||
PIT_CONFIG_UNKNOWN = -1,
|
||||
PIT_CONFIG_SAMSUNG_EVT,
|
||||
PIT_CONFIG_ELPIDA_EVT,
|
||||
PIT_CONFIG_SAMSUNG_DVT,
|
||||
PIT_CONFIG_ELPIDA_DVT,
|
||||
PIT_CONFIG_SAMSUNG_PVT,
|
||||
PIT_CONFIG_ELPIDA_PVT,
|
||||
PIT_CONFIG_SAMSUNG_MP,
|
||||
PIT_CONFIG_ELPIDA_MP,
|
||||
PIT_CONFIG_RSVD,
|
||||
};
|
||||
|
||||
struct {
|
||||
enum mvl3 id0, id1;
|
||||
enum board_config config;
|
||||
} id_map[] = {
|
||||
/* ID0 ID1 config */
|
||||
{ LOGIC_0, LOGIC_0, PIT_CONFIG_SAMSUNG_MP },
|
||||
{ LOGIC_0, LOGIC_1, PIT_CONFIG_ELPIDA_MP },
|
||||
{ LOGIC_1, LOGIC_0, PIT_CONFIG_SAMSUNG_DVT },
|
||||
{ LOGIC_1, LOGIC_1, PIT_CONFIG_ELPIDA_DVT },
|
||||
{ LOGIC_0, LOGIC_Z, PIT_CONFIG_SAMSUNG_PVT },
|
||||
{ LOGIC_1, LOGIC_Z, PIT_CONFIG_ELPIDA_PVT },
|
||||
{ LOGIC_Z, LOGIC_0, PIT_CONFIG_SAMSUNG_MP },
|
||||
{ LOGIC_Z, LOGIC_Z, PIT_CONFIG_ELPIDA_MP },
|
||||
{ LOGIC_Z, LOGIC_1, PIT_CONFIG_RSVD },
|
||||
};
|
||||
|
||||
static int board_get_config(void)
|
||||
{
|
||||
int i;
|
||||
int id0, id1;
|
||||
enum board_config config = PIT_CONFIG_UNKNOWN;
|
||||
|
||||
id0 = gpio_read_mvl3(BOARD_ID0_GPIO);
|
||||
id1 = gpio_read_mvl3(BOARD_ID1_GPIO);
|
||||
if (id0 < 0 || id1 < 0)
|
||||
return -1;
|
||||
printk(BIOS_DEBUG, "%s: id0: %u, id1: %u\n", __func__, id0, id1);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(id_map); i++) {
|
||||
if (id0 == id_map[i].id0 && id1 == id_map[i].id1) {
|
||||
config = id_map[i].config;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
struct mem_timings *get_mem_timings(void)
|
||||
{
|
||||
int i;
|
||||
enum board_config config;
|
||||
enum ddr_mode mem_type;
|
||||
unsigned int frequency_mhz;
|
||||
enum mem_manuf mem_manuf;
|
||||
const struct mem_timings *mem;
|
||||
|
||||
config = board_get_config();
|
||||
switch (config) {
|
||||
case PIT_CONFIG_ELPIDA_EVT:
|
||||
case PIT_CONFIG_ELPIDA_DVT:
|
||||
case PIT_CONFIG_ELPIDA_PVT:
|
||||
case PIT_CONFIG_ELPIDA_MP:
|
||||
mem_manuf = MEM_MANUF_ELPIDA;
|
||||
mem_type = DDR_MODE_DDR3;
|
||||
frequency_mhz = 800;
|
||||
break;
|
||||
case PIT_CONFIG_SAMSUNG_EVT:
|
||||
case PIT_CONFIG_SAMSUNG_DVT:
|
||||
case PIT_CONFIG_SAMSUNG_PVT:
|
||||
case PIT_CONFIG_SAMSUNG_MP:
|
||||
mem_manuf = MEM_MANUF_SAMSUNG;
|
||||
mem_type = DDR_MODE_DDR3;
|
||||
frequency_mhz = 800;
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_CRIT, "Unknown board configuration.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0, mem = mem_timings; i < ARRAY_SIZE(mem_timings);
|
||||
i++, mem++) {
|
||||
if (mem->mem_type == mem_type &&
|
||||
mem->frequency_mhz == frequency_mhz &&
|
||||
mem->mem_manuf == mem_manuf)
|
||||
return (struct mem_timings *)mem;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <armv7.h>
|
||||
#include <cbfs.h>
|
||||
|
||||
#include <arch/cache.h>
|
||||
#include <cpu/samsung/exynos5420/i2c.h>
|
||||
#include <cpu/samsung/exynos5420/clk.h>
|
||||
#include <cpu/samsung/exynos5420/cpu.h>
|
||||
#include <cpu/samsung/exynos5420/dmc.h>
|
||||
#include <cpu/samsung/exynos5420/gpio.h>
|
||||
#include <cpu/samsung/exynos5420/setup.h>
|
||||
#include <cpu/samsung/exynos5420/periph.h>
|
||||
#include <cpu/samsung/exynos5420/power.h>
|
||||
#include <cpu/samsung/exynos5420/wakeup.h>
|
||||
#include <console/console.h>
|
||||
#include <arch/stages.h>
|
||||
|
||||
#include <drivers/maxim/max77686/max77686.h>
|
||||
#include <device/i2c.h>
|
||||
|
||||
#include "exynos5420.h"
|
||||
|
||||
#define PMIC_BUS 0
|
||||
#define MMC0_GPIO_PIN (58)
|
||||
|
||||
static void setup_power(void)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
power_init();
|
||||
|
||||
/* Initialize I2C bus to configure PMIC. */
|
||||
i2c_init(0, I2C_0_SPEED, 0x00);
|
||||
|
||||
printk(BIOS_DEBUG, "%s: Setting up PMIC...\n", __func__);
|
||||
/*
|
||||
* We're using CR1616 coin cell battery that is non-rechargeable
|
||||
* battery. But, BBCHOSTEN bit of the BBAT Charger Register in
|
||||
* MAX77686 is enabled by default for charging coin cell.
|
||||
*
|
||||
* Also, we cannot meet the coin cell reverse current spec. in UL
|
||||
* standard if BBCHOSTEN bit is enabled.
|
||||
*
|
||||
* Disable Coin BATT Charging
|
||||
*/
|
||||
error = max77686_disable_backup_batt(PMIC_BUS);
|
||||
|
||||
error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK2, VDD_ARM_MV,
|
||||
REG_ENABLE, MAX77686_MV);
|
||||
error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK3, VDD_INT_UV,
|
||||
REG_ENABLE, MAX77686_UV);
|
||||
error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK1, VDD_MIF_MV,
|
||||
REG_ENABLE, MAX77686_MV);
|
||||
error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK4, VDD_G3D_MV,
|
||||
REG_ENABLE, MAX77686_MV);
|
||||
error |= max77686_volsetting(PMIC_BUS, PMIC_LDO2, VDD_LDO2_MV,
|
||||
REG_ENABLE, MAX77686_MV);
|
||||
error |= max77686_volsetting(PMIC_BUS, PMIC_LDO3, VDD_LDO3_MV,
|
||||
REG_ENABLE, MAX77686_MV);
|
||||
error |= max77686_volsetting(PMIC_BUS, PMIC_LDO5, VDD_LDO5_MV,
|
||||
REG_ENABLE, MAX77686_MV);
|
||||
error |= max77686_volsetting(PMIC_BUS, PMIC_LDO10, VDD_LDO10_MV,
|
||||
REG_ENABLE, MAX77686_MV);
|
||||
|
||||
error |= max77686_enable_32khz_cp(PMIC_BUS);
|
||||
|
||||
if (error) {
|
||||
printk(BIOS_CRIT, "%s: PMIC error: %#x\n", __func__, error);
|
||||
die("Failed to intialize PMIC.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_storage(void)
|
||||
{
|
||||
/* MMC0: Fixed, 8 bit mode, connected with GPIO. */
|
||||
if (clock_set_mshci(PERIPH_ID_SDMMC0))
|
||||
printk(BIOS_CRIT, "%s: Failed to set MMC0 clock.\n", __func__);
|
||||
if (gpio_direction_output(MMC0_GPIO_PIN, 1)) {
|
||||
printk(BIOS_CRIT, "%s: Unable to power on MMC0.\n", __func__);
|
||||
}
|
||||
gpio_set_pull(MMC0_GPIO_PIN, GPIO_PULL_NONE);
|
||||
gpio_set_drv(MMC0_GPIO_PIN, GPIO_DRV_4X);
|
||||
exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE);
|
||||
|
||||
/* MMC2: Removable, 4 bit mode, no GPIO. */
|
||||
clock_set_mshci(PERIPH_ID_SDMMC2);
|
||||
exynos_pinmux_config(PERIPH_ID_SDMMC2, 0);
|
||||
}
|
||||
|
||||
static void setup_graphics(void)
|
||||
{
|
||||
exynos_pinmux_config(PERIPH_ID_DPHPD, 0);
|
||||
}
|
||||
|
||||
static void setup_gpio(void)
|
||||
{
|
||||
gpio_direction_input(GPIO_D16); // WP_GPIO
|
||||
gpio_set_pull(GPIO_D16, GPIO_PULL_NONE);
|
||||
|
||||
gpio_direction_input(GPIO_Y10); // RECMODE_GPIO
|
||||
gpio_set_pull(GPIO_Y10, GPIO_PULL_NONE);
|
||||
|
||||
gpio_direction_input(GPIO_X35); // LID_GPIO
|
||||
gpio_set_pull(GPIO_X35, GPIO_PULL_NONE);
|
||||
|
||||
gpio_direction_input(GPIO_X13); // POWER_GPIO
|
||||
gpio_set_pull(GPIO_X13, GPIO_PULL_NONE);
|
||||
}
|
||||
|
||||
static void setup_memory(struct mem_timings *mem, int is_resume)
|
||||
{
|
||||
printk(BIOS_SPEW, "man: 0x%x type: 0x%x, div: 0x%x, mhz: 0x%x\n",
|
||||
mem->mem_manuf,
|
||||
mem->mem_type,
|
||||
mem->mpll_mdiv,
|
||||
mem->frequency_mhz);
|
||||
|
||||
/* FIXME Currently memory initialization with mem_reset on normal boot
|
||||
* will cause resume to fail (even if we don't do mem_reset on resume),
|
||||
* and the workaround is to temporarily always enable "is_resume".
|
||||
* This should be removed when the root cause of resume issue is found.
|
||||
*/
|
||||
is_resume = 1;
|
||||
|
||||
if (ddr3_mem_ctrl_init(mem, DMC_INTERLEAVE_SIZE, !is_resume)) {
|
||||
die("Failed to initialize memory controller.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static struct mem_timings *setup_clock(void)
|
||||
{
|
||||
struct mem_timings *mem = get_mem_timings();
|
||||
struct arm_clk_ratios *arm_ratios = get_arm_clk_ratios();
|
||||
if (!mem) {
|
||||
die("Unable to auto-detect memory timings\n");
|
||||
}
|
||||
system_clock_init(mem, arm_ratios);
|
||||
return mem;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
struct mem_timings *mem;
|
||||
void *entry;
|
||||
int is_resume = (get_wakeup_state() != IS_NOT_WAKEUP);
|
||||
|
||||
/* Clock must be initialized before console_init, otherwise you may need
|
||||
* to re-initialize serial console drivers again. */
|
||||
mem = setup_clock();
|
||||
|
||||
if (!is_resume) {
|
||||
console_init();
|
||||
setup_power();
|
||||
}
|
||||
|
||||
setup_memory(mem, is_resume);
|
||||
|
||||
if (is_resume) {
|
||||
wakeup();
|
||||
}
|
||||
|
||||
setup_storage();
|
||||
setup_gpio();
|
||||
setup_graphics();
|
||||
|
||||
/* Set SPI (primary CBFS media) clock to 50MHz. */
|
||||
clock_set_rate(PERIPH_ID_SPI1, 50000000);
|
||||
|
||||
entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, "fallback/coreboot_ram");
|
||||
stage_exit(entry);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <cpu/samsung/exynos5420/gpio.h>
|
||||
#include <cpu/samsung/exynos5420/wakeup.h>
|
||||
|
||||
int wakeup_need_reset(void)
|
||||
{
|
||||
/* The "wake up" event is not reliable (known as "bad wakeup") and needs
|
||||
* reset if GPIO value is high. */
|
||||
return gpio_get_value(GPIO_Y10);
|
||||
}
|
||||
|
Loading…
Reference in New Issue