-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This adds a timer and serial driver to libplatsupport. Co-developed-by: Ivan-Velickovic <i.velickovic@unsw.edu.au> Signed-off-by: Jimmy Brush <code@jimmah.com>
- Loading branch information
1 parent
dba244d
commit d95392e
Showing
6 changed files
with
636 additions
and
0 deletions.
There are no files selected for viewing
39 changes: 39 additions & 0 deletions
39
libplatsupport/plat_include/star64/platsupport/plat/serial.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Copyright 2023, UNSW | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
||
#pragma once | ||
#include <autoconf.h> | ||
|
||
/* The StarFive JH7110 SoC contains five 8250 compatible UARTs. */ | ||
|
||
enum chardev_id { | ||
UART0, | ||
UART1, | ||
UART2, | ||
UART3, | ||
UART4, | ||
UART5, | ||
PS_SERIAL_DEFAULT = UART0 | ||
}; | ||
|
||
#define UART0_PADDR 0x10000000 | ||
#define UART1_PADDR 0x10010000 | ||
#define UART2_PADDR 0x10020000 | ||
#define UART3_PADDR 0x12000000 | ||
#define UART4_PADDR 0x12010000 | ||
#define UART5_PADDR 0x12020000 | ||
|
||
#define UART0_IRQ 32 | ||
#define UART1_IRQ 33 | ||
#define UART2_IRQ 34 | ||
#define UART3_IRQ 45 | ||
#define UART4_IRQ 46 | ||
#define UART5_IRQ 47 | ||
|
||
/* The default serial device corresponds to the UART available via the GPIO | ||
* pins of the Star64 Model-A. */ | ||
#define DEFAULT_SERIAL_PADDR UART0_PADDR | ||
#define DEFAULT_SERIAL_INTERRUPT UART0_IRQ |
71 changes: 71 additions & 0 deletions
71
libplatsupport/plat_include/star64/platsupport/plat/timer.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* | ||
* Copyright 2023, UNSW | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
#pragma once | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
|
||
/* | ||
* The JH7110 SoC contains a timer with four 32-bit counters. Each one of these | ||
* counters is referred to as a "channel". | ||
*/ | ||
|
||
/* Channel information */ | ||
#define STARFIVE_TIMER_NUM_CHANNELS 4 | ||
#define STARFIVE_TIMER_CHANNEL_REGISTERS_LEN_IN_BYTES 0x40 | ||
#define STARFIVE_TIMER_CHANNEL_0_IRQ 69 | ||
#define STARFIVE_TIMER_CHANNEL_1_IRQ 70 | ||
#define STARFIVE_TIMER_CHANNEL_2_IRQ 71 | ||
#define STARFIVE_TIMER_CHANNEL_3_IRQ 72 | ||
|
||
/* This information comes from the DTS file */ | ||
#define STARFIVE_TIMER_BASE 0x13050000 | ||
#define STARFIVE_TIMER_REGISTER_WINDOW_LEN_IN_BYTES 0x10000 | ||
#define STARFIVE_TIMER_TICKS_PER_SECOND 0x16e3600 | ||
|
||
#define STARFIVE_TIMER_MAX_TICKS 0xffffffff | ||
|
||
/* Register value constants */ | ||
#define STARFIVE_TIMER_MODE_CONTINUOUS 0 | ||
#define STARFIVE_TIMER_MODE_SINGLE 1 | ||
#define STARFIVE_TIMER_DISABLED 0 | ||
#define STARFIVE_TIMER_ENABLED 1 | ||
#define STARFIVE_TIMER_INTERRUPT_UNMASKED 0 | ||
#define STARFIVE_TIMER_INTERRUPT_MASKED 1 | ||
#define STARFIVE_TIMER_INTCLR_BUSY BIT(1) | ||
|
||
typedef struct { | ||
/* Registers */ | ||
/* this register doesn't seem to do anything */ | ||
uint32_t status; | ||
uint32_t ctrl; | ||
uint32_t load; | ||
uint32_t unknown1; | ||
uint32_t enable; | ||
uint32_t reload; | ||
uint32_t value; | ||
uint32_t unknown2; | ||
uint32_t intclr; | ||
uint32_t intmask; | ||
} starfive_timer_regs_t; | ||
|
||
typedef struct { | ||
volatile starfive_timer_regs_t *regs; | ||
/* | ||
* Stores the number of times the continuous counter timer has elapsed and started over. | ||
* This allows us to count to a higher number than allowed by the hardware. | ||
*/ | ||
uint32_t value_h; | ||
} starfive_timer_t; | ||
|
||
void starfive_timer_start(starfive_timer_t *timer); | ||
void starfive_timer_stop(starfive_timer_t *timer); | ||
void starfive_timer_handle_irq(starfive_timer_t *timer); | ||
uint64_t starfive_timer_get_time(starfive_timer_t *timer); | ||
void starfive_timer_reset(starfive_timer_t *timer); | ||
int starfive_timer_set_timeout(starfive_timer_t *timer, uint64_t ns, bool is_periodic); | ||
void starfive_timer_disable_all_channels(void *vaddr); | ||
void starfive_timer_init(starfive_timer_t *timer, void *vaddr, uint64_t channel); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Copyright 2023, UNSW | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
||
#include "../../chardev.h" | ||
#include "../../common.h" | ||
#include <utils/util.h> | ||
|
||
static const int uart0_irqs[] = {UART0_IRQ, -1}; | ||
static const int uart1_irqs[] = {UART1_IRQ, -1}; | ||
static const int uart2_irqs[] = {UART2_IRQ, -1}; | ||
static const int uart3_irqs[] = {UART3_IRQ, -1}; | ||
static const int uart4_irqs[] = {UART4_IRQ, -1}; | ||
static const int uart5_irqs[] = {UART5_IRQ, -1}; | ||
|
||
/* | ||
* Despite each UART being 0x10000 in size (according to the device tree) we | ||
* only need to map in the first page for the driver to functon. | ||
*/ | ||
#define UART_DEFN(devid) { \ | ||
.id = UART##devid, \ | ||
.paddr = UART##devid##_PADDR, \ | ||
.size = BIT(12), \ | ||
.irqs = uart##devid##_irqs, \ | ||
.init_fn = &uart_init \ | ||
} | ||
|
||
const struct dev_defn dev_defn[] = { | ||
UART_DEFN(0), | ||
UART_DEFN(1), | ||
UART_DEFN(2), | ||
UART_DEFN(3), | ||
UART_DEFN(4), | ||
UART_DEFN(5), | ||
}; | ||
|
||
struct ps_chardevice* | ||
ps_cdev_init(enum chardev_id id, const ps_io_ops_t* o, struct ps_chardevice* d) { | ||
unsigned int i; | ||
for (i = 0; i < ARRAY_SIZE(dev_defn); i++) { | ||
if (dev_defn[i].id == id) { | ||
return (dev_defn[i].init_fn(dev_defn + i, o, d)) ? NULL : d; | ||
} | ||
} | ||
return NULL; | ||
} |
Oops, something went wrong.