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 715ef3e
Show file tree
Hide file tree
Showing 15 changed files with 321 additions and 105 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
125 changes: 83 additions & 42 deletions platform/bcm28xx/hvs-dance/dance.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <lk/console_cmd.h>
#include <lk/err.h>
#include <lk/reg.h>
#include <pi-logo.h>
//#include <pi-logo.h>
#include <platform/bcm28xx/hvs.h>
#include <platform/bcm28xx/pv.h>
#include <platform/mailbox.h>
Expand All @@ -17,11 +17,13 @@
static int cmd_hvs_dance(int argc, const cmd_args *argv);
static int cmd_hvs_limit(int argc, const cmd_args *argv);
static int cmd_hvs_delay(int argc, const cmd_args *argv);
static int cmd_dance_update(int argc, const cmd_args *argv);

STATIC_COMMAND_START
STATIC_COMMAND("dance", "make the HVS dance in another direction", &cmd_hvs_dance)
STATIC_COMMAND("l", "limit sprites", &cmd_hvs_limit)
STATIC_COMMAND("d", "delay updates", &cmd_hvs_delay)
STATIC_COMMAND("u", "update", &cmd_dance_update)
STATIC_COMMAND_END(hvs_dance);

gfx_surface *fb;
Expand All @@ -33,23 +35,36 @@ struct item {

#define ITEMS 580
struct item items[ITEMS];
uint32_t sprite_limit = 1;
uint32_t sprite_limit = 15;
int delay = 0;

uint32_t screen_width, screen_height;

#define SCALED

void do_frame_update(int frame) {
if (delay != 0) {
if ((frame % delay) != 0) return;
}
if ((display_slot + (sprite_limit * 7) + 1) > 4096) {
//printf("early dlist loop %d\n", display_slot);
printf("early dlist loop %d\n", display_slot);
display_slot = 0;
}

int w,h;
#ifdef SCALED
w = 100;
h = 100;
#else
w = fb->width;
h = fb->height;
#endif

int start = display_slot;
for (unsigned int i=0; i < sprite_limit; i++) {
struct item *it = &items[i];
if (it->x > (0x500 - fb->width)) it->xd *= -1;
if (it->y > (0x400 - fb->height)) it->yd *= -1;
if (it->x > (screen_width - w)) it->xd *= -1;
if (it->y > (screen_height - h)) it->yd *= -1;

it->x += it->xd;
it->y += it->yd;
Expand All @@ -64,12 +79,16 @@ void do_frame_update(int frame) {
it->yd *= -1;
}
#endif
#ifdef SCALED
hvs_add_plane_scaled(fb, it->x, it->y, w, h, false);
#else
hvs_add_plane(fb, it->x, it->y, false);
#endif
}
hvs_terminate_list();

if (display_slot > 4096) {
printf("dlist overflow!!!: %d\n", display_slot);
//printf("dlist overflow!!!: %d\n", display_slot);
display_slot = 0;
do_frame_update(frame);
return;
Expand All @@ -83,6 +102,12 @@ void do_frame_update(int frame) {
}
}

static int cmd_dance_update(int argc, const cmd_args *argv) {
printf("fb 0x%x is %dx%d\n", fb, fb->width, fb->height);
do_frame_update(0);
return 0;
}

uint32_t hsync, hbp, hact, hfp, vsync, vbp, vfps, last_vfps;

static enum handler_return pv_irq(void *pvnr) {
Expand All @@ -96,9 +121,9 @@ static enum handler_return pv_irq(void *pvnr) {
ack |= PV_INTEN_HSYNC_START;
hsync = t;
if ((SCALER_STAT_LINE(stat1) % 5) == 0) {
hvs_channels[1].dispbkgnd = (1<<24) | 0x00ff00;
//hvs_channels[1].dispbkgnd = (1<<24) | 0x00ff00;
} else {
hvs_channels[1].dispbkgnd = (1<<24) | 0xffffff;
//hvs_channels[1].dispbkgnd = (1<<24) | 0xffffff;
}
}
if (stat & PV_INTEN_HBP_START) {
Expand Down Expand Up @@ -128,7 +153,7 @@ static enum handler_return pv_irq(void *pvnr) {
ack |= PV_INTEN_VFP_START;
last_vfps = vfps;
vfps = t;
hvs_channels[1].dispbkgnd = (1<<24) | 0xff0000;
//hvs_channels[1].dispbkgnd = (1<<24) | 0xff0000;
do_frame_update((stat1 >> 12) & 0x3f);
//printf("line: %d frame: %2d start: %4d ", stat1 & 0xfff, (stat1 >> 12) & 0x3f, *REG32(SCALER_DISPLIST1));
//uint32_t idle = *REG32(SD_IDL);
Expand All @@ -137,7 +162,7 @@ static enum handler_return pv_irq(void *pvnr) {
//uint64_t idle_percent = ((uint64_t)idle * 100) / ((uint64_t)total);
//printf("sdram usage: %d %d, %lld\n", idle, total, idle_percent);
//printf("HSYNC:%5d HBP:%d HACT:%d HFP:%d VSYNC:%5d VBP:%5d VFPS:%d FRAME:%d\n", t - vsync, t-hbp, t-hact, t-hfp, t-vsync, t-vbp, t-vfps, t-last_vfps);
hvs_channels[1].dispbkgnd = (1<<24) | 0xffffff;
//hvs_channels[1].dispbkgnd = (1<<24) | 0xffffff;
}
if (stat & PV_INTEN_VFP_END) {
ack |= PV_INTEN_VFP_END;
Expand All @@ -149,16 +174,28 @@ static enum handler_return pv_irq(void *pvnr) {
return INT_NO_RESCHEDULE;
}

static int cmd_hvs_dance(int argc, const cmd_args *argv) {
static void dance_scramble(void) {
int w,h;
#ifdef SCALED
w = 100;
h = 100;
#else
w = fb->width;
h = fb->height;
#endif
for (int i=0; i<ITEMS; i++) {
struct item *it = &items[i];
it->x = (unsigned int)rand() % 0x500;
it->y = (unsigned int)rand() % 0x400;
it->xd = rand() % 25;
it->yd = rand() % 25;
if (it->x > (0x500 - fb->width)) it->x = 0x500 - fb->width;
if (it->y > (0x400 - fb->height)) it->y = 0x400 - fb->height;
it->x = (unsigned int)rand() % screen_width;
it->y = (unsigned int)rand() % screen_height;
it->xd = rand() % 10;
it->yd = rand() % 10;
if (it->x > (screen_width - w)) it->x = screen_width - fb->width;
if (it->y > (screen_height - h)) it->y = screen_height - fb->height;
}
}

static int cmd_hvs_dance(int argc, const cmd_args *argv) {
dance_scramble();
return 0;
}

Expand All @@ -173,8 +210,33 @@ static int cmd_hvs_delay(int argc, const cmd_args *argv) {
return 0;
}

void dance_start(gfx_surface* fbin, int hvs_channel) {
fb = fbin;
gfx_flush(fb);

struct hvs_channel *hvs_channels = (struct hvs_channel*)REG32(SCALER_DISPCTRL0);
hvs_channels[hvs_channel].dispbkgnd = (1<<24) | 0xffffff;
screen_width = (hvs_channels[hvs_channel].dispctrl >> 12) & 0xfff;
screen_height = (hvs_channels[hvs_channel].dispctrl & 0xfff) / 2;
printf("detected a %dx%d screen\n", screen_width, screen_height);

srand(*REG32(ST_CLO));
dance_scramble();
if (true) {
puts("setting up pv interrupt");
int pvnr = 2;
struct pixel_valve *rawpv = getPvAddr(pvnr);
rawpv->int_enable = 0;
rawpv->int_status = 0xff;
setup_pv_interrupt(pvnr, pv_irq, (void*)pvnr);
rawpv->int_enable = PV_INTEN_VFP_START | 0x3f;
//hvs_setup_irq();
puts("done");
}
}

static void dance_init(const struct app_descriptor *app) {
fb = tga_decode(pilogo, sizeof(pilogo), GFX_FORMAT_ARGB_8888);
#if 0
if (!fb) {
fb = gfx_create_surface(NULL, 10, 10, 10, GFX_FORMAT_ARGB_8888);
for (unsigned int i=0; i<fb->width; i++) {
Expand All @@ -188,34 +250,13 @@ static void dance_init(const struct app_descriptor *app) {
}
}
fb->flush = 0;
#endif
screen_width = 0x500;
screen_height = 0x400;
}

static void dance_entry(const struct app_descriptor *app, void *args) {
gfx_flush(fb);
srand(*REG32(ST_CLO));
for (int i=0; i<ITEMS; i++) {
struct item *it = &items[i];
it->x = (unsigned int)rand() % 0x500;
it->y = (unsigned int)rand() % 0x400;
it->xd = rand() % 25;
it->yd = rand() % 25;
if (it->x > (0x500 - fb->width)) it->x = 0x500 - fb->width;
if (it->y > (0x400 - fb->height)) it->y = 0x400 - fb->height;
}
struct hvs_channel *hvs_channels = (struct hvs_channel*)REG32(SCALER_DISPCTRL0);
hvs_channels[1].dispbkgnd = (1<<24) | 0xffffff;

{
puts("setting up pv interrupt");
int pvnr = 2;
struct pixel_valve *rawpv = getPvAddr(pvnr);
rawpv->int_enable = 0;
rawpv->int_status = 0xff;
setup_pv_interrupt(pvnr, pv_irq, (void*)pvnr);
rawpv->int_enable = PV_INTEN_VFP_START | 0x3f;
//hvs_setup_irq();
puts("done");
}
}

APP_START(hvs_dance)
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);
Loading

0 comments on commit 715ef3e

Please sign in to comment.