This list is closed, nobody may subscribe to it.
2004 |
Jan
(53) |
Feb
(78) |
Mar
(34) |
Apr
(26) |
May
(25) |
Jun
(34) |
Jul
(16) |
Aug
(16) |
Sep
(2) |
Oct
(58) |
Nov
(13) |
Dec
(32) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(62) |
Feb
(4) |
Mar
(40) |
Apr
(9) |
May
(13) |
Jun
(26) |
Jul
(32) |
Aug
(24) |
Sep
(18) |
Oct
(18) |
Nov
(14) |
Dec
|
2006 |
Jan
(15) |
Feb
(2) |
Mar
(23) |
Apr
(2) |
May
(2) |
Jun
(13) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
2007 |
Jan
(1) |
Feb
(45) |
Mar
|
Apr
(13) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(31) |
Dec
(5) |
2008 |
Jan
(6) |
Feb
(34) |
Mar
(113) |
Apr
(40) |
May
(19) |
Jun
(5) |
Jul
(41) |
Aug
(13) |
Sep
(53) |
Oct
(4) |
Nov
(53) |
Dec
|
2009 |
Jan
(1) |
Feb
(29) |
Mar
(66) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(163) |
Nov
|
Dec
(91) |
From: <pal...@us...> - 2004-10-31 22:35:14
|
Update of /cvsroot/gc-linux/libgx/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5696/src Modified Files: Makefile.am gu.c gx.c Log Message: Modified the PAL code so only PAL50 is 576 lines (thanks isobel) Index: Makefile.am =================================================================== RCS file: /cvsroot/gc-linux/libgx/src/Makefile.am,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 --- Makefile.am 22 Oct 2004 20:13:53 -0000 1.1.1.1 +++ Makefile.am 31 Oct 2004 22:34:59 -0000 1.2 @@ -1,5 +1,6 @@ AM_CCASFLAGS=-Wa,-mgekko -Wa,-mregnames -Wa,-gstabs+ - +AM_CFLAGS=-Wa,-mgekko -Wa,-mregnames -Wa,-gstabs+ + lib_LTLIBRARIES = libgx.la libgx_la_SOURCES=gx.c gu.c gx_asm.S gu_asm.S Index: gu.c =================================================================== RCS file: /cvsroot/gc-linux/libgx/src/gu.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 --- gu.c 22 Oct 2004 20:13:53 -0000 1.1.1.1 +++ gu.c 31 Oct 2004 22:35:00 -0000 1.2 @@ -222,7 +222,6 @@ c_guMtxRotTrig(mt,axis,sinA,cosA); } -#ifdef GEKKO void ps_guMtxRotRad(register Mtx mt,register const char axis,register f32 rad) { register f32 sinA,cosA; @@ -245,38 +244,36 @@ ps_guVecNormalize(axis); __asm__ __volatile__( - "psq_l %%f1,0(%1),0,0\n" + "psql %%f1,0(%1),0,0\n" "lfs %%f2,8(%1)\n" - "ps_merge00 %2,%2,%2\n" - "ps_muls0 %%f5,%%f1,%3\n" - "ps_muls0 %%f6,%%f2,%3\n" - "ps_muls1 %%f4,%%f5,%%f1\n" - "ps_muls0 %%f3,%%f5,%%f1\n" - "ps_muls0 %%f1,%%f1,%4\n" - "ps_muls0 %%f5,%%f5,%%f2\n" + "psmerge00 %2,%2,%2\n" + "psmuls0 %%f5,%%f1,%3\n" + "psmuls0 %%f6,%%f2,%3\n" + "psmuls1 %%f4,%%f5,%%f1\n" + "psmuls0 %%f3,%%f5,%%f1\n" + "psmuls0 %%f1,%%f1,%4\n" + "psmuls0 %%f5,%%f5,%%f2\n" "fnmsubs %%f7,%%f2,%4,%%f4\n" "fmadds %%f8,%%f2,%4,%%f4\n" - "ps_neg %%f10,%%f1\n" - "ps_sum0 %%f9,%%f5,%5,%%f1\n" - "ps_sum0 %%f3,%%f3,%%f7,%2\n" - "ps_sum1 %%f4,%2,%%f8,%%f4\n" - "ps_sum0 %%f7,%%f10,%5,%%f5\n" - "ps_sum0 %%f10,%%f5,%%f5,%%f10\n" - "psq_st %%f9,8(%0),0,0\n" - "ps_muls0 %%f6,%%f6,%%f2\n" - "psq_st %%f3,0(%0),0,0\n" - "ps_sum1 %%f5,%%f1,%%f10,%%f5\n" - "psq_st %%f4,16(%0),0,0\n" - "ps_sum0 %%f6,%%f6,%5,%2\n" - "psq_st %%f7,24(%0),0,0\n" - "psq_st %%f5,32(%0),0,0\n" - "psq_st %%f6,40(%0),0,0\n" + "psneg %%f10,%%f1\n" + "pssum0 %%f9,%%f5,%5,%%f1\n" + "pssum0 %%f3,%%f3,%%f7,%2\n" + "pssum1 %%f4,%2,%%f8,%%f4\n" + "pssum0 %%f7,%%f10,%5,%%f5\n" + "pssum0 %%f10,%%f5,%%f5,%%f10\n" + "psqst %%f9,8(%0),0,0\n" + "psmuls0 %%f6,%%f6,%%f2\n" + "psqst %%f3,0(%0),0,0\n" + "pssum1 %%f5,%%f1,%%f10,%%f5\n" + "psqst %%f4,16(%0),0,0\n" + "pssum0 %%f6,%%f6,%5,%2\n" + "psqst %%f7,24(%0),0,0\n" + "psqst %%f5,32(%0),0,0\n" + "psqst %%f6,40(%0),0,0\n" : "=r"(mt) : "r"(axis), "f"(cT), "f"(tT), "f"(sT), "f"(fc0) ); } -#endif - void c_guMtxRotTrig(Mtx mt,const char axis,f32 sinA,f32 cosA) { switch(axis) { Index: gx.c =================================================================== RCS file: /cvsroot/gc-linux/libgx/src/gx.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- gx.c 24 Oct 2004 04:35:36 -0000 1.2 +++ gx.c 31 Oct 2004 22:35:00 -0000 1.3 @@ -687,7 +687,7 @@ { /* check horizontal timing to see if pal50/60 */ pInit->vType = ( *((u32*)(_viReg+2)) == 0x476901AD ) ? PAL60 : PAL50; - pInit->height = 576; + pInit->height = ((pInit->vType == PAL50) ? 576 : 480); } else { |
From: <he...@us...> - 2004-10-31 03:16:01
|
Update of /cvsroot/gc-linux/htdocs/xml/en In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2222 Modified Files: news.xml Log Message: 30 October 2004, KDE run on a GameCube Index: news.xml =================================================================== RCS file: /cvsroot/gc-linux/htdocs/xml/en/news.xml,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- news.xml 24 Oct 2004 23:40:14 -0000 1.25 +++ news.xml 31 Oct 2004 03:15:49 -0000 1.26 @@ -2,6 +2,11 @@ <?xml-stylesheet href="news.xsl" type="text/xsl"?> <news> <item> + <date>30 October 2004</date> + <title>KDE run on a GameCube</title> + <text>Diffuse/Skaida, in a completely geek driven act, started KDE on his GameCube. Of course, it was not useable and had crappy colors. But he has finally been the first geek in having a GameKube. You can see <a href="pic/kde.jpg">here</a> how his desktop looked like, and <a href="pic/kde_fixed.jpg">here</a> how would have looked with right colors. His original framebuffer dump (dd if=/dev/fb0 of=./kde.fbdump) is <a href="pic/kde.fbdump">here</a> in case the Guiness Book people need it.</text> + </item> + <item> <date>25 October 2004</date> <title>Hardware accelerated graphics</title> <text>Scream|CT is currently working on improving gc-linux graphics performance by using help from the powerful "Flipper" GPU. Check the new improvements on <a href="http://sourceforge.net/cvs/?group_id=98581">cvs</a> and on <a href="http://voidpointer.org/gc-linux/">Scream|CT's site</a>.</text> |
From: <he...@us...> - 2004-10-30 00:09:45
|
Update of /cvsroot/gc-linux/linux/drivers/video In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25092 Modified Files: gcnfb.c Log Message: Added total lines to video mode. Fixed vtrap so that it uses half _all_ lines, not half _visible_ lines. Index: gcnfb.c =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/video/gcnfb.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- gcnfb.c 29 Oct 2004 22:18:32 -0000 1.5 +++ gcnfb.c 30 Oct 2004 00:09:36 -0000 1.6 @@ -62,6 +62,7 @@ const u32 *regs; int width; int height; + int lines; }; static const u32 VIDEO_Mode640X480NtscYUV16[32] = { @@ -115,6 +116,7 @@ .regs = VIDEO_Mode640X480NtscYUV16, .width = 640, .height = 480, + .lines = 525, }, { .format = VI_FMT_NTSC_480p, @@ -122,6 +124,7 @@ .regs = VIDEO_Mode640x480NtscProgressiveYUV16, .width = 640, .height = 480, + .lines = 525, }, { .format = VI_FMT_PAL50_576i, @@ -129,6 +132,7 @@ .regs = VIDEO_Mode640X576Pal50YUV16, .width = 640, .height = 576, + .lines = 625, }, { .format = VI_FMT_PAL60_480i, @@ -136,6 +140,7 @@ .regs = VIDEO_Mode640X480Pal60YUV16, .width = 640, .height = 480, + .lines = 525, }, { .format = -1 } }; @@ -490,7 +495,7 @@ if (enable) { /* XXX should we incorporate this in the video mode struct ? */ - vtrap = gcnfb_video_mode->height / 2; + vtrap = gcnfb_video_mode->lines / 2; htrap = VI_FMT_IS_NTSC(gcnfb_video_mode->format) ? 430 : 433; /* progressive interrupts at 526 */ |
From: <he...@us...> - 2004-10-29 22:18:43
|
Update of /cvsroot/gc-linux/linux/drivers/video In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv832 Modified Files: gcnfb.c Log Message: Moved copyright notice for gc-linux team to top. Lindented source. Beautified some parts of the code. Moved to old VI_ defines ;) Removed unused debugging macro ENABLE_RUMBLE ;). Added preliminary video mode database to simplify things. Added known video register values for PAL50 and PAL60. Do not check on check_var for y values, we'll fix all of this later. Removed unused vesa_setpalette function. Added some video mode handling functions. Modified some functions to use the values from the mode database. Do NOT blank the screen on init, that's already done for us. Index: gcnfb.c =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/video/gcnfb.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- gcnfb.c 22 Oct 2004 22:54:19 -0000 1.4 +++ gcnfb.c 29 Oct 2004 22:18:32 -0000 1.5 @@ -2,9 +2,9 @@ * drivers/video/gcnfb.c * * Nintendo GameCube "Flipper" chipset frame buffer driver + * Copyright (C) 2004 The GameCube Linux Team * Copyright (C) 2004 Michael Steil <mi...@c6...> * Copyright (C) 2004 Todd Jeffreys <to...@vo...> - * Copyright (C) 2004 The GameCube Linux Team * * Based on vesafb (c) 1998 Gerd Knorr <kr...@go...> * @@ -36,13 +36,33 @@ #define DRV_MODULE_NAME "gcnfb" #define DRV_DESCRIPTION "Nintendo GameCube frame buffer driver" -#define DRV_AUTHOR "Michael Steil <mi...@c6...>, Todd Jeffreys <to...@vo...>" +#define DRV_AUTHOR "Michael Steil <mi...@c6...>, " \ + "Todd Jeffreys <to...@vo...>" MODULE_AUTHOR(DRV_AUTHOR); MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_LICENSE(GPL); +MODULE_LICENSE("GPL"); -static volatile u32 *gamecube_video = (volatile u32*)0xCC002000; +/* + * Video mode handling + */ + +#define VI_FMT_NTSC_480i 0x00000000 +#define VI_FMT_NTSC_480p 0x00000100 +#define VI_FMT_PAL50_576i 0x00000011 +#define VI_FMT_PAL60_480i 0x00000001 +#define VI_FMT_MPAL_480i 0x00000002 + +#define VI_FMT_IS_NTSC(a) (((a)&0x001) == 0) +#define VI_FMT_IS_PAL(a) (((a)&0x003) != 0) + +struct vi_video_mode { + int format; + char *name; + const u32 *regs; + int width; + int height; +}; static const u32 VIDEO_Mode640X480NtscYUV16[32] = { 0x0F060001, 0x476901AD, 0x02EA5140, 0x00030018, @@ -56,59 +76,97 @@ }; static const u32 VIDEO_Mode640x480NtscProgressiveYUV16[32] = { - 0x1e0c0005, 0x476901ad, 0x2ea5140, 0x60030, - 0x60030, 0x81d881d8, 0x81d881d8, 0x10000000, - 0, 0, 0, 0x37702b6, - 0x90010001, 0, 0, 0, - 0, 0, 0x28280100, 0x1ae771f0, - 0xdb4a574, 0xc1188e, 0xc4c0cbe2, 0xfcecdecf, - 0x13130f08, 0x80c0f, 0xff0000, 0x10001, - 0x2800000, 0xff, 0xff00ff, 0xff00ff, + 0x1e0c0005, 0x476901ad, 0x02ea5140, 0x00060030, + 0x00060030, 0x81d881d8, 0x81d881d8, 0x10000000, + 0x00000000, 0x00000000, 0x00000000, 0x037702b6, + 0x90010001, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x28280100, 0x1ae771f0, + 0x0db4a574, 0x00c1188e, 0xc4c0cbe2, 0xfcecdecf, + 0x13130f08, 0x00080c0f, 0x00ff0000, 0x00010001, + 0x02800000, 0x000000ff, 0x00ff00ff, 0x00ff00ff, }; -static const u32 VIDEO_Mode640X480Pal50YUV16[32] = { +static const u32 VIDEO_Mode640X576Pal50YUV16[32] = { 0x11F50101, 0x4B6A01B0, 0x02F85640, 0x00010023, - 0x00000024, 0x4D2B4D6D, 0x4D8A4D4C, 0x00435A4E, - 0x00000000, 0x00435A4E, 0x00000000, 0x013C0144, - 0x113901B1, 0x10010001, 0x00010001, 0x00010001, + 0x00000024, 0x4D2B4D6D, 0x4D8A4D4C, 0x0066D480, + 0x00000000, 0x0066D980, 0x00000000, 0x00C901F3, + 0x913901B1, 0x90010001, 0x00010001, 0x00010001, 0x00000000, 0x00000000, 0x28500100, 0x1AE771F0, 0x0DB4A574, 0x00C1188E, 0xC4C0CBE2, 0xFCECDECF, 0x13130F08, 0x00080C0F, 0x00FF0000, 0x00000000, 0x02800000, 0x000000FF, 0x00FF00FF, 0x00FF00FF }; -#define TV_ENC_DETECT 0 -#define TV_ENC_NTSC 1 -#define TV_ENC_PAL 2 +static const u32 VIDEO_Mode640X480Pal60YUV16[32] = { + 0x0F060001, 0x476901AD, 0x02EA5140, 0x00030018, + 0x00020019, 0x410C410C, 0x40ED40ED, 0x0066D480, + 0x00000000, 0x0066D980, 0x00000000, 0x00C9010F, + 0x910701AE, 0x90010001, 0x00010001, 0x00010001, + 0x00000000, 0x00000000, 0x28500100, 0x1AE771F0, + 0x0DB4A574, 0x00C1188E, 0xC4C0CBE2, 0xFCECDECF, + 0x13130F08, 0x00080C0F, 0x00FF0000, 0x00000000, + 0x02800000, 0x000000FF, 0x00FF00FF, 0x00FF00FF +}; -#define IRQ_VIDEO 8 -#define VIDEO_IRQ_STATUS_1 0xCC002030 -#define VIDEO_IRQ_STATUS_2 0xCC002034 -#define VIDEO_IRQ_STATUS_3 0xCC002038 -#define VIDEO_IRQ_STATUS_4 0xCC00203C -#define VIDEO_IRQ_SET (1 << 31) -#define VIDEO_IRQ_ENABLE (1 << 28) -#define VIDEO_IRQ_VCT_SHIFT 16 -#define VIDEO_IRQ_VCT_MASK 0x03FF0000 -#define VIDEO_IRQ_HCT_SHIFT 0 -#define VIDEO_IRQ_HCT_MASK 0x000003FF +static struct vi_video_mode gcnfb_video_modes[] = { + { + .format = VI_FMT_NTSC_480i, + .name = "NTSC 480i", + .regs = VIDEO_Mode640X480NtscYUV16, + .width = 640, + .height = 480, + }, + { + .format = VI_FMT_NTSC_480p, + .name = "NTSC 480p", + .regs = VIDEO_Mode640x480NtscProgressiveYUV16, + .width = 640, + .height = 480, + }, + { + .format = VI_FMT_PAL50_576i, + .name = "PAL50 576i", + .regs = VIDEO_Mode640X576Pal50YUV16, + .width = 640, + .height = 576, + }, + { + .format = VI_FMT_PAL60_480i, + .name = "PAL60 480i", + .regs = VIDEO_Mode640X480Pal60YUV16, + .width = 640, + .height = 480, + }, + { .format = -1 } +}; -#define VIDEO_VISEL *((volatile u16*)0xCC00206E) -#define VIDEO_VISEL_SUPPORTS_PROGRESSIVE (1 << 0) +static struct vi_video_mode *gcnfb_video_mode = NULL; -#define IS_MODE_PROGRESSIVE(a) (((a) & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) -#define ENABLE_RUMBLE() do \ - { writel(0x00400001,0xCC006400); \ - writel(0x80000000,0xCC006438); } \ - while (0) +#define VI_IRQ 8 -#define SUPPORTS_PROGRESSIVE() (VIDEO_VISEL & VIDEO_VISEL_SUPPORTS_PROGRESSIVE) +#define VI_DI0 0xCC002030 +#define VI_DI1 0xCC002034 +#define VI_DI2 0xCC002038 +#define VI_DI3 0xCC00203C -static int tv_encoding = TV_ENC_DETECT; -static DECLARE_WAIT_QUEUE_HEAD(vtrace_wait_queue); -static struct fb_info gcnfb_info = -{ +#define VI_DI_INT (1 << 31) +#define VI_DI_ENB (1 << 28) +#define VI_DI_VCT_SHIFT 16 +#define VI_DI_VCT_MASK 0x03FF0000 +#define VI_DI_HCT_SHIFT 0 +#define VI_DI_HCT_MASK 0x000003FF + +#define VI_VISEL 0xCC00206E +#define VI_VISEL_PROGRESSIVE (1 << 0) + +static volatile u32 *vi_regs = (volatile u32 *)0xCC002000; + + +static u32 pseudo_palette[17]; +static int ypan = 0; /* 0..nothing, 1..ypan, 2..ywrap */ + +static struct fb_info gcnfb_info = { .var = { .activate = FB_ACTIVATE_NOW, .height = -1, @@ -117,17 +175,31 @@ .upper_margin = 16, .lower_margin = 4, .vsync_len = 4, - .vmode = FB_VMODE_INTERLACED, - }, + .vmode = FB_VMODE_INTERLACED, + }, .fix = { .id = "GameCube", .type = FB_TYPE_PACKED_PIXELS, .accel = FB_ACCEL_NONE, - } + } }; +static DECLARE_WAIT_QUEUE_HEAD(vtrace_wait_queue); + + +int gcnfb_restorefb(struct fb_info *info); + + +static inline int gcnfb_can_do_progressive(void) +{ + return readw(VI_VISEL) & VI_VISEL_PROGRESSIVE; +} + +static inline int gcnfb_is_progressive(__u32 vmode) +{ + return (vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED; +} + -static u32 pseudo_palette[17]; -static int ypan = 0; /* 0..nothing, 1..ypan, 2..ywrap */ /* * RGB to YCbYCr conversion support bits. * We are using here the ITU.BT-601 Y'CbCr standard. @@ -156,43 +228,9 @@ #define clamp(x, y, z) ((z < x) ? x : ((z > y) ? y : z)) -int gcnfb_restorefb(struct fb_info *info); - -static irqreturn_t gcfb_vi_irq_handler(int irq,void *dev_id,struct pt_regs *regs) -{ - u32 val; - - if ((val=readl(VIDEO_IRQ_STATUS_1)) & VIDEO_IRQ_SET) - { - gcngx_vtrace(); - wake_up_interruptible(&vtrace_wait_queue); - writel(val & ~VIDEO_IRQ_SET,VIDEO_IRQ_STATUS_1); - return IRQ_HANDLED; - } - if ((val=readl(VIDEO_IRQ_STATUS_2)) & VIDEO_IRQ_SET) - { - gcngx_vtrace(); - wake_up_interruptible(&vtrace_wait_queue); - writel(val & ~VIDEO_IRQ_SET,VIDEO_IRQ_STATUS_2); - return IRQ_HANDLED; - } - if ((val=readl(VIDEO_IRQ_STATUS_3)) & VIDEO_IRQ_SET) - { - gcngx_vtrace(); - wake_up_interruptible(&vtrace_wait_queue); - writel(val & ~VIDEO_IRQ_SET,VIDEO_IRQ_STATUS_3); - return IRQ_HANDLED; - } - if ((val=readl(VIDEO_IRQ_STATUS_4)) & VIDEO_IRQ_SET) - { - gcngx_vtrace(); - wake_up_interruptible(&vtrace_wait_queue); - writel(val & ~VIDEO_IRQ_SET,VIDEO_IRQ_STATUS_4); - return IRQ_HANDLED; - } - return IRQ_NONE; -} - +/* + * + */ static inline uint32_t rgbrgb16toycbycr(uint16_t rgb1, uint16_t rgb2) { register int Y1, Cb, Y2, Cr; @@ -247,21 +285,65 @@ + RGB2YUV_CHROMA); return (((uint8_t) Y1) << 24) | (((uint8_t) Cb) << 16) | - (((uint8_t) Y2) << 8) | (((uint8_t) Cr) << 0); + (((uint8_t) Y2) << 8) | (((uint8_t) Cr) << 0); } +/** + * + */ unsigned int gcnfb_writel(unsigned int rgbrgb, void *address) { uint16_t *rgb = (uint16_t *) & rgbrgb; return fb_writel_real(rgbrgb16toycbycr(rgb[0], rgb[1]), address); } +/** + * + */ static int gcnfb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) + struct fb_info *info) { return 0; } +/** + * + */ +static irqreturn_t gcnfb_vi_irq_handler(int irq, void *dev_id, + struct pt_regs *regs) +{ + u32 val; + + if ((val = readl(VI_DI0)) & VI_DI_INT) { + gcngx_vtrace(); + wake_up_interruptible(&vtrace_wait_queue); + writel(val & ~VI_DI_INT, VI_DI0); + return IRQ_HANDLED; + } + if ((val = readl(VI_DI1)) & VI_DI_INT) { + gcngx_vtrace(); + wake_up_interruptible(&vtrace_wait_queue); + writel(val & ~VI_DI_INT, VI_DI1); + return IRQ_HANDLED; + } + if ((val = readl(VI_DI2)) & VI_DI_INT) { + gcngx_vtrace(); + wake_up_interruptible(&vtrace_wait_queue); + writel(val & ~VI_DI_INT, VI_DI2); + return IRQ_HANDLED; + } + if ((val = readl(VI_DI3)) & VI_DI_INT) { + gcngx_vtrace(); + wake_up_interruptible(&vtrace_wait_queue); + writel(val & ~VI_DI_INT, VI_DI3); + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +/** + * + */ static u32 gcnfb_uvirt_to_phys(u32 virt) { pgd_t *dir; @@ -272,56 +354,59 @@ u32 offset = virt & (PAGE_SIZE - 1); virt &= PAGE_MASK; - if (!mm) - { + if (!mm) { return 0; } down_read(&mm->mmap_sem); /* convert to kernel address */ if ((dir = pgd_offset(mm, virt)) && pgd_present(*dir)) { if ((pmd = pmd_offset(dir, virt)) && pmd_present(*pmd)) { - pte = pte_offset_kernel(pmd,virt); + pte = pte_offset_kernel(pmd, virt); if (pte && pte_present(*pte)) { - ret = (u32)page_address(pte_page(*pte)) + offset; + ret = + (u32) page_address(pte_page(*pte)) + offset; /* ok now we have the kern addr, map to phys */ - ret = virt_to_phys((void*)ret); + ret = virt_to_phys((void *)ret); } } } - + up_read(&mm->mmap_sem); mmput(mm); return ret; } -static int gcnfb_ioctl(struct inode *inode,struct file *file, - unsigned int cmd,unsigned long arg, - struct fb_info *info) +/** + * + */ +static int gcnfb_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg, + struct fb_info *info) { u32 phys; void __user *argp; - - if (cmd == FBIOWAITRETRACE) - { + + if (cmd == FBIOWAITRETRACE) { interruptible_sleep_on(&vtrace_wait_queue); return (signal_pending(current) ? -EINTR : 0); - } - else if (cmd == FBIOVIRTTOPHYS) - { + } else if (cmd == FBIOVIRTTOPHYS) { argp = (void __user *)arg; - if (copy_from_user(&phys,argp,sizeof(void*))) + if (copy_from_user(&phys, argp, sizeof(void *))) return -EFAULT; phys = gcnfb_uvirt_to_phys(phys); - if (copy_to_user(argp,&phys,sizeof(void*))) + if (copy_to_user(argp, &phys, sizeof(void *))) return -EFAULT; - return 0; + return 0; } /* see if the GX module will handle it */ - return gcngx_ioctl(inode,file,cmd,arg,info); + return gcngx_ioctl(inode, file, cmd, arg, info); } +/** + * + */ static int gcnfb_set_par(struct fb_info *info) { /* update the video registers now */ @@ -329,30 +414,29 @@ return 0; } -static int gcnfb_check_var(struct fb_var_screeninfo *var, - struct fb_info *info) +/** + * + */ +static int gcnfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { /* check bpp */ if (var->bits_per_pixel != 16 || /* check bpp */ - var->xres_virtual != 640 || /* check for 640 x */ - var->xres != 640 || - var->yres_virtual != gcnfb_info.var.yres || /* check for y */ - var->yres != gcnfb_info.var.yres || - (IS_MODE_PROGRESSIVE(var->vmode) && !SUPPORTS_PROGRESSIVE())) /* trying to set progressive? */ - { + var->xres_virtual != gcnfb_video_mode->width || + var->xres != gcnfb_video_mode->width || + /* XXX isobel, do not break old sdl */ + /* var->yres_virtual != gcnfb_info.var.yres || *//* check for y */ + /* var->yres != gcnfb_info.var.yres || */ + (gcnfb_is_progressive(var->vmode) && !gcnfb_can_do_progressive())) { /* trying to set progressive? */ return -EINVAL; } return 0; } -static void vesa_setpalette(int regno, unsigned red, unsigned green, - unsigned blue) -{ -} - +/** + * + */ static int gcnfb_setcolreg(unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, - struct fb_info *info) + unsigned blue, unsigned transp, struct fb_info *info) { /* * Set a single color register. The values supplied are @@ -366,7 +450,6 @@ switch (info->var.bits_per_pixel) { case 8: - vesa_setpalette(regno, red, green, blue); break; case 15: case 16: @@ -374,13 +457,13 @@ /* XXX, not used currently */ /* 1:5:5:5 */ ((u32 *) (info->pseudo_palette))[regno] = - ((red & 0xf800) >> 1) | - ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11); + ((red & 0xf800) >> 1) | + ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11); } else { /* 0:5:6:5 */ ((u32 *) (info->pseudo_palette))[regno] = - ((red & 0xf800)) | - ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); + ((red & 0xf800)) | + ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); } break; case 24: @@ -390,35 +473,150 @@ green >>= 8; blue >>= 8; ((u32 *) (info->pseudo_palette))[regno] = - (red << info->var.red.offset) | - (green << info->var.green.offset) | - (blue << info->var.blue.offset); + (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset); break; } return 0; } +/** + * + */ +void gcnfb_enable_interrupts(int enable) +{ + u16 vtrap, htrap; + + if (enable) { + /* XXX should we incorporate this in the video mode struct ? */ + vtrap = gcnfb_video_mode->height / 2; + htrap = VI_FMT_IS_NTSC(gcnfb_video_mode->format) ? 430 : 433; + + /* progressive interrupts at 526 */ + if (gcnfb_is_progressive(gcnfb_info.var.vmode) + && gcnfb_can_do_progressive()) { + vtrap *= 2; + } + + /* interrupt on line 1 */ + writel(VI_DI_INT | VI_DI_ENB | + (1 << VI_DI_VCT_SHIFT) | (1 << VI_DI_HCT_SHIFT), + VI_DI0); + + writel(VI_DI_INT | VI_DI_ENB | + (vtrap << VI_DI_VCT_SHIFT) | (htrap << VI_DI_HCT_SHIFT), + VI_DI1); + } else { + writel(0, VI_DI0); + writel(0, VI_DI1); + } + writel(0, VI_DI2); + writel(0, VI_DI3); +} + +/** + * + */ +void gcnfb_set_framebuffer(u32 addr) +{ + /* set top field */ + vi_regs[7] = 0x10000000 | (addr >> 5); + + /* set bottom field */ + if (!gcnfb_is_progressive(gcnfb_info.var.vmode)) { + addr += gcnfb_info.fix.line_length; + } + vi_regs[9] = 0x10000000 | (addr >> 5); +} + +/** + * + */ +int gcnfb_restorefb(struct fb_info *info) +{ + int i; + + printk(KERN_INFO "Setting mode %s\n", gcnfb_video_mode->name); + gcnfb_set_framebuffer(info->fix.smem_start); + + /* initialize video registers */ + for (i = 0; i < 7; i++) { + vi_regs[i] = gcnfb_video_mode->regs[i]; + } + vi_regs[8] = gcnfb_video_mode->regs[8]; + vi_regs[10] = gcnfb_video_mode->regs[10]; + vi_regs[11] = gcnfb_video_mode->regs[11]; + for (i = 16; i < 32; i++) { + vi_regs[i] = gcnfb_video_mode->regs[i]; + } + gcnfb_enable_interrupts(1); + return 0; +} + +EXPORT_SYMBOL(gcnfb_restorefb); + struct fb_ops gcnfb_ops = { - .owner = THIS_MODULE, - .fb_setcolreg = gcnfb_setcolreg, + .owner = THIS_MODULE, + .fb_setcolreg = gcnfb_setcolreg, .fb_pan_display = gcnfb_pan_display, - .fb_ioctl = gcnfb_ioctl, - .fb_mmap = gcngx_mmap, - .fb_check_var = gcnfb_check_var, - .fb_set_par = gcnfb_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, + .fb_ioctl = gcnfb_ioctl, + .fb_mmap = gcngx_mmap, + .fb_check_var = gcnfb_check_var, + .fb_set_par = gcnfb_set_par, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_cursor = soft_cursor, }; +/** + * + */ +struct vi_video_mode *gcnfb_lookup_video_mode(int format) +{ + struct vi_video_mode *mode = &gcnfb_video_modes[0]; + + while (mode->format != -1) { + if (mode->format == format) + break; + mode++; + } + return (mode->format == -1) ? NULL : mode; +} + +/** + * + */ +void gcnfb_video_mode_select(void) +{ + if (gcnfb_video_mode == NULL) { + if (vi_regs[1] == 0x4B6A01B0) { + gcnfb_video_mode = + gcnfb_lookup_video_mode(VI_FMT_PAL50_576i); + } else { + gcnfb_video_mode = + gcnfb_lookup_video_mode(*(((u16*)vi_regs) + 2) & 3); + } + } + + /* if we get here something wrong happened */ + if (gcnfb_video_mode == NULL) { + printk(KERN_DEBUG "HEY! SOMETHING WEIRD HERE!\n"); + gcnfb_video_mode = &gcnfb_video_modes[0]; + } +} + +/** + * + */ int __init gcnfb_setup(char *options) { char *this_opt; - printk("gcnfb: options = %s\n", options); if (!options || !*options) return 0; + printk("gcnfb: options = %s\n", options); while ((this_opt = strsep(&options, ",")) != NULL) { printk("this_opt = %s\n", this_opt); @@ -435,136 +633,67 @@ printk("detected \"tv=\"\n"); printk("cmd line: %s\n", this_opt); if (!strncmp(this_opt + 3, "PAL", 3)) - tv_encoding = TV_ENC_PAL; + gcnfb_video_mode = + gcnfb_lookup_video_mode(VI_FMT_PAL50_576i); else if (!strncmp(this_opt + 3, "NTSC", 4)) - tv_encoding = TV_ENC_NTSC; - } - } - return 0; -} - -void gcnfb_enable_interrupts(int enable) -{ - u16 vtrap = (tv_encoding == TV_ENC_NTSC) ? 263 : 313; - u16 htrap = (tv_encoding == TV_ENC_NTSC) ? 430 : 433; - if (enable) - { - /* interrupt on line 1 */ - writel(VIDEO_IRQ_SET | VIDEO_IRQ_ENABLE | (1 << VIDEO_IRQ_VCT_SHIFT) | (1 << VIDEO_IRQ_HCT_SHIFT),VIDEO_IRQ_STATUS_1); - /* progressive interrupts at 526 */ - if (IS_MODE_PROGRESSIVE(gcnfb_info.var.vmode) && SUPPORTS_PROGRESSIVE()) - { - vtrap *= 2; - } - writel(VIDEO_IRQ_SET | VIDEO_IRQ_ENABLE | (vtrap << VIDEO_IRQ_VCT_SHIFT) | (htrap << VIDEO_IRQ_HCT_SHIFT),VIDEO_IRQ_STATUS_2); - } - else - { - writel(0,VIDEO_IRQ_STATUS_1); - writel(0,VIDEO_IRQ_STATUS_2); - } - writel(0,VIDEO_IRQ_STATUS_3); - writel(0,VIDEO_IRQ_STATUS_4); -} - -void gcnfb_set_framebuffer(u32 addr) -{ - /* set top field */ - gamecube_video[7] = 0x10000000 | (addr >> 5); - /* set bottom field */ - if (IS_MODE_PROGRESSIVE(gcnfb_info.var.vmode) && SUPPORTS_PROGRESSIVE()) { - gamecube_video[9] = 0x10000000 | (addr >> 5); - } - else { - gamecube_video[9] = 0x10000000 | ((addr + gcnfb_info.fix.line_length) >> 5); - } -} - -int gcnfb_restorefb(struct fb_info *info) -{ - const u32 *VIDEO_Mode; - const char *msg; - int i; - /* skip for now? */ - - if (tv_encoding == TV_ENC_NTSC) - { - if (IS_MODE_PROGRESSIVE(info->var.vmode) && SUPPORTS_PROGRESSIVE()) - { - msg = "NTSC 480p"; - VIDEO_Mode = VIDEO_Mode640x480NtscProgressiveYUV16; - } - else - { - msg = "NTSC 480i"; - VIDEO_Mode = VIDEO_Mode640X480NtscYUV16; + gcnfb_video_mode = + gcnfb_lookup_video_mode(VI_FMT_NTSC_480i); } } - else - { - msg = "PAL"; - VIDEO_Mode = VIDEO_Mode640X480Pal50YUV16; - } - - printk(KERN_INFO "Setting mode %s\n",msg); - - gcnfb_set_framebuffer(info->fix.smem_start); - - /* initialize video registers */ - for (i = 0; i < 7; i++) { - gamecube_video[i] = VIDEO_Mode[i]; - } - gamecube_video[8] = VIDEO_Mode[8]; - gamecube_video[10] = VIDEO_Mode[10]; - gamecube_video[11] = VIDEO_Mode[11]; - gcnfb_enable_interrupts(1); - for (i = 16; i < 32; i++) { - gamecube_video[i] = VIDEO_Mode[i]; - } return 0; } -EXPORT_SYMBOL(gcnfb_restorefb); - +/** + * + */ int __init gcnfb_init(void) { int video_cmap_len; - int i; int err = -EINVAL; char *option = NULL; - + +#if 0 + int i; + printk(KERN_INFO "vi_regs[] = {\n"); + for (i = 0; i < 32; i += 4) { + printk(KERN_INFO "0x%08X, 0x%08X, 0x%08X, 0x%08X,\n", + vi_regs[i], + vi_regs[i + 1], + vi_regs[i + 2], vi_regs[i + 3]); + } + printk(KERN_INFO "}\n"); +#endif + if (fb_get_options("gcnfb", &option)) { if (fb_get_options("gamecubefb", &option)) return -ENODEV; } - gcnfb_setup(option); - // detect current video mode - if (tv_encoding == TV_ENC_DETECT) { - tv_encoding = ((gamecube_video[0] >> 8) & 3) + 1; - } + + gcnfb_video_mode_select(); gcnfb_info.var.bits_per_pixel = 16; - gcnfb_info.var.xres = 640; - gcnfb_info.var.yres = (tv_encoding == TV_ENC_NTSC) ? 480 : 576; + gcnfb_info.var.xres = gcnfb_video_mode->width; + gcnfb_info.var.yres = gcnfb_video_mode->height; /* enable non-interlaced if it supports progressive */ - if (SUPPORTS_PROGRESSIVE()) - { + if (gcnfb_can_do_progressive()) { gcnfb_info.var.vmode = FB_VMODE_NONINTERLACED; } gcnfb_info.fix.line_length = - gcnfb_info.var.xres * (gcnfb_info.var.bits_per_pixel / 8); - /* add space for double-buffering */ - gcnfb_info.fix.smem_len = 2 * gcnfb_info.fix.line_length * gcnfb_info.var.yres; + gcnfb_info.var.xres * (gcnfb_info.var.bits_per_pixel / 8); + /* add space for double-buffering */ + gcnfb_info.fix.smem_len = + 2 * gcnfb_info.fix.line_length * gcnfb_info.var.yres; /* place XFB at end of RAM */ gcnfb_info.fix.smem_start = GCN_XFB_START; gcnfb_info.fix.visual = (gcnfb_info.var.bits_per_pixel == 8) ? - FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; - + FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; + if (!request_mem_region - (gcnfb_info.fix.smem_start, gcnfb_info.fix.smem_len, "Framebuffer")) { + (gcnfb_info.fix.smem_start, gcnfb_info.fix.smem_len, + "Framebuffer")) { printk(KERN_WARNING "gcnfb: abort, cannot reserve video memory at %p\n", (void *)gcnfb_info.fix.smem_start); @@ -572,12 +701,14 @@ spaces our resource handlers simply don't know about */ } - gcnfb_info.screen_base = ioremap(gcnfb_info.fix.smem_start, gcnfb_info.fix.smem_len); + gcnfb_info.screen_base = + ioremap(gcnfb_info.fix.smem_start, gcnfb_info.fix.smem_len); if (!gcnfb_info.screen_base) { printk(KERN_ERR "gcnfb: abort, cannot ioremap video memory" " at %p (%dk)\n", - (void *)gcnfb_info.fix.smem_start, gcnfb_info.fix.smem_len / 1024); + (void *)gcnfb_info.fix.smem_start, + gcnfb_info.fix.smem_len / 1024); err = -EIO; goto err_ioremap; } @@ -599,7 +730,7 @@ /* FIXME! Please, use here *real* values */ /* some dummy values for timing to make fbset happy */ gcnfb_info.var.pixclock = - 10000000 / gcnfb_info.var.xres * 1000 / gcnfb_info.var.yres; + 10000000 / gcnfb_info.var.xres * 1000 / gcnfb_info.var.yres; gcnfb_info.var.left_margin = (gcnfb_info.var.xres / 8) & 0xf8; gcnfb_info.var.hsync_len = (gcnfb_info.var.xres / 8) & 0xf8; @@ -641,49 +772,57 @@ err = -ENOMEM; goto err_alloc_cmap; } - + /* setup the framebuffer address */ gcnfb_restorefb(&gcnfb_info); + + /* XXX isobel */ +#if 0 /* fill framebuffer memory with black color */ - for (i=0;i<(gcnfb_info.var.xres * gcnfb_info.var.yres / 2);++i) - { - writel(0x00800080, ((u32*)gcnfb_info.screen_base)+i); + for (i = 0; i < (gcnfb_info.var.xres * gcnfb_info.var.yres / 2); ++i) { + writel(0x00800080, ((u32 *) gcnfb_info.screen_base) + i); } +#endif + /* now register us */ if (register_framebuffer(&gcnfb_info) < 0) { err = -EINVAL; goto err_register_framebuffer; } - - if (request_irq(IRQ_VIDEO,gcfb_vi_irq_handler,SA_INTERRUPT,"VI Line",0)) { - printk(KERN_ERR "Unable to register IRQ %u\n",IRQ_VIDEO); + + if (request_irq + (VI_IRQ, gcnfb_vi_irq_handler, SA_INTERRUPT, "VI Line", 0)) { + printk(KERN_ERR "Unable to register IRQ %u\n", VI_IRQ); } - - if ((err=gcngx_init(&gcnfb_info))) { + + if ((err = gcngx_init(&gcnfb_info))) { goto err_gcngx_init; } - + printk(KERN_INFO "fb%d: %s frame buffer device\n", gcnfb_info.node, gcnfb_info.fix.id); return 0; - - err_gcngx_init: - free_irq(IRQ_VIDEO,0); + + err_gcngx_init: + free_irq(VI_IRQ, 0); unregister_framebuffer(&gcnfb_info); - err_register_framebuffer: + err_register_framebuffer: fb_dealloc_cmap(&gcnfb_info.cmap); - err_alloc_cmap: + err_alloc_cmap: iounmap(gcnfb_info.screen_base); - err_ioremap: + err_ioremap: release_mem_region(gcnfb_info.fix.smem_start, gcnfb_info.fix.smem_len); return err; } +/** + * + */ static void __exit gcnfb_exit(void) { gcngx_exit(&gcnfb_info); - free_irq(IRQ_VIDEO,0); + free_irq(VI_IRQ, 0); unregister_framebuffer(&gcnfb_info); fb_dealloc_cmap(&gcnfb_info.cmap); iounmap(gcnfb_info.screen_base); |
From: <he...@us...> - 2004-10-24 23:40:24
|
Update of /cvsroot/gc-linux/htdocs/xml/en In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29618 Modified Files: news.xml Log Message: 25 October 2004, Hardware accelerated graphics Index: news.xml =================================================================== RCS file: /cvsroot/gc-linux/htdocs/xml/en/news.xml,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- news.xml 20 Oct 2004 23:45:22 -0000 1.24 +++ news.xml 24 Oct 2004 23:40:14 -0000 1.25 @@ -2,6 +2,11 @@ <?xml-stylesheet href="news.xsl" type="text/xsl"?> <news> <item> + <date>25 October 2004</date> + <title>Hardware accelerated graphics</title> + <text>Scream|CT is currently working on improving gc-linux graphics performance by using help from the powerful "Flipper" GPU. Check the new improvements on <a href="http://sourceforge.net/cvs/?group_id=98581">cvs</a> and on <a href="http://voidpointer.org/gc-linux/">Scream|CT's site</a>.</text> + </item> + <item> <date>21 October 2004</date> <title>Latest kernel build updated to 2.6.9</title> <text>This latest release includes also new kexec functionality to load homebrew DOLs and a customized Linux logo. Available <a href="http://www.gc-linux.org/down/isobel/2.6.9/zImage-2.6.9.isobel.dol">here</a>.</text> |
From: <pal...@us...> - 2004-10-24 04:35:45
|
Update of /cvsroot/gc-linux/libgx/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16342/src Modified Files: gx.c Log Message: Change to GX_AllocContiguousMemory which supports multiple allocations Index: gx.c =================================================================== RCS file: /cvsroot/gc-linux/libgx/src/gx.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 --- gx.c 22 Oct 2004 20:13:53 -0000 1.1.1.1 +++ gx.c 24 Oct 2004 04:35:36 -0000 1.2 @@ -72,6 +72,7 @@ static u32 mmap_length; static void *front_buffer; static void *back_buffer; +static u32 alloc_pos = 0; static volatile u32* _piReg; static volatile u16* _viReg; @@ -616,6 +617,7 @@ } mmap_addr = NULL; mmap_length = 0; + alloc_pos = 0; gfd = -1; } @@ -3704,7 +3706,7 @@ pmem->length &= ~(4096-1); pmem->user_mem = mmap(0,pmem->length,PROT_READ|PROT_WRITE,MAP_SHARED,gfd, - 0x0D000000); + 0x0D000000 + alloc_pos); if (pmem->user_mem == NULL || pmem->user_mem == MAP_FAILED) { @@ -3712,6 +3714,8 @@ pmem->user_mem = pmem->phys_mem = NULL; return 1; } + /* increment position so next allocation can occur at different offset */ + alloc_pos += pmem->length; /* the kernel writes the physical address in the first dword, read it */ pmem->phys_mem = (void*)(*((u32*)pmem->user_mem)); return 0; |
From: <pal...@us...> - 2004-10-22 22:54:29
|
Update of /cvsroot/gc-linux/linux/drivers/video In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8797/drivers/video Modified Files: gcnfb.c Log Message: First of many future PAL fixes: Fix for interrupt timings Index: gcnfb.c =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/video/gcnfb.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- gcnfb.c 22 Oct 2004 19:42:04 -0000 1.3 +++ gcnfb.c 22 Oct 2004 22:54:19 -0000 1.4 @@ -445,7 +445,8 @@ void gcnfb_enable_interrupts(int enable) { - u16 vtrap = 263; + u16 vtrap = (tv_encoding == TV_ENC_NTSC) ? 263 : 313; + u16 htrap = (tv_encoding == TV_ENC_NTSC) ? 430 : 433; if (enable) { /* interrupt on line 1 */ @@ -455,7 +456,7 @@ { vtrap *= 2; } - writel(VIDEO_IRQ_SET | VIDEO_IRQ_ENABLE | (vtrap << VIDEO_IRQ_VCT_SHIFT) | (0x1AE << VIDEO_IRQ_HCT_SHIFT),VIDEO_IRQ_STATUS_2); + writel(VIDEO_IRQ_SET | VIDEO_IRQ_ENABLE | (vtrap << VIDEO_IRQ_VCT_SHIFT) | (htrap << VIDEO_IRQ_HCT_SHIFT),VIDEO_IRQ_STATUS_2); } else { |
From: <pal...@us...> - 2004-10-22 20:51:26
|
Update of /cvsroot/gc-linux/linux/drivers/video In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12831 Added Files: gcngx.c gcngx.h Log Message: GX driver files --- NEW FILE: gcngx.c --- /* * drivers/video/gcngx.c * * Nintendo GameCube GX driver extension * Copyright (C) 2004 Todd Jeffreys <to...@vo...> * Copyright (C) 2004 The GameCube Linux Team * * Parts borrowed heavily from libogc. This driver would not have * been possible with this library. Thanks! * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/mm.h> #include <linux/fb.h> #include <linux/console.h> #include <linux/vt_kern.h> #include <linux/interrupt.h> #include <linux/wait.h> #include <asm/pgtable.h> #include <asm/atomic.h> #include <platforms/gamecube.h> #include "gcngx.h" /* Function definitions */ static inline void __GX_AckFifoInt(int isOver); static inline void __GX_WriteFifoIntEnable(int over,int under); static void gcngx_munmap(struct vm_area_struct *vma); static void gcngx_free_munmap(struct vm_area_struct *vma); static void gcngx_destroy_fifo(void); static void gcngx_init_fifo(void); extern int gcnfb_restorefb(struct fb_info *info); extern void gcnfb_set_framebuffer(u32 addr); extern struct fb_ops gcnfb_ops; /* Defines */ #define mtwpar(v) mtspr(921,v) #define mfwpar(v) mfspr(921) #define GX_ENABLE 1 #define GX_DISABLE 0 #define GX_TRUE 1 #define GX_FALSE 0 #define _SHIFTL(v, s, w) \ ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s))) #define _SHIFTR(v, s, w) \ ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1))) #define IRQ_VIDEO 8 #define IRQ_PE_TOKEN 9 #define IRQ_PE_FINISH 10 #define IRQ_CP_FIFO 11 #define VIDEO_MMAP_BASE 0x0C000000 #define VIDEO_MMAP_LENGTH 0x9000 #define KMALLOC_BASE 0x0D000000 #define VIDEO_PE_INTERRUPT 0xCC00100A #define VIDEO_PE_TOKEN 0xCC00100E #define VIDEO_PE_INTERRUPT_TOKEN_ENABLE (1 << 0) #define VIDEO_PE_INTERRUPT_FINISH_ENABLE (1 << 1) #define VIDEO_PE_INTERRUPT_TOKEN_INTERRUPT (1 << 2) #define VIDEO_PE_INTERRUPT_FINISH_INTERRUPT (1 << 3) #define gcngx_disable_pe_interrupts() writew(readw(VIDEO_PE_INTERRUPT) & ~(VIDEO_PE_INTERRUPT_TOKEN_ENABLE | VIDEO_PE_INTERRUPT_FINISH_ENABLE),VIDEO_PE_INTERRUPT) #define gcngx_enable_pe_interrupts() { writew(readw(VIDEO_PE_INTERRUPT) | (VIDEO_PE_INTERRUPT_TOKEN_ENABLE | VIDEO_PE_INTERRUPT_FINISH_ENABLE | VIDEO_PE_INTERRUPT_TOKEN_INTERRUPT | VIDEO_PE_INTERRUPT_FINISH_INTERRUPT),VIDEO_PE_INTERRUPT); writew(0,VIDEO_PE_TOKEN); } #define VIDEO_CP_SR ((volatile u16*)0xCC000000) #define VIDEO_CP_CR ((volatile u16*)0xCC000002) #define VIDEO_CP_SR_OVERFLOW (1 << 0) #define VIDEO_CP_SR_UNDERFLOW (1 << 1) #define VIDEO_CP_CR_GP_FIFO_READ_ENABLE (1 << 0) #define VIDEO_CP_CR_CP_IRQ_ENABLE (1 << 1) #define VIDEO_CP_CR_OVERFLOW_IRQ_ENABLE (1 << 2) #define VIDEO_CP_CR_UNDERFLOW_IRQ_ENABLE (1 << 3) #define VIDEO_CP_CR_GP_LINK_ENABLE (1 << 4) #define VIDEO_CP_CR_MASK (0x1F) #define SIG_PE_FINISH (SIGRTMIN+14) #define SIG_PE_TOKEN (SIGRTMIN+15) #define SIG_VTRACE_COMPLETE (SIGRTMIN+16) #define ENABLE_RUMBLE() do \ { writel(0x00400001,0xCC006400); \ writel(0x80000000,0xCC006438); } \ while (0) #define FIFO_PUTU8(x) (*((volatile u8*) WGPIPE) = (x)) #define FIFO_PUTU32(x) (*((volatile u32*)WGPIPE) = (x)) #define LOAD_BP_REG(x) do { FIFO_PUTU8(0x61); FIFO_PUTU32(x); } while (0) /* Static data */ static task_t *mmap_task; static int overflow; static u32 xfb[2]; static int currentFB = 0; static int flipRequest = 0; static u8 *mmap_fifo_base; static u8 *phys_fifo_base; static const u32 fifo_len = GCN_GX_FIFO_SIZE; static struct vm_operations_struct gcngx_vm_ops = { .close = gcngx_munmap, }; static struct vm_operations_struct gcngx_vm_free_ops = { .close = gcngx_free_munmap, }; static volatile u32* const _piReg = (volatile u32*)0xCC003000; static volatile u16* const _cpReg = (volatile u16*)0xCC000000; static volatile u16* const _peReg = (volatile u16*)0xCC001000; static volatile u16* const _memReg = (volatile u16*)0xCC004000; static volatile u32* const WGPIPE = (volatile u32*)0xCC008000; static irqreturn_t gcfb_fifo_irq_handler(int irq,void *dev_id,struct pt_regs *regs) { /* now handle the int */ u16 val = readw(VIDEO_CP_SR); /* ENABLE_RUMBLE(); */ if (val & VIDEO_CP_SR_OVERFLOW) { /* fifo overflow, must halt the current application */ if (mmap_task) { printk(KERN_INFO "Man you are writing too fast! Slow down! I will make you!\n"); set_task_state(mmap_task,TASK_UNINTERRUPTIBLE); overflow = 1; } __GX_AckFifoInt(1); __GX_WriteFifoIntEnable(GX_DISABLE,GX_ENABLE); return IRQ_HANDLED; } else if (val & VIDEO_CP_SR_UNDERFLOW) { /* underflow, resume the current application */ if (mmap_task && overflow) { printk(KERN_INFO "OK dude, the GX has crunched the data, you can resume now\n"); set_task_state(mmap_task,TASK_RUNNING); overflow = 0; } __GX_AckFifoInt(0); __GX_WriteFifoIntEnable(GX_ENABLE,GX_DISABLE); return IRQ_HANDLED; } return IRQ_NONE; } void gcngx_vtrace(void) { struct siginfo sig; /* ok flip the image if we have a flip request. send signal on completion */ if (mmap_task && flipRequest) { /* do the flip! */ flipRequest = 0; /* setup the signal info and flip buffer pointers */ currentFB = currentFB ? 0 : 1; sig.si_errno = xfb[currentFB]; /* inform the hardware */ gcnfb_set_framebuffer(xfb[currentFB]); /* notify the process */ sig.si_signo = SIG_VTRACE_COMPLETE; sig.si_code = 0; send_sig_info(SIG_VTRACE_COMPLETE,&sig,mmap_task); } } static irqreturn_t gcfb_pe_finish_irq_handler(int irq,void *dev_id,struct pt_regs *regs) { u16 val; struct siginfo sig; /* ack the interrupt */ val = readw(VIDEO_PE_INTERRUPT) | VIDEO_PE_INTERRUPT_FINISH_INTERRUPT; writew(val,VIDEO_PE_INTERRUPT); /* send SIG_PE_FINISH to the process */ if (mmap_task) { sig.si_signo = SIG_PE_FINISH; sig.si_errno = 0; sig.si_code = 0; send_sig_info(SIG_PE_FINISH,&sig,mmap_task); } return IRQ_HANDLED; } static irqreturn_t gcfb_pe_token_irq_handler(int irq,void *dev_id,struct pt_regs *regs) { u16 val; struct siginfo sig; /* ack the interrupt */ val = readw(VIDEO_PE_INTERRUPT) | VIDEO_PE_INTERRUPT_TOKEN_INTERRUPT; writew(val,VIDEO_PE_INTERRUPT); /* send SIG_PE_TOKEN to the process */ if (mmap_task) { sig.si_signo = SIG_PE_TOKEN; sig.si_errno = 0; sig.si_code = _peReg[7]; send_sig_info(SIG_PE_TOKEN,&sig,mmap_task); } return IRQ_HANDLED; } int gcngx_ioctl(struct inode *inode,struct file *file, unsigned int cmd,unsigned long arg, struct fb_info *info) { if (cmd == FBIOFLIP) { flipRequest = 1; return 0; } return -EINVAL; } static void *mymalloc(unsigned int len) { struct page *page; void *p = kmalloc(len,GFP_KERNEL); if (p && len) { /* reserve all the memory so remap_page_range works */ for (page=virt_to_page(p);page<virt_to_page(p+len);++page) { SetPageReserved(page); SetPageLocked(page); } } return p; } static void *myfree(void *p) { struct page *page; u32 len; if (p) { len = ksize(p); for (page=virt_to_page(p);page<virt_to_page(p+len);++page) { ClearPageReserved(page); ClearPageLocked(page); } kfree(p); } } static void gcngx_free_munmap(struct vm_area_struct *vma) { if (vma->vm_private_data) { myfree(vma->vm_private_data); vma->vm_private_data = NULL; } } static void gcngx_munmap(struct vm_area_struct *vma) { struct fb_info *info = (struct fb_info*)vma->vm_private_data; gcngx_destroy_fifo(); /* nobody has up mapped anymore */ mmap_task = NULL; overflow = 0; /* restore the framebuffer */ gcnfb_restorefb(info); #ifdef CONFIG_FRAMEBUFFER_CONSOLE acquire_console_sem(); update_screen(info->currcon); unblank_screen(); release_console_sem(); #endif } int gcngx_mmap(struct fb_info *info,struct file *file, struct vm_area_struct *vma) { int ret; static spinlock_t lock = SPIN_LOCK_UNLOCKED; u32 phys; u32 len; len = vma->vm_end - vma->vm_start; if (vma->vm_pgoff == (VIDEO_MMAP_BASE >> PAGE_SHIFT) && len == VIDEO_MMAP_LENGTH) { /* our special case, map the memory info */ vma->vm_flags |= VM_IO; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); if (io_remap_page_range(vma,vma->vm_start, VIDEO_MMAP_BASE, len, vma->vm_page_prot)) { return -EINVAL; } vma->vm_ops = &gcngx_vm_ops; vma->vm_private_data = info; /* store task for when fifo is overflown */ mmap_task = current; overflow = 0; /* init the fifo before we return */ gcngx_init_fifo(); return 0; } else if (vma->vm_pgoff >= (KMALLOC_BASE >> PAGE_SHIFT)) { /* ok kmalloc the memory now */ vma->vm_private_data = mymalloc(len); if (!vma->vm_private_data) { return -ENOMEM; } /* now setup the mapping */ phys = virt_to_phys(vma->vm_private_data); vma->vm_flags |= (VM_RESERVED | VM_LOCKED); if (remap_page_range(vma,vma->vm_start, phys,len,vma->vm_page_prot)) { kfree(vma->vm_private_data); return -EINVAL; } vma->vm_ops = &gcngx_vm_free_ops; /* now write the physical mapping in the first u32 */ *((u32*)vma->vm_private_data) = phys; /* return successful */ return 0; } /* call the frame buffer mmap method */ if (file->f_op->mmap) { spin_lock(&lock); /* reset our mmap since the fb driver will call it */ gcnfb_ops.fb_mmap = NULL; ret = file->f_op->mmap(file,vma); /* reset our mmap */ gcnfb_ops.fb_mmap = gcngx_mmap; spin_unlock(&lock); return ret; } return -EINVAL; } static inline void __GX_AckFifoInt(int isOver) { if (isOver) _cpReg[2] |= (1 << 0); else _cpReg[2] |= (1 << 1); } static inline void __GX_Flush(void) { /* write 8 32 bit values to the WGPIPE */ *WGPIPE = 0; *WGPIPE = 0; *WGPIPE = 0; *WGPIPE = 0; *WGPIPE = 0; *WGPIPE = 0; *WGPIPE = 0; *WGPIPE = 0; } static inline void __GX_WriteFifoIntEnable(int over, int under) { u16 val = _cpReg[1] & ~(VIDEO_CP_CR_GP_FIFO_READ_ENABLE | VIDEO_CP_CR_CP_IRQ_ENABLE | VIDEO_CP_CR_GP_LINK_ENABLE); if (over) val |= VIDEO_CP_CR_OVERFLOW_IRQ_ENABLE; if (under) val |= VIDEO_CP_CR_UNDERFLOW_IRQ_ENABLE; _cpReg[1] = val; /* ack it just for fun */ _cpReg[2] = 0x3; } static inline void __GX_FifoReadEnable(int enable) { if (enable) _cpReg[1] |= VIDEO_CP_CR_GP_FIFO_READ_ENABLE; else _cpReg[1] &= ~VIDEO_CP_CR_GP_FIFO_READ_ENABLE; } static inline void __GX_FifoLink(u8 enable) { if (enable) _cpReg[1] |= VIDEO_CP_CR_GP_LINK_ENABLE; else _cpReg[1] &= ~VIDEO_CP_CR_GP_LINK_ENABLE; } static void __GX_EnableWriteGatherPipe(u8 enable) { u32 flags; if (enable) { mtwpar(0x0C008000); } asm ("isync"); asm ("sync"); flags = mfspr(920); if (enable) { flags |= 0x40000000; } else { flags &= ~0x40000000; } mtspr(920,flags); asm ("isync"); asm ("sync"); } static inline void __GX_DrawDone(void) { LOAD_BP_REG(0x45000002); __GX_Flush(); } static void gcngx_destroy_fifo() { gcngx_disable_pe_interrupts(); _peReg[7] = 0; __GX_DrawDone(); /* wait for the buffer to empty? */ __GX_WriteFifoIntEnable(GX_DISABLE,GX_DISABLE); __GX_FifoReadEnable(0); __GX_FifoLink(GX_FALSE); __GX_EnableWriteGatherPipe(0); } struct fifo_info { u8 *base; u8 *end; u32 length; u8 *lo_water_mark; u8 *hi_water_mark; u8 *write_ptr; u8 *read_ptr; }; static void gcngx_init_fifo(void) { struct fifo_info fi; int i; fi.base = phys_fifo_base; fi.end = phys_fifo_base + fifo_len - 4; fi.length = fifo_len; fi.lo_water_mark = phys_fifo_base + ((fifo_len / 2) & ~31); fi.hi_water_mark = phys_fifo_base + fifo_len - (16*1024); fi.write_ptr = phys_fifo_base; fi.read_ptr = phys_fifo_base; /* reset currentFB pointer */ currentFB = 0; flipRequest = 0; /* printk(KERN_INFO "Initializing Flipper FIFO at %p of length %u\n", fi.base,fifo_len); */ __GX_FifoLink(GX_FALSE); __GX_WriteFifoIntEnable(GX_DISABLE,GX_DISABLE); __GX_FifoReadEnable(0); /* clear the fifo */ for (i=0;i<fifo_len/4;++i) { ((u32*)mmap_fifo_base)[i] = 0; } /* flush it */ flush_dcache_range((u32)mmap_fifo_base, (u32)(mmap_fifo_base+fifo_len)); _peReg[7] = 0; /* fifo base start */ _piReg[3] = (u32)fi.base; /* fifo base end */ _piReg[4] = (u32)fi.end; /* fifo write pointer */ _piReg[5] = (u32)fi.write_ptr; /* init and flush the write gather pipe */ __GX_EnableWriteGatherPipe(1); __GX_Flush(); /* wait for all data to be flushed */ while (mfwpar() & 1); _piReg[3] = (u32)fi.base; _piReg[4] = (u32)fi.end; _piReg[5] = (u32)fi.write_ptr; while (mfwpar() & 1); /* setup fifo base */ _cpReg[16] = _SHIFTL(fi.base,0,16); _cpReg[17] = _SHIFTR(fi.base,16,16); /* setup fifo end */ _cpReg[18] = _SHIFTL(fi.end,0,16); _cpReg[19] = _SHIFTR(fi.end,16,16); /* setup hiwater mark */ _cpReg[20] = _SHIFTL(fi.hi_water_mark,0,16); _cpReg[21] = _SHIFTR(fi.hi_water_mark,16,16); /* setup lowater mark */ _cpReg[22] = _SHIFTL(fi.lo_water_mark,0,16); _cpReg[23] = _SHIFTR(fi.lo_water_mark,16,16); /* setup rd<->wd dist */ /*_cpReg[24] = _SHIFTL((pad)[7],0,16); _cpReg[25] = _SHIFTR((pad)[7],16,16);*/ _cpReg[24] = 0; _cpReg[25] = 0; /* setup wt ptr */ _cpReg[26] = _SHIFTL(fi.write_ptr,0,16); _cpReg[27] = _SHIFTR(fi.write_ptr,16,16); /* setup rd ptr */ _cpReg[28] = _SHIFTL(fi.read_ptr,0,16); _cpReg[29] = _SHIFTR(fi.read_ptr,16,16); asm ("sync"); asm ("isync"); /* enable the write gather pipe */ __GX_WriteFifoIntEnable(GX_ENABLE,GX_DISABLE); __GX_FifoLink(GX_TRUE); __GX_FifoReadEnable(1); /* enable interrupts */ gcngx_enable_pe_interrupts(); asm("sync"); asm("isync"); } int gcngx_init(struct fb_info *info) { int err; /* compute framebuffer pointers */ xfb[0] = (u32)info->fix.smem_start; xfb[1] = (u32)info->fix.smem_start + info->fix.smem_len/2; /* disable the interrupts */ gcngx_disable_pe_interrupts(); __GX_WriteFifoIntEnable(GX_DISABLE,GX_DISABLE); /* map the fifo area */ phys_fifo_base = (u8*)GCN_GX_FIFO_START; if (!request_mem_region((u32)phys_fifo_base,fifo_len,"GX FIFO")) { printk(KERN_ERR "Cannot reserve fifo memory area at %p\n",phys_fifo_base); return -EIO; } if (!(mmap_fifo_base = ioremap((u32)phys_fifo_base,fifo_len))) { printk(KERN_ERR "Cannot map the fifo area at %p\n",phys_fifo_base); err = -EIO; goto free_mem; } if ((err=request_irq(IRQ_PE_TOKEN,gcfb_pe_token_irq_handler,SA_INTERRUPT,"PE Token",0))) { goto free_iounmap; } if ((err=request_irq(IRQ_PE_FINISH,gcfb_pe_finish_irq_handler,SA_INTERRUPT,"PE Finish",0))) { goto free_pe_token; } if ((err=request_irq(IRQ_CP_FIFO,gcfb_fifo_irq_handler,SA_INTERRUPT,"CP FIFO",0))) { goto free_pe_finish; } return 0; free_pe_finish: free_irq(IRQ_PE_FINISH,0); free_pe_token: free_irq(IRQ_PE_TOKEN,0); free_iounmap: iounmap(mmap_fifo_base); free_mem: release_mem_region((u32)phys_fifo_base,fifo_len); return err; } void gcngx_exit(struct fb_info *info) { gcngx_destroy_fifo(); free_irq(IRQ_PE_FINISH,0); free_irq(IRQ_PE_TOKEN,0); free_irq(IRQ_CP_FIFO,0); iounmap(mmap_fifo_base); release_mem_region((u32)phys_fifo_base,fifo_len); } --- NEW FILE: gcngx.h --- #ifndef __GCGX__ #define __GCGX__ int gcngx_mmap(struct fb_info *info,struct file *file, struct vm_area_struct *vma); int gcngx_ioctl(struct inode *inode,struct file *file, unsigned int cmd,unsigned long arg, struct fb_info *info); int gcngx_init(struct fb_info *info); void gcngx_exit(struct fb_info *info); void gcngx_vtrace(void); #endif |
From: <pal...@us...> - 2004-10-22 20:06:21
|
Update of /cvsroot/gc-linux/linux/arch/ppc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3454/arch/ppc Modified Files: Kconfig Log Message: Backing out inadvertent addition of KEXEC Index: Kconfig =================================================================== RCS file: /cvsroot/gc-linux/linux/arch/ppc/Kconfig,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -r1.20 -r1.21 --- Kconfig 22 Oct 2004 19:42:03 -0000 1.20 +++ Kconfig 22 Oct 2004 20:06:10 -0000 1.21 @@ -243,27 +243,6 @@ depends on 4xx || 8xx || GAMECUBE default y -config KEXEC - bool "kexec system call (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - kexec is a system call that implements the ability to shutdown your - current kernel, and to start another kernel. It is like a reboot - but it is indepedent of the system firmware. And like a reboot - you can start any kernel with it, not just Linux. - - The name comes from the similiarity to the exec system call. - - It is an ongoing process to be certain the hardware in a machine - is properly shutdown, so do not be surprised if this code does not - initially work for you. It may help to enable device hotplugging - support. As of this writing the exact hardware interface is - strongly in flux, so no good recommendation can be made. - - In the GameCube implementation, kexec allows you to load and - run DOL files, including kernel and homebrew DOLs. - - endmenu menu "Platform options" |
From: <pal...@us...> - 2004-10-22 19:42:15
|
Update of /cvsroot/gc-linux/linux/drivers/video In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30747/drivers/video Modified Files: Makefile gcnfb.c Log Message: GX driver checkin. Added better support for wavebirds. Faster interrupt handling. Index: Makefile =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/video/Makefile,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- Makefile 20 Oct 2004 00:07:40 -0000 1.9 +++ Makefile 22 Oct 2004 19:42:04 -0000 1.10 @@ -89,7 +89,7 @@ obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_PXA) += pxafb.o cfbimgblt.o cfbcopyarea.o cfbfillrect.o -obj-$(CONFIG_FB_GAMECUBE) += gcnfb.o cfbfillrect.o cfbcopyarea.o \ +obj-$(CONFIG_FB_GAMECUBE) += gcnfb.o gcngx.o cfbfillrect.o cfbcopyarea.o \ cfbimgblt.o # Platform or fallback drivers go here Index: gcnfb.c =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/video/gcnfb.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- gcnfb.c 20 Oct 2004 22:38:31 -0000 1.2 +++ gcnfb.c 22 Oct 2004 19:42:04 -0000 1.3 @@ -3,6 +3,7 @@ * * Nintendo GameCube "Flipper" chipset frame buffer driver * Copyright (C) 2004 Michael Steil <mi...@c6...> + * Copyright (C) 2004 Todd Jeffreys <to...@vo...> * Copyright (C) 2004 The GameCube Linux Team * * Based on vesafb (c) 1998 Gerd Knorr <kr...@go...> @@ -25,23 +26,25 @@ #include <linux/fb.h> #include <linux/ioport.h> #include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/wait.h> #include <asm/io.h> - +#include <asm/pgtable.h> +#include <asm/uaccess.h> #include <platforms/gamecube.h> - +#include "gcngx.h" #define DRV_MODULE_NAME "gcnfb" #define DRV_DESCRIPTION "Nintendo GameCube frame buffer driver" -#define DRV_AUTHOR "Michael Steil <mi...@c6...>" +#define DRV_AUTHOR "Michael Steil <mi...@c6...>, Todd Jeffreys <to...@vo...>" MODULE_AUTHOR(DRV_AUTHOR); MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_LICENSE(GPL); +static volatile u32 *gamecube_video = (volatile u32*)0xCC002000; -volatile static unsigned int *gcn_video = (unsigned int *)0xCC002000; - -static const unsigned int VIDEO_Mode640X480NtscYUV16[32] = { +static const u32 VIDEO_Mode640X480NtscYUV16[32] = { 0x0F060001, 0x476901AD, 0x02EA5140, 0x00030018, 0x00020019, 0x410C410C, 0x40ED40ED, 0x00435A4E, 0x00000000, 0x00435A4E, 0x00000000, 0x00000000, @@ -52,7 +55,18 @@ 0x02800000, 0x000000FF, 0x00FF00FF, 0x00FF00FF }; -static const unsigned int VIDEO_Mode640X480Pal50YUV16[32] = { +static const u32 VIDEO_Mode640x480NtscProgressiveYUV16[32] = { + 0x1e0c0005, 0x476901ad, 0x2ea5140, 0x60030, + 0x60030, 0x81d881d8, 0x81d881d8, 0x10000000, + 0, 0, 0, 0x37702b6, + 0x90010001, 0, 0, 0, + 0, 0, 0x28280100, 0x1ae771f0, + 0xdb4a574, 0xc1188e, 0xc4c0cbe2, 0xfcecdecf, + 0x13130f08, 0x80c0f, 0xff0000, 0x10001, + 0x2800000, 0xff, 0xff00ff, 0xff00ff, +}; + +static const u32 VIDEO_Mode640X480Pal50YUV16[32] = { 0x11F50101, 0x4B6A01B0, 0x02F85640, 0x00010023, 0x00000024, 0x4D2B4D6D, 0x4D8A4D4C, 0x00435A4E, 0x00000000, 0x00435A4E, 0x00000000, 0x013C0144, @@ -63,33 +77,57 @@ 0x02800000, 0x000000FF, 0x00FF00FF, 0x00FF00FF }; -static struct fb_var_screeninfo gcnfb_defined __initdata = { - .activate = FB_ACTIVATE_NOW, - .height = -1, - .width = -1, - .right_margin = 32, - .upper_margin = 16, - .lower_margin = 4, - .vsync_len = 4, - .vmode = FB_VMODE_NONINTERLACED, -}; - -static struct fb_fix_screeninfo gcnfb_fix __initdata = { - .id = "gcnfb", - .type = FB_TYPE_PACKED_PIXELS, - .accel = FB_ACCEL_NONE, -}; - #define TV_ENC_DETECT 0 #define TV_ENC_NTSC 1 #define TV_ENC_PAL 2 -static int tv_encoding __initdata = TV_ENC_DETECT; -static struct fb_info gcnfb_info; -static u32 pseudo_palette[17]; +#define IRQ_VIDEO 8 +#define VIDEO_IRQ_STATUS_1 0xCC002030 +#define VIDEO_IRQ_STATUS_2 0xCC002034 +#define VIDEO_IRQ_STATUS_3 0xCC002038 +#define VIDEO_IRQ_STATUS_4 0xCC00203C +#define VIDEO_IRQ_SET (1 << 31) +#define VIDEO_IRQ_ENABLE (1 << 28) +#define VIDEO_IRQ_VCT_SHIFT 16 +#define VIDEO_IRQ_VCT_MASK 0x03FF0000 +#define VIDEO_IRQ_HCT_SHIFT 0 +#define VIDEO_IRQ_HCT_MASK 0x000003FF -static int ypan = 0; /* 0..nothing, 1..ypan, 2..ywrap */ +#define VIDEO_VISEL *((volatile u16*)0xCC00206E) +#define VIDEO_VISEL_SUPPORTS_PROGRESSIVE (1 << 0) + +#define IS_MODE_PROGRESSIVE(a) (((a) & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) +#define ENABLE_RUMBLE() do \ + { writel(0x00400001,0xCC006400); \ + writel(0x80000000,0xCC006438); } \ + while (0) + +#define SUPPORTS_PROGRESSIVE() (VIDEO_VISEL & VIDEO_VISEL_SUPPORTS_PROGRESSIVE) + +static int tv_encoding = TV_ENC_DETECT; +static DECLARE_WAIT_QUEUE_HEAD(vtrace_wait_queue); +static struct fb_info gcnfb_info = +{ + .var = { + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .right_margin = 32, + .upper_margin = 16, + .lower_margin = 4, + .vsync_len = 4, + .vmode = FB_VMODE_INTERLACED, + }, + .fix = { + .id = "GameCube", + .type = FB_TYPE_PACKED_PIXELS, + .accel = FB_ACCEL_NONE, + } +}; + +static u32 pseudo_palette[17]; +static int ypan = 0; /* 0..nothing, 1..ypan, 2..ywrap */ /* * RGB to YCbYCr conversion support bits. * We are using here the ITU.BT-601 Y'CbCr standard. @@ -118,6 +156,43 @@ #define clamp(x, y, z) ((z < x) ? x : ((z > y) ? y : z)) +int gcnfb_restorefb(struct fb_info *info); + +static irqreturn_t gcfb_vi_irq_handler(int irq,void *dev_id,struct pt_regs *regs) +{ + u32 val; + + if ((val=readl(VIDEO_IRQ_STATUS_1)) & VIDEO_IRQ_SET) + { + gcngx_vtrace(); + wake_up_interruptible(&vtrace_wait_queue); + writel(val & ~VIDEO_IRQ_SET,VIDEO_IRQ_STATUS_1); + return IRQ_HANDLED; + } + if ((val=readl(VIDEO_IRQ_STATUS_2)) & VIDEO_IRQ_SET) + { + gcngx_vtrace(); + wake_up_interruptible(&vtrace_wait_queue); + writel(val & ~VIDEO_IRQ_SET,VIDEO_IRQ_STATUS_2); + return IRQ_HANDLED; + } + if ((val=readl(VIDEO_IRQ_STATUS_3)) & VIDEO_IRQ_SET) + { + gcngx_vtrace(); + wake_up_interruptible(&vtrace_wait_queue); + writel(val & ~VIDEO_IRQ_SET,VIDEO_IRQ_STATUS_3); + return IRQ_HANDLED; + } + if ((val=readl(VIDEO_IRQ_STATUS_4)) & VIDEO_IRQ_SET) + { + gcngx_vtrace(); + wake_up_interruptible(&vtrace_wait_queue); + writel(val & ~VIDEO_IRQ_SET,VIDEO_IRQ_STATUS_4); + return IRQ_HANDLED; + } + return IRQ_NONE; +} + static inline uint32_t rgbrgb16toycbycr(uint16_t rgb1, uint16_t rgb2) { register int Y1, Cb, Y2, Cr; @@ -172,7 +247,7 @@ + RGB2YUV_CHROMA); return (((uint8_t) Y1) << 24) | (((uint8_t) Cb) << 16) | - (((uint8_t) Y2) << 8) | (((uint8_t) Cr) << 0); + (((uint8_t) Y2) << 8) | (((uint8_t) Cr) << 0); } unsigned int gcnfb_writel(unsigned int rgbrgb, void *address) @@ -187,6 +262,89 @@ return 0; } +static u32 gcnfb_uvirt_to_phys(u32 virt) +{ + pgd_t *dir; + pmd_t *pmd; + pte_t *pte; + u32 ret = 0; + struct mm_struct *mm = get_task_mm(current); + u32 offset = virt & (PAGE_SIZE - 1); + virt &= PAGE_MASK; + + if (!mm) + { + return 0; + } + down_read(&mm->mmap_sem); + /* convert to kernel address */ + if ((dir = pgd_offset(mm, virt)) && pgd_present(*dir)) { + if ((pmd = pmd_offset(dir, virt)) && pmd_present(*pmd)) { + pte = pte_offset_kernel(pmd,virt); + if (pte && pte_present(*pte)) { + ret = (u32)page_address(pte_page(*pte)) + offset; + /* ok now we have the kern addr, map to phys */ + ret = virt_to_phys((void*)ret); + } + } + } + + up_read(&mm->mmap_sem); + mmput(mm); + return ret; +} + +static int gcnfb_ioctl(struct inode *inode,struct file *file, + unsigned int cmd,unsigned long arg, + struct fb_info *info) +{ + u32 phys; + void __user *argp; + + if (cmd == FBIOWAITRETRACE) + { + interruptible_sleep_on(&vtrace_wait_queue); + return (signal_pending(current) ? -EINTR : 0); + } + else if (cmd == FBIOVIRTTOPHYS) + { + argp = (void __user *)arg; + if (copy_from_user(&phys,argp,sizeof(void*))) + return -EFAULT; + + phys = gcnfb_uvirt_to_phys(phys); + + if (copy_to_user(argp,&phys,sizeof(void*))) + return -EFAULT; + return 0; + } + /* see if the GX module will handle it */ + return gcngx_ioctl(inode,file,cmd,arg,info); +} + +static int gcnfb_set_par(struct fb_info *info) +{ + /* update the video registers now */ + gcnfb_restorefb(info); + return 0; +} + +static int gcnfb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + /* check bpp */ + if (var->bits_per_pixel != 16 || /* check bpp */ + var->xres_virtual != 640 || /* check for 640 x */ + var->xres != 640 || + var->yres_virtual != gcnfb_info.var.yres || /* check for y */ + var->yres != gcnfb_info.var.yres || + (IS_MODE_PROGRESSIVE(var->vmode) && !SUPPORTS_PROGRESSIVE())) /* trying to set progressive? */ + { + return -EINVAL; + } + return 0; +} + static void vesa_setpalette(int regno, unsigned red, unsigned green, unsigned blue) { @@ -216,13 +374,13 @@ /* XXX, not used currently */ /* 1:5:5:5 */ ((u32 *) (info->pseudo_palette))[regno] = - ((red & 0xf800) >> 1) | - ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11); + ((red & 0xf800) >> 1) | + ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11); } else { /* 0:5:6:5 */ ((u32 *) (info->pseudo_palette))[regno] = - ((red & 0xf800)) | - ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); + ((red & 0xf800)) | + ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); } break; case 24: @@ -232,33 +390,36 @@ green >>= 8; blue >>= 8; ((u32 *) (info->pseudo_palette))[regno] = - (red << info->var.red.offset) | - (green << info->var.green.offset) | - (blue << info->var.blue.offset); + (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset); break; } return 0; } -static struct fb_ops gcnfb_ops = { - .owner = THIS_MODULE, - .fb_setcolreg = gcnfb_setcolreg, +struct fb_ops gcnfb_ops = { + .owner = THIS_MODULE, + .fb_setcolreg = gcnfb_setcolreg, .fb_pan_display = gcnfb_pan_display, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, + .fb_ioctl = gcnfb_ioctl, + .fb_mmap = gcngx_mmap, + .fb_check_var = gcnfb_check_var, + .fb_set_par = gcnfb_set_par, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_cursor = soft_cursor, }; int __init gcnfb_setup(char *options) { char *this_opt; + printk("gcnfb: options = %s\n", options); if (!options || !*options) return 0; - printk("gcnfb: options = %s\n", options); - while ((this_opt = strsep(&options, ",")) != NULL) { printk("this_opt = %s\n", this_opt); if (!*this_opt) @@ -282,109 +443,196 @@ return 0; } +void gcnfb_enable_interrupts(int enable) +{ + u16 vtrap = 263; + if (enable) + { + /* interrupt on line 1 */ + writel(VIDEO_IRQ_SET | VIDEO_IRQ_ENABLE | (1 << VIDEO_IRQ_VCT_SHIFT) | (1 << VIDEO_IRQ_HCT_SHIFT),VIDEO_IRQ_STATUS_1); + /* progressive interrupts at 526 */ + if (IS_MODE_PROGRESSIVE(gcnfb_info.var.vmode) && SUPPORTS_PROGRESSIVE()) + { + vtrap *= 2; + } + writel(VIDEO_IRQ_SET | VIDEO_IRQ_ENABLE | (vtrap << VIDEO_IRQ_VCT_SHIFT) | (0x1AE << VIDEO_IRQ_HCT_SHIFT),VIDEO_IRQ_STATUS_2); + } + else + { + writel(0,VIDEO_IRQ_STATUS_1); + writel(0,VIDEO_IRQ_STATUS_2); + } + writel(0,VIDEO_IRQ_STATUS_3); + writel(0,VIDEO_IRQ_STATUS_4); +} + +void gcnfb_set_framebuffer(u32 addr) +{ + /* set top field */ + gamecube_video[7] = 0x10000000 | (addr >> 5); + /* set bottom field */ + if (IS_MODE_PROGRESSIVE(gcnfb_info.var.vmode) && SUPPORTS_PROGRESSIVE()) { + gamecube_video[9] = 0x10000000 | (addr >> 5); + } + else { + gamecube_video[9] = 0x10000000 | ((addr + gcnfb_info.fix.line_length) >> 5); + } +} + +int gcnfb_restorefb(struct fb_info *info) +{ + const u32 *VIDEO_Mode; + const char *msg; + int i; + /* skip for now? */ + + if (tv_encoding == TV_ENC_NTSC) + { + if (IS_MODE_PROGRESSIVE(info->var.vmode) && SUPPORTS_PROGRESSIVE()) + { + msg = "NTSC 480p"; + VIDEO_Mode = VIDEO_Mode640x480NtscProgressiveYUV16; + } + else + { + msg = "NTSC 480i"; + VIDEO_Mode = VIDEO_Mode640X480NtscYUV16; + } + } + else + { + msg = "PAL"; + VIDEO_Mode = VIDEO_Mode640X480Pal50YUV16; + } + + printk(KERN_INFO "Setting mode %s\n",msg); + + gcnfb_set_framebuffer(info->fix.smem_start); + + /* initialize video registers */ + for (i = 0; i < 7; i++) { + gamecube_video[i] = VIDEO_Mode[i]; + } + gamecube_video[8] = VIDEO_Mode[8]; + gamecube_video[10] = VIDEO_Mode[10]; + gamecube_video[11] = VIDEO_Mode[11]; + gcnfb_enable_interrupts(1); + for (i = 16; i < 32; i++) { + gamecube_video[i] = VIDEO_Mode[i]; + } + return 0; +} + +EXPORT_SYMBOL(gcnfb_restorefb); + int __init gcnfb_init(void) { int video_cmap_len; int i; - int err = 0; + int err = -EINVAL; char *option = NULL; - + if (fb_get_options("gcnfb", &option)) { if (fb_get_options("gamecubefb", &option)) return -ENODEV; } + gcnfb_setup(option); - - /* detect current video mode */ + // detect current video mode if (tv_encoding == TV_ENC_DETECT) { - tv_encoding = ((gcn_video[0] >> 8) & 3) + 1; + tv_encoding = ((gamecube_video[0] >> 8) & 3) + 1; } - gcnfb_defined.bits_per_pixel = 16; - gcnfb_defined.xres = 640; - gcnfb_defined.yres = (tv_encoding == TV_ENC_NTSC) ? 480 : 576; - - gcnfb_fix.line_length = - gcnfb_defined.xres * (gcnfb_defined.bits_per_pixel / 8); - gcnfb_fix.smem_len = gcnfb_fix.line_length * gcnfb_defined.yres; - gcnfb_fix.smem_start = GCN_XFB_START; + gcnfb_info.var.bits_per_pixel = 16; + gcnfb_info.var.xres = 640; + gcnfb_info.var.yres = (tv_encoding == TV_ENC_NTSC) ? 480 : 576; + /* enable non-interlaced if it supports progressive */ + if (SUPPORTS_PROGRESSIVE()) + { + gcnfb_info.var.vmode = FB_VMODE_NONINTERLACED; + } - gcnfb_fix.visual = (gcnfb_defined.bits_per_pixel == 8) ? - FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; + gcnfb_info.fix.line_length = + gcnfb_info.var.xres * (gcnfb_info.var.bits_per_pixel / 8); + /* add space for double-buffering */ + gcnfb_info.fix.smem_len = 2 * gcnfb_info.fix.line_length * gcnfb_info.var.yres; + /* place XFB at end of RAM */ + gcnfb_info.fix.smem_start = GCN_XFB_START; + gcnfb_info.fix.visual = (gcnfb_info.var.bits_per_pixel == 8) ? + FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; + if (!request_mem_region - (gcnfb_fix.smem_start, gcnfb_fix.smem_len, "gcnfb")) { + (gcnfb_info.fix.smem_start, gcnfb_info.fix.smem_len, "Framebuffer")) { printk(KERN_WARNING "gcnfb: abort, cannot reserve video memory at %p\n", - (void *)gcnfb_fix.smem_start); + (void *)gcnfb_info.fix.smem_start); /* We cannot make this fatal. Sometimes this comes from magic spaces our resource handlers simply don't know about */ } - gcnfb_info.screen_base = ioremap(gcnfb_fix.smem_start, gcnfb_fix.smem_len); + gcnfb_info.screen_base = ioremap(gcnfb_info.fix.smem_start, gcnfb_info.fix.smem_len); if (!gcnfb_info.screen_base) { printk(KERN_ERR "gcnfb: abort, cannot ioremap video memory" " at %p (%dk)\n", - (void *)gcnfb_fix.smem_start, gcnfb_fix.smem_len / 1024); + (void *)gcnfb_info.fix.smem_start, gcnfb_info.fix.smem_len / 1024); err = -EIO; goto err_ioremap; } printk(KERN_INFO "gcnfb: framebuffer at 0x%p, mapped to 0x%p, size %dk\n", - (void *)gcnfb_fix.smem_start, gcnfb_info.screen_base, - gcnfb_fix.smem_len / 1024); + (void *)gcnfb_info.fix.smem_start, gcnfb_info.screen_base, + gcnfb_info.fix.smem_len / 1024); printk(KERN_INFO "gcnfb: mode is %dx%dx%d, linelength=%d, pages=%d\n", - gcnfb_defined.xres, gcnfb_defined.yres, - gcnfb_defined.bits_per_pixel, gcnfb_fix.line_length, + gcnfb_info.var.xres, gcnfb_info.var.yres, + gcnfb_info.var.bits_per_pixel, gcnfb_info.fix.line_length, 0 /*screen_info.pages */ ); - gcnfb_defined.xres_virtual = gcnfb_defined.xres; - gcnfb_defined.yres_virtual = gcnfb_defined.yres; + gcnfb_info.var.xres_virtual = gcnfb_info.var.xres; + gcnfb_info.var.yres_virtual = gcnfb_info.var.yres; ypan = 0; /* FIXME! Please, use here *real* values */ /* some dummy values for timing to make fbset happy */ - gcnfb_defined.pixclock = - 10000000 / gcnfb_defined.xres * 1000 / gcnfb_defined.yres; - gcnfb_defined.left_margin = (gcnfb_defined.xres / 8) & 0xf8; - gcnfb_defined.hsync_len = (gcnfb_defined.xres / 8) & 0xf8; + gcnfb_info.var.pixclock = + 10000000 / gcnfb_info.var.xres * 1000 / gcnfb_info.var.yres; + gcnfb_info.var.left_margin = (gcnfb_info.var.xres / 8) & 0xf8; + gcnfb_info.var.hsync_len = (gcnfb_info.var.xres / 8) & 0xf8; - if (gcnfb_defined.bits_per_pixel == 15) { - gcnfb_defined.red.offset = 11; - gcnfb_defined.red.length = 5; - gcnfb_defined.green.offset = 6; - gcnfb_defined.green.length = 5; - gcnfb_defined.blue.offset = 1; - gcnfb_defined.blue.length = 5; - gcnfb_defined.transp.offset = 15; - gcnfb_defined.transp.length = 1; + if (gcnfb_info.var.bits_per_pixel == 15) { + gcnfb_info.var.red.offset = 11; + gcnfb_info.var.red.length = 5; + gcnfb_info.var.green.offset = 6; + gcnfb_info.var.green.length = 5; + gcnfb_info.var.blue.offset = 1; + gcnfb_info.var.blue.length = 5; + gcnfb_info.var.transp.offset = 15; + gcnfb_info.var.transp.length = 1; video_cmap_len = 16; - } else if (gcnfb_defined.bits_per_pixel == 16) { - gcnfb_defined.red.offset = 11; - gcnfb_defined.red.length = 5; - gcnfb_defined.green.offset = 5; - gcnfb_defined.green.length = 6; - gcnfb_defined.blue.offset = 0; - gcnfb_defined.blue.length = 5; - gcnfb_defined.transp.offset = 0; - gcnfb_defined.transp.length = 0; + } else if (gcnfb_info.var.bits_per_pixel == 16) { + gcnfb_info.var.red.offset = 11; + gcnfb_info.var.red.length = 5; + gcnfb_info.var.green.offset = 5; + gcnfb_info.var.green.length = 6; + gcnfb_info.var.blue.offset = 0; + gcnfb_info.var.blue.length = 5; + gcnfb_info.var.transp.offset = 0; + gcnfb_info.var.transp.length = 0; video_cmap_len = 16; } else { - gcnfb_defined.red.length = 6; - gcnfb_defined.green.length = 6; - gcnfb_defined.blue.length = 6; + gcnfb_info.var.red.length = 6; + gcnfb_info.var.green.length = 6; + gcnfb_info.var.blue.length = 6; video_cmap_len = 256; } - gcnfb_fix.ypanstep = ypan ? 1 : 0; - gcnfb_fix.ywrapstep = (ypan > 1) ? 1 : 0; + gcnfb_info.fix.ypanstep = ypan ? 1 : 0; + gcnfb_info.fix.ywrapstep = (ypan > 1) ? 1 : 0; gcnfb_info.fbops = &gcnfb_ops; - gcnfb_info.var = gcnfb_defined; - gcnfb_info.fix = gcnfb_fix; gcnfb_info.pseudo_palette = pseudo_palette; gcnfb_info.flags = FBINFO_FLAG_DEFAULT; @@ -392,62 +640,54 @@ err = -ENOMEM; goto err_alloc_cmap; } - + + /* setup the framebuffer address */ + gcnfb_restorefb(&gcnfb_info); + /* fill framebuffer memory with black color */ + for (i=0;i<(gcnfb_info.var.xres * gcnfb_info.var.yres / 2);++i) + { + writel(0x00800080, ((u32*)gcnfb_info.screen_base)+i); + } + /* now register us */ if (register_framebuffer(&gcnfb_info) < 0) { err = -EINVAL; goto err_register_framebuffer; } - - unsigned int *VIDEO_Mode; - - if (tv_encoding == TV_ENC_NTSC) - VIDEO_Mode = (unsigned int *)VIDEO_Mode640X480NtscYUV16; - else - VIDEO_Mode = (unsigned int *)VIDEO_Mode640X480Pal50YUV16; - - /* initialize video registers */ - for (i = 0; i < 7; i++) { - gcn_video[i] = VIDEO_Mode[i]; + + if (request_irq(IRQ_VIDEO,gcfb_vi_irq_handler,SA_INTERRUPT,"VI Line",0)) { + printk(KERN_ERR "Unable to register IRQ %u\n",IRQ_VIDEO); } - gcn_video[8] = VIDEO_Mode[8]; - for (i = 10; i < 32; i++) { - gcn_video[i] = VIDEO_Mode[i]; + + if ((err=gcngx_init(&gcnfb_info))) { + goto err_gcngx_init; } - - gcn_video[7] = 0x10000000 | (gcnfb_fix.smem_start >> 5); - -/* - * setting both fields to same source means half the resolution, but - * reduces flickering a lot ...mmmh maybe worth a try as a last resort :/ - * gcn_video[9] = 0x10000000 | (gcnfb_fix.smem_start>>5); - * - */ - - gcn_video[9] = - 0x10000000 | ((gcnfb_fix.smem_start + gcnfb_fix.line_length) >> 5); - + printk(KERN_INFO "fb%d: %s frame buffer device\n", gcnfb_info.node, gcnfb_info.fix.id); - goto out; -err_register_framebuffer: + return 0; + + err_gcngx_init: + free_irq(IRQ_VIDEO,0); + unregister_framebuffer(&gcnfb_info); + err_register_framebuffer: fb_dealloc_cmap(&gcnfb_info.cmap); -err_alloc_cmap: + err_alloc_cmap: iounmap(gcnfb_info.screen_base); -err_ioremap: - release_mem_region(gcnfb_fix.smem_start, gcnfb_fix.smem_len); -out: + err_ioremap: + release_mem_region(gcnfb_info.fix.smem_start, gcnfb_info.fix.smem_len); return err; } static void __exit gcnfb_exit(void) { + gcngx_exit(&gcnfb_info); + free_irq(IRQ_VIDEO,0); unregister_framebuffer(&gcnfb_info); fb_dealloc_cmap(&gcnfb_info.cmap); iounmap(gcnfb_info.screen_base); - release_mem_region(gcnfb_fix.smem_start, gcnfb_fix.smem_len); + release_mem_region(gcnfb_info.fix.smem_start, gcnfb_info.fix.smem_len); } module_init(gcnfb_init); module_exit(gcnfb_exit); - |
From: <pal...@us...> - 2004-10-22 19:42:15
|
Update of /cvsroot/gc-linux/linux/drivers/input In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30747/drivers/input Modified Files: gcn-si.c Log Message: GX driver checkin. Added better support for wavebirds. Faster interrupt handling. Index: gcn-si.c =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/input/gcn-si.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- gcn-si.c 19 Oct 2004 23:55:42 -0000 1.1 +++ gcn-si.c 22 Oct 2004 19:42:04 -0000 1.2 @@ -36,7 +36,7 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_AUTHOR(DRV_AUTHOR); -MODULE_LICENSE(GPL); +MODULE_LICENSE("GPL"); #define PFX DRV_MODULE_NAME ": " #define si_printk(level, format, arg...) \ @@ -62,8 +62,10 @@ #define ID_KEYBOARD 0x0820 #define ID_GBA 0x0004 #define ID_GBA_NA 0x0800 -#define ID_WAVEBIRD 0xa800 -#define ID_WAVEBIRD_RCV 0xe960 +#define ID_WAVEBIRD1 0xA800 +#define ID_WAVEBIRD2 0xEBB0 +#define ID_WAVEBIRD3 0xE9A0 +#define ID_WAVEBIRD_RCV 0xE960 #define PAD_START (1 << 28) #define PAD_Y (1 << 27) @@ -100,11 +102,11 @@ struct input_dev idev; struct timer_list timer; - + union { keyboard_status keyboard; }; - + char name[32]; /* char phys[32]; */ } port[4]; @@ -192,6 +194,9 @@ for (i = 0; i < 4; ++i) { switch (port[i].id) { case ID_PAD: + case ID_WAVEBIRD1: + case ID_WAVEBIRD2: + case ID_WAVEBIRD3: writel(0x00400300, SICOUTBUF(i)); break; @@ -238,6 +243,9 @@ switch (port[portno].id) { case ID_PAD: + case ID_WAVEBIRD1: + case ID_WAVEBIRD2: + case ID_WAVEBIRD3: /* buttons */ input_report_key(&port[portno].idev, BTN_A, raw[0] & PAD_A); input_report_key(&port[portno].idev, BTN_B, raw[0] & PAD_B); @@ -396,7 +404,12 @@ switch (port[i].id) { case ID_PAD: - sprintf(port[i].name, "standard pad"); + case ID_WAVEBIRD1: + case ID_WAVEBIRD2: + case ID_WAVEBIRD3: + sprintf(port[i].name, + port[i].id == ID_PAD ? + "standard pad" : "Wavebird"); /* sprintf (port[i].phys, "gcsi/port%d", i); */ /* port[i].idev.phys = port[i].phys; */ @@ -513,11 +526,15 @@ si_printk(KERN_INFO, "exit\n"); for (i = 0; i < 4; ++i) { - if (port[i].id == ID_PAD || port[i].id == ID_KEYBOARD) { + if (port[i].id == ID_PAD || + port[i].id == ID_WAVEBIRD1 || + port[i].id == ID_WAVEBIRD2 || + port[i].id == ID_WAVEBIRD3 || + port[i].id == ID_KEYBOARD) { input_unregister_device(&port[i].idev); } } - + release_resource(&gcn_si_resources); } |
From: <pal...@us...> - 2004-10-22 19:42:14
|
Update of /cvsroot/gc-linux/linux/arch/ppc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30747/arch/ppc Modified Files: Kconfig Log Message: GX driver checkin. Added better support for wavebirds. Faster interrupt handling. Index: Kconfig =================================================================== RCS file: /cvsroot/gc-linux/linux/arch/ppc/Kconfig,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 --- Kconfig 19 Oct 2004 23:36:53 -0000 1.19 +++ Kconfig 22 Oct 2004 19:42:03 -0000 1.20 @@ -240,9 +240,30 @@ config NOT_COHERENT_CACHE bool - depends on 4xx || 8xx + depends on 4xx || 8xx || GAMECUBE default y +config KEXEC + bool "kexec system call (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + kexec is a system call that implements the ability to shutdown your + current kernel, and to start another kernel. It is like a reboot + but it is indepedent of the system firmware. And like a reboot + you can start any kernel with it, not just Linux. + + The name comes from the similiarity to the exec system call. + + It is an ongoing process to be certain the hardware in a machine + is properly shutdown, so do not be surprised if this code does not + initially work for you. It may help to enable device hotplugging + support. As of this writing the exact hardware interface is + strongly in flux, so no good recommendation can be made. + + In the GameCube implementation, kexec allows you to load and + run DOL files, including kernel and homebrew DOLs. + + endmenu menu "Platform options" |
From: <pal...@us...> - 2004-10-22 19:42:14
|
Update of /cvsroot/gc-linux/linux/arch/ppc/platforms In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30747/arch/ppc/platforms Modified Files: gamecube.c gamecube.h Log Message: GX driver checkin. Added better support for wavebirds. Faster interrupt handling. Index: gamecube.c =================================================================== RCS file: /cvsroot/gc-linux/linux/arch/ppc/platforms/gamecube.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -d -r1.22 -r1.23 --- gamecube.c 19 Oct 2004 23:07:13 -0000 1.22 +++ gamecube.c 22 Oct 2004 19:42:03 -0000 1.23 @@ -116,17 +116,15 @@ gcn_get_irq(struct pt_regs *regs) { int irq; - u_int irq_status, irq_test = 1; + u32 irq_status; irq_status = readl(FLIPPER_ICR) & readl(FLIPPER_IMR); if (irq_status == 0) return -1; /* no more IRQs pending */ - for (irq = 0; irq < FLIPPER_NR_IRQS; irq++, irq_test <<= 1) - if (irq_status & irq_test) - break; + __asm __volatile ("cntlzw %0,%1": "=r"(irq) : "r"(irq_status)); - return irq; + return (31 - irq); } static void @@ -173,7 +171,12 @@ { seq_printf(m, "vendor\t\t: IBM\n"); seq_printf(m, "machine\t\t: Nintendo GameCube\n"); - + seq_printf(m, "cpu MHz\t\t: 486\n"); + seq_printf(m, "clock\t\t: 486MHz\n"); + seq_printf(m, "cache size\t: 256 KB\n"); + seq_printf(m, "bus speed\t: 162 MHz\n"); + seq_printf(m, "mem bus speed\t: 200 MHz\n"); + seq_printf(m, "bus width\t: 64 bit\n"); return 0; } Index: gamecube.h =================================================================== RCS file: /cvsroot/gc-linux/linux/arch/ppc/platforms/gamecube.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- gamecube.h 19 Oct 2004 23:07:28 -0000 1.9 +++ gamecube.h 22 Oct 2004 19:42:03 -0000 1.10 @@ -23,7 +23,13 @@ * | framebuffer 640x576x2 bytes | GCN_XFB_END * . . * . . + * | framebuffer 640x576x2 bytes | Second buffer + * . . + * . . * +------------------------------+ GCN_XFB_START + * | GX Fifo reserved 256k | GCN_GX_FIFO_END + * . . + * +------------------------------+ GCN_GX_FIFO_START * | kexec reserved 4x4096 bytes | GCN_KXC_END * . . * +------------------------------+ GCN_KXC_START @@ -43,8 +49,11 @@ /* * Some useful sizes */ +#define GCN_VIDEO_REG (*((volatile u16*)0xCC002002)) +#define GCN_VIDEO_LINES (((GCN_VIDEO_REG >> 8) & 3) ? 576 : 480) +#define GCN_GX_FIFO_SIZE (256*1024) #define GCN_RAM_SIZE (24*1024*1024) /* 24 MB */ -#define GCN_XFB_SIZE (640*576*2) /* pal framebuffer */ +#define GCN_XFB_SIZE (640*GCN_VIDEO_LINES*4) /* framebuffer */ #ifdef CONFIG_KEXEC #define GCN_KXC_SIZE (4*4096) /* PAGE_ALIGN(GCN_PRESERVE_SIZE) */ #else @@ -57,7 +66,9 @@ */ #define GCN_XFB_END (GCN_RAM_SIZE-1) #define GCN_XFB_START (GCN_XFB_END-GCN_XFB_SIZE+1) -#define GCN_KXC_END (GCN_XFB_START-1) +#define GCN_GX_FIFO_END (GCN_XFB_START-1) +#define GCN_GX_FIFO_START (GCN_GX_FIFO_END-GCN_GX_FIFO_SIZE+1) +#define GCN_KXC_END (GCN_GX_FIFO_START-1) #define GCN_KXC_START (GCN_KXC_END-GCN_KXC_SIZE+1) #define GCN_MEM_END (GCN_KXC_START-1) #define GCN_MEM_START (0x00000000) |
From: <pal...@us...> - 2004-10-22 19:42:14
|
Update of /cvsroot/gc-linux/linux/include/linux In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30747/include/linux Modified Files: fb.h Log Message: GX driver checkin. Added better support for wavebirds. Faster interrupt handling. Index: fb.h =================================================================== RCS file: /cvsroot/gc-linux/linux/include/linux/fb.h,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- fb.h 20 Oct 2004 00:07:41 -0000 1.8 +++ fb.h 22 Oct 2004 19:42:04 -0000 1.9 @@ -35,7 +35,10 @@ #define FBIOGET_HWCINFO 0x4616 #define FBIOPUT_MODEINFO 0x4617 #define FBIOGET_DISPINFO 0x4618 - +#define FBIOWAITRETRACE 0x4619 +#define FBIOWAITPEFINISH 0x4620 +#define FBIOVIRTTOPHYS 0x4621 +#define FBIOFLIP 0x4622 #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ #define FB_TYPE_PLANES 1 /* Non interleaved planes */ |
From: <he...@us...> - 2004-10-22 18:20:36
|
Update of /cvsroot/gc-linux/htdocs/include/en In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12901 Modified Files: index.php Log Message: The gc-linux project seems to be past the early phase, doesn't it? Changed "small server" to "tiny server" (using the GameCube as a server should be recommendable only on _very_ few scenarios). Index: index.php =================================================================== RCS file: /cvsroot/gc-linux/htdocs/include/en/index.php,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- index.php 6 Feb 2004 13:39:48 -0000 1.2 +++ index.php 22 Oct 2004 18:20:26 -0000 1.3 @@ -20,10 +20,10 @@ <p>Linux can be used:<br/> • to use a GameCube as a <b>thin client</b><br/> • to use a GameCube as a <b>multimedia terminal</b><br/> - • to use a GameCube as a small <b>PowerPC-based server</b><br/> + • to use a GameCube as a tiny <b>PowerPC-based server</b><br/> • as a runtime environment for <b>homebrew development</b><br/> -<p>The GameCube Linux Project is an early phase, but we already have a small Linux system with Ethernet (telnet and web server). Your are welcome to <b>contribute</b>!</p> +<p>The GameCube Linux Project is in constant development . You are welcome to <b>contribute</b>!</p> </td><td valign=top width="50%"> |
From: <he...@us...> - 2004-10-20 23:45:32
|
Update of /cvsroot/gc-linux/htdocs/xml/en In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13956 Modified Files: news.xml Log Message: 21 October 2004, Latest kernel build updated to 2.6.9 Index: news.xml =================================================================== RCS file: /cvsroot/gc-linux/htdocs/xml/en/news.xml,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- news.xml 7 Oct 2004 20:43:44 -0000 1.23 +++ news.xml 20 Oct 2004 23:45:22 -0000 1.24 @@ -2,6 +2,11 @@ <?xml-stylesheet href="news.xsl" type="text/xsl"?> <news> <item> + <date>21 October 2004</date> + <title>Latest kernel build updated to 2.6.9</title> + <text>This latest release includes also new kexec functionality to load homebrew DOLs and a customized Linux logo. Available <a href="http://www.gc-linux.org/down/isobel/2.6.9/zImage-2.6.9.isobel.dol">here</a>.</text> + </item> + <item> <date>7 October 2004</date> <title>Build your own kernel, step by step</title> <text>Ever wanted to build a customized GameCube Linux kernel and didn't know where to start? Follow <a href="docs/building_a_kernel.html">this</a> guide.</text> |
From: <he...@us...> - 2004-10-20 22:48:20
|
Update of /cvsroot/gc-linux/linux/arch/ppc/configs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv979 Modified Files: gamecube_defconfig Log Message: By default, use new GameCube Linux logo. Index: gamecube_defconfig =================================================================== RCS file: /cvsroot/gc-linux/linux/arch/ppc/configs/gamecube_defconfig,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- gamecube_defconfig 20 Oct 2004 00:17:39 -0000 1.23 +++ gamecube_defconfig 20 Oct 2004 22:48:10 -0000 1.24 @@ -444,9 +444,10 @@ # Logo configuration # CONFIG_LOGO=y -CONFIG_LOGO_LINUX_MONO=y -CONFIG_LOGO_LINUX_VGA16=y -CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +CONFIG_LOGO_GAMECUBE_CLUT224=y # # Sound |
From: <he...@us...> - 2004-10-20 22:44:33
|
Update of /cvsroot/gc-linux/linux/drivers/video/logo In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32570/drivers/video/logo Added Files: Kconfig Makefile logo.c logo_gcn_clut224.ppm Log Message: Added a custom GameCube Linux logo. --- NEW FILE: Kconfig --- # # Logo configuration # menu "Logo configuration" config LOGO bool "Bootup logo" depends on FB || SGI_NEWPORT_CONSOLE config LOGO_LINUX_MONO bool "Standard black and white Linux logo" depends on LOGO default y config LOGO_LINUX_VGA16 bool "Standard 16-color Linux logo" depends on LOGO default y config LOGO_LINUX_CLUT224 bool "Standard 224-color Linux logo" depends on LOGO default y config LOGO_DEC_CLUT224 bool "224-color Digital Equipment Corporation Linux logo" depends on LOGO && DECSTATION default y config LOGO_GAMECUBE_CLUT224 bool "224-color GameCube Linux logo" depends on LOGO && GAMECUBE default y config LOGO_MAC_CLUT224 bool "224-color Macintosh Linux logo" depends on LOGO && MAC default y config LOGO_PARISC_CLUT224 bool "224-color PA-RISC Linux logo" depends on LOGO && PARISC default y config LOGO_SGI_CLUT224 bool "224-color SGI Linux logo" depends on LOGO && (SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS) default y config LOGO_SUN_CLUT224 bool "224-color Sun Linux logo" depends on LOGO && (SPARC || SPARC64) default y config LOGO_SUPERH_MONO bool "Black and white SuperH Linux logo" depends on LOGO && SUPERH default y config LOGO_SUPERH_VGA16 bool "16-color SuperH Linux logo" depends on LOGO && SUPERH default y config LOGO_SUPERH_CLUT224 bool "224-color SuperH Linux logo" depends on LOGO && SUPERH default y endmenu --- NEW FILE: Makefile --- # Makefile for the Linux logos obj-$(CONFIG_LOGO) += logo.o obj-$(CONFIG_LOGO_LINUX_MONO) += logo_linux_mono.o obj-$(CONFIG_LOGO_LINUX_VGA16) += logo_linux_vga16.o obj-$(CONFIG_LOGO_LINUX_CLUT224) += logo_linux_clut224.o obj-$(CONFIG_LOGO_DEC_CLUT224) += logo_dec_clut224.o obj-$(CONFIG_LOGO_GAMECUBE_CLUT224) += logo_gcn_clut224.o obj-$(CONFIG_LOGO_MAC_CLUT224) += logo_mac_clut224.o obj-$(CONFIG_LOGO_PARISC_CLUT224) += logo_parisc_clut224.o obj-$(CONFIG_LOGO_SGI_CLUT224) += logo_sgi_clut224.o obj-$(CONFIG_LOGO_SUN_CLUT224) += logo_sun_clut224.o obj-$(CONFIG_LOGO_SUPERH_MONO) += logo_superh_mono.o obj-$(CONFIG_LOGO_SUPERH_VGA16) += logo_superh_vga16.o obj-$(CONFIG_LOGO_SUPERH_CLUT224) += logo_superh_clut224.o # How to generate logo's # Use logo-cfiles to retreive list of .c files to be built logo-cfiles = $(notdir $(patsubst %.$(2), %.c, \ $(wildcard $(srctree)/$(src)/*$(1).$(2)))) # Mono logos extra-y += $(call logo-cfiles,_mono,pbm) quiet_cmd_logo_mono = MONO $@ cmd_logo_mono = scripts/pnmtologo -t mono -n $*_mono -o $@ $< $(obj)/%_mono.c: $(src)/%_mono.pbm FORCE $(call if_changed,logo_mono) # VGA16 logos extra-y += $(call logo-cfiles,_vga16,ppm) quiet_cmd_logo_vga16 = VGA16 $@ cmd_logo_vga16 = scripts/pnmtologo -t vga16 -n $*_vga16 -o $@ $< $(obj)/%_vga16.c: $(src)/%_vga16.ppm FORCE $(call if_changed,logo_vga16) #224 Logos extra-y += $(call logo-cfiles,_clut224,ppm) quiet_cmd_logo_clut224 = CLUT224 $@ cmd_logo_clut224 = scripts/pnmtologo -t clut224 -n $*_clut224 -o $@ $< $(obj)/%_clut224.c: $(src)/%_clut224.ppm FORCE $(call if_changed,logo_clut224) # Gray 256 extra-y += $(call logo-cfiles,_gray256,pgm) quiet_cmd_logo_gray256 = GRAY256 $@ cmd_logo_gray256 = scripts/pnmtologo -t gray256 -n $*_gray256 -o $@ $< $(obj)/%_gray256.c: $(src)/%_gray256.pgm FORCE $(call if_changed,logo_gray256) --- NEW FILE: logo.c --- /* * Linux logo to be displayed on boot * * Copyright (C) 1996 Larry Ewing (le...@is...) * Copyright (C) 1996,1998 Jakub Jelinek (jj...@su...) * Copyright (C) 2001 Greg Banks <gn...@al...> * Copyright (C) 2001 Jan-Benedict Glaw <jb...@lu...> * Copyright (C) 2003 Geert Uytterhoeven <ge...@li...> */ #include <linux/config.h> #include <linux/linux_logo.h> #include <linux/stddef.h> #ifdef CONFIG_M68K #include <asm/setup.h> #endif #ifdef CONFIG_MIPS #include <asm/bootinfo.h> #endif extern const struct linux_logo logo_linux_mono; extern const struct linux_logo logo_linux_vga16; extern const struct linux_logo logo_linux_clut224; extern const struct linux_logo logo_dec_clut224; extern const struct linux_logo logo_gcn_clut224; extern const struct linux_logo logo_mac_clut224; extern const struct linux_logo logo_parisc_clut224; extern const struct linux_logo logo_sgi_clut224; extern const struct linux_logo logo_sun_clut224; extern const struct linux_logo logo_superh_mono; extern const struct linux_logo logo_superh_vga16; extern const struct linux_logo logo_superh_clut224; const struct linux_logo *fb_find_logo(int depth) { const struct linux_logo *logo = NULL; if (depth >= 1) { #ifdef CONFIG_LOGO_LINUX_MONO /* Generic Linux logo */ logo = &logo_linux_mono; #endif #ifdef CONFIG_LOGO_SUPERH_MONO /* SuperH Linux logo */ logo = &logo_superh_mono; #endif } if (depth >= 4) { #ifdef CONFIG_LOGO_LINUX_VGA16 /* Generic Linux logo */ logo = &logo_linux_vga16; #endif #ifdef CONFIG_LOGO_SUPERH_VGA16 /* SuperH Linux logo */ logo = &logo_superh_vga16; #endif } if (depth >= 8) { #ifdef CONFIG_LOGO_LINUX_CLUT224 /* Generic Linux logo */ logo = &logo_linux_clut224; #endif #ifdef CONFIG_LOGO_DEC_CLUT224 /* DEC Linux logo on MIPS/MIPS64 */ if (mips_machgroup == MACH_GROUP_DEC) logo = &logo_dec_clut224; #endif #ifdef CONFIG_LOGO_GAMECUBE_CLUT224 /* GameCube Linux logo */ logo = &logo_gcn_clut224; #endif #ifdef CONFIG_LOGO_MAC_CLUT224 /* Macintosh Linux logo on m68k */ if (MACH_IS_MAC) logo = &logo_mac_clut224; #endif #ifdef CONFIG_LOGO_PARISC_CLUT224 /* PA-RISC Linux logo */ logo = &logo_parisc_clut224; #endif #ifdef CONFIG_LOGO_SGI_CLUT224 /* SGI Linux logo on MIPS/MIPS64 and VISWS */ #ifndef CONFIG_X86_VISWS if (mips_machgroup == MACH_GROUP_SGI) #endif logo = &logo_sgi_clut224; #endif #ifdef CONFIG_LOGO_SUN_CLUT224 /* Sun Linux logo */ logo = &logo_sun_clut224; #endif #ifdef CONFIG_LOGO_SUPERH_CLUT224 /* SuperH Linux logo */ logo = &logo_superh_clut224; #endif } return logo; } --- NEW FILE: logo_gcn_clut224.ppm --- P3 # CREATOR: The GIMP's PNM Filter Version 1.0 80 80 255 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 [...19165 lines suppressed...] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 |
From: <he...@us...> - 2004-10-20 22:40:36
|
Update of /cvsroot/gc-linux/linux/drivers/video/logo In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31580/logo Log Message: Directory /cvsroot/gc-linux/linux/drivers/video/logo added to the repository |
From: <he...@us...> - 2004-10-20 22:38:41
|
Update of /cvsroot/gc-linux/linux/drivers/video In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30842 Modified Files: gcnfb.c Log Message: Do not fill the whole framebuffer with background color. This is already done for us. Index: gcnfb.c =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/video/gcnfb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- gcnfb.c 20 Oct 2004 00:07:40 -0000 1.1 +++ gcnfb.c 20 Oct 2004 22:38:31 -0000 1.2 @@ -398,12 +398,6 @@ goto err_register_framebuffer; } - /* fill framebuffer memory with black color */ - int c = gcnfb_defined.xres * gcnfb_defined.yres / 2; - volatile unsigned long *p = (unsigned long *)gcnfb_info.screen_base; - while (c--) - writel(0x00800080, p++); - unsigned int *VIDEO_Mode; if (tv_encoding == TV_ENC_NTSC) |
From: <he...@us...> - 2004-10-20 00:17:49
|
Update of /cvsroot/gc-linux/linux/arch/ppc/configs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9536/arch/ppc/configs Modified Files: gamecube_defconfig Log Message: - Updated the default configuration. Index: gamecube_defconfig =================================================================== RCS file: /cvsroot/gc-linux/linux/arch/ppc/configs/gamecube_defconfig,v retrieving revision 1.22 retrieving revision 1.23 diff -u -d -r1.22 -r1.23 --- gamecube_defconfig 19 Oct 2004 09:46:08 -0000 1.22 +++ gamecube_defconfig 20 Oct 2004 00:17:39 -0000 1.23 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.9 -# Tue Oct 19 05:43:13 2004 +# Tue Oct 19 23:48:03 2004 # CONFIG_MMU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y @@ -98,10 +98,10 @@ # CONFIG_TQM8260 is not set # CONFIG_ADS8272 is not set # CONFIG_LITE5200 is not set -CONFIG_GAMECUBE_RESET_SWITCH=y -CONFIG_GAMECUBE_DVD_COVER=y -# CONFIG_SMP is not set # CONFIG_GAMECUBE_CONSOLE is not set +CONFIG_GAMECUBE_RESET=y +CONFIG_GAMECUBE_DVDCOVER=y +# CONFIG_SMP is not set # CONFIG_PREEMPT is not set # CONFIG_HIGHMEM is not set CONFIG_BINFMT_ELF=y @@ -273,7 +273,7 @@ # CONFIG_NET_ETHERNET=y # CONFIG_MII is not set -CONFIG_GAMECUBE_NET=y +CONFIG_GAMECUBE_BBA=y # # Ethernet (1000 Mbit) |
From: <he...@us...> - 2004-10-20 00:15:53
|
Update of /cvsroot/gc-linux/linux/sound/ppc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8301/sound/ppc Modified Files: Kconfig Makefile Added Files: gcn-ai.c Removed Files: gamecube.c Log Message: - Mainly cosmetic changes. Renamed gamecube.c to gcn-ai.c. - Sanitized a bit the exit function. - Stop the sample a little bit earlier. --- NEW FILE: gcn-ai.c --- /* * sound/ppc/gcn-ai.c * * Nintendo GameCube audio interface driver * Copyright (C) 2004 The GameCube Linux Team * * Based on work from mist, kirin, groepaz, Steve_-, isobel and others. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * */ /* #define AI_DEBUG */ #include <sound/driver.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/module.h> #include <linux/kernel.h> #include <sound/core.h> #include <sound/pcm.h> #define SNDRV_GET_ID #include <sound/initval.h> #ifdef AI_DEBUG # define DPRINTK(fmt, args...) \ printk(KERN_ERR "%s: " fmt, __FUNCTION__ , ## args) #else # define DPRINTK(fmt, args...) #endif #define DRV_MODULE_NAME "gcn-ai" #define DRV_DESCRIPTION "Nintendo GameCube Audio Interface driver" #define DRV_AUTHOR "me!" MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_AUTHOR(DRV_AUTHOR); MODULE_LICENSE(GPL); #define PFX DRV_MODULE_NAME ": " #define ai_printk(level, format, arg...) \ printk(level PFX format , ## arg) #define DSP_IRQ 6 #define AUDIO_DSP_CONTROL *(volatile u_int16_t *)(0xCC00500a) #define AI_CSR_RES (1<<0) #define AI_CSR_PIINT (1<<1) #define AI_CSR_HALT (1<<2) #define AI_CSR_AIDINT (1<<3) #define AI_CSR_AIDINTMASK (1<<4) #define AI_CSR_ARINT (1<<5) #define AI_CSR_ARINTMASK (1<<6) #define AI_CSR_DSPINT (1<<7) #define AI_CSR_DSPINTMASK (1<<8) #define AI_CSR_DSPDMA (1<<9) #define AI_CSR_RESETXXX (1<<11) #define AUDIO_IRQ_CAUSE *(volatile u_int16_t *)(0xCC005010) #define AUDIO_DMA_STARTH *(volatile u_int16_t *)(0xCC005030) #define AUDIO_DMA_STARTL *(volatile u_int16_t *)(0xCC005032) #define AUDIO_DMA_LENGTH *(volatile u_int16_t *)(0xCC005036) #define AI_DCL_PLAY (1<<15) #define AUDIO_DMA_LEFT *(volatile u_int16_t *)(0xCC00503a) #define AUDIO_STREAM_STATUS *(volatile u_int32_t *)(0xCC006C00) #define AI_AICR_RATE (1<<6) #define LoadSample(addr, len) \ AUDIO_DMA_STARTH = (addr >> 16) & 0xffff; \ AUDIO_DMA_STARTL = addr & 0xffff; \ AUDIO_DMA_LENGTH = (AUDIO_DMA_LENGTH & AI_DCL_PLAY) | (len >> 5) #define StartSample() AUDIO_DMA_LENGTH |= AI_DCL_PLAY #define StopSample() AUDIO_DMA_LENGTH &= ~AI_DCL_PLAY #define SetFreq32KHz() AUDIO_STREAM_STATUS |= AI_AICR_RATE #define SetFreq48KHz() AUDIO_STREAM_STATUS &= ~AI_AICR_RATE #define chip_t snd_gcn_t static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ typedef struct snd_gcn { snd_card_t *card; snd_pcm_t *pcm; snd_pcm_substream_t *playback_substream; snd_pcm_substream_t *capture_substream; spinlock_t reg_lock; int dma_size; int period_size; int nperiods; volatile int cur_period; volatile int start_play; volatile int stop_play; } snd_gcn_t; static snd_gcn_t *gcn_audio = NULL; static snd_pcm_hardware_t snd_gcn_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID), .formats = SNDRV_PCM_FMTBIT_S16_BE, .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000, .rate_min = 32000, .rate_max = 48000, .channels_min = 2, .channels_max = 2, .buffer_bytes_max = 32768, .period_bytes_min = 32, .period_bytes_max = 32768, .periods_min = 1, .periods_max = 1024, }; static int snd_gcn_open(snd_pcm_substream_t * substream) { snd_gcn_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; DPRINTK("pcm open\n"); chip->playback_substream = substream; runtime->hw = snd_gcn_playback; /* align to 32 bytes */ snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); return 0; } static int snd_gcn_close(snd_pcm_substream_t * substream) { snd_gcn_t *chip = snd_pcm_substream_chip(substream); DPRINTK("pcm close\n"); chip->playback_substream = NULL; return 0; } static int snd_gcn_hw_params(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * hw_params) { DPRINTK("snd_gcn_hw_params\n"); return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); } static int snd_gcn_hw_free(snd_pcm_substream_t * substream) { DPRINTK("snd_gcn_hw_free\n"); return snd_pcm_lib_free_pages(substream); } static int snd_gcn_prepare(snd_pcm_substream_t * substream) { /* snd_gcn_t *chip = snd_pcm_substream_chip(substream); */ snd_pcm_runtime_t *runtime = substream->runtime; DPRINTK("snd_gcn_prepare\n"); DPRINTK("prepare: rate=%i, channels=%i, sample_bits=%i\n", runtime->rate, runtime->channels, runtime->sample_bits); DPRINTK("prepare: format=%i, access=%i\n", runtime->format, runtime->access); /* set requested samplerate */ switch (runtime->rate) { case 32000: SetFreq32KHz(); break; case 48000: SetFreq48KHz(); break; default: DPRINTK("unsupported rate: %i!\n", runtime->rate); return -EINVAL; } return 0; } static int snd_gcn_trigger(snd_pcm_substream_t * substream, int cmd) { snd_gcn_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; DPRINTK("snd_gcn_trigger\n"); switch (cmd) { case SNDRV_PCM_TRIGGER_START: /* do something to start the PCM engine */ DPRINTK("PCM_TRIGGER_START\n"); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { chip->dma_size = snd_pcm_lib_buffer_bytes(substream); chip->period_size = snd_pcm_lib_period_bytes(substream); chip->nperiods = chip->dma_size / chip->period_size; chip->cur_period = 0; chip->stop_play = 0; chip->start_play = 1; DPRINTK("stream is PCM_PLAYBACK," " dma_area=0x%p dma_size=%i\n", runtime->dma_area, chip->dma_size); DPRINTK("%i periods of %i bytes\n", chip->nperiods, chip->period_size); flush_dcache_range((unsigned long)runtime->dma_area, (unsigned long)(runtime->dma_area + chip->period_size)); LoadSample((u_int32_t) runtime->dma_area, chip->period_size); StartSample(); } break; case SNDRV_PCM_TRIGGER_STOP: /* do something to stop the PCM engine */ DPRINTK("PCM_TRIGGER_STOP\n"); chip->stop_play = 1; /* StopSample(); */ break; default: return -EINVAL; } return 0; } static snd_pcm_uframes_t snd_gcn_pointer(snd_pcm_substream_t * substream) { snd_gcn_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; int left, bytes; DPRINTK("snd_gcn_pointer\n"); left = AUDIO_DMA_LEFT << 5; bytes = chip->period_size * (chip->cur_period + 1); /* bytes = snd_pcm_lib_buffer_bytes(substream); */ DPRINTK("pointer: %i of %i(%i) bytes left, period #%i\n", left, chip->period_size, bytes, chip->cur_period); return bytes_to_frames(runtime, bytes - left); } static irqreturn_t snd_gcn_interrupt(int irq, void *dev, struct pt_regs *regs) { snd_gcn_t *chip = (snd_gcn_t *) dev; unsigned short val = AUDIO_DSP_CONTROL; if (val & AI_CSR_AIDINT) { u_int32_t addr; DPRINTK("DSP interrupt! period #%i\n", chip->cur_period); if (chip->start_play) { chip->start_play = 0; } else if (chip->stop_play) { StopSample(); } else { StopSample(); if (chip->cur_period < (chip->nperiods - 1)) { chip->cur_period++; } else chip->cur_period = 0; addr = (u_int32_t) chip->playback_substream->runtime-> dma_area + (chip->cur_period * chip->period_size); flush_dcache_range(addr, addr + chip->period_size); LoadSample(addr, chip->period_size); StartSample(); /* chip->start_play = 1; */ snd_pcm_period_elapsed(chip->playback_substream); } /* ack AI DMA interrupt */ AUDIO_DSP_CONTROL |= AI_CSR_AIDINT; return IRQ_HANDLED; } return IRQ_NONE; } static snd_pcm_ops_t snd_gcn_playback_ops = { .open = snd_gcn_open, .close = snd_gcn_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_gcn_hw_params, .hw_free = snd_gcn_hw_free, .prepare = snd_gcn_prepare, .trigger = snd_gcn_trigger, .pointer = snd_gcn_pointer, }; static int __devinit snd_gcn_new_pcm(snd_gcn_t * chip) { snd_pcm_t *pcm; int err; if ((err = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm)) < 0) return err; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_gcn_playback_ops); /* snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_gcn_capture_ops); */ /* preallocate 64k buffer */ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, snd_dma_continuous_data (GFP_KERNEL), 64 * 1024, 64 * 1024); pcm->info_flags = 0; pcm->private_data = chip; strcpy(pcm->name, chip->card->shortname); chip->pcm = pcm; return 0; } static int __init alsa_card_gcn_init(void) { int err; snd_card_t *card; /* if (!is_gamecube()) return -ENODEV; */ /* register the soundcard */ card = snd_card_new(index, id, THIS_MODULE, sizeof(snd_gcn_t)); if (card == NULL) return -ENOMEM; gcn_audio = (snd_gcn_t *) card->private_data; if (gcn_audio == NULL) return -ENOMEM; memset(gcn_audio, 0, sizeof(snd_gcn_t)); gcn_audio->card = card; gcn_audio->stop_play = 1; strcpy(card->driver, "gcn-ai"); strcpy(card->shortname, card->driver); sprintf(card->longname, "Nintendo GameCube Audio Interface"); if (request_irq (DSP_IRQ, snd_gcn_interrupt, SA_SHIRQ, card->shortname, gcn_audio)) { snd_printk(KERN_ERR "%s: unable to grab IRQ %d\n", card->shortname, DSP_IRQ); return -EBUSY; } else { /* enable AI DMA interrupt */ AUDIO_DSP_CONTROL |= AI_CSR_AIDINTMASK; /* enable any DSP interrupts */ AUDIO_DSP_CONTROL |= AI_CSR_PIINT; } #if 0 if (request_region(AUDIO_INTERFACE_ADDR, 0x200, card->shortname) == NULL) { printk("unable to grab memory region 0x%lx-0x%lx\n", AUDIO_INTERFACE_ADDR, AUDIO_INTERFACE_ADDR + 0x200 - 1); return -EBUSY; } if ((iobase = (unsigned long)ioremap(AUDIO_INTERFACE_ADDR, 0x200)) == 0) { printk("unable to remap memory region 0x%lx-0x%lx\n", AUDIO_INTERFACE_ADDR, AUDIO_INTERFACE_ADDR + 0x200 - 1); return -ENOMEM; } printk("iobase=0x%lx\n", iobase); #endif #if 0 /* mixer */ if ((err = snd_gcn_mixer_new(gcn_audio)) < 0) goto fail; #endif /* PCM */ if ((err = snd_gcn_new_pcm(gcn_audio)) < 0) goto fail; if ((err = snd_card_register(card)) == 0) { ai_printk(KERN_INFO, "%s initialized\n", DRV_DESCRIPTION); return 0; } fail: snd_card_free(card); return err; } static void __exit alsa_card_gcn_exit(void) { DPRINTK("Goodbye, cruel world\n"); StopSample(); AUDIO_DSP_CONTROL &= ~AI_CSR_AIDINTMASK; free_irq(DSP_IRQ, gcn_audio); snd_card_free(gcn_audio->card); } module_init(alsa_card_gcn_init); module_exit(alsa_card_gcn_exit); Index: Kconfig =================================================================== RCS file: /cvsroot/gc-linux/linux/sound/ppc/Kconfig,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- Kconfig 19 Oct 2004 09:46:10 -0000 1.5 +++ Kconfig 20 Oct 2004 00:15:42 -0000 1.6 @@ -15,10 +15,11 @@ select SND_PCM config SND_GAMECUBE - tristate "GameCube audio" + tristate "Nintendo GameCube audio" depends on SND help - Say 'Y' or 'M' to include support for non-working looping random noise. + Say 'Y' or 'M' to include support for the Nintendo GameCube + audio system. endmenu Index: Makefile =================================================================== RCS file: /cvsroot/gc-linux/linux/sound/ppc/Makefile,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- Makefile 19 Oct 2004 09:46:10 -0000 1.2 +++ Makefile 20 Oct 2004 00:15:42 -0000 1.3 @@ -4,9 +4,8 @@ # snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o -snd-gamecube-objs := gamecube.o +snd-gcn-objs := gcn-ai.o # Toplevel Module Dependency obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o -obj-$(CONFIG_SND_GAMECUBE) += snd-gamecube.o - +obj-$(CONFIG_SND_GAMECUBE) += snd-gcn.o --- gamecube.c DELETED --- |
From: <he...@us...> - 2004-10-20 00:08:21
|
Update of /cvsroot/gc-linux/linux/include/linux In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6018/include/linux Modified Files: fb.h Log Message: - Lots of small cosmetic changes. - Renamed gamecubefb.c to gcnfb.c. - Renamed gc* code to gcn* code. - Fixed some compiler warnings related to the fb_writel hack. - Made use of GCN_XFB_START for setting up the start address of the fb. Index: fb.h =================================================================== RCS file: /cvsroot/gc-linux/linux/include/linux/fb.h,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- fb.h 19 Oct 2004 09:46:10 -0000 1.7 +++ fb.h 20 Oct 2004 00:07:41 -0000 1.8 @@ -660,7 +660,8 @@ #ifndef CONFIG_FB_GAMECUBE /* XXX Why? O' why? */ # define fb_writel __raw_writel #else -# define fb_writel(b,addr) gamecubefb_writel(b,addr) + extern unsigned int gcnfb_writel(unsigned int, void *); +# define fb_writel(b,addr) gcnfb_writel(b,addr) # define fb_writel_real(b,addr) /* __raw_writel */ (*(volatile u32 *) (addr) = (b)) #endif #define fb_writeq __raw_writeq |
From: <he...@us...> - 2004-10-20 00:08:21
|
Update of /cvsroot/gc-linux/linux/drivers/video In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6018/drivers/video Modified Files: Kconfig Makefile Added Files: gcnfb.c Removed Files: gamecubefb.c Log Message: - Lots of small cosmetic changes. - Renamed gamecubefb.c to gcnfb.c. - Renamed gc* code to gcn* code. - Fixed some compiler warnings related to the fb_writel hack. - Made use of GCN_XFB_START for setting up the start address of the fb. --- NEW FILE: gcnfb.c --- /* * drivers/video/gcnfb.c * * Nintendo GameCube "Flipper" chipset frame buffer driver * Copyright (C) 2004 Michael Steil <mi...@c6...> * Copyright (C) 2004 The GameCube Linux Team * * Based on vesafb (c) 1998 Gerd Knorr <kr...@go...> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/string.h> #include <linux/mm.h> #include <linux/tty.h> #include <linux/slab.h> #include <linux/delay.h> #include <linux/fb.h> #include <linux/ioport.h> #include <linux/init.h> #include <asm/io.h> #include <platforms/gamecube.h> #define DRV_MODULE_NAME "gcnfb" #define DRV_DESCRIPTION "Nintendo GameCube frame buffer driver" #define DRV_AUTHOR "Michael Steil <mi...@c6...>" MODULE_AUTHOR(DRV_AUTHOR); MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_LICENSE(GPL); volatile static unsigned int *gcn_video = (unsigned int *)0xCC002000; static const unsigned int VIDEO_Mode640X480NtscYUV16[32] = { 0x0F060001, 0x476901AD, 0x02EA5140, 0x00030018, 0x00020019, 0x410C410C, 0x40ED40ED, 0x00435A4E, 0x00000000, 0x00435A4E, 0x00000000, 0x00000000, 0x110701AE, 0x10010001, 0x00010001, 0x00010001, 0x00000000, 0x00000000, 0x28500100, 0x1AE771F0, 0x0DB4A574, 0x00C1188E, 0xC4C0CBE2, 0xFCECDECF, 0x13130F08, 0x00080C0F, 0x00FF0000, 0x00000000, 0x02800000, 0x000000FF, 0x00FF00FF, 0x00FF00FF }; static const unsigned int VIDEO_Mode640X480Pal50YUV16[32] = { 0x11F50101, 0x4B6A01B0, 0x02F85640, 0x00010023, 0x00000024, 0x4D2B4D6D, 0x4D8A4D4C, 0x00435A4E, 0x00000000, 0x00435A4E, 0x00000000, 0x013C0144, 0x113901B1, 0x10010001, 0x00010001, 0x00010001, 0x00000000, 0x00000000, 0x28500100, 0x1AE771F0, 0x0DB4A574, 0x00C1188E, 0xC4C0CBE2, 0xFCECDECF, 0x13130F08, 0x00080C0F, 0x00FF0000, 0x00000000, 0x02800000, 0x000000FF, 0x00FF00FF, 0x00FF00FF }; static struct fb_var_screeninfo gcnfb_defined __initdata = { .activate = FB_ACTIVATE_NOW, .height = -1, .width = -1, .right_margin = 32, .upper_margin = 16, .lower_margin = 4, .vsync_len = 4, .vmode = FB_VMODE_NONINTERLACED, }; static struct fb_fix_screeninfo gcnfb_fix __initdata = { .id = "gcnfb", .type = FB_TYPE_PACKED_PIXELS, .accel = FB_ACCEL_NONE, }; #define TV_ENC_DETECT 0 #define TV_ENC_NTSC 1 #define TV_ENC_PAL 2 static int tv_encoding __initdata = TV_ENC_DETECT; static struct fb_info gcnfb_info; static u32 pseudo_palette[17]; static int ypan = 0; /* 0..nothing, 1..ypan, 2..ywrap */ /* * RGB to YCbYCr conversion support bits. * We are using here the ITU.BT-601 Y'CbCr standard. * * References: * - "Colour Space Conversions" by Adrian Ford and Alan Roberts, 1998 * (google for coloureq.pdf) * */ #define RGB2YUV_SHIFT 16 #define RGB2YUV_LUMA 16 #define RGB2YUV_CHROMA 128 #define Yr ((int)( 0.299*(1<<RGB2YUV_SHIFT))) #define Yg ((int)( 0.587*(1<<RGB2YUV_SHIFT))) #define Yb ((int)( 0.114*(1<<RGB2YUV_SHIFT))) #define Ur ((int)(-0.169*(1<<RGB2YUV_SHIFT))) #define Ug ((int)(-0.331*(1<<RGB2YUV_SHIFT))) #define Ub ((int)( 0.500*(1<<RGB2YUV_SHIFT))) #define Vr ((int)( 0.500*(1<<RGB2YUV_SHIFT))) /* same as Ub */ #define Vg ((int)(-0.419*(1<<RGB2YUV_SHIFT))) #define Vb ((int)(-0.081*(1<<RGB2YUV_SHIFT))) #define clamp(x, y, z) ((z < x) ? x : ((z > y) ? y : z)) static inline uint32_t rgbrgb16toycbycr(uint16_t rgb1, uint16_t rgb2) { register int Y1, Cb, Y2, Cr; register int r1, g1, b1; register int r2, g2, b2; register int r, g, b; /* fast path, thanks to bohdy */ if (!(rgb1 | rgb2)) { return 0x00800080; /* black, black */ } /* RGB565 */ r1 = ((rgb1 >> 11) & 0x1f); g1 = ((rgb1 >> 5) & 0x3f); b1 = ((rgb1 >> 0) & 0x1f); /* fast (approximated) scaling to 8 bits, thanks to Masken */ r1 = (r1 << 3) | (r1 >> 2); g1 = (g1 << 2) | (g1 >> 4); b1 = (b1 << 3) | (b1 >> 2); Y1 = clamp(16, 235, ((Yr * r1 + Yg * g1 + Yb * b1) >> RGB2YUV_SHIFT) + RGB2YUV_LUMA); if (rgb1 == rgb2) { /* this is just another fast path */ Y2 = Y1; r = r1; g = g1; b = b1; } else { /* same as we did for r1 before */ r2 = ((rgb2 >> 11) & 0x1f); g2 = ((rgb2 >> 5) & 0x3f); b2 = ((rgb2 >> 0) & 0x1f); r2 = (r2 << 3) | (r2 >> 2); g2 = (g2 << 2) | (g2 >> 4); b2 = (b2 << 3) | (b2 >> 2); Y2 = clamp(16, 235, ((Yr * r2 + Yg * g2 + Yb * b2) >> RGB2YUV_SHIFT) + RGB2YUV_LUMA); r = (r1 + r2) / 2; g = (g1 + g2) / 2; b = (b1 + b2) / 2; } Cb = clamp(16, 240, ((Ur * r + Ug * g + Ub * b) >> RGB2YUV_SHIFT) + RGB2YUV_CHROMA); Cr = clamp(16, 240, ((Vr * r + Vg * g + Vb * b) >> RGB2YUV_SHIFT) + RGB2YUV_CHROMA); return (((uint8_t) Y1) << 24) | (((uint8_t) Cb) << 16) | (((uint8_t) Y2) << 8) | (((uint8_t) Cr) << 0); } unsigned int gcnfb_writel(unsigned int rgbrgb, void *address) { uint16_t *rgb = (uint16_t *) & rgbrgb; return fb_writel_real(rgbrgb16toycbycr(rgb[0], rgb[1]), address); } static int gcnfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { return 0; } static void vesa_setpalette(int regno, unsigned red, unsigned green, unsigned blue) { } static int gcnfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) { /* * Set a single color register. The values supplied are * already rounded down to the hardware's capabilities * (according to the entries in the `var' structure). Return * != 0 for invalid regno. */ if (regno >= info->cmap.len) return 1; switch (info->var.bits_per_pixel) { case 8: vesa_setpalette(regno, red, green, blue); break; case 15: case 16: if (info->var.red.offset == 10) { /* XXX, not used currently */ /* 1:5:5:5 */ ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800) >> 1) | ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11); } else { /* 0:5:6:5 */ ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); } break; case 24: case 32: /* XXX, not used currently */ red >>= 8; green >>= 8; blue >>= 8; ((u32 *) (info->pseudo_palette))[regno] = (red << info->var.red.offset) | (green << info->var.green.offset) | (blue << info->var.blue.offset); break; } return 0; } static struct fb_ops gcnfb_ops = { .owner = THIS_MODULE, .fb_setcolreg = gcnfb_setcolreg, .fb_pan_display = gcnfb_pan_display, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_cursor = soft_cursor, }; int __init gcnfb_setup(char *options) { char *this_opt; if (!options || !*options) return 0; printk("gcnfb: options = %s\n", options); while ((this_opt = strsep(&options, ",")) != NULL) { printk("this_opt = %s\n", this_opt); if (!*this_opt) continue; if (!strcmp(this_opt, "redraw")) ypan = 0; else if (!strcmp(this_opt, "ypan")) ypan = 1; else if (!strcmp(this_opt, "ywrap")) ypan = 2; else if (!strncmp(this_opt, "tv=", 3)) { printk("detected \"tv=\"\n"); printk("cmd line: %s\n", this_opt); if (!strncmp(this_opt + 3, "PAL", 3)) tv_encoding = TV_ENC_PAL; else if (!strncmp(this_opt + 3, "NTSC", 4)) tv_encoding = TV_ENC_NTSC; } } return 0; } int __init gcnfb_init(void) { int video_cmap_len; int i; int err = 0; char *option = NULL; if (fb_get_options("gcnfb", &option)) { if (fb_get_options("gamecubefb", &option)) return -ENODEV; } gcnfb_setup(option); /* detect current video mode */ if (tv_encoding == TV_ENC_DETECT) { tv_encoding = ((gcn_video[0] >> 8) & 3) + 1; } gcnfb_defined.bits_per_pixel = 16; gcnfb_defined.xres = 640; gcnfb_defined.yres = (tv_encoding == TV_ENC_NTSC) ? 480 : 576; gcnfb_fix.line_length = gcnfb_defined.xres * (gcnfb_defined.bits_per_pixel / 8); gcnfb_fix.smem_len = gcnfb_fix.line_length * gcnfb_defined.yres; gcnfb_fix.smem_start = GCN_XFB_START; gcnfb_fix.visual = (gcnfb_defined.bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; if (!request_mem_region (gcnfb_fix.smem_start, gcnfb_fix.smem_len, "gcnfb")) { printk(KERN_WARNING "gcnfb: abort, cannot reserve video memory at %p\n", (void *)gcnfb_fix.smem_start); /* We cannot make this fatal. Sometimes this comes from magic spaces our resource handlers simply don't know about */ } gcnfb_info.screen_base = ioremap(gcnfb_fix.smem_start, gcnfb_fix.smem_len); if (!gcnfb_info.screen_base) { printk(KERN_ERR "gcnfb: abort, cannot ioremap video memory" " at %p (%dk)\n", (void *)gcnfb_fix.smem_start, gcnfb_fix.smem_len / 1024); err = -EIO; goto err_ioremap; } printk(KERN_INFO "gcnfb: framebuffer at 0x%p, mapped to 0x%p, size %dk\n", (void *)gcnfb_fix.smem_start, gcnfb_info.screen_base, gcnfb_fix.smem_len / 1024); printk(KERN_INFO "gcnfb: mode is %dx%dx%d, linelength=%d, pages=%d\n", gcnfb_defined.xres, gcnfb_defined.yres, gcnfb_defined.bits_per_pixel, gcnfb_fix.line_length, 0 /*screen_info.pages */ ); gcnfb_defined.xres_virtual = gcnfb_defined.xres; gcnfb_defined.yres_virtual = gcnfb_defined.yres; ypan = 0; /* FIXME! Please, use here *real* values */ /* some dummy values for timing to make fbset happy */ gcnfb_defined.pixclock = 10000000 / gcnfb_defined.xres * 1000 / gcnfb_defined.yres; gcnfb_defined.left_margin = (gcnfb_defined.xres / 8) & 0xf8; gcnfb_defined.hsync_len = (gcnfb_defined.xres / 8) & 0xf8; if (gcnfb_defined.bits_per_pixel == 15) { gcnfb_defined.red.offset = 11; gcnfb_defined.red.length = 5; gcnfb_defined.green.offset = 6; gcnfb_defined.green.length = 5; gcnfb_defined.blue.offset = 1; gcnfb_defined.blue.length = 5; gcnfb_defined.transp.offset = 15; gcnfb_defined.transp.length = 1; video_cmap_len = 16; } else if (gcnfb_defined.bits_per_pixel == 16) { gcnfb_defined.red.offset = 11; gcnfb_defined.red.length = 5; gcnfb_defined.green.offset = 5; gcnfb_defined.green.length = 6; gcnfb_defined.blue.offset = 0; gcnfb_defined.blue.length = 5; gcnfb_defined.transp.offset = 0; gcnfb_defined.transp.length = 0; video_cmap_len = 16; } else { gcnfb_defined.red.length = 6; gcnfb_defined.green.length = 6; gcnfb_defined.blue.length = 6; video_cmap_len = 256; } gcnfb_fix.ypanstep = ypan ? 1 : 0; gcnfb_fix.ywrapstep = (ypan > 1) ? 1 : 0; gcnfb_info.fbops = &gcnfb_ops; gcnfb_info.var = gcnfb_defined; gcnfb_info.fix = gcnfb_fix; gcnfb_info.pseudo_palette = pseudo_palette; gcnfb_info.flags = FBINFO_FLAG_DEFAULT; if (fb_alloc_cmap(&gcnfb_info.cmap, video_cmap_len, 0)) { err = -ENOMEM; goto err_alloc_cmap; } if (register_framebuffer(&gcnfb_info) < 0) { err = -EINVAL; goto err_register_framebuffer; } /* fill framebuffer memory with black color */ int c = gcnfb_defined.xres * gcnfb_defined.yres / 2; volatile unsigned long *p = (unsigned long *)gcnfb_info.screen_base; while (c--) writel(0x00800080, p++); unsigned int *VIDEO_Mode; if (tv_encoding == TV_ENC_NTSC) VIDEO_Mode = (unsigned int *)VIDEO_Mode640X480NtscYUV16; else VIDEO_Mode = (unsigned int *)VIDEO_Mode640X480Pal50YUV16; /* initialize video registers */ for (i = 0; i < 7; i++) { gcn_video[i] = VIDEO_Mode[i]; } gcn_video[8] = VIDEO_Mode[8]; for (i = 10; i < 32; i++) { gcn_video[i] = VIDEO_Mode[i]; } gcn_video[7] = 0x10000000 | (gcnfb_fix.smem_start >> 5); /* * setting both fields to same source means half the resolution, but * reduces flickering a lot ...mmmh maybe worth a try as a last resort :/ * gcn_video[9] = 0x10000000 | (gcnfb_fix.smem_start>>5); * */ gcn_video[9] = 0x10000000 | ((gcnfb_fix.smem_start + gcnfb_fix.line_length) >> 5); printk(KERN_INFO "fb%d: %s frame buffer device\n", gcnfb_info.node, gcnfb_info.fix.id); goto out; err_register_framebuffer: fb_dealloc_cmap(&gcnfb_info.cmap); err_alloc_cmap: iounmap(gcnfb_info.screen_base); err_ioremap: release_mem_region(gcnfb_fix.smem_start, gcnfb_fix.smem_len); out: return err; } static void __exit gcnfb_exit(void) { unregister_framebuffer(&gcnfb_info); fb_dealloc_cmap(&gcnfb_info.cmap); iounmap(gcnfb_info.screen_base); release_mem_region(gcnfb_fix.smem_start, gcnfb_fix.smem_len); } module_init(gcnfb_init); module_exit(gcnfb_exit); Index: Kconfig =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/video/Kconfig,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- Kconfig 19 Oct 2004 09:46:09 -0000 1.9 +++ Kconfig 20 Oct 2004 00:07:40 -0000 1.10 @@ -858,10 +858,10 @@ and maybe other boards. config FB_GAMECUBE - bool "GameCube frame buffer support" + bool "Nintendo GameCube frame buffer" depends on FB && GAMECUBE help - GameCube frame buffer + This is the frame buffer device driver for the Nintendo GameCube. config FB_SBUS bool "SBUS and UPA framebuffers" Index: Makefile =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/video/Makefile,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- Makefile 19 Oct 2004 09:46:09 -0000 1.8 +++ Makefile 20 Oct 2004 00:07:40 -0000 1.9 @@ -89,7 +89,8 @@ obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_PXA) += pxafb.o cfbimgblt.o cfbcopyarea.o cfbfillrect.o -obj-$(CONFIG_FB_GAMECUBE) += gamecubefb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o +obj-$(CONFIG_FB_GAMECUBE) += gcnfb.o cfbfillrect.o cfbcopyarea.o \ + cfbimgblt.o # Platform or fallback drivers go here obj-$(CONFIG_FB_VESA) += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o --- gamecubefb.c DELETED --- |
From: <he...@us...> - 2004-10-20 00:01:27
|
Update of /cvsroot/gc-linux/linux/drivers/net In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4504/drivers/net Modified Files: Kconfig Makefile Added Files: gcn-bba.c Removed Files: gc-net.c Log Message: - Lots of cosmetic changes. - Renamed gc-net.c to gcn-bba.c. - Removed the low level EXI code from the driver and made use of the gcn-exi-lite framework. --- NEW FILE: gcn-bba.c --- /** * drivers/net/gcn-bba.c * * Nintendo GameCube Broadband Adapter driver * Copyright (C) 2004 Albert Herranz * Copyright (C) 2004 The GameCube Linux Team * * Based on previous work by Stefan Esser, Franz Lehner, Costis and tmbinc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * */ #define BBA_DEBUG #include <linux/config.h> [...1022 lines suppressed...] /* only one should call exi_lite_init()/exi_lite_exit() */ exi_lite_init(); ret = bba_probe(); return ret; } /** * */ static void __exit bba_exit_module(void) { unregister_netdev(bba_dev); exi_lite_exit(); } module_init(bba_init_module); module_exit(bba_exit_module); Index: Kconfig =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/net/Kconfig,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- Kconfig 19 Oct 2004 09:46:09 -0000 1.9 +++ Kconfig 20 Oct 2004 00:01:16 -0000 1.10 @@ -198,11 +198,11 @@ source "drivers/net/arm/Kconfig" -config GAMECUBE_NET - bool "GameCube Network Driver" - depends on NET_ETHERNET && GAMECUBE - ---help--- - GameCube Broadband Adapter 10/100 Ethernet support. +config GAMECUBE_BBA + bool "Nintendo GameCube BroadBand Adapter network driver" + depends on NET_ETHERNET && GAMECUBE && EXI + help + Nintendo GameCube Broadband Adapter 10/100 Ethernet support. config MACE tristate "MACE (Power Mac ethernet) support" Index: Makefile =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/net/Makefile,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- Makefile 19 Oct 2004 09:46:09 -0000 1.9 +++ Makefile 20 Oct 2004 00:01:17 -0000 1.10 @@ -182,7 +182,7 @@ obj-$(CONFIG_S2IO) += s2io.o obj-$(CONFIG_SMC91X) += smc91x.o obj-$(CONFIG_FEC_8XX) += fec_8xx/ -obj-$(CONFIG_GAMECUBE_NET) += gc-net.o +obj-$(CONFIG_GAMECUBE_BBA) += gcn-bba.o obj-$(CONFIG_ARM) += arm/ obj-$(CONFIG_NET_FC) += fc/ --- gc-net.c DELETED --- |