From 715ef3eddd3477df5d3007c2b7d0bf5696052c99 Mon Sep 17 00:00:00 2001 From: Michael Bishop Date: Mon, 22 Mar 2021 20:31:47 -0300 Subject: [PATCH] vec dance works --- arch/vpu/intc.c | 1 + arch/vpu/thread.c | 8 +- dev/timer/vc4/rules.mk | 1 + dev/timer/vc4/timer.c | 22 +- platform/bcm28xx/hvs-dance/dance.c | 125 +++++++---- platform/bcm28xx/hvs-dance/include/dance.h | 5 + platform/bcm28xx/hvs/hvs.c | 195 +++++++++++++++--- .../hvs/include/platform/bcm28xx/hvs.h | 13 +- platform/bcm28xx/include/platform/bcm28xx.h | 1 + platform/bcm28xx/pixelvalve/pv.c | 6 +- .../power/include/platform/bcm28xx/power.h | 18 +- platform/bcm28xx/power/power.c | 4 +- .../vec/include/platform/bcm28xx/vec.h | 16 +- platform/bcm28xx/vec/vec.c | 10 +- project/rpi3-start.mk | 1 + 15 files changed, 321 insertions(+), 105 deletions(-) create mode 100644 platform/bcm28xx/hvs-dance/include/dance.h diff --git a/arch/vpu/intc.c b/arch/vpu/intc.c index 99caed757a..f74827cb77 100644 --- a/arch/vpu/intc.c +++ b/arch/vpu/intc.c @@ -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); diff --git a/arch/vpu/thread.c b/arch/vpu/thread.c index b90ff8eff7..459937af22 100644 --- a/arch/vpu/thread.c +++ b/arch/vpu/thread.c @@ -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); @@ -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} diff --git a/dev/timer/vc4/rules.mk b/dev/timer/vc4/rules.mk index bedd03f803..eed55d5093 100644 --- a/dev/timer/vc4/rules.mk +++ b/dev/timer/vc4/rules.mk @@ -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 diff --git a/dev/timer/vc4/timer.c b/dev/timer/vc4/timer.c index 87215949e3..d2321075ed 100644 --- a/dev/timer/vc4/timer.c +++ b/dev/timer/vc4/timer.c @@ -1,15 +1,19 @@ #include #include +#include #include #include #include #include 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); @@ -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; } diff --git a/platform/bcm28xx/hvs-dance/dance.c b/platform/bcm28xx/hvs-dance/dance.c index 39ff0930d5..dc4538dc39 100644 --- a/platform/bcm28xx/hvs-dance/dance.c +++ b/platform/bcm28xx/hvs-dance/dance.c @@ -7,7 +7,7 @@ #include #include #include -#include +//#include #include #include #include @@ -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; @@ -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; @@ -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; @@ -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) { @@ -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) { @@ -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); @@ -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; @@ -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; ix = (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; } @@ -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; iwidth; i++) { @@ -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; ix = (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) diff --git a/platform/bcm28xx/hvs-dance/include/dance.h b/platform/bcm28xx/hvs-dance/include/dance.h new file mode 100644 index 0000000000..ee74294439 --- /dev/null +++ b/platform/bcm28xx/hvs-dance/include/dance.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +void dance_start(gfx_surface* fbin, int hvs_channel); diff --git a/platform/bcm28xx/hvs/hvs.c b/platform/bcm28xx/hvs/hvs.c index 6d93123fca..a5d0b51506 100644 --- a/platform/bcm28xx/hvs/hvs.c +++ b/platform/bcm28xx/hvs/hvs.c @@ -1,10 +1,11 @@ #include +#include #include #include #include +#include #include #include -#include // note, 4096 slots total volatile uint32_t* dlist_memory = REG32(SCALER_LIST_MEMORY); @@ -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) @@ -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; @@ -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) { @@ -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)); @@ -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; } diff --git a/platform/bcm28xx/hvs/include/platform/bcm28xx/hvs.h b/platform/bcm28xx/hvs/include/platform/bcm28xx/hvs.h index a33bb0847a..5c9754e4b5 100644 --- a/platform/bcm28xx/hvs/include/platform/bcm28xx/hvs.h +++ b/platform/bcm28xx/hvs/include/platform/bcm28xx/hvs.h @@ -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) @@ -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) @@ -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); diff --git a/platform/bcm28xx/include/platform/bcm28xx.h b/platform/bcm28xx/include/platform/bcm28xx.h index be73696e1c..466c387bf3 100644 --- a/platform/bcm28xx/include/platform/bcm28xx.h +++ b/platform/bcm28xx/include/platform/bcm28xx.h @@ -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) diff --git a/platform/bcm28xx/pixelvalve/pv.c b/platform/bcm28xx/pixelvalve/pv.c index b70b899f00..ffb5186cdb 100644 --- a/platform/bcm28xx/pixelvalve/pv.c +++ b/platform/bcm28xx/pixelvalve/pv.c @@ -4,8 +4,6 @@ #include #include -#define BV(b) (1 << b) - struct pixel_valve *getPvAddr(int pvnr) { uint32_t addr; assert(pvnr <= 2); @@ -22,7 +20,7 @@ struct pixel_valve *getPvAddr(int pvnr) { default: return NULL; } - struct pixel_valve *rawpv = addr; + struct pixel_valve *rawpv = (struct pixel_valve*) addr; return rawpv; } @@ -87,7 +85,7 @@ void setup_pixelvalve(struct pv_timings *t, int pvnr) { } void setup_pv_interrupt(int pvnr, int_handler handler, void *arg) { - struct pixel_valve *rawpv = getPvAddr(pvnr); + //struct pixel_valve *rawpv = getPvAddr(pvnr); unsigned int irq = getPvIrq(pvnr); register_int_handler(irq, handler, arg); diff --git a/platform/bcm28xx/power/include/platform/bcm28xx/power.h b/platform/bcm28xx/power/include/platform/bcm28xx/power.h index a5e38f508d..9c3eaa4ccb 100644 --- a/platform/bcm28xx/power/include/platform/bcm28xx/power.h +++ b/platform/bcm28xx/power/include/platform/bcm28xx/power.h @@ -3,8 +3,6 @@ #include #include -#define BIT(n) (1< #include -#define BIT(n) (1 << n) - #define VEC_BASE (BCM_PERIPH_BASE_VIRT + 0x806000) #define VEC_WSE_RESET (VEC_BASE + 0x0c0) @@ -12,7 +10,7 @@ #define VEC_CONFIG0 (VEC_BASE + 0x104) #define VEC_CONFIG0_NTSC_STD 0 #define VEC_CONFIG0_PAL_BDGHI_STD 1 -#define VEC_CONFIG0_PDEN BIT(6) +#define VEC_CONFIG0_PDEN BV(6) #define VEC_SCHPH (VEC_BASE + 0x108) #define VEC_SOFT_RESET (VEC_BASE + 0x10c) #define VEC_CLMP0_START (VEC_BASE + 0x144) @@ -20,20 +18,20 @@ #define VEC_FREQ3_2 (VEC_BASE + 0x180) #define VEC_FREQ1_0 (VEC_BASE + 0x184) #define VEC_CONFIG1 (VEC_BASE + 0x188) -#define VEC_CONFIG1_CUSTOM_FREQ BIT(0) +#define VEC_CONFIG1_CUSTOM_FREQ BV(0) #define VEC_CONFIG1_C_CVBS_CVBS (7 << 10) #define VEC_CONFIG2 (VEC_BASE + 0x18c) -#define VEC_CONFIG2_UV_DIG_DIS BIT(6) -#define VEC_CONFIG2_RGB_DIG_DIS BIT(5) +#define VEC_CONFIG2_UV_DIG_DIS BV(6) +#define VEC_CONFIG2_RGB_DIG_DIS BV(5) #define VEC_CONFIG3 (VEC_BASE + 0x1a0) #define VEC_CONFIG3_HORIZ_LEN_STD (0 << 0) #define VEC_MASK0 (VEC_BASE + 0x204) #define VEC_CFG (VEC_BASE + 0x208) -#define VEC_CFG_VEC_EN BIT(3) +#define VEC_CFG_VEC_EN BV(3) #define VEC_DAC_CONFIG (VEC_BASE + 0x210) #define VEC_DAC_CONFIG_LDO_BIAS_CTRL(x) ((x) << 24) #define VEC_DAC_CONFIG_DRIVER_CTRL(x) ((x) << 16) #define VEC_DAC_CONFIG_DAC_CTRL(x) (x) #define VEC_DAC_MISC (VEC_BASE + 0x214) -#define VEC_DAC_MISC_DAC_RST_N BIT(0) -#define VEC_DAC_MISC_VID_ACT BIT(8) +#define VEC_DAC_MISC_DAC_RST_N BV(0) +#define VEC_DAC_MISC_VID_ACT BV(8) diff --git a/platform/bcm28xx/vec/vec.c b/platform/bcm28xx/vec/vec.c index baf32bf150..1782cafdcf 100644 --- a/platform/bcm28xx/vec/vec.c +++ b/platform/bcm28xx/vec/vec.c @@ -1,7 +1,8 @@ #include +#include +#include #include #include -#include #include #include #include @@ -12,6 +13,8 @@ #include "pi-logo.h" +//extern uint8_t* pilogo; + enum vec_mode { ntsc, ntscj, @@ -95,7 +98,6 @@ static void vec_init(const struct app_descriptor *app) { stride = t.hactive; framebuffer = gfx_create_surface(NULL, width, height, width, GFX_FORMAT_ARGB_8888); } - printf("framebuffer at 0x%x is %dx%d stride: %d\n", framebuffer->ptr, framebuffer->width, framebuffer->height, framebuffer->stride); int grid = 20; for (int x=0; x< width; x++) { for (int y=0; y < height; y++) { @@ -117,9 +119,11 @@ static void vec_init(const struct app_descriptor *app) { logo = tga_decode(pilogo, sizeof(pilogo), GFX_FORMAT_ARGB_8888); list_start = display_slot; hvs_add_plane(framebuffer, 0, 0, false); - hvs_add_plane(logo, (width/2) - (logo->width/2), 0, false); + hvs_add_plane_scaled(logo, (width/2) - (logo->width/2), 0, 100, 100, false); hvs_terminate_list(); *REG32(SCALER_DISPLIST1) = list_start; + + dance_start(logo, 1); } static void vec_entry(const struct app_descriptor *app, void *args) { diff --git a/project/rpi3-start.mk b/project/rpi3-start.mk index f205b77575..8cd7630134 100644 --- a/project/rpi3-start.mk +++ b/project/rpi3-start.mk @@ -10,3 +10,4 @@ MODULES += \ lib/debugcommands \ platform/bcm28xx/otp \ platform/bcm28xx/vec \ + platform/bcm28xx/hvs-dance \