You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
microwatt/litedram/gen-src/sdram_init/main.c

157 lines
3.2 KiB
C

#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include <stdio.h>
#include <generated/git.h>
#include "microwatt_soc.h"
#include "io.h"
#include "sdram.h"
/*
* Core UART functions to implement for a port
*/
static uint64_t potato_uart_base;
#define PROC_FREQ 100000000
#define UART_FREQ 115200
static uint8_t potato_uart_reg_read(int offset)
{
return readb(potato_uart_base + offset);
}
static void potato_uart_reg_write(int offset, uint8_t val)
{
writeb(val, potato_uart_base + offset);
}
static bool potato_uart_rx_empty(void)
{
uint8_t val = potato_uart_reg_read(POTATO_CONSOLE_STATUS);
return (val & POTATO_CONSOLE_STATUS_RX_EMPTY) != 0;
}
static int potato_uart_tx_full(void)
{
uint8_t val = potato_uart_reg_read(POTATO_CONSOLE_STATUS);
return (val & POTATO_CONSOLE_STATUS_TX_FULL) != 0;
}
static char potato_uart_read(void)
{
return potato_uart_reg_read(POTATO_CONSOLE_RX);
}
static void potato_uart_write(char c)
{
potato_uart_reg_write(POTATO_CONSOLE_TX, c);
}
static unsigned long potato_uart_divisor(unsigned long proc_freq,
unsigned long uart_freq)
{
return proc_freq / (uart_freq * 16) - 1;
}
void potato_uart_init(void)
{
potato_uart_base = UART_BASE;
potato_uart_reg_write(POTATO_CONSOLE_CLOCK_DIV,
potato_uart_divisor(PROC_FREQ, UART_FREQ));
}
int getchar(void)
{
while (potato_uart_rx_empty())
/* Do nothing */ ;
return potato_uart_read();
}
int putchar(int c)
{
while (potato_uart_tx_full())
/* Do Nothing */;
potato_uart_write(c);
return c;
}
void putstr(const char *str, unsigned long len)
{
for (unsigned long i = 0; i < len; i++) {
if (str[i] == '\n')
putchar('\r');
putchar(str[i]);
}
}
int _printf(const char *fmt, ...)
{
int count;
char buffer[320];
va_list ap;
va_start(ap, fmt);
count = vsnprintf(buffer, sizeof(buffer), fmt, ap);
va_end(ap);
putstr(buffer, count);
return count;
}
void flush_cpu_dcache(void) { }
void flush_cpu_icache(void) { }
void flush_l2_cache(void) { }
void main(void)
{
unsigned long long ftr, val;
int i;
/*
* Let things settle ... not sure why but the UART is
* not happy otherwise. The PLL might need to settle ?
*/
potato_uart_init();
for (i = 0; i < 100000; i++)
potato_uart_reg_read(POTATO_CONSOLE_STATUS);
printf("\n\nWelcome to Microwatt !\n\n");
/* TODO: Add core version information somewhere in syscon, possibly
* extracted from git
*/
printf(" Soc signature: %016llx\n",
(unsigned long long)readq(SYSCON_BASE + SYS_REG_SIGNATURE));
printf(" Soc features: ");
ftr = readq(SYSCON_BASE + SYS_REG_INFO);
if (ftr & SYS_REG_INFO_HAS_UART)
printf("UART ");
if (ftr & SYS_REG_INFO_HAS_DRAM)
printf("DRAM ");
printf("\n");
val = readq(SYSCON_BASE + SYS_REG_BRAMINFO);
printf(" BRAM: %lld KB\n", val / 1024);
if (ftr & SYS_REG_INFO_HAS_DRAM) {
val = readq(SYSCON_BASE + SYS_REG_DRAMINFO);
printf(" DRAM: %lld MB\n", val / (1024 * 1024));
}
val = readq(SYSCON_BASE + SYS_REG_CLKINFO);
printf(" CLK: %lld MHz\n", val / 1000000);
printf("\n");
if (ftr & SYS_REG_INFO_HAS_DRAM) {
printf("LiteDRAM built from Migen %s and LiteX %s\n",
MIGEN_GIT_SHA1, LITEX_GIT_SHA1);
sdrinit();
}
printf("Booting from BRAM...\n");
}