From: Sebastien Bourdeauducq Date: Tue, 22 May 2012 11:23:44 +0000 (+0200) Subject: Clock frequency detection X-Git-Tag: 24jan2021_ls180~3178 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f6f42293d1a289c6db3dc9a0373169520d50f569;p=litex.git Clock frequency detection --- diff --git a/milkymist/identifier/__init__.py b/milkymist/identifier/__init__.py index 38002252..9ddeda78 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 1410b63d..e96ef446 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 f4227e31..3ea515fd 100644 --- a/software/bios/boot.c +++ b/software/bios/boot.c @@ -24,11 +24,11 @@ #include #include #include +#include #include #include -#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 dc5a3e20..1aeb4c65 100644 --- a/software/bios/main.c +++ b/software/bios/main.c @@ -24,12 +24,12 @@ #include #include #include +#include #include #include #include "ddrinit.h" -#include "timer.h" #include "boot.h" enum { diff --git a/software/bios/timer.c b/software/bios/timer.c deleted file mode 100644 index 14e6a8c5..00000000 --- a/software/bios/timer.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Milkymist SoC (Software) - * Copyright (C) 2012 Sebastien Bourdeauducq - * - * 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 3 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, see . - */ - -#include - -#include "timer.h" - -unsigned int get_system_frequency(void) -{ - return 83333333; /* TODO */ -} - -void timer_enable(int en) -{ - CSR_TIMER0_EN = en; -} - -unsigned int timer_get(void) -{ - return (CSR_TIMER0_COUNT3 << 24) - |(CSR_TIMER0_COUNT2 << 16) - |(CSR_TIMER0_COUNT1 << 8) - |CSR_TIMER0_COUNT0; -} - -void timer_set_counter(unsigned int value) -{ - CSR_TIMER0_COUNT3 = (value & 0xff000000) >> 24; - CSR_TIMER0_COUNT2 = (value & 0x00ff0000) >> 16; - CSR_TIMER0_COUNT1 = (value & 0x0000ff00) >> 8; - CSR_TIMER0_COUNT0 = value & 0x000000ff; -} - -void timer_set_reload(unsigned int value) -{ - CSR_TIMER0_RELOAD3 = (value & 0xff000000) >> 24; - CSR_TIMER0_RELOAD2 = (value & 0x00ff0000) >> 16; - CSR_TIMER0_RELOAD1 = (value & 0x0000ff00) >> 8; - CSR_TIMER0_RELOAD0 = value & 0x000000ff; -} - -void busy_wait(unsigned int ds) -{ - timer_enable(0); - timer_set_reload(0); - timer_set_counter(get_system_frequency()/10*ds); - timer_enable(1); - while(timer_get()); -} diff --git a/software/bios/timer.h b/software/bios/timer.h deleted file mode 100644 index a7810ed2..00000000 --- a/software/bios/timer.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Milkymist SoC (Software) - * Copyright (C) 2012 Sebastien Bourdeauducq - * - * 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 3 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, see . - */ - -#ifndef __TIMER_H -#define __TIMER_H - -unsigned int get_system_frequency(void); -void timer_enable(int en); -unsigned int timer_get(void); -void timer_set_counter(unsigned int value); -void timer_set_reload(unsigned int value); -void busy_wait(unsigned int ms); - -#endif /* __TIMER_H */ diff --git a/software/include/base/timer.h b/software/include/base/timer.h new file mode 100644 index 00000000..a7810ed2 --- /dev/null +++ b/software/include/base/timer.h @@ -0,0 +1,28 @@ +/* + * Milkymist SoC (Software) + * Copyright (C) 2012 Sebastien Bourdeauducq + * + * 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 3 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, see . + */ + +#ifndef __TIMER_H +#define __TIMER_H + +unsigned int get_system_frequency(void); +void timer_enable(int en); +unsigned int timer_get(void); +void timer_set_counter(unsigned int value); +void timer_set_reload(unsigned int value); +void busy_wait(unsigned int ms); + +#endif /* __TIMER_H */ diff --git a/software/include/hw/id.h b/software/include/hw/id.h index 48c928ea..ae564e5f 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 0ee64cc6..e3ddbfb8 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 b8adcfe9..fc9a122d 100644 --- a/software/libbase/board.c +++ b/software/libbase/board.c @@ -21,6 +21,7 @@ #include #include #include +#include #include 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/libbase/timer.c b/software/libbase/timer.c new file mode 100644 index 00000000..98bb879d --- /dev/null +++ b/software/libbase/timer.c @@ -0,0 +1,67 @@ +/* + * Milkymist SoC (Software) + * Copyright (C) 2012 Sebastien Bourdeauducq + * + * 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 3 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, see . + */ + +#include +#include + +#include "timer.h" + +unsigned int get_system_frequency(void) +{ + return (CSR_ID_FREQ3 << 24) + |(CSR_ID_FREQ2 << 16) + |(CSR_ID_FREQ1 << 8) + |CSR_ID_FREQ0; +} + +void timer_enable(int en) +{ + CSR_TIMER0_EN = en; +} + +unsigned int timer_get(void) +{ + return (CSR_TIMER0_COUNT3 << 24) + |(CSR_TIMER0_COUNT2 << 16) + |(CSR_TIMER0_COUNT1 << 8) + |CSR_TIMER0_COUNT0; +} + +void timer_set_counter(unsigned int value) +{ + CSR_TIMER0_COUNT3 = (value & 0xff000000) >> 24; + CSR_TIMER0_COUNT2 = (value & 0x00ff0000) >> 16; + CSR_TIMER0_COUNT1 = (value & 0x0000ff00) >> 8; + CSR_TIMER0_COUNT0 = value & 0x000000ff; +} + +void timer_set_reload(unsigned int value) +{ + CSR_TIMER0_RELOAD3 = (value & 0xff000000) >> 24; + CSR_TIMER0_RELOAD2 = (value & 0x00ff0000) >> 16; + CSR_TIMER0_RELOAD1 = (value & 0x0000ff00) >> 8; + CSR_TIMER0_RELOAD0 = value & 0x000000ff; +} + +void busy_wait(unsigned int ds) +{ + timer_enable(0); + timer_set_reload(0); + timer_set_counter(get_system_frequency()/10*ds); + timer_enable(1); + while(timer_get()); +} diff --git a/top.py b/top.py index 53b4c04d..0c146287 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,