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