10 #include <sys/ioctl.h>
14 #include "plat_gp2x.h"
15 #include "../common/emu.h"
16 #include "../common/arm_utils.h"
17 #include "pollux_set.h"
19 static volatile unsigned short *memregs;
20 static volatile unsigned long *memregl;
21 static int memdev = -1;
23 extern void *gp2x_screens[4];
25 #define fb_buf_count 4
26 static unsigned int fb_paddr[fb_buf_count];
27 static int fb_work_buf;
28 static int fbdev = -1;
32 static void pollux_video_flip(int buf_count)
34 memregl[0x406C>>2] = fb_paddr[fb_work_buf];
35 memregl[0x4058>>2] |= 0x10;
37 if (fb_work_buf >= buf_count)
39 g_screen_ptr = gp2x_screens[fb_work_buf];
42 static void gp2x_video_flip_(void)
44 pollux_video_flip(fb_buf_count);
47 /* doulblebuffered flip */
48 static void gp2x_video_flip2_(void)
53 static void gp2x_video_changemode_ll_(int bpp)
55 int code = 0, bytes = 2;
71 printf("unhandled bpp request: %d\n", bpp);
75 memregl[0x405c>>2] = bytes;
76 memregl[0x4060>>2] = bytes * 320;
78 r = memregl[0x4058>>2];
79 r = (r & 0xffff) | (code << 16) | 0x10;
80 memregl[0x4058>>2] = r;
83 static void gp2x_video_setpalette_(int *pal, int len)
85 /* pollux palette is 16bpp only.. */
87 for (i = 0; i < len; i++)
90 c = ((c >> 8) & 0xf800) | ((c >> 5) & 0x07c0) | ((c >> 3) & 0x001f);
91 memregl[0x4070>>2] = (i << 24) | c;
95 static void gp2x_video_RGB_setscaling_(int ln_offs, int W, int H)
97 /* maybe a job for 3d hardware? */
100 static void gp2x_video_wait_vsync_(void)
102 while (!(memregl[0x308c>>2] & (1 << 10)));
104 memregl[0x308c>>2] |= 1 << 10;
108 static void gp2x_set_cpuclk_(unsigned int mhz)
111 snprintf(buff, sizeof(buff), "cpuclk=%u", mhz);
112 pollux_set(memregs, buff);
116 static void pollux_set_fromenv(const char *env_var)
118 const char *set_string;
119 set_string = getenv(env_var);
121 pollux_set(memregs, set_string);
123 printf("env var %s not defined.\n", env_var);
127 static unsigned short memtimex[2];
129 static void set_ram_timings_(void)
131 pollux_set_fromenv("POLLUX_RAM_TIMINGS");
134 static void unset_ram_timings_(void)
138 memregs[0x14802>>1] = memtimex[0];
139 memregs[0x14804>>1] = memtimex[1] | 0x8000;
141 for (i = 0; i < 0x100000; i++)
142 if (!(memregs[0x14804>>1] & 0x8000))
145 printf("RAM timings reset to startup values.\n");
149 static void set_lcd_custom_rate_(int is_pal)
153 snprintf(buff, sizeof(buff), "POLLUX_LCD_TIMINGS_%s", is_pal ? "PAL" : "NTSC");
154 pollux_set_fromenv(buff);
157 static void unset_lcd_custom_rate_(void)
161 static void set_lcd_gamma_(int g100, int A_SNs_curve)
163 /* hm, the LCD possibly can do it (but not POLLUX) */
166 void pollux_init(void)
168 struct fb_fix_screeninfo fbfix;
171 memdev = open("/dev/mem", O_RDWR);
173 perror("open(/dev/mem) failed");
177 memregs = mmap(0, 0x20000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0xc0000000);
178 if (memregs == MAP_FAILED) {
179 perror("mmap(memregs) failed");
182 memregl = (volatile void *)memregs;
184 fbdev = open("/dev/fb0", O_RDWR);
186 perror("can't open fbdev");
190 ret = ioctl(fbdev, FBIOGET_FSCREENINFO, &fbfix);
192 perror("ioctl(fbdev) failed");
196 printf("framebuffer: \"%s\" @ %08lx\n", fbfix.id, fbfix.smem_start);
197 fb_paddr[0] = fbfix.smem_start;
199 gp2x_screens[0] = mmap(0, 320*240*2*fb_buf_count, PROT_READ|PROT_WRITE,
200 MAP_SHARED, memdev, fb_paddr[0]);
201 if (gp2x_screens[0] == MAP_FAILED)
203 perror("mmap(gp2x_screens) failed");
206 memset(gp2x_screens[0], 0, 320*240*2*fb_buf_count);
208 printf(" %p -> %08x\n", gp2x_screens[0], fb_paddr[0]);
209 for (i = 1; i < fb_buf_count; i++)
211 fb_paddr[i] = fb_paddr[i-1] + 320*240*2;
212 gp2x_screens[i] = (char *)gp2x_screens[i-1] + 320*240*2;
213 printf(" %p -> %08x\n", gp2x_screens[i], fb_paddr[i]);
216 g_screen_ptr = gp2x_screens[0];
218 memtimex[0] = memregs[0x14802>>1];
219 memtimex[1] = memregs[0x14804>>1];
221 gp2x_video_flip = gp2x_video_flip_;
222 gp2x_video_flip2 = gp2x_video_flip2_;
223 gp2x_video_changemode_ll = gp2x_video_changemode_ll_;
224 gp2x_video_setpalette = gp2x_video_setpalette_;
225 gp2x_video_RGB_setscaling = gp2x_video_RGB_setscaling_;
226 gp2x_video_wait_vsync = gp2x_video_wait_vsync_;
228 gp2x_set_cpuclk = gp2x_set_cpuclk_;
230 set_lcd_custom_rate = set_lcd_custom_rate_;
231 unset_lcd_custom_rate = unset_lcd_custom_rate_;
232 set_lcd_gamma = set_lcd_gamma_;
234 set_ram_timings = set_ram_timings_;
235 unset_ram_timings = unset_ram_timings_;
238 void pollux_finish(void)
240 /* switch to default fb mem, turn portrait off */
241 memregl[0x406C>>2] = fb_paddr[0];
242 memregl[0x4058>>2] |= 0x10;
243 // wiz_lcd_set_portrait(0);
246 munmap((void *)memregs, 0x20000);