Skip to content

Commit

Permalink
vec dance works
Browse files Browse the repository at this point in the history
  • Loading branch information
cleverca22 committed Mar 22, 2021
1 parent 8043bb7 commit 04341ff
Show file tree
Hide file tree
Showing 14 changed files with 238 additions and 63 deletions.
1 change: 1 addition & 0 deletions arch/vpu/intc.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ void sleh_irq(vc4_saved_state_t* pcb, uint32_t tp) {
switch (source) {
case 64: // timer0
case 73: // dwc2
case 106: // pv2
case 121: // uart
assert(irq_handlers[source - 64].h);
ret = irq_handlers[source - 64].h(irq_handlers[source - 64].arg);
Expand Down
8 changes: 6 additions & 2 deletions arch/vpu/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ static inline void push(thread_t *t, uint32_t val) {
static void initial_thread_func(void) __NO_RETURN;
static void initial_thread_func(void) {
thread_t *ct = get_current_thread();
uint32_t own_sp;
//uint32_t own_sp;

__asm__ volatile ("mov %0, sp": "=r"(own_sp));
//__asm__ volatile ("mov %0, sp": "=r"(own_sp));
//dprintf(INFO, "thread %p(%s) starting with sp near 0x%x\n", ct, ct->name, own_sp);
spin_unlock(&thread_lock);
arch_enable_ints();

int ret = ct->entry(ct->arg);

Expand All @@ -39,6 +41,8 @@ void arch_thread_initialize(thread_t *t) {
//printf("thread %p(%s) has a stack of %p+0x%x\n", t, t->name, t->stack, t->stack_size);
t->arch.sp = (uint32_t)((t->stack + t->stack_size) - 4);
__asm__ volatile ("mov %0, sr": "=r"(t->arch.sr));
t->arch.sr &= ~0x40000000; // disable irq in the new thread
//printf("initial sr: 0x%x\n", t->arch.sr);
push(t, (uint32_t)(&initial_thread_func)); // lr
for (int i=6; i<=23; i++) {
push(t, 0); // r${i}
Expand Down
1 change: 1 addition & 0 deletions dev/timer/vc4/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ MODULE := $(LOCAL_DIR)
MODULE_SRCS += $(LOCAL_DIR)/timer.c

GLOBAL_DEFINES += PLATFORM_HAS_DYNAMIC_TIMER=1
MODULE_CFLAGS := -O2

include make/module.mk
22 changes: 17 additions & 5 deletions dev/timer/vc4/timer.c
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
#include <assert.h>
#include <lk/err.h>
#include <lk/init.h>
#include <lk/reg.h>
#include <platform/bcm28xx.h>
#include <platform/interrupts.h>
#include <platform/timer.h>

static enum handler_return timer0_irq(void *arg);
static void vc4_timer_init(uint level);

static platform_timer_callback timer_cb = 0;;
static void *timer_arg = 0;;

LK_INIT_HOOK(vc4_timer, &vc4_timer_init, LK_INIT_LEVEL_PLATFORM);

lk_bigtime_t current_time_hires(void) {
//TODO, deal with rollover
return ( ((lk_bigtime_t)*REG32(ST_CHI)) << 32) | *REG32(ST_CLO);
Expand All @@ -19,22 +23,30 @@ lk_time_t current_time(void) {
return current_time_hires();
}

static void vc4_timer_init(uint level) {
#if VC4_TIMER_CHANNEL == 0
// TODO, only register the interrupt handler once
register_int_handler(0, timer0_irq, NULL);
unmask_interrupt(0);
#elif VC4_TIMER_CHANNEL == 1
register_int_handler(1, timer0_irq, NULL);
unmask_interrupt(1);
#else
#error unsupported timer channel
#endif
}

status_t platform_set_oneshot_timer (platform_timer_callback callback, void *arg, lk_time_t interval) {
timer_cb = callback;
timer_arg = arg;
//printf("platform_set_oneshot_timer(..., ..., %d)\n", interval);
#if VC4_TIMER_CHANNEL == 0
*REG32(ST_C0) = *REG32(ST_CLO) + (interval * 1000);
register_int_handler(0, timer0_irq, NULL);
unmask_interrupt(0);
#elif VC4_TIMER_CHANNEL == 1
*REG32(ST_C1) = *REG32(ST_CLO) + (interval * 1000);
register_int_handler(1, timer0_irq, NULL);
unmask_interrupt(1);
#else
#error unsupported timer channel
#endif

return NO_ERROR;
}

Expand Down
5 changes: 5 additions & 0 deletions platform/bcm28xx/hvs-dance/include/dance.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include <lib/gfx.h>

void dance_start(gfx_surface* fbin, int hvs_channel);
195 changes: 169 additions & 26 deletions platform/bcm28xx/hvs/hvs.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#include <arch/ops.h>
#include <assert.h>
#include <lk/console_cmd.h>
#include <lk/reg.h>
#include <platform/bcm28xx/hvs.h>
#include <platform/interrupts.h>
#include <stdio.h>
#include <stdlib.h>
#include <platform/interrupts.h>

// note, 4096 slots total
volatile uint32_t* dlist_memory = REG32(SCALER_LIST_MEMORY);
Expand Down Expand Up @@ -33,6 +34,8 @@ static uint32_t gfx_to_hvs_pixel_format(gfx_format fmt) {
}

void hvs_add_plane(gfx_surface *fb, int x, int y, bool hflip) {
assert(fb);
printf("rendering FB of size %dx%d at %dx%d\n", fb->width, fb->height, x, y);
dlist_memory[display_slot++] = CONTROL_VALID
| CONTROL_WORDS(7)
| CONTROL_PIXEL_ORDER(HVS_PIXEL_ORDER_ABGR)
Expand All @@ -48,22 +51,66 @@ void hvs_add_plane(gfx_surface *fb, int x, int y, bool hflip) {
dlist_memory[display_slot++] = fb->stride * fb->pixelsize;
}

void hvs_add_plane_scaled(gfx_surface *fb, int x, int y, int width, int height, bool hflip) {
enum scaling_mode {
none,
PPF, // upscaling?
TPZ // downscaling?
};

static void write_tpz(unsigned int source, unsigned int dest) {
uint32_t scale = (1<<16) * source / dest;
uint32_t recip = ~0 / scale;
dlist_memory[display_slot++] = scale << 8;
dlist_memory[display_slot++] = recip;
}

void hvs_add_plane_scaled(gfx_surface *fb, int x, int y, unsigned int width, unsigned int height, bool hflip) {
assert(fb);
//printf("rendering FB of size %dx%d at %dx%d, scaled down to %dx%d\n", fb->width, fb->height, x, y, width, height);
enum scaling_mode xmode, ymode;
if (fb->width > width) xmode = TPZ;
else if (fb->width < width) xmode = PPF;
else xmode = none;

if (fb->height > height) ymode = TPZ;
else if (fb->height < height) ymode = PPF;
else ymode = none;

int scl0;
switch ((xmode << 2) | ymode) {
case (PPF << 2) | PPF:
scl0 = SCALER_CTL0_SCL_H_PPF_V_PPF;
break;
case (TPZ << 2) | PPF:
scl0 = SCALER_CTL0_SCL_H_TPZ_V_PPF;
break;
case (PPF << 2) | TPZ:
scl0 = SCALER_CTL0_SCL_H_PPF_V_TPZ;
break;
case (TPZ << 2) | TPZ:
scl0 = SCALER_CTL0_SCL_H_TPZ_V_TPZ;
break;
default:
puts("unsupported scale combonation");
}

int start = display_slot;
dlist_memory[display_slot++] = CONTROL_VALID
| CONTROL_WORDS(14)
dlist_memory[display_slot++] = 0 // CONTROL_VALID
// | CONTROL_WORDS(14)
| CONTROL_PIXEL_ORDER(HVS_PIXEL_ORDER_ABGR)
// | CONTROL0_VFLIP // makes the HVS addr count down instead, pointer word must be last line of image
| (hflip ? CONTROL0_HFLIP : 0)
| CONTROL_FORMAT(gfx_to_hvs_pixel_format(fb->format));
dlist_memory[display_slot++] = POS0_X(x) | POS0_Y(y) | POS0_ALPHA(0xff);
dlist_memory[display_slot++] = width | (height << 16);
dlist_memory[display_slot++] = POS2_H(fb->height) | POS2_W(fb->width);
dlist_memory[display_slot++] = 0xDEADBEEF; // dummy for HVS state
dlist_memory[display_slot++] = (uint32_t)fb->ptr | 0xc0000000;
dlist_memory[display_slot++] = 0xDEADBEEF; // dummy for HVS state
dlist_memory[display_slot++] = fb->stride * fb->pixelsize;
dlist_memory[display_slot++] = 0x100;
| CONTROL_FORMAT(gfx_to_hvs_pixel_format(fb->format))
| (scl0 << 5)
| (scl0 << 8); // SCL1
dlist_memory[display_slot++] = POS0_X(x) | POS0_Y(y) | POS0_ALPHA(0xff); // position word 0
dlist_memory[display_slot++] = width | (height << 16); // position word 1
dlist_memory[display_slot++] = POS2_H(fb->height) | POS2_W(fb->width); // position word 2
dlist_memory[display_slot++] = 0xDEADBEEF; // position word 3, dummy for HVS state
dlist_memory[display_slot++] = (uint32_t)fb->ptr | 0xc0000000; // pointer word 0
dlist_memory[display_slot++] = 0xDEADBEEF; // pointer context word 0 dummy for HVS state
dlist_memory[display_slot++] = fb->stride * fb->pixelsize; // pitch word 0
dlist_memory[display_slot++] = 0x100; // LBM base addr

#if 0
bool ppf = false;
Expand All @@ -76,19 +123,26 @@ void hvs_add_plane_scaled(gfx_surface *fb, int x, int y, int width, int height,
dlist_memory[display_slot++] = 0xDEADBEEF; //scaling context
}
#endif
bool tpz = true;
if (tpz) {
uint32_t xscale = (1<<16) * fb->width / width;
uint32_t yscale = (1<<16) * fb->height / height;
uint32_t xrecip = ~0 / xscale;
uint32_t yrecip = ~0 / yscale;
dlist_memory[display_slot++] = (xscale << 8);
dlist_memory[display_slot++] = xrecip;
dlist_memory[display_slot++] = (yscale << 8);
dlist_memory[display_slot++] = yrecip;
dlist_memory[display_slot++] = 0xDEADBEEF; //scaling context

if (xmode == PPF) {
puts("unfinished");
}

if (ymode == PPF) {
puts("unfinished");
}

if (xmode == TPZ) {
write_tpz(fb->width, width);
}
printf("entry size: %d\n", display_slot - start);

if (ymode == TPZ) {
write_tpz(fb->height, height);
dlist_memory[display_slot++] = 0xDEADBEEF; // context for scaling
}

//printf("entry size: %d, spans 0x%x-0x%x\n", display_slot - start, start, display_slot);
dlist_memory[start] |= CONTROL_VALID | CONTROL_WORDS(display_slot - start);
}

void hvs_terminate_list(void) {
Expand Down Expand Up @@ -138,6 +192,43 @@ void hvs_wipe_displaylist(void) {
display_slot = 0;
}

static bool bcm_host_is_model_pi4(void) {
return false;
}

void hvs_print_position0(uint32_t w) {
printf("position0: 0x%x\n", w);
if (bcm_host_is_model_pi4()) {
printf(" x: %d y: %d\n", w & 0x3fff, (w >> 16) & 0x3fff);
} else {
printf(" x: %d y: %d\n", w & 0xfff, (w >> 12) & 0xfff);
}
}
void hvs_print_control2(uint32_t w) {
printf("control2: 0x%x\n", w);
printf(" alpha: 0x%x\n", (w >> 4) & 0xffff);
printf(" alpha mode: %d\n", (w >> 30) & 0x3);
}
void hvs_print_word1(uint32_t w) {
printf(" word1: 0x%x\n", w);
}
void hvs_print_position2(uint32_t w) {
printf("position2: 0x%x\n", w);
printf(" width: %d height: %d\n", w & 0xffff, (w >> 16) & 0xfff);
}
void hvs_print_position3(uint32_t w) {
printf("position3: 0x%x\n", w);
}
void hvs_print_pointer0(uint32_t w) {
printf("pointer word: 0x%x\n", w);
}
void hvs_print_pointerctx0(uint32_t w) {
printf("pointer context word: 0x%x\n", w);
}
void hvs_print_pitch0(uint32_t w) {
printf("pitch word: 0x%x\n", w);
}

static int cmd_hvs_dump(int argc, const cmd_args *argv) {
printf("SCALER_DISPCTRL: 0x%x\n", *REG32(SCALER_DISPCTRL));
printf("SCALER_DISPSTAT: 0x%x\n", *REG32(SCALER_DISPSTAT));
Expand All @@ -162,8 +253,60 @@ static int cmd_hvs_dump(int argc, const cmd_args *argv) {
uint32_t base = hvs_channels[i].dispbase;
printf("SCALER_DISPBASE%d: base 0x%x top 0x%x\n\n", i, base & 0xffff, base >> 16);
}
for (uint32_t i=list1; i<(list1+16); i++) {
for (uint32_t i=list1; i<(list1+64); i++) {
printf("dlist[%x]: 0x%x\n", i, dlist_memory[i]);
if (dlist_memory[i] & BV(31)) {
puts("(31)END");
break;
}
if (dlist_memory[i] & BV(30)) {
int x = i;
int words = (dlist_memory[i] >> 24) & 0x3f;
for (unsigned int index=i; index < (i+words); index++) {
printf("raw dlist[%d] == 0x%x\n", index-i, dlist_memory[index]);
}
bool unity;
printf(" (3:0)format: %d\n", dlist_memory[i] & 0xf);
if (dlist_memory[i] & (1<<4)) puts(" (4)unity");
printf(" (7:5)SCL0: %d\n", (dlist_memory[i] >> 5) & 0x7);
printf(" (10:8)SCL1: %d\n", (dlist_memory[i] >> 8) & 0x7);
if (false) { // is bcm2711
if (dlist_memory[i] & (1<<11)) puts(" (11)rgb expand");
if (dlist_memory[i] & (1<<12)) puts(" (12)alpha expand");
} else {
printf(" (12:11)rgb expand: %d\n", (dlist_memory[i] >> 11) & 0x3);
}
printf(" (14:13)pixel order: %d\n", (dlist_memory[i] >> 13) & 0x3);
if (false) { // is bcm2711
unity = dlist_memory[i] & (1<<15);
} else {
unity = dlist_memory[i] & (1<<4);
if (dlist_memory[i] & (1<<15)) puts(" (15)vflip");
if (dlist_memory[i] & (1<<16)) puts(" (16)hflip");
}
printf(" (18:17)key mode: %d\n", (dlist_memory[i] >> 17) & 0x3);
if (dlist_memory[i] & (1<<19)) puts(" (19)alpha mask");
printf(" (21:20)tiling mode: %d\n", (dlist_memory[i] >> 20) & 0x3);
printf(" (29:24)words: %d\n", words);
x++;
hvs_print_position0(dlist_memory[x++]);
if (bcm_host_is_model_pi4()) {
hvs_print_control2(dlist_memory[x++]);
}
if (unity) {
puts("unity scaling");
} else {
hvs_print_word1(dlist_memory[x++]);
}
hvs_print_position2(dlist_memory[x++]);
hvs_print_position3(dlist_memory[x++]);
hvs_print_pointer0(dlist_memory[x++]);
hvs_print_pointerctx0(dlist_memory[x++]);
hvs_print_pitch0(dlist_memory[x++]);
if (words > 1) {
i += words - 1;
}
}
}
return 0;
}
Expand Down
13 changes: 11 additions & 2 deletions platform/bcm28xx/hvs/include/platform/bcm28xx/hvs.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ extern volatile struct hvs_channel *hvs_channels;
#define CONTROL_FORMAT(n) (n & 0xf)
#define CONTROL_END (1<<31)
#define CONTROL_VALID (1<<30)
#define CONTROL_WORDS(n) ((n & 0x3f) << 24)
#define CONTROL_WORDS(n) (((n) & 0x3f) << 24)
#define CONTROL0_FIXED_ALPHA (1<<19)
#define CONTROL0_HFLIP (1<<16)
#define CONTROL0_VFLIP (1<<15)
Expand Down Expand Up @@ -92,6 +92,15 @@ enum hvs_pixel_format {
#define HVS_PIXEL_ORDER_XRGB 2
#define HVS_PIXEL_ORDER_XBGR 3

#define SCALER_CTL0_SCL_H_PPF_V_PPF 0
#define SCALER_CTL0_SCL_H_TPZ_V_PPF 1
#define SCALER_CTL0_SCL_H_PPF_V_TPZ 2
#define SCALER_CTL0_SCL_H_TPZ_V_TPZ 3
#define SCALER_CTL0_SCL_H_PPF_V_NONE 4
#define SCALER_CTL0_SCL_H_NONE_V_PPF 5
#define SCALER_CTL0_SCL_H_NONE_V_TPZ 6
#define SCALER_CTL0_SCL_H_TPZ_V_NONE 7

#define POS0_X(n) (n & 0xfff)
#define POS0_Y(n) ((n & 0xfff) << 12)
#define POS0_ALPHA(n) ((n & 0xff) << 24)
Expand All @@ -103,7 +112,7 @@ extern int display_slot;
extern volatile uint32_t* dlist_memory;

void hvs_add_plane(gfx_surface *fb, int x, int y, bool hflip);
void hvs_add_plane_scaled(gfx_surface *fb, int x, int y, int width, int height, bool hflip);
void hvs_add_plane_scaled(gfx_surface *fb, int x, int y, unsigned int width, unsigned int height, bool hflip);
void hvs_terminate_list(void);
void hvs_wipe_displaylist(void);
void hvs_initialize(void);
Expand Down
1 change: 1 addition & 0 deletions platform/bcm28xx/include/platform/bcm28xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ void print_timestamp(void);
}
#endif

#define BV(n) (1 << n)
#define SDRAM_BASE 0
#ifdef ARCH_VPU
#define BCM_PERIPH_BASE_PHYS (0x7e000000U)
Expand Down
Loading

0 comments on commit 04341ff

Please sign in to comment.