Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 45100 | Differences between
and this patch

Collapse All | Expand All

(-)linux-2.6.5.orig/Makefile (-1 / +1 lines)
Lines 1-7 Link Here
1
VERSION = 2
1
VERSION = 2
2
PATCHLEVEL = 6
2
PATCHLEVEL = 6
3
SUBLEVEL = 5
3
SUBLEVEL = 5
4
EXTRAVERSION =
4
EXTRAVERSION = -xbox
5
NAME=Zonked Quokka
5
NAME=Zonked Quokka
6
6
7
# *DOCUMENTATION*
7
# *DOCUMENTATION*
(-)linux-2.6.5.orig/arch/i386/Kconfig (-2 / +22 lines)
Lines 52-57 Link Here
52
52
53
	  If unsure, choose "PC-compatible" instead.
53
	  If unsure, choose "PC-compatible" instead.
54
54
55
config X86_XBOX
56
	bool "Microsoft Xbox"
57
	help
58
	  This option is needed to make Linux boot on XBox Gaming Systems.
59
	
60
	  The XBox can be considered as a standard PC with a Coppermine-based Celeron 733 MHz,
61
	  IDE harddrive, DVD, Ethernet, USB and graphics.
62
	
63
	  To boot the kernel you need "_romwell", either used as a replacement BIOS (cromwell)
64
	  or as a bootloader.
65
	
66
	  For more information see http://xbox-linux.sourceforge.net/
67
	
68
	  If you do not specifically need a kernel for XBOX machine,
69
	  say N here otherwise the kernel you build will not be bootable.
70
55
config X86_VOYAGER
71
config X86_VOYAGER
56
	bool "Voyager (NCR)"
72
	bool "Voyager (NCR)"
57
	help
73
	help
Lines 517-522 Link Here
517
	  If you have a system with several CPUs, you do not need to say Y
533
	  If you have a system with several CPUs, you do not need to say Y
518
	  here: the IO-APIC will be used automatically.
534
	  here: the IO-APIC will be used automatically.
519
535
536
config XBOX_EJECT
537
	bool "XBOX eject fix"
538
	depends on X86_XBOX
539
520
config X86_LOCAL_APIC
540
config X86_LOCAL_APIC
521
	bool
541
	bool
522
	depends on !SMP && X86_UP_APIC
542
	depends on !SMP && X86_UP_APIC
Lines 1142-1148 Link Here
1142
1162
1143
config MCA
1163
config MCA
1144
	bool "MCA support"
1164
	bool "MCA support"
1145
	depends on !(X86_VISWS || X86_VOYAGER)
1165
	depends on !(X86_VISWS || X86_VOYAGER || X86_XBOX)
1146
	help
1166
	help
1147
	  MicroChannel Architecture is found in some IBM PS/2 machines and
1167
	  MicroChannel Architecture is found in some IBM PS/2 machines and
1148
	  laptops.  It is a bus system similar to PCI or ISA. See
1168
	  laptops.  It is a bus system similar to PCI or ISA. See
Lines 1320-1326 Link Here
1320
1340
1321
config X86_BIOS_REBOOT
1341
config X86_BIOS_REBOOT
1322
	bool
1342
	bool
1323
	depends on !(X86_VISWS || X86_VOYAGER)
1343
	depends on !(X86_VISWS || X86_VOYAGER || X86_XBOX)
1324
	default y
1344
	default y
1325
1345
1326
config X86_TRAMPOLINE
1346
config X86_TRAMPOLINE
(-)linux-2.6.5.orig/arch/i386/Makefile (+4 lines)
Lines 65-70 Link Here
65
# Default subarch .c files
65
# Default subarch .c files
66
mcore-y  := mach-default
66
mcore-y  := mach-default
67
67
68
# Xbox subarch support
69
mflags-$(CONFIG_X86_XBOX)	:= -Iinclude/asm-i386/mach-xbox
70
mcore-$(CONFIG_X86_XBOX)	:= mach-xbox
71
68
# Voyager subarch support
72
# Voyager subarch support
69
mflags-$(CONFIG_X86_VOYAGER)	:= -Iinclude/asm-i386/mach-voyager
73
mflags-$(CONFIG_X86_VOYAGER)	:= -Iinclude/asm-i386/mach-voyager
70
mcore-$(CONFIG_X86_VOYAGER)	:= mach-voyager
74
mcore-$(CONFIG_X86_VOYAGER)	:= mach-voyager
(-)linux-2.6.5.orig/arch/i386/boot/compressed/Makefile (+11 lines)
Lines 5-10 Link Here
5
#
5
#
6
6
7
targets		:= vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
7
targets		:= vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
8
9
#
10
# There is some strange interaction when paging is off, that makes
11
# newer v1.1+ Xboxen (manufactured August 2002 or later) crash while
12
# decrompressing the kernel. Compiling the decrompressor without any
13
# optimization reliably works around this problem.
14
#
15
ifeq ($(CONFIG_X86_XBOX),y)
16
CFLAGS_misc.o	:= -O0
17
endif
18
8
EXTRA_AFLAGS	:= -traditional
19
EXTRA_AFLAGS	:= -traditional
9
20
10
LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32
21
LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32
(-)linux-2.6.5.orig/arch/i386/kernel/Makefile (+1 lines)
Lines 25-30 Link Here
25
obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
25
obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
26
obj-$(CONFIG_X86_NUMAQ)		+= numaq.o
26
obj-$(CONFIG_X86_NUMAQ)		+= numaq.o
27
obj-$(CONFIG_X86_SUMMIT_NUMA)	+= summit.o
27
obj-$(CONFIG_X86_SUMMIT_NUMA)	+= summit.o
28
obj-$(CONFIG_XBOX_EJECT)        += xboxejectfix.o
28
obj-$(CONFIG_MODULES)		+= module.o
29
obj-$(CONFIG_MODULES)		+= module.o
29
obj-y				+= sysenter.o vsyscall.o
30
obj-y				+= sysenter.o vsyscall.o
30
obj-$(CONFIG_ACPI_SRAT) 	+= srat.o
31
obj-$(CONFIG_ACPI_SRAT) 	+= srat.o
(-)linux-2.6.5.orig/arch/i386/kernel/xboxejectfix.c (+147 lines)
Line 0 Link Here
1
/**
2
 * Driver that handles the EXTSMI# interrupt on the xbox.
3
 * Makes it possible to use the eject-button without the xbox rebooting...
4
 *
5
 * smbus-command sequence to prevent reboot from cromwell.
6
 *
7
 * Changelog:
8
 *  2003-01-14 Anders Gustafsson <andersg@0x63.nu>
9
 *             initial version
10
 *  2003-02-08 Milosch Meriac <xboxlinux@meriac.de>
11
 *             rewrote debug macros because of compiler errors
12
 *  2003-08-06 Michael Steil <mist@c64.org>
13
 *             removed Linux I2C dependency, now compiles
14
 *             without I2C in the kernel
15
 *
16
 * Todo: add errorhandling!
17
 *
18
 */
19
20
#include <linux/kernel.h>
21
#include <linux/module.h>
22
#include <linux/init.h>
23
#include <asm/io.h>
24
#include <linux/xbox.h>
25
#include <linux/interrupt.h>
26
27
#define IRQ 12
28
#define DRIVER_NAME "xboxejectfix"
29
30
/* just some crap */
31
static char dev[]=DRIVER_NAME;
32
33
/* External variable from ide-cd.c that specifies whether we simulate drive
34
   locking in software */
35
extern volatile int Xbox_simulate_drive_locked;
36
37
#define BASE 0x8000
38
39
/* Power Management 1 Enable Register */
40
#define PM02 (BASE+0x02)
41
42
/* Power Management 1 Control Register */
43
#define PM04 (BASE+0x04)
44
45
/* ACPI GP Status Register */
46
#define PM20 (BASE+0x20)
47
48
/* ACPI GP Enable Register */
49
#define PM22 (BASE+0x22)
50
# define EXTSMI_EN_MASK 0x0002
51
52
/* Global SMI Enable Register */
53
#define PM2A (BASE+0x2A)
54
55
56
static DECLARE_MUTEX(extsmi_sem);
57
static DECLARE_COMPLETION(extsmi_exited);
58
static int extsmi_pid=0;
59
60
static irqreturn_t extsmi_interupt(int unused, void *dev_id, struct pt_regs *regs) {
61
	int reason;
62
63
	reason=inw(0x8020);
64
	outw(reason,0x8020); /* ack  IS THIS NEEDED? */
65
	if(reason&0x2){
66
		/* wake up thread */
67
		up(&extsmi_sem);
68
	}
69
	return 0;
70
}
71
72
/**
73
 * Process an event. This is run in process-context.
74
 */
75
static void extsmi_process(void){
76
	int reason;
77
	reason=Xbox_SMC_read(SMC_CMD_INTERRUPT_REASON);
78
79
	if(reason&TRAYBUTTON_MASK){ /* Tray button! Respond to prevent reboot! */
80
		Xbox_SMC_write(SMC_CMD_INTERRUPT_RESPOND, SMC_SUBCMD_RESPOND_CONTINUE);
81
		Xbox_SMC_write(0x00, 0x0c);
82
		/* eject unless lock simulation is being used */
83
		if (!Xbox_simulate_drive_locked)
84
			Xbox_tray_eject();
85
	}
86
}
87
88
static int extsmi_thread(void *data){
89
	daemonize("extsmi");
90
	reparent_to_init();
91
	strcpy(current->comm, "xbox_extsmi");
92
93
	do {
94
		extsmi_process();
95
		down_interruptible(&extsmi_sem);
96
	} while (!signal_pending(current));
97
	
98
         complete_and_exit(&extsmi_exited, 0);
99
}
100
101
static int extsmi_init(void){
102
	int pid;
103
	
104
	if (!machine_is_xbox) {
105
		printk("This machine is no Xbox.\n");
106
		return -1;
107
	}
108
	printk("Enabling Xbox eject problem workaround.\n");
109
110
        pid = kernel_thread(extsmi_thread, NULL,
111
			    CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
112
	if (pid < 0) {
113
		return pid;
114
	}
115
116
	extsmi_pid = pid;
117
118
	/* this shuts a lot of interrupts off! */
119
	outw(inw(0x80e2)&0xf8c7,0x80e2);
120
	outw(0,0x80ac);
121
	outb(0,0x8025);
122
	outw(EXTSMI_EN_MASK,PM22); /* enable the EXTSMI# interupt! */
123
	outw(0,PM02);
124
	outb(1,PM04); /* enable sci interrupts! */
125
	Xbox_SMC_write(SMC_CMD_RESET_ON_EJECT, SMC_SUBCMD_RESET_ON_EJECT_DISABLE);
126
127
	/* FIXME! retval! */
128
	request_irq(IRQ,extsmi_interupt,SA_INTERRUPT|SA_SHIRQ,"xboxejectfix",dev);
129
	return 0;
130
}
131
132
static void extsmi_exit(void){
133
	int res;
134
	if (!machine_is_xbox) return; /* can this happen??? */
135
	free_irq(IRQ,dev);
136
137
	/* Kill the thread */
138
	res = kill_proc(extsmi_pid, SIGTERM, 1);
139
	wait_for_completion(&extsmi_exited);
140
	return;
141
}
142
143
module_init(extsmi_init);
144
module_exit(extsmi_exit);
145
146
MODULE_AUTHOR("Anders Gustafsson <andersg@0x63.nu>");
147
MODULE_LICENSE("GPL");
(-)linux-2.6.5.orig/arch/i386/mach-xbox/Makefile (+5 lines)
Line 0 Link Here
1
#
2
# Makefile for the linux kernel.
3
#
4
5
obj-y				:= setup.o reboot.o
(-)linux-2.6.5.orig/arch/i386/mach-xbox/reboot.c (+51 lines)
Line 0 Link Here
1
/*
2
 * arch/i386/mach-xbox/reboot.c 
3
 * Olivier Fauchon <olivier.fauchon@free.fr>
4
 * Anders Gustafsson <andersg@0x63.nu>
5
 *
6
 */
7
8
#include <asm/io.h>
9
10
/* we don't use any of those, but dmi_scan.c needs 'em */
11
void (*pm_power_off)(void);
12
int reboot_thru_bios;
13
14
#define XBOX_SMB_IO_BASE		0xC000
15
#define XBOX_SMB_HOST_ADDRESS		(0x4 + XBOX_SMB_IO_BASE)
16
#define XBOX_SMB_HOST_COMMAND		(0x8 + XBOX_SMB_IO_BASE)
17
#define XBOX_SMB_HOST_DATA		(0x6 + XBOX_SMB_IO_BASE)
18
#define XBOX_SMB_GLOBAL_ENABLE		(0x2 + XBOX_SMB_IO_BASE)
19
20
#define XBOX_PIC_ADDRESS		0x10
21
22
#define SMC_CMD_POWER			0x02
23
#define SMC_SUBCMD_POWER_RESET		0x01
24
#define SMC_SUBCMD_POWER_CYCLE		0x40
25
#define SMC_SUBCMD_POWER_OFF		0x80
26
27
28
static void xbox_pic_cmd(u8 command)
29
{
30
	outw_p(((XBOX_PIC_ADDRESS) << 1), XBOX_SMB_HOST_ADDRESS);
31
	outb_p(SMC_CMD_POWER, XBOX_SMB_HOST_COMMAND);
32
	outw_p(command, XBOX_SMB_HOST_DATA);
33
	outw_p(inw(XBOX_SMB_IO_BASE), XBOX_SMB_IO_BASE);
34
	outb_p(0x0a, XBOX_SMB_GLOBAL_ENABLE);
35
}
36
37
void machine_restart(char * __unused)
38
{
39
	printk(KERN_INFO "Sending POWER_CYCLE to XBOX-PIC.\n");
40
	xbox_pic_cmd(SMC_SUBCMD_POWER_CYCLE);  
41
}
42
43
void machine_power_off(void)
44
{
45
	printk(KERN_INFO "Sending POWER_OFF to XBOX-PIC.\n");
46
	xbox_pic_cmd(SMC_SUBCMD_POWER_OFF);  
47
}
48
49
void machine_halt(void)
50
{
51
}
(-)linux-2.6.5.orig/arch/i386/mach-xbox/setup.c (+84 lines)
Line 0 Link Here
1
/*
2
 *	Machine specific setup for xbox
3
 */
4
5
#include <linux/config.h>
6
#include <linux/smp.h>
7
#include <linux/init.h>
8
#include <linux/irq.h>
9
#include <linux/interrupt.h>
10
#include <asm/arch_hooks.h>
11
12
/**
13
 * pre_intr_init_hook - initialisation prior to setting up interrupt vectors
14
 *
15
 * Description:
16
 *	Perform any necessary interrupt initialisation prior to setting up
17
 *	the "ordinary" interrupt call gates.  For legacy reasons, the ISA
18
 *	interrupts should be initialised here if the machine emulates a PC
19
 *	in any way.
20
 **/
21
void __init pre_intr_init_hook(void)
22
{
23
	init_ISA_irqs();
24
}
25
26
/*
27
 * IRQ2 is cascade interrupt to second interrupt controller
28
 */
29
static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL };
30
31
/**
32
 * intr_init_hook - post gate setup interrupt initialisation
33
 *
34
 * Description:
35
 *	Fill in any interrupts that may have been left out by the general
36
 *	init_IRQ() routine.  interrupts having to do with the machine rather
37
 *	than the devices on the I/O bus (like APIC interrupts in intel MP
38
 *	systems) are started here.
39
 **/
40
void __init intr_init_hook(void)
41
{
42
#ifdef CONFIG_X86_LOCAL_APIC
43
	apic_intr_init();
44
#endif
45
46
	setup_irq(2, &irq2);
47
}
48
49
/**
50
 * pre_setup_arch_hook - hook called prior to any setup_arch() execution
51
 *
52
 * Description:
53
 *	generally used to activate any machine specific identification
54
 *	routines that may be needed before setup_arch() runs.  On VISWS
55
 *	this is used to get the board revision and type.
56
 **/
57
void __init pre_setup_arch_hook(void)
58
{
59
}
60
61
/**
62
 * trap_init_hook - initialise system specific traps
63
 *
64
 * Description:
65
 *	Called as the final act of trap_init().  Used in VISWS to initialise
66
 *	the various board specific APIC traps.
67
 **/
68
void __init trap_init_hook(void)
69
{
70
}
71
72
static struct irqaction irq0  = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL };
73
74
/**
75
 * time_init_hook - do any specific initialisations for the system timer.
76
 *
77
 * Description:
78
 *	Must plug the system timer interrupt source at HZ into the IRQ listed
79
 *	in irq_vectors.h:TIMER_IRQ
80
 **/
81
void __init time_init_hook(void)
82
{
83
	setup_irq(0, &irq0);
84
}
(-)linux-2.6.5.orig/arch/i386/pci/direct.c (+4 lines)
Lines 4-9 Link Here
4
4
5
#include <linux/pci.h>
5
#include <linux/pci.h>
6
#include <linux/init.h>
6
#include <linux/init.h>
7
#include "mach_pci_blacklist.h"
7
#include "pci.h"
8
#include "pci.h"
8
9
9
/*
10
/*
Lines 20-25 Link Here
20
	if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
21
	if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
21
		return -EINVAL;
22
		return -EINVAL;
22
23
24
	if (mach_pci_is_blacklisted(bus, PCI_SLOT(devfn), PCI_FUNC(devfn)))
25
		return -EINVAL;
26
23
	spin_lock_irqsave(&pci_config_lock, flags);
27
	spin_lock_irqsave(&pci_config_lock, flags);
24
28
25
	outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);
29
	outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);
(-)linux-2.6.5.orig/drivers/i2c/busses/Kconfig (+4 lines)
Lines 37-42 Link Here
37
	  This driver can also be built as a module.  If so, the module
37
	  This driver can also be built as a module.  If so, the module
38
	  will be called i2c-amd756.
38
	  will be called i2c-amd756.
39
39
40
config I2C_XBOX
41
	tristate "XBOX I2C"
42
	depends on I2C && EXPERIMENTAL
43
40
config I2C_AMD8111
44
config I2C_AMD8111
41
	tristate "AMD 8111"
45
	tristate "AMD 8111"
42
	depends on I2C && EXPERIMENTAL
46
	depends on I2C && EXPERIMENTAL
(-)linux-2.6.5.orig/drivers/i2c/busses/Makefile (+1 lines)
Lines 5-10 Link Here
5
obj-$(CONFIG_I2C_ALI1535)	+= i2c-ali1535.o
5
obj-$(CONFIG_I2C_ALI1535)	+= i2c-ali1535.o
6
obj-$(CONFIG_I2C_ALI15X3)	+= i2c-ali15x3.o
6
obj-$(CONFIG_I2C_ALI15X3)	+= i2c-ali15x3.o
7
obj-$(CONFIG_I2C_AMD756)	+= i2c-amd756.o
7
obj-$(CONFIG_I2C_AMD756)	+= i2c-amd756.o
8
obj-$(CONFIG_I2C_XBOX)		+= i2c-xbox.o
8
obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
9
obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
9
obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
10
obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
10
obj-$(CONFIG_I2C_HYDRA)		+= i2c-hydra.o
11
obj-$(CONFIG_I2C_HYDRA)		+= i2c-hydra.o
(-)linux-2.6.5.orig/drivers/i2c/busses/i2c-xbox.c (+417 lines)
Line 0 Link Here
1
/*
2
    i2c-xbox.c - Part of lm_sensors, Linux kernel modules for hardware
3
              monitoring
4
5
    Copyright (c) 1999-2002 Edgar Hucek <hostmaster@ed-soft.at>
6
7
    Shamelessly ripped from i2c-xbox.c:
8
9
    This program is free software; you can redistribute it and/or modify
10
    it under the terms of the GNU General Public License as published by
11
    the Free Software Foundation; either version 2 of the License, or
12
    (at your option) any later version.
13
14
    This program is distributed in the hope that it will be useful,
15
    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
    GNU General Public License for more details.
18
19
    You should have received a copy of the GNU General Public License
20
    along with this program; if not, write to the Free Software
21
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
*/
23
24
/*
25
   Supports XBOX, Note: we assume there can only be one device, with one SMBus interface.
26
*/
27
28
#include <linux/version.h>
29
#include <linux/module.h>
30
#include <linux/pci.h>
31
#include <asm/io.h>
32
#include <linux/kernel.h>
33
#include <linux/stddef.h>
34
#include <linux/sched.h>
35
#include <linux/ioport.h>
36
#include <linux/i2c.h>
37
#include <linux/init.h>
38
39
#include <linux/sched.h>
40
#include <linux/errno.h>  /* error codes */
41
#include <linux/interrupt.h> /* intr_count */
42
#include <linux/xbox.h>
43
#include <linux/delay.h>
44
45
46
#define GS_ABRT_STS (1 << 0)
47
#define GS_COL_STS (1 << 1)
48
#define GS_PRERR_STS (1 << 2)
49
#define GS_HST_STS (1 << 3)
50
#define GS_IRQ_ON (1 << 4)
51
#define GS_HCYC_STS (1 << 4)
52
#define GS_TO_STS (1 << 5)
53
#define GS_SMB_STS (1 << 11)
54
55
#define SMB_GCTL_HOST_START      (1 << 3)
56
#define SMB_GCTL_HOST_INTERRUPT  (1 << 4)
57
#define SMB_GCTL_ABORT           (1 << 5)
58
#define SMB_GCTL_SNOOP           (1 << 8)
59
#define SMB_GCTL_SLAVE_INTERRUPT (1 << 9)
60
#define SMB_GCTL_ALERT_INTERRUPT (1 << 10)
61
62
#define GS_CLEAR_STS (GS_ABRT_STS | GS_COL_STS | GS_PRERR_STS | \
63
  GS_HCYC_STS | GS_TO_STS)
64
65
#define GE_CYC_TYPE_MASK (7)
66
#define GE_HOST_STC (1 << 3)
67
#define GE_ABORT (1 << 5)
68
69
#define I2C_HW_SMBUS_XBOX   0x05
70
#define SMBGCFG   0x041          /* mh */
71
#define SMBBA     0x058           /* mh */
72
73
struct sd {
74
    const unsigned short vendor;
75
    const unsigned short device;
76
    const unsigned short function;
77
    const char* name;
78
    int amdsetup:1;
79
};
80
81
static struct sd supported[] = {
82
    {PCI_VENDOR_ID_NVIDIA, 0x01b4, 1, "nVidia XBOX nForce", 0},
83
    {0, 0, 0}
84
};
85
86
/* XBOX SMBus address offsets */
87
#define SMB_ADDR_OFFSET        0x04
88
#define SMB_IOSIZE             8
89
#define SMB_GLOBAL_STATUS      (0x0 + xbox_smba)
90
#define SMB_GLOBAL_ENABLE      (0x2 + xbox_smba)
91
#define SMB_HOST_ADDRESS       (0x4 + xbox_smba)
92
#define SMB_HOST_DATA          (0x6 + xbox_smba)
93
#define SMB_HOST_COMMAND       (0x8 + xbox_smba)
94
95
96
97
98
99
/* Other settings */
100
#define MAX_TIMEOUT 500
101
102
/* XBOX constants */
103
#define XBOX_QUICK        0x00
104
#define XBOX_BYTE         0x01
105
#define XBOX_BYTE_DATA    0x02
106
#define XBOX_WORD_DATA    0x03
107
#define XBOX_PROCESS_CALL 0x04
108
#define XBOX_BLOCK_DATA   0x05
109
110
/* insmod parameters */
111
112
#ifdef MODULE
113
static
114
#else
115
extern
116
#endif
117
int __init i2c_xbox_init(void);
118
static int __init xbox_cleanup(void);
119
static int xbox_setup(void);
120
static s32 xbox_access(struct i2c_adapter *adap, u16 addr,
121
			 unsigned short flags, char read_write,
122
			 u8 command, int size, union i2c_smbus_data *data);
123
static void xbox_do_pause(unsigned int amount);
124
static void xbox_abort(void);
125
static int xbox_transaction(void);
126
static u32 xbox_func(struct i2c_adapter *adapter);
127
128
static struct i2c_algorithm smbus_algorithm = {
129
	/* name */ "Non-I2C SMBus adapter",
130
	/* id */ I2C_ALGO_SMBUS,
131
	/* master_xfer */ NULL,
132
	/* smbus_access */ xbox_access,
133
	/* slave;_send */ NULL,
134
	/* slave_rcv */ NULL,
135
	/* algo_control */ NULL,
136
	/* functionality */ xbox_func,
137
};
138
139
static struct i2c_adapter xbox_adapter = {
140
	.owner          = THIS_MODULE,
141
	.class          = I2C_ADAP_CLASS_SMBUS,
142
	.algo           = &smbus_algorithm,
143
	.name           = "unset",
144
};
145
146
static int __initdata xbox_initialized;
147
static unsigned short xbox_smba = 0;
148
spinlock_t xbox_driver_lock = SPIN_LOCK_UNLOCKED;
149
struct driver_data;
150
static struct pci_dev *XBOX_dev;
151
152
/* Detect whether a XBOX can be found, and initialize it, where necessary.
153
   Note the differences between kernels with the old PCI BIOS interface and
154
   newer kernels with the real PCI interface. In compat.h some things are
155
   defined to make the transition easier. */
156
int xbox_setup(void)
157
{
158
	unsigned char temp;
159
	struct sd *currdev;
160
	u16 cmd;
161
162
	XBOX_dev = NULL;
163
164
	/* Look for a supported chip */
165
	for(currdev = supported; currdev->vendor; ) {
166
		XBOX_dev = pci_find_device(currdev->vendor,
167
						currdev->device, XBOX_dev);
168
		if (XBOX_dev != NULL)	{
169
	                pci_read_config_byte(XBOX_dev, SMBGCFG, &temp);
170
			pci_read_config_word(XBOX_dev, 0x14, &xbox_smba);
171
			
172
			xbox_smba &= 0xfffc;
173
			if (PCI_FUNC(XBOX_dev->devfn) == currdev->function)
174
			{
175
				pci_read_config_word(XBOX_dev,PCI_STATUS,&cmd);
176
				break;
177
			}
178
		} else {
179
		    currdev++;
180
		}
181
	}
182
183
	if (XBOX_dev == NULL) {
184
		printk
185
		    ("i2c-xbox.o: Error: No XBOX or compatible device detected!\n");
186
		return(-ENODEV);
187
	}
188
	printk(KERN_INFO "i2c-xbox.o: Found %s SMBus controller.\n", currdev->name);
189
190
	/* Everything is happy, let's grab the memory and set things up. */
191
	if(!request_region(xbox_smba, SMB_IOSIZE, "xbox-smbus")) {
192
		printk
193
		    ("i2c-xbox.o: SMB region 0x%x already in use!\n",
194
		     xbox_smba);
195
		return(-ENODEV);
196
	}
197
198
	return 0;
199
}
200
201
/* 
202
  SMBUS event = I/O 28-29 bit 11
203
     see E0 for the status bits and enabled in E2
204
     
205
*/
206
207
/* Internally used pause function */
208
void xbox_do_pause(unsigned int amount)
209
{
210
	current->state = TASK_INTERRUPTIBLE;
211
	schedule_timeout(amount);
212
}
213
214
void xbox_abort(void)
215
{
216
	printk("i2c-xbox.o: Sending abort.\n");
217
	outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE);
218
	xbox_do_pause(100);
219
	outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS);
220
}
221
222
int xbox_transaction(void)
223
{
224
	int temp;
225
	int result = 0;
226
	int timeout = 0;
227
228
	/* Make sure the SMBus host is ready to start transmitting */
229
	if ((temp = inw_p(SMB_GLOBAL_STATUS)) & (GS_HST_STS | GS_SMB_STS)) {
230
		do {
231
			udelay(100);
232
			temp = inw_p(SMB_GLOBAL_STATUS);
233
		} while ((temp & (GS_HST_STS | GS_SMB_STS)) &&
234
		         (timeout++ < MAX_TIMEOUT));
235
		/* If the SMBus is still busy, we give up */
236
		if (timeout >= MAX_TIMEOUT) {
237
			printk("i2c-xbox.o: Busy wait timeout! (%04x)\n", temp);
238
			xbox_abort();
239
			return(-1);
240
		}
241
		timeout = 0;
242
	}
243
244
	/* start the transaction by setting the start bit */
245
	outw_p(inw(SMB_GLOBAL_ENABLE) | GE_HOST_STC , SMB_GLOBAL_ENABLE);
246
247
	/* We will always wait for a fraction of a second! */
248
	temp = inw_p(SMB_GLOBAL_STATUS);
249
	while ((temp & GS_HST_STS) && (timeout++ < MAX_TIMEOUT)) {
250
		udelay(100);
251
		temp = inw_p(SMB_GLOBAL_STATUS);		
252
	} 
253
254
	/* If the SMBus is still busy, we give up */
255
	if (timeout >= MAX_TIMEOUT) {
256
		printk("i2c-xbox.o: Completion timeout!\n");
257
		xbox_abort ();
258
		return(-1);
259
	}
260
261
	if (temp & GS_PRERR_STS) {
262
		result = -1;
263
	}
264
265
	if (temp & GS_COL_STS) {
266
		result = -1;
267
		printk("i2c-xbox.o: SMBus collision!\n");
268
	}
269
270
	if (temp & GS_TO_STS) {
271
		result = -1;
272
	}
273
	outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS);
274
275
	return result;
276
}
277
278
/* Return -1 on error. */
279
s32 xbox_access(struct i2c_adapter * adap, u16 addr,
280
		  unsigned short flags, char read_write,
281
		  u8 command, int size, union i2c_smbus_data * data)
282
{
283
  /** TODO: Should I supporte the 10-bit transfers? */
284
	switch (size) {
285
	case I2C_SMBUS_PROC_CALL:
286
		printk
287
		    ("i2c-xbox.o: I2C_SMBUS_PROC_CALL not supported!\n");
288
		/* TODO: Well... It is supported, I'm just not sure what to do here... */
289
		return -1;
290
	case I2C_SMBUS_QUICK:
291
		outw_p(((addr & 0x7f) << 1) | (read_write & 0x01),
292
		       SMB_HOST_ADDRESS);
293
		size = XBOX_QUICK;
294
		break;
295
	case I2C_SMBUS_BYTE:
296
		outw_p(((addr & 0x7f) << 1) | (read_write & 0x01),
297
		       SMB_HOST_ADDRESS);
298
		/* TODO: Why only during write? */
299
		if (read_write == I2C_SMBUS_WRITE)
300
			outb_p(command, SMB_HOST_COMMAND);
301
		size = XBOX_BYTE;
302
		break;
303
	case I2C_SMBUS_BYTE_DATA:
304
		outw_p(((addr & 0x7f) << 1) | (read_write & 0x01),
305
		       SMB_HOST_ADDRESS);
306
		outb_p(command, SMB_HOST_COMMAND);
307
		if (read_write == I2C_SMBUS_WRITE)
308
			outw_p(data->byte, SMB_HOST_DATA);
309
		size = XBOX_BYTE_DATA;
310
		break;
311
	case I2C_SMBUS_WORD_DATA:
312
		outw_p(((addr & 0x7f) << 1) | (read_write & 0x01),
313
		       SMB_HOST_ADDRESS);
314
		outb_p(command, SMB_HOST_COMMAND);
315
		if (read_write == I2C_SMBUS_WRITE)
316
			outw_p(data->word, SMB_HOST_DATA);	/* TODO: endian???? */
317
		size = XBOX_WORD_DATA;
318
		break;
319
	}
320
321
	/* How about enabling interrupts... */
322
	outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE);
323
324
	if (xbox_transaction())	/* Error in transaction */
325
		return -1;
326
327
	if ((read_write == I2C_SMBUS_WRITE) || (size == XBOX_QUICK))
328
		return 0;
329
330
331
	switch (size) {
332
	case XBOX_BYTE:
333
		data->byte = inw_p(SMB_HOST_DATA);
334
		break;
335
	case XBOX_BYTE_DATA:
336
		data->byte = inw_p(SMB_HOST_DATA);
337
		break;
338
	case XBOX_WORD_DATA:
339
		data->word = inw_p(SMB_HOST_DATA);	/* TODO: endian???? */
340
		break;
341
	}
342
343
	return 0;
344
}
345
346
u32 xbox_func(struct i2c_adapter *adapter)
347
{
348
	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
349
	    I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
350
	    I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL;
351
}
352
353
int __init i2c_xbox_init(void)
354
{
355
	int res;
356
	printk("i2c-xbox.o version 0.0.1\n");
357
	xbox_initialized = 0;
358
	if ((res = xbox_setup())) {
359
		printk
360
		    ("i2c-xbox.o: XBOX or compatible device not detected, module not inserted.\n");
361
		xbox_cleanup();
362
		return res;
363
	}
364
	xbox_initialized++;
365
	sprintf(xbox_adapter.name, "SMBus adapter at %04x",xbox_smba);
366
	if ((res = i2c_add_adapter(&xbox_adapter))) {
367
		printk
368
		    ("i2c-xbox.o: Adapter registration failed, module not inserted.\n");
369
		xbox_cleanup();
370
		return res;
371
	}
372
	xbox_initialized++;
373
	printk("i2c-xbox.o: SMBus bus detected and initialized\n");
374
	return 0;
375
}
376
377
int __init xbox_cleanup(void)
378
{
379
	int res;
380
	if (xbox_initialized >= 2) {
381
		if ((res = i2c_del_adapter(&xbox_adapter))) {
382
			printk
383
			    ("i2c-xbox.o: i2c_del_adapter failed, module not removed\n");
384
			return res;
385
		} else
386
			xbox_initialized--;
387
	}
388
	if (xbox_initialized >= 1) {
389
		release_region(xbox_smba, SMB_IOSIZE);
390
		xbox_initialized--;
391
	}
392
	free_irq(XBOX_dev->irq, XBOX_dev);
393
	return 0;
394
}
395
396
EXPORT_SYMBOL(i2c_xbox_init);
397
398
#ifdef MODULE
399
400
MODULE_AUTHOR("Edgar Hucek <hostmaster@ed-soft.at>");
401
MODULE_DESCRIPTION("XBOX nForce SMBus driver");
402
403
#ifdef MODULE_LICENSE
404
MODULE_LICENSE("GPL");
405
#endif
406
407
int init_module(void)
408
{
409
	return i2c_xbox_init();
410
}
411
412
void cleanup_module(void)
413
{
414
	xbox_cleanup();
415
}
416
417
#endif				/* MODULE */
(-)linux-2.6.5.orig/drivers/ide/ide-cd.c (+96 lines)
Lines 324-329 Link Here
324
324
325
#include "ide-cd.h"
325
#include "ide-cd.h"
326
326
327
#ifdef CONFIG_X86_XBOX
328
#include <linux/xbox.h>
329
/* Global flag indicating whether to simulate Xbox drive locking in
330
 * software.  There should only be one Xbox drive in a system!  This
331
 * variable is externally referenced by arch/i386/kernel/xboxejectfix.c. */
332
volatile int Xbox_simulate_drive_locked = 0;
333
#endif /* CONFIG_X86_XBOX */
334
 
327
/****************************************************************************
335
/****************************************************************************
328
 * Generic packet command support and error handling routines.
336
 * Generic packet command support and error handling routines.
329
 */
337
 */
Lines 2113-2118 Link Here
2113
	if (sense == NULL)
2121
	if (sense == NULL)
2114
		sense = &my_sense;
2122
		sense = &my_sense;
2115
2123
2124
#ifdef CONFIG_X86_XBOX
2125
	/* If we're on an Xbox and this is an Xbox drive, simulate the lock
2126
	   request in software.  (See arch/i386/kernel/xboxejectfix.c) */
2127
	if (CDROM_CONFIG_FLAGS(drive)->xbox_drive && machine_is_xbox) {
2128
		CDROM_STATE_FLAGS(drive)->door_locked = lockflag;
2129
		Xbox_simulate_drive_locked = lockflag;
2130
		return 0;
2131
	}
2132
#endif /* CONFIG_X86_XBOX */
2133
		
2116
	/* If the drive cannot lock the door, just pretend. */
2134
	/* If the drive cannot lock the door, just pretend. */
2117
	if (CDROM_CONFIG_FLAGS(drive)->no_doorlock) {
2135
	if (CDROM_CONFIG_FLAGS(drive)->no_doorlock) {
2118
		stat = 0;
2136
		stat = 0;
Lines 2160-2165 Link Here
2160
	if (CDROM_STATE_FLAGS(drive)->door_locked && ejectflag)
2178
	if (CDROM_STATE_FLAGS(drive)->door_locked && ejectflag)
2161
		return 0;
2179
		return 0;
2162
2180
2181
#ifdef CONFIG_X86_XBOX
2182
        /* Older Xbox DVD drives don't understand the ATAPI command, but the SMC
2183
	   can do the eject.  Note that some Xbox drives support the eject
2184
	   command, namely the Samsung, so for that drive we do a regular eject
2185
	   sequence. */
2186
	if (machine_is_xbox && CDROM_CONFIG_FLAGS(drive)->xbox_drive &&
2187
		CDROM_CONFIG_FLAGS(drive)->xbox_eject) {
2188
		if (ejectflag) {
2189
			Xbox_tray_load();
2190
		} else {
2191
			Xbox_simulate_drive_locked = 0;
2192
			Xbox_tray_eject();
2193
		}
2194
		return 0;
2195
	}
2196
#endif
2197
		
2163
	cdrom_prepare_request(&req);
2198
	cdrom_prepare_request(&req);
2164
2199
2165
	req.sense = sense;
2200
	req.sense = sense;
Lines 3245-3250 Link Here
3245
                 /* uses CD in slot 0 when value is set to 3 */
3280
                 /* uses CD in slot 0 when value is set to 3 */
3246
                 cdi->sanyo_slot = 3;
3281
                 cdi->sanyo_slot = 3;
3247
        }
3282
        }
3283
#ifdef CONFIG_X86_XBOX
3284
	/* THOMSON DVD drives in the Xbox report incorrect capabilities
3285
	   and do not understand the ATAPI eject command, but the SMC
3286
	   can do the eject. */
3287
	else if ((strcmp(drive->id->model, "THOMSON-DVD") == 0)) {
3288
		CDROM_CONFIG_FLAGS(drive)->audio_play = 1;
3289
		CDROM_CONFIG_FLAGS(drive)->dvd = 1;
3290
		CDROM_CONFIG_FLAGS(drive)->xbox_drive = 1;
3291
		CDROM_CONFIG_FLAGS(drive)->xbox_eject = 1;
3292
	}
3293
	/* PHILIPS drives in Xboxen manufactured pre September 2003,
3294
	   report correct capabilities, but do not understand the ATAPI
3295
	   eject command, hence require the SMC to do so. */
3296
	else if ((strcmp(drive->id->model, "PHILIPS XBOX DVD DRIVE") == 0)) {
3297
		CDROM_CONFIG_FLAGS(drive)->xbox_drive = 1;
3298
		CDROM_CONFIG_FLAGS(drive)->xbox_eject = 1;
3299
	}
3300
	/* PHILIPS drives in Xboxen manufactured post September 2003,
3301
	   report incorrect capabilities, but understand the ATAPI
3302
	   eject command. */
3303
	else if ((strcmp(drive->id->model, "PHILIPS J5 3235C") == 0)) {
3304
		CDROM_CONFIG_FLAGS(drive)->audio_play = 1;
3305
		CDROM_CONFIG_FLAGS(drive)->dvd = 1;
3306
		CDROM_CONFIG_FLAGS(drive)->xbox_drive = 1;
3307
		CDROM_CONFIG_FLAGS(drive)->xbox_eject = 0;
3308
	}
3309
	/* SAMSUNG drives in the Xbox report correct capabilities
3310
	   and understand the ATAPI eject command. */
3311
	else if (strcmp(drive->id->model, "SAMSUNG DVD-ROM SDG-605B") == 0) {
3312
		CDROM_CONFIG_FLAGS(drive)->xbox_drive = 1;
3313
		CDROM_CONFIG_FLAGS(drive)->xbox_eject = 0;
3314
	}
3315
#endif
3316
3317
	/* Is an Xbox drive detected? */
3318
#ifdef CONFIG_X86_XBOX
3319
	if (CDROM_CONFIG_FLAGS(drive)->xbox_drive) {
3320
#endif
3321
		/* If an Xbox drive is present in a regular PC, we can't eject.
3322
		   Act like the drive cannot eject, unless the ATAPI eject command
3323
		   is supported by the drive.  If the drive doesn't support ATAPI
3324
		   ejecting, act like door locking is impossible as well. */
3325
#ifdef CONFIG_X86_XBOX
3326
		if (!machine_is_xbox) {
3327
#endif /* CONFIG_X86_XBOX */
3328
			CDROM_CONFIG_FLAGS(drive)->no_doorlock = CDROM_CONFIG_FLAGS
3329
				(drive)->xbox_eject;
3330
			CDROM_CONFIG_FLAGS(drive)->no_eject = CDROM_CONFIG_FLAGS(drive)
3331
				->xbox_eject;
3332
#ifdef CONFIG_X86_XBOX
3333
		} else {
3334
			/* An Xbox drive in an Xbox.  We can support ejecting through
3335
			   the SMC and support drive locking in software by ignoring
3336
			   the eject interrupt (see arch/i386/kernel/xboxejectfix.c). */
3337
			CDROM_CONFIG_FLAGS(drive)->no_doorlock = 0;
3338
			CDROM_CONFIG_FLAGS(drive)->no_eject = 0;
3339
			Xbox_simulate_drive_locked = 0;
3340
		}
3341
#endif
3342
	}
3343
3248
#endif /* not STANDARD_ATAPI */
3344
#endif /* not STANDARD_ATAPI */
3249
3345
3250
	info->toc		= NULL;
3346
	info->toc		= NULL;
(-)linux-2.6.5.orig/drivers/ide/ide-cd.h (+4 lines)
Lines 95-100 Link Here
95
	__u8 close_tray		: 1; /* can close the tray */
95
	__u8 close_tray		: 1; /* can close the tray */
96
	__u8 writing		: 1; /* pseudo write in progress */
96
	__u8 writing		: 1; /* pseudo write in progress */
97
	__u8 mo_drive		: 1; /* drive is an MO device */
97
	__u8 mo_drive		: 1; /* drive is an MO device */
98
#ifdef CONFIG_X86_XBOX
99
	__u8 xbox_drive         : 1; /* drive is an Xbox drive */
100
	__u8 xbox_eject         : 1; /* use Xbox SMC eject mechanism */	
101
#endif
98
	__u8 reserved		: 2;
102
	__u8 reserved		: 2;
99
	byte max_speed;		     /* Max speed of the drive */
103
	byte max_speed;		     /* Max speed of the drive */
100
};
104
};
(-)linux-2.6.5.orig/drivers/pci/pci.ids (+1 lines)
Lines 2856-2861 Link Here
2856
	0286  NV28 [GeForce4 Ti 4200 Go AGP 8x]
2856
	0286  NV28 [GeForce4 Ti 4200 Go AGP 8x]
2857
	0288  NV28GL [Quadro4 980 XGL]
2857
	0288  NV28GL [Quadro4 980 XGL]
2858
	0289  NV28GL [Quadro4 780 XGL]
2858
	0289  NV28GL [Quadro4 780 XGL]
2859
	02a0  NV16 [GeForce3 MX - nForce GPU]
2859
	0300  NV30 [GeForce FX]
2860
	0300  NV30 [GeForce FX]
2860
	0301  NV30 [GeForce FX 5800 Ultra]
2861
	0301  NV30 [GeForce FX 5800 Ultra]
2861
	0302  NV30 [GeForce FX 5800]
2862
	0302  NV30 [GeForce FX 5800]
(-)linux-2.6.5.orig/drivers/usb/input/Kconfig.rej (+42 lines)
Line 0 Link Here
1
***************
2
*** 180,194 ****
3
  	  module will be called powermate.
4
  
5
  config USB_XPAD
6
- 	tristate "X-Box gamepad support"
7
  	depends on USB && INPUT
8
  	---help---
9
- 	  Say Y here if you want to use the X-Box pad with your computer.
10
  	  Make sure to say Y to "Joystick support" (CONFIG_INPUT_JOYDEV)
11
  	  and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well.
12
  
13
- 	  For information about how to connect the X-Box pad to USB, see
14
  	  <file:Documentation/input/xpad.txt>.
15
  
16
  	  To compile this driver as a module, choose M here: the
17
  	  module will be called xpad.
18
--- 180,203 ----
19
  	  module will be called powermate.
20
  
21
  config USB_XPAD
22
+ 	tristate "Xbox controller (gamepad) support"
23
  	depends on USB && INPUT
24
  	---help---
25
+ 	  Say Y here if you want to use Xbox controllers with your computer.
26
  	  Make sure to say Y to "Joystick support" (CONFIG_INPUT_JOYDEV)
27
  	  and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well.
28
  
29
+ 	  For information about how to connect an Xbox controller to USB, see
30
  	  <file:Documentation/input/xpad.txt>.
31
  
32
  	  To compile this driver as a module, choose M here: the
33
  	  module will be called xpad.
34
+ 
35
+ config USB_XPAD_MOUSE
36
+ 	bool "Mouse emulation for Xbox controller"
37
+ 	depends on USB_XPAD
38
+ 	---help---
39
+ 	  Say Y here if you want to enable mouse emulation for your Xbox
40
+ 	  controller.
41
+ 	  Make sure to say Y to "Mouse support" (CONFIG_INPUT_MOUSEDEV)
42
+ 	  and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well.
(-)linux-2.6.5.orig/drivers/usb/input/Makefile (+5 lines)
Lines 4-9 Link Here
4
4
5
# Multipart objects.
5
# Multipart objects.
6
hid-objs	:= hid-core.o
6
hid-objs	:= hid-core.o
7
xpad-objs	:= xpad-core.o
7
8
8
# Optional parts of multipart objects.
9
# Optional parts of multipart objects.
9
10
Lines 26-31 Link Here
26
	hid-objs	+= hid-ff.o
27
	hid-objs	+= hid-ff.o
27
endif
28
endif
28
29
30
ifeq ($(CONFIG_USB_XPAD_MOUSE),y)
31
	xpad-objs	+= xpad-mouse.o
32
endif
33
29
obj-$(CONFIG_USB_AIPTEK)	+= aiptek.o
34
obj-$(CONFIG_USB_AIPTEK)	+= aiptek.o
30
obj-$(CONFIG_USB_ATI_REMOTE)	+= ati_remote.o
35
obj-$(CONFIG_USB_ATI_REMOTE)	+= ati_remote.o
31
obj-$(CONFIG_USB_HID)		+= hid.o
36
obj-$(CONFIG_USB_HID)		+= hid.o
(-)linux-2.6.5.orig/drivers/usb/input/xpad-core.c (+577 lines)
Line 0 Link Here
1
/*
2
 * Xbox input device driver for Linux - v0.1.4
3
 *
4
 * Copyright (c)  2002 - 2004  Marko Friedemann <mfr@bmx-chemnitz.de>
5
 *
6
 *	Contributors:
7
 *		Vojtech Pavlik <vojtech@suse.sz>,
8
 *		Oliver Schwartz <Oliver.Schwartz@gmx.de>,
9
 *		Steven Toth <steve@toth.demon.co.uk>,
10
 *		Franz Lehner <franz@caos.at>,
11
 *		Ivan Hawkes <blackhawk@ivanhawkes.com>
12
 *
13
 *
14
 * This program is free software; you can redistribute it and/or
15
 * modify it under the terms of the GNU General Public License as
16
 * published by the Free Software Foundation; either version 2 of
17
 * the License, or (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
 *
28
 *
29
 * This driver is based on:
30
 *  - information from     http://euc.jp/periphs/xbox-controller.en.html
31
 *  - the iForce driver    drivers/char/joystick/iforce.c
32
 *  - the skeleton-driver  drivers/usb/usb-skeleton.c
33
 *
34
 * Thanks to:
35
 *  - ITO Takayuki for providing essential xpad information on his website
36
 *  - Vojtech Pavlik     - iforce driver / input subsystem
37
 *  - Greg Kroah-Hartman - usb-skeleton driver
38
 *
39
 * TODO:
40
 *  - fine tune axes
41
 *  - fine tune mouse behaviour (should not do linear acceleration)
42
 *  - NEW: get rumble working correctly, fix all the bugs and support multiple
43
 *         simultaneous effects
44
 *  - NEW: split funtionality mouse/joustick into two source files
45
 *  - NEW: implement /proc interface (toggle mouse/rumble enable/disable, etc.)
46
 *  - NEW: implement user space daemon application that handles that interface
47
 *
48
 * History: moved to end of file
49
 */
50
 
51
#include <linux/config.h>
52
#include <linux/kernel.h>
53
#include <linux/init.h>
54
#include <linux/slab.h>
55
#include <linux/module.h>
56
#include <linux/smp_lock.h>
57
#include <linux/usb.h>
58
#include <linux/version.h>
59
#include <linux/timer.h>
60
#include <asm/uaccess.h>
61
62
#include "xpad.h"
63
64
static struct xpad_device xpad_device[] = {
65
	/* please keep those ordered wrt. vendor/product ids
66
	  vendor, product, isMat, name                              */
67
	{ 0x045e, 0x0202, 0, "Microsoft Xbox Controller" },
68
	{ 0x045e, 0x0285, 0, "Microsoft Xbox Controller S" },
69
	{ 0x045e, 0x0289, 0, "Microsoft Xbox Controller S" }, /* microsoft is stupid */
70
	{ 0x046d, 0xca88, 0, "Logitech Compact Controller for Xbox" },
71
	{ 0x05fd, 0x1007, 0, "???Mad Catz Controller???" }, /* CHECKME: this seems strange */
72
	{ 0x05fd, 0x107a, 0, "InterAct PowerPad Pro" },
73
	{ 0x0738, 0x4516, 0, "Mad Catz Control Pad" },
74
	{ 0x0738, 0x4522, 0, "Mad Catz LumiCON" },
75
	{ 0x0738, 0x4526, 0, "Mad Catz Control Pad Pro" },
76
	{ 0x0738, 0x4536, 0, "Mad Catz MicroCON" },
77
	{ 0x0738, 0x4540, 1, "Mad Catz Beat Pad" },
78
	{ 0x0738, 0x4556, 0, "Mad Catz Lynx Wireless Controller" },
79
	{ 0x0738, 0x6040, 1, "Mad Catz Beat Pad Pro" },
80
	{ 0x0c12, 0x9902, 0, "HAMA VibraX - lucky boy" }, /* these are broken */
81
	{ 0x0e6f, 0x0003, 0, "Logic3 Freebird wireless Controller" },
82
	{ 0x0f30, 0x0202, 0, "Joytech Advanced Controller" },
83
	{ 0x12ab, 0x8809, 1, "Xbox DDR dancepad" },
84
	{ 0xffff, 0xffff, 0, "Chinese crap Xbox Controller" }, /* WTF are device IDs for? */
85
	{ 0x0000, 0x0000, 0, "nothing detected - FAIL" }
86
};
87
88
static signed short xpad_btn[] = {
89
	BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z,	/* analogue buttons */
90
	BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR,	/* start/back/sticks */
91
	BTN_0, BTN_1, BTN_2, BTN_3,			/* d-pad as buttons */
92
	-1						/* terminating entry */
93
};
94
95
static signed short xpad_mat_btn[] = {
96
	BTN_A, BTN_B, BTN_X, BTN_Y, 	/* A, B, X, Y */
97
	BTN_START, BTN_BACK, 		/* start/back */
98
	BTN_0, BTN_1, BTN_2, BTN_3,	/* directions, LEFT/RIGHT is mouse
99
					 * so we cannot use those! */
100
	-1				/* terminating entry */
101
};
102
103
static signed short xpad_abs[] = {
104
	ABS_X, ABS_Y,		/* left stick */
105
	ABS_RX, ABS_RY,		/* right stick */
106
	ABS_Z, ABS_RZ,		/* triggers left/right */
107
	ABS_HAT0X, ABS_HAT0Y,	/* digital pad */
108
	ABS_HAT1X, ABS_HAT1Y,	/* analogue buttons A + B */
109
	ABS_HAT2X, ABS_HAT2Y,	/* analogue buttons C + X */
110
	ABS_HAT3X, ABS_HAT3Y,	/* analogue buttons Y + Z */
111
	-1			/* terminating entry */
112
};
113
114
static struct usb_device_id xpad_table [] = {
115
	{ USB_INTERFACE_INFO('X', 'B', 0) },	/* Xbox USB-IF not approved class */
116
	{ USB_INTERFACE_INFO( 3 ,  0 , 0) },	/* for Joytech Advanced Controller */
117
	{ }
118
};
119
120
MODULE_DEVICE_TABLE(usb, xpad_table);
121
122
/**
123
 *	xpad_process_packet
124
 *
125
 *	Completes a request by converting the data into events
126
 *	for the input subsystem.
127
 *
128
 *	The report descriptor was taken from ITO Takayukis website:
129
 *	 http://euc.jp/periphs/xbox-controller.en.html
130
 */
131
static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs)
132
{
133
	struct input_dev *dev = &xpad->dev;
134
	
135
	input_regs(dev, regs);
136
137
	/* digital pad (button mode) bits (3 2 1 0) (right left down up) */
138
	input_report_key(dev, BTN_0, (data[2] & 0x01));
139
	input_report_key(dev, BTN_1, (data[2] & 0x08) >> 3);
140
	input_report_key(dev, BTN_2, (data[2] & 0x02) >> 1);
141
	input_report_key(dev, BTN_3, (data[2] & 0x04) >> 2);	
142
	
143
	/* start and back buttons */
144
	input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4);
145
	input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5);
146
	
147
	/* buttons A, B, X, Y digital mode */
148
	input_report_key(dev, BTN_A, data[4]);
149
	input_report_key(dev, BTN_B, data[5]);
150
	input_report_key(dev, BTN_X, data[6]);
151
	input_report_key(dev, BTN_Y, data[7]);
152
	
153
	if (xpad->isMat)
154
		return;
155
	
156
	/* left stick */
157
	input_report_abs(dev, ABS_X, ((__s16) (((__s16)data[13] << 8) | data[12])));
158
	input_report_abs(dev, ABS_Y, ((__s16) (((__s16)data[15] << 8) | data[14])));
159
	
160
	/* right stick */
161
	input_report_abs(dev, ABS_RX, ((__s16) (((__s16)data[17] << 8) | data[16])));
162
	input_report_abs(dev, ABS_RY, ((__s16) (((__s16)data[19] << 8) | data[18])));
163
   	
164
   	/* triggers left/right */
165
	input_report_abs(dev, ABS_Z, data[10]);
166
	input_report_abs(dev, ABS_RZ, data[11]);
167
	
168
	/* digital pad (analogue mode): bits (3 2 1 0) (right left down up) */
169
	input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04));
170
	input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x01) - !!(data[2] & 0x02));
171
172
	/* stick press left/right */
173
	input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6);
174
	input_report_key(dev, BTN_THUMBR, data[2] >> 7);
175
	
176
	/* button A, B, X, Y analogue mode */
177
	input_report_abs(dev, ABS_HAT1X, data[4]);
178
	input_report_abs(dev, ABS_HAT1Y, data[5]);
179
	input_report_abs(dev, ABS_HAT2Y, data[6]);
180
	input_report_abs(dev, ABS_HAT3X, data[7]);
181
	
182
	/* button C (black) digital/analogue mode */
183
	input_report_key(dev, BTN_C, data[8]);
184
	input_report_abs(dev, ABS_HAT2X, data[8]);
185
	
186
	/* button Z (white) digital/analogue mode */
187
	input_report_key(dev, BTN_Z, data[9]);
188
	input_report_abs(dev, ABS_HAT3Y, data[9]);
189
	
190
	input_sync(dev);
191
	
192
	/* process input data for mouse event generation */
193
	xpad_mouse_process_packet(xpad, cmd, data);
194
}
195
196
/**
197
 *	xpad_irq_in
198
 *
199
 *	Completion handler for interrupt in transfers (user input).
200
 *	Just calls xpad_process_packet which does then emit input events.
201
 */
202
static void xpad_irq_in(struct urb *urb, struct pt_regs *regs)
203
{
204
	struct usb_xpad *xpad = urb->context;
205
	int retval;
206
	
207
	switch (urb->status) {
208
	case 0:
209
		/* success */
210
		break;
211
	case -ECONNRESET:
212
	case -ENOENT:
213
	case -ESHUTDOWN:
214
		/* this urb is terminated, clean up */
215
		dbg("%s - urb shutting down with status: %d",
216
		    __FUNCTION__, urb->status);
217
		return;
218
	default:
219
		dbg("%s - nonzero urb status received: %d",
220
		    __FUNCTION__, urb->status);
221
		goto exit;
222
	}
223
	
224
	xpad_process_packet(xpad, 0, xpad->idata, regs);
225
	
226
exit:
227
	retval = usb_submit_urb(urb, GFP_ATOMIC);
228
	if (retval)
229
		err("%s - usb_submit_urb failed with result %d",
230
		    __FUNCTION__, retval);
231
}
232
233
/*	xpad_init_urb
234
 *
235
 *	initialize the input urb
236
 *	this is to be called when joystick or mouse device are opened
237
 */
238
int xpad_start_urb(struct usb_xpad *xpad)
239
{
240
	int status;
241
	
242
	// check if joystick or mouse device are opened
243
	if (xpad->open_count + xpad->mouse_open_count > 0)
244
		return 0;
245
246
	xpad->irq_in->dev = xpad->udev;
247
	if ((status = usb_submit_urb(xpad->irq_in, GFP_KERNEL))) {
248
		err("open input urb failed: %d", status);
249
		return -EIO;
250
	}
251
	
252
	return 0;
253
}
254
255
/**
256
 *	xpad_open
257
 *
258
 *	Called when a an application opens the device.
259
 */
260
static int xpad_open(struct input_dev *dev)
261
{
262
	struct usb_xpad *xpad = dev->private;
263
	int status;
264
	
265
	if (xpad->open_count)
266
		return 0;
267
		
268
	info("opening device");
269
	
270
	if ((status = xpad_start_urb(xpad)))
271
		return status;
272
		
273
	++xpad->open_count;
274
275
	xpad_rumble_open(xpad);
276
	
277
	return 0;
278
}
279
280
void xpad_stop_urb(struct usb_xpad *xpad)
281
{
282
	if (xpad->open_count + xpad->mouse_open_count > 0)
283
		return;
284
	
285
	usb_unlink_urb(xpad->irq_in);
286
}
287
288
/**
289
 *	xpad_close
290
 *
291
 *	Called when an application closes the device.
292
 */
293
static void xpad_close(struct input_dev *dev)
294
{
295
	struct usb_xpad *xpad = dev->private;
296
	
297
	if (--xpad->open_count)
298
		return;
299
	
300
	info("closing device");
301
	
302
	xpad_stop_urb(xpad);
303
	xpad_rumble_close(xpad);
304
}
305
306
/**	xpad_init_input_device
307
 *
308
 *	setup the input device for the kernel
309
 */
310
static void xpad_init_input_device(struct usb_interface *intf, struct xpad_device device)
311
{
312
	struct usb_xpad *xpad = usb_get_intfdata(intf);
313
	struct usb_device *udev = interface_to_usbdev(intf);
314
	char path[64];
315
	int i;
316
	
317
	xpad->dev.id.bustype = BUS_USB;
318
	xpad->dev.id.vendor = udev->descriptor.idVendor;
319
	xpad->dev.id.product = udev->descriptor.idProduct;
320
	xpad->dev.id.version = udev->descriptor.bcdDevice;
321
	xpad->dev.dev = &intf->dev;
322
	xpad->dev.private = xpad;
323
	xpad->dev.name = device.name;
324
	xpad->dev.phys = xpad->phys;
325
	xpad->dev.open = xpad_open;
326
	xpad->dev.close = xpad_close;
327
	
328
	usb_make_path(udev, path, 64);
329
	snprintf(xpad->phys, 64, "%s/input0", path);
330
	
331
	/* this was meant to allow a user space tool on-the-fly configuration
332
	   of driver options (mouse on, rumble on, etc)
333
	   yet, Vojtech said this is better done using sysfs (linux 2.6)
334
	   plus, it needs a patch to the input subsystem */
335
//	xpad->dev.ioctl = xpad_ioctl;
336
337
	if (xpad->isMat) {
338
		xpad->dev.evbit[0] = BIT(EV_KEY);
339
		for (i = 0; xpad_mat_btn[i] >= 0; ++i)
340
			set_bit(xpad_mat_btn[i], xpad->dev.keybit);
341
	} else {
342
		xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
343
		
344
		for (i = 0; xpad_btn[i] >= 0; ++i)
345
		set_bit(xpad_btn[i], xpad->dev.keybit);
346
		
347
		for (i = 0; xpad_abs[i] >= 0; ++i) {
348
			
349
			signed short t = xpad_abs[i];
350
			
351
			set_bit(t, xpad->dev.absbit);
352
			
353
			switch (t) {
354
			case ABS_X:
355
			case ABS_Y:
356
			case ABS_RX:
357
			case ABS_RY:	/* the two sticks */
358
				xpad->dev.absmax[t] =  32767;
359
				xpad->dev.absmin[t] = -32768;
360
				xpad->dev.absflat[t] = 128;
361
				xpad->dev.absfuzz[t] = 16;
362
				break;
363
			case ABS_Z:	/* left trigger */
364
			case ABS_RZ:	/* right trigger */
365
			case ABS_HAT1X:	/* analogue button A */
366
			case ABS_HAT1Y:	/* analogue button B */
367
			case ABS_HAT2X:	/* analogue button C */
368
			case ABS_HAT2Y:	/* analogue button X */
369
			case ABS_HAT3X:	/* analogue button Y */
370
			case ABS_HAT3Y:	/* analogue button Z */
371
				xpad->dev.absmax[t] = 255;
372
				xpad->dev.absmin[t] = 0;
373
				break;
374
			case ABS_HAT0X:
375
			case ABS_HAT0Y:	/* the d-pad */
376
				xpad->dev.absmax[t] =  1;
377
				xpad->dev.absmin[t] = -1;
378
				break;
379
			}
380
		}
381
		
382
		if (xpad_rumble_probe(udev, xpad, ifnum) != 0)
383
			err("could not init rumble");
384
	}
385
386
	input_register_device(&xpad->dev);
387
	printk(KERN_INFO "input: %s on %s\n", xpad->dev.name, path);
388
}
389
390
/**
391
 *	xpad_probe
392
 *
393
 *	Called upon device detection to find a suitable driver.
394
 *	Must return NULL when no xpad is found, else setup everything.
395
 */
396
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
397
{
398
	struct usb_device *udev = interface_to_usbdev(intf);
399
	struct usb_xpad *xpad = NULL;
400
	struct usb_endpoint_descriptor *ep_irq_in;
401
	int i;
402
	int probedDevNum = -1;	/* this takes the index into the known devices
403
				   array for the recognized device */
404
	
405
	// try to detect the device we are called for
406
	for (i = 0; xpad_device[i].idVendor; ++i) {
407
		if ((udev->descriptor.idVendor == xpad_device[i].idVendor) &&
408
		    (udev->descriptor.idProduct == xpad_device[i].idProduct)) {
409
			probedDevNum = i;
410
			break;
411
		}
412
	}
413
	
414
	// sanity check, did we recognize this device? if not, fail
415
	if ((probedDevNum == -1) || (!xpad_device[probedDevNum].idVendor &&
416
				     !xpad_device[probedDevNum].idProduct))
417
		return -ENODEV;
418
		
419
	if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) {
420
		err("cannot allocate memory for new pad");
421
		return -ENOMEM;
422
	}
423
	memset(xpad, 0, sizeof(struct usb_xpad));
424
	
425
	xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN,
426
				       SLAB_ATOMIC, &xpad->idata_dma);
427
	if (!xpad->idata) {
428
		kfree(xpad);
429
		return -ENOMEM;
430
	}
431
	
432
	/* setup input interrupt pipe (button and axis state) */
433
	xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
434
        if (!xpad->irq_in) {
435
		err("cannot allocate memory for new pad irq urb");
436
		usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
437
                kfree(xpad);
438
                return -ENOMEM;
439
	}
440
	
441
	ep_irq_in = &intf->altsetting[0].endpoint[0].desc;
442
	
443
	xpad->udev = udev;
444
	xpad->isMat = xpad_device[probedDevNum].isMat;
445
	
446
	/* init input URB for USB INT transfer from device */
447
	usb_fill_int_urb(xpad->irq_in, udev,
448
			 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
449
			 xpad->idata, XPAD_PKT_LEN,
450
			 xpad_irq_in, xpad, ep_irq_in->bInterval);
451
	xpad->irq_in->transfer_dma = xpad->idata_dma;
452
	xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
453
	
454
	// we set this here so we can extract it in the two functions below
455
	usb_set_intfdata(intf, xpad);
456
	
457
	xpad_init_input_device(intf, xpad_device[probedDevNum]);
458
	xpad_mouse_init_input_device(intf, xpad_device[probedDevNum]);
459
	
460
	return 0;
461
}
462
463
/**
464
 *	xpad_disconnect
465
 *
466
 *	Called upon device disconnect to dispose of the structures and
467
 *	close the USB connections.
468
 */
469
static void xpad_disconnect(struct usb_interface *intf)
470
{
471
	struct usb_xpad *xpad = usb_get_intfdata(intf);
472
	
473
	usb_set_intfdata(intf, NULL);
474
	if (xpad) {
475
		info( "disconnecting device" );
476
		usb_unlink_urb(xpad->irq_in);
477
		xpad_rumble_close(xpad);
478
		input_unregister_device(&xpad->dev);
479
		
480
		usb_free_urb(xpad->irq_in);
481
		xpad_mouse_cleanup(xpad);
482
		
483
		usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN,
484
				xpad->idata, xpad->idata_dma);
485
	
486
		xpad_rumble_disconnect(xpad);
487
		
488
		kfree(xpad);
489
	}
490
}
491
492
/******************* Linux driver framework specific stuff ************/
493
494
static struct usb_driver xpad_driver = {
495
	.owner		= THIS_MODULE,
496
	.name		= "xpad",
497
	.probe		= xpad_probe,
498
	.disconnect	= xpad_disconnect,
499
	.id_table	= xpad_table,
500
};
501
502
/**
503
 * driver init entry point
504
 */
505
static int __init usb_xpad_init(void)
506
{
507
	int result = usb_register(&xpad_driver);
508
	if (result == 0)
509
		info(DRIVER_DESC " " DRIVER_VERSION);
510
	return result;
511
}
512
513
/**
514
 * driver exit entry point
515
 */
516
static void __exit usb_xpad_exit(void)
517
{
518
	usb_deregister(&xpad_driver);
519
}
520
521
module_init(usb_xpad_init);
522
module_exit(usb_xpad_exit);
523
524
MODULE_AUTHOR(DRIVER_AUTHOR);
525
MODULE_DESCRIPTION(DRIVER_DESC);
526
MODULE_LICENSE("GPL");
527
528
/*
529
 *  driver history
530
 * ----------------
531
 *
532
 * 2003-05-15 - 0.1.2 : ioctls, dynamic mouse/rumble activation, /proc fs
533
 *  - added some /proc files for informational purposes (readonly right now)
534
 *  - added init parameters for mouse/rumble activation upon detection
535
 *  - added dynamic changes to mouse events / rumble effect generation via
536
 *    ioctls - NOTE: this requires a currently unofficial joydev patch!
537
 *
538
 * 2003-04-29 - 0.1.1 : minor cleanups, some comments
539
 *  - fixed incorrect handling of unknown devices (please try ir dongle now)
540
 *  - fixed input URB length (the 256 bytes from 0.1.0 broke everything for the
541
 *    MS controller as well as my Interact device, set back to 32 (please
542
 *    REPORT problems BEFORE any further changes here, since those can be fatal)
543
 *  - fixed rumbling for MS controllers (need 6 bytes output report)
544
 *  - dropped kernel-2.5 ifdefs, much more readable now
545
 *  - preparation for major rework under way, stay tuned
546
 *
547
 * 2003-03-25 - 0.1.0 : (Franz) Some Debuggin
548
 *  - Better Handling
549
 *  - X/Y support, Speed differenting
550
 *  - Landing Zone, Dead Zone, Offset kompensation, Zero-adjustment, .... aso.
551
 *  - Removed Wheel handling in Mouse Emulation .. sensless..
552
 *
553
 * 2003-01-23 - 0.1.0-pre : added mouse emulation and rumble support
554
 *  - can provide mouse emulation (compile time switch)
555
 *    this code has been taken from Oliver Schwartz' xpad-mouse driver
556
 *  - basic rumble support (compile time switch)        EXPERIMENTAL!  
557
 *
558
 * 2002-08-05 - 0.0.6 : added analog button support
559
 *
560
 * 2002-07-17 - 0.0.5 : (Vojtech Pavlik) rework
561
 *  - simplified d-pad handling
562
 *
563
 * 2002-07-16 - 0.0.4 : minor changes, merge with Vojtech's v0.0.3
564
 *  - verified the lack of HID and report descriptors
565
 *  - verified that ALL buttons WORK
566
 *  - fixed d-pad to axes mapping
567
 *
568
 * 2002-07-14 - 0.0.3 : (Vojtech Pavlik) rework
569
 *  - indentation fixes
570
 *  - usb + input init sequence fixes
571
 *
572
 * 2002-07-02 - 0.0.2 : basic working version
573
 *  - all axes and 9 of the 10 buttons work (german InterAct device)
574
 *  - the black button does not work
575
 *
576
 * 2002-06-27 - 0.0.1 : first version, just said "XBOX HID controller"
577
 */
(-)linux-2.6.5.orig/drivers/usb/input/xpad-mouse.c (+270 lines)
Line 0 Link Here
1
/*
2
 * Xbox input device driver for Linux - v0.1.4
3
 *
4
 *	mouse emulation stuff, merged from Olivers xpad-mouse
5
 *
6
 * Copyright (c)  2003, 2004  Marko Friedemann <mfr@bmx-chemnitz.de>
7
 *	portions Copyright (c)	2002  Oliver Schwartz <Oliver.Schwartz@gmx.de>,
8
 *				2003  Franz Lehner <franz@chaos.at>
9
 *
10
 * Released under GPL. See xpad-core.c for details
11
 */
12
13
#include <linux/config.h>
14
#include <linux/kernel.h>
15
#include <linux/init.h>
16
#include <linux/slab.h>
17
#include <linux/module.h>
18
#include <linux/smp_lock.h>
19
#include <linux/proc_fs.h>
20
#include <linux/usb.h>
21
#include <linux/version.h>
22
#include <linux/timer.h>
23
#include <asm/uaccess.h>
24
25
#define __USB_XPAD_MOUSE
26
#include "xpad.h"
27
#undef __USB_XPAD_MOUSE
28
29
#define XPAD_WHEELBRAKE		20
30
#define JOY_DeadZone_fast	6000
31
#define JOY_DeadZone_slow	200
32
#define XPAD_OFFSET_COUNTER	5
33
34
35
static int mouse_on_load = 1;
36
MODULE_PARM( mouse_on_load, "i" );
37
MODULE_PARM_DESC( mouse_on_load, "set to 0 to deactivate mouse support on insmod (default 1)" );
38
39
40
/**
41
 *	xpad_removedeadzone
42
 *
43
 *	Franz? Please clarify and correct.
44
 *
45
 *	Removes the deadzone for mouse operation.
46
 *	Allows for better handling near the stick's center.
47
 */   
48
static int xpad_mouse_removedeadzone(signed int position, int speed, int deadzone)
49
{
50
	if (position>31000) position=31000;
51
	if (position<-31000) position=-31000; 
52
	
53
	if ((position>0)&(position<deadzone)) return 0;
54
	if ((position<0)&(position>(-deadzone))) return 0;
55
56
	if (position>deadzone) position -= deadzone;	
57
	if (position<(-(deadzone))) position+= deadzone;	
58
	position = (int)(position / speed);
59
60
	return position;
61
}
62
63
void xpad_mouse_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
64
{
65
        struct input_dev *dev_mouse = &xpad->dev_mouse;
66
	
67
        int signledirection, xyspeed;
68
        //int joy_y2;
69
	unsigned char MouseLeft,MouseRight, MouseMiddle;
70
        signed int left_joy_x, left_joy_y, right_joy_x, right_joy_y;
71
	
72
	if (!xpad->mouse_open_count || !xpad->mouse_enabled)
73
		return;
74
	
75
	left_joy_x = ((__s16) (((__s16)data[13] << 8) | data[12]));
76
	left_joy_y = ((__s16) (((__s16)data[15] << 8) | data[14]));
77
	
78
	right_joy_x = ((__s16) (((__s16)data[17] << 8) | data[16]));
79
	right_joy_y = ((__s16) (((__s16)data[19] << 8) | data[18]));
80
	
81
	// Creates Offset when first starting
82
	/* CHECKME: who coded this? Franz? Please clarify:
83
		1) is this necessary for joystick operation?
84
		2) offset_counter was only defined when MOUSE
85
		   support was configured (has been FIXED, see above) */
86
	if (xpad->offsetset_compensation>0) {
87
		
88
		if (xpad->offsetset_compensation == XPAD_OFFSET_COUNTER) {
89
			xpad->left_offset_x  = left_joy_x;
90
			xpad->left_offset_y  = left_joy_y;
91
			xpad->right_offset_x = right_joy_x;
92
			xpad->right_offset_y = right_joy_y;  
93
		} else {
94
			xpad->left_offset_x  += left_joy_x;
95
			xpad->left_offset_y  += left_joy_y;
96
			xpad->right_offset_x += right_joy_x;
97
			xpad->right_offset_y += right_joy_y;  
98
		}
99
		
100
		if (xpad->offsetset_compensation == 1) {
101
			xpad->left_offset_x  = xpad->left_offset_x  / XPAD_OFFSET_COUNTER;
102
			xpad->left_offset_y  = xpad->left_offset_y  / XPAD_OFFSET_COUNTER;
103
			xpad->right_offset_x = xpad->right_offset_x / XPAD_OFFSET_COUNTER;
104
			xpad->right_offset_y = xpad->right_offset_y / XPAD_OFFSET_COUNTER;  
105
		}
106
		
107
		xpad->offsetset_compensation--;
108
	}
109
	
110
	left_joy_x -= xpad->left_offset_x;
111
	left_joy_y -= xpad->left_offset_y;
112
	
113
	right_joy_x -= xpad->right_offset_x;
114
	right_joy_y -= xpad->right_offset_y;
115
	
116
	if (data[11]<0x10) {
117
		// Normal Speed Mode
118
		xpad->rel_x =  (xpad_mouse_removedeadzone(left_joy_x,0x1500,JOY_DeadZone_fast));
119
		xpad->rel_y = -(xpad_mouse_removedeadzone(left_joy_y,0x1500,JOY_DeadZone_fast));
120
		xyspeed = 2;
121
		//printk("%d:",xpad->rel_y);
122
	} else {
123
		// Ultra Slow Mode                                                 
124
		xpad->rel_x =  (xpad_mouse_removedeadzone(left_joy_x,0x3500,JOY_DeadZone_slow));
125
		xpad->rel_y = -(xpad_mouse_removedeadzone(left_joy_y,0x3500,JOY_DeadZone_slow));    
126
		xyspeed = 1;
127
	}
128
	
129
	// X-Y Steering
130
	signledirection=1;
131
	if (signledirection&((data[2] & 0x04)!=0)) { signledirection=0; xpad->rel_x -=xyspeed; }
132
	if (signledirection&((data[2] & 0x08)!=0)) { signledirection=0; xpad->rel_x +=xyspeed; }
133
	if (signledirection&((data[2] & 0x02)!=0)) { signledirection=0; xpad->rel_y +=xyspeed; }
134
	if (signledirection&((data[2] & 0x01)!=0)) { signledirection=0; xpad->rel_y -=xyspeed; }
135
  	
136
	/* wheel handling */
137
	//joy_y2 = xpad_mouse_removedeadzone(joy_y2);
138
	//xpad->rel_wheel = (joy_y2>0)?1:(joy_y2<0)?-1:0;
139
	xpad->rel_wheel=0;
140
	
141
	if (data[10]==0xFF) MouseLeft=1; else MouseLeft =0;
142
	if ((MouseLeft==0)&(data[7]!=0)) MouseLeft =1;
143
	if ((MouseLeft==0)&(data[4]!=0)) MouseLeft = 1;
144
	if ((MouseLeft==0)&((data[2] >> 7)!=0)) MouseLeft = 1;
145
	if ((MouseLeft==0)&(((data[2] & 0x40) >> 6)!=0)) MouseLeft = 1;
146
	
147
	if (data[5]!=0) MouseRight=1; else MouseRight=0;
148
	if (data[6]!=0) MouseMiddle =1; else MouseMiddle=0;
149
	
150
	// Generating Mouse Emulation Events  (Button Events)
151
	input_report_key(dev_mouse, BTN_LEFT, MouseLeft);
152
	input_report_key(dev_mouse, BTN_RIGHT, MouseRight);
153
	input_report_key(dev_mouse, BTN_MIDDLE, MouseMiddle);
154
	
155
	input_sync(dev_mouse);
156
}
157
158
/**
159
 *	xpad_timer
160
 *
161
 *	Reports the mouse events in the interval given in xpad_open.
162
 *
163
 *	Taken from Oliver Schwartz' xpad-mouse driver to avoid strange mouse
164
 *	 behaviour encountered when the input events where send directly
165
 *	 in xpad_process_packet.
166
 */
167
static void xpad_timer(unsigned long data)
168
{
169
	struct usb_xpad *xpad = (struct usb_xpad *)data;
170
171
	if (xpad->mouse_enabled) {
172
		input_report_rel(&xpad->dev_mouse, REL_X, xpad->rel_x);
173
		input_report_rel(&xpad->dev_mouse, REL_Y, xpad->rel_y); 
174
		
175
		input_sync(&xpad->dev_mouse);
176
	
177
		/*if (xpad->rel_wheeltimer == 0) {
178
			input_report_rel(&xpad->dev_mouse, REL_WHEEL, xpad->rel_wheel);
179
			xpad->rel_wheeltimer = XPAD_WHEELBRAKE;
180
		} else
181
			xpad->rel_wheeltimer--;*/
182
	}
183
	
184
	// reschedule the timer so that it fires continually
185
	add_timer(&xpad->timer);
186
}
187
188
static int xpad_mouse_open(struct input_dev *dev)
189
{
190
	struct usb_xpad *xpad = dev->private;
191
	int status;
192
	
193
	if (xpad->mouse_open_count)
194
		return 0;
195
	
196
	if ((status = xpad_start_urb(xpad)))
197
		return status;
198
		
199
	++xpad->mouse_open_count;
200
	
201
	info("opening mouse device");
202
203
	// set up timer for mouse event generation
204
	init_timer(&xpad->timer);
205
	xpad->timer.expires = 1*HZ/5; /* every 200 ms */
206
	xpad->timer.data = (unsigned long)xpad;
207
	xpad->timer.function = xpad_timer;
208
	// now start the timer
209
	add_timer(&xpad->timer);
210
	
211
	return 0;
212
}
213
214
static void xpad_mouse_close(struct input_dev *dev)
215
{
216
	struct usb_xpad *xpad = dev->private;
217
	
218
	if (--xpad->mouse_open_count)
219
		return;
220
		
221
	xpad_stop_urb(xpad);
222
	
223
	info("closing mouse device"); 
224
	del_timer(&xpad->timer);
225
}
226
227
int xpad_mouse_init_input_device(struct usb_interface *intf, struct xpad_device device)
228
{
229
	struct usb_xpad *xpad = usb_get_intfdata(intf);
230
	struct usb_device *udev = interface_to_usbdev(intf);
231
232
	/* the mouse device struct for the kernel (mouse emulation) */
233
	xpad->dev_mouse.id.bustype = BUS_USB;
234
	xpad->dev_mouse.id.vendor = udev->descriptor.idVendor;
235
	xpad->dev_mouse.id.product = udev->descriptor.idProduct;
236
	xpad->dev_mouse.id.version = udev->descriptor.bcdDevice;
237
	xpad->dev_mouse.dev = &intf->dev;
238
	xpad->dev_mouse.private = xpad;
239
	xpad->dev_mouse.name = device.name;
240
	xpad->dev_mouse.phys = xpad->phys;
241
	xpad->dev_mouse.open = xpad_mouse_open;
242
	xpad->dev_mouse.close = xpad_mouse_close;
243
	xpad->offsetset_compensation = XPAD_OFFSET_COUNTER; // Find new offset point
244
	xpad->mouse_enabled = mouse_on_load;
245
	
246
	/* mouse setup */
247
	xpad->dev_mouse.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
248
249
	set_bit(REL_X,     xpad->dev_mouse.relbit);
250
	set_bit(REL_Y,     xpad->dev_mouse.relbit);
251
	set_bit(REL_WHEEL, xpad->dev_mouse.relbit);
252
253
	set_bit(BTN_LEFT,   xpad->dev_mouse.keybit);
254
	set_bit(BTN_RIGHT,  xpad->dev_mouse.keybit);
255
	set_bit(BTN_MIDDLE, xpad->dev_mouse.keybit);
256
	set_bit(BTN_SIDE,   xpad->dev_mouse.keybit);
257
	set_bit(BTN_EXTRA,  xpad->dev_mouse.keybit);
258
	
259
	input_register_device(&xpad->dev_mouse);
260
	printk(KERN_INFO "input: mouse emulation %s@ %s\n",
261
	       (mouse_on_load ? "" : "(disabled) "), xpad->dev_mouse.name);
262
}
263
264
void xpad_mouse_cleanup(struct usb_xpad *xpad)
265
{
266
	// the timer exists only when the mouse device is used
267
	if (xpad->mouse_open_count)
268
		del_timer(&xpad->timer);
269
	input_unregister_device(&xpad->dev_mouse);
270
}
(-)linux-2.6.5.orig/drivers/usb/input/xpad.h (+167 lines)
Line 0 Link Here
1
/*
2
 * Xbox Controller driver for Linux - v0.1.4
3
 *
4
 *	header file containing ioctl definitions
5
 *
6
 * Copyright (c)  2003  Marko Friedemann <mfr@bmx-chemnitz.de>
7
 *
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License as
11
 * published by the Free Software Foundation; either version 2 of
12
 * the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
 */
23
 
24
#ifndef __XPAD_h
25
#define __XPAD_h
26
27
28
/*********** ioctl stuff, can be used outside of the driver ***********/
29
#define USB_XPAD_IOC_MAGIC 	'x'
30
31
#define USB_XPAD_IOCRESET 	_IO(  USB_XPAD_IOC_MAGIC, 0 )
32
#define USB_XPAD_IOCSMOUSE 	_IOW( USB_XPAD_IOC_MAGIC, 1, int )
33
#define USB_XPAD_IOCGMOUSE 	_IOR( USB_XPAD_IOC_MAGIC, 2, int )
34
#define USB_XPAD_IOCSRUMBLE 	_IOW( USB_XPAD_IOC_MAGIC, 3, int )
35
#define USB_XPAD_IOCGRUMBLE 	_IOR( USB_XPAD_IOC_MAGIC, 4, int )
36
37
#define USB_XPAD_IOCSIR 	_IOW( USB_XPAD_IOC_MAGIC, 5, int )
38
#define USB_XPAD_IOCGIR 	_IOR( USB_XPAD_IOC_MAGIC, 6, int )
39
40
#define USB_XPAD_IOC_MAXNR 	6
41
42
43
/************************* driver internals ***************************/
44
#ifdef __KERNEL__
45
46
#include <linux/input.h>
47
#include <linux/circ_buf.h>
48
49
/****************** driver description and version ********************/
50
#define DRIVER_VERSION		"v0.1.4"
51
#define DRIVER_AUTHOR		"Marko Friedemann <mfr@bmx-chemnitz.de>,\
52
 Oliver Schwartz <Oliver.Schwartz@gmx.de>, Georg Lukas <georg@op-co.de>"
53
54
#ifdef CONFIG_USB_XPAD_MOUSE
55
#define DRIVER_DESC		"driver for Xbox controllers with mouse emulation"
56
#else
57
#define DRIVER_DESC		"driver for Xbox controllers"
58
#endif
59
60
/****************************** constants *****************************/
61
#define XPAD_MAX_DEVICES	4
62
#define XPAD_PKT_LEN		32	/* input packet size */
63
#define XPAD_PKT_LEN_FF		6	/* output packet size - rumble */
64
65
#define XPAD_TX_BUFSIZE		XPAD_PKT_LEN_FF * 8	/* max. 8 requests */
66
67
/************************* the device struct **************************/
68
struct usb_xpad {
69
	struct input_dev dev;			/* input device interface */
70
	struct usb_device *udev;		/* usb device */
71
	
72
	struct urb *irq_in;			/* urb for int. in report */
73
	unsigned char *idata;			/* input data */
74
	dma_addr_t idata_dma;
75
	
76
	char phys[65];				/* physical input dev path */
77
	
78
	int open_count;				/* reference count */
79
80
	unsigned char offsetset_compensation;
81
	int left_offset_x;
82
	int left_offset_y;
83
	int right_offset_x;
84
	int right_offset_y;
85
	
86
	int isMat;				/* is this a dancepad/mat? */
87
	
88
#ifdef CONFIG_USB_XPAD_RUMBLE
89
	int rumble_enabled;			/* ioctl can toggle rumble */
90
	
91
	int ep_out_adr;				/* number of out endpoint */
92
	unsigned char tx_data[XPAD_PKT_LEN_FF];	/* output data (rumble) */
93
	int strong_rumble, play_strong;		/* strong rumbling */
94
	int weak_rumble, play_weak;		/* weak rumbling */
95
	struct timer_list rumble_timer;		/* timed urb out retry */
96
	wait_queue_head_t wait;			/* wait for URBs on queue */
97
	
98
	spinlock_t tx_lock;
99
	struct circ_buf tx;
100
	unsigned char tx_buf[XPAD_TX_BUFSIZE];
101
	long tx_flags[1];			/* transmit flags */
102
#endif
103
	
104
#ifdef CONFIG_USB_XPAD_MOUSE
105
	struct input_dev dev_mouse;		/* mouse device interface */
106
	int mouse_open_count;			/* reference count */
107
	int mouse_enabled;			/* ioctl can toggle rumble */
108
	
109
	int rel_x;
110
	int rel_y;
111
	int rel_wheel;
112
	int rel_wheeltimer;
113
	struct timer_list timer;		/* timed mouse input events */
114
#endif
115
};
116
117
/* for the list of know devices */
118
struct xpad_device {
119
	u16 idVendor;
120
	u16 idProduct;
121
	u8  isMat;
122
	char *name;
123
};
124
125
#ifdef __USB_XPAD_MOUSE
126
 extern int xpad_start_urb(struct usb_xpad *xpad);
127
 extern void xpad_stop_urb(struct usb_xpad *xpad);
128
#endif
129
130
/************************ mouse function stubs ************************/
131
#ifndef CONFIG_USB_XPAD_MOUSE
132
 #define mouse_open_count open_count
133
 #define xpad_mouse_process_packet(xpad, cmd, data) {}
134
 #define xpad_mouse_init_input_device(intf, device) {}
135
 #define xpad_mouse_cleanup(xpad) {}
136
#else /* CONFIG_USB_XPAD_MOUSE */
137
 #ifndef __USB_XPAD_MOUSE
138
  extern void xpad_mouse_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data);
139
  extern void xpad_mouse_init_input_device(struct usb_interface *intf, struct xpad_device device);
140
  extern void xpad_mouse_cleanup(struct usb_xpad *xpad);
141
 #endif /* __USB_XPAD_MOUSE */
142
#endif /* CONFIG_USB_XPAD_MOUSE */
143
144
/************************ rumble function stubs ***********************/
145
#ifndef CONFIG_USB_XPAD_RUMBLE
146
 #define xpad_rumble_ioctl(dev, cmd, arg) -ENOTTY
147
 #define xpad_rumble_open(xpad) {}
148
 #define xpad_rumble_probe(udev, xpad, ifnum) 0
149
 #define xpad_rumble_close(xpad) {}
150
 #define xpad_rumble_disconnect(xpad) {}
151
#else /* CONFIG_USB_XPAD_RUMBLE */
152
153
 #define XPAD_TX_RUNNING	0
154
 #define XPAD_TX_INC(var, n)	(var) += n; (var) %= XPAD_TX_BUFSIZE
155
156
 #ifndef __USB_XPAD_RUMBLE
157
  extern int  xpad_rumble_ioctl(struct input_dev *dev, unsigned int cmd, unsigned long arg);
158
  extern void xpad_rumble_open(struct usb_xpad *xpad);
159
  extern int  xpad_rumble_probe(struct usb_device *udev, struct usb_xpad *xpad, unsigned int ifnum);
160
  extern void xpad_rumble_close(struct usb_xpad *xpad);
161
  extern void xpad_rumble_disconnect(struct usb_xpad *xpad);
162
 #endif /* __USB_XPAD_RUMBLE */
163
#endif /* CONFIG_USB_XPAD_RUMBLE */
164
165
#endif /* __KERNEL__ */
166
167
#endif /* __XPAD_h */
(-)linux-2.6.5.orig/drivers/video/Kconfig (+10 lines)
Lines 405-410 Link Here
405
	  To compile this driver as a module, choose M here: the
405
	  To compile this driver as a module, choose M here: the
406
	  module will be called rivafb.
406
	  module will be called rivafb.
407
407
408
config FB_XBOX
409
	tristate "nVidia Xbox support"
410
	depends on FB && PCI && I2C_XBOX && EXPERIMENTAL
411
	help
412
	  This driver supports the graphics chip of the Microsoft Xbox. 
413
	  Say Y if you have an Xbox, N otherwise
414
415
	  To compile this driver as a module, choose M here: the
416
	  module will be called xboxfb.
417
408
config FB_I810
418
config FB_I810
409
	tristate "Intel 810/815 support (EXPERIMENTAL)"
419
	tristate "Intel 810/815 support (EXPERIMENTAL)"
410
	depends on FB && AGP && AGP_INTEL && EXPERIMENTAL && PCI	
420
	depends on FB && AGP && AGP_INTEL && EXPERIMENTAL && PCI	
(-)linux-2.6.5.orig/drivers/video/Makefile (+1 lines)
Lines 56-61 Link Here
56
56
57
obj-$(CONFIG_FB_MATROX)		  += matrox/ cfbfillrect.o cfbcopyarea.o cfbimgblt.o
57
obj-$(CONFIG_FB_MATROX)		  += matrox/ cfbfillrect.o cfbcopyarea.o cfbimgblt.o
58
obj-$(CONFIG_FB_RIVA)		  += riva/ cfbimgblt.o vgastate.o 
58
obj-$(CONFIG_FB_RIVA)		  += riva/ cfbimgblt.o vgastate.o 
59
obj-$(CONFIG_FB_XBOX)		  += xbox/ cfbimgblt.o vgastate.o 
59
obj-$(CONFIG_FB_SIS)		  += sis/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o
60
obj-$(CONFIG_FB_SIS)		  += sis/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o
60
obj-$(CONFIG_FB_ATY)		  += aty/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o
61
obj-$(CONFIG_FB_ATY)		  += aty/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o
61
obj-$(CONFIG_FB_ATY128)		  += aty/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o
62
obj-$(CONFIG_FB_ATY128)		  += aty/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o
(-)linux-2.6.5.orig/drivers/video/fbmem.c (+5 lines)
Lines 120-125 Link Here
120
extern int sgivwfb_setup(char*);
120
extern int sgivwfb_setup(char*);
121
extern int rivafb_init(void);
121
extern int rivafb_init(void);
122
extern int rivafb_setup(char*);
122
extern int rivafb_setup(char*);
123
extern int xboxfb_init(void);
124
extern int xboxfb_setup(char*);
123
extern int tdfxfb_init(void);
125
extern int tdfxfb_init(void);
124
extern int tdfxfb_setup(char*);
126
extern int tdfxfb_setup(char*);
125
extern int tridentfb_init(void);
127
extern int tridentfb_init(void);
Lines 215-220 Link Here
215
#ifdef CONFIG_FB_RIVA
217
#ifdef CONFIG_FB_RIVA
216
	{ "rivafb", rivafb_init, rivafb_setup },
218
	{ "rivafb", rivafb_init, rivafb_setup },
217
#endif
219
#endif
220
#ifdef CONFIG_FB_XBOX
221
	{ "xboxfb", xboxfb_init, xboxfb_setup },
222
#endif
218
#ifdef CONFIG_FB_3DFX
223
#ifdef CONFIG_FB_3DFX
219
	{ "tdfxfb", tdfxfb_init, tdfxfb_setup },
224
	{ "tdfxfb", tdfxfb_init, tdfxfb_setup },
220
#endif
225
#endif
(-)linux-2.6.5.orig/drivers/video/xbox/Makefile (+7 lines)
Line 0 Link Here
1
#
2
# Makefile for the Xbox framebuffer driver
3
#
4
5
obj-$(CONFIG_FB_XBOX) += xboxfb.o
6
7
xboxfb-objs := fbdev.o riva_hw.o nv_driver.o encoder-i2c.o encoder.o focus.o conexant.o
(-)linux-2.6.5.orig/drivers/video/xbox/conexant.c (+639 lines)
Line 0 Link Here
1
/*
2
 * linux/drivers/video/riva/conexant.c - Xbox driver for conexant chip
3
 *
4
 * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de>
5
 *
6
 * Contributors:
7
 * 
8
 * This file is subject to the terms and conditions of the GNU General Public
9
 * License.  See the file COPYING in the main directory of this archive
10
 * for more details.
11
 *
12
 * Known bugs and issues:
13
 *
14
 *      none
15
 */
16
17
#include "conexant.h"
18
#include "focus.h"
19
20
#define ADR(x) (x / 2 - 0x17)
21
22
typedef struct {
23
	long v_activeo;
24
	long v_linesi;
25
	long h_clki;
26
	long h_clko;
27
	long h_blanki;
28
	long h_blanko;
29
	long v_blanki;
30
	long v_blanko;
31
	long vscale;
32
	double clk_ratio;
33
} xbox_tv_mode_parameter;
34
35
36
	// and here is all the video timing for every standard
37
38
static const conexant_video_parameter vidstda[] = {
39
	{ 3579545.00, 0.0000053, 0.00000782, 0.0000047, 0.000063555, 0.0000094, 0.000035667, 0.0000015, 243, 262.5, 0.0000092 },
40
	{ 3579545.00, 0.0000053, 0.00000782, 0.0000047, 0.000064000, 0.0000094, 0.000035667, 0.0000015, 243, 262.5, 0.0000092 },
41
	{ 4433618.75, 0.0000056, 0.00000785, 0.0000047, 0.000064000, 0.0000105, 0.000036407, 0.0000015, 288, 312.5, 0.0000105 },
42
	{ 4433618.75, 0.0000056, 0.00000785, 0.0000047, 0.000064000, 0.0000094, 0.000035667, 0.0000015, 288, 312.5, 0.0000092 },
43
	{ 3582056.25, 0.0000056, 0.00000811, 0.0000047, 0.000064000, 0.0000105, 0.000036407, 0.0000015, 288, 312.5, 0.0000105 },
44
	{ 3575611.88, 0.0000058, 0.00000832, 0.0000047, 0.000063555, 0.0000094, 0.000035667, 0.0000015, 243, 262.5, 0.0000092 },
45
	{ 4433619.49, 0.0000053, 0.00000755, 0.0000047, 0.000063555, 0.0000105, 0.000036407, 0.0000015, 243, 262.5, 0.0000092 }
46
};
47
48
static const unsigned char default_mode[] = {
49
	0x00,
50
	0x00, 0x28, 0x80, 0xE4, 0x00, 0x00, 0x80, 0x80,
51
	0x80, 0x13, 0xDA, 0x4B, 0x28, 0xA3, 0x9F, 0x25,
52
	0xA3, 0x9F, 0x25, 0x00, 0x00, 0x00, 0x00, 0x44,
53
	0xC7, 0x00, 0x00, 0x41, 0x35, 0x03, 0x46, 0x00,
54
	0x02, 0x00, 0x01, 0x60, 0x88, 0x8a, 0xa6, 0x68,
55
	0xc1, 0x2e, 0xf2, 0x27, 0x00, 0xb0, 0x0a, 0x0b,
56
	0x71, 0x5a, 0xe0, 0x36, 0x00, 0x50, 0x72, 0x1c,
57
	0x0d, 0x24, 0xf0, 0x58, 0x81, 0x49, 0x8c, 0x0c,
58
	0x8c, 0x79, 0x26, 0x52, 0x00, 0x24, 0x00, 0x00,
59
	0x00, 0x00, 0x01, 0x9C, 0x9B, 0xC0, 0xC0, 0x19,
60
	0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x57, 0x20,
61
	0x40, 0x6E, 0x7E, 0xF4, 0x51, 0x0F, 0xF1, 0x05,
62
	0xD3, 0x78, 0xA2, 0x25, 0x54, 0xA5, 0x00, 0x00
63
};
64
65
static const double pll_base = 13.5e6;
66
67
static void conexant_calc_blankings(
68
	xbox_video_mode * mode,
69
	xbox_tv_mode_parameter * param
70
);
71
72
static int conexant_calc_mode_params(
73
	xbox_video_mode * mode,
74
	xbox_tv_mode_parameter * param
75
);
76
77
static double fabs(double d) {
78
	if (d > 0) return d;
79
	else return -d;
80
}
81
82
int conexant_calc_vga_mode(
83
	xbox_av_type av_type,
84
	unsigned char pll_int,
85
	unsigned char * regs
86
){
87
	memset(regs, 0, NUM_CONEXANT_REGS);
88
	// Protect against overclocking
89
	if (pll_int > 36) {
90
		pll_int = 36; // 36 / 6 * 13.5 MHz = 81 MHz, just above the limit.
91
	}
92
	if (pll_int == 0) {
93
		pll_int = 1;  // 0 will cause a burnout ...
94
	}
95
	if (av_type == AV_VGA) {
96
		// use internal sync signals
97
		regs[ADR(0x2e)] = 0xbd; // HDTV_EN = 1, RPR_SYNC_DIS = 1, BPB_SYNC_DIS = 1, GY_SYNC_DIS=1, HD_SYNC_EDGE = 1, RASTER_SEL = 01
98
	}
99
	else {
100
 		// use sync on green
101
		regs[ADR(0x2e)] = 0xad; // HDTV_EN = 1, RPR_SYNC_DIS = 1, BPB_SYNC_DIS = 1, HD_SYNC_EDGE = 1, RASTER_SEL = 01
102
	}
103
	regs[ADR(0x32)] = 0x48; // DRVS = 2, IN_MODE[3] = 1;
104
	regs[ADR(0x3c)] = 0x80; // MCOMPY
105
	regs[ADR(0x3e)] = 0x80; // MCOMPU
106
	regs[ADR(0x40)] = 0x80; // MCOMPV
107
	regs[ADR(0xc6)] = 0x98; // IN_MODE = 24 bit RGB multiplexed
108
	regs[ADR(0x6c)] = 0x46; // FLD_MODE = 10, EACTIVE = 1, EN_SCART = 0, EN_REG_RD = 1
109
	regs[ADR(0x9c)] = 0x00; // PLL_FRACT
110
	regs[ADR(0x9e)] = 0x00; // PLL_FRACT
111
	regs[ADR(0xa0)] = pll_int; // PLL_INT
112
	regs[ADR(0xba)] = 0x28; // SLAVER = 1, DACDISD = 1
113
	regs[ADR(0xce)] = 0xe1; // OUT_MUXA = 01, OUT_MUXB = 00, OUT_MUXC = 10, OUT_MUXD = 11
114
	regs[ADR(0xd6)] = 0x0c; // OUT_MODE = 11 (RGB / SCART / HDTV)
115
116
	return 1;
117
}
118
119
int conexant_calc_hdtv_mode(
120
	xbox_hdtv_mode hdtv_mode,
121
	unsigned char pll_int,
122
	unsigned char * regs
123
){
124
	memset(regs, 0, NUM_CONEXANT_REGS);
125
	// Protect against overclocking
126
	if (pll_int > 36) {
127
		pll_int = 36; // 36 / 6 * 13.5 MHz = 81 MHz, just above the limit.
128
	}
129
	if (pll_int == 0) {
130
		pll_int = 1;  // 0 will cause a burnout ...
131
	}
132
	switch (hdtv_mode) {
133
		case HDTV_480p:
134
			// use sync on green
135
			regs[ADR(0x2e)] = 0xed; // HDTV_EN = 1, RGB2PRPB = 1, RPR_SYNC_DIS = 1, BPB_SYNC_DIS = 1, HD_SYNC_EDGE = 1, RASTER_SEL = 01
136
			regs[ADR(0x32)] = 0x48; // DRVS = 2, IN_MODE[3] = 1;
137
			regs[ADR(0x3e)] = 0x45; // MCOMPU
138
			regs[ADR(0x40)] = 0x51; // MCOMPV
139
			break;
140
		case HDTV_720p:
141
			// use sync on green
142
			regs[ADR(0x2e)] = 0xea; // HDTV_EN = 1, RGB2PRPB = 1, RPR_SYNC_DIS = 1, BPB_SYNC_DIS = 1, HD_SYNC_EDGE = 1, RASTER_SEL = 01
143
			regs[ADR(0x32)] = 0x49; // DRVS = 2, IN_MODE[3] = 1, CSC_SEL=1;
144
			regs[ADR(0x3e)] = 0x45; // MCOMPU
145
			regs[ADR(0x40)] = 0x51; // MCOMPV
146
			break;
147
		case HDTV_1080i:
148
			// use sync on green
149
			regs[ADR(0x2e)] = 0xeb; // HDTV_EN = 1, RGB2PRPB = 1, RPR_SYNC_DIS = 1, BPB_SYNC_DIS = 1, HD_SYNC_EDGE = 1, RASTER_SEL = 01
150
			regs[ADR(0x32)] = 0x49; // DRVS = 2, IN_MODE[3] = 1, CSC_SEL=1;
151
			regs[ADR(0x3e)] = 0x48; // MCOMPU
152
			regs[ADR(0x40)] = 0x5b; // MCOMPV
153
			break;
154
	}
155
	regs[ADR(0x3c)] = 0x80; // MCOMPY
156
	regs[ADR(0xa0)] = pll_int; // PLL_INT
157
	regs[ADR(0xc6)] = 0x98; // IN_MODE = 24 bit RGB multiplexed
158
	regs[ADR(0x6c)] = 0x46; // FLD_MODE = 10, EACTIVE = 1, EN_SCART = 0, EN_REG_RD = 1
159
	regs[ADR(0x9c)] = 0x00; // PLL_FRACT
160
	regs[ADR(0x9e)] = 0x00; // PLL_FRACT
161
	regs[ADR(0xba)] = 0x28; // SLAVER = 1, DACDISD = 1
162
	regs[ADR(0xce)] = 0xe1; // OUT_MUXA = 01, OUT_MUXB = 00, OUT_MUXC = 10, OUT_MUXD = 11
163
	regs[ADR(0xd6)] = 0x0c; // OUT_MODE = 11 (RGB / SCART / HDTV)
164
165
	return 1;
166
}
167
168
int conexant_calc_mode(xbox_video_mode * mode, struct riva_regs * riva_out)
169
{
170
	unsigned char b;
171
	unsigned int m = 0;
172
	double dPllOutputFrequency;
173
	xbox_tv_mode_parameter param;
174
	char* regs = riva_out->encoder_mode;
175
176
	if (conexant_calc_mode_params(mode, &param))
177
	{
178
		// copy default mode settings
179
		memcpy(regs,default_mode,sizeof(default_mode));
180
181
		regs[ADR(0x32)] = 0x28; // DRVS = 1, IN_MODE[3] = 1;
182
183
		// H_CLKI
184
		b=regs[ADR(0x8e)]&(~0x07);
185
		regs[ADR(0x8e)] = ((param.h_clki>>8)&0x07)|b;
186
		regs[ADR(0x8a)] = ((param.h_clki)&0xff);
187
		// H_CLKO
188
		b=regs[ADR(0x86)]&(~0x0f);
189
		regs[ADR(0x86)] = ((param.h_clko>>8)&0x0f)|b;
190
		regs[ADR(0x76)] = ((param.h_clko)&0xff);
191
		// V_LINESI
192
		b=regs[ADR(0x38)]&(~0x02);
193
		regs[ADR(0x38)] = ((param.v_linesi>>9)&0x02)|b;
194
		b=regs[ADR(0x96)]&(~0x03);
195
		regs[ADR(0x96)] = ((param.v_linesi>>8)&0x03)|b;
196
		regs[ADR(0x90)] = ((param.v_linesi)&0xff);
197
		// V_ACTIVEO
198
		/* TODO: Absolutely not sure about other modes than plain NTSC / PAL */
199
		switch(mode->tv_encoding) {
200
			case TV_ENC_NTSC:
201
			case TV_ENC_NTSC60:
202
			case TV_ENC_PALM:
203
			case TV_ENC_PAL60:
204
				m=param.v_activeo + 1;
205
				break;
206
			case TV_ENC_PALBDGHI:
207
				m=param.v_activeo + 2;
208
				break;
209
			default:
210
				m=param.v_activeo + 2;
211
				break;
212
		}
213
		b=regs[ADR(0x86)]&(~0x80);
214
		regs[ADR(0x86)] = ((m>>1)&0x80)|b;
215
		regs[ADR(0x84)] = ((m)&0xff);
216
		// H_ACTIVE
217
		b=regs[ADR(0x86)]&(~0x70);
218
		regs[ADR(0x86)] = (((mode->xres + 5)>>4)&0x70)|b;
219
		regs[ADR(0x78)] = ((mode->xres + 5)&0xff);
220
		// V_ACTIVEI
221
		b=regs[ADR(0x96)]&(~0x0c);
222
		regs[ADR(0x96)] = ((mode->yres>>6)&0x0c)|b;
223
		regs[ADR(0x94)] = ((mode->yres)&0xff);
224
		// H_BLANKI
225
		b=regs[ADR(0x38)]&(~0x01);
226
		regs[ADR(0x38)] = ((param.h_blanki>>9)&0x01)|b;
227
		b=regs[ADR(0x8e)]&(~0x08);
228
		regs[ADR(0x8e)] = ((param.h_blanki>>5)&0x08)|b;
229
		regs[ADR(0x8c)] = ((param.h_blanki)&0xff);
230
		// H_BLANKO
231
		b=regs[ADR(0x9a)]&(~0xc0);
232
		regs[ADR(0x9a)] = ((param.h_blanko>>2)&0xc0)|b;
233
		regs[ADR(0x80)] = ((param.h_blanko)&0xff);
234
235
		// V_SCALE
236
		b=regs[ADR(0x9a)]&(~0x3f);
237
		regs[ADR(0x9a)] = ((param.vscale>>8)&0x3f)|b;
238
		regs[ADR(0x98)] = ((param.vscale)&0xff);
239
		// V_BLANKO
240
		regs[ADR(0x82)] = ((param.v_blanko)&0xff);
241
		// V_BLANKI
242
		regs[ADR(0x92)] = ((param.v_blanki)&0xff);
243
		{
244
			unsigned int dwPllRatio, dwFract, dwInt;
245
			// adjust PLL
246
			dwPllRatio = (int)(6.0 * ((double)param.h_clko / vidstda[mode->tv_encoding].m_dSecHsyncPeriod) *
247
				param.clk_ratio * 0x10000 / pll_base + 0.5);
248
			dwInt = dwPllRatio / 0x10000;
249
			dwFract = dwPllRatio - (dwInt * 0x10000);
250
			b=regs[ADR(0xa0)]&(~0x3f);
251
			regs[ADR(0xa0)] = ((dwInt)&0x3f)|b;
252
			regs[ADR(0x9e)] = ((dwFract>>8)&0xff);
253
			regs[ADR(0x9c)] = ((dwFract)&0xff);
254
			// recalc value
255
			dPllOutputFrequency = ((double)dwInt + ((double)dwFract)/65536.0)/(6 * param.clk_ratio / pll_base);
256
			// enable 3:2 clocking mode
257
			b=regs[ADR(0x38)]&(~0x20);
258
			if (param.clk_ratio > 1.1) {
259
				b |= 0x20;
260
			}
261
			regs[ADR(0x38)] = b;
262
263
			// update burst start position
264
			m=(vidstda[mode->tv_encoding].m_dSecBurstStart) * dPllOutputFrequency + 0.5;
265
			b=regs[ADR(0x38)]&(~0x04);
266
			regs[ADR(0x38)] = ((m>>6)&0x04)|b;
267
			regs[ADR(0x7c)] = (m&0xff);
268
			// update burst end position (note +128 is in hardware)
269
			m=(vidstda[mode->tv_encoding].m_dSecBurstEnd) * dPllOutputFrequency + 0.5;
270
			if(m<128) m=128;
271
			b=regs[ADR(0x38)]&(~0x08);
272
			regs[ADR(0x38)] = (((m-128)>>5)&0x08)|b;
273
			regs[ADR(0x7e)] = ((m-128)&0xff);
274
			// update HSYNC width
275
			m=(vidstda[mode->tv_encoding].m_dSecHsyncWidth) * dPllOutputFrequency + 0.5;
276
			regs[ADR(0x7a)] = ((m)&0xff);
277
		}
278
		// adjust Subcarrier generation increment
279
		{
280
			unsigned int dwSubcarrierIncrement = (unsigned int) (
281
				(65536.0 * 65536.0) * (
282
					vidstda[mode->tv_encoding].m_dHzBurstFrequency
283
					* vidstda[mode->tv_encoding].m_dSecHsyncPeriod
284
					/ (double)param.h_clko
285
				) + 0.5
286
			);
287
			regs[ADR(0xae)] = (dwSubcarrierIncrement&0xff);
288
			regs[ADR(0xb0)] = ((dwSubcarrierIncrement>>8)&0xff);
289
			regs[ADR(0xb2)] = ((dwSubcarrierIncrement>>16)&0xff);
290
			regs[ADR(0xb4)] = ((dwSubcarrierIncrement>>24)&0xff);
291
		}
292
		// adjust WSS increment
293
		{
294
			unsigned int dwWssIncrement = 0;
295
296
			switch(mode->tv_encoding) {
297
				case TV_ENC_NTSC:
298
				case TV_ENC_NTSC60:
299
					dwWssIncrement=(unsigned int) ((1048576.0 / ( 0.000002234 * dPllOutputFrequency))+0.5);
300
					break;
301
				case TV_ENC_PALBDGHI:
302
				case TV_ENC_PALN:
303
				case TV_ENC_PALNC:
304
				case TV_ENC_PALM:
305
				case TV_ENC_PAL60:
306
					dwWssIncrement=(unsigned int) ((1048576.0 / ( 0.0000002 * dPllOutputFrequency))+0.5);
307
					break;
308
				default:
309
					break;
310
				}
311
312
			regs[ADR(0x66)] = (dwWssIncrement&0xff);
313
			regs[ADR(0x68)] = ((dwWssIncrement>>8)&0xff);
314
			regs[ADR(0x6a)] = ((dwWssIncrement>>16)&0xf);
315
		}
316
		// set mode register
317
		b=regs[ADR(0xa2)]&(0x41);
318
		switch(mode->tv_encoding) {
319
				case TV_ENC_NTSC:
320
					b |= 0x0a; // SETUP + VSYNC_DUR
321
					break;
322
				case TV_ENC_NTSC60:
323
					b |= 0x08; // VSYNC_DUR
324
					break;
325
				case TV_ENC_PALBDGHI:
326
				case TV_ENC_PALNC:
327
						b |= 0x24; // PAL_MD + 625LINE
328
					break;
329
				case TV_ENC_PALN:
330
					b |= 0x2e; // PAL_MD + SETUP + 625LINE + VSYNC_DUR
331
					break;
332
				case TV_ENC_PALM:
333
					b |= 0x2a; // PAL_MD + SETUP + VSYNC_DUR
334
					break;
335
				case TV_ENC_PAL60:
336
					b |= 0x28; // PAL_MD + VSYNC_DUR
337
					break;
338
				default:
339
					break;
340
		}
341
		regs[ADR(0xa2)] = b;
342
		regs[ADR(0xc6)] = 0x98; // IN_MODE = 24 bit RGB multiplexed
343
		switch(mode->av_type) {
344
			case AV_COMPOSITE:
345
			case AV_SVIDEO:
346
				regs[ADR(0x2e)] |= 0x40; // RGB2YPRPB = 1
347
				regs[ADR(0x6c)] = 0x46; // FLD_MODE = 10, EACTIVE = 1, EN_SCART = 0, EN_REG_RD = 1
348
				regs[ADR(0x5a)] = 0x00; // Y_OFF (Brightness)
349
				regs[ADR(0xa4)] = 0xe5; // SYNC_AMP
350
				regs[ADR(0xa6)] = 0x74; // BST_AMP
351
				regs[ADR(0xba)] = 0x24; // SLAVER = 1, DACDISC = 1
352
				regs[ADR(0xce)] = 0x19; // OUT_MUXA = 01, OUT_MUXB = 10, OUT_MUXC = 10, OUT_MUXD = 00
353
				regs[ADR(0xd6)] = 0x00; // OUT_MODE = 00 (CVBS)
354
				break;
355
			case AV_SCART_RGB:
356
				regs[ADR(0x6c)] = 0x4e; // FLD_MODE = 10, EACTIVE = 1, EN_SCART = 1, EN_REG_RD = 1
357
				regs[ADR(0x5a)] = 0xff; // Y_OFF (Brightness)
358
				regs[ADR(0xa4)] = 0xe7; // SYNC_AMP
359
				regs[ADR(0xa6)] = 0x77; // BST_AMP
360
				regs[ADR(0xba)] = 0x20; // SLAVER = 1, enable all DACs
361
				regs[ADR(0xce)] = 0xe1; // OUT_MUXA = 01, OUT_MUXB = 00, OUT_MUXC = 10, OUT_MUXD = 11
362
				regs[ADR(0xd6)] = 0x0c; // OUT_MODE = 11 (RGB / SCART / HDTV)
363
				break;
364
			default:
365
				break;
366
		}
367
		riva_out->ext.vend = mode->yres;
368
		riva_out->ext.vtotal = param.v_linesi - 1;
369
		riva_out->ext.vcrtc = mode->yres;
370
		riva_out->ext.vsyncstart = param.v_linesi - param.v_blanki;
371
		riva_out->ext.vsyncend = riva_out->ext.vsyncstart + 3;
372
		riva_out->ext.vvalidstart = 0;
373
		riva_out->ext.vvalidend = mode->yres;
374
		riva_out->ext.hend = mode->xres + 7;
375
		riva_out->ext.htotal = param.h_clki - 1;
376
		riva_out->ext.hcrtc = mode->xres - 1;
377
		riva_out->ext.hsyncstart = param.h_clki - param.h_blanki - 7;
378
		riva_out->ext.hsyncend = riva_out->ext.hsyncstart + 32;
379
		riva_out->ext.hvalidstart = 0;
380
		riva_out->ext.hvalidend = mode->xres - 1;
381
		riva_out->ext.crtchdispend = mode->xres + 8;
382
		riva_out->ext.crtcvstart = mode->yres + 34;
383
		riva_out->ext.crtcvtotal = param.v_linesi + 32;
384
		return 1;
385
	}
386
	else
387
	{
388
		return 0;
389
	}
390
}
391
392
static int conexant_calc_mode_params(
393
	xbox_video_mode * mode,
394
	xbox_tv_mode_parameter * param
395
){
396
	const double dMinHBT = 2.5e-6; // 2.5uSec time for horizontal syncing
397
	const double invalidMetric = 1000;
398
399
	/* algorithm shamelessly ripped from nvtv/calc_bt.c */
400
	double dTempVOC = 0;
401
	double dTempHOC = 0;
402
	double dBestMetric = invalidMetric;
403
	double dTempVSR = 0;
404
	double dBestVSR = 0;
405
	double dTempCLKRATIO = 1;
406
	double dBestCLKRATIO = 1;
407
	unsigned int  minTLI = 0;
408
	unsigned int  maxTLI = 0;
409
	unsigned int  tempTLI = 0;
410
	unsigned int  bestTLI = 0;
411
	unsigned int  minHCLKO = 0;
412
	unsigned int  maxHCLKO = 0;
413
	unsigned int  minHCLKI = 0;
414
	unsigned int  tempHCLKI = 0;
415
	unsigned int  bestHCLKI = 0;
416
	int    actCLKRATIO;
417
	unsigned int  dTempHCLKO = 0;
418
	double dTempVACTIVEO = 0;
419
	double dDelta = 0;
420
	double dMetric = 0;
421
	double alo =  vidstda[mode->tv_encoding].m_dwALO;
422
	double tlo =  vidstda[mode->tv_encoding].m_TotalLinesOut;
423
	double tto = vidstda[mode->tv_encoding].m_dSecHsyncPeriod;
424
	double ato = tto - (vidstda[mode->tv_encoding].m_dSecBlankBeginToHsync + vidstda[mode->tv_encoding].m_dSecActiveBegin);
425
426
	/* Range to search */
427
	double dMinHOC = mode->hoc - 0.02;
428
	double dMaxHOC = mode->hoc + 0.02;
429
	double dMinVOC = mode->voc - 0.02;
430
	double dMaxVOC = mode->voc + 0.02;
431
432
	if (dMinHOC < 0) dMinHOC = 0;
433
	if (dMinVOC < 0) dMinVOC = 0;
434
435
	minTLI= (unsigned int)(mode->yres / ((1 - dMinVOC) * alo) * tlo);
436
	maxTLI = min((unsigned int)(mode->yres / ((1 - dMaxVOC) * alo) * tlo), (unsigned int)1023);
437
	minHCLKO = (unsigned int) ((mode->xres * 2) /
438
				((1 - dMinHOC) * (ato / tto)));
439
	maxHCLKO = (unsigned int) ((mode->xres * 2) /
440
				((1 - dMaxHOC) * (ato / tto)));
441
	for (actCLKRATIO = 0; actCLKRATIO <= 1; actCLKRATIO++)
442
	{
443
		dTempCLKRATIO = 1.0;
444
		if (actCLKRATIO) dTempCLKRATIO = 3.0/2.0;
445
		for(tempTLI = minTLI; tempTLI <= maxTLI; tempTLI++)
446
		{
447
			dTempVSR = (double)tempTLI / tlo;
448
			dTempVACTIVEO = (int)((((double)mode->yres * tlo) +
449
						(tempTLI - 1)) / tempTLI);
450
			dTempVOC = 1 - dTempVACTIVEO / alo;
451
452
			for(dTempHCLKO = minHCLKO; dTempHCLKO <= maxHCLKO; dTempHCLKO++)
453
			{
454
				tempHCLKI = (unsigned int)((dTempHCLKO * dTempCLKRATIO) * (tlo / tempTLI) + 0.5);
455
				minHCLKI = ((dMinHBT / tto) * tempHCLKI) + mode->xres;
456
				// check if solution is valid
457
				if ((fabs((double)(tempTLI * tempHCLKI) - (tlo * dTempHCLKO * dTempCLKRATIO)) < 1e-3) &&
458
					(tempHCLKI >= minHCLKI) && (tempHCLKI < 2048))
459
				{
460
					dTempHOC = 1 - (((double)mode->xres / ((double)dTempHCLKO / 2)) /
461
						(ato / tto));
462
					dDelta = fabs(dTempHOC - mode->hoc) + fabs(dTempVOC - mode->voc);
463
					dMetric = ((dTempHOC - mode->hoc) * (dTempHOC - mode->hoc)) +
464
						((dTempVOC - mode->voc) * (dTempVOC - mode->voc)) +
465
						(2 * dDelta * dDelta);
466
					if(dMetric < dBestMetric)
467
					{
468
						dBestVSR = dTempVSR;
469
						dBestMetric = dMetric;
470
						bestTLI = tempTLI;
471
						bestHCLKI = tempHCLKI;
472
						dBestCLKRATIO = dTempCLKRATIO;
473
					}
474
				} /* valid solution */
475
			} /* dTempHCLKO loop */
476
		} /* tempTLI loop */
477
	} /* CLKRATIO loop */
478
479
	if(dBestMetric != invalidMetric)
480
	{
481
		param->v_linesi = bestTLI;
482
		param->h_clki = bestHCLKI;
483
		param->clk_ratio = dBestCLKRATIO;
484
		param->v_activeo = (unsigned int)(
485
			(
486
				(mode->yres * vidstda[mode->tv_encoding].m_TotalLinesOut)
487
				+ param->v_linesi - 1
488
			) / param->v_linesi
489
		);
490
		param->h_clko = (unsigned int)(
491
			(
492
				(param->v_linesi * param->h_clki) /
493
				(vidstda[mode->tv_encoding].m_TotalLinesOut * param->clk_ratio)
494
			)
495
			+ 0.5
496
		);
497
		conexant_calc_blankings(mode, param);
498
		return 1;
499
	}
500
	else
501
	{
502
		return 0;
503
	}
504
}
505
506
static void conexant_calc_blankings(
507
	xbox_video_mode * mode,
508
	xbox_tv_mode_parameter * param
509
){
510
	double dTotalHBlankI;
511
	double dFrontPorchIn;
512
	double dFrontPorchOut;
513
	double dMinFrontPorchIn;
514
	double dBackPorchIn;
515
	double dBackPorchOut;
516
	double dTotalHBlankO;
517
	double dHeadRoom;
518
	double dMaxHsyncDrift;
519
	double dFifoMargin;
520
	double vsrq;
521
	double dMaxHR;
522
	double tlo =  vidstda[mode->tv_encoding].m_TotalLinesOut;
523
	const int MFP = 14; // Minimum front porch
524
	const int MBP = 4;  // Minimum back porch
525
	const int FIFO_SIZE = 1024;
526
	double vsr = (double)param->v_linesi / vidstda[mode->tv_encoding].m_TotalLinesOut;
527
528
	// H_BLANKO
529
	param->h_blanko = 2 * (int)(
530
		vidstda[mode->tv_encoding].m_dSecImageCentre / (2 * vidstda[mode->tv_encoding].m_dSecHsyncPeriod) *
531
		param->h_clko
532
		+ 0.5
533
	) - mode->xres + 15;
534
535
	// V_BLANKO
536
	switch (mode->tv_encoding) {
537
		case TV_ENC_NTSC:
538
		case TV_ENC_NTSC60:
539
		case TV_ENC_PAL60:
540
		case TV_ENC_PALM:
541
			param->v_blanko = (int)( 140 - ( param->v_activeo / 2.0 ) + 0.5 );
542
			break;
543
		default:
544
			param->v_blanko = (int)( 167 - ( param->v_activeo / 2.0 ) + 0.5 );
545
			break;
546
	}
547
548
	// V_BLANKI
549
	vsrq = ( (int)( vsr * 4096.0 + .5 ) ) / 4096.0;
550
	param->vscale = (int)( ( vsr - 1 ) * 4096 + 0.5 );
551
	if( vsrq < vsr )
552
	{
553
	// These calculations are in units of dHCLKO
554
		dMaxHsyncDrift = ( vsrq - vsr ) * tlo / vsr * param->h_clko;
555
		dMinFrontPorchIn = MFP / ( (double)param->h_clki * vsr ) * param->h_clko;
556
		dFrontPorchOut = param->h_clko - param->h_blanko - mode->xres * 2;
557
		dFifoMargin = ( FIFO_SIZE - mode->xres ) * 2;
558
559
		// Check for fifo overflow
560
		if( dFrontPorchOut + dFifoMargin < -dMaxHsyncDrift + dMinFrontPorchIn )
561
		{
562
			dTotalHBlankO = param->h_clko - mode->xres * 2;
563
			dTotalHBlankI = ( (double)param->h_clki - (double)mode->xres ) / param->h_clki / vsr * param->h_clko;
564
565
			// Try forcing the Hsync drift the opposite direction
566
			dMaxHsyncDrift = ( vsrq + 1.0 / 4096 - vsr ) * tlo / vsr * param->h_clko;
567
568
			// Check that fifo overflow and underflow can be avoided
569
			if( dTotalHBlankO + dFifoMargin >= dTotalHBlankI + dMaxHsyncDrift )
570
			{
571
				vsrq = vsrq + 1.0 / 4096;
572
				param->vscale = (int)( ( vsrq - 1 ) * 4096 );
573
			}
574
575
			// NOTE: If fifo overflow and underflow can't be avoided,
576
			//       alternative overscan compensation ratios should
577
			//       be selected and all calculations repeated.  If
578
			//       that is not feasible, the calculations for
579
			//       H_BLANKI below will delay the overflow or under-
580
			//       flow as much as possible, to minimize the visible
581
			//       artifacts.
582
		}
583
	}
584
585
	param->v_blanki = (int)( ( param->v_blanko - 1 ) * vsrq );
586
587
	// H_BLANKI
588
589
	// These calculations are in units of dHCLKI
590
	dTotalHBlankI = param->h_clki - mode->xres;
591
	dFrontPorchIn = max( (double)MFP, min( dTotalHBlankI / 8.0, dTotalHBlankI - (double)MBP ) );
592
	dBackPorchIn = dTotalHBlankI - dFrontPorchIn;
593
	dMaxHsyncDrift = ( vsrq - vsr ) * tlo * param->h_clki;
594
	dTotalHBlankO = ( param->h_clko - mode->xres * 2.0 ) / param->h_clko * vsr * param->h_clki;
595
	dBackPorchOut = ((double)param->h_blanko) / (double)param->h_clko * vsr * param->h_clki;
596
	dFrontPorchOut = dTotalHBlankO - dBackPorchOut;
597
	dFifoMargin = ( FIFO_SIZE - mode->xres ) * 2.0 / param->h_clko * vsr * param->h_clki;
598
	// This may be excessive, but is adjusted by the code.
599
	dHeadRoom = 32.0;
600
601
	// Check that fifo overflow and underflow can be avoided
602
	if( ( dTotalHBlankO + dFifoMargin ) >= ( dTotalHBlankI + fabs( dMaxHsyncDrift ) ) )
603
	{
604
		dMaxHR = ( dTotalHBlankO + dFifoMargin ) - ( dTotalHBlankI - fabs( dMaxHsyncDrift ) );
605
		if( dMaxHR < ( dHeadRoom * 2.0 ) )
606
		{
607
			dHeadRoom = (int)( dMaxHR / 2.0);
608
		}
609
610
		// Check for overflow
611
		if( ( ( dFrontPorchOut + dFifoMargin ) - dHeadRoom ) < ( dFrontPorchIn - min( dMaxHsyncDrift, 0.0 ) ) )
612
		{
613
			dFrontPorchIn = max( (double)MFP, ( dFrontPorchOut + dFifoMargin + min( dMaxHsyncDrift, 0.0 ) - dHeadRoom ) );
614
			dBackPorchIn = dTotalHBlankI - dFrontPorchIn;
615
		}
616
617
		// Check for underflow
618
		if( dBackPorchOut - dHeadRoom < dBackPorchIn + max( dMaxHsyncDrift, 0.0 ) )
619
		{
620
			dBackPorchIn = max( (double)MBP, ( dBackPorchOut - max( dMaxHsyncDrift, 0.0 ) - dHeadRoom ) );
621
			dFrontPorchIn = dTotalHBlankI - dBackPorchIn;
622
		}
623
	}
624
	else if( dMaxHsyncDrift < 0 )
625
	{
626
		// Delay the overflow as long as possible
627
		dBackPorchIn = min( ( dBackPorchOut - 1 ), ( dTotalHBlankI - MFP ) );
628
		dFrontPorchIn = dTotalHBlankI - dBackPorchIn;
629
	}
630
	else
631
	{
632
		// Delay the underflow as long as possible
633
		dFrontPorchIn = min( ( dFrontPorchOut + dFifoMargin - 1 ), ( dTotalHBlankI - MBP ) );
634
		dBackPorchIn = dTotalHBlankI - dFrontPorchIn;
635
	}
636
637
	param->h_blanki = (int)( dBackPorchIn );
638
639
}
(-)linux-2.6.5.orig/drivers/video/xbox/conexant.h (+28 lines)
Line 0 Link Here
1
/*
2
 * linux/drivers/video/riva/conexant.h - Xbox driver for conexant chip
3
 *
4
 * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de>
5
 *
6
 * Contributors:
7
 *
8
 * This file is subject to the terms and conditions of the GNU General Public
9
 * License.  See the file COPYING in the main directory of this archive
10
 * for more details.
11
 *
12
 * Known bugs and issues:
13
 *
14
 *      none
15
 */
16
17
#ifndef conexant_h
18
#define conexant_h
19
20
#include <linux/xboxfbctl.h>
21
#include "xboxfb.h"
22
#include "encoder.h"
23
24
int conexant_calc_mode(xbox_video_mode * mode, struct riva_regs * riva_out);
25
int conexant_calc_vga_mode(xbox_av_type av_type, unsigned char pll_int, unsigned char * mode_out);
26
int conexant_calc_hdtv_mode(xbox_hdtv_mode hdtv_mode, unsigned char pll_int, unsigned char * mode_out);
27
28
#endif
(-)linux-2.6.5.orig/drivers/video/xbox/encoder-i2c.c (+173 lines)
Line 0 Link Here
1
/*
2
 * linux/drivers/video/riva/encoder-i2c.c - Xbox I2C driver for encoder chip
3
 *
4
 * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de>
5
 *
6
 * Contributors:
7
 *
8
 * Most of the code was stolen from extsmi.c
9
 * 
10
 * This file is subject to the terms and conditions of the GNU General Public
11
 * License.  See the file COPYING in the main directory of this archive
12
 * for more details.
13
 *
14
 * Known bugs and issues:
15
 *
16
 *      none
17
 */
18
19
#include <linux/kernel.h>
20
#include <linux/i2c.h>
21
#include <linux/init.h>
22
#include <linux/delay.h>
23
24
#define CONEXANT_ADDRESS 0x45
25
#define FOCUS_ADDRESS 0x6a
26
#define EEPROM_ADDRESS 0x54
27
#define PIC_ADDRESS 0x10
28
29
#define DRIVER_NAME "xbox-tv-i2c"
30
31
extern int __init i2c_xbox_init(void);
32
33
static int tv_attach_adapter(struct i2c_adapter *adap);
34
35
static struct i2c_driver tv_driver = {
36
	.name		= "i2c xbox conexant driver",
37
	.id		= I2C_DRIVERID_I2CDEV,
38
	.flags		= I2C_DF_NOTIFY,
39
	.attach_adapter	= tv_attach_adapter,
40
};
41
42
static struct i2c_client pic_client = {
43
	.name		= "I2C xbox pic client",
44
	.id		= 2,
45
	.flags		= 0,
46
	.addr		= PIC_ADDRESS,
47
	.adapter	= NULL,
48
	.driver		= &tv_driver,
49
};
50
51
static struct i2c_client conexant_client = {
52
	.name		= "I2C xbox conexant client",
53
	.id		= 1,
54
	.flags		= 0,
55
	.addr		= CONEXANT_ADDRESS,
56
	.adapter	= NULL,
57
	.driver		= &tv_driver,
58
};
59
60
static struct i2c_client focus_client = {
61
	.name		= "I2C xbox focus client",
62
	.id		= 1,
63
	.flags		= 0,
64
	.addr		= FOCUS_ADDRESS,
65
	.adapter	= NULL,
66
	.driver		= &tv_driver,
67
};
68
69
static struct i2c_client eeprom_client = {
70
	.name		= "I2C xbox eeprom client",
71
	.id		= 3,
72
	.flags		= 0,
73
	.addr		= EEPROM_ADDRESS,
74
	.adapter	= NULL,
75
	.driver		= &tv_driver,
76
};
77
78
static int tv_attach_adapter(struct i2c_adapter *adap)
79
{
80
	int i;
81
82
	if ((i = i2c_adapter_id(adap)) < 0) {
83
		printk("i2c-dev.o: Unknown adapter ?!?\n");
84
		return -ENODEV;
85
	}
86
87
	printk(KERN_INFO DRIVER_NAME ": Using '%s'!\n",adap->name);
88
	focus_client.adapter = adap;
89
	conexant_client.adapter = adap;
90
	pic_client.adapter = adap;
91
	eeprom_client.adapter = adap;
92
	i2c_attach_client(&focus_client);
93
	i2c_attach_client(&conexant_client);
94
	i2c_attach_client(&pic_client);
95
	i2c_attach_client(&eeprom_client);
96
97
	return 0;
98
}
99
100
int tv_i2c_init(void) {
101
	int res;
102
	i2c_xbox_init();
103
	if ((res = i2c_add_driver(&tv_driver))) {
104
		printk(KERN_ERR DRIVER_NAME ": XBox tv driver registration failed.\n");
105
		return res;
106
	}
107
	return 0;
108
}
109
110
int conexant_i2c_read_reg(unsigned char adr) {
111
	if (!conexant_client.adapter) {
112
		printk(KERN_ERR DRIVER_NAME " : No conexant client attached.\n");
113
		return -1;
114
	}
115
	udelay(500);
116
	return i2c_smbus_read_byte_data(&conexant_client, adr);
117
}
118
119
int conexant_i2c_write_reg(unsigned char adr, unsigned char value) {
120
	if (!conexant_client.adapter) {
121
		printk(KERN_ERR DRIVER_NAME " : No conexant client attached.\n");
122
		return -1;
123
	}
124
	udelay(500);
125
	return i2c_smbus_write_byte_data(&conexant_client, adr, value);
126
}
127
128
int focus_i2c_read_reg(unsigned char adr) {
129
	if (!focus_client.adapter) {
130
		printk(KERN_ERR DRIVER_NAME " : No focus client attached.\n");
131
		return -1;
132
	}
133
	udelay(500);
134
	return i2c_smbus_read_byte_data(&focus_client, adr);
135
}
136
137
int focus_i2c_write_reg(unsigned char adr, unsigned char value) {
138
	if (!focus_client.adapter) {
139
		printk(KERN_ERR DRIVER_NAME " : No focus client attached.\n");
140
		return -1;
141
	}
142
	udelay(500);
143
	return i2c_smbus_write_byte_data(&focus_client, adr, value);
144
}
145
146
unsigned char pic_i2c_read_reg(unsigned char adr) {
147
	if (!pic_client.adapter) {
148
		printk(KERN_ERR DRIVER_NAME " : No pic client attached.\n");
149
		return 0;
150
	}
151
	udelay(500);
152
	return (unsigned char)i2c_smbus_read_byte_data(&pic_client, adr);
153
}
154
155
unsigned char eeprom_i2c_read(unsigned char adr) {
156
	if (!eeprom_client.adapter) {
157
		printk(KERN_ERR DRIVER_NAME " : No eeprom client attached.\n");
158
		return 0;
159
	}
160
	udelay(500);
161
	return (unsigned char)i2c_smbus_read_byte_data(&eeprom_client, adr);
162
}
163
164
void tv_i2c_exit(void){
165
	int res;
166
	
167
	if ((res = i2c_del_driver(&tv_driver))) {
168
		printk(KERN_ERR DRIVER_NAME ": XBox tv Driver deregistration failed, "
169
		       "module not removed.\n");
170
	}
171
	return;
172
}
173
(-)linux-2.6.5.orig/drivers/video/xbox/encoder-i2c.h (+29 lines)
Line 0 Link Here
1
/*
2
 * linux/drivers/video/riva/encoder-i2c.h - Xbox I2C driver for encoder chip
3
 *
4
 * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de>
5
 *
6
 * Contributors:
7
 * 
8
 * This file is subject to the terms and conditions of the GNU General Public
9
 * License.  See the file COPYING in the main directory of this archive
10
 * for more details.
11
 *
12
 * Known bugs and issues:
13
 *
14
 *      none
15
 */
16
 
17
#ifndef encoder_i2c_h
18
#define encoder_i2c_h
19
20
int tv_i2c_init(void);
21
void tv_i2c_exit(void);
22
int conexant_i2c_read_reg(unsigned char adr);
23
int conexant_i2c_write_reg(unsigned char adr, unsigned char value);
24
int focus_i2c_read_reg(unsigned char adr);
25
int focus_i2c_write_reg(unsigned char adr, unsigned char value);
26
unsigned char pic_i2c_read_reg(unsigned char adr);
27
unsigned char eeprom_i2c_read(unsigned char adr);
28
29
#endif
(-)linux-2.6.5.orig/drivers/video/xbox/encoder.c (+172 lines)
Line 0 Link Here
1
/*
2
 * linux/drivers/video/riva/encoder.c - Xbox driver for encoder chip
3
 *
4
 * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de>
5
 *
6
 * Contributors:
7
 *
8
 * This file is subject to the terms and conditions of the GNU General Public
9
 * License.  See the file COPYING in the main directory of this archive
10
 * for more details.
11
 *
12
 * Known bugs and issues:
13
 *
14
 *      none
15
 */
16
17
#include "encoder-i2c.h"
18
#include "encoder.h"
19
#include "focus.h"
20
#include <asm/io.h>
21
22
#define ADR(x) (x / 2 - 0x17)
23
24
static const conexant_video_parameter vidstda[] = {
25
	{ 3579545.00, 0.0000053, 0.00000782, 0.0000047, 0.000063555, 0.0000094, 0.000035667, 0.0000015, 243, 262.5, 0.0000092 },
26
	{ 3579545.00, 0.0000053, 0.00000782, 0.0000047, 0.000064000, 0.0000094, 0.000035667, 0.0000015, 243, 262.5, 0.0000092 },
27
	{ 4433618.75, 0.0000056, 0.00000785, 0.0000047, 0.000064000, 0.0000105, 0.000036407, 0.0000015, 288, 312.5, 0.0000105 },
28
	{ 4433618.75, 0.0000056, 0.00000785, 0.0000047, 0.000064000, 0.0000094, 0.000035667, 0.0000015, 288, 312.5, 0.0000092 },
29
	{ 3582056.25, 0.0000056, 0.00000811, 0.0000047, 0.000064000, 0.0000105, 0.000036407, 0.0000015, 288, 312.5, 0.0000105 },
30
	{ 3575611.88, 0.0000058, 0.00000832, 0.0000047, 0.000063555, 0.0000094, 0.000035667, 0.0000015, 243, 262.5, 0.0000092 },
31
	{ 4433619.49, 0.0000053, 0.00000755, 0.0000047, 0.000063555, 0.0000105, 0.000036407, 0.0000015, 243, 262.5, 0.0000092 }
32
};
33
34
35
static const double pll_base = 13.5e6;
36
37
xbox_encoder_type tv_get_video_encoder(void) {
38
	unsigned char b = 0;
39
	xbox_encoder_type encoder = 0;
40
41
	b = conexant_i2c_read_reg(0x00);
42
	if(b != 255) {
43
		encoder = ENCODER_CONEXANT;
44
	}
45
	b = focus_i2c_read_reg(0x00);
46
	if(b != 255) {
47
		encoder = ENCODER_FOCUS;
48
	}
49
	return encoder;
50
}
51
52
int tv_init(void) {
53
	return tv_i2c_init();
54
}
55
56
void tv_exit(void) {
57
	tv_i2c_exit();
58
}
59
60
void tv_load_mode(unsigned char * mode) {
61
	int n, n1;
62
	unsigned char b;
63
	int encoder = 0;
64
	
65
	encoder = tv_get_video_encoder();
66
67
	if(encoder == ENCODER_CONEXANT) {
68
		conexant_i2c_write_reg(0xc4, 0x00); // EN_OUT = 1
69
70
		// Conexant init (starts at register 0x2e)
71
		n1=0;
72
		for(n=0x2e;n<0x100;n+=2) {
73
			switch(n) {
74
				case 0x6c: // reset
75
					conexant_i2c_write_reg(n, mode[n1] & 0x7f);
76
					break;
77
				case 0xc4: // EN_OUT
78
					conexant_i2c_write_reg(n, mode[n1] & 0xfe);
79
					break;
80
				case 0xb8: // autoconfig
81
					break;
82
83
				default:
84
					conexant_i2c_write_reg(n, mode[n1]);
85
					break;
86
			}
87
			n1++;
88
		}
89
		// Timing Reset
90
		b=conexant_i2c_read_reg(0x6c) & (0x7f);
91
		conexant_i2c_write_reg(0x6c, 0x80|b);
92
		b=conexant_i2c_read_reg(0xc4) & (0xfe);
93
		conexant_i2c_write_reg(0xc4, 0x01|b); // EN_OUT = 1
94
		
95
		/*
96
		conexant_i2c_write_reg(0xA8, (0xD9/1.3));
97
		conexant_i2c_write_reg(0xAA, (0x9A/1.3));
98
		conexant_i2c_write_reg(0xAC, (0xA4/1.3));
99
		*/
100
		
101
		conexant_i2c_write_reg(0xA8, 0x81);
102
		conexant_i2c_write_reg(0xAA, 0x49);
103
		conexant_i2c_write_reg(0xAC, 0x8C);
104
		
105
	} 
106
	
107
	if(encoder == ENCODER_FOCUS) {
108
		//Set the command register soft reset
109
		focus_i2c_write_reg(0x0c,0x03);
110
		focus_i2c_write_reg(0x0d,0x21);
111
		
112
		for (n = 0; n<0xc4; n++) {
113
			focus_i2c_write_reg(n,mode[n]);
114
		}
115
		//Clear soft reset flag
116
		b = focus_i2c_read_reg(0x0c);
117
		b &= ~0x01;
118
		focus_i2c_write_reg(0x0c,b);
119
		b = focus_i2c_read_reg(0x0d);
120
		focus_i2c_write_reg(0x0d,b);
121
	}
122
}
123
124
void tv_save_mode(unsigned char * mode) {
125
	int n, n1;
126
	int encoder = 0;
127
128
	encoder = tv_get_video_encoder();
129
130
	if(encoder == ENCODER_CONEXANT) {
131
		// Conexant init (starts at register 0x2e)
132
		n1=0;
133
		for(n=0x2e;n<0x100;n+=2) {
134
			mode[n1] = conexant_i2c_read_reg(n);
135
			n1++;
136
		}
137
	} 
138
	else if (encoder == ENCODER_FOCUS) {
139
		for (n=0;n<0xc4;n++) {
140
			mode[n] = focus_i2c_read_reg(n);
141
		}
142
143
	}
144
}
145
146
xbox_tv_encoding get_tv_encoding(void) {
147
	unsigned char eeprom_value;
148
	xbox_tv_encoding enc = TV_ENC_PALBDGHI;
149
	eeprom_value = eeprom_i2c_read(0x5a);
150
	if (eeprom_value == 0x40) {
151
		enc = TV_ENC_NTSC;
152
	}
153
	else {
154
		enc = TV_ENC_PALBDGHI;
155
	}
156
	return enc;
157
}
158
159
xbox_av_type detect_av_type(void) {
160
	xbox_av_type avType;
161
	switch (pic_i2c_read_reg(0x04)) {
162
		case 0: avType = AV_SCART_RGB; break;
163
		case 1: avType = AV_HDTV; break;
164
		case 2: avType = AV_VGA_SOG; break;
165
		case 4: avType = AV_SVIDEO; break;
166
		case 6: avType = AV_COMPOSITE; break;
167
		case 7: avType = AV_VGA; break;
168
		default: avType = AV_COMPOSITE; break;
169
	}
170
	return avType;
171
}
172
(-)linux-2.6.5.orig/drivers/video/xbox/encoder.h (+64 lines)
Line 0 Link Here
1
/*
2
 * linux/drivers/video/riva/encoder.h - Xbox driver for encoder chip
3
 *
4
 * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de>
5
 *
6
 * Contributors:
7
 * 
8
 * This file is subject to the terms and conditions of the GNU General Public
9
 * License.  See the file COPYING in the main directory of this archive
10
 * for more details.
11
 *
12
 * Known bugs and issues:
13
 *
14
 *      none
15
 */
16
17
18
#ifndef encoder_h
19
#define encoder_h
20
21
#include <linux/xboxfbctl.h>
22
23
typedef struct {
24
	double m_dHzBurstFrequency;
25
	double m_dSecBurstStart;
26
	double m_dSecBurstEnd;
27
	double m_dSecHsyncWidth;
28
	double m_dSecHsyncPeriod;
29
	double m_dSecActiveBegin;
30
	double m_dSecImageCentre;
31
	double m_dSecBlankBeginToHsync;
32
	unsigned int m_dwALO;
33
	double m_TotalLinesOut;
34
	double m_dSecHsyncToBlankEnd;
35
} conexant_video_parameter;
36
37
typedef struct _xbox_video_mode {
38
	int xres;
39
	int yres;
40
	int bpp;
41
	double hoc;
42
	double voc;
43
	xbox_av_type av_type;
44
	xbox_tv_encoding tv_encoding;
45
} xbox_video_mode;
46
47
typedef enum enumHdtvModes {
48
        HDTV_480p,
49
	HDTV_720p,
50
	HDTV_1080i
51
} xbox_hdtv_mode;
52
53
static const conexant_video_parameter vidstda[];
54
55
int tv_init(void);
56
void tv_exit(void);
57
xbox_encoder_type tv_get_video_encoder(void);
58
59
void tv_save_mode(unsigned char * mode_out);
60
void tv_load_mode(unsigned char * mode);
61
xbox_tv_encoding get_tv_encoding(void);
62
xbox_av_type detect_av_type(void);
63
64
#endif
(-)linux-2.6.5.orig/drivers/video/xbox/fbdev.c (+2226 lines)
Line 0 Link Here
1
/*
2
 * linux/drivers/video/riva/fbdev.c - nVidia Xbox fb driver
3
 *
4
 * Maintained by Oliver Schwartz <Oliver.Schwartz@gmx.de>
5
 *
6
 * Based on the nVidia RIVA 128/TNT/TNT2 fb driver, maintained by 
7
 * Ani Joshi <ajoshi@shell.unixbox.com>
8
 *
9
 * Copyright 1999-2000 Jeff Garzik
10
 *
11
 * Contributors:
12
 *
13
 *	Ani Joshi:  Lots of debugging and cleanup work, really helped
14
 *	get the driver going
15
 *
16
 *	Ferenc Bakonyi:  Bug fixes, cleanup, modularization
17
 *
18
 *	Jindrich Makovicka:  Accel code help, hw cursor, mtrr
19
 *
20
 *	Paul Richards:  Bug fixes, updates
21
 *
22
 * Initial template from skeletonfb.c, created 28 Dec 1997 by Geert Uytterhoeven
23
 * Includes riva_hw.c from nVidia, see copyright below.
24
 * KGI code provided the basis for state storage, init, and mode switching.
25
 *
26
 * This file is subject to the terms and conditions of the GNU General Public
27
 * License.  See the file COPYING in the main directory of this archive
28
 * for more details.
29
 *
30
 * Known bugs and issues:
31
 *	restoring text mode fails
32
 *	doublescan modes are broken
33
 */
34
35
#include <linux/config.h>
36
#include <linux/module.h>
37
#include <linux/kernel.h>
38
#include <linux/errno.h>
39
#include <linux/string.h>
40
#include <linux/mm.h>
41
#include <linux/tty.h>
42
#include <linux/slab.h>
43
#include <linux/delay.h>
44
#include <linux/fb.h>
45
#include <linux/init.h>
46
#include <linux/pci.h>
47
#ifdef CONFIG_MTRR
48
#include <asm/mtrr.h>
49
#endif
50
#ifdef CONFIG_PPC_OF
51
#include <asm/prom.h>
52
#include <asm/pci-bridge.h>
53
#endif
54
55
#include "xboxfb.h"
56
#include "nvreg.h"
57
#include <linux/sys.h>
58
#include <asm/uaccess.h>
59
#include <linux/xboxfbctl.h>
60
#include "encoder-i2c.h"
61
#include "conexant.h"
62
#include "focus.h"
63
64
#ifndef CONFIG_PCI		/* sanity check */
65
#error This driver requires PCI support.
66
#endif
67
68
/* version number of this driver */
69
#define RIVAFB_VERSION "0.9.5b"
70
71
/* ------------------------------------------------------------------------- *
72
 *
73
 * various helpful macros and constants
74
 *
75
 * ------------------------------------------------------------------------- */
76
77
#undef RIVAFBDEBUG
78
#ifdef RIVAFBDEBUG
79
#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
80
#else
81
#define DPRINTK(fmt, args...)
82
#endif
83
84
#ifndef RIVA_NDEBUG
85
#define assert(expr) \
86
	if(!(expr)) { \
87
	printk( "Assertion failed! %s,%s,%s,line=%d\n",\
88
	#expr,__FILE__,__FUNCTION__,__LINE__); \
89
	BUG(); \
90
	}
91
#else
92
#define assert(expr)
93
#endif
94
95
#define PFX "xboxfb: "
96
97
/* macro that allows you to set overflow bits */
98
#define SetBitField(value,from,to) SetBF(to,GetBF(value,from))
99
#define SetBit(n)		(1<<(n))
100
#define Set8Bits(value)		((value)&0xff)
101
102
/* HW cursor parameters */
103
#define MAX_CURS		32
104
105
/* ------------------------------------------------------------------------- *
106
 *
107
 * prototypes
108
 *
109
 * ------------------------------------------------------------------------- */
110
111
static int xboxfb_blank(int blank, struct fb_info *info);
112
113
/* ------------------------------------------------------------------------- *
114
 *
115
 * card identification
116
 *
117
 * ------------------------------------------------------------------------- */
118
119
enum riva_chips {
120
	CH_GEFORCE3_XBOX
121
};
122
123
/* directly indexed by riva_chips enum, above */
124
static struct riva_chip_info {
125
	const char *name;
126
	unsigned arch_rev;
127
} riva_chip_info[] __initdata = {
128
        { "GeForce3", NV_ARCH_20}
129
};
130
131
static struct pci_device_id xboxfb_pci_tbl[] = {
132
	{ PCI_VENDOR_ID_NVIDIA, 0x2a0,
133
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3_XBOX },
134
	{ 0, } /* terminate list */
135
};
136
MODULE_DEVICE_TABLE(pci, xboxfb_pci_tbl);
137
138
/* ------------------------------------------------------------------------- *
139
 *
140
 * global variables
141
 *
142
 * ------------------------------------------------------------------------- */
143
144
/* command line data, set in xboxfb_setup() */
145
static u32 pseudo_palette[17];
146
static int flatpanel __initdata = -1; /* Autodetect later */
147
static int forceCRTC __initdata = -1;
148
#ifdef CONFIG_MTRR
149
static int nomtrr __initdata = 0;
150
#endif
151
152
#ifndef MODULE
153
static char *mode_option __initdata = NULL;
154
#endif
155
156
static xbox_tv_encoding tv_encoding  __initdata = TV_ENC_INVALID;
157
static xbox_av_type av_type __initdata = AV_INVALID;
158
static int hoc __initdata = -1;
159
static int voc __initdata = -1;
160
161
static struct fb_fix_screeninfo xboxfb_fix = {
162
	.id		= "Xbox",
163
	.type		= FB_TYPE_PACKED_PIXELS,
164
	.xpanstep	= 1,
165
	.ypanstep	= 1,
166
};
167
168
static struct fb_var_screeninfo xboxfb_default_var = {
169
	.xres		= 640,
170
	.yres		= 480,
171
	.xres_virtual	= 640,
172
	.yres_virtual	= 480,
173
	.bits_per_pixel	= 8,
174
	.red		= {0, 8, 0},
175
	.green		= {0, 8, 0},
176
	.blue		= {0, 8, 0},
177
	.transp		= {0, 0, 0},
178
	.activate	= FB_ACTIVATE_NOW,
179
	.height		= -1,
180
	.width		= -1,
181
	.accel_flags	= FB_ACCELF_TEXT,
182
	.pixclock	= 39721,
183
	.left_margin	= 40,
184
	.right_margin	= 24,
185
	.upper_margin	= 32,
186
	.lower_margin	= 11,
187
	.hsync_len	= 96,
188
	.vsync_len	= 2,
189
	.vmode		= FB_VMODE_NONINTERLACED
190
};
191
192
static struct fb_var_screeninfo xboxfb_mode_480p = {
193
	.xres           = 720,
194
	.yres           = 480,
195
	.xres_virtual   = 720,
196
	.yres_virtual   = 480,
197
	.bits_per_pixel = 32,
198
	.red            = {0, 8, 16},
199
	.green          = {0, 8, 8},
200
	.blue           = {0, 8, 0},
201
	.transp         = {0, 0, 0},
202
	.activate       = FB_ACTIVATE_NOW,
203
	.height         = -1,
204
	.width          = -1,
205
	.accel_flags    = FB_ACCELF_TEXT,
206
	.pixclock       = 37000,
207
	.left_margin    = 56,
208
	.right_margin   = 18,
209
	.upper_margin   = 29,
210
	.lower_margin   = 9,
211
	.hsync_len      = 64,
212
	.vsync_len      = 7,
213
	.vmode          = FB_VMODE_NONINTERLACED
214
};
215
216
static struct fb_var_screeninfo xboxfb_mode_720p = {
217
	.xres           = 1280,
218
	.yres           = 720,
219
	.xres_virtual   = 1280,
220
	.yres_virtual   = 720,
221
	.bits_per_pixel = 8,
222
	.red            = {0, 8, 0},
223
	.green          = {0, 8, 0},
224
	.blue           = {0, 8, 0},
225
	.transp         = {0, 0, 0},
226
	.activate       = FB_ACTIVATE_NOW,
227
	.height         = -1,
228
	.width          = -1,
229
	.accel_flags    = FB_ACCELF_TEXT,
230
	.pixclock       = 13468,
231
	.left_margin    = 220,
232
	.right_margin   = 70,
233
	.upper_margin   = 22,
234
	.lower_margin   = 3,
235
	.hsync_len      = 80,
236
	.vsync_len      = 5,
237
	.vmode          = FB_VMODE_NONINTERLACED
238
};
239
240
static const char* tvEncodingNames[] = {
241
        "NTSC",
242
        "NTSC-60",
243
        "PAL-BDGHI",
244
        "PAL-N",
245
        "PAL-NC",
246
        "PAL-M",
247
        "PAL-60"
248
};
249
250
static const char* avTypeNames[] = {
251
        "SCART (RGB)",
252
        "S-Video",
253
        "VGA (Sync on green)",
254
        "HDTV (Component video)",
255
        "Composite",
256
        "VGA (internal syncs)"
257
};
258
259
/* from GGI */
260
static const struct riva_regs reg_template = {
261
	{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,	/* ATTR */
262
	 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
263
	 0x41, 0x01, 0x0F, 0x00, 0x00},
264
	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* CRT  */
265
	 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
266
	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3,	/* 0x10 */
267
	 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268
	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 0x20 */
269
	 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270
	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 0x30 */
271
	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
272
	 0x00,							/* 0x40 */
273
	 },
274
	{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,	/* GRA  */
275
	 0xFF},
276
	{0x03, 0x01, 0x0F, 0x00, 0x0E},				/* SEQ  */
277
	0xEB							/* MISC */
278
};
279
280
/* ------------------------------------------------------------------------- *
281
 *
282
 * MMIO access macros
283
 *
284
 * ------------------------------------------------------------------------- */
285
286
static inline void CRTCout(struct riva_par *par, unsigned char index,
287
			   unsigned char val)
288
{
289
	VGA_WR08(par->riva.PCIO, 0x3d4, index);
290
	VGA_WR08(par->riva.PCIO, 0x3d5, val);
291
}
292
293
static inline unsigned char CRTCin(struct riva_par *par,
294
				   unsigned char index)
295
{
296
	VGA_WR08(par->riva.PCIO, 0x3d4, index);
297
	return (VGA_RD08(par->riva.PCIO, 0x3d5));
298
}
299
300
static inline void GRAout(struct riva_par *par, unsigned char index,
301
			  unsigned char val)
302
{
303
	VGA_WR08(par->riva.PVIO, 0x3ce, index);
304
	VGA_WR08(par->riva.PVIO, 0x3cf, val);
305
}
306
307
static inline unsigned char GRAin(struct riva_par *par,
308
				  unsigned char index)
309
{
310
	VGA_WR08(par->riva.PVIO, 0x3ce, index);
311
	return (VGA_RD08(par->riva.PVIO, 0x3cf));
312
}
313
314
static inline void SEQout(struct riva_par *par, unsigned char index,
315
			  unsigned char val)
316
{
317
	VGA_WR08(par->riva.PVIO, 0x3c4, index);
318
	VGA_WR08(par->riva.PVIO, 0x3c5, val);
319
}
320
321
static inline unsigned char SEQin(struct riva_par *par,
322
				  unsigned char index)
323
{
324
	VGA_WR08(par->riva.PVIO, 0x3c4, index);
325
	return (VGA_RD08(par->riva.PVIO, 0x3c5));
326
}
327
328
static inline void ATTRout(struct riva_par *par, unsigned char index,
329
			   unsigned char val)
330
{
331
	VGA_WR08(par->riva.PCIO, 0x3c0, index);
332
	VGA_WR08(par->riva.PCIO, 0x3c0, val);
333
}
334
335
static inline unsigned char ATTRin(struct riva_par *par,
336
				   unsigned char index)
337
{
338
	VGA_WR08(par->riva.PCIO, 0x3c0, index);
339
	return (VGA_RD08(par->riva.PCIO, 0x3c1));
340
}
341
342
static inline void MISCout(struct riva_par *par, unsigned char val)
343
{
344
	VGA_WR08(par->riva.PVIO, 0x3c2, val);
345
}
346
347
static inline unsigned char MISCin(struct riva_par *par)
348
{
349
	return (VGA_RD08(par->riva.PVIO, 0x3cc));
350
}
351
352
static u8 byte_rev[256] = {
353
	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
354
	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
355
	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
356
	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
357
	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
358
	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
359
	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
360
	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
361
	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
362
	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
363
	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
364
	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
365
	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
366
	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
367
	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
368
	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
369
	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
370
	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
371
	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
372
	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
373
	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
374
	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
375
	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
376
	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
377
	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
378
	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
379
	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
380
	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
381
	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
382
	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
383
	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
384
	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
385
};
386
387
static inline void reverse_order(u32 *l)
388
{
389
	u8 *a = (u8 *)l;
390
	*a = byte_rev[*a], a++;
391
	*a = byte_rev[*a], a++;
392
	*a = byte_rev[*a], a++;
393
	*a = byte_rev[*a];
394
}
395
396
/* ------------------------------------------------------------------------- *
397
 *
398
 * cursor stuff
399
 *
400
 * ------------------------------------------------------------------------- */
401
402
/**
403
 * xboxfb_load_cursor_image - load cursor image to hardware
404
 * @data: address to monochrome bitmap (1 = foreground color, 0 = background)
405
 * @par:  pointer to private data
406
 * @w:    width of cursor image in pixels
407
 * @h:    height of cursor image in scanlines
408
 * @bg:   background color (ARGB1555) - alpha bit determines opacity
409
 * @fg:   foreground color (ARGB1555)
410
 *
411
 * DESCRIPTiON:
412
 * Loads cursor image based on a monochrome source and mask bitmap.  The
413
 * image bits determines the color of the pixel, 0 for background, 1 for
414
 * foreground.  Only the affected region (as determined by @w and @h 
415
 * parameters) will be updated.
416
 *
417
 * CALLED FROM:
418
 * xboxfb_cursor()
419
 */
420
static void xboxfb_load_cursor_image(struct riva_par *par, u8 *data, 
421
				     u8* mask, u16 bg, u16 fg, u32 w, u32 h)
422
{
423
	int i, j, k = 0;
424
	u32 b, m, tmp;
425
426
	for (i = 0; i < h; i++) {
427
		b = *((u32 *)data);
428
		data = (u8 *)((u32 *)data + 1);
429
		m = *((u32 *)mask);
430
		mask = (u8 *)((u32 *)mask + 1);
431
		reverse_order(&b);
432
		
433
		for (j = 0; j < w/2; j++) {
434
			tmp = 0;
435
#if defined (__BIG_ENDIAN)
436
			tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
437
			if (m & (1 << 31)) {
438
				tmp |= 1 << 31;
439
			}
440
			b <<= 1;
441
			m <<= 1;
442
443
			tmp |= (b & (1 << 31)) ? fg : bg;
444
			if (m & (1 << 31)) {
445
				tmp |= 1 << 15;
446
			}
447
			b <<= 1;
448
			m <<= 1;
449
#else
450
			tmp = (b & 1) ? fg : bg;
451
			if (m & 1) {
452
				tmp |= 1 << 15;
453
			}
454
			b >>= 1;
455
			m >>= 1;
456
			
457
			tmp |= (b & 1) ? fg << 16 : bg << 16;
458
			if (m & 1) {
459
				tmp |= 1 << 31;
460
			}
461
			b >>= 1;
462
			m >>= 1;
463
#endif
464
			writel(tmp, par->riva.CURSOR + k++);
465
		}
466
		k += (MAX_CURS - w)/2;
467
	}
468
}
469
470
/* ------------------------------------------------------------------------- *
471
 *
472
 * general utility functions
473
 *
474
 * ------------------------------------------------------------------------- */
475
476
/**
477
 * riva_wclut - set CLUT entry
478
 * @chip: pointer to RIVA_HW_INST object
479
 * @regnum: register number
480
 * @red: red component
481
 * @green: green component
482
 * @blue: blue component
483
 *
484
 * DESCRIPTION:
485
 * Sets color register @regnum.
486
 *
487
 * CALLED FROM:
488
 * xboxfb_setcolreg()
489
 */
490
static void riva_wclut(RIVA_HW_INST *chip,
491
		       unsigned char regnum, unsigned char red,
492
		       unsigned char green, unsigned char blue)
493
{
494
	VGA_WR08(chip->PDIO, 0x3c8, regnum);
495
	VGA_WR08(chip->PDIO, 0x3c9, red);
496
	VGA_WR08(chip->PDIO, 0x3c9, green);
497
	VGA_WR08(chip->PDIO, 0x3c9, blue);
498
}
499
500
/**
501
 * riva_rclut - read fromCLUT register
502
 * @chip: pointer to RIVA_HW_INST object
503
 * @regnum: register number
504
 * @red: red component
505
 * @green: green component
506
 * @blue: blue component
507
 *
508
 * DESCRIPTION:
509
 * Reads red, green, and blue from color register @regnum.
510
 *
511
 * CALLED FROM:
512
 * xboxfb_setcolreg()
513
 */
514
static void riva_rclut(RIVA_HW_INST *chip,
515
		       unsigned char regnum, unsigned char *red,
516
		       unsigned char *green, unsigned char *blue)
517
{
518
	
519
	VGA_WR08(chip->PDIO, 0x3c8, regnum);
520
	*red = VGA_RD08(chip->PDIO, 0x3c9);
521
	*green = VGA_RD08(chip->PDIO, 0x3c9);
522
	*blue = VGA_RD08(chip->PDIO, 0x3c9);
523
}
524
525
/**
526
 * riva_save_state - saves current chip state
527
 * @par: pointer to riva_par object containing info for current riva board
528
 * @regs: pointer to riva_regs object
529
 *
530
 * DESCRIPTION:
531
 * Saves current chip state to @regs.
532
 *
533
 * CALLED FROM:
534
 * xboxfb_probe()
535
 */
536
/* from GGI */
537
static void riva_save_state(struct riva_par *par, struct riva_regs *regs)
538
{
539
	int i;
540
541
	par->riva.LockUnlock(&par->riva, 0);
542
543
	par->riva.UnloadStateExt(&par->riva, &regs->ext);
544
545
	regs->misc_output = MISCin(par);
546
547
	for (i = 0; i < NUM_CRT_REGS; i++)
548
		regs->crtc[i] = CRTCin(par, i);
549
550
	for (i = 0; i < NUM_ATC_REGS; i++)
551
		regs->attr[i] = ATTRin(par, i);
552
553
	for (i = 0; i < NUM_GRC_REGS; i++)
554
		regs->gra[i] = GRAin(par, i);
555
556
	for (i = 0; i < NUM_SEQ_REGS; i++)
557
		regs->seq[i] = SEQin(par, i);
558
}
559
560
/**
561
 * riva_load_state - loads current chip state
562
 * @par: pointer to riva_par object containing info for current riva board
563
 * @regs: pointer to riva_regs object
564
 *
565
 * DESCRIPTION:
566
 * Loads chip state from @regs.
567
 *
568
 * CALLED FROM:
569
 * riva_load_video_mode()
570
 * xboxfb_probe()
571
 * xboxfb_remove()
572
 */
573
/* from GGI */
574
static void riva_load_state(struct riva_par *par, struct riva_regs *regs)
575
{
576
	RIVA_HW_STATE *state = &regs->ext;
577
	int i;
578
579
	CRTCout(par, 0x11, 0x00);
580
581
	par->riva.LockUnlock(&par->riva, 0);
582
583
	par->riva.LoadStateExt(&par->riva, state);
584
585
	par->riva.PGRAPH[0x00000820/4] = par->riva_fb_start;
586
	par->riva.PGRAPH[0x00000824/4] = par->riva_fb_start;
587
	par->riva.PGRAPH[0x00000828/4] = par->riva_fb_start;
588
	par->riva.PGRAPH[0x0000082c/4] = par->riva_fb_start;
589
590
	par->riva.PGRAPH[0x00000684/4] = par->riva.RamAmountKBytes * 1024 - 1;
591
	par->riva.PGRAPH[0x00000688/4] = par->riva.RamAmountKBytes * 1024 - 1;
592
	par->riva.PGRAPH[0x0000068c/4] = par->riva.RamAmountKBytes * 1024 - 1;
593
	par->riva.PGRAPH[0x00000690/4] = par->riva.RamAmountKBytes * 1024 - 1;
594
	par->riva.PRAMDAC[0x00000848/4] = 0x10100111;
595
	par->riva.PRAMDAC[0x00000880/4] = 0;
596
	par->riva.PRAMDAC[0x000008a0/4] = 0;
597
	par->riva.PMC[0x00008908/4] = par->riva.RamAmountKBytes * 1024 - 1;
598
	par->riva.PMC[0x0000890c/4] = par->riva.RamAmountKBytes * 1024 - 1;
599
	/* Switch GPU to RGB output */
600
	par->riva.PRAMDAC[0x00000630/4] = 0; 
601
	/* These fix the maroon borders seen when booting from Xromwell or 
602
	* xbeboot
603
	*/
604
	par->riva.PRAMDAC[0x0000084c/4] = 0;
605
	par->riva.PRAMDAC[0x000008c4/4] = 0;
606
	
607
	/* for YCrCb:
608
	par->riva.PRAMDAC[0x00000630/4] = 2; 
609
	par->riva.PRAMDAC[0x0000084c/4] =0x00801080;
610
	par->riva.PRAMDAC[0x000008c4/4] =0x40801080;
611
	*/
612
	MISCout(par, regs->misc_output);
613
614
	for (i = 0; i < NUM_CRT_REGS; i++) {
615
		switch (i) {
616
		case 0x0c:
617
		case 0x0d:
618
		case 0x19:
619
		case 0x20 ... 0x40:
620
			break;
621
		default:
622
			CRTCout(par, i, regs->crtc[i]);
623
		}
624
	}
625
626
	for (i = 0; i < NUM_ATC_REGS; i++)
627
		ATTRout(par, i, regs->attr[i]);
628
629
	for (i = 0; i < NUM_GRC_REGS; i++)
630
		GRAout(par, i, regs->gra[i]);
631
632
	for (i = 0; i < NUM_SEQ_REGS; i++)
633
		SEQout(par, i, regs->seq[i]);
634
	tv_save_mode(regs->encoder_mode);
635
}
636
637
static inline unsigned long xbox_memory_size(void) {
638
	/* make a guess on the xbox memory size. There are just
639
	two possibilities */
640
	if ((num_physpages << PAGE_SHIFT) > 64*1024*1024) {
641
		return 128*1024*1024;
642
	} else {
643
		return 64*1024*1024;
644
	}
645
}
646
647
static inline unsigned long available_framebuffer_memory(void) {
648
	return xbox_memory_size() - (num_physpages << PAGE_SHIFT);
649
}
650
651
/**
652
 * riva_load_video_mode - calculate timings
653
 * @info: pointer to fb_info object containing info for current riva board
654
 *
655
 * DESCRIPTION:
656
 * Calculate some timings and then send em off to riva_load_state().
657
 *
658
 * CALLED FROM:
659
 * xboxfb_set_par()
660
 */
661
static void riva_load_video_mode(struct fb_info *info)
662
{
663
	int bpp, width, height, hDisplaySize, hStart, hTotal, vStart, vTotal;
664
	int crtc_hDisplay, crtc_hStart, crtc_hEnd, crtc_hTotal;
665
	int crtc_vDisplay, crtc_vStart, crtc_vEnd, crtc_vTotal, dotClock;
666
	int crtc_hBlankStart, crtc_hBlankEnd, crtc_vBlankStart, crtc_vBlankEnd;
667
	struct riva_par *par = (struct riva_par *) info->par;
668
	struct riva_regs newmode;
669
	int encoder_ok = 0;	
670
	
671
	/* time to calculate */
672
	xboxfb_blank(1, info);
673
674
	bpp = info->var.bits_per_pixel;
675
	if (bpp == 16 && info->var.green.length == 5)
676
		bpp = 15;
677
	width = info->var.xres_virtual;
678
	height = info->var.yres_virtual;
679
	hDisplaySize = info->var.xres;
680
	hStart = hDisplaySize + info->var.right_margin;
681
	hTotal = hDisplaySize + info->var.right_margin +
682
		  info->var.hsync_len + info->var.left_margin;
683
	vStart = info->var.yres + info->var.lower_margin;
684
	vTotal = info->var.yres + info->var.lower_margin +
685
		 info->var.vsync_len + info->var.upper_margin;
686
	
687
	crtc_hDisplay = (hDisplaySize / 8) - 1;
688
	crtc_hStart = (hTotal - 32) / 8;
689
	/* crtc_hStart = hStart / 8 - 1; */
690
	crtc_hEnd = crtc_hStart + 1;
691
	/* crtc_hEnd = (hStart + info->var.hsync_len) / 8 - 1; */
692
	crtc_hTotal = hTotal / 8 - 5;
693
	crtc_hBlankStart = crtc_hDisplay;
694
	crtc_hBlankEnd = crtc_hTotal + 4;
695
	
696
	crtc_vDisplay = info->var.yres - 1;
697
	/* crtc_vStart = vStart - 1; */
698
	crtc_vStart = vStart - 1;
699
	/* crtc_vEnd = vStart + info->var.vsync_len - 1; */
700
	crtc_vEnd = crtc_vStart + 2;
701
	crtc_vTotal = vTotal + 2;
702
	crtc_vDisplay = info->var.yres - 1;
703
	crtc_vBlankStart = crtc_vDisplay;
704
	crtc_vBlankEnd = crtc_vTotal + 1;
705
	
706
	dotClock = 1000000000 / info->var.pixclock;
707
708
	memcpy(&newmode, &reg_template, sizeof(struct riva_regs));
709
710
	if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
711
		vTotal |= 1;
712
713
	if (par->FlatPanel) {
714
		crtc_vStart = crtc_vTotal - 3;
715
		crtc_vEnd = crtc_vTotal - 2;
716
		crtc_vBlankStart = crtc_vStart;
717
		crtc_hStart = crtc_hTotal - 3;
718
		crtc_hEnd = crtc_hTotal - 2;
719
		crtc_hBlankEnd = crtc_hTotal + 4;
720
	}
721
722
	newmode.ext.bpp = bpp;
723
	newmode.ext.fb_start = par->riva_fb_start;
724
725
	if((par->av_type == AV_VGA) || (par->av_type == AV_VGA_SOG) || (par->av_type == AV_HDTV)) {
726
		unsigned char pll_int = (unsigned char)((double)dotClock * 6.0 / 13.5e3 + 0.5);
727
		if (par->av_type == AV_HDTV) {
728
			xbox_hdtv_mode hdtv_mode = HDTV_480p;
729
			if (info->var.yres > 800) {
730
				hdtv_mode = HDTV_1080i;
731
				crtc_vStart = vStart + 31;
732
				crtc_vEnd = crtc_vStart + 2;
733
			}
734
			else if (info->var.yres > 600) {
735
				hdtv_mode = HDTV_720p;
736
			}
737
			if (par->video_encoder == ENCODER_CONEXANT)
738
				encoder_ok = conexant_calc_hdtv_mode(hdtv_mode, pll_int, newmode.encoder_mode);
739
			else if (par->video_encoder == ENCODER_FOCUS)
740
				encoder_ok = focus_calc_hdtv_mode(hdtv_mode, pll_int, newmode.encoder_mode);
741
			else printk("Error - unknown encoder type detected\n");
742
		}
743
		else {
744
			if (par->video_encoder == ENCODER_CONEXANT)
745
				encoder_ok = conexant_calc_vga_mode(par->av_type, pll_int, newmode.encoder_mode);
746
			else if (par->video_encoder == ENCODER_FOCUS) {
747
				//No vga functions as yet - so set up for 480p otherwise we dont boot at all. 
748
				encoder_ok = focus_calc_hdtv_mode(HDTV_480p, pll_int, newmode.encoder_mode);
749
			}
750
			
751
			else printk("Error - unknown encoder type detected\n");
752
		}
753
		newmode.ext.vend = info->var.yres - 1;
754
		newmode.ext.vtotal = vTotal;
755
		newmode.ext.vcrtc = info->var.yres - 1;
756
		newmode.ext.vsyncstart = vStart;
757
		newmode.ext.vsyncend = vStart + 3;
758
		newmode.ext.vvalidstart = 0;
759
		newmode.ext.vvalidend = info->var.yres - 1;
760
		newmode.ext.hend = info->var.xres - 1;
761
		newmode.ext.htotal = hTotal;
762
		newmode.ext.hcrtc = info->var.xres - 1;
763
		newmode.ext.hsyncstart = hStart;
764
		newmode.ext.hsyncend = hStart + 32;
765
		newmode.ext.hvalidstart = 0;
766
		newmode.ext.hvalidend = info->var.xres - 1;
767
	}
768
769
	/* Normal composite */
770
	else {
771
		xbox_video_mode encoder_mode;
772
		encoder_mode.xres = info->var.xres;
773
		encoder_mode.yres = info->var.yres;
774
		encoder_mode.tv_encoding = par->tv_encoding;
775
		encoder_mode.bpp = bpp;
776
		encoder_mode.hoc = par->hoc;
777
		encoder_mode.voc = par->voc;
778
		encoder_mode.av_type = par->av_type;
779
780
		if (par->video_encoder == ENCODER_CONEXANT) {
781
			encoder_ok = conexant_calc_mode(&encoder_mode, &newmode);
782
		}
783
		else if (par->video_encoder == ENCODER_FOCUS) {
784
			encoder_ok = focus_calc_mode(&encoder_mode, &newmode);
785
		}
786
		else printk("Error - unknown encoder type detected\n");
787
788
		crtc_hDisplay = (newmode.ext.crtchdispend / 8) - 1;
789
		crtc_hStart = (newmode.ext.htotal - 32) / 8;
790
		crtc_hEnd = crtc_hStart + 1;
791
		crtc_hTotal = (newmode.ext.htotal) / 8 - 5;
792
		crtc_hBlankStart = crtc_hDisplay;
793
		crtc_hBlankEnd = (newmode.ext.htotal) / 8 - 1;
794
		
795
		crtc_vDisplay = info->var.yres;
796
		crtc_vStart = newmode.ext.crtcvstart;
797
		crtc_vEnd = newmode.ext.crtcvstart + 3;
798
		crtc_vTotal = newmode.ext.crtcvtotal;
799
		crtc_vBlankStart = crtc_vDisplay;
800
		crtc_vBlankEnd = crtc_vTotal + 1;
801
	}
802
803
	if (encoder_ok) {
804
		newmode.crtc[0x0] = Set8Bits (crtc_hTotal); 
805
		newmode.crtc[0x1] = Set8Bits (crtc_hDisplay);
806
		newmode.crtc[0x2] = Set8Bits (crtc_hBlankStart);
807
		newmode.crtc[0x3] = SetBitField (crtc_hBlankEnd, 4: 0, 4:0) | SetBit (7);
808
		newmode.crtc[0x4] = Set8Bits (crtc_hStart);
809
		newmode.crtc[0x5] = SetBitField (crtc_hBlankEnd, 5: 5, 7:7)
810
			| SetBitField (crtc_hEnd, 4: 0, 4:0);
811
		newmode.crtc[0x6] = SetBitField (crtc_vTotal, 7: 0, 7:0);
812
		newmode.crtc[0x7] = SetBitField (crtc_vTotal, 8: 8, 0:0)
813
			| SetBitField (crtc_vDisplay, 8: 8, 1:1)
814
			| SetBitField (crtc_vStart, 8: 8, 2:2)
815
			| SetBitField (crtc_vBlankStart, 8: 8, 3:3)
816
			| SetBit (4)
817
			| SetBitField (crtc_vTotal, 9: 9, 5:5)
818
			| SetBitField (crtc_vDisplay, 9: 9, 6:6)
819
			| SetBitField (crtc_vStart, 9: 9, 7:7);
820
		newmode.crtc[0x9] = SetBitField (crtc_vBlankStart, 9: 9, 5:5)
821
			| SetBit (6);
822
		newmode.crtc[0x10] = Set8Bits (crtc_vStart);
823
		newmode.crtc[0x11] = SetBitField (crtc_vEnd, 3: 0, 3:0)
824
			| SetBit (5);
825
		newmode.crtc[0x12] = Set8Bits (crtc_vDisplay);
826
		newmode.crtc[0x13] = (width / 8) * ((bpp + 1) / 8);
827
		newmode.crtc[0x15] = Set8Bits (crtc_vBlankStart);
828
		newmode.crtc[0x16] = Set8Bits (crtc_vBlankEnd);
829
	
830
		newmode.ext.screen = SetBitField(crtc_hBlankEnd,6:6,4:4)
831
			| SetBitField(crtc_vBlankStart,10:10,3:3)
832
			| SetBitField(crtc_vStart,10:10,2:2)
833
			| SetBitField(crtc_vDisplay,10:10,1:1)
834
			| SetBitField(crtc_vTotal,10:10,0:0);
835
		newmode.ext.horiz  = SetBitField(crtc_hTotal,8:8,0:0) 
836
			| SetBitField(crtc_hDisplay,8:8,1:1)
837
			| SetBitField(crtc_hBlankStart,8:8,2:2)
838
			| SetBitField(crtc_hStart,8:8,3:3);
839
		newmode.ext.extra  = SetBitField(crtc_vTotal,11:11,0:0)
840
			| SetBitField(crtc_vDisplay,11:11,2:2)
841
			| SetBitField(crtc_vStart,11:11,4:4)
842
			| SetBitField(crtc_vBlankStart,11:11,6:6); 
843
	
844
		if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
845
			int tmp = (crtc_hTotal >> 1) & ~1;
846
			newmode.ext.interlace = Set8Bits(tmp);
847
			newmode.ext.horiz |= SetBitField(tmp, 8:8,4:4);
848
		} else 
849
			newmode.ext.interlace = 0xff; /* interlace off */
850
	
851
		if (par->riva.Architecture >= NV_ARCH_10)
852
			par->riva.CURSOR = (U032 *)(info->screen_base + info->fix.smem_len);
853
	
854
		if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
855
			newmode.misc_output &= ~0x40;
856
		else
857
			newmode.misc_output |= 0x40;
858
		if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
859
			newmode.misc_output &= ~0x80;
860
		else
861
			newmode.misc_output |= 0x80;	
862
	
863
		par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width,
864
					hDisplaySize, height, dotClock);
865
	
866
		newmode.ext.scale = par->riva.PRAMDAC[0x00000848/4] & 0xfff000ff;
867
		if (par->FlatPanel == 1) {
868
			newmode.ext.pixel |= (1 << 7);
869
			newmode.ext.scale |= (1 << 8);
870
		}
871
		if (par->SecondCRTC) {
872
			newmode.ext.head  = par->riva.PCRTC0[0x00000860/4] & ~0x00001000;
873
			newmode.ext.head2 = par->riva.PCRTC0[0x00002860/4] | 0x00001000;
874
			newmode.ext.crtcOwner = 3;
875
			newmode.ext.pllsel |= 0x20000800;
876
			newmode.ext.vpll2 = newmode.ext.vpll;
877
		} else if (par->riva.twoHeads) {
878
			newmode.ext.head  =  par->riva.PCRTC0[0x00000860/4] | 0x00001000;
879
			newmode.ext.head2 =  par->riva.PCRTC0[0x00002860/4] & ~0x00001000;
880
			newmode.ext.crtcOwner = 0;
881
			newmode.ext.vpll2 = par->riva.PRAMDAC0[0x00000520/4];
882
		}
883
		if (par->FlatPanel == 1) {
884
			newmode.ext.pixel |= (1 << 7);
885
			newmode.ext.scale |= (1 << 8);
886
		}
887
		newmode.ext.cursorConfig = 0x02000100;
888
		par->current_state = newmode;
889
		riva_load_state(par, &par->current_state);
890
		tv_load_mode(newmode.encoder_mode);
891
		par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */
892
	}
893
	else {
894
		printk("Error: Unable to set encoder resolution %dx%d\n",info->var.xres, info->var.yres);
895
	}
896
	
897
	xboxfb_blank(0, info);
898
}
899
900
/**
901
 * xboxfb_do_maximize - 
902
 * @info: pointer to fb_info object containing info for current riva board
903
 * @var:
904
 * @nom:
905
 * @den:
906
 *
907
 * DESCRIPTION:
908
 * .
909
 *
910
 * RETURNS:
911
 * -EINVAL on failure, 0 on success
912
 * 
913
 *
914
 * CALLED FROM:
915
 * xboxfb_check_var()
916
 */
917
static int xboxfb_do_maximize(struct fb_info *info,
918
			      struct fb_var_screeninfo *var,
919
			      int nom, int den)
920
{
921
	static struct {
922
		int xres, yres;
923
	} modes[] = {
924
		{1600, 1280},
925
		{1280, 1024},
926
		{1024, 768},
927
		{800, 600},
928
		{640, 480},
929
		{-1, -1}
930
	};
931
	int i;
932
933
	/* use highest possible virtual resolution */
934
	if (var->xres_virtual == -1 && var->yres_virtual == -1) {
935
		printk(KERN_WARNING PFX
936
		       "using maximum available virtual resolution\n");
937
		for (i = 0; modes[i].xres != -1; i++) {
938
			if (modes[i].xres * nom / den * modes[i].yres <
939
			    info->fix.smem_len / 2)
940
				break;
941
		}
942
		if (modes[i].xres == -1) {
943
			printk(KERN_ERR PFX
944
			       "could not find a virtual resolution that fits into video memory!!\n");
945
			DPRINTK("EXIT - EINVAL error\n");
946
			return -EINVAL;
947
		}
948
		var->xres_virtual = modes[i].xres;
949
		var->yres_virtual = modes[i].yres;
950
951
		printk(KERN_INFO PFX
952
		       "virtual resolution set to maximum of %dx%d\n",
953
		       var->xres_virtual, var->yres_virtual);
954
	} else if (var->xres_virtual == -1) {
955
		var->xres_virtual = (info->fix.smem_len * den /
956
			(nom * var->yres_virtual * 2)) & ~15;
957
		printk(KERN_WARNING PFX
958
		       "setting virtual X resolution to %d\n", var->xres_virtual);
959
	} else if (var->yres_virtual == -1) {
960
		var->xres_virtual = (var->xres_virtual + 15) & ~15;
961
		var->yres_virtual = info->fix.smem_len * den /
962
			(nom * var->xres_virtual * 2);
963
		printk(KERN_WARNING PFX
964
		       "setting virtual Y resolution to %d\n", var->yres_virtual);
965
	} else {
966
		var->xres_virtual = (var->xres_virtual + 15) & ~15;
967
		if (var->xres_virtual * nom / den * var->yres_virtual > info->fix.smem_len) {
968
			printk(KERN_ERR PFX
969
			       "mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
970
			       var->xres, var->yres, var->bits_per_pixel);
971
			DPRINTK("EXIT - EINVAL error\n");
972
			return -EINVAL;
973
		}
974
	}
975
	
976
	if (var->xres_virtual * nom / den >= 8192) {
977
		printk(KERN_WARNING PFX
978
		       "virtual X resolution (%d) is too high, lowering to %d\n",
979
		       var->xres_virtual, 8192 * den / nom - 16);
980
		var->xres_virtual = 8192 * den / nom - 16;
981
	}
982
	
983
	if (var->xres_virtual < var->xres) {
984
		printk(KERN_ERR PFX
985
		       "virtual X resolution (%d) is smaller than real\n", var->xres_virtual);
986
		return -EINVAL;
987
	}
988
989
	if (var->yres_virtual < var->yres) {
990
		printk(KERN_ERR PFX
991
		       "virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);
992
		return -EINVAL;
993
	}
994
	return 0;
995
}
996
997
/* acceleration routines */
998
inline void wait_for_idle(struct riva_par *par)
999
{
1000
	while (par->riva.Busy(&par->riva));
1001
}
1002
1003
/* set copy ROP, no mask */
1004
static void riva_setup_ROP(struct riva_par *par)
1005
{
1006
	RIVA_FIFO_FREE(par->riva, Patt, 5);
1007
	par->riva.Patt->Shape = 0;
1008
	par->riva.Patt->Color0 = 0xffffffff;
1009
	par->riva.Patt->Color1 = 0xffffffff;
1010
	par->riva.Patt->Monochrome[0] = 0xffffffff;
1011
	par->riva.Patt->Monochrome[1] = 0xffffffff;
1012
1013
	RIVA_FIFO_FREE(par->riva, Rop, 1);
1014
	par->riva.Rop->Rop3 = 0xCC;
1015
}
1016
1017
void riva_setup_accel(struct riva_par *par)
1018
{
1019
	RIVA_FIFO_FREE(par->riva, Clip, 2);
1020
	par->riva.Clip->TopLeft     = 0x0;
1021
	par->riva.Clip->WidthHeight = 0x80008000;
1022
	riva_setup_ROP(par);
1023
	wait_for_idle(par);
1024
}
1025
1026
/**
1027
 * riva_get_cmap_len - query current color map length
1028
 * @var: standard kernel fb changeable data
1029
 *
1030
 * DESCRIPTION:
1031
 * Get current color map length.
1032
 *
1033
 * RETURNS:
1034
 * Length of color map
1035
 *
1036
 * CALLED FROM:
1037
 * xboxfb_setcolreg()
1038
 */
1039
static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
1040
{
1041
	int rc = 256;		/* reasonable default */
1042
1043
	switch (var->green.length) {
1044
	case 8:
1045
		rc = 256;	/* 256 entries (2^8), 8 bpp and RGB8888 */
1046
		break;
1047
	case 5:
1048
		rc = 32;	/* 32 entries (2^5), 16 bpp, RGB555 */
1049
		break;
1050
	case 6:
1051
		rc = 64;	/* 64 entries (2^6), 16 bpp, RGB565 */
1052
		break;		
1053
	default:
1054
		/* should not occur */
1055
		break;
1056
	}
1057
	return rc;
1058
}
1059
1060
/* ------------------------------------------------------------------------- *
1061
 *
1062
 * framebuffer operations
1063
 *
1064
 * ------------------------------------------------------------------------- */
1065
1066
static int xboxfb_open(struct fb_info *info, int user)
1067
{
1068
	struct riva_par *par = (struct riva_par *) info->par;
1069
	int cnt = atomic_read(&par->ref_count);
1070
1071
	if (!cnt) {
1072
		memset(&par->state, 0, sizeof(struct vgastate));
1073
		par->state.flags = VGA_SAVE_MODE  | VGA_SAVE_FONTS;
1074
		/* save the DAC for Riva128 */
1075
		if (par->riva.Architecture == NV_ARCH_03)
1076
			par->state.flags |= VGA_SAVE_CMAP;
1077
		save_vga(&par->state);
1078
1079
		RivaGetConfig(&par->riva, par->Chipset);
1080
		par->riva.CURSOR = (U032*)(info->screen_base + info->fix.smem_len);
1081
		par->riva.PCRTC[0x00000800/4] = par->riva_fb_start;
1082
		par->riva.PGRAPH[0x00000820/4] = par->riva_fb_start;
1083
		par->riva.PGRAPH[0x00000824/4] = par->riva_fb_start;
1084
		par->riva.PGRAPH[0x00000828/4] = par->riva_fb_start;
1085
		par->riva.PGRAPH[0x0000082c/4] = par->riva_fb_start;
1086
		
1087
		par->riva.PGRAPH[0x00000684/4] = par->riva.RamAmountKBytes * 1024 - 1;
1088
		par->riva.PGRAPH[0x00000688/4] = par->riva.RamAmountKBytes * 1024 - 1;
1089
		par->riva.PGRAPH[0x0000068c/4] = par->riva.RamAmountKBytes * 1024 - 1;
1090
		par->riva.PGRAPH[0x00000690/4] = par->riva.RamAmountKBytes * 1024 - 1;
1091
		par->riva.PMC[0x00008908/4] = par->riva.RamAmountKBytes * 1024 - 1;
1092
		par->riva.PMC[0x0000890c/4] = par->riva.RamAmountKBytes * 1024 - 1;
1093
		
1094
		/* vgaHWunlock() + riva unlock (0x7F) */		
1095
		CRTCout(par, 0x11, 0xFF);
1096
		par->riva.LockUnlock(&par->riva, 0);
1097
	
1098
		riva_save_state(par, &par->initial_state);
1099
	}
1100
	atomic_inc(&par->ref_count);
1101
	return 0;
1102
}
1103
1104
static int xboxfb_release(struct fb_info *info, int user)
1105
{
1106
	struct riva_par *par = (struct riva_par *) info->par;
1107
	int cnt = atomic_read(&par->ref_count);
1108
1109
	if (!cnt)
1110
		return -EINVAL;
1111
	if (cnt == 1) {
1112
		par->riva.LockUnlock(&par->riva, 0);
1113
		par->riva.LoadStateExt(&par->riva, &par->initial_state.ext);
1114
		riva_load_state(par, &par->initial_state);
1115
		restore_vga(&par->state);
1116
		par->riva.LockUnlock(&par->riva, 1);
1117
	}
1118
	atomic_dec(&par->ref_count);
1119
	return 0;
1120
}
1121
1122
static int xboxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1123
{
1124
	int nom, den;		/* translating from pixels->bytes */
1125
	
1126
	switch (var->bits_per_pixel) {
1127
	case 1 ... 8:
1128
		var->red.offset = var->green.offset = var->blue.offset = 0;
1129
		var->red.length = var->green.length = var->blue.length = 8;
1130
		var->bits_per_pixel = 8;
1131
		nom = den = 1;
1132
		break;
1133
	case 9 ... 15:
1134
		var->green.length = 5;
1135
		/* fall through */
1136
	case 16:
1137
		var->bits_per_pixel = 16;
1138
		if (var->green.length == 5) {
1139
			/* 0rrrrrgg gggbbbbb */
1140
			var->red.offset = 10;
1141
			var->green.offset = 5;
1142
			var->blue.offset = 0;
1143
			var->red.length = 5;
1144
			var->green.length = 5;
1145
			var->blue.length = 5;
1146
		} else {
1147
			/* rrrrrggg gggbbbbb */
1148
			var->red.offset = 11;
1149
			var->green.offset = 5;
1150
			var->blue.offset = 0;
1151
			var->red.length = 5;
1152
			var->green.length = 6;
1153
			var->blue.length = 5;
1154
		}
1155
		nom = 2;
1156
		den = 1;
1157
		break;
1158
	case 17 ... 32:
1159
		var->red.length = var->green.length = var->blue.length = 8;
1160
		var->bits_per_pixel = 32;
1161
		var->red.offset = 16;
1162
		var->green.offset = 8;
1163
		var->blue.offset = 0;
1164
		nom = 4;
1165
		den = 1;
1166
		break;
1167
	default:
1168
		printk(KERN_ERR PFX
1169
		       "mode %dx%dx%d rejected...color depth not supported.\n",
1170
		       var->xres, var->yres, var->bits_per_pixel);
1171
		DPRINTK("EXIT, returning -EINVAL\n");
1172
		return -EINVAL;
1173
	}
1174
1175
	if (xboxfb_do_maximize(info, var, nom, den) < 0)
1176
		return -EINVAL;
1177
1178
	if (var->xoffset < 0)
1179
		var->xoffset = 0;
1180
	if (var->yoffset < 0)
1181
		var->yoffset = 0;
1182
1183
	/* truncate xoffset and yoffset to maximum if too high */
1184
	if (var->xoffset > var->xres_virtual - var->xres)
1185
		var->xoffset = var->xres_virtual - var->xres - 1;
1186
1187
	if (var->yoffset > var->yres_virtual - var->yres)
1188
		var->yoffset = var->yres_virtual - var->yres - 1;
1189
1190
	var->red.msb_right = 
1191
	    var->green.msb_right =
1192
	    var->blue.msb_right =
1193
	    var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1194
	return 0;
1195
}
1196
1197
static int xboxfb_set_par(struct fb_info *info)
1198
{
1199
	struct riva_par *par = (struct riva_par *) info->par;
1200
1201
	riva_load_video_mode(info);
1202
	riva_setup_accel(par);
1203
	
1204
	info->fix.line_length = (info->var.xres_virtual * (info->var.bits_per_pixel >> 3));
1205
	info->fix.visual = (info->var.bits_per_pixel == 8) ?
1206
				FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1207
	return 0;
1208
}
1209
1210
/**
1211
 * xboxfb_pan_display
1212
 * @var: standard kernel fb changeable data
1213
 * @con: TODO
1214
 * @info: pointer to fb_info object containing info for current riva board
1215
 *
1216
 * DESCRIPTION:
1217
 * Pan (or wrap, depending on the `vmode' field) the display using the
1218
 * `xoffset' and `yoffset' fields of the `var' structure.
1219
 * If the values don't fit, return -EINVAL.
1220
 *
1221
 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1222
 */
1223
static int xboxfb_pan_display(struct fb_var_screeninfo *var,
1224
			      struct fb_info *info)
1225
{
1226
	struct riva_par *par = (struct riva_par *)info->par;
1227
	unsigned int base;
1228
1229
	if (var->xoffset > (var->xres_virtual - var->xres))
1230
		return -EINVAL;
1231
	if (var->yoffset > (var->yres_virtual - var->yres))
1232
		return -EINVAL;
1233
1234
	if (var->vmode & FB_VMODE_YWRAP) {
1235
		if (var->yoffset < 0
1236
		    || var->yoffset >= info->var.yres_virtual
1237
		    || var->xoffset) return -EINVAL;
1238
	} else {
1239
		if (var->xoffset + info->var.xres > info->var.xres_virtual ||
1240
		    var->yoffset + info->var.yres > info->var.yres_virtual)
1241
			return -EINVAL;
1242
	}
1243
1244
	base = var->yoffset * info->fix.line_length + var->xoffset;
1245
	base += par->riva_fb_start;
1246
	
1247
	par->riva.SetStartAddress(&par->riva, base);
1248
1249
	info->var.xoffset = var->xoffset;
1250
	info->var.yoffset = var->yoffset;
1251
1252
	if (var->vmode & FB_VMODE_YWRAP)
1253
		info->var.vmode |= FB_VMODE_YWRAP;
1254
	else
1255
		info->var.vmode &= ~FB_VMODE_YWRAP;
1256
	return 0;
1257
}
1258
1259
static int xboxfb_blank(int blank, struct fb_info *info)
1260
{
1261
	struct riva_par *par= (struct riva_par *)info->par;
1262
	unsigned char tmp, vesa;
1263
1264
	tmp = SEQin(par, 0x01) & ~0x20;	/* screen on/off */
1265
	vesa = CRTCin(par, 0x1a) & ~0xc0;	/* sync on/off */
1266
1267
	if (blank) {
1268
		tmp |= 0x20;
1269
		switch (blank - 1) {
1270
		case VESA_NO_BLANKING:
1271
			break;
1272
		case VESA_VSYNC_SUSPEND:
1273
			vesa |= 0x80;
1274
			break;
1275
		case VESA_HSYNC_SUSPEND:
1276
			vesa |= 0x40;
1277
			break;
1278
		case VESA_POWERDOWN:
1279
			vesa |= 0xc0;
1280
			break;
1281
		}
1282
	}
1283
	SEQout(par, 0x01, tmp);
1284
	CRTCout(par, 0x1a, vesa);
1285
	return 0;
1286
}
1287
1288
/**
1289
 * xboxfb_setcolreg
1290
 * @regno: register index
1291
 * @red: red component
1292
 * @green: green component
1293
 * @blue: blue component
1294
 * @transp: transparency
1295
 * @info: pointer to fb_info object containing info for current riva board
1296
 *
1297
 * DESCRIPTION:
1298
 * Set a single color register. The values supplied have a 16 bit
1299
 * magnitude.
1300
 *
1301
 * RETURNS:
1302
 * Return != 0 for invalid regno.
1303
 *
1304
 * CALLED FROM:
1305
 * fbcmap.c:fb_set_cmap()
1306
 */
1307
static int xboxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1308
			  unsigned blue, unsigned transp,
1309
			  struct fb_info *info)
1310
{
1311
	struct riva_par *par = (struct riva_par *)info->par;
1312
	RIVA_HW_INST *chip = &par->riva;
1313
	int i;
1314
1315
	if (regno >= riva_get_cmap_len(&info->var))
1316
		return -EINVAL;
1317
1318
	if (info->var.grayscale) {
1319
		/* gray = 0.30*R + 0.59*G + 0.11*B */
1320
		red = green = blue =
1321
		    (red * 77 + green * 151 + blue * 28) >> 8;
1322
	}
1323
1324
	switch (info->var.bits_per_pixel) {
1325
	case 8:
1326
		/* "transparent" stuff is completely ignored. */
1327
		riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1328
		break;
1329
	case 16:
1330
		if (info->var.green.length == 5) {
1331
			if (regno < 16) {
1332
				/* 0rrrrrgg gggbbbbb */
1333
				((u32 *)info->pseudo_palette)[regno] =
1334
					((red & 0xf800) >> 1) |
1335
					((green & 0xf800) >> 6) |
1336
					((blue & 0xf800) >> 11);
1337
			}
1338
			for (i = 0; i < 8; i++) 
1339
				riva_wclut(chip, regno*8+i, red >> 8,
1340
					   green >> 8, blue >> 8);
1341
		} else {
1342
			u8 r, g, b;
1343
1344
			if (regno < 16) {
1345
				/* rrrrrggg gggbbbbb */
1346
				((u32 *)info->pseudo_palette)[regno] =
1347
					((red & 0xf800) >> 0) |
1348
					((green & 0xf800) >> 5) |
1349
					((blue & 0xf800) >> 11);
1350
			}
1351
			if (regno < 32) {
1352
				for (i = 0; i < 8; i++) {
1353
					riva_wclut(chip, regno*8+i, red >> 8, 
1354
						   green >> 8, blue >> 8);
1355
				}
1356
			}
1357
			for (i = 0; i < 4; i++) {
1358
				riva_rclut(chip, regno*2+i, &r, &g, &b);
1359
				riva_wclut(chip, regno*4+i, r, green >> 8, b);
1360
			}
1361
		}
1362
		break;
1363
	case 32:
1364
		if (regno < 16) {
1365
			((u32 *)info->pseudo_palette)[regno] =
1366
				((red & 0xff00) << 8) |
1367
				((green & 0xff00)) | ((blue & 0xff00) >> 8);
1368
			
1369
		}
1370
		riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1371
		break;
1372
	default:
1373
		/* do nothing */
1374
		break;
1375
	}
1376
	return 0;
1377
}
1378
1379
/**
1380
 * xboxfb_fillrect - hardware accelerated color fill function
1381
 * @info: pointer to fb_info structure
1382
 * @rect: pointer to fb_fillrect structure
1383
 *
1384
 * DESCRIPTION:
1385
 * This function fills up a region of framebuffer memory with a solid
1386
 * color with a choice of two different ROP's, copy or invert.
1387
 *
1388
 * CALLED FROM:
1389
 * framebuffer hook
1390
 */
1391
static void xboxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
1392
{
1393
	struct riva_par *par = (struct riva_par *) info->par;
1394
	u_int color, rop = 0;
1395
1396
	if (info->var.bits_per_pixel == 8)
1397
		color = rect->color;
1398
	else
1399
		color = ((u32 *)info->pseudo_palette)[rect->color];
1400
1401
	switch (rect->rop) {
1402
	case ROP_XOR:
1403
		rop = 0x66;
1404
		break;
1405
	case ROP_COPY:
1406
	default:
1407
		rop = 0xCC;
1408
		break;
1409
	}
1410
1411
	RIVA_FIFO_FREE(par->riva, Rop, 1);
1412
	par->riva.Rop->Rop3 = rop;
1413
1414
	RIVA_FIFO_FREE(par->riva, Bitmap, 1);
1415
	par->riva.Bitmap->Color1A = color;
1416
1417
	RIVA_FIFO_FREE(par->riva, Bitmap, 2);
1418
	par->riva.Bitmap->UnclippedRectangle[0].TopLeft =
1419
			(rect->dx << 16) | rect->dy;
1420
	par->riva.Bitmap->UnclippedRectangle[0].WidthHeight =
1421
			(rect->width << 16) | rect->height;
1422
	RIVA_FIFO_FREE(par->riva, Rop, 1);
1423
	par->riva.Rop->Rop3 = 0xCC;	/* back to COPY */
1424
}
1425
1426
/**
1427
 * xboxfb_copyarea - hardware accelerated blit function
1428
 * @info: pointer to fb_info structure
1429
 * @region: pointer to fb_copyarea structure
1430
 *
1431
 * DESCRIPTION:
1432
 * This copies an area of pixels from one location to another
1433
 *
1434
 * CALLED FROM:
1435
 * framebuffer hook
1436
 */
1437
static void xboxfb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
1438
{
1439
	struct riva_par *par = (struct riva_par *) info->par;
1440
1441
	RIVA_FIFO_FREE(par->riva, Blt, 3);
1442
	par->riva.Blt->TopLeftSrc  = (region->sy << 16) | region->sx;
1443
	par->riva.Blt->TopLeftDst  = (region->dy << 16) | region->dx;
1444
	par->riva.Blt->WidthHeight = (region->height << 16) | region->width;
1445
	wait_for_idle(par);
1446
}
1447
1448
static inline void convert_bgcolor_16(u32 *col)
1449
{
1450
	*col = ((*col & 0x00007C00) << 9)
1451
		| ((*col & 0x000003E0) << 6)
1452
		| ((*col & 0x0000001F) << 3)
1453
		|	   0xFF000000;
1454
}
1455
1456
/**
1457
 * xboxfb_imageblit: hardware accelerated color expand function
1458
 * @info: pointer to fb_info structure
1459
 * @image: pointer to fb_image structure
1460
 *
1461
 * DESCRIPTION:
1462
 * If the source is a monochrome bitmap, the function fills up a a region
1463
 * of framebuffer memory with pixels whose color is determined by the bit
1464
 * setting of the bitmap, 1 - foreground, 0 - background.
1465
 *
1466
 * If the source is not a monochrome bitmap, color expansion is not done.
1467
 * In this case, it is channeled to a software function.
1468
 *
1469
 * CALLED FROM:
1470
 * framebuffer hook
1471
 */
1472
static void xboxfb_imageblit(struct fb_info *info, 
1473
			     const struct fb_image *image)
1474
{
1475
	struct riva_par *par = (struct riva_par *) info->par;
1476
	u32 fgx = 0, bgx = 0, width, tmp;
1477
	u8 *cdat = (u8 *) image->data;
1478
	volatile u32 *d;
1479
	int i, size;
1480
1481
	if (image->depth != 1) {
1482
		cfb_imageblit(info, image);
1483
		return;
1484
	}
1485
1486
	switch (info->var.bits_per_pixel) {
1487
	case 8:
1488
		fgx = image->fg_color;
1489
		bgx = image->bg_color;
1490
		break;
1491
	case 16:
1492
		fgx = ((u32 *)info->pseudo_palette)[image->fg_color];
1493
		bgx = ((u32 *)info->pseudo_palette)[image->bg_color];
1494
		if (info->var.green.length == 6)
1495
			convert_bgcolor_16(&bgx);	
1496
		break;
1497
	case 32:
1498
		fgx = ((u32 *)info->pseudo_palette)[image->fg_color];
1499
		bgx = ((u32 *)info->pseudo_palette)[image->bg_color];
1500
		break;
1501
	}
1502
1503
	RIVA_FIFO_FREE(par->riva, Bitmap, 7);
1504
	par->riva.Bitmap->ClipE.TopLeft     = 
1505
		(image->dy << 16) | (image->dx & 0xFFFF);
1506
	par->riva.Bitmap->ClipE.BottomRight = 
1507
		(((image->dy + image->height) << 16) |
1508
		 ((image->dx + image->width) & 0xffff));
1509
	par->riva.Bitmap->Color0E           = bgx;
1510
	par->riva.Bitmap->Color1E           = fgx;
1511
	par->riva.Bitmap->WidthHeightInE    = 
1512
		(image->height << 16) | ((image->width + 31) & ~31);
1513
	par->riva.Bitmap->WidthHeightOutE   = 
1514
		(image->height << 16) | ((image->width + 31) & ~31);
1515
	par->riva.Bitmap->PointE            = 
1516
		(image->dy << 16) | (image->dx & 0xFFFF);
1517
1518
	d = &par->riva.Bitmap->MonochromeData01E;
1519
1520
	width = (image->width + 31)/32;
1521
	size = width * image->height;
1522
	while (size >= 16) {
1523
		RIVA_FIFO_FREE(par->riva, Bitmap, 16);
1524
		for (i = 0; i < 16; i++) {
1525
			tmp = *((u32 *)cdat);
1526
			cdat = (u8 *)((u32 *)cdat + 1);
1527
			reverse_order(&tmp);
1528
			d[i] = tmp;
1529
		}
1530
		size -= 16;
1531
	}
1532
	if (size) {
1533
		RIVA_FIFO_FREE(par->riva, Bitmap, size);
1534
		for (i = 0; i < size; i++) {
1535
			tmp = *((u32 *) cdat);
1536
			cdat = (u8 *)((u32 *)cdat + 1);
1537
			reverse_order(&tmp);
1538
			d[i] = tmp;
1539
		}
1540
	}
1541
}
1542
1543
/**
1544
 * xboxfb_cursor - hardware cursor function
1545
 * @info: pointer to info structure
1546
 * @cursor: pointer to fbcursor structure
1547
 *
1548
 * DESCRIPTION:
1549
 * A cursor function that supports displaying a cursor image via hardware.
1550
 * Within the kernel, copy and invert rops are supported.  If exported
1551
 * to user space, only the copy rop will be supported.
1552
 *
1553
 * CALLED FROM
1554
 * framebuffer hook
1555
 */
1556
static int xboxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1557
{
1558
	struct riva_par *par = (struct riva_par *) info->par;
1559
	u8 mask[MAX_CURS * MAX_CURS/8];
1560
	u16 fg, bg;
1561
1562
	par->riva.ShowHideCursor(&par->riva, 0);
1563
1564
	if (cursor->set & FB_CUR_SETPOS) {
1565
		u32 xx, yy, temp;
1566
1567
		info->cursor.image.dx = cursor->image.dx;
1568
		info->cursor.image.dy = cursor->image.dy;
1569
		yy = cursor->image.dy - info->var.yoffset;
1570
		xx = cursor->image.dx - info->var.xoffset;
1571
		temp = xx & 0xFFFF;
1572
		temp |= yy << 16;
1573
1574
		par->riva.PRAMDAC[0x0000300/4] = temp;
1575
	}
1576
1577
	if (cursor->set & FB_CUR_SETSIZE) {
1578
		info->cursor.image.height = cursor->image.height;
1579
		info->cursor.image.width = cursor->image.width;
1580
		memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
1581
	}
1582
1583
	if (cursor->set & FB_CUR_SETCMAP) {
1584
		info->cursor.image.bg_color = cursor->image.bg_color;
1585
		info->cursor.image.fg_color = cursor->image.fg_color;
1586
	}
1587
1588
	if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP)) {
1589
		u32 bg_idx = info->cursor.image.bg_color;
1590
		u32 fg_idx = info->cursor.image.fg_color;
1591
		u32 s_pitch = (info->cursor.image.width+7) >> 3;
1592
		u32 d_pitch = MAX_CURS/8;
1593
		u8 *msk = (u8 *) info->cursor.mask;
1594
		
1595
		fb_move_buf_aligned(info, &info->sprite, mask, d_pitch, msk, s_pitch, info->cursor.image.height);
1596
		bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
1597
		     ((info->cmap.green[bg_idx] & 0xf8) << 2) |
1598
		     ((info->cmap.blue[bg_idx] & 0xf8) >> 3);
1599
1600
		fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
1601
		     ((info->cmap.green[fg_idx] & 0xf8) << 2) |
1602
		     ((info->cmap.blue[fg_idx] & 0xf8) >> 3);
1603
1604
		par->riva.LockUnlock(&par->riva, 0);
1605
1606
		xboxfb_load_cursor_image(par, mask, mask, bg, fg,
1607
					 info->cursor.image.width, 
1608
					 info->cursor.image.height);
1609
	}
1610
	if (info->cursor.enable)
1611
		par->riva.ShowHideCursor(&par->riva, 1);
1612
	return 0;
1613
}
1614
1615
static int xboxfb_sync(struct fb_info *info)
1616
{
1617
	struct riva_par *par = (struct riva_par *)info->par;
1618
1619
	wait_for_idle(par);
1620
	return 0;
1621
}
1622
1623
static int xboxfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
1624
                        unsigned long arg, struct fb_info *info)
1625
{
1626
	struct riva_par *par = (struct riva_par *) info->par;
1627
	
1628
	xbox_overscan overscan;
1629
	xboxfb_config config;
1630
	xbox_tv_encoding encoding;
1631
	int ret = 0;
1632
1633
	switch (cmd) {
1634
	case FBIO_XBOX_SET_OVERSCAN:
1635
		if(!copy_from_user(&overscan, (xbox_overscan*)arg, sizeof(overscan))) {
1636
			par->hoc = overscan.hoc;
1637
			par->voc = overscan.voc;
1638
			riva_load_video_mode (info);
1639
			if (info->var.accel_flags & FB_ACCELF_TEXT) {
1640
				riva_setup_accel(par);
1641
			}
1642
1643
		}
1644
		else {
1645
			ret = -EFAULT;
1646
		}
1647
	break;
1648
	case FBIO_XBOX_GET_OVERSCAN:
1649
		overscan.hoc = par->hoc;
1650
		overscan.voc = par->voc;
1651
		if (copy_to_user((xbox_overscan*)arg, &overscan, sizeof(overscan))) {
1652
			ret = -EFAULT;
1653
		}
1654
	break;
1655
	case FBIO_XBOX_GET_CONFIG:
1656
		config.av_type = par->av_type;
1657
		config.encoder_type = par->video_encoder;
1658
		if (copy_to_user((xboxfb_config*)arg, &config, sizeof(config))) {
1659
			ret = -EFAULT;
1660
		}
1661
	break;
1662
	case FBIO_XBOX_GET_TV_ENCODING:
1663
		encoding = par->tv_encoding;
1664
		if (copy_to_user((xbox_tv_encoding*)arg, &encoding, sizeof(encoding))) {
1665
			ret = -EFAULT;
1666
		}
1667
	break;
1668
	case FBIO_XBOX_SET_TV_ENCODING:
1669
		if(!copy_from_user(&encoding, (xbox_tv_encoding*)arg, sizeof(encoding))) {
1670
			par->tv_encoding = encoding;
1671
			riva_load_video_mode (info);
1672
			if (info->var.accel_flags & FB_ACCELF_TEXT) {
1673
				riva_setup_accel(par);
1674
			}
1675
		}
1676
		else {
1677
			ret = -EFAULT;
1678
		}
1679
	break;
1680
	default:
1681
		ret = -EINVAL;
1682
	}
1683
	return ret;
1684
}
1685
1686
1687
/* ------------------------------------------------------------------------- *
1688
 *
1689
 * initialization helper functions
1690
 *
1691
 * ------------------------------------------------------------------------- */
1692
1693
/* kernel interface */
1694
static struct fb_ops riva_fb_ops = {
1695
	.owner 		= THIS_MODULE,
1696
	.fb_open	= xboxfb_open,
1697
	.fb_release	= xboxfb_release,
1698
	.fb_check_var 	= xboxfb_check_var,
1699
	.fb_set_par 	= xboxfb_set_par,
1700
	.fb_setcolreg 	= xboxfb_setcolreg,
1701
	.fb_pan_display	= xboxfb_pan_display,
1702
	.fb_blank 	= xboxfb_blank,
1703
	.fb_fillrect 	= xboxfb_fillrect,
1704
	.fb_copyarea 	= xboxfb_copyarea,
1705
	.fb_imageblit 	= xboxfb_imageblit,
1706
	.fb_cursor	= xboxfb_cursor,
1707
	.fb_sync 	= xboxfb_sync,
1708
	.fb_ioctl	= xboxfb_ioctl,
1709
};
1710
1711
static int __devinit riva_set_fbinfo(struct fb_info *info)
1712
{
1713
	struct riva_par *par = (struct riva_par *) info->par;
1714
	unsigned int cmap_len;
1715
1716
	info->flags = FBINFO_FLAG_DEFAULT;
1717
	info->var = xboxfb_default_var;
1718
	info->fix = xboxfb_fix;
1719
	info->fbops = &riva_fb_ops;
1720
	info->pseudo_palette = pseudo_palette;
1721
1722
#ifndef MODULE
1723
	if (mode_option)
1724
	{
1725
		if (!strncmp(mode_option, "480p", 4)) {
1726
			info->var = xboxfb_mode_480p;
1727
		}
1728
		else if (!strncmp(mode_option, "720p", 4)) {
1729
			info->var = xboxfb_mode_720p;
1730
		}
1731
		else {
1732
			fb_find_mode(&info->var, info, mode_option,
1733
				NULL, 0, NULL, 8);
1734
		}
1735
	}
1736
#endif
1737
	if (par->use_default_var)
1738
		/* We will use the modified default var */
1739
		info->var = xboxfb_default_var;
1740
1741
	cmap_len = riva_get_cmap_len(&info->var);
1742
	fb_alloc_cmap(&info->cmap, cmap_len, 0);	
1743
1744
	info->pixmap.size = 64 * 1024;
1745
	info->pixmap.buf_align = 4;
1746
	info->pixmap.scan_align = 4;
1747
	info->pixmap.flags = FB_PIXMAP_SYSTEM;
1748
	return 0;
1749
}
1750
1751
#ifdef CONFIG_PPC_OF
1752
static int riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
1753
{
1754
	struct riva_par *par = (struct riva_par *) info->par;
1755
	struct device_node *dp;
1756
	unsigned char *pedid = NULL;
1757
1758
	dp = pci_device_to_OF_node(pd);
1759
	pedid = (unsigned char *)get_property(dp, "EDID,B", 0);
1760
1761
	if (pedid) {
1762
		par->EDID = pedid;
1763
		return 1;
1764
	} else
1765
		return 0;
1766
}
1767
#endif /* CONFIG_PPC_OF */
1768
1769
static int riva_dfp_parse_EDID(struct riva_par *par)
1770
{
1771
	unsigned char *block = par->EDID;
1772
1773
	if (!block)
1774
		return 0;
1775
1776
	/* jump to detailed timing block section */
1777
	block += 54;
1778
1779
	par->clock = (block[0] + (block[1] << 8));
1780
	par->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
1781
	par->hblank = (block[3] + ((block[4] & 0x0f) << 8));
1782
	par->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
1783
	par->vblank = (block[6] + ((block[7] & 0x0f) << 8));
1784
	par->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
1785
	par->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
1786
	par->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
1787
	par->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
1788
	par->interlaced = ((block[17] & 0x80) >> 7);
1789
	par->synct = ((block[17] & 0x18) >> 3);
1790
	par->misc = ((block[17] & 0x06) >> 1);
1791
	par->hAct_high = par->vAct_high = 0;
1792
	if (par->synct == 3) {
1793
		if (par->misc & 2)
1794
			par->hAct_high = 1;
1795
		if (par->misc & 1)
1796
			par->vAct_high = 1;
1797
	}
1798
1799
	printk(KERN_INFO PFX
1800
			"detected DFP panel size from EDID: %dx%d\n", 
1801
			par->panel_xres, par->panel_yres);
1802
	par->got_dfpinfo = 1;
1803
	return 1;
1804
}
1805
1806
static void riva_update_default_var(struct fb_info *info)
1807
{
1808
	struct fb_var_screeninfo *var = &xboxfb_default_var;
1809
	struct riva_par *par = (struct riva_par *) info->par;
1810
1811
        var->xres = par->panel_xres;
1812
        var->yres = par->panel_yres;
1813
        var->xres_virtual = par->panel_xres;
1814
        var->yres_virtual = par->panel_yres;
1815
        var->xoffset = var->yoffset = 0;
1816
        var->bits_per_pixel = 8;
1817
        var->pixclock = 100000000 / par->clock;
1818
        var->left_margin = (par->hblank - par->hOver_plus - par->hSync_width);
1819
        var->right_margin = par->hOver_plus;
1820
        var->upper_margin = (par->vblank - par->vOver_plus - par->vSync_width);
1821
        var->lower_margin = par->vOver_plus;
1822
        var->hsync_len = par->hSync_width;
1823
        var->vsync_len = par->vSync_width;
1824
        var->sync = 0;
1825
1826
        if (par->synct == 3) {
1827
                if (par->hAct_high)
1828
                        var->sync |= FB_SYNC_HOR_HIGH_ACT;
1829
                if (par->vAct_high)
1830
                        var->sync |= FB_SYNC_VERT_HIGH_ACT;
1831
        }
1832
 
1833
        var->vmode = 0;
1834
        if (par->interlaced)
1835
                var->vmode |= FB_VMODE_INTERLACED;
1836
1837
	var->accel_flags |= FB_ACCELF_TEXT;
1838
        
1839
        par->use_default_var = 1;
1840
}
1841
1842
1843
static void riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
1844
{
1845
#ifdef CONFIG_PPC_OF
1846
	if (!riva_get_EDID_OF(info, pdev))
1847
		printk("xboxfb: could not retrieve EDID from OF\n");
1848
#else
1849
	/* XXX use other methods later */
1850
#endif
1851
}
1852
1853
1854
static void riva_get_dfpinfo(struct fb_info *info)
1855
{
1856
	struct riva_par *par = (struct riva_par *) info->par;
1857
1858
	if (riva_dfp_parse_EDID(par))
1859
		riva_update_default_var(info);
1860
1861
	/* if user specified flatpanel, we respect that */
1862
	if (par->got_dfpinfo == 1)
1863
		par->FlatPanel = 1;
1864
}
1865
1866
/* ------------------------------------------------------------------------- *
1867
 *
1868
 * PCI bus
1869
 *
1870
 * ------------------------------------------------------------------------- */
1871
1872
static int __devinit xboxfb_probe(struct pci_dev *pd,
1873
			     	const struct pci_device_id *ent)
1874
{
1875
	struct riva_chip_info *rci = &riva_chip_info[ent->driver_data];
1876
	struct riva_par *default_par;
1877
	struct fb_info *info;
1878
	unsigned long fb_start;
1879
	unsigned long fb_size;
1880
1881
	assert(pd != NULL);
1882
	assert(rci != NULL);
1883
1884
	info = kmalloc(sizeof(struct fb_info), GFP_KERNEL);
1885
	if (!info)
1886
		goto err_out;
1887
1888
	default_par = kmalloc(sizeof(struct riva_par), GFP_KERNEL);
1889
	if (!default_par)
1890
		goto err_out_kfree;
1891
1892
	memset(info, 0, sizeof(struct fb_info));
1893
	memset(default_par, 0, sizeof(struct riva_par));
1894
1895
	info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL);
1896
	if (info->pixmap.addr == NULL)
1897
		goto err_out_kfree1;
1898
	memset(info->pixmap.addr, 0, 64 * 1024);
1899
1900
	strcat(xboxfb_fix.id, rci->name);
1901
	default_par->riva.Architecture = rci->arch_rev;
1902
1903
	default_par->Chipset = (pd->vendor << 16) | pd->device;
1904
	printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset);
1905
	
1906
	default_par->FlatPanel = flatpanel;
1907
	if (flatpanel == 1)
1908
		printk(KERN_INFO PFX "flatpanel support enabled\n");
1909
	default_par->forceCRTC = forceCRTC;
1910
	
1911
	xboxfb_fix.mmio_len = pci_resource_len(pd, 0);
1912
1913
	{
1914
		/* enable IO and mem if not already done */
1915
		unsigned short cmd;
1916
1917
		pci_read_config_word(pd, PCI_COMMAND, &cmd);
1918
		cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
1919
		pci_write_config_word(pd, PCI_COMMAND, cmd);
1920
	}
1921
	
1922
	xboxfb_fix.mmio_start = pci_resource_start(pd, 0);
1923
	xboxfb_fix.smem_start = pci_resource_start(pd, 1);
1924
	
1925
        if (xbox_memory_size() == 64*1024*1024) printk(KERN_INFO PFX "Detected 64MB of system RAM\n");
1926
	else printk(KERN_INFO PFX "Detected 128MB of system RAM\n");
1927
	
1928
	fb_size = available_framebuffer_memory();
1929
	fb_start = xbox_memory_size() - fb_size;
1930
	printk(KERN_INFO PFX "Using %dM framebuffer memory\n", (int)(fb_size/(1024*1024)));
1931
	default_par->riva_fb_start = fb_start;
1932
	xboxfb_fix.smem_start += fb_start;
1933
	xboxfb_fix.smem_len = fb_size - 1024 * 2; /* 2 KByte for Cursor */
1934
	tv_init();
1935
	if (tv_encoding == TV_ENC_INVALID) {
1936
		tv_encoding = get_tv_encoding();
1937
		printk(KERN_INFO PFX "Setting TV mode from EEPROM (%s)\n", tvEncodingNames[tv_encoding]);
1938
	}
1939
	default_par->tv_encoding = tv_encoding;
1940
	default_par->video_encoder = tv_get_video_encoder();
1941
	switch(default_par->video_encoder) {
1942
		case ENCODER_CONEXANT:
1943
			printk(KERN_INFO PFX "detected conexant encoder\n");
1944
			break;
1945
		case ENCODER_FOCUS:
1946
			printk(KERN_INFO PFX "detected focus encoder\n");
1947
			break;
1948
	}
1949
	
1950
	
1951
	if (av_type == AV_INVALID) {
1952
		av_type = detect_av_type();
1953
		printk(KERN_INFO PFX "Setting cable type from AVIP ID: %s\n", avTypeNames[av_type]);
1954
	}
1955
	default_par->av_type = av_type;
1956
	if ((hoc < 0) || (hoc > 20)) {
1957
		hoc = 10;
1958
	}
1959
	default_par->hoc = hoc / 100.0;
1960
	if ((voc < 0) || (voc > 20)) {
1961
		voc = 10;
1962
	}
1963
	default_par->voc = voc / 100.0;
1964
	
1965
	if (!request_mem_region(xboxfb_fix.mmio_start,
1966
				xboxfb_fix.mmio_len, "xboxfb")) {
1967
		printk(KERN_ERR PFX "cannot reserve MMIO region\n");
1968
		goto err_out_kfree2;
1969
	}
1970
1971
	default_par->ctrl_base = ioremap(xboxfb_fix.mmio_start,
1972
					 xboxfb_fix.mmio_len);
1973
	if (!default_par->ctrl_base) {
1974
		printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
1975
		goto err_out_free_base0;
1976
	}
1977
1978
	info->par = default_par;
1979
1980
	riva_get_EDID(info, pd);
1981
1982
	riva_get_dfpinfo(info);
1983
1984
	switch (default_par->riva.Architecture) {
1985
	case NV_ARCH_03:
1986
		/* Riva128's PRAMIN is in the "framebuffer" space
1987
		 * Since these cards were never made with more than 8 megabytes
1988
		 * we can safely allocate this separately.
1989
		 */
1990
		if (!request_mem_region(xboxfb_fix.smem_start + 0x00C00000,
1991
					 0x00008000, "xboxfb")) {
1992
			printk(KERN_ERR PFX "cannot reserve PRAMIN region\n");
1993
			goto err_out_iounmap_ctrl;
1994
		}
1995
		default_par->riva.PRAMIN = ioremap(xboxfb_fix.smem_start + 0x00C00000, 0x00008000);
1996
		if (!default_par->riva.PRAMIN) {
1997
			printk(KERN_ERR PFX "cannot ioremap PRAMIN region\n");
1998
			goto err_out_free_nv3_pramin;
1999
		}
2000
		xboxfb_fix.accel = FB_ACCEL_NV3;
2001
		break;
2002
	case NV_ARCH_04:
2003
	case NV_ARCH_10:
2004
	case NV_ARCH_20:
2005
		default_par->riva.PCRTC0 = (unsigned *)(default_par->ctrl_base + 0x00600000);
2006
		default_par->riva.PRAMIN = (unsigned *)(default_par->ctrl_base + 0x00710000);
2007
		xboxfb_fix.accel = FB_ACCEL_NV4;
2008
		break;
2009
	}
2010
2011
	riva_common_setup(default_par);
2012
2013
	if (default_par->riva.Architecture == NV_ARCH_03) {
2014
		default_par->riva.PCRTC = default_par->riva.PCRTC0 = default_par->riva.PGRAPH;
2015
	}
2016
2017
	/* xboxfb_fix.smem_len = riva_get_memlen(default_par) * 1024; */
2018
	default_par->dclk_max = riva_get_maxdclk(default_par) * 1000;
2019
2020
	if (!request_mem_region(xboxfb_fix.smem_start, xboxfb_fix.smem_len, "xboxfb")) {
2021
		printk(KERN_ERR PFX "cannot reserve FB region\n");
2022
		goto err_out_iounmap_nv3_pramin;
2023
	}
2024
	
2025
	info->screen_base = ioremap(xboxfb_fix.smem_start, fb_size);
2026
	if (!info->screen_base) {
2027
		printk(KERN_ERR PFX "cannot ioremap FB base\n");
2028
		goto err_out_free_base1;
2029
	}
2030
2031
#ifdef CONFIG_MTRR
2032
	if (!nomtrr) {
2033
		default_par->mtrr.vram = mtrr_add(xboxfb_fix.smem_start, fb_size,
2034
			MTRR_TYPE_WRCOMB, 1);
2035
		if (default_par->mtrr.vram < 0) {
2036
			printk(KERN_ERR PFX "unable to setup MTRR\n");
2037
		} else {
2038
			default_par->mtrr.vram_valid = 1;
2039
			/* let there be speed */
2040
			printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
2041
		}
2042
	}
2043
#endif /* CONFIG_MTRR */
2044
2045
	if (riva_set_fbinfo(info) < 0) {
2046
		printk(KERN_ERR PFX "error setting initial video mode\n");
2047
		goto err_out_iounmap_fb;
2048
	}
2049
2050
	if (register_framebuffer(info) < 0) {
2051
		printk(KERN_ERR PFX
2052
			"error registering riva framebuffer\n");
2053
		goto err_out_iounmap_fb;
2054
	}
2055
2056
	pci_set_drvdata(pd, info);
2057
2058
	printk(KERN_INFO PFX
2059
		"PCI nVidia NV%x framebuffer ver %s (%s, %ldMB @ 0x%lX)\n",
2060
		default_par->riva.Architecture,
2061
		RIVAFB_VERSION,
2062
		info->fix.id,
2063
		fb_size / (1024 * 1024),
2064
		info->fix.smem_start);
2065
	return 0;
2066
2067
err_out_iounmap_fb:
2068
	iounmap(info->screen_base);
2069
err_out_free_base1:
2070
	release_mem_region(xboxfb_fix.smem_start, fb_size);
2071
err_out_iounmap_nv3_pramin:
2072
	if (default_par->riva.Architecture == NV_ARCH_03) 
2073
		iounmap((caddr_t)default_par->riva.PRAMIN);
2074
err_out_free_nv3_pramin:
2075
	if (default_par->riva.Architecture == NV_ARCH_03)
2076
		release_mem_region(xboxfb_fix.smem_start + 0x00C00000, 0x00008000);
2077
err_out_iounmap_ctrl:
2078
	iounmap(default_par->ctrl_base);
2079
err_out_free_base0:
2080
	release_mem_region(xboxfb_fix.mmio_start, xboxfb_fix.mmio_len);
2081
err_out_kfree2:
2082
	kfree(info->pixmap.addr);
2083
err_out_kfree1:
2084
	kfree(default_par);
2085
err_out_kfree:
2086
	kfree(info);
2087
err_out:
2088
	return -ENODEV;
2089
}
2090
2091
static void __exit xboxfb_remove(struct pci_dev *pd)
2092
{
2093
	struct fb_info *info = pci_get_drvdata(pd);
2094
	struct riva_par *par = (struct riva_par *) info->par;
2095
	
2096
	if (!info)
2097
		return;
2098
2099
	unregister_framebuffer(info);
2100
#ifdef CONFIG_MTRR
2101
	if (par->mtrr.vram_valid)
2102
		mtrr_del(par->mtrr.vram, info->fix.smem_start, info->fix.smem_len + 1024 * 2);
2103
#endif /* CONFIG_MTRR */
2104
2105
	iounmap(par->ctrl_base);
2106
	iounmap(info->screen_base);
2107
2108
	release_mem_region(info->fix.mmio_start,
2109
			   info->fix.mmio_len);
2110
	release_mem_region(info->fix.smem_start, info->fix.smem_len + 1024 * 2);
2111
2112
	if (par->riva.Architecture == NV_ARCH_03) {
2113
		iounmap((caddr_t)par->riva.PRAMIN);
2114
		release_mem_region(info->fix.smem_start + 0x00C00000, 0x00008000);
2115
	}
2116
	kfree(info->pixmap.addr);
2117
	kfree(par);
2118
	kfree(info);
2119
	pci_set_drvdata(pd, NULL);
2120
}
2121
2122
/* ------------------------------------------------------------------------- *
2123
 *
2124
 * initialization
2125
 *
2126
 * ------------------------------------------------------------------------- */
2127
2128
#ifndef MODULE
2129
int __init xboxfb_setup(char *options)
2130
{
2131
	char *this_opt;
2132
2133
	if (!options || !*options)
2134
		return 0;
2135
2136
	while ((this_opt = strsep(&options, ",")) != NULL) {
2137
		if (!strncmp(this_opt, "forceCRTC", 9)) {
2138
			char *p;
2139
			
2140
			p = this_opt + 9;
2141
			if (!*p || !*(++p)) continue; 
2142
			forceCRTC = *p - '0';
2143
			if (forceCRTC < 0 || forceCRTC > 1) 
2144
				forceCRTC = -1;
2145
		} else if (!strncmp(this_opt, "flatpanel", 9)) {
2146
			flatpanel = 1;
2147
#ifdef CONFIG_MTRR
2148
		} else if (!strncmp(this_opt, "nomtrr", 6)) {
2149
			nomtrr = 1;
2150
#endif
2151
		} else if (!strncmp(this_opt, "tv=", 3)) {
2152
				if(!strncmp(this_opt + 3, "PAL", 3)) {
2153
						tv_encoding = TV_ENC_PALBDGHI;
2154
				}
2155
				else if(!strncmp(this_opt + 3, "NTSC", 4)) {
2156
						tv_encoding = TV_ENC_NTSC;
2157
				}
2158
				else if(!strncmp(this_opt + 3, "VGA", 3)) {
2159
						av_type = AV_VGA_SOG;
2160
				}
2161
		} else if (!strncmp(this_opt, "hoc=", 4)) {
2162
				sscanf(this_opt+4, "%d", &hoc);
2163
		} else if (!strncmp(this_opt, "voc=", 4)) {
2164
				sscanf(this_opt+4, "%d", &voc);
2165
		} else
2166
			mode_option = this_opt;
2167
	}
2168
	return 0;
2169
}
2170
#endif /* !MODULE */
2171
2172
static struct pci_driver xboxfb_driver = {
2173
	.name		= "xboxfb",
2174
	.id_table	= xboxfb_pci_tbl,
2175
	.probe		= xboxfb_probe,
2176
	.remove		= __exit_p(xboxfb_remove),
2177
};
2178
2179
2180
2181
/* ------------------------------------------------------------------------- *
2182
 *
2183
 * modularization
2184
 *
2185
 * ------------------------------------------------------------------------- */
2186
2187
int __init xboxfb_init(void)
2188
{
2189
	if (pci_register_driver(&xboxfb_driver) > 0)
2190
		return 0;
2191
	pci_unregister_driver(&xboxfb_driver);
2192
	return -ENODEV;
2193
}
2194
2195
2196
#ifdef MODULE
2197
static void __exit xboxfb_exit(void)
2198
{
2199
	pci_unregister_driver(&xboxfb_driver);
2200
}
2201
2202
module_init(xboxfb_init);
2203
module_exit(xboxfb_exit);
2204
2205
MODULE_PARM(flatpanel, "i");
2206
MODULE_PARM_DESC(flatpanel, "Enables experimental flat panel support for some chipsets. (0 or 1=enabled) (default=0)");
2207
MODULE_PARM(forceCRTC, "i");
2208
MODULE_PARM_DESC(forceCRTC, "Forces usage of a particular CRTC in case autodetection fails. (0 or 1) (default=autodetect)");
2209
2210
#ifdef CONFIG_MTRR
2211
MODULE_PARM(nomtrr, "i");
2212
MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
2213
#endif
2214
2215
MODULE_PARM(tv, "s");
2216
MODULE_PARM_DESC(tv, "Specifies the TV encoding (\"PAL\", \"NTSC\" or \"VGA\").");
2217
MODULE_PARM(hoc, "i");
2218
MODULE_PARM_DESC(hoc, "Horizontal overscan compensation ratio, in % (0-20)");
2219
MODULE_PARM(voc, "i");
2220
MODULE_PARM_DESC(voc, "Vertical overscan compensation ratio, in % (0-20)");
2221
2222
#endif /* MODULE */
2223
2224
MODULE_AUTHOR("Oliver Schwartz");
2225
MODULE_DESCRIPTION("Framebuffer driver for Xbox");
2226
MODULE_LICENSE("GPL");
(-)linux-2.6.5.orig/drivers/video/xbox/focus.c (+328 lines)
Line 0 Link Here
1
/*
2
 * linux/drivers/video/riva/focus.c - Xbox driver for Focus encoder
3
 *
4
 * Maintainer: David Pye (dmp) <dmp@davidmpye.dyndns.org>
5
 *
6
 * This file is subject to the terms and conditions of the GNU General Public
7
 * License.  See the file COPYING in the main directory of this archive
8
 * for more details.
9
 *
10
 * Known bugs and issues:
11
 *
12
 * VGA SoG/internal sync not yet implemented
13
*/
14
#include "focus.h"
15
#include "encoder.h"
16
17
18
static const unsigned char focus_defaults[0xc4] = {
19
	/*0x00*/ 0x00,0x00,0x00,0x00,0x80,0x02,0xaa,0x0a,
20
	/*0x08*/ 0x00,0x10,0x00,0x00,0x03,0x21,0x15,0x04,
21
	/*0x10*/ 0x00,0xe9,0x07,0x00,0x80,0xf5,0x20,0x00,
22
	/*0x18*/ 0xef,0x21,0x1f,0x00,0x03,0x03,0x00,0x00,
23
	/*0x20*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,
24
	/*0x28*/ 0x0c,0x01,0x00,0x00,0x00,0x00,0x08,0x11,
25
	/*0x30*/ 0x00,0x0f,0x05,0xfe,0x0b,0x80,0x00,0x00,
26
	/*0x38*/ 0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
27
	/*0x40*/ 0x2a,0x09,0x8a,0xcb,0x00,0x00,0x8d,0x00,
28
	/*0x48*/ 0x7c,0x3c,0x9a,0x2f,0x21,0x01,0x3f,0x00,
29
	/*0x50*/ 0x3e,0x03,0x17,0x21,0x1b,0x1b,0x24,0x9c,
30
	/*0x58*/ 0x01,0x3e,0x0f,0x0f,0x60,0x05,0xc8,0x00,
31
	/*0x60*/ 0x9d,0x04,0x9d,0x01,0x02,0x00,0x0a,0x05,
32
	/*0x68*/ 0x00,0x1a,0xff,0x03,0x1e,0x0f,0x78,0x00,
33
	/*0x70*/ 0x00,0xb1,0x04,0x15,0x49,0x10,0x00,0xa3,
34
	/*0x78*/ 0xc8,0x15,0x05,0x15,0x3e,0x03,0x00,0x20,
35
	/*0x80*/ 0x57,0x2f,0x07,0x00,0x00,0x08,0x00,0x00,
36
	/*0x88*/ 0x08,0x16,0x16,0x9c,0x03,0x00,0x00,0x00,
37
	/*0x90*/ 0x00,0x00,0xc4,0x48,0x00,0x00,0x00,0x00,
38
	/*0x98*/ 0x00,0x00,0x00,0x80,0x00,0x00,0xe4,0x00,
39
	/*0xa0*/ 0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
40
	/*0xa8*/ 0xFF,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,
41
	/*0xb0*/ 0x00,0x00,0xd7,0x05,0x00,0x00,0xf0,0x00,
42
	/*0xb8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
43
	/*0xc0*/ 0x00,0x00,0xee,0x00
44
};
45
46
int focus_calc_hdtv_mode(
47
	xbox_hdtv_mode hdtv_mode,
48
	unsigned char pll_int,
49
	unsigned char * regs
50
	){
51
	unsigned char b;
52
	int m=0;
53
	int tv_vtotal, tv_htotal, tv_vactive, tv_hactive, vga_htotal, vga_vtotal;
54
	int pll_n, pll_m, pll_p, ncon, ncod;
55
56
	memcpy(regs,focus_defaults,sizeof(focus_defaults));	
57
	/* Uncomment for HDTV 480p colour bars */
58
	//regs[0x0d]|=0x02;
59
	
60
	/* Turn on bridge bypass */
61
	regs[0x0a] |= 0x10;
62
	/* Turn on the HDTV clock, and turn off the SDTV one */	
63
	regs[0xa1] = 0x04;
64
	
65
	/* HDTV Hor start */
66
	regs[0xb8] = 0xbe;
67
	
68
	/*Set up video mode to HDTV, progressive, 
69
	 * and disable YUV matrix bypass */
70
	regs[0x92] = 0x1a;	
71
	regs[0x93] &= ~0x40;
72
	
73
	switch (hdtv_mode) {
74
		case HDTV_480p:
75
			/* PLL settings */
76
			regs[0x10] = 0x00;
77
			regs[0x11] = 0x00;
78
			regs[0x12] = 0x00;
79
			regs[0x13] = 0x00;
80
			regs[0x14] = 0x00;
81
			regs[0x15] = 0x00;
82
			regs[0x16] = 0x00;
83
			regs[0x17] = 0x00;
84
			regs[0x18] = 0xD7;
85
			regs[0x19] = 0x03;
86
			regs[0x1A] = 0x7C;
87
			regs[0x1B] = 0x00;
88
			regs[0x1C] = 0x07;
89
			regs[0x1D] = 0x07;
90
			/* Porches/HSync width/Luma offset */
91
			regs[0x94] = 0x3F;
92
			regs[0x95] = 0x2D;
93
			regs[0x96] = 0x3B;
94
			regs[0x97] = 0x00;
95
			regs[0x98] = 0x1B;
96
			regs[0x99] = 0x03;
97
			/* Colour scaling */
98
			regs[0xA2] = 0x4D;
99
			regs[0xA4] = 0x96;
100
			regs[0xA6] = 0x1D;
101
			regs[0xA8] = 0x58;
102
			regs[0xAA] = 0x8A;
103
			regs[0xAC] = 0x4A;
104
			break;
105
		case HDTV_720p:
106
			/* PLL settings */
107
			regs[0x10] = 0x00;
108
			regs[0x11] = 0x00;
109
			regs[0x12] = 0x00;
110
			regs[0x13] = 0x00;
111
			regs[0x14] = 0x00;
112
			regs[0x15] = 0x00;
113
			regs[0x16] = 0x00;
114
			regs[0x17] = 0x00;
115
			regs[0x18] = 0x3B;
116
			regs[0x19] = 0x04;
117
			regs[0x1A] = 0xC7;
118
			regs[0x1B] = 0x00;
119
			regs[0x1C] = 0x01;
120
			regs[0x1D] = 0x01;
121
			/* Porches/HSync width/Luma offset */
122
			regs[0x94] = 0x28;
123
			regs[0x95] = 0x46;
124
			regs[0x96] = 0xDC;
125
			regs[0x97] = 0x00;
126
			regs[0x98] = 0x2C;
127
			regs[0x99] = 0x06;
128
			/* Colour scaling */
129
			regs[0xA2] = 0x36;
130
			regs[0xA4] = 0xB7;
131
			regs[0xA6] = 0x13;
132
			regs[0xA8] = 0x58;
133
			regs[0xAA] = 0x8A;
134
			regs[0xAC] = 0x4A;
135
			/* HSync timing invert - needed to centre picture */
136
			regs[0x93] |= 0x01;
137
			
138
			break;
139
		case HDTV_1080i:
140
			/* PLL settings */
141
			regs[0x10] = 0x00;
142
			regs[0x11] = 0x00;
143
			regs[0x12] = 0x00;
144
			regs[0x13] = 0x00;
145
			regs[0x14] = 0x00;
146
			regs[0x15] = 0x00;
147
			regs[0x16] = 0x00;
148
			regs[0x17] = 0x00;
149
			regs[0x18] = 0x3B;
150
			regs[0x19] = 0x04;
151
			regs[0x1A] = 0xC7;
152
			regs[0x1B] = 0x00;
153
			regs[0x1C] = 0x01;
154
			regs[0x1D] = 0x01;
155
			/* Porches/HSync width/Luma offset */
156
			regs[0x94] = 0x2C;
157
			regs[0x95] = 0x2C;
158
			regs[0x96] = 0x58;
159
			regs[0x97] = 0x00;
160
			regs[0x98] = 0x6C;
161
			regs[0x99] = 0x08;
162
			/* Colour scaling */
163
			regs[0xA2] = 0x36;
164
			regs[0xA4] = 0xB7;
165
			regs[0xA6] = 0x13;
166
			regs[0xA8] = 0x58;
167
			regs[0xAA] = 0x8A;
168
			regs[0xAC] = 0x4A;
169
			/* Set mode to interlaced */
170
			regs[0x92] |= 0x80;
171
			break;
172
	}
173
	return 1;
174
}
175
176
int focus_calc_mode(xbox_video_mode * mode, struct riva_regs * riva_out)
177
{
178
	unsigned char b;
179
	char* regs = riva_out->encoder_mode;
180
	int m = 0;
181
	int tv_htotal, tv_vtotal, tv_vactive, tv_hactive;
182
	int vga_htotal, vga_vtotal;
183
	long ncon, ncod;
184
	int pll_m, pll_n, pll_p, vsc, hsc;
185
186
	memcpy(regs,focus_defaults,sizeof(focus_defaults));
187
	
188
	/* Uncomment for SDTV colour bars */
189
	//regs[0x45]=0x02;
190
	
191
	switch(mode->tv_encoding) {
192
		case TV_ENC_NTSC:
193
			tv_vtotal=525;
194
			tv_vactive=480;			
195
			tv_hactive = 710;
196
			tv_htotal  = 858;
197
			regs[0x0d] &= ~0x01;
198
			regs[0x40] = 0x21;
199
			regs[0x41] = 0xF0;
200
			regs[0x42] = 0x7C;
201
			regs[0x43] = 0x1F;
202
			regs[0x49] = 0x44;
203
			regs[0x4a] = 0x76;
204
			regs[0x4b] = 0x3B;
205
			regs[0x4c] = 0x00;
206
			regs[0x60] = 0x89;
207
			regs[0x62] = 0x89;
208
			regs[0x69] = 0x16;
209
			regs[0x6C] = 0x20;
210
			regs[0x74] = 0x04;		
211
			regs[0x75] = 0x10;
212
			regs[0x80] = 0x67; 
213
			regs[0x81] = 0x21; 
214
			regs[0x82] = 0x0C;
215
			regs[0x83] = 0x18;
216
			regs[0x86] = 0x18;
217
			regs[0x89] = 0x13;
218
			regs[0x8A] = 0x13;
219
			break;
220
		case TV_ENC_PALBDGHI:
221
			tv_vtotal = 625;
222
			tv_vactive = 576;
223
			tv_hactive = 702;
224
			tv_htotal = 864;
225
			break;
226
		default:
227
			/* Default to PAL */
228
			tv_vtotal = 625;
229
			tv_vactive = 576;
230
			tv_hactive = 702;
231
			tv_htotal = 864;
232
			break;
233
	}
234
235
	/* Video control  - set to RGB input*/
236
	b = (regs[0x92] &= ~0x04);
237
	regs[0x92] = (b|= 0x01);
238
	regs[0x93] &= ~0x40;
239
	/* Colour scaling */
240
	regs[0xA2] = 0x4D;
241
	regs[0xA4] = 0x96;
242
	regs[0xA6] = 0x1D;
243
	regs[0xA8] = 0xA0;
244
	regs[0xAA] = 0xDB;
245
	regs[0xAC] = 0x7E;
246
	
247
	tv_vactive = tv_vactive * (1.0f-mode->voc);
248
	vga_vtotal = mode->yres * ((float)tv_vtotal/tv_vactive);
249
	vga_htotal = mode->xres * 1.25f;
250
	tv_hactive = tv_hactive * (1.0f-mode->hoc);
251
	/*These should be calculated or at least deduced.
252
	 *However they are good enough for 640x480 -> 800x600 now*/
253
	pll_n  = 32;
254
	pll_m = 512;
255
	pll_p = 4; 
256
	
257
	ncon = vga_htotal * vga_vtotal;
258
	ncod = tv_htotal * tv_vtotal  * pll_p;
259
	
260
	regs[0x04] = (mode->xres+64)&0xFF;
261
	regs[0x05] = ((mode->xres+64)>>8)&0xFF;
262
263
	if (tv_vtotal>vga_vtotal) {
264
		/* Upscaling */
265
		vsc = ((((float)tv_vtotal/(float)vga_vtotal)-1)*65536);
266
		/* For upscaling, adjust FIFO_LAT (FIFO latency) */
267
		regs[0x38] = 0x82;
268
	}
269
	else {
270
		/* Downscaling */
271
		vsc = ((((float)tv_vtotal/(float)vga_vtotal))*65536);
272
	}
273
	regs[0x06] = (vsc)&0xFF;
274
	regs[0x07] = (vsc>>8)&0xFF;
275
276
	hsc = 128*((float)tv_hactive/(float)mode->xres-1);
277
	if (tv_hactive > mode->xres) {
278
		/* Upscaling */
279
		regs[0x08] = 0;
280
		regs[0x09] = hsc&0xFF;
281
	}
282
	else {  /* Downscaling */
283
		hsc = 256 + hsc;
284
		regs[0x08] = hsc&0xFF;
285
		regs[0x09] = 0;
286
	}
287
288
289
	regs[0x10] = (ncon)&0xFF;
290
	regs[0x11] = (ncon>>8)&0xFF ;
291
	regs[0x12] = (ncon>>16)&0xFF ;
292
	regs[0x13] = (ncon>>24)&0xFF ;
293
	regs[0x14] = (ncod)&0xFF ;
294
	regs[0x15] = (ncod>>8)&0xFF ;
295
	regs[0x16] = (ncod>>16)&0xFF ;
296
	regs[0x17] = (ncod>>24)&0xFF ;
297
	regs[0x18] = (pll_m-17)&0xFF;
298
	regs[0x19] = ((pll_m-17)>>8)&0xFF;
299
	regs[0x1A] = (pll_n-1)&0xFF ;
300
	regs[0x1B] = ((pll_n-1)>>8)&0xFF ;
301
	regs[0x1C] = (pll_p-1)&0xFF;
302
	regs[0x1D] = (pll_p-1)&0xFF;
303
	        
304
	/* Guesswork */
305
	riva_out->ext.vsyncstart = vga_vtotal * 0.95;
306
	riva_out->ext.hsyncstart = vga_htotal * 0.95;
307
	
308
	riva_out->ext.width = mode->xres;
309
	riva_out->ext.height = mode->yres;
310
	riva_out->ext.htotal = vga_htotal - 1;
311
	riva_out->ext.vend = mode->yres - 1;
312
	riva_out->ext.vtotal = vga_vtotal- 1;
313
	riva_out->ext.vcrtc = mode->yres - 1;
314
	riva_out->ext.vsyncend = riva_out->ext.vsyncstart + 3;
315
        riva_out->ext.vvalidstart = 0;
316
	riva_out->ext.vvalidend = mode->yres - 1;
317
	riva_out->ext.hend = mode->xres + 7 ;
318
	riva_out->ext.hcrtc = mode->xres - 1;
319
        riva_out->ext.hsyncend = riva_out->ext.hsyncstart + 32;
320
        riva_out->ext.hvalidstart = 0;
321
        riva_out->ext.hvalidend = mode->xres - 1;
322
	riva_out->ext.crtchdispend = mode->xres;
323
        riva_out->ext.crtcvstart = mode->yres + 32;
324
	//increased from 32
325
	riva_out->ext.crtcvtotal = mode->yres + 64;
326
327
	return 1;
328
}
(-)linux-2.6.5.orig/drivers/video/xbox/focus.h (+26 lines)
Line 0 Link Here
1
/*
2
 * linux/drivers/video/riva/focus.c - Xbox driver for Focus encoder
3
 *
4
 * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de>
5
 *
6
 * Contributors: David Pye (dmp) <dmp@davidmpye.dyndns.org>
7
 *
8
 * This file is subject to the terms and conditions of the GNU General Public
9
 * License.  See the file COPYING in the main directory of this archive
10
 * for more details.
11
 *
12
 * Known bugs and issues:
13
 *
14
 * none
15
 */
16
17
18
#ifndef focus_h_
19
#define focus_h_
20
21
#include "encoder.h"
22
#include "xboxfb.h"
23
24
int focus_calc_mode(xbox_video_mode * mode, struct riva_regs * riva_out );
25
int focus_calc_hdtv_mode(xbox_hdtv_mode hdtv_mode, unsigned char pll_int, unsigned char * mode_out);
26
#endif
(-)linux-2.6.5.orig/drivers/video/xbox/nv_driver.c (+364 lines)
Line 0 Link Here
1
/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
2
/*
3
 * Copyright 1996-1997  David J. McKay
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * copy of this software and associated documentation files (the "Software"),
7
 * to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following conditions:
11
 *
12
 * The above copyright notice and this permission notice shall be included in
13
 * all copies or substantial portions of the Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
 * SOFTWARE.
22
 */
23
24
/*
25
 * GPL licensing note -- nVidia is allowing a liberal interpretation of
26
 * the documentation restriction above, to merely say that this nVidia's
27
 * copyright and disclaimer should be included with all code derived
28
 * from this source.  -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99 
29
 */
30
31
/* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen
32
   <jpaana@s2.org> */
33
34
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.18 2002/08/0
35
5 20:47:06 mvojkovi Exp $ */
36
37
#include <linux/delay.h>
38
#include <linux/pci.h>
39
#include <linux/pci_ids.h>
40
#include "nv_type.h"
41
#include "xboxfb.h"
42
#include "nvreg.h"
43
44
45
#ifndef CONFIG_PCI		/* sanity check */
46
#error This driver requires PCI support.
47
#endif
48
49
#define PFX "rivafb: "
50
51
static inline unsigned char MISCin(struct riva_par *par)
52
{
53
	return (VGA_RD08(par->riva.PVIO, 0x3cc));
54
}
55
56
static Bool 
57
riva_is_connected(struct riva_par *par, Bool second)
58
{
59
	volatile U032 *PRAMDAC = par->riva.PRAMDAC0;
60
	U032 reg52C, reg608;
61
	Bool present;
62
63
	if(second) PRAMDAC += 0x800;
64
65
	reg52C = PRAMDAC[0x052C/4];
66
	reg608 = PRAMDAC[0x0608/4];
67
68
	PRAMDAC[0x0608/4] = reg608 & ~0x00010000;
69
70
	PRAMDAC[0x052C/4] = reg52C & 0x0000FEEE;
71
	mdelay(1); 
72
	PRAMDAC[0x052C/4] |= 1;
73
74
	par->riva.PRAMDAC0[0x0610/4] = 0x94050140;
75
	par->riva.PRAMDAC0[0x0608/4] |= 0x00001000;
76
77
	mdelay(1);
78
79
	present = (PRAMDAC[0x0608/4] & (1 << 28)) ? TRUE : FALSE;
80
81
	par->riva.PRAMDAC0[0x0608/4] &= 0x0000EFFF;
82
83
	PRAMDAC[0x052C/4] = reg52C;
84
	PRAMDAC[0x0608/4] = reg608;
85
86
	return present;
87
}
88
89
static void
90
riva_override_CRTC(struct riva_par *par)
91
{
92
	printk(KERN_INFO PFX
93
		"Detected CRTC controller %i being used\n",
94
		par->SecondCRTC ? 1 : 0);
95
96
	if(par->forceCRTC != -1) {
97
		printk(KERN_INFO PFX
98
			"Forcing usage of CRTC %i\n", par->forceCRTC);
99
		par->SecondCRTC = par->forceCRTC;
100
	}
101
}
102
103
static void
104
riva_is_second(struct riva_par *par)
105
{
106
	if (par->FlatPanel == 1) {
107
		switch(par->Chipset) {
108
		case NV_CHIP_GEFORCE4_440_GO:
109
		case NV_CHIP_GEFORCE4_440_GO_M64:
110
		case NV_CHIP_GEFORCE4_420_GO:
111
		case NV_CHIP_GEFORCE4_420_GO_M32:
112
		case NV_CHIP_QUADRO4_500_GOGL:
113
			par->SecondCRTC = TRUE;
114
			break;
115
		default:
116
			par->SecondCRTC = FALSE;
117
			break;
118
		}
119
	} else {
120
		if(riva_is_connected(par, 0)) {
121
			if(par->riva.PRAMDAC0[0x0000052C/4] & 0x100)
122
				par->SecondCRTC = TRUE;
123
			else
124
				par->SecondCRTC = FALSE;
125
		} else 
126
		if (riva_is_connected(par, 1)) {
127
			if(par->riva.PRAMDAC0[0x0000252C/4] & 0x100)
128
				par->SecondCRTC = TRUE;
129
			else
130
				par->SecondCRTC = FALSE;
131
		} else /* default */
132
			par->SecondCRTC = FALSE;
133
	}
134
	riva_override_CRTC(par);
135
}
136
137
unsigned long riva_get_memlen(struct riva_par *par)
138
{
139
	RIVA_HW_INST *chip = &par->riva;
140
	unsigned long memlen = 0;
141
	unsigned int chipset = par->Chipset;
142
	struct pci_dev* dev;
143
	int amt;
144
145
	switch (chip->Architecture) {
146
	case NV_ARCH_03:
147
		if (chip->PFB[0x00000000/4] & 0x00000020) {
148
			if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20)
149
			    && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02)) {
150
				/*
151
				 * SDRAM 128 ZX.
152
				 */
153
				switch (chip->PFB[0x00000000/4] & 0x03) {
154
				case 2:
155
					memlen = 1024 * 4;
156
					break;
157
				case 1:
158
					memlen = 1024 * 2;
159
					break;
160
				default:
161
					memlen = 1024 * 8;
162
					break;
163
				}
164
			} else {
165
				memlen = 1024 * 8;
166
			}            
167
		} else 	{
168
			/*
169
			 * SGRAM 128.
170
			 */
171
			switch (chip->PFB[0x00000000/4] & 0x00000003) {
172
			case 0:
173
				memlen = 1024 * 8;
174
				break;
175
			case 2:
176
				memlen = 1024 * 4;
177
				break;
178
			default:
179
				memlen = 1024 * 2;
180
				break;
181
			}
182
		}        
183
		break;
184
	case NV_ARCH_04:
185
		if (chip->PFB[0x00000000/4] & 0x00000100) {
186
			memlen = ((chip->PFB[0x00000000/4] >> 12) & 0x0F) * 
187
				1024 * 2 + 1024 * 2;
188
		} else {
189
			switch (chip->PFB[0x00000000/4] & 0x00000003) {
190
			case 0:
191
				memlen = 1024 * 32;
192
				break;
193
			case 1:
194
				memlen = 1024 * 4;
195
				break;
196
			case 2:
197
				memlen = 1024 * 8;
198
				break;
199
			case 3:
200
			default:
201
				memlen = 1024 * 16;
202
				break;
203
			}
204
		}
205
		break;
206
	case NV_ARCH_10:
207
	case NV_ARCH_20:
208
		if(chipset == NV_CHIP_IGEFORCE2) {
209
210
			dev = pci_find_slot(0, 1);
211
			pci_read_config_dword(dev, 0x7C, &amt);
212
			memlen = (((amt >> 6) & 31) + 1) * 1024;
213
		} else if (chipset == NV_CHIP_0x01F0) {
214
			dev = pci_find_slot(0, 1);
215
			pci_read_config_dword(dev, 0x84, &amt);
216
			memlen = (((amt >> 4) & 127) + 1) * 1024;
217
		} else {
218
			switch ((chip->PFB[0x0000020C/4] >> 20) & 0x000000FF){
219
			case 0x02:
220
				memlen = 1024 * 2;
221
				break;
222
			case 0x04:
223
				memlen = 1024 * 4;
224
				break;
225
			case 0x08:
226
				memlen = 1024 * 8;
227
				break;
228
			case 0x10:
229
				memlen = 1024 * 16;
230
				break;
231
			case 0x20:
232
				memlen = 1024 * 32;
233
				break;
234
			case 0x40:
235
				memlen = 1024 * 64;
236
				break;
237
			case 0x80:
238
				memlen = 1024 * 128;
239
				break;
240
			default:
241
				memlen = 1024 * 16;
242
				break;
243
			}
244
		}
245
		break;
246
	}
247
	return memlen;
248
}
249
250
unsigned long riva_get_maxdclk(struct riva_par *par)
251
{
252
	RIVA_HW_INST *chip = &par->riva;
253
	unsigned long dclk = 0;
254
255
	switch (chip->Architecture) {
256
	case NV_ARCH_03:
257
		if (chip->PFB[0x00000000/4] & 0x00000020) {
258
			if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20)
259
			    && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02)) {   
260
				/*
261
				 * SDRAM 128 ZX.
262
				 */
263
				dclk = 800000;
264
			} else {
265
				dclk = 1000000;
266
			}            
267
		} else {
268
			/*
269
			 * SGRAM 128.
270
			 */
271
			dclk = 1000000;
272
		} 
273
		break;
274
	case NV_ARCH_04:
275
	case NV_ARCH_10:
276
	case NV_ARCH_20:
277
		switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003) {
278
		case 3:
279
			dclk = 800000;
280
			break;
281
		default:
282
			dclk = 1000000;
283
			break;
284
		}
285
		break;
286
	}
287
	return dclk;
288
}
289
290
void
291
riva_common_setup(struct riva_par *par)
292
{
293
	par->riva.EnableIRQ = 0;
294
	par->riva.PRAMDAC0 = (unsigned *)(par->ctrl_base + 0x00680000);
295
	par->riva.PFB = (unsigned *)(par->ctrl_base + 0x00100000);
296
	par->riva.PFIFO = (unsigned *)(par->ctrl_base + 0x00002000);
297
	par->riva.PGRAPH = (unsigned *)(par->ctrl_base + 0x00400000);
298
	par->riva.PEXTDEV = (unsigned *)(par->ctrl_base + 0x00101000);
299
	par->riva.PTIMER = (unsigned *)(par->ctrl_base + 0x00009000);
300
	par->riva.PMC = (unsigned *)(par->ctrl_base + 0x00000000);
301
	par->riva.FIFO = (unsigned *)(par->ctrl_base + 0x00800000);
302
	par->riva.PCIO0 = (U008 *)(par->ctrl_base + 0x00601000);
303
	par->riva.PDIO0 = (U008 *)(par->ctrl_base + 0x00681000);
304
	par->riva.PVIO = (U008 *)(par->ctrl_base + 0x000C0000);
305
306
	par->riva.IO = (MISCin(par) & 0x01) ? 0x3D0 : 0x3B0;
307
	
308
	if (par->FlatPanel == -1) {
309
		switch (par->Chipset) {
310
		case NV_CHIP_GEFORCE4_440_GO:
311
		case NV_CHIP_GEFORCE4_440_GO_M64:
312
		case NV_CHIP_GEFORCE4_420_GO:
313
		case NV_CHIP_GEFORCE4_420_GO_M32:
314
		case NV_CHIP_QUADRO4_500_GOGL:
315
		case NV_CHIP_GEFORCE2_GO:
316
			printk(KERN_INFO PFX 
317
				"On a laptop.  Assuming Digital Flat Panel\n");
318
			par->FlatPanel = 1;
319
			break;
320
		default:
321
			break;
322
		}
323
	}
324
	
325
	switch (par->Chipset & 0x0ff0) {
326
	case 0x0110:
327
		if (par->Chipset == NV_CHIP_GEFORCE2_GO)
328
			par->SecondCRTC = TRUE; 
329
#if defined(__powerpc__)
330
		if (par->FlatPanel == 1)
331
			par->SecondCRTC = TRUE;
332
#endif
333
		riva_override_CRTC(par);
334
		break;
335
	case 0x0170:
336
	case 0x0180:
337
	case 0x01F0:
338
	case 0x0250:
339
	case 0x0280:
340
		riva_is_second(par);
341
		break;
342
	default:
343
		break;
344
	}
345
346
	if (par->SecondCRTC) {
347
		par->riva.PCIO = par->riva.PCIO0 + 0x2000;
348
		par->riva.PCRTC = par->riva.PCRTC0 + 0x800;
349
		par->riva.PRAMDAC = par->riva.PRAMDAC0 + 0x800;
350
		par->riva.PDIO = par->riva.PDIO0 + 0x2000;
351
	} else {
352
		par->riva.PCIO = par->riva.PCIO0;
353
		par->riva.PCRTC = par->riva.PCRTC0;
354
		par->riva.PRAMDAC = par->riva.PRAMDAC0;
355
		par->riva.PDIO = par->riva.PDIO0;
356
	}
357
358
	if (par->FlatPanel == -1) {
359
		/* Fix me, need x86 DDC code */
360
		par->FlatPanel = 0;
361
	}
362
	par->riva.flatPanel = (par->FlatPanel > 0) ? TRUE : FALSE;
363
}
364
(-)linux-2.6.5.orig/drivers/video/xbox/nv_type.h (+58 lines)
Line 0 Link Here
1
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_type.h,v 1.35 2002/08/05 20:47:06 mvojkovi Exp $ */
2
3
#ifndef __NV_STRUCT_H__
4
#define __NV_STRUCT_H__
5
6
#define NV_CHIP_RIVA_128            ((PCI_VENDOR_ID_NVIDIA_SGS << 16)| PCI_DEVICE_ID_NVIDIA_RIVA128)
7
#define NV_CHIP_TNT                 ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_TNT)
8
#define NV_CHIP_TNT2                ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_TNT2)
9
#define NV_CHIP_UTNT2               ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_UTNT2)
10
#define NV_CHIP_VTNT2               ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_VTNT2)
11
#define NV_CHIP_UVTNT2              ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_UVTNT2)
12
#define NV_CHIP_ITNT2               ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_ITNT2)
13
#define NV_CHIP_GEFORCE_256         ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_GEFORCE_256)
14
#define NV_CHIP_GEFORCE_DDR         ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR)
15
#define NV_CHIP_QUADRO              ((PCI_VENDOR_ID_NVIDIA << 16)| PCI_DEVICE_ID_NVIDIA_QUADRO)
16
#define NV_CHIP_GEFORCE2_MX         ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX)
17
#define NV_CHIP_GEFORCE2_MX_100     ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX_100)
18
#define NV_CHIP_QUADRO2_MXR         ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR)
19
#define NV_CHIP_GEFORCE2_GO         ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO)
20
#define NV_CHIP_GEFORCE2_GTS        ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS)
21
#define NV_CHIP_GEFORCE2_TI         ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE2_TI)
22
#define NV_CHIP_GEFORCE2_ULTRA      ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA)
23
#define NV_CHIP_QUADRO2_PRO         ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO)
24
#define NV_CHIP_GEFORCE4_MX_460     ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460)
25
#define NV_CHIP_GEFORCE4_MX_440     ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440)
26
#define NV_CHIP_GEFORCE4_MX_420     ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420)
27
#define NV_CHIP_GEFORCE4_440_GO     ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO)
28
#define NV_CHIP_GEFORCE4_420_GO     ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO)
29
#define NV_CHIP_GEFORCE4_420_GO_M32 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32)
30
#define NV_CHIP_QUADRO4_500XGL      ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL)
31
#define NV_CHIP_GEFORCE4_440_GO_M64 ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64)
32
#define NV_CHIP_QUADRO4_200         ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_200)
33
#define NV_CHIP_QUADRO4_550XGL      ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL)
34
#define NV_CHIP_QUADRO4_500_GOGL    ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL)
35
#define NV_CHIP_0x0180              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0180)
36
#define NV_CHIP_0x0181              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0181)
37
#define NV_CHIP_0x0182              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0182)
38
#define NV_CHIP_0x0188              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0188)
39
#define NV_CHIP_0x018A              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x018A)
40
#define NV_CHIP_0x018B              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x018B)
41
#define NV_CHIP_IGEFORCE2           ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_IGEFORCE2)
42
#define NV_CHIP_0x01F0              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x01F0)
43
#define NV_CHIP_GEFORCE3            ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE3)
44
#define NV_CHIP_GEFORCE3_TI_200     ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE3_TI_200)
45
#define NV_CHIP_GEFORCE3_TI_500     ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE3_TI_500)
46
#define NV_CHIP_QUADRO_DCC          ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO_DCC)
47
#define NV_CHIP_GEFORCE4_TI_4600    ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600)
48
#define NV_CHIP_GEFORCE4_TI_4400    ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400)
49
#define NV_CHIP_GEFORCE4_TI_4200    ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200)
50
#define NV_CHIP_QUADRO4_900XGL      ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL)
51
#define NV_CHIP_QUADRO4_750XGL      ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL)
52
#define NV_CHIP_QUADRO4_700XGL      ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL)
53
#define NV_CHIP_0x0280              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0280)
54
#define NV_CHIP_0x0281              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0281)
55
#define NV_CHIP_0x0288              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0288)
56
#define NV_CHIP_0x0289              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0289)
57
58
#endif /* __NV_STRUCT_H__ */
(-)linux-2.6.5.orig/drivers/video/xbox/nvreg.h (+188 lines)
Line 0 Link Here
1
/* $XConsortium: nvreg.h /main/2 1996/10/28 05:13:41 kaleb $ */
2
/*
3
 * Copyright 1996-1997  David J. McKay
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * copy of this software and associated documentation files (the "Software"),
7
 * to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following conditions:
11
 *
12
 * The above copyright notice and this permission notice shall be included in
13
 * all copies or substantial portions of the Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
 * SOFTWARE.
22
 */
23
24
/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/nv/nvreg.h,v 3.2.2.1 1998/01/18 10:35:36 hohndel Exp $ */
25
26
#ifndef __NVREG_H_
27
#define __NVREG_H_
28
29
/* Little macro to construct bitmask for contiguous ranges of bits */
30
#define BITMASK(t,b) (((unsigned)(1U << (((t)-(b)+1)))-1)  << (b))
31
#define MASKEXPAND(mask) BITMASK(1?mask,0?mask)
32
33
/* Macro to set specific bitfields (mask has to be a macro x:y) ! */
34
#define SetBF(mask,value) ((value) << (0?mask))
35
#define GetBF(var,mask) (((unsigned)((var) & MASKEXPAND(mask))) >> (0?mask) )
36
37
#define MaskAndSetBF(var,mask,value) (var)=(((var)&(~MASKEXPAND(mask)) \
38
                                             | SetBF(mask,value)))
39
40
#define DEVICE_BASE(device) (0?NV##_##device)
41
#define DEVICE_SIZE(device) ((1?NV##_##device) - DEVICE_BASE(device)+1)
42
43
/* This is where we will have to have conditional compilation */
44
#define DEVICE_ACCESS(device,reg) \
45
  nvCONTROL[(NV_##device##_##reg)/4]
46
47
#define DEVICE_WRITE(device,reg,value) DEVICE_ACCESS(device,reg)=(value)
48
#define DEVICE_READ(device,reg)        DEVICE_ACCESS(device,reg)
49
#define DEVICE_PRINT(device,reg) \
50
  ErrorF("NV_"#device"_"#reg"=#%08lx\n",DEVICE_ACCESS(device,reg))
51
#define DEVICE_DEF(device,mask,value) \
52
  SetBF(NV_##device##_##mask,NV_##device##_##mask##_##value)
53
#define DEVICE_VALUE(device,mask,value) SetBF(NV_##device##_##mask,value)
54
#define DEVICE_MASK(device,mask) MASKEXPAND(NV_##device##_##mask)
55
56
#define PDAC_Write(reg,value)           DEVICE_WRITE(PDAC,reg,value)
57
#define PDAC_Read(reg)                  DEVICE_READ(PDAC,reg)
58
#define PDAC_Print(reg)                 DEVICE_PRINT(PDAC,reg)
59
#define PDAC_Def(mask,value)            DEVICE_DEF(PDAC,mask,value)
60
#define PDAC_Val(mask,value)            DEVICE_VALUE(PDAC,mask,value)
61
#define PDAC_Mask(mask)                 DEVICE_MASK(PDAC,mask)
62
63
#define PFB_Write(reg,value)            DEVICE_WRITE(PFB,reg,value)
64
#define PFB_Read(reg)                   DEVICE_READ(PFB,reg)
65
#define PFB_Print(reg)                  DEVICE_PRINT(PFB,reg)
66
#define PFB_Def(mask,value)             DEVICE_DEF(PFB,mask,value)
67
#define PFB_Val(mask,value)             DEVICE_VALUE(PFB,mask,value)
68
#define PFB_Mask(mask)                  DEVICE_MASK(PFB,mask)
69
70
#define PRM_Write(reg,value)            DEVICE_WRITE(PRM,reg,value)
71
#define PRM_Read(reg)                   DEVICE_READ(PRM,reg)
72
#define PRM_Print(reg)                  DEVICE_PRINT(PRM,reg)
73
#define PRM_Def(mask,value)             DEVICE_DEF(PRM,mask,value)
74
#define PRM_Val(mask,value)             DEVICE_VALUE(PRM,mask,value)
75
#define PRM_Mask(mask)                  DEVICE_MASK(PRM,mask)
76
77
#define PGRAPH_Write(reg,value)         DEVICE_WRITE(PGRAPH,reg,value)
78
#define PGRAPH_Read(reg)                DEVICE_READ(PGRAPH,reg)
79
#define PGRAPH_Print(reg)               DEVICE_PRINT(PGRAPH,reg)
80
#define PGRAPH_Def(mask,value)          DEVICE_DEF(PGRAPH,mask,value)
81
#define PGRAPH_Val(mask,value)          DEVICE_VALUE(PGRAPH,mask,value)
82
#define PGRAPH_Mask(mask)               DEVICE_MASK(PGRAPH,mask)
83
84
#define PDMA_Write(reg,value)           DEVICE_WRITE(PDMA,reg,value)
85
#define PDMA_Read(reg)                  DEVICE_READ(PDMA,reg)
86
#define PDMA_Print(reg)                 DEVICE_PRINT(PDMA,reg)
87
#define PDMA_Def(mask,value)            DEVICE_DEF(PDMA,mask,value)
88
#define PDMA_Val(mask,value)            DEVICE_VALUE(PDMA,mask,value)
89
#define PDMA_Mask(mask)                 DEVICE_MASK(PDMA,mask)
90
91
#define PTIMER_Write(reg,value)         DEVICE_WRITE(PTIMER,reg,value)
92
#define PTIMER_Read(reg)                DEVICE_READ(PTIMER,reg)
93
#define PTIMER_Print(reg)               DEVICE_PRINT(PTIMER,reg)
94
#define PTIMER_Def(mask,value)          DEVICE_DEF(PTIMER,mask,value)
95
#define PTIMER_Val(mask,value)          DEVICE_VALUE(PTIEMR,mask,value)
96
#define PTIMER_Mask(mask)               DEVICE_MASK(PTIMER,mask)
97
98
#define PEXTDEV_Write(reg,value)         DEVICE_WRITE(PEXTDEV,reg,value)
99
#define PEXTDEV_Read(reg)                DEVICE_READ(PEXTDEV,reg)
100
#define PEXTDEV_Print(reg)               DEVICE_PRINT(PEXTDEV,reg)
101
#define PEXTDEV_Def(mask,value)          DEVICE_DEF(PEXTDEV,mask,value)
102
#define PEXTDEV_Val(mask,value)          DEVICE_VALUE(PEXTDEV,mask,value)
103
#define PEXTDEV_Mask(mask)               DEVICE_MASK(PEXTDEV,mask)
104
105
#define PFIFO_Write(reg,value)          DEVICE_WRITE(PFIFO,reg,value)
106
#define PFIFO_Read(reg)                 DEVICE_READ(PFIFO,reg)
107
#define PFIFO_Print(reg)                DEVICE_PRINT(PFIFO,reg)
108
#define PFIFO_Def(mask,value)           DEVICE_DEF(PFIFO,mask,value)
109
#define PFIFO_Val(mask,value)           DEVICE_VALUE(PFIFO,mask,value)
110
#define PFIFO_Mask(mask)                DEVICE_MASK(PFIFO,mask)
111
112
#define PRAM_Write(reg,value)           DEVICE_WRITE(PRAM,reg,value)
113
#define PRAM_Read(reg)                  DEVICE_READ(PRAM,reg)
114
#define PRAM_Print(reg)                 DEVICE_PRINT(PRAM,reg)
115
#define PRAM_Def(mask,value)            DEVICE_DEF(PRAM,mask,value)
116
#define PRAM_Val(mask,value)            DEVICE_VALUE(PRAM,mask,value)
117
#define PRAM_Mask(mask)                 DEVICE_MASK(PRAM,mask)
118
119
#define PRAMFC_Write(reg,value)         DEVICE_WRITE(PRAMFC,reg,value)
120
#define PRAMFC_Read(reg)                DEVICE_READ(PRAMFC,reg)
121
#define PRAMFC_Print(reg)               DEVICE_PRINT(PRAMFC,reg)
122
#define PRAMFC_Def(mask,value)          DEVICE_DEF(PRAMFC,mask,value)
123
#define PRAMFC_Val(mask,value)          DEVICE_VALUE(PRAMFC,mask,value)
124
#define PRAMFC_Mask(mask)               DEVICE_MASK(PRAMFC,mask)
125
126
#define PMC_Write(reg,value)            DEVICE_WRITE(PMC,reg,value)
127
#define PMC_Read(reg)                   DEVICE_READ(PMC,reg)
128
#define PMC_Print(reg)                  DEVICE_PRINT(PMC,reg)
129
#define PMC_Def(mask,value)             DEVICE_DEF(PMC,mask,value)
130
#define PMC_Val(mask,value)             DEVICE_VALUE(PMC,mask,value)
131
#define PMC_Mask(mask)                  DEVICE_MASK(PMC,mask)
132
133
#define PMC_Write(reg,value)            DEVICE_WRITE(PMC,reg,value)
134
#define PMC_Read(reg)                   DEVICE_READ(PMC,reg)
135
#define PMC_Print(reg)                  DEVICE_PRINT(PMC,reg)
136
#define PMC_Def(mask,value)             DEVICE_DEF(PMC,mask,value)
137
#define PMC_Val(mask,value)             DEVICE_VALUE(PMC,mask,value)
138
#define PMC_Mask(mask)                  DEVICE_MASK(PMC,mask)
139
140
141
#define PBUS_Write(reg,value)         DEVICE_WRITE(PBUS,reg,value)
142
#define PBUS_Read(reg)                DEVICE_READ(PBUS,reg)
143
#define PBUS_Print(reg)               DEVICE_PRINT(PBUS,reg)
144
#define PBUS_Def(mask,value)          DEVICE_DEF(PBUS,mask,value)
145
#define PBUS_Val(mask,value)          DEVICE_VALUE(PBUS,mask,value)
146
#define PBUS_Mask(mask)               DEVICE_MASK(PBUS,mask)
147
148
149
#define PRAMDAC_Write(reg,value)         DEVICE_WRITE(PRAMDAC,reg,value)
150
#define PRAMDAC_Read(reg)                DEVICE_READ(PRAMDAC,reg)
151
#define PRAMDAC_Print(reg)               DEVICE_PRINT(PRAMDAC,reg)
152
#define PRAMDAC_Def(mask,value)          DEVICE_DEF(PRAMDAC,mask,value)
153
#define PRAMDAC_Val(mask,value)          DEVICE_VALUE(PRAMDAC,mask,value)
154
#define PRAMDAC_Mask(mask)               DEVICE_MASK(PRAMDAC,mask)
155
156
157
#define PDAC_ReadExt(reg) \
158
  ((PDAC_Write(INDEX_LO,(NV_PDAC_EXT_##reg) & 0xff)),\
159
  (PDAC_Write(INDEX_HI,((NV_PDAC_EXT_##reg) >> 8) & 0xff)),\
160
  (PDAC_Read(INDEX_DATA)))
161
162
#define PDAC_WriteExt(reg,value)\
163
  ((PDAC_Write(INDEX_LO,(NV_PDAC_EXT_##reg) & 0xff)),\
164
  (PDAC_Write(INDEX_HI,((NV_PDAC_EXT_##reg) >> 8) & 0xff)),\
165
  (PDAC_Write(INDEX_DATA,(value))))
166
167
#define CRTC_Write(index,value) outb((index), 0x3d4); outb(value, 0x3d5)
168
#define CRTC_Read(index) (outb(index, 0x3d4),inb(0x3d5))
169
170
#define PCRTC_Write(index,value) CRTC_Write(NV_PCRTC_##index,value)
171
#define PCRTC_Read(index) CRTC_Read(NV_PCRTC_##index)
172
173
#define PCRTC_Def(mask,value)          DEVICE_DEF(PCRTC,mask,value)
174
#define PCRTC_Val(mask,value)          DEVICE_VALUE(PCRTC,mask,value)
175
#define PCRTC_Mask(mask)               DEVICE_MASK(PCRTC,mask)
176
177
#define SR_Write(index,value) outb(0x3c4,(index));outb(0x3c5,value)
178
#define SR_Read(index) (outb(0x3c4,index),inb(0x3c5))
179
180
extern volatile unsigned  *nvCONTROL;
181
182
typedef enum {NV1,NV3,NV4,NumNVChips} NVChipType;
183
184
NVChipType GetChipType(void);
185
186
#endif
187
188
(-)linux-2.6.5.orig/drivers/video/xbox/riva_hw.c (+2253 lines)
Line 0 Link Here
1
 /***************************************************************************\
2
|*                                                                           *|
3
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
4
|*                                                                           *|
5
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
6
|*     international laws.  Users and possessors of this source code are     *|
7
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
8
|*     use this code in individual and commercial software.                  *|
9
|*                                                                           *|
10
|*     Any use of this source code must include,  in the user documenta-     *|
11
|*     tion and  internal comments to the code,  notices to the end user     *|
12
|*     as follows:                                                           *|
13
|*                                                                           *|
14
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
15
|*                                                                           *|
16
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
17
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
18
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
19
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
20
|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
21
|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
22
|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
23
|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
24
|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
25
|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
26
|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
27
|*                                                                           *|
28
|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
29
|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
30
|*     consisting  of "commercial  computer  software"  and  "commercial     *|
31
|*     computer  software  documentation,"  as such  terms  are  used in     *|
32
|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
33
|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
34
|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
35
|*     all U.S. Government End Users  acquire the source code  with only     *|
36
|*     those rights set forth herein.                                        *|
37
|*                                                                           *|
38
 \***************************************************************************/
39
40
/*
41
 * GPL licensing note -- nVidia is allowing a liberal interpretation of
42
 * the documentation restriction above, to merely say that this nVidia's
43
 * copyright and disclaimer should be included with all code derived
44
 * from this source.  -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99 
45
 */
46
47
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.c,v 1.33 2002/08/05 20:47:06 mvojkovi Exp $ */
48
49
#include <linux/pci.h>
50
#include <linux/pci_ids.h>
51
#include "riva_hw.h"
52
#include "riva_tbl.h"
53
#include "nv_type.h"
54
55
/*
56
 * This file is an OS-agnostic file used to make RIVA 128 and RIVA TNT
57
 * operate identically (except TNT has more memory and better 3D quality.
58
 */
59
static int nv3Busy
60
(
61
    RIVA_HW_INST *chip
62
)
63
{
64
    return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x000006B0/4] & 0x01));
65
}
66
static int nv4Busy
67
(
68
    RIVA_HW_INST *chip
69
)
70
{
71
    return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x00000700/4] & 0x01));
72
}
73
static int nv10Busy
74
(
75
    RIVA_HW_INST *chip
76
)
77
{
78
    return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x00000700/4] & 0x01));
79
}
80
81
static void vgaLockUnlock
82
(
83
    RIVA_HW_INST *chip,
84
    int           Lock
85
)
86
{
87
    U008 cr11;
88
    VGA_WR08(chip->PCIO, 0x3D4, 0x11);
89
    cr11 = VGA_RD08(chip->PCIO, 0x3D5);
90
    if(Lock) cr11 |= 0x80;
91
    else cr11 &= ~0x80;
92
    VGA_WR08(chip->PCIO, 0x3D5, cr11);
93
}
94
static void nv3LockUnlock
95
(
96
    RIVA_HW_INST *chip,
97
    int           Lock
98
)
99
{
100
    VGA_WR08(chip->PVIO, 0x3C4, 0x06);
101
    VGA_WR08(chip->PVIO, 0x3C5, Lock ? 0x99 : 0x57);
102
    vgaLockUnlock(chip, Lock);
103
}
104
static void nv4LockUnlock
105
(
106
    RIVA_HW_INST *chip,
107
    int           Lock
108
)
109
{
110
    VGA_WR08(chip->PCIO, 0x3D4, 0x1F);
111
    VGA_WR08(chip->PCIO, 0x3D5, Lock ? 0x99 : 0x57);
112
    vgaLockUnlock(chip, Lock);
113
}
114
115
static int ShowHideCursor
116
(
117
    RIVA_HW_INST *chip,
118
    int           ShowHide
119
)
120
{
121
    int cursor;
122
    cursor                      =  chip->CurrentState->cursor1;
123
    chip->CurrentState->cursor1 = (chip->CurrentState->cursor1 & 0xFE) |
124
                                  (ShowHide & 0x01);
125
    VGA_WR08(chip->PCIO, 0x3D4, 0x31);
126
    VGA_WR08(chip->PCIO, 0x3D5, chip->CurrentState->cursor1);
127
    return (cursor & 0x01);
128
}
129
130
static int nv10ShowHideCursor
131
(
132
    RIVA_HW_INST *chip,
133
    int           ShowHide
134
)
135
{
136
    unsigned int cursor;
137
    cursor                           =  chip->CurrentState->cursorConfig;
138
    chip->CurrentState->cursorConfig = (chip->PCRTC[0x00000810/4] & 0xFFFFFFFE) |
139
                                  (ShowHide & 0x01);
140
    chip->PCRTC[0x00000810/4] = chip->CurrentState->cursorConfig;
141
    return (cursor & 0x01);
142
}
143
144
/****************************************************************************\
145
*                                                                            *
146
* The video arbitration routines calculate some "magic" numbers.  Fixes      *
147
* the snow seen when accessing the framebuffer without it.                   *
148
* It just works (I hope).                                                    *
149
*                                                                            *
150
\****************************************************************************/
151
152
#define DEFAULT_GR_LWM 100
153
#define DEFAULT_VID_LWM 100
154
#define DEFAULT_GR_BURST_SIZE 256
155
#define DEFAULT_VID_BURST_SIZE 128
156
#define VIDEO		0
157
#define GRAPHICS	1
158
#define MPORT		2
159
#define ENGINE		3
160
#define GFIFO_SIZE	320
161
#define GFIFO_SIZE_128	256
162
#define MFIFO_SIZE	120
163
#define VFIFO_SIZE	256
164
#define	ABS(a)	(a>0?a:-a)
165
typedef struct {
166
  int gdrain_rate;
167
  int vdrain_rate;
168
  int mdrain_rate;
169
  int gburst_size;
170
  int vburst_size;
171
  char vid_en;
172
  char gr_en;
173
  int wcmocc, wcgocc, wcvocc, wcvlwm, wcglwm;
174
  int by_gfacc;
175
  char vid_only_once;
176
  char gr_only_once;
177
  char first_vacc;
178
  char first_gacc;
179
  char first_macc;
180
  int vocc;
181
  int gocc;
182
  int mocc;
183
  char cur;
184
  char engine_en;
185
  char converged;
186
  int priority;
187
} nv3_arb_info;
188
typedef struct {
189
  int graphics_lwm;
190
  int video_lwm;
191
  int graphics_burst_size;
192
  int video_burst_size;
193
  int graphics_hi_priority;
194
  int media_hi_priority;
195
  int rtl_values;
196
  int valid;
197
} nv3_fifo_info;
198
typedef struct {
199
  char pix_bpp;
200
  char enable_video;
201
  char gr_during_vid;
202
  char enable_mp;
203
  int memory_width;
204
  int video_scale;
205
  int pclk_khz;
206
  int mclk_khz;
207
  int mem_page_miss;
208
  int mem_latency;
209
  char mem_aligned;
210
} nv3_sim_state;
211
typedef struct {
212
  int graphics_lwm;
213
  int video_lwm;
214
  int graphics_burst_size;
215
  int video_burst_size;
216
  int valid;
217
} nv4_fifo_info;
218
typedef struct {
219
  int pclk_khz;
220
  int mclk_khz;
221
  int nvclk_khz;
222
  char mem_page_miss;
223
  char mem_latency;
224
  int memory_width;
225
  char enable_video;
226
  char gr_during_vid;
227
  char pix_bpp;
228
  char mem_aligned;
229
  char enable_mp;
230
} nv4_sim_state;
231
typedef struct {
232
  int graphics_lwm;
233
  int video_lwm;
234
  int graphics_burst_size;
235
  int video_burst_size;
236
  int valid;
237
} nv10_fifo_info;
238
typedef struct {
239
  int pclk_khz;
240
  int mclk_khz;
241
  int nvclk_khz;
242
  char mem_page_miss;
243
  char mem_latency;
244
  int memory_type;
245
  int memory_width;
246
  char enable_video;
247
  char gr_during_vid;
248
  char pix_bpp;
249
  char mem_aligned;
250
  char enable_mp;
251
} nv10_sim_state;
252
static int nv3_iterate(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
253
{
254
    int iter = 0;
255
    int tmp;
256
    int vfsize, mfsize, gfsize;
257
    int mburst_size = 32;
258
    int mmisses, gmisses, vmisses;
259
    int misses;
260
    int vlwm, glwm, mlwm;
261
    int last, next, cur;
262
    int max_gfsize ;
263
    long ns;
264
265
    vlwm = 0;
266
    glwm = 0;
267
    mlwm = 0;
268
    vfsize = 0;
269
    gfsize = 0;
270
    cur = ainfo->cur;
271
    mmisses = 2;
272
    gmisses = 2;
273
    vmisses = 2;
274
    if (ainfo->gburst_size == 128) max_gfsize = GFIFO_SIZE_128;
275
    else  max_gfsize = GFIFO_SIZE;
276
    max_gfsize = GFIFO_SIZE;
277
    while (1)
278
    {
279
        if (ainfo->vid_en)
280
        {
281
            if (ainfo->wcvocc > ainfo->vocc) ainfo->wcvocc = ainfo->vocc;
282
            if (ainfo->wcvlwm > vlwm) ainfo->wcvlwm = vlwm ;
283
            ns = 1000000 * ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz;
284
            vfsize = ns * ainfo->vdrain_rate / 1000000;
285
            vfsize =  ainfo->wcvlwm - ainfo->vburst_size + vfsize;
286
        }
287
        if (state->enable_mp)
288
        {
289
            if (ainfo->wcmocc > ainfo->mocc) ainfo->wcmocc = ainfo->mocc;
290
        }
291
        if (ainfo->gr_en)
292
        {
293
            if (ainfo->wcglwm > glwm) ainfo->wcglwm = glwm ;
294
            if (ainfo->wcgocc > ainfo->gocc) ainfo->wcgocc = ainfo->gocc;
295
            ns = 1000000 * (ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz;
296
            gfsize = (ns * (long) ainfo->gdrain_rate)/1000000;
297
            gfsize = ainfo->wcglwm - ainfo->gburst_size + gfsize;
298
        }
299
        mfsize = 0;
300
        if (!state->gr_during_vid && ainfo->vid_en)
301
            if (ainfo->vid_en && (ainfo->vocc < 0) && !ainfo->vid_only_once)
302
                next = VIDEO;
303
            else if (ainfo->mocc < 0)
304
                next = MPORT;
305
            else if (ainfo->gocc< ainfo->by_gfacc)
306
                next = GRAPHICS;
307
            else return (0);
308
        else switch (ainfo->priority)
309
            {
310
                case VIDEO:
311
                    if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
312
                        next = VIDEO;
313
                    else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
314
                        next = GRAPHICS;
315
                    else if (ainfo->mocc<0)
316
                        next = MPORT;
317
                    else    return (0);
318
                    break;
319
                case GRAPHICS:
320
                    if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
321
                        next = GRAPHICS;
322
                    else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
323
                        next = VIDEO;
324
                    else if (ainfo->mocc<0)
325
                        next = MPORT;
326
                    else    return (0);
327
                    break;
328
                default:
329
                    if (ainfo->mocc<0)
330
                        next = MPORT;
331
                    else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
332
                        next = GRAPHICS;
333
                    else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
334
                        next = VIDEO;
335
                    else    return (0);
336
                    break;
337
            }
338
        last = cur;
339
        cur = next;
340
        iter++;
341
        switch (cur)
342
        {
343
            case VIDEO:
344
                if (last==cur)    misses = 0;
345
                else if (ainfo->first_vacc)   misses = vmisses;
346
                else    misses = 1;
347
                ainfo->first_vacc = 0;
348
                if (last!=cur)
349
                {
350
                    ns =  1000000 * (vmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz; 
351
                    vlwm = ns * ainfo->vdrain_rate/ 1000000;
352
                    vlwm = ainfo->vocc - vlwm;
353
                }
354
                ns = 1000000*(misses*state->mem_page_miss + ainfo->vburst_size)/(state->memory_width/8)/state->mclk_khz;
355
                ainfo->vocc = ainfo->vocc + ainfo->vburst_size - ns*ainfo->vdrain_rate/1000000;
356
                ainfo->gocc = ainfo->gocc - ns*ainfo->gdrain_rate/1000000;
357
                ainfo->mocc = ainfo->mocc - ns*ainfo->mdrain_rate/1000000;
358
                break;
359
            case GRAPHICS:
360
                if (last==cur)    misses = 0;
361
                else if (ainfo->first_gacc)   misses = gmisses;
362
                else    misses = 1;
363
                ainfo->first_gacc = 0;
364
                if (last!=cur)
365
                {
366
                    ns = 1000000*(gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz ;
367
                    glwm = ns * ainfo->gdrain_rate/1000000;
368
                    glwm = ainfo->gocc - glwm;
369
                }
370
                ns = 1000000*(misses*state->mem_page_miss + ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz;
371
                ainfo->vocc = ainfo->vocc + 0 - ns*ainfo->vdrain_rate/1000000;
372
                ainfo->gocc = ainfo->gocc + ainfo->gburst_size - ns*ainfo->gdrain_rate/1000000;
373
                ainfo->mocc = ainfo->mocc + 0 - ns*ainfo->mdrain_rate/1000000;
374
                break;
375
            default:
376
                if (last==cur)    misses = 0;
377
                else if (ainfo->first_macc)   misses = mmisses;
378
                else    misses = 1;
379
                ainfo->first_macc = 0;
380
                ns = 1000000*(misses*state->mem_page_miss + mburst_size/(state->memory_width/8))/state->mclk_khz;
381
                ainfo->vocc = ainfo->vocc + 0 - ns*ainfo->vdrain_rate/1000000;
382
                ainfo->gocc = ainfo->gocc + 0 - ns*ainfo->gdrain_rate/1000000;
383
                ainfo->mocc = ainfo->mocc + mburst_size - ns*ainfo->mdrain_rate/1000000;
384
                break;
385
        }
386
        if (iter>100)
387
        {
388
            ainfo->converged = 0;
389
            return (1);
390
        }
391
        ns = 1000000*ainfo->gburst_size/(state->memory_width/8)/state->mclk_khz;
392
        tmp = ns * ainfo->gdrain_rate/1000000;
393
        if (ABS(ainfo->gburst_size) + ((ABS(ainfo->wcglwm) + 16 ) & ~0x7) - tmp > max_gfsize)
394
        {
395
            ainfo->converged = 0;
396
            return (1);
397
        }
398
        ns = 1000000*ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz;
399
        tmp = ns * ainfo->vdrain_rate/1000000;
400
        if (ABS(ainfo->vburst_size) + (ABS(ainfo->wcvlwm + 32) & ~0xf)  - tmp> VFIFO_SIZE)
401
        {
402
            ainfo->converged = 0;
403
            return (1);
404
        }
405
        if (ABS(ainfo->gocc) > max_gfsize)
406
        {
407
            ainfo->converged = 0;
408
            return (1);
409
        }
410
        if (ABS(ainfo->vocc) > VFIFO_SIZE)
411
        {
412
            ainfo->converged = 0;
413
            return (1);
414
        }
415
        if (ABS(ainfo->mocc) > MFIFO_SIZE)
416
        {
417
            ainfo->converged = 0;
418
            return (1);
419
        }
420
        if (ABS(vfsize) > VFIFO_SIZE)
421
        {
422
            ainfo->converged = 0;
423
            return (1);
424
        }
425
        if (ABS(gfsize) > max_gfsize)
426
        {
427
            ainfo->converged = 0;
428
            return (1);
429
        }
430
        if (ABS(mfsize) > MFIFO_SIZE)
431
        {
432
            ainfo->converged = 0;
433
            return (1);
434
        }
435
    }
436
}
437
static char nv3_arb(nv3_fifo_info * res_info, nv3_sim_state * state,  nv3_arb_info *ainfo) 
438
{
439
    long ens, vns, mns, gns;
440
    int mmisses, gmisses, vmisses, eburst_size, mburst_size;
441
    int refresh_cycle;
442
443
    refresh_cycle = 0;
444
    refresh_cycle = 2*(state->mclk_khz/state->pclk_khz) + 5;
445
    mmisses = 2;
446
    if (state->mem_aligned) gmisses = 2;
447
    else    gmisses = 3;
448
    vmisses = 2;
449
    eburst_size = state->memory_width * 1;
450
    mburst_size = 32;
451
    gns = 1000000 * (gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz;
452
    ainfo->by_gfacc = gns*ainfo->gdrain_rate/1000000;
453
    ainfo->wcmocc = 0;
454
    ainfo->wcgocc = 0;
455
    ainfo->wcvocc = 0;
456
    ainfo->wcvlwm = 0;
457
    ainfo->wcglwm = 0;
458
    ainfo->engine_en = 1;
459
    ainfo->converged = 1;
460
    if (ainfo->engine_en)
461
    {
462
        ens =  1000000*(state->mem_page_miss + eburst_size/(state->memory_width/8) +refresh_cycle)/state->mclk_khz;
463
        ainfo->mocc = state->enable_mp ? 0-ens*ainfo->mdrain_rate/1000000 : 0;
464
        ainfo->vocc = ainfo->vid_en ? 0-ens*ainfo->vdrain_rate/1000000 : 0;
465
        ainfo->gocc = ainfo->gr_en ? 0-ens*ainfo->gdrain_rate/1000000 : 0;
466
        ainfo->cur = ENGINE;
467
        ainfo->first_vacc = 1;
468
        ainfo->first_gacc = 1;
469
        ainfo->first_macc = 1;
470
        nv3_iterate(res_info, state,ainfo);
471
    }
472
    if (state->enable_mp)
473
    {
474
        mns = 1000000 * (mmisses*state->mem_page_miss + mburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
475
        ainfo->mocc = state->enable_mp ? 0 : mburst_size - mns*ainfo->mdrain_rate/1000000;
476
        ainfo->vocc = ainfo->vid_en ? 0 : 0- mns*ainfo->vdrain_rate/1000000;
477
        ainfo->gocc = ainfo->gr_en ? 0: 0- mns*ainfo->gdrain_rate/1000000;
478
        ainfo->cur = MPORT;
479
        ainfo->first_vacc = 1;
480
        ainfo->first_gacc = 1;
481
        ainfo->first_macc = 0;
482
        nv3_iterate(res_info, state,ainfo);
483
    }
484
    if (ainfo->gr_en)
485
    {
486
        ainfo->first_vacc = 1;
487
        ainfo->first_gacc = 0;
488
        ainfo->first_macc = 1;
489
        gns = 1000000*(gmisses*state->mem_page_miss + ainfo->gburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
490
        ainfo->gocc = ainfo->gburst_size - gns*ainfo->gdrain_rate/1000000;
491
        ainfo->vocc = ainfo->vid_en? 0-gns*ainfo->vdrain_rate/1000000 : 0;
492
        ainfo->mocc = state->enable_mp ?  0-gns*ainfo->mdrain_rate/1000000: 0;
493
        ainfo->cur = GRAPHICS;
494
        nv3_iterate(res_info, state,ainfo);
495
    }
496
    if (ainfo->vid_en)
497
    {
498
        ainfo->first_vacc = 0;
499
        ainfo->first_gacc = 1;
500
        ainfo->first_macc = 1;
501
        vns = 1000000*(vmisses*state->mem_page_miss + ainfo->vburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
502
        ainfo->vocc = ainfo->vburst_size - vns*ainfo->vdrain_rate/1000000;
503
        ainfo->gocc = ainfo->gr_en? (0-vns*ainfo->gdrain_rate/1000000) : 0;
504
        ainfo->mocc = state->enable_mp? 0-vns*ainfo->mdrain_rate/1000000 :0 ;
505
        ainfo->cur = VIDEO;
506
        nv3_iterate(res_info, state, ainfo);
507
    }
508
    if (ainfo->converged)
509
    {
510
        res_info->graphics_lwm = (int)ABS(ainfo->wcglwm) + 16;
511
        res_info->video_lwm = (int)ABS(ainfo->wcvlwm) + 32;
512
        res_info->graphics_burst_size = ainfo->gburst_size;
513
        res_info->video_burst_size = ainfo->vburst_size;
514
        res_info->graphics_hi_priority = (ainfo->priority == GRAPHICS);
515
        res_info->media_hi_priority = (ainfo->priority == MPORT);
516
        if (res_info->video_lwm > 160)
517
        {
518
            res_info->graphics_lwm = 256;
519
            res_info->video_lwm = 128;
520
            res_info->graphics_burst_size = 64;
521
            res_info->video_burst_size = 64;
522
            res_info->graphics_hi_priority = 0;
523
            res_info->media_hi_priority = 0;
524
            ainfo->converged = 0;
525
            return (0);
526
        }
527
        if (res_info->video_lwm > 128)
528
        {
529
            res_info->video_lwm = 128;
530
        }
531
        return (1);
532
    }
533
    else
534
    {
535
        res_info->graphics_lwm = 256;
536
        res_info->video_lwm = 128;
537
        res_info->graphics_burst_size = 64;
538
        res_info->video_burst_size = 64;
539
        res_info->graphics_hi_priority = 0;
540
        res_info->media_hi_priority = 0;
541
        return (0);
542
    }
543
}
544
static char nv3_get_param(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
545
{
546
    int done, g,v, p;
547
    
548
    done = 0;
549
    for (p=0; p < 2; p++)
550
    {
551
        for (g=128 ; g > 32; g= g>> 1)
552
        {
553
            for (v=128; v >=32; v = v>> 1)
554
            {
555
                ainfo->priority = p;
556
                ainfo->gburst_size = g;     
557
                ainfo->vburst_size = v;
558
                done = nv3_arb(res_info, state,ainfo);
559
                if (done && (g==128))
560
                    if ((res_info->graphics_lwm + g) > 256)
561
                        done = 0;
562
                if (done)
563
                    goto Done;
564
            }
565
        }
566
    }
567
568
 Done:
569
    return done;
570
}
571
static void nv3CalcArbitration 
572
(
573
    nv3_fifo_info * res_info,
574
    nv3_sim_state * state
575
)
576
{
577
    nv3_fifo_info save_info;
578
    nv3_arb_info ainfo;
579
    char   res_gr, res_vid;
580
581
    ainfo.gr_en = 1;
582
    ainfo.vid_en = state->enable_video;
583
    ainfo.vid_only_once = 0;
584
    ainfo.gr_only_once = 0;
585
    ainfo.gdrain_rate = (int) state->pclk_khz * (state->pix_bpp/8);
586
    ainfo.vdrain_rate = (int) state->pclk_khz * 2;
587
    if (state->video_scale != 0)
588
        ainfo.vdrain_rate = ainfo.vdrain_rate/state->video_scale;
589
    ainfo.mdrain_rate = 33000;
590
    res_info->rtl_values = 0;
591
    if (!state->gr_during_vid && state->enable_video)
592
    {
593
        ainfo.gr_only_once = 1;
594
        ainfo.gr_en = 1;
595
        ainfo.gdrain_rate = 0;
596
        res_vid = nv3_get_param(res_info, state,  &ainfo);
597
        res_vid = ainfo.converged;
598
        save_info.video_lwm = res_info->video_lwm;
599
        save_info.video_burst_size = res_info->video_burst_size;
600
        ainfo.vid_en = 1;
601
        ainfo.vid_only_once = 1;
602
        ainfo.gr_en = 1;
603
        ainfo.gdrain_rate = (int) state->pclk_khz * (state->pix_bpp/8);
604
        ainfo.vdrain_rate = 0;
605
        res_gr = nv3_get_param(res_info, state,  &ainfo);
606
        res_gr = ainfo.converged;
607
        res_info->video_lwm = save_info.video_lwm;
608
        res_info->video_burst_size = save_info.video_burst_size;
609
        res_info->valid = res_gr & res_vid;
610
    }
611
    else
612
    {
613
        if (!ainfo.gr_en) ainfo.gdrain_rate = 0;
614
        if (!ainfo.vid_en) ainfo.vdrain_rate = 0;
615
        res_gr = nv3_get_param(res_info, state,  &ainfo);
616
        res_info->valid = ainfo.converged;
617
    }
618
}
619
static void nv3UpdateArbitrationSettings
620
(
621
    unsigned      VClk, 
622
    unsigned      pixelDepth, 
623
    unsigned     *burst,
624
    unsigned     *lwm,
625
    RIVA_HW_INST *chip
626
)
627
{
628
    nv3_fifo_info fifo_data;
629
    nv3_sim_state sim_data;
630
    unsigned int M, N, P, pll, MClk;
631
    
632
    pll = chip->PRAMDAC0[0x00000504/4]; 
633
    M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
634
    MClk = (N * chip->CrystalFreqKHz / M) >> P;
635
    sim_data.pix_bpp        = (char)pixelDepth;
636
    sim_data.enable_video   = 0;
637
    sim_data.enable_mp      = 0;
638
    sim_data.video_scale    = 1;
639
    sim_data.memory_width   = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64;
640
    sim_data.memory_width   = 128;
641
642
    sim_data.mem_latency    = 9;
643
    sim_data.mem_aligned    = 1;
644
    sim_data.mem_page_miss  = 11;
645
    sim_data.gr_during_vid  = 0;
646
    sim_data.pclk_khz       = VClk;
647
    sim_data.mclk_khz       = MClk;
648
    nv3CalcArbitration(&fifo_data, &sim_data);
649
    if (fifo_data.valid)
650
    {
651
        int  b = fifo_data.graphics_burst_size >> 4;
652
        *burst = 0;
653
        while (b >>= 1) (*burst)++;
654
        *lwm   = fifo_data.graphics_lwm >> 3;
655
    }
656
    else
657
    {
658
        *lwm   = 0x24;
659
        *burst = 0x2;
660
    }
661
}
662
static void nv4CalcArbitration 
663
(
664
    nv4_fifo_info *fifo,
665
    nv4_sim_state *arb
666
)
667
{
668
    int data, pagemiss, cas,width, video_enable, color_key_enable, bpp, align;
669
    int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
670
    int found, mclk_extra, mclk_loop, cbs, m1, p1;
671
    int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
672
    int us_m, us_n, us_p, video_drain_rate, crtc_drain_rate;
673
    int vpm_us, us_video, vlwm, video_fill_us, cpm_us, us_crt,clwm;
674
    int craw, vraw;
675
676
    fifo->valid = 1;
677
    pclk_freq = arb->pclk_khz;
678
    mclk_freq = arb->mclk_khz;
679
    nvclk_freq = arb->nvclk_khz;
680
    pagemiss = arb->mem_page_miss;
681
    cas = arb->mem_latency;
682
    width = arb->memory_width >> 6;
683
    video_enable = arb->enable_video;
684
    color_key_enable = arb->gr_during_vid;
685
    bpp = arb->pix_bpp;
686
    align = arb->mem_aligned;
687
    mp_enable = arb->enable_mp;
688
    clwm = 0;
689
    vlwm = 0;
690
    cbs = 128;
691
    pclks = 2;
692
    nvclks = 2;
693
    nvclks += 2;
694
    nvclks += 1;
695
    mclks = 5;
696
    mclks += 3;
697
    mclks += 1;
698
    mclks += cas;
699
    mclks += 1;
700
    mclks += 1;
701
    mclks += 1;
702
    mclks += 1;
703
    mclk_extra = 3;
704
    nvclks += 2;
705
    nvclks += 1;
706
    nvclks += 1;
707
    nvclks += 1;
708
    if (mp_enable)
709
        mclks+=4;
710
    nvclks += 0;
711
    pclks += 0;
712
    found = 0;
713
    vbs = 0;
714
    while (found != 1)
715
    {
716
        fifo->valid = 1;
717
        found = 1;
718
        mclk_loop = mclks+mclk_extra;
719
        us_m = mclk_loop *1000*1000 / mclk_freq;
720
        us_n = nvclks*1000*1000 / nvclk_freq;
721
        us_p = nvclks*1000*1000 / pclk_freq;
722
        if (video_enable)
723
        {
724
            video_drain_rate = pclk_freq * 2;
725
            crtc_drain_rate = pclk_freq * bpp/8;
726
            vpagemiss = 2;
727
            vpagemiss += 1;
728
            crtpagemiss = 2;
729
            vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq;
730
            if (nvclk_freq * 2 > mclk_freq * width)
731
                video_fill_us = cbs*1000*1000 / 16 / nvclk_freq ;
732
            else
733
                video_fill_us = cbs*1000*1000 / (8 * width) / mclk_freq;
734
            us_video = vpm_us + us_m + us_n + us_p + video_fill_us;
735
            vlwm = us_video * video_drain_rate/(1000*1000);
736
            vlwm++;
737
            vbs = 128;
738
            if (vlwm > 128) vbs = 64;
739
            if (vlwm > (256-64)) vbs = 32;
740
            if (nvclk_freq * 2 > mclk_freq * width)
741
                video_fill_us = vbs *1000*1000/ 16 / nvclk_freq ;
742
            else
743
                video_fill_us = vbs*1000*1000 / (8 * width) / mclk_freq;
744
            cpm_us = crtpagemiss  * pagemiss *1000*1000/ mclk_freq;
745
            us_crt =
746
            us_video
747
            +video_fill_us
748
            +cpm_us
749
            +us_m + us_n +us_p
750
            ;
751
            clwm = us_crt * crtc_drain_rate/(1000*1000);
752
            clwm++;
753
        }
754
        else
755
        {
756
            crtc_drain_rate = pclk_freq * bpp/8;
757
            crtpagemiss = 2;
758
            crtpagemiss += 1;
759
            cpm_us = crtpagemiss  * pagemiss *1000*1000/ mclk_freq;
760
            us_crt =  cpm_us + us_m + us_n + us_p ;
761
            clwm = us_crt * crtc_drain_rate/(1000*1000);
762
            clwm++;
763
        }
764
        m1 = clwm + cbs - 512;
765
        p1 = m1 * pclk_freq / mclk_freq;
766
        p1 = p1 * bpp / 8;
767
        if ((p1 < m1) && (m1 > 0))
768
        {
769
            fifo->valid = 0;
770
            found = 0;
771
            if (mclk_extra ==0)   found = 1;
772
            mclk_extra--;
773
        }
774
        else if (video_enable)
775
        {
776
            if ((clwm > 511) || (vlwm > 255))
777
            {
778
                fifo->valid = 0;
779
                found = 0;
780
                if (mclk_extra ==0)   found = 1;
781
                mclk_extra--;
782
            }
783
        }
784
        else
785
        {
786
            if (clwm > 519)
787
            {
788
                fifo->valid = 0;
789
                found = 0;
790
                if (mclk_extra ==0)   found = 1;
791
                mclk_extra--;
792
            }
793
        }
794
        craw = clwm;
795
        vraw = vlwm;
796
        if (clwm < 384) clwm = 384;
797
        if (vlwm < 128) vlwm = 128;
798
        data = (int)(clwm);
799
        fifo->graphics_lwm = data;
800
        fifo->graphics_burst_size = 128;
801
        data = (int)((vlwm+15));
802
        fifo->video_lwm = data;
803
        fifo->video_burst_size = vbs;
804
    }
805
}
806
static void nv4UpdateArbitrationSettings
807
(
808
    unsigned      VClk, 
809
    unsigned      pixelDepth, 
810
    unsigned     *burst,
811
    unsigned     *lwm,
812
    RIVA_HW_INST *chip
813
)
814
{
815
    nv4_fifo_info fifo_data;
816
    nv4_sim_state sim_data;
817
    unsigned int M, N, P, pll, MClk, NVClk, cfg1;
818
819
    pll = chip->PRAMDAC0[0x00000504/4];
820
    M = (pll >> 0)  & 0xFF; N = (pll >> 8)  & 0xFF; P = (pll >> 16) & 0x0F;
821
    MClk  = (N * chip->CrystalFreqKHz / M) >> P;
822
    pll = chip->PRAMDAC0[0x00000500/4];
823
    M = (pll >> 0)  & 0xFF; N = (pll >> 8)  & 0xFF; P = (pll >> 16) & 0x0F;
824
    NVClk  = (N * chip->CrystalFreqKHz / M) >> P;
825
    cfg1 = chip->PFB[0x00000204/4];
826
    sim_data.pix_bpp        = (char)pixelDepth;
827
    sim_data.enable_video   = 0;
828
    sim_data.enable_mp      = 0;
829
    sim_data.memory_width   = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64;
830
    sim_data.mem_latency    = (char)cfg1 & 0x0F;
831
    sim_data.mem_aligned    = 1;
832
    sim_data.mem_page_miss  = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01));
833
    sim_data.gr_during_vid  = 0;
834
    sim_data.pclk_khz       = VClk;
835
    sim_data.mclk_khz       = MClk;
836
    sim_data.nvclk_khz      = NVClk;
837
    nv4CalcArbitration(&fifo_data, &sim_data);
838
    if (fifo_data.valid)
839
    {
840
        int  b = fifo_data.graphics_burst_size >> 4;
841
        *burst = 0;
842
        while (b >>= 1) (*burst)++;
843
        *lwm   = fifo_data.graphics_lwm >> 3;
844
    }
845
}
846
static void nv10CalcArbitration 
847
(
848
    nv10_fifo_info *fifo,
849
    nv10_sim_state *arb
850
)
851
{
852
    int data, pagemiss, cas,width, video_enable, color_key_enable, bpp, align;
853
    int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
854
    int nvclk_fill, us_extra;
855
    int found, mclk_extra, mclk_loop, cbs, m1;
856
    int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
857
    int us_m, us_m_min, us_n, us_p, video_drain_rate, crtc_drain_rate;
858
    int vus_m, vus_n, vus_p;
859
    int vpm_us, us_video, vlwm, cpm_us, us_crt,clwm;
860
    int clwm_rnd_down;
861
    int craw, m2us, us_pipe, us_pipe_min, vus_pipe, p1clk, p2;
862
    int pclks_2_top_fifo, min_mclk_extra;
863
    int us_min_mclk_extra;
864
865
    fifo->valid = 1;
866
    pclk_freq = arb->pclk_khz; /* freq in KHz */
867
    mclk_freq = arb->mclk_khz;
868
    nvclk_freq = arb->nvclk_khz;
869
    pagemiss = arb->mem_page_miss;
870
    cas = arb->mem_latency;
871
    width = arb->memory_width/64;
872
    video_enable = arb->enable_video;
873
    color_key_enable = arb->gr_during_vid;
874
    bpp = arb->pix_bpp;
875
    align = arb->mem_aligned;
876
    mp_enable = arb->enable_mp;
877
    clwm = 0;
878
    vlwm = 1024;
879
880
    cbs = 512;
881
    vbs = 512;
882
883
    pclks = 4; /* lwm detect. */
884
885
    nvclks = 3; /* lwm -> sync. */
886
    nvclks += 2; /* fbi bus cycles (1 req + 1 busy) */
887
888
    mclks  = 1;   /* 2 edge sync.  may be very close to edge so just put one. */
889
890
    mclks += 1;   /* arb_hp_req */
891
    mclks += 5;   /* ap_hp_req   tiling pipeline */
892
893
    mclks += 2;    /* tc_req     latency fifo */
894
    mclks += 2;    /* fb_cas_n_  memory request to fbio block */
895
    mclks += 7;    /* sm_d_rdv   data returned from fbio block */
896
897
    /* fb.rd.d.Put_gc   need to accumulate 256 bits for read */
898
    if (arb->memory_type == 0)
899
      if (arb->memory_width == 64) /* 64 bit bus */
900
        mclks += 4;
901
      else
902
        mclks += 2;
903
    else
904
      if (arb->memory_width == 64) /* 64 bit bus */
905
        mclks += 2;
906
      else
907
        mclks += 1;
908
909
    if ((!video_enable) && (arb->memory_width == 128))
910
    {  
911
      mclk_extra = (bpp == 32) ? 31 : 42; /* Margin of error */
912
      min_mclk_extra = 17;
913
    }
914
    else
915
    {
916
      mclk_extra = (bpp == 32) ? 8 : 4; /* Margin of error */
917
      /* mclk_extra = 4; */ /* Margin of error */
918
      min_mclk_extra = 18;
919
    }
920
921
    nvclks += 1; /* 2 edge sync.  may be very close to edge so just put one. */
922
    nvclks += 1; /* fbi_d_rdv_n */
923
    nvclks += 1; /* Fbi_d_rdata */
924
    nvclks += 1; /* crtfifo load */
925
926
    if(mp_enable)
927
      mclks+=4; /* Mp can get in with a burst of 8. */
928
    /* Extra clocks determined by heuristics */
929
930
    nvclks += 0;
931
    pclks += 0;
932
    found = 0;
933
    while(found != 1) {
934
      fifo->valid = 1;
935
      found = 1;
936
      mclk_loop = mclks+mclk_extra;
937
      us_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */
938
      us_m_min = mclks * 1000*1000 / mclk_freq; /* Minimum Mclk latency in us */
939
      us_min_mclk_extra = min_mclk_extra *1000*1000 / mclk_freq;
940
      us_n = nvclks*1000*1000 / nvclk_freq;/* nvclk latency in us */
941
      us_p = pclks*1000*1000 / pclk_freq;/* nvclk latency in us */
942
      us_pipe = us_m + us_n + us_p;
943
      us_pipe_min = us_m_min + us_n + us_p;
944
      us_extra = 0;
945
946
      vus_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */
947
      vus_n = (4)*1000*1000 / nvclk_freq;/* nvclk latency in us */
948
      vus_p = 0*1000*1000 / pclk_freq;/* pclk latency in us */
949
      vus_pipe = vus_m + vus_n + vus_p;
950
951
      if(video_enable) {
952
        video_drain_rate = pclk_freq * 4; /* MB/s */
953
        crtc_drain_rate = pclk_freq * bpp/8; /* MB/s */
954
955
        vpagemiss = 1; /* self generating page miss */
956
        vpagemiss += 1; /* One higher priority before */
957
958
        crtpagemiss = 2; /* self generating page miss */
959
        if(mp_enable)
960
            crtpagemiss += 1; /* if MA0 conflict */
961
962
        vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq;
963
964
        us_video = vpm_us + vus_m; /* Video has separate read return path */
965
966
        cpm_us = crtpagemiss  * pagemiss *1000*1000/ mclk_freq;
967
        us_crt =
968
          us_video  /* Wait for video */
969
          +cpm_us /* CRT Page miss */
970
          +us_m + us_n +us_p /* other latency */
971
          ;
972
973
        clwm = us_crt * crtc_drain_rate/(1000*1000);
974
        clwm++; /* fixed point <= float_point - 1.  Fixes that */
975
      } else {
976
        crtc_drain_rate = pclk_freq * bpp/8; /* bpp * pclk/8 */
977
978
        crtpagemiss = 1; /* self generating page miss */
979
        crtpagemiss += 1; /* MA0 page miss */
980
        if(mp_enable)
981
            crtpagemiss += 1; /* if MA0 conflict */
982
        cpm_us = crtpagemiss  * pagemiss *1000*1000/ mclk_freq;
983
        us_crt =  cpm_us + us_m + us_n + us_p ;
984
        clwm = us_crt * crtc_drain_rate/(1000*1000);
985
        clwm++; /* fixed point <= float_point - 1.  Fixes that */
986
987
  /*
988
          //
989
          // Another concern, only for high pclks so don't do this
990
          // with video:
991
          // What happens if the latency to fetch the cbs is so large that
992
          // fifo empties.  In that case we need to have an alternate clwm value
993
          // based off the total burst fetch
994
          //
995
          us_crt = (cbs * 1000 * 1000)/ (8*width)/mclk_freq ;
996
          us_crt = us_crt + us_m + us_n + us_p + (4 * 1000 * 1000)/mclk_freq;
997
          clwm_mt = us_crt * crtc_drain_rate/(1000*1000);
998
          clwm_mt ++;
999
          if(clwm_mt > clwm)
1000
              clwm = clwm_mt;
1001
  */
1002
          /* Finally, a heuristic check when width == 64 bits */
1003
          if(width == 1){
1004
              nvclk_fill = nvclk_freq * 8;
1005
              if(crtc_drain_rate * 100 >= nvclk_fill * 102)
1006
                      clwm = 0xfff; /*Large number to fail */
1007
1008
              else if(crtc_drain_rate * 100  >= nvclk_fill * 98) {
1009
                  clwm = 1024;
1010
                  cbs = 512;
1011
                  us_extra = (cbs * 1000 * 1000)/ (8*width)/mclk_freq ;
1012
              }
1013
          }
1014
      }
1015
1016
1017
      /*
1018
        Overfill check:
1019
1020
        */
1021
1022
      clwm_rnd_down = ((int)clwm/8)*8;
1023
      if (clwm_rnd_down < clwm)
1024
          clwm += 8;
1025
1026
      m1 = clwm + cbs -  1024; /* Amount of overfill */
1027
      m2us = us_pipe_min + us_min_mclk_extra;
1028
      pclks_2_top_fifo = (1024-clwm)/(8*width);
1029
1030
      /* pclk cycles to drain */
1031
      p1clk = m2us * pclk_freq/(1000*1000); 
1032
      p2 = p1clk * bpp / 8; /* bytes drained. */
1033
1034
      if((p2 < m1) && (m1 > 0)) {
1035
          fifo->valid = 0;
1036
          found = 0;
1037
          if(min_mclk_extra == 0)   {
1038
            if(cbs <= 32) {
1039
              found = 1; /* Can't adjust anymore! */
1040
            } else {
1041
              cbs = cbs/2;  /* reduce the burst size */
1042
            }
1043
          } else {
1044
            min_mclk_extra--;
1045
          }
1046
      } else {
1047
        if (clwm > 1023){ /* Have some margin */
1048
          fifo->valid = 0;
1049
          found = 0;
1050
          if(min_mclk_extra == 0)   
1051
              found = 1; /* Can't adjust anymore! */
1052
          else 
1053
              min_mclk_extra--;
1054
        }
1055
      }
1056
      craw = clwm;
1057
1058
      if(clwm < (1024-cbs+8)) clwm = 1024-cbs+8;
1059
      data = (int)(clwm);
1060
      /*  printf("CRT LWM: %f bytes, prog: 0x%x, bs: 256\n", clwm, data ); */
1061
      fifo->graphics_lwm = data;   fifo->graphics_burst_size = cbs;
1062
1063
      /*  printf("VID LWM: %f bytes, prog: 0x%x, bs: %d\n, ", vlwm, data, vbs ); */
1064
      fifo->video_lwm = 1024;  fifo->video_burst_size = 512;
1065
    }
1066
}
1067
static void nv10UpdateArbitrationSettings
1068
(
1069
    unsigned      VClk, 
1070
    unsigned      pixelDepth, 
1071
    unsigned     *burst,
1072
    unsigned     *lwm,
1073
    RIVA_HW_INST *chip
1074
)
1075
{
1076
    nv10_fifo_info fifo_data;
1077
    nv10_sim_state sim_data;
1078
    unsigned int M, N, P, pll, MClk, NVClk, cfg1;
1079
1080
    pll = chip->PRAMDAC0[0x00000504/4];
1081
    M = (pll >> 0)  & 0xFF; N = (pll >> 8)  & 0xFF; P = (pll >> 16) & 0x0F;
1082
    MClk  = (N * chip->CrystalFreqKHz / M) >> P;
1083
    pll = chip->PRAMDAC0[0x00000500/4];
1084
    M = (pll >> 0)  & 0xFF; N = (pll >> 8)  & 0xFF; P = (pll >> 16) & 0x0F;
1085
    NVClk  = (N * chip->CrystalFreqKHz / M) >> P;
1086
    cfg1 = chip->PFB[0x00000204/4];
1087
    sim_data.pix_bpp        = (char)pixelDepth;
1088
    sim_data.enable_video   = 0;
1089
    sim_data.enable_mp      = 0;
1090
    sim_data.memory_type    = (chip->PFB[0x00000200/4] & 0x01) ? 1 : 0;
1091
    sim_data.memory_width   = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64;
1092
    sim_data.mem_latency    = (char)cfg1 & 0x0F;
1093
    sim_data.mem_aligned    = 1;
1094
    sim_data.mem_page_miss  = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01));
1095
    sim_data.gr_during_vid  = 0;
1096
    sim_data.pclk_khz       = VClk;
1097
    sim_data.mclk_khz       = MClk;
1098
    sim_data.nvclk_khz      = NVClk;
1099
    nv10CalcArbitration(&fifo_data, &sim_data);
1100
    if (fifo_data.valid)
1101
    {
1102
        int  b = fifo_data.graphics_burst_size >> 4;
1103
        *burst = 0;
1104
        while (b >>= 1) (*burst)++;
1105
        *lwm   = fifo_data.graphics_lwm >> 3;
1106
    }
1107
}
1108
1109
static void nForceUpdateArbitrationSettings
1110
(
1111
    unsigned      VClk,
1112
    unsigned      pixelDepth,
1113
    unsigned     *burst,
1114
    unsigned     *lwm,
1115
    RIVA_HW_INST *chip
1116
)
1117
{
1118
    nv10_fifo_info fifo_data;
1119
    nv10_sim_state sim_data;
1120
    unsigned int M, N, P, pll, MClk, NVClk;
1121
    unsigned int uMClkPostDiv;
1122
    struct pci_dev *dev;
1123
1124
    dev = pci_find_slot(0, 3);
1125
    pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
1126
    uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
1127
1128
    if(!uMClkPostDiv) uMClkPostDiv = 4;
1129
    MClk = 400000 / uMClkPostDiv;
1130
1131
    pll = chip->PRAMDAC0[0x00000500/4];
1132
    M = (pll >> 0)  & 0xFF; N = (pll >> 8)  & 0xFF; P = (pll >> 16) & 0x0F;
1133
    NVClk  = (N * chip->CrystalFreqKHz / M) >> P;
1134
    sim_data.pix_bpp        = (char)pixelDepth;
1135
    sim_data.enable_video   = 0;
1136
    sim_data.enable_mp      = 0;
1137
1138
    dev = pci_find_slot(0, 1);
1139
    pci_read_config_dword(dev, 0x7C, &sim_data.memory_type);
1140
    sim_data.memory_type    = (sim_data.memory_type >> 12) & 1;
1141
1142
    sim_data.memory_width   = 64;
1143
    sim_data.mem_latency    = 3;
1144
    sim_data.mem_aligned    = 1;
1145
    sim_data.mem_page_miss  = 10;
1146
    sim_data.gr_during_vid  = 0;
1147
    sim_data.pclk_khz       = VClk;
1148
    sim_data.mclk_khz       = MClk;
1149
    sim_data.nvclk_khz      = NVClk;
1150
    nv10CalcArbitration(&fifo_data, &sim_data);
1151
    if (fifo_data.valid)
1152
    {
1153
        int  b = fifo_data.graphics_burst_size >> 4;
1154
        *burst = 0;
1155
        while (b >>= 1) (*burst)++;
1156
        *lwm   = fifo_data.graphics_lwm >> 3;
1157
    }
1158
}
1159
1160
/****************************************************************************\
1161
*                                                                            *
1162
*                          RIVA Mode State Routines                          *
1163
*                                                                            *
1164
\****************************************************************************/
1165
1166
/*
1167
 * Calculate the Video Clock parameters for the PLL.
1168
 */
1169
static int CalcVClock
1170
(
1171
    int           clockIn,
1172
    int          *clockOut,
1173
    int          *mOut,
1174
    int          *nOut,
1175
    int          *pOut,
1176
    RIVA_HW_INST *chip
1177
)
1178
{
1179
    unsigned lowM, highM, highP;
1180
    unsigned DeltaNew, DeltaOld;
1181
    unsigned VClk, Freq;
1182
    unsigned M, N, P;
1183
    
1184
    DeltaOld = 0xFFFFFFFF;
1185
1186
    VClk     = (unsigned)clockIn;
1187
    
1188
    if (chip->CrystalFreqKHz == 13500)
1189
    {
1190
        lowM  = 7;
1191
        highM = 13 - (chip->Architecture == NV_ARCH_03);
1192
    }
1193
    else
1194
    {
1195
        lowM  = 8;
1196
        highM = 14 - (chip->Architecture == NV_ARCH_03);
1197
    }                      
1198
1199
    highP = 4 - (chip->Architecture == NV_ARCH_03);
1200
    for (P = 0; P <= highP; P ++)
1201
    {
1202
        Freq = VClk << P;
1203
        if ((Freq >= 128000) && (Freq <= chip->MaxVClockFreqKHz))
1204
        {
1205
            for (M = lowM; M <= highM; M++)
1206
            {
1207
                N    = (VClk << P) * M / chip->CrystalFreqKHz;
1208
                if(N <= 255) {
1209
                Freq = (chip->CrystalFreqKHz * N / M) >> P;
1210
                if (Freq > VClk)
1211
                    DeltaNew = Freq - VClk;
1212
                else
1213
                    DeltaNew = VClk - Freq;
1214
                if (DeltaNew < DeltaOld)
1215
                {
1216
                    *mOut     = M;
1217
                    *nOut     = N;
1218
                    *pOut     = P;
1219
                    *clockOut = Freq;
1220
                    DeltaOld  = DeltaNew;
1221
                }
1222
            }
1223
        }
1224
    }
1225
    }
1226
    return (DeltaOld != 0xFFFFFFFF);
1227
}
1228
/*
1229
 * Calculate extended mode parameters (SVGA) and save in a 
1230
 * mode state structure.
1231
 */
1232
static void CalcStateExt
1233
(
1234
    RIVA_HW_INST  *chip,
1235
    RIVA_HW_STATE *state,
1236
    int            bpp,
1237
    int            width,
1238
    int            hDisplaySize,
1239
    int            height,
1240
    int            dotClock
1241
)
1242
{
1243
    int pixelDepth, VClk, m, n, p;
1244
    /*
1245
     * Save mode parameters.
1246
     */
1247
    state->bpp    = bpp;    /* this is not bitsPerPixel, it's 8,15,16,32 */
1248
    state->width  = width;
1249
    state->height = height;
1250
    /*
1251
     * Extended RIVA registers.
1252
     */
1253
    pixelDepth = (bpp + 1)/8;
1254
    CalcVClock(dotClock, &VClk, &m, &n, &p, chip);
1255
1256
    switch (chip->Architecture)
1257
    {
1258
        case NV_ARCH_03:
1259
            nv3UpdateArbitrationSettings(VClk, 
1260
                                         pixelDepth * 8, 
1261
                                        &(state->arbitration0),
1262
                                        &(state->arbitration1),
1263
                                         chip);
1264
            state->cursor0  = 0x00;
1265
            state->cursor1  = 0x78;
1266
            state->cursor2  = 0x00000000;
1267
            state->pllsel   = 0x10010100;
1268
            state->config   = ((width + 31)/32)
1269
                            | (((pixelDepth > 2) ? 3 : pixelDepth) << 8)
1270
                            | 0x1000;
1271
            state->general  = 0x00100100;
1272
            state->repaint1 = hDisplaySize < 1280 ? 0x06 : 0x02;
1273
            break;
1274
        case NV_ARCH_04:
1275
            nv4UpdateArbitrationSettings(VClk, 
1276
                                         pixelDepth * 8, 
1277
                                        &(state->arbitration0),
1278
                                        &(state->arbitration1),
1279
                                         chip);
1280
            state->cursor0  = 0x00;
1281
            state->cursor1  = 0xFC;
1282
            state->cursor2  = 0x00000000;
1283
            state->pllsel   = 0x10000700;
1284
            state->config   = 0x00001114;
1285
            state->general  = bpp == 16 ? 0x00101100 : 0x00100100;
1286
            state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
1287
            break;
1288
        case NV_ARCH_10:
1289
        case NV_ARCH_20:
1290
            if((chip->Chipset == NV_CHIP_IGEFORCE2) ||
1291
               (chip->Chipset == NV_CHIP_0x01F0))
1292
            {
1293
                nForceUpdateArbitrationSettings(VClk,
1294
                                          pixelDepth * 8,
1295
                                         &(state->arbitration0),
1296
                                         &(state->arbitration1),
1297
                                          chip);
1298
            } else {
1299
                nv10UpdateArbitrationSettings(VClk, 
1300
                                          pixelDepth * 8, 
1301
                                         &(state->arbitration0),
1302
                                         &(state->arbitration1),
1303
                                          chip);
1304
            }
1305
            state->cursor0  = chip->CursorStart;
1306
            state->pllsel   = 0x10000700;
1307
            state->config   = chip->PFB[0x00000200/4];
1308
            state->general  = bpp == 16 ? 0x00101100 : 0x00100100;
1309
            state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
1310
            break;
1311
    }
1312
1313
    /* Paul Richards: below if block borks things in kernel for some reason */
1314
    /* if((bpp != 8) && (chip->Architecture != NV_ARCH_03))
1315
    state->general |= 0x00000030; */
1316
1317
    state->vpll     = (p << 16) | (n << 8) | m;
1318
    state->repaint0 = (((width/8)*pixelDepth) & 0x700) >> 3;
1319
    state->pixel    = pixelDepth > 2   ? 3    : pixelDepth;
1320
    state->pixel    |= 0x80;
1321
    state->offset0  =
1322
    state->offset1  =
1323
    state->offset2  =
1324
    state->offset3  = 0;
1325
    state->pitch0   =
1326
    state->pitch1   =
1327
    state->pitch2   =
1328
    state->pitch3   = pixelDepth * width;
1329
}
1330
/*
1331
 * Load fixed function state and pre-calculated/stored state.
1332
 */
1333
#define LOAD_FIXED_STATE(tbl,dev)                                       \
1334
    for (i = 0; i < sizeof(tbl##Table##dev)/8; i++)                 \
1335
        chip->dev[tbl##Table##dev[i][0]] = tbl##Table##dev[i][1]
1336
#define LOAD_FIXED_STATE_8BPP(tbl,dev)                                  \
1337
    for (i = 0; i < sizeof(tbl##Table##dev##_8BPP)/8; i++)            \
1338
        chip->dev[tbl##Table##dev##_8BPP[i][0]] = tbl##Table##dev##_8BPP[i][1]
1339
#define LOAD_FIXED_STATE_15BPP(tbl,dev)                                 \
1340
    for (i = 0; i < sizeof(tbl##Table##dev##_15BPP)/8; i++)           \
1341
        chip->dev[tbl##Table##dev##_15BPP[i][0]] = tbl##Table##dev##_15BPP[i][1]
1342
#define LOAD_FIXED_STATE_16BPP(tbl,dev)                                 \
1343
    for (i = 0; i < sizeof(tbl##Table##dev##_16BPP)/8; i++)           \
1344
        chip->dev[tbl##Table##dev##_16BPP[i][0]] = tbl##Table##dev##_16BPP[i][1]
1345
#define LOAD_FIXED_STATE_32BPP(tbl,dev)                                 \
1346
    for (i = 0; i < sizeof(tbl##Table##dev##_32BPP)/8; i++)           \
1347
        chip->dev[tbl##Table##dev##_32BPP[i][0]] = tbl##Table##dev##_32BPP[i][1]
1348
static void UpdateFifoState
1349
(
1350
    RIVA_HW_INST  *chip
1351
)
1352
{
1353
    int i;
1354
1355
    switch (chip->Architecture)
1356
    {
1357
        case NV_ARCH_04:
1358
            LOAD_FIXED_STATE(nv4,FIFO);
1359
            chip->Tri03 = 0L;
1360
            chip->Tri05 = (RivaTexturedTriangle05 *)&(chip->FIFO[0x0000E000/4]);
1361
            break;
1362
        case NV_ARCH_10:
1363
        case NV_ARCH_20:
1364
            /*
1365
             * Initialize state for the RivaTriangle3D05 routines.
1366
             */
1367
            LOAD_FIXED_STATE(nv10tri05,PGRAPH);
1368
            LOAD_FIXED_STATE(nv10,FIFO);
1369
            chip->Tri03 = 0L;
1370
            chip->Tri05 = (RivaTexturedTriangle05 *)&(chip->FIFO[0x0000E000/4]);
1371
            break;
1372
    }
1373
}
1374
static void LoadStateExt
1375
(
1376
    RIVA_HW_INST  *chip,
1377
    RIVA_HW_STATE *state
1378
)
1379
{
1380
    int i;
1381
1382
    /*
1383
     * Load HW fixed function state.
1384
     */
1385
    LOAD_FIXED_STATE(Riva,PMC);
1386
    LOAD_FIXED_STATE(Riva,PTIMER);
1387
    switch (chip->Architecture)
1388
    {
1389
        case NV_ARCH_03:
1390
            /*
1391
             * Make sure frame buffer config gets set before loading PRAMIN.
1392
             */
1393
            chip->PFB[0x00000200/4] = state->config;
1394
            LOAD_FIXED_STATE(nv3,PFIFO);
1395
            LOAD_FIXED_STATE(nv3,PRAMIN);
1396
            LOAD_FIXED_STATE(nv3,PGRAPH);
1397
            switch (state->bpp)
1398
            {
1399
                case 15:
1400
                case 16:
1401
                    LOAD_FIXED_STATE_15BPP(nv3,PRAMIN);
1402
                    LOAD_FIXED_STATE_15BPP(nv3,PGRAPH);
1403
                    chip->Tri03 = (RivaTexturedTriangle03  *)&(chip->FIFO[0x0000E000/4]);
1404
                    break;
1405
                case 24:
1406
                case 32:
1407
                    LOAD_FIXED_STATE_32BPP(nv3,PRAMIN);
1408
                    LOAD_FIXED_STATE_32BPP(nv3,PGRAPH);
1409
                    chip->Tri03 = 0L;
1410
                    break;
1411
                case 8:
1412
                default:
1413
                    LOAD_FIXED_STATE_8BPP(nv3,PRAMIN);
1414
                    LOAD_FIXED_STATE_8BPP(nv3,PGRAPH);
1415
                    chip->Tri03 = 0L;
1416
                    break;
1417
            }
1418
            for (i = 0x00000; i < 0x00800; i++)
1419
                chip->PRAMIN[0x00000502 + i] = (i << 12) | 0x03;
1420
            chip->PGRAPH[0x00000630/4] = state->offset0;
1421
            chip->PGRAPH[0x00000634/4] = state->offset1;
1422
            chip->PGRAPH[0x00000638/4] = state->offset2;
1423
            chip->PGRAPH[0x0000063C/4] = state->offset3;
1424
            chip->PGRAPH[0x00000650/4] = state->pitch0;
1425
            chip->PGRAPH[0x00000654/4] = state->pitch1;
1426
            chip->PGRAPH[0x00000658/4] = state->pitch2;
1427
            chip->PGRAPH[0x0000065C/4] = state->pitch3;
1428
            break;
1429
        case NV_ARCH_04:
1430
            /*
1431
             * Make sure frame buffer config gets set before loading PRAMIN.
1432
             */
1433
            chip->PFB[0x00000200/4] = state->config;
1434
            LOAD_FIXED_STATE(nv4,PFIFO);
1435
            LOAD_FIXED_STATE(nv4,PRAMIN);
1436
            LOAD_FIXED_STATE(nv4,PGRAPH);
1437
            switch (state->bpp)
1438
            {
1439
                case 15:
1440
                    LOAD_FIXED_STATE_15BPP(nv4,PRAMIN);
1441
                    LOAD_FIXED_STATE_15BPP(nv4,PGRAPH);
1442
                    chip->Tri03 = (RivaTexturedTriangle03  *)&(chip->FIFO[0x0000E000/4]);
1443
                    break;
1444
                case 16:
1445
                    LOAD_FIXED_STATE_16BPP(nv4,PRAMIN);
1446
                    LOAD_FIXED_STATE_16BPP(nv4,PGRAPH);
1447
                    chip->Tri03 = (RivaTexturedTriangle03  *)&(chip->FIFO[0x0000E000/4]);
1448
                    break;
1449
                case 24:
1450
                case 32:
1451
                    LOAD_FIXED_STATE_32BPP(nv4,PRAMIN);
1452
                    LOAD_FIXED_STATE_32BPP(nv4,PGRAPH);
1453
                    chip->Tri03 = 0L;
1454
                    break;
1455
                case 8:
1456
                default:
1457
                    LOAD_FIXED_STATE_8BPP(nv4,PRAMIN);
1458
                    LOAD_FIXED_STATE_8BPP(nv4,PGRAPH);
1459
                    chip->Tri03 = 0L;
1460
                    break;
1461
            }
1462
            chip->PGRAPH[0x00000640/4] = state->offset0;
1463
            chip->PGRAPH[0x00000644/4] = state->offset1;
1464
            chip->PGRAPH[0x00000648/4] = state->offset2;
1465
            chip->PGRAPH[0x0000064C/4] = state->offset3;
1466
            chip->PGRAPH[0x00000670/4] = state->pitch0;
1467
            chip->PGRAPH[0x00000674/4] = state->pitch1;
1468
            chip->PGRAPH[0x00000678/4] = state->pitch2;
1469
            chip->PGRAPH[0x0000067C/4] = state->pitch3;
1470
            break;
1471
        case NV_ARCH_10:
1472
        case NV_ARCH_20:
1473
            if(chip->twoHeads) {
1474
               VGA_WR08(chip->PCIO, 0x03D4, 0x44);
1475
               VGA_WR08(chip->PCIO, 0x03D5, state->crtcOwner);
1476
               chip->LockUnlock(chip, 0);
1477
            }
1478
1479
            LOAD_FIXED_STATE(nv10,PFIFO);
1480
            LOAD_FIXED_STATE(nv10,PRAMIN);
1481
            LOAD_FIXED_STATE(nv10,PGRAPH);
1482
            switch (state->bpp)
1483
            {
1484
                case 15:
1485
                    LOAD_FIXED_STATE_15BPP(nv10,PRAMIN);
1486
                    LOAD_FIXED_STATE_15BPP(nv10,PGRAPH);
1487
                    chip->Tri03 = (RivaTexturedTriangle03  *)&(chip->FIFO[0x0000E000/4]);
1488
                    break;
1489
                case 16:
1490
                    LOAD_FIXED_STATE_16BPP(nv10,PRAMIN);
1491
                    LOAD_FIXED_STATE_16BPP(nv10,PGRAPH);
1492
                    chip->Tri03 = (RivaTexturedTriangle03  *)&(chip->FIFO[0x0000E000/4]);
1493
                    break;
1494
                case 24:
1495
                case 32:
1496
                    LOAD_FIXED_STATE_32BPP(nv10,PRAMIN);
1497
                    LOAD_FIXED_STATE_32BPP(nv10,PGRAPH);
1498
                    chip->Tri03 = 0L;
1499
                    break;
1500
                case 8:
1501
                default:
1502
                    LOAD_FIXED_STATE_8BPP(nv10,PRAMIN);
1503
                    LOAD_FIXED_STATE_8BPP(nv10,PGRAPH);
1504
                    chip->Tri03 = 0L;
1505
                    break;
1506
            }
1507
1508
            if(chip->Architecture == NV_ARCH_10) {
1509
                chip->PGRAPH[0x00000640/4] = state->offset0;
1510
                chip->PGRAPH[0x00000644/4] = state->offset1;
1511
                chip->PGRAPH[0x00000648/4] = state->offset2;
1512
                chip->PGRAPH[0x0000064C/4] = state->offset3;
1513
                chip->PGRAPH[0x00000670/4] = state->pitch0;
1514
                chip->PGRAPH[0x00000674/4] = state->pitch1;
1515
                chip->PGRAPH[0x00000678/4] = state->pitch2;
1516
                chip->PGRAPH[0x0000067C/4] = state->pitch3;
1517
                chip->PGRAPH[0x00000680/4] = state->pitch3;
1518
        } else {
1519
        chip->PGRAPH[0x00000820/4] = state->offset0;
1520
        chip->PGRAPH[0x00000824/4] = state->offset1;
1521
        chip->PGRAPH[0x00000828/4] = state->offset2;
1522
        chip->PGRAPH[0x0000082C/4] = state->offset3;
1523
        chip->PGRAPH[0x00000850/4] = state->pitch0;
1524
        chip->PGRAPH[0x00000854/4] = state->pitch1;
1525
        chip->PGRAPH[0x00000858/4] = state->pitch2;
1526
        chip->PGRAPH[0x0000085C/4] = state->pitch3;
1527
        chip->PGRAPH[0x00000860/4] = state->pitch3;
1528
        chip->PGRAPH[0x00000864/4] = state->pitch3;
1529
        chip->PGRAPH[0x000009A4/4] = chip->PFB[0x00000200/4];
1530
        chip->PGRAPH[0x000009A8/4] = chip->PFB[0x00000204/4];
1531
        }
1532
            if(chip->twoHeads) {
1533
               chip->PCRTC0[0x00000860/4] = state->head;
1534
               chip->PCRTC0[0x00002860/4] = state->head2;
1535
            }
1536
            chip->PRAMDAC[0x00000404/4] |= (1 << 25);
1537
1538
            chip->PMC[0x00008704/4] = 1;
1539
            chip->PMC[0x00008140/4] = 0;
1540
            chip->PMC[0x00008920/4] = 0;
1541
            chip->PMC[0x00008924/4] = 0;
1542
            chip->PMC[0x00008908/4] = 0x01ffffff;
1543
            chip->PMC[0x0000890C/4] = 0x01ffffff;
1544
            chip->PMC[0x00001588/4] = 0;
1545
1546
            chip->PFB[0x00000240/4] = 0;
1547
            chip->PFB[0x00000244/4] = 0;
1548
            chip->PFB[0x00000248/4] = 0;
1549
            chip->PFB[0x0000024C/4] = 0;
1550
            chip->PFB[0x00000250/4] = 0;
1551
            chip->PFB[0x00000254/4] = 0;
1552
            chip->PFB[0x00000258/4] = 0;
1553
            chip->PFB[0x0000025C/4] = 0;
1554
1555
            chip->PGRAPH[0x00000B00/4] = chip->PFB[0x00000240/4];
1556
            chip->PGRAPH[0x00000B04/4] = chip->PFB[0x00000244/4];
1557
            chip->PGRAPH[0x00000B08/4] = chip->PFB[0x00000248/4];
1558
            chip->PGRAPH[0x00000B0C/4] = chip->PFB[0x0000024C/4];
1559
            chip->PGRAPH[0x00000B10/4] = chip->PFB[0x00000250/4];
1560
            chip->PGRAPH[0x00000B14/4] = chip->PFB[0x00000254/4];
1561
            chip->PGRAPH[0x00000B18/4] = chip->PFB[0x00000258/4];
1562
            chip->PGRAPH[0x00000B1C/4] = chip->PFB[0x0000025C/4];
1563
            chip->PGRAPH[0x00000B20/4] = chip->PFB[0x00000260/4];
1564
            chip->PGRAPH[0x00000B24/4] = chip->PFB[0x00000264/4];
1565
            chip->PGRAPH[0x00000B28/4] = chip->PFB[0x00000268/4];
1566
            chip->PGRAPH[0x00000B2C/4] = chip->PFB[0x0000026C/4];
1567
            chip->PGRAPH[0x00000B30/4] = chip->PFB[0x00000270/4];
1568
            chip->PGRAPH[0x00000B34/4] = chip->PFB[0x00000274/4];
1569
            chip->PGRAPH[0x00000B38/4] = chip->PFB[0x00000278/4];
1570
            chip->PGRAPH[0x00000B3C/4] = chip->PFB[0x0000027C/4];
1571
            chip->PGRAPH[0x00000B40/4] = chip->PFB[0x00000280/4];
1572
            chip->PGRAPH[0x00000B44/4] = chip->PFB[0x00000284/4];
1573
            chip->PGRAPH[0x00000B48/4] = chip->PFB[0x00000288/4];
1574
            chip->PGRAPH[0x00000B4C/4] = chip->PFB[0x0000028C/4];
1575
            chip->PGRAPH[0x00000B50/4] = chip->PFB[0x00000290/4];
1576
            chip->PGRAPH[0x00000B54/4] = chip->PFB[0x00000294/4];
1577
            chip->PGRAPH[0x00000B58/4] = chip->PFB[0x00000298/4];
1578
            chip->PGRAPH[0x00000B5C/4] = chip->PFB[0x0000029C/4];
1579
            chip->PGRAPH[0x00000B60/4] = chip->PFB[0x000002A0/4];
1580
            chip->PGRAPH[0x00000B64/4] = chip->PFB[0x000002A4/4];
1581
            chip->PGRAPH[0x00000B68/4] = chip->PFB[0x000002A8/4];
1582
            chip->PGRAPH[0x00000B6C/4] = chip->PFB[0x000002AC/4];
1583
            chip->PGRAPH[0x00000B70/4] = chip->PFB[0x000002B0/4];
1584
            chip->PGRAPH[0x00000B74/4] = chip->PFB[0x000002B4/4];
1585
            chip->PGRAPH[0x00000B78/4] = chip->PFB[0x000002B8/4];
1586
            chip->PGRAPH[0x00000B7C/4] = chip->PFB[0x000002BC/4];
1587
            chip->PGRAPH[0x00000F40/4] = 0x10000000;
1588
            chip->PGRAPH[0x00000F44/4] = 0x00000000;
1589
            chip->PGRAPH[0x00000F50/4] = 0x00000040;
1590
            chip->PGRAPH[0x00000F54/4] = 0x00000008;
1591
            chip->PGRAPH[0x00000F50/4] = 0x00000200;
1592
            for (i = 0; i < (3*16); i++)
1593
                chip->PGRAPH[0x00000F54/4] = 0x00000000;
1594
            chip->PGRAPH[0x00000F50/4] = 0x00000040;
1595
            chip->PGRAPH[0x00000F54/4] = 0x00000000;
1596
            chip->PGRAPH[0x00000F50/4] = 0x00000800;
1597
            for (i = 0; i < (16*16); i++)
1598
                chip->PGRAPH[0x00000F54/4] = 0x00000000;
1599
            chip->PGRAPH[0x00000F40/4] = 0x30000000;
1600
            chip->PGRAPH[0x00000F44/4] = 0x00000004;
1601
            chip->PGRAPH[0x00000F50/4] = 0x00006400;
1602
            for (i = 0; i < (59*4); i++)
1603
                chip->PGRAPH[0x00000F54/4] = 0x00000000;
1604
            chip->PGRAPH[0x00000F50/4] = 0x00006800;
1605
            for (i = 0; i < (47*4); i++)
1606
                chip->PGRAPH[0x00000F54/4] = 0x00000000;
1607
            chip->PGRAPH[0x00000F50/4] = 0x00006C00;
1608
            for (i = 0; i < (3*4); i++)
1609
                chip->PGRAPH[0x00000F54/4] = 0x00000000;
1610
            chip->PGRAPH[0x00000F50/4] = 0x00007000;
1611
            for (i = 0; i < (19*4); i++)
1612
                chip->PGRAPH[0x00000F54/4] = 0x00000000;
1613
            chip->PGRAPH[0x00000F50/4] = 0x00007400;
1614
            for (i = 0; i < (12*4); i++)
1615
                chip->PGRAPH[0x00000F54/4] = 0x00000000;
1616
            chip->PGRAPH[0x00000F50/4] = 0x00007800;
1617
            for (i = 0; i < (12*4); i++)
1618
                chip->PGRAPH[0x00000F54/4] = 0x00000000;
1619
            chip->PGRAPH[0x00000F50/4] = 0x00004400;
1620
            for (i = 0; i < (8*4); i++)
1621
                chip->PGRAPH[0x00000F54/4] = 0x00000000;
1622
            chip->PGRAPH[0x00000F50/4] = 0x00000000;
1623
            for (i = 0; i < 16; i++)
1624
                chip->PGRAPH[0x00000F54/4] = 0x00000000;
1625
            chip->PGRAPH[0x00000F50/4] = 0x00000040;
1626
            for (i = 0; i < 4; i++)
1627
                chip->PGRAPH[0x00000F54/4] = 0x00000000;
1628
1629
            chip->PCRTC[0x0000080c/4] = state->cursor0;
1630
            chip->PCRTC[0x00000810/4] = state->cursorConfig;
1631
1632
            if(chip->flatPanel) {
1633
               if((chip->Chipset & 0x0ff0) == 0x0110) {
1634
                   chip->PRAMDAC[0x0528/4] = state->dither;
1635
               } else 
1636
               if((chip->Chipset & 0x0ff0) >= 0x0170) {
1637
                   chip->PRAMDAC[0x083C/4] = state->dither;
1638
               }
1639
            
1640
               VGA_WR08(chip->PCIO, 0x03D4, 0x53);
1641
               VGA_WR08(chip->PCIO, 0x03D5, 0);
1642
               VGA_WR08(chip->PCIO, 0x03D4, 0x54);
1643
               VGA_WR08(chip->PCIO, 0x03D5, 0);
1644
               VGA_WR08(chip->PCIO, 0x03D4, 0x21);
1645
               VGA_WR08(chip->PCIO, 0x03D5, 0xfa);
1646
            }
1647
1648
            VGA_WR08(chip->PCIO, 0x03D4, 0x41);
1649
            VGA_WR08(chip->PCIO, 0x03D5, state->extra);
1650
    }
1651
    LOAD_FIXED_STATE(Riva,FIFO);
1652
    UpdateFifoState(chip);
1653
    /*
1654
     * Load HW mode state.
1655
     */
1656
    VGA_WR08(chip->PCIO, 0x03D4, 0x19);
1657
    VGA_WR08(chip->PCIO, 0x03D5, state->repaint0);
1658
    VGA_WR08(chip->PCIO, 0x03D4, 0x1A);
1659
    VGA_WR08(chip->PCIO, 0x03D5, state->repaint1);
1660
    VGA_WR08(chip->PCIO, 0x03D4, 0x25);
1661
    VGA_WR08(chip->PCIO, 0x03D5, state->screen);
1662
    VGA_WR08(chip->PCIO, 0x03D4, 0x28);
1663
    VGA_WR08(chip->PCIO, 0x03D5, state->pixel);
1664
    VGA_WR08(chip->PCIO, 0x03D4, 0x2D);
1665
    VGA_WR08(chip->PCIO, 0x03D5, state->horiz);
1666
    VGA_WR08(chip->PCIO, 0x03D4, 0x1B);
1667
    VGA_WR08(chip->PCIO, 0x03D5, state->arbitration0);
1668
    VGA_WR08(chip->PCIO, 0x03D4, 0x20);
1669
    VGA_WR08(chip->PCIO, 0x03D5, state->arbitration1);
1670
    VGA_WR08(chip->PCIO, 0x03D4, 0x30);
1671
    VGA_WR08(chip->PCIO, 0x03D4, 0x39);
1672
    VGA_WR08(chip->PCIO, 0x03D5, state->interlace);
1673
1674
    if(!chip->flatPanel) {
1675
       chip->PRAMDAC0[0x00000508/4] = state->vpll;
1676
       chip->PRAMDAC0[0x0000050C/4] = state->pllsel;
1677
       if(chip->twoHeads)
1678
          chip->PRAMDAC0[0x00000520/4] = state->vpll2;
1679
    }  else {
1680
       chip->PRAMDAC[0x00000848/4]  = state->scale;
1681
    }  
1682
    chip->PRAMDAC[0x00000600/4]  = state->general;
1683
    chip->PCRTC[0x00000800/4] = state->fb_start;
1684
    chip->PRAMDAC[0x00000800/4] = state->vend;
1685
    chip->PRAMDAC[0x00000804/4] = state->vtotal;
1686
    chip->PRAMDAC[0x00000808/4] = state->vcrtc;
1687
    chip->PRAMDAC[0x0000080c/4] = state->vsyncstart;
1688
    chip->PRAMDAC[0x00000810/4] = state->vsyncend;
1689
    chip->PRAMDAC[0x00000814/4] = state->vvalidstart;
1690
    chip->PRAMDAC[0x00000818/4] = state->vvalidend;
1691
    chip->PRAMDAC[0x00000820/4] = state->hend;
1692
    chip->PRAMDAC[0x00000824/4] = state->htotal;
1693
    chip->PRAMDAC[0x00000828/4] = state->hcrtc;
1694
    chip->PRAMDAC[0x0000082c/4] = state->hsyncstart;
1695
    chip->PRAMDAC[0x00000830/4] = state->hsyncend;
1696
    chip->PRAMDAC[0x00000834/4] = state->hvalidstart;
1697
    chip->PRAMDAC[0x00000838/4] = state->hvalidend;
1698
    chip->PRAMDAC[0x00000840/4] = state->checksum ;
1699
1700
    /*
1701
     * Turn off VBlank enable and reset.
1702
     */
1703
    chip->PCRTC[0x00000140/4] = 0;
1704
    chip->PCRTC[0x00000100/4] = chip->VBlankBit;
1705
    /*
1706
     * Set interrupt enable.
1707
     */    
1708
    chip->PMC[0x00000140/4]  = chip->EnableIRQ & 0x01;
1709
    /*
1710
     * Set current state pointer.
1711
     */
1712
    chip->CurrentState = state;
1713
    /*
1714
     * Reset FIFO free and empty counts.
1715
     */
1716
    chip->FifoFreeCount  = 0;
1717
    /* Free count from first subchannel */
1718
    chip->FifoEmptyCount = chip->Rop->FifoFree; 
1719
}
1720
static void UnloadStateExt
1721
(
1722
    RIVA_HW_INST  *chip,
1723
    RIVA_HW_STATE *state
1724
)
1725
{
1726
    /*
1727
     * Save current HW state.
1728
     */
1729
    VGA_WR08(chip->PCIO, 0x03D4, 0x19);
1730
    state->repaint0     = VGA_RD08(chip->PCIO, 0x03D5);
1731
    VGA_WR08(chip->PCIO, 0x03D4, 0x1A);
1732
    state->repaint1     = VGA_RD08(chip->PCIO, 0x03D5);
1733
    VGA_WR08(chip->PCIO, 0x03D4, 0x25);
1734
    state->screen       = VGA_RD08(chip->PCIO, 0x03D5);
1735
    VGA_WR08(chip->PCIO, 0x03D4, 0x28);
1736
    state->pixel        = VGA_RD08(chip->PCIO, 0x03D5);
1737
    VGA_WR08(chip->PCIO, 0x03D4, 0x2D);
1738
    state->horiz        = VGA_RD08(chip->PCIO, 0x03D5);
1739
    VGA_WR08(chip->PCIO, 0x03D4, 0x1B);
1740
    state->arbitration0 = VGA_RD08(chip->PCIO, 0x03D5);
1741
    VGA_WR08(chip->PCIO, 0x03D4, 0x20);
1742
    state->arbitration1 = VGA_RD08(chip->PCIO, 0x03D5);
1743
    VGA_WR08(chip->PCIO, 0x03D4, 0x39);
1744
    state->interlace    = VGA_RD08(chip->PCIO, 0x03D5);
1745
    state->vpll         = chip->PRAMDAC0[0x00000508/4];
1746
    state->vpll2        = chip->PRAMDAC0[0x00000520/4];
1747
    state->pllsel       = chip->PRAMDAC0[0x0000050C/4];
1748
    state->general      = chip->PRAMDAC[0x00000600/4];
1749
    state->scale        = chip->PRAMDAC[0x00000848/4];
1750
    state->config       = chip->PFB[0x00000200/4];
1751
    switch (chip->Architecture)
1752
    {
1753
        case NV_ARCH_03:
1754
            state->offset0  = chip->PGRAPH[0x00000630/4];
1755
            state->offset1  = chip->PGRAPH[0x00000634/4];
1756
            state->offset2  = chip->PGRAPH[0x00000638/4];
1757
            state->offset3  = chip->PGRAPH[0x0000063C/4];
1758
            state->pitch0   = chip->PGRAPH[0x00000650/4];
1759
            state->pitch1   = chip->PGRAPH[0x00000654/4];
1760
            state->pitch2   = chip->PGRAPH[0x00000658/4];
1761
            state->pitch3   = chip->PGRAPH[0x0000065C/4];
1762
            VGA_WR08(chip->PCIO, 0x03D4, 0x30);
1763
            state->cursor0      = VGA_RD08(chip->PCIO, 0x03D5);
1764
            VGA_WR08(chip->PCIO, 0x03D4, 0x31);
1765
            state->cursor1      = VGA_RD08(chip->PCIO, 0x03D5);
1766
            VGA_WR08(chip->PCIO, 0x03D4, 0x2F);
1767
            state->cursor2      = VGA_RD08(chip->PCIO, 0x03D5);
1768
            break;
1769
        case NV_ARCH_04:
1770
            state->offset0  = chip->PGRAPH[0x00000640/4];
1771
            state->offset1  = chip->PGRAPH[0x00000644/4];
1772
            state->offset2  = chip->PGRAPH[0x00000648/4];
1773
            state->offset3  = chip->PGRAPH[0x0000064C/4];
1774
            state->pitch0   = chip->PGRAPH[0x00000670/4];
1775
            state->pitch1   = chip->PGRAPH[0x00000674/4];
1776
            state->pitch2   = chip->PGRAPH[0x00000678/4];
1777
            state->pitch3   = chip->PGRAPH[0x0000067C/4];
1778
            VGA_WR08(chip->PCIO, 0x03D4, 0x30);
1779
            state->cursor0      = VGA_RD08(chip->PCIO, 0x03D5);
1780
            VGA_WR08(chip->PCIO, 0x03D4, 0x31);
1781
            state->cursor1      = VGA_RD08(chip->PCIO, 0x03D5);
1782
            VGA_WR08(chip->PCIO, 0x03D4, 0x2F);
1783
            state->cursor2      = VGA_RD08(chip->PCIO, 0x03D5);
1784
            break;
1785
        case NV_ARCH_10:
1786
        case NV_ARCH_20:
1787
            state->offset0  = chip->PGRAPH[0x00000640/4];
1788
            state->offset1  = chip->PGRAPH[0x00000644/4];
1789
            state->offset2  = chip->PGRAPH[0x00000648/4];
1790
            state->offset3  = chip->PGRAPH[0x0000064C/4];
1791
            state->pitch0   = chip->PGRAPH[0x00000670/4];
1792
            state->pitch1   = chip->PGRAPH[0x00000674/4];
1793
            state->pitch2   = chip->PGRAPH[0x00000678/4];
1794
            state->pitch3   = chip->PGRAPH[0x0000067C/4];
1795
            if(chip->twoHeads) {
1796
               state->head     = chip->PCRTC0[0x00000860/4];
1797
               state->head2    = chip->PCRTC0[0x00002860/4];
1798
               VGA_WR08(chip->PCIO, 0x03D4, 0x44);
1799
               state->crtcOwner = VGA_RD08(chip->PCIO, 0x03D5);
1800
            }
1801
            VGA_WR08(chip->PCIO, 0x03D4, 0x41);
1802
            state->extra = VGA_RD08(chip->PCIO, 0x03D5);
1803
            state->cursorConfig = chip->PCRTC[0x00000810/4];
1804
1805
            if((chip->Chipset & 0x0ff0) == 0x0110) {
1806
                state->dither = chip->PRAMDAC[0x0528/4];
1807
            } else 
1808
            if((chip->Chipset & 0x0ff0) >= 0x0170) {
1809
                state->dither = chip->PRAMDAC[0x083C/4];
1810
            }
1811
            state->fb_start    = chip->PCRTC[0x00000800/4];
1812
            state->cursor0     = chip->PCRTC[0x0000080c/4];
1813
            state->vend        = chip->PRAMDAC[0x00000800/4];
1814
            state->vtotal      = chip->PRAMDAC[0x00000804/4];
1815
            state->vcrtc       = chip->PRAMDAC[0x00000808/4];
1816
            state->vsyncstart  = chip->PRAMDAC[0x0000080c/4];
1817
            state->vsyncend    = chip->PRAMDAC[0x00000810/4];
1818
            state->vvalidstart = chip->PRAMDAC[0x00000814/4];
1819
            state->vvalidend   = chip->PRAMDAC[0x00000818/4];
1820
            state->hend        = chip->PRAMDAC[0x00000820/4];
1821
            state->htotal      = chip->PRAMDAC[0x00000824/4];
1822
            state->hcrtc       = chip->PRAMDAC[0x00000828/4];
1823
            state->hsyncstart  = chip->PRAMDAC[0x0000082c/4];
1824
            state->hsyncend    = chip->PRAMDAC[0x00000830/4];
1825
            state->hvalidstart = chip->PRAMDAC[0x00000834/4];
1826
            state->hvalidend   = chip->PRAMDAC[0x00000838/4];
1827
            state->checksum    = chip->PRAMDAC[0x00000840/4];	    
1828
            break;
1829
    }
1830
}
1831
static void SetStartAddress
1832
(
1833
    RIVA_HW_INST *chip,
1834
    unsigned      start
1835
)
1836
{
1837
    chip->PCRTC[0x800/4] = start;
1838
}
1839
1840
static void SetStartAddress3
1841
(
1842
    RIVA_HW_INST *chip,
1843
    unsigned      start
1844
)
1845
{
1846
    int offset = start >> 2;
1847
    int pan    = (start & 3) << 1;
1848
    unsigned char tmp;
1849
1850
    /*
1851
     * Unlock extended registers.
1852
     */
1853
    chip->LockUnlock(chip, 0);
1854
    /*
1855
     * Set start address.
1856
     */
1857
    VGA_WR08(chip->PCIO, 0x3D4, 0x0D); VGA_WR08(chip->PCIO, 0x3D5, offset);
1858
    offset >>= 8;
1859
    VGA_WR08(chip->PCIO, 0x3D4, 0x0C); VGA_WR08(chip->PCIO, 0x3D5, offset);
1860
    offset >>= 8;
1861
    VGA_WR08(chip->PCIO, 0x3D4, 0x19); tmp = VGA_RD08(chip->PCIO, 0x3D5);
1862
    VGA_WR08(chip->PCIO, 0x3D5, (offset & 0x01F) | (tmp & ~0x1F));
1863
    VGA_WR08(chip->PCIO, 0x3D4, 0x2D); tmp = VGA_RD08(chip->PCIO, 0x3D5);
1864
    VGA_WR08(chip->PCIO, 0x3D5, (offset & 0x60) | (tmp & ~0x60));
1865
    /*
1866
     * 4 pixel pan register.
1867
     */
1868
    offset = VGA_RD08(chip->PCIO, chip->IO + 0x0A);
1869
    VGA_WR08(chip->PCIO, 0x3C0, 0x13);
1870
    VGA_WR08(chip->PCIO, 0x3C0, pan);
1871
}
1872
static void nv3SetSurfaces2D
1873
(
1874
    RIVA_HW_INST *chip,
1875
    unsigned     surf0,
1876
    unsigned     surf1
1877
)
1878
{
1879
    RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]);
1880
1881
    RIVA_FIFO_FREE(*chip,Tri03,5);
1882
    chip->FIFO[0x00003800] = 0x80000003;
1883
    Surface->Offset        = surf0;
1884
    chip->FIFO[0x00003800] = 0x80000004;
1885
    Surface->Offset        = surf1;
1886
    chip->FIFO[0x00003800] = 0x80000013;
1887
}
1888
static void nv4SetSurfaces2D
1889
(
1890
    RIVA_HW_INST *chip,
1891
    unsigned     surf0,
1892
    unsigned     surf1
1893
)
1894
{
1895
    RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]);
1896
1897
    chip->FIFO[0x00003800] = 0x80000003;
1898
    Surface->Offset        = surf0;
1899
    chip->FIFO[0x00003800] = 0x80000004;
1900
    Surface->Offset        = surf1;
1901
    chip->FIFO[0x00003800] = 0x80000014;
1902
}
1903
static void nv10SetSurfaces2D
1904
(
1905
    RIVA_HW_INST *chip,
1906
    unsigned     surf0,
1907
    unsigned     surf1
1908
)
1909
{
1910
    RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]);
1911
1912
    chip->FIFO[0x00003800] = 0x80000003;
1913
    Surface->Offset        = surf0;
1914
    chip->FIFO[0x00003800] = 0x80000004;
1915
    Surface->Offset        = surf1;
1916
    chip->FIFO[0x00003800] = 0x80000014;
1917
}
1918
static void nv3SetSurfaces3D
1919
(
1920
    RIVA_HW_INST *chip,
1921
    unsigned     surf0,
1922
    unsigned     surf1
1923
)
1924
{
1925
    RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]);
1926
1927
    RIVA_FIFO_FREE(*chip,Tri03,5);
1928
    chip->FIFO[0x00003800] = 0x80000005;
1929
    Surface->Offset        = surf0;
1930
    chip->FIFO[0x00003800] = 0x80000006;
1931
    Surface->Offset        = surf1;
1932
    chip->FIFO[0x00003800] = 0x80000013;
1933
}
1934
static void nv4SetSurfaces3D
1935
(
1936
    RIVA_HW_INST *chip,
1937
    unsigned     surf0,
1938
    unsigned     surf1
1939
)
1940
{
1941
    RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]);
1942
1943
    chip->FIFO[0x00003800] = 0x80000005;
1944
    Surface->Offset        = surf0;
1945
    chip->FIFO[0x00003800] = 0x80000006;
1946
    Surface->Offset        = surf1;
1947
    chip->FIFO[0x00003800] = 0x80000014;
1948
}
1949
static void nv10SetSurfaces3D
1950
(
1951
    RIVA_HW_INST *chip,
1952
    unsigned     surf0,
1953
    unsigned     surf1
1954
)
1955
{
1956
    RivaSurface3D *Surfaces3D = (RivaSurface3D *)&(chip->FIFO[0x0000E000/4]);
1957
1958
    RIVA_FIFO_FREE(*chip,Tri03,4);
1959
    chip->FIFO[0x00003800]         = 0x80000007;
1960
    Surfaces3D->RenderBufferOffset = surf0;
1961
    Surfaces3D->ZBufferOffset      = surf1;
1962
    chip->FIFO[0x00003800]         = 0x80000014;
1963
}
1964
1965
/****************************************************************************\
1966
*                                                                            *
1967
*                      Probe RIVA Chip Configuration                         *
1968
*                                                                            *
1969
\****************************************************************************/
1970
1971
static void nv3GetConfig
1972
(
1973
    RIVA_HW_INST *chip
1974
)
1975
{
1976
    /*
1977
     * Fill in chip configuration.
1978
     */
1979
    if (chip->PFB[0x00000000/4] & 0x00000020)
1980
    {
1981
        if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20)
1982
         && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02))
1983
        {        
1984
            /*
1985
             * SDRAM 128 ZX.
1986
             */
1987
            chip->RamBandwidthKBytesPerSec = 800000;
1988
            switch (chip->PFB[0x00000000/4] & 0x03)
1989
            {
1990
                case 2:
1991
                    chip->RamAmountKBytes = 1024 * 4;
1992
                    break;
1993
                case 1:
1994
                    chip->RamAmountKBytes = 1024 * 2;
1995
                    break;
1996
                default:
1997
                    chip->RamAmountKBytes = 1024 * 8;
1998
                    break;
1999
            }
2000
        }            
2001
        else            
2002
        {
2003
            chip->RamBandwidthKBytesPerSec = 1000000;
2004
            chip->RamAmountKBytes          = 1024 * 8;
2005
        }            
2006
    }
2007
    else
2008
    {
2009
        /*
2010
         * SGRAM 128.
2011
         */
2012
        chip->RamBandwidthKBytesPerSec = 1000000;
2013
        switch (chip->PFB[0x00000000/4] & 0x00000003)
2014
        {
2015
            case 0:
2016
                chip->RamAmountKBytes = 1024 * 8;
2017
                break;
2018
            case 2:
2019
                chip->RamAmountKBytes = 1024 * 4;
2020
                break;
2021
            default:
2022
                chip->RamAmountKBytes = 1024 * 2;
2023
                break;
2024
        }
2025
    }        
2026
    chip->CrystalFreqKHz   = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500;
2027
    chip->CURSOR           = &(chip->PRAMIN[0x00008000/4 - 0x0800/4]);
2028
    chip->VBlankBit        = 0x00000100;
2029
    chip->MaxVClockFreqKHz = 256000;
2030
    /*
2031
     * Set chip functions.
2032
     */
2033
    chip->Busy            = nv3Busy;
2034
    chip->ShowHideCursor  = ShowHideCursor;
2035
    chip->CalcStateExt    = CalcStateExt;
2036
    chip->LoadStateExt    = LoadStateExt;
2037
    chip->UnloadStateExt  = UnloadStateExt;
2038
    chip->SetStartAddress = SetStartAddress3;
2039
    chip->SetSurfaces2D   = nv3SetSurfaces2D;
2040
    chip->SetSurfaces3D   = nv3SetSurfaces3D;
2041
    chip->LockUnlock      = nv3LockUnlock;
2042
}
2043
static void nv4GetConfig
2044
(
2045
    RIVA_HW_INST *chip
2046
)
2047
{
2048
    /*
2049
     * Fill in chip configuration.
2050
     */
2051
    if (chip->PFB[0x00000000/4] & 0x00000100)
2052
    {
2053
        chip->RamAmountKBytes = ((chip->PFB[0x00000000/4] >> 12) & 0x0F) * 1024 * 2
2054
                              + 1024 * 2;
2055
    }
2056
    else
2057
    {
2058
        switch (chip->PFB[0x00000000/4] & 0x00000003)
2059
        {
2060
            case 0:
2061
                chip->RamAmountKBytes = 1024 * 32;
2062
                break;
2063
            case 1:
2064
                chip->RamAmountKBytes = 1024 * 4;
2065
                break;
2066
            case 2:
2067
                chip->RamAmountKBytes = 1024 * 8;
2068
                break;
2069
            case 3:
2070
            default:
2071
                chip->RamAmountKBytes = 1024 * 16;
2072
                break;
2073
        }
2074
    }
2075
    switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003)
2076
    {
2077
        case 3:
2078
            chip->RamBandwidthKBytesPerSec = 800000;
2079
            break;
2080
        default:
2081
            chip->RamBandwidthKBytesPerSec = 1000000;
2082
            break;
2083
    }
2084
    chip->CrystalFreqKHz   = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500;
2085
    chip->CURSOR           = &(chip->PRAMIN[0x00010000/4 - 0x0800/4]);
2086
    chip->VBlankBit        = 0x00000001;
2087
    chip->MaxVClockFreqKHz = 350000;
2088
    /*
2089
     * Set chip functions.
2090
     */
2091
    chip->Busy            = nv4Busy;
2092
    chip->ShowHideCursor  = ShowHideCursor;
2093
    chip->CalcStateExt    = CalcStateExt;
2094
    chip->LoadStateExt    = LoadStateExt;
2095
    chip->UnloadStateExt  = UnloadStateExt;
2096
    chip->SetStartAddress = SetStartAddress;
2097
    chip->SetSurfaces2D   = nv4SetSurfaces2D;
2098
    chip->SetSurfaces3D   = nv4SetSurfaces3D;
2099
    chip->LockUnlock      = nv4LockUnlock;
2100
}
2101
static void nv10GetConfig
2102
(
2103
    RIVA_HW_INST *chip,
2104
    unsigned int chipset
2105
)
2106
{
2107
    struct pci_dev* dev;
2108
    int amt;
2109
2110
#ifdef __BIG_ENDIAN
2111
    /* turn on big endian register access */
2112
    chip->PMC[0x00000004/4] = 0x01000001;
2113
#endif
2114
2115
    /*
2116
     * Fill in chip configuration.
2117
     */
2118
    if(chipset == NV_CHIP_IGEFORCE2) {
2119
        dev = pci_find_slot(0, 1);
2120
        pci_read_config_dword(dev, 0x7C, &amt);
2121
        chip->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024;
2122
    } else if(chipset == NV_CHIP_0x01F0) {
2123
        dev = pci_find_slot(0, 1);
2124
        pci_read_config_dword(dev, 0x84, &amt);
2125
        chip->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024;
2126
    } else {
2127
        switch ((chip->PFB[0x0000020C/4] >> 20) & 0x000000FF)
2128
        {
2129
            case 0x02:
2130
                chip->RamAmountKBytes = 1024 * 2;
2131
                break;
2132
            case 0x04:
2133
                chip->RamAmountKBytes = 1024 * 4;
2134
                break;
2135
            case 0x08:
2136
                chip->RamAmountKBytes = 1024 * 8;
2137
                break;
2138
            case 0x10:
2139
                chip->RamAmountKBytes = 1024 * 16;
2140
                break;
2141
            case 0x20:
2142
                chip->RamAmountKBytes = 1024 * 32;
2143
                break;
2144
            case 0x40:
2145
                chip->RamAmountKBytes = 1024 * 64;
2146
                break;
2147
            case 0x80:
2148
                chip->RamAmountKBytes = 1024 * 128;
2149
                break;
2150
            default:
2151
                chip->RamAmountKBytes = 1024 * 16;
2152
                break;
2153
        }
2154
    }
2155
    switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003)
2156
    {
2157
        case 3:
2158
            chip->RamBandwidthKBytesPerSec = 800000;
2159
            break;
2160
        default:
2161
            chip->RamBandwidthKBytesPerSec = 1000000;
2162
            break;
2163
    }
2164
    chip->CrystalFreqKHz = (chip->PEXTDEV[0x0000/4] & (1 << 6)) ? 14318 :
2165
                                                                  13500;
2166
2167
    switch (chipset & 0x0ff0) {
2168
    case 0x0170:
2169
    case 0x0180:
2170
    case 0x01F0:
2171
    case 0x0250:
2172
    case 0x0280:
2173
       if(chip->PEXTDEV[0x0000/4] & (1 << 22))
2174
           chip->CrystalFreqKHz = 27000;
2175
       break;
2176
    default:
2177
       break;
2178
    }
2179
2180
    chip->CursorStart      = (chip->RamAmountKBytes - 2) * 1024;
2181
    chip->CURSOR           = NULL;  /* can't set this here */
2182
    chip->VBlankBit        = 0x00000001;
2183
    chip->MaxVClockFreqKHz = 350000;
2184
    /*
2185
     * Set chip functions.
2186
     */
2187
    chip->Busy            = nv10Busy;
2188
    chip->ShowHideCursor  = nv10ShowHideCursor;
2189
    chip->CalcStateExt    = CalcStateExt;
2190
    chip->LoadStateExt    = LoadStateExt;
2191
    chip->UnloadStateExt  = UnloadStateExt;
2192
    chip->SetStartAddress = SetStartAddress;
2193
    chip->SetSurfaces2D   = nv10SetSurfaces2D;
2194
    chip->SetSurfaces3D   = nv10SetSurfaces3D;
2195
    chip->LockUnlock      = nv4LockUnlock;
2196
2197
    switch(chipset & 0x0ff0) {
2198
    case 0x0110:
2199
    case 0x0170:
2200
    case 0x0180:
2201
    case 0x01F0:
2202
    case 0x0250:
2203
    case 0x0280:
2204
        chip->twoHeads = TRUE;
2205
        break;
2206
    default:
2207
        chip->twoHeads = FALSE;
2208
        break;
2209
    }
2210
}
2211
int RivaGetConfig
2212
(
2213
    RIVA_HW_INST *chip,
2214
    unsigned int chipset
2215
)
2216
{
2217
    /*
2218
     * Save this so future SW know whats it's dealing with.
2219
     */
2220
    chip->Version = RIVA_SW_VERSION;
2221
    /*
2222
     * Chip specific configuration.
2223
     */
2224
    switch (chip->Architecture)
2225
    {
2226
        case NV_ARCH_03:
2227
            nv3GetConfig(chip);
2228
            break;
2229
        case NV_ARCH_04:
2230
            nv4GetConfig(chip);
2231
            break;
2232
        case NV_ARCH_10:
2233
        case NV_ARCH_20:
2234
            nv10GetConfig(chip, chipset);
2235
            break;
2236
        default:
2237
            return (-1);
2238
    }
2239
    chip->Chipset = chipset;
2240
    /*
2241
     * Fill in FIFO pointers.
2242
     */
2243
    chip->Rop    = (RivaRop                 *)&(chip->FIFO[0x00000000/4]);
2244
    chip->Clip   = (RivaClip                *)&(chip->FIFO[0x00002000/4]);
2245
    chip->Patt   = (RivaPattern             *)&(chip->FIFO[0x00004000/4]);
2246
    chip->Pixmap = (RivaPixmap              *)&(chip->FIFO[0x00006000/4]);
2247
    chip->Blt    = (RivaScreenBlt           *)&(chip->FIFO[0x00008000/4]);
2248
    chip->Bitmap = (RivaBitmap              *)&(chip->FIFO[0x0000A000/4]);
2249
    chip->Line   = (RivaLine                *)&(chip->FIFO[0x0000C000/4]);
2250
    chip->Tri03  = (RivaTexturedTriangle03  *)&(chip->FIFO[0x0000E000/4]);
2251
    return (0);
2252
}
2253
(-)linux-2.6.5.orig/drivers/video/xbox/riva_hw.h (+566 lines)
Line 0 Link Here
1
/***************************************************************************\
2
|*                                                                           *|
3
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
4
|*                                                                           *|
5
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
6
|*     international laws.  Users and possessors of this source code are     *|
7
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
8
|*     use this code in individual and commercial software.                  *|
9
|*                                                                           *|
10
|*     Any use of this source code must include,  in the user documenta-     *|
11
|*     tion and  internal comments to the code,  notices to the end user     *|
12
|*     as follows:                                                           *|
13
|*                                                                           *|
14
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
15
|*                                                                           *|
16
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
17
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
18
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
19
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
20
|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
21
|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
22
|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
23
|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
24
|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
25
|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
26
|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
27
|*                                                                           *|
28
|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
29
|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
30
|*     consisting  of "commercial  computer  software"  and  "commercial     *|
31
|*     computer  software  documentation,"  as such  terms  are  used in     *|
32
|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
33
|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
34
|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
35
|*     all U.S. Government End Users  acquire the source code  with only     *|
36
|*     those rights set forth herein.                                        *|
37
|*                                                                           *|
38
\***************************************************************************/
39
40
/*
41
 * GPL licensing note -- nVidia is allowing a liberal interpretation of
42
 * the documentation restriction above, to merely say that this nVidia's
43
 * copyright and disclaimer should be included with all code derived
44
 * from this source.  -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99 
45
 */
46
47
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h,v 1.21 2002/10/14 18:22:46 mvojkovi Exp $ */
48
#ifndef __RIVA_HW_H__
49
#define __RIVA_HW_H__
50
#define RIVA_SW_VERSION 0x00010003
51
52
#ifndef Bool
53
typedef int Bool;
54
#endif
55
56
#ifndef TRUE
57
#define TRUE 1
58
#endif
59
#ifndef FALSE
60
#define FALSE 0
61
#endif
62
#ifndef NULL
63
#define NULL 0
64
#endif
65
66
/*
67
 * Typedefs to force certain sized values.
68
 */
69
typedef unsigned char  U008;
70
typedef unsigned short U016;
71
typedef unsigned int   U032;
72
73
/*
74
 * HW access macros.
75
 */
76
#if defined(__powerpc__)
77
#include <asm/io.h>
78
#define NV_WR08(p,i,d)	out_8(p+i, d)
79
#define NV_RD08(p,i)	in_8(p+i)
80
#else
81
#define NV_WR08(p,i,d)  (((U008 *)(p))[i]=(d))
82
#define NV_RD08(p,i)    (((U008 *)(p))[i])
83
#endif
84
#define NV_WR16(p,i,d)  (((U016 *)(p))[(i)/2]=(d))
85
#define NV_RD16(p,i)    (((U016 *)(p))[(i)/2])
86
#define NV_WR32(p,i,d)  (((U032 *)(p))[(i)/4]=(d))
87
#define NV_RD32(p,i)    (((U032 *)(p))[(i)/4])
88
#define VGA_WR08(p,i,d) NV_WR08(p,i,d)
89
#define VGA_RD08(p,i)   NV_RD08(p,i)
90
91
/*
92
 * Define supported architectures.
93
 */
94
#define NV_ARCH_03  0x03
95
#define NV_ARCH_04  0x04
96
#define NV_ARCH_10  0x10
97
#define NV_ARCH_20  0x20
98
99
/***************************************************************************\
100
*                                                                           *
101
*                             FIFO registers.                               *
102
*                                                                           *
103
\***************************************************************************/
104
105
/*
106
 * Raster OPeration. Windows style ROP3.
107
 */
108
typedef volatile struct
109
{
110
    U032 reserved00[4];
111
#ifdef __BIG_ENDIAN
112
    U032 FifoFree;
113
#else
114
    U016 FifoFree;
115
    U016 Nop;
116
#endif
117
    U032 reserved01[0x0BB];
118
    U032 Rop3;
119
} RivaRop;
120
/*
121
 * 8X8 Monochrome pattern.
122
 */
123
typedef volatile struct
124
{
125
    U032 reserved00[4];
126
#ifdef __BIG_ENDIAN
127
    U032 FifoFree;
128
#else
129
    U016 FifoFree;
130
    U016 Nop;
131
#endif
132
    U032 reserved01[0x0BD];
133
    U032 Shape;
134
    U032 reserved03[0x001];
135
    U032 Color0;
136
    U032 Color1;
137
    U032 Monochrome[2];
138
} RivaPattern;
139
/*
140
 * Scissor clip rectangle.
141
 */
142
typedef volatile struct
143
{
144
    U032 reserved00[4];
145
#ifdef __BIG_ENDIAN
146
    U032 FifoFree;
147
#else
148
    U016 FifoFree;
149
    U016 Nop;
150
#endif
151
    U032 reserved01[0x0BB];
152
    U032 TopLeft;
153
    U032 WidthHeight;
154
} RivaClip;
155
/*
156
 * 2D filled rectangle.
157
 */
158
typedef volatile struct
159
{
160
    U032 reserved00[4];
161
#ifdef __BIG_ENDIAN
162
    U032 FifoFree;
163
#else
164
    U016 FifoFree;
165
    U016 Nop[1];
166
#endif
167
    U032 reserved01[0x0BC];
168
    U032 Color;
169
    U032 reserved03[0x03E];
170
    U032 TopLeft;
171
    U032 WidthHeight;
172
} RivaRectangle;
173
/*
174
 * 2D screen-screen BLT.
175
 */
176
typedef volatile struct
177
{
178
    U032 reserved00[4];
179
#ifdef __BIG_ENDIAN
180
    U032 FifoFree;
181
#else
182
    U016 FifoFree;
183
    U016 Nop;
184
#endif
185
    U032 reserved01[0x0BB];
186
    U032 TopLeftSrc;
187
    U032 TopLeftDst;
188
    U032 WidthHeight;
189
} RivaScreenBlt;
190
/*
191
 * 2D pixel BLT.
192
 */
193
typedef volatile struct
194
{
195
    U032 reserved00[4];
196
#ifdef __BIG_ENDIAN
197
    U032 FifoFree;
198
#else
199
    U016 FifoFree;
200
    U016 Nop[1];
201
#endif
202
    U032 reserved01[0x0BC];
203
    U032 TopLeft;
204
    U032 WidthHeight;
205
    U032 WidthHeightIn;
206
    U032 reserved02[0x03C];
207
    U032 Pixels;
208
} RivaPixmap;
209
/*
210
 * Filled rectangle combined with monochrome expand.  Useful for glyphs.
211
 */
212
typedef volatile struct
213
{
214
    U032 reserved00[4];
215
#ifdef __BIG_ENDIAN
216
    U032 FifoFree;
217
#else
218
    U016 FifoFree;
219
    U016 Nop;
220
#endif
221
    U032 reserved01[0x0BB];
222
    U032 reserved03[(0x040)-1];
223
    U032 Color1A;
224
    struct
225
    {
226
        U032 TopLeft;
227
        U032 WidthHeight;
228
    } UnclippedRectangle[64];
229
    U032 reserved04[(0x080)-3];
230
    struct
231
    {
232
        U032 TopLeft;
233
        U032 BottomRight;
234
    } ClipB;
235
    U032 Color1B;
236
    struct
237
    {
238
        U032 TopLeft;
239
        U032 BottomRight;
240
    } ClippedRectangle[64];
241
    U032 reserved05[(0x080)-5];
242
    struct
243
    {
244
        U032 TopLeft;
245
        U032 BottomRight;
246
    } ClipC;
247
    U032 Color1C;
248
    U032 WidthHeightC;
249
    U032 PointC;
250
    U032 MonochromeData1C;
251
    U032 reserved06[(0x080)+121];
252
    struct
253
    {
254
        U032 TopLeft;
255
        U032 BottomRight;
256
    } ClipD;
257
    U032 Color1D;
258
    U032 WidthHeightInD;
259
    U032 WidthHeightOutD;
260
    U032 PointD;
261
    U032 MonochromeData1D;
262
    U032 reserved07[(0x080)+120];
263
    struct
264
    {
265
        U032 TopLeft;
266
        U032 BottomRight;
267
    } ClipE;
268
    U032 Color0E;
269
    U032 Color1E;
270
    U032 WidthHeightInE;
271
    U032 WidthHeightOutE;
272
    U032 PointE;
273
    U032 MonochromeData01E;
274
} RivaBitmap;
275
/*
276
 * 3D textured, Z buffered triangle.
277
 */
278
typedef volatile struct
279
{
280
    U032 reserved00[4];
281
#ifdef __BIG_ENDIAN
282
    U032 FifoFree;
283
#else
284
    U016 FifoFree;
285
    U016 Nop;
286
#endif
287
    U032 reserved01[0x0BC];
288
    U032 TextureOffset;
289
    U032 TextureFormat;
290
    U032 TextureFilter;
291
    U032 FogColor;
292
/* This is a problem on LynxOS */
293
#ifdef Control
294
#undef Control
295
#endif
296
    U032 Control;
297
    U032 AlphaTest;
298
    U032 reserved02[0x339];
299
    U032 FogAndIndex;
300
    U032 Color;
301
    float ScreenX;
302
    float ScreenY;
303
    float ScreenZ;
304
    float EyeM;
305
    float TextureS;
306
    float TextureT;
307
} RivaTexturedTriangle03;
308
typedef volatile struct
309
{
310
    U032 reserved00[4];
311
#ifdef __BIG_ENDIAN
312
    U032 FifoFree;
313
#else
314
    U016 FifoFree;
315
    U016 Nop;
316
#endif
317
    U032 reserved01[0x0BB];
318
    U032 ColorKey;
319
    U032 TextureOffset;
320
    U032 TextureFormat;
321
    U032 TextureFilter;
322
    U032 Blend;
323
/* This is a problem on LynxOS */
324
#ifdef Control
325
#undef Control
326
#endif
327
    U032 Control;
328
    U032 FogColor;
329
    U032 reserved02[0x39];
330
    struct
331
    {
332
        float ScreenX;
333
        float ScreenY;
334
        float ScreenZ;
335
        float EyeM;
336
        U032 Color;
337
        U032 Specular;
338
        float TextureS;
339
        float TextureT;
340
    } Vertex[16];
341
    U032 DrawTriangle3D;
342
} RivaTexturedTriangle05;
343
/*
344
 * 2D line.
345
 */
346
typedef volatile struct
347
{
348
    U032 reserved00[4];
349
#ifdef __BIG_ENDIAN
350
    U032 FifoFree;
351
#else
352
    U016 FifoFree;
353
    U016 Nop[1];
354
#endif
355
    U032 reserved01[0x0BC];
356
    U032 Color;             /* source color               0304-0307*/
357
    U032 Reserved02[0x03e];
358
    struct {                /* start aliased methods in array   0400-    */
359
        U032 point0;        /* y_x S16_S16 in pixels            0-   3*/
360
        U032 point1;        /* y_x S16_S16 in pixels            4-   7*/
361
    } Lin[16];              /* end of aliased methods in array      -047f*/
362
    struct {                /* start aliased methods in array   0480-    */
363
        U032 point0X;       /* in pixels, 0 at left                0-   3*/
364
        U032 point0Y;       /* in pixels, 0 at top                 4-   7*/
365
        U032 point1X;       /* in pixels, 0 at left                8-   b*/
366
        U032 point1Y;       /* in pixels, 0 at top                 c-   f*/
367
    } Lin32[8];             /* end of aliased methods in array      -04ff*/
368
    U032 PolyLin[32];       /* y_x S16_S16 in pixels         0500-057f*/
369
    struct {                /* start aliased methods in array   0580-    */
370
        U032 x;             /* in pixels, 0 at left                0-   3*/
371
        U032 y;             /* in pixels, 0 at top                 4-   7*/
372
    } PolyLin32[16];        /* end of aliased methods in array      -05ff*/
373
    struct {                /* start aliased methods in array   0600-    */
374
        U032 color;         /* source color                     0-   3*/
375
        U032 point;         /* y_x S16_S16 in pixels            4-   7*/
376
    } ColorPolyLin[16];     /* end of aliased methods in array      -067f*/
377
} RivaLine;
378
/*
379
 * 2D/3D surfaces
380
 */
381
typedef volatile struct
382
{
383
    U032 reserved00[4];
384
#ifdef __BIG_ENDIAN
385
    U032 FifoFree;
386
#else
387
    U016 FifoFree;
388
    U016 Nop;
389
#endif
390
    U032 reserved01[0x0BE];
391
    U032 Offset;
392
} RivaSurface;
393
typedef volatile struct
394
{
395
    U032 reserved00[4];
396
#ifdef __BIG_ENDIAN
397
    U032 FifoFree;
398
#else
399
    U016 FifoFree;
400
    U016 Nop;
401
#endif
402
    U032 reserved01[0x0BD];
403
    U032 Pitch;
404
    U032 RenderBufferOffset;
405
    U032 ZBufferOffset;
406
} RivaSurface3D;
407
    
408
/***************************************************************************\
409
*                                                                           *
410
*                        Virtualized RIVA H/W interface.                    *
411
*                                                                           *
412
\***************************************************************************/
413
414
#define FP_ENABLE  1
415
#define FP_DITHER  2
416
417
struct _riva_hw_inst;
418
struct _riva_hw_state;
419
/*
420
 * Virtialized chip interface. Makes RIVA 128 and TNT look alike.
421
 */
422
typedef struct _riva_hw_inst
423
{
424
    /*
425
     * Chip specific settings.
426
     */
427
    U032 Architecture;
428
    U032 Version;
429
    U032 Chipset;
430
    U032 CrystalFreqKHz;
431
    U032 RamAmountKBytes;
432
    U032 MaxVClockFreqKHz;
433
    U032 RamBandwidthKBytesPerSec;
434
    U032 EnableIRQ;
435
    U032 IO;
436
    U032 VBlankBit;
437
    U032 FifoFreeCount;
438
    U032 FifoEmptyCount;
439
    U032 CursorStart;
440
    U032 flatPanel;
441
    Bool twoHeads;
442
    /*
443
     * Non-FIFO registers.
444
     */
445
    volatile U032 *PCRTC0;
446
    volatile U032 *PCRTC;
447
    volatile U032 *PRAMDAC0;
448
    volatile U032 *PFB;
449
    volatile U032 *PFIFO;
450
    volatile U032 *PGRAPH;
451
    volatile U032 *PEXTDEV;
452
    volatile U032 *PTIMER;
453
    volatile U032 *PMC;
454
    volatile U032 *PRAMIN;
455
    volatile U032 *FIFO;
456
    volatile U032 *CURSOR;
457
    volatile U008 *PCIO0;
458
    volatile U008 *PCIO;
459
    volatile U008 *PVIO;
460
    volatile U008 *PDIO0;
461
    volatile U008 *PDIO;
462
    volatile U032 *PRAMDAC;
463
    /*
464
     * Common chip functions.
465
     */
466
    int  (*Busy)(struct _riva_hw_inst *);
467
    void (*CalcStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *,int,int,int,int,int);
468
    void (*LoadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
469
    void (*UnloadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
470
    void (*SetStartAddress)(struct _riva_hw_inst *,U032);
471
    void (*SetSurfaces2D)(struct _riva_hw_inst *,U032,U032);
472
    void (*SetSurfaces3D)(struct _riva_hw_inst *,U032,U032);
473
    int  (*ShowHideCursor)(struct _riva_hw_inst *,int);
474
    void (*LockUnlock)(struct _riva_hw_inst *, int);
475
    /*
476
     * Current extended mode settings.
477
     */
478
    struct _riva_hw_state *CurrentState;
479
    /*
480
     * FIFO registers.
481
     */
482
    RivaRop                 *Rop;
483
    RivaPattern             *Patt;
484
    RivaClip                *Clip;
485
    RivaPixmap              *Pixmap;
486
    RivaScreenBlt           *Blt;
487
    RivaBitmap              *Bitmap;
488
    RivaLine                *Line;
489
    RivaTexturedTriangle03  *Tri03;
490
    RivaTexturedTriangle05  *Tri05;
491
} RIVA_HW_INST;
492
/*
493
 * Extended mode state information.
494
 */
495
typedef struct _riva_hw_state
496
{
497
    U032 bpp;
498
    U032 width;
499
    U032 height;
500
    U032 interlace;
501
    U032 repaint0;
502
    U032 repaint1;
503
    U032 screen;
504
    U032 scale;
505
    U032 dither;
506
    U032 extra;
507
    U032 pixel;
508
    U032 horiz;
509
    U032 arbitration0;
510
    U032 arbitration1;
511
    U032 vpll;
512
    U032 vpll2;
513
    U032 pllsel;
514
    U032 general;
515
    U032 crtcOwner;
516
    U032 head; 
517
    U032 head2; 
518
    U032 config;
519
    U032 cursorConfig;	
520
    U032 cursor0;
521
    U032 cursor1;
522
    U032 cursor2;
523
    U032 offset0;
524
    U032 offset1;
525
    U032 offset2;
526
    U032 offset3;
527
    U032 pitch0;
528
    U032 pitch1;
529
    U032 pitch2;
530
    U032 pitch3;
531
    U032 fb_start;
532
    U032 vend;
533
    U032 vtotal;
534
    U032 vcrtc;
535
    U032 vsyncstart;
536
    U032 vsyncend;
537
    U032 vvalidstart;
538
    U032 vvalidend;
539
    U032 hend;
540
    U032 htotal;
541
    U032 hcrtc;
542
    U032 hsyncstart;
543
    U032 hsyncend;
544
    U032 hvalidstart;
545
    U032 hvalidend;
546
    U032 crtchdispend;
547
    U032 crtcvstart;
548
    U032 crtcvtotal;
549
    U032 checksum;   
550
} RIVA_HW_STATE;
551
/*
552
 * External routines.
553
 */
554
int RivaGetConfig(RIVA_HW_INST *, unsigned int);
555
/*
556
 * FIFO Free Count. Should attempt to yield processor if RIVA is busy.
557
 */
558
559
#define RIVA_FIFO_FREE(hwinst,hwptr,cnt)                            \
560
{                                                                   \
561
    while ((hwinst).FifoFreeCount < (cnt))                          \
562
        (hwinst).FifoFreeCount = (hwinst).hwptr->FifoFree >> 2;     \
563
    (hwinst).FifoFreeCount -= (cnt);                                \
564
}
565
#endif /* __RIVA_HW_H__ */
566
(-)linux-2.6.5.orig/drivers/video/xbox/riva_tbl.h (+1008 lines)
Line 0 Link Here
1
 /***************************************************************************\
2
|*                                                                           *|
3
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
4
|*                                                                           *|
5
|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
6
|*     international laws.  Users and possessors of this source code are     *|
7
|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
8
|*     use this code in individual and commercial software.                  *|
9
|*                                                                           *|
10
|*     Any use of this source code must include,  in the user documenta-     *|
11
|*     tion and  internal comments to the code,  notices to the end user     *|
12
|*     as follows:                                                           *|
13
|*                                                                           *|
14
|*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
15
|*                                                                           *|
16
|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
17
|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
18
|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
19
|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
20
|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
21
|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
22
|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
23
|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
24
|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
25
|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
26
|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
27
|*                                                                           *|
28
|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
29
|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
30
|*     consisting  of "commercial  computer  software"  and  "commercial     *|
31
|*     computer  software  documentation,"  as such  terms  are  used in     *|
32
|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
33
|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
34
|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
35
|*     all U.S. Government End Users  acquire the source code  with only     *|
36
|*     those rights set forth herein.                                        *|
37
|*                                                                           *|
38
 \***************************************************************************/
39
40
/*
41
 * GPL licensing note -- nVidia is allowing a liberal interpretation of
42
 * the documentation restriction above, to merely say that this nVidia's
43
 * copyright and disclaimer should be included with all code derived
44
 * from this source.  -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99 
45
 */
46
47
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_tbl.h,v 1.9 2002/01/30 01:35:03 mvojkovi Exp $ */
48
49
50
/*
51
 * RIVA Fixed Functionality Init Tables.
52
 */
53
static unsigned RivaTablePMC[][2] =
54
{
55
    {0x00000050, 0x00000000},
56
    {0x00000080, 0xFFFF00FF},
57
    {0x00000080, 0xFFFFFFFF}
58
};
59
static unsigned RivaTablePTIMER[][2] =
60
{
61
    {0x00000080, 0x00000008},
62
    {0x00000084, 0x00000003},
63
    {0x00000050, 0x00000000},
64
    {0x00000040, 0xFFFFFFFF}
65
};
66
static unsigned RivaTableFIFO[][2] =
67
{
68
    {0x00000000, 0x80000000},
69
    {0x00000800, 0x80000001},
70
    {0x00001000, 0x80000002},
71
    {0x00001800, 0x80000010},
72
    {0x00002000, 0x80000011},
73
    {0x00002800, 0x80000012},
74
    {0x00003000, 0x80000016},
75
    {0x00003800, 0x80000013}
76
};
77
static unsigned nv3TablePFIFO[][2] =
78
{
79
    {0x00000140, 0x00000000},
80
    {0x00000480, 0x00000000},
81
    {0x00000490, 0x00000000},
82
    {0x00000494, 0x00000000},
83
    {0x00000481, 0x00000000},
84
    {0x00000084, 0x00000000},
85
    {0x00000086, 0x00002000},
86
    {0x00000085, 0x00002200},
87
    {0x00000484, 0x00000000},
88
    {0x0000049C, 0x00000000},
89
    {0x00000104, 0x00000000},
90
    {0x00000108, 0x00000000},
91
    {0x00000100, 0x00000000},
92
    {0x000004A0, 0x00000000},
93
    {0x000004A4, 0x00000000},
94
    {0x000004A8, 0x00000000},
95
    {0x000004AC, 0x00000000},
96
    {0x000004B0, 0x00000000},
97
    {0x000004B4, 0x00000000},
98
    {0x000004B8, 0x00000000},
99
    {0x000004BC, 0x00000000},
100
    {0x00000050, 0x00000000},
101
    {0x00000040, 0xFFFFFFFF},
102
    {0x00000480, 0x00000001},
103
    {0x00000490, 0x00000001},
104
    {0x00000140, 0x00000001}
105
};
106
static unsigned nv3TablePGRAPH[][2] =
107
{
108
    {0x00000020, 0x1230001F},
109
    {0x00000021, 0x10113000},
110
    {0x00000022, 0x1131F101},
111
    {0x00000023, 0x0100F531},
112
    {0x00000060, 0x00000000},
113
    {0x00000065, 0x00000000},
114
    {0x00000068, 0x00000000},
115
    {0x00000069, 0x00000000},
116
    {0x0000006A, 0x00000000},
117
    {0x0000006B, 0x00000000},
118
    {0x0000006C, 0x00000000},
119
    {0x0000006D, 0x00000000},
120
    {0x0000006E, 0x00000000},
121
    {0x0000006F, 0x00000000},
122
    {0x000001A8, 0x00000000},
123
    {0x00000440, 0xFFFFFFFF},
124
    {0x00000480, 0x00000001},
125
    {0x000001A0, 0x00000000},
126
    {0x000001A2, 0x00000000},
127
    {0x0000018A, 0xFFFFFFFF},
128
    {0x00000190, 0x00000000},
129
    {0x00000142, 0x00000000},
130
    {0x00000154, 0x00000000},
131
    {0x00000155, 0xFFFFFFFF},
132
    {0x00000156, 0x00000000},
133
    {0x00000157, 0xFFFFFFFF},
134
    {0x00000064, 0x10010002},
135
    {0x00000050, 0x00000000},
136
    {0x00000051, 0x00000000},
137
    {0x00000040, 0xFFFFFFFF},
138
    {0x00000041, 0xFFFFFFFF},
139
    {0x00000440, 0xFFFFFFFF},
140
    {0x000001A9, 0x00000001}
141
};
142
static unsigned nv3TablePGRAPH_8BPP[][2] =
143
{
144
    {0x000001AA, 0x00001111}
145
};
146
static unsigned nv3TablePGRAPH_15BPP[][2] =
147
{
148
    {0x000001AA, 0x00002222}
149
};
150
static unsigned nv3TablePGRAPH_32BPP[][2] =
151
{
152
    {0x000001AA, 0x00003333}
153
};
154
static unsigned nv3TablePRAMIN[][2] =
155
{
156
    {0x00000500, 0x00010000},
157
    {0x00000501, 0x007FFFFF},
158
    {0x00000200, 0x80000000},
159
    {0x00000201, 0x00C20341},
160
    {0x00000204, 0x80000001},
161
    {0x00000205, 0x00C50342},
162
    {0x00000208, 0x80000002},
163
    {0x00000209, 0x00C60343},
164
    {0x0000020C, 0x80000003},
165
    {0x0000020D, 0x00DC0348},
166
    {0x00000210, 0x80000004},
167
    {0x00000211, 0x00DC0349},
168
    {0x00000214, 0x80000005},
169
    {0x00000215, 0x00DC034A},
170
    {0x00000218, 0x80000006},
171
    {0x00000219, 0x00DC034B},
172
    {0x00000240, 0x80000010},
173
    {0x00000241, 0x00D10344},
174
    {0x00000244, 0x80000011},
175
    {0x00000245, 0x00D00345},
176
    {0x00000248, 0x80000012},
177
    {0x00000249, 0x00CC0346},
178
    {0x0000024C, 0x80000013},
179
    {0x0000024D, 0x00D70347},
180
    {0x00000258, 0x80000016},
181
    {0x00000259, 0x00CA034C},
182
    {0x00000D05, 0x00000000},
183
    {0x00000D06, 0x00000000},
184
    {0x00000D07, 0x00000000},
185
    {0x00000D09, 0x00000000},
186
    {0x00000D0A, 0x00000000},
187
    {0x00000D0B, 0x00000000},
188
    {0x00000D0D, 0x00000000},
189
    {0x00000D0E, 0x00000000},
190
    {0x00000D0F, 0x00000000},
191
    {0x00000D11, 0x00000000},
192
    {0x00000D12, 0x00000000},
193
    {0x00000D13, 0x00000000},
194
    {0x00000D15, 0x00000000},
195
    {0x00000D16, 0x00000000},
196
    {0x00000D17, 0x00000000},
197
    {0x00000D19, 0x00000000},
198
    {0x00000D1A, 0x00000000},
199
    {0x00000D1B, 0x00000000},
200
    {0x00000D1D, 0x00000140},
201
    {0x00000D1E, 0x00000000},
202
    {0x00000D1F, 0x00000000},
203
    {0x00000D20, 0x10100200},
204
    {0x00000D21, 0x00000000},
205
    {0x00000D22, 0x00000000},
206
    {0x00000D23, 0x00000000},
207
    {0x00000D24, 0x10210200},
208
    {0x00000D25, 0x00000000},
209
    {0x00000D26, 0x00000000},
210
    {0x00000D27, 0x00000000},
211
    {0x00000D28, 0x10420200},
212
    {0x00000D29, 0x00000000},
213
    {0x00000D2A, 0x00000000},
214
    {0x00000D2B, 0x00000000},
215
    {0x00000D2C, 0x10830200},
216
    {0x00000D2D, 0x00000000},
217
    {0x00000D2E, 0x00000000},
218
    {0x00000D2F, 0x00000000},
219
    {0x00000D31, 0x00000000},
220
    {0x00000D32, 0x00000000},
221
    {0x00000D33, 0x00000000}
222
};
223
static unsigned nv3TablePRAMIN_8BPP[][2] =
224
{
225
    /*           0xXXXXX3XX For  MSB mono format */
226
    /*           0xXXXXX2XX For  LSB mono format */
227
    {0x00000D04, 0x10110203},
228
    {0x00000D08, 0x10110203},
229
    {0x00000D0C, 0x1011020B},
230
    {0x00000D10, 0x10118203},
231
    {0x00000D14, 0x10110203},
232
    {0x00000D18, 0x10110203},
233
    {0x00000D1C, 0x10419208},
234
    {0x00000D30, 0x10118203}
235
};
236
static unsigned nv3TablePRAMIN_15BPP[][2] =
237
{
238
    /*           0xXXXXX2XX For  MSB mono format */
239
    /*           0xXXXXX3XX For  LSB mono format */
240
    {0x00000D04, 0x10110200},
241
    {0x00000D08, 0x10110200},
242
    {0x00000D0C, 0x10110208},
243
    {0x00000D10, 0x10118200},
244
    {0x00000D14, 0x10110200},
245
    {0x00000D18, 0x10110200},
246
    {0x00000D1C, 0x10419208},
247
    {0x00000D30, 0x10118200}
248
};
249
static unsigned nv3TablePRAMIN_32BPP[][2] =
250
{
251
    /*           0xXXXXX3XX For  MSB mono format */
252
    /*           0xXXXXX2XX For  LSB mono format */
253
    {0x00000D04, 0x10110201},
254
    {0x00000D08, 0x10110201},
255
    {0x00000D0C, 0x10110209},
256
    {0x00000D10, 0x10118201},
257
    {0x00000D14, 0x10110201},
258
    {0x00000D18, 0x10110201},
259
    {0x00000D1C, 0x10419208},
260
    {0x00000D30, 0x10118201}
261
};
262
static unsigned nv4TableFIFO[][2] =
263
{
264
    {0x00003800, 0x80000014}
265
};
266
static unsigned nv4TablePFIFO[][2] =
267
{
268
    {0x00000140, 0x00000000},
269
    {0x00000480, 0x00000000},
270
    {0x00000494, 0x00000000},
271
    {0x00000481, 0x00000000},
272
    {0x0000048B, 0x00000000},
273
    {0x00000400, 0x00000000},
274
    {0x00000414, 0x00000000},
275
    {0x00000084, 0x03000100},  
276
    {0x00000085, 0x00000110},
277
    {0x00000086, 0x00000112},  
278
    {0x00000143, 0x0000FFFF},
279
    {0x00000496, 0x0000FFFF},
280
    {0x00000050, 0x00000000},
281
    {0x00000040, 0xFFFFFFFF},
282
    {0x00000415, 0x00000001},
283
    {0x00000480, 0x00000001},
284
    {0x00000494, 0x00000001},
285
    {0x00000495, 0x00000001},
286
    {0x00000140, 0x00000001}
287
};
288
static unsigned nv4TablePGRAPH[][2] =
289
{
290
    {0x00000020, 0x1231C001},
291
    {0x00000021, 0x72111101},
292
    {0x00000022, 0x11D5F071},
293
    {0x00000023, 0x10D4FF31},
294
    {0x00000060, 0x00000000},
295
    {0x00000068, 0x00000000},
296
    {0x00000070, 0x00000000},
297
    {0x00000078, 0x00000000},
298
    {0x00000061, 0x00000000},
299
    {0x00000069, 0x00000000},
300
    {0x00000071, 0x00000000},
301
    {0x00000079, 0x00000000},
302
    {0x00000062, 0x00000000},
303
    {0x0000006A, 0x00000000},
304
    {0x00000072, 0x00000000},
305
    {0x0000007A, 0x00000000},
306
    {0x00000063, 0x00000000},
307
    {0x0000006B, 0x00000000},
308
    {0x00000073, 0x00000000},
309
    {0x0000007B, 0x00000000},
310
    {0x00000064, 0x00000000},
311
    {0x0000006C, 0x00000000},
312
    {0x00000074, 0x00000000},
313
    {0x0000007C, 0x00000000},
314
    {0x00000065, 0x00000000},
315
    {0x0000006D, 0x00000000},
316
    {0x00000075, 0x00000000},
317
    {0x0000007D, 0x00000000},
318
    {0x00000066, 0x00000000},
319
    {0x0000006E, 0x00000000},
320
    {0x00000076, 0x00000000},
321
    {0x0000007E, 0x00000000},
322
    {0x00000067, 0x00000000},
323
    {0x0000006F, 0x00000000},
324
    {0x00000077, 0x00000000},
325
    {0x0000007F, 0x00000000},
326
    {0x00000058, 0x00000000},
327
    {0x00000059, 0x00000000},
328
    {0x0000005A, 0x00000000},
329
    {0x0000005B, 0x00000000},
330
    {0x00000196, 0x00000000},
331
    {0x000001A1, 0x01FFFFFF},
332
    {0x00000197, 0x00000000},
333
    {0x000001A2, 0x01FFFFFF},
334
    {0x00000198, 0x00000000},
335
    {0x000001A3, 0x01FFFFFF},
336
    {0x00000199, 0x00000000},
337
    {0x000001A4, 0x01FFFFFF},
338
    {0x00000050, 0x00000000},
339
    {0x00000040, 0xFFFFFFFF},
340
    {0x0000005C, 0x10010100},
341
    {0x000001C4, 0xFFFFFFFF},
342
    {0x000001C8, 0x00000001},
343
    {0x00000204, 0x00000000},
344
    {0x000001C3, 0x00000001}
345
};
346
static unsigned nv4TablePGRAPH_8BPP[][2] =
347
{
348
    {0x000001C9, 0x00111111},
349
    {0x00000186, 0x00001010},
350
    {0x0000020C, 0x03020202}
351
};
352
static unsigned nv4TablePGRAPH_15BPP[][2] =
353
{
354
    {0x000001C9, 0x00226222},
355
    {0x00000186, 0x00002071},
356
    {0x0000020C, 0x09080808}
357
};
358
static unsigned nv4TablePGRAPH_16BPP[][2] =
359
{
360
    {0x000001C9, 0x00556555},
361
    {0x00000186, 0x000050C2},
362
    {0x0000020C, 0x0C0B0B0B}
363
};
364
static unsigned nv4TablePGRAPH_32BPP[][2] =
365
{
366
    {0x000001C9, 0x0077D777},
367
    {0x00000186, 0x000070E5},
368
    {0x0000020C, 0x0E0D0D0D}
369
};
370
static unsigned nv4TablePRAMIN[][2] =
371
{
372
    {0x00000000, 0x80000010},
373
    {0x00000001, 0x80011145},
374
    {0x00000002, 0x80000011},
375
    {0x00000003, 0x80011146},
376
    {0x00000004, 0x80000012},
377
    {0x00000005, 0x80011147},
378
    {0x00000006, 0x80000013},
379
    {0x00000007, 0x80011148},
380
    {0x00000008, 0x80000014},
381
    {0x00000009, 0x80011149},
382
    {0x0000000A, 0x80000015},
383
    {0x0000000B, 0x8001114A},
384
    {0x0000000C, 0x80000016},
385
    {0x0000000D, 0x8001114F},
386
    {0x00000020, 0x80000000},
387
    {0x00000021, 0x80011142},
388
    {0x00000022, 0x80000001},
389
    {0x00000023, 0x80011143},
390
    {0x00000024, 0x80000002},
391
    {0x00000025, 0x80011144}, 
392
    {0x00000026, 0x80000003},
393
    {0x00000027, 0x8001114B},
394
    {0x00000028, 0x80000004},
395
    {0x00000029, 0x8001114C},
396
    {0x0000002A, 0x80000005},
397
    {0x0000002B, 0x8001114D},
398
    {0x0000002C, 0x80000006},
399
    {0x0000002D, 0x8001114E},
400
    {0x00000500, 0x00003000},
401
    {0x00000501, 0x01FFFFFF},
402
    {0x00000502, 0x00000002},
403
    {0x00000503, 0x00000002},
404
    {0x00000508, 0x01008043},
405
    {0x0000050A, 0x00000000},
406
    {0x0000050B, 0x00000000},
407
    {0x0000050C, 0x01008019},
408
    {0x0000050E, 0x00000000},
409
    {0x0000050F, 0x00000000},
410
#if 1
411
    {0x00000510, 0x01008018},
412
#else
413
    {0x00000510, 0x01008044},
414
#endif
415
    {0x00000512, 0x00000000},
416
    {0x00000513, 0x00000000},
417
    {0x00000514, 0x01008021},
418
    {0x00000516, 0x00000000},
419
    {0x00000517, 0x00000000},
420
    {0x00000518, 0x0100805F},
421
    {0x0000051A, 0x00000000},
422
    {0x0000051B, 0x00000000},
423
#if 1
424
    {0x0000051C, 0x0100804B},
425
#else
426
    {0x0000051C, 0x0100804A},
427
#endif
428
    {0x0000051E, 0x00000000},
429
    {0x0000051F, 0x00000000},
430
    {0x00000520, 0x0100A048},
431
    {0x00000521, 0x00000D01},
432
    {0x00000522, 0x11401140},
433
    {0x00000523, 0x00000000},
434
    {0x00000524, 0x0300A054},
435
    {0x00000525, 0x00000D01},
436
    {0x00000526, 0x11401140},
437
    {0x00000527, 0x00000000},
438
    {0x00000528, 0x0300A055},
439
    {0x00000529, 0x00000D01},
440
    {0x0000052A, 0x11401140},
441
    {0x0000052B, 0x00000000},
442
    {0x0000052C, 0x00000058},
443
    {0x0000052E, 0x11401140},
444
    {0x0000052F, 0x00000000},
445
    {0x00000530, 0x00000059},
446
    {0x00000532, 0x11401140},
447
    {0x00000533, 0x00000000},
448
    {0x00000534, 0x0000005A},
449
    {0x00000536, 0x11401140},
450
    {0x00000537, 0x00000000},
451
    {0x00000538, 0x0000005B},
452
    {0x0000053A, 0x11401140},
453
    {0x0000053B, 0x00000000},
454
    {0x0000053C, 0x0300A01C},
455
    {0x0000053E, 0x11401140},
456
    {0x0000053F, 0x00000000}
457
};
458
static unsigned nv4TablePRAMIN_8BPP[][2] =
459
{
460
    /*           0xXXXXXX01 For  MSB mono format */
461
    /*           0xXXXXXX02 For  LSB mono format */
462
    {0x00000509, 0x00000302},
463
    {0x0000050D, 0x00000302},
464
    {0x00000511, 0x00000202},
465
    {0x00000515, 0x00000302},
466
    {0x00000519, 0x00000302},
467
    {0x0000051D, 0x00000302},
468
    {0x0000052D, 0x00000302},
469
    {0x0000052E, 0x00000302},
470
    {0x00000535, 0x00000000},
471
    {0x00000539, 0x00000000},
472
    {0x0000053D, 0x00000302}
473
};
474
static unsigned nv4TablePRAMIN_15BPP[][2] =
475
{
476
    /*           0xXXXXXX01 For  MSB mono format */
477
    /*           0xXXXXXX02 For  LSB mono format */
478
    {0x00000509, 0x00000902},
479
    {0x0000050D, 0x00000902},
480
    {0x00000511, 0x00000802},
481
    {0x00000515, 0x00000902},
482
    {0x00000519, 0x00000902},
483
    {0x0000051D, 0x00000902},
484
    {0x0000052D, 0x00000902},
485
    {0x0000052E, 0x00000902},
486
    {0x00000535, 0x00000702},
487
    {0x00000539, 0x00000702},
488
    {0x0000053D, 0x00000902}
489
};
490
static unsigned nv4TablePRAMIN_16BPP[][2] =
491
{
492
    /*           0xXXXXXX01 For  MSB mono format */
493
    /*           0xXXXXXX02 For  LSB mono format */
494
    {0x00000509, 0x00000C02},
495
    {0x0000050D, 0x00000C02},
496
    {0x00000511, 0x00000B02},
497
    {0x00000515, 0x00000C02},
498
    {0x00000519, 0x00000C02},
499
    {0x0000051D, 0x00000C02},
500
    {0x0000052D, 0x00000C02},
501
    {0x0000052E, 0x00000C02},
502
    {0x00000535, 0x00000702},
503
    {0x00000539, 0x00000702},
504
    {0x0000053D, 0x00000C02}
505
};
506
static unsigned nv4TablePRAMIN_32BPP[][2] =
507
{
508
    /*           0xXXXXXX01 For  MSB mono format */
509
    /*           0xXXXXXX02 For  LSB mono format */
510
    {0x00000509, 0x00000E02},
511
    {0x0000050D, 0x00000E02},
512
    {0x00000511, 0x00000D02},
513
    {0x00000515, 0x00000E02},
514
    {0x00000519, 0x00000E02},
515
    {0x0000051D, 0x00000E02},
516
    {0x0000052D, 0x00000E02},
517
    {0x0000052E, 0x00000E02},
518
    {0x00000535, 0x00000E02},
519
    {0x00000539, 0x00000E02},
520
    {0x0000053D, 0x00000E02}
521
};
522
static unsigned nv10TableFIFO[][2] =
523
{
524
    {0x00003800, 0x80000014}
525
};
526
static unsigned nv10TablePFIFO[][2] =
527
{
528
    {0x00000140, 0x00000000},
529
    {0x00000480, 0x00000000},
530
    {0x00000494, 0x00000000},
531
    {0x00000481, 0x00000000},
532
    {0x0000048B, 0x00000000},
533
    {0x00000400, 0x00000000},
534
    {0x00000414, 0x00000000},
535
    {0x00000084, 0x03000100},
536
    {0x00000085, 0x00000110},
537
    {0x00000086, 0x00000112},
538
    {0x00000143, 0x0000FFFF},
539
    {0x00000496, 0x0000FFFF},
540
    {0x00000050, 0x00000000},
541
    {0x00000040, 0xFFFFFFFF},
542
    {0x00000415, 0x00000001},
543
    {0x00000480, 0x00000001},
544
    {0x00000494, 0x00000001},
545
    {0x00000495, 0x00000001},
546
    {0x00000140, 0x00000001}
547
};
548
static unsigned nv10TablePGRAPH[][2] =
549
{
550
    {0x00000020, 0x0003FFFF},
551
    {0x00000021, 0x00118701},
552
    {0x00000022, 0x24F82AD9},
553
    {0x00000023, 0x55DE0030},
554
    {0x00000020, 0x00000000},
555
    {0x00000024, 0x00000000},
556
    {0x00000058, 0x00000000},
557
    {0x00000060, 0x00000000},
558
    {0x00000068, 0x00000000},
559
    {0x00000070, 0x00000000},
560
    {0x00000078, 0x00000000},
561
    {0x00000059, 0x00000000},
562
    {0x00000061, 0x00000000},
563
    {0x00000069, 0x00000000},
564
    {0x00000071, 0x00000000},
565
    {0x00000079, 0x00000000},
566
    {0x0000005A, 0x00000000},
567
    {0x00000062, 0x00000000},
568
    {0x0000006A, 0x00000000},
569
    {0x00000072, 0x00000000},
570
    {0x0000007A, 0x00000000},
571
    {0x0000005B, 0x00000000},
572
    {0x00000063, 0x00000000},
573
    {0x0000006B, 0x00000000},
574
    {0x00000073, 0x00000000},
575
    {0x0000007B, 0x00000000},
576
    {0x0000005C, 0x00000000},
577
    {0x00000064, 0x00000000},
578
    {0x0000006C, 0x00000000},
579
    {0x00000074, 0x00000000},
580
    {0x0000007C, 0x00000000},
581
    {0x0000005D, 0x00000000},
582
    {0x00000065, 0x00000000},
583
    {0x0000006D, 0x00000000},
584
    {0x00000075, 0x00000000},
585
    {0x0000007D, 0x00000000},
586
    {0x0000005E, 0x00000000},
587
    {0x00000066, 0x00000000},
588
    {0x0000006E, 0x00000000},
589
    {0x00000076, 0x00000000},
590
    {0x0000007E, 0x00000000},
591
    {0x0000005F, 0x00000000},
592
    {0x00000067, 0x00000000},
593
    {0x0000006F, 0x00000000},
594
    {0x00000077, 0x00000000},
595
    {0x0000007F, 0x00000000},
596
    {0x00000053, 0x00000000},
597
    {0x00000054, 0x00000000},
598
    {0x00000055, 0x00000000},
599
    {0x00000056, 0x00000000},
600
    {0x00000057, 0x00000000},
601
    {0x00000196, 0x00000000},
602
    {0x000001A1, 0x01FFFFFF},
603
    {0x00000197, 0x00000000},
604
    {0x000001A2, 0x01FFFFFF},
605
    {0x00000198, 0x00000000},
606
    {0x000001A3, 0x01FFFFFF},
607
    {0x00000199, 0x00000000},
608
    {0x000001A4, 0x01FFFFFF},
609
    {0x0000019A, 0x00000000},
610
    {0x000001A5, 0x01FFFFFF},
611
    {0x0000019B, 0x00000000},
612
    {0x000001A6, 0x01FFFFFF},
613
    {0x00000050, 0x01111111},
614
    {0x00000040, 0xFFFFFFFF},
615
    {0x00000051, 0x10010100},
616
    {0x000001C5, 0xFFFFFFFF},
617
    {0x000001C8, 0x00000001},
618
    {0x00000204, 0x00000000},
619
    {0x000001C4, 0x00000001}
620
};
621
static unsigned nv10TablePGRAPH_8BPP[][2] =
622
{
623
    {0x000001C9, 0x00111111},
624
    {0x00000186, 0x00001010},
625
    {0x0000020C, 0x03020202}
626
};
627
static unsigned nv10TablePGRAPH_15BPP[][2] =
628
{
629
    {0x000001C9, 0x00226222},
630
    {0x00000186, 0x00002071},
631
    {0x0000020C, 0x09080808}
632
};
633
static unsigned nv10TablePGRAPH_16BPP[][2] =
634
{
635
    {0x000001C9, 0x00556555},
636
    {0x00000186, 0x000050C2},
637
    {0x0000020C, 0x000B0B0C}
638
};
639
static unsigned nv10TablePGRAPH_32BPP[][2] =
640
{
641
    {0x000001C9, 0x0077D777},
642
    {0x00000186, 0x000070E5},
643
    {0x0000020C, 0x0E0D0D0D}
644
};
645
static unsigned nv10tri05TablePGRAPH[][2] =
646
{
647
    {(0x00000E00/4), 0x00000000},
648
    {(0x00000E04/4), 0x00000000},
649
    {(0x00000E08/4), 0x00000000},
650
    {(0x00000E0C/4), 0x00000000},
651
    {(0x00000E10/4), 0x00001000},
652
    {(0x00000E14/4), 0x00001000},
653
    {(0x00000E18/4), 0x4003ff80},
654
    {(0x00000E1C/4), 0x00000000},
655
    {(0x00000E20/4), 0x00000000},
656
    {(0x00000E24/4), 0x00000000},
657
    {(0x00000E28/4), 0x00000000},
658
    {(0x00000E2C/4), 0x00000000},
659
    {(0x00000E30/4), 0x00080008},
660
    {(0x00000E34/4), 0x00080008},
661
    {(0x00000E38/4), 0x00000000},
662
    {(0x00000E3C/4), 0x00000000},
663
    {(0x00000E40/4), 0x00000000},
664
    {(0x00000E44/4), 0x00000000},
665
    {(0x00000E48/4), 0x00000000},
666
    {(0x00000E4C/4), 0x00000000},
667
    {(0x00000E50/4), 0x00000000},
668
    {(0x00000E54/4), 0x00000000},
669
    {(0x00000E58/4), 0x00000000},
670
    {(0x00000E5C/4), 0x00000000},
671
    {(0x00000E60/4), 0x00000000},
672
    {(0x00000E64/4), 0x10000000},
673
    {(0x00000E68/4), 0x00000000},
674
    {(0x00000E6C/4), 0x00000000},
675
    {(0x00000E70/4), 0x00000000},
676
    {(0x00000E74/4), 0x00000000},
677
    {(0x00000E78/4), 0x00000000},
678
    {(0x00000E7C/4), 0x00000000},
679
    {(0x00000E80/4), 0x00000000},
680
    {(0x00000E84/4), 0x00000000},
681
    {(0x00000E88/4), 0x08000000},
682
    {(0x00000E8C/4), 0x00000000},
683
    {(0x00000E90/4), 0x00000000},
684
    {(0x00000E94/4), 0x00000000},
685
    {(0x00000E98/4), 0x00000000},
686
    {(0x00000E9C/4), 0x4B7FFFFF},
687
    {(0x00000EA0/4), 0x00000000},
688
    {(0x00000EA4/4), 0x00000000},
689
    {(0x00000EA8/4), 0x00000000},
690
    {(0x00000F00/4), 0x07FF0800},
691
    {(0x00000F04/4), 0x07FF0800},
692
    {(0x00000F08/4), 0x07FF0800},
693
    {(0x00000F0C/4), 0x07FF0800},
694
    {(0x00000F10/4), 0x07FF0800},
695
    {(0x00000F14/4), 0x07FF0800},
696
    {(0x00000F18/4), 0x07FF0800},
697
    {(0x00000F1C/4), 0x07FF0800},
698
    {(0x00000F20/4), 0x07FF0800},
699
    {(0x00000F24/4), 0x07FF0800},
700
    {(0x00000F28/4), 0x07FF0800},
701
    {(0x00000F2C/4), 0x07FF0800},
702
    {(0x00000F30/4), 0x07FF0800},
703
    {(0x00000F34/4), 0x07FF0800},
704
    {(0x00000F38/4), 0x07FF0800},
705
    {(0x00000F3C/4), 0x07FF0800},
706
    {(0x00000F40/4), 0x10000000},
707
    {(0x00000F44/4), 0x00000000},
708
    {(0x00000F50/4), 0x00006740},
709
    {(0x00000F54/4), 0x00000000},
710
    {(0x00000F54/4), 0x00000000},
711
    {(0x00000F54/4), 0x00000000},
712
    {(0x00000F54/4), 0x3F800000},
713
    {(0x00000F50/4), 0x00006750},
714
    {(0x00000F54/4), 0x40000000},
715
    {(0x00000F54/4), 0x40000000},
716
    {(0x00000F54/4), 0x40000000},
717
    {(0x00000F54/4), 0x40000000},
718
    {(0x00000F50/4), 0x00006760},
719
    {(0x00000F54/4), 0x00000000},
720
    {(0x00000F54/4), 0x00000000},
721
    {(0x00000F54/4), 0x3F800000},
722
    {(0x00000F54/4), 0x00000000},
723
    {(0x00000F50/4), 0x00006770},
724
    {(0x00000F54/4), 0xC5000000},
725
    {(0x00000F54/4), 0xC5000000},
726
    {(0x00000F54/4), 0x00000000},
727
    {(0x00000F54/4), 0x00000000},
728
    {(0x00000F50/4), 0x00006780},
729
    {(0x00000F54/4), 0x00000000},
730
    {(0x00000F54/4), 0x00000000},
731
    {(0x00000F54/4), 0x3F800000},
732
    {(0x00000F54/4), 0x00000000},
733
    {(0x00000F50/4), 0x000067A0},
734
    {(0x00000F54/4), 0x3F800000},
735
    {(0x00000F54/4), 0x3F800000},
736
    {(0x00000F54/4), 0x3F800000},
737
    {(0x00000F54/4), 0x3F800000},
738
    {(0x00000F50/4), 0x00006AB0},
739
    {(0x00000F54/4), 0x3F800000},
740
    {(0x00000F54/4), 0x3F800000},
741
    {(0x00000F54/4), 0x3F800000},
742
    {(0x00000F50/4), 0x00006AC0},
743
    {(0x00000F54/4), 0x00000000},
744
    {(0x00000F54/4), 0x00000000},
745
    {(0x00000F54/4), 0x00000000},
746
    {(0x00000F50/4), 0x00006C10},
747
    {(0x00000F54/4), 0xBF800000},
748
    {(0x00000F50/4), 0x00007030},
749
    {(0x00000F54/4), 0x7149F2CA},
750
    {(0x00000F50/4), 0x00007040},
751
    {(0x00000F54/4), 0x7149F2CA},
752
    {(0x00000F50/4), 0x00007050},
753
    {(0x00000F54/4), 0x7149F2CA},
754
    {(0x00000F50/4), 0x00007060},
755
    {(0x00000F54/4), 0x7149F2CA},
756
    {(0x00000F50/4), 0x00007070},
757
    {(0x00000F54/4), 0x7149F2CA},
758
    {(0x00000F50/4), 0x00007080},
759
    {(0x00000F54/4), 0x7149F2CA},
760
    {(0x00000F50/4), 0x00007090},
761
    {(0x00000F54/4), 0x7149F2CA},
762
    {(0x00000F50/4), 0x000070A0},
763
    {(0x00000F54/4), 0x7149F2CA},
764
    {(0x00000F50/4), 0x00006A80},
765
    {(0x00000F54/4), 0x00000000},
766
    {(0x00000F54/4), 0x00000000},
767
    {(0x00000F54/4), 0x3F800000},
768
    {(0x00000F50/4), 0x00006AA0},
769
    {(0x00000F54/4), 0x00000000},
770
    {(0x00000F54/4), 0x00000000},
771
    {(0x00000F54/4), 0x00000000},
772
    {(0x00000F50/4), 0x00000040},
773
    {(0x00000F54/4), 0x00000005},
774
    {(0x00000F50/4), 0x00006400},
775
    {(0x00000F54/4), 0x3F800000},
776
    {(0x00000F54/4), 0x3F800000},
777
    {(0x00000F54/4), 0x4B7FFFFF},
778
    {(0x00000F54/4), 0x00000000},
779
    {(0x00000F50/4), 0x00006410},
780
    {(0x00000F54/4), 0xC5000000},
781
    {(0x00000F54/4), 0xC5000000},
782
    {(0x00000F54/4), 0x00000000},
783
    {(0x00000F54/4), 0x00000000},
784
    {(0x00000F50/4), 0x00006420},
785
    {(0x00000F54/4), 0x00000000},
786
    {(0x00000F54/4), 0x00000000},
787
    {(0x00000F54/4), 0x00000000},
788
    {(0x00000F54/4), 0x00000000},
789
    {(0x00000F50/4), 0x00006430},
790
    {(0x00000F54/4), 0x00000000},
791
    {(0x00000F54/4), 0x00000000},
792
    {(0x00000F54/4), 0x00000000},
793
    {(0x00000F54/4), 0x00000000},
794
    {(0x00000F50/4), 0x000064C0},
795
    {(0x00000F54/4), 0x3F800000},
796
    {(0x00000F54/4), 0x3F800000},
797
    {(0x00000F54/4), 0x477FFFFF},
798
    {(0x00000F54/4), 0x3F800000},
799
    {(0x00000F50/4), 0x000064D0},
800
    {(0x00000F54/4), 0xC5000000},
801
    {(0x00000F54/4), 0xC5000000},
802
    {(0x00000F54/4), 0x00000000},
803
    {(0x00000F54/4), 0x00000000},
804
    {(0x00000F50/4), 0x000064E0},
805
    {(0x00000F54/4), 0xC4FFF000},
806
    {(0x00000F54/4), 0xC4FFF000},
807
    {(0x00000F54/4), 0x00000000},
808
    {(0x00000F54/4), 0x00000000},
809
    {(0x00000F50/4), 0x000064F0},
810
    {(0x00000F54/4), 0x00000000},
811
    {(0x00000F54/4), 0x00000000},
812
    {(0x00000F54/4), 0x00000000},
813
    {(0x00000F54/4), 0x00000000},
814
    {(0x00000F40/4), 0x30000000},
815
    {(0x00000F44/4), 0x00000004},
816
    {(0x00000F48/4), 0x10000000},
817
    {(0x00000F4C/4), 0x00000000}
818
};
819
static unsigned nv10TablePRAMIN[][2] =
820
{
821
    {0x00000000, 0x80000010},
822
    {0x00000001, 0x80011145},
823
    {0x00000002, 0x80000011},
824
    {0x00000003, 0x80011146},
825
    {0x00000004, 0x80000012},
826
    {0x00000005, 0x80011147},
827
    {0x00000006, 0x80000013},
828
    {0x00000007, 0x80011148},
829
    {0x00000008, 0x80000014},
830
    {0x00000009, 0x80011149},
831
    {0x0000000A, 0x80000015},
832
    {0x0000000B, 0x8001114A},
833
    {0x0000000C, 0x80000016},
834
    {0x0000000D, 0x80011150},
835
    {0x00000020, 0x80000000},
836
    {0x00000021, 0x80011142},
837
    {0x00000022, 0x80000001},
838
    {0x00000023, 0x80011143},
839
    {0x00000024, 0x80000002},
840
    {0x00000025, 0x80011144},
841
    {0x00000026, 0x80000003},
842
    {0x00000027, 0x8001114B},
843
    {0x00000028, 0x80000004},
844
    {0x00000029, 0x8001114C},
845
    {0x0000002A, 0x80000005},
846
    {0x0000002B, 0x8001114D},
847
    {0x0000002C, 0x80000006},
848
    {0x0000002D, 0x8001114E},
849
    {0x0000002E, 0x80000007},
850
    {0x0000002F, 0x8001114F},
851
    {0x00000500, 0x00003000},
852
    {0x00000501, 0x01FFFFFF},
853
    {0x00000502, 0x00000002},
854
    {0x00000503, 0x00000002},
855
#ifdef __BIG_ENDIAN
856
    {0x00000508, 0x01088043}, 
857
#else
858
    {0x00000508, 0x01008043},
859
#endif
860
    {0x0000050A, 0x00000000},
861
    {0x0000050B, 0x00000000},
862
#ifdef __BIG_ENDIAN
863
    {0x0000050C, 0x01088019},
864
#else
865
    {0x0000050C, 0x01008019},
866
#endif
867
    {0x0000050E, 0x00000000},
868
    {0x0000050F, 0x00000000},
869
#ifdef __BIG_ENDIAN
870
    {0x00000510, 0x01088018},
871
#else
872
    {0x00000510, 0x01008018},
873
#endif
874
    {0x00000512, 0x00000000},
875
    {0x00000513, 0x00000000},
876
#ifdef __BIG_ENDIAN
877
    {0x00000514, 0x01088021},
878
#else
879
    {0x00000514, 0x01008021},
880
#endif
881
    {0x00000516, 0x00000000},
882
    {0x00000517, 0x00000000},
883
#ifdef __BIG_ENDIAN
884
    {0x00000518, 0x0108805F},
885
#else
886
    {0x00000518, 0x0100805F},
887
#endif
888
    {0x0000051A, 0x00000000},
889
    {0x0000051B, 0x00000000},
890
#ifdef __BIG_ENDIAN
891
    {0x0000051C, 0x0108804B},
892
#else
893
    {0x0000051C, 0x0100804B},
894
#endif
895
    {0x0000051E, 0x00000000},
896
    {0x0000051F, 0x00000000},
897
    {0x00000520, 0x0100A048},
898
    {0x00000521, 0x00000D01},
899
    {0x00000522, 0x11401140},
900
    {0x00000523, 0x00000000},
901
    {0x00000524, 0x0300A094},
902
    {0x00000525, 0x00000D01},
903
    {0x00000526, 0x11401140},
904
    {0x00000527, 0x00000000},
905
    {0x00000528, 0x0300A095},
906
    {0x00000529, 0x00000D01},
907
    {0x0000052A, 0x11401140},
908
    {0x0000052B, 0x00000000},
909
#ifdef __BIG_ENDIAN
910
    {0x0000052C, 0x00080058},
911
#else
912
    {0x0000052C, 0x00000058},
913
#endif
914
    {0x0000052E, 0x11401140},
915
    {0x0000052F, 0x00000000},
916
#ifdef __BIG_ENDIAN
917
    {0x00000530, 0x00080059},
918
#else
919
    {0x00000530, 0x00000059},
920
#endif
921
    {0x00000532, 0x11401140},
922
    {0x00000533, 0x00000000},
923
    {0x00000534, 0x0000005A},
924
    {0x00000536, 0x11401140},
925
    {0x00000537, 0x00000000},
926
    {0x00000538, 0x0000005B},
927
    {0x0000053A, 0x11401140},
928
    {0x0000053B, 0x00000000},
929
    {0x0000053C, 0x00000093},
930
    {0x0000053E, 0x11401140},
931
    {0x0000053F, 0x00000000},
932
#ifdef __BIG_ENDIAN
933
    {0x00000540, 0x0308A01C},
934
#else
935
    {0x00000540, 0x0300A01C},
936
#endif
937
    {0x00000542, 0x11401140},
938
    {0x00000543, 0x00000000}
939
};
940
static unsigned nv10TablePRAMIN_8BPP[][2] =
941
{
942
    /*           0xXXXXXX01 For  MSB mono format */
943
    /*           0xXXXXXX02 For  LSB mono format */
944
    {0x00000509, 0x00000302},
945
    {0x0000050D, 0x00000302},
946
    {0x00000511, 0x00000202},
947
    {0x00000515, 0x00000302},
948
    {0x00000519, 0x00000302},
949
    {0x0000051D, 0x00000302},
950
    {0x0000052D, 0x00000302},
951
    {0x0000052E, 0x00000302},
952
    {0x00000535, 0x00000000},
953
    {0x00000539, 0x00000000},
954
    {0x0000053D, 0x00000000},
955
    {0x00000541, 0x00000302}
956
};
957
static unsigned nv10TablePRAMIN_15BPP[][2] =
958
{
959
    /*           0xXXXXXX01 For  MSB mono format */
960
    /*           0xXXXXXX02 For  LSB mono format */
961
    {0x00000509, 0x00000902},
962
    {0x0000050D, 0x00000902},
963
    {0x00000511, 0x00000802},
964
    {0x00000515, 0x00000902},
965
    {0x00000519, 0x00000902},
966
    {0x0000051D, 0x00000902},
967
    {0x0000052D, 0x00000902},
968
    {0x0000052E, 0x00000902},
969
    {0x00000535, 0x00000902},
970
    {0x00000539, 0x00000902}, 
971
    {0x0000053D, 0x00000902},
972
    {0x00000541, 0x00000902}
973
};
974
static unsigned nv10TablePRAMIN_16BPP[][2] =
975
{
976
    /*           0xXXXXXX01 For  MSB mono format */
977
    /*           0xXXXXXX02 For  LSB mono format */
978
    {0x00000509, 0x00000C02},
979
    {0x0000050D, 0x00000C02},
980
    {0x00000511, 0x00000B02},
981
    {0x00000515, 0x00000C02},
982
    {0x00000519, 0x00000C02},
983
    {0x0000051D, 0x00000C02},
984
    {0x0000052D, 0x00000C02},
985
    {0x0000052E, 0x00000C02},
986
    {0x00000535, 0x00000C02},
987
    {0x00000539, 0x00000C02},
988
    {0x0000053D, 0x00000C02},
989
    {0x00000541, 0x00000C02}
990
};
991
static unsigned nv10TablePRAMIN_32BPP[][2] =
992
{
993
    /*           0xXXXXXX01 For  MSB mono format */
994
    /*           0xXXXXXX02 For  LSB mono format */
995
    {0x00000509, 0x00000E02},
996
    {0x0000050D, 0x00000E02},
997
    {0x00000511, 0x00000D02},
998
    {0x00000515, 0x00000E02},
999
    {0x00000519, 0x00000E02},
1000
    {0x0000051D, 0x00000E02},
1001
    {0x0000052D, 0x00000E02},
1002
    {0x0000052E, 0x00000E02},
1003
    {0x00000535, 0x00000E02},
1004
    {0x00000539, 0x00000E02},
1005
    {0x0000053D, 0x00000E02},
1006
    {0x00000541, 0x00000E02}
1007
};
1008
(-)linux-2.6.5.orig/drivers/video/xbox/xboxfb.h (+73 lines)
Line 0 Link Here
1
#ifndef __XBOXFB_H
2
#define __XBOXFB_H
3
4
#include <linux/config.h>
5
#include <linux/fb.h>
6
#include <video/vga.h>
7
#include "riva_hw.h"
8
#include <linux/xboxfbctl.h>
9
10
/* GGI compatibility macros */
11
#define NUM_SEQ_REGS		0x05
12
#define NUM_CRT_REGS		0x41
13
#define NUM_GRC_REGS		0x09
14
#define NUM_ATC_REGS		0x15
15
16
#define NUM_CONEXANT_REGS	0x69
17
#define NUM_FOCUS_REGS 	    0xff
18
#define MAX_ENCODER_REGS    0xff
19
20
/* holds the state of the VGA core and extended Riva hw state from riva_hw.c.
21
 * From KGI originally. */
22
struct riva_regs {
23
	u8 attr[NUM_ATC_REGS];
24
	u8 crtc[NUM_CRT_REGS];
25
	u8 gra[NUM_GRC_REGS];
26
	u8 seq[NUM_SEQ_REGS];
27
	u8 misc_output;
28
	RIVA_HW_STATE ext;
29
	u8 encoder_mode[MAX_ENCODER_REGS];
30
};
31
32
struct riva_par {
33
	RIVA_HW_INST riva;	/* interface to riva_hw.c */
34
35
	caddr_t ctrl_base;	/* virtual control register base addr */
36
	unsigned dclk_max;	/* max DCLK */
37
38
	struct riva_regs initial_state;	/* initial startup video mode */
39
	struct riva_regs current_state;
40
	struct vgastate state;
41
	atomic_t ref_count;
42
	u32 cursor_data[32 * 32/4];
43
	int cursor_reset;
44
	unsigned char *EDID;
45
46
	int panel_xres, panel_yres;
47
	int hOver_plus, hSync_width, hblank;
48
	int vOver_plus, vSync_width, vblank;
49
	int hAct_high, vAct_high, interlaced;
50
	int synct, misc, clock;
51
52
	int use_default_var;
53
	int got_dfpinfo;
54
	unsigned int Chipset;
55
	int forceCRTC;
56
	Bool SecondCRTC;
57
	int FlatPanel;
58
#ifdef CONFIG_MTRR
59
	struct { int vram; int vram_valid; } mtrr;
60
#endif
61
	unsigned riva_fb_start; /* start address of fb in riva address space */
62
	xbox_tv_encoding tv_encoding;
63
	xbox_av_type av_type;
64
	xbox_encoder_type video_encoder;
65
	double hoc;
66
	double voc;
67
};
68
69
void riva_common_setup(struct riva_par *);
70
unsigned long riva_get_memlen(struct riva_par *);
71
unsigned long riva_get_maxdclk(struct riva_par *);
72
73
#endif /* __XBOXFB_H */
(-)linux-2.6.5.orig/fs/Kconfig (+20 lines)
Lines 664-669 Link Here
664
	  (the one containing the directory /) cannot be a module, so saying M
664
	  (the one containing the directory /) cannot be a module, so saying M
665
	  could be dangerous.  If unsure, say N.
665
	  could be dangerous.  If unsure, say N.
666
666
667
config FATX_FS
668
	tristate "FATX filesystem support (EXPERIMENTAL)"
669
	depends on EXPERIMENTAL && !LBD
670
	help
671
	  This adds support for the FATX filesystem as found in Microsoft's Xbox.
672
	  
673
	  The FATX filesystem is a derivative of the FAT filesystem minus some
674
	  legacy fields and redundant information. For lengthier discussions on
675
	  the filesystem, see:
676
	  
677
	  http://xbox-linux.sourceforge.net/docs/fatxfat.html
678
	  http://xbox-linux.sourceforge.net/docs/hdpartfs.html
679
	  http://xbox-linux.sourceforge.net/docs/hackingfatx.html
680
	  
681
	  If you are running Linux on the Xbox, choose Y unless you know
682
	  what you're doing. Otherwise, choose N.
683
	  
684
	  To compile this filesystem support as a module, choose M here: the
685
	  module will be called fatx.
686
667
config NTFS_FS
687
config NTFS_FS
668
	tristate "NTFS file system support"
688
	tristate "NTFS file system support"
669
	select NLS
689
	select NLS
(-)linux-2.6.5.orig/fs/Makefile (+1 lines)
Lines 59-64 Link Here
59
obj-$(CONFIG_UMSDOS_FS)		+= umsdos/
59
obj-$(CONFIG_UMSDOS_FS)		+= umsdos/
60
obj-$(CONFIG_MSDOS_FS)		+= msdos/
60
obj-$(CONFIG_MSDOS_FS)		+= msdos/
61
obj-$(CONFIG_VFAT_FS)		+= vfat/
61
obj-$(CONFIG_VFAT_FS)		+= vfat/
62
obj-$(CONFIG_FATX_FS)		+= fatx/
62
obj-$(CONFIG_BFS_FS)		+= bfs/
63
obj-$(CONFIG_BFS_FS)		+= bfs/
63
obj-$(CONFIG_ISO9660_FS)	+= isofs/
64
obj-$(CONFIG_ISO9660_FS)	+= isofs/
64
obj-$(CONFIG_DEVFS_FS)		+= devfs/
65
obj-$(CONFIG_DEVFS_FS)		+= devfs/
(-)linux-2.6.5.orig/fs/fatx/Makefile (+7 lines)
Line 0 Link Here
1
#
2
# Makefile for the Linux fatx filesystem routines.
3
#
4
5
obj-$(CONFIG_FATX_FS) += fatx.o
6
7
fatx-objs := namei.o cache.o dir.o file.o inode.o misc.o fatxfs_syms.o
(-)linux-2.6.5.orig/fs/fatx/cache.c (+319 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/fatx/cache.c
3
 *
4
 *  Written 2003 by Edgar Hucek and Lehner Franz
5
 *
6
 */
7
8
#include <linux/fatx_fs.h>
9
#include <linux/kernel.h>
10
#include <linux/errno.h>
11
#include <linux/string.h>
12
#include <linux/stat.h>
13
#include <linux/buffer_head.h>
14
15
#define PRINTK(format, args...) do { if (fatx_debug) printk( format, ##args ); } while(0)
16
17
static struct fatx_cache *fatx_cache,cache[FATX_CACHE];
18
static spinlock_t fatx_cache_lock = SPIN_LOCK_UNLOCKED;
19
20
int fatx_access(struct super_block *sb,int nr,int new_value)
21
{
22
	struct buffer_head *bh, *bh2, *c_bh, *c_bh2;
23
	unsigned char *p_first, *p_last;
24
	int copy, first = 0, last = 0, next, b;
25
26
	next = 0;
27
28
	if ((unsigned) (nr-2) >= FATX_SB(sb)->clusters)
29
		return 0;
30
	if (FATX_SB(sb)->fat_bits == 32) {
31
		first = last = nr*4;
32
	} else if (FATX_SB(sb)->fat_bits == 16) {
33
		first = last = nr*2;
34
	}
35
36
	b = FATX_SB(sb)->fat_start + (first >> sb->s_blocksize_bits);
37
	if (!(bh = sb_bread(sb, b))) {
38
		PRINTK("FATX: bread in fatx_access failed\n");
39
		return 0;
40
	}
41
	if ((first >> sb->s_blocksize_bits) == (last >> sb->s_blocksize_bits)) {
42
		bh2 = bh;
43
	} else {
44
		if (!(bh2 = sb_bread(sb, b+1))) {
45
			if(bh) brelse(bh);
46
			PRINTK("FATX: 2nd bread in fatx_access failed\n");
47
			return 0;
48
		}
49
	}
50
	if (FATX_SB(sb)->fat_bits == 32) {
51
		p_first = p_last = NULL; /* GCC needs that stuff */
52
		next = CF_LE_L(((__u32 *) bh->b_data)[(first & (sb->s_blocksize - 1)) >> 2]);
53
		next &= 0xffffffff;
54
		if (next >= EOC_FAT32) next = -1;
55
	} else if (FATX_SB(sb)->fat_bits == 16) {
56
		p_first = p_last = NULL; /* GCC needs that stuff */
57
		next = CF_LE_W(((__u16 *) bh->b_data)[(first & (sb->s_blocksize - 1)) >> 1]);
58
		if (next >= EOC_FAT16) next = -1;
59
	}
60
	PRINTK("FATX: fatx_access: 0x%x, nr=0x%x, first=0x%x, next=0x%x\n", b, nr, first, next);
61
	if (new_value != -1) {
62
		if (FATX_SB(sb)->fat_bits == 32) {
63
			((__u32 *)bh->b_data)[(first & (sb->s_blocksize - 1)) >> 2]
64
				= CT_LE_L(new_value);
65
		} else if (FATX_SB(sb)->fat_bits == 16) {
66
			((__u16 *)bh->b_data)[(first & (sb->s_blocksize - 1)) >> 1]
67
				= CT_LE_W(new_value);
68
		}
69
		mark_buffer_dirty(bh);
70
		for (copy = 1; copy < FATX_SB(sb)->fats; copy++) {
71
			b = FATX_SB(sb)->fat_start + (first >> sb->s_blocksize_bits)
72
				+ FATX_SB(sb)->fat_length * copy;
73
			if (!(c_bh = sb_bread(sb, b)))
74
				break;
75
			if (bh != bh2) {
76
				if (!(c_bh2 = sb_bread(sb, b+1))) {
77
					if(c_bh) brelse(c_bh);
78
					break;
79
				}
80
				memcpy(c_bh2->b_data, bh2->b_data, sb->s_blocksize);
81
				mark_buffer_dirty(c_bh2);
82
				if(c_bh2) brelse(c_bh2);
83
			}
84
			memcpy(c_bh->b_data, bh->b_data, sb->s_blocksize);
85
			mark_buffer_dirty(c_bh);
86
			if(c_bh) brelse(c_bh);
87
		}
88
	}
89
	if(bh) brelse(bh);
90
	if (bh != bh2)
91
		if(bh2) brelse(bh2);
92
	return next;
93
}
94
95
void fatx_cache_init(void)
96
{
97
	static int initialized = 0;
98
	int count;
99
100
	spin_lock(&fatx_cache_lock);
101
	if (initialized) {
102
		spin_unlock(&fatx_cache_lock);
103
		return;
104
	}
105
	fatx_cache = &cache[0];
106
	for (count = 0; count < FATX_CACHE; count++) {
107
		cache[count].device = 0;
108
		cache[count].next = count == FATX_CACHE-1 ? NULL :
109
		    &cache[count+1];
110
	}
111
	initialized = 1;
112
	spin_unlock(&fatx_cache_lock);
113
}
114
115
116
void fatx_cache_lookup(struct inode *inode,int cluster,int *f_clu,int *d_clu)
117
{
118
	struct fatx_cache *walk;
119
	int first = FATX_I(inode)->i_start;
120
121
	if (!first)
122
		return;
123
	spin_lock(&fatx_cache_lock);
124
	for (walk = fatx_cache; walk; walk = walk->next)
125
		if (inode->i_rdev == walk->device
126
		    && walk->start_cluster == first
127
		    && walk->file_cluster <= cluster
128
		    && walk->file_cluster > *f_clu) {
129
			*d_clu = walk->disk_cluster;
130
#ifdef DEBUG
131
printk("cache hit: %d (%d)\n",walk->file_cluster,*d_clu);
132
#endif
133
			if ((*f_clu = walk->file_cluster) == cluster) { 
134
				spin_unlock(&fatx_cache_lock);
135
				return;
136
			}
137
		}
138
	spin_unlock(&fatx_cache_lock);
139
#ifdef DEBUG
140
printk("cache miss\n");
141
#endif
142
}
143
144
145
#ifdef DEBUG
146
static void list_cache(void)
147
{
148
	struct fatx_cache *walk;
149
150
	for (walk = fatx_cache; walk; walk = walk->next) {
151
		if (walk->device)
152
			printk("<%s,%d>(%d,%d) ", kdevname(walk->device),
153
			       walk->start_cluster, walk->file_cluster,
154
			       walk->disk_cluster);
155
		else printk("-- ");
156
	}
157
	printk("\n");
158
}
159
#endif
160
161
162
void fatx_cache_add(struct inode *inode,int f_clu,int d_clu)
163
{
164
	struct fatx_cache *walk,*last;
165
	int first = FATX_I(inode)->i_start;
166
167
	last = NULL;
168
	spin_lock(&fatx_cache_lock);
169
	for (walk = fatx_cache; walk->next; walk = (last = walk)->next)
170
		if (walk->device == inode->i_rdev
171
		    && walk->start_cluster == first
172
		    && walk->file_cluster == f_clu) {
173
			if (walk->disk_cluster != d_clu) {
174
				printk("FAT cache corruption inode=%ld\n",
175
					inode->i_ino);
176
				spin_unlock(&fatx_cache_lock);
177
				fatx_cache_inval_inode(inode);
178
				return;
179
			}
180
			/* update LRU */
181
			if (last == NULL) {
182
				spin_unlock(&fatx_cache_lock);
183
				return;
184
			}
185
			last->next = walk->next;
186
			walk->next = fatx_cache;
187
			fatx_cache = walk;
188
#ifdef DEBUG
189
list_cache();
190
#endif
191
			spin_unlock(&fatx_cache_lock);
192
			return;
193
		}
194
	walk->device = inode->i_rdev;
195
	walk->start_cluster = first;
196
	walk->file_cluster = f_clu;
197
	walk->disk_cluster = d_clu;
198
	last->next = NULL;
199
	walk->next = fatx_cache;
200
	fatx_cache = walk;
201
	spin_unlock(&fatx_cache_lock);
202
#ifdef DEBUG
203
list_cache();
204
#endif
205
}
206
207
208
/* Cache invalidation occurs rarely, thus the LRU chain is not updated. It
209
   fixes itself after a while. */
210
211
void fatx_cache_inval_inode(struct inode *inode)
212
{
213
	struct fatx_cache *walk;
214
	int first = FATX_I(inode)->i_start;
215
216
	spin_lock(&fatx_cache_lock);
217
	for (walk = fatx_cache; walk; walk = walk->next)
218
		if (walk->device == inode->i_rdev
219
		    && walk->start_cluster == first)
220
			walk->device = 0;
221
	spin_unlock(&fatx_cache_lock);
222
}
223
224
225
void fatx_cache_inval_dev(dev_t device)
226
{
227
	struct fatx_cache *walk;
228
229
	spin_lock(&fatx_cache_lock);
230
	for (walk = fatx_cache; walk; walk = walk->next)
231
		if (walk->device == device)
232
			walk->device = 0;
233
	spin_unlock(&fatx_cache_lock);
234
}
235
236
237
int fatx_get_cluster(struct inode *inode,int cluster)
238
{
239
	int nr,count;
240
241
	if (!(nr = FATX_I(inode)->i_start)) return 0;
242
	if (!cluster) return nr;
243
	count = 0;
244
	for (fatx_cache_lookup(inode,cluster,&count,&nr); count < cluster;
245
	    count++) {
246
		if ((nr = fatx_access(inode->i_sb,nr,-1)) == -1) return 0;
247
		if (!nr) return 0;
248
	}
249
	fatx_cache_add(inode,cluster,nr);
250
	return nr;
251
}
252
253
unsigned long fatx_bmap(struct inode *inode,unsigned long sector)
254
{
255
	struct super_block *sb = inode->i_sb;
256
	struct fatx_sb_info *sbi = FATX_SB(sb);
257
	unsigned long cluster, offset, last_block;
258
259
	if ((inode->i_ino == FATX_ROOT_INO || (S_ISDIR(inode->i_mode) &&
260
	     !FATX_I(inode)->i_start))) {
261
		if (sector >= sbi->dir_entries >> sbi->dir_per_block_bits)
262
			return 0;
263
		return sector + sbi->dir_start;
264
	}
265
	
266
	last_block = (FATX_I(inode)->mmu_private + (sb->s_blocksize - 1))
267
		>> sb->s_blocksize_bits;
268
	if (sector >= last_block)
269
		return 0;
270
271
	cluster = sector / sbi->cluster_size;
272
	offset  = sector % sbi->cluster_size;
273
	if (!(cluster = fatx_get_cluster(inode, cluster)))
274
		return 0;
275
276
	return (cluster - 2) * sbi->cluster_size + sbi->data_start + offset;
277
}
278
279
280
/* Free all clusters after the skip'th cluster. Doesn't use the cache,
281
   because this way we get an additional sanity check. */
282
283
int fatx_free(struct inode *inode,int skip)
284
{
285
	int nr,last;
286
287
	if (!(nr = FATX_I(inode)->i_start)) return 0;
288
	last = 0;
289
	while (skip--) {
290
		last = nr;
291
		if ((nr = fatx_access(inode->i_sb,nr,-1)) == -1) return 0;
292
		if (!nr) {
293
			printk("fatx_free: skipped EOF\n");
294
			return -EIO;
295
		}
296
	}
297
	if (last) {
298
		fatx_access(inode->i_sb,last,EOF_FAT(inode->i_sb));
299
		fatx_cache_inval_inode(inode);
300
	} else {
301
		fatx_cache_inval_inode(inode);
302
		FATX_I(inode)->i_start = 0;
303
		FATX_I(inode)->i_logstart = 0;
304
		mark_inode_dirty(inode);
305
	}
306
	lock_fatx(inode->i_sb);
307
	while (nr != -1) {
308
		if (!(nr = fatx_access(inode->i_sb,nr,0))) {
309
			fatx_fs_panic(inode->i_sb,"fatx_free: deleting beyond EOF");
310
			break;
311
		}
312
		if (FATX_SB(inode->i_sb)->free_clusters != -1) {
313
			FATX_SB(inode->i_sb)->free_clusters++;
314
		}
315
		inode->i_blocks -= (1 << FATX_SB(inode->i_sb)->cluster_bits) / 512;
316
	}
317
	unlock_fatx(inode->i_sb);
318
	return 0;
319
}
(-)linux-2.6.5.orig/fs/fatx/dir.c (+436 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/fatx/dir.c
3
 *
4
 *  Written 2003 by Edgar Hucek and Lehner Franz
5
 *
6
 */
7
8
#include <linux/fs.h>
9
#include <linux/fatx_fs.h>
10
#include <linux/nls.h>
11
#include <linux/kernel.h>
12
#include <linux/errno.h>
13
#include <linux/stat.h>
14
#include <linux/string.h>
15
#include <linux/ioctl.h>
16
#include <linux/dirent.h>
17
#include <linux/mm.h>
18
#include <linux/ctype.h>
19
20
#include <asm/uaccess.h>
21
22
#define DEBUG
23
#define PRINTK(format, args...) do { if (fatx_debug) printk( format, ##args ); } while(0)
24
25
static inline void fatx_printname(const char *name, int length)
26
{
27
	int i;
28
	for(i=0;i<length;i++) {
29
		PRINTK("%c",name[i]);
30
	}
31
}
32
33
/*
34
 * Now an ugly part: this set of directory scan routines works on clusters
35
 * rather than on inodes and sectors. They are necessary to locate the '..'
36
 * directory "inode". raw_scan_sector operates in four modes:
37
 *
38
 * name     number   ino      action
39
 * -------- -------- -------- -------------------------------------------------
40
 * non-NULL -        X        Find an entry with that name
41
 * NULL     non-NULL non-NULL Find an entry whose data starts at *number
42
 * NULL     non-NULL NULL     Count subdirectories in *number. (*)
43
 * NULL     NULL     non-NULL Find an empty entry
44
 *
45
 * (*) The return code should be ignored. It DOES NOT indicate success or
46
 *     failure. *number has to be initialized to zero.
47
 *
48
 * - = not used, X = a value is returned unless NULL
49
 *
50
 * If res_bh is non-NULL, the buffer is not deallocated but returned to the
51
 * caller on success. res_de is set accordingly.
52
 *
53
 * If cont is non-zero, raw_found continues with the entry after the one
54
 * res_bh/res_de point to.
55
 */
56
static int fatx_raw_scan_sector(struct super_block *sb,	int sector,
57
		const char *name, int name_length, int *number,
58
		loff_t *i_pos, struct buffer_head **res_bh,
59
		struct fatx_dir_entry **res_de )
60
{
61
	struct buffer_head *bh;
62
	struct fatx_dir_entry *data;
63
	int entry,start,done = 0;
64
65
	PRINTK("FATX: fatx_raw_scan_sector: sector=%08lX\n",(long)sector);
66
	
67
	if (!(bh = sb_bread(sb,sector))) {
68
		printk("FATX: fatx_raw_scan_sector: sb_bread failed\n");
69
		return -EIO;
70
	}
71
	data = (struct fatx_dir_entry *) bh->b_data;
72
	for (entry = 0; entry < FATX_SB(sb)->dir_per_block; entry++) {
73
		if (FATX_END_OF_DIR(&data[entry])) {
74
			//no more entries to look through...
75
			if(bh) brelse(bh);
76
			PRINTK("FATX: fatx_raw_scan_sector: END OF DIR\n");
77
			return -ENOENT;
78
		} else if (name) { //search for name
79
			done = 	(data[entry].name_length == name_length) &&
80
				!strncmp(data[entry].name,name,name_length);
81
		} else if (!i_pos) { /* count subdirectories */
82
			done = 0;
83
			if (!FATX_IS_FREE(&data[entry]) && (data[entry].attr & ATTR_DIR))
84
				(*number)++;
85
		} else if (number) { /* search for start cluster */
86
			done = !FATX_IS_FREE(&data[entry]) && 
87
				(CF_LE_L(data[entry].start) == *number);
88
		} else { /* search for free entry */
89
			done = FATX_IS_FREE(&data[entry]);
90
		}
91
		if (done) {
92
			if (i_pos)
93
				*i_pos = sector * FATX_SB(sb)->dir_per_block + entry;
94
			start = CF_LE_L(data[entry].start);
95
			if (!res_bh) {
96
				if(bh) brelse(bh);
97
			} else {
98
				*res_bh = bh;
99
				*res_de = &data[entry];
100
			}
101
			PRINTK("FATX: fatx_raw_scan_sector: found: start=%08lX\n",(long)start);
102
			return start;
103
		}
104
	}
105
	if(bh) brelse(bh);
106
	PRINTK("FATX: fatx_raw_scan_sector: entry not in sector %08lX\n",(long)sector);
107
	return -EAGAIN;
108
}
109
110
/*
111
 * raw_scan_root performs raw_scan_sector on the root directory until the
112
 * requested entry is found or the end of the directory is reached.
113
 */
114
static int fatx_raw_scan_root(struct super_block *sb, const char *name,
115
		int name_length, int *number, loff_t *i_pos,
116
		struct buffer_head **res_bh, struct fatx_dir_entry **res_de )
117
{
118
	int count,cluster;
119
120
	for (count = 0; count < FATX_SB(sb)->cluster_size; count++) {
121
		if ((cluster = fatx_raw_scan_sector(sb,FATX_SB(sb)->dir_start + count,
122
				       name,name_length,number,i_pos,res_bh,res_de)) >= 0)
123
			return cluster;
124
		if (cluster == -ENOENT) {
125
			//end of dir...act like all sectors scanned and !found
126
			PRINTK("FATX: fatx_raw_scan_root cluster %d\n",cluster);
127
			return cluster;
128
		}
129
	}
130
	
131
	PRINTK("FATX: fatx_raw_scan_root leave\n");
132
133
	return -ENOENT;
134
}
135
136
/*
137
 * raw_scan_nonroot performs raw_scan_sector on a non-root directory until the
138
 * requested entry is found or the end of the directory is reached.
139
 */
140
static int fatx_raw_scan_nonroot(struct super_block *sb, int start,
141
		const char *name, int name_length, int *number,
142
		loff_t *i_pos, struct buffer_head **res_bh,
143
		struct fatx_dir_entry **res_de )
144
{
145
	int count,cluster;
146
	
147
	PRINTK("FATX: fatx_raw_scan_nonroot: entered (start=%08lX)\n",(long)start);
148
149
	do {
150
		for (count = 0; count < FATX_SB(sb)->cluster_size; count++) {
151
			if ((cluster = fatx_raw_scan_sector(sb,FATX_SB(sb)->data_start + 
152
					(FATX_SB(sb)->cluster_size * (start - 2) ) + count,
153
			    name,name_length,number,i_pos,res_bh,res_de)) >= 0)
154
				return cluster;
155
			if (cluster == -ENOENT) {
156
				//EOD: act like all sectors scanned and !found
157
				return cluster;
158
			}
159
		}
160
		if (!(start = fatx_access(sb,start,-1))) {
161
			printk("FATX: fatx_raw_scan_nonroot: start sector %lX not in use\n",(long)start);
162
			fatx_fs_panic(sb,"FATX error");
163
			break;
164
		}
165
	}
166
	while (start != -1);
167
	return -ENOENT;
168
}
169
170
/*
171
 * Scans a directory for a given file (name points to its formatted name) or
172
 * for an empty directory slot (name is NULL). Returns an error code or zero.
173
 */
174
int fatx_scan(struct inode *dir, const char *name, int name_length,
175
		struct buffer_head **res_bh, struct fatx_dir_entry **res_de,
176
		loff_t *i_pos )
177
{
178
	int res;
179
180
	if (FATX_I(dir)->i_start)
181
		res = fatx_raw_scan_nonroot(dir->i_sb,FATX_I(dir)->i_start,name,name_length,NULL,i_pos,res_bh,res_de);
182
	else
183
		res = fatx_raw_scan_root(dir->i_sb,name,name_length,NULL,i_pos,res_bh,res_de);
184
185
	return res<0 ? res : 0;
186
}
187
188
/*
189
 * See if directory is empty
190
 */
191
int fatx_dir_empty(struct inode *dir)
192
{
193
	loff_t pos;
194
	struct buffer_head *bh;
195
	struct fatx_dir_entry *de;
196
	loff_t i_pos;
197
	int result = 0;
198
199
	pos = 0;
200
	bh = NULL;
201
	while (fatx_get_entry(dir,&pos,&bh,&de,&i_pos) > -1) {
202
		if (FATX_END_OF_DIR(de)) {
203
			break;
204
		}
205
		if (!FATX_IS_FREE(de)) {
206
			result = -ENOTEMPTY;
207
			break;
208
		}
209
	}
210
	if (bh)
211
		brelse(bh);
212
213
	return result;
214
}
215
216
/*
217
 * fatx_subdirs counts the number of sub-directories of dir. It can be run
218
 * on directories being created.
219
 */
220
int fatx_subdirs(struct inode *dir)
221
{
222
	int count;
223
224
	count = 0;
225
	if (dir->i_ino == FATX_ROOT_INO) {
226
		fatx_raw_scan_root(dir->i_sb,NULL,0,&count,NULL,NULL,NULL);
227
	} else {
228
		if ((dir->i_ino != FATX_ROOT_INO) && !FATX_I(dir)->i_start) {
229
			return 0; /* in mkdir */
230
		} else {
231
			fatx_raw_scan_nonroot(dir->i_sb,FATX_I(dir)->i_start,
232
			                      NULL,0,&count,NULL,NULL,NULL);
233
		}
234
	}
235
	return count;
236
}
237
238
int fatx_do_add_entry(
239
		struct inode *dir,
240
		struct buffer_head **bh,
241
		struct fatx_dir_entry **de,
242
		loff_t *i_pos)
243
{
244
	loff_t offset, curr;
245
	struct buffer_head *new_bh;
246
247
	offset = curr = 0;
248
	*bh = NULL;
249
	while (fatx_get_entry(dir,&curr,bh,de,i_pos) > -1) {
250
		if (FATX_IS_FREE(*de)) {
251
			PRINTK("FATX: fatx_do_add_entry: found free entry\n");
252
			return offset;
253
		}
254
		if (FATX_END_OF_DIR(*de)) {
255
			struct buffer_head *eod_bh = NULL;
256
			struct fatx_dir_entry *eod_de = NULL;
257
			loff_t eod_i_pos;
258
			
259
			PRINTK("FATX: fatx_do_add_entry: found EOD at %lX\n",(long)(*de));
260
			//make sure the next one isn't first in new cluster
261
			if (fatx_get_entry(dir,&curr,&eod_bh,&eod_de,&eod_i_pos) > -1) {
262
				//EOD in same cluster...find proper de and mark new EOD
263
				eod_de->name_length = 0xFF;
264
				mark_buffer_dirty(eod_bh);
265
				PRINTK("FATX: fatx_do_add_entry: marked new EOD at %lX\n",(long)eod_de);
266
				if(eod_bh) brelse(eod_bh);
267
			} else {
268
				//we will take the easy out...do nothing...
269
				//assume fat table used to indicate EOD
270
				//if this is wrong, need to fatx_extend_dir
271
				//making first entry in next cluster EOD
272
				printk("FATX: fatx_do_add_entry: EOD marked by FAT\n");
273
				printk("FATX: ...:offset=%08lX, curr=%08lX\n",
274
						(unsigned long)offset,(unsigned long)curr);
275
			}
276
			PRINTK("FATX: fatx_do_add_entry: using entry at %lX\n",(long)(*de));
277
			return offset;
278
		}
279
		offset = curr;
280
	}
281
	PRINTK("FATX: fatx_do_add_entry: need to extend dir\n");
282
	if (dir->i_ino == FATX_ROOT_INO) {
283
		printk("FATX: fatx_do_add_entry: but it's root dir...can't extend\n");
284
		return -ENOSPC;
285
	}
286
	new_bh = fatx_extend_dir(dir);
287
	if (!new_bh) {
288
		PRINTK("FATX: fatx_do_add_entry: fatx_extend_dir failed...no space?\n");
289
		return -ENOSPC;
290
	}
291
	if(new_bh) brelse(new_bh);
292
	fatx_get_entry(dir,&curr,bh,de,i_pos);
293
	(*de)[1].name_length = 0xFF;
294
	PRINTK("FATX: fatx_do_add_entry: using entry at %ld\n",(long)offset);
295
	return offset;
296
}
297
298
int fatx_new_dir(struct inode *dir, struct inode *parent)
299
{
300
	struct buffer_head *bh;
301
	struct fatx_dir_entry *de;
302
303
	if ((bh = fatx_extend_dir(dir)) == NULL) {
304
		printk("FATX: fatx_new_dir: failed to get new cluster...no space?\n");
305
		return -ENOSPC;
306
	}
307
	/* zeroed out, so... */
308
	de = (struct fatx_dir_entry*)&bh->b_data[0];
309
	de[0].attr = de[1].attr = ATTR_DIR;
310
	de[0].name_length = 0xFF; //end of dir marker
311
        de[0].start = CT_LE_W(FATX_I(dir)->i_logstart);
312
	de[1].start = CT_LE_W(FATX_I(parent)->i_logstart);	
313
	mark_buffer_dirty(bh);
314
	if(bh) brelse(bh);
315
	dir->i_atime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
316
	mark_inode_dirty(dir);
317
318
	return 0;
319
}
320
321
// sure to hope this is correct...
322
int fatx_readdir(struct file *filp, void *dirent, filldir_t filldir)
323
{
324
	struct inode *inode = filp->f_dentry->d_inode;
325
	struct inode *tmpi;
326
	struct super_block *sb = inode->i_sb;
327
	struct fatx_dir_entry *de;
328
	struct buffer_head *bh;
329
	loff_t i_pos;
330
	int inum;
331
	loff_t cpos = 0;	//file position (dir position)
332
	int offset = 0;		//cpos offset for root dir handling
333
	int entry = 0;		//next filldir entry location
334
335
	PRINTK("FATX: fatx_readdir entered\n");
336
	
337
	cpos = filp->f_pos;
338
	
339
	if (cpos == 0) {
340
		if (filldir(dirent,".",1,entry++,inode->i_ino,DT_DIR)<0) {
341
			printk("\nFATX: fatx_readdir exiting in root defaults\n");
342
			return 0;
343
		}
344
		cpos += 1 << FATX_DIR_BITS;
345
	}
346
	
347
	if (cpos == 1 << FATX_DIR_BITS) {
348
		if (filldir(dirent,"..",2,entry++,
349
		            filp->f_dentry->d_parent->d_inode->i_ino,DT_DIR)<0) {
350
			printk("\nFATX: fatx_readdir exiting in root defaults\n");
351
			filp->f_pos = 1 << FATX_DIR_BITS;
352
			return 0;
353
		}
354
		cpos += 1 << FATX_DIR_BITS;
355
	}
356
	
357
	offset = 2 << FATX_DIR_BITS;
358
	cpos -= offset;
359
360
 	bh = NULL;
361
362
	while(fatx_get_entry(inode,&cpos,&bh,&de,&i_pos) != -1) {
363
		if (FATX_END_OF_DIR(de)) {
364
			PRINTK("FATX: entry %ld marked as END OF DIR\n",(long)(cpos >> FATX_DIR_BITS));
365
			cpos -= 1 << FATX_DIR_BITS; // make sure it comes back to here if re-entered
366
			break;		//done...end of dir.
367
		}
368
		
369
		if (FATX_IS_FREE(de)) {
370
			PRINTK("FATX: entry %ld marked as FREE\n",(long)(cpos >> FATX_DIR_BITS));
371
			continue;
372
		}
373
374
		tmpi = fatx_iget(sb, i_pos);
375
		if (tmpi) {
376
			inum = tmpi->i_ino;
377
			iput(tmpi);
378
		} else {
379
			inum = iunique(sb, FATX_ROOT_INO);
380
		}
381
382
		if (filldir(dirent,de->name,de->name_length,entry++,inum,
383
		            (de->attr & ATTR_DIR) ? DT_DIR : DT_REG ) < 0 ) {
384
			break;
385
		}
386
		PRINTK("\nFATX: fatx_readdir: dir entry %3d: ",(int)entry);
387
		fatx_printname(de->name,de->name_length);
388
		PRINTK("\n");
389
	}
390
391
	filp->f_pos = cpos + offset;		
392
	if (bh)
393
		brelse(bh);
394
	
395
	PRINTK("\nFATX: fatx_readdir leaving\n");
396
	
397
	return 0;
398
}
399
400
struct file_operations fatx_dir_operations = {
401
	.read		= generic_read_dir,
402
	.readdir	= fatx_readdir,
403
	.ioctl		= NULL,
404
	.fsync		= file_fsync,
405
};
406
407
/* This assumes that size of cluster is above the 32*slots */
408
409
int fatx_add_entries(struct inode *dir,int slots, struct buffer_head **bh,
410
		  struct fatx_dir_entry **de, loff_t *i_pos)
411
{
412
	loff_t offset, curr;
413
	int row;
414
	struct buffer_head *new_bh;
415
416
	offset = curr = 0;
417
	*bh = NULL;
418
	row = 0;
419
	while (fatx_get_entry(dir,&curr,bh,de,i_pos) > -1) {
420
		if (IS_FREE((*de)->name)) {
421
			if (++row == slots)
422
				return offset;
423
		} else {
424
			row = 0;
425
			offset = curr;
426
		}
427
	}
428
	if (dir->i_ino == FATX_ROOT_INO) 
429
		return -ENOSPC;
430
	new_bh = fatx_extend_dir(dir);
431
	if (!new_bh)
432
		return -ENOSPC;
433
	if(new_bh) brelse(new_bh);
434
	do fatx_get_entry(dir,&curr,bh,de,i_pos); while (++row<slots);
435
	return offset;
436
}
(-)linux-2.6.5.orig/fs/fatx/fatxfs_syms.c (+77 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/fatx/fatxfs_syms.c
3
 *
4
 *  Exported kernel symbols for the FATX filesystem.
5
 *
6
 *  Written 2003 by Edgar Hucek and Lehner Franz
7
 *
8
 */
9
10
#include <linux/module.h>
11
#include <linux/mm.h>
12
#include <linux/fatx_fs.h>
13
#include <linux/init.h>
14
15
unsigned int fatx_debug = 0;
16
17
MODULE_PARM(fatx_debug,"i");
18
MODULE_PARM_DESC(fatx_debug,"turn on fatx debugging output");
19
20
EXPORT_SYMBOL(fatx_lookup);
21
EXPORT_SYMBOL(fatx_create);
22
EXPORT_SYMBOL(fatx_rmdir);
23
EXPORT_SYMBOL(fatx_mkdir);
24
EXPORT_SYMBOL(fatx_rename);
25
EXPORT_SYMBOL(fatx_unlink);
26
27
EXPORT_SYMBOL(fatx_new_dir);
28
EXPORT_SYMBOL(fatx_get_block);
29
EXPORT_SYMBOL(fatx_clear_inode);
30
EXPORT_SYMBOL(fatx_date_unix2dos);
31
EXPORT_SYMBOL(fatx_delete_inode);
32
EXPORT_SYMBOL(fatx_get_entry);
33
EXPORT_SYMBOL(fatx_notify_change);
34
EXPORT_SYMBOL(fatx_put_super);
35
EXPORT_SYMBOL(fatx_attach);
36
EXPORT_SYMBOL(fatx_detach);
37
EXPORT_SYMBOL(fatx_build_inode);
38
EXPORT_SYMBOL(fatx_fill_super);
39
EXPORT_SYMBOL(fatx_readdir);
40
EXPORT_SYMBOL(fatx_scan);
41
EXPORT_SYMBOL(fatx_statfs);
42
EXPORT_SYMBOL(fatx_write_inode);
43
EXPORT_SYMBOL(fatx_get_cluster);
44
EXPORT_SYMBOL(fatx_add_entries);
45
EXPORT_SYMBOL(fatx_dir_empty);
46
EXPORT_SYMBOL(fatx_truncate);
47
48
static struct super_block *fatx_get_sb(struct file_system_type *fs_type,
49
		        int flags, const char *dev_name, void *data)
50
{
51
	return get_sb_bdev(fs_type, flags, dev_name, data, fatx_fill_super);
52
}
53
54
static struct file_system_type fatx_fs_type = {
55
	.owner          = THIS_MODULE,
56
	.name           = "fatx",
57
	.get_sb         = fatx_get_sb,
58
	.kill_sb        = kill_block_super,
59
	.fs_flags       = FS_REQUIRES_DEV,
60
};
61
62
static int __init init_fatx_fs(void)
63
{
64
	printk("FATX driver Version 0.1.0\n");
65
	fatx_hash_init();
66
	return register_filesystem(&fatx_fs_type);
67
}
68
69
static void __exit exit_fatx_fs(void)
70
{
71
	unregister_filesystem(&fatx_fs_type);
72
}
73
74
module_init(init_fatx_fs)
75
module_exit(exit_fatx_fs)
76
MODULE_LICENSE("GPL");
77
(-)linux-2.6.5.orig/fs/fatx/file.c (+103 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/fatx/file.c
3
 *
4
 *  Written 2003 by Edgar Hucek and Lehner Franz
5
 *
6
 */
7
8
#include <linux/sched.h>
9
#include <linux/fs.h>
10
#include <linux/fatx_fs.h>
11
#include <linux/errno.h>
12
#include <linux/fcntl.h>
13
#include <linux/stat.h>
14
#include <linux/string.h>
15
#include <linux/pagemap.h>
16
17
#include <asm/uaccess.h>
18
#include <asm/system.h>
19
20
#define PRINTK(format, args...) do { if (fatx_debug) printk( format, ##args ); } while(0)
21
22
struct file_operations fatx_file_operations = {
23
	.llseek		= generic_file_llseek,
24
	.read		= generic_file_read,
25
	.write		= fatx_file_write,
26
	.mmap		= generic_file_mmap,
27
	.fsync		= file_fsync,
28
	.readv          = generic_file_readv,
29
	.writev         = generic_file_writev,
30
	.sendfile       = generic_file_sendfile,			
31
};
32
33
struct inode_operations fatx_file_inode_operations = {
34
	.truncate	= fatx_truncate,
35
	.setattr	= fatx_notify_change,
36
};
37
38
int fatx_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
39
{
40
	struct super_block *sb = inode->i_sb;
41
	unsigned long phys;
42
43
	phys = fatx_bmap(inode, iblock);
44
	if (phys) {
45
		map_bh(bh_result, sb, phys);
46
		return 0;
47
	}
48
	if (!create)
49
		return 0;
50
	if (iblock << sb->s_blocksize_bits != FATX_I(inode)->mmu_private) {
51
		BUG();
52
		return -EIO;
53
	}
54
	if (!(iblock % FATX_SB(inode->i_sb)->cluster_size)) {
55
		if (fatx_add_cluster(inode) < 0)
56
			return -ENOSPC;
57
	}
58
	FATX_I(inode)->mmu_private += sb->s_blocksize;
59
	phys = fatx_bmap(inode, iblock);
60
	if (!phys)
61
		BUG();
62
	set_buffer_new(bh_result);
63
	map_bh(bh_result, sb, phys);
64
	return 0;
65
}
66
67
ssize_t fatx_file_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
68
{
69
	struct inode *inode = filp->f_dentry->d_inode;
70
	int retval;
71
72
	retval = generic_file_write(filp, buf, count, ppos);
73
	if (retval > 0) {
74
		inode->i_mtime = inode->i_ctime = inode->i_atime = CURRENT_TIME;
75
		FATX_I(inode)->i_attrs |= ATTR_ARCH;
76
		mark_inode_dirty(inode);
77
	}
78
	return retval;
79
}
80
81
void fatx_truncate(struct inode *inode)
82
{
83
	struct fatx_sb_info *sbi = FATX_SB(inode->i_sb);
84
	int cluster;
85
86
	/* Why no return value?  Surely the disk could fail... */
87
	if (IS_RDONLY (inode))
88
		return /* -EPERM */;
89
	if (IS_IMMUTABLE(inode))
90
		return /* -EPERM */;
91
	cluster = 1 << sbi->cluster_bits;
92
	/* 
93
	 * This protects against truncating a file bigger than it was then
94
	 * trying to write into the hole.
95
	 */
96
	if (FATX_I(inode)->mmu_private > inode->i_size)
97
		FATX_I(inode)->mmu_private = inode->i_size;
98
99
	fatx_free(inode, (inode->i_size + (cluster - 1)) >> sbi->cluster_bits);
100
	FATX_I(inode)->i_attrs |= ATTR_ARCH;
101
	inode->i_ctime = inode->i_mtime = inode->i_atime = CURRENT_TIME;
102
	mark_inode_dirty(inode);
103
}
(-)linux-2.6.5.orig/fs/fatx/inode.c (+671 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/fatx/inode.c
3
 *
4
 *  Written 2003 by Edgar Hucek and Lehner Franz
5
 *
6
 */
7
8
#include <linux/module.h>
9
#include <linux/time.h>
10
#include <linux/slab.h>
11
#include <linux/smp_lock.h>
12
#include <linux/seq_file.h>
13
14
#include <linux/fatx_fs.h>
15
#include <linux/fatx_fs_sb.h>
16
17
#include <linux/pagemap.h>
18
#include <linux/buffer_head.h>
19
#include <linux/mount.h>
20
#include <linux/vfs.h>
21
#include <linux/parser.h>
22
#include <asm/unaligned.h>
23
24
25
#ifndef CONFIG_NLS_DEFAULT
26
#define CONFIG_NLS_DEFAULT "iso8859-15"
27
#endif
28
29
#define FAT_HASH_BITS   8
30
#define FAT_HASH_SIZE    (1UL << FAT_HASH_BITS)
31
#define FAT_HASH_MASK    (FAT_HASH_SIZE-1)
32
33
#define PRINTK(format, args...) do { if (fatx_debug) printk( format, ##args ); } while(0)
34
35
static int fatx_writepage(struct page *page, struct writeback_control *wbc)
36
{
37
	return block_write_full_page(page,fatx_get_block, wbc);
38
}
39
40
static int fatx_readpage(struct file *file, struct page *page)
41
{
42
	return block_read_full_page(page,fatx_get_block);
43
}
44
45
static int fatx_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
46
{
47
	return cont_prepare_write(page,from,to,fatx_get_block,
48
		&FATX_I(page->mapping->host)->mmu_private);
49
}
50
51
static sector_t _fatx_bmap(struct address_space *mapping, sector_t block)
52
{
53
	return generic_block_bmap(mapping,block,fatx_get_block);
54
}
55
56
static int fatx_commit_write(struct file *file, struct page *page, unsigned from, unsigned to)
57
{
58
	kunmap(page);
59
	return generic_commit_write(file, page, from, to);
60
}
61
62
struct address_space_operations fatx_aops = {
63
	.readpage	= fatx_readpage,
64
	.writepage	= fatx_writepage,
65
	.sync_page	= block_sync_page,
66
	.prepare_write	= fatx_prepare_write,
67
	.commit_write	= fatx_commit_write,
68
	.bmap		= _fatx_bmap
69
};
70
71
void fatx_put_super(struct super_block *sb)
72
{
73
	fatx_cache_inval_dev(sb->s_dev);
74
	set_blocksize(sb->s_bdev,BLOCK_SIZE);
75
        if (FATX_SB(sb)->nls_io) {
76
		unload_nls(FATX_SB(sb)->nls_io);
77
		FATX_SB(sb)->nls_io = NULL;
78
	}
79
}
80
81
static struct list_head fatx_inode_hashtable[FAT_HASH_SIZE];
82
spinlock_t fatx_inode_lock = SPIN_LOCK_UNLOCKED;
83
84
void fatx_hash_init(void)
85
{
86
	int i;
87
	for(i = 0; i < FAT_HASH_SIZE; i++) {
88
		INIT_LIST_HEAD(&fatx_inode_hashtable[i]);
89
	}
90
}
91
92
static inline unsigned long fatx_hash(struct super_block *sb, int i_pos)
93
{
94
	unsigned long tmp = (unsigned long)i_pos | (unsigned long) sb;
95
	tmp = tmp + (tmp >> FAT_HASH_BITS) + (tmp >> FAT_HASH_BITS * 2);
96
	return tmp & FAT_HASH_MASK;
97
}
98
99
void fatx_attach(struct inode *inode, loff_t i_pos)
100
{
101
	spin_lock(&fatx_inode_lock);
102
	FATX_I(inode)->i_pos = i_pos;
103
	list_add(&FATX_I(inode)->i_fat_hash,
104
		fatx_inode_hashtable + fatx_hash(inode->i_sb, i_pos));
105
	spin_unlock(&fatx_inode_lock);
106
}
107
108
void fatx_detach(struct inode *inode)
109
{
110
	spin_lock(&fatx_inode_lock);
111
	FATX_I(inode)->i_pos = 0;
112
	list_del(&FATX_I(inode)->i_fat_hash);
113
	INIT_LIST_HEAD(&FATX_I(inode)->i_fat_hash);
114
	spin_unlock(&fatx_inode_lock);
115
}
116
117
struct inode *fatx_iget(struct super_block *sb, loff_t i_pos)
118
{
119
	struct list_head *p = fatx_inode_hashtable + fatx_hash(sb, i_pos);
120
	struct list_head *walk;
121
	struct fatx_inode_info *i;
122
	struct inode *inode = NULL;
123
124
	spin_lock(&fatx_inode_lock);
125
	list_for_each(walk, p) {
126
		i = list_entry(walk, struct fatx_inode_info, i_fat_hash);
127
		if (i->i_fat_inode->i_sb != sb)
128
			continue;
129
		if (i->i_pos != i_pos)
130
			continue;
131
		inode = igrab(i->i_fat_inode);
132
		if (inode)
133
			break;
134
	}
135
	spin_unlock(&fatx_inode_lock);
136
	return inode;
137
}
138
139
/* doesn't deal with root inode */
140
static void fatx_fill_inode(struct inode *inode, struct fatx_dir_entry *de)
141
{
142
	struct super_block *sb = inode->i_sb;
143
	struct fatx_sb_info *sbi = FATX_SB(sb);
144
	int nr;
145
146
	INIT_LIST_HEAD(&FATX_I(inode)->i_fat_hash);
147
	FATX_I(inode)->i_pos = 0;
148
	FATX_I(inode)->i_fat_inode = inode;
149
	inode->i_uid = sbi->options.fs_uid;
150
	inode->i_gid = sbi->options.fs_gid;
151
	inode->i_version++;
152
	inode->i_generation = get_seconds();
153
	
154
	if ((de->attr & ATTR_DIR) && !FATX_IS_FREE(de)) {
155
		inode->i_generation &= ~1;
156
		inode->i_mode = FATX_MKMODE(de->attr,S_IRWXUGO & 
157
			~sbi->options.fs_umask) | S_IFDIR;
158
		inode->i_op = sbi->dir_ops;
159
		inode->i_fop = &fatx_dir_operations;
160
161
		FATX_I(inode)->i_start = CF_LE_L(de->start);
162
		FATX_I(inode)->i_logstart = FATX_I(inode)->i_start;
163
		inode->i_nlink = fatx_subdirs(inode) + 2;
164
		    /* includes .., compensating for "self" */
165
#ifdef DEBUG
166
		if (!inode->i_nlink) {
167
			printk("directory %d: i_nlink == 0\n",inode->i_ino);
168
			inode->i_nlink = 1;
169
		}
170
#endif
171
		if ((nr = FATX_I(inode)->i_start) != 0)
172
			while (nr != -1) {
173
				inode->i_size += 1 << sbi->cluster_bits;
174
				if (!(nr = fatx_access(sb, nr, -1))) {
175
					printk("Directory %ld: bad FAT\n",
176
					    inode->i_ino);
177
					break;
178
				}
179
			}
180
		FATX_I(inode)->mmu_private = inode->i_size;
181
	} else { /* not a directory */
182
		inode->i_generation |= 1;
183
		inode->i_mode = FATX_MKMODE(de->attr,S_IRWXUGO & ~sbi->options.fs_umask) | S_IFREG;
184
		FATX_I(inode)->i_start = CF_LE_L(de->start);
185
		FATX_I(inode)->i_logstart = FATX_I(inode)->i_start;
186
		inode->i_size = CF_LE_L(de->size);
187
	        inode->i_op = &fatx_file_inode_operations;
188
	        inode->i_fop = &fatx_file_operations;
189
		inode->i_mapping->a_ops = &fatx_aops;
190
		FATX_I(inode)->mmu_private = inode->i_size;
191
	}
192
	FATX_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
193
	/* this is as close to the truth as we can get ... */
194
	inode->i_blksize = 1 << sbi->cluster_bits;
195
	inode->i_blocks = ((inode->i_size + inode->i_blksize - 1)
196
			   & ~(inode->i_blksize - 1)) >> 9;
197
	inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec =
198
		fatx_date_dos2unix(CF_LE_W(de->time),CF_LE_W(de->date));
199
	inode->i_ctime.tv_nsec = fatx_date_dos2unix(CF_LE_W(de->ctime),CF_LE_W(de->cdate));
200
}
201
202
struct inode *fatx_build_inode(	struct super_block *sb,	struct fatx_dir_entry *de, loff_t i_pos, int *res )
203
{
204
	struct inode *inode;
205
	*res = 0;
206
	inode = fatx_iget(sb, i_pos);
207
	if (inode)
208
		goto out;
209
	inode = new_inode(sb);
210
	*res = -ENOMEM;
211
	if (!inode)
212
		goto out;
213
	*res = 0;
214
	inode->i_ino = iunique(sb, FATX_ROOT_INO);
215
	inode->i_version = 1;
216
	fatx_fill_inode(inode, de);
217
	fatx_attach(inode, i_pos);
218
	insert_inode_hash(inode);
219
out:
220
	return inode;
221
}
222
223
/*
224
 * parse super block values out of FATX "boot block"
225
 * unlike the other FAT variants, much of the data is calculated from the
226
 * the partition information.
227
 */
228
int fatx_parse_boot_block ( struct super_block *sb, struct buffer_head *bh )
229
{
230
	struct fatx_boot_sector *b = (struct fatx_boot_sector *)bh->b_data;
231
	struct fatx_sb_info *sbi = FATX_SB(sb);
232
	int logical_sector_size, hard_blksize;
233
	unsigned int total_sectors;
234
	unsigned long cl_count;
235
	unsigned long fat_length;
236
237
	PRINTK("FATX: entered fatx_parse_boot_block\n");
238
	
239
	if (b->magic != FATX_BOOTBLOCK_MAGIC) {
240
		printk("FATX: boot block signature not found.  Not FATX?\n");
241
		return -1;
242
	}
243
		
244
	PRINTK("FATX: fatx_magic: %08lX\n",(unsigned long)b->magic);
245
			
246
	logical_sector_size = 512;
247
	
248
	sbi->cluster_size = CLUSTER_SIZE;
249
	
250
	PRINTK("FATX: cluster_size: %d\n",(int)sbi->cluster_size);
251
	
252
	//sb->s_block_size enters as hardware block (sector) size
253
	hard_blksize = sb->s_blocksize;
254
	sb->s_blocksize = logical_sector_size;
255
	sb->s_blocksize_bits = ffs(logical_sector_size) - 1;
256
257
	//figure total sector count
258
	//total_sectors = fatx_get_total_size(sb);
259
	total_sectors = sb->s_bdev->bd_inode->i_size >> 9;
260
	
261
	PRINTK("FATX: total_sectors for given device: %ld\n",(unsigned long)total_sectors);
262
	
263
	sbi->cluster_bits = 14;
264
	sbi->fats = 1;
265
	
266
	//hmm...fat should start right after boot block sectors (first 8)
267
	sbi->fat_start = 8;	//this might be: + CF_LE_W(b->fatx_unknown)
268
	sbi->root_cluster = 0;
269
	sbi->dir_per_block = logical_sector_size/sizeof(struct fatx_dir_entry);
270
	sbi->dir_per_block_bits = ffs(sbi->dir_per_block) - 1;
271
	sbi->dir_entries = 256;
272
	
273
	//check cluster count
274
	
275
	cl_count = total_sectors / sbi->cluster_size;
276
277
	if( cl_count >= 0xfff4 ) {
278
		//FATX-32
279
		sb->s_maxbytes = FATX32_MAX_NON_LFS;
280
		sbi->fat_bits = 32;
281
	} else {
282
		//FATX-16
283
		sb->s_maxbytes = FATX16_MAX_NON_LFS;
284
		sbi->fat_bits = 16;
285
	}
286
287
	fat_length = cl_count * (sbi->fat_bits>>3);		
288
	if(fat_length % 4096) {
289
		fat_length = ((fat_length / 4096) + 1) * 4096;
290
	}
291
	sbi->fat_length = fat_length / logical_sector_size;
292
293
	sbi->dir_start = sbi->fat_start + sbi->fat_length;
294
	sbi->data_start = sbi->dir_start + CLUSTER_SIZE;
295
	sbi->clusters = ((total_sectors-sbi->data_start) / sbi->cluster_size);
296
	sbi->free_clusters = -1; /* Don't know yet */
297
	
298
	PRINTK("FATX: logical_sector_size:	%d\n",(int)logical_sector_size);
299
	PRINTK("FATX: fat_length:		%d\n",(int)sbi->fat_length);
300
	PRINTK("FATX: spc_bits:			%d\n",sbi->fat_bits>>3);
301
	PRINTK("FATX: fat_start:		%d\n",(int)sbi->fat_start);
302
	PRINTK("FATX: dir_start:		%d\n",(int)sbi->dir_start);
303
	PRINTK("FATX: data_start:		%d\n",(int)sbi->data_start);
304
	PRINTK("FATX: clusters:			%ld\n",(unsigned long)sbi->clusters);
305
	PRINTK("FATX: fat_bits:			%d\n",(int)sbi->fat_bits);
306
	PRINTK("FATX: fat_length:		%d\n",(int)sbi->fat_length);
307
	PRINTK("FATX: root_dir_sectors:		%d\n",(int)CLUSTER_SIZE);
308
	PRINTK("FATX: dir_per_block:		%d\n",(int)sbi->dir_per_block);
309
	PRINTK("FATX: dir_per_block_bits:	%d\n",(int)sbi->dir_per_block_bits);
310
	PRINTK("FATX: dir_entries :		%d\n",(int)sbi->dir_entries);
311
	PRINTK("FATX: cluster_bits:		%d\n",(int)sbi->cluster_bits);
312
	
313
	PRINTK("FATX: leaving fatx_parse_boot_block\n");
314
		
315
	return 0;
316
}
317
318
static void fatx_read_root(struct inode *inode)
319
{
320
	struct super_block *sb = inode->i_sb;
321
	struct fatx_sb_info *sbi = FATX_SB(sb);
322
323
	INIT_LIST_HEAD(&FATX_I(inode)->i_fat_hash);
324
	FATX_I(inode)->i_pos = 0;
325
	FATX_I(inode)->i_fat_inode = inode;
326
	inode->i_uid = sbi->options.fs_uid;
327
	inode->i_gid = sbi->options.fs_gid;
328
	inode->i_version = 1;
329
	inode->i_generation = 0;
330
	inode->i_mode = (S_IRWXUGO & ~sbi->options.fs_umask) | S_IFDIR;
331
	inode->i_op = sbi->dir_ops;
332
	inode->i_fop = &fatx_dir_operations;
333
	
334
	FATX_I(inode)->i_start = FATX_ROOT_INO;
335
	inode->i_size = sbi->dir_entries * sizeof(struct fatx_dir_entry);
336
337
	inode->i_blksize = 1 << sbi->cluster_bits;
338
	inode->i_blocks = ((inode->i_size + inode->i_blksize - 1)
339
			   & ~(inode->i_blksize - 1)) >> 9;
340
	FATX_I(inode)->i_logstart = 0;
341
	FATX_I(inode)->mmu_private = inode->i_size;
342
343
	FATX_I(inode)->i_attrs = 0;
344
	inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = 0;
345
	inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = 0;
346
	FATX_I(inode)->i_ctime_ms = 0;
347
	inode->i_nlink = fatx_subdirs(inode) + 2;
348
}
349
350
/* The public inode operations for the fatx fs */
351
struct inode_operations fatx_dir_inode_operations = {
352
	.create		= fatx_create,
353
	.lookup		= fatx_lookup,
354
	.unlink		= fatx_unlink,
355
	.mkdir		= fatx_mkdir,
356
	.rmdir		= fatx_rmdir,
357
	.rename		= fatx_rename,
358
	.setattr	= fatx_notify_change,
359
};
360
361
void fatx_write_inode(struct inode *inode, int wait)
362
{
363
	struct super_block *sb = inode->i_sb;
364
	struct buffer_head *bh;
365
	struct fatx_dir_entry *raw_entry;
366
	unsigned int i_pos;
367
	
368
	PRINTK("FATX: fatx_write_inode: entered\n");
369
370
retry:
371
	i_pos = FATX_I(inode)->i_pos;
372
	if (inode->i_ino == FATX_ROOT_INO || !i_pos) {
373
		return;
374
	}
375
	lock_kernel();
376
	if (!(bh = sb_bread(sb, i_pos >> FATX_SB(sb)->dir_per_block_bits))) {
377
		PRINTK("dev = %s, ino = %d\n", sb->s_id, i_pos);
378
		fatx_fs_panic(sb, "fatx_write_inode: unable to read i-node block");
379
		unlock_kernel();
380
		return;
381
	}
382
	spin_lock(&fatx_inode_lock);
383
	if (i_pos != FATX_I(inode)->i_pos) {
384
		spin_unlock(&fatx_inode_lock);
385
		if(bh) brelse(bh);
386
		unlock_kernel();
387
		goto retry;
388
	}
389
390
	raw_entry = &((struct fatx_dir_entry *) (bh->b_data))
391
	    [i_pos & (FATX_SB(sb)->dir_per_block - 1)];
392
	if (S_ISDIR(inode->i_mode)) {
393
		raw_entry->attr = ATTR_DIR;
394
		raw_entry->size = 0;
395
	}
396
	else {
397
		raw_entry->attr = ATTR_NONE;
398
		raw_entry->size = CT_LE_L(inode->i_size);
399
	}
400
	raw_entry->attr |= FATX_MKATTR(inode->i_mode) |
401
	    FATX_I(inode)->i_attrs;
402
	raw_entry->start = CT_LE_L(FATX_I(inode)->i_logstart);
403
	
404
	PRINTK("FATX: fatx_write_inode: start == %08lX (LE=%08lX)\n",
405
			(long)FATX_I(inode)->i_logstart,
406
			(long)CT_LE_L(FATX_I(inode)->i_logstart));
407
	
408
	fatx_date_unix2dos(inode->i_mtime.tv_sec,&raw_entry->time,&raw_entry->date);
409
	raw_entry->time = CT_LE_W(raw_entry->time);
410
	raw_entry->date = CT_LE_W(raw_entry->date);
411
	
412
	fatx_date_unix2dos(inode->i_ctime.tv_sec,&raw_entry->ctime,&raw_entry->cdate);
413
	raw_entry->ctime = CT_LE_W(raw_entry->ctime);
414
	raw_entry->cdate = CT_LE_W(raw_entry->cdate);
415
	raw_entry->atime = CT_LE_W(raw_entry->ctime);
416
	raw_entry->adate = CT_LE_W(raw_entry->cdate);
417
	
418
	spin_unlock(&fatx_inode_lock);
419
	mark_buffer_dirty(bh);
420
	if(bh) brelse(bh);
421
	unlock_kernel();
422
	
423
	PRINTK("FATX: fatx_write_inode: leaving\n");
424
}
425
426
int fatx_statfs(struct super_block *sb,struct kstatfs *buf)
427
{
428
	int free,nr;
429
430
	lock_fatx(sb);
431
        if (FATX_SB(sb)->free_clusters != -1)
432
		free = FATX_SB(sb)->free_clusters;
433
	else {
434
		free = 0;
435
		for (nr = 2; nr < FATX_SB(sb)->clusters+2; nr++)
436
			if (!fatx_access(sb,nr,-1)) free++;
437
		FATX_SB(sb)->free_clusters = free;
438
	}
439
	unlock_fatx(sb);
440
	buf->f_type = sb->s_magic;
441
	buf->f_bsize = 1 << FATX_SB(sb)->cluster_bits;
442
	buf->f_blocks = FATX_SB(sb)->clusters;
443
	buf->f_bfree = free;
444
	buf->f_bavail = free;
445
	buf->f_namelen = FATX_MAX_NAME_LENGTH;
446
	return 0;
447
}
448
449
450
void fatx_delete_inode(struct inode *inode)
451
{
452
	if (!is_bad_inode(inode)) {
453
		lock_kernel();
454
		inode->i_size = 0;
455
		fatx_truncate(inode);
456
		unlock_kernel();
457
	}
458
	clear_inode(inode);
459
}
460
461
void fatx_clear_inode(struct inode *inode)
462
{
463
	if (is_bad_inode(inode))
464
		return;
465
	lock_kernel();
466
	spin_lock(&fatx_inode_lock);
467
	fatx_cache_inval_inode(inode);
468
	list_del(&FATX_I(inode)->i_fat_hash);
469
	spin_unlock(&fatx_inode_lock);
470
	unlock_kernel();
471
}
472
473
static struct super_operations fatx_sops = { 
474
	.write_inode	= fatx_write_inode,
475
	.delete_inode	= fatx_delete_inode,
476
	.put_super	= fatx_put_super,
477
	.statfs		= fatx_statfs,
478
	.clear_inode	= fatx_clear_inode,
479
	.read_inode	= make_bad_inode,
480
};
481
482
enum {
483
	Opt_uid, Opt_gid, Opt_umask, Opt_quiet, Opt_err,
484
};
485
486
static match_table_t fat_tokens = {
487
	{Opt_uid, "uid=%u"},
488
	{Opt_gid, "gid=%u"},
489
        {Opt_umask, "umask=%o"},
490
	{Opt_quiet, "quiet"},
491
	{Opt_err, NULL}
492
};
493
494
static int parse_options(char *options,struct fatx_mount_options *opts)
495
{
496
        char *p;
497
        substring_t args[MAX_OPT_ARGS];
498
        int option;
499
500
	opts->fs_uid = current->uid;
501
        opts->fs_gid = current->gid;
502
        opts->fs_umask = current->fs->umask;
503
504
	while ((p = strsep(&options, ",")) != NULL) {
505
		int token;
506
		if (!*p)
507
			continue;
508
		token = match_token(p, fat_tokens, args);
509
		switch(token) {
510
			case Opt_quiet:
511
				opts->quiet = 1;
512
				break;
513
			case Opt_uid:
514
				if (match_int(&args[0], &option))
515
					return 0;
516
				opts->fs_uid = option;
517
				break;
518
			case Opt_gid:
519
				if (match_int(&args[0], &option))
520
					return 0;
521
				opts->fs_gid = option;
522
				break;
523
			case Opt_umask:
524
				if (match_octal(&args[0], &option))
525
					return 0;
526
				opts->fs_umask = option;
527
				break;
528
			default:
529
				printk(KERN_ERR "FATX: Unrecognized mount option \"%s\" "
530
					"or missing value\n", p);
531
				return 0;
532
		}
533
	}
534
	return 1;
535
}
536
537
int fatx_fill_super(struct super_block *sb,void *data, int silent)
538
{
539
	struct inode *root_inode;
540
	struct buffer_head *bh;
541
	struct fatx_sb_info *sbi;
542
	int hard_blksize;
543
	int error;
544
545
	PRINTK("FATX: entering fatx_fill_super\n");
546
547
	sbi = kmalloc(sizeof(struct fatx_sb_info), GFP_KERNEL);
548
	if (!sbi)
549
		return -ENOMEM;
550
	sb->s_fs_info = sbi;
551
	memset(sbi, 0, sizeof(struct fatx_sb_info));
552
	sbi->private_data = NULL;
553
554
	sbi->dir_ops = &fatx_dir_inode_operations;
555
556
	sb->s_op = &fatx_sops;
557
558
	hard_blksize = 512;
559
560
	//store fat value parsed into fatx_bits...possibly overridden later
561
	sbi->fat_bits = 0;
562
	
563
	error = -EINVAL;
564
        if (!parse_options((char *) data, &(sbi->options)))
565
                goto out_fail;
566
	
567
	fatx_cache_init();
568
569
	error = -EIO;
570
571
	sb_min_blocksize(sb, 512);
572
//	sb_set_blocksize(sb, hard_blksize);
573
	bh = sb_bread(sb, 0);
574
	if (bh == NULL) {
575
		PRINTK("FATX: unable to read boot sector\n");
576
		goto out_fail;
577
	}
578
579
	// insert call(s) to superblock parsing
580
	error = fatx_parse_boot_block(sb,bh);
581
	brelse(bh);
582
583
	if (error)
584
		goto out_invalid;
585
586
	sb_set_blocksize(sb, sb->s_blocksize);
587
588
	sb->s_magic = FATX_BOOTBLOCK_MAGIC;
589
	/* set up enough so that it can read an inode */
590
	init_MUTEX(&sbi->fatx_lock);
591
	sbi->prev_free = 0;
592
593
	
594
	sbi->nls_io = NULL;
595
	if (! sbi->nls_io)
596
		sbi->nls_io = load_nls_default();
597
	
598
	root_inode = new_inode(sb);
599
	if (!root_inode)
600
		goto out_unload_nls;
601
	root_inode->i_ino = FATX_ROOT_INO;
602
	fatx_read_root(root_inode);
603
	insert_inode_hash(root_inode);
604
	sb->s_root = d_alloc_root(root_inode);
605
	if (!sb->s_root)
606
		goto out_no_root;
607
608
	PRINTK("FATX: leave fatx_fill_super\n");
609
	
610
	return 0;
611
612
out_no_root:
613
	PRINTK("FATX: get root inode failed\n");
614
	iput(root_inode);
615
out_unload_nls:
616
	unload_nls(sbi->nls_io);
617
	goto out_fail;
618
out_invalid:
619
	error = -EINVAL;
620
	if (!silent) {
621
		PRINTK("VFS: Can't find a valid FAT filesystem on dev %s.\n",
622
			sb->s_id);
623
	}
624
out_fail:
625
	if(sbi->private_data)
626
		kfree(sbi->private_data);
627
	sbi->private_data = NULL;
628
	kfree(sbi); 
629
	return error;
630
}
631
		
632
int fatx_notify_change(struct dentry * dentry, struct iattr * attr)
633
{
634
	struct super_block *sb = dentry->d_sb;
635
	struct inode *inode = dentry->d_inode;
636
	int error;
637
638
	/* FAT cannot truncate to a longer file */
639
	if (attr->ia_valid & ATTR_SIZE) {
640
		if (attr->ia_size > inode->i_size)
641
			return -EPERM;
642
	}
643
644
	error = inode_change_ok(inode, attr);
645
	if (error)
646
		return FATX_SB(sb)->options.quiet ? 0 : error;
647
648
	if (((attr->ia_valid & ATTR_UID) && 
649
	     (attr->ia_uid != FATX_SB(sb)->options.fs_uid)) ||
650
	    ((attr->ia_valid & ATTR_GID) && 
651
	     (attr->ia_gid != FATX_SB(sb)->options.fs_gid)) ||
652
	    ((attr->ia_valid & ATTR_MODE) &&
653
	     (attr->ia_mode & ~FATX_VALID_MODE)))
654
		error = -EPERM;
655
656
	if (error)
657
		return FATX_SB(sb)->options.quiet ? 0 : error;
658
659
	error = inode_setattr(inode, attr);
660
	if (error)
661
		return error;
662
663
	if (S_ISDIR(inode->i_mode))
664
		inode->i_mode |= S_IXUGO;
665
666
	inode->i_mode = ((inode->i_mode & S_IFMT) | ((((inode->i_mode & S_IRWXU
667
	    & ~FATX_SB(sb)->options.fs_umask) | S_IRUSR) >> 6)*S_IXUGO)) &
668
	    ~FATX_SB(sb)->options.fs_umask;
669
	return 0;
670
}
671
(-)linux-2.6.5.orig/fs/fatx/misc.c (+272 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/fatx/misc.c
3
 *
4
 *  Written 2003 by Edgar Hucek and Lehner Franz
5
 *
6
 */
7
8
#include <linux/fatx_fs.h>
9
#include <linux/sched.h>
10
#include <linux/kernel.h>
11
#include <linux/errno.h>
12
#include <linux/string.h>
13
#include <linux/stat.h>
14
#include <linux/time.h>
15
#include <linux/types.h>
16
17
#define PRINTK(format, args...) do { if (fatx_debug) printk( format, ##args ); } while(0)
18
19
/*
20
 * fatx_fs_panic reports a severe file system problem and sets the file system
21
 * read-only. The file system can be made writable again by remounting it.
22
 */
23
24
void fatx_fs_panic(struct super_block *s,const char *msg)
25
{
26
	int not_ro;
27
28
	not_ro = !(s->s_flags & MS_RDONLY);
29
	if (not_ro) s->s_flags |= MS_RDONLY;
30
	printk("Filesystem panic (dev %s).\n  %s\n", s->s_id, msg);
31
	if (not_ro)
32
		printk("  File system has been set read-only\n");
33
}
34
35
static int day_n[] = {  0, 31, 59, 90,120,151,181,212,243,273,304,334,0,0,0,0 };
36
		/*    Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
37
38
extern struct timezone sys_tz;
39
40
int fatx_date_dos2unix(unsigned short time,unsigned short date)
41
{
42
	int month,year,secs,days;
43
44
	/* first subtract and mask after that... Otherwise, if
45
	   date == 0, bad things happen */
46
	month=  ((date >> 5) - 1) & 15;
47
	year =  date >> 9;
48
	days =  (date & 31)-1+day_n[month]+(year/4)+(year+30)*365;
49
	//skipped and current leap years
50
	days += ((year & 3) == 0 && month < 2 ? 0 : 1) + 7; 
51
	
52
	secs =  (time & 31)*2;		//seconds into curr minute
53
	secs += 60*((time >> 5) & 63);	//minutes into curr hour
54
	secs += 3600*(time >> 11);	//hours into curr day
55
	secs += 86400*days;		//days (from 1.1.70)
56
	
57
	secs += sys_tz.tz_minuteswest*60;
58
	return secs;
59
}
60
61
62
/*
63
 * fat_add_cluster tries to allocate a new cluster and adds it to the
64
 * file represented by inode.
65
 */
66
int fatx_add_cluster(struct inode *inode)
67
{
68
	struct super_block *sb = inode->i_sb;
69
	int count, nr, limit, last, curr, file_cluster;
70
	int cluster_size = FATX_SB(sb)->cluster_size;
71
	int res = -ENOSPC;
72
	
73
	lock_fatx(sb);
74
75
	if (FATX_SB(sb)->free_clusters == 0) {
76
		unlock_fatx(sb);
77
		return res;
78
	}
79
	limit = FATX_SB(sb)->clusters;
80
	nr = limit; /* to keep GCC happy */
81
	for (count = 0; count < limit; count++) {
82
		nr = ((count + FATX_SB(sb)->prev_free) % limit) + 2;
83
		if (fatx_access(sb, nr, -1) == 0)
84
			break;
85
	}
86
	if (count >= limit) {
87
		FATX_SB(sb)->free_clusters = 0;
88
		unlock_fatx(sb);
89
		return res;
90
	}
91
	
92
	FATX_SB(sb)->prev_free = (count + FATX_SB(sb)->prev_free + 1) % limit;
93
	fatx_access(sb, nr, EOF_FAT(sb));
94
	if (FATX_SB(sb)->free_clusters != -1)
95
		FATX_SB(sb)->free_clusters--;
96
	
97
	unlock_fatx(sb);
98
	
99
	/* We must locate the last cluster of the file to add this
100
	   new one (nr) to the end of the link list (the FAT).
101
	   
102
	   Here file_cluster will be the number of the last cluster of the
103
	   file (before we add nr).
104
	   
105
	   last is the corresponding cluster number on the disk. We will
106
	   use last to plug the nr cluster. We will use file_cluster to
107
	   update the cache.
108
	*/
109
	last = file_cluster = 0;
110
	if ((curr = FATX_I(inode)->i_start) != 0) {
111
		fatx_cache_lookup(inode, INT_MAX, &last, &curr);
112
		file_cluster = last;
113
		while (curr && curr != -1){
114
			file_cluster++;
115
			if (!(curr = fatx_access(sb, last = curr,-1))) {
116
				fatx_fs_panic(sb, "File without EOF");
117
				return res;
118
			}
119
		}
120
	}
121
	if (last) {
122
		fatx_access(sb, last, nr);
123
		fatx_cache_add(inode, file_cluster, nr);
124
	} else {
125
		FATX_I(inode)->i_start = nr;
126
		FATX_I(inode)->i_logstart = nr;
127
		mark_inode_dirty(inode);
128
	}
129
	if (file_cluster
130
	    != inode->i_blocks / cluster_size / (sb->s_blocksize / 512)) {
131
		printk ("file_cluster badly computed!!! %d <> %ld\n",
132
			file_cluster,
133
			inode->i_blocks / cluster_size / (sb->s_blocksize / 512));
134
		fatx_cache_inval_inode(inode);
135
	}
136
	inode->i_blocks += (1 << FATX_SB(sb)->cluster_bits) / 512;
137
	return nr;
138
}
139
140
/* Convert linear UNIX date to a MS-DOS time/date pair. */
141
142
void fatx_date_unix2dos(int unix_date,unsigned short *time,
143
    unsigned short *date)
144
{
145
	int day,year,nl_day,month;
146
147
	unix_date -= sys_tz.tz_minuteswest*60;
148
149
	/* bound low end at Jan 1 GMT 00:00:00 2000. */
150
	if (unix_date < ((30 * 365) + 7) * 24 * 60 * 60) {
151
		unix_date = ((30 * 365) + 7) * 24 * 60 * 60;
152
	}
153
		
154
	*time = (unix_date % 60)/2 + 			//seconds
155
		(((unix_date/60) % 60) << 5) +		//minutes
156
		(((unix_date/3600) % 24) << 11);	//hours
157
	
158
	day = unix_date/86400-(30 * 365 + 7);		//days (from 1.1.2000)
159
	year = day/365;
160
	if ((year+3)/4+365*year > day) year--;
161
	day -= (year+3)/4+365*year;
162
	if (day == 59 && !(year & 3)) {
163
		nl_day = day;
164
		month = 2;
165
	}
166
	else {
167
		nl_day = (year & 3) || day <= 59 ? day : day-1;
168
		for (month = 0; month < 12; month++)
169
			if (day_n[month] > nl_day) break;
170
	}
171
	*date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9);
172
}
173
174
struct buffer_head *fatx_extend_dir(struct inode *inode)
175
{
176
	struct super_block *sb = inode->i_sb;
177
	int nr, sector, last_sector;
178
	struct buffer_head *bh, *res = NULL;
179
	int cluster_size = FATX_SB(sb)->cluster_size;
180
181
	if (inode->i_ino == FATX_ROOT_INO)
182
			return res;
183
184
	nr = fatx_add_cluster(inode);
185
	if (nr < 0)
186
		return res;
187
	
188
	sector = FATX_SB(sb)->data_start + (nr - 2) * cluster_size;
189
	last_sector = sector + cluster_size;
190
	for ( ; sector < last_sector; sector++) {
191
#ifdef DEBUG
192
		printk("zeroing sector %d\n", sector);
193
#endif
194
		if (!(bh = sb_getblk(sb, sector)))
195
			printk("getblk failed\n");
196
		else {
197
			memset(bh->b_data, 0xFF, sb->s_blocksize);
198
			set_buffer_uptodate(bh);
199
			mark_buffer_dirty(bh);
200
			if (!res)
201
				res = bh;
202
			else
203
				if(bh) brelse(bh);
204
		}
205
	}
206
	if (inode->i_size & (sb->s_blocksize - 1)) {
207
		fatx_fs_panic(sb, "Odd directory size");
208
		inode->i_size = (inode->i_size + sb->s_blocksize)
209
			& ~(sb->s_blocksize - 1);
210
	}
211
	inode->i_size += 1 << FATX_SB(sb)->cluster_bits;
212
	FATX_I(inode)->mmu_private += 1 << FATX_SB(sb)->cluster_bits;
213
	mark_inode_dirty(inode);
214
215
	return res;
216
}
217
218
/* Returns the inode number of the directory entry at offset pos. If bh is
219
   non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
220
   returned in bh.
221
   AV. Most often we do it item-by-item. Makes sense to optimize.
222
   AV. OK, there we go: if both bh and de are non-NULL we assume that we just
223
   AV. want the next entry (took one explicit de=NULL in vfat/namei.c).
224
   AV. It's done in fatx_get_entry() (inlined), here the slow case lives.
225
   AV. Additionally, when we return -1 (i.e. reached the end of directory)
226
   AV. we make bh NULL. 
227
 */
228
229
int fatx_get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
230
    struct fatx_dir_entry **de, loff_t *i_pos)
231
{
232
	struct super_block *sb = dir->i_sb;
233
	struct fatx_sb_info *sbi = FATX_SB(sb);
234
	int sector, offset;
235
236
	while (1) {
237
		offset = *pos;
238
		PRINTK("get_entry offset %d\n",offset);
239
		if (*bh)
240
			if(*bh) brelse(*bh);
241
		*bh = NULL;
242
		if ((sector = fatx_bmap(dir,offset >> sb->s_blocksize_bits)) == -1)
243
			return -1;
244
		PRINTK("FATX: get_entry sector %d %p\n",sector,*bh);
245
		PRINTK("FATX: get_entry sector apres brelse\n");
246
		if (!sector)
247
			return -1; /* beyond EOF */
248
		*pos += sizeof(struct fatx_dir_entry);
249
		if (!(*bh = sb_bread(sb, sector))) {
250
			printk("Directory sread (sector 0x%x) failed\n",sector);
251
			continue;
252
		}
253
		PRINTK("FATX: get_entry apres sread\n");
254
255
		offset &= sb->s_blocksize - 1;
256
		*de = (struct fatx_dir_entry *) ((*bh)->b_data + offset);
257
		*i_pos = (sector << sbi->dir_per_block_bits) + (offset >> FATX_DIR_BITS);
258
259
		return 0;
260
	}
261
}
262
263
void lock_fatx(struct super_block *sb)
264
{
265
	down(&(FATX_SB(sb)->fatx_lock));
266
}
267
268
void unlock_fatx(struct super_block *sb)
269
{
270
	up(&(FATX_SB(sb)->fatx_lock));
271
}
272
(-)linux-2.6.5.orig/fs/fatx/namei.c (+419 lines)
Line 0 Link Here
1
/*
2
 *  linux/fs/fatx/namei.c
3
 *
4
 *  Written 2003 by Edgar Hucek and Lehner Franz
5
 *
6
 */
7
8
#define __NO_VERSION__
9
#include <linux/module.h>
10
11
#include <linux/sched.h>
12
#include <linux/fatx_fs.h>
13
#include <linux/errno.h>
14
#include <linux/string.h>
15
16
#include <asm/uaccess.h>
17
18
#define PRINTK(format, args...) do { if (fatx_debug) printk( format, ##args ); } while(0)
19
20
/* Characters that are undesirable in an MS-DOS file name */
21
  
22
static char bad_chars[] = "*?<>|\";";
23
24
/*
25
 * Formats a FATX file name. Rejects invalid names. 
26
 */
27
28
static int fatx_format_name( const char *name,int len,char *out_name )
29
{
30
	int i;
31
	char trash[FATX_MAX_NAME_LENGTH];
32
33
	if (len > FATX_MAX_NAME_LENGTH) return -EINVAL;
34
	
35
	if (out_name == NULL) out_name = trash;
36
	
37
	memset(out_name,0xFF,FATX_MAX_NAME_LENGTH);
38
	
39
	//check for bad characters in name
40
	for(i=0; i<len; i++) {
41
		if (strchr(bad_chars,name[i])) return -EINVAL;
42
		out_name[i] = name[i];
43
	}
44
45
	return 0;
46
}
47
48
/*
49
 * Locates a directory entry.  Uses unformatted name. 
50
 */
51
52
static int fatx_find( struct inode *dir, const char *name, int len, struct buffer_head **bh, 
53
		struct fatx_dir_entry **de, loff_t *i_pos)
54
{
55
	//verify its a valid name
56
	if (fatx_format_name(name,len,NULL) < 0) return -ENOENT;
57
58
	PRINTK("FATX: fatx_find\n");
59
	
60
	//find the name in the directory
61
	return fatx_scan(dir,name,len,bh,de,i_pos);
62
63
}
64
65
/* 
66
 * Get inode using directory and name 
67
 */
68
69
struct dentry *fatx_lookup(struct inode *dir,struct dentry *dentry,struct nameidata *nd)
70
{
71
	struct super_block *sb = dir->i_sb;
72
	struct inode *inode = NULL;
73
	struct fatx_dir_entry *de;
74
	struct buffer_head *bh = NULL;
75
	loff_t i_pos;
76
	int res;
77
	
78
	PRINTK("FATX: fatx_lookup\n");
79
80
	res = fatx_find(dir, dentry->d_name.name, dentry->d_name.len, &bh,
81
			&de, &i_pos);
82
83
	if (res == -ENOENT)
84
		goto add;
85
	if (res < 0)
86
		goto out;
87
	inode = fatx_build_inode(sb, de, i_pos, &res);
88
	if (res)
89
		goto out;
90
add:
91
	d_add(dentry, inode);
92
	res = 0;
93
out:
94
	if (bh)
95
		brelse(bh);
96
	return ERR_PTR(res);
97
}
98
99
/* 
100
 * Creates a directory entry (name is already formatted). 
101
 */
102
103
static int fatx_add_entry(
104
		struct inode *dir, 
105
		const char *name,
106
		int len,
107
		struct buffer_head **bh,
108
		struct fatx_dir_entry **de,
109
		loff_t *i_pos,
110
		int is_dir )
111
{
112
	int res;
113
114
	if ((res = fatx_do_add_entry(dir, bh, de, i_pos))<0)
115
		return res;
116
	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
117
	mark_inode_dirty(dir);
118
	memset((*de)->name,0xFF,FATX_MAX_NAME_LENGTH);
119
	memcpy((*de)->name,name,len);
120
	(*de)->name_length = len;
121
	(*de)->attr = is_dir ? ATTR_DIR : ATTR_ARCH;
122
	(*de)->start = 0;
123
	fatx_date_unix2dos(dir->i_mtime.tv_sec,&(*de)->time,&(*de)->date);
124
	(*de)->size = 0;
125
	mark_buffer_dirty(*bh);
126
	return 0;
127
}
128
129
/* 
130
 * Create a file 
131
 */
132
133
int fatx_create(struct inode *dir,struct dentry *dentry,int mode, struct nameidata *nd)
134
{
135
	struct buffer_head *bh;
136
	struct fatx_dir_entry *de;
137
	struct inode *inode;
138
	loff_t i_pos;
139
	int res;
140
	const char *name = dentry->d_name.name;
141
	int name_length = dentry->d_name.len;
142
	char szFormatName[FATX_MAX_NAME_LENGTH];
143
	
144
	res = fatx_format_name(name,name_length,szFormatName);
145
	if (res < 0)
146
		return res;
147
	
148
	if (fatx_scan(dir,name,name_length,&bh,&de,&i_pos) >= 0) {
149
		if(bh) brelse(bh);
150
		return -EINVAL;
151
 	}
152
	inode = NULL;
153
	res = fatx_add_entry(dir, szFormatName, name_length, &bh, &de, &i_pos, 0);
154
	if (res)
155
		return res;
156
	inode = fatx_build_inode(dir->i_sb, de, i_pos, &res);
157
	if(bh) brelse(bh);
158
	if (!inode)
159
		return res;
160
	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
161
	mark_inode_dirty(inode);
162
	d_instantiate(dentry, inode);
163
	return 0;
164
}
165
166
/*
167
 * Remove a directory 
168
 */
169
170
int fatx_rmdir(struct inode *dir, struct dentry *dentry)
171
{
172
	struct inode *inode = dentry->d_inode;
173
	loff_t i_pos;	
174
	int res;
175
	struct buffer_head *bh;
176
	struct fatx_dir_entry *de;
177
178
	bh = NULL;
179
	res = fatx_find(dir, dentry->d_name.name, dentry->d_name.len,
180
				&bh, &de, &i_pos);
181
	if (res < 0)
182
		goto rmdir_done;
183
	/*
184
	 * Check whether the directory is not in use, then check
185
	 * whether it is empty.
186
	 */
187
	res = fatx_dir_empty(inode);
188
	if (res)
189
		goto rmdir_done;
190
191
	de->name_length = DELETED_FLAG;
192
	mark_buffer_dirty(bh);
193
	fatx_detach(inode);
194
	inode->i_nlink = 0;
195
	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
196
	dir->i_nlink--;
197
	mark_inode_dirty(inode);
198
	mark_inode_dirty(dir);
199
	res = 0;
200
201
rmdir_done:
202
	if(bh) brelse(bh);
203
	return res;
204
}
205
206
/*
207
 * Make a directory 
208
 */
209
210
int fatx_mkdir(struct inode *dir,struct dentry *dentry,int mode)
211
{
212
	struct buffer_head *bh;
213
	struct fatx_dir_entry *de;
214
	struct inode *inode;
215
	int res;
216
	const char *name = dentry->d_name.name;
217
	int name_length = dentry->d_name.len;
218
	loff_t i_pos;
219
	char szFormatName[FATX_MAX_NAME_LENGTH];
220
	
221
	res = fatx_format_name(name,name_length,szFormatName);
222
	if (res < 0)
223
		return res;
224
	if (fatx_scan(dir,name,name_length,&bh,&de,&i_pos) >= 0)
225
		goto out_exist;
226
227
	res = fatx_add_entry(dir, szFormatName, name_length, &bh, &de, &i_pos, 1);
228
	if (res)
229
		goto out_unlock;
230
	inode = fatx_build_inode(dir->i_sb, de, i_pos, &res);
231
	if (!inode) {
232
		if(bh) brelse(bh);
233
		goto out_unlock;
234
	}
235
	res = 0;
236
237
	dir->i_nlink++;
238
	inode->i_nlink = 2; /* no need to mark them dirty */
239
240
	res = fatx_new_dir(inode, dir);
241
	if (res)
242
		goto mkdir_error;
243
244
	if(bh) brelse(bh);
245
	d_instantiate(dentry, inode);
246
	res = 0;
247
248
out_unlock:
249
	return res;
250
251
mkdir_error:
252
	printk(KERN_WARNING "fatx_mkdir: error=%d, attempting cleanup\n", res);
253
	inode->i_nlink = 0;
254
	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
255
	dir->i_nlink--;
256
	mark_inode_dirty(inode);
257
	mark_inode_dirty(dir);
258
	de->name_length = DELETED_FLAG;
259
	mark_buffer_dirty(bh);
260
	if(bh) brelse(bh);
261
	fatx_detach(inode);
262
	iput(inode);
263
	goto out_unlock;
264
265
out_exist:
266
	if(bh) brelse(bh);
267
	res = -EINVAL;
268
	goto out_unlock;
269
}
270
271
/*
272
 * Unlink a file 
273
 */
274
275
int fatx_unlink( struct inode *dir, struct dentry *dentry)
276
{
277
	struct inode *inode = dentry->d_inode;
278
	loff_t i_pos;
279
	int res;
280
	struct buffer_head *bh;
281
	struct fatx_dir_entry *de;
282
283
	bh = NULL;
284
	res = fatx_find(dir, dentry->d_name.name, dentry->d_name.len,
285
			&bh, &de, &i_pos);
286
	if (res < 0)
287
		goto unlink_done;
288
289
	de->name_length = DELETED_FLAG;
290
	mark_buffer_dirty(bh);
291
	fatx_detach(inode);
292
	if(bh) brelse(bh);
293
	inode->i_nlink = 0;
294
	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
295
	mark_inode_dirty(inode);
296
	mark_inode_dirty(dir);
297
	res = 0;
298
unlink_done:
299
	return res;
300
}
301
302
static int do_fatx_rename(struct inode *old_dir, struct dentry *old_dentry,
303
		struct inode *new_dir, struct dentry *new_dentry,
304
		struct buffer_head *old_bh, struct fatx_dir_entry *old_de,
305
		int old_ino )
306
{
307
	struct buffer_head *new_bh=NULL,*dotdot_bh=NULL;
308
	struct fatx_dir_entry *new_de,*dotdot_de;
309
	struct inode *old_inode,*new_inode;
310
	loff_t new_ino;
311
	int error;
312
	int is_dir;
313
	const char *new_name = new_dentry->d_name.name;
314
	int new_name_len = new_dentry->d_name.len;
315
316
	PRINTK("FATX: do_fatx_rename: entered\n");
317
	
318
	old_inode = old_dentry->d_inode;
319
	new_inode = new_dentry->d_inode;
320
	is_dir = S_ISDIR(old_inode->i_mode);
321
322
	error = fatx_scan(new_dir,new_name,new_name_len,&new_bh,&new_de,&new_ino);
323
	if (error>=0 &&!new_inode)
324
		goto degenerate_case;
325
	if (!new_bh) {
326
		error = fatx_add_entry(	new_dir, new_name, new_name_len, &new_bh, 
327
				&new_de, &new_ino, is_dir );
328
		if (error)
329
			goto out;
330
	}
331
	new_dir->i_version++;
332
333
	/* There we go */
334
335
	if (new_inode)
336
		fatx_detach(new_inode);
337
	old_de->name_length = DELETED_FLAG;
338
	mark_buffer_dirty(old_bh);
339
	fatx_detach(old_inode);
340
	fatx_attach(old_inode, new_ino);
341
	FATX_I(old_inode)->i_attrs &= ~ATTR_HIDDEN;
342
	mark_inode_dirty(old_inode);
343
	old_dir->i_version++;
344
	old_dir->i_ctime = old_dir->i_mtime = old_dir->i_atime = CURRENT_TIME;
345
	mark_inode_dirty(old_dir);
346
	if (new_inode) {
347
		new_inode->i_nlink--;
348
		new_inode->i_ctime = new_inode->i_atime = CURRENT_TIME;
349
		mark_inode_dirty(new_inode);
350
	}
351
	if (dotdot_bh) {
352
		dotdot_de->start = CT_LE_L(FATX_I(new_dir)->i_logstart);
353
		
354
		PRINTK("FATX: do_fatx_rename: start = %08lX (LE=%08lX)\n",
355
				(long)FATX_I(new_dir)->i_logstart,
356
				(long)dotdot_de->start);
357
		
358
		mark_buffer_dirty(dotdot_bh);
359
		old_dir->i_nlink--;
360
		mark_inode_dirty(old_dir);
361
		if (new_inode) {
362
			new_inode->i_nlink--;
363
			mark_inode_dirty(new_inode);
364
		} else {
365
			new_dir->i_nlink++;
366
			mark_inode_dirty(new_dir);
367
		}
368
	}
369
	error = 0;
370
out:
371
	if(new_bh) brelse(new_bh);
372
	if(dotdot_bh) brelse(dotdot_bh);
373
	PRINTK("FATX: do_fatx_rename: leaving (normal)\n");
374
	return error;
375
376
degenerate_case:
377
	error = -EINVAL;
378
	if (new_de!=old_de)
379
		goto out;
380
	FATX_I(old_inode)->i_attrs &= ~ATTR_HIDDEN;
381
	mark_inode_dirty(old_inode);
382
	old_dir->i_version++;
383
	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
384
	mark_inode_dirty(old_dir);
385
	PRINTK("FATX: do_fatx_rename: leaving (degenerate)\n");
386
	return 0;
387
}
388
389
/*
390
 * Rename, a wrapper for rename_same_dir & rename_diff_dir 
391
 */
392
393
int fatx_rename(struct inode *old_dir,struct dentry *old_dentry,
394
		 struct inode *new_dir,struct dentry *new_dentry)
395
{
396
	struct buffer_head *old_bh;
397
	struct fatx_dir_entry *old_de;
398
	loff_t old_ino;
399
	int error;
400
401
	error = fatx_format_name(old_dentry->d_name.name,old_dentry->d_name.len,NULL);
402
	if (error < 0)
403
		goto rename_done;
404
	error = fatx_format_name(new_dentry->d_name.name,new_dentry->d_name.len,NULL);
405
	if (error < 0)
406
		goto rename_done;
407
408
	error = fatx_scan(old_dir, old_dentry->d_name.name, old_dentry->d_name.len,
409
			&old_bh, &old_de, &old_ino );
410
	if (error < 0)
411
		goto rename_done;
412
413
	error = do_fatx_rename( old_dir, old_dentry, new_dir, new_dentry,
414
			old_bh, old_de, (ino_t)old_ino );
415
	if(old_bh) brelse(old_bh);
416
417
rename_done:
418
	return error;
419
}
(-)linux-2.6.5.orig/fs/partitions/Kconfig (+8 lines)
Lines 233-236 Link Here
233
	  were partitioned using EFI GPT.  Presently only useful on the
233
	  were partitioned using EFI GPT.  Presently only useful on the
234
	  IA-64 platform.
234
	  IA-64 platform.
235
235
236
config XBOX_PARTITION
237
	bool "Xbox Partition support (EXPERIMENTAL)"
238
	depends on PARTITION_ADVANCED && EXPERIMENTAL && BROKEN
239
	help
240
	  Say Y here if you are running Linux on the Xbox, or would
241
	  like to access a hard disk partitioned for the Xbox under
242
	  a PC running Linux. Otherwise, say N.
243
236
#      define_bool CONFIG_ACORN_PARTITION_CUMANA y
244
#      define_bool CONFIG_ACORN_PARTITION_CUMANA y
(-)linux-2.6.5.orig/fs/partitions/Makefile (+1 lines)
Lines 18-20 Link Here
18
obj-$(CONFIG_IBM_PARTITION) += ibm.o
18
obj-$(CONFIG_IBM_PARTITION) += ibm.o
19
obj-$(CONFIG_EFI_PARTITION) += efi.o
19
obj-$(CONFIG_EFI_PARTITION) += efi.o
20
obj-$(CONFIG_NEC98_PARTITION) += nec98.o msdos.o
20
obj-$(CONFIG_NEC98_PARTITION) += nec98.o msdos.o
21
obj-$(CONFIG_XBOX_PARTITION) += xbox.o
(-)linux-2.6.5.orig/fs/partitions/check.c (+11 lines)
Lines 36-41 Link Here
36
#include "ibm.h"
36
#include "ibm.h"
37
#include "ultrix.h"
37
#include "ultrix.h"
38
#include "efi.h"
38
#include "efi.h"
39
#ifdef CONFIG_XBOX_PARTITION
40
#include "xbox.h"
41
#endif
39
42
40
#ifdef CONFIG_BLK_DEV_MD
43
#ifdef CONFIG_BLK_DEV_MD
41
extern void md_autodetect_dev(dev_t dev);
44
extern void md_autodetect_dev(dev_t dev);
Lines 190-195 Link Here
190
		memset(&state->parts, 0, sizeof(state->parts));
193
		memset(&state->parts, 0, sizeof(state->parts));
191
		res = check_part[i++](state, bdev);
194
		res = check_part[i++](state, bdev);
192
	}
195
	}
196
#ifdef CONFIG_XBOX_PARTITION
197
	{
198
		int xbox;
199
200
		xbox = xbox_partition(state, bdev);
201
		if(!res) res = xbox;
202
	}
203
#endif
193
	if (res > 0)
204
	if (res > 0)
194
		return state;
205
		return state;
195
	if (!res)
206
	if (!res)
(-)linux-2.6.5.orig/fs/partitions/xbox.c (+113 lines)
Line 0 Link Here
1
/*
2
 *  fs/partitions/xbox.c
3
 *
4
 *  //TODO: find and insert GPL notice
5
 *
6
 *  June 2002 by SpeedBump:	initial implementation
7
 */
8
9
#include <linux/errno.h>
10
#include <linux/genhd.h>
11
#include <linux/kernel.h>
12
13
#include "check.h"
14
#include "xbox.h"
15
16
17
/*
18
 * The native Xbox kernel makes use of an implicit partitioning
19
 * scheme. Partition locations and sizes on-disk are hard-coded.
20
 */
21
#define XBOX_CONFIG_START	0x00000000L
22
#define XBOX_CACHE1_START	0x00000400L
23
#define XBOX_CACHE2_START	0x00177400L
24
#define XBOX_CACHE3_START	0x002EE400L
25
#define XBOX_SYSTEM_START	0x00465400L
26
#define XBOX_DATA_START		0x0055F400L
27
#define XBOX_EXTEND_START	0x00EE8AB0L
28
29
#define XBOX_CONFIG_SIZE	(XBOX_CACHE1_START - XBOX_CONFIG_START)
30
#define XBOX_CACHE1_SIZE	(XBOX_CACHE2_START - XBOX_CACHE1_START)
31
#define XBOX_CACHE2_SIZE	(XBOX_CACHE3_START - XBOX_CACHE2_START)
32
#define XBOX_CACHE3_SIZE	(XBOX_SYSTEM_START - XBOX_CACHE3_START)
33
#define XBOX_SYSTEM_SIZE	(XBOX_DATA_START - XBOX_SYSTEM_START)
34
#define XBOX_DATA_SIZE		(XBOX_EXTEND_START - XBOX_DATA_START)
35
36
#define XBOX_MAGIC_SECT		3L
37
38
39
static int xbox_check_magic(struct block_device *bdev, sector_t at_sect,
40
		char *magic)
41
{
42
	Sector sect;
43
	char *data;
44
	int ret;
45
46
	data = read_dev_sector(bdev, at_sect, &sect);
47
	if (!data)
48
		return -1;
49
50
	/* Ick! */
51
	ret = (*(u32*)data == *(u32*)magic) ? 1 : 0;
52
	put_dev_sector(sect);
53
54
	return ret;
55
}
56
57
static inline int xbox_drive_detect(struct block_device *bdev)
58
{
59
	/** 
60
	* "BRFR" is apparently the magic number in the config area
61
	* the others are just paranoid checks to assure the expected
62
	* "FATX" tags for the other xbox partitions
63
	*
64
	* the odds against a non-xbox drive having random data to match is
65
	* astronomical...but it's possible I guess...you should only include
66
	* this check if you actually *have* an xbox drive...since it has to
67
	* be detected first
68
	*
69
	* @see check.c
70
	*/
71
	return (xbox_check_magic(bdev, XBOX_MAGIC_SECT, "BRFR") &&
72
		xbox_check_magic(bdev, XBOX_SYSTEM_START, "FATX") &&
73
		xbox_check_magic(bdev, XBOX_DATA_START, "FATX")) ?
74
		0 : -ENODEV;
75
}
76
77
int xbox_partition(struct parsed_partitions *state, struct block_device *bdev)
78
{
79
	int slot, err;
80
	sector_t last, size;
81
82
	err = xbox_drive_detect(bdev);
83
	if (err)
84
		return err;
85
86
	slot = 50;
87
	printk(" [xbox]");
88
89
	put_partition(state, slot++, XBOX_DATA_START, XBOX_DATA_SIZE);
90
	put_partition(state, slot++, XBOX_SYSTEM_START, XBOX_SYSTEM_SIZE);
91
	put_partition(state, slot++, XBOX_CACHE1_START, XBOX_CACHE1_SIZE);
92
	put_partition(state, slot++, XBOX_CACHE2_START, XBOX_CACHE2_SIZE);
93
	put_partition(state, slot++, XBOX_CACHE3_START, XBOX_CACHE3_SIZE);
94
95
	/*
96
	 * Xbox HDDs come in two sizes - 8GB and 10GB. The native Xbox kernel
97
	 * will only acknowledge the first 8GB, regardless of actual disk
98
	 * size. For disks larger than 8GB, anything above that limit is made
99
	 * available as a seperate partition.
100
	 */
101
	last = bdev->bd_disk->capacity;
102
	if (last == XBOX_EXTEND_START)
103
		goto out;
104
105
	printk(" <");
106
	size = last - XBOX_EXTEND_START;
107
	put_partition(state, slot++, XBOX_EXTEND_START, size);
108
	printk(" >");
109
110
out:
111
	printk("\n");
112
	return 1;
113
}
(-)linux-2.6.5.orig/fs/partitions/xbox.h (+6 lines)
Line 0 Link Here
1
/*
2
 *  fs/partitions/xbox.h
3
 */
4
5
int xbox_partition(struct parsed_partitions *state,
6
			struct block_device *bdev);
(-)linux-2.6.5.orig/include/asm-i386/mach-default/mach_pci_blacklist.h (+6 lines)
Line 0 Link Here
1
#ifndef __ASM_MACH_PCI_BLACKLIST_H
2
#define __ASM_MACH_PCI_BLACKLIST_H
3
4
#define mach_pci_is_blacklisted(bus,dev,fn) 0
5
6
#endif
(-)linux-2.6.5.orig/include/asm-i386/mach-xbox/mach_pci_blacklist.h (+14 lines)
Line 0 Link Here
1
#ifndef __ASM_MACH_PCI_BLACKLIST_H
2
#define __ASM_MACH_PCI_BLACKLIST_H
3
4
#include <linux/xbox.h>
5
6
static inline int mach_pci_is_blacklisted(int bus, int dev, int fn)
7
{
8
	if(machine_is_xbox) {
9
		return (bus > 1) || ((bus != 0) && ((dev != 0) || (fn != 0))) ||
10
			(!bus && !dev && ((fn == 1) || (fn == 2)));
11
	}
12
}
13
14
#endif
(-)linux-2.6.5.orig/include/asm-i386/mach-xbox/setup_arch_pre.h (+26 lines)
Line 0 Link Here
1
#ifndef _SETUP_PRE_XBOX_
2
#define _SETUP_PRE_XBOX_
3
4
/* Hook to call BIOS initialisation function */
5
6
/* no action for generic */
7
8
#define ARCH_SETUP arch_setup_xbox();
9
10
#include <linux/timex.h>
11
#include <asm/io.h>
12
13
//int CLOCK_TICK_RATE;
14
int machine_is_xbox __initdata = 0;
15
16
static  inline void arch_setup_xbox(void) {
17
	outl(0x80000000, 0xcf8);
18
	if (inl(0xcfc)==0x02a510de) { /* Xbox PCI 0:0:0 ID 0x10de/0x02a5 */
19
		machine_is_xbox = 1;
20
//		CLOCK_TICK_RATE = 1125000;
21
	} else {
22
//		CLOCK_TICK_RATE = 1193180;
23
	}
24
}
25
26
#endif
(-)linux-2.6.5.orig/include/asm-i386/timex.h (-5 / +5 lines)
Lines 11-22 Link Here
11
11
12
#ifdef CONFIG_X86_PC9800
12
#ifdef CONFIG_X86_PC9800
13
   extern int CLOCK_TICK_RATE;
13
   extern int CLOCK_TICK_RATE;
14
#elif defined(CONFIG_MELAN)
15
# define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */
16
#elif defined(CONFIG_X86_XBOX)
17
# define CLOCK_TICK_RATE 1125000
14
#else
18
#else
15
#ifdef CONFIG_X86_ELAN
19
# define CLOCK_TICK_RATE 1193182 /* Underlying HZ */
16
#  define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */
17
#else
18
#  define CLOCK_TICK_RATE 1193182 /* Underlying HZ */
19
#endif
20
#endif
20
#endif
21
21
22
#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
22
#define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
(-)linux-2.6.5.orig/include/linux/fatx_fs.h (+253 lines)
Line 0 Link Here
1
#ifndef _LINUX_FATX_FS_H
2
#define _LINUX_FATX_FS_H
3
4
/*
5
 *  The FATX filesystem constants/structures
6
 *
7
 */
8
9
#include <linux/fs.h>
10
#include <linux/buffer_head.h>
11
#include <asm/byteorder.h>
12
13
#define FATX_ROOT_INO  1 /* == MINIX_ROOT_INO */
14
15
#define FATX_CACHE    8 /* FAT cache size */
16
17
#define MSDOS_DOTDOT "..         " /* "..", padded to MSDOS_NAME chars */
18
19
#define FATX_ENT_FREE   (0)
20
#define FATX32_MAX_NON_LFS     ((1UL<<32) - 1)
21
#define FATX16_MAX_NON_LFS     ((1UL<<30) - 1)
22
	
23
#define CLUSTER_SIZE 32
24
#define ATTR_RO      1  /* read-only */
25
#define ATTR_HIDDEN  2  /* hidden */
26
#define ATTR_SYS     4  /* system */
27
#define ATTR_DIR     16 /* directory */
28
#define ATTR_ARCH    0  /* archived */
29
#define ATTR_UNUSED  (ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
30
31
#define ATTR_NONE    0 /* no attribute bits */
32
33
#define FATX_BOOTBLOCK_MAGIC cpu_to_le32(0x58544146)
34
#define FATX_MAX_NAME_LENGTH 42
35
#define FATX_DIR_BITS 6
36
37
#define DELETED_FLAG 0xe5 /* marks file as deleted when in name_length */
38
39
//FF == end of directory info, E5 == deleted entry
40
#define FATX_IS_FREE(de) ((de)->name_length==DELETED_FLAG)
41
#define FATX_END_OF_DIR(de) ((de)->name_length==0xFF)
42
43
#define IS_FREE(n) (!*(n) || *(const unsigned char *) (n) == DELETED_FLAG)
44
45
#define CF_LE_W(v) le16_to_cpu(v)
46
#define CF_LE_L(v) le32_to_cpu(v)
47
#define CT_LE_W(v) cpu_to_le16(v)
48
#define CT_LE_L(v) cpu_to_le32(v)
49
50
/* bad cluster mark */
51
#define BAD_FAT16 0xFFF7
52
#define BAD_FAT32 0x0FFFFFF7
53
#define BAD_FAT(s) (FATX_SB(s)->fat_bits == 32 ? BAD_FAT32 : BAD_FAT16)
54
55
#define EOC_FAT16 0xFFF8	// end of chain marker
56
#define EOC_FAT32 0xFFFFFFF8	// end of chain marker
57
#define EOF_FAT16 0xFFF8	// end of file marker
58
#define EOF_FAT32 0xFFFFFFF8	// end of file marker
59
#define EOF_FAT(s) (FATX_SB(s)->fat_bits == 32 ? EOF_FAT32 : EOF_FAT16)
60
61
#define FATX_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)
62
63
/* Convert attribute bits and a mask to the UNIX mode. */
64
#define FATX_MKMODE(a,m) (m & (a & ATTR_RO ? S_IRUGO|S_IXUGO : S_IRWXUGO))
65
66
/* Convert the UNIX mode to FATX attribute bits. */
67
#define FATX_MKATTR(m) ((m & S_IWUGO) ? ATTR_NONE : ATTR_RO)
68
69
struct fatx_boot_sector {
70
        __u32	magic;		/* "FATX" */
71
	__u32	volume_id;	/* Volume ID */
72
        __u32	cluster_size;	/* sectors/cluster */
73
	__u16	fats;		/* number of FATs */
74
	__u32	unknown;
75
};
76
77
struct fatx_dir_entry {
78
        __u8	name_length;	/* length of filename (bytes) */
79
	__u8	attr;		/* attribute bits */
80
        __s8	name[42];	/* filename */
81
	__u32	start;		/* first cluster */
82
	__u32	size;		/* file size (in bytes) */
83
	__u16	time,date;	/* time, date */
84
	__u16	ctime,cdate;	/* Creation time */
85
	__u16	atime,adate;	/* Last access time */
86
};
87
88
struct fatx_boot_fsinfo {
89
	__u32   signature1;	/* 0x41615252L */
90
	__u32   reserved1[120];	/* Nothing as far as I can tell */
91
	__u32   signature2;	/* 0x61417272L */
92
	__u32   free_clusters;	/* Free cluster count.  -1 if unknown */
93
	__u32   next_cluster;	/* Most recently allocated cluster.
94
				 * Unused under Linux. */
95
	__u32   reserved2[4];
96
};
97
98
struct fatx_cache {
99
	dev_t device; /* device number. 0 means unused. */
100
	int start_cluster; /* first cluster of the chain. */
101
	int file_cluster; /* cluster number in the file. */
102
	int disk_cluster; /* cluster number on disk. */
103
	struct fatx_cache *next; /* next cache entry */
104
};
105
106
#ifdef __KERNEL__
107
108
#include <linux/buffer_head.h>
109
#include <linux/string.h>
110
#include <linux/nls.h>
111
#include <linux/fatx_fs_i.h>
112
#include <linux/fatx_fs_sb.h>
113
#include <asm/statfs.h>
114
115
static inline struct fatx_sb_info *FATX_SB(struct super_block *sb)
116
{
117
	return sb->s_fs_info;
118
}
119
120
static inline struct fatx_inode_info *FATX_I(struct inode *inode)
121
{
122
	return container_of(inode, struct fatx_inode_info, vfs_inode);
123
}
124
125
/* fatx/cache.c */
126
extern int fatx_access(struct super_block *sb, int nr, int new_value);
127
extern unsigned long fatx_bmap(struct inode *inode,unsigned long sector);
128
extern void fatx_cache_init(void);
129
extern void fatx_cache_lookup(struct inode *inode, int cluster, int *f_clu,
130
			     int *d_clu);
131
extern void fatx_cache_add(struct inode *inode, int f_clu, int d_clu);
132
extern void fatx_cache_inval_inode(struct inode *inode);
133
extern void fatx_cache_inval_dev(dev_t device);
134
extern int fatx_get_cluster(struct inode *inode,int cluster);
135
extern int fatx_free(struct inode *inode, int skip);
136
extern void fatx_clusters_flush(struct super_block *sb);
137
138
/* fatx/dir.c */
139
extern struct file_operations fat_dir_operations;
140
extern int fatx_readdir(struct file *filp, void *dirent, filldir_t filldir);
141
extern int fatx_dir_empty(struct inode *dir);
142
extern int fatx_add_entries(struct inode *dir, int slots, struct buffer_head **bh,
143
			   struct fatx_dir_entry **de, loff_t *i_pos);
144
extern int fatx_new_dir(struct inode *dir, struct inode *parent);
145
146
/* fat/file.c */
147
extern struct file_operations fatx_file_operations;
148
extern struct inode_operations fatx_file_inode_operations;
149
extern ssize_t fatx_file_read(struct file *filp, char *buf, size_t count,
150
			     loff_t *ppos);
151
extern int fatx_get_block(struct inode *inode, sector_t iblock,
152
			 struct buffer_head *bh_result, int create);
153
extern ssize_t fatx_file_write(struct file *filp, const char __user *buf, size_t count,
154
			      loff_t *ppos);
155
extern void fatx_truncate(struct inode *inode);
156
157
/* fat/inode.c */
158
extern void fatx_hash_init(void);
159
extern void fatx_attach(struct inode *inode, loff_t i_pos);
160
extern void fatx_detach(struct inode *inode);
161
extern struct inode *fatx_iget(struct super_block *sb, loff_t i_pos);
162
extern struct inode *fatx_build_inode(
163
		struct super_block *sb,
164
		struct fatx_dir_entry *de, 
165
		loff_t i_pos, 
166
		int *res);
167
extern int fatx_fill_super(struct super_block *sb,void *data, int silent);
168
169
extern void fatx_delete_inode(struct inode *inode);
170
extern void fatx_clear_inode(struct inode *inode);
171
extern void fatx_put_super(struct super_block *sb);
172
173
typedef int (*fatx_boot_block_parse_func)(
174
		struct super_block *sb, 
175
		struct buffer_head *bh );
176
typedef void (*fatx_read_root_func)(struct inode *inode);
177
178
extern int fatx_statfs(struct super_block *sb, struct kstatfs *buf);
179
extern void fatx_write_inode(struct inode *inode, int wait);
180
extern int fatx_notify_change(struct dentry * dentry, struct iattr * attr);
181
182
extern struct address_space_operations fatx_aops;
183
extern spinlock_t fatx_inode_lock;
184
185
186
/* fatx/namei.c - these are for the xbox's FATX */
187
struct dentry *fatx_lookup(struct inode *dir,struct dentry *dentry, struct nameidata *nd);
188
extern int fatx_create(struct inode *dir, struct dentry *dentry, int mode, 
189
		struct nameidata *nd);
190
extern int fatx_rmdir(struct inode *dir, struct dentry *dentry);
191
extern int fatx_unlink(struct inode *dir, struct dentry *dentry);
192
extern int fatx_mkdir(struct inode *dir, struct dentry *dentry, int mode);
193
extern int fatx_rename(struct inode *old_dir, struct dentry *old_dentry,
194
		       struct inode *new_dir, struct dentry *new_dentry);
195
196
/* fatx/fatxfs_syms.c */
197
extern unsigned int fatx_debug;
198
199
extern struct file_system_type fatx_fs_type;
200
201
extern int fatx_get_entry(struct inode *dir,loff_t *pos,struct buffer_head **bh,
202
		struct fatx_dir_entry **de,loff_t *i_pos );
203
204
extern int fatx_scan(struct inode *dir, const char *name, int name_length,
205
		struct buffer_head **res_bh,struct fatx_dir_entry **res_de,
206
		loff_t *i_pos);
207
		
208
/* miscelaneous support code for fatx fs */
209
extern int fatx_date_dos2unix( unsigned short, unsigned short );
210
extern void fatx_date_unix2dos(int unix_date, unsigned short *time, unsigned short *date);
211
212
static inline unsigned char fatx_tolower(struct nls_table *t, unsigned char c)
213
{
214
	unsigned char nc = t->charset2lower[c];
215
216
	return nc ? nc : c;
217
}
218
219
static inline unsigned char fatx_toupper(struct nls_table *t, unsigned char c)
220
{
221
	unsigned char nc = t->charset2upper[c];
222
223
	return nc ? nc : c;
224
}
225
226
static inline int fatx_strnicmp(struct nls_table *t, const unsigned char *s1,
227
		const unsigned char *s2, int len )
228
{
229
	while(len--) {
230
		if (fatx_tolower(t, *s1++) != fatx_tolower(t, *s2++))
231
			return 1;
232
	}
233
	return 0;
234
}
235
236
/* directory code for fatx fs */
237
extern int fatx_do_add_entry(struct inode *dir,	struct buffer_head **bh,
238
		struct fatx_dir_entry **de, loff_t *i_pos);
239
		
240
extern int fatx_dir_empty(struct inode *dir);
241
extern int fatx_subdirs(struct inode *dir);
242
		
243
extern struct file_operations fatx_dir_operations;
244
#endif /* __KERNEL__ */
245
246
extern int fatx_access(struct super_block *sb, int nr, int new_value);
247
extern void fatx_fs_panic(struct super_block *s,const char *msg);
248
extern struct buffer_head *fatx_extend_dir(struct inode *inode);
249
extern int fatx_add_cluster(struct inode *inode);
250
extern void lock_fatx(struct super_block *sb);
251
extern void unlock_fatx(struct super_block *sb);
252
253
#endif /* _LINUX_FATX_FS_H */
(-)linux-2.6.5.orig/include/linux/fatx_fs_i.h (+26 lines)
Line 0 Link Here
1
#ifndef _FATX_FS_I
2
#define _FATX_FS_I
3
4
#include <linux/fs.h>
5
6
/*
7
 *  FATX file system inode data in memory
8
 */
9
10
struct fatx_inode_info {
11
	/* cache of lastest accessed cluster */
12
	int file_cluster;       /* cluster number in the file. */
13
	int disk_cluster;       /* cluster number on disk. */
14
	
15
	loff_t mmu_private;
16
	int i_start;	/* first cluster or 0 */
17
	int i_logstart;	/* logical first cluster */
18
	int i_attrs;	/* unused attribute bits */
19
	int i_ctime_ms;	/* unused change time in milliseconds */
20
	loff_t i_pos;   /* on-disk position of directory entry or 0 */
21
	struct inode *i_fat_inode;      /* struct inode of this one */
22
	struct list_head i_fat_hash;	/* hash by i_location */
23
	struct inode vfs_inode;
24
};
25
26
#endif
(-)linux-2.6.5.orig/include/linux/fatx_fs_sb.h (+51 lines)
Line 0 Link Here
1
#ifndef _FATX_FS_SB
2
#define _FATX_FS_SB
3
4
/*
5
 *  FATX file system in-core superblock data
6
 *
7
 *  Written 2003 by Edgar Hucek and Lehner Franz
8
 *
9
 */
10
11
struct fatx_mount_options {
12
	uid_t fs_uid;
13
	gid_t fs_gid;
14
	unsigned short fs_umask;
15
	unsigned short codepage;  /* Codepage for shortname conversions */
16
	unsigned short shortname; /* flags for shortname display/create rule */
17
	unsigned char name_check; /* r = relaxed, n = normal, s = strict */
18
	unsigned char conversion; /* b = binary, t = text, a = auto */
19
	unsigned quiet:1;         /* set = fake successful chmods and chowns */
20
};
21
22
#define FATX_CACHE_NR    8 /* number of FAT cache */
23
24
struct fatx_sb_info {
25
	unsigned short sec_per_clus; /* sectors/cluster */
26
	unsigned short cluster_bits; /* log2(cluster_size) */
27
	unsigned int cluster_size;   /* cluster size */
28
	unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */
29
	unsigned short fat_start;
30
	unsigned long fat_length;    /* FAT start & length (sec.) */
31
	unsigned long dir_start;
32
	unsigned short dir_entries;  /* root dir start & entries */
33
	unsigned long data_start;    /* first data sector */
34
	unsigned long clusters;      /* number of clusters */
35
	unsigned long root_cluster;  /* first cluster of the root directory */
36
	unsigned long fsinfo_sector; /* FAT32 fsinfo offset from start of disk */
37
	struct semaphore fatx_lock;
38
	int prev_free;               /* previously returned free cluster number */
39
	int free_clusters;           /* -1 if undefined */
40
	struct fatx_mount_options options;
41
	struct nls_table *nls_disk;  /* Codepage used on disk */
42
	struct nls_table *nls_io;    /* Charset used for input and display */
43
	void *dir_ops;		     /* Opaque; default directory operations */
44
	void *private_data;
45
	int dir_per_block;	     /* dir entries per block */
46
	int dir_per_block_bits;	     /* log2(dir_per_block) */
47
48
	spinlock_t cache_lock;
49
};
50
51
#endif
(-)linux-2.6.5.orig/include/linux/pci_ids.h (+1 lines)
Lines 1095-1100 Link Here
1095
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL	0x0258
1095
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL	0x0258
1096
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL	0x0259
1096
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL	0x0259
1097
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL	0x025B
1097
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL	0x025B
1098
#define PCI_DEVICE_ID_NVIDIA_IGEFORCE3		0x02a0
1098
1099
1099
#define PCI_VENDOR_ID_IMS		0x10e0
1100
#define PCI_VENDOR_ID_IMS		0x10e0
1100
#define PCI_DEVICE_ID_IMS_8849		0x8849
1101
#define PCI_DEVICE_ID_IMS_8849		0x8849
(-)linux-2.6.5.orig/include/linux/xbox.h (+135 lines)
Line 0 Link Here
1
#ifndef _XBOX_H_
2
#define _XBOX_H_
3
4
#define XBOX_SMB_IO_BASE 0xC000
5
#define XBOX_SMB_HOST_ADDRESS       (0x4 + XBOX_SMB_IO_BASE)
6
#define XBOX_SMB_HOST_COMMAND       (0x8 + XBOX_SMB_IO_BASE)
7
#define XBOX_SMB_HOST_DATA          (0x6 + XBOX_SMB_IO_BASE)
8
#define XBOX_SMB_GLOBAL_ENABLE       (0x2 + XBOX_SMB_IO_BASE)
9
#define XBOX_GE_CYC_TYPE_MASK (7)
10
#define XBOX_BYTE_DATA    0x02
11
12
#define XBOX_SMC_ADDRESS 0x10
13
#define XBOX_TV_ADDRESS 0x45
14
15
#define SMC_CMD_POWER 0x02
16
#define SMC_CMD_TRAY_STATE 0x03
17
#define SMC_CMD_AV_PACK 0x04
18
#define SMC_CMD_LED_MODE 0x07
19
#define SMC_CMD_LED_REGISTER 0x08
20
#define SMC_CMD_EJECT 0x0C
21
#define SMC_CMD_INTERRUPT_RESPOND 0x0D
22
#define SMC_CMD_INTERRUPT_REASON 0x11
23
#define SMC_CMD_RESET_ON_EJECT 0x19
24
#define SMC_CMD_SCRATCH_REGISTER 0x1B
25
// I think commands 20 and 21 are used for bootup authentication, but
26
// I don't know those commands.  The CROM people know.
27
//
28
#define SMC_SUBCMD_POWER_RESET 0x01
29
#define SMC_SUBCMD_POWER_CYCLE 0x40
30
#define SMC_SUBCMD_POWER_OFF 0x80
31
//
32
#define SMC_SUBCMD_RESPOND_CONTINUE 0x04
33
//
34
// These are from recent posts to this list (except MISSING)
35
#define SMC_VALUE_AV_SCART 0x00
36
#define SMC_VALUE_AV_HDTV 0x01
37
#define SMC_VALUE_AV_VGA 0x02
38
#define SMC_VALUE_AV_RFU 0x03
39
#define SMC_VALUE_AV_SVIDEO 0x04
40
#define SMC_VALUE_AV_STANDARD 0x06
41
#define SMC_VALUE_AV_UNDEFINED 0x05
42
#define SMC_VALUE_AV_MISSING 0x07
43
//
44
#define SMC_SUBCMD_LED_MODE_DEFAULT 0x00
45
#define SMC_SUBCMD_LED_MODE_CUSTOM 0x01
46
47
#define SMC_SUBCMD_EJECT_EJECT 0x00
48
#define SMC_SUBCMD_EJECT_LOAD 0x01
49
50
// Bits 01...40 all have meaning but I don't know them all.
51
#define SMC_VALUE_INTERRUPT_POWER_BUTTON 0x01
52
#define SMC_VALUE_INTERRUPT_AV_REMOVED 0x10
53
#define SMC_VALUE_INTERRUPT_EJECT_BUTTON 0x20
54
55
#define SMC_SUBCMD_RESET_ON_EJECT_ENABLE 0x00
56
#define SMC_SUBCMD_RESET_ON_EJECT_DISABLE 0x01
57
58
// These are defined by the *kernel*, not the SMC.
59
#define SMC_SCRATCH_EJECT_AFTER_BOOT 0x01
60
#define SMC_SCRATCH_DISPLAY_ERROR 0x02
61
#define SMC_SCRATCH_NO_ANIMATION 0x04
62
#define SMC_SCRATCH_RUN_DASHBOARD 0x08
63
64
/* interrupt causes */
65
#define POWERDOWN_MASK (1<<0)
66
#define TRAYCLOSED_MASK (1<<1)
67
#define TRAYOPENING_MASK (1<<2)
68
#define AVPLUGGED_MASK (1<<3)
69
#define AVUNPLUGGED_MASK (1<<4)
70
#define TRAYBUTTON_MASK (1<<5)
71
#define TRAYCLOSING_MASK (1<<6)
72
#define UNKNOWN_MASK (1<<7)
73
74
extern int machine_is_xbox;
75
76
#define XBOX_I2C_IO_BASE 0xc000
77
static inline void Xbox_SMC_write(u8 d1,u8 d2) {
78
	int c=4;
79
	u8 b=0;
80
	u32 dwSpinsToLive = 0x8000000;
81
82
	/*
83
	while(inw(XBOX_I2C_IO_BASE+0)&0x0800);
84
	*/
85
	while(c--) {
86
		outb(XBOX_SMC_ADDRESS<<1, XBOX_SMB_HOST_ADDRESS);
87
		outb((u8)d1, XBOX_SMB_HOST_COMMAND);
88
		outb((u8)d2, XBOX_SMB_HOST_DATA);
89
		outw(0xffff, XBOX_I2C_IO_BASE+0);
90
		outb(0x0a, XBOX_SMB_GLOBAL_ENABLE);
91
		{
92
			while((b !=0x10) && ((b&0x26)==0) && (dwSpinsToLive--)) {
93
				b=inb(XBOX_I2C_IO_BASE);
94
			}
95
			if(b&0x2) continue;
96
			if(b&0x24) continue;
97
			if(!(b&0x10)) continue;
98
			break;
99
		}
100
	}
101
}
102
103
static inline int Xbox_SMC_read(u8 d) {
104
        int c=4;
105
	u8 b=0;
106
	u32 dwSpinsToLive = 0x8000000;
107
	
108
	/*
109
	while(inw(XBOX_I2C_IO_BASE+0)&0x0800);
110
	*/
111
        while(c--) {
112
		outb((XBOX_SMC_ADDRESS<<1)|1, XBOX_SMB_HOST_ADDRESS);
113
                outb(d, XBOX_SMB_HOST_COMMAND);
114
                outw(0xffff, XBOX_I2C_IO_BASE+0);
115
                outb(0x0a, XBOX_SMB_GLOBAL_ENABLE);
116
		{
117
			while((b !=0x10) && ((b&0x26)==0) && (dwSpinsToLive--)) {
118
				b=inb(XBOX_I2C_IO_BASE);
119
			}
120
			if(b&0x2) continue;
121
			if(b&0x24) continue;
122
			if(!(b&0x10)) continue;
123
			break;	
124
		}
125
	}
126
	return (int)inb(XBOX_SMB_HOST_DATA);
127
}
128
129
#define Xbox_tray_load() Xbox_SMC_write(SMC_CMD_EJECT, SMC_SUBCMD_EJECT_LOAD);
130
#define Xbox_tray_eject() Xbox_SMC_write(SMC_CMD_EJECT, SMC_SUBCMD_EJECT_EJECT);
131
132
#define Xbox_power_off() Xbox_SMC_write(SMC_CMD_POWER, SMC_SUBCMD_POWER_OFF);
133
#define Xbox_reset() Xbox_SMC_write(SMC_CMD_POWER, SMC_SUBCMD_POWER_RESET);
134
135
#endif /* _XBOX_H_ */
(-)linux-2.6.5.orig/include/linux/xboxfbctl.h (+66 lines)
Line 0 Link Here
1
/*
2
 * linux/include/video/xboxfbctl.h
3
 * - Type definitions for ioctls of Xbox video driver
4
 *
5
 * Maintainer: Oliver Schwartz <Oliver.Schwartz@gmx.de>
6
 *
7
 * Contributors:
8
 *
9
 * This file is subject to the terms and conditions of the GNU General Public
10
 * License.  See the file COPYING in the main directory of this archive
11
 * for more details.
12
 *
13
 * Known bugs and issues:
14
 *
15
 *      none
16
 */
17
18
#ifndef xbofbctl_h
19
#define xbofbctl_h
20
21
typedef enum enumVideoStandards {
22
	TV_ENC_INVALID=-1,
23
	TV_ENC_NTSC=0,
24
	TV_ENC_NTSC60,
25
	TV_ENC_PALBDGHI,
26
	TV_ENC_PALN,
27
	TV_ENC_PALNC,
28
	TV_ENC_PALM,
29
	TV_ENC_PAL60
30
} xbox_tv_encoding;
31
32
typedef enum enumAvTypes {
33
	AV_INVALID=-1,
34
	AV_SCART_RGB,
35
	AV_SVIDEO,
36
	AV_VGA_SOG,
37
	AV_HDTV,
38
	AV_COMPOSITE,
39
	AV_VGA
40
} xbox_av_type;
41
42
typedef enum enumEncoderType {
43
	ENCODER_CONEXANT,
44
	ENCODER_FOCUS
45
} xbox_encoder_type;
46
47
typedef struct _xboxOverscan {
48
	double hoc;
49
	double voc;
50
} xbox_overscan;
51
52
typedef struct _xboxFbConfig {
53
	xbox_av_type av_type;
54
	xbox_encoder_type encoder_type;
55
} xboxfb_config;
56
57
#define FBIO_XBOX_GET_OVERSCAN  _IOR('x', 1, xbox_overscan)
58
/* in param: double  hoc (0.0-0.2), double voc (0.0 - 0.2) */
59
#define FBIO_XBOX_SET_OVERSCAN  _IOW('x', 2, xbox_overscan)
60
61
#define FBIO_XBOX_GET_TV_ENCODING  _IOR('x', 3, xbox_tv_encoding)
62
#define FBIO_XBOX_SET_TV_ENCODING  _IOW('x', 4, xbox_tv_encoding)
63
64
#define FBIO_XBOX_GET_CONFIG  _IOR('x', 5, xboxfb_config)
65
66
#endif
(-)linux-2.6.5.orig/kernel.config (+1250 lines)
Line 0 Link Here
1
#
2
# Automatically generated make config: don't edit
3
#
4
CONFIG_X86=y
5
CONFIG_MMU=y
6
CONFIG_UID16=y
7
CONFIG_GENERIC_ISA_DMA=y
8
9
#
10
# Code maturity level options
11
#
12
CONFIG_EXPERIMENTAL=y
13
# CONFIG_CLEAN_COMPILE is not set
14
# CONFIG_STANDALONE is not set
15
CONFIG_BROKEN=y
16
CONFIG_BROKEN_ON_SMP=y
17
18
#
19
# General setup
20
#
21
CONFIG_SWAP=y
22
CONFIG_SYSVIPC=y
23
CONFIG_BSD_PROCESS_ACCT=y
24
CONFIG_SYSCTL=y
25
CONFIG_LOG_BUF_SHIFT=14
26
# CONFIG_HOTPLUG is not set
27
CONFIG_IKCONFIG=y
28
CONFIG_IKCONFIG_PROC=y
29
CONFIG_EMBEDDED=y
30
# CONFIG_KALLSYMS is not set
31
CONFIG_FUTEX=y
32
CONFIG_EPOLL=y
33
# CONFIG_IOSCHED_NOOP is not set
34
# CONFIG_IOSCHED_AS is not set
35
CONFIG_IOSCHED_DEADLINE=y
36
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
37
38
#
39
# Loadable module support
40
#
41
CONFIG_MODULES=y
42
CONFIG_MODULE_UNLOAD=y
43
CONFIG_MODULE_FORCE_UNLOAD=y
44
CONFIG_OBSOLETE_MODPARM=y
45
# CONFIG_MODVERSIONS is not set
46
CONFIG_KMOD=y
47
48
#
49
# Processor type and features
50
#
51
# CONFIG_X86_PC is not set
52
# CONFIG_X86_ELAN is not set
53
CONFIG_X86_XBOX=y
54
# CONFIG_X86_VOYAGER is not set
55
# CONFIG_X86_NUMAQ is not set
56
# CONFIG_X86_SUMMIT is not set
57
# CONFIG_X86_BIGSMP is not set
58
# CONFIG_X86_VISWS is not set
59
# CONFIG_X86_GENERICARCH is not set
60
# CONFIG_X86_ES7000 is not set
61
# CONFIG_M386 is not set
62
# CONFIG_M486 is not set
63
# CONFIG_M586 is not set
64
# CONFIG_M586TSC is not set
65
# CONFIG_M586MMX is not set
66
# CONFIG_M686 is not set
67
# CONFIG_MPENTIUMII is not set
68
CONFIG_MPENTIUMIII=y
69
# CONFIG_MPENTIUMM is not set
70
# CONFIG_MPENTIUM4 is not set
71
# CONFIG_MK6 is not set
72
# CONFIG_MK7 is not set
73
# CONFIG_MK8 is not set
74
# CONFIG_MELAN is not set
75
# CONFIG_MCRUSOE is not set
76
# CONFIG_MWINCHIPC6 is not set
77
# CONFIG_MWINCHIP2 is not set
78
# CONFIG_MWINCHIP3D is not set
79
# CONFIG_MCYRIXIII is not set
80
# CONFIG_MVIAC3_2 is not set
81
CONFIG_X86_GENERIC=y
82
CONFIG_X86_CMPXCHG=y
83
CONFIG_X86_XADD=y
84
CONFIG_X86_L1_CACHE_SHIFT=7
85
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
86
CONFIG_X86_WP_WORKS_OK=y
87
CONFIG_X86_INVLPG=y
88
CONFIG_X86_BSWAP=y
89
CONFIG_X86_POPAD_OK=y
90
CONFIG_X86_GOOD_APIC=y
91
CONFIG_X86_INTEL_USERCOPY=y
92
CONFIG_X86_USE_PPRO_CHECKSUM=y
93
CONFIG_HPET_TIMER=y
94
# CONFIG_HPET_EMULATE_RTC is not set
95
# CONFIG_PREEMPT is not set
96
# CONFIG_X86_UP_APIC is not set
97
CONFIG_XBOX_EJECT=y
98
CONFIG_X86_TSC=y
99
# CONFIG_X86_MCE is not set
100
# CONFIG_TOSHIBA is not set
101
# CONFIG_I8K is not set
102
# CONFIG_MICROCODE is not set
103
# CONFIG_X86_MSR is not set
104
# CONFIG_X86_CPUID is not set
105
# CONFIG_EDD is not set
106
CONFIG_NOHIGHMEM=y
107
# CONFIG_HIGHMEM4G is not set
108
# CONFIG_HIGHMEM64G is not set
109
# CONFIG_MATH_EMULATION is not set
110
CONFIG_MTRR=y
111
# CONFIG_REGPARM is not set
112
113
#
114
# Power management options (ACPI, APM)
115
#
116
# CONFIG_PM is not set
117
118
#
119
# ACPI (Advanced Configuration and Power Interface) Support
120
#
121
# CONFIG_ACPI is not set
122
123
#
124
# CPU Frequency scaling
125
#
126
# CONFIG_CPU_FREQ is not set
127
128
#
129
# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
130
#
131
CONFIG_PCI=y
132
# CONFIG_PCI_GOBIOS is not set
133
# CONFIG_PCI_GOMMCONFIG is not set
134
CONFIG_PCI_GODIRECT=y
135
# CONFIG_PCI_GOANY is not set
136
CONFIG_PCI_DIRECT=y
137
# CONFIG_PCI_LEGACY_PROC is not set
138
# CONFIG_PCI_NAMES is not set
139
# CONFIG_ISA is not set
140
# CONFIG_SCx200 is not set
141
142
#
143
# Executable file formats
144
#
145
CONFIG_BINFMT_ELF=y
146
CONFIG_BINFMT_AOUT=m
147
CONFIG_BINFMT_MISC=m
148
149
#
150
# Device Drivers
151
#
152
153
#
154
# Generic Driver Options
155
#
156
157
#
158
# Memory Technology Devices (MTD)
159
#
160
# CONFIG_MTD is not set
161
162
#
163
# Parallel port support
164
#
165
# CONFIG_PARPORT is not set
166
167
#
168
# Plug and Play support
169
#
170
171
#
172
# Block devices
173
#
174
# CONFIG_BLK_DEV_FD is not set
175
# CONFIG_BLK_CPQ_DA is not set
176
# CONFIG_BLK_CPQ_CISS_DA is not set
177
# CONFIG_BLK_DEV_DAC960 is not set
178
# CONFIG_BLK_DEV_UMEM is not set
179
CONFIG_BLK_DEV_LOOP=m
180
CONFIG_BLK_DEV_CRYPTOLOOP=m
181
CONFIG_BLK_DEV_NBD=m
182
CONFIG_BLK_DEV_RAM=y
183
CONFIG_BLK_DEV_RAM_SIZE=4096
184
CONFIG_BLK_DEV_INITRD=y
185
# CONFIG_LBD is not set
186
187
#
188
# ATA/ATAPI/MFM/RLL support
189
#
190
CONFIG_IDE=y
191
CONFIG_BLK_DEV_IDE=y
192
193
#
194
# Please see Documentation/ide.txt for help/info on IDE drives
195
#
196
# CONFIG_BLK_DEV_HD_IDE is not set
197
CONFIG_BLK_DEV_IDEDISK=y
198
# CONFIG_IDEDISK_MULTI_MODE is not set
199
# CONFIG_IDEDISK_STROKE is not set
200
CONFIG_BLK_DEV_IDECD=y
201
# CONFIG_BLK_DEV_IDETAPE is not set
202
# CONFIG_BLK_DEV_IDEFLOPPY is not set
203
# CONFIG_BLK_DEV_IDESCSI is not set
204
# CONFIG_IDE_TASK_IOCTL is not set
205
# CONFIG_IDE_TASKFILE_IO is not set
206
207
#
208
# IDE chipset support/bugfixes
209
#
210
CONFIG_IDE_GENERIC=y
211
# CONFIG_BLK_DEV_CMD640 is not set
212
CONFIG_BLK_DEV_IDEPCI=y
213
CONFIG_IDEPCI_SHARE_IRQ=y
214
# CONFIG_BLK_DEV_OFFBOARD is not set
215
CONFIG_BLK_DEV_GENERIC=y
216
# CONFIG_BLK_DEV_OPTI621 is not set
217
# CONFIG_BLK_DEV_RZ1000 is not set
218
CONFIG_BLK_DEV_IDEDMA_PCI=y
219
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
220
CONFIG_IDEDMA_PCI_AUTO=y
221
# CONFIG_IDEDMA_ONLYDISK is not set
222
CONFIG_BLK_DEV_ADMA=y
223
# CONFIG_BLK_DEV_AEC62XX is not set
224
# CONFIG_BLK_DEV_ALI15X3 is not set
225
CONFIG_BLK_DEV_AMD74XX=y
226
# CONFIG_BLK_DEV_CMD64X is not set
227
# CONFIG_BLK_DEV_TRIFLEX is not set
228
# CONFIG_BLK_DEV_CY82C693 is not set
229
# CONFIG_BLK_DEV_CS5520 is not set
230
# CONFIG_BLK_DEV_CS5530 is not set
231
# CONFIG_BLK_DEV_HPT34X is not set
232
# CONFIG_BLK_DEV_HPT366 is not set
233
# CONFIG_BLK_DEV_SC1200 is not set
234
# CONFIG_BLK_DEV_PIIX is not set
235
# CONFIG_BLK_DEV_NS87415 is not set
236
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
237
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
238
# CONFIG_BLK_DEV_SVWKS is not set
239
# CONFIG_BLK_DEV_SIIMAGE is not set
240
# CONFIG_BLK_DEV_SIS5513 is not set
241
# CONFIG_BLK_DEV_SLC90E66 is not set
242
# CONFIG_BLK_DEV_TRM290 is not set
243
# CONFIG_BLK_DEV_VIA82CXXX is not set
244
CONFIG_BLK_DEV_IDEDMA=y
245
# CONFIG_IDEDMA_IVB is not set
246
CONFIG_IDEDMA_AUTO=y
247
# CONFIG_DMA_NONPCI is not set
248
# CONFIG_BLK_DEV_HD is not set
249
250
#
251
# SCSI device support
252
#
253
CONFIG_SCSI=m
254
CONFIG_SCSI_PROC_FS=y
255
256
#
257
# SCSI support type (disk, tape, CD-ROM)
258
#
259
CONFIG_BLK_DEV_SD=m
260
CONFIG_CHR_DEV_ST=m
261
CONFIG_CHR_DEV_OSST=m
262
CONFIG_BLK_DEV_SR=m
263
CONFIG_BLK_DEV_SR_VENDOR=y
264
CONFIG_CHR_DEV_SG=m
265
266
#
267
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
268
#
269
CONFIG_SCSI_MULTI_LUN=y
270
CONFIG_SCSI_REPORT_LUNS=y
271
# CONFIG_SCSI_CONSTANTS is not set
272
# CONFIG_SCSI_LOGGING is not set
273
274
#
275
# SCSI low-level drivers
276
#
277
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
278
# CONFIG_SCSI_ACARD is not set
279
# CONFIG_SCSI_AACRAID is not set
280
# CONFIG_SCSI_AIC7XXX is not set
281
# CONFIG_SCSI_AIC7XXX_OLD is not set
282
# CONFIG_SCSI_AIC79XX is not set
283
# CONFIG_SCSI_DPT_I2O is not set
284
# CONFIG_SCSI_ADVANSYS is not set
285
# CONFIG_SCSI_MEGARAID is not set
286
# CONFIG_SCSI_SATA is not set
287
# CONFIG_SCSI_BUSLOGIC is not set
288
# CONFIG_SCSI_CPQFCTS is not set
289
# CONFIG_SCSI_DMX3191D is not set
290
# CONFIG_SCSI_EATA is not set
291
# CONFIG_SCSI_EATA_PIO is not set
292
# CONFIG_SCSI_FUTURE_DOMAIN is not set
293
# CONFIG_SCSI_GDTH is not set
294
# CONFIG_SCSI_IPS is not set
295
# CONFIG_SCSI_INITIO is not set
296
# CONFIG_SCSI_INIA100 is not set
297
# CONFIG_SCSI_SYM53C8XX_2 is not set
298
# CONFIG_SCSI_PCI2000 is not set
299
# CONFIG_SCSI_PCI2220I is not set
300
# CONFIG_SCSI_QLOGIC_ISP is not set
301
# CONFIG_SCSI_QLOGIC_FC is not set
302
# CONFIG_SCSI_QLOGIC_1280 is not set
303
CONFIG_SCSI_QLA2XXX=m
304
# CONFIG_SCSI_QLA21XX is not set
305
# CONFIG_SCSI_QLA22XX is not set
306
# CONFIG_SCSI_QLA2300 is not set
307
# CONFIG_SCSI_QLA2322 is not set
308
# CONFIG_SCSI_QLA6312 is not set
309
# CONFIG_SCSI_QLA6322 is not set
310
# CONFIG_SCSI_DC395x is not set
311
# CONFIG_SCSI_DC390T is not set
312
# CONFIG_SCSI_NSP32 is not set
313
# CONFIG_SCSI_DEBUG is not set
314
315
#
316
# Multi-device support (RAID and LVM)
317
#
318
CONFIG_MD=y
319
# CONFIG_BLK_DEV_MD is not set
320
CONFIG_BLK_DEV_DM=m
321
# CONFIG_DM_CRYPT is not set
322
323
#
324
# Fusion MPT device support
325
#
326
# CONFIG_FUSION is not set
327
328
#
329
# IEEE 1394 (FireWire) support
330
#
331
# CONFIG_IEEE1394 is not set
332
333
#
334
# I2O device support
335
#
336
# CONFIG_I2O is not set
337
338
#
339
# Macintosh device drivers
340
#
341
342
#
343
# Networking support
344
#
345
CONFIG_NET=y
346
347
#
348
# Networking options
349
#
350
CONFIG_PACKET=m
351
CONFIG_PACKET_MMAP=y
352
CONFIG_NETLINK_DEV=m
353
CONFIG_UNIX=m
354
# CONFIG_NET_KEY is not set
355
CONFIG_INET=y
356
CONFIG_IP_MULTICAST=y
357
CONFIG_IP_ADVANCED_ROUTER=y
358
CONFIG_IP_MULTIPLE_TABLES=y
359
CONFIG_IP_ROUTE_NAT=y
360
CONFIG_IP_ROUTE_MULTIPATH=y
361
CONFIG_IP_ROUTE_TOS=y
362
CONFIG_IP_ROUTE_VERBOSE=y
363
# CONFIG_IP_PNP is not set
364
# CONFIG_NET_IPIP is not set
365
# CONFIG_NET_IPGRE is not set
366
# CONFIG_IP_MROUTE is not set
367
# CONFIG_ARPD is not set
368
# CONFIG_INET_ECN is not set
369
# CONFIG_SYN_COOKIES is not set
370
# CONFIG_INET_AH is not set
371
# CONFIG_INET_ESP is not set
372
# CONFIG_INET_IPCOMP is not set
373
CONFIG_IPV6=m
374
CONFIG_IPV6_PRIVACY=y
375
# CONFIG_INET6_AH is not set
376
# CONFIG_INET6_ESP is not set
377
# CONFIG_INET6_IPCOMP is not set
378
# CONFIG_IPV6_TUNNEL is not set
379
# CONFIG_DECNET is not set
380
# CONFIG_BRIDGE is not set
381
# CONFIG_NETFILTER is not set
382
383
#
384
# SCTP Configuration (EXPERIMENTAL)
385
#
386
CONFIG_IPV6_SCTP__=m
387
# CONFIG_IP_SCTP is not set
388
# CONFIG_ATM is not set
389
# CONFIG_VLAN_8021Q is not set
390
# CONFIG_LLC2 is not set
391
# CONFIG_IPX is not set
392
# CONFIG_ATALK is not set
393
# CONFIG_X25 is not set
394
# CONFIG_LAPB is not set
395
# CONFIG_NET_DIVERT is not set
396
# CONFIG_ECONET is not set
397
# CONFIG_WAN_ROUTER is not set
398
# CONFIG_NET_FASTROUTE is not set
399
# CONFIG_NET_HW_FLOWCONTROL is not set
400
401
#
402
# QoS and/or fair queueing
403
#
404
# CONFIG_NET_SCHED is not set
405
406
#
407
# Network testing
408
#
409
# CONFIG_NET_PKTGEN is not set
410
CONFIG_NETDEVICES=y
411
412
#
413
# ARCnet devices
414
#
415
# CONFIG_ARCNET is not set
416
CONFIG_DUMMY=m
417
# CONFIG_BONDING is not set
418
# CONFIG_EQUALIZER is not set
419
# CONFIG_TUN is not set
420
CONFIG_ETHERTAP=m
421
422
#
423
# Ethernet (10 or 100Mbit)
424
#
425
CONFIG_NET_ETHERNET=y
426
CONFIG_MII=m
427
# CONFIG_HAPPYMEAL is not set
428
# CONFIG_SUNGEM is not set
429
# CONFIG_NET_VENDOR_3COM is not set
430
431
#
432
# Tulip family network device support
433
#
434
# CONFIG_NET_TULIP is not set
435
# CONFIG_HP100 is not set
436
CONFIG_NET_PCI=y
437
CONFIG_PCNET32=m
438
# CONFIG_AMD8111_ETH is not set
439
# CONFIG_ADAPTEC_STARFIRE is not set
440
# CONFIG_B44 is not set
441
CONFIG_FORCEDETH=m
442
# CONFIG_DGRS is not set
443
# CONFIG_EEPRO100 is not set
444
# CONFIG_E100 is not set
445
# CONFIG_FEALNX is not set
446
# CONFIG_NATSEMI is not set
447
# CONFIG_NE2K_PCI is not set
448
# CONFIG_8139CP is not set
449
# CONFIG_8139TOO is not set
450
# CONFIG_SIS900 is not set
451
# CONFIG_EPIC100 is not set
452
# CONFIG_SUNDANCE is not set
453
# CONFIG_TLAN is not set
454
# CONFIG_VIA_RHINE is not set
455
456
#
457
# Ethernet (1000 Mbit)
458
#
459
# CONFIG_ACENIC is not set
460
# CONFIG_DL2K is not set
461
# CONFIG_E1000 is not set
462
# CONFIG_NS83820 is not set
463
# CONFIG_HAMACHI is not set
464
# CONFIG_YELLOWFIN is not set
465
# CONFIG_R8169 is not set
466
# CONFIG_SIS190 is not set
467
# CONFIG_SK98LIN is not set
468
# CONFIG_TIGON3 is not set
469
470
#
471
# Ethernet (10000 Mbit)
472
#
473
# CONFIG_IXGB is not set
474
# CONFIG_FDDI is not set
475
# CONFIG_HIPPI is not set
476
# CONFIG_PPP is not set
477
# CONFIG_SLIP is not set
478
479
#
480
# Wireless LAN (non-hamradio)
481
#
482
# CONFIG_NET_RADIO is not set
483
484
#
485
# Token Ring devices
486
#
487
# CONFIG_TR is not set
488
# CONFIG_NET_FC is not set
489
# CONFIG_RCPCI is not set
490
# CONFIG_SHAPER is not set
491
492
#
493
# Wan interfaces
494
#
495
# CONFIG_WAN is not set
496
497
#
498
# Amateur Radio support
499
#
500
# CONFIG_HAMRADIO is not set
501
502
#
503
# IrDA (infrared) support
504
#
505
# CONFIG_IRDA is not set
506
507
#
508
# Bluetooth support
509
#
510
# CONFIG_BT is not set
511
512
#
513
# ISDN subsystem
514
#
515
# CONFIG_ISDN is not set
516
517
#
518
# Telephony Support
519
#
520
# CONFIG_PHONE is not set
521
522
#
523
# Input device support
524
#
525
CONFIG_INPUT=y
526
527
#
528
# Userland interfaces
529
#
530
CONFIG_INPUT_MOUSEDEV=y
531
CONFIG_INPUT_MOUSEDEV_PSAUX=y
532
CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
533
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=576
534
CONFIG_INPUT_JOYDEV=m
535
# CONFIG_INPUT_TSDEV is not set
536
CONFIG_INPUT_EVDEV=m
537
# CONFIG_INPUT_EVBUG is not set
538
539
#
540
# Input I/O drivers
541
#
542
# CONFIG_GAMEPORT is not set
543
CONFIG_SOUND_GAMEPORT=y
544
CONFIG_SERIO=y
545
CONFIG_SERIO_I8042=y
546
CONFIG_SERIO_SERPORT=m
547
# CONFIG_SERIO_CT82C710 is not set
548
CONFIG_SERIO_PCIPS2=m
549
550
#
551
# Input Device Drivers
552
#
553
CONFIG_INPUT_KEYBOARD=y
554
CONFIG_KEYBOARD_ATKBD=y
555
# CONFIG_KEYBOARD_SUNKBD is not set
556
# CONFIG_KEYBOARD_XTKBD is not set
557
# CONFIG_KEYBOARD_NEWTON is not set
558
CONFIG_INPUT_MOUSE=y
559
CONFIG_MOUSE_PS2=m
560
CONFIG_MOUSE_SERIAL=m
561
# CONFIG_INPUT_JOYSTICK is not set
562
# CONFIG_INPUT_TOUCHSCREEN is not set
563
CONFIG_INPUT_MISC=y
564
CONFIG_INPUT_PCSPKR=m
565
CONFIG_INPUT_UINPUT=m
566
567
#
568
# Character devices
569
#
570
CONFIG_VT=y
571
CONFIG_VT_CONSOLE=y
572
CONFIG_HW_CONSOLE=y
573
# CONFIG_SERIAL_NONSTANDARD is not set
574
575
#
576
# Serial drivers
577
#
578
CONFIG_SERIAL_8250=m
579
CONFIG_SERIAL_8250_NR_UARTS=4
580
# CONFIG_SERIAL_8250_EXTENDED is not set
581
582
#
583
# Non-8250 serial port support
584
#
585
CONFIG_SERIAL_CORE=m
586
CONFIG_UNIX98_PTYS=y
587
CONFIG_LEGACY_PTYS=y
588
CONFIG_LEGACY_PTY_COUNT=256
589
590
#
591
# Mice
592
#
593
CONFIG_BUSMOUSE=m
594
# CONFIG_QIC02_TAPE is not set
595
596
#
597
# IPMI
598
#
599
# CONFIG_IPMI_HANDLER is not set
600
601
#
602
# Watchdog Cards
603
#
604
# CONFIG_WATCHDOG is not set
605
# CONFIG_HW_RANDOM is not set
606
# CONFIG_NVRAM is not set
607
CONFIG_RTC=m
608
CONFIG_GEN_RTC=m
609
CONFIG_GEN_RTC_X=y
610
# CONFIG_DTLK is not set
611
# CONFIG_R3964 is not set
612
# CONFIG_APPLICOM is not set
613
# CONFIG_SONYPI is not set
614
615
#
616
# Ftape, the floppy tape device driver
617
#
618
CONFIG_FTAPE=m
619
CONFIG_ZFTAPE=m
620
CONFIG_ZFT_DFLT_BLK_SZ=10240
621
622
#
623
# The compressor will be built as a module only!
624
#
625
CONFIG_ZFT_COMPRESSOR=m
626
CONFIG_FT_NR_BUFFERS=3
627
CONFIG_FT_PROC_FS=y
628
CONFIG_FT_NORMAL_DEBUG=y
629
# CONFIG_FT_FULL_DEBUG is not set
630
# CONFIG_FT_NO_TRACE is not set
631
# CONFIG_FT_NO_TRACE_AT_ALL is not set
632
633
#
634
# Hardware configuration
635
#
636
CONFIG_FT_STD_FDC=y
637
# CONFIG_FT_MACH2 is not set
638
# CONFIG_FT_PROBE_FC10 is not set
639
# CONFIG_FT_ALT_FDC is not set
640
CONFIG_FT_FDC_THR=8
641
CONFIG_FT_FDC_MAX_RATE=2000
642
CONFIG_FT_ALPHA_CLOCK=0
643
CONFIG_AGP=m
644
# CONFIG_AGP_ALI is not set
645
# CONFIG_AGP_ATI is not set
646
# CONFIG_AGP_AMD is not set
647
# CONFIG_AGP_AMD64 is not set
648
# CONFIG_AGP_INTEL is not set
649
CONFIG_AGP_NVIDIA=m
650
# CONFIG_AGP_SIS is not set
651
# CONFIG_AGP_SWORKS is not set
652
# CONFIG_AGP_VIA is not set
653
# CONFIG_AGP_EFFICEON is not set
654
CONFIG_DRM=y
655
# CONFIG_DRM_TDFX is not set
656
# CONFIG_DRM_GAMMA is not set
657
# CONFIG_DRM_R128 is not set
658
# CONFIG_DRM_RADEON is not set
659
# CONFIG_DRM_MGA is not set
660
# CONFIG_DRM_SIS is not set
661
# CONFIG_MWAVE is not set
662
CONFIG_RAW_DRIVER=m
663
CONFIG_MAX_RAW_DEVS=256
664
CONFIG_HANGCHECK_TIMER=m
665
666
#
667
# I2C support
668
#
669
CONFIG_I2C=y
670
CONFIG_I2C_CHARDEV=y
671
672
#
673
# I2C Algorithms
674
#
675
CONFIG_I2C_ALGOBIT=m
676
CONFIG_I2C_ALGOPCF=m
677
678
#
679
# I2C Hardware Bus support
680
#
681
# CONFIG_I2C_ALI1535 is not set
682
# CONFIG_I2C_ALI15X3 is not set
683
CONFIG_I2C_AMD756=m
684
CONFIG_I2C_XBOX=y
685
# CONFIG_I2C_AMD8111 is not set
686
# CONFIG_I2C_ELV is not set
687
# CONFIG_I2C_I801 is not set
688
# CONFIG_I2C_I810 is not set
689
# CONFIG_I2C_ISA is not set
690
CONFIG_I2C_NFORCE2=m
691
# CONFIG_I2C_PARPORT_LIGHT is not set
692
# CONFIG_I2C_PIIX4 is not set
693
# CONFIG_I2C_PROSAVAGE is not set
694
# CONFIG_I2C_SAVAGE4 is not set
695
# CONFIG_SCx200_ACB is not set
696
# CONFIG_I2C_SIS5595 is not set
697
# CONFIG_I2C_SIS630 is not set
698
# CONFIG_I2C_SIS96X is not set
699
# CONFIG_I2C_VELLEMAN is not set
700
# CONFIG_I2C_VIA is not set
701
# CONFIG_I2C_VIAPRO is not set
702
# CONFIG_I2C_VOODOO3 is not set
703
704
#
705
# I2C Hardware Sensors Chip support
706
#
707
CONFIG_I2C_SENSOR=m
708
CONFIG_SENSORS_ADM1021=m
709
# CONFIG_SENSORS_ASB100 is not set
710
# CONFIG_SENSORS_EEPROM is not set
711
# CONFIG_SENSORS_FSCHER is not set
712
# CONFIG_SENSORS_GL518SM is not set
713
# CONFIG_SENSORS_IT87 is not set
714
# CONFIG_SENSORS_LM75 is not set
715
# CONFIG_SENSORS_LM78 is not set
716
# CONFIG_SENSORS_LM83 is not set
717
# CONFIG_SENSORS_LM85 is not set
718
# CONFIG_SENSORS_LM90 is not set
719
# CONFIG_SENSORS_VIA686A is not set
720
# CONFIG_SENSORS_W83781D is not set
721
# CONFIG_SENSORS_W83L785TS is not set
722
# CONFIG_I2C_DEBUG_CORE is not set
723
# CONFIG_I2C_DEBUG_BUS is not set
724
# CONFIG_I2C_DEBUG_CHIP is not set
725
726
#
727
# Misc devices
728
#
729
# CONFIG_IBM_ASM is not set
730
731
#
732
# Multimedia devices
733
#
734
# CONFIG_VIDEO_DEV is not set
735
736
#
737
# Digital Video Broadcasting Devices
738
#
739
# CONFIG_DVB is not set
740
741
#
742
# Graphics support
743
#
744
CONFIG_FB=y
745
# CONFIG_FB_CIRRUS is not set
746
# CONFIG_FB_PM2 is not set
747
# CONFIG_FB_CYBER2000 is not set
748
# CONFIG_FB_IMSTT is not set
749
# CONFIG_FB_VGA16 is not set
750
# CONFIG_FB_VESA is not set
751
CONFIG_VIDEO_SELECT=y
752
# CONFIG_FB_HGA is not set
753
# CONFIG_FB_RIVA is not set
754
CONFIG_FB_XBOX=y
755
# CONFIG_FB_MATROX is not set
756
# CONFIG_FB_RADEON_OLD is not set
757
# CONFIG_FB_RADEON is not set
758
# CONFIG_FB_ATY128 is not set
759
# CONFIG_FB_ATY is not set
760
# CONFIG_FB_SIS is not set
761
# CONFIG_FB_NEOMAGIC is not set
762
# CONFIG_FB_KYRO is not set
763
# CONFIG_FB_3DFX is not set
764
# CONFIG_FB_VOODOO1 is not set
765
# CONFIG_FB_TRIDENT is not set
766
# CONFIG_FB_PM3 is not set
767
# CONFIG_FB_VIRTUAL is not set
768
769
#
770
# Console display driver support
771
#
772
CONFIG_VGA_CONSOLE=y
773
# CONFIG_MDA_CONSOLE is not set
774
CONFIG_DUMMY_CONSOLE=y
775
CONFIG_FRAMEBUFFER_CONSOLE=y
776
CONFIG_PCI_CONSOLE=y
777
CONFIG_FONTS=y
778
CONFIG_FONT_8x8=y
779
CONFIG_FONT_8x16=y
780
# CONFIG_FONT_6x11 is not set
781
# CONFIG_FONT_PEARL_8x8 is not set
782
# CONFIG_FONT_ACORN_8x8 is not set
783
# CONFIG_FONT_MINI_4x6 is not set
784
# CONFIG_FONT_SUN8x16 is not set
785
# CONFIG_FONT_SUN12x22 is not set
786
787
#
788
# Logo configuration
789
#
790
CONFIG_LOGO=y
791
CONFIG_LOGO_LINUX_MONO=y
792
CONFIG_LOGO_LINUX_VGA16=y
793
CONFIG_LOGO_LINUX_CLUT224=y
794
795
#
796
# Sound
797
#
798
CONFIG_SOUND=m
799
800
#
801
# Advanced Linux Sound Architecture
802
#
803
CONFIG_SND=m
804
CONFIG_SND_SEQUENCER=m
805
CONFIG_SND_SEQ_DUMMY=m
806
CONFIG_SND_OSSEMUL=y
807
CONFIG_SND_MIXER_OSS=m
808
CONFIG_SND_PCM_OSS=m
809
CONFIG_SND_SEQUENCER_OSS=y
810
CONFIG_SND_RTCTIMER=m
811
# CONFIG_SND_VERBOSE_PRINTK is not set
812
# CONFIG_SND_DEBUG is not set
813
814
#
815
# Generic devices
816
#
817
CONFIG_SND_DUMMY=m
818
CONFIG_SND_VIRMIDI=m
819
CONFIG_SND_MTPAV=m
820
CONFIG_SND_SERIAL_U16550=m
821
CONFIG_SND_MPU401=m
822
823
#
824
# PCI devices
825
#
826
# CONFIG_SND_ALI5451 is not set
827
# CONFIG_SND_AZT3328 is not set
828
# CONFIG_SND_BT87X is not set
829
# CONFIG_SND_CS46XX is not set
830
# CONFIG_SND_CS4281 is not set
831
# CONFIG_SND_EMU10K1 is not set
832
# CONFIG_SND_KORG1212 is not set
833
# CONFIG_SND_NM256 is not set
834
# CONFIG_SND_RME32 is not set
835
# CONFIG_SND_RME96 is not set
836
# CONFIG_SND_RME9652 is not set
837
# CONFIG_SND_HDSP is not set
838
# CONFIG_SND_TRIDENT is not set
839
# CONFIG_SND_YMFPCI is not set
840
# CONFIG_SND_ALS4000 is not set
841
# CONFIG_SND_CMIPCI is not set
842
# CONFIG_SND_ENS1370 is not set
843
# CONFIG_SND_ENS1371 is not set
844
# CONFIG_SND_ES1938 is not set
845
# CONFIG_SND_ES1968 is not set
846
# CONFIG_SND_MAESTRO3 is not set
847
# CONFIG_SND_FM801 is not set
848
# CONFIG_SND_ICE1712 is not set
849
# CONFIG_SND_ICE1724 is not set
850
CONFIG_SND_INTEL8X0=m
851
# CONFIG_SND_SONICVIBES is not set
852
# CONFIG_SND_VIA82XX is not set
853
# CONFIG_SND_VX222 is not set
854
855
#
856
# ALSA USB devices
857
#
858
CONFIG_SND_USB_AUDIO=m
859
860
#
861
# Open Sound System
862
#
863
# CONFIG_SOUND_PRIME is not set
864
865
#
866
# USB support
867
#
868
CONFIG_USB=m
869
# CONFIG_USB_DEBUG is not set
870
871
#
872
# Miscellaneous USB options
873
#
874
CONFIG_USB_DEVICEFS=y
875
CONFIG_USB_BANDWIDTH=y
876
CONFIG_USB_DYNAMIC_MINORS=y
877
878
#
879
# USB Host Controller Drivers
880
#
881
CONFIG_USB_EHCI_HCD=m
882
CONFIG_USB_OHCI_HCD=m
883
CONFIG_USB_UHCI_HCD=m
884
885
#
886
# USB Device Class drivers
887
#
888
CONFIG_USB_AUDIO=m
889
CONFIG_USB_BLUETOOTH_TTY=m
890
CONFIG_USB_MIDI=m
891
CONFIG_USB_ACM=m
892
CONFIG_USB_PRINTER=m
893
CONFIG_USB_STORAGE=m
894
# CONFIG_USB_STORAGE_DEBUG is not set
895
CONFIG_USB_STORAGE_DATAFAB=y
896
CONFIG_USB_STORAGE_FREECOM=y
897
CONFIG_USB_STORAGE_ISD200=y
898
CONFIG_USB_STORAGE_DPCM=y
899
CONFIG_USB_STORAGE_HP8200e=y
900
CONFIG_USB_STORAGE_SDDR09=y
901
CONFIG_USB_STORAGE_SDDR55=y
902
CONFIG_USB_STORAGE_JUMPSHOT=y
903
904
#
905
# USB Human Interface Devices (HID)
906
#
907
CONFIG_USB_HID=m
908
CONFIG_USB_HIDINPUT=y
909
CONFIG_HID_FF=y
910
CONFIG_HID_PID=y
911
CONFIG_LOGITECH_FF=y
912
CONFIG_THRUSTMASTER_FF=y
913
CONFIG_USB_HIDDEV=y
914
915
#
916
# USB HID Boot Protocol drivers
917
#
918
CONFIG_USB_KBD=m
919
CONFIG_USB_MOUSE=m
920
CONFIG_USB_AIPTEK=m
921
CONFIG_USB_WACOM=m
922
CONFIG_USB_KBTAB=m
923
CONFIG_USB_POWERMATE=m
924
CONFIG_USB_XPAD=m
925
CONFIG_USB_XPAD_MOUSE=y
926
927
#
928
# USB Imaging devices
929
#
930
CONFIG_USB_MDC800=m
931
CONFIG_USB_MICROTEK=m
932
CONFIG_USB_HPUSBSCSI=m
933
934
#
935
# USB Multimedia devices
936
#
937
CONFIG_USB_DABUSB=m
938
939
#
940
# Video4Linux support is needed for USB Multimedia device support
941
#
942
943
#
944
# USB Network adaptors
945
#
946
CONFIG_USB_CATC=m
947
CONFIG_USB_KAWETH=m
948
CONFIG_USB_PEGASUS=m
949
CONFIG_USB_RTL8150=m
950
CONFIG_USB_USBNET=m
951
952
#
953
# USB Host-to-Host Cables
954
#
955
CONFIG_USB_AN2720=y
956
CONFIG_USB_BELKIN=y
957
CONFIG_USB_GENESYS=y
958
CONFIG_USB_NET1080=y
959
CONFIG_USB_PL2301=y
960
961
#
962
# Intelligent USB Devices/Gadgets
963
#
964
CONFIG_USB_ARMLINUX=y
965
CONFIG_USB_EPSON2888=y
966
CONFIG_USB_ZAURUS=y
967
CONFIG_USB_CDCETHER=y
968
969
#
970
# USB Network Adapters
971
#
972
CONFIG_USB_AX8817X=y
973
974
#
975
# USB port drivers
976
#
977
978
#
979
# USB Serial Converter support
980
#
981
CONFIG_USB_SERIAL=m
982
CONFIG_USB_SERIAL_GENERIC=y
983
CONFIG_USB_SERIAL_BELKIN=m
984
CONFIG_USB_SERIAL_WHITEHEAT=m
985
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
986
CONFIG_USB_SERIAL_EMPEG=m
987
CONFIG_USB_SERIAL_FTDI_SIO=m
988
CONFIG_USB_SERIAL_VISOR=m
989
CONFIG_USB_SERIAL_IPAQ=m
990
CONFIG_USB_SERIAL_IR=m
991
CONFIG_USB_SERIAL_EDGEPORT=m
992
CONFIG_USB_SERIAL_EDGEPORT_TI=m
993
CONFIG_USB_SERIAL_KEYSPAN_PDA=m
994
CONFIG_USB_SERIAL_KEYSPAN=m
995
CONFIG_USB_SERIAL_KEYSPAN_MPR=y
996
CONFIG_USB_SERIAL_KEYSPAN_USA28=y
997
CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
998
CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
999
CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
1000
CONFIG_USB_SERIAL_KEYSPAN_USA19=y
1001
CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
1002
CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
1003
CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
1004
CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
1005
CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
1006
CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
1007
CONFIG_USB_SERIAL_KLSI=m
1008
CONFIG_USB_SERIAL_KOBIL_SCT=m
1009
CONFIG_USB_SERIAL_MCT_U232=m
1010
CONFIG_USB_SERIAL_PL2303=m
1011
# CONFIG_USB_SERIAL_SAFE is not set
1012
CONFIG_USB_SERIAL_CYBERJACK=m
1013
CONFIG_USB_SERIAL_XIRCOM=m
1014
CONFIG_USB_SERIAL_OMNINET=m
1015
CONFIG_USB_EZUSB=y
1016
1017
#
1018
# USB Miscellaneous drivers
1019
#
1020
CONFIG_USB_EMI62=m
1021
CONFIG_USB_EMI26=m
1022
CONFIG_USB_TIGL=m
1023
CONFIG_USB_AUERSWALD=m
1024
CONFIG_USB_RIO500=m
1025
CONFIG_USB_LEGOTOWER=m
1026
CONFIG_USB_BRLVGER=m
1027
CONFIG_USB_LCD=m
1028
CONFIG_USB_LED=m
1029
CONFIG_USB_TEST=m
1030
1031
#
1032
# USB Gadget Support
1033
#
1034
CONFIG_USB_GADGET=m
1035
CONFIG_USB_GADGET_NET2280=y
1036
CONFIG_USB_NET2280=m
1037
# CONFIG_USB_GADGET_PXA2XX is not set
1038
# CONFIG_USB_GADGET_GOKU is not set
1039
# CONFIG_USB_GADGET_SA1100 is not set
1040
CONFIG_USB_ZERO=m
1041
CONFIG_USB_ETH=m
1042
CONFIG_USB_GADGETFS=m
1043
CONFIG_USB_FILE_STORAGE=m
1044
# CONFIG_USB_FILE_STORAGE_TEST is not set
1045
CONFIG_USB_G_SERIAL=m
1046
1047
#
1048
# File systems
1049
#
1050
CONFIG_EXT2_FS=y
1051
CONFIG_EXT3_FS=m
1052
# CONFIG_JBD is not set
1053
CONFIG_REISERFS_FS=y
1054
# CONFIG_REISERFS_CHECK is not set
1055
CONFIG_REISERFS_PROC_INFO=y
1056
# CONFIG_JFS_FS is not set
1057
# CONFIG_XFS_FS is not set
1058
# CONFIG_MINIX_FS is not set
1059
# CONFIG_ROMFS_FS is not set
1060
# CONFIG_QUOTA is not set
1061
# CONFIG_AUTOFS_FS is not set
1062
# CONFIG_AUTOFS4_FS is not set
1063
1064
#
1065
# CD-ROM/DVD Filesystems
1066
#
1067
CONFIG_ISO9660_FS=y
1068
CONFIG_JOLIET=y
1069
CONFIG_ZISOFS=y
1070
CONFIG_ZISOFS_FS=y
1071
CONFIG_UDF_FS=y
1072
1073
#
1074
# DOS/FAT/NT Filesystems
1075
#
1076
CONFIG_FAT_FS=m
1077
CONFIG_MSDOS_FS=m
1078
CONFIG_VFAT_FS=m
1079
CONFIG_NTFS_FS=m
1080
# CONFIG_NTFS_DEBUG is not set
1081
CONFIG_NTFS_RW=y
1082
CONFIG_FATX_FS=m
1083
1084
#
1085
# Pseudo filesystems
1086
#
1087
CONFIG_PROC_FS=y
1088
CONFIG_PROC_KCORE=y
1089
CONFIG_DEVFS_FS=y
1090
CONFIG_DEVFS_MOUNT=y
1091
# CONFIG_DEVFS_DEBUG is not set
1092
# CONFIG_DEVPTS_FS_XATTR is not set
1093
CONFIG_TMPFS=y
1094
# CONFIG_HUGETLBFS is not set
1095
# CONFIG_HUGETLB_PAGE is not set
1096
CONFIG_RAMFS=y
1097
1098
#
1099
# Miscellaneous filesystems
1100
#
1101
# CONFIG_ADFS_FS is not set
1102
# CONFIG_AFFS_FS is not set
1103
# CONFIG_HFS_FS is not set
1104
# CONFIG_HFSPLUS_FS is not set
1105
# CONFIG_BEFS_FS is not set
1106
# CONFIG_BFS_FS is not set
1107
# CONFIG_EFS_FS is not set
1108
CONFIG_CRAMFS=y
1109
# CONFIG_VXFS_FS is not set
1110
# CONFIG_HPFS_FS is not set
1111
# CONFIG_QNX4FS_FS is not set
1112
# CONFIG_SYSV_FS is not set
1113
# CONFIG_UFS_FS is not set
1114
1115
#
1116
# Network File Systems
1117
#
1118
CONFIG_NFS_FS=m
1119
CONFIG_NFS_V3=y
1120
CONFIG_NFS_V4=y
1121
CONFIG_NFS_DIRECTIO=y
1122
CONFIG_NFSD=m
1123
CONFIG_NFSD_V3=y
1124
CONFIG_NFSD_V4=y
1125
CONFIG_NFSD_TCP=y
1126
CONFIG_LOCKD=m
1127
CONFIG_LOCKD_V4=y
1128
CONFIG_EXPORTFS=m
1129
CONFIG_SUNRPC=m
1130
# CONFIG_SUNRPC_GSS is not set
1131
CONFIG_SMB_FS=m
1132
CONFIG_SMB_NLS_DEFAULT=y
1133
CONFIG_SMB_NLS_REMOTE="cp850"
1134
CONFIG_CIFS=m
1135
# CONFIG_NCP_FS is not set
1136
# CONFIG_CODA_FS is not set
1137
# CONFIG_INTERMEZZO_FS is not set
1138
# CONFIG_AFS_FS is not set
1139
1140
#
1141
# Partition Types
1142
#
1143
CONFIG_PARTITION_ADVANCED=y
1144
# CONFIG_ACORN_PARTITION is not set
1145
# CONFIG_OSF_PARTITION is not set
1146
# CONFIG_AMIGA_PARTITION is not set
1147
# CONFIG_ATARI_PARTITION is not set
1148
# CONFIG_MAC_PARTITION is not set
1149
CONFIG_MSDOS_PARTITION=y
1150
# CONFIG_BSD_DISKLABEL is not set
1151
# CONFIG_MINIX_SUBPARTITION is not set
1152
# CONFIG_SOLARIS_X86_PARTITION is not set
1153
# CONFIG_UNIXWARE_DISKLABEL is not set
1154
# CONFIG_LDM_PARTITION is not set
1155
# CONFIG_NEC98_PARTITION is not set
1156
# CONFIG_SGI_PARTITION is not set
1157
# CONFIG_ULTRIX_PARTITION is not set
1158
# CONFIG_SUN_PARTITION is not set
1159
# CONFIG_EFI_PARTITION is not set
1160
CONFIG_XBOX_PARTITION=y
1161
1162
#
1163
# Native Language Support
1164
#
1165
CONFIG_NLS=y
1166
CONFIG_NLS_DEFAULT="iso8859-15"
1167
CONFIG_NLS_CODEPAGE_437=m
1168
CONFIG_NLS_CODEPAGE_737=m
1169
CONFIG_NLS_CODEPAGE_775=m
1170
CONFIG_NLS_CODEPAGE_850=m
1171
CONFIG_NLS_CODEPAGE_852=m
1172
CONFIG_NLS_CODEPAGE_855=m
1173
CONFIG_NLS_CODEPAGE_857=m
1174
CONFIG_NLS_CODEPAGE_860=m
1175
CONFIG_NLS_CODEPAGE_861=m
1176
CONFIG_NLS_CODEPAGE_862=m
1177
CONFIG_NLS_CODEPAGE_863=m
1178
CONFIG_NLS_CODEPAGE_864=m
1179
CONFIG_NLS_CODEPAGE_865=m
1180
CONFIG_NLS_CODEPAGE_866=m
1181
CONFIG_NLS_CODEPAGE_869=m
1182
CONFIG_NLS_CODEPAGE_936=m
1183
CONFIG_NLS_CODEPAGE_950=m
1184
CONFIG_NLS_CODEPAGE_932=m
1185
CONFIG_NLS_CODEPAGE_949=m
1186
CONFIG_NLS_CODEPAGE_874=m
1187
CONFIG_NLS_ISO8859_8=m
1188
CONFIG_NLS_CODEPAGE_1250=m
1189
CONFIG_NLS_CODEPAGE_1251=m
1190
CONFIG_NLS_ISO8859_1=m
1191
CONFIG_NLS_ISO8859_2=m
1192
CONFIG_NLS_ISO8859_3=m
1193
CONFIG_NLS_ISO8859_4=m
1194
CONFIG_NLS_ISO8859_5=m
1195
CONFIG_NLS_ISO8859_6=m
1196
CONFIG_NLS_ISO8859_7=m
1197
CONFIG_NLS_ISO8859_9=m
1198
CONFIG_NLS_ISO8859_13=m
1199
CONFIG_NLS_ISO8859_14=m
1200
CONFIG_NLS_ISO8859_15=m
1201
CONFIG_NLS_KOI8_R=m
1202
CONFIG_NLS_KOI8_U=m
1203
CONFIG_NLS_UTF8=m
1204
1205
#
1206
# Profiling support
1207
#
1208
# CONFIG_PROFILING is not set
1209
1210
#
1211
# Kernel hacking
1212
#
1213
# CONFIG_DEBUG_KERNEL is not set
1214
# CONFIG_EARLY_PRINTK is not set
1215
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1216
# CONFIG_FRAME_POINTER is not set
1217
1218
#
1219
# Security options
1220
#
1221
# CONFIG_SECURITY is not set
1222
1223
#
1224
# Cryptographic options
1225
#
1226
CONFIG_CRYPTO=y
1227
CONFIG_CRYPTO_HMAC=y
1228
CONFIG_CRYPTO_NULL=m
1229
CONFIG_CRYPTO_MD4=m
1230
CONFIG_CRYPTO_MD5=m
1231
CONFIG_CRYPTO_SHA1=m
1232
CONFIG_CRYPTO_SHA256=m
1233
CONFIG_CRYPTO_SHA512=m
1234
CONFIG_CRYPTO_DES=m
1235
CONFIG_CRYPTO_BLOWFISH=m
1236
CONFIG_CRYPTO_TWOFISH=m
1237
CONFIG_CRYPTO_SERPENT=m
1238
CONFIG_CRYPTO_AES=m
1239
CONFIG_CRYPTO_CAST5=m
1240
CONFIG_CRYPTO_CAST6=m
1241
# CONFIG_CRYPTO_ARC4 is not set
1242
CONFIG_CRYPTO_DEFLATE=m
1243
CONFIG_CRYPTO_TEST=m
1244
1245
#
1246
# Library routines
1247
#
1248
CONFIG_CRC32=m
1249
CONFIG_ZLIB_INFLATE=y
1250
CONFIG_ZLIB_DEFLATE=m
(-)linux-2.6.5.orig/sound/pci/ac97/ac97_codec.c (+3 lines)
Lines 1807-1816 Link Here
1807
	}
1807
	}
1808
1808
1809
	if (!ac97_is_audio(ac97) && !ac97_is_modem(ac97)) {
1809
	if (!ac97_is_audio(ac97) && !ac97_is_modem(ac97)) {
1810
		/* PATCH FOR XBOX */
1811
		/*
1810
		if (!(ac97->scaps & (AC97_SCAP_SKIP_AUDIO|AC97_SCAP_SKIP_MODEM)))
1812
		if (!(ac97->scaps & (AC97_SCAP_SKIP_AUDIO|AC97_SCAP_SKIP_MODEM)))
1811
			snd_printk(KERN_ERR "AC'97 %d access error (not audio or modem codec)\n", ac97->num);
1813
			snd_printk(KERN_ERR "AC'97 %d access error (not audio or modem codec)\n", ac97->num);
1812
		snd_ac97_free(ac97);
1814
		snd_ac97_free(ac97);
1813
		return -EACCES;
1815
		return -EACCES;
1816
		*/
1814
	}
1817
	}
1815
1818
1816
	if (bus->reset) // FIXME: always skipping?
1819
	if (bus->reset) // FIXME: always skipping?
(-)linux-2.6.5.orig/sound/usb/usbquirks.h (+74 lines)
Lines 653-658 Link Here
653
		.type = QUIRK_MIDI_STANDARD_INTERFACE
653
		.type = QUIRK_MIDI_STANDARD_INTERFACE
654
	}
654
	}
655
},
655
},
656
{	/*
657
	 * This quirk is for the Xbox Communicator
658
	 * please NOTE:
659
	 *
660
	 *  THIS HAS _NOT_ BEEN TESTED THOROUGHLY!
661
	 *
662
	 *  IT IS REALLY JUST SOME COPY&PASTE FROM ABOVE.
663
	 *  You have been warned.
664
	 *
665
	 *  In fact, I managed to kinda crash it and the Xbox hung while
666
	 *   cleaning up alsa on shutdown.
667
	 *
668
	 * What worked was to cat <file> > /dev/dsp and get static
669
	 *  on the headset. Getting Mplayer to output sound did not work
670
	 *  for me (no music files and therefore no extensive tests, though).
671
	 * Also I had no luck with the mic, mixer said it "found no elements".
672
	 *
673
	 * If you wanna try, go ahead and report to xbox-linux.org (ML, IRC)
674
	 *
675
	 * Marko Friedemann <mfr@bmx-chemnitz.de>
676
	 */
677
	USB_DEVICE(0x045e, 0x0283),
678
	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
679
		.vendor_name = "Microsoft",
680
		.product_name = "Xbox Communicator",
681
		.ifnum = QUIRK_ANY_INTERFACE,
682
		.type = QUIRK_COMPOSITE,
683
		.data = & (const snd_usb_audio_quirk_t[]) {
684
			{
685
				.ifnum = 0,
686
				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
687
				.data = & (const struct audioformat) {
688
					/* seems might as well be wrong */
689
					.format = SNDRV_PCM_FORMAT_S16_LE,
690
					/* as might this */
691
					.channels = 1,
692
					.iface = 0,
693
					.altsetting = 0,
694
					.altset_idx = 0,
695
					.attributes = 0,
696
					.endpoint = 0x04,
697
					.ep_attr = 0x05,
698
					/* and those */
699
					.rates = SNDRV_PCM_RATE_CONTINUOUS,
700
					.rate_min = 44100,
701
					.rate_max = 44100,
702
				}
703
			},
704
			{
705
				.ifnum = 1,
706
				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
707
				.data = & (const struct audioformat) {
708
					/* seems might as well be wrong */
709
					.format = SNDRV_PCM_FORMAT_S16_LE,
710
					/* as might this */
711
					.channels = 1,
712
					.iface = 1,
713
					.altsetting = 0,
714
					.altset_idx = 0,
715
					.attributes = 0,
716
					.endpoint = 0x85,
717
					.ep_attr = 0x05,
718
					/* and those */
719
					.rates = SNDRV_PCM_RATE_CONTINUOUS,
720
					.rate_min = 44100,
721
					.rate_max = 44100,
722
				}
723
			},
724
			{
725
				.ifnum = -1
726
			}
727
		}
728
	}
729
},
656
730
657
/* Midiman/M-Audio devices */
731
/* Midiman/M-Audio devices */
658
{
732
{

Return to bug 45100