the following patch was just integrated into master:
commit cd4c8c1e0e9049b264bdbe62e9f2192dee8c3d31
Author: David Hendricks <dhendrix(a)chromium.org>
Date: Fri Apr 12 16:02:44 2013 -0700
exynos5/snow: remove wait_ms arg from dp_controller_init()
This removes the wait_ms argument from the dp_controller_init(). The
only delay involved is a constant 60ms delay that happens if
everything else goes well. This delay is derived from the LCD spec
so there's no reason it should be baked into the controller code.
(This patch also has the side-effect of fixing a bug where we were
delaying on an undefined value for wait_ms).
Change-Id: I03aa19f2ac2f720524fcb7c795e10cc57f0a226e
Signed-off-by: David Hendricks <dhendrix(a)chromium.org>
Reviewed-on: http://review.coreboot.org/3078
Reviewed-by: Gabe Black <gabeblack(a)chromium.org>
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich(a)gmail.com>
Build-Tested: build bot (Jenkins) at Sat Apr 13 03:37:24 2013, giving +1
Reviewed-By: Ronald G. Minnich <rminnich(a)gmail.com> at Sat Apr 13 05:12:18 2013, giving +2
See http://review.coreboot.org/3078 for details.
-gerrit
David Hendricks (dhendrix(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3079
-gerrit
commit b88fe21f723f8c3d192b383e7ddc9e6d57cfb9e9
Author: David Hendricks <dhendrix(a)chromium.org>
Date: Fri Apr 12 15:11:05 2013 -0700
armv7/exynos5250: Deprecate sdelay in favor of udelay
This gets rid of the clock-tick based sdelay in favor of udelay().
udelay() is more consistent and easier to work with, and this allows
us to carry one less variation of timers (and headers and sources...).
Every 1 unit in the sdelay() argument was assumed to cause a delay of
2 clock ticks (@1.7GHz). So the conversion factor is roughly:
sdelay(N) = udelay(((N * 2) / 1.7 * 10^9) * 10^6)
= udelay((N * 2) / (1.7 * 10^3))
The sdelay() periods used were:
sdelay(100) --> udelay(1)
sdelay(0x10000) --> udelay(78) (rounded up to udelay(100))
There was one instance of sdelay(10000), which looked like sort of a
typo since sdelay(0x10000) was used elsewhere. sdelay(10000) should
approximate to about 12us, so we'll stick with that for now and leave
a note.
Change-Id: I5e7407865ceafa701eea1d613bbe50cf4734f33e
Signed-off-by: David Hendricks <dhendrix(a)chromium.org>
---
src/arch/armv7/bootblock.inc | 2 --
src/arch/armv7/include/system.h | 26 --------------------
src/arch/armv7/lib/Makefile.inc | 1 -
src/arch/armv7/lib/syslib.c | 39 ------------------------------
src/cpu/samsung/exynos5250/clock_init.c | 1 -
src/cpu/samsung/exynos5250/dmc_common.c | 23 +++++++++++-------
src/cpu/samsung/exynos5250/dmc_init_ddr3.c | 7 ++++--
7 files changed, 19 insertions(+), 80 deletions(-)
diff --git a/src/arch/armv7/bootblock.inc b/src/arch/armv7/bootblock.inc
index 8db31b4..bac32e2 100644
--- a/src/arch/armv7/bootblock.inc
+++ b/src/arch/armv7/bootblock.inc
@@ -29,8 +29,6 @@
* MA 02111-1307 USA
*/
-#include <system.h>
-
.section ".bl1", "a", %progbits
_bl1:
/* For now we have to live with a first stage boot loader
diff --git a/src/arch/armv7/include/system.h b/src/arch/armv7/include/system.h
deleted file mode 100644
index 0643852..0000000
--- a/src/arch/armv7/include/system.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* FIXME(dhendrix): This is split out from asm/system.h. */
-#ifndef SYSTEM_H_
-#define SYSTEM_H_
-
-/*
- * This is used to ensure the compiler did actually allocate the register we
- * asked it for some inline assembly sequences. Apparently we can't trust
- * the compiler from one version to another so a bit of paranoia won't hurt.
- * This string is meant to be concatenated with the inline asm string and
- * will cause compilation to stop on mismatch.
- * (for details, see gcc PR 15089)
- */
-#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
-
-#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
-
-#define arch_align_stack(x) (x)
-
-#ifndef __ASSEMBLER__
- /*
- * FIXME: sdelay originally came from arch/arm/cpu/armv7/exynos5/setup.h in
- * u-boot but does not seem specific to exynos5...
- */
-void sdelay(unsigned long loops);
-#endif // __ASSEMBLY__
-#endif /* SYSTEM_H_ */
diff --git a/src/arch/armv7/lib/Makefile.inc b/src/arch/armv7/lib/Makefile.inc
index 0cb5737..b10c1ab 100644
--- a/src/arch/armv7/lib/Makefile.inc
+++ b/src/arch/armv7/lib/Makefile.inc
@@ -5,7 +5,6 @@ bootblock-y += cache.c
romstage-y += cache.c
romstage-y += div0.c
-romstage-y += syslib.c
romstage-$(CONFIG_EARLY_CONSOLE) += early_console.c
ramstage-y += div0.c
diff --git a/src/arch/armv7/lib/syslib.c b/src/arch/armv7/lib/syslib.c
deleted file mode 100644
index a6ed080..0000000
--- a/src/arch/armv7/lib/syslib.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * (C) Copyright 2008
- * Texas Instruments, <www.ti.com>
- *
- * Richard Woodruff <r-woodruff2(a)ti.com>
- * Syed Mohammed Khasim <khasim(a)ti.com>
- *
- * 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; either version 2 of
- * the License, or (at your option) any later version.
- *
- * 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., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <arch/io.h>
-#include <system.h> /* FIXME: dumping ground for prototypes */
-
-/************************************************************
- * sdelay() - simple spin loop. Will be constant time as
- * its generally used in bypass conditions only. This
- * is necessary until timers are accessible.
- *
- * not inline to increase chances its in cache when called
- *************************************************************/
-void sdelay(unsigned long loops)
-{
- __asm__ volatile ("1:\n" "subs %0, %1, #1\n"
- "bne 1b":"=r" (loops):"0"(loops));
-}
-
diff --git a/src/cpu/samsung/exynos5250/clock_init.c b/src/cpu/samsung/exynos5250/clock_init.c
index c8479de..c94cadf 100644
--- a/src/cpu/samsung/exynos5250/clock_init.c
+++ b/src/cpu/samsung/exynos5250/clock_init.c
@@ -25,7 +25,6 @@
#include <delay.h>
#include <stdlib.h>
#include <types.h>
-#include <system.h>
#include <console/console.h>
diff --git a/src/cpu/samsung/exynos5250/dmc_common.c b/src/cpu/samsung/exynos5250/dmc_common.c
index 8c4b583..bcfc9fe 100644
--- a/src/cpu/samsung/exynos5250/dmc_common.c
+++ b/src/cpu/samsung/exynos5250/dmc_common.c
@@ -24,12 +24,11 @@
#include <arch/io.h>
#include <assert.h>
-#include <common.h>
+#include <delay.h>
#include <console/console.h>
#include <cpu/samsung/exynos5250/setup.h>
#include <cpu/samsung/exynos5250/dmc.h>
#include <cpu/samsung/exynos5250/clock_init.h>
-#include <system.h>
#include "clock_init.h"
#include "setup.h"
@@ -75,7 +74,7 @@ int dmc_config_zq(struct mem_timings *mem,
*/
i = ZQ_INIT_TIMEOUT;
while ((readl(&phy0_ctrl->phy_con17) & ZQ_DONE) != ZQ_DONE && i > 0) {
- sdelay(100);
+ udelay(1);
i--;
}
if (!i)
@@ -84,7 +83,7 @@ int dmc_config_zq(struct mem_timings *mem,
i = ZQ_INIT_TIMEOUT;
while ((readl(&phy1_ctrl->phy_con17) & ZQ_DONE) != ZQ_DONE && i > 0) {
- sdelay(100);
+ udelay(1);
i--;
}
if (!i)
@@ -135,21 +134,27 @@ void dmc_config_mrs(struct mem_timings *mem, struct exynos5_dmc *dmc)
* delays? This one and the next were not there for
* DDR3.
*/
- sdelay(0x10000);
+ udelay(100);
/* Sending EMRS/MRS commands */
for (i = 0; i < MEM_TIMINGS_MSR_COUNT; i++) {
writel(mem->direct_cmd_msr[i] | mask,
&dmc->directcmd);
- sdelay(0x10000);
+ udelay(100);
}
if (mem->send_zq_init) {
/* Sending ZQINIT command */
writel(DIRECT_CMD_ZQINIT | mask,
&dmc->directcmd);
-
- sdelay(10000);
+ /*
+ * FIXME: This was originally sdelay(10000)
+ * in the imported u-boot code. That may have
+ * been meant to be sdelay(0x10000) since that
+ * was used elsewhere in this function. Either
+ * way seems to work, though.
+ */
+ udelay(12);
}
}
}
@@ -168,7 +173,7 @@ void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc)
/* PALL (all banks precharge) CMD */
writel(DIRECT_CMD_PALL | mask, &dmc->directcmd);
- sdelay(0x10000);
+ udelay(100);
}
}
}
diff --git a/src/cpu/samsung/exynos5250/dmc_init_ddr3.c b/src/cpu/samsung/exynos5250/dmc_init_ddr3.c
index 9a4ead0..5bb8a37 100644
--- a/src/cpu/samsung/exynos5250/dmc_init_ddr3.c
+++ b/src/cpu/samsung/exynos5250/dmc_init_ddr3.c
@@ -23,12 +23,12 @@
*/
#include <config.h>
+#include <delay.h>
#include <arch/io.h>
#include <console/console.h>
//#include "clock.h"
/* FIXME(dhendrix): untangle clock/clk ... */
#include <cpu/samsung/exynos5-common/clock.h>
-#include <system.h>
#include "clk.h"
#include "cpu.h"
#include "dmc.h"
@@ -44,6 +44,7 @@ static void reset_phy_ctrl(void)
writel(LPDDR3PHY_CTRL_PHY_RESET_OFF, &clk->lpddr3phy_ctrl);
writel(LPDDR3PHY_CTRL_PHY_RESET, &clk->lpddr3phy_ctrl);
+#if 0
/*
* For proper memory initialization there should be a minimum delay of
* 500us after the LPDDR3PHY_CTRL_PHY_RESET signal.
@@ -56,6 +57,8 @@ static void reset_phy_ctrl(void)
* TODO(hatim.rv(a)samsung.com): Implement the delay using timer/counter
*/
sdelay(425000);
+#endif
+ udelay(500);
}
int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size)
@@ -236,7 +239,7 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size)
* TODO(waihong): Comment on how long this take to
* timeout
*/
- sdelay(100);
+ udelay(1);
i--;
}
if (!i){
David Hendricks (dhendrix(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3078
-gerrit
commit 6a055d2d3c13dabb1a1f33dbb099230d2290e74d
Author: David Hendricks <dhendrix(a)chromium.org>
Date: Fri Apr 12 16:02:44 2013 -0700
exynos5/snow: remove wait_ms arg from dp_controller_init()
This removes the wait_ms argument from the dp_controller_init(). The
only delay involved is a constant 60ms delay that happens if
everything else goes well. This delay is derived from the LCD spec
so there's no reason it should be baked into the controller code.
(This patch also has the side-effect of fixing a bug where we were
delaying on an undefined value for wait_ms).
Change-Id: I03aa19f2ac2f720524fcb7c795e10cc57f0a226e
Signed-off-by: David Hendricks <dhendrix(a)chromium.org>
---
src/cpu/samsung/exynos5-common/exynos-fb.c | 11 +----------
src/cpu/samsung/exynos5-common/s5p-dp-core.h | 2 +-
src/mainboard/google/snow/ramstage.c | 20 +++++++++++++-------
3 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/src/cpu/samsung/exynos5-common/exynos-fb.c b/src/cpu/samsung/exynos5-common/exynos-fb.c
index b57e276..11d666b 100644
--- a/src/cpu/samsung/exynos5-common/exynos-fb.c
+++ b/src/cpu/samsung/exynos5-common/exynos-fb.c
@@ -505,7 +505,7 @@ static int s5p_dp_hw_link_training(struct s5p_dp_device *dp,
/*
* Initialize DP display
*/
-int dp_controller_init(struct s5p_dp_device *dp_device, unsigned *wait_ms)
+int dp_controller_init(struct s5p_dp_device *dp_device)
{
int ret;
struct s5p_dp_device *dp = dp_device;
@@ -561,15 +561,6 @@ int dp_controller_init(struct s5p_dp_device *dp_device, unsigned *wait_ms)
return ret;
}
- /*
- * 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.
- */
- *wait_ms = 60;
return 0;
}
diff --git a/src/cpu/samsung/exynos5-common/s5p-dp-core.h b/src/cpu/samsung/exynos5-common/s5p-dp-core.h
index 2988d5d..4df848d 100644
--- a/src/cpu/samsung/exynos5-common/s5p-dp-core.h
+++ b/src/cpu/samsung/exynos5-common/s5p-dp-core.h
@@ -252,6 +252,6 @@ void s5p_dp_wait_hw_link_training_done(struct s5p_dp_device *dp);
/* startup and init */
struct exynos5_fimd_panel;
void fb_init(vidinfo_t *panel_info, void *lcdbase, struct exynos5_fimd_panel *pd);
-int dp_controller_init(struct s5p_dp_device *dp_device, unsigned *wait_ms);
+int dp_controller_init(struct s5p_dp_device *dp_device);
int lcd_ctrl_init(vidinfo_t *panel_info, struct exynos5_fimd_panel *panel_data, void *lcdbase);
#endif /* _S5P_DP_CORE_H */
diff --git a/src/mainboard/google/snow/ramstage.c b/src/mainboard/google/snow/ramstage.c
index ad0266b..962c79b 100644
--- a/src/mainboard/google/snow/ramstage.c
+++ b/src/mainboard/google/snow/ramstage.c
@@ -139,6 +139,16 @@ static void exynos_dp_reset(void)
udelay(300 * 1000);
}
+/*
+ * 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
@@ -199,7 +209,6 @@ static struct video_info snow_dp_video_info = {
static void mainboard_init(device_t dev)
{
int dp_tries;
- unsigned int wait_ms;
struct s5p_dp_device dp_device = {
.base = (struct exynos5_dp *)EXYNOS5250_DP1_BASE,
.video_info = &snow_dp_video_info,
@@ -215,20 +224,17 @@ static void mainboard_init(device_t dev)
exynos_dp_bridge_setup();
for (dp_tries = 1; dp_tries <= SNOW_MAX_DP_TRIES; dp_tries++) {
- if (wait_ms) {
- udelay(wait_ms);
- wait_ms = 0;
- }
-
exynos_dp_bridge_init();
if (exynos_dp_hotplug()) {
exynos_dp_reset();
continue;
}
- if (dp_controller_init(&dp_device, &wait_ms))
+ if (dp_controller_init(&dp_device))
continue;
+ udelay(LCD_T3_DELAY_MS * 1000);
+
snow_backlight_vdd();
snow_backlight_pwm();
snow_backlight_en();
David Hendricks (dhendrix(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3078
-gerrit
commit a79ad3ef6f8c10f141e9c796478649c4d9a68908
Author: David Hendricks <dhendrix(a)chromium.org>
Date: Fri Apr 12 16:02:44 2013 -0700
exynos5/snow: remove wait_ms arg from dp_controller_init()
This removes the wait_ms argument from the dp_controller_init(). The
only delay involved is a constant 60ms delay that happens if
everything else goes well. This delay is derived from the LCD spec
so there's no reason it should be baked into the controller code.
(This patch also has the side-effect of fixing a bug where we were
delaying on an undefined value for wait_ms).
Change-Id: I03aa19f2ac2f720524fcb7c795e10cc57f0a226e
Signed-off-by: David Hendricks <dhendrix(a)chromium.org>
---
src/cpu/samsung/exynos5-common/exynos-fb.c | 11 +----------
src/cpu/samsung/exynos5-common/s5p-dp-core.h | 2 +-
src/mainboard/google/snow/ramstage.c | 20 +++++++++++++-------
3 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/src/cpu/samsung/exynos5-common/exynos-fb.c b/src/cpu/samsung/exynos5-common/exynos-fb.c
index b57e276..11d666b 100644
--- a/src/cpu/samsung/exynos5-common/exynos-fb.c
+++ b/src/cpu/samsung/exynos5-common/exynos-fb.c
@@ -505,7 +505,7 @@ static int s5p_dp_hw_link_training(struct s5p_dp_device *dp,
/*
* Initialize DP display
*/
-int dp_controller_init(struct s5p_dp_device *dp_device, unsigned *wait_ms)
+int dp_controller_init(struct s5p_dp_device *dp_device)
{
int ret;
struct s5p_dp_device *dp = dp_device;
@@ -561,15 +561,6 @@ int dp_controller_init(struct s5p_dp_device *dp_device, unsigned *wait_ms)
return ret;
}
- /*
- * 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.
- */
- *wait_ms = 60;
return 0;
}
diff --git a/src/cpu/samsung/exynos5-common/s5p-dp-core.h b/src/cpu/samsung/exynos5-common/s5p-dp-core.h
index 2988d5d..4df848d 100644
--- a/src/cpu/samsung/exynos5-common/s5p-dp-core.h
+++ b/src/cpu/samsung/exynos5-common/s5p-dp-core.h
@@ -252,6 +252,6 @@ void s5p_dp_wait_hw_link_training_done(struct s5p_dp_device *dp);
/* startup and init */
struct exynos5_fimd_panel;
void fb_init(vidinfo_t *panel_info, void *lcdbase, struct exynos5_fimd_panel *pd);
-int dp_controller_init(struct s5p_dp_device *dp_device, unsigned *wait_ms);
+int dp_controller_init(struct s5p_dp_device *dp_device);
int lcd_ctrl_init(vidinfo_t *panel_info, struct exynos5_fimd_panel *panel_data, void *lcdbase);
#endif /* _S5P_DP_CORE_H */
diff --git a/src/mainboard/google/snow/ramstage.c b/src/mainboard/google/snow/ramstage.c
index ad0266b..50295cd 100644
--- a/src/mainboard/google/snow/ramstage.c
+++ b/src/mainboard/google/snow/ramstage.c
@@ -139,6 +139,16 @@ static void exynos_dp_reset(void)
udelay(300 * 1000);
}
+/*
+ * 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
@@ -199,7 +209,6 @@ static struct video_info snow_dp_video_info = {
static void mainboard_init(device_t dev)
{
int dp_tries;
- unsigned int wait_ms;
struct s5p_dp_device dp_device = {
.base = (struct exynos5_dp *)EXYNOS5250_DP1_BASE,
.video_info = &snow_dp_video_info,
@@ -215,20 +224,17 @@ static void mainboard_init(device_t dev)
exynos_dp_bridge_setup();
for (dp_tries = 1; dp_tries <= SNOW_MAX_DP_TRIES; dp_tries++) {
- if (wait_ms) {
- udelay(wait_ms);
- wait_ms = 0;
- }
-
exynos_dp_bridge_init();
if (exynos_dp_hotplug()) {
exynos_dp_reset();
continue;
}
- if (dp_controller_init(&dp_device, &wait_ms))
+ if (dp_controller_init(&dp_device))
continue;
+ udelay(LCD_T3_DELAY_MS * 1000):
+
snow_backlight_vdd();
snow_backlight_pwm();
snow_backlight_en();
David Hendricks (dhendrix(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3078
-gerrit
commit 561be97b37e76395110cb9cc17b7de3beb120e71
Author: David Hendricks <dhendrix(a)chromium.org>
Date: Fri Apr 12 16:02:44 2013 -0700
exynos5/snow: remove wait_ms arg from dp_controller_init()
This removes the wait_ms argument from the dp_controller_init(). The
only delay involved is a constant 60ms delay that happens if
everything else goes well. This delay is derived from the LCD spec
so there's no reason it should be baked into the controller code.
(This patch also has the side-effect of fixing a bug where we were
delaying on an undefined value for wait_ms).
Change-Id: I03aa19f2ac2f720524fcb7c795e10cc57f0a226e
Signed-off-by: David Hendricks <dhendrix(a)chromium.org>
---
src/cpu/samsung/exynos5-common/exynos-fb.c | 11 +----------
src/cpu/samsung/exynos5-common/s5p-dp-core.h | 2 +-
src/mainboard/google/snow/ramstage.c | 19 ++++++++++++-------
3 files changed, 14 insertions(+), 18 deletions(-)
diff --git a/src/cpu/samsung/exynos5-common/exynos-fb.c b/src/cpu/samsung/exynos5-common/exynos-fb.c
index b57e276..11d666b 100644
--- a/src/cpu/samsung/exynos5-common/exynos-fb.c
+++ b/src/cpu/samsung/exynos5-common/exynos-fb.c
@@ -505,7 +505,7 @@ static int s5p_dp_hw_link_training(struct s5p_dp_device *dp,
/*
* Initialize DP display
*/
-int dp_controller_init(struct s5p_dp_device *dp_device, unsigned *wait_ms)
+int dp_controller_init(struct s5p_dp_device *dp_device)
{
int ret;
struct s5p_dp_device *dp = dp_device;
@@ -561,15 +561,6 @@ int dp_controller_init(struct s5p_dp_device *dp_device, unsigned *wait_ms)
return ret;
}
- /*
- * 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.
- */
- *wait_ms = 60;
return 0;
}
diff --git a/src/cpu/samsung/exynos5-common/s5p-dp-core.h b/src/cpu/samsung/exynos5-common/s5p-dp-core.h
index 2988d5d..4df848d 100644
--- a/src/cpu/samsung/exynos5-common/s5p-dp-core.h
+++ b/src/cpu/samsung/exynos5-common/s5p-dp-core.h
@@ -252,6 +252,6 @@ void s5p_dp_wait_hw_link_training_done(struct s5p_dp_device *dp);
/* startup and init */
struct exynos5_fimd_panel;
void fb_init(vidinfo_t *panel_info, void *lcdbase, struct exynos5_fimd_panel *pd);
-int dp_controller_init(struct s5p_dp_device *dp_device, unsigned *wait_ms);
+int dp_controller_init(struct s5p_dp_device *dp_device);
int lcd_ctrl_init(vidinfo_t *panel_info, struct exynos5_fimd_panel *panel_data, void *lcdbase);
#endif /* _S5P_DP_CORE_H */
diff --git a/src/mainboard/google/snow/ramstage.c b/src/mainboard/google/snow/ramstage.c
index ad0266b..718bb27 100644
--- a/src/mainboard/google/snow/ramstage.c
+++ b/src/mainboard/google/snow/ramstage.c
@@ -139,6 +139,7 @@ static void exynos_dp_reset(void)
udelay(300 * 1000);
}
+#define LCD_T3_DELAY_MS 60
#define LCD_T5_DELAY_MS 10
#define LCD_T6_DELAY_MS 10
@@ -199,7 +200,6 @@ static struct video_info snow_dp_video_info = {
static void mainboard_init(device_t dev)
{
int dp_tries;
- unsigned int wait_ms;
struct s5p_dp_device dp_device = {
.base = (struct exynos5_dp *)EXYNOS5250_DP1_BASE,
.video_info = &snow_dp_video_info,
@@ -215,20 +215,25 @@ static void mainboard_init(device_t dev)
exynos_dp_bridge_setup();
for (dp_tries = 1; dp_tries <= SNOW_MAX_DP_TRIES; dp_tries++) {
- if (wait_ms) {
- udelay(wait_ms);
- wait_ms = 0;
- }
-
exynos_dp_bridge_init();
if (exynos_dp_hotplug()) {
exynos_dp_reset();
continue;
}
- if (dp_controller_init(&dp_device, &wait_ms))
+ if (dp_controller_init(&dp_device))
continue;
+ /*
+ * 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.
+ */
+ udelay(LCD_T3_DELAY_MS * 1000);
+
snow_backlight_vdd();
snow_backlight_pwm();
snow_backlight_en();
the following patch was just integrated into master:
commit c0b972f60dbd1a3dadfc568b5245c6b0ee6df559
Author: Ronald G. Minnich <rminnich(a)gmail.com>
Date: Thu Apr 11 15:03:28 2013 -0700
Exynos5250: add a microsecond timer
Add a microsecond timer, its declaration, the function to start it,
and its usage. To start it, one calls timer_start(). From that point
on, one can call timer_us() to find microseconds since the timer was
started.
We show its use in the bootblock. You want it started very early.
Finally, the delay.h change having been (ironically) delayed, we
create time.h and have it hold one declaration, for the timer_us() and
timer_start() prototype.
We feel that these two functions should become the hardware specific
functions, allowing us to finally move udelay() into src/lib where it
belongs.
Change-Id: I19cbc2bb0089a3de88cfb94276266af38b9363c5
Signed-off-by: Ronald G. Minnich <rminnich(a)gmail.com>
Reviewed-on: http://review.coreboot.org/3073
Tested-by: build bot (Jenkins)
Build-Tested: build bot (Jenkins) at Sat Apr 13 00:39:01 2013, giving +1
Reviewed-By: Ronald G. Minnich <rminnich(a)gmail.com> at Fri Apr 12 22:35:04 2013, giving +2
See http://review.coreboot.org/3073 for details.
-gerrit
Ronald G. Minnich (rminnich(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3073
-gerrit
commit baa285c6846458f7669cc14ae02f8f15ddd013c7
Author: Ronald G. Minnich <rminnich(a)gmail.com>
Date: Thu Apr 11 15:03:28 2013 -0700
Exynos5250: add a microsecond timer
Add a microsecond timer, its declaration, the function to start it,
and its usage. To start it, one calls timer_start(). From that point
on, one can call timer_us() to find microseconds since the timer was
started.
We show its use in the bootblock. You want it started very early.
Finally, the delay.h change having been (ironically) delayed, we
create time.h and have it hold one declaration, for the timer_us() and
timer_start() prototype.
We feel that these two functions should become the hardware specific
functions, allowing us to finally move udelay() into src/lib where it
belongs.
Change-Id: I19cbc2bb0089a3de88cfb94276266af38b9363c5
Signed-off-by: Ronald G. Minnich <rminnich(a)gmail.com>
---
src/arch/armv7/lib/Makefile.inc | 2 -
src/cpu/samsung/exynos5-common/timer.c | 15 ++--
src/cpu/samsung/exynos5250/Makefile.inc | 4 +-
src/cpu/samsung/exynos5250/clk.h | 5 ++
src/cpu/samsung/exynos5250/clock_init.c | 13 ----
src/cpu/samsung/exynos5250/mct.c | 117 ++++++++++++++++++++++++++++++++
src/include/time.h | 26 +++++++
src/mainboard/google/snow/bootblock.c | 6 ++
src/mainboard/google/snow/romstage.c | 1 +
9 files changed, 169 insertions(+), 20 deletions(-)
diff --git a/src/arch/armv7/lib/Makefile.inc b/src/arch/armv7/lib/Makefile.inc
index 56a1bb7..0cb5737 100644
--- a/src/arch/armv7/lib/Makefile.inc
+++ b/src/arch/armv7/lib/Makefile.inc
@@ -1,6 +1,5 @@
#FIXME: cache_v7 and cache-cp15 will go away eventually
-bootblock-y += syslib.c
bootblock-$(CONFIG_EARLY_CONSOLE) += early_console.c
bootblock-y += cache.c
@@ -13,7 +12,6 @@ ramstage-y += div0.c
#ramstage-y += interrupts.c
#ramstage-y += memcpy.S
#ramstage-y += memset.S
-ramstage-y += syslib.c
ramstage-y += cache.c
ramstage-y += mmu.c
diff --git a/src/cpu/samsung/exynos5-common/timer.c b/src/cpu/samsung/exynos5-common/timer.c
index 6cd5f5d..ca15501 100644
--- a/src/cpu/samsung/exynos5-common/timer.c
+++ b/src/cpu/samsung/exynos5-common/timer.c
@@ -25,6 +25,8 @@
#include <common.h>
#include <arch/io.h>
+#include <time.h>
+#include <console/console.h>
#include <cpu/samsung/exynos5-common/pwm.h>
#include <cpu/samsung/exynos5-common/clk.h>
#include <cpu/samsung/exynos5250/cpu.h>
@@ -117,12 +119,17 @@ unsigned long timer_get_us(void)
}
/* delay x useconds */
-void __udelay(unsigned long usec)
+void udelay(unsigned long usec)
{
- unsigned long count_value;
+ unsigned long start;
- count_value = timer_get_us_down();
- while ((int)(count_value - timer_get_us_down()) < (int)usec)
+ start = timer_us();
+ if ((start + usec) < start){
+ printk(BIOS_EMERG, "udelay: %08lx is impossibly large\n",
+ usec);
+ usec = 1000000;
+ }
+ while ((timer_us() - start) < usec)
;
}
diff --git a/src/cpu/samsung/exynos5250/Makefile.inc b/src/cpu/samsung/exynos5250/Makefile.inc
index 74bc871..1046b8b 100644
--- a/src/cpu/samsung/exynos5250/Makefile.inc
+++ b/src/cpu/samsung/exynos5250/Makefile.inc
@@ -3,7 +3,7 @@
# image outside of CBFS
#INTERMEDIATE += exynos5250_add_bl1
-bootblock-y += pinmux.c
+bootblock-y += pinmux.c mct.c
# Clock is required for UART
bootblock-$(CONFIG_EARLY_CONSOLE) += clock_init.c
bootblock-$(CONFIG_EARLY_CONSOLE) += clock.c
@@ -16,6 +16,7 @@ romstage-y += pinmux.c # required by s3c24x0_i2c (exynos5-common) and uart.
romstage-y += dmc_common.c
romstage-y += dmc_init_ddr3.c
romstage-y += power.c
+romstage-y += mct.c
romstage-$(CONFIG_EARLY_CONSOLE) += soc.c
romstage-$(CONFIG_EARLY_CONSOLE) += uart.c
@@ -27,6 +28,7 @@ ramstage-y += power.c
ramstage-y += soc.c
ramstage-$(CONFIG_CONSOLE_SERIAL_UART) += uart.c
ramstage-y += cpu.c
+ramstage-y += mct.c
#ramstage-$(CONFIG_SATA_AHCI) += sata.c
diff --git a/src/cpu/samsung/exynos5250/clk.h b/src/cpu/samsung/exynos5250/clk.h
index dbddce0..4785894 100644
--- a/src/cpu/samsung/exynos5250/clk.h
+++ b/src/cpu/samsung/exynos5250/clk.h
@@ -25,6 +25,11 @@
#include <cpu/samsung/exynos5-common/clk.h>
#include <cpu/samsung/exynos5250/pinmux.h>
+
+#define MCT_ADDRESS 0x101c0000
+
+#define MCT_HZ 24000000
+
/*
* Set mshci controller instances clock drivder
*
diff --git a/src/cpu/samsung/exynos5250/clock_init.c b/src/cpu/samsung/exynos5250/clock_init.c
index 618fdb6..c8479de 100644
--- a/src/cpu/samsung/exynos5250/clock_init.c
+++ b/src/cpu/samsung/exynos5250/clock_init.c
@@ -452,16 +452,3 @@ void clock_init_dp_clock(void)
setbits_le32(&clk->div_disp1_0, CLK_DIV_DISP1_0_FIMD1);
}
-/*
- * This is a custom implementation for the udelay(), as we do not the timer
- * initialise during the SPL boot. We are assuming the cpu takes 3 instruction
- * pre cycle. This is based on the implementation of sdelay() function.
- */
-void udelay(unsigned usec)
-{
- unsigned long count;
-
- /* TODO(alim.akhtar(a)samsung.com): Comment on why divided by 30000000 */
- count = usec * (get_pll_clk(APLL) / (3 * 10000000));
- sdelay(count);
-}
diff --git a/src/cpu/samsung/exynos5250/mct.c b/src/cpu/samsung/exynos5250/mct.c
new file mode 100644
index 0000000..ddabbf7
--- /dev/null
+++ b/src/cpu/samsung/exynos5250/mct.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <arch/io.h>
+#include <stdint.h>
+#include <time.h>
+#include "clk.h"
+
+struct __attribute__((packed)) mct_regs
+{
+ uint32_t mct_cfg;
+ uint8_t reserved0[0xfc];
+ uint32_t g_cnt_l;
+ uint32_t g_cnt_u;
+ uint8_t reserved1[0x8];
+ uint32_t g_cnt_wstat;
+ uint8_t reserved2[0xec];
+ uint32_t g_comp0_l;
+ uint32_t g_comp0_u;
+ uint32_t g_comp0_addr_incr;
+ uint8_t reserved3[0x4];
+ uint32_t g_comp1_l;
+ uint32_t g_comp1_u;
+ uint32_t g_comp1_addr_incr;
+ uint8_t reserved4[0x4];
+ uint32_t g_comp2_l;
+ uint32_t g_comp2_u;
+ uint32_t g_comp2_addr_incr;
+ uint8_t reserved5[0x4];
+ uint32_t g_comp3_l;
+ uint32_t g_comp3_u;
+ uint32_t g_comp3_addr_incr;
+ uint8_t reserved6[0x4];
+ uint32_t g_tcon;
+ uint32_t g_int_cstat;
+ uint32_t g_int_enb;
+ uint32_t g_wstat;
+ uint8_t reserved7[0xb0];
+ uint32_t l0_tcntb;
+ uint32_t l0_tcnto;
+ uint32_t l0_icntb;
+ uint32_t l0_icnto;
+ uint32_t l0_frcntb;
+ uint32_t l0_frcnto;
+ uint8_t reserved8[0x8];
+ uint32_t l0_tcon;
+ uint8_t reserved9[0xc];
+ uint32_t l0_int_cstat;
+ uint32_t l0_int_enb;
+ uint8_t reserved10[0x8];
+ uint32_t l0_wstat;
+ uint8_t reserved11[0xbc];
+ uint32_t l1_tcntb;
+ uint32_t l1_tcnto;
+ uint32_t l1_icntb;
+ uint32_t l1_icnto;
+ uint32_t l1_frcntb;
+ uint32_t l1_frcnto;
+ uint8_t reserved12[0x8];
+ uint32_t l1_tcon;
+ uint8_t reserved13[0xc];
+ uint32_t l1_int_cstat;
+ uint32_t l1_int_enb;
+ uint8_t reserved14[0x8];
+ uint32_t l1_wstat;
+};
+
+static int enabled = 0;
+static struct mct_regs *const mct =
+ (struct mct_regs *)MCT_ADDRESS;
+
+static uint64_t timer_raw_value(void)
+{
+ if (!enabled) {
+ writel(readl(&mct->g_tcon) | (0x1 << 8), &mct->g_tcon);
+ enabled = 1;
+ }
+
+ uint64_t upper = readl(&mct->g_cnt_u);
+ uint64_t lower = readl(&mct->g_cnt_l);
+
+ return (upper << 32) | lower;
+}
+
+void timer_start(void)
+{
+ writel(readl(&mct->g_tcon) | (0x1 << 8), &mct->g_tcon);
+ enabled = 1;
+}
+
+u32 timer_us(void)
+{
+ uint64_t raw = timer_raw_value();
+ static uint32_t ticks_per_microsecond = MCT_HZ/1000000;
+ uint32_t usec = raw / ticks_per_microsecond;
+ return usec;
+}
+
diff --git a/src/include/time.h b/src/include/time.h
new file mode 100644
index 0000000..2cfcb35
--- /dev/null
+++ b/src/include/time.h
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 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
+ */
+
+#ifndef TIME_H
+#define TIME_H
+
+void timer_start(void);
+u32 timer_us(void);
+
+#endif /* TIME_H */
diff --git a/src/mainboard/google/snow/bootblock.c b/src/mainboard/google/snow/bootblock.c
index 2df0e4e..d2e0b50 100644
--- a/src/mainboard/google/snow/bootblock.c
+++ b/src/mainboard/google/snow/bootblock.c
@@ -21,6 +21,7 @@
#include <arch/io.h>
#include <cbfs.h>
#include <uart.h>
+#include <time.h>
#include <console/console.h>
#include <cpu/samsung/exynos5250/periph.h>
#include <cpu/samsung/exynos5250/pinmux.h>
@@ -28,6 +29,11 @@
void bootblock_mainboard_init(void);
void bootblock_mainboard_init(void)
{
+ /* kick off the microsecond timer. We want to do this as early
+ * as we can.
+ */
+ timer_start();
+
exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE);
#if CONFIG_EARLY_CONSOLE
exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE);
diff --git a/src/mainboard/google/snow/romstage.c b/src/mainboard/google/snow/romstage.c
index 7a26ed9..dda4e7c 100644
--- a/src/mainboard/google/snow/romstage.c
+++ b/src/mainboard/google/snow/romstage.c
@@ -36,6 +36,7 @@
#include <cpu/samsung/exynos5250/clock_init.h>
#include <console/console.h>
#include <arch/stages.h>
+#include <time.h>
#include <drivers/maxim/max77686/max77686.h>
#include <device/i2c.h>