Skip to content

Commit

Permalink
[platform][vc4] fix time resolution, start genet driver, fix rpi2-tes…
Browse files Browse the repository at this point in the history
…t build
  • Loading branch information
cleverca22 committed Jan 14, 2020
1 parent 6177b60 commit b87e962
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 43 deletions.
4 changes: 2 additions & 2 deletions arch/vc4/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ static enum handler_return timer0_irq(void *arg);

lk_bigtime_t current_time_hires(void) {
//TODO, deal with rollover
return ( ((lk_bigtime_t)*REG32(ST_CHI)) << 32) | *REG32(ST_CLO);
return (( ((lk_bigtime_t)*REG32(ST_CHI)) << 32) | *REG32(ST_CLO)) / 1000;
}

lk_time_t current_time(void) {
return *REG32(ST_CLO);
return current_time_hires();
}

static platform_timer_callback timer_cb = 0;;
Expand Down
27 changes: 27 additions & 0 deletions platform/bcm28xx/genet.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// based on drivers/net/ethernet/broadcom/genet/bcmgenet.c from linux
// for PHY control, look at the cmd_bits variable in drivers/net/ethernet/broadcom/genet/bcmmii.c

#include <lk/reg.h>
#include <stdio.h>
#include <lk/console_cmd.h>
#include <platform/bcm28xx.h>
#include <lk/debug.h>

static int cmd_genet_dump(int argc, const cmd_args *argv);

STATIC_COMMAND_START
STATIC_COMMAND("dump_genet", "print genet information", &cmd_genet_dump)
STATIC_COMMAND_END(genet);

#define SYS_REV_CTRL (GENET_BASE + 0x0)

static int cmd_genet_dump(int argc, const cmd_args *argv) {
uint32_t reg = *REG32(SYS_REV_CTRL);
uint8_t major = (reg >> 24 & 0x0f);
if (major == 6) major = 5;
else if (major == 5) major = 4;
else if (major == 0) major = 1;

dprintf(INFO, "found GENET controller version %d\n", major);
return 0;
}
29 changes: 29 additions & 0 deletions platform/bcm28xx/include/platform/bcm28xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#define ARM_BASE (BCM_PERIPH_BASE_VIRT + 0xB000)
#define PM_BASE (BCM_PERIPH_BASE_VIRT + 0x100000)
#define CM_BASE (BCM_PERIPH_BASE_VIRT + 0x101000)
#define A2W_BASE (BCM_PERIPH_BASE_VIRT + 0x102000)
#define PCM_CLOCK_BASE (BCM_PERIPH_BASE_VIRT + 0x101098)
#define RNG_BASE (BCM_PERIPH_BASE_VIRT + 0x104000)
#define GPIO_BASE (BCM_PERIPH_BASE_VIRT + 0x200000)
Expand All @@ -55,13 +56,16 @@
#define SMI_BASE (BCM_PERIPH_BASE_VIRT + 0x600000)
#define BSC1_BASE (BCM_PERIPH_BASE_VIRT + 0x804000)
#define USB_BASE (BCM_PERIPH_BASE_VIRT + 0x980000)
#define GENET_BASE (0x7d580000) // TODO, this is before the normal BCM_PERIPH_BASE_VIRT bank
#define MCORE_BASE (BCM_PERIPH_BASE_VIRT + 0x0000)

#define ST_CS (ST_BASE + 0x0)
#define ST_CLO (ST_BASE + 0x4)
#define ST_CHI (ST_BASE + 0x8)
#define ST_C0 (ST_BASE + 0xc)

#define CM_VPUCTL (CM_BASE + 0x008)
#define CM_VPUDIV (CM_BASE + 0x00c)
#define CM_UARTCTL (CM_BASE + 0xf0)
#define CM_UARTDIV (CM_BASE + 0xf4)

Expand All @@ -70,19 +74,44 @@
#define IC0_SRC0 (IC0_BASE + 0x8)
#define IC0_SRC1 (IC0_BASE + 0xc)
#define IC0_VADDR (IC0_BASE + 0x30)
#define IC0_WAKEUP (IC0_BASE + 0x34)

#define IC1_C (IC1_BASE + 0x0)
#define IC1_S (IC1_BASE + 0x4)
#define IC1_SRC0 (IC1_BASE + 0x8)
#define IC1_SRC1 (IC1_BASE + 0xc)
#define IC1_VADDR (IC1_BASE + 0x30)
#define IC1_WAKEUP (IC1_BASE + 0x34)

#define PM_PASSWORD 0x5a000000
#define PM_RSTC (PM_BASE + 0x1c)
#define PM_RSTC_WRCFG_CLR 0xffffffcf // mask to keep everything but the watchdog config
#define PM_WDOG (PM_BASE + 0x24)
#define PM_WDOG_MASK 0x00000fff

#define A2W_PASSWORD 0x5a000000
#define A2W_PLLA_CTRL (A2W_BASE + 0x100)
#define A2W_PLLC_CTRL (A2W_BASE + 0x120)
#define A2W_PLLC_CTRL_PDIV_SET 0x00007000
#define A2W_PLLC_CTRL_NDIV_SET 0x000003ff
#define A2W_PLLC_CTRL_PDIV_LSB 12
#define A2W_PLLD_CTRL (A2W_BASE + 0x140)
#define A2W_PLLH_CTRL (A2W_BASE + 0x160)
#define A2W_PLLB_CTRL (A2W_BASE + 0x1e0)
#define A2W_PLLA_FRAC (A2W_BASE + 0x200)
#define A2W_PLLC_FRAC (A2W_BASE + 0x220)
#define A2W_PLLD_FRAC (A2W_BASE + 0x240)
#define A2W_PLLH_FRAC (A2W_BASE + 0x260)
#define A2W_PLLB_FRAC (A2W_BASE + 0x2e0)
#define A2W_PLLC_CORE1 (A2W_BASE + 0x420)
#define A2W_PLLC_CORE0 (A2W_BASE + 0x620)
#define A2W_PLLC_CORE0_DIV_SET 0x000000ff
#define A2W_PLLA_FRAC_MASK 0x000fffff
#define A2W_PLLB_FRAC_MASK 0x000fffff
#define A2W_PLLC_FRAC_MASK 0x000fffff
#define A2W_PLLD_FRAC_MASK 0x000fffff
#define A2W_PLLH_FRAC_MASK 0x000fffff

#define ARMCTRL_BASE (ARM_BASE + 0x000)
#define ARMCTRL_INTC_BASE (ARM_BASE + 0x200)
#define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400)
Expand Down
18 changes: 9 additions & 9 deletions platform/bcm28xx/include/platform/bcm28xx/pll_read.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
#ifdef __cplusplus
extern "C" {
#endif
uint32_t clk_get_input_freq(volatile uint32_t *ctlreg);
uint32_t clk_get_freq(volatile uint32_t *divreg, volatile uint32_t *ctlreg);
uint32_t get_vpu_per_freq();
uint32_t get_uart_base_freq();
uint32_t plla();
uint32_t pllb();
uint32_t pllc();
uint32_t plld();
uint32_t pllh();
uint32_t clk_get_input_freq(uint32_t ctlreg);
uint32_t clk_get_freq(uint32_t divreg, uint32_t ctlreg);
uint32_t get_vpu_per_freq(void);
uint32_t get_uart_base_freq(void);
uint32_t plla(void);
uint32_t pllb(void);
uint32_t pllc(void);
uint32_t plld(void);
uint32_t pllh(void);
extern uint32_t xtal_freq;
#ifdef __cplusplus
}
Expand Down
91 changes: 71 additions & 20 deletions platform/bcm28xx/pll_read.c
Original file line number Diff line number Diff line change
@@ -1,66 +1,76 @@
#include <hardware.h>
#include <stdio.h>
#include <platform/bcm28xx/pll_read.h>
#include <platform/bcm28xx.h>
#include <lk/reg.h>
#include <lk/console_cmd.h>
#include <lk/debug.h>

uint32_t xtal_freq;

uint32_t get_vpu_per_freq() {
return clk_get_freq(&CM_VPUDIV, &CM_VPUCTL);
static int cmd_pll_dump(int argc, const cmd_args *argv);

STATIC_COMMAND_START
STATIC_COMMAND("dump_pll_state", "print all pll state", &cmd_pll_dump)
STATIC_COMMAND_END(pll);

uint32_t get_vpu_per_freq(void) {
return clk_get_freq(CM_VPUDIV, CM_VPUCTL);
}

uint32_t get_uart_base_freq() {
return clk_get_freq(&CM_UARTDIV, &CM_UARTCTL);
return clk_get_freq(CM_UARTDIV, CM_UARTCTL);
}

uint32_t compute_pll_freq(uint32_t ctrl, uint32_t frac) {
uint32_t ndiv = A2W_PLLC_CTRL & A2W_PLLC_CTRL_NDIV_SET;
uint32_t pdiv = (A2W_PLLC_CTRL & A2W_PLLC_CTRL_PDIV_SET) >> A2W_PLLC_CTRL_PDIV_LSB;
uint64_t mult1 = (ndiv << 20) | frac;
// FIXME, ignores the addr passed in
uint32_t ndiv = *REG32(ctrl) & A2W_PLLC_CTRL_NDIV_SET;
uint32_t pdiv = (*REG32(ctrl) & A2W_PLLC_CTRL_PDIV_SET) >> A2W_PLLC_CTRL_PDIV_LSB;
uint64_t mult1 = (ndiv << 20) | *REG32(frac);
mult1 *= pdiv;
// TODO, the optional /2 phase
uint32_t freq = (xtal_freq * mult1) >> 20;
return freq;
}

uint32_t plla() {
return compute_pll_freq(A2W_PLLA_CTRL, A2W_PLLA_FRAC & A2W_PLLA_FRAC_MASK);
return compute_pll_freq(*REG32(A2W_PLLA_CTRL), *REG32(A2W_PLLA_FRAC) & A2W_PLLA_FRAC_MASK);
}

uint32_t pllb() {
return compute_pll_freq(A2W_PLLB_CTRL, A2W_PLLB_FRAC & A2W_PLLB_FRAC_MASK);
return compute_pll_freq(*REG32(A2W_PLLB_CTRL), *REG32(A2W_PLLB_FRAC) & A2W_PLLB_FRAC_MASK);
}

uint32_t pllc() {
//uint32_t ana1 = A2W_PLLC_ANA1;
uint32_t ctrl = A2W_PLLC_CTRL;
uint32_t frac = A2W_PLLC_FRAC & A2W_PLLC_FRAC_MASK;
uint32_t ctrl = *REG32(A2W_PLLC_CTRL);
uint32_t frac = *REG32(A2W_PLLC_FRAC) & A2W_PLLC_FRAC_MASK;
return compute_pll_freq(ctrl, frac);
}

uint32_t plld() {
return compute_pll_freq(A2W_PLLD_CTRL, A2W_PLLD_FRAC & A2W_PLLD_FRAC_MASK);
return compute_pll_freq(*REG32(A2W_PLLD_CTRL), *REG32(A2W_PLLD_FRAC) & A2W_PLLD_FRAC_MASK);
}

uint32_t pllh() {
return compute_pll_freq(A2W_PLLH_CTRL, A2W_PLLH_FRAC & A2W_PLLH_FRAC_MASK);
return compute_pll_freq(*REG32(A2W_PLLH_CTRL), *REG32(A2W_PLLH_FRAC) & A2W_PLLH_FRAC_MASK);
}

uint32_t pllc_core0() {
uint32_t ctrl = A2W_PLLC_CORE0;
uint32_t pllc_core0(void) {
uint32_t ctrl = *REG32(A2W_PLLC_CORE0);
uint32_t div = ctrl & A2W_PLLC_CORE0_DIV_SET;
uint32_t pllc_freq = pllc();
return pllc_freq / div;
}

uint32_t clk_get_freq(volatile uint32_t *divreg, volatile uint32_t *ctlreg) {
uint32_t div = *divreg;
uint32_t clk_get_freq(uint32_t divreg, uint32_t ctlreg) {
uint32_t div = *REG32(divreg);
if (div == 0) return 0;
uint64_t input_freq = clk_get_input_freq(ctlreg);
return ((input_freq << 12) / *divreg);
return ((input_freq << 12) / div);
}

uint32_t clk_get_input_freq(volatile uint32_t *ctlreg) {
uint32_t ctl = *ctlreg;
uint32_t clk_get_input_freq(uint32_t ctlreg) {
uint32_t ctl = *REG32(ctlreg);
switch (ctl & 0xf) {
case 0: // GND clock source
return 0;
Expand All @@ -85,3 +95,44 @@ uint32_t clk_get_input_freq(volatile uint32_t *ctlreg) {
return 0;
}
}

static uint32_t dump_pll_state(const char *prefix, uint32_t ctrl, uint32_t frac) {
uint32_t ctrl_val = *REG32(ctrl);
uint32_t frac_value = *REG32(frac);
dprintf(INFO, "A2W_%s_CTRL: 0x%x\n", prefix, ctrl_val);
dprintf(INFO, "A2W_%s_FRAC: 0x%x\n", prefix, frac_value);
uint32_t freq = compute_pll_freq(ctrl, frac);
dprintf(INFO, "%s freq: %u\n", prefix, freq);
return freq;
}

static void dump_plldiv_state(const char *prefix, uint32_t ctrl, uint32_t input) {
uint32_t ctrl_val = *REG32(ctrl);
dprintf(INFO, "\tA2W_%s: 0x%x\n", prefix, ctrl_val);
uint8_t div = ctrl_val & 0xff;
if (div == 0) return;
uint32_t freq = input / div;
dprintf(INFO, "\t%s freq: %u\n", prefix, freq);
}

static void dump_plldiv2_state(const char *prefix, uint32_t ctrl, uint32_t div) {
uint32_t ctrl_val = *REG32(ctrl);
uint32_t div_val = *REG32(div);
dprintf(INFO, "CM_%sCTL: 0x%x\n", prefix, ctrl_val);
dprintf(INFO, "CM_%sDIV: 0x%x\n", prefix, div_val);
}

static int cmd_pll_dump(int argc, const cmd_args *argv) {
dump_pll_state("PLLA", A2W_PLLA_CTRL, A2W_PLLA_FRAC);
dump_pll_state("PLLB", A2W_PLLB_CTRL, A2W_PLLB_FRAC);
uint32_t pllc_freq = dump_pll_state("PLLC", A2W_PLLC_CTRL, A2W_PLLC_FRAC);
if (pllc_freq > 0) {
dump_plldiv_state("PLLC_CORE0", A2W_PLLC_CORE0, pllc_freq);
dump_plldiv_state("PLLC_CORE1", A2W_PLLC_CORE1, pllc_freq);
}
dump_pll_state("PLLD", A2W_PLLD_CTRL, A2W_PLLD_FRAC);
dump_pll_state("PLLH", A2W_PLLH_CTRL, A2W_PLLH_FRAC);

dump_plldiv2_state("VPU", CM_VPUCTL, CM_VPUDIV);
return 0;
}
32 changes: 21 additions & 11 deletions platform/bcm28xx/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,28 @@ MODULE := $(LOCAL_DIR)
WITH_SMP := 1
#LK_HEAP_IMPLEMENTATION ?= dlmalloc

ifeq ($(ARCJ),arm)
MODULE_DEPS := \
# 1st pass to set arch
ifeq ($(TARGET),rpi2)
ARCH := arm
ARM_CPU := cortex-a7
GLOBAL_DEFINES += CRYSTAL=19200000
else ifeq ($(TARGET),rpi3)
ARCH := arm64
ARM_CPU := cortex-a53
GLOBAL_DEFINES += CRYSTAL=19200000
else ifeq ($(TARGET),rpi4-vpu)
ARCH ?= vc4
GLOBAL_DEFINES += CRYSTAL=54000000
endif


ifeq ($(ARCH),arm)
MODULE_DEPS += \
dev/timer/arm_generic \
lib/cbuf
MODULE_SRCS +=
MODULE_SRCS += \
$(LOCAL_DIR)/mailbox.c \
$(LOCAL_DIR)/intc.c \

endif

Expand All @@ -24,7 +40,7 @@ endif
MODULE_SRCS += \
$(LOCAL_DIR)/gpio.c \
$(LOCAL_DIR)/platform.c \
#$(LOCAL_DIR)/intc.c \
$(LOCAL_DIR)/pll_read.c \


MEMBASE := 0x00000000
Expand All @@ -36,8 +52,6 @@ LINKER_SCRIPT += \
$(BUILDDIR)/system-onesegment.ld

ifeq ($(TARGET),rpi2)
ARCH := arm
ARM_CPU := cortex-a7
# put our kernel at 0x80000000
KERNEL_BASE = 0x80000000
KERNEL_LOAD_OFFSET := 0x00008000
Expand All @@ -50,8 +64,6 @@ MODULE_SRCS += \
$(LOCAL_DIR)/uart.c

else ifeq ($(TARGET),rpi3)
ARCH := arm64
ARM_CPU := cortex-a53

KERNEL_LOAD_OFFSET := 0x00080000
MEMSIZE ?= 0x40000000 # 1GB
Expand All @@ -70,18 +82,16 @@ MODULE_DEPS += \
app/tests \
lib/fdt
else ifeq ($(TARGET),rpi4-vpu)
ARCH ?= vc4
MEMSIZE ?= 0x1400000 # 20MB
MEMBASE ?= 0
GLOBAL_DEFINES += \
BCM2XXX_VPU=1 SMP_MAX_CPUS=1 \
MEMSIZE=$(MEMSIZE) \
MEMBASE=$(MEMBASE) \
CRYSTAL=54000000 \

MODULE_SRCS += \
$(LOCAL_DIR)/uart.c \
$(LOCAL_DIR)/pll_read.c \
$(LOCAL_DIR)/genet.c \

endif

Expand Down
1 change: 0 additions & 1 deletion platform/bcm28xx/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ void uart_init(void) {
// assumes interrupts are contiguous
register_int_handler(INTERRUPT_VC_UART + i, &uart_irq, (void *)i);
uint32_t divisor = calculate_baud_divisor(115200);
dprintf(INFO, "changing divisor to %d\n", divisor);

uart_flush(i);

Expand Down

0 comments on commit b87e962

Please sign in to comment.