1 /*
2 TI Davinci driver - Graphics Driver
3
4 (c) Copyright 2007 Telio AG
5
6 Written by Denis Oliver Kropp <dok@directfb.org>
7
8 Code is derived from VMWare driver.
9
10 (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
11 (c) Copyright 2000-2004 Convergence (integrated media) GmbH
12
13 All rights reserved.
14
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Lesser General Public
17 License as published by the Free Software Foundation; either
18 version 2 of the License, or (at your option) any later version.
19
20 This library is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 Lesser General Public License for more details.
24
25 You should have received a copy of the GNU Lesser General Public
26 License along with this library; if not, write to the
27 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28 Boston, MA 02111-1307, USA.
29 */
30
31 //#define DIRECT_ENABLE_DEBUG
32
33 #include <config.h>
34
35 #include <asm/types.h>
36
37 #include <string.h>
38 #include <stdio.h>
39 #include <fcntl.h>
40 #include <sys/ioctl.h>
41 #include <sys/mman.h>
42 #include <sys/types.h>
43 #include <unistd.h>
44
45 #include <directfb.h>
46
47 #include <direct/debug.h>
48 #include <direct/messages.h>
49
50 #include <core/core.h>
51 #include <core/gfxcard.h>
52 #include <core/surface_pool.h>
53 #include <core/system.h>
54
55 #include <misc/conf.h>
56
57 #include "davincifb.h"
58
59 #include "davinci_2d.h"
60 #include "davinci_gfxdriver.h"
61 #include "davinci_osd.h"
62 #include "davinci_osd_pool.h"
63 #include "davinci_screen.h"
64 #include "davinci_video.h"
65 #include "davinci_video_pool.h"
66
67
68 #include <core/graphics_driver.h>
69
DFB_GRAPHICS_DRIVER(davinci)70 DFB_GRAPHICS_DRIVER( davinci )
71
72 /**********************************************************************************************************************/
73
74 static DFBResult
75 open_fb( DavinciDriverData *ddrv,
76 DavinciDeviceData *ddev,
77 unsigned int fbnum )
78 {
79 int ret;
80 char buf1[16];
81 char buf2[16];
82 DavinciFB *fb;
83 struct fb_var_screeninfo var;
84
85 D_ASSERT( ddrv != NULL );
86 D_ASSERT( ddev != NULL );
87 D_ASSERT( fbnum < D_ARRAY_SIZE(ddrv->fb) );
88 D_ASSERT( fbnum < D_ARRAY_SIZE(ddev->fix) );
89
90 fb = &ddrv->fb[fbnum];
91
92 fb->num = fbnum;
93
94 snprintf( buf1, sizeof(buf1), "/dev/fb%u", fbnum );
95 snprintf( buf2, sizeof(buf2), "/dev/fb/%u", fbnum );
96
97 fb->fd = direct_try_open( buf1, buf2, O_RDWR, true );
98 if (fb->fd < 0)
99 return DFB_INIT;
100
101 ret = ioctl( fb->fd, FBIOGET_VSCREENINFO, &var );
102 if (ret) {
103 D_PERROR( "Davinci/Driver: FBIOGET_VSCREENINFO (fb%d) failed!\n", fbnum );
104 close( fb->fd );
105 return DFB_INIT;
106 }
107
108 ret = ioctl( fb->fd, FBIOGET_FSCREENINFO, &ddev->fix[fbnum] );
109 if (ret) {
110 D_PERROR( "Davinci/Driver: FBIOGET_FSCREENINFO (fb%d) failed!\n", fbnum );
111 close( fb->fd );
112 return DFB_INIT;
113 }
114
115 fb->size = ddev->fix[fbnum].smem_len;
116
117 fb->mem = mmap( NULL, fb->size, PROT_READ | PROT_WRITE, MAP_SHARED, fb->fd, 0 );
118 if (fb->mem == MAP_FAILED) {
119 D_PERROR( "Davinci/Driver: mmap (fb%d, length %d) failed!\n", fbnum, fb->size );
120 close( fb->fd );
121 return DFB_INIT;
122 }
123
124 D_INFO( "Davinci/Driver: Mapped fb%d with length %u at %p to %p\n",
125 fbnum, fb->size, (void*)ddev->fix[fbnum].smem_start, fb->mem );
126
127 return DFB_OK;
128 }
129
130 static void
close_fb(DavinciFB * fb)131 close_fb( DavinciFB *fb )
132 {
133 munmap( fb->mem, fb->size );
134 close( fb->fd );
135 }
136
137 /**********************************************************************************************************************/
138
139 static int
driver_probe(CoreGraphicsDevice * device)140 driver_probe( CoreGraphicsDevice *device )
141 {
142 int ret;
143 int fd;
144 vpbe_fb_videomode_t videomode;
145
146 switch (dfb_system_type()) {
147 case CORE_DEVMEM:
148 case CORE_TI_CMEM:
149 if (dfb_config->accelerator == 6400)
150 return 1;
151 break;
152
153 default:
154 return 0;
155 }
156
157 fd = direct_try_open( "/dev/fb0", "/dev/fb/0", O_RDWR, true );
158 if (fd < 0)
159 return 0;
160
161 ret = ioctl( fd, FBIO_GET_TIMING, &videomode);
162
163 close( fd );
164
165 if (ret) {
166 D_PERROR( "Davinci/Driver: FBIO_GET_TIMING failed!\n" );
167 return 0;
168 }
169
170 if (videomode.xres > 768 || videomode.yres > 576 || videomode.fps > 60) {
171 D_ERROR( "Davinci/Driver: Invalid mode %dx%d @%d!\n", videomode.xres, videomode.yres, videomode.fps );
172 return 0;
173 }
174
175 if (strncmp( (char*)videomode.name, "PAL", 3 ) &&
176 strncmp( (char*)videomode.name, "NTSC", 4 ))
177 {
178 D_ERROR( "Davinci/Driver: Unknown mode name '%s'!\n", videomode.name );
179 return 0;
180 }
181
182 return 1;
183 }
184
185 static void
driver_get_info(CoreGraphicsDevice * device,GraphicsDriverInfo * info)186 driver_get_info( CoreGraphicsDevice *device,
187 GraphicsDriverInfo *info )
188 {
189 /* fill driver info structure */
190 snprintf( info->name,
191 DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH,
192 "TI Davinci Driver" );
193
194 snprintf( info->vendor,
195 DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH,
196 "Telio AG" );
197
198 info->version.major = 0;
199 info->version.minor = 4;
200
201 info->driver_data_size = sizeof(DavinciDriverData);
202 info->device_data_size = sizeof(DavinciDeviceData);
203 }
204
205 static DFBResult
driver_init_driver(CoreGraphicsDevice * device,GraphicsDeviceFuncs * funcs,void * driver_data,void * device_data,CoreDFB * core)206 driver_init_driver( CoreGraphicsDevice *device,
207 GraphicsDeviceFuncs *funcs,
208 void *driver_data,
209 void *device_data,
210 CoreDFB *core )
211 {
212 DFBResult ret;
213 DavinciDriverData *ddrv = driver_data;
214 DavinciDeviceData *ddev = device_data;
215 bool master = dfb_core_is_master( core );
216
217 ddrv->ddev = ddev;
218 ddrv->core = core;
219
220 ret = open_fb( ddrv, ddev, OSD0 );
221 if (ret)
222 return ret;
223
224 ret = open_fb( ddrv, ddev, VID0 );
225 if (ret)
226 goto error_fb1;
227
228 ret = open_fb( ddrv, ddev, OSD1 );
229 if (ret)
230 goto error_fb2;
231
232 ret = open_fb( ddrv, ddev, VID1 );
233 if (ret)
234 goto error_fb3;
235
236 ret = davinci_c64x_open( &ddrv->c64x );
237 if (ret)
238 D_WARN( "running without DSP acceleration" );
239 else {
240 ret = davinci_c64x_tasks_init( &ddrv->tasks, 2048 );
241 if (ret) {
242 D_DERROR( ret, "Davinci/Driver: Error initializing local task buffer!\n" );
243 return ret;
244 }
245
246 ddrv->c64x_present = true;
247
248 /* initialize function pointers */
249 funcs->EngineSync = davinciEngineSync;
250 funcs->EngineReset = davinciEngineReset;
251 funcs->EmitCommands = davinciEmitCommands;
252 funcs->FlushTextureCache = davinciFlushTextureCache;
253 funcs->CheckState = davinciCheckState;
254 funcs->SetState = davinciSetState;
255 funcs->StretchBlit = davinciStretchBlit32;
256 }
257
258 ddrv->screen = dfb_screens_register( device, driver_data, &davinciScreenFuncs );
259
260 ddrv->osd = dfb_layers_register( ddrv->screen, driver_data, &davinciOSDLayerFuncs );
261 ddrv->video = dfb_layers_register( ddrv->screen, driver_data, &davinciVideoLayerFuncs );
262
263 if (!master) {
264 dfb_surface_pool_join( core, ddev->osd_pool, &davinciOSDSurfacePoolFuncs );
265 // dfb_surface_pool_join( core, ddev->video_pool, &davinciVideoSurfacePoolFuncs );
266 }
267
268 if (!dfb_config->software_only && funcs->CheckState) {
269 dfb_config->font_format = DSPF_ARGB;
270 dfb_config->font_premult = true;
271 }
272
273 return DFB_OK;
274
275 error_fb3:
276 close_fb( &ddrv->fb[OSD1] );
277
278 error_fb2:
279 close_fb( &ddrv->fb[VID0] );
280
281 error_fb1:
282 close_fb( &ddrv->fb[OSD0] );
283
284 return DFB_INIT;
285 }
286
287 static DFBResult
driver_init_device(CoreGraphicsDevice * device,GraphicsDeviceInfo * device_info,void * driver_data,void * device_data)288 driver_init_device( CoreGraphicsDevice *device,
289 GraphicsDeviceInfo *device_info,
290 void *driver_data,
291 void *device_data )
292 {
293 DavinciDriverData *ddrv = driver_data;
294 DavinciDeviceData *ddev = device_data;
295
296 /* fill device info */
297 snprintf( device_info->vendor, DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "Texas Instruments" );
298 snprintf( device_info->name, DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "Davinci" );
299
300 /* device limitations */
301 device_info->limits.surface_byteoffset_alignment = 64;
302 device_info->limits.surface_bytepitch_alignment = 32;
303
304 if (ddrv->c64x_present) {
305 device_info->caps.flags = 0;
306 device_info->caps.accel = DAVINCI_SUPPORTED_DRAWINGFUNCTIONS |
307 DAVINCI_SUPPORTED_BLITTINGFUNCTIONS;
308 device_info->caps.drawing = DAVINCI_SUPPORTED_DRAWINGFLAGS;
309 device_info->caps.blitting = DAVINCI_SUPPORTED_BLITTINGFLAGS;
310 device_info->caps.clip = DFXL_STRETCHBLIT;
311 }
312
313 dfb_surface_pool_initialize( ddrv->core, &davinciOSDSurfacePoolFuncs, &ddev->osd_pool );
314 // dfb_surface_pool_initialize( ddrv->core, &davinciVideoSurfacePoolFuncs, &ddev->video_pool );
315
316 return DFB_OK;
317 }
318
319 static void
driver_close_device(CoreGraphicsDevice * device,void * driver_data,void * device_data)320 driver_close_device( CoreGraphicsDevice *device,
321 void *driver_data,
322 void *device_data )
323 {
324 }
325
326 static void
driver_close_driver(CoreGraphicsDevice * device,void * driver_data)327 driver_close_driver( CoreGraphicsDevice *device,
328 void *driver_data )
329 {
330 DavinciDriverData *ddrv = driver_data;
331
332 if (ddrv->c64x_present) {
333 davinci_c64x_tasks_destroy( &ddrv->tasks );
334
335 davinci_c64x_close( &ddrv->c64x );
336 }
337
338 close_fb( &ddrv->fb[VID1] );
339 close_fb( &ddrv->fb[OSD1] );
340 close_fb( &ddrv->fb[VID0] );
341 close_fb( &ddrv->fb[OSD0] );
342 }
343
344