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.6.orig/Makefile (-1 / +1 lines)
Lines 1-7 Link Here
1
VERSION = 2
1
VERSION = 2
2
PATCHLEVEL = 6
2
PATCHLEVEL = 6
3
SUBLEVEL = 6
3
SUBLEVEL = 6
4
EXTRAVERSION =
4
EXTRAVERSION = -xbox
5
NAME=Zonked Quokka
5
NAME=Zonked Quokka
6
6
7
# *DOCUMENTATION*
7
# *DOCUMENTATION*
(-)linux-2.6.6.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 521-526 Link Here
521
	  If you have a system with several CPUs, you do not need to say Y
537
	  If you have a system with several CPUs, you do not need to say Y
522
	  here: the IO-APIC will be used automatically.
538
	  here: the IO-APIC will be used automatically.
523
539
540
config XBOX_EJECT
541
	bool "XBOX eject fix"
542
	depends on X86_XBOX
543
524
config X86_LOCAL_APIC
544
config X86_LOCAL_APIC
525
	bool
545
	bool
526
	depends on !SMP && X86_UP_APIC
546
	depends on !SMP && X86_UP_APIC
Lines 1127-1133 Link Here
1127
1147
1128
config MCA
1148
config MCA
1129
	bool "MCA support"
1149
	bool "MCA support"
1130
	depends on !(X86_VISWS || X86_VOYAGER)
1150
	depends on !(X86_VISWS || X86_VOYAGER || X86_XBOX)
1131
	help
1151
	help
1132
	  MicroChannel Architecture is found in some IBM PS/2 machines and
1152
	  MicroChannel Architecture is found in some IBM PS/2 machines and
1133
	  laptops.  It is a bus system similar to PCI or ISA. See
1153
	  laptops.  It is a bus system similar to PCI or ISA. See
Lines 1314-1320 Link Here
1314
1334
1315
config X86_BIOS_REBOOT
1335
config X86_BIOS_REBOOT
1316
	bool
1336
	bool
1317
	depends on !(X86_VISWS || X86_VOYAGER)
1337
	depends on !(X86_VISWS || X86_VOYAGER || X86_XBOX)
1318
	default y
1338
	default y
1319
1339
1320
config X86_TRAMPOLINE
1340
config X86_TRAMPOLINE
(-)linux-2.6.6.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.6.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.6.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.6.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.6.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.6.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.6.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.6.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.6.orig/drivers/i2c/busses/Kconfig (+4 lines)
Lines 49-54 Link Here
49
	  This driver can also be built as a module.  If so, the module
49
	  This driver can also be built as a module.  If so, the module
50
	  will be called i2c-amd756.
50
	  will be called i2c-amd756.
51
51
52
config I2C_XBOX
53
	tristate "XBOX I2C"
54
	depends on I2C && EXPERIMENTAL
55
52
config I2C_AMD8111
56
config I2C_AMD8111
53
	tristate "AMD 8111"
57
	tristate "AMD 8111"
54
	depends on I2C && EXPERIMENTAL
58
	depends on I2C && EXPERIMENTAL
(-)linux-2.6.6.orig/drivers/i2c/busses/Makefile (+1 lines)
Lines 6-11 Link Here
6
obj-$(CONFIG_I2C_ALI1563)	+= i2c-ali1563.o
6
obj-$(CONFIG_I2C_ALI1563)	+= i2c-ali1563.o
7
obj-$(CONFIG_I2C_ALI15X3)	+= i2c-ali15x3.o
7
obj-$(CONFIG_I2C_ALI15X3)	+= i2c-ali15x3.o
8
obj-$(CONFIG_I2C_AMD756)	+= i2c-amd756.o
8
obj-$(CONFIG_I2C_AMD756)	+= i2c-amd756.o
9
obj-$(CONFIG_I2C_XBOX)		+= i2c-xbox.o
9
obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
10
obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
10
obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
11
obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
11
obj-$(CONFIG_I2C_HYDRA)		+= i2c-hydra.o
12
obj-$(CONFIG_I2C_HYDRA)		+= i2c-hydra.o
(-)linux-2.6.6.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.6.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 2121-2126 Link Here
2121
	if (sense == NULL)
2129
	if (sense == NULL)
2122
		sense = &my_sense;
2130
		sense = &my_sense;
2123
2131
2132
#ifdef CONFIG_X86_XBOX
2133
	/* If we're on an Xbox and this is an Xbox drive, simulate the lock
2134
	   request in software.  (See arch/i386/kernel/xboxejectfix.c) */
2135
	if (CDROM_CONFIG_FLAGS(drive)->xbox_drive && machine_is_xbox) {
2136
		CDROM_STATE_FLAGS(drive)->door_locked = lockflag;
2137
		Xbox_simulate_drive_locked = lockflag;
2138
		return 0;
2139
	}
2140
#endif /* CONFIG_X86_XBOX */
2141
		
2124
	/* If the drive cannot lock the door, just pretend. */
2142
	/* If the drive cannot lock the door, just pretend. */
2125
	if (CDROM_CONFIG_FLAGS(drive)->no_doorlock) {
2143
	if (CDROM_CONFIG_FLAGS(drive)->no_doorlock) {
2126
		stat = 0;
2144
		stat = 0;
Lines 2169-2174 Link Here
2169
	if (CDROM_STATE_FLAGS(drive)->door_locked && ejectflag)
2187
	if (CDROM_STATE_FLAGS(drive)->door_locked && ejectflag)
2170
		return 0;
2188
		return 0;
2171
2189
2190
#ifdef CONFIG_X86_XBOX
2191
        /* Older Xbox DVD drives don't understand the ATAPI command, but the SMC
2192
	   can do the eject.  Note that some Xbox drives support the eject
2193
	   command, namely the Samsung, so for that drive we do a regular eject
2194
	   sequence. */
2195
	if (machine_is_xbox && CDROM_CONFIG_FLAGS(drive)->xbox_drive &&
2196
		CDROM_CONFIG_FLAGS(drive)->xbox_eject) {
2197
		if (ejectflag) {
2198
			Xbox_tray_load();
2199
		} else {
2200
			Xbox_simulate_drive_locked = 0;
2201
			Xbox_tray_eject();
2202
		}
2203
		return 0;
2204
	}
2205
#endif
2206
		
2172
	cdrom_prepare_request(&req);
2207
	cdrom_prepare_request(&req);
2173
2208
2174
	/* only tell drive to close tray if open, if it can do that */
2209
	/* only tell drive to close tray if open, if it can do that */
Lines 3258-3263 Link Here
3258
                 /* uses CD in slot 0 when value is set to 3 */
3293
                 /* uses CD in slot 0 when value is set to 3 */
3259
                 cdi->sanyo_slot = 3;
3294
                 cdi->sanyo_slot = 3;
3260
        }
3295
        }
3296
#ifdef CONFIG_X86_XBOX
3297
	/* THOMSON DVD drives in the Xbox report incorrect capabilities
3298
	   and do not understand the ATAPI eject command, but the SMC
3299
	   can do the eject. */
3300
	else if ((strcmp(drive->id->model, "THOMSON-DVD") == 0)) {
3301
		CDROM_CONFIG_FLAGS(drive)->audio_play = 1;
3302
		CDROM_CONFIG_FLAGS(drive)->dvd = 1;
3303
		CDROM_CONFIG_FLAGS(drive)->xbox_drive = 1;
3304
		CDROM_CONFIG_FLAGS(drive)->xbox_eject = 1;
3305
	}
3306
	/* PHILIPS drives in Xboxen manufactured pre September 2003,
3307
	   report correct capabilities, but do not understand the ATAPI
3308
	   eject command, hence require the SMC to do so. */
3309
	else if ((strcmp(drive->id->model, "PHILIPS XBOX DVD DRIVE") == 0)) {
3310
		CDROM_CONFIG_FLAGS(drive)->xbox_drive = 1;
3311
		CDROM_CONFIG_FLAGS(drive)->xbox_eject = 1;
3312
	}
3313
	/* PHILIPS drives in Xboxen manufactured post September 2003,
3314
	   report incorrect capabilities, but understand the ATAPI
3315
	   eject command. */
3316
	else if ((strcmp(drive->id->model, "PHILIPS J5 3235C") == 0)) {
3317
		CDROM_CONFIG_FLAGS(drive)->audio_play = 1;
3318
		CDROM_CONFIG_FLAGS(drive)->dvd = 1;
3319
		CDROM_CONFIG_FLAGS(drive)->xbox_drive = 1;
3320
		CDROM_CONFIG_FLAGS(drive)->xbox_eject = 0;
3321
	}
3322
	/* SAMSUNG drives in the Xbox report correct capabilities
3323
	   and understand the ATAPI eject command. */
3324
	else if (strcmp(drive->id->model, "SAMSUNG DVD-ROM SDG-605B") == 0) {
3325
		CDROM_CONFIG_FLAGS(drive)->xbox_drive = 1;
3326
		CDROM_CONFIG_FLAGS(drive)->xbox_eject = 0;
3327
	}
3328
#endif
3329
3330
	/* Is an Xbox drive detected? */
3331
#ifdef CONFIG_X86_XBOX
3332
	if (CDROM_CONFIG_FLAGS(drive)->xbox_drive) {
3333
#endif
3334
		/* If an Xbox drive is present in a regular PC, we can't eject.
3335
		   Act like the drive cannot eject, unless the ATAPI eject command
3336
		   is supported by the drive.  If the drive doesn't support ATAPI
3337
		   ejecting, act like door locking is impossible as well. */
3338
#ifdef CONFIG_X86_XBOX
3339
		if (!machine_is_xbox) {
3340
#endif /* CONFIG_X86_XBOX */
3341
			CDROM_CONFIG_FLAGS(drive)->no_doorlock = CDROM_CONFIG_FLAGS
3342
				(drive)->xbox_eject;
3343
			CDROM_CONFIG_FLAGS(drive)->no_eject = CDROM_CONFIG_FLAGS(drive)
3344
				->xbox_eject;
3345
#ifdef CONFIG_X86_XBOX
3346
		} else {
3347
			/* An Xbox drive in an Xbox.  We can support ejecting through
3348
			   the SMC and support drive locking in software by ignoring
3349
			   the eject interrupt (see arch/i386/kernel/xboxejectfix.c). */
3350
			CDROM_CONFIG_FLAGS(drive)->no_doorlock = 0;
3351
			CDROM_CONFIG_FLAGS(drive)->no_eject = 0;
3352
			Xbox_simulate_drive_locked = 0;
3353
		}
3354
#endif
3355
	}
3356
3261
#endif /* not STANDARD_ATAPI */
3357
#endif /* not STANDARD_ATAPI */
3262
3358
3263
	info->toc		= NULL;
3359
	info->toc		= NULL;
(-)linux-2.6.6.orig/drivers/ide/ide-cd.h (+4 lines)
Lines 93-98 Link Here
93
	__u8 close_tray		: 1; /* can close the tray */
93
	__u8 close_tray		: 1; /* can close the tray */
94
	__u8 writing		: 1; /* pseudo write in progress */
94
	__u8 writing		: 1; /* pseudo write in progress */
95
	__u8 mo_drive		: 1; /* drive is an MO device */
95
	__u8 mo_drive		: 1; /* drive is an MO device */
96
#ifdef CONFIG_X86_XBOX
97
	__u8 xbox_drive         : 1; /* drive is an Xbox drive */
98
	__u8 xbox_eject         : 1; /* use Xbox SMC eject mechanism */	
99
#endif
96
	__u8 reserved		: 2;
100
	__u8 reserved		: 2;
97
	byte max_speed;		     /* Max speed of the drive */
101
	byte max_speed;		     /* Max speed of the drive */
98
};
102
};
(-)linux-2.6.6.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.6.orig/drivers/usb/input/Kconfig (-3 / +13 lines)
Lines 192-210 Link Here
192
	  module will be called mtouchusb.
192
	  module will be called mtouchusb.
193
193
194
config USB_XPAD
194
config USB_XPAD
195
	tristate "X-Box gamepad support"
195
	tristate "X-Box controller (gamepad) support"
196
	depends on USB && INPUT
196
	depends on USB && INPUT
197
	---help---
197
	---help---
198
	  Say Y here if you want to use the X-Box pad with your computer.
198
	  Say Y here if you want to use Xbox controllers with your computer.
199
	  Make sure to say Y to "Joystick support" (CONFIG_INPUT_JOYDEV)
199
	  Make sure to say Y to "Joystick support" (CONFIG_INPUT_JOYDEV)
200
	  and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well.
200
	  and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well.
201
201
202
	  For information about how to connect the X-Box pad to USB, see
202
	  For information about how to connect an Xbox controller to USB, see
203
	  <file:Documentation/input/xpad.txt>.
203
	  <file:Documentation/input/xpad.txt>.
204
204
205
	  To compile this driver as a module, choose M here: the
205
	  To compile this driver as a module, choose M here: the
206
	  module will be called xpad.
206
	  module will be called xpad.
207
	  
207
	  
208
config USB_XPAD_MOUSE
209
       bool "Mouse emulation for Xbox controller"
210
       depends on USB_XPAD
211
       ---help---
212
         Say Y here if you want to enable mouse emulation for your Xbox
213
         controller.
214
         Make sure to say Y to "Mouse support" (CONFIG_INPUT_MOUSEDEV)
215
         and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well.
216
217
208
config USB_ATI_REMOTE
218
config USB_ATI_REMOTE
209
	tristate "ATI USB RF remote control"
219
	tristate "ATI USB RF remote control"
210
	depends on USB && INPUT
220
	depends on USB && INPUT
(-)linux-2.6.6.orig/drivers/usb/input/Makefile (+5 lines)
Lines 4-9 Link Here
4
4
5
# Multipart objects.
5
# Multipart objects.
6
usbhid-objs	:= hid-core.o
6
usbhid-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
	usbhid-objs	+= hid-ff.o
27
	usbhid-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)		+= usbhid.o
36
obj-$(CONFIG_USB_HID)		+= usbhid.o
(-)linux-2.6.6.orig/drivers/usb/input/xpad-core.c (+579 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
	{ 0x044f, 0x0f07, 0, "Thrustmaster, Inc. Controller" },
68
	{ 0x045e, 0x0202, 0, "Microsoft Xbox Controller" },
69
	{ 0x045e, 0x0285, 0, "Microsoft Xbox Controller S" },
70
	{ 0x045e, 0x0289, 0, "Microsoft Xbox Controller S" }, /* microsoft is stupid */
71
	{ 0x046d, 0xca88, 0, "Logitech Compact Controller for Xbox" },
72
	{ 0x05fd, 0x1007, 0, "???Mad Catz Controller???" }, /* CHECKME: this seems strange */
73
	{ 0x05fd, 0x107a, 0, "InterAct PowerPad Pro" },
74
	{ 0x0738, 0x4516, 0, "Mad Catz Control Pad" },
75
	{ 0x0738, 0x4522, 0, "Mad Catz LumiCON" },
76
	{ 0x0738, 0x4526, 0, "Mad Catz Control Pad Pro" },
77
	{ 0x0738, 0x4536, 0, "Mad Catz MicroCON" },
78
	{ 0x0738, 0x4540, 1, "Mad Catz Beat Pad" },
79
	{ 0x0738, 0x4556, 0, "Mad Catz Lynx Wireless Controller" },
80
	{ 0x0738, 0x6040, 1, "Mad Catz Beat Pad Pro" },
81
	{ 0x0c12, 0x9902, 0, "HAMA VibraX - *FAULTY HARDWARE*" }, /* these are broken */
82
	{ 0x0e4c, 0x2390, 0, "Radica Games Jtech Controller"},	
83
	{ 0x0e6f, 0x0003, 0, "Logic3 Freebird wireless Controller" },
84
	{ 0x0f30, 0x0202, 0, "Joytech Advanced Controller" },
85
	{ 0x12ab, 0x8809, 1, "Xbox DDR dancepad" },
86
	{ 0xffff, 0xffff, 0, "Chinese-made Xbox Controller" }, /* WTF are device IDs for? */
87
	{ 0x0000, 0x0000, 0, "nothing detected - FAIL" }
88
};
89
90
static signed short xpad_btn[] = {
91
	BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z,	/* analogue buttons */
92
	BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR,	/* start/back/sticks */
93
	BTN_0, BTN_1, BTN_2, BTN_3,			/* d-pad as buttons */
94
	-1						/* terminating entry */
95
};
96
97
static signed short xpad_mat_btn[] = {
98
	BTN_A, BTN_B, BTN_X, BTN_Y, 	/* A, B, X, Y */
99
	BTN_START, BTN_BACK, 		/* start/back */
100
	BTN_0, BTN_1, BTN_2, BTN_3,	/* directions, LEFT/RIGHT is mouse
101
					 * so we cannot use those! */
102
	-1				/* terminating entry */
103
};
104
105
static signed short xpad_abs[] = {
106
	ABS_X, ABS_Y,		/* left stick */
107
	ABS_RX, ABS_RY,		/* right stick */
108
	ABS_Z, ABS_RZ,		/* triggers left/right */
109
	ABS_HAT0X, ABS_HAT0Y,	/* digital pad */
110
	ABS_HAT1X, ABS_HAT1Y,	/* analogue buttons A + B */
111
	ABS_HAT2X, ABS_HAT2Y,	/* analogue buttons C + X */
112
	ABS_HAT3X, ABS_HAT3Y,	/* analogue buttons Y + Z */
113
	-1			/* terminating entry */
114
};
115
116
static struct usb_device_id xpad_table [] = {
117
	{ USB_INTERFACE_INFO('X', 'B', 0) },	/* Xbox USB-IF not approved class */
118
	{ USB_INTERFACE_INFO( 3 ,  0 , 0) },	/* for Joytech Advanced Controller */
119
	{ }
120
};
121
122
MODULE_DEVICE_TABLE(usb, xpad_table);
123
124
/**
125
 *	xpad_process_packet
126
 *
127
 *	Completes a request by converting the data into events
128
 *	for the input subsystem.
129
 *
130
 *	The report descriptor was taken from ITO Takayukis website:
131
 *	 http://euc.jp/periphs/xbox-controller.en.html
132
 */
133
static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs)
134
{
135
	struct input_dev *dev = &xpad->dev;
136
	
137
	input_regs(dev, regs);
138
139
	/* digital pad (button mode) bits (3 2 1 0) (right left down up) */
140
	input_report_key(dev, BTN_0, (data[2] & 0x01));
141
	input_report_key(dev, BTN_1, (data[2] & 0x08) >> 3);
142
	input_report_key(dev, BTN_2, (data[2] & 0x02) >> 1);
143
	input_report_key(dev, BTN_3, (data[2] & 0x04) >> 2);	
144
	
145
	/* start and back buttons */
146
	input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4);
147
	input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5);
148
	
149
	/* buttons A, B, X, Y digital mode */
150
	input_report_key(dev, BTN_A, data[4]);
151
	input_report_key(dev, BTN_B, data[5]);
152
	input_report_key(dev, BTN_X, data[6]);
153
	input_report_key(dev, BTN_Y, data[7]);
154
	
155
	if (xpad->isMat)
156
		return;
157
	
158
	/* left stick */
159
	input_report_abs(dev, ABS_X, ((__s16) (((__s16)data[13] << 8) | data[12])));
160
	input_report_abs(dev, ABS_Y, ((__s16) (((__s16)data[15] << 8) | data[14])));
161
	
162
	/* right stick */
163
	input_report_abs(dev, ABS_RX, ((__s16) (((__s16)data[17] << 8) | data[16])));
164
	input_report_abs(dev, ABS_RY, ((__s16) (((__s16)data[19] << 8) | data[18])));
165
   	
166
   	/* triggers left/right */
167
	input_report_abs(dev, ABS_Z, data[10]);
168
	input_report_abs(dev, ABS_RZ, data[11]);
169
	
170
	/* digital pad (analogue mode): bits (3 2 1 0) (right left down up) */
171
	input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04));
172
	input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x01) - !!(data[2] & 0x02));
173
174
	/* stick press left/right */
175
	input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6);
176
	input_report_key(dev, BTN_THUMBR, data[2] >> 7);
177
	
178
	/* button A, B, X, Y analogue mode */
179
	input_report_abs(dev, ABS_HAT1X, data[4]);
180
	input_report_abs(dev, ABS_HAT1Y, data[5]);
181
	input_report_abs(dev, ABS_HAT2Y, data[6]);
182
	input_report_abs(dev, ABS_HAT3X, data[7]);
183
	
184
	/* button C (black) digital/analogue mode */
185
	input_report_key(dev, BTN_C, data[8]);
186
	input_report_abs(dev, ABS_HAT2X, data[8]);
187
	
188
	/* button Z (white) digital/analogue mode */
189
	input_report_key(dev, BTN_Z, data[9]);
190
	input_report_abs(dev, ABS_HAT3Y, data[9]);
191
	
192
	input_sync(dev);
193
	
194
	/* process input data for mouse event generation */
195
	xpad_mouse_process_packet(xpad, cmd, data);
196
}
197
198
/**
199
 *	xpad_irq_in
200
 *
201
 *	Completion handler for interrupt in transfers (user input).
202
 *	Just calls xpad_process_packet which does then emit input events.
203
 */
204
static void xpad_irq_in(struct urb *urb, struct pt_regs *regs)
205
{
206
	struct usb_xpad *xpad = urb->context;
207
	int retval;
208
	
209
	switch (urb->status) {
210
	case 0:
211
		/* success */
212
		break;
213
	case -ECONNRESET:
214
	case -ENOENT:
215
	case -ESHUTDOWN:
216
		/* this urb is terminated, clean up */
217
		dbg("%s - urb shutting down with status: %d",
218
		    __FUNCTION__, urb->status);
219
		return;
220
	default:
221
		dbg("%s - nonzero urb status received: %d",
222
		    __FUNCTION__, urb->status);
223
		goto exit;
224
	}
225
	
226
	xpad_process_packet(xpad, 0, xpad->idata, regs);
227
	
228
exit:
229
	retval = usb_submit_urb(urb, GFP_ATOMIC);
230
	if (retval)
231
		err("%s - usb_submit_urb failed with result %d",
232
		    __FUNCTION__, retval);
233
}
234
235
/*	xpad_init_urb
236
 *
237
 *	initialize the input urb
238
 *	this is to be called when joystick or mouse device are opened
239
 */
240
int xpad_start_urb(struct usb_xpad *xpad)
241
{
242
	int status;
243
	
244
	// check if joystick or mouse device are opened
245
	if (xpad->open_count + xpad->mouse_open_count > 0)
246
		return 0;
247
248
	xpad->irq_in->dev = xpad->udev;
249
	if ((status = usb_submit_urb(xpad->irq_in, GFP_KERNEL))) {
250
		err("open input urb failed: %d", status);
251
		return -EIO;
252
	}
253
	
254
	return 0;
255
}
256
257
/**
258
 *	xpad_open
259
 *
260
 *	Called when a an application opens the device.
261
 */
262
static int xpad_open(struct input_dev *dev)
263
{
264
	struct usb_xpad *xpad = dev->private;
265
	int status;
266
	
267
	if (xpad->open_count)
268
		return 0;
269
		
270
	info("opening device");
271
	
272
	if ((status = xpad_start_urb(xpad)))
273
		return status;
274
		
275
	++xpad->open_count;
276
277
	xpad_rumble_open(xpad);
278
	
279
	return 0;
280
}
281
282
void xpad_stop_urb(struct usb_xpad *xpad)
283
{
284
	if (xpad->open_count + xpad->mouse_open_count > 0)
285
		return;
286
	
287
	usb_unlink_urb(xpad->irq_in);
288
}
289
290
/**
291
 *	xpad_close
292
 *
293
 *	Called when an application closes the device.
294
 */
295
static void xpad_close(struct input_dev *dev)
296
{
297
	struct usb_xpad *xpad = dev->private;
298
	
299
	if (--xpad->open_count)
300
		return;
301
	
302
	info("closing device");
303
	
304
	xpad_stop_urb(xpad);
305
	xpad_rumble_close(xpad);
306
}
307
308
/**	xpad_init_input_device
309
 *
310
 *	setup the input device for the kernel
311
 */
312
static void xpad_init_input_device(struct usb_interface *intf, struct xpad_device device)
313
{
314
	struct usb_xpad *xpad = usb_get_intfdata(intf);
315
	struct usb_device *udev = interface_to_usbdev(intf);
316
	char path[64];
317
	int i;
318
	
319
	xpad->dev.id.bustype = BUS_USB;
320
	xpad->dev.id.vendor = udev->descriptor.idVendor;
321
	xpad->dev.id.product = udev->descriptor.idProduct;
322
	xpad->dev.id.version = udev->descriptor.bcdDevice;
323
	xpad->dev.dev = &intf->dev;
324
	xpad->dev.private = xpad;
325
	xpad->dev.name = device.name;
326
	xpad->dev.phys = xpad->phys;
327
	xpad->dev.open = xpad_open;
328
	xpad->dev.close = xpad_close;
329
	
330
	usb_make_path(udev, path, 64);
331
	snprintf(xpad->phys, 64, "%s/input0", path);
332
	
333
	/* this was meant to allow a user space tool on-the-fly configuration
334
	   of driver options (mouse on, rumble on, etc)
335
	   yet, Vojtech said this is better done using sysfs (linux 2.6)
336
	   plus, it needs a patch to the input subsystem */
337
//	xpad->dev.ioctl = xpad_ioctl;
338
339
	if (xpad->isMat) {
340
		xpad->dev.evbit[0] = BIT(EV_KEY);
341
		for (i = 0; xpad_mat_btn[i] >= 0; ++i)
342
			set_bit(xpad_mat_btn[i], xpad->dev.keybit);
343
	} else {
344
		xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
345
		
346
		for (i = 0; xpad_btn[i] >= 0; ++i)
347
		set_bit(xpad_btn[i], xpad->dev.keybit);
348
		
349
		for (i = 0; xpad_abs[i] >= 0; ++i) {
350
			
351
			signed short t = xpad_abs[i];
352
			
353
			set_bit(t, xpad->dev.absbit);
354
			
355
			switch (t) {
356
			case ABS_X:
357
			case ABS_Y:
358
			case ABS_RX:
359
			case ABS_RY:	/* the two sticks */
360
				xpad->dev.absmax[t] =  32767;
361
				xpad->dev.absmin[t] = -32768;
362
				xpad->dev.absflat[t] = 128;
363
				xpad->dev.absfuzz[t] = 16;
364
				break;
365
			case ABS_Z:	/* left trigger */
366
			case ABS_RZ:	/* right trigger */
367
			case ABS_HAT1X:	/* analogue button A */
368
			case ABS_HAT1Y:	/* analogue button B */
369
			case ABS_HAT2X:	/* analogue button C */
370
			case ABS_HAT2Y:	/* analogue button X */
371
			case ABS_HAT3X:	/* analogue button Y */
372
			case ABS_HAT3Y:	/* analogue button Z */
373
				xpad->dev.absmax[t] = 255;
374
				xpad->dev.absmin[t] = 0;
375
				break;
376
			case ABS_HAT0X:
377
			case ABS_HAT0Y:	/* the d-pad */
378
				xpad->dev.absmax[t] =  1;
379
				xpad->dev.absmin[t] = -1;
380
				break;
381
			}
382
		}
383
		
384
		if (xpad_rumble_probe(udev, xpad, ifnum) != 0)
385
			err("could not init rumble");
386
	}
387
388
	input_register_device(&xpad->dev);
389
	printk(KERN_INFO "input: %s on %s\n", xpad->dev.name, path);
390
}
391
392
/**
393
 *	xpad_probe
394
 *
395
 *	Called upon device detection to find a suitable driver.
396
 *	Must return NULL when no xpad is found, else setup everything.
397
 */
398
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
399
{
400
	struct usb_device *udev = interface_to_usbdev(intf);
401
	struct usb_xpad *xpad = NULL;
402
	struct usb_endpoint_descriptor *ep_irq_in;
403
	int i;
404
	int probedDevNum = -1;	/* this takes the index into the known devices
405
				   array for the recognized device */
406
	
407
	// try to detect the device we are called for
408
	for (i = 0; xpad_device[i].idVendor; ++i) {
409
		if ((udev->descriptor.idVendor == xpad_device[i].idVendor) &&
410
		    (udev->descriptor.idProduct == xpad_device[i].idProduct)) {
411
			probedDevNum = i;
412
			break;
413
		}
414
	}
415
	
416
	// sanity check, did we recognize this device? if not, fail
417
	if ((probedDevNum == -1) || (!xpad_device[probedDevNum].idVendor &&
418
				     !xpad_device[probedDevNum].idProduct))
419
		return -ENODEV;
420
		
421
	if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) {
422
		err("cannot allocate memory for new pad");
423
		return -ENOMEM;
424
	}
425
	memset(xpad, 0, sizeof(struct usb_xpad));
426
	
427
	xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN,
428
				       SLAB_ATOMIC, &xpad->idata_dma);
429
	if (!xpad->idata) {
430
		kfree(xpad);
431
		return -ENOMEM;
432
	}
433
	
434
	/* setup input interrupt pipe (button and axis state) */
435
	xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
436
        if (!xpad->irq_in) {
437
		err("cannot allocate memory for new pad irq urb");
438
		usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
439
                kfree(xpad);
440
                return -ENOMEM;
441
	}
442
	
443
	ep_irq_in = &intf->altsetting[0].endpoint[0].desc;
444
	
445
	xpad->udev = udev;
446
	xpad->isMat = xpad_device[probedDevNum].isMat;
447
	
448
	/* init input URB for USB INT transfer from device */
449
	usb_fill_int_urb(xpad->irq_in, udev,
450
			 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
451
			 xpad->idata, XPAD_PKT_LEN,
452
			 xpad_irq_in, xpad, ep_irq_in->bInterval);
453
	xpad->irq_in->transfer_dma = xpad->idata_dma;
454
	xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
455
	
456
	// we set this here so we can extract it in the two functions below
457
	usb_set_intfdata(intf, xpad);
458
	
459
	xpad_init_input_device(intf, xpad_device[probedDevNum]);
460
	xpad_mouse_init_input_device(intf, xpad_device[probedDevNum]);
461
	
462
	return 0;
463
}
464
465
/**
466
 *	xpad_disconnect
467
 *
468
 *	Called upon device disconnect to dispose of the structures and
469
 *	close the USB connections.
470
 */
471
static void xpad_disconnect(struct usb_interface *intf)
472
{
473
	struct usb_xpad *xpad = usb_get_intfdata(intf);
474
	
475
	usb_set_intfdata(intf, NULL);
476
	if (xpad) {
477
		info( "disconnecting device" );
478
		usb_unlink_urb(xpad->irq_in);
479
		xpad_rumble_close(xpad);
480
		input_unregister_device(&xpad->dev);
481
		
482
		usb_free_urb(xpad->irq_in);
483
		xpad_mouse_cleanup(xpad);
484
		
485
		usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN,
486
				xpad->idata, xpad->idata_dma);
487
	
488
		xpad_rumble_disconnect(xpad);
489
		
490
		kfree(xpad);
491
	}
492
}
493
494
/******************* Linux driver framework specific stuff ************/
495
496
static struct usb_driver xpad_driver = {
497
	.owner		= THIS_MODULE,
498
	.name		= "xpad",
499
	.probe		= xpad_probe,
500
	.disconnect	= xpad_disconnect,
501
	.id_table	= xpad_table,
502
};
503
504
/**
505
 * driver init entry point
506
 */
507
static int __init usb_xpad_init(void)
508
{
509
	int result = usb_register(&xpad_driver);
510
	if (result == 0)
511
		info(DRIVER_DESC " " DRIVER_VERSION);
512
	return result;
513
}
514
515
/**
516
 * driver exit entry point
517
 */
518
static void __exit usb_xpad_exit(void)
519
{
520
	usb_deregister(&xpad_driver);
521
}
522
523
module_init(usb_xpad_init);
524
module_exit(usb_xpad_exit);
525
526
MODULE_AUTHOR(DRIVER_AUTHOR);
527
MODULE_DESCRIPTION(DRIVER_DESC);
528
MODULE_LICENSE("GPL");
529
530
/*
531
 *  driver history
532
 * ----------------
533
 *
534
 * 2003-05-15 - 0.1.2 : ioctls, dynamic mouse/rumble activation, /proc fs
535
 *  - added some /proc files for informational purposes (readonly right now)
536
 *  - added init parameters for mouse/rumble activation upon detection
537
 *  - added dynamic changes to mouse events / rumble effect generation via
538
 *    ioctls - NOTE: this requires a currently unofficial joydev patch!
539
 *
540
 * 2003-04-29 - 0.1.1 : minor cleanups, some comments
541
 *  - fixed incorrect handling of unknown devices (please try ir dongle now)
542
 *  - fixed input URB length (the 256 bytes from 0.1.0 broke everything for the
543
 *    MS controller as well as my Interact device, set back to 32 (please
544
 *    REPORT problems BEFORE any further changes here, since those can be fatal)
545
 *  - fixed rumbling for MS controllers (need 6 bytes output report)
546
 *  - dropped kernel-2.5 ifdefs, much more readable now
547
 *  - preparation for major rework under way, stay tuned
548
 *
549
 * 2003-03-25 - 0.1.0 : (Franz) Some Debuggin
550
 *  - Better Handling
551
 *  - X/Y support, Speed differenting
552
 *  - Landing Zone, Dead Zone, Offset kompensation, Zero-adjustment, .... aso.
553
 *  - Removed Wheel handling in Mouse Emulation .. sensless..
554
 *
555
 * 2003-01-23 - 0.1.0-pre : added mouse emulation and rumble support
556
 *  - can provide mouse emulation (compile time switch)
557
 *    this code has been taken from Oliver Schwartz' xpad-mouse driver
558
 *  - basic rumble support (compile time switch)        EXPERIMENTAL!  
559
 *
560
 * 2002-08-05 - 0.0.6 : added analog button support
561
 *
562
 * 2002-07-17 - 0.0.5 : (Vojtech Pavlik) rework
563
 *  - simplified d-pad handling
564
 *
565
 * 2002-07-16 - 0.0.4 : minor changes, merge with Vojtech's v0.0.3
566
 *  - verified the lack of HID and report descriptors
567
 *  - verified that ALL buttons WORK
568
 *  - fixed d-pad to axes mapping
569
 *
570
 * 2002-07-14 - 0.0.3 : (Vojtech Pavlik) rework
571
 *  - indentation fixes
572
 *  - usb + input init sequence fixes
573
 *
574
 * 2002-07-02 - 0.0.2 : basic working version
575
 *  - all axes and 9 of the 10 buttons work (german InterAct device)
576
 *  - the black button does not work
577
 *
578
 * 2002-06-27 - 0.0.1 : first version, just said "XBOX HID controller"
579
 */
(-)linux-2.6.6.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.6.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.6.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.6.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.6.orig/drivers/video/fbmem.c (+5 lines)
Lines 123-128 Link Here
123
extern int sgivwfb_setup(char*);
123
extern int sgivwfb_setup(char*);
124
extern int rivafb_init(void);
124
extern int rivafb_init(void);
125
extern int rivafb_setup(char*);
125
extern int rivafb_setup(char*);
126
extern int xboxfb_init(void);
127
extern int xboxfb_setup(char*);
126
extern int tdfxfb_init(void);
128
extern int tdfxfb_init(void);
127
extern int tdfxfb_setup(char*);
129
extern int tdfxfb_setup(char*);
128
extern int tridentfb_init(void);
130
extern int tridentfb_init(void);
Lines 218-223 Link Here
218
#ifdef CONFIG_FB_RIVA
220
#ifdef CONFIG_FB_RIVA
219
	{ "rivafb", rivafb_init, rivafb_setup },
221
	{ "rivafb", rivafb_init, rivafb_setup },
220
#endif
222
#endif
223
#ifdef CONFIG_FB_XBOX
224
	{ "xboxfb", xboxfb_init, xboxfb_setup },
225
#endif
221
#ifdef CONFIG_FB_3DFX
226
#ifdef CONFIG_FB_3DFX
222
	{ "tdfxfb", tdfxfb_init, tdfxfb_setup },
227
	{ "tdfxfb", tdfxfb_init, tdfxfb_setup },
223
#endif
228
#endif
(-)linux-2.6.6.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 xlb.o
(-)linux-2.6.6.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.6.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.6.orig/drivers/video/xbox/encoder-i2c.c (+203 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 XLB_ADDRESS 0x70
27
#define EEPROM_ADDRESS 0x54
28
#define PIC_ADDRESS 0x10
29
30
#define DRIVER_NAME "xbox-tv-i2c"
31
32
extern int __init i2c_xbox_init(void);
33
34
static int tv_attach_adapter(struct i2c_adapter *adap);
35
36
static struct i2c_driver tv_driver = {
37
	.name		= "i2c xbox conexant driver",
38
	.id		= I2C_DRIVERID_I2CDEV,
39
	.flags		= I2C_DF_NOTIFY,
40
	.attach_adapter	= tv_attach_adapter,
41
};
42
43
static struct i2c_client pic_client = {
44
	.name		= "I2C xbox pic client",
45
	.id		= 2,
46
	.flags		= 0,
47
	.addr		= PIC_ADDRESS,
48
	.adapter	= NULL,
49
	.driver		= &tv_driver,
50
};
51
52
static struct i2c_client conexant_client = {
53
	.name		= "I2C xbox conexant client",
54
	.id		= 1,
55
	.flags		= 0,
56
	.addr		= CONEXANT_ADDRESS,
57
	.adapter	= NULL,
58
	.driver		= &tv_driver,
59
};
60
61
static struct i2c_client focus_client = {
62
	.name		= "I2C xbox focus client",
63
	.id		= 1,
64
	.flags		= 0,
65
	.addr		= FOCUS_ADDRESS,
66
	.adapter	= NULL,
67
	.driver		= &tv_driver,
68
};
69
70
static struct i2c_client xlb_client = {
71
	.name		= "I2C xbox XLB client",
72
	.id		= 1,
73
	.flags		= 0,
74
	.addr		= XLB_ADDRESS,
75
	.adapter	= NULL,
76
	.driver		= &tv_driver,
77
};
78
79
static struct i2c_client eeprom_client = {
80
	.name		= "I2C xbox eeprom client",
81
	.id		= 3,
82
	.flags		= 0,
83
	.addr		= EEPROM_ADDRESS,
84
	.adapter	= NULL,
85
	.driver		= &tv_driver,
86
};
87
88
static int tv_attach_adapter(struct i2c_adapter *adap)
89
{
90
	int i;
91
92
	if ((i = i2c_adapter_id(adap)) < 0) {
93
		printk("i2c-dev.o: Unknown adapter ?!?\n");
94
		return -ENODEV;
95
	}
96
97
	printk(KERN_INFO DRIVER_NAME ": Using '%s'!\n",adap->name);
98
	conexant_client.adapter = adap;
99
	focus_client.adapter = adap;
100
	xlb_client.adapter = adap;
101
	pic_client.adapter = adap;
102
	eeprom_client.adapter = adap;
103
	i2c_attach_client(&conexant_client);
104
	i2c_attach_client(&focus_client);
105
	i2c_attach_client(&xlb_client);
106
	i2c_attach_client(&pic_client);
107
	i2c_attach_client(&eeprom_client);
108
109
	return 0;
110
}
111
112
int tv_i2c_init(void) {
113
	int res;
114
	i2c_xbox_init();
115
	if ((res = i2c_add_driver(&tv_driver))) {
116
		printk(KERN_ERR DRIVER_NAME ": XBox tv driver registration failed.\n");
117
		return res;
118
	}
119
	return 0;
120
}
121
122
int conexant_i2c_read_reg(unsigned char adr) {
123
	if (!conexant_client.adapter) {
124
		printk(KERN_ERR DRIVER_NAME " : No conexant client attached.\n");
125
		return -1;
126
	}
127
	udelay(500);
128
	return i2c_smbus_read_byte_data(&conexant_client, adr);
129
}
130
131
int conexant_i2c_write_reg(unsigned char adr, unsigned char value) {
132
	if (!conexant_client.adapter) {
133
		printk(KERN_ERR DRIVER_NAME " : No conexant client attached.\n");
134
		return -1;
135
	}
136
	udelay(500);
137
	return i2c_smbus_write_byte_data(&conexant_client, adr, value);
138
}
139
140
int focus_i2c_read_reg(unsigned char adr) {
141
	if (!focus_client.adapter) {
142
		printk(KERN_ERR DRIVER_NAME " : No focus client attached.\n");
143
		return -1;
144
	}
145
	udelay(500);
146
	return i2c_smbus_read_byte_data(&focus_client, adr);
147
}
148
149
int focus_i2c_write_reg(unsigned char adr, unsigned char value) {
150
	if (!focus_client.adapter) {
151
		printk(KERN_ERR DRIVER_NAME " : No focus client attached.\n");
152
		return -1;
153
	}
154
	udelay(500);
155
	return i2c_smbus_write_byte_data(&focus_client, adr, value);
156
}
157
158
int xlb_i2c_read_reg(unsigned char adr) {
159
	if (!xlb_client.adapter) {
160
		printk(KERN_ERR DRIVER_NAME " : No XLB client attached.\n");
161
		return -1;
162
	}
163
	udelay(500);
164
	return i2c_smbus_read_byte_data(&xlb_client, adr);
165
}
166
167
int xlb_i2c_write_reg(unsigned char adr, unsigned char value) {
168
	if (!xlb_client.adapter) {
169
		printk(KERN_ERR DRIVER_NAME " : No XLB client attached.\n");
170
		return -1;
171
	}
172
	udelay(500);
173
	return i2c_smbus_write_byte_data(&xlb_client, adr, value);
174
}
175
176
unsigned char pic_i2c_read_reg(unsigned char adr) {
177
	if (!pic_client.adapter) {
178
		printk(KERN_ERR DRIVER_NAME " : No pic client attached.\n");
179
		return 0;
180
	}
181
	udelay(500);
182
	return (unsigned char)i2c_smbus_read_byte_data(&pic_client, adr);
183
}
184
185
unsigned char eeprom_i2c_read(unsigned char adr) {
186
	if (!eeprom_client.adapter) {
187
		printk(KERN_ERR DRIVER_NAME " : No eeprom client attached.\n");
188
		return 0;
189
	}
190
	udelay(500);
191
	return (unsigned char)i2c_smbus_read_byte_data(&eeprom_client, adr);
192
}
193
194
void tv_i2c_exit(void){
195
	int res;
196
	
197
	if ((res = i2c_del_driver(&tv_driver))) {
198
		printk(KERN_ERR DRIVER_NAME ": XBox tv Driver deregistration failed, "
199
		       "module not removed.\n");
200
	}
201
	return;
202
}
203
(-)linux-2.6.6.orig/drivers/video/xbox/encoder-i2c.h (+31 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
int xlb_i2c_read_reg(unsigned char adr);
27
int xlb_i2c_write_reg(unsigned char adr, unsigned char value);
28
unsigned char pic_i2c_read_reg(unsigned char adr);
29
unsigned char eeprom_i2c_read(unsigned char adr);
30
31
#endif
(-)linux-2.6.6.orig/drivers/video/xbox/encoder.c (+174 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
40
	b = conexant_i2c_read_reg(0x00);
41
	if(b != 255) {
42
		return ENCODER_CONEXANT;
43
	}
44
	b = focus_i2c_read_reg(0x00);
45
	if(b != 255) {
46
		return ENCODER_FOCUS;
47
	}
48
	b = xlb_i2c_read_reg(0x00);
49
	if(b != 255) {
50
		return ENCODER_XLB;
51
	}
52
	return 0;
53
}
54
55
int tv_init(void) {
56
	return tv_i2c_init();
57
}
58
59
void tv_exit(void) {
60
	tv_i2c_exit();
61
}
62
63
void tv_load_mode(unsigned char * mode) {
64
	int n, n1;
65
	unsigned char b;
66
	
67
	switch (tv_get_video_encoder()) {
68
		case ENCODER_CONEXANT:
69
			conexant_i2c_write_reg(0xc4, 0x00); // EN_OUT = 1
70
71
			// Conexant init (starts at register 0x2e)
72
			n1=0;
73
			for(n=0x2e;n<0x100;n+=2) {
74
				switch(n) {
75
					case 0x6c: // reset
76
						conexant_i2c_write_reg(n, mode[n1] & 0x7f);
77
						break;
78
					case 0xc4: // EN_OUT
79
						conexant_i2c_write_reg(n, mode[n1] & 0xfe);
80
						break;
81
					case 0xb8: // autoconfig
82
						break;
83
	
84
					default:
85
						conexant_i2c_write_reg(n, mode[n1]);
86
						break;
87
				}
88
				n1++;
89
			}
90
			// Timing Reset
91
			b=conexant_i2c_read_reg(0x6c) & (0x7f);
92
			conexant_i2c_write_reg(0x6c, 0x80|b);
93
			b=conexant_i2c_read_reg(0xc4) & (0xfe);
94
			conexant_i2c_write_reg(0xc4, 0x01|b); // EN_OUT = 1
95
			
96
			/*
97
			conexant_i2c_write_reg(0xA8, (0xD9/1.3));
98
			conexant_i2c_write_reg(0xAA, (0x9A/1.3));
99
			conexant_i2c_write_reg(0xAC, (0xA4/1.3));
100
			*/
101
		
102
			conexant_i2c_write_reg(0xA8, 0x81);
103
			conexant_i2c_write_reg(0xAA, 0x49);
104
			conexant_i2c_write_reg(0xAC, 0x8C);
105
			break;
106
		case ENCODER_FOCUS:
107
			//Set the command register soft reset
108
			focus_i2c_write_reg(0x0c,0x03);
109
			focus_i2c_write_reg(0x0d,0x21);
110
			
111
			for (n = 0; n<0xc4; n++) {
112
				focus_i2c_write_reg(n,mode[n]);
113
			}
114
			//Clear soft reset flag
115
			b = focus_i2c_read_reg(0x0c);
116
			b &= ~0x01;
117
			focus_i2c_write_reg(0x0c,b);
118
			b = focus_i2c_read_reg(0x0d);
119
			focus_i2c_write_reg(0x0d,b);
120
			break;
121
		case ENCODER_XLB:
122
			//Nothing yet
123
			break;		
124
		}	
125
}
126
127
void tv_save_mode(unsigned char * mode) {
128
	int n, n1;
129
	switch (tv_get_video_encoder()) {
130
		case 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
			break;
138
		case ENCODER_FOCUS:
139
			for (n=0;n<0xc4;n++) {
140
				mode[n] = focus_i2c_read_reg(n);
141
			}
142
			break;
143
		case ENCODER_XLB:
144
			break;
145
	}			
146
}
147
148
xbox_tv_encoding get_tv_encoding(void) {
149
	unsigned char eeprom_value;
150
	xbox_tv_encoding enc = TV_ENC_PALBDGHI;
151
	eeprom_value = eeprom_i2c_read(0x5a);
152
	if (eeprom_value == 0x40) {
153
		enc = TV_ENC_NTSC;
154
	}
155
	else {
156
		enc = TV_ENC_PALBDGHI;
157
	}
158
	return enc;
159
}
160
161
xbox_av_type detect_av_type(void) {
162
	xbox_av_type avType;
163
	switch (pic_i2c_read_reg(0x04)) {
164
		case 0: avType = AV_SCART_RGB; break;
165
		case 1: avType = AV_HDTV; break;
166
		case 2: avType = AV_VGA_SOG; break;
167
		case 4: avType = AV_SVIDEO; break;
168
		case 6: avType = AV_COMPOSITE; break;
169
		case 7: avType = AV_VGA; break;
170
		default: avType = AV_COMPOSITE; break;
171
	}
172
	return avType;
173
}
174
(-)linux-2.6.6.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.6.orig/drivers/video/xbox/fbdev.c (+2254 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
#include "xlb.h"
64
65
#ifndef CONFIG_PCI		/* sanity check */
66
#error This driver requires PCI support.
67
#endif
68
69
/* version number of this driver */
70
#define RIVAFB_VERSION "0.9.5b"
71
72
/* ------------------------------------------------------------------------- *
73
 *
74
 * various helpful macros and constants
75
 *
76
 * ------------------------------------------------------------------------- */
77
78
#undef RIVAFBDEBUG
79
#ifdef RIVAFBDEBUG
80
#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
81
#else
82
#define DPRINTK(fmt, args...)
83
#endif
84
85
#ifndef RIVA_NDEBUG
86
#define assert(expr) \
87
	if(!(expr)) { \
88
	printk( "Assertion failed! %s,%s,%s,line=%d\n",\
89
	#expr,__FILE__,__FUNCTION__,__LINE__); \
90
	BUG(); \
91
	}
92
#else
93
#define assert(expr)
94
#endif
95
96
#define PFX "xboxfb: "
97
98
/* macro that allows you to set overflow bits */
99
#define SetBitField(value,from,to) SetBF(to,GetBF(value,from))
100
#define SetBit(n)		(1<<(n))
101
#define Set8Bits(value)		((value)&0xff)
102
103
/* HW cursor parameters */
104
#define MAX_CURS		32
105
106
/* ------------------------------------------------------------------------- *
107
 *
108
 * prototypes
109
 *
110
 * ------------------------------------------------------------------------- */
111
112
static int xboxfb_blank(int blank, struct fb_info *info);
113
114
/* ------------------------------------------------------------------------- *
115
 *
116
 * card identification
117
 *
118
 * ------------------------------------------------------------------------- */
119
120
enum riva_chips {
121
	CH_GEFORCE3_XBOX
122
};
123
124
/* directly indexed by riva_chips enum, above */
125
static struct riva_chip_info {
126
	const char *name;
127
	unsigned arch_rev;
128
} riva_chip_info[] __initdata = {
129
        { "GeForce3", NV_ARCH_20}
130
};
131
132
static struct pci_device_id xboxfb_pci_tbl[] = {
133
	{ PCI_VENDOR_ID_NVIDIA, 0x2a0,
134
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3_XBOX },
135
	{ 0, } /* terminate list */
136
};
137
MODULE_DEVICE_TABLE(pci, xboxfb_pci_tbl);
138
139
/* ------------------------------------------------------------------------- *
140
 *
141
 * global variables
142
 *
143
 * ------------------------------------------------------------------------- */
144
145
/* command line data, set in xboxfb_setup() */
146
static u32 pseudo_palette[17];
147
static int flatpanel __initdata = -1; /* Autodetect later */
148
static int forceCRTC __initdata = -1;
149
#ifdef CONFIG_MTRR
150
static int nomtrr __initdata = 0;
151
#endif
152
153
#ifndef MODULE
154
static char *mode_option __initdata = NULL;
155
#endif
156
157
static xbox_tv_encoding tv_encoding  __initdata = TV_ENC_INVALID;
158
static xbox_av_type av_type __initdata = AV_INVALID;
159
static int hoc __initdata = -1;
160
static int voc __initdata = -1;
161
162
static struct fb_fix_screeninfo xboxfb_fix = {
163
	.id		= "Xbox",
164
	.type		= FB_TYPE_PACKED_PIXELS,
165
	.xpanstep	= 1,
166
	.ypanstep	= 1,
167
};
168
169
static struct fb_var_screeninfo xboxfb_default_var = {
170
	.xres		= 640,
171
	.yres		= 480,
172
	.xres_virtual	= 640,
173
	.yres_virtual	= 480,
174
	.bits_per_pixel	= 8,
175
	.red		= {0, 8, 0},
176
	.green		= {0, 8, 0},
177
	.blue		= {0, 8, 0},
178
	.transp		= {0, 0, 0},
179
	.activate	= FB_ACTIVATE_NOW,
180
	.height		= -1,
181
	.width		= -1,
182
	.accel_flags	= FB_ACCELF_TEXT,
183
	.pixclock	= 39721,
184
	.left_margin	= 40,
185
	.right_margin	= 24,
186
	.upper_margin	= 32,
187
	.lower_margin	= 11,
188
	.hsync_len	= 96,
189
	.vsync_len	= 2,
190
	.vmode		= FB_VMODE_NONINTERLACED
191
};
192
193
static struct fb_var_screeninfo xboxfb_mode_480p = {
194
	.xres           = 720,
195
	.yres           = 480,
196
	.xres_virtual   = 720,
197
	.yres_virtual   = 480,
198
	.bits_per_pixel = 32,
199
	.red            = {0, 8, 16},
200
	.green          = {0, 8, 8},
201
	.blue           = {0, 8, 0},
202
	.transp         = {0, 0, 0},
203
	.activate       = FB_ACTIVATE_NOW,
204
	.height         = -1,
205
	.width          = -1,
206
	.accel_flags    = FB_ACCELF_TEXT,
207
	.pixclock       = 37000,
208
	.left_margin    = 56,
209
	.right_margin   = 18,
210
	.upper_margin   = 29,
211
	.lower_margin   = 9,
212
	.hsync_len      = 64,
213
	.vsync_len      = 7,
214
	.vmode          = FB_VMODE_NONINTERLACED
215
};
216
217
static struct fb_var_screeninfo xboxfb_mode_720p = {
218
	.xres           = 1280,
219
	.yres           = 720,
220
	.xres_virtual   = 1280,
221
	.yres_virtual   = 720,
222
	.bits_per_pixel = 8,
223
	.red            = {0, 8, 0},
224
	.green          = {0, 8, 0},
225
	.blue           = {0, 8, 0},
226
	.transp         = {0, 0, 0},
227
	.activate       = FB_ACTIVATE_NOW,
228
	.height         = -1,
229
	.width          = -1,
230
	.accel_flags    = FB_ACCELF_TEXT,
231
	.pixclock       = 13468,
232
	.left_margin    = 220,
233
	.right_margin   = 70,
234
	.upper_margin   = 22,
235
	.lower_margin   = 3,
236
	.hsync_len      = 80,
237
	.vsync_len      = 5,
238
	.vmode          = FB_VMODE_NONINTERLACED
239
};
240
241
static const char* tvEncodingNames[] = {
242
        "NTSC",
243
        "NTSC-60",
244
        "PAL-BDGHI",
245
        "PAL-N",
246
        "PAL-NC",
247
        "PAL-M",
248
        "PAL-60"
249
};
250
251
static const char* avTypeNames[] = {
252
        "SCART (RGB)",
253
        "S-Video",
254
        "VGA (Sync on green)",
255
        "HDTV (Component video)",
256
        "Composite",
257
        "VGA (internal syncs)"
258
};
259
260
/* from GGI */
261
static const struct riva_regs reg_template = {
262
	{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,	/* ATTR */
263
	 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
264
	 0x41, 0x01, 0x0F, 0x00, 0x00},
265
	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* CRT  */
266
	 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
267
	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3,	/* 0x10 */
268
	 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269
	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 0x20 */
270
	 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271
	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 0x30 */
272
	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273
	 0x00,							/* 0x40 */
274
	 },
275
	{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,	/* GRA  */
276
	 0xFF},
277
	{0x03, 0x01, 0x0F, 0x00, 0x0E},				/* SEQ  */
278
	0xEB							/* MISC */
279
};
280
281
/* ------------------------------------------------------------------------- *
282
 *
283
 * MMIO access macros
284
 *
285
 * ------------------------------------------------------------------------- */
286
287
static inline void CRTCout(struct riva_par *par, unsigned char index,
288
			   unsigned char val)
289
{
290
	VGA_WR08(par->riva.PCIO, 0x3d4, index);
291
	VGA_WR08(par->riva.PCIO, 0x3d5, val);
292
}
293
294
static inline unsigned char CRTCin(struct riva_par *par,
295
				   unsigned char index)
296
{
297
	VGA_WR08(par->riva.PCIO, 0x3d4, index);
298
	return (VGA_RD08(par->riva.PCIO, 0x3d5));
299
}
300
301
static inline void GRAout(struct riva_par *par, unsigned char index,
302
			  unsigned char val)
303
{
304
	VGA_WR08(par->riva.PVIO, 0x3ce, index);
305
	VGA_WR08(par->riva.PVIO, 0x3cf, val);
306
}
307
308
static inline unsigned char GRAin(struct riva_par *par,
309
				  unsigned char index)
310
{
311
	VGA_WR08(par->riva.PVIO, 0x3ce, index);
312
	return (VGA_RD08(par->riva.PVIO, 0x3cf));
313
}
314
315
static inline void SEQout(struct riva_par *par, unsigned char index,
316
			  unsigned char val)
317
{
318
	VGA_WR08(par->riva.PVIO, 0x3c4, index);
319
	VGA_WR08(par->riva.PVIO, 0x3c5, val);
320
}
321
322
static inline unsigned char SEQin(struct riva_par *par,
323
				  unsigned char index)
324
{
325
	VGA_WR08(par->riva.PVIO, 0x3c4, index);
326
	return (VGA_RD08(par->riva.PVIO, 0x3c5));
327
}
328
329
static inline void ATTRout(struct riva_par *par, unsigned char index,
330
			   unsigned char val)
331
{
332
	VGA_WR08(par->riva.PCIO, 0x3c0, index);
333
	VGA_WR08(par->riva.PCIO, 0x3c0, val);
334
}
335
336
static inline unsigned char ATTRin(struct riva_par *par,
337
				   unsigned char index)
338
{
339
	VGA_WR08(par->riva.PCIO, 0x3c0, index);
340
	return (VGA_RD08(par->riva.PCIO, 0x3c1));
341
}
342
343
static inline void MISCout(struct riva_par *par, unsigned char val)
344
{
345
	VGA_WR08(par->riva.PVIO, 0x3c2, val);
346
}
347
348
static inline unsigned char MISCin(struct riva_par *par)
349
{
350
	return (VGA_RD08(par->riva.PVIO, 0x3cc));
351
}
352
353
static u8 byte_rev[256] = {
354
	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
355
	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
356
	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
357
	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
358
	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
359
	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
360
	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
361
	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
362
	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
363
	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
364
	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
365
	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
366
	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
367
	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
368
	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
369
	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
370
	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
371
	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
372
	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
373
	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
374
	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
375
	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
376
	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
377
	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
378
	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
379
	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
380
	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
381
	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
382
	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
383
	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
384
	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
385
	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
386
};
387
388
static inline void reverse_order(u32 *l)
389
{
390
	u8 *a = (u8 *)l;
391
	*a = byte_rev[*a], a++;
392
	*a = byte_rev[*a], a++;
393
	*a = byte_rev[*a], a++;
394
	*a = byte_rev[*a];
395
}
396
397
/* ------------------------------------------------------------------------- *
398
 *
399
 * cursor stuff
400
 *
401
 * ------------------------------------------------------------------------- */
402
403
/**
404
 * xboxfb_load_cursor_image - load cursor image to hardware
405
 * @data: address to monochrome bitmap (1 = foreground color, 0 = background)
406
 * @par:  pointer to private data
407
 * @w:    width of cursor image in pixels
408
 * @h:    height of cursor image in scanlines
409
 * @bg:   background color (ARGB1555) - alpha bit determines opacity
410
 * @fg:   foreground color (ARGB1555)
411
 *
412
 * DESCRIPTiON:
413
 * Loads cursor image based on a monochrome source and mask bitmap.  The
414
 * image bits determines the color of the pixel, 0 for background, 1 for
415
 * foreground.  Only the affected region (as determined by @w and @h 
416
 * parameters) will be updated.
417
 *
418
 * CALLED FROM:
419
 * xboxfb_cursor()
420
 */
421
static void xboxfb_load_cursor_image(struct riva_par *par, u8 *data, 
422
				     u8* mask, u16 bg, u16 fg, u32 w, u32 h)
423
{
424
	int i, j, k = 0;
425
	u32 b, m, tmp;
426
427
	for (i = 0; i < h; i++) {
428
		b = *((u32 *)data);
429
		data = (u8 *)((u32 *)data + 1);
430
		m = *((u32 *)mask);
431
		mask = (u8 *)((u32 *)mask + 1);
432
		reverse_order(&b);
433
		
434
		for (j = 0; j < w/2; j++) {
435
			tmp = 0;
436
#if defined (__BIG_ENDIAN)
437
			tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
438
			if (m & (1 << 31)) {
439
				tmp |= 1 << 31;
440
			}
441
			b <<= 1;
442
			m <<= 1;
443
444
			tmp |= (b & (1 << 31)) ? fg : bg;
445
			if (m & (1 << 31)) {
446
				tmp |= 1 << 15;
447
			}
448
			b <<= 1;
449
			m <<= 1;
450
#else
451
			tmp = (b & 1) ? fg : bg;
452
			if (m & 1) {
453
				tmp |= 1 << 15;
454
			}
455
			b >>= 1;
456
			m >>= 1;
457
			
458
			tmp |= (b & 1) ? fg << 16 : bg << 16;
459
			if (m & 1) {
460
				tmp |= 1 << 31;
461
			}
462
			b >>= 1;
463
			m >>= 1;
464
#endif
465
			writel(tmp, par->riva.CURSOR + k++);
466
		}
467
		k += (MAX_CURS - w)/2;
468
	}
469
}
470
471
/* ------------------------------------------------------------------------- *
472
 *
473
 * general utility functions
474
 *
475
 * ------------------------------------------------------------------------- */
476
477
/**
478
 * riva_wclut - set CLUT entry
479
 * @chip: pointer to RIVA_HW_INST object
480
 * @regnum: register number
481
 * @red: red component
482
 * @green: green component
483
 * @blue: blue component
484
 *
485
 * DESCRIPTION:
486
 * Sets color register @regnum.
487
 *
488
 * CALLED FROM:
489
 * xboxfb_setcolreg()
490
 */
491
static void riva_wclut(RIVA_HW_INST *chip,
492
		       unsigned char regnum, unsigned char red,
493
		       unsigned char green, unsigned char blue)
494
{
495
	VGA_WR08(chip->PDIO, 0x3c8, regnum);
496
	VGA_WR08(chip->PDIO, 0x3c9, red);
497
	VGA_WR08(chip->PDIO, 0x3c9, green);
498
	VGA_WR08(chip->PDIO, 0x3c9, blue);
499
}
500
501
/**
502
 * riva_rclut - read fromCLUT register
503
 * @chip: pointer to RIVA_HW_INST object
504
 * @regnum: register number
505
 * @red: red component
506
 * @green: green component
507
 * @blue: blue component
508
 *
509
 * DESCRIPTION:
510
 * Reads red, green, and blue from color register @regnum.
511
 *
512
 * CALLED FROM:
513
 * xboxfb_setcolreg()
514
 */
515
static void riva_rclut(RIVA_HW_INST *chip,
516
		       unsigned char regnum, unsigned char *red,
517
		       unsigned char *green, unsigned char *blue)
518
{
519
	
520
	VGA_WR08(chip->PDIO, 0x3c8, regnum);
521
	*red = VGA_RD08(chip->PDIO, 0x3c9);
522
	*green = VGA_RD08(chip->PDIO, 0x3c9);
523
	*blue = VGA_RD08(chip->PDIO, 0x3c9);
524
}
525
526
/**
527
 * riva_save_state - saves current chip state
528
 * @par: pointer to riva_par object containing info for current riva board
529
 * @regs: pointer to riva_regs object
530
 *
531
 * DESCRIPTION:
532
 * Saves current chip state to @regs.
533
 *
534
 * CALLED FROM:
535
 * xboxfb_probe()
536
 */
537
/* from GGI */
538
static void riva_save_state(struct riva_par *par, struct riva_regs *regs)
539
{
540
	int i;
541
542
	par->riva.LockUnlock(&par->riva, 0);
543
544
	par->riva.UnloadStateExt(&par->riva, &regs->ext);
545
546
	regs->misc_output = MISCin(par);
547
548
	for (i = 0; i < NUM_CRT_REGS; i++)
549
		regs->crtc[i] = CRTCin(par, i);
550
551
	for (i = 0; i < NUM_ATC_REGS; i++)
552
		regs->attr[i] = ATTRin(par, i);
553
554
	for (i = 0; i < NUM_GRC_REGS; i++)
555
		regs->gra[i] = GRAin(par, i);
556
557
	for (i = 0; i < NUM_SEQ_REGS; i++)
558
		regs->seq[i] = SEQin(par, i);
559
}
560
561
/**
562
 * riva_load_state - loads current chip state
563
 * @par: pointer to riva_par object containing info for current riva board
564
 * @regs: pointer to riva_regs object
565
 *
566
 * DESCRIPTION:
567
 * Loads chip state from @regs.
568
 *
569
 * CALLED FROM:
570
 * riva_load_video_mode()
571
 * xboxfb_probe()
572
 * xboxfb_remove()
573
 */
574
/* from GGI */
575
static void riva_load_state(struct riva_par *par, struct riva_regs *regs)
576
{
577
	RIVA_HW_STATE *state = &regs->ext;
578
	int i;
579
580
	CRTCout(par, 0x11, 0x00);
581
582
	par->riva.LockUnlock(&par->riva, 0);
583
584
	par->riva.LoadStateExt(&par->riva, state);
585
586
	par->riva.PGRAPH[0x00000820/4] = par->riva_fb_start;
587
	par->riva.PGRAPH[0x00000824/4] = par->riva_fb_start;
588
	par->riva.PGRAPH[0x00000828/4] = par->riva_fb_start;
589
	par->riva.PGRAPH[0x0000082c/4] = par->riva_fb_start;
590
591
	par->riva.PGRAPH[0x00000684/4] = par->riva.RamAmountKBytes * 1024 - 1;
592
	par->riva.PGRAPH[0x00000688/4] = par->riva.RamAmountKBytes * 1024 - 1;
593
	par->riva.PGRAPH[0x0000068c/4] = par->riva.RamAmountKBytes * 1024 - 1;
594
	par->riva.PGRAPH[0x00000690/4] = par->riva.RamAmountKBytes * 1024 - 1;
595
	par->riva.PRAMDAC[0x00000848/4] = 0x10100111;
596
	par->riva.PRAMDAC[0x00000880/4] = 0;
597
	par->riva.PRAMDAC[0x000008a0/4] = 0;
598
	par->riva.PMC[0x00008908/4] = par->riva.RamAmountKBytes * 1024 - 1;
599
	par->riva.PMC[0x0000890c/4] = par->riva.RamAmountKBytes * 1024 - 1;
600
	/* Switch GPU to RGB output */
601
	par->riva.PRAMDAC[0x00000630/4] = 0; 
602
	/* These fix the maroon borders seen when booting from Xromwell or 
603
	* xbeboot
604
	*/
605
	par->riva.PRAMDAC[0x0000084c/4] = 0;
606
	par->riva.PRAMDAC[0x000008c4/4] = 0;
607
	
608
	/* for YCrCb:
609
	par->riva.PRAMDAC[0x00000630/4] = 2; 
610
	par->riva.PRAMDAC[0x0000084c/4] =0x00801080;
611
	par->riva.PRAMDAC[0x000008c4/4] =0x40801080;
612
	*/
613
	MISCout(par, regs->misc_output);
614
615
	for (i = 0; i < NUM_CRT_REGS; i++) {
616
		switch (i) {
617
		case 0x0c:
618
		case 0x0d:
619
		case 0x19:
620
		case 0x20 ... 0x40:
621
			break;
622
		default:
623
			CRTCout(par, i, regs->crtc[i]);
624
		}
625
	}
626
627
	for (i = 0; i < NUM_ATC_REGS; i++)
628
		ATTRout(par, i, regs->attr[i]);
629
630
	for (i = 0; i < NUM_GRC_REGS; i++)
631
		GRAout(par, i, regs->gra[i]);
632
633
	for (i = 0; i < NUM_SEQ_REGS; i++)
634
		SEQout(par, i, regs->seq[i]);
635
	tv_save_mode(regs->encoder_mode);
636
}
637
638
static inline unsigned long xbox_memory_size(void) {
639
	/* make a guess on the xbox memory size. There are just
640
	two possibilities */
641
	if ((num_physpages << PAGE_SHIFT) > 64*1024*1024) {
642
		return 128*1024*1024;
643
	} else {
644
		return 64*1024*1024;
645
	}
646
}
647
648
static inline unsigned long available_framebuffer_memory(void) {
649
	return xbox_memory_size() - (num_physpages << PAGE_SHIFT);
650
}
651
652
/**
653
 * riva_load_video_mode - calculate timings
654
 * @info: pointer to fb_info object containing info for current riva board
655
 *
656
 * DESCRIPTION:
657
 * Calculate some timings and then send em off to riva_load_state().
658
 *
659
 * CALLED FROM:
660
 * xboxfb_set_par()
661
 */
662
static void riva_load_video_mode(struct fb_info *info)
663
{
664
	int bpp, width, height, hDisplaySize, hStart, hTotal, vStart, vTotal;
665
	int crtc_hDisplay, crtc_hStart, crtc_hEnd, crtc_hTotal;
666
	int crtc_vDisplay, crtc_vStart, crtc_vEnd, crtc_vTotal, dotClock;
667
	int crtc_hBlankStart, crtc_hBlankEnd, crtc_vBlankStart, crtc_vBlankEnd;
668
	struct riva_par *par = (struct riva_par *) info->par;
669
	struct riva_regs newmode;
670
	int encoder_ok = 0;	
671
	
672
	/* time to calculate */
673
	xboxfb_blank(1, info);
674
675
	bpp = info->var.bits_per_pixel;
676
	if (bpp == 16 && info->var.green.length == 5)
677
		bpp = 15;
678
	width = info->var.xres_virtual;
679
	height = info->var.yres_virtual;
680
	hDisplaySize = info->var.xres;
681
	hStart = hDisplaySize + info->var.right_margin;
682
	hTotal = hDisplaySize + info->var.right_margin +
683
		  info->var.hsync_len + info->var.left_margin;
684
	vStart = info->var.yres + info->var.lower_margin;
685
	vTotal = info->var.yres + info->var.lower_margin +
686
		 info->var.vsync_len + info->var.upper_margin;
687
	
688
	crtc_hDisplay = (hDisplaySize / 8) - 1;
689
	crtc_hStart = (hTotal - 32) / 8;
690
	/* crtc_hStart = hStart / 8 - 1; */
691
	crtc_hEnd = crtc_hStart + 1;
692
	/* crtc_hEnd = (hStart + info->var.hsync_len) / 8 - 1; */
693
	crtc_hTotal = hTotal / 8 - 5;
694
	crtc_hBlankStart = crtc_hDisplay;
695
	crtc_hBlankEnd = crtc_hTotal + 4;
696
	
697
	crtc_vDisplay = info->var.yres - 1;
698
	/* crtc_vStart = vStart - 1; */
699
	crtc_vStart = vStart - 1;
700
	/* crtc_vEnd = vStart + info->var.vsync_len - 1; */
701
	crtc_vEnd = crtc_vStart + 2;
702
	crtc_vTotal = vTotal + 2;
703
	crtc_vDisplay = info->var.yres - 1;
704
	crtc_vBlankStart = crtc_vDisplay;
705
	crtc_vBlankEnd = crtc_vTotal + 1;
706
	
707
	dotClock = 1000000000 / info->var.pixclock;
708
709
	memcpy(&newmode, &reg_template, sizeof(struct riva_regs));
710
711
	if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
712
		vTotal |= 1;
713
714
	if (par->FlatPanel) {
715
		crtc_vStart = crtc_vTotal - 3;
716
		crtc_vEnd = crtc_vTotal - 2;
717
		crtc_vBlankStart = crtc_vStart;
718
		crtc_hStart = crtc_hTotal - 3;
719
		crtc_hEnd = crtc_hTotal - 2;
720
		crtc_hBlankEnd = crtc_hTotal + 4;
721
	}
722
723
	newmode.ext.bpp = bpp;
724
	newmode.ext.fb_start = par->riva_fb_start;
725
726
	if((par->av_type == AV_VGA) || (par->av_type == AV_VGA_SOG) || (par->av_type == AV_HDTV)) {
727
		unsigned char pll_int = (unsigned char)((double)dotClock * 6.0 / 13.5e3 + 0.5);
728
		if (par->av_type == AV_HDTV) {
729
			xbox_hdtv_mode hdtv_mode = HDTV_480p;
730
			if (info->var.yres > 800) {
731
				hdtv_mode = HDTV_1080i;
732
				crtc_vStart = vStart + 31;
733
				crtc_vEnd = crtc_vStart + 2;
734
			}
735
			else if (info->var.yres > 600) {
736
				hdtv_mode = HDTV_720p;
737
			}
738
			switch (par->video_encoder) {
739
				case ENCODER_CONEXANT:
740
					encoder_ok = conexant_calc_hdtv_mode(hdtv_mode, pll_int, newmode.encoder_mode);
741
					break;
742
				case ENCODER_FOCUS:
743
					encoder_ok = focus_calc_hdtv_mode(hdtv_mode, pll_int, newmode.encoder_mode);
744
					break;
745
				case ENCODER_XLB:
746
					encoder_ok = xlb_calc_hdtv_mode(hdtv_mode, pll_int, newmode.encoder_mode);
747
					break;
748
				default:
749
					printk("Error - unknown encoder type detected\n");
750
			}
751
		}
752
		else {
753
			switch (par->video_encoder) {
754
				case ENCODER_CONEXANT:
755
					encoder_ok = conexant_calc_vga_mode(par->av_type, pll_int, newmode.encoder_mode);
756
					break;
757
				case ENCODER_FOCUS:
758
					//No vga functions as yet - so set up for 480p otherwise we dont boot at all. 
759
					encoder_ok = focus_calc_hdtv_mode(HDTV_480p, pll_int, newmode.encoder_mode);
760
					break;
761
				case ENCODER_XLB:
762
					//No vga functions as yet - so set up for 480p otherwise we dont boot at all. 
763
					encoder_ok = xlb_calc_hdtv_mode(HDTV_480p, pll_int, newmode.encoder_mode);
764
					break;
765
				default:
766
					printk("Error - unknown encoder type detected\n");
767
			}
768
		}
769
		newmode.ext.vend = info->var.yres - 1;
770
		newmode.ext.vtotal = vTotal;
771
		newmode.ext.vcrtc = info->var.yres - 1;
772
		newmode.ext.vsyncstart = vStart;
773
		newmode.ext.vsyncend = vStart + 3;
774
		newmode.ext.vvalidstart = 0;
775
		newmode.ext.vvalidend = info->var.yres - 1;
776
		newmode.ext.hend = info->var.xres - 1;
777
		newmode.ext.htotal = hTotal;
778
		newmode.ext.hcrtc = info->var.xres - 1;
779
		newmode.ext.hsyncstart = hStart;
780
		newmode.ext.hsyncend = hStart + 32;
781
		newmode.ext.hvalidstart = 0;
782
		newmode.ext.hvalidend = info->var.xres - 1;
783
	}
784
785
	/* Normal composite */
786
	else {
787
		xbox_video_mode encoder_mode;
788
		encoder_mode.xres = info->var.xres;
789
		encoder_mode.yres = info->var.yres;
790
		encoder_mode.tv_encoding = par->tv_encoding;
791
		encoder_mode.bpp = bpp;
792
		encoder_mode.hoc = par->hoc;
793
		encoder_mode.voc = par->voc;
794
		encoder_mode.av_type = par->av_type;
795
796
		switch (par->video_encoder) {
797
			case ENCODER_CONEXANT:
798
				encoder_ok = conexant_calc_mode(&encoder_mode, &newmode);
799
				break;
800
			case ENCODER_FOCUS:
801
				encoder_ok = focus_calc_mode(&encoder_mode, &newmode);
802
				break;
803
			case ENCODER_XLB:
804
				encoder_ok = xlb_calc_mode(&encoder_mode, &newmode);
805
				break;
806
			default:
807
				printk("Error - unknown encoder type detected\n");
808
		}
809
810
		crtc_hDisplay = (newmode.ext.crtchdispend / 8) - 1;
811
		crtc_hStart = (newmode.ext.htotal - 32) / 8;
812
		crtc_hEnd = crtc_hStart + 1;
813
		crtc_hTotal = (newmode.ext.htotal) / 8 - 5;
814
		crtc_hBlankStart = crtc_hDisplay;
815
		crtc_hBlankEnd = (newmode.ext.htotal) / 8 - 1;
816
		
817
		crtc_vDisplay = info->var.yres - 1;
818
		crtc_vStart = newmode.ext.crtcvstart;
819
		crtc_vEnd = newmode.ext.crtcvstart + 3;
820
		crtc_vTotal = newmode.ext.crtcvtotal;
821
		crtc_vBlankStart = crtc_vDisplay;
822
		crtc_vBlankEnd = crtc_vTotal + 1;
823
	}
824
825
	if (encoder_ok) {
826
		newmode.crtc[0x0] = Set8Bits (crtc_hTotal); 
827
		newmode.crtc[0x1] = Set8Bits (crtc_hDisplay);
828
		newmode.crtc[0x2] = Set8Bits (crtc_hBlankStart);
829
		newmode.crtc[0x3] = SetBitField (crtc_hBlankEnd, 4: 0, 4:0) | SetBit (7);
830
		newmode.crtc[0x4] = Set8Bits (crtc_hStart);
831
		newmode.crtc[0x5] = SetBitField (crtc_hBlankEnd, 5: 5, 7:7)
832
			| SetBitField (crtc_hEnd, 4: 0, 4:0);
833
		newmode.crtc[0x6] = SetBitField (crtc_vTotal, 7: 0, 7:0);
834
		newmode.crtc[0x7] = SetBitField (crtc_vTotal, 8: 8, 0:0)
835
			| SetBitField (crtc_vDisplay, 8: 8, 1:1)
836
			| SetBitField (crtc_vStart, 8: 8, 2:2)
837
			| SetBitField (crtc_vBlankStart, 8: 8, 3:3)
838
			| SetBit (4)
839
			| SetBitField (crtc_vTotal, 9: 9, 5:5)
840
			| SetBitField (crtc_vDisplay, 9: 9, 6:6)
841
			| SetBitField (crtc_vStart, 9: 9, 7:7);
842
		newmode.crtc[0x9] = SetBitField (crtc_vBlankStart, 9: 9, 5:5)
843
			| SetBit (6);
844
		newmode.crtc[0x10] = Set8Bits (crtc_vStart);
845
		newmode.crtc[0x11] = SetBitField (crtc_vEnd, 3: 0, 3:0)
846
			| SetBit (5);
847
		newmode.crtc[0x12] = Set8Bits (crtc_vDisplay);
848
		newmode.crtc[0x13] = (width / 8) * ((bpp + 1) / 8);
849
		newmode.crtc[0x15] = Set8Bits (crtc_vBlankStart);
850
		newmode.crtc[0x16] = Set8Bits (crtc_vBlankEnd);
851
	
852
		newmode.ext.screen = SetBitField(crtc_hBlankEnd,6:6,4:4)
853
			| SetBitField(crtc_vBlankStart,10:10,3:3)
854
			| SetBitField(crtc_vStart,10:10,2:2)
855
			| SetBitField(crtc_vDisplay,10:10,1:1)
856
			| SetBitField(crtc_vTotal,10:10,0:0);
857
		newmode.ext.horiz  = SetBitField(crtc_hTotal,8:8,0:0) 
858
			| SetBitField(crtc_hDisplay,8:8,1:1)
859
			| SetBitField(crtc_hBlankStart,8:8,2:2)
860
			| SetBitField(crtc_hStart,8:8,3:3);
861
		newmode.ext.extra  = SetBitField(crtc_vTotal,11:11,0:0)
862
			| SetBitField(crtc_vDisplay,11:11,2:2)
863
			| SetBitField(crtc_vStart,11:11,4:4)
864
			| SetBitField(crtc_vBlankStart,11:11,6:6); 
865
	
866
		if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
867
			int tmp = (crtc_hTotal >> 1) & ~1;
868
			newmode.ext.interlace = Set8Bits(tmp);
869
			newmode.ext.horiz |= SetBitField(tmp, 8:8,4:4);
870
		} else 
871
			newmode.ext.interlace = 0xff; /* interlace off */
872
	
873
		if (par->riva.Architecture >= NV_ARCH_10)
874
			/* use 2 KByte at top of framebuffer */
875
			par->riva.CURSOR = (U032 *)(info->screen_base + info->fix.smem_len - 2 * 1024);
876
	
877
		if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
878
			newmode.misc_output &= ~0x40;
879
		else
880
			newmode.misc_output |= 0x40;
881
		if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
882
			newmode.misc_output &= ~0x80;
883
		else
884
			newmode.misc_output |= 0x80;	
885
	
886
		par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width,
887
					hDisplaySize, height, dotClock);
888
	
889
		newmode.ext.scale = par->riva.PRAMDAC[0x00000848/4] & 0xfff000ff;
890
		if (par->FlatPanel == 1) {
891
			newmode.ext.pixel |= (1 << 7);
892
			newmode.ext.scale |= (1 << 8);
893
		}
894
		if (par->SecondCRTC) {
895
			newmode.ext.head  = par->riva.PCRTC0[0x00000860/4] & ~0x00001000;
896
			newmode.ext.head2 = par->riva.PCRTC0[0x00002860/4] | 0x00001000;
897
			newmode.ext.crtcOwner = 3;
898
			newmode.ext.pllsel |= 0x20000800;
899
			newmode.ext.vpll2 = newmode.ext.vpll;
900
		} else if (par->riva.twoHeads) {
901
			newmode.ext.head  =  par->riva.PCRTC0[0x00000860/4] | 0x00001000;
902
			newmode.ext.head2 =  par->riva.PCRTC0[0x00002860/4] & ~0x00001000;
903
			newmode.ext.crtcOwner = 0;
904
			newmode.ext.vpll2 = par->riva.PRAMDAC0[0x00000520/4];
905
		}
906
		if (par->FlatPanel == 1) {
907
			newmode.ext.pixel |= (1 << 7);
908
			newmode.ext.scale |= (1 << 8);
909
		}
910
		newmode.ext.cursorConfig = 0x02000100;
911
		par->current_state = newmode;
912
		riva_load_state(par, &par->current_state);
913
		tv_load_mode(newmode.encoder_mode);
914
		par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */
915
	}
916
	else {
917
		printk("Error: Unable to set encoder resolution %dx%d\n",info->var.xres, info->var.yres);
918
	}
919
	
920
	xboxfb_blank(0, info);
921
}
922
923
/**
924
 * xboxfb_do_maximize - 
925
 * @info: pointer to fb_info object containing info for current riva board
926
 * @var:
927
 * @nom:
928
 * @den:
929
 *
930
 * DESCRIPTION:
931
 * .
932
 *
933
 * RETURNS:
934
 * -EINVAL on failure, 0 on success
935
 * 
936
 *
937
 * CALLED FROM:
938
 * xboxfb_check_var()
939
 */
940
static int xboxfb_do_maximize(struct fb_info *info,
941
			      struct fb_var_screeninfo *var,
942
			      int nom, int den)
943
{
944
	static struct {
945
		int xres, yres;
946
	} modes[] = {
947
		{1600, 1280},
948
		{1280, 1024},
949
		{1024, 768},
950
		{800, 600},
951
		{640, 480},
952
		{-1, -1}
953
	};
954
	int i;
955
956
	/* use highest possible virtual resolution */
957
	if (var->xres_virtual == -1 && var->yres_virtual == -1) {
958
		printk(KERN_WARNING PFX
959
		       "using maximum available virtual resolution\n");
960
		for (i = 0; modes[i].xres != -1; i++) {
961
			if (modes[i].xres * nom / den * modes[i].yres <
962
			    info->fix.smem_len / 2)
963
				break;
964
		}
965
		if (modes[i].xres == -1) {
966
			printk(KERN_ERR PFX
967
			       "could not find a virtual resolution that fits into video memory!!\n");
968
			DPRINTK("EXIT - EINVAL error\n");
969
			return -EINVAL;
970
		}
971
		var->xres_virtual = modes[i].xres;
972
		var->yres_virtual = modes[i].yres;
973
974
		printk(KERN_INFO PFX
975
		       "virtual resolution set to maximum of %dx%d\n",
976
		       var->xres_virtual, var->yres_virtual);
977
	} else if (var->xres_virtual == -1) {
978
		var->xres_virtual = (info->fix.smem_len * den /
979
			(nom * var->yres_virtual * 2)) & ~15;
980
		printk(KERN_WARNING PFX
981
		       "setting virtual X resolution to %d\n", var->xres_virtual);
982
	} else if (var->yres_virtual == -1) {
983
		var->xres_virtual = (var->xres_virtual + 15) & ~15;
984
		var->yres_virtual = info->fix.smem_len * den /
985
			(nom * var->xres_virtual * 2);
986
		printk(KERN_WARNING PFX
987
		       "setting virtual Y resolution to %d\n", var->yres_virtual);
988
	} else {
989
		var->xres_virtual = (var->xres_virtual + 15) & ~15;
990
		if (var->xres_virtual * nom / den * var->yres_virtual > info->fix.smem_len) {
991
			printk(KERN_ERR PFX
992
			       "mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
993
			       var->xres, var->yres, var->bits_per_pixel);
994
			DPRINTK("EXIT - EINVAL error\n");
995
			return -EINVAL;
996
		}
997
	}
998
	
999
	if (var->xres_virtual * nom / den >= 8192) {
1000
		printk(KERN_WARNING PFX
1001
		       "virtual X resolution (%d) is too high, lowering to %d\n",
1002
		       var->xres_virtual, 8192 * den / nom - 16);
1003
		var->xres_virtual = 8192 * den / nom - 16;
1004
	}
1005
	
1006
	if (var->xres_virtual < var->xres) {
1007
		printk(KERN_ERR PFX
1008
		       "virtual X resolution (%d) is smaller than real\n", var->xres_virtual);
1009
		return -EINVAL;
1010
	}
1011
1012
	if (var->yres_virtual < var->yres) {
1013
		printk(KERN_ERR PFX
1014
		       "virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);
1015
		return -EINVAL;
1016
	}
1017
	return 0;
1018
}
1019
1020
/* acceleration routines */
1021
inline void wait_for_idle(struct riva_par *par)
1022
{
1023
	while (par->riva.Busy(&par->riva));
1024
}
1025
1026
/* set copy ROP, no mask */
1027
static void riva_setup_ROP(struct riva_par *par)
1028
{
1029
	RIVA_FIFO_FREE(par->riva, Patt, 5);
1030
	par->riva.Patt->Shape = 0;
1031
	par->riva.Patt->Color0 = 0xffffffff;
1032
	par->riva.Patt->Color1 = 0xffffffff;
1033
	par->riva.Patt->Monochrome[0] = 0xffffffff;
1034
	par->riva.Patt->Monochrome[1] = 0xffffffff;
1035
1036
	RIVA_FIFO_FREE(par->riva, Rop, 1);
1037
	par->riva.Rop->Rop3 = 0xCC;
1038
}
1039
1040
void riva_setup_accel(struct riva_par *par)
1041
{
1042
	RIVA_FIFO_FREE(par->riva, Clip, 2);
1043
	par->riva.Clip->TopLeft     = 0x0;
1044
	par->riva.Clip->WidthHeight = 0x80008000;
1045
	riva_setup_ROP(par);
1046
	wait_for_idle(par);
1047
}
1048
1049
/**
1050
 * riva_get_cmap_len - query current color map length
1051
 * @var: standard kernel fb changeable data
1052
 *
1053
 * DESCRIPTION:
1054
 * Get current color map length.
1055
 *
1056
 * RETURNS:
1057
 * Length of color map
1058
 *
1059
 * CALLED FROM:
1060
 * xboxfb_setcolreg()
1061
 */
1062
static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
1063
{
1064
	int rc = 256;		/* reasonable default */
1065
1066
	switch (var->green.length) {
1067
	case 8:
1068
		rc = 256;	/* 256 entries (2^8), 8 bpp and RGB8888 */
1069
		break;
1070
	case 5:
1071
		rc = 32;	/* 32 entries (2^5), 16 bpp, RGB555 */
1072
		break;
1073
	case 6:
1074
		rc = 64;	/* 64 entries (2^6), 16 bpp, RGB565 */
1075
		break;		
1076
	default:
1077
		/* should not occur */
1078
		break;
1079
	}
1080
	return rc;
1081
}
1082
1083
/* ------------------------------------------------------------------------- *
1084
 *
1085
 * framebuffer operations
1086
 *
1087
 * ------------------------------------------------------------------------- */
1088
1089
static int xboxfb_open(struct fb_info *info, int user)
1090
{
1091
	struct riva_par *par = (struct riva_par *) info->par;
1092
	int cnt = atomic_read(&par->ref_count);
1093
1094
	if (!cnt) {
1095
		memset(&par->state, 0, sizeof(struct vgastate));
1096
		par->state.flags = VGA_SAVE_MODE  | VGA_SAVE_FONTS;
1097
		/* save the DAC for Riva128 */
1098
		if (par->riva.Architecture == NV_ARCH_03)
1099
			par->state.flags |= VGA_SAVE_CMAP;
1100
		save_vga(&par->state);
1101
1102
		RivaGetConfig(&par->riva, par->Chipset);
1103
		par->riva.CURSOR = (U032*)(info->screen_base + info->fix.smem_len);
1104
		par->riva.PCRTC[0x00000800/4] = par->riva_fb_start;
1105
		par->riva.PGRAPH[0x00000820/4] = par->riva_fb_start;
1106
		par->riva.PGRAPH[0x00000824/4] = par->riva_fb_start;
1107
		par->riva.PGRAPH[0x00000828/4] = par->riva_fb_start;
1108
		par->riva.PGRAPH[0x0000082c/4] = par->riva_fb_start;
1109
		
1110
		par->riva.PGRAPH[0x00000684/4] = par->riva.RamAmountKBytes * 1024 - 1;
1111
		par->riva.PGRAPH[0x00000688/4] = par->riva.RamAmountKBytes * 1024 - 1;
1112
		par->riva.PGRAPH[0x0000068c/4] = par->riva.RamAmountKBytes * 1024 - 1;
1113
		par->riva.PGRAPH[0x00000690/4] = par->riva.RamAmountKBytes * 1024 - 1;
1114
		par->riva.PMC[0x00008908/4] = par->riva.RamAmountKBytes * 1024 - 1;
1115
		par->riva.PMC[0x0000890c/4] = par->riva.RamAmountKBytes * 1024 - 1;
1116
		
1117
		/* vgaHWunlock() + riva unlock (0x7F) */		
1118
		CRTCout(par, 0x11, 0xFF);
1119
		par->riva.LockUnlock(&par->riva, 0);
1120
	
1121
		riva_save_state(par, &par->initial_state);
1122
	}
1123
	atomic_inc(&par->ref_count);
1124
	return 0;
1125
}
1126
1127
static int xboxfb_release(struct fb_info *info, int user)
1128
{
1129
	struct riva_par *par = (struct riva_par *) info->par;
1130
	int cnt = atomic_read(&par->ref_count);
1131
1132
	if (!cnt)
1133
		return -EINVAL;
1134
	if (cnt == 1) {
1135
		par->riva.LockUnlock(&par->riva, 0);
1136
		par->riva.LoadStateExt(&par->riva, &par->initial_state.ext);
1137
		riva_load_state(par, &par->initial_state);
1138
		restore_vga(&par->state);
1139
		par->riva.LockUnlock(&par->riva, 1);
1140
	}
1141
	atomic_dec(&par->ref_count);
1142
	return 0;
1143
}
1144
1145
static int xboxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1146
{
1147
	int nom, den;		/* translating from pixels->bytes */
1148
	
1149
	switch (var->bits_per_pixel) {
1150
	case 1 ... 8:
1151
		var->red.offset = var->green.offset = var->blue.offset = 0;
1152
		var->red.length = var->green.length = var->blue.length = 8;
1153
		var->bits_per_pixel = 8;
1154
		nom = den = 1;
1155
		break;
1156
	case 9 ... 15:
1157
		var->green.length = 5;
1158
		/* fall through */
1159
	case 16:
1160
		var->bits_per_pixel = 16;
1161
		if (var->green.length == 5) {
1162
			/* 0rrrrrgg gggbbbbb */
1163
			var->red.offset = 10;
1164
			var->green.offset = 5;
1165
			var->blue.offset = 0;
1166
			var->red.length = 5;
1167
			var->green.length = 5;
1168
			var->blue.length = 5;
1169
		} else {
1170
			/* rrrrrggg gggbbbbb */
1171
			var->red.offset = 11;
1172
			var->green.offset = 5;
1173
			var->blue.offset = 0;
1174
			var->red.length = 5;
1175
			var->green.length = 6;
1176
			var->blue.length = 5;
1177
		}
1178
		nom = 2;
1179
		den = 1;
1180
		break;
1181
	case 17 ... 32:
1182
		var->red.length = var->green.length = var->blue.length = 8;
1183
		var->bits_per_pixel = 32;
1184
		var->red.offset = 16;
1185
		var->green.offset = 8;
1186
		var->blue.offset = 0;
1187
		nom = 4;
1188
		den = 1;
1189
		break;
1190
	default:
1191
		printk(KERN_ERR PFX
1192
		       "mode %dx%dx%d rejected...color depth not supported.\n",
1193
		       var->xres, var->yres, var->bits_per_pixel);
1194
		DPRINTK("EXIT, returning -EINVAL\n");
1195
		return -EINVAL;
1196
	}
1197
1198
	if (xboxfb_do_maximize(info, var, nom, den) < 0)
1199
		return -EINVAL;
1200
1201
	if (var->xoffset < 0)
1202
		var->xoffset = 0;
1203
	if (var->yoffset < 0)
1204
		var->yoffset = 0;
1205
1206
	/* truncate xoffset and yoffset to maximum if too high */
1207
	if (var->xoffset > var->xres_virtual - var->xres)
1208
		var->xoffset = var->xres_virtual - var->xres - 1;
1209
1210
	if (var->yoffset > var->yres_virtual - var->yres)
1211
		var->yoffset = var->yres_virtual - var->yres - 1;
1212
1213
	var->red.msb_right = 
1214
	    var->green.msb_right =
1215
	    var->blue.msb_right =
1216
	    var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1217
	return 0;
1218
}
1219
1220
static int xboxfb_set_par(struct fb_info *info)
1221
{
1222
	struct riva_par *par = (struct riva_par *) info->par;
1223
1224
	riva_load_video_mode(info);
1225
	riva_setup_accel(par);
1226
	
1227
	info->fix.line_length = (info->var.xres_virtual * (info->var.bits_per_pixel >> 3));
1228
	info->fix.visual = (info->var.bits_per_pixel == 8) ?
1229
				FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1230
	return 0;
1231
}
1232
1233
/**
1234
 * xboxfb_pan_display
1235
 * @var: standard kernel fb changeable data
1236
 * @con: TODO
1237
 * @info: pointer to fb_info object containing info for current riva board
1238
 *
1239
 * DESCRIPTION:
1240
 * Pan (or wrap, depending on the `vmode' field) the display using the
1241
 * `xoffset' and `yoffset' fields of the `var' structure.
1242
 * If the values don't fit, return -EINVAL.
1243
 *
1244
 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1245
 */
1246
static int xboxfb_pan_display(struct fb_var_screeninfo *var,
1247
			      struct fb_info *info)
1248
{
1249
	struct riva_par *par = (struct riva_par *)info->par;
1250
	unsigned int base;
1251
1252
	if (var->xoffset > (var->xres_virtual - var->xres))
1253
		return -EINVAL;
1254
	if (var->yoffset > (var->yres_virtual - var->yres))
1255
		return -EINVAL;
1256
1257
	if (var->vmode & FB_VMODE_YWRAP) {
1258
		if (var->yoffset < 0
1259
		    || var->yoffset >= info->var.yres_virtual
1260
		    || var->xoffset) return -EINVAL;
1261
	} else {
1262
		if (var->xoffset + info->var.xres > info->var.xres_virtual ||
1263
		    var->yoffset + info->var.yres > info->var.yres_virtual)
1264
			return -EINVAL;
1265
	}
1266
1267
	base = var->yoffset * info->fix.line_length + var->xoffset;
1268
	base += par->riva_fb_start;
1269
	
1270
	par->riva.SetStartAddress(&par->riva, base);
1271
1272
	info->var.xoffset = var->xoffset;
1273
	info->var.yoffset = var->yoffset;
1274
1275
	if (var->vmode & FB_VMODE_YWRAP)
1276
		info->var.vmode |= FB_VMODE_YWRAP;
1277
	else
1278
		info->var.vmode &= ~FB_VMODE_YWRAP;
1279
	return 0;
1280
}
1281
1282
static int xboxfb_blank(int blank, struct fb_info *info)
1283
{
1284
	struct riva_par *par= (struct riva_par *)info->par;
1285
	unsigned char tmp, vesa;
1286
1287
	tmp = SEQin(par, 0x01) & ~0x20;	/* screen on/off */
1288
	vesa = CRTCin(par, 0x1a) & ~0xc0;	/* sync on/off */
1289
1290
	if (blank) {
1291
		tmp |= 0x20;
1292
		switch (blank - 1) {
1293
		case VESA_NO_BLANKING:
1294
			break;
1295
		case VESA_VSYNC_SUSPEND:
1296
			vesa |= 0x80;
1297
			break;
1298
		case VESA_HSYNC_SUSPEND:
1299
			vesa |= 0x40;
1300
			break;
1301
		case VESA_POWERDOWN:
1302
			vesa |= 0xc0;
1303
			break;
1304
		}
1305
	}
1306
	SEQout(par, 0x01, tmp);
1307
	CRTCout(par, 0x1a, vesa);
1308
	return 0;
1309
}
1310
1311
/**
1312
 * xboxfb_setcolreg
1313
 * @regno: register index
1314
 * @red: red component
1315
 * @green: green component
1316
 * @blue: blue component
1317
 * @transp: transparency
1318
 * @info: pointer to fb_info object containing info for current riva board
1319
 *
1320
 * DESCRIPTION:
1321
 * Set a single color register. The values supplied have a 16 bit
1322
 * magnitude.
1323
 *
1324
 * RETURNS:
1325
 * Return != 0 for invalid regno.
1326
 *
1327
 * CALLED FROM:
1328
 * fbcmap.c:fb_set_cmap()
1329
 */
1330
static int xboxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1331
			  unsigned blue, unsigned transp,
1332
			  struct fb_info *info)
1333
{
1334
	struct riva_par *par = (struct riva_par *)info->par;
1335
	RIVA_HW_INST *chip = &par->riva;
1336
	int i;
1337
1338
	if (regno >= riva_get_cmap_len(&info->var))
1339
		return -EINVAL;
1340
1341
	if (info->var.grayscale) {
1342
		/* gray = 0.30*R + 0.59*G + 0.11*B */
1343
		red = green = blue =
1344
		    (red * 77 + green * 151 + blue * 28) >> 8;
1345
	}
1346
1347
	switch (info->var.bits_per_pixel) {
1348
	case 8:
1349
		/* "transparent" stuff is completely ignored. */
1350
		riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1351
		break;
1352
	case 16:
1353
		if (info->var.green.length == 5) {
1354
			if (regno < 16) {
1355
				/* 0rrrrrgg gggbbbbb */
1356
				((u32 *)info->pseudo_palette)[regno] =
1357
					((red & 0xf800) >> 1) |
1358
					((green & 0xf800) >> 6) |
1359
					((blue & 0xf800) >> 11);
1360
			}
1361
			for (i = 0; i < 8; i++) 
1362
				riva_wclut(chip, regno*8+i, red >> 8,
1363
					   green >> 8, blue >> 8);
1364
		} else {
1365
			u8 r, g, b;
1366
1367
			if (regno < 16) {
1368
				/* rrrrrggg gggbbbbb */
1369
				((u32 *)info->pseudo_palette)[regno] =
1370
					((red & 0xf800) >> 0) |
1371
					((green & 0xf800) >> 5) |
1372
					((blue & 0xf800) >> 11);
1373
			}
1374
			if (regno < 32) {
1375
				for (i = 0; i < 8; i++) {
1376
					riva_wclut(chip, regno*8+i, red >> 8, 
1377
						   green >> 8, blue >> 8);
1378
				}
1379
			}
1380
			for (i = 0; i < 4; i++) {
1381
				riva_rclut(chip, regno*2+i, &r, &g, &b);
1382
				riva_wclut(chip, regno*4+i, r, green >> 8, b);
1383
			}
1384
		}
1385
		break;
1386
	case 32:
1387
		if (regno < 16) {
1388
			((u32 *)info->pseudo_palette)[regno] =
1389
				((red & 0xff00) << 8) |
1390
				((green & 0xff00)) | ((blue & 0xff00) >> 8);
1391
			
1392
		}
1393
		riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1394
		break;
1395
	default:
1396
		/* do nothing */
1397
		break;
1398
	}
1399
	return 0;
1400
}
1401
1402
/**
1403
 * xboxfb_fillrect - hardware accelerated color fill function
1404
 * @info: pointer to fb_info structure
1405
 * @rect: pointer to fb_fillrect structure
1406
 *
1407
 * DESCRIPTION:
1408
 * This function fills up a region of framebuffer memory with a solid
1409
 * color with a choice of two different ROP's, copy or invert.
1410
 *
1411
 * CALLED FROM:
1412
 * framebuffer hook
1413
 */
1414
static void xboxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
1415
{
1416
	struct riva_par *par = (struct riva_par *) info->par;
1417
	u_int color, rop = 0;
1418
1419
	if (info->var.bits_per_pixel == 8)
1420
		color = rect->color;
1421
	else
1422
		color = ((u32 *)info->pseudo_palette)[rect->color];
1423
1424
	switch (rect->rop) {
1425
	case ROP_XOR:
1426
		rop = 0x66;
1427
		break;
1428
	case ROP_COPY:
1429
	default:
1430
		rop = 0xCC;
1431
		break;
1432
	}
1433
1434
	RIVA_FIFO_FREE(par->riva, Rop, 1);
1435
	par->riva.Rop->Rop3 = rop;
1436
1437
	RIVA_FIFO_FREE(par->riva, Bitmap, 1);
1438
	par->riva.Bitmap->Color1A = color;
1439
1440
	RIVA_FIFO_FREE(par->riva, Bitmap, 2);
1441
	par->riva.Bitmap->UnclippedRectangle[0].TopLeft =
1442
			(rect->dx << 16) | rect->dy;
1443
	par->riva.Bitmap->UnclippedRectangle[0].WidthHeight =
1444
			(rect->width << 16) | rect->height;
1445
	RIVA_FIFO_FREE(par->riva, Rop, 1);
1446
	par->riva.Rop->Rop3 = 0xCC;	/* back to COPY */
1447
}
1448
1449
/**
1450
 * xboxfb_copyarea - hardware accelerated blit function
1451
 * @info: pointer to fb_info structure
1452
 * @region: pointer to fb_copyarea structure
1453
 *
1454
 * DESCRIPTION:
1455
 * This copies an area of pixels from one location to another
1456
 *
1457
 * CALLED FROM:
1458
 * framebuffer hook
1459
 */
1460
static void xboxfb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
1461
{
1462
	struct riva_par *par = (struct riva_par *) info->par;
1463
1464
	RIVA_FIFO_FREE(par->riva, Blt, 3);
1465
	par->riva.Blt->TopLeftSrc  = (region->sy << 16) | region->sx;
1466
	par->riva.Blt->TopLeftDst  = (region->dy << 16) | region->dx;
1467
	par->riva.Blt->WidthHeight = (region->height << 16) | region->width;
1468
	wait_for_idle(par);
1469
}
1470
1471
static inline void convert_bgcolor_16(u32 *col)
1472
{
1473
	*col = ((*col & 0x00007C00) << 9)
1474
		| ((*col & 0x000003E0) << 6)
1475
		| ((*col & 0x0000001F) << 3)
1476
		|	   0xFF000000;
1477
}
1478
1479
/**
1480
 * xboxfb_imageblit: hardware accelerated color expand function
1481
 * @info: pointer to fb_info structure
1482
 * @image: pointer to fb_image structure
1483
 *
1484
 * DESCRIPTION:
1485
 * If the source is a monochrome bitmap, the function fills up a a region
1486
 * of framebuffer memory with pixels whose color is determined by the bit
1487
 * setting of the bitmap, 1 - foreground, 0 - background.
1488
 *
1489
 * If the source is not a monochrome bitmap, color expansion is not done.
1490
 * In this case, it is channeled to a software function.
1491
 *
1492
 * CALLED FROM:
1493
 * framebuffer hook
1494
 */
1495
static void xboxfb_imageblit(struct fb_info *info, 
1496
			     const struct fb_image *image)
1497
{
1498
	struct riva_par *par = (struct riva_par *) info->par;
1499
	u32 fgx = 0, bgx = 0, width, tmp;
1500
	u8 *cdat = (u8 *) image->data;
1501
	volatile u32 *d;
1502
	int i, size;
1503
1504
	if (image->depth != 1) {
1505
		cfb_imageblit(info, image);
1506
		return;
1507
	}
1508
1509
	switch (info->var.bits_per_pixel) {
1510
	case 8:
1511
		fgx = image->fg_color;
1512
		bgx = image->bg_color;
1513
		break;
1514
	case 16:
1515
		fgx = ((u32 *)info->pseudo_palette)[image->fg_color];
1516
		bgx = ((u32 *)info->pseudo_palette)[image->bg_color];
1517
		if (info->var.green.length == 6)
1518
			convert_bgcolor_16(&bgx);	
1519
		break;
1520
	case 32:
1521
		fgx = ((u32 *)info->pseudo_palette)[image->fg_color];
1522
		bgx = ((u32 *)info->pseudo_palette)[image->bg_color];
1523
		break;
1524
	}
1525
1526
	RIVA_FIFO_FREE(par->riva, Bitmap, 7);
1527
	par->riva.Bitmap->ClipE.TopLeft     = 
1528
		(image->dy << 16) | (image->dx & 0xFFFF);
1529
	par->riva.Bitmap->ClipE.BottomRight = 
1530
		(((image->dy + image->height) << 16) |
1531
		 ((image->dx + image->width) & 0xffff));
1532
	par->riva.Bitmap->Color0E           = bgx;
1533
	par->riva.Bitmap->Color1E           = fgx;
1534
	par->riva.Bitmap->WidthHeightInE    = 
1535
		(image->height << 16) | ((image->width + 31) & ~31);
1536
	par->riva.Bitmap->WidthHeightOutE   = 
1537
		(image->height << 16) | ((image->width + 31) & ~31);
1538
	par->riva.Bitmap->PointE            = 
1539
		(image->dy << 16) | (image->dx & 0xFFFF);
1540
1541
	d = &par->riva.Bitmap->MonochromeData01E;
1542
1543
	width = (image->width + 31)/32;
1544
	size = width * image->height;
1545
	while (size >= 16) {
1546
		RIVA_FIFO_FREE(par->riva, Bitmap, 16);
1547
		for (i = 0; i < 16; i++) {
1548
			tmp = *((u32 *)cdat);
1549
			cdat = (u8 *)((u32 *)cdat + 1);
1550
			reverse_order(&tmp);
1551
			d[i] = tmp;
1552
		}
1553
		size -= 16;
1554
	}
1555
	if (size) {
1556
		RIVA_FIFO_FREE(par->riva, Bitmap, size);
1557
		for (i = 0; i < size; i++) {
1558
			tmp = *((u32 *) cdat);
1559
			cdat = (u8 *)((u32 *)cdat + 1);
1560
			reverse_order(&tmp);
1561
			d[i] = tmp;
1562
		}
1563
	}
1564
}
1565
1566
/**
1567
 * xboxfb_cursor - hardware cursor function
1568
 * @info: pointer to info structure
1569
 * @cursor: pointer to fbcursor structure
1570
 *
1571
 * DESCRIPTION:
1572
 * A cursor function that supports displaying a cursor image via hardware.
1573
 * Within the kernel, copy and invert rops are supported.  If exported
1574
 * to user space, only the copy rop will be supported.
1575
 *
1576
 * CALLED FROM
1577
 * framebuffer hook
1578
 */
1579
static int xboxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1580
{
1581
	struct riva_par *par = (struct riva_par *) info->par;
1582
	u8 mask[MAX_CURS * MAX_CURS/8];
1583
	u16 fg, bg;
1584
1585
	par->riva.ShowHideCursor(&par->riva, 0);
1586
1587
	if (cursor->set & FB_CUR_SETPOS) {
1588
		u32 xx, yy, temp;
1589
1590
		info->cursor.image.dx = cursor->image.dx;
1591
		info->cursor.image.dy = cursor->image.dy;
1592
		yy = cursor->image.dy - info->var.yoffset;
1593
		xx = cursor->image.dx - info->var.xoffset;
1594
		temp = xx & 0xFFFF;
1595
		temp |= yy << 16;
1596
1597
		par->riva.PRAMDAC[0x0000300/4] = temp;
1598
	}
1599
1600
	if (cursor->set & FB_CUR_SETSIZE) {
1601
		info->cursor.image.height = cursor->image.height;
1602
		info->cursor.image.width = cursor->image.width;
1603
		memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
1604
	}
1605
1606
	if (cursor->set & FB_CUR_SETCMAP) {
1607
		info->cursor.image.bg_color = cursor->image.bg_color;
1608
		info->cursor.image.fg_color = cursor->image.fg_color;
1609
	}
1610
1611
	if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP)) {
1612
		u32 bg_idx = info->cursor.image.bg_color;
1613
		u32 fg_idx = info->cursor.image.fg_color;
1614
		u32 s_pitch = (info->cursor.image.width+7) >> 3;
1615
		u32 d_pitch = MAX_CURS/8;
1616
		u8 *msk = (u8 *) info->cursor.mask;
1617
		
1618
		fb_move_buf_aligned(info, &info->sprite, mask, d_pitch, msk, s_pitch, info->cursor.image.height);
1619
		bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
1620
		     ((info->cmap.green[bg_idx] & 0xf8) << 2) |
1621
		     ((info->cmap.blue[bg_idx] & 0xf8) >> 3);
1622
1623
		fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
1624
		     ((info->cmap.green[fg_idx] & 0xf8) << 2) |
1625
		     ((info->cmap.blue[fg_idx] & 0xf8) >> 3);
1626
1627
		par->riva.LockUnlock(&par->riva, 0);
1628
1629
		xboxfb_load_cursor_image(par, mask, mask, bg, fg,
1630
					 info->cursor.image.width, 
1631
					 info->cursor.image.height);
1632
	}
1633
	if (info->cursor.enable)
1634
		par->riva.ShowHideCursor(&par->riva, 1);
1635
	return 0;
1636
}
1637
1638
static int xboxfb_sync(struct fb_info *info)
1639
{
1640
	struct riva_par *par = (struct riva_par *)info->par;
1641
1642
	wait_for_idle(par);
1643
	return 0;
1644
}
1645
1646
static int xboxfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
1647
                        unsigned long arg, struct fb_info *info)
1648
{
1649
	struct riva_par *par = (struct riva_par *) info->par;
1650
	
1651
	xbox_overscan overscan;
1652
	xboxfb_config config;
1653
	xbox_tv_encoding encoding;
1654
	int ret = 0;
1655
1656
	switch (cmd) {
1657
	case FBIO_XBOX_SET_OVERSCAN:
1658
		if(!copy_from_user(&overscan, (xbox_overscan*)arg, sizeof(overscan))) {
1659
			par->hoc = overscan.hoc;
1660
			par->voc = overscan.voc;
1661
			riva_load_video_mode (info);
1662
			if (info->var.accel_flags & FB_ACCELF_TEXT) {
1663
				riva_setup_accel(par);
1664
			}
1665
1666
		}
1667
		else {
1668
			ret = -EFAULT;
1669
		}
1670
	break;
1671
	case FBIO_XBOX_GET_OVERSCAN:
1672
		overscan.hoc = par->hoc;
1673
		overscan.voc = par->voc;
1674
		if (copy_to_user((xbox_overscan*)arg, &overscan, sizeof(overscan))) {
1675
			ret = -EFAULT;
1676
		}
1677
	break;
1678
	case FBIO_XBOX_GET_CONFIG:
1679
		config.av_type = par->av_type;
1680
		config.encoder_type = par->video_encoder;
1681
		if (copy_to_user((xboxfb_config*)arg, &config, sizeof(config))) {
1682
			ret = -EFAULT;
1683
		}
1684
	break;
1685
	case FBIO_XBOX_GET_TV_ENCODING:
1686
		encoding = par->tv_encoding;
1687
		if (copy_to_user((xbox_tv_encoding*)arg, &encoding, sizeof(encoding))) {
1688
			ret = -EFAULT;
1689
		}
1690
	break;
1691
	case FBIO_XBOX_SET_TV_ENCODING:
1692
		if(!copy_from_user(&encoding, (xbox_tv_encoding*)arg, sizeof(encoding))) {
1693
			par->tv_encoding = encoding;
1694
			riva_load_video_mode (info);
1695
			if (info->var.accel_flags & FB_ACCELF_TEXT) {
1696
				riva_setup_accel(par);
1697
			}
1698
		}
1699
		else {
1700
			ret = -EFAULT;
1701
		}
1702
	break;
1703
	default:
1704
		ret = -EINVAL;
1705
	}
1706
	return ret;
1707
}
1708
1709
1710
/* ------------------------------------------------------------------------- *
1711
 *
1712
 * initialization helper functions
1713
 *
1714
 * ------------------------------------------------------------------------- */
1715
1716
/* kernel interface */
1717
static struct fb_ops riva_fb_ops = {
1718
	.owner 		= THIS_MODULE,
1719
	.fb_open	= xboxfb_open,
1720
	.fb_release	= xboxfb_release,
1721
	.fb_check_var 	= xboxfb_check_var,
1722
	.fb_set_par 	= xboxfb_set_par,
1723
	.fb_setcolreg 	= xboxfb_setcolreg,
1724
	.fb_pan_display	= xboxfb_pan_display,
1725
	.fb_blank 	= xboxfb_blank,
1726
	.fb_fillrect 	= xboxfb_fillrect,
1727
	.fb_copyarea 	= xboxfb_copyarea,
1728
	.fb_imageblit 	= xboxfb_imageblit,
1729
	.fb_cursor	= xboxfb_cursor,
1730
	.fb_sync 	= xboxfb_sync,
1731
	.fb_ioctl	= xboxfb_ioctl,
1732
};
1733
1734
static int __devinit riva_set_fbinfo(struct fb_info *info)
1735
{
1736
	struct riva_par *par = (struct riva_par *) info->par;
1737
	unsigned int cmap_len;
1738
1739
	info->flags = FBINFO_FLAG_DEFAULT;
1740
	info->var = xboxfb_default_var;
1741
	info->fix = xboxfb_fix;
1742
	info->fbops = &riva_fb_ops;
1743
	info->pseudo_palette = pseudo_palette;
1744
1745
#ifndef MODULE
1746
	if (mode_option)
1747
	{
1748
		if (!strncmp(mode_option, "480p", 4)) {
1749
			info->var = xboxfb_mode_480p;
1750
		}
1751
		else if (!strncmp(mode_option, "720p", 4)) {
1752
			info->var = xboxfb_mode_720p;
1753
		}
1754
		else {
1755
			fb_find_mode(&info->var, info, mode_option,
1756
				NULL, 0, NULL, 8);
1757
		}
1758
	}
1759
#endif
1760
	if (par->use_default_var)
1761
		/* We will use the modified default var */
1762
		info->var = xboxfb_default_var;
1763
1764
	cmap_len = riva_get_cmap_len(&info->var);
1765
	fb_alloc_cmap(&info->cmap, cmap_len, 0);	
1766
1767
	info->pixmap.size = 64 * 1024;
1768
	info->pixmap.buf_align = 4;
1769
	info->pixmap.scan_align = 4;
1770
	info->pixmap.flags = FB_PIXMAP_SYSTEM;
1771
	return 0;
1772
}
1773
1774
#ifdef CONFIG_PPC_OF
1775
static int riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
1776
{
1777
	struct riva_par *par = (struct riva_par *) info->par;
1778
	struct device_node *dp;
1779
	unsigned char *pedid = NULL;
1780
1781
	dp = pci_device_to_OF_node(pd);
1782
	pedid = (unsigned char *)get_property(dp, "EDID,B", 0);
1783
1784
	if (pedid) {
1785
		par->EDID = pedid;
1786
		return 1;
1787
	} else
1788
		return 0;
1789
}
1790
#endif /* CONFIG_PPC_OF */
1791
1792
static int riva_dfp_parse_EDID(struct riva_par *par)
1793
{
1794
	unsigned char *block = par->EDID;
1795
1796
	if (!block)
1797
		return 0;
1798
1799
	/* jump to detailed timing block section */
1800
	block += 54;
1801
1802
	par->clock = (block[0] + (block[1] << 8));
1803
	par->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
1804
	par->hblank = (block[3] + ((block[4] & 0x0f) << 8));
1805
	par->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
1806
	par->vblank = (block[6] + ((block[7] & 0x0f) << 8));
1807
	par->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
1808
	par->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
1809
	par->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
1810
	par->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
1811
	par->interlaced = ((block[17] & 0x80) >> 7);
1812
	par->synct = ((block[17] & 0x18) >> 3);
1813
	par->misc = ((block[17] & 0x06) >> 1);
1814
	par->hAct_high = par->vAct_high = 0;
1815
	if (par->synct == 3) {
1816
		if (par->misc & 2)
1817
			par->hAct_high = 1;
1818
		if (par->misc & 1)
1819
			par->vAct_high = 1;
1820
	}
1821
1822
	printk(KERN_INFO PFX
1823
			"detected DFP panel size from EDID: %dx%d\n", 
1824
			par->panel_xres, par->panel_yres);
1825
	par->got_dfpinfo = 1;
1826
	return 1;
1827
}
1828
1829
static void riva_update_default_var(struct fb_info *info)
1830
{
1831
	struct fb_var_screeninfo *var = &xboxfb_default_var;
1832
	struct riva_par *par = (struct riva_par *) info->par;
1833
1834
        var->xres = par->panel_xres;
1835
        var->yres = par->panel_yres;
1836
        var->xres_virtual = par->panel_xres;
1837
        var->yres_virtual = par->panel_yres;
1838
        var->xoffset = var->yoffset = 0;
1839
        var->bits_per_pixel = 8;
1840
        var->pixclock = 100000000 / par->clock;
1841
        var->left_margin = (par->hblank - par->hOver_plus - par->hSync_width);
1842
        var->right_margin = par->hOver_plus;
1843
        var->upper_margin = (par->vblank - par->vOver_plus - par->vSync_width);
1844
        var->lower_margin = par->vOver_plus;
1845
        var->hsync_len = par->hSync_width;
1846
        var->vsync_len = par->vSync_width;
1847
        var->sync = 0;
1848
1849
        if (par->synct == 3) {
1850
                if (par->hAct_high)
1851
                        var->sync |= FB_SYNC_HOR_HIGH_ACT;
1852
                if (par->vAct_high)
1853
                        var->sync |= FB_SYNC_VERT_HIGH_ACT;
1854
        }
1855
 
1856
        var->vmode = 0;
1857
        if (par->interlaced)
1858
                var->vmode |= FB_VMODE_INTERLACED;
1859
1860
	var->accel_flags |= FB_ACCELF_TEXT;
1861
        
1862
        par->use_default_var = 1;
1863
}
1864
1865
1866
static void riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
1867
{
1868
#ifdef CONFIG_PPC_OF
1869
	if (!riva_get_EDID_OF(info, pdev))
1870
		printk("xboxfb: could not retrieve EDID from OF\n");
1871
#else
1872
	/* XXX use other methods later */
1873
#endif
1874
}
1875
1876
1877
static void riva_get_dfpinfo(struct fb_info *info)
1878
{
1879
	struct riva_par *par = (struct riva_par *) info->par;
1880
1881
	if (riva_dfp_parse_EDID(par))
1882
		riva_update_default_var(info);
1883
1884
	/* if user specified flatpanel, we respect that */
1885
	if (par->got_dfpinfo == 1)
1886
		par->FlatPanel = 1;
1887
}
1888
1889
/* ------------------------------------------------------------------------- *
1890
 *
1891
 * PCI bus
1892
 *
1893
 * ------------------------------------------------------------------------- */
1894
1895
static int __devinit xboxfb_probe(struct pci_dev *pd,
1896
			     	const struct pci_device_id *ent)
1897
{
1898
	struct riva_chip_info *rci = &riva_chip_info[ent->driver_data];
1899
	struct riva_par *default_par;
1900
	struct fb_info *info;
1901
	unsigned long fb_start;
1902
	unsigned long fb_size;
1903
1904
	assert(pd != NULL);
1905
	assert(rci != NULL);
1906
1907
	info = kmalloc(sizeof(struct fb_info), GFP_KERNEL);
1908
	if (!info)
1909
		goto err_out;
1910
1911
	default_par = kmalloc(sizeof(struct riva_par), GFP_KERNEL);
1912
	if (!default_par)
1913
		goto err_out_kfree;
1914
1915
	memset(info, 0, sizeof(struct fb_info));
1916
	memset(default_par, 0, sizeof(struct riva_par));
1917
1918
	info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL);
1919
	if (info->pixmap.addr == NULL)
1920
		goto err_out_kfree1;
1921
	memset(info->pixmap.addr, 0, 64 * 1024);
1922
1923
	strcat(xboxfb_fix.id, rci->name);
1924
	default_par->riva.Architecture = rci->arch_rev;
1925
1926
	default_par->Chipset = (pd->vendor << 16) | pd->device;
1927
	printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset);
1928
	
1929
	default_par->FlatPanel = flatpanel;
1930
	if (flatpanel == 1)
1931
		printk(KERN_INFO PFX "flatpanel support enabled\n");
1932
	default_par->forceCRTC = forceCRTC;
1933
	
1934
	xboxfb_fix.mmio_len = pci_resource_len(pd, 0);
1935
1936
	{
1937
		/* enable IO and mem if not already done */
1938
		unsigned short cmd;
1939
1940
		pci_read_config_word(pd, PCI_COMMAND, &cmd);
1941
		cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
1942
		pci_write_config_word(pd, PCI_COMMAND, cmd);
1943
	}
1944
	
1945
	xboxfb_fix.mmio_start = pci_resource_start(pd, 0);
1946
	xboxfb_fix.smem_start = pci_resource_start(pd, 1);
1947
	
1948
        if (xbox_memory_size() == 64*1024*1024) printk(KERN_INFO PFX "Detected 64MB of system RAM\n");
1949
	else printk(KERN_INFO PFX "Detected 128MB of system RAM\n");
1950
	
1951
	fb_size = available_framebuffer_memory();
1952
	fb_start = xbox_memory_size() - fb_size;
1953
	printk(KERN_INFO PFX "Using %dM framebuffer memory\n", (int)(fb_size/(1024*1024)));
1954
	default_par->riva_fb_start = fb_start;
1955
	xboxfb_fix.smem_start += fb_start;
1956
	xboxfb_fix.smem_len = fb_size; 
1957
	tv_init();
1958
	if (tv_encoding == TV_ENC_INVALID) {
1959
		tv_encoding = get_tv_encoding();
1960
		printk(KERN_INFO PFX "Setting TV mode from EEPROM (%s)\n", tvEncodingNames[tv_encoding]);
1961
	}
1962
	default_par->tv_encoding = tv_encoding;
1963
	default_par->video_encoder = tv_get_video_encoder();
1964
	switch(default_par->video_encoder) {
1965
		case ENCODER_CONEXANT:
1966
			printk(KERN_INFO PFX "detected conexant encoder\n");
1967
			break;
1968
		case ENCODER_FOCUS:
1969
			printk(KERN_INFO PFX "detected focus encoder\n");
1970
			break;
1971
		case ENCODER_XLB:
1972
			printk(KERN_INFO PFX "detected Xcalibur encoder\n");
1973
			break;
1974
		default: 
1975
			printk(KERN_INFO PFX "detected unknown encoder\n");
1976
	}
1977
	
1978
	
1979
	if (av_type == AV_INVALID) {
1980
		av_type = detect_av_type();
1981
		printk(KERN_INFO PFX "Setting cable type from AVIP ID: %s\n", avTypeNames[av_type]);
1982
	}
1983
	default_par->av_type = av_type;
1984
	if ((hoc < 0) || (hoc > 20)) {
1985
		hoc = 10;
1986
	}
1987
	default_par->hoc = hoc / 100.0;
1988
	if ((voc < 0) || (voc > 20)) {
1989
		voc = 10;
1990
	}
1991
	default_par->voc = voc / 100.0;
1992
	
1993
	if (!request_mem_region(xboxfb_fix.mmio_start,
1994
				xboxfb_fix.mmio_len, "xboxfb")) {
1995
		printk(KERN_ERR PFX "cannot reserve MMIO region\n");
1996
		goto err_out_kfree2;
1997
	}
1998
1999
	default_par->ctrl_base = ioremap(xboxfb_fix.mmio_start,
2000
					 xboxfb_fix.mmio_len);
2001
	if (!default_par->ctrl_base) {
2002
		printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
2003
		goto err_out_free_base0;
2004
	}
2005
2006
	info->par = default_par;
2007
2008
	riva_get_EDID(info, pd);
2009
2010
	riva_get_dfpinfo(info);
2011
2012
	switch (default_par->riva.Architecture) {
2013
	case NV_ARCH_03:
2014
		/* Riva128's PRAMIN is in the "framebuffer" space
2015
		 * Since these cards were never made with more than 8 megabytes
2016
		 * we can safely allocate this separately.
2017
		 */
2018
		if (!request_mem_region(xboxfb_fix.smem_start + 0x00C00000,
2019
					 0x00008000, "xboxfb")) {
2020
			printk(KERN_ERR PFX "cannot reserve PRAMIN region\n");
2021
			goto err_out_iounmap_ctrl;
2022
		}
2023
		default_par->riva.PRAMIN = ioremap(xboxfb_fix.smem_start + 0x00C00000, 0x00008000);
2024
		if (!default_par->riva.PRAMIN) {
2025
			printk(KERN_ERR PFX "cannot ioremap PRAMIN region\n");
2026
			goto err_out_free_nv3_pramin;
2027
		}
2028
		xboxfb_fix.accel = FB_ACCEL_NV3;
2029
		break;
2030
	case NV_ARCH_04:
2031
	case NV_ARCH_10:
2032
	case NV_ARCH_20:
2033
		default_par->riva.PCRTC0 = (unsigned *)(default_par->ctrl_base + 0x00600000);
2034
		default_par->riva.PRAMIN = (unsigned *)(default_par->ctrl_base + 0x00710000);
2035
		xboxfb_fix.accel = FB_ACCEL_NV4;
2036
		break;
2037
	}
2038
2039
	riva_common_setup(default_par);
2040
2041
	if (default_par->riva.Architecture == NV_ARCH_03) {
2042
		default_par->riva.PCRTC = default_par->riva.PCRTC0 = default_par->riva.PGRAPH;
2043
	}
2044
2045
	/* xboxfb_fix.smem_len = riva_get_memlen(default_par) * 1024; */
2046
	default_par->dclk_max = riva_get_maxdclk(default_par) * 1000;
2047
2048
	if (!request_mem_region(xboxfb_fix.smem_start, xboxfb_fix.smem_len, "xboxfb")) {
2049
		printk(KERN_ERR PFX "cannot reserve FB region\n");
2050
		goto err_out_iounmap_nv3_pramin;
2051
	}
2052
	
2053
	info->screen_base = ioremap(xboxfb_fix.smem_start, fb_size);
2054
	if (!info->screen_base) {
2055
		printk(KERN_ERR PFX "cannot ioremap FB base\n");
2056
		goto err_out_free_base1;
2057
	}
2058
2059
#ifdef CONFIG_MTRR
2060
	if (!nomtrr) {
2061
		default_par->mtrr.vram = mtrr_add(xboxfb_fix.smem_start, fb_size,
2062
			MTRR_TYPE_WRCOMB, 1);
2063
		if (default_par->mtrr.vram < 0) {
2064
			printk(KERN_ERR PFX "unable to setup MTRR\n");
2065
		} else {
2066
			default_par->mtrr.vram_valid = 1;
2067
			/* let there be speed */
2068
			printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
2069
		}
2070
	}
2071
#endif /* CONFIG_MTRR */
2072
2073
	if (riva_set_fbinfo(info) < 0) {
2074
		printk(KERN_ERR PFX "error setting initial video mode\n");
2075
		goto err_out_iounmap_fb;
2076
	}
2077
2078
	if (register_framebuffer(info) < 0) {
2079
		printk(KERN_ERR PFX
2080
			"error registering riva framebuffer\n");
2081
		goto err_out_iounmap_fb;
2082
	}
2083
2084
	pci_set_drvdata(pd, info);
2085
2086
	printk(KERN_INFO PFX
2087
		"PCI nVidia NV%x framebuffer ver %s (%s, %ldMB @ 0x%lX)\n",
2088
		default_par->riva.Architecture,
2089
		RIVAFB_VERSION,
2090
		info->fix.id,
2091
		fb_size / (1024 * 1024),
2092
		info->fix.smem_start);
2093
	return 0;
2094
2095
err_out_iounmap_fb:
2096
	iounmap(info->screen_base);
2097
err_out_free_base1:
2098
	release_mem_region(xboxfb_fix.smem_start, fb_size);
2099
err_out_iounmap_nv3_pramin:
2100
	if (default_par->riva.Architecture == NV_ARCH_03) 
2101
		iounmap((caddr_t)default_par->riva.PRAMIN);
2102
err_out_free_nv3_pramin:
2103
	if (default_par->riva.Architecture == NV_ARCH_03)
2104
		release_mem_region(xboxfb_fix.smem_start + 0x00C00000, 0x00008000);
2105
err_out_iounmap_ctrl:
2106
	iounmap(default_par->ctrl_base);
2107
err_out_free_base0:
2108
	release_mem_region(xboxfb_fix.mmio_start, xboxfb_fix.mmio_len);
2109
err_out_kfree2:
2110
	kfree(info->pixmap.addr);
2111
err_out_kfree1:
2112
	kfree(default_par);
2113
err_out_kfree:
2114
	kfree(info);
2115
err_out:
2116
	return -ENODEV;
2117
}
2118
2119
static void __exit xboxfb_remove(struct pci_dev *pd)
2120
{
2121
	struct fb_info *info = pci_get_drvdata(pd);
2122
	struct riva_par *par = (struct riva_par *) info->par;
2123
	
2124
	if (!info)
2125
		return;
2126
2127
	unregister_framebuffer(info);
2128
#ifdef CONFIG_MTRR
2129
	if (par->mtrr.vram_valid)
2130
		mtrr_del(par->mtrr.vram, info->fix.smem_start, info->fix.smem_len);
2131
#endif /* CONFIG_MTRR */
2132
2133
	iounmap(par->ctrl_base);
2134
	iounmap(info->screen_base);
2135
2136
	release_mem_region(info->fix.mmio_start,
2137
			   info->fix.mmio_len);
2138
	release_mem_region(info->fix.smem_start, info->fix.smem_len);
2139
2140
	if (par->riva.Architecture == NV_ARCH_03) {
2141
		iounmap((caddr_t)par->riva.PRAMIN);
2142
		release_mem_region(info->fix.smem_start + 0x00C00000, 0x00008000);
2143
	}
2144
	kfree(info->pixmap.addr);
2145
	kfree(par);
2146
	kfree(info);
2147
	pci_set_drvdata(pd, NULL);
2148
}
2149
2150
/* ------------------------------------------------------------------------- *
2151
 *
2152
 * initialization
2153
 *
2154
 * ------------------------------------------------------------------------- */
2155
2156
#ifndef MODULE
2157
int __init xboxfb_setup(char *options)
2158
{
2159
	char *this_opt;
2160
2161
	if (!options || !*options)
2162
		return 0;
2163
2164
	while ((this_opt = strsep(&options, ",")) != NULL) {
2165
		if (!strncmp(this_opt, "forceCRTC", 9)) {
2166
			char *p;
2167
			
2168
			p = this_opt + 9;
2169
			if (!*p || !*(++p)) continue; 
2170
			forceCRTC = *p - '0';
2171
			if (forceCRTC < 0 || forceCRTC > 1) 
2172
				forceCRTC = -1;
2173
		} else if (!strncmp(this_opt, "flatpanel", 9)) {
2174
			flatpanel = 1;
2175
#ifdef CONFIG_MTRR
2176
		} else if (!strncmp(this_opt, "nomtrr", 6)) {
2177
			nomtrr = 1;
2178
#endif
2179
		} else if (!strncmp(this_opt, "tv=", 3)) {
2180
				if(!strncmp(this_opt + 3, "PAL", 3)) {
2181
						tv_encoding = TV_ENC_PALBDGHI;
2182
				}
2183
				else if(!strncmp(this_opt + 3, "NTSC", 4)) {
2184
						tv_encoding = TV_ENC_NTSC;
2185
				}
2186
				else if(!strncmp(this_opt + 3, "VGA", 3)) {
2187
						av_type = AV_VGA_SOG;
2188
				}
2189
		} else if (!strncmp(this_opt, "hoc=", 4)) {
2190
				sscanf(this_opt+4, "%d", &hoc);
2191
		} else if (!strncmp(this_opt, "voc=", 4)) {
2192
				sscanf(this_opt+4, "%d", &voc);
2193
		} else
2194
			mode_option = this_opt;
2195
	}
2196
	return 0;
2197
}
2198
#endif /* !MODULE */
2199
2200
static struct pci_driver xboxfb_driver = {
2201
	.name		= "xboxfb",
2202
	.id_table	= xboxfb_pci_tbl,
2203
	.probe		= xboxfb_probe,
2204
	.remove		= __exit_p(xboxfb_remove),
2205
};
2206
2207
2208
2209
/* ------------------------------------------------------------------------- *
2210
 *
2211
 * modularization
2212
 *
2213
 * ------------------------------------------------------------------------- */
2214
2215
int __init xboxfb_init(void)
2216
{
2217
	if (pci_register_driver(&xboxfb_driver) > 0)
2218
		return 0;
2219
	pci_unregister_driver(&xboxfb_driver);
2220
	return -ENODEV;
2221
}
2222
2223
2224
#ifdef MODULE
2225
static void __exit xboxfb_exit(void)
2226
{
2227
	pci_unregister_driver(&xboxfb_driver);
2228
}
2229
2230
module_init(xboxfb_init);
2231
module_exit(xboxfb_exit);
2232
2233
MODULE_PARM(flatpanel, "i");
2234
MODULE_PARM_DESC(flatpanel, "Enables experimental flat panel support for some chipsets. (0 or 1=enabled) (default=0)");
2235
MODULE_PARM(forceCRTC, "i");
2236
MODULE_PARM_DESC(forceCRTC, "Forces usage of a particular CRTC in case autodetection fails. (0 or 1) (default=autodetect)");
2237
2238
#ifdef CONFIG_MTRR
2239
MODULE_PARM(nomtrr, "i");
2240
MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
2241
#endif
2242
2243
MODULE_PARM(tv, "s");
2244
MODULE_PARM_DESC(tv, "Specifies the TV encoding (\"PAL\", \"NTSC\" or \"VGA\").");
2245
MODULE_PARM(hoc, "i");
2246
MODULE_PARM_DESC(hoc, "Horizontal overscan compensation ratio, in % (0-20)");
2247
MODULE_PARM(voc, "i");
2248
MODULE_PARM_DESC(voc, "Vertical overscan compensation ratio, in % (0-20)");
2249
2250
#endif /* MODULE */
2251
2252
MODULE_AUTHOR("Oliver Schwartz");
2253
MODULE_DESCRIPTION("Framebuffer driver for Xbox");
2254
MODULE_LICENSE("GPL");
(-)linux-2.6.6.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.6.orig/drivers/video/xbox/focus.h (+24 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
 * none
13
 */
14
15
16
#ifndef focus_h_
17
#define focus_h_
18
19
#include "encoder.h"
20
#include "xboxfb.h"
21
22
int focus_calc_mode(xbox_video_mode * mode, struct riva_regs * riva_out );
23
int focus_calc_hdtv_mode(xbox_hdtv_mode hdtv_mode, unsigned char pll_int, unsigned char * mode_out);
24
#endif
(-)linux-2.6.6.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.6.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.6.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.6.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.6.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.6.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.6.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.6.orig/drivers/video/xbox/xlb.c (+30 lines)
Line 0 Link Here
1
/*
2
 * linux/drivers/video/riva/xlb.c - Xbox driver for Xcalibur 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
 * It doesnt work!
13
*/
14
#include "xlb.h"
15
#include "encoder.h"
16
17
18
int xlb_calc_hdtv_mode(
19
	xbox_hdtv_mode hdtv_mode,
20
	unsigned char pll_int,
21
	unsigned char * regs
22
	){
23
24
	return 1;
25
}
26
27
int xlb_calc_mode(xbox_video_mode * mode, struct riva_regs * riva_out)
28
{
29
	return 1;
30
}
(-)linux-2.6.6.orig/drivers/video/xbox/xlb.h (+24 lines)
Line 0 Link Here
1
/*
2
 * linux/drivers/video/riva/xlb.c - Xbox driver for Xcalibur 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
 * none
13
 */
14
15
16
#ifndef xlb_h_
17
#define xlb_h_
18
19
#include "encoder.h"
20
#include "xboxfb.h"
21
22
int xlb_calc_mode(xbox_video_mode * mode, struct riva_regs * riva_out );
23
int xlb_calc_hdtv_mode(xbox_hdtv_mode hdtv_mode, unsigned char pll_int, unsigned char * mode_out);
24
#endif
(-)linux-2.6.6.orig/fs/Kconfig (+20 lines)
Lines 667-672 Link Here
667
	  (the one containing the directory /) cannot be a module, so saying M
667
	  (the one containing the directory /) cannot be a module, so saying M
668
	  could be dangerous.  If unsure, say N.
668
	  could be dangerous.  If unsure, say N.
669
669
670
config FATX_FS
671
	tristate "FATX filesystem support (EXPERIMENTAL)"
672
	depends on EXPERIMENTAL && !LBD
673
	help
674
	  This adds support for the FATX filesystem as found in Microsoft's Xbox.
675
	  
676
	  The FATX filesystem is a derivative of the FAT filesystem minus some
677
	  legacy fields and redundant information. For lengthier discussions on
678
	  the filesystem, see:
679
	  
680
	  http://xbox-linux.sourceforge.net/docs/fatxfat.html
681
	  http://xbox-linux.sourceforge.net/docs/hdpartfs.html
682
	  http://xbox-linux.sourceforge.net/docs/hackingfatx.html
683
	  
684
	  If you are running Linux on the Xbox, choose Y unless you know
685
	  what you're doing. Otherwise, choose N.
686
	  
687
	  To compile this filesystem support as a module, choose M here: the
688
	  module will be called fatx.
689
670
config NTFS_FS
690
config NTFS_FS
671
	tristate "NTFS file system support"
691
	tristate "NTFS file system support"
672
	select NLS
692
	select NLS
(-)linux-2.6.6.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.6.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.6.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.6.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.6.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.6.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.6.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.6.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.6.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.6.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.6.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.6.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.6.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.6.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.6.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.6.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.6.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 = 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.6.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.6.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.6.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.6.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.6.orig/include/linux/pci_ids.h (+1 lines)
Lines 1100-1105 Link Here
1100
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL	0x0258
1100
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL	0x0258
1101
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL	0x0259
1101
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL	0x0259
1102
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL	0x025B
1102
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL	0x025B
1103
#define PCI_DEVICE_ID_NVIDIA_IGEFORCE3		0x02a0
1103
1104
1104
#define PCI_VENDOR_ID_IMS		0x10e0
1105
#define PCI_VENDOR_ID_IMS		0x10e0
1105
#define PCI_DEVICE_ID_IMS_8849		0x8849
1106
#define PCI_DEVICE_ID_IMS_8849		0x8849
(-)linux-2.6.6.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.6.orig/include/linux/xboxfbctl.h (+67 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
	ENCODER_XLB
46
} xbox_encoder_type;
47
48
typedef struct _xboxOverscan {
49
	double hoc;
50
	double voc;
51
} xbox_overscan;
52
53
typedef struct _xboxFbConfig {
54
	xbox_av_type av_type;
55
	xbox_encoder_type encoder_type;
56
} xboxfb_config;
57
58
#define FBIO_XBOX_GET_OVERSCAN  _IOR('x', 1, xbox_overscan)
59
/* in param: double  hoc (0.0-0.2), double voc (0.0 - 0.2) */
60
#define FBIO_XBOX_SET_OVERSCAN  _IOW('x', 2, xbox_overscan)
61
62
#define FBIO_XBOX_GET_TV_ENCODING  _IOR('x', 3, xbox_tv_encoding)
63
#define FBIO_XBOX_SET_TV_ENCODING  _IOW('x', 4, xbox_tv_encoding)
64
65
#define FBIO_XBOX_GET_CONFIG  _IOR('x', 5, xboxfb_config)
66
67
#endif
(-)linux-2.6.6.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.6.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.6.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