source: rtems/c/src/lib/libbsp/lm32/shared/milkymist_framebuffer/framebuffer.c @ 9bf34835

4.115
Last change on this file since 9bf34835 was 9bf34835, checked in by Joel Sherrill <joel.sherrill@…>, on 08/20/10 at 21:23:27

2010-08-20 <yann.sionneau@…>

  • shared/milkymist_ac97/ac97.c, shared/milkymist_clock/ckinit.c, shared/milkymist_clock/clock.h, shared/milkymist_console/console.c, shared/milkymist_console/uart.c, shared/milkymist_console/uart.h, shared/milkymist_framebuffer/framebuffer.c, shared/milkymist_gpio/gpio.c, shared/milkymist_networking/mm_crc32.c, shared/milkymist_networking/network.c, shared/milkymist_networking/network.h, shared/milkymist_timer/timer.c: New files.
  • Property mode set to 100644
File size: 6.6 KB
Line 
1/*  framebuffer.c
2 *
3 *  This file is the framebuffer driver for the Milkymist VGA IP-core
4 *  This VGA Core is a part of Milkymist System-on-Chip
5 *
6 *  The license and distribution terms for this file may be
7 *  found in the file LICENSE in this distribution or at
8 *  http://www.rtems.com/license/LICENSE.
9 *
10 *  $Id$
11 *
12 *  COPYRIGHT (c) Yann Sionneau <yann.sionneau@telecom-sudparis.eu> (GSoC 2010)
13 *  Telecom SudParis
14 */
15
16#include <stdlib.h>
17#include <stdio.h>
18#include <errno.h>
19#include <sys/types.h>
20#include <pthread.h>
21#include <rtems.h>
22#include <bsp.h>
23#include "../include/system_conf.h"
24#include <rtems/libio.h>
25#include <rtems/fb.h>
26
27#define FRAMEBUFFER_DEVICE_NAME "/dev/fb"
28
29pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
30
31static unsigned short int framebufferA[640*480] __attribute__((aligned(32)));
32static unsigned short int framebufferB[640*480] __attribute__((aligned(32)));
33static unsigned short int framebufferC[640*480] __attribute__((aligned(32)));
34
35static unsigned short int *frontbuffer = framebufferA;
36static unsigned short int *backbuffer = framebufferB;
37static unsigned short int *lastbuffer = framebufferC;
38
39static inline void fb_write(unsigned int reg, int value)
40{
41  *((int*)reg) = value;
42}
43
44static inline int fb_read(unsigned int reg)
45{
46  return *((int*)(reg));
47}
48
49/* screen information for the VGA driver */
50static struct fb_var_screeninfo fb_var =
51{
52  .xres                = 640,
53  .yres                = 480,
54  .bits_per_pixel      = 16
55};
56
57static struct fb_fix_screeninfo fb_fix =
58{
59// this is initialized at start-up
60  .smem_len            = 640 * 480 * 2,                      /* buffer size       */
61// 2 bytes per pixels
62  .type                = FB_TYPE_VGA_PLANES,           /* type of display    */
63  .visual              = FB_VISUAL_TRUECOLOR,        /* color scheme used */
64  .line_length         = 80                            /* chars per line    */
65};
66
67
68static int get_fix_screen_info( struct fb_fix_screeninfo *info )
69{
70  *info = fb_fix;
71  return 0;
72}
73
74static int get_var_screen_info( struct fb_var_screeninfo *info )
75{
76  *info =  fb_var;
77  return 0;
78}
79
80
81rtems_device_driver frame_buffer_initialize(
82rtems_device_major_number  major,
83rtems_device_minor_number  minor,
84void *arg)
85{
86  rtems_status_code status;
87
88  printk( "frame buffer driver initializing..\n" );
89
90  fb_fix.smem_start = (volatile char *)frontbuffer;
91
92  fb_write(MM_VGA_BASEADDRESS, (unsigned int)frontbuffer);
93  fb_write(MM_VGA_RESET, (unsigned int)0);
94
95  /*
96  * Register the device
97  */
98  status = rtems_io_register_name(FRAMEBUFFER_DEVICE_NAME, major, 0);
99  if (status != RTEMS_SUCCESSFUL)
100  {
101    printk("Error registering frame buffer device!\n");
102    rtems_fatal_error_occurred( status );
103  }
104
105  printk("VGA: initialized at resolution %dx%d\n", fb_var.xres, fb_var.yres);
106  printk("VGA: framebuffers at 0x%08x 0x%08x 0x%08x\n",
107  (unsigned int)frontbuffer, (unsigned int)backbuffer,
108  (unsigned int)lastbuffer);
109
110  /*
111  * graphics hardware initialization goes here for non-console
112  * devices
113  */
114  return RTEMS_SUCCESSFUL;
115}
116
117rtems_device_driver frame_buffer_close(
118  rtems_device_major_number  major,
119  rtems_device_minor_number  minor,
120  void *arg
121)
122{
123  if (pthread_mutex_unlock(&mutex) == 0){
124  /* restore previous state.  for VGA this means return to text mode.
125   * leave out if graphics hardware has been initialized in
126   * frame_buffer_initialize() */
127    fb_write(MM_VGA_RESET, MM_VGA_RESET_MODE);
128    return RTEMS_SUCCESSFUL;
129  }
130  return RTEMS_UNSATISFIED;
131}
132
133rtems_device_driver frame_buffer_open(
134  rtems_device_major_number  major,
135  rtems_device_minor_number  minor,
136  void *arg
137)
138{
139  if (pthread_mutex_trylock(&mutex) == 0){
140    fb_write(MM_VGA_RESET, (unsigned int)0);
141    return RTEMS_SUCCESSFUL;
142  }
143  return RTEMS_UNSATISFIED;
144}
145
146static void vga_swap_buffers(void)
147{
148  unsigned short int *p;
149
150  /*
151  * Make sure last buffer swap has been executed.
152  * Beware, DMA address registers of vgafb are incomplete
153  * (only LSBs are present) so don't compare them directly
154  * with CPU pointers.
155  */
156  while( fb_read(MM_VGA_BASEADDRESS_ACT) != fb_read(MM_VGA_BASEADDRESS) );
157
158  p = frontbuffer;
159  frontbuffer = backbuffer;
160  backbuffer = lastbuffer;
161  lastbuffer = p;
162
163  fb_fix.smem_start = (volatile char *)backbuffer;
164
165  fb_write(MM_VGA_BASEADDRESS, (unsigned int)frontbuffer);
166}
167
168rtems_device_driver frame_buffer_read(
169  rtems_device_major_number  major,
170  rtems_device_minor_number  minor,
171  void                      *arg
172)
173{
174  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
175  rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
176  memcpy(rw_args->buffer, (const void *) (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved);
177  return RTEMS_SUCCESSFUL;
178}
179
180rtems_device_driver frame_buffer_write(
181  rtems_device_major_number  major,
182  rtems_device_minor_number  minor,
183  void                      *arg
184)
185{
186  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
187  rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
188  memcpy( (void *) (fb_fix.smem_start + rw_args->offset), rw_args->buffer, rw_args->bytes_moved);
189  return RTEMS_SUCCESSFUL;
190}
191
192rtems_device_driver frame_buffer_control(
193  rtems_device_major_number  major,
194  rtems_device_minor_number  minor,
195  void                      *arg
196)
197{
198  rtems_libio_ioctl_args_t *args = arg;
199
200  switch( args->command ) {
201    case FBIOGET_FSCREENINFO:
202      args->ioctl_return =  get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer );
203      break;
204    case FBIOGET_VSCREENINFO:
205      args->ioctl_return =  get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer );
206      break;
207    case FBIOPUT_VSCREENINFO:
208      /* not implemented yet */
209      args->ioctl_return = -1;
210      return RTEMS_UNSATISFIED;
211    case FBIOGETCMAP:
212      /* not implemented yet */
213      args->ioctl_return = -1;
214      return RTEMS_UNSATISFIED;
215      break;
216    case FBIOPUTCMAP:
217      /* not implemented yet */
218      args->ioctl_return = -1;
219      return RTEMS_UNSATISFIED;
220      break;
221    case FBIOSWAPBUFFERS:
222      vga_swap_buffers();
223      args->ioctl_return = 0;
224      break;
225    case FBIOSETBUFFERMODE:
226      args->ioctl_return = 0;
227      switch ( (unsigned int)args->buffer ) {
228        case FB_SINGLE_BUFFERED:
229          fb_fix.smem_start = (volatile char *)frontbuffer;
230          break;
231        case  FB_TRIPLE_BUFFERED:
232          fb_fix.smem_start = (volatile char *)backbuffer;
233          break;
234        default:
235          printk("[framebuffer] : error no such buffer mode\n");
236      }
237      break;
238    default:
239     args->ioctl_return = 0;
240     break;
241  }
242  return RTEMS_SUCCESSFUL;
243}
244
Note: See TracBrowser for help on using the repository browser.