Patrick Georgi (patrick(a)georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4413
-gerrit
commit a11df88a9ea549bc525d4326b499db503e160a2b
Author: Gabe Black <gabeblack(a)google.com>
Date: Tue Jul 30 22:43:47 2013 -0700
kirby: Clean some cruft from mainboard.c
1. Kirby doesn't have a backlight enable GPIO on the AP since that's handled
entirely by the DP-to-LVDS bridge.
2. There is no tps65090 on the other side of the EC who's settings need to be
adjusted. If we need to turn on the LCD or backlight power manually, it will
have to be done in a different way.
3. The PMIC doesn't provide a 32KHz output for the audio codec.
Change-Id: Iadc5f3aec4818805edf3f2517da9e6fee87085dc
Signed-off-by: Gabe Black <gabeblack(a)google.com>
Reviewed-on: https://gerrit.chromium.org/gerrit/63883
Commit-Queue: Gabe Black <gabeblack(a)chromium.org>
Reviewed-by: Gabe Black <gabeblack(a)chromium.org>
Tested-by: Gabe Black <gabeblack(a)chromium.org>
---
src/mainboard/google/kirby/mainboard.c | 33 +--------------------------------
1 file changed, 1 insertion(+), 32 deletions(-)
diff --git a/src/mainboard/google/kirby/mainboard.c b/src/mainboard/google/kirby/mainboard.c
index 9975202..064d0f1 100644
--- a/src/mainboard/google/kirby/mainboard.c
+++ b/src/mainboard/google/kirby/mainboard.c
@@ -172,7 +172,6 @@ static enum exynos5_gpio_pin dp_pd_l = GPIO_X35; /* active low */
static enum exynos5_gpio_pin dp_rst_l = GPIO_Y77; /* active low */
static enum exynos5_gpio_pin dp_hpd = GPIO_X26; /* active high */
static enum exynos5_gpio_pin bl_pwm = GPIO_B20; /* active high */
-static enum exynos5_gpio_pin bl_en = GPIO_X22; /* active high */
static void parade_dp_bridge_setup(void)
{
@@ -224,12 +223,6 @@ static void backlight_pwm(void)
udelay(LCD_T6_DELAY_MS * 1000);
}
-static void backlight_en(void)
-{
- /* Configure GPIO for LCD_BL_EN */
- gpio_direction_output(bl_en, 1);
-}
-
//static struct video_info smdk5420_dp_config = {
static struct video_info dp_video_info = {
/* FIXME: fix video_info struct to use const for name */
@@ -273,33 +266,12 @@ static void gpio_init(void)
exynos_pinmux_i2c10();
}
-enum {
- FET_CTRL_WAIT = 3 << 2,
- FET_CTRL_ADENFET = 1 << 1,
- FET_CTRL_ENFET = 1 << 0
-};
-
-static void tps65090_thru_ec_fet_set(int index)
-{
- uint8_t value = FET_CTRL_ADENFET | FET_CTRL_WAIT | FET_CTRL_ENFET;
-
- if (google_chromeec_i2c_xfer(0x48, 0xe + index, 1, &value, 1, 0)) {
- printk(BIOS_ERR,
- "Error sending i2c pass through command to EC.\n");
- return;
- }
-}
-
static void lcd_vdd(void)
{
- /* Enable FET6, lcd panel */
- tps65090_thru_ec_fet_set(6);
}
static void backlight_vdd(void)
{
- /* Enable FET1, backlight */
- tps65090_thru_ec_fet_set(1);
}
/* this happens after cpu_init where exynos resources are set */
@@ -332,7 +304,6 @@ static void mainboard_init(device_t dev)
backlight_vdd();
backlight_pwm();
- backlight_en();
// Uncomment to get excessive GPIO output:
// gpio_info();
@@ -372,11 +343,9 @@ static void mainboard_enable(device_t dev)
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",
+ .name = "Google ARM Chromebook",
.enable_dev = mainboard_enable,
};
Patrick Georgi (patrick(a)georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4412
-gerrit
commit 6b7b18c934feccb79acb6e19811fff84f5626970
Author: Gabe Black <gabeblack(a)google.com>
Date: Tue Jul 30 22:41:13 2013 -0700
kirby: Neutralize wakeup.c and delete the mostly unused exynos5420.h
The function in wakeup.c isn't applicable on kirby. The only constant in
exynos5420.h that was used was the speed of the 4th i2c bus. Instead of having
a whole header file for that one constant used in one place, the constant is
just moved inline along with the comment it had in the header.
Change-Id: I5ad50c5eeaecbbf7865d76afb31a12d36c3371ee
Signed-off-by: Gabe Black <gabeblack(a)google.com>
Reviewed-on: https://gerrit.chromium.org/gerrit/63882
Commit-Queue: Gabe Black <gabeblack(a)chromium.org>
Reviewed-by: Gabe Black <gabeblack(a)chromium.org>
Tested-by: Gabe Black <gabeblack(a)chromium.org>
---
src/mainboard/google/kirby/exynos5420.h | 34 ---------------------------------
src/mainboard/google/kirby/mainboard.c | 2 --
src/mainboard/google/kirby/romstage.c | 4 +---
src/mainboard/google/kirby/wakeup.c | 4 +---
4 files changed, 2 insertions(+), 42 deletions(-)
diff --git a/src/mainboard/google/kirby/exynos5420.h b/src/mainboard/google/kirby/exynos5420.h
deleted file mode 100644
index 21b704c..0000000
--- a/src/mainboard/google/kirby/exynos5420.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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_4_SPEED 1000000 /* 1MHz */
-#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
-
diff --git a/src/mainboard/google/kirby/mainboard.c b/src/mainboard/google/kirby/mainboard.c
index 98e591a..9975202 100644
--- a/src/mainboard/google/kirby/mainboard.c
+++ b/src/mainboard/google/kirby/mainboard.c
@@ -38,8 +38,6 @@
#include <ec/google/chromeec/ec.h>
#include <stdlib.h>
-#include "exynos5420.h"
-
/* convenient shorthand (in MB) */
#define DRAM_START (CONFIG_SYS_SDRAM_BASE >> 20)
#define DRAM_SIZE CONFIG_DRAM_SIZE_MB
diff --git a/src/mainboard/google/kirby/romstage.c b/src/mainboard/google/kirby/romstage.c
index 255f292..c11f712 100644
--- a/src/mainboard/google/kirby/romstage.c
+++ b/src/mainboard/google/kirby/romstage.c
@@ -40,8 +40,6 @@
#include <drivers/maxim/max77802/max77802.h>
#include <device/i2c.h>
-#include "exynos5420.h"
-
#define MMC0_GPIO_PIN (58)
struct pmic_write
@@ -89,7 +87,7 @@ static void setup_power(int is_resume)
/* Initialize I2C bus to configure PMIC. */
exynos_pinmux_i2c4();
- i2c_init(4, I2C_4_SPEED, 0x00);
+ i2c_init(4, 1000000, 0x00); /* 1MHz */
printk(BIOS_DEBUG, "%s: Setting up PMIC...\n", __func__);
diff --git a/src/mainboard/google/kirby/wakeup.c b/src/mainboard/google/kirby/wakeup.c
index a82b632..43bad6f 100644
--- a/src/mainboard/google/kirby/wakeup.c
+++ b/src/mainboard/google/kirby/wakeup.c
@@ -22,8 +22,6 @@
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);
+ return 0;
}
Patrick Georgi (patrick(a)georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4411
-gerrit
commit b7d699f47760f6b1361d42de4b55b713141fbdee
Author: Gabe Black <gabeblack(a)google.com>
Date: Tue Jul 30 21:35:31 2013 -0700
Add a kirby board which is mostly a copy of pit
Change-Id: Ic78c65486816015f7574a13affc6e54acbbea73e
Signed-off-by: Gabe Black <gabeblack(a)google.com>
Reviewed-on: https://gerrit.chromium.org/gerrit/63875
Commit-Queue: Gabe Black <gabeblack(a)chromium.org>
Reviewed-by: Gabe Black <gabeblack(a)chromium.org>
Tested-by: Gabe Black <gabeblack(a)chromium.org>
---
src/mainboard/google/Kconfig | 3 +
src/mainboard/google/kirby/Kconfig | 52 +++++
src/mainboard/google/kirby/Makefile.inc | 27 +++
src/mainboard/google/kirby/chromeos.c | 105 +++++++++
src/mainboard/google/kirby/devicetree.cb | 35 +++
src/mainboard/google/kirby/exynos5420.h | 34 +++
src/mainboard/google/kirby/mainboard.c | 384 +++++++++++++++++++++++++++++++
src/mainboard/google/kirby/memory.c | 110 +++++++++
src/mainboard/google/kirby/romstage.c | 280 ++++++++++++++++++++++
src/mainboard/google/kirby/wakeup.c | 29 +++
10 files changed, 1059 insertions(+)
diff --git a/src/mainboard/google/Kconfig b/src/mainboard/google/Kconfig
index c866c1f..8f5fbaa 100644
--- a/src/mainboard/google/Kconfig
+++ b/src/mainboard/google/Kconfig
@@ -32,6 +32,8 @@ config BOARD_GOOGLE_BUTTERFLY
bool "Butterfly"
config BOARD_GOOGLE_FALCO
bool "Falco"
+config BOARD_GOOGLE_KIRBY
+ bool "Kirby"
config BOARD_GOOGLE_LINK
bool "Link"
config BOARD_GOOGLE_PARROT
@@ -52,6 +54,7 @@ endchoice
source "src/mainboard/google/bolt/Kconfig"
source "src/mainboard/google/butterfly/Kconfig"
source "src/mainboard/google/falco/Kconfig"
+source "src/mainboard/google/kirby/Kconfig"
source "src/mainboard/google/link/Kconfig"
source "src/mainboard/google/parrot/Kconfig"
source "src/mainboard/google/peppy/Kconfig"
diff --git a/src/mainboard/google/kirby/Kconfig b/src/mainboard/google/kirby/Kconfig
new file mode 100644
index 0000000..0fa2a61
--- /dev/null
+++ b/src/mainboard/google/kirby/Kconfig
@@ -0,0 +1,52 @@
+##
+## 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_KIRBY
+
+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_SPI
+ select BOARD_ROMSIZE_KB_4096
+ select MAINBOARD_HAS_CHROMEOS
+ select MAINBOARD_HAS_NATIVE_VGA_INIT
+ select MAINBOARD_DO_NATIVE_VGA_INIT
+ select HAVE_INIT_TIMER
+ select DRIVER_PARADE_PS8625
+
+config MAINBOARD_DIR
+ string
+ default google/kirby
+
+config MAINBOARD_PART_NUMBER
+ string
+ default "Kirby"
+
+config DRAM_SIZE_MB
+ int
+ default 4096
+
+config EC_GOOGLE_CHROMEEC_SPI_BUS
+ hex
+ default 2
+
+endif # BOARD_GOOGLE_PIT
diff --git a/src/mainboard/google/kirby/Makefile.inc b/src/mainboard/google/kirby/Makefile.inc
new file mode 100644
index 0000000..1409e54
--- /dev/null
+++ b/src/mainboard/google/kirby/Makefile.inc
@@ -0,0 +1,27 @@
+##
+## 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
+##
+
+bootblock-y += wakeup.c
+
+romstage-y += memory.c
+romstage-y += romstage.c
+romstage-y += wakeup.c
+
+ramstage-y += mainboard.c
+ramstage-y += chromeos.c
diff --git a/src/mainboard/google/kirby/chromeos.c b/src/mainboard/google/kirby/chromeos.c
new file mode 100644
index 0000000..ae219bb
--- /dev/null
+++ b/src/mainboard/google/kirby/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_GPX3;
+ gpios->gpios[count].polarity = ACTIVE_LOW;
+ gpios->gpios[count].value = gpio_get_value(GPIO_X30); // 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_X34); // 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_X12); // 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_X07)) // 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;
+}
diff --git a/src/mainboard/google/kirby/devicetree.cb b/src/mainboard/google/kirby/devicetree.cb
new file mode 100644
index 0000000..2c9e668
--- /dev/null
+++ b/src/mainboard/google/kirby/devicetree.cb
@@ -0,0 +1,35 @@
+##
+## 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
+##
+
+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"
+ register "usb_vbus_gpio" = "GPIO_X11"
+ register "usb_hsic_gpio" = "GPIO_E10"
+end
diff --git a/src/mainboard/google/kirby/exynos5420.h b/src/mainboard/google/kirby/exynos5420.h
new file mode 100644
index 0000000..21b704c
--- /dev/null
+++ b/src/mainboard/google/kirby/exynos5420.h
@@ -0,0 +1,34 @@
+/*
+ * 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_4_SPEED 1000000 /* 1MHz */
+#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
+
diff --git a/src/mainboard/google/kirby/mainboard.c b/src/mainboard/google/kirby/mainboard.c
new file mode 100644
index 0000000..98e591a
--- /dev/null
+++ b/src/mainboard/google/kirby/mainboard.c
@@ -0,0 +1,384 @@
+/*
+ * 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 <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 <drivers/parade/ps8625/ps8625.h>
+#include <ec/google/chromeec/ec.h>
+#include <stdlib.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,
+ .x_resolution = 1366,
+ .y_resolution = 768,
+ .bytes_per_line = 2 * 1366
+};
+
+static const struct parade_write parade_writes[] = {
+ { 0x02, 0xa1, 0x01 }, /* HPD low */
+ /*
+ * SW setting
+ * [1:0] SW output 1.2V voltage is lower to 96%
+ */
+ { 0x04, 0x14, 0x01 },
+ /*
+ * RCO SS setting
+ * [5:4] = b01 0.5%, b10 1%, b11 1.5%
+ */
+ { 0x04, 0xe3, 0x20 },
+ { 0x04, 0xe2, 0x80 }, /* [7] RCO SS enable */
+ /*
+ * RPHY Setting
+ * [3:2] CDR tune wait cycle before
+ * measure for fine tune b00: 1us,
+ * 01: 0.5us, 10:2us, 11:4us.
+ */
+ { 0x04, 0x8a, 0x0c },
+ { 0x04, 0x89, 0x08 }, /* [3] RFD always on */
+ /*
+ * CTN lock in/out:
+ * 20000ppm/80000ppm. Lock out 2
+ * times.
+ */
+ { 0x04, 0x71, 0x2d },
+ /*
+ * 2.7G CDR settings
+ * NOF=40LSB for HBR CDR setting
+ */
+ { 0x04, 0x7d, 0x07 },
+ { 0x04, 0x7b, 0x00 }, /* [1:0] Fmin=+4bands */
+ { 0x04, 0x7a, 0xfd }, /* [7:5] DCO_FTRNG=+-40% */
+ /*
+ * 1.62G CDR settings
+ * [5:2]NOF=64LSB [1:0]DCO scale is 2/5
+ */
+ { 0x04, 0xc0, 0x12 },
+ { 0x04, 0xc1, 0x92 }, /* Gitune=-37% */
+ { 0x04, 0xc2, 0x1c }, /* Fbstep=100% */
+ { 0x04, 0x32, 0x80 }, /* [7] LOS signal disable */
+ /*
+ * RPIO Setting
+ * [7:4] LVDS driver bias current :
+ * 75% (250mV swing)
+ */
+ { 0x04, 0x00, 0xb0 },
+ /*
+ * [7:6] Right-bar GPIO output strength is 8mA
+ */
+ { 0x04, 0x15, 0x40 },
+ /* EQ Training State Machine Setting */
+ { 0x04, 0x54, 0x10 }, /* RCO calibration start */
+ /* [4:0] MAX_LANE_COUNT set to one lane */
+ { 0x01, 0x02, 0x81 },
+ /* [4:0] LANE_COUNT_SET set to one lane */
+ { 0x01, 0x21, 0x81 },
+ { 0x00, 0x52, 0x20 },
+ { 0x00, 0xf1, 0x03 }, /* HPD CP toggle enable */
+ { 0x00, 0x62, 0x41 },
+ /* Counter number, add 1ms counter delay */
+ { 0x00, 0xf6, 0x01 },
+ /*
+ * [6]PWM function control by
+ * DPCD0040f[7], default is PWM
+ * block always works.
+ */
+ { 0x00, 0x77, 0x06 },
+ /*
+ * 04h Adjust VTotal tolerance to
+ * fix the 30Hz no display issue
+ */
+ { 0x00, 0x4c, 0x04 },
+ /* DPCD00400='h00, Parade OUI = 'h001cf8 */
+ { 0x01, 0xc0, 0x00 },
+ { 0x01, 0xc1, 0x1c }, /* DPCD00401='h1c */
+ { 0x01, 0xc2, 0xf8 }, /* DPCD00402='hf8 */
+ /*
+ * DPCD403~408 = ASCII code
+ * D2SLV5='h4432534c5635
+ */
+ { 0x01, 0xc3, 0x44 },
+ { 0x01, 0xc4, 0x32 }, /* DPCD404 */
+ { 0x01, 0xc5, 0x53 }, /* DPCD405 */
+ { 0x01, 0xc6, 0x4c }, /* DPCD406 */
+ { 0x01, 0xc7, 0x56 }, /* DPCD407 */
+ { 0x01, 0xc8, 0x35 }, /* DPCD408 */
+ /*
+ * DPCD40A, Initial Code major revision
+ * '01'
+ */
+ { 0x01, 0xca, 0x01 },
+ /* DPCD40B, Initial Code minor revision '05' */
+ { 0x01, 0xcb, 0x05 },
+ /* DPCD720, Select external PWM */
+ { 0x01, 0xa5, 0x80 },
+ /*
+ * Set LVDS output as 6bit-VESA mapping,
+ * single LVDS channel
+ */
+ { 0x01, 0xcc, 0x13 },
+ /* Enable SSC set by register */
+ { 0x02, 0xb1, 0x20 },
+ /*
+ * Set SSC enabled and +/-1% central
+ * spreading
+ */
+ { 0x04, 0x10, 0x16 },
+ /* MPU Clock source: LC => RCO */
+ { 0x04, 0x59, 0x60 },
+ { 0x04, 0x54, 0x14 }, /* LC -> RCO */
+ { 0x02, 0xa1, 0x91 } /* HPD high */
+};
+
+/* TODO: transplanted DP stuff, clean up once we have something that works */
+static enum exynos5_gpio_pin dp_pd_l = GPIO_X35; /* active low */
+static enum exynos5_gpio_pin dp_rst_l = GPIO_Y77; /* active low */
+static enum exynos5_gpio_pin dp_hpd = GPIO_X26; /* active high */
+static enum exynos5_gpio_pin bl_pwm = GPIO_B20; /* active high */
+static enum exynos5_gpio_pin bl_en = GPIO_X22; /* active high */
+
+static void parade_dp_bridge_setup(void)
+{
+ 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);
+
+ gpio_cfg_pin(dp_hpd, GPIO_INPUT);
+
+ /* 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);
+
+ /* Hang around for the bridge to come up. */
+ mdelay(40);
+
+ /* Configure the bridge chip. */
+ exynos_pinmux_i2c7();
+ i2c_init(7, 100000, 0x00);
+
+ parade_ps8625_bridge_setup(7, 0x48,
+ parade_writes,
+ ARRAY_SIZE(parade_writes));
+}
+
+/*
+ * 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(bl_pwm, 1);
+ udelay(LCD_T6_DELAY_MS * 1000);
+}
+
+static void backlight_en(void)
+{
+ /* Configure GPIO for LCD_BL_EN */
+ gpio_direction_output(bl_en, 1);
+}
+
+//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);
+}
+
+static void gpio_init(void)
+{
+ /* Set up the I2C busses. */
+ exynos_pinmux_i2c2();
+ exynos_pinmux_i2c4();
+ exynos_pinmux_i2c7();
+ exynos_pinmux_i2c8();
+ exynos_pinmux_i2c9();
+ exynos_pinmux_i2c10();
+}
+
+enum {
+ FET_CTRL_WAIT = 3 << 2,
+ FET_CTRL_ADENFET = 1 << 1,
+ FET_CTRL_ENFET = 1 << 0
+};
+
+static void tps65090_thru_ec_fet_set(int index)
+{
+ uint8_t value = FET_CTRL_ADENFET | FET_CTRL_WAIT | FET_CTRL_ENFET;
+
+ if (google_chromeec_i2c_xfer(0x48, 0xe + index, 1, &value, 1, 0)) {
+ printk(BIOS_ERR,
+ "Error sending i2c pass through command to EC.\n");
+ return;
+ }
+}
+
+static void lcd_vdd(void)
+{
+ /* Enable FET6, lcd panel */
+ tps65090_thru_ec_fet_set(6);
+}
+
+static void backlight_vdd(void)
+{
+ /* Enable FET1, backlight */
+ tps65090_thru_ec_fet_set(1);
+}
+
+/* this happens after cpu_init where exynos resources are set */
+static void mainboard_init(device_t dev)
+{
+ struct s5p_dp_device dp_device = {
+ .base = (struct exynos5_dp *)EXYNOS5420_DP1_BASE,
+ .video_info = &dp_video_info,
+ };
+ void *fb_addr = (void *)(get_fb_base_kb() * KiB);
+
+ gpio_init();
+
+ 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();
+
+ set_vbe_mode_info_valid(&edid, (uintptr_t)fb_addr);
+
+ lcd_vdd();
+
+ parade_dp_bridge_setup();
+ dp_controller_init(&dp_device);
+
+ udelay(LCD_T3_DELAY_MS * 1000);
+
+ backlight_vdd();
+ backlight_pwm();
+ backlight_en();
+
+ // Uncomment to get excessive GPIO output:
+ // gpio_info();
+}
+
+static void mainboard_enable(device_t dev)
+{
+ dev->ops->init = &mainboard_init;
+
+#if !CONFIG_DYNAMIC_CBMEM
+ /* 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);
+#endif
+
+ /* 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,
+};
diff --git a/src/mainboard/google/kirby/memory.c b/src/mainboard/google/kirby/memory.c
new file mode 100644
index 0000000..74f3e6e
--- /dev/null
+++ b/src/mainboard/google/kirby/memory.c
@@ -0,0 +1,110 @@
+/*
+ * 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/dmc.h>
+#include <cpu/samsung/exynos5420/setup.h>
+#include <cpu/samsung/exynos5420/clk.h>
+
+const struct mem_timings mem_timings = {
+ .mem_manuf = MEM_MANUF_SAMSUNG,
+ .mem_type = DDR_MODE_DDR3,
+ .frequency_mhz = 800,
+ .direct_cmd_msr = {
+ 0x00020018, 0x00030000, 0x00010002, 0x00000d70
+ },
+ .timing_ref = 0x000000bb,
+ .timing_row = 0x6836650f,
+ .timing_data = 0x3630580b,
+ .timing_power = 0x41000a26,
+ .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 = 0x6,
+ .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_DISABLE |
+ DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
+ DMC_MEMCONTROL_MEM_TYPE_DDR3 |
+ DMC_MEMCONTROL_MEM_WIDTH_32BIT |
+ DMC_MEMCONTROL_NUM_CHIP_2 |
+ DMC_MEMCONTROL_BL_8 |
+ DMC_MEMCONTROL_PZQ_DISABLE |
+ DMC_MEMCONTROL_MRR_BYTE_7_0,
+ .memconfig = DMC_MEMCONFIG_CHIP_MAP_SPLIT |
+ DMC_MEMCONFIGx_CHIP_COL_10 |
+ DMC_MEMCONFIGx_CHIP_ROW_15 |
+ DMC_MEMCONFIGx_CHIP_BANK_8,
+ .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 = 1,
+ .chips_per_channel = 2,
+ .chips_to_configure = 2,
+ .send_zq_init = 1,
+ .gate_leveling_enable = 1,
+};
diff --git a/src/mainboard/google/kirby/romstage.c b/src/mainboard/google/kirby/romstage.c
new file mode 100644
index 0000000..255f292
--- /dev/null
+++ b/src/mainboard/google/kirby/romstage.c
@@ -0,0 +1,280 @@
+/*
+ * 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 <types.h>
+#include <stdlib.h>
+
+#include <armv7.h>
+#include <cbfs.h>
+#include <cbmem.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/max77802/max77802.h>
+#include <device/i2c.h>
+
+#include "exynos5420.h"
+
+#define MMC0_GPIO_PIN (58)
+
+struct pmic_write
+{
+ int or_orig; // Whether to or in the original value.
+ uint8_t reg; // Register to write.
+ uint8_t val; // Value to write.
+};
+
+/*
+ * Use read-modify-write for MAX77802 control registers and clobber the
+ * output voltage setting (BUCK?DVS?) registers.
+ */
+struct pmic_write pmic_writes[] =
+{
+ { 1, MAX77802_REG_PMIC_32KHZ, MAX77802_32KHCP_EN },
+ { 0, MAX77802_REG_PMIC_BUCK1DVS1, MAX77802_BUCK1DVS1_1V },
+ { 1, MAX77802_REG_PMIC_BUCK1CTRL, MAX77802_BUCK_TYPE1_ON |
+ MAX77802_BUCK_TYPE1_IGNORE_PWRREQ },
+ { 0, MAX77802_REG_PMIC_BUCK2DVS1, MAX77802_BUCK2DVS1_1V },
+ { 1, MAX77802_REG_PMIC_BUCK2CTRL1, MAX77802_BUCK_TYPE2_ON |
+ MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
+ { 0, MAX77802_REG_PMIC_BUCK3DVS1, MAX77802_BUCK3DVS1_1V },
+ { 1, MAX77802_REG_PMIC_BUCK3CTRL1, MAX77802_BUCK_TYPE2_ON |
+ MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
+ { 0, MAX77802_REG_PMIC_BUCK4DVS1, MAX77802_BUCK4DVS1_1V },
+ { 1, MAX77802_REG_PMIC_BUCK4CTRL1, MAX77802_BUCK_TYPE2_ON |
+ MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
+ { 0, MAX77802_REG_PMIC_BUCK6DVS1, MAX77802_BUCK6DVS1_1V },
+ { 1, MAX77802_REG_PMIC_BUCK6CTRL, MAX77802_BUCK_TYPE1_ON |
+ MAX77802_BUCK_TYPE1_IGNORE_PWRREQ },
+ { 1, MAX77802_REG_PMIC_LDO35CTRL1, MAX77802_LDO35CTRL1_1_2V },
+};
+
+static void setup_power(int is_resume)
+{
+ int error = 0;
+ int i;
+
+ power_init();
+
+ if (is_resume) {
+ return;
+ }
+
+ /* Initialize I2C bus to configure PMIC. */
+ exynos_pinmux_i2c4();
+ i2c_init(4, I2C_4_SPEED, 0x00);
+
+ printk(BIOS_DEBUG, "%s: Setting up PMIC...\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(pmic_writes); i++) {
+ uint8_t data = 0;
+ uint8_t reg = pmic_writes[i].reg;
+
+ if (pmic_writes[i].or_orig)
+ error |= i2c_read(4, MAX77802_I2C_ADDR,
+ reg, sizeof(reg),
+ &data, sizeof(data));
+ data |= pmic_writes[i].val;
+ error |= i2c_write(4, MAX77802_I2C_ADDR,
+ reg, sizeof(reg),
+ &data, sizeof(data));
+ }
+
+ if (error)
+ die("Failed to intialize PMIC.\n");
+}
+
+static void setup_storage(void)
+{
+ /* MMC0: Fixed, 8 bit mode, connected with GPIO. */
+ if (clock_set_dwmci(PERIPH_ID_SDMMC0))
+ printk(BIOS_CRIT, "%s: Failed to set MMC0 clock.\n", __func__);
+ exynos_pinmux_sdmmc0();
+
+ /* MMC2: Removable, 4 bit mode, no GPIO. */
+ clock_set_dwmci(PERIPH_ID_SDMMC2);
+ exynos_pinmux_sdmmc2();
+}
+
+static void setup_ec(void)
+{
+ /* SPI2 (EC) is slower and needs to work in half-duplex mode with
+ * single byte bus width. */
+ clock_set_rate(PERIPH_ID_SPI2, 5000000);
+ exynos_pinmux_spi2();
+}
+
+static void setup_gpio(void)
+{
+ gpio_direction_input(GPIO_X30); // WP_GPIO
+ gpio_set_pull(GPIO_X30, GPIO_PULL_NONE);
+
+ gpio_direction_input(GPIO_X07); // RECMODE_GPIO
+ gpio_set_pull(GPIO_X07, GPIO_PULL_NONE);
+
+ gpio_direction_input(GPIO_X34); // LID_GPIO
+ gpio_set_pull(GPIO_X34, GPIO_PULL_NONE);
+
+ gpio_direction_input(GPIO_X12); // POWER_GPIO
+ gpio_set_pull(GPIO_X12, GPIO_PULL_NONE);
+}
+
+static void setup_memory(struct mem_timings *mem, int is_resume)
+{
+ printk(BIOS_SPEW, "manufacturer: 0x%x type: 0x%x, div: 0x%x, mhz: %d\n",
+ mem->mem_manuf,
+ mem->mem_type,
+ mem->mpll_mdiv,
+ mem->frequency_mhz);
+
+ if (ddr3_mem_ctrl_init(mem, DMC_INTERLEAVE_SIZE, !is_resume)) {
+ die("Failed to initialize memory controller.\n");
+ }
+}
+
+#define PRIMITIVE_MEM_TEST 0
+#if PRIMITIVE_MEM_TEST
+static unsigned long primitive_mem_test(void)
+{
+ unsigned long *l = (void *)0x40000000;
+ int bad = 0;
+ unsigned long i;
+ for(i = 0; i < 256*1048576; i++){
+ if (! (i%1048576))
+ printk(BIOS_SPEW, "%lu ...", i);
+ l[i] = 0xffffffff - i;
+ }
+
+ for(i = 0; i < 256*1048576; i++){
+ if (! (i%1048576))
+ printk(BIOS_SPEW, "%lu ...", i);
+ if (l[i] != (0xffffffff - i)){
+ printk(BIOS_SPEW, "%p: want %08lx got %08lx\n", l, l[i], 0xffffffff - i);
+ bad++;
+ }
+ }
+
+ printk(BIOS_SPEW, "%d errors\n", bad);
+
+ return bad;
+}
+#else
+#define primitive_mem_test()
+#endif
+
+#define SIMPLE_SPI_TEST 0
+#if SIMPLE_SPI_TEST
+/* here is a simple SPI debug test, known to fid trouble */
+static void simple_spi_test(void)
+{
+ struct cbfs_media default_media, *media;
+ int i, amt = 4 * MiB, errors = 0;
+ //u32 *data = (void *)0x40000000;
+ u32 data[1024];
+ u32 in;
+
+ amt = sizeof(data);
+ media = &default_media;
+ if (init_default_cbfs_media(media) != 0) {
+ printk(BIOS_SPEW, "Failed to initialize default media.\n");
+ return;
+ }
+
+
+ media->open(media);
+ if (media->read(media, data, (size_t) 0, amt) < amt){
+ printk(BIOS_SPEW, "simple_spi_test fails\n");
+ return;
+ }
+
+
+ for(i = 0; i < amt; i += 4){
+ if (media->read(media, &in, (size_t) i, 4) < 1){
+ printk(BIOS_SPEW, "simple_spi_test fails at %d\n", i);
+ return;
+ }
+ if (data[i/4] != in){
+ errors++;
+ printk(BIOS_SPEW, "BAD at %d(%p):\nRAM %08lx\nSPI %08lx\n",
+ i, &data[i/4], (unsigned long)data[i/4], (unsigned long)in);
+ /* reread it to see which is wrong. */
+ if (media->read(media, &in, (size_t) i, 4) < 1){
+ printk(BIOS_SPEW, "simple_spi_test fails at %d\n", i);
+ return;
+ }
+ printk(BIOS_SPEW, "RTRY at %d(%p):\nRAM %08lx\nSPI %08lx\n",
+ i, &data[i/4], (unsigned long)data[i/4], (unsigned long)in);
+ }
+
+ }
+ printk(BIOS_SPEW, "%d errors\n", errors);
+}
+#else
+#define simple_spi_test()
+#endif
+
+void main(void)
+{
+
+ extern struct mem_timings mem_timings;
+ 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. */
+ system_clock_init();
+
+ console_init();
+
+ setup_power(is_resume);
+ setup_memory(&mem_timings, is_resume);
+
+ primitive_mem_test();
+
+ if (is_resume) {
+ wakeup();
+ }
+
+ setup_storage();
+ setup_gpio();
+ setup_ec();
+
+ simple_spi_test();
+ /* Set SPI (primary CBFS media) clock to 50MHz. */
+ /* if this is uncommented SPI will not work correctly. */
+ clock_set_rate(PERIPH_ID_SPI1, 50000000);
+ simple_spi_test();
+
+ cbmem_initialize_empty();
+
+ entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, "fallback/coreboot_ram");
+ simple_spi_test();
+ stage_exit(entry);
+}
diff --git a/src/mainboard/google/kirby/wakeup.c b/src/mainboard/google/kirby/wakeup.c
new file mode 100644
index 0000000..a82b632
--- /dev/null
+++ b/src/mainboard/google/kirby/wakeup.c
@@ -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);
+}
+
Patrick Georgi (patrick(a)georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4464
-gerrit
commit fba9056560c2024f8c758cc2371144a2d10f780b
Author: David Hendricks <dhendrix(a)chromium.org>
Date: Fri Aug 9 18:59:02 2013 -0700
exynos5420: Set SPLL to 400MHz
Increase SPLL to 400MHz from 300MHz as we set SPLL as the
switching parent for ARM and KFC. This value is as per
recommendation of the hardware team.
This is ported from https://gerrit.chromium.org/gerrit/62618
Signed-off-by: David Hendricks <dhendrix(a)chromium.org>
Change-Id: I8a5a5b957083b0b1f3e3e318fe5753cf7ae19223
Reviewed-on: https://gerrit.chromium.org/gerrit/65432
Reviewed-by: Gabe Black <gabeblack(a)chromium.org>
Tested-by: David Hendricks <dhendrix(a)chromium.org>
Commit-Queue: Gabe Black <gabeblack(a)chromium.org>
---
src/cpu/samsung/exynos5420/clock_init.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/cpu/samsung/exynos5420/clock_init.c b/src/cpu/samsung/exynos5420/clock_init.c
index 07bf5d9..8be286d 100644
--- a/src/cpu/samsung/exynos5420/clock_init.c
+++ b/src/cpu/samsung/exynos5420/clock_init.c
@@ -141,7 +141,7 @@ void system_clock_init(void)
/* Set SPLL */
writel(SPLL_CON1_VAL, &clk->spll_con1);
- val = set_pll(0xc8, 0x2, 0x3);
+ val = set_pll(200, 0x3, 0x2); /* 400MHz */
writel(val, &clk->spll_con0);
while ((readl(&clk->spll_con0) & PLL_LOCKED) == 0)
;
Patrick Georgi (patrick(a)georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4470
-gerrit
commit 7dbc0dc4ee034d94a8fe6d50567e6889f581896d
Author: David Hendricks <dhendrix(a)chromium.org>
Date: Thu Aug 1 19:09:21 2013 -0700
pit: disable LCD FETs before doing any graphics init
This ensures that the LCD FETs are off before we do graphics init.
FIXME: The location of the code is sub-optimal and should probably be
done in romstage, but there are __PRE_RAM__ considerations to take
into account.
Signed-off-by: David Hendricks <dhendrix(a)chromium.org>
Change-Id: I0844030d0a0e51eee1d29f1762f0b495777268df
Reviewed-on: https://gerrit.chromium.org/gerrit/64305
Reviewed-by: Ronald G. Minnich <rminnich(a)chromium.org>
Commit-Queue: Ronald G. Minnich <rminnich(a)chromium.org>
Tested-by: Ronald G. Minnich <rminnich(a)chromium.org>
---
src/cpu/samsung/exynos5420/cpu.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/src/cpu/samsung/exynos5420/cpu.c b/src/cpu/samsung/exynos5420/cpu.c
index bda46de..5ff345e 100644
--- a/src/cpu/samsung/exynos5420/cpu.c
+++ b/src/cpu/samsung/exynos5420/cpu.c
@@ -33,6 +33,8 @@
#include "usb.h"
#include "chip.h"
+#include <ec/google/chromeec/ec.h>
+
static unsigned int cpu_id;
static unsigned int cpu_rev;
@@ -141,6 +143,17 @@ static void exynos_displayport_init(device_t dev, u32 lcdbase,
mmio_resource(dev, 1, lcdbase/KiB, (fb_size + KiB - 1)/KiB);
}
+static void tps65090_thru_ec_fet_disable(int index)
+{
+ uint8_t value = 0;
+
+ if (google_chromeec_i2c_xfer(0x48, 0xe + index, 1, &value, 1, 0)) {
+ printk(BIOS_ERR,
+ "Error sending i2c pass through command to EC.\n");
+ return;
+ }
+}
+
static void cpu_enable(device_t dev)
{
unsigned long fb_size = FB_SIZE_KB * KiB;
@@ -149,6 +162,14 @@ static void cpu_enable(device_t dev)
ram_resource(dev, 0, RAM_BASE_KB, RAM_SIZE_KB - FB_SIZE_KB);
mmio_resource(dev, 1, lcdbase / KiB, (fb_size + KiB - 1) / KiB);
+ /*
+ * Disable LCD FETs before we do anything with the display.
+ * FIXME(dhendrix): This is a gross hack and should be done
+ * elsewhere (romstage?).
+ */
+ tps65090_thru_ec_fet_disable(1);
+ tps65090_thru_ec_fet_disable(6);
+
exynos_displayport_init(dev, lcdbase, fb_size);
set_cpu_id();
Patrick Georgi (patrick(a)georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4468
-gerrit
commit 4177ee4e44f2c45c60bf448e8c6daf191a5e8823
Author: David Hendricks <dhendrix(a)chromium.org>
Date: Mon Aug 12 13:24:24 2013 -0700
exynos5420: don't assume MPLL for i2c parent clock
This reads the clock select field for MUX_ACLK_66_SEL in the
CLK_SRC_TOP1 register in order to obtain the source clock rate
for I2C peripherals. Before we were always assuming that the source
was the MPLL.
Unfortunately not all fields in the CLK_SRC_TOPn registers are
enumerated the same with regard to clock select. So this is just
a one-off for now.
This is basically ported from https://gerrit.chromium.org/gerrit/#/c/62443.
Signed-off-by: David Hendricks <dhendrix(a)chromium.org>
Change-Id: I9fa85194ae1a1fadab79695f059efdc2e2f1f75f
Reviewed-on: https://gerrit.chromium.org/gerrit/65611
Reviewed-by: Ronald G. Minnich <rminnich(a)chromium.org>
Tested-by: David Hendricks <dhendrix(a)chromium.org>
Commit-Queue: David Hendricks <dhendrix(a)chromium.org>
---
src/cpu/samsung/exynos5420/clock.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/src/cpu/samsung/exynos5420/clock.c b/src/cpu/samsung/exynos5420/clock.c
index 783679a..34d3fb5 100644
--- a/src/cpu/samsung/exynos5420/clock.c
+++ b/src/cpu/samsung/exynos5420/clock.c
@@ -231,7 +231,23 @@ unsigned long clock_get_periph_rate(enum periph_id peripheral)
case PERIPH_ID_I2C8:
case PERIPH_ID_I2C9:
case PERIPH_ID_I2C10:
- sclk = get_pll_clk(MPLL);
+ /*
+ * I2C block parent clock selection is different from other
+ * peripherals, so we handle it all here.
+ * TODO: Add a helper function like with the peripheral clock
+ * select fields?
+ */
+ src = (readl(&clk->clk_src_top1) >> 8) & 0x3;
+ if (src == 0x0)
+ src = CPLL;
+ else if (src == 0x1)
+ src = DPLL;
+ else if (src == 0x2)
+ src = MPLL;
+ else
+ return -1;
+
+ sclk = get_pll_clk(src);
div = ((readl(&clk->clk_div_top1) >> 8) & 0x3f) + 1;
return sclk / div;
default: