1 #ifdef SH7722_DEBUG_LAYER
2 #define DIRECT_ENABLE_DEBUG
3 #endif
4 
5 
6 #include <config.h>
7 
8 #include <stdio.h>
9 
10 #include <sys/mman.h>
11 
12 #include <asm/types.h>
13 
14 #include <directfb.h>
15 
16 #include <fusion/fusion.h>
17 #include <fusion/shmalloc.h>
18 
19 #include <core/core.h>
20 #include <core/coredefs.h>
21 #include <core/coretypes.h>
22 #include <core/layers.h>
23 #include <core/palette.h>
24 #include <core/surface.h>
25 #include <core/surface_buffer.h>
26 #include <core/system.h>
27 
28 #include <gfx/convert.h>
29 
30 #include <misc/conf.h>
31 
32 #include <direct/memcpy.h>
33 #include <direct/messages.h>
34 
35 #include "sh7722.h"
36 #include "sh7722_types.h"
37 #include "sh7722_multi.h"
38 
39 
40 D_DEBUG_DOMAIN( SH7722_Layer, "SH772x/Layer", "Renesas SH772x Layers" );
41 
42 /**********************************************************************************************************************/
43 
44 static int
sh7722LayerDataSize(void)45 sh7722LayerDataSize( void )
46 {
47      return sizeof(SH7722MultiLayerData);
48 }
49 
50 static int
sh7722RegionDataSize(void)51 sh7722RegionDataSize( void )
52 {
53      return sizeof(SH7722MultiRegionData);
54 }
55 
56 static DFBResult
sh7722InitLayer(CoreLayer * layer,void * driver_data,void * layer_data,DFBDisplayLayerDescription * description,DFBDisplayLayerConfig * config,DFBColorAdjustment * adjustment)57 sh7722InitLayer( CoreLayer                  *layer,
58                  void                       *driver_data,
59                  void                       *layer_data,
60                  DFBDisplayLayerDescription *description,
61                  DFBDisplayLayerConfig      *config,
62                  DFBColorAdjustment         *adjustment )
63 {
64      SH7722DriverData *sdrv = driver_data;
65      SH7722DeviceData *sdev = sdrv->dev;
66      D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
67 
68      /* set capabilities and type */
69      description->caps    = DLCAPS_SURFACE | DLCAPS_SCREEN_POSITION | DLCAPS_SRC_COLORKEY | DLCAPS_WINDOWS;
70      description->type    = DLTF_GRAPHICS;
71      description->regions = 4;
72 
73      /* set name */
74      snprintf( description->name, DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "Multi Window" );
75 
76      /* fill out the default configuration */
77      config->flags       = DLCONF_WIDTH       | DLCONF_HEIGHT |
78                            DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | DLCONF_OPTIONS;
79      config->width       = sdev->lcd_width;
80      config->height      = sdev->lcd_height;
81      config->pixelformat = DSPF_NV16;
82      config->buffermode  = DLBM_FRONTONLY;
83      config->options     = DLOP_NONE;
84 
85      return DFB_OK;
86 }
87 
88 static DFBResult
sh7722TestRegion(CoreLayer * layer,void * driver_data,void * layer_data,CoreLayerRegionConfig * config,CoreLayerRegionConfigFlags * failed)89 sh7722TestRegion( CoreLayer                  *layer,
90                   void                       *driver_data,
91                   void                       *layer_data,
92                   CoreLayerRegionConfig      *config,
93                   CoreLayerRegionConfigFlags *failed )
94 {
95      CoreLayerRegionConfigFlags fail = 0;
96 
97      D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
98 
99      if (config->options & ~SH7722_MULTI_SUPPORTED_OPTIONS)
100           fail |= CLRCF_OPTIONS;
101 
102      switch (config->format) {
103           case DSPF_ARGB:
104           case DSPF_RGB32:
105           case DSPF_RGB24:
106           case DSPF_RGB16:
107                break;
108 
109 #if FIXME_MAKE_CONFIGURABLE_
110           case DSPF_NV12:
111           case DSPF_NV16:
112                break;
113 #endif
114 
115           default:
116                fail |= CLRCF_FORMAT;
117      }
118 
119      if (config->width  < 32 || config->width  > 1280)
120           fail |= CLRCF_WIDTH;
121 
122      if (config->height < 32 || config->height > 1024)
123           fail |= CLRCF_HEIGHT;
124 
125 
126      if (failed)
127           *failed = fail;
128 
129      if (fail)
130           return DFB_UNSUPPORTED;
131 
132      return DFB_OK;
133 }
134 
135 static DFBResult
sh7722AddRegion(CoreLayer * layer,void * driver_data,void * layer_data,void * region_data,CoreLayerRegionConfig * config)136 sh7722AddRegion( CoreLayer             *layer,
137                  void                  *driver_data,
138                  void                  *layer_data,
139                  void                  *region_data,
140                  CoreLayerRegionConfig *config )
141 {
142      int                    n;
143      SH7722MultiRegionData *sreg = region_data;
144      SH7722MultiLayerData  *slay = layer_data;
145 
146      D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
147 
148      if (slay->added == 0xF)
149           return DFB_LIMITEXCEEDED;
150 
151      for (n=0; n<4; n++)
152           if (! (slay->added & (1 << n)))
153                break;
154 
155      D_ASSERT( n < 4 );
156 
157      sreg->config = *config;
158 
159 
160      slay->added |= 1 << n;
161 
162      D_MAGIC_SET( sreg, SH7722MultiRegionData );
163 
164      return DFB_OK;
165 }
166 
167 static DFBResult
sh7722SetRegion(CoreLayer * layer,void * driver_data,void * layer_data,void * region_data,CoreLayerRegionConfig * config,CoreLayerRegionConfigFlags updated,CoreSurface * surface,CorePalette * palette,CoreSurfaceBufferLock * lock)168 sh7722SetRegion( CoreLayer                  *layer,
169                  void                       *driver_data,
170                  void                       *layer_data,
171                  void                       *region_data,
172                  CoreLayerRegionConfig      *config,
173                  CoreLayerRegionConfigFlags  updated,
174                  CoreSurface                *surface,
175                  CorePalette                *palette,
176                  CoreSurfaceBufferLock      *lock )
177 {
178      int                    n;
179      SH7722DriverData      *sdrv = driver_data;
180      SH7722DeviceData      *sdev = sdrv->dev;
181      SH7722MultiRegionData *sreg = region_data;
182 
183      D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
184 
185      D_MAGIC_ASSERT( sreg, SH7722MultiRegionData );
186 
187      fusion_skirmish_prevail( &sdev->beu_lock );
188 
189      /* Wait for idle BEU. */
190      BEU_Wait( sdrv, sdev );
191 
192      n = sreg->index;
193 
194      D_ASSERT( n >= 0 );
195      D_ASSERT( n <= 3 );
196 
197      /* Update position? */
198      if (updated & CLRCF_DEST) {
199           /* Set horizontal and vertical offset. */
200           SH7722_SETREG32( sdrv, BMLOCR(n), (config->dest.y << 16) | config->dest.x );
201      }
202 
203      /* Update size? */
204      if (updated & (CLRCF_WIDTH | CLRCF_HEIGHT)) {
205           /* Set width and height. */
206           SH7722_SETREG32( sdrv, BMSSZR(n), (config->height << 16) | config->width );
207      }
208 
209      /* Update surface? */
210      if (updated & CLRCF_SURFACE) {
211           CoreSurfaceBuffer *buffer;
212 
213           D_ASSERT( surface != NULL );
214 
215           buffer = lock->buffer;
216 
217           D_ASSERT( buffer != NULL );
218 
219           /* Set buffer pitch. */
220           SH7722_SETREG32( sdrv, BMSMWR(n), lock->pitch );
221 
222           /* Set buffer offset (Y plane or RGB packed). */
223           SH7722_SETREG32( sdrv, BMSAYR(n), lock->phys );
224 
225           /* Set buffer offset (UV plane). */
226           if (DFB_PLANAR_PIXELFORMAT(buffer->format)) {
227                D_ASSUME( buffer->format == DSPF_NV12 || buffer->format == DSPF_NV16 );
228 
229                SH7722_SETREG32( sdrv, BMSACR(n), lock->phys + lock->pitch * surface->config.size.h );
230           }
231      }
232 
233      /* Update format? */
234      if (updated & CLRCF_FORMAT) {
235           unsigned long tBMSIFR = 0;
236 
237           /* Set pixel format. */
238           switch (config->format) {
239                case DSPF_NV12:
240                     tBMSIFR |= CHRR_YCBCR_420;
241                     break;
242 
243                case DSPF_NV16:
244                     tBMSIFR |= CHRR_YCBCR_422;
245                     break;
246 
247                case DSPF_ARGB:
248                     tBMSIFR |= RPKF_ARGB;
249                     break;
250 
251                case DSPF_RGB32:
252                     tBMSIFR |= RPKF_RGB32;
253                     break;
254 
255                case DSPF_RGB24:
256                     tBMSIFR |= RPKF_RGB24;
257                     break;
258 
259                case DSPF_RGB16:
260                     tBMSIFR |= RPKF_RGB16;
261                     break;
262 
263                default:
264                     break;
265           }
266 
267           /* FIXME: all regions need to have the same format! */
268           SH7722_SETREG32( sdrv, BMSIFR, tBMSIFR );
269      }
270 
271      SH7722_SETREG32( sdrv, BMWCR0, SH7722_GETREG32( sdrv, BMWCR0 ) | (1 << n) );
272 
273      fusion_skirmish_dismiss( &sdev->beu_lock );
274 
275      return DFB_OK;
276 }
277 
278 static DFBResult
sh7722RemoveRegion(CoreLayer * layer,void * driver_data,void * layer_data,void * region_data)279 sh7722RemoveRegion( CoreLayer             *layer,
280                     void                  *driver_data,
281                     void                  *layer_data,
282                     void                  *region_data )
283 {
284      int                    n;
285      SH7722DriverData      *sdrv = driver_data;
286      SH7722DeviceData      *sdev = sdrv->dev;
287      SH7722MultiRegionData *sreg = region_data;
288 
289      D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
290 
291      D_MAGIC_ASSERT( sreg, SH7722MultiRegionData );
292 
293      n = sreg->index;
294 
295      D_ASSERT( n >= 0 );
296      D_ASSERT( n <= 3 );
297 
298      fusion_skirmish_prevail( &sdev->beu_lock );
299 
300      /* Wait for idle BEU. */
301      BEU_Wait( sdrv, sdev );
302 
303      /* Disable multi window. */
304      SH7722_SETREG32( sdrv, BMWCR0, SH7722_GETREG32( sdrv, BMWCR0 ) & ~(1 << n) );
305 
306      /* Start operation! */
307      BEU_Start( sdrv, sdev );
308 
309      fusion_skirmish_dismiss( &sdev->beu_lock );
310 
311      return DFB_OK;
312 }
313 
314 static DFBResult
sh7722FlipRegion(CoreLayer * layer,void * driver_data,void * layer_data,void * region_data,CoreSurface * surface,DFBSurfaceFlipFlags flags,CoreSurfaceBufferLock * lock)315 sh7722FlipRegion( CoreLayer             *layer,
316                   void                  *driver_data,
317                   void                  *layer_data,
318                   void                  *region_data,
319                   CoreSurface           *surface,
320                   DFBSurfaceFlipFlags    flags,
321                   CoreSurfaceBufferLock *lock )
322 {
323      int                    n;
324      CoreSurfaceBuffer     *buffer;
325      SH7722DriverData      *sdrv = driver_data;
326      SH7722DeviceData      *sdev = sdrv->dev;
327      SH7722MultiRegionData *sreg = region_data;
328 
329      D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
330 
331      D_ASSERT( surface != NULL );
332      D_ASSERT( sdrv != NULL );
333      D_ASSERT( sdev != NULL );
334      D_MAGIC_ASSERT( sreg, SH7722MultiRegionData );
335 
336      n = sreg->index;
337 
338      D_ASSERT( n >= 0 );
339      D_ASSERT( n <= 3 );
340 
341      buffer = lock->buffer;
342      D_ASSERT( buffer != NULL );
343 
344      fusion_skirmish_prevail( &sdev->beu_lock );
345 
346      /* Wait for idle BEU. */
347      BEU_Wait( sdrv, sdev );
348 
349      /* Set buffer pitch. */
350      SH7722_SETREG32( sdrv, BMSMWR(n), lock->pitch );
351 
352      /* Set buffer offset (Y plane or RGB packed). */
353      SH7722_SETREG32( sdrv, BMSAYR(n), lock->phys );
354 
355      /* Set buffer offset (UV plane). */
356      if (DFB_PLANAR_PIXELFORMAT(buffer->format)) {
357           D_ASSUME( buffer->format == DSPF_NV12 || buffer->format == DSPF_NV16 );
358 
359           SH7722_SETREG32( sdrv, BMSACR(n), lock->phys + lock->pitch * surface->config.size.h );
360      }
361 
362      /* Start operation! */
363      BEU_Start( sdrv, sdev );
364 
365      fusion_skirmish_dismiss( &sdev->beu_lock );
366 
367      /* Wait for idle BEU? */
368      if (flags & DSFLIP_WAIT)
369           BEU_Wait( sdrv, sdev );
370 
371      dfb_surface_flip( surface, false );
372 
373      return DFB_OK;
374 }
375 
376 static DFBResult
sh7722UpdateRegion(CoreLayer * layer,void * driver_data,void * layer_data,void * region_data,CoreSurface * surface,const DFBRegion * update,CoreSurfaceBufferLock * lock)377 sh7722UpdateRegion( CoreLayer             *layer,
378                     void                  *driver_data,
379                     void                  *layer_data,
380                     void                  *region_data,
381                     CoreSurface           *surface,
382                     const DFBRegion       *update,
383                     CoreSurfaceBufferLock *lock )
384 {
385      SH7722DriverData *sdrv = driver_data;
386      SH7722DeviceData *sdev = sdrv->dev;
387 
388      D_DEBUG_AT( SH7722_Layer, "%s()\n", __FUNCTION__ );
389 
390      D_ASSERT( surface != NULL );
391      D_ASSERT( sdrv != NULL );
392      D_ASSERT( sdev != NULL );
393 
394      /* Start operation! */
395      BEU_Start( sdrv, sdev );
396 
397      return DFB_OK;
398 }
399 
400 DisplayLayerFuncs sh7722MultiLayerFuncs = {
401      .LayerDataSize  = sh7722LayerDataSize,
402      .RegionDataSize = sh7722RegionDataSize,
403      .InitLayer      = sh7722InitLayer,
404 
405      .TestRegion     = sh7722TestRegion,
406      .AddRegion      = sh7722AddRegion,
407      .SetRegion      = sh7722SetRegion,
408      .RemoveRegion   = sh7722RemoveRegion,
409      .FlipRegion     = sh7722FlipRegion,
410      .UpdateRegion   = sh7722UpdateRegion,
411 };
412 
413