@@ -285,6 +285,7 @@ LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
endif
LIBS += drivers/rtc/librtc.o
LIBS += drivers/serial/libserial.o
+LIBS += drivers/timer/libtimer.o
ifeq ($(CONFIG_GENERIC_LPC_TPM),y)
LIBS += drivers/tpm/libtpm.o
endif
new file mode 100644
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB := $(obj)libtimer.o
+
+COBJS-$(CONFIG_HPET_TIMER) += hpet.o
+
+COBJS := $(COBJS-y)
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+all: $(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
new file mode 100644
@@ -0,0 +1,101 @@
+/*
+ * (C) Copyright 2011
+ * Graeme Russ, <graeme.russ@gmail.com>
+ *
+ * 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
+ */
+
+/* High Precision Event Timers (HPET) */
+
+#include <common.h>
+#include <asm/io.h>
+#include <hpet.h>
+#include <div64.h>
+
+static struct hpet_regs *hpet_registers = (struct hpet_regs *)HPET_BASE_ADDR;
+
+int hpet_enable(void)
+{
+ u8 hpet8_val;
+
+ hpet8_val = readb(&hpet_registers->general_config);
+ hpet8_val |= HPET_ENABLE;
+ writeb(hpet8_val, &hpet_registers->general_config);
+
+ return 0;
+}
+
+void hpet_udelay(unsigned long usec)
+{
+ u32 count_low;
+ u32 count_high;
+ u32 fs_per_tick;
+ u64 fs_to_wait = (u64)usec * 1000000000;
+ u64 ticks_to_wait;
+ u64 end_count;
+
+ u32 end_count_low;
+ u32 end_count_high;
+
+ count_low = readl(&hpet_registers->main_count_low);
+ count_high = readl(&hpet_registers->main_count_high);
+ fs_per_tick = readl(&hpet_registers->counter_clk_period);
+
+ ticks_to_wait = lldiv(fs_to_wait, fs_per_tick);
+
+ end_count = ((u64)count_high << 32) | ((u64)count_low);
+ end_count += ticks_to_wait;
+
+ end_count_low = (u32)(end_count & 0x00000000ffffffffULL);
+ end_count_high = (u32)((end_count >> 32) & 0x00000000ffffffffULL);
+
+ while (1) {
+ count_low = readl(&hpet_registers->main_count_low);
+ count_high = readl(&hpet_registers->main_count_high);
+
+ if ((count_high > end_count_high) ||
+ ((count_high == end_count_high) &&
+ (count_low > end_count_low)))
+ break;
+ }
+}
+
+ulong hpet_get_timer(ulong base)
+{
+ u32 count_low;
+ u32 count_high;
+ u32 fs_per_tick;
+ u64 ticks;
+ u64 fs;
+ u32 ms;
+
+ count_low = readl(&hpet_registers->main_count_low);
+ count_high = readl(&hpet_registers->main_count_high);
+ fs_per_tick = readl(&hpet_registers->counter_clk_period);
+
+ ticks = ((u64)count_high << 32) | ((u64)count_low);
+
+ fs = fs_per_tick * ticks;
+
+ /* Allow a 64/32 bit division by dividing by 4096 */
+ ms = (u32)(lldiv(fs, 244140625) >> 12);
+
+ return ms - base;
+}
+
new file mode 100644
@@ -0,0 +1,69 @@
+/*
+ * (C) Copyright 2011
+ * Graeme Russ, <graeme.russ@gmail.com>
+ *
+ * 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
+ */
+
+/* High Precision Event Timers (HPET) */
+
+#ifndef __HPET_H__
+#define __HPET_H__
+#include <common.h>
+
+struct hpet_timer_regs {
+ u8 timer0_caps;
+ u8 timer0_cnf;
+ u16 timer0_reserved;
+ u32 timer0_int_route_cap;
+ u32 comparator_value;
+ u32 reserved_comparator_value;
+ u32 fsb_int_val;
+ u32 fsb_int_addr;
+ u8 reserved018[8];
+};
+
+struct hpet_regs {
+ u8 rev_id;
+ u8 general_caps;
+ u16 vendor_id;
+ u32 counter_clk_period;
+ u8 reserved008[8];
+ u8 general_config;
+ u8 reserved_manufacturer[3];
+ u8 reserved018[8];
+ u8 general_interupt_status;
+ u8 reserved_gen_int_sts[7];
+ u8 reserved028[200];
+ u32 main_count_high;
+ u32 main_count_low;
+ u8 reserved0f8[8];
+ struct hpet_timer_regs timer_regs[3];
+ u8 reserved160[672];
+};
+
+int hpet_dump_info(void);
+int hpet_enable(void);
+void hpet_udelay(unsigned long usec);
+ulong hpet_get_timer(ulong base);
+
+#define HPET_BASE_ADDR 0xfed00000
+#define HPET_ENABLE 0x01
+
+#endif