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 1316d6defb4bb3a4494bf87e7e600de724767436
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/3706
-gerrit
commit 47bcf7ad31b87b5d22770acb325ea8a82a000c7d
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/3707
-gerrit
commit b0da504fdd2b97c6ef8be9910d6921fb1ee48742
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/3722
-gerrit
commit c04507b91dd792abb8749c9acca5673e425f0646
Author: Gabe Black <gabeblack(a)google.com>
Date: Sun Jun 30 06:09:12 2013 -0700
pit: Enable the ps8625 driver.
Change-Id: Id1277ceefc844a052627483e6c9d01bcb5da975f
Signed-off-by: Gabe Black <gabeblack(a)chromium.org>
---
src/mainboard/google/pit/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/mainboard/google/pit/Kconfig b/src/mainboard/google/pit/Kconfig
index 20e0084..89ffb5b 100644
--- a/src/mainboard/google/pit/Kconfig
+++ b/src/mainboard/google/pit/Kconfig
@@ -31,6 +31,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select MAINBOARD_HAS_NATIVE_VGA_INIT
select MAINBOARD_DO_NATIVE_VGA_INIT
select HAVE_INIT_TIMER
+ select DRIVER_PARADE_PS8625
config MAINBOARD_DIR
string
Gabe Black (gabeblack(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3723
-gerrit
commit 7dacce455e4e8d395eeefae88bfd5872b8313627
Author: Gabe Black <gabeblack(a)google.com>
Date: Sun Jun 30 05:19:53 2013 -0700
pit: Redo the display port bridge initialization code.
The display port bridge on pit is different from the one on snow and needs to
be initialized differently. Instead of waiting for the chip to come up on its
own and assert the hotplug detect, we need to access it over i2c and get it up
and running ourselves.
Change-Id: I4bc911cb8e4463edff7beabd2f356cb70ae9f507
Signed-off-by: Gabe Black <gabeblack(a)chromium.org>
---
src/mainboard/google/pit/mainboard.c | 71 +++++++++---------------------------
1 file changed, 17 insertions(+), 54 deletions(-)
diff --git a/src/mainboard/google/pit/mainboard.c b/src/mainboard/google/pit/mainboard.c
index 67d3b5d..54ea042 100644
--- a/src/mainboard/google/pit/mainboard.c
+++ b/src/mainboard/google/pit/mainboard.c
@@ -34,7 +34,9 @@
#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"
@@ -56,7 +58,7 @@ 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 exynos_dp_bridge_setup(void)
+static void parade_dp_bridge_setup(void)
{
gpio_set_value(dp_pd_l, 1);
gpio_cfg_pin(dp_pd_l, GPIO_OUTPUT);
@@ -69,37 +71,19 @@ static void exynos_dp_bridge_setup(void)
gpio_set_value(dp_rst_l, 1);
gpio_cfg_pin(dp_hpd, GPIO_INPUT);
-}
-static void exynos_dp_bridge_init(void)
-{
- /* De-assert PD (and possibly RST) to power up the bridge */
+ /* 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);
-}
+ /* Hang around for the bridge to come up. */
+ mdelay(40);
-static int exynos_dp_hotplug(void)
-{
- /* Check HPD. If it's high, we're all good. */
- return gpio_get_value(dp_hpd) ? 0 : 1;
-}
+ /* Configure the bridge chip. */
+ exynos_pinmux_i2c7();
+ i2c_init(7, 100000, 0x00);
-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);
+ parade_ps8625_bridge_setup(7, 0x48);
}
/*
@@ -203,7 +187,6 @@ static void backlight_vdd(void)
/* 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,
@@ -225,34 +208,14 @@ static void mainboard_init(device_t dev)
lcd_vdd();
- // FIXME: should timeout
- 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()) {
- printk(BIOS_ERR, "Hotplug detect failed.\n");
- 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;
- }
+ parade_dp_bridge_setup();
+ dp_controller_init(&dp_device);
+
+ udelay(LCD_T3_DELAY_MS * 1000);
- if (dp_tries > MAX_DP_TRIES)
- printk(BIOS_ERR, "%s: Failed to set up displayport\n", __func__);
+ backlight_vdd();
+ backlight_pwm();
+ backlight_en();
// Uncomment to get excessive GPIO output:
// gpio_info();