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 2002c41d13d616d2ef22a5f8e07a31b3312cf4fb
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/3699
-gerrit
commit 25aab46e3fdf2c2c683ae36cc79ff148ae251567
Author: Gabe Black <gabeblack(a)google.com>
Date: Sat Jun 22 19:43:40 2013 -0700
exynos5420: Fix the way the rate of the input clock for i2c buses is found.
The clock divider was being read from registers incorrectly which meant that
the periph rate was wrong.
Change-Id: I50efb62849ef29bdfb0efc56c49642d3edca094c
Signed-off-by: Gabe Black <gabeblack(a)chromium.org>
---
src/cpu/samsung/exynos5420/clock.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/cpu/samsung/exynos5420/clock.c b/src/cpu/samsung/exynos5420/clock.c
index e5ab001..8c4baf8 100644
--- a/src/cpu/samsung/exynos5420/clock.c
+++ b/src/cpu/samsung/exynos5420/clock.c
@@ -196,9 +196,8 @@ unsigned long clock_get_periph_rate(enum periph_id peripheral)
case PERIPH_ID_I2C9:
case PERIPH_ID_I2C10:
sclk = get_pll_clk(MPLL);
- sub_div = ((readl(&clk->clk_div_top1) >> 24) & 0x7) + 1;
- div = (readl(&clk->clk_div_top0) & 0x7) + 1;
- return (sclk / sub_div) / div;
+ div = ((readl(&clk->clk_div_top1) >> 8) & 0x3f) + 1;
+ return sclk / div;
default:
printk(BIOS_DEBUG, "%s: invalid peripheral %d", __func__, peripheral);
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/3704
-gerrit
commit 2fe23decc3039c1fc496576d881f041945eb7d82
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;
}