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