1 /*
2    (c) Copyright 2001-2009  The world wide DirectFB Open Source Community (directfb.org)
3    (c) Copyright 2000-2004  Convergence (integrated media) GmbH
4 
5    All rights reserved.
6 
7    Written by Denis Oliver Kropp <dok@directfb.org>,
8               Andreas Hundt <andi@fischlustig.de>,
9               Sven Neumann <neo@directfb.org>,
10               Ville Syrjälä <syrjala@sci.fi> and
11               Claudio Ciccani <klan@users.sf.net>.
12 
13    This library is free software; you can redistribute it and/or
14    modify it under the terms of the GNU Lesser General Public
15    License as published by the Free Software Foundation; either
16    version 2 of the License, or (at your option) any later version.
17 
18    This library is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    Lesser General Public License for more details.
22 
23    You should have received a copy of the GNU Lesser General Public
24    License along with this library; if not, write to the
25    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26    Boston, MA 02111-1307, USA.
27 */
28 
29 #include <config.h>
30 
31 #include <stdio.h>
32 #include <sys/ioctl.h>
33 
34 #include <fbdev/fbdev.h>  /* FIXME: Needs to be included before dfb_types.h to work around a type clash with asm/types.h */
35 
36 #include <directfb.h>
37 
38 #include <direct/messages.h>
39 
40 #include <core/coredefs.h>
41 #include <core/coretypes.h>
42 #include <core/screens.h>
43 #include <core/system.h>
44 
45 #include <fbdev/fbdev.h>
46 
47 #include <misc/conf.h>
48 
49 #include "regs.h"
50 #include "mmio.h"
51 #include "matrox.h"
52 
53 
54 typedef struct {
55      DFBScreenPowerMode power_mode;
56 } MatroxCrtc2ScreenData;
57 
58 static void crtc2_wait_vsync( MatroxDriverData *mdrv );
59 
60 /**************************************************************************************************/
61 
62 static int
crtc2ScreenDataSize(void)63 crtc2ScreenDataSize( void )
64 {
65      return sizeof(MatroxCrtc2ScreenData);
66 }
67 
68 static DFBResult
crtc2InitScreen(CoreScreen * screen,CoreGraphicsDevice * device,void * driver_data,void * screen_data,DFBScreenDescription * description)69 crtc2InitScreen( CoreScreen           *screen,
70                  CoreGraphicsDevice   *device,
71                  void                 *driver_data,
72                  void                 *screen_data,
73                  DFBScreenDescription *description )
74 {
75      /* Set the screen capabilities. */
76      description->caps = DSCCAPS_VSYNC | DSCCAPS_ENCODERS | DSCCAPS_OUTPUTS;
77 
78      /* Set the screen name. */
79      snprintf( description->name,
80                DFB_SCREEN_DESC_NAME_LENGTH, "Matrox CRTC2 Screen" );
81 
82      /* Set number of encoders and outputs. */
83      description->encoders = 1;
84      description->outputs  = 1;
85 
86      return DFB_OK;
87 }
88 
89 /**************************************************************************************************/
90 
91 static DFBResult
crtc2InitEncoder(CoreScreen * screen,void * driver_data,void * screen_data,int encoder,DFBScreenEncoderDescription * description,DFBScreenEncoderConfig * config)92 crtc2InitEncoder( CoreScreen                  *screen,
93                   void                        *driver_data,
94                   void                        *screen_data,
95                   int                          encoder,
96                   DFBScreenEncoderDescription *description,
97                   DFBScreenEncoderConfig      *config )
98 {
99      /* Set the encoder capabilities & type. */
100      description->caps = DSECAPS_TV_STANDARDS;
101      description->type = DSET_TV;
102 
103      /* Set supported TV standards. */
104      description->tv_standards = DSETV_PAL | DSETV_NTSC | DSETV_PAL_60;
105 
106      /* Set default configuration. */
107      config->flags       = DSECONF_TV_STANDARD;
108      config->tv_standard = dfb_config->matrox_tv_std;
109 
110      return DFB_OK;
111 }
112 
113 static DFBResult
crtc2InitOutput(CoreScreen * screen,void * driver_data,void * screen_data,int output,DFBScreenOutputDescription * description,DFBScreenOutputConfig * config)114 crtc2InitOutput( CoreScreen                 *screen,
115                  void                       *driver_data,
116                  void                       *screen_data,
117                  int                         output,
118                  DFBScreenOutputDescription *description,
119                  DFBScreenOutputConfig      *config )
120 {
121      /* Set the output capabilities. */
122      description->caps = DSOCAPS_CONNECTORS |
123                          DSOCAPS_SIGNAL_SEL | DSOCAPS_CONNECTOR_SEL;
124 
125      /* Set supported output connectors and signals. */
126      description->all_connectors = DSOC_CVBS | DSOC_YC | DSOC_SCART;
127      description->all_signals    = DSOS_CVBS | DSOS_YC | DSOS_RGB;
128 
129      /* Set default configuration. */
130      config->flags = DSOCONF_SIGNALS | DSOCONF_CONNECTORS;
131 
132      switch (dfb_config->matrox_cable) {
133           case 1:
134                /* SCART RGB */
135                config->out_signals    = DSOS_RGB;
136                config->out_connectors = DSOC_SCART;
137                break;
138           case 2:
139                /* SCART Composite */
140                config->out_signals    = DSOS_CVBS;
141                config->out_connectors = DSOC_SCART;
142                break;
143           default:
144                /* Composite / S-Video */
145                config->out_signals    = DSOS_CVBS | DSOS_YC;
146                config->out_connectors = DSOC_CVBS | DSOC_YC;
147                break;
148      }
149 
150      return DFB_OK;
151 }
152 
153 /**************************************************************************************************/
154 
155 static DFBResult
crtc2SetPowerMode(CoreScreen * screen,void * driver_data,void * screen_data,DFBScreenPowerMode mode)156 crtc2SetPowerMode( CoreScreen         *screen,
157                    void               *driver_data,
158                    void               *screen_data,
159                    DFBScreenPowerMode  mode )
160 {
161      MatroxCrtc2ScreenData *msc2 = (MatroxCrtc2ScreenData*) screen_data;
162 
163      msc2->power_mode = mode;
164 
165      return DFB_OK;
166 }
167 
168 static DFBResult
crtc2WaitVSync(CoreScreen * screen,void * driver_data,void * screen_data)169 crtc2WaitVSync( CoreScreen *screen,
170                 void       *driver_data,
171                 void       *screen_data )
172 {
173      MatroxDriverData      *mdrv = (MatroxDriverData*) driver_data;
174      MatroxCrtc2ScreenData *msc2 = (MatroxCrtc2ScreenData*) screen_data;
175 
176      if (msc2->power_mode == DSPM_ON)
177           crtc2_wait_vsync( mdrv );
178 
179      return DFB_OK;
180 }
181 
182 /**************************************************************************************************/
183 
184 static DFBResult
crtc2TestEncoderConfig(CoreScreen * screen,void * driver_data,void * screen_data,int encoder,const DFBScreenEncoderConfig * config,DFBScreenEncoderConfigFlags * failed)185 crtc2TestEncoderConfig( CoreScreen                   *screen,
186                         void                         *driver_data,
187                         void                         *screen_data,
188                         int                           encoder,
189                         const DFBScreenEncoderConfig *config,
190                         DFBScreenEncoderConfigFlags  *failed )
191 {
192      D_UNIMPLEMENTED();
193 
194      return DFB_UNIMPLEMENTED;
195 }
196 
197 static DFBResult
crtc2SetEncoderConfig(CoreScreen * screen,void * driver_data,void * screen_data,int encoder,const DFBScreenEncoderConfig * config)198 crtc2SetEncoderConfig( CoreScreen                   *screen,
199                        void                         *driver_data,
200                        void                         *screen_data,
201                        int                           encoder,
202                        const DFBScreenEncoderConfig *config )
203 {
204 //     D_UNIMPLEMENTED();
205 
206      return DFB_UNIMPLEMENTED;
207 }
208 
209 /**************************************************************************************************/
210 
211 static DFBResult
crtc2TestOutputConfig(CoreScreen * screen,void * driver_data,void * screen_data,int output,const DFBScreenOutputConfig * config,DFBScreenOutputConfigFlags * failed)212 crtc2TestOutputConfig( CoreScreen                  *screen,
213                        void                        *driver_data,
214                        void                        *screen_data,
215                        int                          output,
216                        const DFBScreenOutputConfig *config,
217                        DFBScreenOutputConfigFlags  *failed )
218 {
219      D_UNIMPLEMENTED();
220 
221      return DFB_UNIMPLEMENTED;
222 }
223 
224 static DFBResult
crtc2SetOutputConfig(CoreScreen * screen,void * driver_data,void * screen_data,int output,const DFBScreenOutputConfig * config)225 crtc2SetOutputConfig( CoreScreen                  *screen,
226                       void                        *driver_data,
227                       void                        *screen_data,
228                       int                          output,
229                       const DFBScreenOutputConfig *config )
230 {
231 //     D_UNIMPLEMENTED();
232 
233      return DFB_UNIMPLEMENTED;
234 }
235 
236 /**************************************************************************************************/
237 
238 static DFBResult
crtc2GetScreenSize(CoreScreen * screen,void * driver_data,void * screen_data,int * ret_width,int * ret_height)239 crtc2GetScreenSize( CoreScreen *screen,
240                     void       *driver_data,
241                     void       *screen_data,
242                     int        *ret_width,
243                     int        *ret_height )
244 {
245      *ret_width  = 720;
246      *ret_height = (dfb_config->matrox_tv_std != DSETV_PAL) ? 480 : 576;
247 
248      return DFB_OK;
249 }
250 
251 ScreenFuncs matroxCrtc2ScreenFuncs = {
252      .ScreenDataSize    = crtc2ScreenDataSize,
253      .InitScreen        = crtc2InitScreen,
254      .InitEncoder       = crtc2InitEncoder,
255      .InitOutput        = crtc2InitOutput,
256      .SetPowerMode      = crtc2SetPowerMode,
257      .WaitVSync         = crtc2WaitVSync,
258      .TestEncoderConfig = crtc2TestEncoderConfig,
259      .SetEncoderConfig  = crtc2SetEncoderConfig,
260      .TestOutputConfig  = crtc2TestOutputConfig,
261      .SetOutputConfig   = crtc2SetOutputConfig,
262      .GetScreenSize     = crtc2GetScreenSize,
263 };
264 
265 /**************************************************************************************************/
266 
crtc2_wait_vsync(MatroxDriverData * mdrv)267 static void crtc2_wait_vsync( MatroxDriverData *mdrv )
268 {
269      int vdisplay = ((dfb_config->matrox_tv_std != DSETV_PAL) ? 480/2 : 576/2) + 1;
270 
271 #ifdef FBIO_WAITFORVSYNC
272      static const int one = 1;
273      FBDev *dfb_fbdev = dfb_system_data();
274      if (ioctl( dfb_fbdev->fd, FBIO_WAITFORVSYNC, &one ))
275 #endif
276           while ((int)(mga_in32( mdrv->mmio_base, C2VCOUNT ) & 0x00000FFF) != vdisplay)
277                ;
278 }
279 
280