Marc Jones (marc.jones(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7909
-gerrit
commit e8d6d3110318644a30779012e56bf8334478ec7c
Author: Vadim Bendebury <vbendeb(a)chromium.org>
Date: Thu May 15 14:06:29 2014 -0700
Fix libpayload build compilation warnings
When emerging libpayload a warning is generated about selfboot() being
defined without a prior prototype.
Addinf cbfs.h when CBFS use if compiled fixes the warning.
BUG=none
TEST=run the following
$ for b in rambi storm nyan_big; do
cros_workon-$b start libpayload
emerge-$b libpayload
done
verify that there is no compilation warnings thrown any more
Original-Change-Id: Ic9cb5571f708bb006a0d477e451fd1f3b3eb833f
Original-Signed-off-by: Vadim Bendebury <vbendeb(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/200099
Original-Reviewed-by: Hung-Te Lin <hungte(a)chromium.org>
(cherry picked from commit 7e4aa17936b70dd08f58b3a55c6db55ea03709d7)
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
Change-Id: Ie3baaaca82fb6ec432860c638acb2a3ef9451469
---
payloads/libpayload/include/libpayload.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/payloads/libpayload/include/libpayload.h b/payloads/libpayload/include/libpayload.h
index 824e96e..1d4d0da 100644
--- a/payloads/libpayload/include/libpayload.h
+++ b/payloads/libpayload/include/libpayload.h
@@ -60,6 +60,9 @@
#ifdef CONFIG_LP_LAR
#include <lar.h>
#endif
+#ifdef CONFIG_LP_CBFS
+#include <cbfs.h>
+#endif
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
Marc Jones (marc.jones(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7911
-gerrit
commit 825b699988cd8ae616ab222600e76d33f53be957
Author: Vadim Bendebury <vbendeb(a)chromium.org>
Date: Thu May 15 14:12:54 2014 -0700
Do not tolerate compilation warnings when building libpayload
Make sure the build breaks in case of warnings.
BUG=none
TEST=run the following command with the previous patch removed and
then restored:
$ for b in rambi storm nyan_big; do
cros_workon-$b start libpayload
emerge-$b libpayload
done
all builds succeed with the restored patch and fail when a
compilation warning is thrown.
Original-Change-Id: I9bdcd8938f59913e4ba86df5e4921b3f821ef920
Original-Signed-off-by: Vadim Bendebury <vbendeb(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/200110
Original-Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
(cherry picked from commit 16dde875950d6806cc770cdbee4d3ff456ed6f02)
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
Change-Id: I86988f8d3f1acaa6ceeabdcbfa3cede1e67c28fe
---
payloads/libpayload/Makefile.inc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/payloads/libpayload/Makefile.inc b/payloads/libpayload/Makefile.inc
index ffe8371..dd83f88 100644
--- a/payloads/libpayload/Makefile.inc
+++ b/payloads/libpayload/Makefile.inc
@@ -57,7 +57,7 @@ CFLAGS = $(EXTRA_CFLAGS) $(INCLUDES) -Os -pipe -nostdinc -ggdb3
CFLAGS += -nostdlib -fno-builtin -ffreestanding -fomit-frame-pointer
CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wmissing-prototypes
CFLAGS += -Wwrite-strings -Wredundant-decls -Wno-trigraphs
-CFLAGS += -Wstrict-aliasing -Wshadow
+CFLAGS += -Wstrict-aliasing -Wshadow -Werror
$(obj)/libpayload-config.h: $(KCONFIG_AUTOHEADER)
cmp $@ $< 2>/dev/null || cp $< $@
Marc Jones (marc.jones(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7910
-gerrit
commit 17d415a6979f76de700c6927610cd4f6e4857e24
Author: Julius Werner <jwerner(a)chromium.org>
Date: Tue May 20 17:56:25 2014 -0700
libpayload: video: Check for 'console' pointer before dereferencing it
Seems that the 'if (cursor_enabled)' check in
video_console_fixup_cursor() that was removed in commit 1f880bca0 really
meant to check for 'if (console)'. Looks like the whole video console
driver is built extra robust to not fail no matter how screwed up the
console is, so let's add this missing check here as well. Also fixed up
a few other missing 'if (!console)' checks while I'm at it.
However, what payloads should really be doing is check the return value
of video_(console_)init() and not call the other video functions if that
failed. This also adapts video_console_init() to correctly pass through
the return value for that purpose (something that seems to have been
overlooked in the dd9e4e58 refactoring).
BUG=chrome-os-partner:28494
TEST=None. I don't know what Dave did to trigger this in the first
place, but it's pretty straight-forward.
Original-Change-Id: I1b9f09d49dc70dacf20621b19e081c754d4814f7
Original-Signed-off-by: Julius Werner <jwerner(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/200688
Original-Reviewed-by: David Hendricks <dhendrix(a)chromium.org>
(cherry picked from commit 3f01d1dc0974774f0b3ba5fc4e069978f266f2fc)
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
Change-Id: I98c1d8360539b457e6df07cbcf799acaf6c4631b
---
payloads/libpayload/drivers/video/video.c | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/payloads/libpayload/drivers/video/video.c b/payloads/libpayload/drivers/video/video.c
index 318548b..5f76a30 100644
--- a/payloads/libpayload/drivers/video/video.c
+++ b/payloads/libpayload/drivers/video/video.c
@@ -73,6 +73,9 @@ void video_get_rows_cols(unsigned int *rows, unsigned int *cols)
static void video_console_fixup_cursor(void)
{
+ if (!console)
+ return;
+
if (cursorx < 0)
cursorx = 0;
@@ -89,7 +92,7 @@ static void video_console_fixup_cursor(void)
cursory--;
}
- if (console && console->set_cursor)
+ if (console->set_cursor)
console->set_cursor(cursorx, cursory);
}
@@ -119,6 +122,9 @@ void video_console_putc(u8 row, u8 col, unsigned int ch)
void video_console_putchar(unsigned int ch)
{
+ if (!console)
+ return;
+
/* replace black-on-black with light-gray-on-black.
* do it here, instead of in libc/console.c
*/
@@ -145,16 +151,11 @@ void video_console_putchar(unsigned int ch)
break;
case '\t':
- while(cursorx % 8 && cursorx < console->columns) {
- if (console)
- console->putc(cursory, cursorx, (ch & 0xFF00) | ' ');
-
- cursorx++;
- }
+ while(cursorx % 8 && cursorx < console->columns)
+ console->putc(cursory, cursorx++, (ch & 0xFF00) | ' ');
break;
default:
- if (console)
- console->putc(cursory, cursorx++, ch);
+ console->putc(cursory, cursorx++, ch);
break;
}
@@ -167,7 +168,7 @@ void video_console_get_cursor(unsigned int *x, unsigned int *y, unsigned int *en
*y=0;
*en=0;
- if (console->get_cursor)
+ if (console && console->get_cursor)
console->get_cursor(x, y, en);
*x = cursorx;
@@ -214,9 +215,10 @@ int video_init(void)
int video_console_init(void)
{
- video_init();
- if (console)
- console_add_output_driver(&cons);
+ int ret = video_init();
+ if (ret)
+ return ret;
+ console_add_output_driver(&cons);
return 0;
}
Marc Jones (marc.jones(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7890
-gerrit
commit c035c1e3937a254eb062879b6a0644fac1f4bd55
Author: Gabe Black <gabeblack(a)google.com>
Date: Wed Apr 30 21:37:14 2014 -0700
rtc: Add an RTC driver for the AS3722 PMIC.
The AS3722 PMIC, like many PMICs, has an RTC built into it. This change adds a
driver for it which implements the new RTC API.
BUG=None
TEST=Built and booted with the event log code modified to use this interface.
Verified that events had accurate timestamps.
BRANCH=nyan
Original-Change-Id: I400adccbf84221dcba8d520276bb91b389f72268
Original-Signed-off-by: Gabe Black <gabeblack(a)google.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/197796
Original-Reviewed-by: Gabe Black <gabeblack(a)chromium.org>
Original-Tested-by: Gabe Black <gabeblack(a)chromium.org>
Original-Commit-Queue: Gabe Black <gabeblack(a)chromium.org>
(cherry picked from commit 011e49beba3a99abbd122866891e3c20bf1188d2)
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
Change-Id: Ibc1d342062c7853a30d195496c077e37a02b35b0
---
src/drivers/Kconfig | 1 +
src/drivers/Makefile.inc | 1 +
src/drivers/ams/Kconfig | 11 ++++++
src/drivers/ams/Makefile.inc | 1 +
src/drivers/ams/as3722rtc.c | 91 ++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 105 insertions(+)
diff --git a/src/drivers/Kconfig b/src/drivers/Kconfig
index 12f9a79..08de415 100644
--- a/src/drivers/Kconfig
+++ b/src/drivers/Kconfig
@@ -17,6 +17,7 @@
## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
##
+source src/drivers/ams/Kconfig
source src/drivers/ati/Kconfig
source src/drivers/dec/Kconfig
source src/drivers/elog/Kconfig
diff --git a/src/drivers/Makefile.inc b/src/drivers/Makefile.inc
index 7ae3eb2..151e3f7 100644
--- a/src/drivers/Makefile.inc
+++ b/src/drivers/Makefile.inc
@@ -17,6 +17,7 @@
## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
##
+subdirs-y += ams
subdirs-y += ati
subdirs-y += dec
subdirs-y += emulation
diff --git a/src/drivers/ams/Kconfig b/src/drivers/ams/Kconfig
new file mode 100644
index 0000000..44b89c5
--- /dev/null
+++ b/src/drivers/ams/Kconfig
@@ -0,0 +1,11 @@
+config DRIVERS_AS3722_RTC
+ bool "AS3722 RTC support"
+ default n
+
+config DRIVERS_AS3722_RTC_BUS
+ int "AS3722 RTC bus"
+ depends on DRIVERS_AS3722_RTC
+
+config DRIVERS_AS3722_RTC_ADDR
+ hex "AS3722 RTC chip address"
+ depends on DRIVERS_AS3722_RTC
diff --git a/src/drivers/ams/Makefile.inc b/src/drivers/ams/Makefile.inc
new file mode 100644
index 0000000..cf51831
--- /dev/null
+++ b/src/drivers/ams/Makefile.inc
@@ -0,0 +1 @@
+ramstage-$(CONFIG_DRIVERS_AS3722_RTC) += as3722rtc.c
diff --git a/src/drivers/ams/as3722rtc.c b/src/drivers/ams/as3722rtc.c
new file mode 100644
index 0000000..8fe5748
--- /dev/null
+++ b/src/drivers/ams/as3722rtc.c
@@ -0,0 +1,91 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 The Chromium OS Authors. All rights reserved.
+ *
+ * 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 <bcd.h>
+#include <console/console.h>
+#include <device/i2c.h>
+#include <rtc.h>
+#include <stdint.h>
+
+enum AS3722_RTC_REG
+{
+ AS3722_RTC_CONTROL = 0x60,
+ AS3722_RTC_SECOND = 0x61,
+ AS3722_RTC_MINUTE = 0x62,
+ AS3722_RTC_HOUR = 0x63,
+ AS3722_RTC_DAY = 0x64,
+ AS3722_RTC_MONTH = 0x65,
+ AS3722_RTC_YEAR = 0x66
+};
+
+enum {
+ AS3722_RTC_CONTROL_ON = 0x1 << 2
+};
+
+static uint8_t as3722_read(enum AS3722_RTC_REG reg)
+{
+ uint8_t val;
+ i2c_readb(CONFIG_DRIVERS_AS3722_RTC_BUS,
+ CONFIG_DRIVERS_AS3722_RTC_ADDR, reg, &val);
+ return val;
+}
+
+static void as3722_write(enum AS3722_RTC_REG reg, uint8_t val)
+{
+ i2c_writeb(CONFIG_DRIVERS_AS3722_RTC_BUS,
+ CONFIG_DRIVERS_AS3722_RTC_ADDR, reg, val);
+}
+
+static void as3722rtc_init(void)
+{
+ static int initialized;
+ if (initialized)
+ return;
+
+ uint8_t control = as3722_read(AS3722_RTC_CONTROL);
+ as3722_write(AS3722_RTC_CONTROL, control | AS3722_RTC_CONTROL_ON);
+
+ initialized = 1;
+}
+
+int rtc_set(const struct rtc_time *time)
+{
+ as3722rtc_init();
+
+ as3722_write(AS3722_RTC_SECOND, bin2bcd(time->sec));
+ as3722_write(AS3722_RTC_MINUTE, bin2bcd(time->min));
+ as3722_write(AS3722_RTC_HOUR, bin2bcd(time->hour));
+ as3722_write(AS3722_RTC_DAY, bin2bcd(time->mday));
+ as3722_write(AS3722_RTC_MONTH, bin2bcd(time->mon + 1));
+ as3722_write(AS3722_RTC_YEAR, bin2bcd(time->year));
+ return 0;
+}
+
+int rtc_get(struct rtc_time *time)
+{
+ as3722rtc_init();
+
+ time->sec = bcd2bin(as3722_read(AS3722_RTC_SECOND) & 0x7f);
+ time->min = bcd2bin(as3722_read(AS3722_RTC_MINUTE) & 0x7f);
+ time->hour = bcd2bin(as3722_read(AS3722_RTC_HOUR) & 0x3f);
+ time->mday = bcd2bin(as3722_read(AS3722_RTC_DAY) & 0x3f);
+ time->mon = bcd2bin(as3722_read(AS3722_RTC_MONTH) & 0x1f) - 1;
+ time->year = bcd2bin(as3722_read(AS3722_RTC_YEAR) & 0x7f);
+ return 0;
+}
Marc Jones (marc.jones(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7891
-gerrit
commit 7b56063995befe17a54a9997cd45a9f2eb008a6b
Author: Gabe Black <gabeblack(a)google.com>
Date: Wed Apr 30 21:41:23 2014 -0700
elog: Use the RTC driver interface instead of reading CMOS directly.
Use the RTC driver interface to find the timestamp for events instead of
reading the CMOS based RTC directly on x86 or punting on ARM. This makes
timestamps available on both architectures, assuming an RTC driver is
available.
BUG=None
TEST=Built and booted on nyan_big and link and verified that the timestamps
in the event log were accurate.
BRANCH=nyan
Original-Change-Id: Id45da53bc7ddfac8dd0978e7f2a3b8bc2c7ea753
Original-Signed-off-by: Gabe Black <gabeblack(a)google.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/197798
Original-Reviewed-by: David Hendricks <dhendrix(a)chromium.org>
Original-Tested-by: Gabe Black <gabeblack(a)chromium.org>
Original-Commit-Queue: Gabe Black <gabeblack(a)chromium.org>
(cherry picked from commit 493b05e06dd461532c9366fb09025efb3568a975)
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
Change-Id: I4fad296ecfeff8987e4a18054661190239245f32
---
src/drivers/elog/elog.c | 25 +++++++++++--------------
1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/src/drivers/elog/elog.c b/src/drivers/elog/elog.c
index 92d5af3..85198e2 100644
--- a/src/drivers/elog/elog.c
+++ b/src/drivers/elog/elog.c
@@ -25,6 +25,8 @@
#if CONFIG_ARCH_X86
#include <pc80/mc146818rtc.h>
#endif
+#include <bcd.h>
+#include <rtc.h>
#include <smbios.h>
#include <spi-generic.h>
#include <spi_flash.h>
@@ -637,20 +639,15 @@ int elog_init(void)
*/
static void elog_fill_timestamp(struct event_header *event)
{
-#if CONFIG_ARCH_X86
- event->second = cmos_read(RTC_CLK_SECOND);
- event->minute = cmos_read(RTC_CLK_MINUTE);
- event->hour = cmos_read(RTC_CLK_HOUR);
- event->day = cmos_read(RTC_CLK_DAYOFMONTH);
- event->month = cmos_read(RTC_CLK_MONTH);
- event->year = cmos_read(RTC_CLK_YEAR);
-#else
- /*
- * FIXME: We need to abstract the CMOS stuff on non-x86 platforms.
- * Until then, use bogus data here to force the values to 0.
- */
- event->month = 0xff;
-#endif
+ struct rtc_time time;
+
+ rtc_get(&time);
+ event->second = bin2bcd(time.sec);
+ event->minute = bin2bcd(time.min);
+ event->hour = bin2bcd(time.hour);
+ event->day = bin2bcd(time.mday);
+ event->month = bin2bcd(time.mon);
+ event->year = bin2bcd(time.year) & 0xff;
/* Basic sanity check of expected ranges */
if (event->month > 0x12 || event->day > 0x31 || event->hour > 0x23 ||
Marc Jones (marc.jones(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7889
-gerrit
commit 58e6a37b47be78d80def1f45484f93d6c6cb9c68
Author: Gabe Black <gabeblack(a)google.com>
Date: Wed Apr 30 21:31:44 2014 -0700
rtc: Add an RTC API, and implement it for x86.
This CL adds an API for RTC drivers, and implements its two functions, rtc_get
and rtc_set, for x86's RTC. The function which resets the clock when the CMOS
has lost state now uses the RTC driver instead of accessing the those registers
directly. The availability of "ALTCENTURY" is now set through a kconfig
variable so it can be available to the RTC driver without having to have a
specialized interface.
BUG=None
TEST=Built and booted on Link with the event log code modified to use the RTC
interface. Verified that the event times were accurate.
BRANCH=nyan
Original-Change-Id: Ifa807898e583254e57167fd44932ea86627a02ee
Original-Signed-off-by: Gabe Black <gabeblack(a)google.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/197795
Original-Reviewed-by: David Hendricks <dhendrix(a)chromium.org>
Original-Tested-by: Gabe Black <gabeblack(a)chromium.org>
Original-Commit-Queue: Gabe Black <gabeblack(a)chromium.org>
(cherry picked from commit 9e0fd75142d29afe34f6c6b9ce0099f478ca5a93)
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
Change-Id: I159f9b4872a0bb932961b4168b180c087dfb1883
---
src/drivers/pc80/Kconfig | 15 ++
src/drivers/pc80/Makefile.inc | 10 +-
src/drivers/pc80/mc146818.c | 323 ++++++++++++++++++++++++++++
src/drivers/pc80/mc146818rtc.c | 372 +++++----------------------------
src/include/bcd.h | 35 ++++
src/include/pc80/mc146818rtc.h | 5 +-
src/include/rtc.h | 37 ++++
src/southbridge/amd/agesa/hudson/lpc.c | 2 +-
src/southbridge/amd/cimx/sb700/late.c | 2 +-
src/southbridge/amd/cimx/sb800/late.c | 2 +-
src/southbridge/amd/cimx/sb900/late.c | 2 +-
src/southbridge/amd/pi/avalon/lpc.c | 2 +-
src/southbridge/amd/sb600/lpc.c | 2 +-
src/southbridge/amd/sb700/lpc.c | 2 +-
src/southbridge/amd/sb800/lpc.c | 2 +-
15 files changed, 476 insertions(+), 337 deletions(-)
diff --git a/src/drivers/pc80/Kconfig b/src/drivers/pc80/Kconfig
index 5fad3a5..8043177 100644
--- a/src/drivers/pc80/Kconfig
+++ b/src/drivers/pc80/Kconfig
@@ -22,3 +22,18 @@ config LPC_TPM
Enable this option to enable TPM support in coreboot.
If unsure, say N.
+
+config DRIVERS_MC146818_RTC
+ bool
+ default y if ARCH_X86
+ default n if !ARCH_X86
+
+config DRIVERS_MC146818_CMOS
+ bool
+ default y if ARCH_X86
+ default n if !ARCH_X86
+
+config DRIVERS_RTC_HAS_ALTCENTURY
+ bool "The RTC supports alt century"
+ depends on DRIVERS_MC146818_RTC
+ default y
diff --git a/src/drivers/pc80/Makefile.inc b/src/drivers/pc80/Makefile.inc
index fe6d11f..d792764 100644
--- a/src/drivers/pc80/Makefile.inc
+++ b/src/drivers/pc80/Makefile.inc
@@ -1,5 +1,7 @@
-romstage-y += mc146818rtc.c
-ramstage-y += mc146818rtc.c
+romstage-$(CONFIG_DRIVERS_MC146818_RTC) += mc146818rtc.c
+ramstage-$(CONFIG_DRIVERS_MC146818_RTC) += mc146818rtc.c
+romstage-$(CONFIG_DRIVERS_MC146818_CMOS) += mc146818.c
+ramstage-$(CONFIG_DRIVERS_MC146818_CMOS) += mc146818.c
ramstage-y += isa-dma.c
ramstage-y += i8254.c
ramstage-y += i8259.c
@@ -7,7 +9,10 @@ ramstage-$(CONFIG_UDELAY_IO) += udelay_io.c
ramstage-y += keyboard.c
ramstage-$(CONFIG_SPKMODEM) += spkmodem.c
+ifeq ($(CONFIG_DRIVERS_MC146818_CMOS),y)
romstage-$(CONFIG_USE_OPTION_TABLE) += mc146818rtc_early.c
+endif
+
romstage-$(CONFIG_LPC_TPM) += tpm.c
romstage-$(CONFIG_SPKMODEM) += spkmodem.c
@@ -17,4 +22,5 @@ cbfs-files-$(CONFIG_HAVE_CMOS_DEFAULT) += cmos.default
cmos.default-file = $(CONFIG_CMOS_DEFAULT_FILE):nvramtool
cmos.default-type = 0xaa
+smm-y += mc146818.c
smm-y += mc146818rtc.c
diff --git a/src/drivers/pc80/mc146818.c b/src/drivers/pc80/mc146818.c
new file mode 100644
index 0000000..23b92fd
--- /dev/null
+++ b/src/drivers/pc80/mc146818.c
@@ -0,0 +1,323 @@
+#include <bcd.h>
+#include <stdint.h>
+#include <build.h>
+#include <console/console.h>
+#include <pc80/mc146818rtc.h>
+#include <boot/coreboot_tables.h>
+#include <rtc.h>
+#include <string.h>
+#if CONFIG_USE_OPTION_TABLE
+#include "option_table.h"
+#include <cbfs.h>
+#endif
+#if CONFIG_HAVE_ACPI_RESUME
+#include <arch/acpi.h>
+#endif
+
+
+static void cmos_reset_date(void)
+{
+ /* Now setup a default date equals to the build date */
+ struct rtc_time time = {
+ .sec = 0,
+ .min = 0,
+ .hour = 1,
+ .mday = bcd2bin(COREBOOT_BUILD_DAY_BCD),
+ .mon = bcd2bin(COREBOOT_BUILD_MONTH_BCD),
+ .year = 2000 + bcd2bin(COREBOOT_BUILD_YEAR_BCD),
+ .wday = bcd2bin(COREBOOT_BUILD_WEEKDAY_BCD)
+ };
+ rtc_set(&time);
+}
+
+#if CONFIG_USE_OPTION_TABLE
+static int cmos_checksum_valid(int range_start, int range_end, int cks_loc)
+{
+ int i;
+ u16 sum, old_sum;
+ sum = 0;
+ for (i = range_start; i <= range_end; i++)
+ sum += cmos_read(i);
+ old_sum = ((cmos_read(cks_loc) << 8) | cmos_read(cks_loc + 1)) &
+ 0x0ffff;
+ return sum == old_sum;
+}
+
+static void cmos_set_checksum(int range_start, int range_end, int cks_loc)
+{
+ int i;
+ u16 sum;
+ sum = 0;
+ for (i = range_start; i <= range_end; i++)
+ sum += cmos_read(i);
+ cmos_write(((sum >> 8) & 0x0ff), cks_loc);
+ cmos_write(((sum >> 0) & 0x0ff), cks_loc + 1);
+}
+#endif
+
+#define RTC_CONTROL_DEFAULT (RTC_24H)
+#define RTC_FREQ_SELECT_DEFAULT (RTC_REF_CLCK_32KHZ | RTC_RATE_1024HZ)
+
+#ifndef __SMM__
+void cmos_init(int invalid)
+{
+ int cmos_invalid = 0;
+ int checksum_invalid = 0;
+#if CONFIG_USE_OPTION_TABLE
+ unsigned char x;
+#endif
+
+#if CONFIG_HAVE_ACPI_RESUME
+ /* Avoid clearing pending interrupts and resetting the RTC control
+ * register in the resume path because the Linux kernel relies on
+ * this to know if it should restart the RTC timerqueue if the wake
+ * was due to the RTC alarm.
+ */
+ if (acpi_slp_type == 3)
+ return;
+#endif
+
+ printk(BIOS_DEBUG, "RTC Init\n");
+
+#if CONFIG_USE_OPTION_TABLE
+ /* See if there has been a CMOS power problem. */
+ x = cmos_read(RTC_VALID);
+ cmos_invalid = !(x & RTC_VRT);
+
+ /* See if there is a CMOS checksum error */
+ checksum_invalid = !cmos_checksum_valid(PC_CKS_RANGE_START,
+ PC_CKS_RANGE_END,PC_CKS_LOC);
+
+#define CLEAR_CMOS 0
+#else
+#define CLEAR_CMOS 1
+#endif
+
+ if (invalid || cmos_invalid || checksum_invalid) {
+#if CLEAR_CMOS
+ int i;
+
+ cmos_write(0, 0x01);
+ cmos_write(0, 0x03);
+ cmos_write(0, 0x05);
+ for (i = 10; i < 128; i++)
+ cmos_write(0, i);
+#endif
+ if (cmos_invalid)
+ cmos_reset_date();
+
+ printk(BIOS_WARNING, "RTC:%s%s%s%s\n",
+ invalid?" Clear requested":"",
+ cmos_invalid?" Power Problem":"",
+ checksum_invalid?" Checksum invalid":"",
+ CLEAR_CMOS?" zeroing cmos":"");
+ }
+
+ /* Setup the real time clock */
+ cmos_write(RTC_CONTROL_DEFAULT, RTC_CONTROL);
+ /* Setup the frequency it operates at */
+ cmos_write(RTC_FREQ_SELECT_DEFAULT, RTC_FREQ_SELECT);
+ /* Ensure all reserved bits are 0 in register D */
+ cmos_write(RTC_VRT, RTC_VALID);
+
+#if CONFIG_USE_OPTION_TABLE
+ /* See if there is a LB CMOS checksum error */
+ checksum_invalid = !cmos_checksum_valid(LB_CKS_RANGE_START,
+ LB_CKS_RANGE_END,LB_CKS_LOC);
+ if (checksum_invalid)
+ printk(BIOS_DEBUG, "RTC: coreboot checksum invalid\n");
+
+ /* Make certain we have a valid checksum */
+ cmos_set_checksum(PC_CKS_RANGE_START, PC_CKS_RANGE_END, PC_CKS_LOC);
+#endif
+
+ /* Clear any pending interrupts */
+ cmos_read(RTC_INTR_FLAGS);
+}
+#endif
+
+
+#if CONFIG_USE_OPTION_TABLE
+/*
+ * This routine returns the value of the requested bits
+ * input bit = bit count from the beginning of the cmos image
+ * length = number of bits to include in the value
+ * vret = a character pointer to where the value is to be returned
+ * returns 0 = successful, -1 = an error occurred
+ */
+static int get_cmos_value(unsigned long bit, unsigned long length, void *vret)
+{
+ unsigned char *ret;
+ unsigned long byte,byte_bit;
+ unsigned long i;
+ unsigned char uchar;
+
+ /*
+ * The table is checked when it is built to ensure all
+ * values are valid.
+ */
+ ret = vret;
+ byte = bit / 8; /* find the byte where the data starts */
+ byte_bit = bit % 8; /* find the bit in the byte where the data starts */
+ if (length < 9) { /* one byte or less */
+ uchar = cmos_read(byte); /* load the byte */
+ uchar >>= byte_bit; /* shift the bits to byte align */
+ /* clear unspecified bits */
+ ret[0] = uchar & ((1 << length) - 1);
+ } else { /* more that one byte so transfer the whole bytes */
+ for (i = 0; length; i++, length -= 8, byte++) {
+ /* load the byte */
+ ret[i] = cmos_read(byte);
+ }
+ }
+ return 0;
+}
+
+int get_option(void *dest, const char *name)
+{
+ struct cmos_option_table *ct;
+ struct cmos_entries *ce;
+ size_t namelen;
+ int found = 0;
+
+ /* Figure out how long name is */
+ namelen = strnlen(name, CMOS_MAX_NAME_LENGTH);
+
+ /* find the requested entry record */
+ ct = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "cmos_layout.bin",
+ CBFS_COMPONENT_CMOS_LAYOUT, NULL);
+ if (!ct) {
+ printk(BIOS_ERR, "RTC: cmos_layout.bin could not be found. "
+ "Options are disabled\n");
+ return -2;
+ }
+ ce = (struct cmos_entries*)((unsigned char *)ct + ct->header_length);
+ for(; ce->tag == LB_TAG_OPTION;
+ ce = (struct cmos_entries*)((unsigned char *)ce + ce->size)) {
+ if (memcmp(ce->name, name, namelen) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ printk(BIOS_DEBUG, "WARNING: No CMOS option '%s'.\n", name);
+ return -2;
+ }
+
+ if (get_cmos_value(ce->bit, ce->length, dest))
+ return -3;
+ if (!cmos_checksum_valid(LB_CKS_RANGE_START, LB_CKS_RANGE_END,
+ LB_CKS_LOC))
+ return -4;
+ return 0 ;
+}
+
+static int set_cmos_value(unsigned long bit, unsigned long length, void *vret)
+{
+ unsigned char *ret;
+ unsigned long byte,byte_bit;
+ unsigned long i;
+ unsigned char uchar, mask;
+ unsigned int chksum_update_needed = 0;
+
+ ret = vret;
+ byte = bit / 8; /* find the byte where the data starts */
+ byte_bit = bit % 8; /* find the bit where the data starts */
+ if (length <= 8) { /* one byte or less */
+ mask = (1 << length) - 1;
+ mask <<= byte_bit;
+
+ uchar = cmos_read(byte);
+ uchar &= ~mask;
+ uchar |= (ret[0] << byte_bit);
+ cmos_write(uchar, byte);
+ if (byte >= LB_CKS_RANGE_START && byte <= LB_CKS_RANGE_END)
+ chksum_update_needed = 1;
+ } else { /* more that one byte so transfer the whole bytes */
+ if (byte_bit || length % 8)
+ return -1;
+
+ for (i = 0; length; i++, length -= 8, byte++)
+ cmos_write(ret[i], byte);
+ if (byte >= LB_CKS_RANGE_START &&
+ byte <= LB_CKS_RANGE_END)
+ chksum_update_needed = 1;
+ }
+
+ if (chksum_update_needed) {
+ cmos_set_checksum(LB_CKS_RANGE_START, LB_CKS_RANGE_END,
+ LB_CKS_LOC);
+ }
+ return 0;
+}
+
+
+int set_option(const char *name, void *value)
+{
+ struct cmos_option_table *ct;
+ struct cmos_entries *ce;
+ unsigned long length;
+ size_t namelen;
+ int found = 0;
+
+ /* Figure out how long name is */
+ namelen = strnlen(name, CMOS_MAX_NAME_LENGTH);
+
+ /* find the requested entry record */
+ ct = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "cmos_layout.bin",
+ CBFS_COMPONENT_CMOS_LAYOUT, NULL);
+ if (!ct) {
+ printk(BIOS_ERR, "cmos_layout.bin could not be found. "
+ "Options are disabled\n");
+ return -2;
+ }
+ ce = (struct cmos_entries*)((unsigned char *)ct + ct->header_length);
+ for(; ce->tag == LB_TAG_OPTION;
+ ce = (struct cmos_entries*)((unsigned char *)ce + ce->size)) {
+ if (memcmp(ce->name, name, namelen) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ printk(BIOS_DEBUG, "WARNING: No CMOS option '%s'.\n", name);
+ return -2;
+ }
+
+ length = ce->length;
+ if (ce->config == 's') {
+ length = MAX(strlen((const char *)value) * 8, ce->length - 8);
+ /* make sure the string is null terminated */
+ if ((set_cmos_value(ce->bit + ce->length - 8, 8, &(u8[]){0})))
+ return -3;
+ }
+
+ if ((set_cmos_value(ce->bit, length, value)))
+ return -3;
+
+ return 0;
+}
+#endif /* CONFIG_USE_OPTION_TABLE */
+
+/*
+ * If the CMOS is cleared, the rtc_reg has the invalid date. That
+ * hurts some OSes. Even if we don't set USE_OPTION_TABLE, we need
+ * to make sure the date is valid.
+ */
+void cmos_check_update_date(void)
+{
+ u8 year, century;
+
+ /* Note: Need to check if the hardware supports RTC_CLK_ALTCENTURY. */
+ century = CONFIG_DRIVERS_RTC_HAS_ALTCENTURY ?
+ cmos_read(RTC_CLK_ALTCENTURY) : 0;
+ year = cmos_read(RTC_CLK_YEAR);
+
+ /*
+ * TODO: If century is 0xFF, 100% that the cmos is cleared.
+ * Other than that, so far rtc_year is the only entry to check
+ * if the date is valid.
+ */
+ if (century > 0x99 || year > 0x99) /* Invalid date */
+ cmos_reset_date();
+}
diff --git a/src/drivers/pc80/mc146818rtc.c b/src/drivers/pc80/mc146818rtc.c
index 014a8c9..7954af4 100644
--- a/src/drivers/pc80/mc146818rtc.c
+++ b/src/drivers/pc80/mc146818rtc.c
@@ -1,327 +1,53 @@
-#include <stdint.h>
-#include <version.h>
-#include <console/console.h>
-#include <pc80/mc146818rtc.h>
-#include <boot/coreboot_tables.h>
-#include <string.h>
-#if CONFIG_USE_OPTION_TABLE
-#include "option_table.h"
-#include <cbfs.h>
-#endif
-#include <arch/acpi.h>
-
-
-static void cmos_update_date(u8 has_century)
-{
- /* Now setup a default date equals to the build date */
- cmos_write(0, RTC_CLK_SECOND);
- cmos_write(0, RTC_CLK_MINUTE);
- cmos_write(1, RTC_CLK_HOUR);
- cmos_write(coreboot_build_date.weekday + 1, RTC_CLK_DAYOFWEEK);
- cmos_write(coreboot_build_date.day, RTC_CLK_DAYOFMONTH);
- cmos_write(coreboot_build_date.month, RTC_CLK_MONTH);
- cmos_write(coreboot_build_date.year, RTC_CLK_YEAR);
- if (has_century)
- cmos_write(coreboot_build_date.century, RTC_CLK_ALTCENTURY);
-}
-
-#if CONFIG_USE_OPTION_TABLE
-static int cmos_checksum_valid(int range_start, int range_end, int cks_loc)
-{
- int i;
- u16 sum, old_sum;
- sum = 0;
- for (i = range_start; i <= range_end; i++)
- sum += cmos_read(i);
- old_sum = ((cmos_read(cks_loc) << 8) | cmos_read(cks_loc + 1)) &
- 0x0ffff;
- return sum == old_sum;
-}
-
-static void cmos_set_checksum(int range_start, int range_end, int cks_loc)
-{
- int i;
- u16 sum;
- sum = 0;
- for (i = range_start; i <= range_end; i++)
- sum += cmos_read(i);
- cmos_write(((sum >> 8) & 0x0ff), cks_loc);
- cmos_write(((sum >> 0) & 0x0ff), cks_loc + 1);
-}
-#endif
-
-#if CONFIG_ARCH_X86
-#define RTC_CONTROL_DEFAULT (RTC_24H)
-#define RTC_FREQ_SELECT_DEFAULT (RTC_REF_CLCK_32KHZ | RTC_RATE_1024HZ)
-#else
-#if CONFIG_ARCH_ALPHA
-#define RTC_CONTROL_DEFAULT (RTC_SQWE | RTC_24H)
-#define RTC_FREQ_SELECT_DEFAULT (RTC_REF_CLCK_32KHZ | RTC_RATE_1024HZ)
-#endif
-#endif
-
-#ifndef __SMM__
-void cmos_init(int invalid)
-{
- int cmos_invalid = 0;
- int checksum_invalid = 0;
-#if CONFIG_USE_OPTION_TABLE
- unsigned char x;
-#endif
-
-#ifndef __PRE_RAM__
- /*
- * Avoid clearing pending interrupts and resetting the RTC control
- * register in the resume path because the Linux kernel relies on
- * this to know if it should restart the RTC timer queue if the wake
- * was due to the RTC alarm.
- */
- if (acpi_is_wakeup_s3())
- return;
-#endif /* __PRE_RAM__ */
-
- printk(BIOS_DEBUG, "RTC Init\n");
-
-#if CONFIG_USE_OPTION_TABLE
- /* See if there has been a CMOS power problem. */
- x = cmos_read(RTC_VALID);
- cmos_invalid = !(x & RTC_VRT);
-
- /* See if there is a CMOS checksum error */
- checksum_invalid = !cmos_checksum_valid(PC_CKS_RANGE_START,
- PC_CKS_RANGE_END,PC_CKS_LOC);
-
-#define CLEAR_CMOS 0
-#else
-#define CLEAR_CMOS 1
-#endif
-
- if (invalid || cmos_invalid || checksum_invalid) {
-#if CLEAR_CMOS
- int i;
-
- cmos_write(0, 0x01);
- cmos_write(0, 0x03);
- cmos_write(0, 0x05);
- for (i = 10; i < 128; i++)
- cmos_write(0, i);
-#endif
- if (cmos_invalid)
- cmos_update_date(RTC_HAS_NO_ALTCENTURY);
-
- printk(BIOS_WARNING, "RTC:%s%s%s%s\n",
- invalid?" Clear requested":"",
- cmos_invalid?" Power Problem":"",
- checksum_invalid?" Checksum invalid":"",
- CLEAR_CMOS?" zeroing cmos":"");
- }
-
- /* Setup the real time clock */
- cmos_write(RTC_CONTROL_DEFAULT, RTC_CONTROL);
- /* Setup the frequency it operates at */
- cmos_write(RTC_FREQ_SELECT_DEFAULT, RTC_FREQ_SELECT);
- /* Ensure all reserved bits are 0 in register D */
- cmos_write(RTC_VRT, RTC_VALID);
-
-#if CONFIG_USE_OPTION_TABLE
- /* See if there is a LB CMOS checksum error */
- checksum_invalid = !cmos_checksum_valid(LB_CKS_RANGE_START,
- LB_CKS_RANGE_END,LB_CKS_LOC);
- if (checksum_invalid)
- printk(BIOS_DEBUG, "RTC: coreboot checksum invalid\n");
-
- /* Make certain we have a valid checksum */
- cmos_set_checksum(PC_CKS_RANGE_START, PC_CKS_RANGE_END, PC_CKS_LOC);
-#endif
-
- /* Clear any pending interrupts */
- cmos_read(RTC_INTR_FLAGS);
-}
-#endif
-
-
-#if CONFIG_USE_OPTION_TABLE
-/*
- * This routine returns the value of the requested bits.
- * input bit = bit count from the beginning of the cmos image
- * length = number of bits to include in the value
- * ret = a character pointer to where the value is to be returned
- * returns CB_SUCCESS = successful, cb_err code if an error occurred
- */
-static enum cb_err get_cmos_value(unsigned long bit, unsigned long length,
- void *vret)
-{
- unsigned char *ret;
- unsigned long byte,byte_bit;
- unsigned long i;
- unsigned char uchar;
-
- /*
- * The table is checked when it is built to ensure all
- * values are valid.
- */
- ret = vret;
- byte = bit / 8; /* find the byte where the data starts */
- byte_bit = bit % 8; /* find the bit in the byte where the data starts */
- if (length < 9) { /* one byte or less */
- uchar = cmos_read(byte); /* load the byte */
- uchar >>= byte_bit; /* shift the bits to byte align */
- /* clear unspecified bits */
- ret[0] = uchar & ((1 << length) - 1);
- } else { /* more that one byte so transfer the whole bytes */
- for (i = 0; length; i++, length -= 8, byte++) {
- /* load the byte */
- ret[i] = cmos_read(byte);
- }
- }
- return CB_SUCCESS;
-}
-
-enum cb_err get_option(void *dest, const char *name)
-{
- struct cmos_option_table *ct;
- struct cmos_entries *ce;
- size_t namelen;
- int found = 0;
-
- /* Figure out how long name is */
- namelen = strnlen(name, CMOS_MAX_NAME_LENGTH);
-
- /* find the requested entry record */
- ct = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "cmos_layout.bin",
- CBFS_COMPONENT_CMOS_LAYOUT, NULL);
- if (!ct) {
- printk(BIOS_ERR, "RTC: cmos_layout.bin could not be found. "
- "Options are disabled\n");
- return CB_CMOS_LAYOUT_NOT_FOUND;
- }
- ce = (struct cmos_entries*)((unsigned char *)ct + ct->header_length);
- for(; ce->tag == LB_TAG_OPTION;
- ce = (struct cmos_entries*)((unsigned char *)ce + ce->size)) {
- if (memcmp(ce->name, name, namelen) == 0) {
- found = 1;
- break;
- }
- }
- if (!found) {
- printk(BIOS_DEBUG, "WARNING: No CMOS option '%s'.\n", name);
- return CB_CMOS_OPTION_NOT_FOUND;
- }
-
- if (get_cmos_value(ce->bit, ce->length, dest) != CB_SUCCESS)
- return CB_CMOS_ACCESS_ERROR;
- if (!cmos_checksum_valid(LB_CKS_RANGE_START, LB_CKS_RANGE_END, LB_CKS_LOC))
- return CB_CMOS_CHECKSUM_INVALID;
- return CB_SUCCESS;
-}
-
-static enum cb_err set_cmos_value(unsigned long bit, unsigned long length,
- void *vret)
-{
- unsigned char *ret;
- unsigned long byte,byte_bit;
- unsigned long i;
- unsigned char uchar, mask;
- unsigned int chksum_update_needed = 0;
-
- ret = vret;
- byte = bit / 8; /* find the byte where the data starts */
- byte_bit = bit % 8; /* find the bit where the data starts */
- if (length <= 8) { /* one byte or less */
- mask = (1 << length) - 1;
- mask <<= byte_bit;
-
- uchar = cmos_read(byte);
- uchar &= ~mask;
- uchar |= (ret[0] << byte_bit);
- cmos_write(uchar, byte);
- if (byte >= LB_CKS_RANGE_START && byte <= LB_CKS_RANGE_END)
- chksum_update_needed = 1;
- } else { /* more that one byte so transfer the whole bytes */
- if (byte_bit || length % 8)
- return CB_ERR_ARG;
-
- for (i = 0; length; i++, length -= 8, byte++)
- cmos_write(ret[i], byte);
- if (byte >= LB_CKS_RANGE_START &&
- byte <= LB_CKS_RANGE_END)
- chksum_update_needed = 1;
- }
-
- if (chksum_update_needed) {
- cmos_set_checksum(LB_CKS_RANGE_START, LB_CKS_RANGE_END,
- LB_CKS_LOC);
- }
- return CB_SUCCESS;
-}
-
-
-enum cb_err set_option(const char *name, void *value)
-{
- struct cmos_option_table *ct;
- struct cmos_entries *ce;
- unsigned long length;
- size_t namelen;
- int found = 0;
-
- /* Figure out how long name is */
- namelen = strnlen(name, CMOS_MAX_NAME_LENGTH);
-
- /* find the requested entry record */
- ct = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "cmos_layout.bin",
- CBFS_COMPONENT_CMOS_LAYOUT, NULL);
- if (!ct) {
- printk(BIOS_ERR, "cmos_layout.bin could not be found. "
- "Options are disabled\n");
- return CB_CMOS_LAYOUT_NOT_FOUND;
- }
- ce = (struct cmos_entries*)((unsigned char *)ct + ct->header_length);
- for(; ce->tag == LB_TAG_OPTION;
- ce = (struct cmos_entries*)((unsigned char *)ce + ce->size)) {
- if (memcmp(ce->name, name, namelen) == 0) {
- found = 1;
- break;
- }
- }
- if (!found) {
- printk(BIOS_DEBUG, "WARNING: No CMOS option '%s'.\n", name);
- return CB_CMOS_OPTION_NOT_FOUND;
- }
-
- length = ce->length;
- if (ce->config == 's') {
- length = MAX(strlen((const char *)value) * 8, ce->length - 8);
- /* make sure the string is null terminated */
- if (set_cmos_value(ce->bit + ce->length - 8, 8, &(u8[]){0})
- != CB_SUCCESS)
- return (CB_CMOS_ACCESS_ERROR);
- }
-
- if (set_cmos_value(ce->bit, length, value) != CB_SUCCESS)
- return (CB_CMOS_ACCESS_ERROR);
-
- return CB_SUCCESS;
-}
-#endif /* CONFIG_USE_OPTION_TABLE */
-
/*
- * If the CMOS is cleared, the rtc_reg has the invalid date. That
- * hurts some OSes. Even if we don't set USE_OPTION_TABLE, we need
- * to make sure the date is valid.
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 The Chromium OS Authors. All rights reserved.
+ *
+ * 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
*/
-void cmos_check_update_date(u8 has_century)
-{
- u8 year, century;
-
- /* Note: Need to check if the hardware supports RTC_CLK_ALTCENTURY. */
- century = has_century ? cmos_read(RTC_CLK_ALTCENTURY) : 0;
- year = cmos_read(RTC_CLK_YEAR);
- /*
- * TODO: If century is 0xFF, 100% that the cmos is cleared.
- * Other than that, so far rtc_year is the only entry to check
- * if the date is valid.
- */
- if (century > 0x99 || year > 0x99) /* Invalid date */
- cmos_update_date(has_century);
+#include <bcd.h>
+#include <pc80/mc146818rtc.h>
+#include <rtc.h>
+
+int rtc_set(const struct rtc_time *time)
+{
+ cmos_write(bin2bcd(time->sec), RTC_CLK_SECOND);
+ cmos_write(bin2bcd(time->min), RTC_CLK_MINUTE);
+ cmos_write(bin2bcd(time->hour), RTC_CLK_HOUR);
+ cmos_write(bin2bcd(time->mday), RTC_CLK_DAYOFMONTH);
+ cmos_write(bin2bcd(time->mon), RTC_CLK_MONTH);
+ cmos_write(bin2bcd(time->year % 100), RTC_CLK_YEAR);
+ if (CONFIG_DRIVERS_RTC_HAS_ALTCENTURY)
+ cmos_write(bin2bcd(time->year / 100),
+ RTC_CLK_ALTCENTURY);
+ cmos_write(bin2bcd(time->wday + 1), RTC_CLK_DAYOFWEEK);
+ return 0;
+}
+
+int rtc_get(struct rtc_time *time)
+{
+ time->sec = bcd2bin(cmos_read(RTC_CLK_SECOND));
+ time->min = bcd2bin(cmos_read(RTC_CLK_MINUTE));
+ time->hour = bcd2bin(cmos_read(RTC_CLK_HOUR));
+ time->mday = bcd2bin(cmos_read(RTC_CLK_DAYOFMONTH));
+ time->mon = bcd2bin(cmos_read(RTC_CLK_MONTH));
+ time->year = bcd2bin(cmos_read(RTC_CLK_YEAR));
+ if (CONFIG_DRIVERS_RTC_HAS_ALTCENTURY)
+ time->year += bcd2bin(cmos_read(RTC_CLK_ALTCENTURY)) * 100;
+ else
+ time->year += 2000;
+ time->wday = bcd2bin(cmos_read(RTC_CLK_DAYOFWEEK)) - 1;
+ return 0;
}
diff --git a/src/include/bcd.h b/src/include/bcd.h
new file mode 100644
index 0000000..a085027
--- /dev/null
+++ b/src/include/bcd.h
@@ -0,0 +1,35 @@
+/*
+ * 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 _BCD_H_
+#define _BCD_H_
+
+#include <stdint.h>
+
+static inline uint8_t bcd2bin(uint8_t val)
+{
+ return ((val >> 4) & 0xf) * 10 + (val & 0xf);
+}
+
+static inline uint8_t bin2bcd(uint8_t val)
+{
+ return ((val / 10) << 4) | (val % 10);
+}
+
+#endif /* _BCD_H_ */
diff --git a/src/include/pc80/mc146818rtc.h b/src/include/pc80/mc146818rtc.h
index 3d65909..90ae7ae 100644
--- a/src/include/pc80/mc146818rtc.h
+++ b/src/include/pc80/mc146818rtc.h
@@ -94,9 +94,6 @@
#define RTC_CLK_YEAR 9
#define RTC_CLK_ALTCENTURY 0x32
-#define RTC_HAS_ALTCENTURY 1
-#define RTC_HAS_NO_ALTCENTURY 0
-
/* On PCs, the checksum is built only over bytes 16..45 */
#define PC_CKS_RANGE_START 16
#define PC_CKS_RANGE_END 45
@@ -173,7 +170,7 @@ static inline void cmos_write32(u8 offset, u32 value)
#if !defined(__ROMCC__)
void cmos_init(int invalid);
-void cmos_check_update_date(u8 has_century);
+void cmos_check_update_date(void);
#if CONFIG_USE_OPTION_TABLE
enum cb_err set_option(const char *name, void *val);
enum cb_err get_option(void *dest, const char *name);
diff --git a/src/include/rtc.h b/src/include/rtc.h
new file mode 100644
index 0000000..ba9a9c3
--- /dev/null
+++ b/src/include/rtc.h
@@ -0,0 +1,37 @@
+/*
+ * 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 _RTC_H_
+#define _RTC_H_
+
+struct rtc_time
+{
+ int sec;
+ int min;
+ int hour;
+ int mday;
+ int mon;
+ int year;
+ int wday;
+};
+
+int rtc_set(const struct rtc_time *time);
+int rtc_get(struct rtc_time *time);
+
+#endif /* _RTC_H_ */
diff --git a/src/southbridge/amd/agesa/hudson/lpc.c b/src/southbridge/amd/agesa/hudson/lpc.c
index 836966e..b784fc4 100644
--- a/src/southbridge/amd/agesa/hudson/lpc.c
+++ b/src/southbridge/amd/agesa/hudson/lpc.c
@@ -71,7 +71,7 @@ static void lpc_init(device_t dev)
byte |= 1 << 0 | 1 << 3;
pci_write_config8(dev, 0xBB, byte);
- cmos_check_update_date(RTC_HAS_ALTCENTURY);
+ cmos_check_update_date();
/* Initialize the real time clock.
* The 0 argument tells cmos_init not to
diff --git a/src/southbridge/amd/cimx/sb700/late.c b/src/southbridge/amd/cimx/sb700/late.c
index 9c70482..3fa6940 100644
--- a/src/southbridge/amd/cimx/sb700/late.c
+++ b/src/southbridge/amd/cimx/sb700/late.c
@@ -81,7 +81,7 @@ static void lpc_init(device_t dev)
{
printk(BIOS_DEBUG, "SB700 - Late.c - lpc_init - Start.\n");
- cmos_check_update_date(RTC_HAS_ALTCENTURY);
+ cmos_check_update_date();
/* Initialize the real time clock.
* The 0 argument tells cmos_init not to
diff --git a/src/southbridge/amd/cimx/sb800/late.c b/src/southbridge/amd/cimx/sb800/late.c
index 9c4047f..d7f22d3 100644
--- a/src/southbridge/amd/cimx/sb800/late.c
+++ b/src/southbridge/amd/cimx/sb800/late.c
@@ -132,7 +132,7 @@ static void lpc_init(device_t dev)
{
printk(BIOS_DEBUG, "SB800 - Late.c - lpc_init - Start.\n");
- cmos_check_update_date(RTC_HAS_ALTCENTURY);
+ cmos_check_update_date();
/* Initialize the real time clock.
* The 0 argument tells cmos_init not to
diff --git a/src/southbridge/amd/cimx/sb900/late.c b/src/southbridge/amd/cimx/sb900/late.c
index 6f6a501..e9f5ad6 100644
--- a/src/southbridge/amd/cimx/sb900/late.c
+++ b/src/southbridge/amd/cimx/sb900/late.c
@@ -103,7 +103,7 @@ static void lpc_init(device_t dev)
printk(BIOS_DEBUG, "SB900 - Late.c - lpc_init - Start.\n");
/* SB Configure HPET base and enable bit */
//- hpetInit(sb_config, &(sb_config->BuildParameters));
- cmos_check_update_date(RTC_HAS_ALTCENTURY);
+ cmos_check_update_date();
/* Initialize the real time clock.
* The 0 argument tells cmos_init not to
diff --git a/src/southbridge/amd/pi/avalon/lpc.c b/src/southbridge/amd/pi/avalon/lpc.c
index 1f60bc4..7b54cc3 100644
--- a/src/southbridge/amd/pi/avalon/lpc.c
+++ b/src/southbridge/amd/pi/avalon/lpc.c
@@ -70,7 +70,7 @@ static void lpc_init(device_t dev)
byte |= 1 << 0 | 1 << 3;
pci_write_config8(dev, 0xBB, byte);
- cmos_check_update_date(RTC_HAS_ALTCENTURY);
+ cmos_check_update_date();
/* Initialize the real time clock.
* The 0 argument tells cmos_init not to
diff --git a/src/southbridge/amd/sb600/lpc.c b/src/southbridge/amd/sb600/lpc.c
index acee69d..dc2f31b 100644
--- a/src/southbridge/amd/sb600/lpc.c
+++ b/src/southbridge/amd/sb600/lpc.c
@@ -63,7 +63,7 @@ static void lpc_init(device_t dev)
byte &= ~(1 << 1);
pci_write_config8(dev, 0x78, byte);
- cmos_check_update_date(RTC_HAS_ALTCENTURY);
+ cmos_check_update_date();
}
static void sb600_lpc_read_resources(device_t dev)
diff --git a/src/southbridge/amd/sb700/lpc.c b/src/southbridge/amd/sb700/lpc.c
index 26478b7..8ebc765 100644
--- a/src/southbridge/amd/sb700/lpc.c
+++ b/src/southbridge/amd/sb700/lpc.c
@@ -90,7 +90,7 @@ static void lpc_init(device_t dev)
}
#endif
- cmos_check_update_date(RTC_HAS_ALTCENTURY);
+ cmos_check_update_date();
}
void backup_top_of_ram(uint64_t ramtop)
diff --git a/src/southbridge/amd/sb800/lpc.c b/src/southbridge/amd/sb800/lpc.c
index f862a97..87c09a2 100644
--- a/src/southbridge/amd/sb800/lpc.c
+++ b/src/southbridge/amd/sb800/lpc.c
@@ -74,7 +74,7 @@ static void lpc_init(device_t dev)
byte |= 1 << 0 | 1 << 3;
pci_write_config8(dev, 0xBB, byte);
- cmos_check_update_date(RTC_HAS_ALTCENTURY);
+ cmos_check_update_date();
}
static void sb800_lpc_read_resources(device_t dev)
Marc Jones (marc.jones(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7871
-gerrit
commit a93fda78d2a68d6cccb4f531ff4add504e887c72
Author: Vadim Bendebury <vbendeb(a)chromium.org>
Date: Wed Apr 23 16:17:26 2014 -0700
ipq8064: SOC UART driver belongs in the SOC directory
Move the driver to where it belongs.
BUG=chrome-os-partner:27784
TEST=none
Original-Change-Id: Iee33de0b29a6bb86ba7c37e7e89aabc0fee42e80
Original-Signed-off-by: Vadim Bendebury <vbendeb(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/196658
Original-Reviewed-by: Stefan Reinauer <reinauer(a)chromium.org>
(cherry picked from commit 64afb0a2ac9b6cd4c202b879a484220e70ff5bbe)
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
Change-Id: Iee33de0b29a6bb86ba7c37e7e89aabc0fee42e80
---
src/lib/uart_ipq806.c | 440 ----------------------------------------
src/soc/qualcomm/ipq806x/uart.c | 440 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 440 insertions(+), 440 deletions(-)
diff --git a/src/lib/uart_ipq806.c b/src/lib/uart_ipq806.c
deleted file mode 100644
index c65f876..0000000
--- a/src/lib/uart_ipq806.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Copyright (c) 2012 The Linux Foundation. All rights reserved.
- * Source : APQ8064 LK boot
- *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-
-#include <common.h>
-#include <asm/arch-ipq806x/gsbi.h>
-#include <asm/arch-ipq806x/clock.h>
-#include <asm/arch-ipq806x/uart.h>
-#include <serial.h>
-
-#define FIFO_DATA_SIZE 4
-
-extern board_ipq806x_params_t *gboard_param;
-
-static unsigned int msm_boot_uart_dm_init(unsigned int uart_dm_base);
-
-/* Received data is valid or not */
-static int valid_data = 0;
-
-/* Received data */
-static unsigned int word = 0;
-
-/**
- * msm_boot_uart_dm_init_rx_transfer - Init Rx transfer
- * @uart_dm_base: UART controller base address
- */
-static unsigned int msm_boot_uart_dm_init_rx_transfer(unsigned int uart_dm_base)
-{
- /* Reset receiver */
- writel(MSM_BOOT_UART_DM_CMD_RESET_RX,
- MSM_BOOT_UART_DM_CR(uart_dm_base));
-
- /* Enable receiver */
- writel(MSM_BOOT_UART_DM_CR_RX_ENABLE,
- MSM_BOOT_UART_DM_CR(uart_dm_base));
- writel(MSM_BOOT_UART_DM_DMRX_DEF_VALUE,
- MSM_BOOT_UART_DM_DMRX(uart_dm_base));
-
- /* Clear stale event */
- writel(MSM_BOOT_UART_DM_CMD_RES_STALE_INT,
- MSM_BOOT_UART_DM_CR(uart_dm_base));
-
- /* Enable stale event */
- writel(MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT,
- MSM_BOOT_UART_DM_CR(uart_dm_base));
-
- return MSM_BOOT_UART_DM_E_SUCCESS;
-}
-
-/**
- * msm_boot_uart_dm_read - reads a word from the RX FIFO.
- * @data: location where the read data is stored
- * @count: no of valid data in the FIFO
- * @wait: indicates blocking call or not blocking call
- *
- * Reads a word from the RX FIFO. If no data is available blocks if
- * @wait is true, else returns %MSM_BOOT_UART_DM_E_RX_NOT_READY.
- */
-static unsigned int
-msm_boot_uart_dm_read(unsigned int *data, int *count, int wait)
-{
- static int total_rx_data = 0;
- static int rx_data_read = 0;
- unsigned int base = 0;
- uint32_t status_reg;
-
- base = gboard_param->uart_dm_base;
-
- if (data == NULL)
- return MSM_BOOT_UART_DM_E_INVAL;
-
- status_reg = readl(MSM_BOOT_UART_DM_MISR(base));
-
- /* Check for DM_RXSTALE for RX transfer to finish */
- while (!(status_reg & MSM_BOOT_UART_DM_RXSTALE)) {
- status_reg = readl(MSM_BOOT_UART_DM_MISR(base));
- if (!wait)
- return MSM_BOOT_UART_DM_E_RX_NOT_READY;
- }
-
- /* Check for Overrun error. We'll just reset Error Status */
- if (readl(MSM_BOOT_UART_DM_SR(base)) &
- MSM_BOOT_UART_DM_SR_UART_OVERRUN) {
- writel(MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT,
- MSM_BOOT_UART_DM_CR(base));
- total_rx_data = rx_data_read = 0;
- msm_boot_uart_dm_init(base);
- return MSM_BOOT_UART_DM_E_RX_NOT_READY;
- }
-
- /* Read UART_DM_RX_TOTAL_SNAP for actual number of bytes received */
- if (total_rx_data == 0)
- total_rx_data = readl(MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base));
-
- /* Data available in FIFO; read a word. */
- *data = readl(MSM_BOOT_UART_DM_RF(base, 0));
-
- /* WAR for http://prism/CR/548280 */
- if (*data == 0) {
- return MSM_BOOT_UART_DM_E_RX_NOT_READY;
- }
-
- /* increment the total count of chars we've read so far */
- rx_data_read += FIFO_DATA_SIZE;
-
- /* actual count of valid data in word */
- *count = ((total_rx_data < rx_data_read) ?
- (FIFO_DATA_SIZE - (rx_data_read - total_rx_data)) :
- FIFO_DATA_SIZE);
-
- /* If there are still data left in FIFO we'll read them before
- * initializing RX Transfer again
- */
- if (rx_data_read < total_rx_data)
- return MSM_BOOT_UART_DM_E_SUCCESS;
-
- msm_boot_uart_dm_init_rx_transfer(base);
- total_rx_data = rx_data_read = 0;
-
- return MSM_BOOT_UART_DM_E_SUCCESS;
-}
-
-/**
- * msm_boot_uart_replace_lr_with_cr - replaces "\n" with "\r\n"
- * @data_in: characters to be converted
- * @num_of_chars: no. of characters
- * @data_out: location where converted chars are stored
- *
- * Replace linefeed char "\n" with carriage return + linefeed
- * "\r\n". Currently keeping it simple than efficient.
- */
-static unsigned int
-msm_boot_uart_replace_lr_with_cr(char *data_in,
- int num_of_chars,
- char *data_out, int *num_of_chars_out)
-{
- int i = 0, j = 0;
-
- if ((data_in == NULL) || (data_out == NULL) || (num_of_chars < 0))
- return MSM_BOOT_UART_DM_E_INVAL;
-
- for (i = 0, j = 0; i < num_of_chars; i++, j++) {
- if (data_in[i] == '\n')
- data_out[j++] = '\r';
-
- data_out[j] = data_in[i];
- }
-
- *num_of_chars_out = j;
-
- return MSM_BOOT_UART_DM_E_SUCCESS;
-}
-
-/**
- * msm_boot_uart_dm_write - transmit data
- * @data: data to transmit
- * @num_of_chars: no. of bytes to transmit
- *
- * Writes the data to the TX FIFO. If no space is available blocks
- * till space becomes available.
- */
-static unsigned int
-msm_boot_uart_dm_write(char *data, unsigned int num_of_chars)
-{
- unsigned int tx_word_count = 0;
- unsigned int tx_char_left = 0, tx_char = 0;
- unsigned int tx_word = 0;
- int i = 0;
- char *tx_data = NULL;
- char new_data[1024];
- unsigned int base = gboard_param->uart_dm_base;
-
- if ((data == NULL) || (num_of_chars <= 0))
- return MSM_BOOT_UART_DM_E_INVAL;
-
- /* Replace line-feed (/n) with carriage-return + line-feed (/r/n) */
- msm_boot_uart_replace_lr_with_cr(data, num_of_chars, new_data, &i);
-
- tx_data = new_data;
- num_of_chars = i;
-
- /* Write to NO_CHARS_FOR_TX register number of characters
- * to be transmitted. However, before writing TX_FIFO must
- * be empty as indicated by TX_READY interrupt in IMR register
- */
- /* Check if transmit FIFO is empty.
- * If not we'll wait for TX_READY interrupt. */
-
- if (!(readl(MSM_BOOT_UART_DM_SR(base)) & MSM_BOOT_UART_DM_SR_TXEMT)) {
- while (!(readl(MSM_BOOT_UART_DM_ISR(base)) & MSM_BOOT_UART_DM_TX_READY))
- __udelay(1);
- }
-
- /* We are here. FIFO is ready to be written. */
- /* Write number of characters to be written */
- writel(num_of_chars, MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base));
-
- /* Clear TX_READY interrupt */
- writel(MSM_BOOT_UART_DM_GCMD_RES_TX_RDY_INT, MSM_BOOT_UART_DM_CR(base));
-
- /* We use four-character word FIFO. So we need to divide data into
- * four characters and write in UART_DM_TF register */
- tx_word_count = (num_of_chars % 4) ? ((num_of_chars / 4) + 1) :
- (num_of_chars / 4);
- tx_char_left = num_of_chars;
-
- for (i = 0; i < (int)tx_word_count; i++) {
- tx_char = (tx_char_left < 4) ? tx_char_left : 4;
- PACK_CHARS_INTO_WORDS(tx_data, tx_char, tx_word);
-
- /* Wait till TX FIFO has space */
- while (!(readl(MSM_BOOT_UART_DM_SR(base)) & MSM_BOOT_UART_DM_SR_TXRDY))
- __udelay(1);
-
- /* TX FIFO has space. Write the chars */
- writel(tx_word, MSM_BOOT_UART_DM_TF(base, 0));
- tx_char_left = num_of_chars - (i + 1) * 4;
- tx_data = tx_data + 4;
- }
-
- return MSM_BOOT_UART_DM_E_SUCCESS;
-}
-
-/*
- * msm_boot_uart_dm_reset - resets UART controller
- * @base: UART controller base address
- */
-static unsigned int msm_boot_uart_dm_reset(unsigned int base)
-{
- writel(MSM_BOOT_UART_DM_CMD_RESET_RX, MSM_BOOT_UART_DM_CR(base));
- writel(MSM_BOOT_UART_DM_CMD_RESET_TX, MSM_BOOT_UART_DM_CR(base));
- writel(MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT, MSM_BOOT_UART_DM_CR(base));
- writel(MSM_BOOT_UART_DM_CMD_RES_TX_ERR, MSM_BOOT_UART_DM_CR(base));
- writel(MSM_BOOT_UART_DM_CMD_RES_STALE_INT, MSM_BOOT_UART_DM_CR(base));
-
- return MSM_BOOT_UART_DM_E_SUCCESS;
-}
-
-/*
- * msm_boot_uart_dm_init - initilaizes UART controller
- * @uart_dm_base: UART controller base address
- */
-static unsigned int msm_boot_uart_dm_init(unsigned int uart_dm_base)
-{
- /* Configure UART mode registers MR1 and MR2 */
- /* Hardware flow control isn't supported */
- writel(0x0, MSM_BOOT_UART_DM_MR1(uart_dm_base));
-
- /* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */
- writel(MSM_BOOT_UART_DM_8_N_1_MODE, MSM_BOOT_UART_DM_MR2(uart_dm_base));
-
- /* Configure Interrupt Mask register IMR */
- writel(MSM_BOOT_UART_DM_IMR_ENABLED, MSM_BOOT_UART_DM_IMR(uart_dm_base));
-
- /*
- * Configure Tx and Rx watermarks configuration registers
- * TX watermark value is set to 0 - interrupt is generated when
- * FIFO level is less than or equal to 0
- */
- writel(MSM_BOOT_UART_DM_TFW_VALUE, MSM_BOOT_UART_DM_TFWR(uart_dm_base));
-
- /* RX watermark value */
- writel(MSM_BOOT_UART_DM_RFW_VALUE, MSM_BOOT_UART_DM_RFWR(uart_dm_base));
-
- /* Configure Interrupt Programming Register */
- /* Set initial Stale timeout value */
- writel(MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB,
- MSM_BOOT_UART_DM_IPR(uart_dm_base));
-
- /* Configure IRDA if required */
- /* Disabling IRDA mode */
- writel(0x0, MSM_BOOT_UART_DM_IRDA(uart_dm_base));
-
- /* Configure hunt character value in HCR register */
- /* Keep it in reset state */
- writel(0x0, MSM_BOOT_UART_DM_HCR(uart_dm_base));
-
- /*
- * Configure Rx FIFO base address
- * Both TX/RX shares same SRAM and default is half-n-half.
- * Sticking with default value now.
- * As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries).
- * We have found RAM_ADDR_WIDTH = 0x7f
- */
-
- /* Issue soft reset command */
- msm_boot_uart_dm_reset(uart_dm_base);
-
- /* Enable/Disable Rx/Tx DM interfaces */
- /* Data Mover not currently utilized. */
- writel(0x0, MSM_BOOT_UART_DM_DMEN(uart_dm_base));
-
- /* Enable transmitter */
- writel(MSM_BOOT_UART_DM_CR_TX_ENABLE,
- MSM_BOOT_UART_DM_CR(uart_dm_base));
-
- /* Initialize Receive Path */
- msm_boot_uart_dm_init_rx_transfer(uart_dm_base);
-
- return 0;
-}
-
-/**
- * uart_dm_init - initializes UART
- *
- * Initializes clocks, GPIO and UART controller.
- */
-static int uart_dm_init(void)
-{
- unsigned int dm_base, gsbi_base;
-
- dm_base = gboard_param->uart_dm_base;
- gsbi_base = gboard_param->uart_gsbi_base;
- ipq_configure_gpio(gboard_param->dbg_uart_gpio, NO_OF_DBG_UART_GPIOS);
-
- /* Configure the uart clock */
- uart_clock_config(gboard_param->uart_gsbi,
- gboard_param->mnd_value.m_value,
- gboard_param->mnd_value.n_value,
- gboard_param->mnd_value.d_value,
- gboard_param->clk_dummy);
-
- writel(GSBI_PROTOCOL_CODE_I2C_UART <<
- GSBI_CTRL_REG_PROTOCOL_CODE_S,
- GSBI_CTRL_REG(gsbi_base));
- writel(UART_DM_CLK_RX_TX_BIT_RATE, MSM_BOOT_UART_DM_CSR(dm_base));
- /* Intialize UART_DM */
- msm_boot_uart_dm_init(dm_base);
-
- return 0;
-}
-
-/**
- * ipq806x_serial_putc - transmits a character
- * @c: character to transmit
- */
-static void ipq806x_serial_putc(char c)
-{
- msm_boot_uart_dm_write(&c, 1);
-}
-
-/**
- * ipq806x_serial_puts - transmits a string of data
- * @s: string to transmit
- */
-static void ipq806x_serial_puts(const char *s)
-{
- while (*s != '\0')
- serial_putc(*s++);
-}
-
-/**
- * ipq806x_serial_tstc - checks if data available for reading
- *
- * Returns 1 if data available, 0 otherwise
- */
-static int ipq806x_serial_tstc(void)
-{
- /* Return if data is already read */
- if (valid_data)
- return 1;
-
- /* Read data from the FIFO */
- if (msm_boot_uart_dm_read(&word, &valid_data, 0) != MSM_BOOT_UART_DM_E_SUCCESS)
- return 0;
-
- return 1;
-}
-
-/**
- * ipq806x_serial_getc - reads a character
- *
- * Returns the character read from serial port.
- */
-static int ipq806x_serial_getc(void)
-{
- int byte;
-
- while (!serial_tstc()) {
- /* wait for incoming data */
- }
-
- byte = (int)word & 0xff;
- word = word >> 8;
- valid_data--;
-
- return byte;
-}
-
-static struct serial_device ipq_serial_device = {
- .name = "ipq_serial",
- .start = uart_dm_init,
- .getc = ipq806x_serial_getc,
- .tstc = ipq806x_serial_tstc,
- .putc = ipq806x_serial_putc,
- .puts = ipq806x_serial_puts,
-};
-
-__weak struct serial_device *default_serial_console(void)
-{
- return &ipq_serial_device;
-}
-
-/**
- * ipq806x_serial_init - initializes serial controller
- */
-void ipq806x_serial_initialize(void)
-{
- serial_register(&ipq_serial_device);
-}
diff --git a/src/soc/qualcomm/ipq806x/uart.c b/src/soc/qualcomm/ipq806x/uart.c
new file mode 100644
index 0000000..c65f876
--- /dev/null
+++ b/src/soc/qualcomm/ipq806x/uart.c
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 2012 The Linux Foundation. All rights reserved.
+ * Source : APQ8064 LK boot
+ *
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <common.h>
+#include <asm/arch-ipq806x/gsbi.h>
+#include <asm/arch-ipq806x/clock.h>
+#include <asm/arch-ipq806x/uart.h>
+#include <serial.h>
+
+#define FIFO_DATA_SIZE 4
+
+extern board_ipq806x_params_t *gboard_param;
+
+static unsigned int msm_boot_uart_dm_init(unsigned int uart_dm_base);
+
+/* Received data is valid or not */
+static int valid_data = 0;
+
+/* Received data */
+static unsigned int word = 0;
+
+/**
+ * msm_boot_uart_dm_init_rx_transfer - Init Rx transfer
+ * @uart_dm_base: UART controller base address
+ */
+static unsigned int msm_boot_uart_dm_init_rx_transfer(unsigned int uart_dm_base)
+{
+ /* Reset receiver */
+ writel(MSM_BOOT_UART_DM_CMD_RESET_RX,
+ MSM_BOOT_UART_DM_CR(uart_dm_base));
+
+ /* Enable receiver */
+ writel(MSM_BOOT_UART_DM_CR_RX_ENABLE,
+ MSM_BOOT_UART_DM_CR(uart_dm_base));
+ writel(MSM_BOOT_UART_DM_DMRX_DEF_VALUE,
+ MSM_BOOT_UART_DM_DMRX(uart_dm_base));
+
+ /* Clear stale event */
+ writel(MSM_BOOT_UART_DM_CMD_RES_STALE_INT,
+ MSM_BOOT_UART_DM_CR(uart_dm_base));
+
+ /* Enable stale event */
+ writel(MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT,
+ MSM_BOOT_UART_DM_CR(uart_dm_base));
+
+ return MSM_BOOT_UART_DM_E_SUCCESS;
+}
+
+/**
+ * msm_boot_uart_dm_read - reads a word from the RX FIFO.
+ * @data: location where the read data is stored
+ * @count: no of valid data in the FIFO
+ * @wait: indicates blocking call or not blocking call
+ *
+ * Reads a word from the RX FIFO. If no data is available blocks if
+ * @wait is true, else returns %MSM_BOOT_UART_DM_E_RX_NOT_READY.
+ */
+static unsigned int
+msm_boot_uart_dm_read(unsigned int *data, int *count, int wait)
+{
+ static int total_rx_data = 0;
+ static int rx_data_read = 0;
+ unsigned int base = 0;
+ uint32_t status_reg;
+
+ base = gboard_param->uart_dm_base;
+
+ if (data == NULL)
+ return MSM_BOOT_UART_DM_E_INVAL;
+
+ status_reg = readl(MSM_BOOT_UART_DM_MISR(base));
+
+ /* Check for DM_RXSTALE for RX transfer to finish */
+ while (!(status_reg & MSM_BOOT_UART_DM_RXSTALE)) {
+ status_reg = readl(MSM_BOOT_UART_DM_MISR(base));
+ if (!wait)
+ return MSM_BOOT_UART_DM_E_RX_NOT_READY;
+ }
+
+ /* Check for Overrun error. We'll just reset Error Status */
+ if (readl(MSM_BOOT_UART_DM_SR(base)) &
+ MSM_BOOT_UART_DM_SR_UART_OVERRUN) {
+ writel(MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT,
+ MSM_BOOT_UART_DM_CR(base));
+ total_rx_data = rx_data_read = 0;
+ msm_boot_uart_dm_init(base);
+ return MSM_BOOT_UART_DM_E_RX_NOT_READY;
+ }
+
+ /* Read UART_DM_RX_TOTAL_SNAP for actual number of bytes received */
+ if (total_rx_data == 0)
+ total_rx_data = readl(MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base));
+
+ /* Data available in FIFO; read a word. */
+ *data = readl(MSM_BOOT_UART_DM_RF(base, 0));
+
+ /* WAR for http://prism/CR/548280 */
+ if (*data == 0) {
+ return MSM_BOOT_UART_DM_E_RX_NOT_READY;
+ }
+
+ /* increment the total count of chars we've read so far */
+ rx_data_read += FIFO_DATA_SIZE;
+
+ /* actual count of valid data in word */
+ *count = ((total_rx_data < rx_data_read) ?
+ (FIFO_DATA_SIZE - (rx_data_read - total_rx_data)) :
+ FIFO_DATA_SIZE);
+
+ /* If there are still data left in FIFO we'll read them before
+ * initializing RX Transfer again
+ */
+ if (rx_data_read < total_rx_data)
+ return MSM_BOOT_UART_DM_E_SUCCESS;
+
+ msm_boot_uart_dm_init_rx_transfer(base);
+ total_rx_data = rx_data_read = 0;
+
+ return MSM_BOOT_UART_DM_E_SUCCESS;
+}
+
+/**
+ * msm_boot_uart_replace_lr_with_cr - replaces "\n" with "\r\n"
+ * @data_in: characters to be converted
+ * @num_of_chars: no. of characters
+ * @data_out: location where converted chars are stored
+ *
+ * Replace linefeed char "\n" with carriage return + linefeed
+ * "\r\n". Currently keeping it simple than efficient.
+ */
+static unsigned int
+msm_boot_uart_replace_lr_with_cr(char *data_in,
+ int num_of_chars,
+ char *data_out, int *num_of_chars_out)
+{
+ int i = 0, j = 0;
+
+ if ((data_in == NULL) || (data_out == NULL) || (num_of_chars < 0))
+ return MSM_BOOT_UART_DM_E_INVAL;
+
+ for (i = 0, j = 0; i < num_of_chars; i++, j++) {
+ if (data_in[i] == '\n')
+ data_out[j++] = '\r';
+
+ data_out[j] = data_in[i];
+ }
+
+ *num_of_chars_out = j;
+
+ return MSM_BOOT_UART_DM_E_SUCCESS;
+}
+
+/**
+ * msm_boot_uart_dm_write - transmit data
+ * @data: data to transmit
+ * @num_of_chars: no. of bytes to transmit
+ *
+ * Writes the data to the TX FIFO. If no space is available blocks
+ * till space becomes available.
+ */
+static unsigned int
+msm_boot_uart_dm_write(char *data, unsigned int num_of_chars)
+{
+ unsigned int tx_word_count = 0;
+ unsigned int tx_char_left = 0, tx_char = 0;
+ unsigned int tx_word = 0;
+ int i = 0;
+ char *tx_data = NULL;
+ char new_data[1024];
+ unsigned int base = gboard_param->uart_dm_base;
+
+ if ((data == NULL) || (num_of_chars <= 0))
+ return MSM_BOOT_UART_DM_E_INVAL;
+
+ /* Replace line-feed (/n) with carriage-return + line-feed (/r/n) */
+ msm_boot_uart_replace_lr_with_cr(data, num_of_chars, new_data, &i);
+
+ tx_data = new_data;
+ num_of_chars = i;
+
+ /* Write to NO_CHARS_FOR_TX register number of characters
+ * to be transmitted. However, before writing TX_FIFO must
+ * be empty as indicated by TX_READY interrupt in IMR register
+ */
+ /* Check if transmit FIFO is empty.
+ * If not we'll wait for TX_READY interrupt. */
+
+ if (!(readl(MSM_BOOT_UART_DM_SR(base)) & MSM_BOOT_UART_DM_SR_TXEMT)) {
+ while (!(readl(MSM_BOOT_UART_DM_ISR(base)) & MSM_BOOT_UART_DM_TX_READY))
+ __udelay(1);
+ }
+
+ /* We are here. FIFO is ready to be written. */
+ /* Write number of characters to be written */
+ writel(num_of_chars, MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base));
+
+ /* Clear TX_READY interrupt */
+ writel(MSM_BOOT_UART_DM_GCMD_RES_TX_RDY_INT, MSM_BOOT_UART_DM_CR(base));
+
+ /* We use four-character word FIFO. So we need to divide data into
+ * four characters and write in UART_DM_TF register */
+ tx_word_count = (num_of_chars % 4) ? ((num_of_chars / 4) + 1) :
+ (num_of_chars / 4);
+ tx_char_left = num_of_chars;
+
+ for (i = 0; i < (int)tx_word_count; i++) {
+ tx_char = (tx_char_left < 4) ? tx_char_left : 4;
+ PACK_CHARS_INTO_WORDS(tx_data, tx_char, tx_word);
+
+ /* Wait till TX FIFO has space */
+ while (!(readl(MSM_BOOT_UART_DM_SR(base)) & MSM_BOOT_UART_DM_SR_TXRDY))
+ __udelay(1);
+
+ /* TX FIFO has space. Write the chars */
+ writel(tx_word, MSM_BOOT_UART_DM_TF(base, 0));
+ tx_char_left = num_of_chars - (i + 1) * 4;
+ tx_data = tx_data + 4;
+ }
+
+ return MSM_BOOT_UART_DM_E_SUCCESS;
+}
+
+/*
+ * msm_boot_uart_dm_reset - resets UART controller
+ * @base: UART controller base address
+ */
+static unsigned int msm_boot_uart_dm_reset(unsigned int base)
+{
+ writel(MSM_BOOT_UART_DM_CMD_RESET_RX, MSM_BOOT_UART_DM_CR(base));
+ writel(MSM_BOOT_UART_DM_CMD_RESET_TX, MSM_BOOT_UART_DM_CR(base));
+ writel(MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT, MSM_BOOT_UART_DM_CR(base));
+ writel(MSM_BOOT_UART_DM_CMD_RES_TX_ERR, MSM_BOOT_UART_DM_CR(base));
+ writel(MSM_BOOT_UART_DM_CMD_RES_STALE_INT, MSM_BOOT_UART_DM_CR(base));
+
+ return MSM_BOOT_UART_DM_E_SUCCESS;
+}
+
+/*
+ * msm_boot_uart_dm_init - initilaizes UART controller
+ * @uart_dm_base: UART controller base address
+ */
+static unsigned int msm_boot_uart_dm_init(unsigned int uart_dm_base)
+{
+ /* Configure UART mode registers MR1 and MR2 */
+ /* Hardware flow control isn't supported */
+ writel(0x0, MSM_BOOT_UART_DM_MR1(uart_dm_base));
+
+ /* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */
+ writel(MSM_BOOT_UART_DM_8_N_1_MODE, MSM_BOOT_UART_DM_MR2(uart_dm_base));
+
+ /* Configure Interrupt Mask register IMR */
+ writel(MSM_BOOT_UART_DM_IMR_ENABLED, MSM_BOOT_UART_DM_IMR(uart_dm_base));
+
+ /*
+ * Configure Tx and Rx watermarks configuration registers
+ * TX watermark value is set to 0 - interrupt is generated when
+ * FIFO level is less than or equal to 0
+ */
+ writel(MSM_BOOT_UART_DM_TFW_VALUE, MSM_BOOT_UART_DM_TFWR(uart_dm_base));
+
+ /* RX watermark value */
+ writel(MSM_BOOT_UART_DM_RFW_VALUE, MSM_BOOT_UART_DM_RFWR(uart_dm_base));
+
+ /* Configure Interrupt Programming Register */
+ /* Set initial Stale timeout value */
+ writel(MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB,
+ MSM_BOOT_UART_DM_IPR(uart_dm_base));
+
+ /* Configure IRDA if required */
+ /* Disabling IRDA mode */
+ writel(0x0, MSM_BOOT_UART_DM_IRDA(uart_dm_base));
+
+ /* Configure hunt character value in HCR register */
+ /* Keep it in reset state */
+ writel(0x0, MSM_BOOT_UART_DM_HCR(uart_dm_base));
+
+ /*
+ * Configure Rx FIFO base address
+ * Both TX/RX shares same SRAM and default is half-n-half.
+ * Sticking with default value now.
+ * As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries).
+ * We have found RAM_ADDR_WIDTH = 0x7f
+ */
+
+ /* Issue soft reset command */
+ msm_boot_uart_dm_reset(uart_dm_base);
+
+ /* Enable/Disable Rx/Tx DM interfaces */
+ /* Data Mover not currently utilized. */
+ writel(0x0, MSM_BOOT_UART_DM_DMEN(uart_dm_base));
+
+ /* Enable transmitter */
+ writel(MSM_BOOT_UART_DM_CR_TX_ENABLE,
+ MSM_BOOT_UART_DM_CR(uart_dm_base));
+
+ /* Initialize Receive Path */
+ msm_boot_uart_dm_init_rx_transfer(uart_dm_base);
+
+ return 0;
+}
+
+/**
+ * uart_dm_init - initializes UART
+ *
+ * Initializes clocks, GPIO and UART controller.
+ */
+static int uart_dm_init(void)
+{
+ unsigned int dm_base, gsbi_base;
+
+ dm_base = gboard_param->uart_dm_base;
+ gsbi_base = gboard_param->uart_gsbi_base;
+ ipq_configure_gpio(gboard_param->dbg_uart_gpio, NO_OF_DBG_UART_GPIOS);
+
+ /* Configure the uart clock */
+ uart_clock_config(gboard_param->uart_gsbi,
+ gboard_param->mnd_value.m_value,
+ gboard_param->mnd_value.n_value,
+ gboard_param->mnd_value.d_value,
+ gboard_param->clk_dummy);
+
+ writel(GSBI_PROTOCOL_CODE_I2C_UART <<
+ GSBI_CTRL_REG_PROTOCOL_CODE_S,
+ GSBI_CTRL_REG(gsbi_base));
+ writel(UART_DM_CLK_RX_TX_BIT_RATE, MSM_BOOT_UART_DM_CSR(dm_base));
+ /* Intialize UART_DM */
+ msm_boot_uart_dm_init(dm_base);
+
+ return 0;
+}
+
+/**
+ * ipq806x_serial_putc - transmits a character
+ * @c: character to transmit
+ */
+static void ipq806x_serial_putc(char c)
+{
+ msm_boot_uart_dm_write(&c, 1);
+}
+
+/**
+ * ipq806x_serial_puts - transmits a string of data
+ * @s: string to transmit
+ */
+static void ipq806x_serial_puts(const char *s)
+{
+ while (*s != '\0')
+ serial_putc(*s++);
+}
+
+/**
+ * ipq806x_serial_tstc - checks if data available for reading
+ *
+ * Returns 1 if data available, 0 otherwise
+ */
+static int ipq806x_serial_tstc(void)
+{
+ /* Return if data is already read */
+ if (valid_data)
+ return 1;
+
+ /* Read data from the FIFO */
+ if (msm_boot_uart_dm_read(&word, &valid_data, 0) != MSM_BOOT_UART_DM_E_SUCCESS)
+ return 0;
+
+ return 1;
+}
+
+/**
+ * ipq806x_serial_getc - reads a character
+ *
+ * Returns the character read from serial port.
+ */
+static int ipq806x_serial_getc(void)
+{
+ int byte;
+
+ while (!serial_tstc()) {
+ /* wait for incoming data */
+ }
+
+ byte = (int)word & 0xff;
+ word = word >> 8;
+ valid_data--;
+
+ return byte;
+}
+
+static struct serial_device ipq_serial_device = {
+ .name = "ipq_serial",
+ .start = uart_dm_init,
+ .getc = ipq806x_serial_getc,
+ .tstc = ipq806x_serial_tstc,
+ .putc = ipq806x_serial_putc,
+ .puts = ipq806x_serial_puts,
+};
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &ipq_serial_device;
+}
+
+/**
+ * ipq806x_serial_init - initializes serial controller
+ */
+void ipq806x_serial_initialize(void)
+{
+ serial_register(&ipq_serial_device);
+}
Marc Jones (marc.jones(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7879
-gerrit
commit bf88bdf144d578d11917ffe7b67485728d796ace
Author: Vadim Bendebury <vbendeb(a)chromium.org>
Date: Wed Apr 23 11:09:44 2014 -0700
ipq/arm: Redesign hooks for bootblock and add timer service
The IPQ timer service patch requires the additional squashed patches
to properly build all the different ARM boards.
ipq8064: make timer services available
Make sure it is initialized at different stages.
BUG=chrome-os-partner:27784
TEST=manual
. not much at this point, just verified that it compiles
Original-Change-Id: I343e7a6648e2ca935606cd76befd204aabd93726
Original-Signed-off-by: Vadim Bendebury <vbendeb(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/196592
(cherry picked from commit aedc41924313e5c21aef97b036f5a0643d59082d)
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
ipq8064: storm: re-arrange bootblock initialization
The recent addition of the storm bootblock initialization broke
compilation of Exynos platforms. The SOC specific code needs to be
kept in the respective source files, not in the common CPU code.
As of now coreboot does not provide a separate SOC initialization API.
In general it makes sense to invoke SOC initialization from the board
initialization code, as the board knows what SOC it is running on.
Presently all what's need initialization on 8064 is the timer. This
patch adds the SOC initialization framework for 8064 and moves there
the related code.
BUG=chrome-os-partner:27784
TEST=manual
. nyan_big, peach_pit, and storm targets build fine now.
Original-Change-Id: Iae9a021f8cbf7d009770b02d798147a3e08420e8
Original-Signed-off-by: Vadim Bendebury <vbendeb(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/197835
(cherry picked from commit 3ea7307b531b1a78c692e4f71a0d81b32108ebf0)
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
arm: Redesign mainboard and SoC hooks for bootblock
This patch makes some slight changes to the way bootblock_cpu_init() and
bootblock_mainboard_init() are used on ARM. Experience has shown that
nearly every board needs either one or both of these hooks, so having
explicit Kconfigs for them has become unwieldy. Instead, this patch
implements them as a weak symbol that can be overridden by mainboard/SoC
code, as the more recent arm64_soc_init() is also doing.
Since the whole concept of a single "CPU" on ARM systems has kinda died
out, rename bootblock_cpu_init() to bootblock_soc_init(). (This had
already been done on Storm/ipq806x, which is now adjusted to directly
use the generic hook.) Also add a proper license header to
bootblock_common.h that was somehow missing.
Leaving non-ARM32 architectures out for now, since they are still using
the really old and weird x86 model of directly including a file. These
architectures should also eventually be aligned with the cleaner ARM32
model as they mature.
BRANCH=None
BUG=chrome-os-partner:32123
TEST=Booted on Pinky. Compiled for Storm and confirmed in the
disassembly that bootblock_soc_init() is still compiled in and called
right before the (now no-op) bootblock_mainboard_init().
Original-Change-Id: I57013b99c3af455cc3d7e78f344888d27ffb8d79
Original-Signed-off-by: Julius Werner <jwerner(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/231940
Original-Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
(cherry picked from commit 257aaee9e3aeeffe50ed54de7342dd2bc9baae76)
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
Change-Id: Id055fe60a8caf63a9787138811dc69ac04dfba57
---
src/arch/arm/armv4/bootblock_simple.c | 5 ++++-
src/arch/arm/armv7/bootblock_simple.c | 5 ++++-
src/arch/arm/include/bootblock_common.h | 38 ++++++++++++++++++++++-----------
src/cpu/allwinner/a10/bootblock.c | 2 +-
src/cpu/armltd/cortex-a9/Kconfig | 6 ------
src/cpu/armltd/cortex-a9/bootblock.c | 17 ---------------
src/cpu/ti/am335x/bootblock.c | 2 +-
src/mainboard/google/storm/mainboard.c | 5 +++--
src/soc/qualcomm/ipq806x/Makefile.inc | 22 +++++++++++++++++++
src/soc/qualcomm/ipq806x/bootblock.c | 26 ++++++++++++++++++++++
src/soc/qualcomm/ipq806x/timer.c | 2 +-
src/soc/samsung/exynos5250/bootblock.c | 2 +-
src/soc/samsung/exynos5420/bootblock.c | 2 +-
13 files changed, 89 insertions(+), 45 deletions(-)
diff --git a/src/arch/arm/armv4/bootblock_simple.c b/src/arch/arm/armv4/bootblock_simple.c
index 207279b..15b6bde 100644
--- a/src/arch/arm/armv4/bootblock_simple.c
+++ b/src/arch/arm/armv4/bootblock_simple.c
@@ -26,12 +26,15 @@
#include <console/console.h>
#include <halt.h>
+__attribute__((weak)) void bootblock_soc_init(void) { /* do nothing */ }
+__attribute__((weak)) void bootblock_mainboard_init(void) { /* do nothing */ }
+
void main(void)
{
const char *stage_name = "fallback/romstage";
void *entry;
- bootblock_cpu_init();
+ bootblock_soc_init();
bootblock_mainboard_init();
if (CONFIG_BOOTBLOCK_CONSOLE) {
diff --git a/src/arch/arm/armv7/bootblock_simple.c b/src/arch/arm/armv7/bootblock_simple.c
index aad63b6..2fc000d 100644
--- a/src/arch/arm/armv7/bootblock_simple.c
+++ b/src/arch/arm/armv7/bootblock_simple.c
@@ -28,12 +28,15 @@
#include <halt.h>
#include <smp/node.h>
+__attribute__((weak)) void bootblock_soc_init(void) { /* do nothing */ }
+__attribute__((weak)) void bootblock_mainboard_init(void) { /* do nothing */ }
+
void main(void)
{
const char *stage_name = "fallback/romstage";
void *entry;
- bootblock_cpu_init();
+ bootblock_soc_init();
bootblock_mainboard_init();
#if CONFIG_BOOTBLOCK_CONSOLE
diff --git a/src/arch/arm/include/bootblock_common.h b/src/arch/arm/include/bootblock_common.h
index 034a12b..413a206 100644
--- a/src/arch/arm/include/bootblock_common.h
+++ b/src/arch/arm/include/bootblock_common.h
@@ -1,15 +1,27 @@
-#if CONFIG_CPU_HAS_BOOTBLOCK_INIT
-void bootblock_cpu_init(void);
-#else
-static void __attribute__((unused)) bootblock_cpu_init(void)
-{
-}
-#endif
+/*
+ * 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
+ */
-#if CONFIG_MAINBOARD_HAS_BOOTBLOCK_INIT
+#ifndef __ARCH_BOOTBLOCK_COMMON_H
+#define __ARCH_BOOTBLOCK_COMMON_H
+
+/* These are defined as weak no-ops that can be overridden by mainboard/SoC. */
void bootblock_mainboard_init(void);
-#else
-static void __attribute__((unused)) bootblock_mainboard_init(void)
-{
-}
-#endif
+void bootblock_soc_init(void);
+
+#endif /* __ARCH_BOOTBLOCK_COMMON_H */
diff --git a/src/cpu/allwinner/a10/bootblock.c b/src/cpu/allwinner/a10/bootblock.c
index d470755..808982c 100644
--- a/src/cpu/allwinner/a10/bootblock.c
+++ b/src/cpu/allwinner/a10/bootblock.c
@@ -10,7 +10,7 @@
#include <arch/cache.h>
#include <bootblock_common.h>
-void bootblock_cpu_init(void)
+void bootblock_soc_init(void)
{
uint32_t sctlr;
diff --git a/src/cpu/armltd/cortex-a9/Kconfig b/src/cpu/armltd/cortex-a9/Kconfig
index c456847..fb6cd0f 100644
--- a/src/cpu/armltd/cortex-a9/Kconfig
+++ b/src/cpu/armltd/cortex-a9/Kconfig
@@ -7,10 +7,4 @@ config CPU_ARMLTD_CORTEX_A9
if CPU_ARMLTD_CORTEX_A9
-config BOOTBLOCK_CPU_INIT
- string
- default "cpu/armltd/cortex-a9/bootblock.c"
- help
- CPU/SoC-specific bootblock code.
-
endif
diff --git a/src/cpu/armltd/cortex-a9/bootblock.c b/src/cpu/armltd/cortex-a9/bootblock.c
deleted file mode 100644
index 8925439..0000000
--- a/src/cpu/armltd/cortex-a9/bootblock.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2013 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- */
-
-void bootblock_cpu_init(void);
-void bootblock_cpu_init(void)
-{
-}
diff --git a/src/cpu/ti/am335x/bootblock.c b/src/cpu/ti/am335x/bootblock.c
index 04c9304..f586e17 100644
--- a/src/cpu/ti/am335x/bootblock.c
+++ b/src/cpu/ti/am335x/bootblock.c
@@ -22,7 +22,7 @@
#include <arch/cache.h>
#include <bootblock_common.h>
-void bootblock_cpu_init(void)
+void bootblock_soc_init(void)
{
uint32_t sctlr;
diff --git a/src/mainboard/google/storm/mainboard.c b/src/mainboard/google/storm/mainboard.c
index 0b0182f..89ed8da 100644
--- a/src/mainboard/google/storm/mainboard.c
+++ b/src/mainboard/google/storm/mainboard.c
@@ -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
@@ -17,11 +17,12 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <device/device.h>
#include <boot/coreboot_tables.h>
+#include <device/device.h>
static void mainboard_init(device_t dev)
{
+ /* Not sure if this is needed at all */
}
static void mainboard_enable(device_t dev)
diff --git a/src/soc/qualcomm/ipq806x/Makefile.inc b/src/soc/qualcomm/ipq806x/Makefile.inc
index cffcc12..dfbbf3d 100644
--- a/src/soc/qualcomm/ipq806x/Makefile.inc
+++ b/src/soc/qualcomm/ipq806x/Makefile.inc
@@ -1,10 +1,32 @@
+##
+## 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
+##
+
+bootblock-y += bootblock.c
bootblock-y += cbfs.c
bootblock-y += clock.c
bootblock-y += gpio.c
+bootblock-y += timer.c
romstage-y += cbfs.c
romstage-y += clock.c
romstage-y += gpio.c
+romstage-y += timer.c
ramstage-y += cbfs.c
ramstage-y += clock.c
diff --git a/src/soc/qualcomm/ipq806x/bootblock.c b/src/soc/qualcomm/ipq806x/bootblock.c
new file mode 100644
index 0000000..a079d42
--- /dev/null
+++ b/src/soc/qualcomm/ipq806x/bootblock.c
@@ -0,0 +1,26 @@
+/*
+ * 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 <bootblock_common.h>
+#include <delay.h>
+
+void bootblock_soc_init(void)
+{
+ init_timer();
+}
diff --git a/src/soc/qualcomm/ipq806x/timer.c b/src/soc/qualcomm/ipq806x/timer.c
index 5c0dcb2..0d44e4a 100644
--- a/src/soc/qualcomm/ipq806x/timer.c
+++ b/src/soc/qualcomm/ipq806x/timer.c
@@ -40,7 +40,7 @@
#define GPT_FREQ (GPT_FREQ_KHZ * 1000) /* 32 KHz */
/**
- * timer_init - initialize timer
+ * init_timer - initialize timer
*/
void init_timer(void)
{
diff --git a/src/soc/samsung/exynos5250/bootblock.c b/src/soc/samsung/exynos5250/bootblock.c
index f524399..1f101d6 100644
--- a/src/soc/samsung/exynos5250/bootblock.c
+++ b/src/soc/samsung/exynos5250/bootblock.c
@@ -22,7 +22,7 @@
#include "clk.h"
#include "wakeup.h"
-void bootblock_cpu_init(void)
+void bootblock_soc_init(void)
{
/* kick off the multi-core timer.
* We want to do this as early as we can.
diff --git a/src/soc/samsung/exynos5420/bootblock.c b/src/soc/samsung/exynos5420/bootblock.c
index 5d2d2b7..d5f92ee 100644
--- a/src/soc/samsung/exynos5420/bootblock.c
+++ b/src/soc/samsung/exynos5420/bootblock.c
@@ -29,7 +29,7 @@
#define SRAM_SIZE 1
#define SRAM_END (SRAM_START + SRAM_SIZE) /* plus one... */
-void bootblock_cpu_init(void)
+void bootblock_soc_init(void)
{
/* kick off the multi-core timer.
* We want to do this as early as we can.