From f6f42293d1a289c6db3dc9a0373169520d50f569 Mon Sep 17 00:00:00 2001
From: Sebastien Bourdeauducq <sebastien@milkymist.org>
Date: Tue, 22 May 2012 13:23:44 +0200
Subject: [PATCH] Clock frequency detection

---
 milkymist/identifier/__init__.py        | 10 +++++++---
 software/bios/Makefile                  |  2 +-
 software/bios/boot.c                    |  2 +-
 software/bios/main.c                    |  2 +-
 software/{bios => include/base}/timer.h |  0
 software/include/hw/id.h                |  6 +++++-
 software/libbase/Makefile               |  2 +-
 software/libbase/board.c                |  4 +++-
 software/{bios => libbase}/timer.c      |  6 +++++-
 top.py                                  |  2 +-
 10 files changed, 25 insertions(+), 11 deletions(-)
 rename software/{bios => include/base}/timer.h (100%)
 rename software/{bios => libbase}/timer.c (93%)

diff --git a/milkymist/identifier/__init__.py b/milkymist/identifier/__init__.py
index 380022520..9ddeda789 100644
--- a/milkymist/identifier/__init__.py
+++ b/milkymist/identifier/__init__.py
@@ -16,17 +16,21 @@ def encode_version(version):
 	return r
 
 class Identifier:
-	def __init__(self, address, sysid, version):
+	def __init__(self, address, sysid, version, frequency):
 		self.sysid = sysid
 		self.version = encode_version(version)
+		self.frequency = frequency
 		
 		self._r_sysid = RegisterField("sysid", 16, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
 		self._r_version = RegisterField("version", 16, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
-		self.bank = csrgen.Bank([self._r_sysid, self._r_version], address=address)
+		self._r_frequency = RegisterField("frequency", 32, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
+		regs = [self._r_sysid, self._r_version, self._r_frequency]
+		self.bank = csrgen.Bank(regs, address=address)
 		
 	def get_fragment(self):
 		comb = [
 			self._r_sysid.field.w.eq(self.sysid),
-			self._r_version.field.w.eq(self.version)
+			self._r_version.field.w.eq(self.version),
+			self._r_frequency.field.w.eq(self.frequency)
 		]
 		return self.bank.get_fragment() + Fragment(comb)
diff --git a/software/bios/Makefile b/software/bios/Makefile
index 1410b63d6..e96ef4469 100644
--- a/software/bios/Makefile
+++ b/software/bios/Makefile
@@ -1,7 +1,7 @@
 M2DIR=../..
 include $(M2DIR)/software/include.mak
 
-OBJECTS=crt0.o isr.o ddrinit.o timer.o main.o microudp.o tftp.o boot-helper.o boot.o
+OBJECTS=crt0.o isr.o ddrinit.o main.o microudp.o tftp.o boot-helper.o boot.o
 
 all: bios.bin
 
diff --git a/software/bios/boot.c b/software/bios/boot.c
index f4227e315..3ea515fdd 100644
--- a/software/bios/boot.c
+++ b/software/bios/boot.c
@@ -24,11 +24,11 @@
 #include <sfl.h>
 #include <string.h>
 #include <irq.h>
+#include <timer.h>
 
 #include <hw/flash.h>
 #include <hw/mem.h>
 
-#include "timer.h"
 #include "microudp.h"
 #include "tftp.h"
 #include "boot.h"
diff --git a/software/bios/main.c b/software/bios/main.c
index dc5a3e203..1aeb4c654 100644
--- a/software/bios/main.c
+++ b/software/bios/main.c
@@ -24,12 +24,12 @@
 #include <irq.h>
 #include <version.h>
 #include <extra/crc.h>
+#include <timer.h>
 
 #include <hw/flash.h>
 #include <hw/minimac.h>
 
 #include "ddrinit.h"
-#include "timer.h"
 #include "boot.h"
 
 enum {
diff --git a/software/bios/timer.h b/software/include/base/timer.h
similarity index 100%
rename from software/bios/timer.h
rename to software/include/base/timer.h
diff --git a/software/include/hw/id.h b/software/include/hw/id.h
index 48c928ea5..ae564e5fa 100644
--- a/software/include/hw/id.h
+++ b/software/include/hw/id.h
@@ -26,6 +26,10 @@
 #define CSR_ID_SYSTEMH		ID_CSR(0x00)
 #define CSR_ID_SYSTEML		ID_CSR(0x04)
 #define CSR_ID_VERSIONH		ID_CSR(0x08)
-#define CSR_ID_VERSIONL		ID_CSR(0x0c)
+#define CSR_ID_VERSIONL		ID_CSR(0x0C)
+#define CSR_ID_FREQ3		ID_CSR(0x10)
+#define CSR_ID_FREQ2		ID_CSR(0x14)
+#define CSR_ID_FREQ1		ID_CSR(0x18)
+#define CSR_ID_FREQ0		ID_CSR(0x1C)
 
 #endif /* __HW_ID_H */
diff --git a/software/libbase/Makefile b/software/libbase/Makefile
index 0ee64cc6d..e3ddbfb8e 100644
--- a/software/libbase/Makefile
+++ b/software/libbase/Makefile
@@ -1,7 +1,7 @@
 M2DIR=../..
 include $(M2DIR)/software/include.mak
 
-OBJECTS=divsi3.o libc.o console.o system.o board.o uart.o softfloat.o softfloat-glue.o vsnprintf.o atof.o
+OBJECTS=divsi3.o libc.o console.o timer.o system.o board.o uart.o softfloat.o softfloat-glue.o vsnprintf.o atof.o
 
 all: libbase.a
 
diff --git a/software/libbase/board.c b/software/libbase/board.c
index b8adcfe96..fc9a122de 100644
--- a/software/libbase/board.c
+++ b/software/libbase/board.c
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <version.h>
+#include <timer.h>
 #include <board.h>
 
 static const struct board_desc boards[1] = {
@@ -106,7 +107,8 @@ void board_init(void)
 	}
 	rev = get_pcb_revision();
 	get_soc_version_formatted(soc_version);
-	printf("Detected SoC %s on %s (PCB revision %d)\n", soc_version, brd_desc->name, rev);
+	printf("Detected SoC %s at %dMHz on %s (PCB revision %d)\n", soc_version, get_system_frequency()/1000000,
+	       brd_desc->name, rev);
 	if(strcmp(soc_version, VERSION) != 0)
 		printf("SoC and BIOS versions do not match!\n");
 	if(rev > 2)
diff --git a/software/bios/timer.c b/software/libbase/timer.c
similarity index 93%
rename from software/bios/timer.c
rename to software/libbase/timer.c
index 14e6a8c56..98bb879d5 100644
--- a/software/bios/timer.c
+++ b/software/libbase/timer.c
@@ -16,12 +16,16 @@
  */
 
 #include <hw/timer.h>
+#include <hw/id.h>
 
 #include "timer.h"
 
 unsigned int get_system_frequency(void)
 {
-	return 83333333; /* TODO */
+	return (CSR_ID_FREQ3 << 24)
+		|(CSR_ID_FREQ2 << 16)
+		|(CSR_ID_FREQ1 << 8)
+		|CSR_ID_FREQ0;
 }
 
 void timer_enable(int en)
diff --git a/top.py b/top.py
index 53b4c04d8..0c146287e 100644
--- a/top.py
+++ b/top.py
@@ -120,7 +120,7 @@ def get():
 	# CSR
 	#
 	uart0 = uart.UART(csr_offset("UART"), clk_freq, baud=115200)
-	identifier0 = identifier.Identifier(csr_offset("ID"), 0x4D31, version)
+	identifier0 = identifier.Identifier(csr_offset("ID"), 0x4D31, version, int(clk_freq))
 	timer0 = timer.Timer(csr_offset("TIMER0"))
 	csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
 		uart0.bank.interface,