Skip to content

Commit b87e962

Browse files
committed
[platform][vc4] fix time resolution, start genet driver, fix rpi2-test build
1 parent 6177b60 commit b87e962

7 files changed

Lines changed: 159 additions & 43 deletions

File tree

arch/vc4/timer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ static enum handler_return timer0_irq(void *arg);
1010

1111
lk_bigtime_t current_time_hires(void) {
1212
//TODO, deal with rollover
13-
return ( ((lk_bigtime_t)*REG32(ST_CHI)) << 32) | *REG32(ST_CLO);
13+
return (( ((lk_bigtime_t)*REG32(ST_CHI)) << 32) | *REG32(ST_CLO)) / 1000;
1414
}
1515

1616
lk_time_t current_time(void) {
17-
return *REG32(ST_CLO);
17+
return current_time_hires();
1818
}
1919

2020
static platform_timer_callback timer_cb = 0;;

platform/bcm28xx/genet.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// based on drivers/net/ethernet/broadcom/genet/bcmgenet.c from linux
2+
// for PHY control, look at the cmd_bits variable in drivers/net/ethernet/broadcom/genet/bcmmii.c
3+
4+
#include <lk/reg.h>
5+
#include <stdio.h>
6+
#include <lk/console_cmd.h>
7+
#include <platform/bcm28xx.h>
8+
#include <lk/debug.h>
9+
10+
static int cmd_genet_dump(int argc, const cmd_args *argv);
11+
12+
STATIC_COMMAND_START
13+
STATIC_COMMAND("dump_genet", "print genet information", &cmd_genet_dump)
14+
STATIC_COMMAND_END(genet);
15+
16+
#define SYS_REV_CTRL (GENET_BASE + 0x0)
17+
18+
static int cmd_genet_dump(int argc, const cmd_args *argv) {
19+
uint32_t reg = *REG32(SYS_REV_CTRL);
20+
uint8_t major = (reg >> 24 & 0x0f);
21+
if (major == 6) major = 5;
22+
else if (major == 5) major = 4;
23+
else if (major == 0) major = 1;
24+
25+
dprintf(INFO, "found GENET controller version %d\n", major);
26+
return 0;
27+
}

platform/bcm28xx/include/platform/bcm28xx.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#define ARM_BASE (BCM_PERIPH_BASE_VIRT + 0xB000)
4242
#define PM_BASE (BCM_PERIPH_BASE_VIRT + 0x100000)
4343
#define CM_BASE (BCM_PERIPH_BASE_VIRT + 0x101000)
44+
#define A2W_BASE (BCM_PERIPH_BASE_VIRT + 0x102000)
4445
#define PCM_CLOCK_BASE (BCM_PERIPH_BASE_VIRT + 0x101098)
4546
#define RNG_BASE (BCM_PERIPH_BASE_VIRT + 0x104000)
4647
#define GPIO_BASE (BCM_PERIPH_BASE_VIRT + 0x200000)
@@ -55,13 +56,16 @@
5556
#define SMI_BASE (BCM_PERIPH_BASE_VIRT + 0x600000)
5657
#define BSC1_BASE (BCM_PERIPH_BASE_VIRT + 0x804000)
5758
#define USB_BASE (BCM_PERIPH_BASE_VIRT + 0x980000)
59+
#define GENET_BASE (0x7d580000) // TODO, this is before the normal BCM_PERIPH_BASE_VIRT bank
5860
#define MCORE_BASE (BCM_PERIPH_BASE_VIRT + 0x0000)
5961

6062
#define ST_CS (ST_BASE + 0x0)
6163
#define ST_CLO (ST_BASE + 0x4)
6264
#define ST_CHI (ST_BASE + 0x8)
6365
#define ST_C0 (ST_BASE + 0xc)
6466

67+
#define CM_VPUCTL (CM_BASE + 0x008)
68+
#define CM_VPUDIV (CM_BASE + 0x00c)
6569
#define CM_UARTCTL (CM_BASE + 0xf0)
6670
#define CM_UARTDIV (CM_BASE + 0xf4)
6771

@@ -70,19 +74,44 @@
7074
#define IC0_SRC0 (IC0_BASE + 0x8)
7175
#define IC0_SRC1 (IC0_BASE + 0xc)
7276
#define IC0_VADDR (IC0_BASE + 0x30)
77+
#define IC0_WAKEUP (IC0_BASE + 0x34)
7378

7479
#define IC1_C (IC1_BASE + 0x0)
7580
#define IC1_S (IC1_BASE + 0x4)
7681
#define IC1_SRC0 (IC1_BASE + 0x8)
7782
#define IC1_SRC1 (IC1_BASE + 0xc)
7883
#define IC1_VADDR (IC1_BASE + 0x30)
84+
#define IC1_WAKEUP (IC1_BASE + 0x34)
7985

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

92+
#define A2W_PASSWORD 0x5a000000
93+
#define A2W_PLLA_CTRL (A2W_BASE + 0x100)
94+
#define A2W_PLLC_CTRL (A2W_BASE + 0x120)
95+
#define A2W_PLLC_CTRL_PDIV_SET 0x00007000
96+
#define A2W_PLLC_CTRL_NDIV_SET 0x000003ff
97+
#define A2W_PLLC_CTRL_PDIV_LSB 12
98+
#define A2W_PLLD_CTRL (A2W_BASE + 0x140)
99+
#define A2W_PLLH_CTRL (A2W_BASE + 0x160)
100+
#define A2W_PLLB_CTRL (A2W_BASE + 0x1e0)
101+
#define A2W_PLLA_FRAC (A2W_BASE + 0x200)
102+
#define A2W_PLLC_FRAC (A2W_BASE + 0x220)
103+
#define A2W_PLLD_FRAC (A2W_BASE + 0x240)
104+
#define A2W_PLLH_FRAC (A2W_BASE + 0x260)
105+
#define A2W_PLLB_FRAC (A2W_BASE + 0x2e0)
106+
#define A2W_PLLC_CORE1 (A2W_BASE + 0x420)
107+
#define A2W_PLLC_CORE0 (A2W_BASE + 0x620)
108+
#define A2W_PLLC_CORE0_DIV_SET 0x000000ff
109+
#define A2W_PLLA_FRAC_MASK 0x000fffff
110+
#define A2W_PLLB_FRAC_MASK 0x000fffff
111+
#define A2W_PLLC_FRAC_MASK 0x000fffff
112+
#define A2W_PLLD_FRAC_MASK 0x000fffff
113+
#define A2W_PLLH_FRAC_MASK 0x000fffff
114+
86115
#define ARMCTRL_BASE (ARM_BASE + 0x000)
87116
#define ARMCTRL_INTC_BASE (ARM_BASE + 0x200)
88117
#define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400)

platform/bcm28xx/include/platform/bcm28xx/pll_read.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
#ifdef __cplusplus
44
extern "C" {
55
#endif
6-
uint32_t clk_get_input_freq(volatile uint32_t *ctlreg);
7-
uint32_t clk_get_freq(volatile uint32_t *divreg, volatile uint32_t *ctlreg);
8-
uint32_t get_vpu_per_freq();
9-
uint32_t get_uart_base_freq();
10-
uint32_t plla();
11-
uint32_t pllb();
12-
uint32_t pllc();
13-
uint32_t plld();
14-
uint32_t pllh();
6+
uint32_t clk_get_input_freq(uint32_t ctlreg);
7+
uint32_t clk_get_freq(uint32_t divreg, uint32_t ctlreg);
8+
uint32_t get_vpu_per_freq(void);
9+
uint32_t get_uart_base_freq(void);
10+
uint32_t plla(void);
11+
uint32_t pllb(void);
12+
uint32_t pllc(void);
13+
uint32_t plld(void);
14+
uint32_t pllh(void);
1515
extern uint32_t xtal_freq;
1616
#ifdef __cplusplus
1717
}

platform/bcm28xx/pll_read.c

Lines changed: 71 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,76 @@
1-
#include <hardware.h>
21
#include <stdio.h>
32
#include <platform/bcm28xx/pll_read.h>
3+
#include <platform/bcm28xx.h>
4+
#include <lk/reg.h>
5+
#include <lk/console_cmd.h>
6+
#include <lk/debug.h>
47

58
uint32_t xtal_freq;
69

7-
uint32_t get_vpu_per_freq() {
8-
return clk_get_freq(&CM_VPUDIV, &CM_VPUCTL);
10+
static int cmd_pll_dump(int argc, const cmd_args *argv);
11+
12+
STATIC_COMMAND_START
13+
STATIC_COMMAND("dump_pll_state", "print all pll state", &cmd_pll_dump)
14+
STATIC_COMMAND_END(pll);
15+
16+
uint32_t get_vpu_per_freq(void) {
17+
return clk_get_freq(CM_VPUDIV, CM_VPUCTL);
918
}
1019

1120
uint32_t get_uart_base_freq() {
12-
return clk_get_freq(&CM_UARTDIV, &CM_UARTCTL);
21+
return clk_get_freq(CM_UARTDIV, CM_UARTCTL);
1322
}
1423

1524
uint32_t compute_pll_freq(uint32_t ctrl, uint32_t frac) {
16-
uint32_t ndiv = A2W_PLLC_CTRL & A2W_PLLC_CTRL_NDIV_SET;
17-
uint32_t pdiv = (A2W_PLLC_CTRL & A2W_PLLC_CTRL_PDIV_SET) >> A2W_PLLC_CTRL_PDIV_LSB;
18-
uint64_t mult1 = (ndiv << 20) | frac;
25+
// FIXME, ignores the addr passed in
26+
uint32_t ndiv = *REG32(ctrl) & A2W_PLLC_CTRL_NDIV_SET;
27+
uint32_t pdiv = (*REG32(ctrl) & A2W_PLLC_CTRL_PDIV_SET) >> A2W_PLLC_CTRL_PDIV_LSB;
28+
uint64_t mult1 = (ndiv << 20) | *REG32(frac);
1929
mult1 *= pdiv;
2030
// TODO, the optional /2 phase
2131
uint32_t freq = (xtal_freq * mult1) >> 20;
2232
return freq;
2333
}
2434

2535
uint32_t plla() {
26-
return compute_pll_freq(A2W_PLLA_CTRL, A2W_PLLA_FRAC & A2W_PLLA_FRAC_MASK);
36+
return compute_pll_freq(*REG32(A2W_PLLA_CTRL), *REG32(A2W_PLLA_FRAC) & A2W_PLLA_FRAC_MASK);
2737
}
2838

2939
uint32_t pllb() {
30-
return compute_pll_freq(A2W_PLLB_CTRL, A2W_PLLB_FRAC & A2W_PLLB_FRAC_MASK);
40+
return compute_pll_freq(*REG32(A2W_PLLB_CTRL), *REG32(A2W_PLLB_FRAC) & A2W_PLLB_FRAC_MASK);
3141
}
3242

3343
uint32_t pllc() {
3444
//uint32_t ana1 = A2W_PLLC_ANA1;
35-
uint32_t ctrl = A2W_PLLC_CTRL;
36-
uint32_t frac = A2W_PLLC_FRAC & A2W_PLLC_FRAC_MASK;
45+
uint32_t ctrl = *REG32(A2W_PLLC_CTRL);
46+
uint32_t frac = *REG32(A2W_PLLC_FRAC) & A2W_PLLC_FRAC_MASK;
3747
return compute_pll_freq(ctrl, frac);
3848
}
3949

4050
uint32_t plld() {
41-
return compute_pll_freq(A2W_PLLD_CTRL, A2W_PLLD_FRAC & A2W_PLLD_FRAC_MASK);
51+
return compute_pll_freq(*REG32(A2W_PLLD_CTRL), *REG32(A2W_PLLD_FRAC) & A2W_PLLD_FRAC_MASK);
4252
}
4353

4454
uint32_t pllh() {
45-
return compute_pll_freq(A2W_PLLH_CTRL, A2W_PLLH_FRAC & A2W_PLLH_FRAC_MASK);
55+
return compute_pll_freq(*REG32(A2W_PLLH_CTRL), *REG32(A2W_PLLH_FRAC) & A2W_PLLH_FRAC_MASK);
4656
}
4757

48-
uint32_t pllc_core0() {
49-
uint32_t ctrl = A2W_PLLC_CORE0;
58+
uint32_t pllc_core0(void) {
59+
uint32_t ctrl = *REG32(A2W_PLLC_CORE0);
5060
uint32_t div = ctrl & A2W_PLLC_CORE0_DIV_SET;
5161
uint32_t pllc_freq = pllc();
5262
return pllc_freq / div;
5363
}
5464

55-
uint32_t clk_get_freq(volatile uint32_t *divreg, volatile uint32_t *ctlreg) {
56-
uint32_t div = *divreg;
65+
uint32_t clk_get_freq(uint32_t divreg, uint32_t ctlreg) {
66+
uint32_t div = *REG32(divreg);
5767
if (div == 0) return 0;
5868
uint64_t input_freq = clk_get_input_freq(ctlreg);
59-
return ((input_freq << 12) / *divreg);
69+
return ((input_freq << 12) / div);
6070
}
6171

62-
uint32_t clk_get_input_freq(volatile uint32_t *ctlreg) {
63-
uint32_t ctl = *ctlreg;
72+
uint32_t clk_get_input_freq(uint32_t ctlreg) {
73+
uint32_t ctl = *REG32(ctlreg);
6474
switch (ctl & 0xf) {
6575
case 0: // GND clock source
6676
return 0;
@@ -85,3 +95,44 @@ uint32_t clk_get_input_freq(volatile uint32_t *ctlreg) {
8595
return 0;
8696
}
8797
}
98+
99+
static uint32_t dump_pll_state(const char *prefix, uint32_t ctrl, uint32_t frac) {
100+
uint32_t ctrl_val = *REG32(ctrl);
101+
uint32_t frac_value = *REG32(frac);
102+
dprintf(INFO, "A2W_%s_CTRL: 0x%x\n", prefix, ctrl_val);
103+
dprintf(INFO, "A2W_%s_FRAC: 0x%x\n", prefix, frac_value);
104+
uint32_t freq = compute_pll_freq(ctrl, frac);
105+
dprintf(INFO, "%s freq: %u\n", prefix, freq);
106+
return freq;
107+
}
108+
109+
static void dump_plldiv_state(const char *prefix, uint32_t ctrl, uint32_t input) {
110+
uint32_t ctrl_val = *REG32(ctrl);
111+
dprintf(INFO, "\tA2W_%s: 0x%x\n", prefix, ctrl_val);
112+
uint8_t div = ctrl_val & 0xff;
113+
if (div == 0) return;
114+
uint32_t freq = input / div;
115+
dprintf(INFO, "\t%s freq: %u\n", prefix, freq);
116+
}
117+
118+
static void dump_plldiv2_state(const char *prefix, uint32_t ctrl, uint32_t div) {
119+
uint32_t ctrl_val = *REG32(ctrl);
120+
uint32_t div_val = *REG32(div);
121+
dprintf(INFO, "CM_%sCTL: 0x%x\n", prefix, ctrl_val);
122+
dprintf(INFO, "CM_%sDIV: 0x%x\n", prefix, div_val);
123+
}
124+
125+
static int cmd_pll_dump(int argc, const cmd_args *argv) {
126+
dump_pll_state("PLLA", A2W_PLLA_CTRL, A2W_PLLA_FRAC);
127+
dump_pll_state("PLLB", A2W_PLLB_CTRL, A2W_PLLB_FRAC);
128+
uint32_t pllc_freq = dump_pll_state("PLLC", A2W_PLLC_CTRL, A2W_PLLC_FRAC);
129+
if (pllc_freq > 0) {
130+
dump_plldiv_state("PLLC_CORE0", A2W_PLLC_CORE0, pllc_freq);
131+
dump_plldiv_state("PLLC_CORE1", A2W_PLLC_CORE1, pllc_freq);
132+
}
133+
dump_pll_state("PLLD", A2W_PLLD_CTRL, A2W_PLLD_FRAC);
134+
dump_pll_state("PLLH", A2W_PLLH_CTRL, A2W_PLLH_FRAC);
135+
136+
dump_plldiv2_state("VPU", CM_VPUCTL, CM_VPUDIV);
137+
return 0;
138+
}

platform/bcm28xx/rules.mk

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,28 @@ MODULE := $(LOCAL_DIR)
55
WITH_SMP := 1
66
#LK_HEAP_IMPLEMENTATION ?= dlmalloc
77

8-
ifeq ($(ARCJ),arm)
9-
MODULE_DEPS := \
8+
# 1st pass to set arch
9+
ifeq ($(TARGET),rpi2)
10+
ARCH := arm
11+
ARM_CPU := cortex-a7
12+
GLOBAL_DEFINES += CRYSTAL=19200000
13+
else ifeq ($(TARGET),rpi3)
14+
ARCH := arm64
15+
ARM_CPU := cortex-a53
16+
GLOBAL_DEFINES += CRYSTAL=19200000
17+
else ifeq ($(TARGET),rpi4-vpu)
18+
ARCH ?= vc4
19+
GLOBAL_DEFINES += CRYSTAL=54000000
20+
endif
21+
22+
23+
ifeq ($(ARCH),arm)
24+
MODULE_DEPS += \
1025
dev/timer/arm_generic \
1126
lib/cbuf
12-
MODULE_SRCS +=
27+
MODULE_SRCS += \
1328
$(LOCAL_DIR)/mailbox.c \
29+
$(LOCAL_DIR)/intc.c \
1430

1531
endif
1632

@@ -24,7 +40,7 @@ endif
2440
MODULE_SRCS += \
2541
$(LOCAL_DIR)/gpio.c \
2642
$(LOCAL_DIR)/platform.c \
27-
#$(LOCAL_DIR)/intc.c \
43+
$(LOCAL_DIR)/pll_read.c \
2844

2945

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

3854
ifeq ($(TARGET),rpi2)
39-
ARCH := arm
40-
ARM_CPU := cortex-a7
4155
# put our kernel at 0x80000000
4256
KERNEL_BASE = 0x80000000
4357
KERNEL_LOAD_OFFSET := 0x00008000
@@ -50,8 +64,6 @@ MODULE_SRCS += \
5064
$(LOCAL_DIR)/uart.c
5165

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

5668
KERNEL_LOAD_OFFSET := 0x00080000
5769
MEMSIZE ?= 0x40000000 # 1GB
@@ -70,18 +82,16 @@ MODULE_DEPS += \
7082
app/tests \
7183
lib/fdt
7284
else ifeq ($(TARGET),rpi4-vpu)
73-
ARCH ?= vc4
7485
MEMSIZE ?= 0x1400000 # 20MB
7586
MEMBASE ?= 0
7687
GLOBAL_DEFINES += \
7788
BCM2XXX_VPU=1 SMP_MAX_CPUS=1 \
7889
MEMSIZE=$(MEMSIZE) \
7990
MEMBASE=$(MEMBASE) \
80-
CRYSTAL=54000000 \
8191

8292
MODULE_SRCS += \
8393
$(LOCAL_DIR)/uart.c \
84-
$(LOCAL_DIR)/pll_read.c \
94+
$(LOCAL_DIR)/genet.c \
8595

8696
endif
8797

platform/bcm28xx/uart.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ void uart_init(void) {
102102
// assumes interrupts are contiguous
103103
register_int_handler(INTERRUPT_VC_UART + i, &uart_irq, (void *)i);
104104
uint32_t divisor = calculate_baud_divisor(115200);
105-
dprintf(INFO, "changing divisor to %d\n", divisor);
106105

107106
uart_flush(i);
108107

0 commit comments

Comments
 (0)