Gabe Black (gabeblack(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3707
-gerrit
commit f755ff58db0ed3afc985678de09ba3911e655602
Author: Hung-Te Lin <hungte(a)chromium.org>
Date: Mon Jun 24 20:02:01 2013 +0800
armv7/pit: Setup EC on SPI2.
The Embedded Controller (EC) for Pit is connected via SPI2, and needs to be
configured before we can talk to it.
Change-Id: I1f8e921b4616f15951f3e5fae1ecbf116de4ba90
Signed-off-by: Hung-Te Lin <hungte(a)chromium.org>
Signed-off-by: Gabe Black <gabeblack(a)chromium.org>
---
src/mainboard/google/pit/romstage.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/mainboard/google/pit/romstage.c b/src/mainboard/google/pit/romstage.c
index 41b64b2..7ba66a4 100644
--- a/src/mainboard/google/pit/romstage.c
+++ b/src/mainboard/google/pit/romstage.c
@@ -122,6 +122,14 @@ static void setup_storage(void)
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, 500000);
+ exynos_pinmux_spi2();
+}
+
static void setup_graphics(void)
{
exynos_pinmux_dphpd();
@@ -271,6 +279,7 @@ void main(void)
setup_storage();
setup_gpio();
setup_graphics();
+ setup_ec();
simple_spi_test();
/* Set SPI (primary CBFS media) clock to 50MHz. */
Gabe Black (gabeblack(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3706
-gerrit
commit a619a3a4c9cc9216fdcbe76be9da4dcaba95cab6
Author: Hung-Te Lin <hungte(a)chromium.org>
Date: Sun Jun 23 08:14:30 2013 +0800
arm/exynos: Correct SPI session commands.
Some initialization / shutdown commands should be paired correctly in a SPI I/O
session. For example, setting CS should be enabled and disabled in each read;
and the bus width (byte or word) should be configured only when opening /
closing the SPI device.
Change-Id: Ie56b1c3a6df7d542f7ea8f1193ac435987f937ba
Signed-off-by: Hung-Te Lin <hungte(a)chromium.org>
Signed-off-by: Gabe Black <gabeblack(a)chromium.org>
---
src/cpu/samsung/exynos5250/spi.c | 13 +++++++------
src/cpu/samsung/exynos5420/spi.c | 13 +++++++------
2 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/src/cpu/samsung/exynos5250/spi.c b/src/cpu/samsung/exynos5250/spi.c
index 503cee9..642ae23 100644
--- a/src/cpu/samsung/exynos5250/spi.c
+++ b/src/cpu/samsung/exynos5250/spi.c
@@ -102,7 +102,6 @@ int exynos_spi_open(struct exynos_spi *regs)
/* now set rx and tx channel ON */
setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
- clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
return 0;
}
@@ -110,6 +109,8 @@ int exynos_spi_read(struct exynos_spi *regs, void *dest, u32 len, u32 off)
{
int upto, todo;
int i;
+ clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
+
/* Send read instruction (0x3h) followed by a 24 bit addr */
writel((SF_READ_DATA_CMD << 24) | off, ®s->tx_data);
@@ -123,6 +124,11 @@ int exynos_spi_read(struct exynos_spi *regs, void *dest, u32 len, u32 off)
setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT);/* make the CS high */
+ return len;
+}
+
+int exynos_spi_close(struct exynos_spi *regs)
+{
/*
* Let put controller mode to BYTE as
* SPI driver does not support WORD mode yet
@@ -131,11 +137,6 @@ int exynos_spi_read(struct exynos_spi *regs, void *dest, u32 len, u32 off)
SPI_MODE_CH_WIDTH_WORD | SPI_MODE_BUS_WIDTH_WORD);
writel(0, ®s->swap_cfg);
- return len;
-}
-
-int exynos_spi_close(struct exynos_spi *regs)
-{
/*
* Flush spi tx, rx fifos and reset the SPI controller
* and clear rx/tx channel
diff --git a/src/cpu/samsung/exynos5420/spi.c b/src/cpu/samsung/exynos5420/spi.c
index 503cee9..642ae23 100644
--- a/src/cpu/samsung/exynos5420/spi.c
+++ b/src/cpu/samsung/exynos5420/spi.c
@@ -102,7 +102,6 @@ int exynos_spi_open(struct exynos_spi *regs)
/* now set rx and tx channel ON */
setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
- clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
return 0;
}
@@ -110,6 +109,8 @@ int exynos_spi_read(struct exynos_spi *regs, void *dest, u32 len, u32 off)
{
int upto, todo;
int i;
+ clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
+
/* Send read instruction (0x3h) followed by a 24 bit addr */
writel((SF_READ_DATA_CMD << 24) | off, ®s->tx_data);
@@ -123,6 +124,11 @@ int exynos_spi_read(struct exynos_spi *regs, void *dest, u32 len, u32 off)
setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT);/* make the CS high */
+ return len;
+}
+
+int exynos_spi_close(struct exynos_spi *regs)
+{
/*
* Let put controller mode to BYTE as
* SPI driver does not support WORD mode yet
@@ -131,11 +137,6 @@ int exynos_spi_read(struct exynos_spi *regs, void *dest, u32 len, u32 off)
SPI_MODE_CH_WIDTH_WORD | SPI_MODE_BUS_WIDTH_WORD);
writel(0, ®s->swap_cfg);
- return len;
-}
-
-int exynos_spi_close(struct exynos_spi *regs)
-{
/*
* Flush spi tx, rx fifos and reset the SPI controller
* and clear rx/tx channel
Gabe Black (gabeblack(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3704
-gerrit
commit 92a5dd84a3c163147390126e75e2b5cd9b2fbca2
Author: Gabe Black <gabeblack(a)google.com>
Date: Mon Jun 24 03:20:22 2013 -0700
exynos5420: i2c: Fix error handling.
The functions which checked the status of a transfer would return success if
the bus was no longer occupied, even if it's no longer occupied because the
transfer failed. This change modifies those functions to return three possible
values, 0 if the transfer isn't done, -1 if there was a fault, and 1 if the
transaction completed successfully.
Change-Id: Idcc5fdf73cab3c3ece0e96f14113a216db289e05
Signed-off-by: Gabe Black <gabeblack(a)chromium.org>
---
src/cpu/samsung/exynos5420/i2c.c | 55 ++++++++++++++++++++++++++--------------
1 file changed, 36 insertions(+), 19 deletions(-)
diff --git a/src/cpu/samsung/exynos5420/i2c.c b/src/cpu/samsung/exynos5420/i2c.c
index b16d068..acb5bcf 100644
--- a/src/cpu/samsung/exynos5420/i2c.c
+++ b/src/cpu/samsung/exynos5420/i2c.c
@@ -357,23 +357,39 @@ void i2c_init(unsigned bus_num, int speed, int slaveadd)
/*
* Check whether the transfer is complete.
+ * Return values:
+ * 0 - transfer not done
+ * 1 - transfer finished successfully
+ * -1 - transfer failed
*/
static int hsi2c_check_transfer(struct exynos5_hsi2c *i2c)
{
uint32_t status = read32(&i2c->usi_trans_status);
- if (status & HSI2C_TRANS_ABORT)
- printk(BIOS_ERR, "%s: Transaction aborted.\n", __func__);
- if (status & HSI2C_NO_DEV_ACK)
- printk(BIOS_ERR, "%s: No ack from device.\n", __func__);
- if (status & HSI2C_NO_DEV)
- printk(BIOS_ERR, "%s: No response from device.\n", __func__);
- if (status & HSI2C_TIMEOUT_AUTO)
- printk(BIOS_ERR, "%s: Transaction time out.\n", __func__);
- return !!(status & HSI2C_MASTER_BUSY);
+ if (status & (HSI2C_TRANS_ABORT | HSI2C_NO_DEV_ACK |
+ HSI2C_NO_DEV | HSI2C_TIMEOUT_AUTO)) {
+ if (status & HSI2C_TRANS_ABORT)
+ printk(BIOS_ERR,
+ "%s: Transaction aborted.\n", __func__);
+ if (status & HSI2C_NO_DEV_ACK)
+ printk(BIOS_ERR,
+ "%s: No ack from device.\n", __func__);
+ if (status & HSI2C_NO_DEV)
+ printk(BIOS_ERR,
+ "%s: No response from device.\n", __func__);
+ if (status & HSI2C_TIMEOUT_AUTO)
+ printk(BIOS_ERR,
+ "%s: Transaction time out.\n", __func__);
+ return -1;
+ }
+ return !(status & HSI2C_MASTER_BUSY);
}
/*
* Wait for the transfer to finish.
+ * Return values:
+ * 0 - transfer not done
+ * 1 - transfer finished successfully
+ * -1 - transfer failed
*/
static int hsi2c_wait_for_transfer(struct exynos5_hsi2c *i2c)
{
@@ -383,17 +399,18 @@ static int hsi2c_wait_for_transfer(struct exynos5_hsi2c *i2c)
end = current;
mono_time_add_usecs(&end, HSI2C_TIMEOUT * 1000);
while (mono_time_before(¤t, &end)) {
- if (!hsi2c_check_transfer(i2c))
- return 0;
+ int ret = hsi2c_check_transfer(i2c);
+ if (ret)
+ return ret;
udelay(5);
timer_monotonic_get(¤t);
}
- return 1;
+ return 0;
}
static int hsi2c_senddata(struct exynos5_hsi2c *i2c, uint8_t *data, int len)
{
- while (hsi2c_check_transfer(i2c) && len) {
+ while (!hsi2c_check_transfer(i2c) && len) {
if (!(read32(&i2c->usi_fifo_stat) & HSI2C_TX_FIFO_FULL)) {
write32(*data++, &i2c->usi_txdata);
len--;
@@ -404,7 +421,7 @@ static int hsi2c_senddata(struct exynos5_hsi2c *i2c, uint8_t *data, int len)
static int hsi2c_recvdata(struct exynos5_hsi2c *i2c, uint8_t *data, int len)
{
- while (hsi2c_check_transfer(i2c) && len) {
+ while (!hsi2c_check_transfer(i2c) && len) {
if (!(read32(&i2c->usi_fifo_stat) & HSI2C_RX_FIFO_EMPTY)) {
*data++ = read32(&i2c->usi_rxdata);
len--;
@@ -422,7 +439,7 @@ static int hsi2c_write(struct exynos5_hsi2c *i2c,
{
uint32_t i2c_auto_conf;
- if (hsi2c_wait_for_transfer(i2c))
+ if (hsi2c_wait_for_transfer(i2c) != 1)
return -1;
/* chip address */
@@ -441,7 +458,7 @@ static int hsi2c_write(struct exynos5_hsi2c *i2c,
if (hsi2c_senddata(i2c, addr, alen) ||
hsi2c_senddata(i2c, data, len) ||
- hsi2c_wait_for_transfer(i2c)) {
+ hsi2c_wait_for_transfer(i2c) != 1) {
return -1;
}
@@ -460,7 +477,7 @@ static int hsi2c_read(struct exynos5_hsi2c *i2c,
uint32_t i2c_auto_conf;
/* start read */
- if (hsi2c_wait_for_transfer(i2c))
+ if (hsi2c_wait_for_transfer(i2c) != 1)
return -1;
/* chip address */
@@ -475,7 +492,7 @@ static int hsi2c_read(struct exynos5_hsi2c *i2c,
&i2c->usi_auto_conf);
if (hsi2c_senddata(i2c, addr, alen) ||
- hsi2c_wait_for_transfer(i2c)) {
+ hsi2c_wait_for_transfer(i2c) != 1) {
return -1;
}
@@ -490,7 +507,7 @@ static int hsi2c_read(struct exynos5_hsi2c *i2c,
write32(i2c_auto_conf, &i2c->usi_auto_conf);
if (hsi2c_recvdata(i2c, data, len) ||
- hsi2c_wait_for_transfer(i2c)) {
+ hsi2c_wait_for_transfer(i2c) != 1) {
return -1;
}
Gabe Black (gabeblack(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3703
-gerrit
commit dc097d6fe319c58d68de65aa6e252675098ac418
Author: Gabe Black <gabeblack(a)google.com>
Date: Mon Jun 24 03:14:41 2013 -0700
exynos5420: Clock the mmc blocks off of the mpll.
The exynos manual suggests hooking the mmc ip blocks to the mpll. They had
been set to use a different pll. This changes them over and modifies the
divider so that the frequency stays the same.
Change-Id: I85103388d6cc2c63d1ca004654fc08fcc8929962
Signed-off-by: Gabe Black <gabeblack(a)chromium.org>
---
src/cpu/samsung/exynos5420/setup.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/cpu/samsung/exynos5420/setup.h b/src/cpu/samsung/exynos5420/setup.h
index 7d63772..e89ed8e 100644
--- a/src/cpu/samsung/exynos5420/setup.h
+++ b/src/cpu/samsung/exynos5420/setup.h
@@ -222,7 +222,7 @@ struct exynos5_phy_control;
#define CLK_DIV_CPU0_VAL 0x01440020
/* CLK_SRC_TOP */
-#define CLK_SRC_TOP0_VAL 0x12221222
+#define CLK_SRC_TOP0_VAL 0x12222222
#define CLK_SRC_TOP1_VAL 0x00100200
#define CLK_SRC_TOP2_VAL 0x11101000
#define CLK_SRC_TOP3_VAL 0x11111111
@@ -231,7 +231,7 @@ struct exynos5_phy_control;
#define CLK_SRC_TOP7_VAL 0x00022200
/* CLK_DIV_TOP */
-#define CLK_DIV_TOP0_VAL 0x23712311
+#define CLK_DIV_TOP0_VAL 0x23713311
#define CLK_DIV_TOP1_VAL 0x13100B00
#define CLK_DIV_TOP2_VAL 0x11101100
Gabe Black (gabeblack(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3702
-gerrit
commit ef19e8015dea86043511e1788ba2468e155826ef
Author: Gabe Black <gabeblack(a)google.com>
Date: Sun Jun 23 03:16:46 2013 -0700
pit: Configure the pinmux for the i2c busses that are connected on pit.
Change-Id: I2dc4caa370473dd86fee2b5cc8b1b9eb154b970e
Signed-off-by: Gabe Black <gabeblack(a)chromium.org>
---
src/mainboard/google/pit/mainboard.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/mainboard/google/pit/mainboard.c b/src/mainboard/google/pit/mainboard.c
index 1608788..64783ad 100644
--- a/src/mainboard/google/pit/mainboard.c
+++ b/src/mainboard/google/pit/mainboard.c
@@ -159,6 +159,17 @@ static void disable_usb30_pll(void)
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();
+}
+
/* this happens after cpu_init where exynos resources are set */
static void mainboard_init(device_t dev)
{
@@ -169,6 +180,8 @@ static void mainboard_init(device_t dev)
};
void *fb_addr;
+ gpio_init();
+
tmu_init(&exynos5420_tmu_info);
/* Clock Gating all the unused IP's to save power */