summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mainboard/google/nyan/Makefile.inc3
-rw-r--r--src/mainboard/google/nyan/pmic.c14
-rw-r--r--src/mainboard/google/nyan/reset.c29
-rw-r--r--src/mainboard/google/nyan/reset.h25
-rw-r--r--src/mainboard/google/nyan_big/Makefile.inc1
-rw-r--r--src/mainboard/google/nyan_big/pmic.c14
-rw-r--r--src/mainboard/google/nyan_big/reset.c29
-rw-r--r--src/mainboard/google/nyan_big/reset.h25
-rw-r--r--src/mainboard/google/nyan_blaze/Makefile.inc1
-rw-r--r--src/mainboard/google/nyan_blaze/pmic.c14
-rw-r--r--src/mainboard/google/nyan_blaze/reset.c29
-rw-r--r--src/mainboard/google/nyan_blaze/reset.h25
-rw-r--r--src/soc/nvidia/tegra/i2c.c34
-rw-r--r--src/soc/nvidia/tegra/i2c.h17
14 files changed, 247 insertions, 13 deletions
diff --git a/src/mainboard/google/nyan/Makefile.inc b/src/mainboard/google/nyan/Makefile.inc
index 825b33e9d7..30cd27d9fc 100644
--- a/src/mainboard/google/nyan/Makefile.inc
+++ b/src/mainboard/google/nyan/Makefile.inc
@@ -1,7 +1,7 @@
##
## This file is part of the coreboot project.
##
-## Copyright 2013 Google Inc.
+## Copyright 2014 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
@@ -30,6 +30,7 @@ subdirs-y += bct
bootblock-y += boardid.c
bootblock-y += bootblock.c
bootblock-y += pmic.c
+bootblock-y += reset.c
romstage-y += romstage.c
romstage-y += sdram_configs.c
diff --git a/src/mainboard/google/nyan/pmic.c b/src/mainboard/google/nyan/pmic.c
index a6e881d10f..dc5f7447a6 100644
--- a/src/mainboard/google/nyan/pmic.c
+++ b/src/mainboard/google/nyan/pmic.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <console/console.h>
#include <delay.h>
#include <device/i2c.h>
#include <stdint.h>
@@ -25,6 +26,7 @@
#include "boardid.h"
#include "pmic.h"
+#include "reset.h"
enum {
AS3722_I2C_ADDR = 0x40
@@ -59,9 +61,15 @@ static struct as3722_init_reg init_list[] = {
static void pmic_write_reg(unsigned bus, uint8_t reg, uint8_t val, int do_delay)
{
- i2c_writeb(bus, AS3722_I2C_ADDR, reg, val);
- if (do_delay)
- udelay(500);
+ if (i2c_writeb(bus, AS3722_I2C_ADDR, reg, val)) {
+ printk(BIOS_ERR, "%s: reg = 0x%02X, value = 0x%02X failed!\n",
+ __func__, reg, val);
+ /* Reset the SoC on any PMIC write error */
+ cpu_reset();
+ } else {
+ if (do_delay)
+ udelay(500);
+ }
}
static void pmic_slam_defaults(unsigned bus)
diff --git a/src/mainboard/google/nyan/reset.c b/src/mainboard/google/nyan/reset.c
new file mode 100644
index 0000000000..7f1fff922a
--- /dev/null
+++ b/src/mainboard/google/nyan/reset.c
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 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 <arch/io.h>
+#include <soc/nvidia/tegra124/gpio.h>
+
+#include "reset.h"
+
+void cpu_reset(void)
+{
+ gpio_output(GPIO(I5), 0);
+ while(1);
+}
diff --git a/src/mainboard/google/nyan/reset.h b/src/mainboard/google/nyan/reset.h
new file mode 100644
index 0000000000..debe83818b
--- /dev/null
+++ b/src/mainboard/google/nyan/reset.h
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 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
+ */
+
+#ifndef __MAINBOARD_GOOGLE_NYAN_BOOTBLOCK_H__
+#define __MAINBOARD_GOOGLE_NYAN_BOOTBLOCK_H__
+
+void cpu_reset(void);
+
+#endif /* __MAINBOARD_GOOGLE_NYAN_BOOTBLOCK_H__ */
diff --git a/src/mainboard/google/nyan_big/Makefile.inc b/src/mainboard/google/nyan_big/Makefile.inc
index 9cdff3b9b0..30cd27d9fc 100644
--- a/src/mainboard/google/nyan_big/Makefile.inc
+++ b/src/mainboard/google/nyan_big/Makefile.inc
@@ -30,6 +30,7 @@ subdirs-y += bct
bootblock-y += boardid.c
bootblock-y += bootblock.c
bootblock-y += pmic.c
+bootblock-y += reset.c
romstage-y += romstage.c
romstage-y += sdram_configs.c
diff --git a/src/mainboard/google/nyan_big/pmic.c b/src/mainboard/google/nyan_big/pmic.c
index 6bbff0da8b..4d52f7072c 100644
--- a/src/mainboard/google/nyan_big/pmic.c
+++ b/src/mainboard/google/nyan_big/pmic.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <console/console.h>
#include <delay.h>
#include <device/i2c.h>
#include <stdint.h>
@@ -25,6 +26,7 @@
#include "boardid.h"
#include "pmic.h"
+#include "reset.h"
enum {
AS3722_I2C_ADDR = 0x40
@@ -59,9 +61,15 @@ static struct as3722_init_reg init_list[] = {
static void pmic_write_reg(unsigned bus, uint8_t reg, uint8_t val, int do_delay)
{
- i2c_writeb(bus, AS3722_I2C_ADDR, reg, val);
- if (do_delay)
- udelay(500);
+ if (i2c_writeb(bus, AS3722_I2C_ADDR, reg, val)) {
+ printk(BIOS_ERR, "%s: reg = 0x%02X, value = 0x%02X failed!\n",
+ __func__, reg, val);
+ /* Reset the SoC on any PMIC write error */
+ cpu_reset();
+ } else {
+ if (do_delay)
+ udelay(500);
+ }
}
static void pmic_slam_defaults(unsigned bus)
diff --git a/src/mainboard/google/nyan_big/reset.c b/src/mainboard/google/nyan_big/reset.c
new file mode 100644
index 0000000000..7f1fff922a
--- /dev/null
+++ b/src/mainboard/google/nyan_big/reset.c
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 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 <arch/io.h>
+#include <soc/nvidia/tegra124/gpio.h>
+
+#include "reset.h"
+
+void cpu_reset(void)
+{
+ gpio_output(GPIO(I5), 0);
+ while(1);
+}
diff --git a/src/mainboard/google/nyan_big/reset.h b/src/mainboard/google/nyan_big/reset.h
new file mode 100644
index 0000000000..debe83818b
--- /dev/null
+++ b/src/mainboard/google/nyan_big/reset.h
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 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
+ */
+
+#ifndef __MAINBOARD_GOOGLE_NYAN_BOOTBLOCK_H__
+#define __MAINBOARD_GOOGLE_NYAN_BOOTBLOCK_H__
+
+void cpu_reset(void);
+
+#endif /* __MAINBOARD_GOOGLE_NYAN_BOOTBLOCK_H__ */
diff --git a/src/mainboard/google/nyan_blaze/Makefile.inc b/src/mainboard/google/nyan_blaze/Makefile.inc
index 9cdff3b9b0..30cd27d9fc 100644
--- a/src/mainboard/google/nyan_blaze/Makefile.inc
+++ b/src/mainboard/google/nyan_blaze/Makefile.inc
@@ -30,6 +30,7 @@ subdirs-y += bct
bootblock-y += boardid.c
bootblock-y += bootblock.c
bootblock-y += pmic.c
+bootblock-y += reset.c
romstage-y += romstage.c
romstage-y += sdram_configs.c
diff --git a/src/mainboard/google/nyan_blaze/pmic.c b/src/mainboard/google/nyan_blaze/pmic.c
index 6bbff0da8b..4d52f7072c 100644
--- a/src/mainboard/google/nyan_blaze/pmic.c
+++ b/src/mainboard/google/nyan_blaze/pmic.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <console/console.h>
#include <delay.h>
#include <device/i2c.h>
#include <stdint.h>
@@ -25,6 +26,7 @@
#include "boardid.h"
#include "pmic.h"
+#include "reset.h"
enum {
AS3722_I2C_ADDR = 0x40
@@ -59,9 +61,15 @@ static struct as3722_init_reg init_list[] = {
static void pmic_write_reg(unsigned bus, uint8_t reg, uint8_t val, int do_delay)
{
- i2c_writeb(bus, AS3722_I2C_ADDR, reg, val);
- if (do_delay)
- udelay(500);
+ if (i2c_writeb(bus, AS3722_I2C_ADDR, reg, val)) {
+ printk(BIOS_ERR, "%s: reg = 0x%02X, value = 0x%02X failed!\n",
+ __func__, reg, val);
+ /* Reset the SoC on any PMIC write error */
+ cpu_reset();
+ } else {
+ if (do_delay)
+ udelay(500);
+ }
}
static void pmic_slam_defaults(unsigned bus)
diff --git a/src/mainboard/google/nyan_blaze/reset.c b/src/mainboard/google/nyan_blaze/reset.c
new file mode 100644
index 0000000000..7f1fff922a
--- /dev/null
+++ b/src/mainboard/google/nyan_blaze/reset.c
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 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 <arch/io.h>
+#include <soc/nvidia/tegra124/gpio.h>
+
+#include "reset.h"
+
+void cpu_reset(void)
+{
+ gpio_output(GPIO(I5), 0);
+ while(1);
+}
diff --git a/src/mainboard/google/nyan_blaze/reset.h b/src/mainboard/google/nyan_blaze/reset.h
new file mode 100644
index 0000000000..debe83818b
--- /dev/null
+++ b/src/mainboard/google/nyan_blaze/reset.h
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 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
+ */
+
+#ifndef __MAINBOARD_GOOGLE_NYAN_BOOTBLOCK_H__
+#define __MAINBOARD_GOOGLE_NYAN_BOOTBLOCK_H__
+
+void cpu_reset(void);
+
+#endif /* __MAINBOARD_GOOGLE_NYAN_BOOTBLOCK_H__ */
diff --git a/src/soc/nvidia/tegra/i2c.c b/src/soc/nvidia/tegra/i2c.c
index 9a4d71bc3c..6c269cfaed 100644
--- a/src/soc/nvidia/tegra/i2c.c
+++ b/src/soc/nvidia/tegra/i2c.c
@@ -23,9 +23,36 @@
#include <stdlib.h>
#include <string.h>
#include <soc/addressmap.h>
-
#include "i2c.h"
+static void do_bus_clear(int bus)
+{
+ struct tegra_i2c_bus_info *info = &tegra_i2c_info[bus];
+ struct tegra_i2c_regs * const regs = info->base;
+ uint32_t bc;
+
+ // BUS CLEAR regs (from TRM):
+ // 1. Reset the I2C controller (already done)
+ // 2. Set the # of clock pulses required (using default of 9)
+ // 3. Select STOP condition (using default of 1 = STOP)
+ // 4. Set TERMINATE condition (1 = THRESHOLD)
+ bc = read32(&regs->bus_clear_config);
+ bc |= I2C_BUS_CLEAR_CONFIG_BC_TERMINATE_THRESHOLD;
+ write32(bc, &regs->bus_clear_config);
+ // 4.1 Set MSTR_CONFIG_LOAD and wait for clear
+ write32(I2C_CONFIG_LOAD_MSTR_CONFIG_LOAD_ENABLE, &regs->config_load);
+ do {
+ printk(BIOS_DEBUG, "%s: wait for MSTR_CONFIG_LOAD to clear\n",
+ __func__);
+ } while (read32(&regs->config_load) & I2C_CONFIG_LOAD_MSTR_CONFIG_LOAD_ENABLE);
+ // 5. Set ENABLE to start the bus clear op
+ write32(bc | I2C_BUS_CLEAR_CONFIG_BC_ENABLE, &regs->bus_clear_config);
+ do {
+ printk(BIOS_DEBUG, "%s: wait for bus clear completion\n",
+ __func__);
+ } while (read32(&regs->bus_clear_config) & I2C_BUS_CLEAR_CONFIG_BC_ENABLE);
+}
+
static int tegra_i2c_send_recv(int bus, int read,
uint32_t *headers, int header_words,
uint8_t *data, int data_len)
@@ -91,6 +118,11 @@ static int tegra_i2c_send_recv(int bus, int read,
"%s: Lost arbitration.\n",
__func__);
info->reset_func(info->reset_bit);
+
+ /* Use Tegra bus clear registers to unlock SDA */
+ do_bus_clear(bus);
+
+ /* Return w/error, let caller decide what to do */
return -1;
}
}
diff --git a/src/soc/nvidia/tegra/i2c.h b/src/soc/nvidia/tegra/i2c.h
index 03a6d66e1f..6347fff8ad 100644
--- a/src/soc/nvidia/tegra/i2c.h
+++ b/src/soc/nvidia/tegra/i2c.h
@@ -110,6 +110,19 @@ enum {
0xf << I2C_FIFO_STATUS_RX_FIFO_FULL_CNT_SHIFT
};
+enum {
+ I2C_BUS_CLEAR_CONFIG_BC_SCLK_THRESHOLD_SHIFT = 16,
+ I2C_BUS_CLEAR_CONFIG_BC_SCLK_THRESHOLD_MASK =
+ 0x7f << I2C_BUS_CLEAR_CONFIG_BC_SCLK_THRESHOLD_SHIFT,
+ I2C_BUS_CLEAR_CONFIG_BC_STOP_COND_STOP = 0x1 << 2,
+ I2C_BUS_CLEAR_CONFIG_BC_TERMINATE_THRESHOLD = 0x1 << 1,
+ I2C_BUS_CLEAR_CONFIG_BC_ENABLE = 0x1 << 0,
+
+ I2C_BUS_CLEAR_STATUS_CLEARED = 0x1 << 0,
+
+ I2C_CONFIG_LOAD_MSTR_CONFIG_LOAD_ENABLE = 0x1 << 0
+};
+
struct tegra_i2c_bus_info {
void *base;
uint32_t reset_bit;
@@ -153,8 +166,8 @@ struct tegra_i2c_regs {
uint32_t slv_packet_status;
uint32_t bus_clear_config;
uint32_t bus_clear_status;
- uint32_t spare;
+ uint32_t config_load;
};
-check_member(tegra_i2c_regs, bus_clear_status, 0x88);
+check_member(tegra_i2c_regs, config_load, 0x8C);
#endif /* __SOC_NVIDIA_TEGRA_I2C_H__ */