Skip to content

Commit

Permalink
Add pine64 star64 platform
Browse files Browse the repository at this point in the history
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
canarysnort01 committed Aug 22, 2023
1 parent dba244d commit 5d02912
Show file tree
Hide file tree
Showing 6 changed files with 641 additions and 0 deletions.
39 changes: 39 additions & 0 deletions libplatsupport/plat_include/star64/platsupport/plat/serial.h
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 libplatsupport/plat_include/star64/platsupport/plat/timer.h
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);
49 changes: 49 additions & 0 deletions libplatsupport/src/plat/star64/chardev.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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;
}
Loading

0 comments on commit 5d02912

Please sign in to comment.