11#include <arch/ops.h>
2+ #include <assert.h>
23#include <lk/console_cmd.h>
34#include <lk/reg.h>
45#include <platform/bcm28xx/hvs.h>
6+ #include <platform/interrupts.h>
57#include <stdio.h>
68#include <stdlib.h>
7- #include <platform/interrupts.h>
89
910// note, 4096 slots total
1011volatile uint32_t * dlist_memory = REG32 (SCALER_LIST_MEMORY );
@@ -33,6 +34,8 @@ static uint32_t gfx_to_hvs_pixel_format(gfx_format fmt) {
3334}
3435
3536void hvs_add_plane (gfx_surface * fb , int x , int y , bool hflip ) {
37+ assert (fb );
38+ printf ("rendering FB of size %dx%d at %dx%d\n" , fb -> width , fb -> height , x , y );
3639 dlist_memory [display_slot ++ ] = CONTROL_VALID
3740 | CONTROL_WORDS (7 )
3841 | CONTROL_PIXEL_ORDER (HVS_PIXEL_ORDER_ABGR )
@@ -48,22 +51,66 @@ void hvs_add_plane(gfx_surface *fb, int x, int y, bool hflip) {
4851 dlist_memory [display_slot ++ ] = fb -> stride * fb -> pixelsize ;
4952}
5053
51- void hvs_add_plane_scaled (gfx_surface * fb , int x , int y , int width , int height , bool hflip ) {
54+ enum scaling_mode {
55+ none ,
56+ PPF , // upscaling?
57+ TPZ // downscaling?
58+ };
59+
60+ static void write_tpz (unsigned int source , unsigned int dest ) {
61+ uint32_t scale = (1 <<16 ) * source / dest ;
62+ uint32_t recip = ~0 / scale ;
63+ dlist_memory [display_slot ++ ] = scale << 8 ;
64+ dlist_memory [display_slot ++ ] = recip ;
65+ }
66+
67+ void hvs_add_plane_scaled (gfx_surface * fb , int x , int y , unsigned int width , unsigned int height , bool hflip ) {
68+ assert (fb );
69+ //printf("rendering FB of size %dx%d at %dx%d, scaled down to %dx%d\n", fb->width, fb->height, x, y, width, height);
70+ enum scaling_mode xmode , ymode ;
71+ if (fb -> width > width ) xmode = TPZ ;
72+ else if (fb -> width < width ) xmode = PPF ;
73+ else xmode = none ;
74+
75+ if (fb -> height > height ) ymode = TPZ ;
76+ else if (fb -> height < height ) ymode = PPF ;
77+ else ymode = none ;
78+
79+ int scl0 ;
80+ switch ((xmode << 2 ) | ymode ) {
81+ case (PPF << 2 ) | PPF :
82+ scl0 = SCALER_CTL0_SCL_H_PPF_V_PPF ;
83+ break ;
84+ case (TPZ << 2 ) | PPF :
85+ scl0 = SCALER_CTL0_SCL_H_TPZ_V_PPF ;
86+ break ;
87+ case (PPF << 2 ) | TPZ :
88+ scl0 = SCALER_CTL0_SCL_H_PPF_V_TPZ ;
89+ break ;
90+ case (TPZ << 2 ) | TPZ :
91+ scl0 = SCALER_CTL0_SCL_H_TPZ_V_TPZ ;
92+ break ;
93+ default :
94+ puts ("unsupported scale combonation" );
95+ }
96+
5297 int start = display_slot ;
53- dlist_memory [display_slot ++ ] = CONTROL_VALID
54- | CONTROL_WORDS (14 )
98+ dlist_memory [display_slot ++ ] = 0 // CONTROL_VALID
99+ // | CONTROL_WORDS(14)
55100 | CONTROL_PIXEL_ORDER (HVS_PIXEL_ORDER_ABGR )
56101// | CONTROL0_VFLIP // makes the HVS addr count down instead, pointer word must be last line of image
57102 | (hflip ? CONTROL0_HFLIP : 0 )
58- | CONTROL_FORMAT (gfx_to_hvs_pixel_format (fb -> format ));
59- dlist_memory [display_slot ++ ] = POS0_X (x ) | POS0_Y (y ) | POS0_ALPHA (0xff );
60- dlist_memory [display_slot ++ ] = width | (height << 16 );
61- dlist_memory [display_slot ++ ] = POS2_H (fb -> height ) | POS2_W (fb -> width );
62- dlist_memory [display_slot ++ ] = 0xDEADBEEF ; // dummy for HVS state
63- dlist_memory [display_slot ++ ] = (uint32_t )fb -> ptr | 0xc0000000 ;
64- dlist_memory [display_slot ++ ] = 0xDEADBEEF ; // dummy for HVS state
65- dlist_memory [display_slot ++ ] = fb -> stride * fb -> pixelsize ;
66- dlist_memory [display_slot ++ ] = 0x100 ;
103+ | CONTROL_FORMAT (gfx_to_hvs_pixel_format (fb -> format ))
104+ | (scl0 << 5 )
105+ | (scl0 << 8 ); // SCL1
106+ dlist_memory [display_slot ++ ] = POS0_X (x ) | POS0_Y (y ) | POS0_ALPHA (0xff ); // position word 0
107+ dlist_memory [display_slot ++ ] = width | (height << 16 ); // position word 1
108+ dlist_memory [display_slot ++ ] = POS2_H (fb -> height ) | POS2_W (fb -> width ); // position word 2
109+ dlist_memory [display_slot ++ ] = 0xDEADBEEF ; // position word 3, dummy for HVS state
110+ dlist_memory [display_slot ++ ] = (uint32_t )fb -> ptr | 0xc0000000 ; // pointer word 0
111+ dlist_memory [display_slot ++ ] = 0xDEADBEEF ; // pointer context word 0 dummy for HVS state
112+ dlist_memory [display_slot ++ ] = fb -> stride * fb -> pixelsize ; // pitch word 0
113+ dlist_memory [display_slot ++ ] = 0x100 ; // LBM base addr
67114
68115#if 0
69116 bool ppf = false;
@@ -76,19 +123,26 @@ void hvs_add_plane_scaled(gfx_surface *fb, int x, int y, int width, int height,
76123 dlist_memory [display_slot ++ ] = 0xDEADBEEF ; //scaling context
77124 }
78125#endif
79- bool tpz = true;
80- if (tpz ) {
81- uint32_t xscale = ( 1 << 16 ) * fb -> width / width ;
82- uint32_t yscale = ( 1 << 16 ) * fb -> height / height ;
83- uint32_t xrecip = ~ 0 / xscale ;
84- uint32_t yrecip = ~ 0 / yscale ;
85- dlist_memory [ display_slot ++ ] = ( xscale << 8 );
86- dlist_memory [ display_slot ++ ] = xrecip ;
87- dlist_memory [ display_slot ++ ] = ( yscale << 8 );
88- dlist_memory [ display_slot ++ ] = yrecip ;
89- dlist_memory [ display_slot ++ ] = 0xDEADBEEF ; //scaling context
126+
127+ if (xmode == PPF ) {
128+ puts ( "unfinished" ) ;
129+ }
130+
131+ if ( ymode == PPF ) {
132+ puts ( "unfinished" );
133+ }
134+
135+ if ( xmode == TPZ ) {
136+ write_tpz ( fb -> width , width );
90137 }
91- printf ("entry size: %d\n" , display_slot - start );
138+
139+ if (ymode == TPZ ) {
140+ write_tpz (fb -> height , height );
141+ dlist_memory [display_slot ++ ] = 0xDEADBEEF ; // context for scaling
142+ }
143+
144+ //printf("entry size: %d, spans 0x%x-0x%x\n", display_slot - start, start, display_slot);
145+ dlist_memory [start ] |= CONTROL_VALID | CONTROL_WORDS (display_slot - start );
92146}
93147
94148void hvs_terminate_list (void ) {
@@ -138,6 +192,43 @@ void hvs_wipe_displaylist(void) {
138192 display_slot = 0 ;
139193}
140194
195+ static bool bcm_host_is_model_pi4 (void ) {
196+ return false;
197+ }
198+
199+ void hvs_print_position0 (uint32_t w ) {
200+ printf ("position0: 0x%x\n" , w );
201+ if (bcm_host_is_model_pi4 ()) {
202+ printf (" x: %d y: %d\n" , w & 0x3fff , (w >> 16 ) & 0x3fff );
203+ } else {
204+ printf (" x: %d y: %d\n" , w & 0xfff , (w >> 12 ) & 0xfff );
205+ }
206+ }
207+ void hvs_print_control2 (uint32_t w ) {
208+ printf ("control2: 0x%x\n" , w );
209+ printf (" alpha: 0x%x\n" , (w >> 4 ) & 0xffff );
210+ printf (" alpha mode: %d\n" , (w >> 30 ) & 0x3 );
211+ }
212+ void hvs_print_word1 (uint32_t w ) {
213+ printf (" word1: 0x%x\n" , w );
214+ }
215+ void hvs_print_position2 (uint32_t w ) {
216+ printf ("position2: 0x%x\n" , w );
217+ printf (" width: %d height: %d\n" , w & 0xffff , (w >> 16 ) & 0xfff );
218+ }
219+ void hvs_print_position3 (uint32_t w ) {
220+ printf ("position3: 0x%x\n" , w );
221+ }
222+ void hvs_print_pointer0 (uint32_t w ) {
223+ printf ("pointer word: 0x%x\n" , w );
224+ }
225+ void hvs_print_pointerctx0 (uint32_t w ) {
226+ printf ("pointer context word: 0x%x\n" , w );
227+ }
228+ void hvs_print_pitch0 (uint32_t w ) {
229+ printf ("pitch word: 0x%x\n" , w );
230+ }
231+
141232static int cmd_hvs_dump (int argc , const cmd_args * argv ) {
142233 printf ("SCALER_DISPCTRL: 0x%x\n" , * REG32 (SCALER_DISPCTRL ));
143234 printf ("SCALER_DISPSTAT: 0x%x\n" , * REG32 (SCALER_DISPSTAT ));
@@ -162,8 +253,60 @@ static int cmd_hvs_dump(int argc, const cmd_args *argv) {
162253 uint32_t base = hvs_channels [i ].dispbase ;
163254 printf ("SCALER_DISPBASE%d: base 0x%x top 0x%x\n\n" , i , base & 0xffff , base >> 16 );
164255 }
165- for (uint32_t i = list1 ; i < (list1 + 16 ); i ++ ) {
256+ for (uint32_t i = list1 ; i < (list1 + 64 ); i ++ ) {
166257 printf ("dlist[%x]: 0x%x\n" , i , dlist_memory [i ]);
258+ if (dlist_memory [i ] & BV (31 )) {
259+ puts ("(31)END" );
260+ break ;
261+ }
262+ if (dlist_memory [i ] & BV (30 )) {
263+ int x = i ;
264+ int words = (dlist_memory [i ] >> 24 ) & 0x3f ;
265+ for (unsigned int index = i ; index < (i + words ); index ++ ) {
266+ printf ("raw dlist[%d] == 0x%x\n" , index - i , dlist_memory [index ]);
267+ }
268+ bool unity ;
269+ printf (" (3:0)format: %d\n" , dlist_memory [i ] & 0xf );
270+ if (dlist_memory [i ] & (1 <<4 )) puts (" (4)unity" );
271+ printf (" (7:5)SCL0: %d\n" , (dlist_memory [i ] >> 5 ) & 0x7 );
272+ printf (" (10:8)SCL1: %d\n" , (dlist_memory [i ] >> 8 ) & 0x7 );
273+ if (false) { // is bcm2711
274+ if (dlist_memory [i ] & (1 <<11 )) puts (" (11)rgb expand" );
275+ if (dlist_memory [i ] & (1 <<12 )) puts (" (12)alpha expand" );
276+ } else {
277+ printf (" (12:11)rgb expand: %d\n" , (dlist_memory [i ] >> 11 ) & 0x3 );
278+ }
279+ printf (" (14:13)pixel order: %d\n" , (dlist_memory [i ] >> 13 ) & 0x3 );
280+ if (false) { // is bcm2711
281+ unity = dlist_memory [i ] & (1 <<15 );
282+ } else {
283+ unity = dlist_memory [i ] & (1 <<4 );
284+ if (dlist_memory [i ] & (1 <<15 )) puts (" (15)vflip" );
285+ if (dlist_memory [i ] & (1 <<16 )) puts (" (16)hflip" );
286+ }
287+ printf (" (18:17)key mode: %d\n" , (dlist_memory [i ] >> 17 ) & 0x3 );
288+ if (dlist_memory [i ] & (1 <<19 )) puts (" (19)alpha mask" );
289+ printf (" (21:20)tiling mode: %d\n" , (dlist_memory [i ] >> 20 ) & 0x3 );
290+ printf (" (29:24)words: %d\n" , words );
291+ x ++ ;
292+ hvs_print_position0 (dlist_memory [x ++ ]);
293+ if (bcm_host_is_model_pi4 ()) {
294+ hvs_print_control2 (dlist_memory [x ++ ]);
295+ }
296+ if (unity ) {
297+ puts ("unity scaling" );
298+ } else {
299+ hvs_print_word1 (dlist_memory [x ++ ]);
300+ }
301+ hvs_print_position2 (dlist_memory [x ++ ]);
302+ hvs_print_position3 (dlist_memory [x ++ ]);
303+ hvs_print_pointer0 (dlist_memory [x ++ ]);
304+ hvs_print_pointerctx0 (dlist_memory [x ++ ]);
305+ hvs_print_pitch0 (dlist_memory [x ++ ]);
306+ if (words > 1 ) {
307+ i += words - 1 ;
308+ }
309+ }
167310 }
168311 return 0 ;
169312}
0 commit comments