aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-02 16:15:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-02 16:15:58 -0400
commit467cbd207abdbfe29514b5804a22661ab6e80dc6 (patch)
tree026a03bfcb0f755c5d61fcf288d98582ebd55093
parent7125764c5d1a5c72d522f1011b6cc8b8100b48fe (diff)
parentb5660ba76b41af69a0c09d434927bb4b4cadd4b1 (diff)
Merge branch 'x86-nuke-platforms-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 old platform removal from Peter Anvin: "This patchset removes support for several completely obsolete platforms, where the maintainers either have completely vanished or acked the removal. For some of them it is questionable if there even exists functional specimens of the hardware" Geert Uytterhoeven apparently thought this was a April Fool's pull request ;) * 'x86-nuke-platforms-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86, platforms: Remove NUMAQ x86, platforms: Remove SGI Visual Workstation x86, apic: Remove support for IBM Summit/EXA chipset x86, apic: Remove support for ia32-based Unisys ES7000
-rw-r--r--Documentation/00-INDEX2
-rw-r--r--Documentation/sgi-visws.txt13
-rw-r--r--Documentation/sound/oss/vwsnd293
-rw-r--r--MAINTAINERS7
-rw-r--r--arch/x86/Kconfig82
-rw-r--r--arch/x86/Kconfig.cpu2
-rw-r--r--arch/x86/include/asm/fixmap.h6
-rw-r--r--arch/x86/include/asm/hw_irq.h1
-rw-r--r--arch/x86/include/asm/mmzone_32.h3
-rw-r--r--arch/x86/include/asm/mpspec.h6
-rw-r--r--arch/x86/include/asm/numaq.h171
-rw-r--r--arch/x86/include/asm/setup.h6
-rw-r--r--arch/x86/include/asm/visws/cobalt.h127
-rw-r--r--arch/x86/include/asm/visws/lithium.h53
-rw-r--r--arch/x86/include/asm/visws/piix4.h107
-rw-r--r--arch/x86/include/asm/visws/sgivw.h5
-rw-r--r--arch/x86/kernel/acpi/boot.c12
-rw-r--r--arch/x86/kernel/apic/Makefile3
-rw-r--r--arch/x86/kernel/apic/apic.c1
-rw-r--r--arch/x86/kernel/apic/es7000_32.c738
-rw-r--r--arch/x86/kernel/apic/numaq_32.c524
-rw-r--r--arch/x86/kernel/apic/summit_32.c550
-rw-r--r--arch/x86/kernel/cpu/intel.c4
-rw-r--r--arch/x86/kernel/setup.c1
-rw-r--r--arch/x86/mm/numa.c4
-rw-r--r--arch/x86/pci/Makefile3
-rw-r--r--arch/x86/pci/common.c5
-rw-r--r--arch/x86/pci/numaq_32.c165
-rw-r--r--arch/x86/pci/visws.c87
-rw-r--r--arch/x86/platform/Makefile1
-rw-r--r--arch/x86/platform/visws/Makefile1
-rw-r--r--arch/x86/platform/visws/visws_quirks.c608
-rw-r--r--arch/x86/xen/Kconfig2
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/cyclone.c113
-rw-r--r--drivers/pci/Makefile1
-rw-r--r--drivers/scsi/qla1280.c7
-rw-r--r--drivers/video/Kconfig11
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/gbefb.c4
-rw-r--r--drivers/video/logo/Kconfig2
-rw-r--r--drivers/video/logo/logo.c2
-rw-r--r--drivers/video/sgivwfb.c889
-rw-r--r--include/video/sgivw.h681
-rw-r--r--sound/oss/Kconfig9
-rw-r--r--sound/oss/Makefile1
-rw-r--r--sound/oss/vwsnd.c3506
47 files changed, 15 insertions, 8806 deletions
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 07de7e19b4ce..27e67a98b7be 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -413,8 +413,6 @@ serial-console.txt
413 - how to set up Linux with a serial line console as the default. 413 - how to set up Linux with a serial line console as the default.
414sgi-ioc4.txt 414sgi-ioc4.txt
415 - description of the SGI IOC4 PCI (multi function) device. 415 - description of the SGI IOC4 PCI (multi function) device.
416sgi-visws.txt
417 - short blurb on the SGI Visual Workstations.
418sh/ 416sh/
419 - directory with info on porting Linux to a new architecture. 417 - directory with info on porting Linux to a new architecture.
420smsc_ece1099.txt 418smsc_ece1099.txt
diff --git a/Documentation/sgi-visws.txt b/Documentation/sgi-visws.txt
deleted file mode 100644
index 7ff0811ca2ba..000000000000
--- a/Documentation/sgi-visws.txt
+++ /dev/null
@@ -1,13 +0,0 @@
1
2The SGI Visual Workstations (models 320 and 540) are based around
3the Cobalt, Lithium, and Arsenic ASICs. The Cobalt ASIC is the
4main system ASIC which interfaces the 1-4 IA32 cpus, the memory
5system, and the I/O system in the Lithium ASIC. The Cobalt ASIC
6also contains the 3D gfx rendering engine which renders to main
7system memory -- part of which is used as the frame buffer which
8is DMA'ed to a video connector using the Arsenic ASIC. A PIIX4
9chip and NS87307 are used to provide legacy device support (IDE,
10serial, floppy, and parallel).
11
12The Visual Workstation chipset largely conforms to the PC architecture
13with some notable exceptions such as interrupt handling.
diff --git a/Documentation/sound/oss/vwsnd b/Documentation/sound/oss/vwsnd
deleted file mode 100644
index 4c6cbdb3c548..000000000000
--- a/Documentation/sound/oss/vwsnd
+++ /dev/null
@@ -1,293 +0,0 @@
1vwsnd - Sound driver for the Silicon Graphics 320 and 540 Visual
2Workstations' onboard audio.
3
4Copyright 1999 Silicon Graphics, Inc. All rights reserved.
5
6
7At the time of this writing, March 1999, there are two models of
8Visual Workstation, the 320 and the 540. This document only describes
9those models. Future Visual Workstation models may have different
10sound capabilities, and this driver will probably not work on those
11boxes.
12
13The Visual Workstation has an Analog Devices AD1843 "SoundComm" audio
14codec chip. The AD1843 is accessed through the Cobalt I/O ASIC, also
15known as Lithium. This driver programs both chips.
16
17==============================================================================
18QUICK CONFIGURATION
19
20 # insmod soundcore
21 # insmod vwsnd
22
23==============================================================================
24I/O CONNECTIONS
25
26On the Visual Workstation, only three of the AD1843 inputs are hooked
27up. The analog line in jacks are connected to the AD1843's AUX1
28input. The CD audio lines are connected to the AD1843's AUX2 input.
29The microphone jack is connected to the AD1843's MIC input. The mic
30jack is mono, but the signal is delivered to both the left and right
31MIC inputs. You can record in stereo from the mic input, but you will
32get the same signal on both channels (within the limits of A/D
33accuracy). Full scale on the Line input is +/- 2.0 V. Full scale on
34the MIC input is 20 dB less, or +/- 0.2 V.
35
36The AD1843's LOUT1 outputs are connected to the Line Out jacks. The
37AD1843's HPOUT outputs are connected to the speaker/headphone jack.
38LOUT2 is not connected. Line out's maximum level is +/- 2.0 V peak to
39peak. The speaker/headphone out's maximum is +/- 4.0 V peak to peak.
40
41The AD1843's PCM input channel and one of its output channels (DAC1)
42are connected to Lithium. The other output channel (DAC2) is not
43connected.
44
45==============================================================================
46CAPABILITIES
47
48The AD1843 has PCM input and output (Pulse Code Modulation, also known
49as wavetable). PCM input and output can be mono or stereo in any of
50four formats. The formats are 16 bit signed and 8 bit unsigned,
51u-Law, and A-Law format. Any sample rate from 4 KHz to 49 KHz is
52available, in 1 Hz increments.
53
54The AD1843 includes an analog mixer that can mix all three input
55signals (line, mic and CD) into the analog outputs. The mixer has a
56separate gain control and mute switch for each input.
57
58There are two outputs, line out and speaker/headphone out. They
59always produce the same signal, and the speaker always has 3 dB more
60gain than the line out. The speaker/headphone output can be muted,
61but this driver does not export that function.
62
63The hardware can sync audio to the video clock, but this driver does
64not have a way to specify syncing to video.
65
66==============================================================================
67PROGRAMMING
68
69This section explains the API supported by the driver. Also see the
70Open Sound Programming Guide at http://www.opensound.com/pguide/ .
71This section assumes familiarity with that document.
72
73The driver has two interfaces, an I/O interface and a mixer interface.
74There is no MIDI or sequencer capability.
75
76==============================================================================
77PROGRAMMING PCM I/O
78
79The I/O interface is usually accessed as /dev/audio or /dev/dsp.
80Using the standard Open Sound System (OSS) ioctl calls, the sample
81rate, number of channels, and sample format may be set within the
82limitations described above. The driver supports triggering. It also
83supports getting the input and output pointers with one-sample
84accuracy.
85
86The SNDCTL_DSP_GETCAP ioctl returns these capabilities.
87
88 DSP_CAP_DUPLEX - driver supports full duplex.
89
90 DSP_CAP_TRIGGER - driver supports triggering.
91
92 DSP_CAP_REALTIME - values returned by SNDCTL_DSP_GETIPTR
93 and SNDCTL_DSP_GETOPTR are accurate to a few samples.
94
95Memory mapping (mmap) is not implemented.
96
97The driver permits subdivided fragment sizes from 64 to 4096 bytes.
98The number of fragments can be anything from 3 fragments to however
99many fragments fit into 124 kilobytes. It is up to the user to
100determine how few/small fragments can be used without introducing
101glitches with a given workload. Linux is not realtime, so we can't
102promise anything. (sigh...)
103
104When this driver is switched into or out of mu-Law or A-Law mode on
105output, it may produce an audible click. This is unavoidable. To
106prevent clicking, use signed 16-bit mode instead, and convert from
107mu-Law or A-Law format in software.
108
109==============================================================================
110PROGRAMMING THE MIXER INTERFACE
111
112The mixer interface is usually accessed as /dev/mixer. It is accessed
113through ioctls. The mixer allows the application to control gain or
114mute several audio signal paths, and also allows selection of the
115recording source.
116
117Each of the constants described here can be read using the
118MIXER_READ(SOUND_MIXER_xxx) ioctl. Those that are not read-only can
119also be written using the MIXER_WRITE(SOUND_MIXER_xxx) ioctl. In most
120cases, <sys/soundcard.h> defines constants SOUND_MIXER_READ_xxx and
121SOUND_MIXER_WRITE_xxx which work just as well.
122
123SOUND_MIXER_CAPS Read-only
124
125This is a mask of optional driver capabilities that are implemented.
126This driver's only capability is SOUND_CAP_EXCL_INPUT, which means
127that only one recording source can be active at a time.
128
129SOUND_MIXER_DEVMASK Read-only
130
131This is a mask of the sound channels. This driver's channels are PCM,
132LINE, MIC, CD, and RECLEV.
133
134SOUND_MIXER_STEREODEVS Read-only
135
136This is a mask of which sound channels are capable of stereo. All
137channels are capable of stereo. (But see caveat on MIC input in I/O
138CONNECTIONS section above).
139
140SOUND_MIXER_OUTMASK Read-only
141
142This is a mask of channels that route inputs through to outputs.
143Those are LINE, MIC, and CD.
144
145SOUND_MIXER_RECMASK Read-only
146
147This is a mask of channels that can be recording sources. Those are
148PCM, LINE, MIC, CD.
149
150SOUND_MIXER_PCM Default: 0x5757 (0 dB)
151
152This is the gain control for PCM output. The left and right channel
153gain are controlled independently. This gain control has 64 levels,
154which range from -82.5 dB to +12.0 dB in 1.5 dB steps. Those 64
155levels are mapped onto 100 levels at the ioctl, see below.
156
157SOUND_MIXER_LINE Default: 0x4a4a (0 dB)
158
159This is the gain control for mixing the Line In source into the
160outputs. The left and right channel gain are controlled
161independently. This gain control has 32 levels, which range from
162-34.5 dB to +12.0 dB in 1.5 dB steps. Those 32 levels are mapped onto
163100 levels at the ioctl, see below.
164
165SOUND_MIXER_MIC Default: 0x4a4a (0 dB)
166
167This is the gain control for mixing the MIC source into the outputs.
168The left and right channel gain are controlled independently. This
169gain control has 32 levels, which range from -34.5 dB to +12.0 dB in
1701.5 dB steps. Those 32 levels are mapped onto 100 levels at the
171ioctl, see below.
172
173SOUND_MIXER_CD Default: 0x4a4a (0 dB)
174
175This is the gain control for mixing the CD audio source into the
176outputs. The left and right channel gain are controlled
177independently. This gain control has 32 levels, which range from
178-34.5 dB to +12.0 dB in 1.5 dB steps. Those 32 levels are mapped onto
179100 levels at the ioctl, see below.
180
181SOUND_MIXER_RECLEV Default: 0 (0 dB)
182
183This is the gain control for PCM input (RECording LEVel). The left
184and right channel gain are controlled independently. This gain
185control has 16 levels, which range from 0 dB to +22.5 dB in 1.5 dB
186steps. Those 16 levels are mapped onto 100 levels at the ioctl, see
187below.
188
189SOUND_MIXER_RECSRC Default: SOUND_MASK_LINE
190
191This is a mask of currently selected PCM input sources (RECording
192SouRCes). Because the AD1843 can only have a single recording source
193at a time, only one bit at a time can be set in this mask. The
194allowable values are SOUND_MASK_PCM, SOUND_MASK_LINE, SOUND_MASK_MIC,
195or SOUND_MASK_CD. Selecting SOUND_MASK_PCM sets up internal
196resampling which is useful for loopback testing and for hardware
197sample rate conversion. But software sample rate conversion is
198probably faster, so I don't know how useful that is.
199
200SOUND_MIXER_OUTSRC DEFAULT: SOUND_MASK_LINE|SOUND_MASK_MIC|SOUND_MASK_CD
201
202This is a mask of sources that are currently passed through to the
203outputs. Those sources whose bits are not set are muted.
204
205==============================================================================
206GAIN CONTROL
207
208There are five gain controls listed above. Each has 16, 32, or 64
209steps. Each control has 1.5 dB of gain per step. Each control is
210stereo.
211
212The OSS defines the argument to a channel gain ioctl as having two
213components, left and right, each of which ranges from 0 to 100. The
214two components are packed into the same word, with the left side gain
215in the least significant byte, and the right side gain in the second
216least significant byte. In C, we would say this.
217
218 #include <assert.h>
219
220 ...
221
222 assert(leftgain >= 0 && leftgain <= 100);
223 assert(rightgain >= 0 && rightgain <= 100);
224 arg = leftgain | rightgain << 8;
225
226So each OSS gain control has 101 steps. But the hardware has 16, 32,
227or 64 steps. The hardware steps are spread across the 101 OSS steps
228nearly evenly. The conversion formulas are like this, given N equals
22916, 32, or 64.
230
231 int round = N/2 - 1;
232 OSS_gain_steps = (hw_gain_steps * 100 + round) / (N - 1);
233 hw_gain_steps = (OSS_gain_steps * (N - 1) + round) / 100;
234
235Here is a snippet of C code that will return the left and right gain
236of any channel in dB. Pass it one of the predefined gain_desc_t
237structures to access any of the five channels' gains.
238
239 typedef struct gain_desc {
240 float min_gain;
241 float gain_step;
242 int nbits;
243 int chan;
244 } gain_desc_t;
245
246 const gain_desc_t gain_pcm = { -82.5, 1.5, 6, SOUND_MIXER_PCM };
247 const gain_desc_t gain_line = { -34.5, 1.5, 5, SOUND_MIXER_LINE };
248 const gain_desc_t gain_mic = { -34.5, 1.5, 5, SOUND_MIXER_MIC };
249 const gain_desc_t gain_cd = { -34.5, 1.5, 5, SOUND_MIXER_CD };
250 const gain_desc_t gain_reclev = { 0.0, 1.5, 4, SOUND_MIXER_RECLEV };
251
252 int get_gain_dB(int fd, const gain_desc_t *gp,
253 float *left, float *right)
254 {
255 int word;
256 int lg, rg;
257 int mask = (1 << gp->nbits) - 1;
258
259 if (ioctl(fd, MIXER_READ(gp->chan), &word) != 0)
260 return -1; /* fail */
261 lg = word & 0xFF;
262 rg = word >> 8 & 0xFF;
263 lg = (lg * mask + mask / 2) / 100;
264 rg = (rg * mask + mask / 2) / 100;
265 *left = gp->min_gain + gp->gain_step * lg;
266 *right = gp->min_gain + gp->gain_step * rg;
267 return 0;
268 }
269
270And here is the corresponding routine to set a channel's gain in dB.
271
272 int set_gain_dB(int fd, const gain_desc_t *gp, float left, float right)
273 {
274 float max_gain =
275 gp->min_gain + (1 << gp->nbits) * gp->gain_step;
276 float round = gp->gain_step / 2;
277 int mask = (1 << gp->nbits) - 1;
278 int word;
279 int lg, rg;
280
281 if (left < gp->min_gain || right < gp->min_gain)
282 return EINVAL;
283 lg = (left - gp->min_gain + round) / gp->gain_step;
284 rg = (right - gp->min_gain + round) / gp->gain_step;
285 if (lg >= (1 << gp->nbits) || rg >= (1 << gp->nbits))
286 return EINVAL;
287 lg = (100 * lg + mask / 2) / mask;
288 rg = (100 * rg + mask / 2) / mask;
289 word = lg | rg << 8;
290
291 return ioctl(fd, MIXER_WRITE(gp->chan), &word);
292 }
293
diff --git a/MAINTAINERS b/MAINTAINERS
index c1b982cd52db..b99bbbc4c5dd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7840,13 +7840,6 @@ F: Documentation/ia64/serial.txt
7840F: drivers/tty/serial/ioc?_serial.c 7840F: drivers/tty/serial/ioc?_serial.c
7841F: include/linux/ioc?.h 7841F: include/linux/ioc?.h
7842 7842
7843SGI VISUAL WORKSTATION 320 AND 540
7844M: Andrey Panin <pazke@donpac.ru>
7845L: linux-visws-devel@lists.sf.net
7846W: http://linux-visws.sf.net
7847S: Maintained for 2.6.
7848F: Documentation/sgi-visws.txt
7849
7850SGI XP/XPC/XPNET DRIVER 7843SGI XP/XPC/XPNET DRIVER
7851M: Cliff Whickman <cpw@sgi.com> 7844M: Cliff Whickman <cpw@sgi.com>
7852M: Robin Holt <robinmholt@gmail.com> 7845M: Robin Holt <robinmholt@gmail.com>
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ac04d9804391..f73071742975 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -344,12 +344,9 @@ config X86_EXTENDED_PLATFORM
344 for the following (non-PC) 32 bit x86 platforms: 344 for the following (non-PC) 32 bit x86 platforms:
345 Goldfish (Android emulator) 345 Goldfish (Android emulator)
346 AMD Elan 346 AMD Elan
347 NUMAQ (IBM/Sequent)
348 RDC R-321x SoC 347 RDC R-321x SoC
349 SGI 320/540 (Visual Workstation) 348 SGI 320/540 (Visual Workstation)
350 STA2X11-based (e.g. Northville) 349 STA2X11-based (e.g. Northville)
351 Summit/EXA (IBM x440)
352 Unisys ES7000 IA32 series
353 Moorestown MID devices 350 Moorestown MID devices
354 351
355 If you have one of these systems, or if you want to build a 352 If you have one of these systems, or if you want to build a
@@ -487,49 +484,22 @@ config X86_32_NON_STANDARD
487 depends on X86_32 && SMP 484 depends on X86_32 && SMP
488 depends on X86_EXTENDED_PLATFORM 485 depends on X86_EXTENDED_PLATFORM
489 ---help--- 486 ---help---
490 This option compiles in the NUMAQ, Summit, bigsmp, ES7000, 487 This option compiles in the bigsmp and STA2X11 default
491 STA2X11, default subarchitectures. It is intended for a generic 488 subarchitectures. It is intended for a generic binary
492 binary kernel. If you select them all, kernel will probe it 489 kernel. If you select them all, kernel will probe it one by
493 one by one and will fallback to default. 490 one and will fallback to default.
494 491
495# Alphabetically sorted list of Non standard 32 bit platforms 492# Alphabetically sorted list of Non standard 32 bit platforms
496 493
497config X86_NUMAQ
498 bool "NUMAQ (IBM/Sequent)"
499 depends on X86_32_NON_STANDARD
500 depends on PCI
501 select NUMA
502 select X86_MPPARSE
503 ---help---
504 This option is used for getting Linux to run on a NUMAQ (IBM/Sequent)
505 NUMA multiquad box. This changes the way that processors are
506 bootstrapped, and uses Clustered Logical APIC addressing mode instead
507 of Flat Logical. You will need a new lynxer.elf file to flash your
508 firmware with - send email to <Martin.Bligh@us.ibm.com>.
509
510config X86_SUPPORTS_MEMORY_FAILURE 494config X86_SUPPORTS_MEMORY_FAILURE
511 def_bool y 495 def_bool y
512 # MCE code calls memory_failure(): 496 # MCE code calls memory_failure():
513 depends on X86_MCE 497 depends on X86_MCE
514 # On 32-bit this adds too big of NODES_SHIFT and we run out of page flags: 498 # On 32-bit this adds too big of NODES_SHIFT and we run out of page flags:
515 depends on !X86_NUMAQ
516 # On 32-bit SPARSEMEM adds too big of SECTIONS_WIDTH: 499 # On 32-bit SPARSEMEM adds too big of SECTIONS_WIDTH:
517 depends on X86_64 || !SPARSEMEM 500 depends on X86_64 || !SPARSEMEM
518 select ARCH_SUPPORTS_MEMORY_FAILURE 501 select ARCH_SUPPORTS_MEMORY_FAILURE
519 502
520config X86_VISWS
521 bool "SGI 320/540 (Visual Workstation)"
522 depends on X86_32 && PCI && X86_MPPARSE && PCI_GODIRECT
523 depends on X86_32_NON_STANDARD
524 ---help---
525 The SGI Visual Workstation series is an IA32-based workstation
526 based on SGI systems chips with some legacy PC hardware attached.
527
528 Say Y here to create a kernel to run on the SGI 320 or 540.
529
530 A kernel compiled for the Visual Workstation will run on general
531 PCs as well. See <file:Documentation/sgi-visws.txt> for details.
532
533config STA2X11 503config STA2X11
534 bool "STA2X11 Companion Chip Support" 504 bool "STA2X11 Companion Chip Support"
535 depends on X86_32_NON_STANDARD && PCI 505 depends on X86_32_NON_STANDARD && PCI
@@ -546,20 +516,6 @@ config STA2X11
546 option is selected the kernel will still be able to boot on 516 option is selected the kernel will still be able to boot on
547 standard PC machines. 517 standard PC machines.
548 518
549config X86_SUMMIT
550 bool "Summit/EXA (IBM x440)"
551 depends on X86_32_NON_STANDARD
552 ---help---
553 This option is needed for IBM systems that use the Summit/EXA chipset.
554 In particular, it is needed for the x440.
555
556config X86_ES7000
557 bool "Unisys ES7000 IA32 series"
558 depends on X86_32_NON_STANDARD && X86_BIGSMP
559 ---help---
560 Support for Unisys ES7000 systems. Say 'Y' here if this kernel is
561 supposed to run on an IA32-based Unisys ES7000 system.
562
563config X86_32_IRIS 519config X86_32_IRIS
564 tristate "Eurobraille/Iris poweroff module" 520 tristate "Eurobraille/Iris poweroff module"
565 depends on X86_32 521 depends on X86_32
@@ -682,14 +638,6 @@ config MEMTEST
682 memtest=4, mean do 4 test patterns. 638 memtest=4, mean do 4 test patterns.
683 If you are unsure how to answer this question, answer N. 639 If you are unsure how to answer this question, answer N.
684 640
685config X86_SUMMIT_NUMA
686 def_bool y
687 depends on X86_32 && NUMA && X86_32_NON_STANDARD
688
689config X86_CYCLONE_TIMER
690 def_bool y
691 depends on X86_SUMMIT
692
693source "arch/x86/Kconfig.cpu" 641source "arch/x86/Kconfig.cpu"
694 642
695config HPET_TIMER 643config HPET_TIMER
@@ -818,7 +766,7 @@ config NR_CPUS
818 range 2 8192 if SMP && !MAXSMP && CPUMASK_OFFSTACK && X86_64 766 range 2 8192 if SMP && !MAXSMP && CPUMASK_OFFSTACK && X86_64
819 default "1" if !SMP 767 default "1" if !SMP
820 default "8192" if MAXSMP 768 default "8192" if MAXSMP
821 default "32" if SMP && (X86_NUMAQ || X86_SUMMIT || X86_BIGSMP || X86_ES7000) 769 default "32" if SMP && X86_BIGSMP
822 default "8" if SMP 770 default "8" if SMP
823 ---help--- 771 ---help---
824 This allows you to specify the maximum number of CPUs which this 772 This allows you to specify the maximum number of CPUs which this
@@ -882,10 +830,6 @@ config X86_IO_APIC
882 def_bool y 830 def_bool y
883 depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_IOAPIC || PCI_MSI 831 depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_IOAPIC || PCI_MSI
884 832
885config X86_VISWS_APIC
886 def_bool y
887 depends on X86_32 && X86_VISWS
888
889config X86_REROUTE_FOR_BROKEN_BOOT_IRQS 833config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
890 bool "Reroute for broken boot IRQs" 834 bool "Reroute for broken boot IRQs"
891 depends on X86_IO_APIC 835 depends on X86_IO_APIC
@@ -1103,13 +1047,11 @@ config X86_CPUID
1103 1047
1104choice 1048choice
1105 prompt "High Memory Support" 1049 prompt "High Memory Support"
1106 default HIGHMEM64G if X86_NUMAQ
1107 default HIGHMEM4G 1050 default HIGHMEM4G
1108 depends on X86_32 1051 depends on X86_32
1109 1052
1110config NOHIGHMEM 1053config NOHIGHMEM
1111 bool "off" 1054 bool "off"
1112 depends on !X86_NUMAQ
1113 ---help--- 1055 ---help---
1114 Linux can use up to 64 Gigabytes of physical memory on x86 systems. 1056 Linux can use up to 64 Gigabytes of physical memory on x86 systems.
1115 However, the address space of 32-bit x86 processors is only 4 1057 However, the address space of 32-bit x86 processors is only 4
@@ -1146,7 +1088,6 @@ config NOHIGHMEM
1146 1088
1147config HIGHMEM4G 1089config HIGHMEM4G
1148 bool "4GB" 1090 bool "4GB"
1149 depends on !X86_NUMAQ
1150 ---help--- 1091 ---help---
1151 Select this if you have a 32-bit processor and between 1 and 4 1092 Select this if you have a 32-bit processor and between 1 and 4
1152 gigabytes of physical RAM. 1093 gigabytes of physical RAM.
@@ -1238,8 +1179,8 @@ config DIRECT_GBPAGES
1238config NUMA 1179config NUMA
1239 bool "Numa Memory Allocation and Scheduler Support" 1180 bool "Numa Memory Allocation and Scheduler Support"
1240 depends on SMP 1181 depends on SMP
1241 depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || X86_BIGSMP || X86_SUMMIT && ACPI)) 1182 depends on X86_64 || (X86_32 && HIGHMEM64G && X86_BIGSMP)
1242 default y if (X86_NUMAQ || X86_SUMMIT || X86_BIGSMP) 1183 default y if X86_BIGSMP
1243 ---help--- 1184 ---help---
1244 Enable NUMA (Non Uniform Memory Access) support. 1185 Enable NUMA (Non Uniform Memory Access) support.
1245 1186
@@ -1250,15 +1191,11 @@ config NUMA
1250 For 64-bit this is recommended if the system is Intel Core i7 1191 For 64-bit this is recommended if the system is Intel Core i7
1251 (or later), AMD Opteron, or EM64T NUMA. 1192 (or later), AMD Opteron, or EM64T NUMA.
1252 1193
1253 For 32-bit this is only needed on (rare) 32-bit-only platforms 1194 For 32-bit this is only needed if you boot a 32-bit
1254 that support NUMA topologies, such as NUMAQ / Summit, or if you 1195 kernel on a 64-bit NUMA platform.
1255 boot a 32-bit kernel on a 64-bit NUMA platform.
1256 1196
1257 Otherwise, you should say N. 1197 Otherwise, you should say N.
1258 1198
1259comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI"
1260 depends on X86_32 && X86_SUMMIT && (!HIGHMEM64G || !ACPI)
1261
1262config AMD_NUMA 1199config AMD_NUMA
1263 def_bool y 1200 def_bool y
1264 prompt "Old style AMD Opteron NUMA detection" 1201 prompt "Old style AMD Opteron NUMA detection"
@@ -1300,7 +1237,6 @@ config NODES_SHIFT
1300 range 1 10 1237 range 1 10
1301 default "10" if MAXSMP 1238 default "10" if MAXSMP
1302 default "6" if X86_64 1239 default "6" if X86_64
1303 default "4" if X86_NUMAQ
1304 default "3" 1240 default "3"
1305 depends on NEED_MULTIPLE_NODES 1241 depends on NEED_MULTIPLE_NODES
1306 ---help--- 1242 ---help---
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index f3aaf231b4e5..6983314c8b37 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -359,7 +359,7 @@ config X86_P6_NOP
359 359
360config X86_TSC 360config X86_TSC
361 def_bool y 361 def_bool y
362 depends on ((MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) && !X86_NUMAQ) || X86_64 362 depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) || X86_64
363 363
364config X86_CMPXCHG64 364config X86_CMPXCHG64
365 def_bool y 365 def_bool y
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index 2377f5618fb7..8dcd35c4c787 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -90,12 +90,6 @@ enum fixed_addresses {
90 FIX_IO_APIC_BASE_0, 90 FIX_IO_APIC_BASE_0,
91 FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1, 91 FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1,
92#endif 92#endif
93#ifdef CONFIG_X86_VISWS_APIC
94 FIX_CO_CPU, /* Cobalt timer */
95 FIX_CO_APIC, /* Cobalt APIC Redirection Table */
96 FIX_LI_PCIA, /* Lithium PCI Bridge A */
97 FIX_LI_PCIB, /* Lithium PCI Bridge B */
98#endif
99 FIX_RO_IDT, /* Virtual mapping for read-only IDT */ 93 FIX_RO_IDT, /* Virtual mapping for read-only IDT */
100#ifdef CONFIG_X86_32 94#ifdef CONFIG_X86_32
101 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ 95 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 67d69b8e2d20..a307b7530e54 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -98,7 +98,6 @@ extern void trace_call_function_single_interrupt(void);
98#define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs)) 98#define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs))
99extern unsigned long io_apic_irqs; 99extern unsigned long io_apic_irqs;
100 100
101extern void init_VISWS_APIC_irqs(void);
102extern void setup_IO_APIC(void); 101extern void setup_IO_APIC(void);
103extern void disable_IO_APIC(void); 102extern void disable_IO_APIC(void);
104 103
diff --git a/arch/x86/include/asm/mmzone_32.h b/arch/x86/include/asm/mmzone_32.h
index 8a9b3e288cb4..1ec990bd7dc0 100644
--- a/arch/x86/include/asm/mmzone_32.h
+++ b/arch/x86/include/asm/mmzone_32.h
@@ -11,9 +11,6 @@
11#ifdef CONFIG_NUMA 11#ifdef CONFIG_NUMA
12extern struct pglist_data *node_data[]; 12extern struct pglist_data *node_data[];
13#define NODE_DATA(nid) (node_data[nid]) 13#define NODE_DATA(nid) (node_data[nid])
14
15#include <asm/numaq.h>
16
17#endif /* CONFIG_NUMA */ 14#endif /* CONFIG_NUMA */
18 15
19#ifdef CONFIG_DISCONTIGMEM 16#ifdef CONFIG_DISCONTIGMEM
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 3e6b4920ef5d..f5a617956735 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -25,12 +25,6 @@ extern int pic_mode;
25 25
26extern unsigned int def_to_bigsmp; 26extern unsigned int def_to_bigsmp;
27 27
28#ifdef CONFIG_X86_NUMAQ
29extern int mp_bus_id_to_node[MAX_MP_BUSSES];
30extern int mp_bus_id_to_local[MAX_MP_BUSSES];
31extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
32#endif
33
34#else /* CONFIG_X86_64: */ 28#else /* CONFIG_X86_64: */
35 29
36#define MAX_MP_BUSSES 256 30#define MAX_MP_BUSSES 256
diff --git a/arch/x86/include/asm/numaq.h b/arch/x86/include/asm/numaq.h
deleted file mode 100644
index c3b3c322fd87..000000000000
--- a/arch/x86/include/asm/numaq.h
+++ /dev/null
@@ -1,171 +0,0 @@
1/*
2 * Written by: Patricia Gaughen, IBM Corporation
3 *
4 * Copyright (C) 2002, IBM Corp.
5 *
6 * All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16 * NON INFRINGEMENT. See the GNU General Public License for more
17 * 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 * Send feedback to <gone@us.ibm.com>
24 */
25
26#ifndef _ASM_X86_NUMAQ_H
27#define _ASM_X86_NUMAQ_H
28
29#ifdef CONFIG_X86_NUMAQ
30
31extern int found_numaq;
32extern int numaq_numa_init(void);
33extern int pci_numaq_init(void);
34
35extern void *xquad_portio;
36
37#define XQUAD_PORTIO_BASE 0xfe400000
38#define XQUAD_PORTIO_QUAD 0x40000 /* 256k per quad. */
39#define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port)
40
41/*
42 * SYS_CFG_DATA_PRIV_ADDR, struct eachquadmem, and struct sys_cfg_data are the
43 */
44#define SYS_CFG_DATA_PRIV_ADDR 0x0009d000 /* place for scd in private
45 quad space */
46
47/*
48 * Communication area for each processor on lynxer-processor tests.
49 *
50 * NOTE: If you change the size of this eachproc structure you need
51 * to change the definition for EACH_QUAD_SIZE.
52 */
53struct eachquadmem {
54 unsigned int priv_mem_start; /* Starting address of this */
55 /* quad's private memory. */
56 /* This is always 0. */
57 /* In MB. */
58 unsigned int priv_mem_size; /* Size of this quad's */
59 /* private memory. */
60 /* In MB. */
61 unsigned int low_shrd_mem_strp_start;/* Starting address of this */
62 /* quad's low shared block */
63 /* (untranslated). */
64 /* In MB. */
65 unsigned int low_shrd_mem_start; /* Starting address of this */
66 /* quad's low shared memory */
67 /* (untranslated). */
68 /* In MB. */
69 unsigned int low_shrd_mem_size; /* Size of this quad's low */
70 /* shared memory. */
71 /* In MB. */
72 unsigned int lmmio_copb_start; /* Starting address of this */
73 /* quad's local memory */
74 /* mapped I/O in the */
75 /* compatibility OPB. */
76 /* In MB. */
77 unsigned int lmmio_copb_size; /* Size of this quad's local */
78 /* memory mapped I/O in the */
79 /* compatibility OPB. */
80 /* In MB. */
81 unsigned int lmmio_nopb_start; /* Starting address of this */
82 /* quad's local memory */
83 /* mapped I/O in the */
84 /* non-compatibility OPB. */
85 /* In MB. */
86 unsigned int lmmio_nopb_size; /* Size of this quad's local */
87 /* memory mapped I/O in the */
88 /* non-compatibility OPB. */
89 /* In MB. */
90 unsigned int io_apic_0_start; /* Starting address of I/O */
91 /* APIC 0. */
92 unsigned int io_apic_0_sz; /* Size I/O APIC 0. */
93 unsigned int io_apic_1_start; /* Starting address of I/O */
94 /* APIC 1. */
95 unsigned int io_apic_1_sz; /* Size I/O APIC 1. */
96 unsigned int hi_shrd_mem_start; /* Starting address of this */
97 /* quad's high shared memory.*/
98 /* In MB. */
99 unsigned int hi_shrd_mem_size; /* Size of this quad's high */
100 /* shared memory. */
101 /* In MB. */
102 unsigned int mps_table_addr; /* Address of this quad's */
103 /* MPS tables from BIOS, */
104 /* in system space.*/
105 unsigned int lcl_MDC_pio_addr; /* Port-I/O address for */
106 /* local access of MDC. */
107 unsigned int rmt_MDC_mmpio_addr; /* MM-Port-I/O address for */
108 /* remote access of MDC. */
109 unsigned int mm_port_io_start; /* Starting address of this */
110 /* quad's memory mapped Port */
111 /* I/O space. */
112 unsigned int mm_port_io_size; /* Size of this quad's memory*/
113 /* mapped Port I/O space. */
114 unsigned int mm_rmt_io_apic_start; /* Starting address of this */
115 /* quad's memory mapped */
116 /* remote I/O APIC space. */
117 unsigned int mm_rmt_io_apic_size; /* Size of this quad's memory*/
118 /* mapped remote I/O APIC */
119 /* space. */
120 unsigned int mm_isa_start; /* Starting address of this */
121 /* quad's memory mapped ISA */
122 /* space (contains MDC */
123 /* memory space). */
124 unsigned int mm_isa_size; /* Size of this quad's memory*/
125 /* mapped ISA space (contains*/
126 /* MDC memory space). */
127 unsigned int rmt_qmi_addr; /* Remote addr to access QMI.*/
128 unsigned int lcl_qmi_addr; /* Local addr to access QMI. */
129};
130
131/*
132 * Note: This structure must be NOT be changed unless the multiproc and
133 * OS are changed to reflect the new structure.
134 */
135struct sys_cfg_data {
136 unsigned int quad_id;
137 unsigned int bsp_proc_id; /* Boot Strap Processor in this quad. */
138 unsigned int scd_version; /* Version number of this table. */
139 unsigned int first_quad_id;
140 unsigned int quads_present31_0; /* 1 bit for each quad */
141 unsigned int quads_present63_32; /* 1 bit for each quad */
142 unsigned int config_flags;
143 unsigned int boot_flags;
144 unsigned int csr_start_addr; /* Absolute value (not in MB) */
145 unsigned int csr_size; /* Absolute value (not in MB) */
146 unsigned int lcl_apic_start_addr; /* Absolute value (not in MB) */
147 unsigned int lcl_apic_size; /* Absolute value (not in MB) */
148 unsigned int low_shrd_mem_base; /* 0 or 512MB or 1GB */
149 unsigned int low_shrd_mem_quad_offset; /* 0,128M,256M,512M,1G */
150 /* may not be totally populated */
151 unsigned int split_mem_enbl; /* 0 for no low shared memory */
152 unsigned int mmio_sz; /* Size of total system memory mapped I/O */
153 /* (in MB). */
154 unsigned int quad_spin_lock; /* Spare location used for quad */
155 /* bringup. */
156 unsigned int nonzero55; /* For checksumming. */
157 unsigned int nonzeroaa; /* For checksumming. */
158 unsigned int scd_magic_number;
159 unsigned int system_type;
160 unsigned int checksum;
161 /*
162 * memory configuration area for each quad
163 */
164 struct eachquadmem eq[MAX_NUMNODES]; /* indexed by quad id */
165};
166
167void numaq_tsc_disable(void);
168
169#endif /* CONFIG_X86_NUMAQ */
170#endif /* _ASM_X86_NUMAQ_H */
171
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index d62c9f809bc5..9264f04a4c55 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -39,12 +39,6 @@ static inline void vsmp_init(void) { }
39 39
40void setup_bios_corruption_check(void); 40void setup_bios_corruption_check(void);
41 41
42#ifdef CONFIG_X86_VISWS
43extern void visws_early_detect(void);
44#else
45static inline void visws_early_detect(void) { }
46#endif
47
48extern unsigned long saved_video_mode; 42extern unsigned long saved_video_mode;
49 43
50extern void reserve_standard_io_resources(void); 44extern void reserve_standard_io_resources(void);
diff --git a/arch/x86/include/asm/visws/cobalt.h b/arch/x86/include/asm/visws/cobalt.h
deleted file mode 100644
index 2edb37637ead..000000000000
--- a/arch/x86/include/asm/visws/cobalt.h
+++ /dev/null
@@ -1,127 +0,0 @@
1#ifndef _ASM_X86_VISWS_COBALT_H
2#define _ASM_X86_VISWS_COBALT_H
3
4#include <asm/fixmap.h>
5
6/*
7 * Cobalt SGI Visual Workstation system ASIC
8 */
9
10#define CO_CPU_NUM_PHYS 0x1e00
11#define CO_CPU_TAB_PHYS (CO_CPU_NUM_PHYS + 2)
12
13#define CO_CPU_MAX 4
14
15#define CO_CPU_PHYS 0xc2000000
16#define CO_APIC_PHYS 0xc4000000
17
18/* see set_fixmap() and asm/fixmap.h */
19#define CO_CPU_VADDR (fix_to_virt(FIX_CO_CPU))
20#define CO_APIC_VADDR (fix_to_virt(FIX_CO_APIC))
21
22/* Cobalt CPU registers -- relative to CO_CPU_VADDR, use co_cpu_*() */
23#define CO_CPU_REV 0x08
24#define CO_CPU_CTRL 0x10
25#define CO_CPU_STAT 0x20
26#define CO_CPU_TIMEVAL 0x30
27
28/* CO_CPU_CTRL bits */
29#define CO_CTRL_TIMERUN 0x04 /* 0 == disabled */
30#define CO_CTRL_TIMEMASK 0x08 /* 0 == unmasked */
31
32/* CO_CPU_STATUS bits */
33#define CO_STAT_TIMEINTR 0x02 /* (r) 1 == int pend, (w) 0 == clear */
34
35/* CO_CPU_TIMEVAL value */
36#define CO_TIME_HZ 100000000 /* Cobalt core rate */
37
38/* Cobalt APIC registers -- relative to CO_APIC_VADDR, use co_apic_*() */
39#define CO_APIC_HI(n) (((n) * 0x10) + 4)
40#define CO_APIC_LO(n) ((n) * 0x10)
41#define CO_APIC_ID 0x0ffc
42
43/* CO_APIC_ID bits */
44#define CO_APIC_ENABLE 0x00000100
45
46/* CO_APIC_LO bits */
47#define CO_APIC_MASK 0x00010000 /* 0 = enabled */
48#define CO_APIC_LEVEL 0x00008000 /* 0 = edge */
49
50/*
51 * Where things are physically wired to Cobalt
52 * #defines with no board _<type>_<rev>_ are common to all (thus far)
53 */
54#define CO_APIC_IDE0 4
55#define CO_APIC_IDE1 2 /* Only on 320 */
56
57#define CO_APIC_8259 12 /* serial, floppy, par-l-l */
58
59/* Lithium PCI Bridge A -- "the one with 82557 Ethernet" */
60#define CO_APIC_PCIA_BASE0 0 /* and 1 */ /* slot 0, line 0 */
61#define CO_APIC_PCIA_BASE123 5 /* and 6 */ /* slot 0, line 1 */
62
63#define CO_APIC_PIIX4_USB 7 /* this one is weird */
64
65/* Lithium PCI Bridge B -- "the one with PIIX4" */
66#define CO_APIC_PCIB_BASE0 8 /* and 9-12 *//* slot 0, line 0 */
67#define CO_APIC_PCIB_BASE123 13 /* 14.15 */ /* slot 0, line 1 */
68
69#define CO_APIC_VIDOUT0 16
70#define CO_APIC_VIDOUT1 17
71#define CO_APIC_VIDIN0 18
72#define CO_APIC_VIDIN1 19
73
74#define CO_APIC_LI_AUDIO 22
75
76#define CO_APIC_AS 24
77#define CO_APIC_RE 25
78
79#define CO_APIC_CPU 28 /* Timer and Cache interrupt */
80#define CO_APIC_NMI 29
81#define CO_APIC_LAST CO_APIC_NMI
82
83/*
84 * This is how irqs are assigned on the Visual Workstation.
85 * Legacy devices get irq's 1-15 (system clock is 0 and is CO_APIC_CPU).
86 * All other devices (including PCI) go to Cobalt and are irq's 16 on up.
87 */
88#define CO_IRQ_APIC0 16 /* irq of apic entry 0 */
89#define IS_CO_APIC(irq) ((irq) >= CO_IRQ_APIC0)
90#define CO_IRQ(apic) (CO_IRQ_APIC0 + (apic)) /* apic ent to irq */
91#define CO_APIC(irq) ((irq) - CO_IRQ_APIC0) /* irq to apic ent */
92#define CO_IRQ_IDE0 14 /* knowledge of... */
93#define CO_IRQ_IDE1 15 /* ... ide driver defaults! */
94#define CO_IRQ_8259 CO_IRQ(CO_APIC_8259)
95
96#ifdef CONFIG_X86_VISWS_APIC
97static inline void co_cpu_write(unsigned long reg, unsigned long v)
98{
99 *((volatile unsigned long *)(CO_CPU_VADDR+reg))=v;
100}
101
102static inline unsigned long co_cpu_read(unsigned long reg)
103{
104 return *((volatile unsigned long *)(CO_CPU_VADDR+reg));
105}
106
107static inline void co_apic_write(unsigned long reg, unsigned long v)
108{
109 *((volatile unsigned long *)(CO_APIC_VADDR+reg))=v;
110}
111
112static inline unsigned long co_apic_read(unsigned long reg)
113{
114 return *((volatile unsigned long *)(CO_APIC_VADDR+reg));
115}
116#endif
117
118extern char visws_board_type;
119
120#define VISWS_320 0
121#define VISWS_540 1
122
123extern char visws_board_rev;
124
125extern int pci_visws_init(void);
126
127#endif /* _ASM_X86_VISWS_COBALT_H */
diff --git a/arch/x86/include/asm/visws/lithium.h b/arch/x86/include/asm/visws/lithium.h
deleted file mode 100644
index a10d89bc1270..000000000000
--- a/arch/x86/include/asm/visws/lithium.h
+++ /dev/null
@@ -1,53 +0,0 @@
1#ifndef _ASM_X86_VISWS_LITHIUM_H
2#define _ASM_X86_VISWS_LITHIUM_H
3
4#include <asm/fixmap.h>
5
6/*
7 * Lithium is the SGI Visual Workstation I/O ASIC
8 */
9
10#define LI_PCI_A_PHYS 0xfc000000 /* Enet is dev 3 */
11#define LI_PCI_B_PHYS 0xfd000000 /* PIIX4 is here */
12
13/* see set_fixmap() and asm/fixmap.h */
14#define LI_PCIA_VADDR (fix_to_virt(FIX_LI_PCIA))
15#define LI_PCIB_VADDR (fix_to_virt(FIX_LI_PCIB))
16
17/* Not a standard PCI? (not in linux/pci.h) */
18#define LI_PCI_BUSNUM 0x44 /* lo8: primary, hi8: sub */
19#define LI_PCI_INTEN 0x46
20
21/* LI_PCI_INTENT bits */
22#define LI_INTA_0 0x0001
23#define LI_INTA_1 0x0002
24#define LI_INTA_2 0x0004
25#define LI_INTA_3 0x0008
26#define LI_INTA_4 0x0010
27#define LI_INTB 0x0020
28#define LI_INTC 0x0040
29#define LI_INTD 0x0080
30
31/* More special purpose macros... */
32static inline void li_pcia_write16(unsigned long reg, unsigned short v)
33{
34 *((volatile unsigned short *)(LI_PCIA_VADDR+reg))=v;
35}
36
37static inline unsigned short li_pcia_read16(unsigned long reg)
38{
39 return *((volatile unsigned short *)(LI_PCIA_VADDR+reg));
40}
41
42static inline void li_pcib_write16(unsigned long reg, unsigned short v)
43{
44 *((volatile unsigned short *)(LI_PCIB_VADDR+reg))=v;
45}
46
47static inline unsigned short li_pcib_read16(unsigned long reg)
48{
49 return *((volatile unsigned short *)(LI_PCIB_VADDR+reg));
50}
51
52#endif /* _ASM_X86_VISWS_LITHIUM_H */
53
diff --git a/arch/x86/include/asm/visws/piix4.h b/arch/x86/include/asm/visws/piix4.h
deleted file mode 100644
index d0af4d338e7f..000000000000
--- a/arch/x86/include/asm/visws/piix4.h
+++ /dev/null
@@ -1,107 +0,0 @@
1#ifndef _ASM_X86_VISWS_PIIX4_H
2#define _ASM_X86_VISWS_PIIX4_H
3
4/*
5 * PIIX4 as used on SGI Visual Workstations
6 */
7
8#define PIIX_PM_START 0x0F80
9
10#define SIO_GPIO_START 0x0FC0
11
12#define SIO_PM_START 0x0FC8
13
14#define PMBASE PIIX_PM_START
15#define GPIREG0 (PMBASE+0x30)
16#define GPIREG(x) (GPIREG0+((x)/8))
17#define GPIBIT(x) (1 << ((x)%8))
18
19#define PIIX_GPI_BD_ID1 18
20#define PIIX_GPI_BD_ID2 19
21#define PIIX_GPI_BD_ID3 20
22#define PIIX_GPI_BD_ID4 21
23#define PIIX_GPI_BD_REG GPIREG(PIIX_GPI_BD_ID1)
24#define PIIX_GPI_BD_MASK (GPIBIT(PIIX_GPI_BD_ID1) | \
25 GPIBIT(PIIX_GPI_BD_ID2) | \
26 GPIBIT(PIIX_GPI_BD_ID3) | \
27 GPIBIT(PIIX_GPI_BD_ID4) )
28
29#define PIIX_GPI_BD_SHIFT (PIIX_GPI_BD_ID1 % 8)
30
31#define SIO_INDEX 0x2e
32#define SIO_DATA 0x2f
33
34#define SIO_DEV_SEL 0x7
35#define SIO_DEV_ENB 0x30
36#define SIO_DEV_MSB 0x60
37#define SIO_DEV_LSB 0x61
38
39#define SIO_GP_DEV 0x7
40
41#define SIO_GP_BASE SIO_GPIO_START
42#define SIO_GP_MSB (SIO_GP_BASE>>8)
43#define SIO_GP_LSB (SIO_GP_BASE&0xff)
44
45#define SIO_GP_DATA1 (SIO_GP_BASE+0)
46
47#define SIO_PM_DEV 0x8
48
49#define SIO_PM_BASE SIO_PM_START
50#define SIO_PM_MSB (SIO_PM_BASE>>8)
51#define SIO_PM_LSB (SIO_PM_BASE&0xff)
52#define SIO_PM_INDEX (SIO_PM_BASE+0)
53#define SIO_PM_DATA (SIO_PM_BASE+1)
54
55#define SIO_PM_FER2 0x1
56
57#define SIO_PM_GP_EN 0x80
58
59
60
61/*
62 * This is the dev/reg where generating a config cycle will
63 * result in a PCI special cycle.
64 */
65#define SPECIAL_DEV 0xff
66#define SPECIAL_REG 0x00
67
68/*
69 * PIIX4 needs to see a special cycle with the following data
70 * to be convinced the processor has gone into the stop grant
71 * state. PIIX4 insists on seeing this before it will power
72 * down a system.
73 */
74#define PIIX_SPECIAL_STOP 0x00120002
75
76#define PIIX4_RESET_PORT 0xcf9
77#define PIIX4_RESET_VAL 0x6
78
79#define PMSTS_PORT 0xf80 // 2 bytes PM Status
80#define PMEN_PORT 0xf82 // 2 bytes PM Enable
81#define PMCNTRL_PORT 0xf84 // 2 bytes PM Control
82
83#define PM_SUSPEND_ENABLE 0x2000 // start sequence to suspend state
84
85/*
86 * PMSTS and PMEN I/O bit definitions.
87 * (Bits are the same in both registers)
88 */
89#define PM_STS_RSM (1<<15) // Resume Status
90#define PM_STS_PWRBTNOR (1<<11) // Power Button Override
91#define PM_STS_RTC (1<<10) // RTC status
92#define PM_STS_PWRBTN (1<<8) // Power Button Pressed?
93#define PM_STS_GBL (1<<5) // Global Status
94#define PM_STS_BM (1<<4) // Bus Master Status
95#define PM_STS_TMROF (1<<0) // Timer Overflow Status.
96
97/*
98 * Stop clock GPI register
99 */
100#define PIIX_GPIREG0 (0xf80 + 0x30)
101
102/*
103 * Stop clock GPI bit in GPIREG0
104 */
105#define PIIX_GPI_STPCLK 0x4 // STPCLK signal routed back in
106
107#endif /* _ASM_X86_VISWS_PIIX4_H */
diff --git a/arch/x86/include/asm/visws/sgivw.h b/arch/x86/include/asm/visws/sgivw.h
deleted file mode 100644
index 5fbf63e1003c..000000000000
--- a/arch/x86/include/asm/visws/sgivw.h
+++ /dev/null
@@ -1,5 +0,0 @@
1/*
2 * Frame buffer position and size:
3 */
4extern unsigned long sgivwfb_mem_phys;
5extern unsigned long sgivwfb_mem_size;
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 8e61d23b8f64..86281ffb96d6 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -903,10 +903,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
903#ifdef CONFIG_X86_IO_APIC 903#ifdef CONFIG_X86_IO_APIC
904#define MP_ISA_BUS 0 904#define MP_ISA_BUS 0
905 905
906#ifdef CONFIG_X86_ES7000
907extern int es7000_plat;
908#endif
909
910void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) 906void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
911{ 907{
912 int ioapic; 908 int ioapic;
@@ -956,14 +952,6 @@ void __init mp_config_acpi_legacy_irqs(void)
956 set_bit(MP_ISA_BUS, mp_bus_not_pci); 952 set_bit(MP_ISA_BUS, mp_bus_not_pci);
957 pr_debug("Bus #%d is ISA\n", MP_ISA_BUS); 953 pr_debug("Bus #%d is ISA\n", MP_ISA_BUS);
958 954
959#ifdef CONFIG_X86_ES7000
960 /*
961 * Older generations of ES7000 have no legacy identity mappings
962 */
963 if (es7000_plat == 1)
964 return;
965#endif
966
967 /* 955 /*
968 * Use the default configuration for the IRQs 0-15. Unless 956 * Use the default configuration for the IRQs 0-15. Unless
969 * overridden by (MADT) interrupt source override entries. 957 * overridden by (MADT) interrupt source override entries.
diff --git a/arch/x86/kernel/apic/Makefile b/arch/x86/kernel/apic/Makefile
index 0ae0323b1f9c..dcb5b15401ce 100644
--- a/arch/x86/kernel/apic/Makefile
+++ b/arch/x86/kernel/apic/Makefile
@@ -18,10 +18,7 @@ obj-y += apic_flat_64.o
18endif 18endif
19 19
20# APIC probe will depend on the listing order here 20# APIC probe will depend on the listing order here
21obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
22obj-$(CONFIG_X86_SUMMIT) += summit_32.o
23obj-$(CONFIG_X86_BIGSMP) += bigsmp_32.o 21obj-$(CONFIG_X86_BIGSMP) += bigsmp_32.o
24obj-$(CONFIG_X86_ES7000) += es7000_32.o
25 22
26# For 32bit, probe_32 need to be listed last 23# For 32bit, probe_32 need to be listed last
27obj-$(CONFIG_X86_LOCAL_APIC) += probe_$(BITS).o 24obj-$(CONFIG_X86_LOCAL_APIC) += probe_$(BITS).o
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 53e20531470e..481ae38f6a44 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -2136,7 +2136,6 @@ int generic_processor_info(int apicid, int version)
2136 * 2136 *
2137 * - arch/x86/kernel/mpparse.c: MP_processor_info() 2137 * - arch/x86/kernel/mpparse.c: MP_processor_info()
2138 * - arch/x86/mm/amdtopology.c: amd_numa_init() 2138 * - arch/x86/mm/amdtopology.c: amd_numa_init()
2139 * - arch/x86/platform/visws/visws_quirks.c: MP_processor_info()
2140 * 2139 *
2141 * This function is executed with the modified 2140 * This function is executed with the modified
2142 * boot_cpu_physical_apicid. So, disabled_cpu_apicid kernel 2141 * boot_cpu_physical_apicid. So, disabled_cpu_apicid kernel
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
deleted file mode 100644
index 6f8f8b348a39..000000000000
--- a/arch/x86/kernel/apic/es7000_32.c
+++ /dev/null
@@ -1,738 +0,0 @@
1/*
2 * Written by: Garry Forsgren, Unisys Corporation
3 * Natalie Protasevich, Unisys Corporation
4 *
5 * This file contains the code to configure and interface
6 * with Unisys ES7000 series hardware system manager.
7 *
8 * Copyright (c) 2003 Unisys Corporation.
9 * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
10 *
11 * All Rights Reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of version 2 of the GNU General Public License as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it would be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write the Free Software Foundation, Inc., 59
23 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
24 *
25 * Contact information: Unisys Corporation, Township Line & Union Meeting
26 * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or:
27 *
28 * http://www.unisys.com
29 */
30
31#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
32
33#include <linux/notifier.h>
34#include <linux/spinlock.h>
35#include <linux/cpumask.h>
36#include <linux/threads.h>
37#include <linux/kernel.h>
38#include <linux/module.h>
39#include <linux/reboot.h>
40#include <linux/string.h>
41#include <linux/types.h>
42#include <linux/errno.h>
43#include <linux/acpi.h>
44#include <linux/init.h>
45#include <linux/gfp.h>
46#include <linux/nmi.h>
47#include <linux/smp.h>
48#include <linux/io.h>
49
50#include <asm/apicdef.h>
51#include <linux/atomic.h>
52#include <asm/fixmap.h>
53#include <asm/mpspec.h>
54#include <asm/setup.h>
55#include <asm/apic.h>
56#include <asm/ipi.h>
57
58/*
59 * ES7000 chipsets
60 */
61
62#define NON_UNISYS 0
63#define ES7000_CLASSIC 1
64#define ES7000_ZORRO 2
65
66#define MIP_REG 1
67#define MIP_PSAI_REG 4
68
69#define MIP_BUSY 1
70#define MIP_SPIN 0xf0000
71#define MIP_VALID 0x0100000000000000ULL
72#define MIP_SW_APIC 0x1020b
73
74#define MIP_PORT(val) ((val >> 32) & 0xffff)
75
76#define MIP_RD_LO(val) (val & 0xffffffff)
77
78struct mip_reg {
79 unsigned long long off_0x00;
80 unsigned long long off_0x08;
81 unsigned long long off_0x10;
82 unsigned long long off_0x18;
83 unsigned long long off_0x20;
84 unsigned long long off_0x28;
85 unsigned long long off_0x30;
86 unsigned long long off_0x38;
87};
88
89struct mip_reg_info {
90 unsigned long long mip_info;
91 unsigned long long delivery_info;
92 unsigned long long host_reg;
93 unsigned long long mip_reg;
94};
95
96struct psai {
97 unsigned long long entry_type;
98 unsigned long long addr;
99 unsigned long long bep_addr;
100};
101
102#ifdef CONFIG_ACPI
103
104struct es7000_oem_table {
105 struct acpi_table_header Header;
106 u32 OEMTableAddr;
107 u32 OEMTableSize;
108};
109
110static unsigned long oem_addrX;
111static unsigned long oem_size;
112
113#endif
114
115/*
116 * ES7000 Globals
117 */
118
119static volatile unsigned long *psai;
120static struct mip_reg *mip_reg;
121static struct mip_reg *host_reg;
122static int mip_port;
123static unsigned long mip_addr;
124static unsigned long host_addr;
125
126int es7000_plat;
127
128/*
129 * GSI override for ES7000 platforms.
130 */
131
132
133static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
134{
135 unsigned long vect = 0, psaival = 0;
136
137 if (psai == NULL)
138 return -1;
139
140 vect = ((unsigned long)__pa(eip)/0x1000) << 16;
141 psaival = (0x1000000 | vect | cpu);
142
143 while (*psai & 0x1000000)
144 ;
145
146 *psai = psaival;
147
148 return 0;
149}
150
151static int es7000_apic_is_cluster(void)
152{
153 /* MPENTIUMIII */
154 if (boot_cpu_data.x86 == 6 &&
155 (boot_cpu_data.x86_model >= 7 && boot_cpu_data.x86_model <= 11))
156 return 1;
157
158 return 0;
159}
160
161static void setup_unisys(void)
162{
163 /*
164 * Determine the generation of the ES7000 currently running.
165 *
166 * es7000_plat = 1 if the machine is a 5xx ES7000 box
167 * es7000_plat = 2 if the machine is a x86_64 ES7000 box
168 *
169 */
170 if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
171 es7000_plat = ES7000_ZORRO;
172 else
173 es7000_plat = ES7000_CLASSIC;
174}
175
176/*
177 * Parse the OEM Table:
178 */
179static int parse_unisys_oem(char *oemptr)
180{
181 int i;
182 int success = 0;
183 unsigned char type, size;
184 unsigned long val;
185 char *tp = NULL;
186 struct psai *psaip = NULL;
187 struct mip_reg_info *mi;
188 struct mip_reg *host, *mip;
189
190 tp = oemptr;
191
192 tp += 8;
193
194 for (i = 0; i <= 6; i++) {
195 type = *tp++;
196 size = *tp++;
197 tp -= 2;
198 switch (type) {
199 case MIP_REG:
200 mi = (struct mip_reg_info *)tp;
201 val = MIP_RD_LO(mi->host_reg);
202 host_addr = val;
203 host = (struct mip_reg *)val;
204 host_reg = __va(host);
205 val = MIP_RD_LO(mi->mip_reg);
206 mip_port = MIP_PORT(mi->mip_info);
207 mip_addr = val;
208 mip = (struct mip_reg *)val;
209 mip_reg = __va(mip);
210 pr_debug("host_reg = 0x%lx\n",
211 (unsigned long)host_reg);
212 pr_debug("mip_reg = 0x%lx\n",
213 (unsigned long)mip_reg);
214 success++;
215 break;
216 case MIP_PSAI_REG:
217 psaip = (struct psai *)tp;
218 if (tp != NULL) {
219 if (psaip->addr)
220 psai = __va(psaip->addr);
221 else
222 psai = NULL;
223 success++;
224 }
225 break;
226 default:
227 break;
228 }
229 tp += size;
230 }
231
232 if (success < 2)
233 es7000_plat = NON_UNISYS;
234 else
235 setup_unisys();
236
237 return es7000_plat;
238}
239
240#ifdef CONFIG_ACPI
241static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
242{
243 struct acpi_table_header *header = NULL;
244 struct es7000_oem_table *table;
245 acpi_size tbl_size;
246 acpi_status ret;
247 int i = 0;
248
249 for (;;) {
250 ret = acpi_get_table_with_size("OEM1", i++, &header, &tbl_size);
251 if (!ACPI_SUCCESS(ret))
252 return -1;
253
254 if (!memcmp((char *) &header->oem_id, "UNISYS", 6))
255 break;
256
257 early_acpi_os_unmap_memory(header, tbl_size);
258 }
259
260 table = (void *)header;
261
262 oem_addrX = table->OEMTableAddr;
263 oem_size = table->OEMTableSize;
264
265 early_acpi_os_unmap_memory(header, tbl_size);
266
267 *oem_addr = (unsigned long)__acpi_map_table(oem_addrX, oem_size);
268
269 return 0;
270}
271
272static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr)
273{
274 if (!oem_addr)
275 return;
276
277 __acpi_unmap_table((char *)oem_addr, oem_size);
278}
279
280static int es7000_check_dsdt(void)
281{
282 struct acpi_table_header header;
283
284 if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) &&
285 !strncmp(header.oem_id, "UNISYS", 6))
286 return 1;
287 return 0;
288}
289
290static int es7000_acpi_ret;
291
292/* Hook from generic ACPI tables.c */
293static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
294{
295 unsigned long oem_addr = 0;
296 int check_dsdt;
297 int ret = 0;
298
299 /* check dsdt at first to avoid clear fix_map for oem_addr */
300 check_dsdt = es7000_check_dsdt();
301
302 if (!find_unisys_acpi_oem_table(&oem_addr)) {
303 if (check_dsdt) {
304 ret = parse_unisys_oem((char *)oem_addr);
305 } else {
306 setup_unisys();
307 ret = 1;
308 }
309 /*
310 * we need to unmap it
311 */
312 unmap_unisys_acpi_oem_table(oem_addr);
313 }
314
315 es7000_acpi_ret = ret;
316
317 return ret && !es7000_apic_is_cluster();
318}
319
320static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id)
321{
322 int ret = es7000_acpi_ret;
323
324 return ret && es7000_apic_is_cluster();
325}
326
327#else /* !CONFIG_ACPI: */
328static int es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
329{
330 return 0;
331}
332
333static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id)
334{
335 return 0;
336}
337#endif /* !CONFIG_ACPI */
338
339static void es7000_spin(int n)
340{
341 int i = 0;
342
343 while (i++ < n)
344 rep_nop();
345}
346
347static int es7000_mip_write(struct mip_reg *mip_reg)
348{
349 int status = 0;
350 int spin;
351
352 spin = MIP_SPIN;
353 while ((host_reg->off_0x38 & MIP_VALID) != 0) {
354 if (--spin <= 0) {
355 WARN(1, "Timeout waiting for Host Valid Flag\n");
356 return -1;
357 }
358 es7000_spin(MIP_SPIN);
359 }
360
361 memcpy(host_reg, mip_reg, sizeof(struct mip_reg));
362 outb(1, mip_port);
363
364 spin = MIP_SPIN;
365
366 while ((mip_reg->off_0x38 & MIP_VALID) == 0) {
367 if (--spin <= 0) {
368 WARN(1, "Timeout waiting for MIP Valid Flag\n");
369 return -1;
370 }
371 es7000_spin(MIP_SPIN);
372 }
373
374 status = (mip_reg->off_0x00 & 0xffff0000000000ULL) >> 48;
375 mip_reg->off_0x38 &= ~MIP_VALID;
376
377 return status;
378}
379
380static void es7000_enable_apic_mode(void)
381{
382 struct mip_reg es7000_mip_reg;
383 int mip_status;
384
385 if (!es7000_plat)
386 return;
387
388 pr_info("Enabling APIC mode.\n");
389 memset(&es7000_mip_reg, 0, sizeof(struct mip_reg));
390 es7000_mip_reg.off_0x00 = MIP_SW_APIC;
391 es7000_mip_reg.off_0x38 = MIP_VALID;
392
393 while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0)
394 WARN(1, "Command failed, status = %x\n", mip_status);
395}
396
397static unsigned int es7000_get_apic_id(unsigned long x)
398{
399 return (x >> 24) & 0xFF;
400}
401
402static void es7000_send_IPI_mask(const struct cpumask *mask, int vector)
403{
404 default_send_IPI_mask_sequence_phys(mask, vector);
405}
406
407static void es7000_send_IPI_allbutself(int vector)
408{
409 default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
410}
411
412static void es7000_send_IPI_all(int vector)
413{
414 es7000_send_IPI_mask(cpu_online_mask, vector);
415}
416
417static int es7000_apic_id_registered(void)
418{
419 return 1;
420}
421
422static const struct cpumask *target_cpus_cluster(void)
423{
424 return cpu_all_mask;
425}
426
427static const struct cpumask *es7000_target_cpus(void)
428{
429 return cpumask_of(smp_processor_id());
430}
431
432static unsigned long es7000_check_apicid_used(physid_mask_t *map, int apicid)
433{
434 return 0;
435}
436
437static unsigned long es7000_check_apicid_present(int bit)
438{
439 return physid_isset(bit, phys_cpu_present_map);
440}
441
442static int es7000_early_logical_apicid(int cpu)
443{
444 /* on es7000, logical apicid is the same as physical */
445 return early_per_cpu(x86_bios_cpu_apicid, cpu);
446}
447
448static unsigned long calculate_ldr(int cpu)
449{
450 unsigned long id = per_cpu(x86_bios_cpu_apicid, cpu);
451
452 return SET_APIC_LOGICAL_ID(id);
453}
454
455/*
456 * Set up the logical destination ID.
457 *
458 * Intel recommends to set DFR, LdR and TPR before enabling
459 * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
460 * document number 292116). So here it goes...
461 */
462static void es7000_init_apic_ldr_cluster(void)
463{
464 unsigned long val;
465 int cpu = smp_processor_id();
466
467 apic_write(APIC_DFR, APIC_DFR_CLUSTER);
468 val = calculate_ldr(cpu);
469 apic_write(APIC_LDR, val);
470}
471
472static void es7000_init_apic_ldr(void)
473{
474 unsigned long val;
475 int cpu = smp_processor_id();
476
477 apic_write(APIC_DFR, APIC_DFR_FLAT);
478 val = calculate_ldr(cpu);
479 apic_write(APIC_LDR, val);
480}
481
482static void es7000_setup_apic_routing(void)
483{
484 int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
485
486 pr_info("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n",
487 (apic_version[apic] == 0x14) ?
488 "Physical Cluster" : "Logical Cluster",
489 nr_ioapics, cpumask_bits(es7000_target_cpus())[0]);
490}
491
492static int es7000_cpu_present_to_apicid(int mps_cpu)
493{
494 if (!mps_cpu)
495 return boot_cpu_physical_apicid;
496 else if (mps_cpu < nr_cpu_ids)
497 return per_cpu(x86_bios_cpu_apicid, mps_cpu);
498 else
499 return BAD_APICID;
500}
501
502static int cpu_id;
503
504static void es7000_apicid_to_cpu_present(int phys_apicid, physid_mask_t *retmap)
505{
506 physid_set_mask_of_physid(cpu_id, retmap);
507 ++cpu_id;
508}
509
510static void es7000_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
511{
512 /* For clustered we don't have a good way to do this yet - hack */
513 physids_promote(0xFFL, retmap);
514}
515
516static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
517{
518 boot_cpu_physical_apicid = read_apic_id();
519 return 1;
520}
521
522static inline int
523es7000_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id)
524{
525 unsigned int round = 0;
526 unsigned int cpu, uninitialized_var(apicid);
527
528 /*
529 * The cpus in the mask must all be on the apic cluster.
530 */
531 for_each_cpu_and(cpu, cpumask, cpu_online_mask) {
532 int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
533
534 if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
535 WARN(1, "Not a valid mask!");
536
537 return -EINVAL;
538 }
539 apicid |= new_apicid;
540 round++;
541 }
542 if (!round)
543 return -EINVAL;
544 *dest_id = apicid;
545 return 0;
546}
547
548static int
549es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask,
550 const struct cpumask *andmask,
551 unsigned int *apicid)
552{
553 cpumask_var_t cpumask;
554 *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0);
555
556 if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
557 return 0;
558
559 cpumask_and(cpumask, inmask, andmask);
560 es7000_cpu_mask_to_apicid(cpumask, apicid);
561
562 free_cpumask_var(cpumask);
563
564 return 0;
565}
566
567static int es7000_phys_pkg_id(int cpuid_apic, int index_msb)
568{
569 return cpuid_apic >> index_msb;
570}
571
572static int probe_es7000(void)
573{
574 /* probed later in mptable/ACPI hooks */
575 return 0;
576}
577
578static int es7000_mps_ret;
579static int es7000_mps_oem_check(struct mpc_table *mpc, char *oem,
580 char *productid)
581{
582 int ret = 0;
583
584 if (mpc->oemptr) {
585 struct mpc_oemtable *oem_table =
586 (struct mpc_oemtable *)mpc->oemptr;
587
588 if (!strncmp(oem, "UNISYS", 6))
589 ret = parse_unisys_oem((char *)oem_table);
590 }
591
592 es7000_mps_ret = ret;
593
594 return ret && !es7000_apic_is_cluster();
595}
596
597static int es7000_mps_oem_check_cluster(struct mpc_table *mpc, char *oem,
598 char *productid)
599{
600 int ret = es7000_mps_ret;
601
602 return ret && es7000_apic_is_cluster();
603}
604
605/* We've been warned by a false positive warning.Use __refdata to keep calm. */
606static struct apic __refdata apic_es7000_cluster = {
607
608 .name = "es7000",
609 .probe = probe_es7000,
610 .acpi_madt_oem_check = es7000_acpi_madt_oem_check_cluster,
611 .apic_id_valid = default_apic_id_valid,
612 .apic_id_registered = es7000_apic_id_registered,
613
614 .irq_delivery_mode = dest_LowestPrio,
615 /* logical delivery broadcast to all procs: */
616 .irq_dest_mode = 1,
617
618 .target_cpus = target_cpus_cluster,
619 .disable_esr = 1,
620 .dest_logical = 0,
621 .check_apicid_used = es7000_check_apicid_used,
622 .check_apicid_present = es7000_check_apicid_present,
623
624 .vector_allocation_domain = flat_vector_allocation_domain,
625 .init_apic_ldr = es7000_init_apic_ldr_cluster,
626
627 .ioapic_phys_id_map = es7000_ioapic_phys_id_map,
628 .setup_apic_routing = es7000_setup_apic_routing,
629 .multi_timer_check = NULL,
630 .cpu_present_to_apicid = es7000_cpu_present_to_apicid,
631 .apicid_to_cpu_present = es7000_apicid_to_cpu_present,
632 .setup_portio_remap = NULL,
633 .check_phys_apicid_present = es7000_check_phys_apicid_present,
634 .enable_apic_mode = es7000_enable_apic_mode,
635 .phys_pkg_id = es7000_phys_pkg_id,
636 .mps_oem_check = es7000_mps_oem_check_cluster,
637
638 .get_apic_id = es7000_get_apic_id,
639 .set_apic_id = NULL,
640 .apic_id_mask = 0xFF << 24,
641
642 .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and,
643
644 .send_IPI_mask = es7000_send_IPI_mask,
645 .send_IPI_mask_allbutself = NULL,
646 .send_IPI_allbutself = es7000_send_IPI_allbutself,
647 .send_IPI_all = es7000_send_IPI_all,
648 .send_IPI_self = default_send_IPI_self,
649
650 .wakeup_secondary_cpu = wakeup_secondary_cpu_via_mip,
651
652 .trampoline_phys_low = 0x467,
653 .trampoline_phys_high = 0x469,
654
655 .wait_for_init_deassert = false,
656 /* Nothing to do for most platforms, since cleared by the INIT cycle: */
657 .smp_callin_clear_local_apic = NULL,
658 .inquire_remote_apic = default_inquire_remote_apic,
659
660 .read = native_apic_mem_read,
661 .write = native_apic_mem_write,
662 .eoi_write = native_apic_mem_write,
663 .icr_read = native_apic_icr_read,
664 .icr_write = native_apic_icr_write,
665 .wait_icr_idle = native_apic_wait_icr_idle,
666 .safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
667
668 .x86_32_early_logical_apicid = es7000_early_logical_apicid,
669};
670
671static struct apic __refdata apic_es7000 = {
672
673 .name = "es7000",
674 .probe = probe_es7000,
675 .acpi_madt_oem_check = es7000_acpi_madt_oem_check,
676 .apic_id_valid = default_apic_id_valid,
677 .apic_id_registered = es7000_apic_id_registered,
678
679 .irq_delivery_mode = dest_Fixed,
680 /* phys delivery to target CPUs: */
681 .irq_dest_mode = 0,
682
683 .target_cpus = es7000_target_cpus,
684 .disable_esr = 1,
685 .dest_logical = 0,
686 .check_apicid_used = es7000_check_apicid_used,
687 .check_apicid_present = es7000_check_apicid_present,
688
689 .vector_allocation_domain = flat_vector_allocation_domain,
690 .init_apic_ldr = es7000_init_apic_ldr,
691
692 .ioapic_phys_id_map = es7000_ioapic_phys_id_map,
693 .setup_apic_routing = es7000_setup_apic_routing,
694 .multi_timer_check = NULL,
695 .cpu_present_to_apicid = es7000_cpu_present_to_apicid,
696 .apicid_to_cpu_present = es7000_apicid_to_cpu_present,
697 .setup_portio_remap = NULL,
698 .check_phys_apicid_present = es7000_check_phys_apicid_present,
699 .enable_apic_mode = es7000_enable_apic_mode,
700 .phys_pkg_id = es7000_phys_pkg_id,
701 .mps_oem_check = es7000_mps_oem_check,
702
703 .get_apic_id = es7000_get_apic_id,
704 .set_apic_id = NULL,
705 .apic_id_mask = 0xFF << 24,
706
707 .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and,
708
709 .send_IPI_mask = es7000_send_IPI_mask,
710 .send_IPI_mask_allbutself = NULL,
711 .send_IPI_allbutself = es7000_send_IPI_allbutself,
712 .send_IPI_all = es7000_send_IPI_all,
713 .send_IPI_self = default_send_IPI_self,
714
715 .trampoline_phys_low = 0x467,
716 .trampoline_phys_high = 0x469,
717
718 .wait_for_init_deassert = true,
719 /* Nothing to do for most platforms, since cleared by the INIT cycle: */
720 .smp_callin_clear_local_apic = NULL,
721 .inquire_remote_apic = default_inquire_remote_apic,
722
723 .read = native_apic_mem_read,
724 .write = native_apic_mem_write,
725 .eoi_write = native_apic_mem_write,
726 .icr_read = native_apic_icr_read,
727 .icr_write = native_apic_icr_write,
728 .wait_icr_idle = native_apic_wait_icr_idle,
729 .safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
730
731 .x86_32_early_logical_apicid = es7000_early_logical_apicid,
732};
733
734/*
735 * Need to check for es7000 followed by es7000_cluster, so this order
736 * in apic_drivers is important.
737 */
738apic_drivers(apic_es7000, apic_es7000_cluster);
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c
deleted file mode 100644
index 030ea1c04f72..000000000000
--- a/arch/x86/kernel/apic/numaq_32.c
+++ /dev/null
@@ -1,524 +0,0 @@
1/*
2 * Written by: Patricia Gaughen, IBM Corporation
3 *
4 * Copyright (C) 2002, IBM Corp.
5 * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
6 *
7 * All rights reserved.
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, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
17 * NON INFRINGEMENT. See the GNU General Public License for more
18 * details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * Send feedback to <gone@us.ibm.com>
25 */
26#include <linux/nodemask.h>
27#include <linux/topology.h>
28#include <linux/bootmem.h>
29#include <linux/memblock.h>
30#include <linux/threads.h>
31#include <linux/cpumask.h>
32#include <linux/kernel.h>
33#include <linux/mmzone.h>
34#include <linux/module.h>
35#include <linux/string.h>
36#include <linux/init.h>
37#include <linux/numa.h>
38#include <linux/smp.h>
39#include <linux/io.h>
40#include <linux/mm.h>
41
42#include <asm/processor.h>
43#include <asm/fixmap.h>
44#include <asm/mpspec.h>
45#include <asm/numaq.h>
46#include <asm/setup.h>
47#include <asm/apic.h>
48#include <asm/e820.h>
49#include <asm/ipi.h>
50
51int found_numaq;
52
53/*
54 * Have to match translation table entries to main table entries by counter
55 * hence the mpc_record variable .... can't see a less disgusting way of
56 * doing this ....
57 */
58struct mpc_trans {
59 unsigned char mpc_type;
60 unsigned char trans_len;
61 unsigned char trans_type;
62 unsigned char trans_quad;
63 unsigned char trans_global;
64 unsigned char trans_local;
65 unsigned short trans_reserved;
66};
67
68static int mpc_record;
69
70static struct mpc_trans *translation_table[MAX_MPC_ENTRY];
71
72int mp_bus_id_to_node[MAX_MP_BUSSES];
73int mp_bus_id_to_local[MAX_MP_BUSSES];
74int quad_local_to_mp_bus_id[NR_CPUS/4][4];
75
76
77static inline void numaq_register_node(int node, struct sys_cfg_data *scd)
78{
79 struct eachquadmem *eq = scd->eq + node;
80 u64 start = (u64)(eq->hi_shrd_mem_start - eq->priv_mem_size) << 20;
81 u64 end = (u64)(eq->hi_shrd_mem_start + eq->hi_shrd_mem_size) << 20;
82 int ret;
83
84 node_set(node, numa_nodes_parsed);
85 ret = numa_add_memblk(node, start, end);
86 BUG_ON(ret < 0);
87}
88
89/*
90 * Function: smp_dump_qct()
91 *
92 * Description: gets memory layout from the quad config table. This
93 * function also updates numa_nodes_parsed with the nodes (quads) present.
94 */
95static void __init smp_dump_qct(void)
96{
97 struct sys_cfg_data *scd;
98 int node;
99
100 scd = (void *)__va(SYS_CFG_DATA_PRIV_ADDR);
101
102 for_each_node(node) {
103 if (scd->quads_present31_0 & (1 << node))
104 numaq_register_node(node, scd);
105 }
106}
107
108void numaq_tsc_disable(void)
109{
110 if (!found_numaq)
111 return;
112
113 if (num_online_nodes() > 1) {
114 printk(KERN_DEBUG "NUMAQ: disabling TSC\n");
115 setup_clear_cpu_cap(X86_FEATURE_TSC);
116 }
117}
118
119static void __init numaq_tsc_init(void)
120{
121 numaq_tsc_disable();
122}
123
124static inline int generate_logical_apicid(int quad, int phys_apicid)
125{
126 return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
127}
128
129/* x86_quirks member */
130static int mpc_apic_id(struct mpc_cpu *m)
131{
132 int quad = translation_table[mpc_record]->trans_quad;
133 int logical_apicid = generate_logical_apicid(quad, m->apicid);
134
135 printk(KERN_DEBUG
136 "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n",
137 m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8,
138 (m->cpufeature & CPU_MODEL_MASK) >> 4,
139 m->apicver, quad, logical_apicid);
140
141 return logical_apicid;
142}
143
144/* x86_quirks member */
145static void mpc_oem_bus_info(struct mpc_bus *m, char *name)
146{
147 int quad = translation_table[mpc_record]->trans_quad;
148 int local = translation_table[mpc_record]->trans_local;
149
150 mp_bus_id_to_node[m->busid] = quad;
151 mp_bus_id_to_local[m->busid] = local;
152
153 printk(KERN_INFO "Bus #%d is %s (node %d)\n", m->busid, name, quad);
154}
155
156/* x86_quirks member */
157static void mpc_oem_pci_bus(struct mpc_bus *m)
158{
159 int quad = translation_table[mpc_record]->trans_quad;
160 int local = translation_table[mpc_record]->trans_local;
161
162 quad_local_to_mp_bus_id[quad][local] = m->busid;
163}
164
165/*
166 * Called from mpparse code.
167 * mode = 0: prescan
168 * mode = 1: one mpc entry scanned
169 */
170static void numaq_mpc_record(unsigned int mode)
171{
172 if (!mode)
173 mpc_record = 0;
174 else
175 mpc_record++;
176}
177
178static void __init MP_translation_info(struct mpc_trans *m)
179{
180 printk(KERN_INFO
181 "Translation: record %d, type %d, quad %d, global %d, local %d\n",
182 mpc_record, m->trans_type, m->trans_quad, m->trans_global,
183 m->trans_local);
184
185 if (mpc_record >= MAX_MPC_ENTRY)
186 printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
187 else
188 translation_table[mpc_record] = m; /* stash this for later */
189
190 if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad))
191 node_set_online(m->trans_quad);
192}
193
194static int __init mpf_checksum(unsigned char *mp, int len)
195{
196 int sum = 0;
197
198 while (len--)
199 sum += *mp++;
200
201 return sum & 0xFF;
202}
203
204/*
205 * Read/parse the MPC oem tables
206 */
207static void __init smp_read_mpc_oem(struct mpc_table *mpc)
208{
209 struct mpc_oemtable *oemtable = (void *)(long)mpc->oemptr;
210 int count = sizeof(*oemtable); /* the header size */
211 unsigned char *oemptr = ((unsigned char *)oemtable) + count;
212
213 mpc_record = 0;
214 printk(KERN_INFO
215 "Found an OEM MPC table at %8p - parsing it...\n", oemtable);
216
217 if (memcmp(oemtable->signature, MPC_OEM_SIGNATURE, 4)) {
218 printk(KERN_WARNING
219 "SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
220 oemtable->signature[0], oemtable->signature[1],
221 oemtable->signature[2], oemtable->signature[3]);
222 return;
223 }
224
225 if (mpf_checksum((unsigned char *)oemtable, oemtable->length)) {
226 printk(KERN_WARNING "SMP oem mptable: checksum error!\n");
227 return;
228 }
229
230 while (count < oemtable->length) {
231 switch (*oemptr) {
232 case MP_TRANSLATION:
233 {
234 struct mpc_trans *m = (void *)oemptr;
235
236 MP_translation_info(m);
237 oemptr += sizeof(*m);
238 count += sizeof(*m);
239 ++mpc_record;
240 break;
241 }
242 default:
243 printk(KERN_WARNING
244 "Unrecognised OEM table entry type! - %d\n",
245 (int)*oemptr);
246 return;
247 }
248 }
249}
250
251static __init void early_check_numaq(void)
252{
253 /*
254 * get boot-time SMP configuration:
255 */
256 if (smp_found_config)
257 early_get_smp_config();
258
259 if (found_numaq) {
260 x86_init.mpparse.mpc_record = numaq_mpc_record;
261 x86_init.mpparse.setup_ioapic_ids = x86_init_noop;
262 x86_init.mpparse.mpc_apic_id = mpc_apic_id;
263 x86_init.mpparse.smp_read_mpc_oem = smp_read_mpc_oem;
264 x86_init.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus;
265 x86_init.mpparse.mpc_oem_bus_info = mpc_oem_bus_info;
266 x86_init.timers.tsc_pre_init = numaq_tsc_init;
267 x86_init.pci.init = pci_numaq_init;
268 }
269}
270
271int __init numaq_numa_init(void)
272{
273 early_check_numaq();
274 if (!found_numaq)
275 return -ENOENT;
276 smp_dump_qct();
277
278 return 0;
279}
280
281#define NUMAQ_APIC_DFR_VALUE (APIC_DFR_CLUSTER)
282
283static inline unsigned int numaq_get_apic_id(unsigned long x)
284{
285 return (x >> 24) & 0x0F;
286}
287
288static inline void numaq_send_IPI_mask(const struct cpumask *mask, int vector)
289{
290 default_send_IPI_mask_sequence_logical(mask, vector);
291}
292
293static inline void numaq_send_IPI_allbutself(int vector)
294{
295 default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector);
296}
297
298static inline void numaq_send_IPI_all(int vector)
299{
300 numaq_send_IPI_mask(cpu_online_mask, vector);
301}
302
303#define NUMAQ_TRAMPOLINE_PHYS_LOW (0x8)
304#define NUMAQ_TRAMPOLINE_PHYS_HIGH (0xa)
305
306/*
307 * Because we use NMIs rather than the INIT-STARTUP sequence to
308 * bootstrap the CPUs, the APIC may be in a weird state. Kick it:
309 */
310static inline void numaq_smp_callin_clear_local_apic(void)
311{
312 clear_local_APIC();
313}
314
315static inline const struct cpumask *numaq_target_cpus(void)
316{
317 return cpu_all_mask;
318}
319
320static unsigned long numaq_check_apicid_used(physid_mask_t *map, int apicid)
321{
322 return physid_isset(apicid, *map);
323}
324
325static inline unsigned long numaq_check_apicid_present(int bit)
326{
327 return physid_isset(bit, phys_cpu_present_map);
328}
329
330static inline int numaq_apic_id_registered(void)
331{
332 return 1;
333}
334
335static inline void numaq_init_apic_ldr(void)
336{
337 /* Already done in NUMA-Q firmware */
338}
339
340static inline void numaq_setup_apic_routing(void)
341{
342 printk(KERN_INFO
343 "Enabling APIC mode: NUMA-Q. Using %d I/O APICs\n",
344 nr_ioapics);
345}
346
347/*
348 * Skip adding the timer int on secondary nodes, which causes
349 * a small but painful rift in the time-space continuum.
350 */
351static inline int numaq_multi_timer_check(int apic, int irq)
352{
353 return apic != 0 && irq == 0;
354}
355
356static inline void numaq_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
357{
358 /* We don't have a good way to do this yet - hack */
359 return physids_promote(0xFUL, retmap);
360}
361
362/*
363 * Supporting over 60 cpus on NUMA-Q requires a locality-dependent
364 * cpu to APIC ID relation to properly interact with the intelligent
365 * mode of the cluster controller.
366 */
367static inline int numaq_cpu_present_to_apicid(int mps_cpu)
368{
369 if (mps_cpu < 60)
370 return ((mps_cpu >> 2) << 4) | (1 << (mps_cpu & 0x3));
371 else
372 return BAD_APICID;
373}
374
375static inline int numaq_apicid_to_node(int logical_apicid)
376{
377 return logical_apicid >> 4;
378}
379
380static int numaq_numa_cpu_node(int cpu)
381{
382 int logical_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
383
384 if (logical_apicid != BAD_APICID)
385 return numaq_apicid_to_node(logical_apicid);
386 return NUMA_NO_NODE;
387}
388
389static void numaq_apicid_to_cpu_present(int logical_apicid, physid_mask_t *retmap)
390{
391 int node = numaq_apicid_to_node(logical_apicid);
392 int cpu = __ffs(logical_apicid & 0xf);
393
394 physid_set_mask_of_physid(cpu + 4*node, retmap);
395}
396
397/* Where the IO area was mapped on multiquad, always 0 otherwise */
398void *xquad_portio;
399
400static inline int numaq_check_phys_apicid_present(int phys_apicid)
401{
402 return 1;
403}
404
405/*
406 * We use physical apicids here, not logical, so just return the default
407 * physical broadcast to stop people from breaking us
408 */
409static int
410numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
411 const struct cpumask *andmask,
412 unsigned int *apicid)
413{
414 *apicid = 0x0F;
415 return 0;
416}
417
418/* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */
419static inline int numaq_phys_pkg_id(int cpuid_apic, int index_msb)
420{
421 return cpuid_apic >> index_msb;
422}
423
424static int
425numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
426{
427 if (strncmp(oem, "IBM NUMA", 8))
428 printk(KERN_ERR "Warning! Not a NUMA-Q system!\n");
429 else
430 found_numaq = 1;
431
432 return found_numaq;
433}
434
435static int probe_numaq(void)
436{
437 /* already know from get_memcfg_numaq() */
438 return found_numaq;
439}
440
441static void numaq_setup_portio_remap(void)
442{
443 int num_quads = num_online_nodes();
444
445 if (num_quads <= 1)
446 return;
447
448 printk(KERN_INFO
449 "Remapping cross-quad port I/O for %d quads\n", num_quads);
450
451 xquad_portio = ioremap(XQUAD_PORTIO_BASE, num_quads*XQUAD_PORTIO_QUAD);
452
453 printk(KERN_INFO
454 "xquad_portio vaddr 0x%08lx, len %08lx\n",
455 (u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD);
456}
457
458/* Use __refdata to keep false positive warning calm. */
459static struct apic __refdata apic_numaq = {
460
461 .name = "NUMAQ",
462 .probe = probe_numaq,
463 .acpi_madt_oem_check = NULL,
464 .apic_id_valid = default_apic_id_valid,
465 .apic_id_registered = numaq_apic_id_registered,
466
467 .irq_delivery_mode = dest_LowestPrio,
468 /* physical delivery on LOCAL quad: */
469 .irq_dest_mode = 0,
470
471 .target_cpus = numaq_target_cpus,
472 .disable_esr = 1,
473 .dest_logical = APIC_DEST_LOGICAL,
474 .check_apicid_used = numaq_check_apicid_used,
475 .check_apicid_present = numaq_check_apicid_present,
476
477 .vector_allocation_domain = flat_vector_allocation_domain,
478 .init_apic_ldr = numaq_init_apic_ldr,
479
480 .ioapic_phys_id_map = numaq_ioapic_phys_id_map,
481 .setup_apic_routing = numaq_setup_apic_routing,
482 .multi_timer_check = numaq_multi_timer_check,
483 .cpu_present_to_apicid = numaq_cpu_present_to_apicid,
484 .apicid_to_cpu_present = numaq_apicid_to_cpu_present,
485 .setup_portio_remap = numaq_setup_portio_remap,
486 .check_phys_apicid_present = numaq_check_phys_apicid_present,
487 .enable_apic_mode = NULL,
488 .phys_pkg_id = numaq_phys_pkg_id,
489 .mps_oem_check = numaq_mps_oem_check,
490
491 .get_apic_id = numaq_get_apic_id,
492 .set_apic_id = NULL,
493 .apic_id_mask = 0x0F << 24,
494
495 .cpu_mask_to_apicid_and = numaq_cpu_mask_to_apicid_and,
496
497 .send_IPI_mask = numaq_send_IPI_mask,
498 .send_IPI_mask_allbutself = NULL,
499 .send_IPI_allbutself = numaq_send_IPI_allbutself,
500 .send_IPI_all = numaq_send_IPI_all,
501 .send_IPI_self = default_send_IPI_self,
502
503 .wakeup_secondary_cpu = wakeup_secondary_cpu_via_nmi,
504 .trampoline_phys_low = NUMAQ_TRAMPOLINE_PHYS_LOW,
505 .trampoline_phys_high = NUMAQ_TRAMPOLINE_PHYS_HIGH,
506
507 /* We don't do anything here because we use NMI's to boot instead */
508 .wait_for_init_deassert = false,
509 .smp_callin_clear_local_apic = numaq_smp_callin_clear_local_apic,
510 .inquire_remote_apic = NULL,
511
512 .read = native_apic_mem_read,
513 .write = native_apic_mem_write,
514 .eoi_write = native_apic_mem_write,
515 .icr_read = native_apic_icr_read,
516 .icr_write = native_apic_icr_write,
517 .wait_icr_idle = native_apic_wait_icr_idle,
518 .safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
519
520 .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid,
521 .x86_32_numa_cpu_node = numaq_numa_cpu_node,
522};
523
524apic_driver(apic_numaq);
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c
deleted file mode 100644
index b656128611cd..000000000000
--- a/arch/x86/kernel/apic/summit_32.c
+++ /dev/null
@@ -1,550 +0,0 @@
1/*
2 * IBM Summit-Specific Code
3 *
4 * Written By: Matthew Dobson, IBM Corporation
5 *
6 * Copyright (c) 2003 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <colpatch@us.ibm.com>
26 *
27 */
28
29#define pr_fmt(fmt) "summit: %s: " fmt, __func__
30
31#include <linux/mm.h>
32#include <asm/io.h>
33#include <asm/bios_ebda.h>
34
35/*
36 * APIC driver for the IBM "Summit" chipset.
37 */
38#include <linux/threads.h>
39#include <linux/cpumask.h>
40#include <asm/mpspec.h>
41#include <asm/apic.h>
42#include <asm/smp.h>
43#include <asm/fixmap.h>
44#include <asm/apicdef.h>
45#include <asm/ipi.h>
46#include <linux/kernel.h>
47#include <linux/string.h>
48#include <linux/gfp.h>
49#include <linux/smp.h>
50
51static unsigned summit_get_apic_id(unsigned long x)
52{
53 return (x >> 24) & 0xFF;
54}
55
56static inline void summit_send_IPI_mask(const struct cpumask *mask, int vector)
57{
58 default_send_IPI_mask_sequence_logical(mask, vector);
59}
60
61static void summit_send_IPI_allbutself(int vector)
62{
63 default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector);
64}
65
66static void summit_send_IPI_all(int vector)
67{
68 summit_send_IPI_mask(cpu_online_mask, vector);
69}
70
71#include <asm/tsc.h>
72
73extern int use_cyclone;
74
75#ifdef CONFIG_X86_SUMMIT_NUMA
76static void setup_summit(void);
77#else
78static inline void setup_summit(void) {}
79#endif
80
81static int summit_mps_oem_check(struct mpc_table *mpc, char *oem,
82 char *productid)
83{
84 if (!strncmp(oem, "IBM ENSW", 8) &&
85 (!strncmp(productid, "VIGIL SMP", 9)
86 || !strncmp(productid, "EXA", 3)
87 || !strncmp(productid, "RUTHLESS SMP", 12))){
88 mark_tsc_unstable("Summit based system");
89 use_cyclone = 1; /*enable cyclone-timer*/
90 setup_summit();
91 return 1;
92 }
93 return 0;
94}
95
96/* Hook from generic ACPI tables.c */
97static int summit_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
98{
99 if (!strncmp(oem_id, "IBM", 3) &&
100 (!strncmp(oem_table_id, "SERVIGIL", 8)
101 || !strncmp(oem_table_id, "EXA", 3))){
102 mark_tsc_unstable("Summit based system");
103 use_cyclone = 1; /*enable cyclone-timer*/
104 setup_summit();
105 return 1;
106 }
107 return 0;
108}
109
110struct rio_table_hdr {
111 unsigned char version; /* Version number of this data structure */
112 /* Version 3 adds chassis_num & WP_index */
113 unsigned char num_scal_dev; /* # of Scalability devices (Twisters for Vigil) */
114 unsigned char num_rio_dev; /* # of RIO I/O devices (Cyclones and Winnipegs) */
115} __attribute__((packed));
116
117struct scal_detail {
118 unsigned char node_id; /* Scalability Node ID */
119 unsigned long CBAR; /* Address of 1MB register space */
120 unsigned char port0node; /* Node ID port connected to: 0xFF=None */
121 unsigned char port0port; /* Port num port connected to: 0,1,2, or 0xFF=None */
122 unsigned char port1node; /* Node ID port connected to: 0xFF = None */
123 unsigned char port1port; /* Port num port connected to: 0,1,2, or 0xFF=None */
124 unsigned char port2node; /* Node ID port connected to: 0xFF = None */
125 unsigned char port2port; /* Port num port connected to: 0,1,2, or 0xFF=None */
126 unsigned char chassis_num; /* 1 based Chassis number (1 = boot node) */
127} __attribute__((packed));
128
129struct rio_detail {
130 unsigned char node_id; /* RIO Node ID */
131 unsigned long BBAR; /* Address of 1MB register space */
132 unsigned char type; /* Type of device */
133 unsigned char owner_id; /* For WPEG: Node ID of Cyclone that owns this WPEG*/
134 /* For CYC: Node ID of Twister that owns this CYC */
135 unsigned char port0node; /* Node ID port connected to: 0xFF=None */
136 unsigned char port0port; /* Port num port connected to: 0,1,2, or 0xFF=None */
137 unsigned char port1node; /* Node ID port connected to: 0xFF=None */
138 unsigned char port1port; /* Port num port connected to: 0,1,2, or 0xFF=None */
139 unsigned char first_slot; /* For WPEG: Lowest slot number below this WPEG */
140 /* For CYC: 0 */
141 unsigned char status; /* For WPEG: Bit 0 = 1 : the XAPIC is used */
142 /* = 0 : the XAPIC is not used, ie:*/
143 /* ints fwded to another XAPIC */
144 /* Bits1:7 Reserved */
145 /* For CYC: Bits0:7 Reserved */
146 unsigned char WP_index; /* For WPEG: WPEG instance index - lower ones have */
147 /* lower slot numbers/PCI bus numbers */
148 /* For CYC: No meaning */
149 unsigned char chassis_num; /* 1 based Chassis number */
150 /* For LookOut WPEGs this field indicates the */
151 /* Expansion Chassis #, enumerated from Boot */
152 /* Node WPEG external port, then Boot Node CYC */
153 /* external port, then Next Vigil chassis WPEG */
154 /* external port, etc. */
155 /* Shared Lookouts have only 1 chassis number (the */
156 /* first one assigned) */
157} __attribute__((packed));
158
159
160typedef enum {
161 CompatTwister = 0, /* Compatibility Twister */
162 AltTwister = 1, /* Alternate Twister of internal 8-way */
163 CompatCyclone = 2, /* Compatibility Cyclone */
164 AltCyclone = 3, /* Alternate Cyclone of internal 8-way */
165 CompatWPEG = 4, /* Compatibility WPEG */
166 AltWPEG = 5, /* Second Planar WPEG */
167 LookOutAWPEG = 6, /* LookOut WPEG */
168 LookOutBWPEG = 7, /* LookOut WPEG */
169} node_type;
170
171static inline int is_WPEG(struct rio_detail *rio){
172 return (rio->type == CompatWPEG || rio->type == AltWPEG ||
173 rio->type == LookOutAWPEG || rio->type == LookOutBWPEG);
174}
175
176#define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER)
177
178static const struct cpumask *summit_target_cpus(void)
179{
180 /* CPU_MASK_ALL (0xff) has undefined behaviour with
181 * dest_LowestPrio mode logical clustered apic interrupt routing
182 * Just start on cpu 0. IRQ balancing will spread load
183 */
184 return cpumask_of(0);
185}
186
187static unsigned long summit_check_apicid_used(physid_mask_t *map, int apicid)
188{
189 return 0;
190}
191
192/* we don't use the phys_cpu_present_map to indicate apicid presence */
193static unsigned long summit_check_apicid_present(int bit)
194{
195 return 1;
196}
197
198static int summit_early_logical_apicid(int cpu)
199{
200 int count = 0;
201 u8 my_id = early_per_cpu(x86_cpu_to_apicid, cpu);
202 u8 my_cluster = APIC_CLUSTER(my_id);
203#ifdef CONFIG_SMP
204 u8 lid;
205 int i;
206
207 /* Create logical APIC IDs by counting CPUs already in cluster. */
208 for (count = 0, i = nr_cpu_ids; --i >= 0; ) {
209 lid = early_per_cpu(x86_cpu_to_logical_apicid, i);
210 if (lid != BAD_APICID && APIC_CLUSTER(lid) == my_cluster)
211 ++count;
212 }
213#endif
214 /* We only have a 4 wide bitmap in cluster mode. If a deranged
215 * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
216 BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
217 return my_cluster | (1UL << count);
218}
219
220static void summit_init_apic_ldr(void)
221{
222 int cpu = smp_processor_id();
223 unsigned long id = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
224 unsigned long val;
225
226 apic_write(APIC_DFR, SUMMIT_APIC_DFR_VALUE);
227 val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
228 val |= SET_APIC_LOGICAL_ID(id);
229 apic_write(APIC_LDR, val);
230}
231
232static int summit_apic_id_registered(void)
233{
234 return 1;
235}
236
237static void summit_setup_apic_routing(void)
238{
239 pr_info("Enabling APIC mode: Summit. Using %d I/O APICs\n",
240 nr_ioapics);
241}
242
243static int summit_cpu_present_to_apicid(int mps_cpu)
244{
245 if (mps_cpu < nr_cpu_ids)
246 return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu);
247 else
248 return BAD_APICID;
249}
250
251static void summit_ioapic_phys_id_map(physid_mask_t *phys_id_map, physid_mask_t *retmap)
252{
253 /* For clustered we don't have a good way to do this yet - hack */
254 physids_promote(0x0FL, retmap);
255}
256
257static void summit_apicid_to_cpu_present(int apicid, physid_mask_t *retmap)
258{
259 physid_set_mask_of_physid(0, retmap);
260}
261
262static int summit_check_phys_apicid_present(int physical_apicid)
263{
264 return 1;
265}
266
267static inline int
268summit_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id)
269{
270 unsigned int round = 0;
271 unsigned int cpu, apicid = 0;
272
273 /*
274 * The cpus in the mask must all be on the apic cluster.
275 */
276 for_each_cpu_and(cpu, cpumask, cpu_online_mask) {
277 int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
278
279 if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
280 pr_err("Not a valid mask!\n");
281 return -EINVAL;
282 }
283 apicid |= new_apicid;
284 round++;
285 }
286 if (!round)
287 return -EINVAL;
288 *dest_id = apicid;
289 return 0;
290}
291
292static int
293summit_cpu_mask_to_apicid_and(const struct cpumask *inmask,
294 const struct cpumask *andmask,
295 unsigned int *apicid)
296{
297 cpumask_var_t cpumask;
298 *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0);
299
300 if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
301 return 0;
302
303 cpumask_and(cpumask, inmask, andmask);
304 summit_cpu_mask_to_apicid(cpumask, apicid);
305
306 free_cpumask_var(cpumask);
307
308 return 0;
309}
310
311/*
312 * cpuid returns the value latched in the HW at reset, not the APIC ID
313 * register's value. For any box whose BIOS changes APIC IDs, like
314 * clustered APIC systems, we must use hard_smp_processor_id.
315 *
316 * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
317 */
318static int summit_phys_pkg_id(int cpuid_apic, int index_msb)
319{
320 return hard_smp_processor_id() >> index_msb;
321}
322
323static int probe_summit(void)
324{
325 /* probed later in mptable/ACPI hooks */
326 return 0;
327}
328
329#ifdef CONFIG_X86_SUMMIT_NUMA
330static struct rio_table_hdr *rio_table_hdr;
331static struct scal_detail *scal_devs[MAX_NUMNODES];
332static struct rio_detail *rio_devs[MAX_NUMNODES*4];
333
334#ifndef CONFIG_X86_NUMAQ
335static int mp_bus_id_to_node[MAX_MP_BUSSES];
336#endif
337
338static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus)
339{
340 int twister = 0, node = 0;
341 int i, bus, num_buses;
342
343 for (i = 0; i < rio_table_hdr->num_rio_dev; i++) {
344 if (rio_devs[i]->node_id == rio_devs[wpeg_num]->owner_id) {
345 twister = rio_devs[i]->owner_id;
346 break;
347 }
348 }
349 if (i == rio_table_hdr->num_rio_dev) {
350 pr_err("Couldn't find owner Cyclone for Winnipeg!\n");
351 return last_bus;
352 }
353
354 for (i = 0; i < rio_table_hdr->num_scal_dev; i++) {
355 if (scal_devs[i]->node_id == twister) {
356 node = scal_devs[i]->node_id;
357 break;
358 }
359 }
360 if (i == rio_table_hdr->num_scal_dev) {
361 pr_err("Couldn't find owner Twister for Cyclone!\n");
362 return last_bus;
363 }
364
365 switch (rio_devs[wpeg_num]->type) {
366 case CompatWPEG:
367 /*
368 * The Compatibility Winnipeg controls the 2 legacy buses,
369 * the 66MHz PCI bus [2 slots] and the 2 "extra" buses in case
370 * a PCI-PCI bridge card is used in either slot: total 5 buses.
371 */
372 num_buses = 5;
373 break;
374 case AltWPEG:
375 /*
376 * The Alternate Winnipeg controls the 2 133MHz buses [1 slot
377 * each], their 2 "extra" buses, the 100MHz bus [2 slots] and
378 * the "extra" buses for each of those slots: total 7 buses.
379 */
380 num_buses = 7;
381 break;
382 case LookOutAWPEG:
383 case LookOutBWPEG:
384 /*
385 * A Lookout Winnipeg controls 3 100MHz buses [2 slots each]
386 * & the "extra" buses for each of those slots: total 9 buses.
387 */
388 num_buses = 9;
389 break;
390 default:
391 pr_info("Unsupported Winnipeg type!\n");
392 return last_bus;
393 }
394
395 for (bus = last_bus; bus < last_bus + num_buses; bus++)
396 mp_bus_id_to_node[bus] = node;
397 return bus;
398}
399
400static int build_detail_arrays(void)
401{
402 unsigned long ptr;
403 int i, scal_detail_size, rio_detail_size;
404
405 if (rio_table_hdr->num_scal_dev > MAX_NUMNODES) {
406 pr_warn("MAX_NUMNODES too low! Defined as %d, but system has %d nodes\n",
407 MAX_NUMNODES, rio_table_hdr->num_scal_dev);
408 return 0;
409 }
410
411 switch (rio_table_hdr->version) {
412 default:
413 pr_warn("Invalid Rio Grande Table Version: %d\n",
414 rio_table_hdr->version);
415 return 0;
416 case 2:
417 scal_detail_size = 11;
418 rio_detail_size = 13;
419 break;
420 case 3:
421 scal_detail_size = 12;
422 rio_detail_size = 15;
423 break;
424 }
425
426 ptr = (unsigned long)rio_table_hdr + 3;
427 for (i = 0; i < rio_table_hdr->num_scal_dev; i++, ptr += scal_detail_size)
428 scal_devs[i] = (struct scal_detail *)ptr;
429
430 for (i = 0; i < rio_table_hdr->num_rio_dev; i++, ptr += rio_detail_size)
431 rio_devs[i] = (struct rio_detail *)ptr;
432
433 return 1;
434}
435
436void setup_summit(void)
437{
438 unsigned long ptr;
439 unsigned short offset;
440 int i, next_wpeg, next_bus = 0;
441
442 /* The pointer to the EBDA is stored in the word @ phys 0x40E(40:0E) */
443 ptr = get_bios_ebda();
444 ptr = (unsigned long)phys_to_virt(ptr);
445
446 rio_table_hdr = NULL;
447 offset = 0x180;
448 while (offset) {
449 /* The block id is stored in the 2nd word */
450 if (*((unsigned short *)(ptr + offset + 2)) == 0x4752) {
451 /* set the pointer past the offset & block id */
452 rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4);
453 break;
454 }
455 /* The next offset is stored in the 1st word. 0 means no more */
456 offset = *((unsigned short *)(ptr + offset));
457 }
458 if (!rio_table_hdr) {
459 pr_err("Unable to locate Rio Grande Table in EBDA - bailing!\n");
460 return;
461 }
462
463 if (!build_detail_arrays())
464 return;
465
466 /* The first Winnipeg we're looking for has an index of 0 */
467 next_wpeg = 0;
468 do {
469 for (i = 0; i < rio_table_hdr->num_rio_dev; i++) {
470 if (is_WPEG(rio_devs[i]) && rio_devs[i]->WP_index == next_wpeg) {
471 /* It's the Winnipeg we're looking for! */
472 next_bus = setup_pci_node_map_for_wpeg(i, next_bus);
473 next_wpeg++;
474 break;
475 }
476 }
477 /*
478 * If we go through all Rio devices and don't find one with
479 * the next index, it means we've found all the Winnipegs,
480 * and thus all the PCI buses.
481 */
482 if (i == rio_table_hdr->num_rio_dev)
483 next_wpeg = 0;
484 } while (next_wpeg != 0);
485}
486#endif
487
488static struct apic apic_summit = {
489
490 .name = "summit",
491 .probe = probe_summit,
492 .acpi_madt_oem_check = summit_acpi_madt_oem_check,
493 .apic_id_valid = default_apic_id_valid,
494 .apic_id_registered = summit_apic_id_registered,
495
496 .irq_delivery_mode = dest_LowestPrio,
497 /* logical delivery broadcast to all CPUs: */
498 .irq_dest_mode = 1,
499
500 .target_cpus = summit_target_cpus,
501 .disable_esr = 1,
502 .dest_logical = APIC_DEST_LOGICAL,
503 .check_apicid_used = summit_check_apicid_used,
504 .check_apicid_present = summit_check_apicid_present,
505
506 .vector_allocation_domain = flat_vector_allocation_domain,
507 .init_apic_ldr = summit_init_apic_ldr,
508
509 .ioapic_phys_id_map = summit_ioapic_phys_id_map,
510 .setup_apic_routing = summit_setup_apic_routing,
511 .multi_timer_check = NULL,
512 .cpu_present_to_apicid = summit_cpu_present_to_apicid,
513 .apicid_to_cpu_present = summit_apicid_to_cpu_present,
514 .setup_portio_remap = NULL,
515 .check_phys_apicid_present = summit_check_phys_apicid_present,
516 .enable_apic_mode = NULL,
517 .phys_pkg_id = summit_phys_pkg_id,
518 .mps_oem_check = summit_mps_oem_check,
519
520 .get_apic_id = summit_get_apic_id,
521 .set_apic_id = NULL,
522 .apic_id_mask = 0xFF << 24,
523
524 .cpu_mask_to_apicid_and = summit_cpu_mask_to_apicid_and,
525
526 .send_IPI_mask = summit_send_IPI_mask,
527 .send_IPI_mask_allbutself = NULL,
528 .send_IPI_allbutself = summit_send_IPI_allbutself,
529 .send_IPI_all = summit_send_IPI_all,
530 .send_IPI_self = default_send_IPI_self,
531
532 .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW,
533 .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
534
535 .wait_for_init_deassert = true,
536 .smp_callin_clear_local_apic = NULL,
537 .inquire_remote_apic = default_inquire_remote_apic,
538
539 .read = native_apic_mem_read,
540 .write = native_apic_mem_write,
541 .eoi_write = native_apic_mem_write,
542 .icr_read = native_apic_icr_read,
543 .icr_write = native_apic_icr_write,
544 .wait_icr_idle = native_apic_wait_icr_idle,
545 .safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
546
547 .x86_32_early_logical_apicid = summit_early_logical_apicid,
548};
549
550apic_driver(apic_summit);
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 897d6201ef10..a80029035bf2 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -274,10 +274,6 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
274 } 274 }
275#endif 275#endif
276 276
277#ifdef CONFIG_X86_NUMAQ
278 numaq_tsc_disable();
279#endif
280
281 intel_smp_check(c); 277 intel_smp_check(c);
282} 278}
283#else 279#else
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index fa511acff7e6..09c76d265550 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -869,7 +869,6 @@ void __init setup_arch(char **cmdline_p)
869 869
870#ifdef CONFIG_X86_32 870#ifdef CONFIG_X86_32
871 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); 871 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
872 visws_early_detect();
873 872
874 /* 873 /*
875 * copy kernel address range established so far and switch 874 * copy kernel address range established so far and switch
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index 27aa0455fab3..1d045f9c390f 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -687,10 +687,6 @@ static int __init dummy_numa_init(void)
687void __init x86_numa_init(void) 687void __init x86_numa_init(void)
688{ 688{
689 if (!numa_off) { 689 if (!numa_off) {
690#ifdef CONFIG_X86_NUMAQ
691 if (!numa_init(numaq_numa_init))
692 return;
693#endif
694#ifdef CONFIG_ACPI_NUMA 690#ifdef CONFIG_ACPI_NUMA
695 if (!numa_init(x86_acpi_numa_init)) 691 if (!numa_init(x86_acpi_numa_init))
696 return; 692 return;
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index e063eed0f912..5c6fc3577a49 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -13,9 +13,6 @@ obj-y += legacy.o irq.o
13 13
14obj-$(CONFIG_STA2X11) += sta2x11-fixup.o 14obj-$(CONFIG_STA2X11) += sta2x11-fixup.o
15 15
16obj-$(CONFIG_X86_VISWS) += visws.o
17
18obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
19obj-$(CONFIG_X86_NUMACHIP) += numachip.o 16obj-$(CONFIG_X86_NUMACHIP) += numachip.o
20 17
21obj-$(CONFIG_X86_INTEL_MID) += intel_mid_pci.o 18obj-$(CONFIG_X86_INTEL_MID) += intel_mid_pci.o
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index d491deddebae..059a76c29739 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -567,7 +567,6 @@ char * __init pcibios_setup(char *str)
567 pci_probe |= PCI_PROBE_NOEARLY; 567 pci_probe |= PCI_PROBE_NOEARLY;
568 return NULL; 568 return NULL;
569 } 569 }
570#ifndef CONFIG_X86_VISWS
571 else if (!strcmp(str, "usepirqmask")) { 570 else if (!strcmp(str, "usepirqmask")) {
572 pci_probe |= PCI_USE_PIRQ_MASK; 571 pci_probe |= PCI_USE_PIRQ_MASK;
573 return NULL; 572 return NULL;
@@ -577,9 +576,7 @@ char * __init pcibios_setup(char *str)
577 } else if (!strncmp(str, "lastbus=", 8)) { 576 } else if (!strncmp(str, "lastbus=", 8)) {
578 pcibios_last_bus = simple_strtol(str+8, NULL, 0); 577 pcibios_last_bus = simple_strtol(str+8, NULL, 0);
579 return NULL; 578 return NULL;
580 } 579 } else if (!strcmp(str, "rom")) {
581#endif
582 else if (!strcmp(str, "rom")) {
583 pci_probe |= PCI_ASSIGN_ROMS; 580 pci_probe |= PCI_ASSIGN_ROMS;
584 return NULL; 581 return NULL;
585 } else if (!strcmp(str, "norom")) { 582 } else if (!strcmp(str, "norom")) {
diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c
deleted file mode 100644
index 080eb0374fff..000000000000
--- a/arch/x86/pci/numaq_32.c
+++ /dev/null
@@ -1,165 +0,0 @@
1/*
2 * numaq_32.c - Low-level PCI access for NUMA-Q machines
3 */
4
5#include <linux/pci.h>
6#include <linux/init.h>
7#include <linux/nodemask.h>
8#include <asm/apic.h>
9#include <asm/mpspec.h>
10#include <asm/pci_x86.h>
11#include <asm/numaq.h>
12
13#define BUS2QUAD(global) (mp_bus_id_to_node[global])
14
15#define BUS2LOCAL(global) (mp_bus_id_to_local[global])
16
17#define QUADLOCAL2BUS(quad,local) (quad_local_to_mp_bus_id[quad][local])
18
19#define PCI_CONF1_MQ_ADDRESS(bus, devfn, reg) \
20 (0x80000000 | (BUS2LOCAL(bus) << 16) | (devfn << 8) | (reg & ~3))
21
22static void write_cf8(unsigned bus, unsigned devfn, unsigned reg)
23{
24 unsigned val = PCI_CONF1_MQ_ADDRESS(bus, devfn, reg);
25 if (xquad_portio)
26 writel(val, XQUAD_PORT_ADDR(0xcf8, BUS2QUAD(bus)));
27 else
28 outl(val, 0xCF8);
29}
30
31static int pci_conf1_mq_read(unsigned int seg, unsigned int bus,
32 unsigned int devfn, int reg, int len, u32 *value)
33{
34 unsigned long flags;
35 void *adr __iomem = XQUAD_PORT_ADDR(0xcfc, BUS2QUAD(bus));
36
37 WARN_ON(seg);
38 if (!value || (bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255))
39 return -EINVAL;
40
41 raw_spin_lock_irqsave(&pci_config_lock, flags);
42
43 write_cf8(bus, devfn, reg);
44
45 switch (len) {
46 case 1:
47 if (xquad_portio)
48 *value = readb(adr + (reg & 3));
49 else
50 *value = inb(0xCFC + (reg & 3));
51 break;
52 case 2:
53 if (xquad_portio)
54 *value = readw(adr + (reg & 2));
55 else
56 *value = inw(0xCFC + (reg & 2));
57 break;
58 case 4:
59 if (xquad_portio)
60 *value = readl(adr);
61 else
62 *value = inl(0xCFC);
63 break;
64 }
65
66 raw_spin_unlock_irqrestore(&pci_config_lock, flags);
67
68 return 0;
69}
70
71static int pci_conf1_mq_write(unsigned int seg, unsigned int bus,
72 unsigned int devfn, int reg, int len, u32 value)
73{
74 unsigned long flags;
75 void *adr __iomem = XQUAD_PORT_ADDR(0xcfc, BUS2QUAD(bus));
76
77 WARN_ON(seg);
78 if ((bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255))
79 return -EINVAL;
80
81 raw_spin_lock_irqsave(&pci_config_lock, flags);
82
83 write_cf8(bus, devfn, reg);
84
85 switch (len) {
86 case 1:
87 if (xquad_portio)
88 writeb(value, adr + (reg & 3));
89 else
90 outb((u8)value, 0xCFC + (reg & 3));
91 break;
92 case 2:
93 if (xquad_portio)
94 writew(value, adr + (reg & 2));
95 else
96 outw((u16)value, 0xCFC + (reg & 2));
97 break;
98 case 4:
99 if (xquad_portio)
100 writel(value, adr + reg);
101 else
102 outl((u32)value, 0xCFC);
103 break;
104 }
105
106 raw_spin_unlock_irqrestore(&pci_config_lock, flags);
107
108 return 0;
109}
110
111#undef PCI_CONF1_MQ_ADDRESS
112
113static const struct pci_raw_ops pci_direct_conf1_mq = {
114 .read = pci_conf1_mq_read,
115 .write = pci_conf1_mq_write
116};
117
118
119static void pci_fixup_i450nx(struct pci_dev *d)
120{
121 /*
122 * i450NX -- Find and scan all secondary buses on all PXB's.
123 */
124 int pxb, reg;
125 u8 busno, suba, subb;
126 int quad = BUS2QUAD(d->bus->number);
127
128 dev_info(&d->dev, "searching for i450NX host bridges\n");
129 reg = 0xd0;
130 for(pxb=0; pxb<2; pxb++) {
131 pci_read_config_byte(d, reg++, &busno);
132 pci_read_config_byte(d, reg++, &suba);
133 pci_read_config_byte(d, reg++, &subb);
134 dev_dbg(&d->dev, "i450NX PXB %d: %02x/%02x/%02x\n",
135 pxb, busno, suba, subb);
136 if (busno) {
137 /* Bus A */
138 pcibios_scan_root(QUADLOCAL2BUS(quad, busno));
139 }
140 if (suba < subb) {
141 /* Bus B */
142 pcibios_scan_root(QUADLOCAL2BUS(quad, suba+1));
143 }
144 }
145 pcibios_last_bus = -1;
146}
147DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx);
148
149int __init pci_numaq_init(void)
150{
151 int quad;
152
153 raw_pci_ops = &pci_direct_conf1_mq;
154
155 pcibios_scan_root(0);
156 if (num_online_nodes() > 1)
157 for_each_online_node(quad) {
158 if (quad == 0)
159 continue;
160 printk("Scanning PCI bus %d for quad %d\n",
161 QUADLOCAL2BUS(quad,0), quad);
162 pcibios_scan_root(QUADLOCAL2BUS(quad, 0));
163 }
164 return 0;
165}
diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c
deleted file mode 100644
index cd9d4d1681d2..000000000000
--- a/arch/x86/pci/visws.c
+++ /dev/null
@@ -1,87 +0,0 @@
1/*
2 * Low-Level PCI Support for SGI Visual Workstation
3 *
4 * (c) 1999--2000 Martin Mares <mj@ucw.cz>
5 */
6
7#include <linux/kernel.h>
8#include <linux/pci.h>
9#include <linux/init.h>
10
11#include <asm/setup.h>
12#include <asm/pci_x86.h>
13#include <asm/visws/cobalt.h>
14#include <asm/visws/lithium.h>
15
16static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; }
17static void pci_visws_disable_irq(struct pci_dev *dev) { }
18
19/* int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq; */
20/* void (*pcibios_disable_irq)(struct pci_dev *dev) = &pci_visws_disable_irq; */
21
22/* void __init pcibios_penalize_isa_irq(int irq, int active) {} */
23
24
25unsigned int pci_bus0, pci_bus1;
26
27static int __init visws_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
28{
29 int irq, bus = dev->bus->number;
30
31 pin--;
32
33 /* Nothing useful at PIIX4 pin 1 */
34 if (bus == pci_bus0 && slot == 4 && pin == 0)
35 return -1;
36
37 /* PIIX4 USB is on Bus 0, Slot 4, Line 3 */
38 if (bus == pci_bus0 && slot == 4 && pin == 3) {
39 irq = CO_IRQ(CO_APIC_PIIX4_USB);
40 goto out;
41 }
42
43 /* First pin spread down 1 APIC entry per slot */
44 if (pin == 0) {
45 irq = CO_IRQ((bus == pci_bus0 ? CO_APIC_PCIB_BASE0 :
46 CO_APIC_PCIA_BASE0) + slot);
47 goto out;
48 }
49
50 /* lines 1,2,3 from any slot is shared in this twirly pattern */
51 if (bus == pci_bus1) {
52 /* lines 1-3 from devices 0 1 rotate over 2 apic entries */
53 irq = CO_IRQ(CO_APIC_PCIA_BASE123 + ((slot + (pin - 1)) % 2));
54 } else { /* bus == pci_bus0 */
55 /* lines 1-3 from devices 0-3 rotate over 3 apic entries */
56 if (slot == 0)
57 slot = 3; /* same pattern */
58 irq = CO_IRQ(CO_APIC_PCIA_BASE123 + ((3 - slot) + (pin - 1) % 3));
59 }
60out:
61 printk(KERN_DEBUG "PCI: Bus %d Slot %d Line %d -> IRQ %d\n", bus, slot, pin, irq);
62 return irq;
63}
64
65int __init pci_visws_init(void)
66{
67 pcibios_enable_irq = &pci_visws_enable_irq;
68 pcibios_disable_irq = &pci_visws_disable_irq;
69
70 /* The VISWS supports configuration access type 1 only */
71 pci_probe = (pci_probe | PCI_PROBE_CONF1) &
72 ~(PCI_PROBE_BIOS | PCI_PROBE_CONF2);
73
74 pci_bus0 = li_pcib_read16(LI_PCI_BUSNUM) & 0xff;
75 pci_bus1 = li_pcia_read16(LI_PCI_BUSNUM) & 0xff;
76
77 printk(KERN_INFO "PCI: Lithium bridge A bus: %u, "
78 "bridge B (PIIX4) bus: %u\n", pci_bus1, pci_bus0);
79
80 raw_pci_ops = &pci_direct_conf1;
81 pcibios_scan_root(pci_bus0);
82 pcibios_scan_root(pci_bus1);
83 pci_fixup_irqs(pci_common_swizzle, visws_map_irq);
84 pcibios_resource_survey();
85 /* Request bus scan */
86 return 1;
87}
diff --git a/arch/x86/platform/Makefile b/arch/x86/platform/Makefile
index 20342d4c82ce..85afde1fa3e5 100644
--- a/arch/x86/platform/Makefile
+++ b/arch/x86/platform/Makefile
@@ -9,5 +9,4 @@ obj-y += olpc/
9obj-y += scx200/ 9obj-y += scx200/
10obj-y += sfi/ 10obj-y += sfi/
11obj-y += ts5500/ 11obj-y += ts5500/
12obj-y += visws/
13obj-y += uv/ 12obj-y += uv/
diff --git a/arch/x86/platform/visws/Makefile b/arch/x86/platform/visws/Makefile
deleted file mode 100644
index 91bc17ab2fd5..000000000000
--- a/arch/x86/platform/visws/Makefile
+++ /dev/null
@@ -1 +0,0 @@
1obj-$(CONFIG_X86_VISWS) += visws_quirks.o
diff --git a/arch/x86/platform/visws/visws_quirks.c b/arch/x86/platform/visws/visws_quirks.c
deleted file mode 100644
index 94d8a39332ec..000000000000
--- a/arch/x86/platform/visws/visws_quirks.c
+++ /dev/null
@@ -1,608 +0,0 @@
1/*
2 * SGI Visual Workstation support and quirks, unmaintained.
3 *
4 * Split out from setup.c by davej@suse.de
5 *
6 * Copyright (C) 1999 Bent Hagemark, Ingo Molnar
7 *
8 * SGI Visual Workstation interrupt controller
9 *
10 * The Cobalt system ASIC in the Visual Workstation contains a "Cobalt" APIC
11 * which serves as the main interrupt controller in the system. Non-legacy
12 * hardware in the system uses this controller directly. Legacy devices
13 * are connected to the PIIX4 which in turn has its 8259(s) connected to
14 * a of the Cobalt APIC entry.
15 *
16 * 09/02/2000 - Updated for 2.4 by jbarnes@sgi.com
17 *
18 * 25/11/2002 - Updated for 2.5 by Andrey Panin <pazke@orbita1.ru>
19 */
20#include <linux/interrupt.h>
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/smp.h>
24
25#include <asm/visws/cobalt.h>
26#include <asm/visws/piix4.h>
27#include <asm/io_apic.h>
28#include <asm/fixmap.h>
29#include <asm/reboot.h>
30#include <asm/setup.h>
31#include <asm/apic.h>
32#include <asm/e820.h>
33#include <asm/time.h>
34#include <asm/io.h>
35
36#include <linux/kernel_stat.h>
37
38#include <asm/i8259.h>
39#include <asm/irq_vectors.h>
40#include <asm/visws/lithium.h>
41
42#include <linux/sched.h>
43#include <linux/kernel.h>
44#include <linux/pci.h>
45#include <linux/pci_ids.h>
46
47extern int no_broadcast;
48
49char visws_board_type = -1;
50char visws_board_rev = -1;
51
52static void __init visws_time_init(void)
53{
54 printk(KERN_INFO "Starting Cobalt Timer system clock\n");
55
56 /* Set the countdown value */
57 co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ);
58
59 /* Start the timer */
60 co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN);
61
62 /* Enable (unmask) the timer interrupt */
63 co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK);
64
65 setup_default_timer_irq();
66}
67
68/* Replaces the default init_ISA_irqs in the generic setup */
69static void __init visws_pre_intr_init(void);
70
71/* Quirk for machine specific memory setup. */
72
73#define MB (1024 * 1024)
74
75unsigned long sgivwfb_mem_phys;
76unsigned long sgivwfb_mem_size;
77EXPORT_SYMBOL(sgivwfb_mem_phys);
78EXPORT_SYMBOL(sgivwfb_mem_size);
79
80long long mem_size __initdata = 0;
81
82static char * __init visws_memory_setup(void)
83{
84 long long gfx_mem_size = 8 * MB;
85
86 mem_size = boot_params.alt_mem_k;
87
88 if (!mem_size) {
89 printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n");
90 mem_size = 128 * MB;
91 }
92
93 /*
94 * this hardcodes the graphics memory to 8 MB
95 * it really should be sized dynamically (or at least
96 * set as a boot param)
97 */
98 if (!sgivwfb_mem_size) {
99 printk(KERN_WARNING "Defaulting to 8 MB framebuffer size\n");
100 sgivwfb_mem_size = 8 * MB;
101 }
102
103 /*
104 * Trim to nearest MB
105 */
106 sgivwfb_mem_size &= ~((1 << 20) - 1);
107 sgivwfb_mem_phys = mem_size - gfx_mem_size;
108
109 e820_add_region(0, LOWMEMSIZE(), E820_RAM);
110 e820_add_region(HIGH_MEMORY, mem_size - sgivwfb_mem_size - HIGH_MEMORY, E820_RAM);
111 e820_add_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED);
112
113 return "PROM";
114}
115
116static void visws_machine_emergency_restart(void)
117{
118 /*
119 * Visual Workstations restart after this
120 * register is poked on the PIIX4
121 */
122 outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT);
123}
124
125static void visws_machine_power_off(void)
126{
127 unsigned short pm_status;
128/* extern unsigned int pci_bus0; */
129
130 while ((pm_status = inw(PMSTS_PORT)) & 0x100)
131 outw(pm_status, PMSTS_PORT);
132
133 outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT);
134
135 mdelay(10);
136
137#define PCI_CONF1_ADDRESS(bus, devfn, reg) \
138 (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
139
140/* outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8); */
141 outl(PIIX_SPECIAL_STOP, 0xCFC);
142}
143
144static void __init visws_get_smp_config(unsigned int early)
145{
146}
147
148/*
149 * The Visual Workstation is Intel MP compliant in the hardware
150 * sense, but it doesn't have a BIOS(-configuration table).
151 * No problem for Linux.
152 */
153
154static void __init MP_processor_info(struct mpc_cpu *m)
155{
156 int ver, logical_apicid;
157 physid_mask_t apic_cpus;
158
159 if (!(m->cpuflag & CPU_ENABLED))
160 return;
161
162 logical_apicid = m->apicid;
163 printk(KERN_INFO "%sCPU #%d %u:%u APIC version %d\n",
164 m->cpuflag & CPU_BOOTPROCESSOR ? "Bootup " : "",
165 m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8,
166 (m->cpufeature & CPU_MODEL_MASK) >> 4, m->apicver);
167
168 if (m->cpuflag & CPU_BOOTPROCESSOR)
169 boot_cpu_physical_apicid = m->apicid;
170
171 ver = m->apicver;
172 if ((ver >= 0x14 && m->apicid >= 0xff) || m->apicid >= 0xf) {
173 printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
174 m->apicid, MAX_LOCAL_APIC);
175 return;
176 }
177
178 apic->apicid_to_cpu_present(m->apicid, &apic_cpus);
179 physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus);
180 /*
181 * Validate version
182 */
183 if (ver == 0x0) {
184 printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! "
185 "fixing up to 0x10. (tell your hw vendor)\n",
186 m->apicid);
187 ver = 0x10;
188 }
189 apic_version[m->apicid] = ver;
190}
191
192static void __init visws_find_smp_config(void)
193{
194 struct mpc_cpu *mp = phys_to_virt(CO_CPU_TAB_PHYS);
195 unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS));
196
197 if (ncpus > CO_CPU_MAX) {
198 printk(KERN_WARNING "find_visws_smp: got cpu count of %d at %p\n",
199 ncpus, mp);
200
201 ncpus = CO_CPU_MAX;
202 }
203
204 if (ncpus > setup_max_cpus)
205 ncpus = setup_max_cpus;
206
207#ifdef CONFIG_X86_LOCAL_APIC
208 smp_found_config = 1;
209#endif
210 while (ncpus--)
211 MP_processor_info(mp++);
212
213 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
214}
215
216static void visws_trap_init(void);
217
218void __init visws_early_detect(void)
219{
220 int raw;
221
222 visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG)
223 >> PIIX_GPI_BD_SHIFT;
224
225 if (visws_board_type < 0)
226 return;
227
228 /*
229 * Override the default platform setup functions
230 */
231 x86_init.resources.memory_setup = visws_memory_setup;
232 x86_init.mpparse.get_smp_config = visws_get_smp_config;
233 x86_init.mpparse.find_smp_config = visws_find_smp_config;
234 x86_init.irqs.pre_vector_init = visws_pre_intr_init;
235 x86_init.irqs.trap_init = visws_trap_init;
236 x86_init.timers.timer_init = visws_time_init;
237 x86_init.pci.init = pci_visws_init;
238 x86_init.pci.init_irq = x86_init_noop;
239
240 /*
241 * Install reboot quirks:
242 */
243 pm_power_off = visws_machine_power_off;
244 machine_ops.emergency_restart = visws_machine_emergency_restart;
245
246 /*
247 * Do not use broadcast IPIs:
248 */
249 no_broadcast = 0;
250
251#ifdef CONFIG_X86_IO_APIC
252 /*
253 * Turn off IO-APIC detection and initialization:
254 */
255 skip_ioapic_setup = 1;
256#endif
257
258 /*
259 * Get Board rev.
260 * First, we have to initialize the 307 part to allow us access
261 * to the GPIO registers. Let's map them at 0x0fc0 which is right
262 * after the PIIX4 PM section.
263 */
264 outb_p(SIO_DEV_SEL, SIO_INDEX);
265 outb_p(SIO_GP_DEV, SIO_DATA); /* Talk to GPIO regs. */
266
267 outb_p(SIO_DEV_MSB, SIO_INDEX);
268 outb_p(SIO_GP_MSB, SIO_DATA); /* MSB of GPIO base address */
269
270 outb_p(SIO_DEV_LSB, SIO_INDEX);
271 outb_p(SIO_GP_LSB, SIO_DATA); /* LSB of GPIO base address */
272
273 outb_p(SIO_DEV_ENB, SIO_INDEX);
274 outb_p(1, SIO_DATA); /* Enable GPIO registers. */
275
276 /*
277 * Now, we have to map the power management section to write
278 * a bit which enables access to the GPIO registers.
279 * What lunatic came up with this shit?
280 */
281 outb_p(SIO_DEV_SEL, SIO_INDEX);
282 outb_p(SIO_PM_DEV, SIO_DATA); /* Talk to GPIO regs. */
283
284 outb_p(SIO_DEV_MSB, SIO_INDEX);
285 outb_p(SIO_PM_MSB, SIO_DATA); /* MSB of PM base address */
286
287 outb_p(SIO_DEV_LSB, SIO_INDEX);
288 outb_p(SIO_PM_LSB, SIO_DATA); /* LSB of PM base address */
289
290 outb_p(SIO_DEV_ENB, SIO_INDEX);
291 outb_p(1, SIO_DATA); /* Enable PM registers. */
292
293 /*
294 * Now, write the PM register which enables the GPIO registers.
295 */
296 outb_p(SIO_PM_FER2, SIO_PM_INDEX);
297 outb_p(SIO_PM_GP_EN, SIO_PM_DATA);
298
299 /*
300 * Now, initialize the GPIO registers.
301 * We want them all to be inputs which is the
302 * power on default, so let's leave them alone.
303 * So, let's just read the board rev!
304 */
305 raw = inb_p(SIO_GP_DATA1);
306 raw &= 0x7f; /* 7 bits of valid board revision ID. */
307
308 if (visws_board_type == VISWS_320) {
309 if (raw < 0x6) {
310 visws_board_rev = 4;
311 } else if (raw < 0xc) {
312 visws_board_rev = 5;
313 } else {
314 visws_board_rev = 6;
315 }
316 } else if (visws_board_type == VISWS_540) {
317 visws_board_rev = 2;
318 } else {
319 visws_board_rev = raw;
320 }
321
322 printk(KERN_INFO "Silicon Graphics Visual Workstation %s (rev %d) detected\n",
323 (visws_board_type == VISWS_320 ? "320" :
324 (visws_board_type == VISWS_540 ? "540" :
325 "unknown")), visws_board_rev);
326}
327
328#define A01234 (LI_INTA_0 | LI_INTA_1 | LI_INTA_2 | LI_INTA_3 | LI_INTA_4)
329#define BCD (LI_INTB | LI_INTC | LI_INTD)
330#define ALLDEVS (A01234 | BCD)
331
332static __init void lithium_init(void)
333{
334 set_fixmap(FIX_LI_PCIA, LI_PCI_A_PHYS);
335 set_fixmap(FIX_LI_PCIB, LI_PCI_B_PHYS);
336
337 if ((li_pcia_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) ||
338 (li_pcia_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) {
339 printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'A');
340/* panic("This machine is not SGI Visual Workstation 320/540"); */
341 }
342
343 if ((li_pcib_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) ||
344 (li_pcib_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) {
345 printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'B');
346/* panic("This machine is not SGI Visual Workstation 320/540"); */
347 }
348
349 li_pcia_write16(LI_PCI_INTEN, ALLDEVS);
350 li_pcib_write16(LI_PCI_INTEN, ALLDEVS);
351}
352
353static __init void cobalt_init(void)
354{
355 /*
356 * On normal SMP PC this is used only with SMP, but we have to
357 * use it and set it up here to start the Cobalt clock
358 */
359 set_fixmap(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE);
360 setup_local_APIC();
361 printk(KERN_INFO "Local APIC Version %#x, ID %#x\n",
362 (unsigned int)apic_read(APIC_LVR),
363 (unsigned int)apic_read(APIC_ID));
364
365 set_fixmap(FIX_CO_CPU, CO_CPU_PHYS);
366 set_fixmap(FIX_CO_APIC, CO_APIC_PHYS);
367 printk(KERN_INFO "Cobalt Revision %#lx, APIC ID %#lx\n",
368 co_cpu_read(CO_CPU_REV), co_apic_read(CO_APIC_ID));
369
370 /* Enable Cobalt APIC being careful to NOT change the ID! */
371 co_apic_write(CO_APIC_ID, co_apic_read(CO_APIC_ID) | CO_APIC_ENABLE);
372
373 printk(KERN_INFO "Cobalt APIC enabled: ID reg %#lx\n",
374 co_apic_read(CO_APIC_ID));
375}
376
377static void __init visws_trap_init(void)
378{
379 lithium_init();
380 cobalt_init();
381}
382
383/*
384 * IRQ controller / APIC support:
385 */
386
387static DEFINE_SPINLOCK(cobalt_lock);
388
389/*
390 * Set the given Cobalt APIC Redirection Table entry to point
391 * to the given IDT vector/index.
392 */
393static inline void co_apic_set(int entry, int irq)
394{
395 co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL | (irq + FIRST_EXTERNAL_VECTOR));
396 co_apic_write(CO_APIC_HI(entry), 0);
397}
398
399/*
400 * Cobalt (IO)-APIC functions to handle PCI devices.
401 */
402static inline int co_apic_ide0_hack(void)
403{
404 extern char visws_board_type;
405 extern char visws_board_rev;
406
407 if (visws_board_type == VISWS_320 && visws_board_rev == 5)
408 return 5;
409 return CO_APIC_IDE0;
410}
411
412static int is_co_apic(unsigned int irq)
413{
414 if (IS_CO_APIC(irq))
415 return CO_APIC(irq);
416
417 switch (irq) {
418 case 0: return CO_APIC_CPU;
419 case CO_IRQ_IDE0: return co_apic_ide0_hack();
420 case CO_IRQ_IDE1: return CO_APIC_IDE1;
421 default: return -1;
422 }
423}
424
425
426/*
427 * This is the SGI Cobalt (IO-)APIC:
428 */
429static void enable_cobalt_irq(struct irq_data *data)
430{
431 co_apic_set(is_co_apic(data->irq), data->irq);
432}
433
434static void disable_cobalt_irq(struct irq_data *data)
435{
436 int entry = is_co_apic(data->irq);
437
438 co_apic_write(CO_APIC_LO(entry), CO_APIC_MASK);
439 co_apic_read(CO_APIC_LO(entry));
440}
441
442static void ack_cobalt_irq(struct irq_data *data)
443{
444 unsigned long flags;
445
446 spin_lock_irqsave(&cobalt_lock, flags);
447 disable_cobalt_irq(data);
448 apic_write(APIC_EOI, APIC_EOI_ACK);
449 spin_unlock_irqrestore(&cobalt_lock, flags);
450}
451
452static struct irq_chip cobalt_irq_type = {
453 .name = "Cobalt-APIC",
454 .irq_enable = enable_cobalt_irq,
455 .irq_disable = disable_cobalt_irq,
456 .irq_ack = ack_cobalt_irq,
457};
458
459
460/*
461 * This is the PIIX4-based 8259 that is wired up indirectly to Cobalt
462 * -- not the manner expected by the code in i8259.c.
463 *
464 * there is a 'master' physical interrupt source that gets sent to
465 * the CPU. But in the chipset there are various 'virtual' interrupts
466 * waiting to be handled. We represent this to Linux through a 'master'
467 * interrupt controller type, and through a special virtual interrupt-
468 * controller. Device drivers only see the virtual interrupt sources.
469 */
470static unsigned int startup_piix4_master_irq(struct irq_data *data)
471{
472 legacy_pic->init(0);
473 enable_cobalt_irq(data);
474 return 0;
475}
476
477static struct irq_chip piix4_master_irq_type = {
478 .name = "PIIX4-master",
479 .irq_startup = startup_piix4_master_irq,
480 .irq_ack = ack_cobalt_irq,
481};
482
483static void pii4_mask(struct irq_data *data) { }
484
485static struct irq_chip piix4_virtual_irq_type = {
486 .name = "PIIX4-virtual",
487 .irq_mask = pii4_mask,
488};
489
490/*
491 * PIIX4-8259 master/virtual functions to handle interrupt requests
492 * from legacy devices: floppy, parallel, serial, rtc.
493 *
494 * None of these get Cobalt APIC entries, neither do they have IDT
495 * entries. These interrupts are purely virtual and distributed from
496 * the 'master' interrupt source: CO_IRQ_8259.
497 *
498 * When the 8259 interrupts its handler figures out which of these
499 * devices is interrupting and dispatches to its handler.
500 *
501 * CAREFUL: devices see the 'virtual' interrupt only. Thus disable/
502 * enable_irq gets the right irq. This 'master' irq is never directly
503 * manipulated by any driver.
504 */
505static irqreturn_t piix4_master_intr(int irq, void *dev_id)
506{
507 unsigned long flags;
508 int realirq;
509
510 raw_spin_lock_irqsave(&i8259A_lock, flags);
511
512 /* Find out what's interrupting in the PIIX4 master 8259 */
513 outb(0x0c, 0x20); /* OCW3 Poll command */
514 realirq = inb(0x20);
515
516 /*
517 * Bit 7 == 0 means invalid/spurious
518 */
519 if (unlikely(!(realirq & 0x80)))
520 goto out_unlock;
521
522 realirq &= 7;
523
524 if (unlikely(realirq == 2)) {
525 outb(0x0c, 0xa0);
526 realirq = inb(0xa0);
527
528 if (unlikely(!(realirq & 0x80)))
529 goto out_unlock;
530
531 realirq = (realirq & 7) + 8;
532 }
533
534 /* mask and ack interrupt */
535 cached_irq_mask |= 1 << realirq;
536 if (unlikely(realirq > 7)) {
537 inb(0xa1);
538 outb(cached_slave_mask, 0xa1);
539 outb(0x60 + (realirq & 7), 0xa0);
540 outb(0x60 + 2, 0x20);
541 } else {
542 inb(0x21);
543 outb(cached_master_mask, 0x21);
544 outb(0x60 + realirq, 0x20);
545 }
546
547 raw_spin_unlock_irqrestore(&i8259A_lock, flags);
548
549 /*
550 * handle this 'virtual interrupt' as a Cobalt one now.
551 */
552 generic_handle_irq(realirq);
553
554 return IRQ_HANDLED;
555
556out_unlock:
557 raw_spin_unlock_irqrestore(&i8259A_lock, flags);
558 return IRQ_NONE;
559}
560
561static struct irqaction master_action = {
562 .handler = piix4_master_intr,
563 .name = "PIIX4-8259",
564 .flags = IRQF_NO_THREAD,
565};
566
567static struct irqaction cascade_action = {
568 .handler = no_action,
569 .name = "cascade",
570 .flags = IRQF_NO_THREAD,
571};
572
573static inline void set_piix4_virtual_irq_type(void)
574{
575 piix4_virtual_irq_type.irq_enable = i8259A_chip.irq_unmask;
576 piix4_virtual_irq_type.irq_disable = i8259A_chip.irq_mask;
577 piix4_virtual_irq_type.irq_unmask = i8259A_chip.irq_unmask;
578}
579
580static void __init visws_pre_intr_init(void)
581{
582 int i;
583
584 set_piix4_virtual_irq_type();
585
586 for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) {
587 struct irq_chip *chip = NULL;
588
589 if (i == 0)
590 chip = &cobalt_irq_type;
591 else if (i == CO_IRQ_IDE0)
592 chip = &cobalt_irq_type;
593 else if (i == CO_IRQ_IDE1)
594 chip = &cobalt_irq_type;
595 else if (i == CO_IRQ_8259)
596 chip = &piix4_master_irq_type;
597 else if (i < CO_IRQ_APIC0)
598 chip = &piix4_virtual_irq_type;
599 else if (IS_CO_APIC(i))
600 chip = &cobalt_irq_type;
601
602 if (chip)
603 irq_set_chip(i, chip);
604 }
605
606 setup_irq(CO_IRQ_8259, &master_action);
607 setup_irq(2, &cascade_action);
608}
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index 01b90261fa38..9c50cc2e403b 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -7,7 +7,7 @@ config XEN
7 depends on PARAVIRT 7 depends on PARAVIRT
8 select PARAVIRT_CLOCK 8 select PARAVIRT_CLOCK
9 select XEN_HAVE_PVMMU 9 select XEN_HAVE_PVMMU
10 depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS) 10 depends on X86_64 || (X86_32 && X86_PAE)
11 depends on X86_TSC 11 depends on X86_TSC
12 help 12 help
13 This is the Linux Xen port. Enabling this will allow the 13 This is the Linux Xen port. Enabling this will allow the
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index aed3488d9426..f3fe4cb4974b 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -1,6 +1,5 @@
1obj-$(CONFIG_CLKSRC_OF) += clksrc-of.o 1obj-$(CONFIG_CLKSRC_OF) += clksrc-of.o
2obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o 2obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o
3obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o
4obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o 3obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
5obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o 4obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o
6obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o 5obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o
diff --git a/drivers/clocksource/cyclone.c b/drivers/clocksource/cyclone.c
deleted file mode 100644
index 9e0998f22885..000000000000
--- a/drivers/clocksource/cyclone.c
+++ /dev/null
@@ -1,113 +0,0 @@
1#include <linux/clocksource.h>
2#include <linux/string.h>
3#include <linux/errno.h>
4#include <linux/timex.h>
5#include <linux/init.h>
6
7#include <asm/pgtable.h>
8#include <asm/io.h>
9
10#include <asm/mach_timer.h>
11
12#define CYCLONE_CBAR_ADDR 0xFEB00CD0 /* base address ptr */
13#define CYCLONE_PMCC_OFFSET 0x51A0 /* offset to control register */
14#define CYCLONE_MPCS_OFFSET 0x51A8 /* offset to select register */
15#define CYCLONE_MPMC_OFFSET 0x51D0 /* offset to count register */
16#define CYCLONE_TIMER_FREQ 99780000 /* 100Mhz, but not really */
17#define CYCLONE_TIMER_MASK CLOCKSOURCE_MASK(32) /* 32 bit mask */
18
19int use_cyclone = 0;
20static void __iomem *cyclone_ptr;
21
22static cycle_t read_cyclone(struct clocksource *cs)
23{
24 return (cycle_t)readl(cyclone_ptr);
25}
26
27static struct clocksource clocksource_cyclone = {
28 .name = "cyclone",
29 .rating = 250,
30 .read = read_cyclone,
31 .mask = CYCLONE_TIMER_MASK,
32 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
33};
34
35static int __init init_cyclone_clocksource(void)
36{
37 unsigned long base; /* saved value from CBAR */
38 unsigned long offset;
39 u32 __iomem* volatile cyclone_timer; /* Cyclone MPMC0 register */
40 u32 __iomem* reg;
41 int i;
42
43 /* make sure we're on a summit box: */
44 if (!use_cyclone)
45 return -ENODEV;
46
47 printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n");
48
49 /* find base address: */
50 offset = CYCLONE_CBAR_ADDR;
51 reg = ioremap_nocache(offset, sizeof(reg));
52 if (!reg) {
53 printk(KERN_ERR "Summit chipset: Could not find valid CBAR register.\n");
54 return -ENODEV;
55 }
56 /* even on 64bit systems, this is only 32bits: */
57 base = readl(reg);
58 iounmap(reg);
59 if (!base) {
60 printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n");
61 return -ENODEV;
62 }
63
64 /* setup PMCC: */
65 offset = base + CYCLONE_PMCC_OFFSET;
66 reg = ioremap_nocache(offset, sizeof(reg));
67 if (!reg) {
68 printk(KERN_ERR "Summit chipset: Could not find valid PMCC register.\n");
69 return -ENODEV;
70 }
71 writel(0x00000001,reg);
72 iounmap(reg);
73
74 /* setup MPCS: */
75 offset = base + CYCLONE_MPCS_OFFSET;
76 reg = ioremap_nocache(offset, sizeof(reg));
77 if (!reg) {
78 printk(KERN_ERR "Summit chipset: Could not find valid MPCS register.\n");
79 return -ENODEV;
80 }
81 writel(0x00000001,reg);
82 iounmap(reg);
83
84 /* map in cyclone_timer: */
85 offset = base + CYCLONE_MPMC_OFFSET;
86 cyclone_timer = ioremap_nocache(offset, sizeof(u64));
87 if (!cyclone_timer) {
88 printk(KERN_ERR "Summit chipset: Could not find valid MPMC register.\n");
89 return -ENODEV;
90 }
91
92 /* quick test to make sure its ticking: */
93 for (i = 0; i < 3; i++){
94 u32 old = readl(cyclone_timer);
95 int stall = 100;
96
97 while (stall--)
98 barrier();
99
100 if (readl(cyclone_timer) == old) {
101 printk(KERN_ERR "Summit chipset: Counter not counting! DISABLED\n");
102 iounmap(cyclone_timer);
103 cyclone_timer = NULL;
104 return -ENODEV;
105 }
106 }
107 cyclone_ptr = cyclone_timer;
108
109 return clocksource_register_hz(&clocksource_cyclone,
110 CYCLONE_TIMER_FREQ);
111}
112
113arch_initcall(init_cyclone_clocksource);
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index e2501ac6fe84..e04fe2d9df3b 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -38,7 +38,6 @@ obj-$(CONFIG_ARM) += setup-irq.o
38obj-$(CONFIG_UNICORE32) += setup-irq.o 38obj-$(CONFIG_UNICORE32) += setup-irq.o
39obj-$(CONFIG_SUPERH) += setup-irq.o 39obj-$(CONFIG_SUPERH) += setup-irq.o
40obj-$(CONFIG_MIPS) += setup-irq.o 40obj-$(CONFIG_MIPS) += setup-irq.o
41obj-$(CONFIG_X86_VISWS) += setup-irq.o
42obj-$(CONFIG_TILE) += setup-irq.o 41obj-$(CONFIG_TILE) += setup-irq.o
43obj-$(CONFIG_SPARC_LEON) += setup-irq.o 42obj-$(CONFIG_SPARC_LEON) += setup-irq.o
44obj-$(CONFIG_M68K) += setup-irq.o 43obj-$(CONFIG_M68K) += setup-irq.o
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 97dabd39b092..158020522dfb 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -379,14 +379,7 @@
379#define DEBUG_PRINT_NVRAM 0 379#define DEBUG_PRINT_NVRAM 0
380#define DEBUG_QLA1280 0 380#define DEBUG_QLA1280 0
381 381
382/*
383 * The SGI VISWS is broken and doesn't support MMIO ;-(
384 */
385#ifdef CONFIG_X86_VISWS
386#define MEMORY_MAPPED_IO 0
387#else
388#define MEMORY_MAPPED_IO 1 382#define MEMORY_MAPPED_IO 1
389#endif
390 383
391#include "qla1280.h" 384#include "qla1280.h"
392 385
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 97a8f3a12a7b..b4b209ce8029 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -796,18 +796,9 @@ config FB_HGA
796 As this card technology is at least 25 years old, 796 As this card technology is at least 25 years old,
797 most people will answer N here. 797 most people will answer N here.
798 798
799config FB_SGIVW
800 tristate "SGI Visual Workstation framebuffer support"
801 depends on FB && X86_VISWS
802 select FB_CFB_FILLRECT
803 select FB_CFB_COPYAREA
804 select FB_CFB_IMAGEBLIT
805 help
806 SGI Visual Workstation support for framebuffer graphics.
807
808config FB_GBE 799config FB_GBE
809 bool "SGI Graphics Backend frame buffer support" 800 bool "SGI Graphics Backend frame buffer support"
810 depends on (FB = y) && (SGI_IP32 || X86_VISWS) 801 depends on (FB = y) && SGI_IP32
811 select FB_CFB_FILLRECT 802 select FB_CFB_FILLRECT
812 select FB_CFB_COPYAREA 803 select FB_CFB_COPYAREA
813 select FB_CFB_IMAGEBLIT 804 select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 08d6a4ab3ace..1be26fe10592 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -75,7 +75,6 @@ obj-$(CONFIG_FB_CG14) += cg14.o sbuslib.o
75obj-$(CONFIG_FB_P9100) += p9100.o sbuslib.o 75obj-$(CONFIG_FB_P9100) += p9100.o sbuslib.o
76obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o 76obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o
77obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o 77obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o
78obj-$(CONFIG_FB_SGIVW) += sgivwfb.o
79obj-$(CONFIG_FB_ACORN) += acornfb.o 78obj-$(CONFIG_FB_ACORN) += acornfb.o
80obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \ 79obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \
81 atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o 80 atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 4c7cb368a9dc..3ec65a878ac8 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -45,10 +45,6 @@ struct gbefb_par {
45#define GBE_BASE 0x16000000 /* SGI O2 */ 45#define GBE_BASE 0x16000000 /* SGI O2 */
46#endif 46#endif
47 47
48#ifdef CONFIG_X86_VISWS
49#define GBE_BASE 0xd0000000 /* SGI Visual Workstation */
50#endif
51
52/* macro for fastest write-though access to the framebuffer */ 48/* macro for fastest write-though access to the framebuffer */
53#ifdef CONFIG_MIPS 49#ifdef CONFIG_MIPS
54#ifdef CONFIG_CPU_R10000 50#ifdef CONFIG_CPU_R10000
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index 39ac49e0682c..0037104d66ac 100644
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -54,7 +54,7 @@ config LOGO_PARISC_CLUT224
54 54
55config LOGO_SGI_CLUT224 55config LOGO_SGI_CLUT224
56 bool "224-color SGI Linux logo" 56 bool "224-color SGI Linux logo"
57 depends on SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS 57 depends on SGI_IP22 || SGI_IP27 || SGI_IP32
58 default y 58 default y
59 59
60config LOGO_SUN_CLUT224 60config LOGO_SUN_CLUT224
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
index b670cbda38e3..940cd196eef5 100644
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -81,7 +81,7 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
81 logo = &logo_parisc_clut224; 81 logo = &logo_parisc_clut224;
82#endif 82#endif
83#ifdef CONFIG_LOGO_SGI_CLUT224 83#ifdef CONFIG_LOGO_SGI_CLUT224
84 /* SGI Linux logo on MIPS/MIPS64 and VISWS */ 84 /* SGI Linux logo on MIPS/MIPS64 */
85 logo = &logo_sgi_clut224; 85 logo = &logo_sgi_clut224;
86#endif 86#endif
87#ifdef CONFIG_LOGO_SUN_CLUT224 87#ifdef CONFIG_LOGO_SUN_CLUT224
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
deleted file mode 100644
index bc74d0408998..000000000000
--- a/drivers/video/sgivwfb.c
+++ /dev/null
@@ -1,889 +0,0 @@
1/*
2 * linux/drivers/video/sgivwfb.c -- SGI DBE frame buffer device
3 *
4 * Copyright (C) 1999 Silicon Graphics, Inc.
5 * Jeffrey Newquist, newquist@engr.sgi.som
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive for
9 * more details.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/mm.h>
15#include <linux/errno.h>
16#include <linux/delay.h>
17#include <linux/fb.h>
18#include <linux/init.h>
19#include <linux/ioport.h>
20#include <linux/platform_device.h>
21
22#include <asm/io.h>
23#include <asm/mtrr.h>
24#include <asm/visws/sgivw.h>
25
26#define INCLUDE_TIMING_TABLE_DATA
27#define DBE_REG_BASE par->regs
28#include <video/sgivw.h>
29
30struct sgivw_par {
31 struct asregs *regs;
32 u32 cmap_fifo;
33 u_long timing_num;
34};
35
36#define FLATPANEL_SGI_1600SW 5
37
38/*
39 * RAM we reserve for the frame buffer. This defines the maximum screen
40 * size
41 *
42 * The default can be overridden if the driver is compiled as a module
43 */
44
45static int ypan = 0;
46static int ywrap = 0;
47
48static int flatpanel_id = -1;
49
50static struct fb_fix_screeninfo sgivwfb_fix = {
51 .id = "SGI Vis WS FB",
52 .type = FB_TYPE_PACKED_PIXELS,
53 .visual = FB_VISUAL_PSEUDOCOLOR,
54 .mmio_start = DBE_REG_PHYS,
55 .mmio_len = DBE_REG_SIZE,
56 .accel = FB_ACCEL_NONE,
57 .line_length = 640,
58};
59
60static struct fb_var_screeninfo sgivwfb_var = {
61 /* 640x480, 8 bpp */
62 .xres = 640,
63 .yres = 480,
64 .xres_virtual = 640,
65 .yres_virtual = 480,
66 .bits_per_pixel = 8,
67 .red = { 0, 8, 0 },
68 .green = { 0, 8, 0 },
69 .blue = { 0, 8, 0 },
70 .height = -1,
71 .width = -1,
72 .pixclock = 20000,
73 .left_margin = 64,
74 .right_margin = 64,
75 .upper_margin = 32,
76 .lower_margin = 32,
77 .hsync_len = 64,
78 .vsync_len = 2,
79 .vmode = FB_VMODE_NONINTERLACED
80};
81
82static struct fb_var_screeninfo sgivwfb_var1600sw = {
83 /* 1600x1024, 8 bpp */
84 .xres = 1600,
85 .yres = 1024,
86 .xres_virtual = 1600,
87 .yres_virtual = 1024,
88 .bits_per_pixel = 8,
89 .red = { 0, 8, 0 },
90 .green = { 0, 8, 0 },
91 .blue = { 0, 8, 0 },
92 .height = -1,
93 .width = -1,
94 .pixclock = 9353,
95 .left_margin = 20,
96 .right_margin = 30,
97 .upper_margin = 37,
98 .lower_margin = 3,
99 .hsync_len = 20,
100 .vsync_len = 3,
101 .vmode = FB_VMODE_NONINTERLACED
102};
103
104/*
105 * Interface used by the world
106 */
107int sgivwfb_init(void);
108
109static int sgivwfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
110static int sgivwfb_set_par(struct fb_info *info);
111static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green,
112 u_int blue, u_int transp,
113 struct fb_info *info);
114static int sgivwfb_mmap(struct fb_info *info,
115 struct vm_area_struct *vma);
116
117static struct fb_ops sgivwfb_ops = {
118 .owner = THIS_MODULE,
119 .fb_check_var = sgivwfb_check_var,
120 .fb_set_par = sgivwfb_set_par,
121 .fb_setcolreg = sgivwfb_setcolreg,
122 .fb_fillrect = cfb_fillrect,
123 .fb_copyarea = cfb_copyarea,
124 .fb_imageblit = cfb_imageblit,
125 .fb_mmap = sgivwfb_mmap,
126};
127
128/*
129 * Internal routines
130 */
131static unsigned long bytes_per_pixel(int bpp)
132{
133 switch (bpp) {
134 case 8:
135 return 1;
136 case 16:
137 return 2;
138 case 32:
139 return 4;
140 default:
141 printk(KERN_INFO "sgivwfb: unsupported bpp %d\n", bpp);
142 return 0;
143 }
144}
145
146static unsigned long get_line_length(int xres_virtual, int bpp)
147{
148 return (xres_virtual * bytes_per_pixel(bpp));
149}
150
151/*
152 * Function: dbe_TurnOffDma
153 * Parameters: (None)
154 * Description: This should turn off the monitor and dbe. This is used
155 * when switching between the serial console and the graphics
156 * console.
157 */
158
159static void dbe_TurnOffDma(struct sgivw_par *par)
160{
161 unsigned int readVal;
162 int i;
163
164 // Check to see if things are already turned off:
165 // 1) Check to see if dbe is not using the internal dotclock.
166 // 2) Check to see if the xy counter in dbe is already off.
167
168 DBE_GETREG(ctrlstat, readVal);
169 if (GET_DBE_FIELD(CTRLSTAT, PCLKSEL, readVal) < 2)
170 return;
171
172 DBE_GETREG(vt_xy, readVal);
173 if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1)
174 return;
175
176 // Otherwise, turn off dbe
177
178 DBE_GETREG(ovr_control, readVal);
179 SET_DBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, readVal, 0);
180 DBE_SETREG(ovr_control, readVal);
181 udelay(1000);
182 DBE_GETREG(frm_control, readVal);
183 SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, readVal, 0);
184 DBE_SETREG(frm_control, readVal);
185 udelay(1000);
186 DBE_GETREG(did_control, readVal);
187 SET_DBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, readVal, 0);
188 DBE_SETREG(did_control, readVal);
189 udelay(1000);
190
191 // XXX HACK:
192 //
193 // This was necessary for GBE--we had to wait through two
194 // vertical retrace periods before the pixel DMA was
195 // turned off for sure. I've left this in for now, in
196 // case dbe needs it.
197
198 for (i = 0; i < 10000; i++) {
199 DBE_GETREG(frm_inhwctrl, readVal);
200 if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) ==
201 0)
202 udelay(10);
203 else {
204 DBE_GETREG(ovr_inhwctrl, readVal);
205 if (GET_DBE_FIELD
206 (OVR_INHWCTRL, OVR_DMA_ENABLE, readVal) == 0)
207 udelay(10);
208 else {
209 DBE_GETREG(did_inhwctrl, readVal);
210 if (GET_DBE_FIELD
211 (DID_INHWCTRL, DID_DMA_ENABLE,
212 readVal) == 0)
213 udelay(10);
214 else
215 break;
216 }
217 }
218 }
219}
220
221/*
222 * Set the User Defined Part of the Display. Again if par use it to get
223 * real video mode.
224 */
225static int sgivwfb_check_var(struct fb_var_screeninfo *var,
226 struct fb_info *info)
227{
228 struct sgivw_par *par = (struct sgivw_par *)info->par;
229 struct dbe_timing_info *timing;
230 u_long line_length;
231 u_long min_mode;
232 int req_dot;
233 int test_mode;
234
235 /*
236 * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
237 * as FB_VMODE_SMOOTH_XPAN is only used internally
238 */
239
240 if (var->vmode & FB_VMODE_CONUPDATE) {
241 var->vmode |= FB_VMODE_YWRAP;
242 var->xoffset = info->var.xoffset;
243 var->yoffset = info->var.yoffset;
244 }
245
246 /* XXX FIXME - forcing var's */
247 var->xoffset = 0;
248 var->yoffset = 0;
249
250 /* Limit bpp to 8, 16, and 32 */
251 if (var->bits_per_pixel <= 8)
252 var->bits_per_pixel = 8;
253 else if (var->bits_per_pixel <= 16)
254 var->bits_per_pixel = 16;
255 else if (var->bits_per_pixel <= 32)
256 var->bits_per_pixel = 32;
257 else
258 return -EINVAL;
259
260 var->grayscale = 0; /* No grayscale for now */
261
262 /* determine valid resolution and timing */
263 for (min_mode = 0; min_mode < ARRAY_SIZE(dbeVTimings); min_mode++) {
264 if (dbeVTimings[min_mode].width >= var->xres &&
265 dbeVTimings[min_mode].height >= var->yres)
266 break;
267 }
268
269 if (min_mode == ARRAY_SIZE(dbeVTimings))
270 return -EINVAL; /* Resolution to high */
271
272 /* XXX FIXME - should try to pick best refresh rate */
273 /* for now, pick closest dot-clock within 3MHz */
274 req_dot = PICOS2KHZ(var->pixclock);
275 printk(KERN_INFO "sgivwfb: requested pixclock=%d ps (%d KHz)\n",
276 var->pixclock, req_dot);
277 test_mode = min_mode;
278 while (dbeVTimings[min_mode].width == dbeVTimings[test_mode].width) {
279 if (dbeVTimings[test_mode].cfreq + 3000 > req_dot)
280 break;
281 test_mode++;
282 }
283 if (dbeVTimings[min_mode].width != dbeVTimings[test_mode].width)
284 test_mode--;
285 min_mode = test_mode;
286 timing = &dbeVTimings[min_mode];
287 printk(KERN_INFO "sgivwfb: granted dot-clock=%d KHz\n", timing->cfreq);
288
289 /* Adjust virtual resolution, if necessary */
290 if (var->xres > var->xres_virtual || (!ywrap && !ypan))
291 var->xres_virtual = var->xres;
292 if (var->yres > var->yres_virtual || (!ywrap && !ypan))
293 var->yres_virtual = var->yres;
294
295 /*
296 * Memory limit
297 */
298 line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
299 if (line_length * var->yres_virtual > sgivwfb_mem_size)
300 return -ENOMEM; /* Virtual resolution to high */
301
302 info->fix.line_length = line_length;
303
304 switch (var->bits_per_pixel) {
305 case 8:
306 var->red.offset = 0;
307 var->red.length = 8;
308 var->green.offset = 0;
309 var->green.length = 8;
310 var->blue.offset = 0;
311 var->blue.length = 8;
312 var->transp.offset = 0;
313 var->transp.length = 0;
314 break;
315 case 16: /* RGBA 5551 */
316 var->red.offset = 11;
317 var->red.length = 5;
318 var->green.offset = 6;
319 var->green.length = 5;
320 var->blue.offset = 1;
321 var->blue.length = 5;
322 var->transp.offset = 0;
323 var->transp.length = 0;
324 break;
325 case 32: /* RGB 8888 */
326 var->red.offset = 0;
327 var->red.length = 8;
328 var->green.offset = 8;
329 var->green.length = 8;
330 var->blue.offset = 16;
331 var->blue.length = 8;
332 var->transp.offset = 24;
333 var->transp.length = 8;
334 break;
335 }
336 var->red.msb_right = 0;
337 var->green.msb_right = 0;
338 var->blue.msb_right = 0;
339 var->transp.msb_right = 0;
340
341 /* set video timing information */
342 var->pixclock = KHZ2PICOS(timing->cfreq);
343 var->left_margin = timing->htotal - timing->hsync_end;
344 var->right_margin = timing->hsync_start - timing->width;
345 var->upper_margin = timing->vtotal - timing->vsync_end;
346 var->lower_margin = timing->vsync_start - timing->height;
347 var->hsync_len = timing->hsync_end - timing->hsync_start;
348 var->vsync_len = timing->vsync_end - timing->vsync_start;
349
350 /* Ouch. This breaks the rules but timing_num is only important if you
351 * change a video mode */
352 par->timing_num = min_mode;
353
354 printk(KERN_INFO "sgivwfb: new video mode xres=%d yres=%d bpp=%d\n",
355 var->xres, var->yres, var->bits_per_pixel);
356 printk(KERN_INFO " vxres=%d vyres=%d\n", var->xres_virtual,
357 var->yres_virtual);
358 return 0;
359}
360
361/*
362 * Setup flatpanel related registers.
363 */
364static void sgivwfb_setup_flatpanel(struct sgivw_par *par, struct dbe_timing_info *currentTiming)
365{
366 int fp_wid, fp_hgt, fp_vbs, fp_vbe;
367 u32 outputVal = 0;
368
369 SET_DBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal,
370 (currentTiming->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1);
371 SET_DBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal,
372 (currentTiming->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1);
373 DBE_SETREG(vt_flags, outputVal);
374
375 /* Turn on the flat panel */
376 switch (flatpanel_id) {
377 case FLATPANEL_SGI_1600SW:
378 fp_wid = 1600;
379 fp_hgt = 1024;
380 fp_vbs = 0;
381 fp_vbe = 1600;
382 currentTiming->pll_m = 4;
383 currentTiming->pll_n = 1;
384 currentTiming->pll_p = 0;
385 break;
386 default:
387 fp_wid = fp_hgt = fp_vbs = fp_vbe = 0xfff;
388 }
389
390 outputVal = 0;
391 SET_DBE_FIELD(FP_DE, FP_DE_ON, outputVal, fp_vbs);
392 SET_DBE_FIELD(FP_DE, FP_DE_OFF, outputVal, fp_vbe);
393 DBE_SETREG(fp_de, outputVal);
394 outputVal = 0;
395 SET_DBE_FIELD(FP_HDRV, FP_HDRV_OFF, outputVal, fp_wid);
396 DBE_SETREG(fp_hdrv, outputVal);
397 outputVal = 0;
398 SET_DBE_FIELD(FP_VDRV, FP_VDRV_ON, outputVal, 1);
399 SET_DBE_FIELD(FP_VDRV, FP_VDRV_OFF, outputVal, fp_hgt + 1);
400 DBE_SETREG(fp_vdrv, outputVal);
401}
402
403/*
404 * Set the hardware according to 'par'.
405 */
406static int sgivwfb_set_par(struct fb_info *info)
407{
408 struct sgivw_par *par = info->par;
409 int i, j, htmp, temp;
410 u32 readVal, outputVal;
411 int wholeTilesX, maxPixelsPerTileX;
412 int frmWrite1, frmWrite2, frmWrite3b;
413 struct dbe_timing_info *currentTiming; /* Current Video Timing */
414 int xpmax, ypmax; // Monitor resolution
415 int bytesPerPixel; // Bytes per pixel
416
417 currentTiming = &dbeVTimings[par->timing_num];
418 bytesPerPixel = bytes_per_pixel(info->var.bits_per_pixel);
419 xpmax = currentTiming->width;
420 ypmax = currentTiming->height;
421
422 /* dbe_InitGraphicsBase(); */
423 /* Turn on dotclock PLL */
424 DBE_SETREG(ctrlstat, 0x20000000);
425
426 dbe_TurnOffDma(par);
427
428 /* dbe_CalculateScreenParams(); */
429 maxPixelsPerTileX = 512 / bytesPerPixel;
430 wholeTilesX = xpmax / maxPixelsPerTileX;
431 if (wholeTilesX * maxPixelsPerTileX < xpmax)
432 wholeTilesX++;
433
434 printk(KERN_DEBUG "sgivwfb: pixPerTile=%d wholeTilesX=%d\n",
435 maxPixelsPerTileX, wholeTilesX);
436
437 /* dbe_InitGammaMap(); */
438 udelay(10);
439
440 for (i = 0; i < 256; i++) {
441 DBE_ISETREG(gmap, i, (i << 24) | (i << 16) | (i << 8));
442 }
443
444 /* dbe_TurnOn(); */
445 DBE_GETREG(vt_xy, readVal);
446 if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1) {
447 DBE_SETREG(vt_xy, 0x00000000);
448 udelay(1);
449 } else
450 dbe_TurnOffDma(par);
451
452 /* dbe_Initdbe(); */
453 for (i = 0; i < 256; i++) {
454 for (j = 0; j < 100; j++) {
455 DBE_GETREG(cm_fifo, readVal);
456 if (readVal != 0x00000000)
457 break;
458 else
459 udelay(10);
460 }
461
462 // DBE_ISETREG(cmap, i, 0x00000000);
463 DBE_ISETREG(cmap, i, (i << 8) | (i << 16) | (i << 24));
464 }
465
466 /* dbe_InitFramebuffer(); */
467 frmWrite1 = 0;
468 SET_DBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, frmWrite1,
469 wholeTilesX);
470 SET_DBE_FIELD(FRM_SIZE_TILE, FRM_RHS, frmWrite1, 0);
471
472 switch (bytesPerPixel) {
473 case 1:
474 SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
475 DBE_FRM_DEPTH_8);
476 break;
477 case 2:
478 SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
479 DBE_FRM_DEPTH_16);
480 break;
481 case 4:
482 SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
483 DBE_FRM_DEPTH_32);
484 break;
485 }
486
487 frmWrite2 = 0;
488 SET_DBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, frmWrite2, ypmax);
489
490 // Tell dbe about the framebuffer location and type
491 // XXX What format is the FRM_TILE_PTR?? 64K aligned address?
492 frmWrite3b = 0;
493 SET_DBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, frmWrite3b,
494 sgivwfb_mem_phys >> 9);
495 SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, frmWrite3b, 1);
496 SET_DBE_FIELD(FRM_CONTROL, FRM_LINEAR, frmWrite3b, 1);
497
498 /* Initialize DIDs */
499
500 outputVal = 0;
501 switch (bytesPerPixel) {
502 case 1:
503 SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_I8);
504 break;
505 case 2:
506 SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGBA5);
507 break;
508 case 4:
509 SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGB8);
510 break;
511 }
512 SET_DBE_FIELD(WID, BUF, outputVal, DBE_BMODE_BOTH);
513
514 for (i = 0; i < 32; i++) {
515 DBE_ISETREG(mode_regs, i, outputVal);
516 }
517
518 /* dbe_InitTiming(); */
519 DBE_SETREG(vt_intr01, 0xffffffff);
520 DBE_SETREG(vt_intr23, 0xffffffff);
521
522 DBE_GETREG(dotclock, readVal);
523 DBE_SETREG(dotclock, readVal & 0xffff);
524
525 DBE_SETREG(vt_xymax, 0x00000000);
526 outputVal = 0;
527 SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_ON, outputVal,
528 currentTiming->vsync_start);
529 SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_OFF, outputVal,
530 currentTiming->vsync_end);
531 DBE_SETREG(vt_vsync, outputVal);
532 outputVal = 0;
533 SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_ON, outputVal,
534 currentTiming->hsync_start);
535 SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_OFF, outputVal,
536 currentTiming->hsync_end);
537 DBE_SETREG(vt_hsync, outputVal);
538 outputVal = 0;
539 SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_ON, outputVal,
540 currentTiming->vblank_start);
541 SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_OFF, outputVal,
542 currentTiming->vblank_end);
543 DBE_SETREG(vt_vblank, outputVal);
544 outputVal = 0;
545 SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_ON, outputVal,
546 currentTiming->hblank_start);
547 SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_OFF, outputVal,
548 currentTiming->hblank_end - 3);
549 DBE_SETREG(vt_hblank, outputVal);
550 outputVal = 0;
551 SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_ON, outputVal,
552 currentTiming->vblank_start);
553 SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_OFF, outputVal,
554 currentTiming->vblank_end);
555 DBE_SETREG(vt_vcmap, outputVal);
556 outputVal = 0;
557 SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_ON, outputVal,
558 currentTiming->hblank_start);
559 SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_OFF, outputVal,
560 currentTiming->hblank_end - 3);
561 DBE_SETREG(vt_hcmap, outputVal);
562
563 if (flatpanel_id != -1)
564 sgivwfb_setup_flatpanel(par, currentTiming);
565
566 outputVal = 0;
567 temp = currentTiming->vblank_start - currentTiming->vblank_end - 1;
568 if (temp > 0)
569 temp = -temp;
570
571 SET_DBE_FIELD(DID_START_XY, DID_STARTY, outputVal, (u32) temp);
572 if (currentTiming->hblank_end >= 20)
573 SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,
574 currentTiming->hblank_end - 20);
575 else
576 SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,
577 currentTiming->htotal - (20 -
578 currentTiming->
579 hblank_end));
580 DBE_SETREG(did_start_xy, outputVal);
581
582 outputVal = 0;
583 SET_DBE_FIELD(CRS_START_XY, CRS_STARTY, outputVal,
584 (u32) (temp + 1));
585 if (currentTiming->hblank_end >= DBE_CRS_MAGIC)
586 SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,
587 currentTiming->hblank_end - DBE_CRS_MAGIC);
588 else
589 SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,
590 currentTiming->htotal - (DBE_CRS_MAGIC -
591 currentTiming->
592 hblank_end));
593 DBE_SETREG(crs_start_xy, outputVal);
594
595 outputVal = 0;
596 SET_DBE_FIELD(VC_START_XY, VC_STARTY, outputVal, (u32) temp);
597 SET_DBE_FIELD(VC_START_XY, VC_STARTX, outputVal,
598 currentTiming->hblank_end - 4);
599 DBE_SETREG(vc_start_xy, outputVal);
600
601 DBE_SETREG(frm_size_tile, frmWrite1);
602 DBE_SETREG(frm_size_pixel, frmWrite2);
603
604 outputVal = 0;
605 SET_DBE_FIELD(DOTCLK, M, outputVal, currentTiming->pll_m - 1);
606 SET_DBE_FIELD(DOTCLK, N, outputVal, currentTiming->pll_n - 1);
607 SET_DBE_FIELD(DOTCLK, P, outputVal, currentTiming->pll_p);
608 SET_DBE_FIELD(DOTCLK, RUN, outputVal, 1);
609 DBE_SETREG(dotclock, outputVal);
610
611 udelay(11 * 1000);
612
613 DBE_SETREG(vt_vpixen, 0xffffff);
614 DBE_SETREG(vt_hpixen, 0xffffff);
615
616 outputVal = 0;
617 SET_DBE_FIELD(VT_XYMAX, VT_MAXX, outputVal, currentTiming->htotal);
618 SET_DBE_FIELD(VT_XYMAX, VT_MAXY, outputVal, currentTiming->vtotal);
619 DBE_SETREG(vt_xymax, outputVal);
620
621 outputVal = frmWrite1;
622 SET_DBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, outputVal, 1);
623 DBE_SETREG(frm_size_tile, outputVal);
624 DBE_SETREG(frm_size_tile, frmWrite1);
625
626 outputVal = 0;
627 SET_DBE_FIELD(OVR_WIDTH_TILE, OVR_FIFO_RESET, outputVal, 1);
628 DBE_SETREG(ovr_width_tile, outputVal);
629 DBE_SETREG(ovr_width_tile, 0);
630
631 DBE_SETREG(frm_control, frmWrite3b);
632 DBE_SETREG(did_control, 0);
633
634 // Wait for dbe to take frame settings
635 for (i = 0; i < 100000; i++) {
636 DBE_GETREG(frm_inhwctrl, readVal);
637 if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) !=
638 0)
639 break;
640 else
641 udelay(1);
642 }
643
644 if (i == 100000)
645 printk(KERN_INFO
646 "sgivwfb: timeout waiting for frame DMA enable.\n");
647
648 outputVal = 0;
649 htmp = currentTiming->hblank_end - 19;
650 if (htmp < 0)
651 htmp += currentTiming->htotal; /* allow blank to wrap around */
652 SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_ON, outputVal, htmp);
653 SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_OFF, outputVal,
654 ((htmp + currentTiming->width -
655 2) % currentTiming->htotal));
656 DBE_SETREG(vt_hpixen, outputVal);
657
658 outputVal = 0;
659 SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_OFF, outputVal,
660 currentTiming->vblank_start);
661 SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_ON, outputVal,
662 currentTiming->vblank_end);
663 DBE_SETREG(vt_vpixen, outputVal);
664
665 // Turn off mouse cursor
666 par->regs->crs_ctl = 0;
667
668 // XXX What's this section for??
669 DBE_GETREG(ctrlstat, readVal);
670 readVal &= 0x02000000;
671
672 if (readVal != 0) {
673 DBE_SETREG(ctrlstat, 0x30000000);
674 }
675 return 0;
676}
677
678/*
679 * Set a single color register. The values supplied are already
680 * rounded down to the hardware's capabilities (according to the
681 * entries in the var structure). Return != 0 for invalid regno.
682 */
683
684static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green,
685 u_int blue, u_int transp,
686 struct fb_info *info)
687{
688 struct sgivw_par *par = (struct sgivw_par *) info->par;
689
690 if (regno > 255)
691 return 1;
692 red >>= 8;
693 green >>= 8;
694 blue >>= 8;
695
696 /* wait for the color map FIFO to have a free entry */
697 while (par->cmap_fifo == 0)
698 par->cmap_fifo = par->regs->cm_fifo;
699
700 par->regs->cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
701 par->cmap_fifo--; /* assume FIFO is filling up */
702 return 0;
703}
704
705static int sgivwfb_mmap(struct fb_info *info,
706 struct vm_area_struct *vma)
707{
708 int r;
709
710 pgprot_val(vma->vm_page_prot) =
711 pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
712
713 r = vm_iomap_memory(vma, sgivwfb_mem_phys, sgivwfb_mem_size);
714
715 printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n",
716 sgivwfb_mem_phys + (vma->vm_pgoff << PAGE_SHIFT), vma->vm_start);
717
718 return r;
719}
720
721int __init sgivwfb_setup(char *options)
722{
723 char *this_opt;
724
725 if (!options || !*options)
726 return 0;
727
728 while ((this_opt = strsep(&options, ",")) != NULL) {
729 if (!strncmp(this_opt, "monitor:", 8)) {
730 if (!strncmp(this_opt + 8, "crt", 3))
731 flatpanel_id = -1;
732 else if (!strncmp(this_opt + 8, "1600sw", 6))
733 flatpanel_id = FLATPANEL_SGI_1600SW;
734 }
735 }
736 return 0;
737}
738
739/*
740 * Initialisation
741 */
742static int sgivwfb_probe(struct platform_device *dev)
743{
744 struct sgivw_par *par;
745 struct fb_info *info;
746 char *monitor;
747
748 info = framebuffer_alloc(sizeof(struct sgivw_par) + sizeof(u32) * 16, &dev->dev);
749 if (!info)
750 return -ENOMEM;
751 par = info->par;
752
753 if (!request_mem_region(DBE_REG_PHYS, DBE_REG_SIZE, "sgivwfb")) {
754 printk(KERN_ERR "sgivwfb: couldn't reserve mmio region\n");
755 framebuffer_release(info);
756 return -EBUSY;
757 }
758
759 par->regs = (struct asregs *) ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE);
760 if (!par->regs) {
761 printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n");
762 goto fail_ioremap_regs;
763 }
764
765 mtrr_add(sgivwfb_mem_phys, sgivwfb_mem_size, MTRR_TYPE_WRCOMB, 1);
766
767 sgivwfb_fix.smem_start = sgivwfb_mem_phys;
768 sgivwfb_fix.smem_len = sgivwfb_mem_size;
769 sgivwfb_fix.ywrapstep = ywrap;
770 sgivwfb_fix.ypanstep = ypan;
771
772 info->fix = sgivwfb_fix;
773
774 switch (flatpanel_id) {
775 case FLATPANEL_SGI_1600SW:
776 info->var = sgivwfb_var1600sw;
777 monitor = "SGI 1600SW flatpanel";
778 break;
779 default:
780 info->var = sgivwfb_var;
781 monitor = "CRT";
782 }
783
784 printk(KERN_INFO "sgivwfb: %s monitor selected\n", monitor);
785
786 info->fbops = &sgivwfb_ops;
787 info->pseudo_palette = (void *) (par + 1);
788 info->flags = FBINFO_DEFAULT;
789
790 info->screen_base = ioremap_nocache((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size);
791 if (!info->screen_base) {
792 printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n");
793 goto fail_ioremap_fbmem;
794 }
795
796 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)
797 goto fail_color_map;
798
799 if (register_framebuffer(info) < 0) {
800 printk(KERN_ERR "sgivwfb: couldn't register framebuffer\n");
801 goto fail_register_framebuffer;
802 }
803
804 platform_set_drvdata(dev, info);
805
806 fb_info(info, "SGI DBE frame buffer device, using %ldK of video memory at %#lx\n",
807 sgivwfb_mem_size >> 10, sgivwfb_mem_phys);
808 return 0;
809
810fail_register_framebuffer:
811 fb_dealloc_cmap(&info->cmap);
812fail_color_map:
813 iounmap((char *) info->screen_base);
814fail_ioremap_fbmem:
815 iounmap(par->regs);
816fail_ioremap_regs:
817 release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE);
818 framebuffer_release(info);
819 return -ENXIO;
820}
821
822static int sgivwfb_remove(struct platform_device *dev)
823{
824 struct fb_info *info = platform_get_drvdata(dev);
825
826 if (info) {
827 struct sgivw_par *par = info->par;
828
829 unregister_framebuffer(info);
830 dbe_TurnOffDma(par);
831 iounmap(par->regs);
832 iounmap(info->screen_base);
833 release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE);
834 fb_dealloc_cmap(&info->cmap);
835 framebuffer_release(info);
836 }
837 return 0;
838}
839
840static struct platform_driver sgivwfb_driver = {
841 .probe = sgivwfb_probe,
842 .remove = sgivwfb_remove,
843 .driver = {
844 .name = "sgivwfb",
845 },
846};
847
848static struct platform_device *sgivwfb_device;
849
850int __init sgivwfb_init(void)
851{
852 int ret;
853
854#ifndef MODULE
855 char *option = NULL;
856
857 if (fb_get_options("sgivwfb", &option))
858 return -ENODEV;
859 sgivwfb_setup(option);
860#endif
861 ret = platform_driver_register(&sgivwfb_driver);
862 if (!ret) {
863 sgivwfb_device = platform_device_alloc("sgivwfb", 0);
864 if (sgivwfb_device) {
865 ret = platform_device_add(sgivwfb_device);
866 } else
867 ret = -ENOMEM;
868 if (ret) {
869 platform_driver_unregister(&sgivwfb_driver);
870 platform_device_put(sgivwfb_device);
871 }
872 }
873 return ret;
874}
875
876module_init(sgivwfb_init);
877
878#ifdef MODULE
879MODULE_LICENSE("GPL");
880
881static void __exit sgivwfb_exit(void)
882{
883 platform_device_unregister(sgivwfb_device);
884 platform_driver_unregister(&sgivwfb_driver);
885}
886
887module_exit(sgivwfb_exit);
888
889#endif /* MODULE */
diff --git a/include/video/sgivw.h b/include/video/sgivw.h
deleted file mode 100644
index f6aa5692e74b..000000000000
--- a/include/video/sgivw.h
+++ /dev/null
@@ -1,681 +0,0 @@
1/*
2 * linux/drivers/video/sgivw.h -- SGI DBE frame buffer device header
3 *
4 * Copyright (C) 1999 Silicon Graphics, Inc.
5 * Jeffrey Newquist, newquist@engr.sgi.som
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive for
9 * more details.
10 */
11
12#ifndef __SGIVWFB_H__
13#define __SGIVWFB_H__
14
15#define DBE_GETREG(reg, dest) ((dest) = DBE_REG_BASE->reg)
16#define DBE_SETREG(reg, src) DBE_REG_BASE->reg = (src)
17#define DBE_IGETREG(reg, idx, dest) ((dest) = DBE_REG_BASE->reg[idx])
18#define DBE_ISETREG(reg, idx, src) (DBE_REG_BASE->reg[idx] = (src))
19
20#define MASK(msb, lsb) ( (((u32)1<<((msb)-(lsb)+1))-1) << (lsb) )
21#define GET(v, msb, lsb) ( ((u32)(v) & MASK(msb,lsb)) >> (lsb) )
22#define SET(v, f, msb, lsb) ( (v) = ((v)&~MASK(msb,lsb)) | (( (u32)(f)<<(lsb) ) & MASK(msb,lsb)) )
23
24#define GET_DBE_FIELD(reg, field, v) GET((v), DBE_##reg##_##field##_MSB, DBE_##reg##_##field##_LSB)
25#define SET_DBE_FIELD(reg, field, v, f) SET((v), (f), DBE_##reg##_##field##_MSB, DBE_##reg##_##field##_LSB)
26
27/* NOTE: All loads/stores must be 32 bits and uncached */
28
29#define DBE_REG_PHYS 0xd0000000
30#define DBE_REG_SIZE 0x01000000
31
32struct asregs {
33 volatile u32 ctrlstat; /* 0x000000 general control */
34 volatile u32 dotclock; /* 0x000004 dot clock PLL control */
35 volatile u32 i2c; /* 0x000008 crt I2C control */
36 volatile u32 sysclk; /* 0x00000c system clock PLL control */
37 volatile u32 i2cfp; /* 0x000010 flat panel I2C control */
38 volatile u32 id; /* 0x000014 device id/chip revision */
39 volatile u32 config; /* 0x000018 power on configuration */
40 volatile u32 bist; /* 0x00001c internal bist status */
41
42 char _pad0[ 0x010000 - 0x000020 ];
43
44 volatile u32 vt_xy; /* 0x010000 current dot coords */
45 volatile u32 vt_xymax; /* 0x010004 maximum dot coords */
46 volatile u32 vt_vsync; /* 0x010008 vsync on/off */
47 volatile u32 vt_hsync; /* 0x01000c hsync on/off */
48 volatile u32 vt_vblank; /* 0x010010 vblank on/off */
49 volatile u32 vt_hblank; /* 0x010014 hblank on/off */
50 volatile u32 vt_flags; /* 0x010018 polarity of vt signals */
51 volatile u32 vt_f2rf_lock; /* 0x01001c f2rf & framelck y coord */
52 volatile u32 vt_intr01; /* 0x010020 intr 0,1 y coords */
53 volatile u32 vt_intr23; /* 0x010024 intr 2,3 y coords */
54 volatile u32 fp_hdrv; /* 0x010028 flat panel hdrv on/off */
55 volatile u32 fp_vdrv; /* 0x01002c flat panel vdrv on/off */
56 volatile u32 fp_de; /* 0x010030 flat panel de on/off */
57 volatile u32 vt_hpixen; /* 0x010034 intrnl horiz pixel on/off*/
58 volatile u32 vt_vpixen; /* 0x010038 intrnl vert pixel on/off */
59 volatile u32 vt_hcmap; /* 0x01003c cmap write (horiz) */
60 volatile u32 vt_vcmap; /* 0x010040 cmap write (vert) */
61 volatile u32 did_start_xy; /* 0x010044 eol/f did/xy reset val */
62 volatile u32 crs_start_xy; /* 0x010048 eol/f crs/xy reset val */
63 volatile u32 vc_start_xy; /* 0x01004c eol/f vc/xy reset val */
64
65 char _pad1[ 0x020000 - 0x010050 ];
66
67 volatile u32 ovr_width_tile; /* 0x020000 overlay plane ctrl 0 */
68 volatile u32 ovr_inhwctrl; /* 0x020004 overlay plane ctrl 1 */
69 volatile u32 ovr_control; /* 0x020008 overlay plane ctrl 1 */
70
71 char _pad2[ 0x030000 - 0x02000C ];
72
73 volatile u32 frm_size_tile; /* 0x030000 normal plane ctrl 0 */
74 volatile u32 frm_size_pixel; /* 0x030004 normal plane ctrl 1 */
75 volatile u32 frm_inhwctrl; /* 0x030008 normal plane ctrl 2 */
76 volatile u32 frm_control; /* 0x03000C normal plane ctrl 3 */
77
78 char _pad3[ 0x040000 - 0x030010 ];
79
80 volatile u32 did_inhwctrl; /* 0x040000 DID control */
81 volatile u32 did_control; /* 0x040004 DID shadow */
82
83 char _pad4[ 0x048000 - 0x040008 ];
84
85 volatile u32 mode_regs[32]; /* 0x048000 - 0x04807c WID table */
86
87 char _pad5[ 0x050000 - 0x048080 ];
88
89 volatile u32 cmap[6144]; /* 0x050000 - 0x055ffc color map */
90
91 char _pad6[ 0x058000 - 0x056000 ];
92
93 volatile u32 cm_fifo; /* 0x058000 color map fifo status */
94
95 char _pad7[ 0x060000 - 0x058004 ];
96
97 volatile u32 gmap[256]; /* 0x060000 - 0x0603fc gamma map */
98
99 char _pad8[ 0x068000 - 0x060400 ];
100
101 volatile u32 gmap10[1024]; /* 0x068000 - 0x068ffc gamma map */
102
103 char _pad9[ 0x070000 - 0x069000 ];
104
105 volatile u32 crs_pos; /* 0x070000 cusror control 0 */
106 volatile u32 crs_ctl; /* 0x070004 cusror control 1 */
107 volatile u32 crs_cmap[3]; /* 0x070008 - 0x070010 crs cmap */
108
109 char _pad10[ 0x078000 - 0x070014 ];
110
111 volatile u32 crs_glyph[64]; /* 0x078000 - 0x0780fc crs glyph */
112
113 char _pad11[ 0x080000 - 0x078100 ];
114
115 volatile u32 vc_0; /* 0x080000 video capture crtl 0 */
116 volatile u32 vc_1; /* 0x080004 video capture crtl 1 */
117 volatile u32 vc_2; /* 0x080008 video capture crtl 2 */
118 volatile u32 vc_3; /* 0x08000c video capture crtl 3 */
119 volatile u32 vc_4; /* 0x080010 video capture crtl 3 */
120 volatile u32 vc_5; /* 0x080014 video capture crtl 3 */
121 volatile u32 vc_6; /* 0x080018 video capture crtl 3 */
122 volatile u32 vc_7; /* 0x08001c video capture crtl 3 */
123 volatile u32 vc_8; /* 0x08000c video capture crtl 3 */
124};
125
126/* Bit mask information */
127
128#define DBE_CTRLSTAT_CHIPID_MSB 3
129#define DBE_CTRLSTAT_CHIPID_LSB 0
130#define DBE_CTRLSTAT_SENSE_N_MSB 4
131#define DBE_CTRLSTAT_SENSE_N_LSB 4
132#define DBE_CTRLSTAT_PCLKSEL_MSB 29
133#define DBE_CTRLSTAT_PCLKSEL_LSB 28
134
135#define DBE_DOTCLK_M_MSB 7
136#define DBE_DOTCLK_M_LSB 0
137#define DBE_DOTCLK_N_MSB 13
138#define DBE_DOTCLK_N_LSB 8
139#define DBE_DOTCLK_P_MSB 15
140#define DBE_DOTCLK_P_LSB 14
141#define DBE_DOTCLK_RUN_MSB 20
142#define DBE_DOTCLK_RUN_LSB 20
143
144#define DBE_VT_XY_VT_FREEZE_MSB 31
145#define DBE_VT_XY_VT_FREEZE_LSB 31
146
147#define DBE_FP_VDRV_FP_VDRV_ON_MSB 23
148#define DBE_FP_VDRV_FP_VDRV_ON_LSB 12
149#define DBE_FP_VDRV_FP_VDRV_OFF_MSB 11
150#define DBE_FP_VDRV_FP_VDRV_OFF_LSB 0
151
152#define DBE_FP_HDRV_FP_HDRV_ON_MSB 23
153#define DBE_FP_HDRV_FP_HDRV_ON_LSB 12
154#define DBE_FP_HDRV_FP_HDRV_OFF_MSB 11
155#define DBE_FP_HDRV_FP_HDRV_OFF_LSB 0
156
157#define DBE_FP_DE_FP_DE_ON_MSB 23
158#define DBE_FP_DE_FP_DE_ON_LSB 12
159#define DBE_FP_DE_FP_DE_OFF_MSB 11
160#define DBE_FP_DE_FP_DE_OFF_LSB 0
161
162#define DBE_VT_VSYNC_VT_VSYNC_ON_MSB 23
163#define DBE_VT_VSYNC_VT_VSYNC_ON_LSB 12
164#define DBE_VT_VSYNC_VT_VSYNC_OFF_MSB 11
165#define DBE_VT_VSYNC_VT_VSYNC_OFF_LSB 0
166
167#define DBE_VT_HSYNC_VT_HSYNC_ON_MSB 23
168#define DBE_VT_HSYNC_VT_HSYNC_ON_LSB 12
169#define DBE_VT_HSYNC_VT_HSYNC_OFF_MSB 11
170#define DBE_VT_HSYNC_VT_HSYNC_OFF_LSB 0
171
172#define DBE_VT_VBLANK_VT_VBLANK_ON_MSB 23
173#define DBE_VT_VBLANK_VT_VBLANK_ON_LSB 12
174#define DBE_VT_VBLANK_VT_VBLANK_OFF_MSB 11
175#define DBE_VT_VBLANK_VT_VBLANK_OFF_LSB 0
176
177#define DBE_VT_HBLANK_VT_HBLANK_ON_MSB 23
178#define DBE_VT_HBLANK_VT_HBLANK_ON_LSB 12
179#define DBE_VT_HBLANK_VT_HBLANK_OFF_MSB 11
180#define DBE_VT_HBLANK_VT_HBLANK_OFF_LSB 0
181
182#define DBE_VT_FLAGS_VDRV_INVERT_MSB 0
183#define DBE_VT_FLAGS_VDRV_INVERT_LSB 0
184#define DBE_VT_FLAGS_HDRV_INVERT_MSB 2
185#define DBE_VT_FLAGS_HDRV_INVERT_LSB 2
186
187#define DBE_VT_VCMAP_VT_VCMAP_ON_MSB 23
188#define DBE_VT_VCMAP_VT_VCMAP_ON_LSB 12
189#define DBE_VT_VCMAP_VT_VCMAP_OFF_MSB 11
190#define DBE_VT_VCMAP_VT_VCMAP_OFF_LSB 0
191
192#define DBE_VT_HCMAP_VT_HCMAP_ON_MSB 23
193#define DBE_VT_HCMAP_VT_HCMAP_ON_LSB 12
194#define DBE_VT_HCMAP_VT_HCMAP_OFF_MSB 11
195#define DBE_VT_HCMAP_VT_HCMAP_OFF_LSB 0
196
197#define DBE_VT_XYMAX_VT_MAXX_MSB 11
198#define DBE_VT_XYMAX_VT_MAXX_LSB 0
199#define DBE_VT_XYMAX_VT_MAXY_MSB 23
200#define DBE_VT_XYMAX_VT_MAXY_LSB 12
201
202#define DBE_VT_HPIXEN_VT_HPIXEN_ON_MSB 23
203#define DBE_VT_HPIXEN_VT_HPIXEN_ON_LSB 12
204#define DBE_VT_HPIXEN_VT_HPIXEN_OFF_MSB 11
205#define DBE_VT_HPIXEN_VT_HPIXEN_OFF_LSB 0
206
207#define DBE_VT_VPIXEN_VT_VPIXEN_ON_MSB 23
208#define DBE_VT_VPIXEN_VT_VPIXEN_ON_LSB 12
209#define DBE_VT_VPIXEN_VT_VPIXEN_OFF_MSB 11
210#define DBE_VT_VPIXEN_VT_VPIXEN_OFF_LSB 0
211
212#define DBE_OVR_CONTROL_OVR_DMA_ENABLE_MSB 0
213#define DBE_OVR_CONTROL_OVR_DMA_ENABLE_LSB 0
214
215#define DBE_OVR_INHWCTRL_OVR_DMA_ENABLE_MSB 0
216#define DBE_OVR_INHWCTRL_OVR_DMA_ENABLE_LSB 0
217
218#define DBE_OVR_WIDTH_TILE_OVR_FIFO_RESET_MSB 13
219#define DBE_OVR_WIDTH_TILE_OVR_FIFO_RESET_LSB 13
220
221#define DBE_FRM_CONTROL_FRM_DMA_ENABLE_MSB 0
222#define DBE_FRM_CONTROL_FRM_DMA_ENABLE_LSB 0
223#define DBE_FRM_CONTROL_FRM_TILE_PTR_MSB 31
224#define DBE_FRM_CONTROL_FRM_TILE_PTR_LSB 9
225#define DBE_FRM_CONTROL_FRM_LINEAR_MSB 1
226#define DBE_FRM_CONTROL_FRM_LINEAR_LSB 1
227
228#define DBE_FRM_INHWCTRL_FRM_DMA_ENABLE_MSB 0
229#define DBE_FRM_INHWCTRL_FRM_DMA_ENABLE_LSB 0
230
231#define DBE_FRM_SIZE_TILE_FRM_WIDTH_TILE_MSB 12
232#define DBE_FRM_SIZE_TILE_FRM_WIDTH_TILE_LSB 5
233#define DBE_FRM_SIZE_TILE_FRM_RHS_MSB 4
234#define DBE_FRM_SIZE_TILE_FRM_RHS_LSB 0
235#define DBE_FRM_SIZE_TILE_FRM_DEPTH_MSB 14
236#define DBE_FRM_SIZE_TILE_FRM_DEPTH_LSB 13
237#define DBE_FRM_SIZE_TILE_FRM_FIFO_RESET_MSB 15
238#define DBE_FRM_SIZE_TILE_FRM_FIFO_RESET_LSB 15
239
240#define DBE_FRM_SIZE_PIXEL_FB_HEIGHT_PIX_MSB 31
241#define DBE_FRM_SIZE_PIXEL_FB_HEIGHT_PIX_LSB 16
242
243#define DBE_DID_CONTROL_DID_DMA_ENABLE_MSB 0
244#define DBE_DID_CONTROL_DID_DMA_ENABLE_LSB 0
245#define DBE_DID_INHWCTRL_DID_DMA_ENABLE_MSB 0
246#define DBE_DID_INHWCTRL_DID_DMA_ENABLE_LSB 0
247
248#define DBE_DID_START_XY_DID_STARTY_MSB 23
249#define DBE_DID_START_XY_DID_STARTY_LSB 12
250#define DBE_DID_START_XY_DID_STARTX_MSB 11
251#define DBE_DID_START_XY_DID_STARTX_LSB 0
252
253#define DBE_CRS_START_XY_CRS_STARTY_MSB 23
254#define DBE_CRS_START_XY_CRS_STARTY_LSB 12
255#define DBE_CRS_START_XY_CRS_STARTX_MSB 11
256#define DBE_CRS_START_XY_CRS_STARTX_LSB 0
257
258#define DBE_WID_TYP_MSB 4
259#define DBE_WID_TYP_LSB 2
260#define DBE_WID_BUF_MSB 1
261#define DBE_WID_BUF_LSB 0
262
263#define DBE_VC_START_XY_VC_STARTY_MSB 23
264#define DBE_VC_START_XY_VC_STARTY_LSB 12
265#define DBE_VC_START_XY_VC_STARTX_MSB 11
266#define DBE_VC_START_XY_VC_STARTX_LSB 0
267
268/* Constants */
269
270#define DBE_FRM_DEPTH_8 0
271#define DBE_FRM_DEPTH_16 1
272#define DBE_FRM_DEPTH_32 2
273
274#define DBE_CMODE_I8 0
275#define DBE_CMODE_I12 1
276#define DBE_CMODE_RG3B2 2
277#define DBE_CMODE_RGB4 3
278#define DBE_CMODE_ARGB5 4
279#define DBE_CMODE_RGB8 5
280#define DBE_CMODE_RGBA5 6
281#define DBE_CMODE_RGB10 7
282
283#define DBE_BMODE_BOTH 3
284
285#define DBE_CRS_MAGIC 54
286
287#define DBE_CLOCK_REF_KHZ 27000
288
289/* Config Register (DBE Only) Definitions */
290
291#define DBE_CONFIG_VDAC_ENABLE 0x00000001
292#define DBE_CONFIG_VDAC_GSYNC 0x00000002
293#define DBE_CONFIG_VDAC_PBLANK 0x00000004
294#define DBE_CONFIG_FPENABLE 0x00000008
295#define DBE_CONFIG_LENDIAN 0x00000020
296#define DBE_CONFIG_TILEHIST 0x00000040
297#define DBE_CONFIG_EXT_ADDR 0x00000080
298
299#define DBE_CONFIG_FBDEV ( DBE_CONFIG_VDAC_ENABLE | \
300 DBE_CONFIG_VDAC_GSYNC | \
301 DBE_CONFIG_VDAC_PBLANK | \
302 DBE_CONFIG_LENDIAN | \
303 DBE_CONFIG_EXT_ADDR )
304
305/*
306 * Available Video Timings and Corresponding Indices
307 */
308
309typedef enum {
310 DBE_VT_640_480_60,
311
312 DBE_VT_800_600_60,
313 DBE_VT_800_600_75,
314 DBE_VT_800_600_120,
315
316 DBE_VT_1024_768_50,
317 DBE_VT_1024_768_60,
318 DBE_VT_1024_768_75,
319 DBE_VT_1024_768_85,
320 DBE_VT_1024_768_120,
321
322 DBE_VT_1280_1024_50,
323 DBE_VT_1280_1024_60,
324 DBE_VT_1280_1024_75,
325 DBE_VT_1280_1024_85,
326
327 DBE_VT_1600_1024_53,
328 DBE_VT_1600_1024_60,
329
330 DBE_VT_1600_1200_50,
331 DBE_VT_1600_1200_60,
332 DBE_VT_1600_1200_75,
333
334 DBE_VT_1920_1080_50,
335 DBE_VT_1920_1080_60,
336 DBE_VT_1920_1080_72,
337
338 DBE_VT_1920_1200_50,
339 DBE_VT_1920_1200_60,
340 DBE_VT_1920_1200_66,
341
342 DBE_VT_UNKNOWN
343} dbe_timing_t;
344
345
346
347/*
348 * Crime Video Timing Data Structure
349 */
350
351struct dbe_timing_info
352{
353 dbe_timing_t type;
354 int flags;
355 short width; /* Monitor resolution */
356 short height;
357 int fields_sec; /* fields/sec (Hz -3 dec. places */
358 int cfreq; /* pixel clock frequency (MHz -3 dec. places) */
359 short htotal; /* Horizontal total pixels */
360 short hblank_start; /* Horizontal blank start */
361 short hblank_end; /* Horizontal blank end */
362 short hsync_start; /* Horizontal sync start */
363 short hsync_end; /* Horizontal sync end */
364 short vtotal; /* Vertical total lines */
365 short vblank_start; /* Vertical blank start */
366 short vblank_end; /* Vertical blank end */
367 short vsync_start; /* Vertical sync start */
368 short vsync_end; /* Vertical sync end */
369 short pll_m; /* PLL M parameter */
370 short pll_n; /* PLL P parameter */
371 short pll_p; /* PLL N parameter */
372};
373
374/* Defines for dbe_vof_info_t flags */
375
376#define DBE_VOF_UNKNOWNMON 1
377#define DBE_VOF_STEREO 2
378#define DBE_VOF_DO_GENSYNC 4 /* enable incoming sync */
379#define DBE_VOF_SYNC_ON_GREEN 8 /* sync on green */
380#define DBE_VOF_FLATPANEL 0x1000 /* FLATPANEL Timing */
381#define DBE_VOF_MAGICKEY 0x2000 /* Backdoor key */
382
383/*
384 * DBE Timing Tables
385 */
386
387#ifdef INCLUDE_TIMING_TABLE_DATA
388struct dbe_timing_info dbeVTimings[] = {
389 {
390 DBE_VT_640_480_60,
391 /* flags, width, height, fields_sec, cfreq */
392 0, 640, 480, 59940, 25175,
393 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
394 800, 640, 800, 656, 752,
395 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
396 525, 480, 525, 490, 492,
397 /* pll_m, pll_n, pll_p */
398 15, 2, 3
399 },
400
401 {
402 DBE_VT_800_600_60,
403 /* flags, width, height, fields_sec, cfreq */
404 0, 800, 600, 60317, 40000,
405 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
406 1056, 800, 1056, 840, 968,
407 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
408 628, 600, 628, 601, 605,
409 /* pll_m, pll_n, pll_p */
410 3, 1, 1
411 },
412
413 {
414 DBE_VT_800_600_75,
415 /* flags, width, height, fields_sec, cfreq */
416 0, 800, 600, 75000, 49500,
417 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
418 1056, 800, 1056, 816, 896,
419 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
420 625, 600, 625, 601, 604,
421 /* pll_m, pll_n, pll_p */
422 11, 3, 1
423 },
424
425 {
426 DBE_VT_800_600_120,
427 /* flags, width, height, fields_sec, cfreq */
428 DBE_VOF_STEREO, 800, 600, 119800, 82978,
429 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
430 1040, 800, 1040, 856, 976,
431 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
432 666, 600, 666, 637, 643,
433 /* pll_m, pll_n, pll_p */
434 31, 5, 1
435 },
436
437 {
438 DBE_VT_1024_768_50,
439 /* flags, width, height, fields_sec, cfreq */
440 0, 1024, 768, 50000, 54163,
441 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
442 1344, 1024, 1344, 1048, 1184,
443 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
444 806, 768, 806, 771, 777,
445 /* pll_m, pll_n, pll_p */
446 4, 1, 1
447 },
448
449 {
450 DBE_VT_1024_768_60,
451 /* flags, width, height, fields_sec, cfreq */
452 0, 1024, 768, 60004, 65000,
453 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
454 1344, 1024, 1344, 1048, 1184,
455 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
456 806, 768, 806, 771, 777,
457 /* pll_m, pll_n, pll_p */
458 12, 5, 0
459 },
460
461 {
462 DBE_VT_1024_768_75,
463 /* flags, width, height, fields_sec, cfreq */
464 0, 1024, 768, 75029, 78750,
465 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
466 1312, 1024, 1312, 1040, 1136,
467 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
468 800, 768, 800, 769, 772,
469 /* pll_m, pll_n, pll_p */
470 29, 5, 1
471 },
472
473 {
474 DBE_VT_1024_768_85,
475 /* flags, width, height, fields_sec, cfreq */
476 0, 1024, 768, 84997, 94500,
477 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
478 1376, 1024, 1376, 1072, 1168,
479 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
480 808, 768, 808, 769, 772,
481 /* pll_m, pll_n, pll_p */
482 7, 2, 0
483 },
484
485 {
486 DBE_VT_1024_768_120,
487 /* flags, width, height, fields_sec, cfreq */
488 DBE_VOF_STEREO, 1024, 768, 119800, 133195,
489 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
490 1376, 1024, 1376, 1072, 1168,
491 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
492 808, 768, 808, 769, 772,
493 /* pll_m, pll_n, pll_p */
494 5, 1, 0
495 },
496
497 {
498 DBE_VT_1280_1024_50,
499 /* flags, width, height, fields_sec, cfreq */
500 0, 1280, 1024, 50000, 89460,
501 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
502 1680, 1280, 1680, 1360, 1480,
503 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
504 1065, 1024, 1065, 1027, 1030,
505 /* pll_m, pll_n, pll_p */
506 10, 3, 0
507 },
508
509 {
510 DBE_VT_1280_1024_60,
511 /* flags, width, height, fields_sec, cfreq */
512 0, 1280, 1024, 60020, 108000,
513 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
514 1688, 1280, 1688, 1328, 1440,
515 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
516 1066, 1024, 1066, 1025, 1028,
517 /* pll_m, pll_n, pll_p */
518 4, 1, 0
519 },
520
521 {
522 DBE_VT_1280_1024_75,
523 /* flags, width, height, fields_sec, cfreq */
524 0, 1280, 1024, 75025, 135000,
525 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
526 1688, 1280, 1688, 1296, 1440,
527 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
528 1066, 1024, 1066, 1025, 1028,
529 /* pll_m, pll_n, pll_p */
530 5, 1, 0
531 },
532
533 {
534 DBE_VT_1280_1024_85,
535 /* flags, width, height, fields_sec, cfreq */
536 0, 1280, 1024, 85024, 157500,
537 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
538 1728, 1280, 1728, 1344, 1504,
539 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
540 1072, 1024, 1072, 1025, 1028,
541 /* pll_m, pll_n, pll_p */
542 29, 5, 0
543 },
544
545 {
546 DBE_VT_1600_1024_53,
547 /* flags, width, height, fields_sec, cfreq */
548 DBE_VOF_FLATPANEL | DBE_VOF_MAGICKEY,
549 1600, 1024, 53000, 107447,
550 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
551 1900, 1600, 1900, 1630, 1730,
552 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
553 1067, 1024, 1067, 1027, 1030,
554 /* pll_m, pll_n, pll_p */
555 4, 1, 0
556 },
557
558 {
559 DBE_VT_1600_1024_60,
560 /* flags, width, height, fields_sec, cfreq */
561 DBE_VOF_FLATPANEL, 1600, 1024, 60000, 106913,
562 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
563 1670, 1600, 1670, 1630, 1650,
564 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
565 1067, 1024, 1067, 1027, 1030,
566 /* pll_m, pll_n, pll_p */
567 4, 1, 0
568 },
569
570 {
571 DBE_VT_1600_1200_50,
572 /* flags, width, height, fields_sec, cfreq */
573 0, 1600, 1200, 50000, 130500,
574 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
575 2088, 1600, 2088, 1644, 1764,
576 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
577 1250, 1200, 1250, 1205, 1211,
578 /* pll_m, pll_n, pll_p */
579 24, 5, 0
580 },
581
582 {
583 DBE_VT_1600_1200_60,
584 /* flags, width, height, fields_sec, cfreq */
585 0, 1600, 1200, 59940, 162000,
586 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
587 2160, 1600, 2160, 1644, 1856,
588 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
589 1250, 1200, 1250, 1201, 1204,
590 /* pll_m, pll_n, pll_p */
591 6, 1, 0
592 },
593
594 {
595 DBE_VT_1600_1200_75,
596 /* flags, width, height, fields_sec, cfreq */
597 0, 1600, 1200, 75000, 202500,
598 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
599 2160, 1600, 2160, 1644, 1856,
600 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
601 1250, 1200, 1250, 1201, 1204,
602 /* pll_m, pll_n, pll_p */
603 15, 2, 0
604 },
605
606 {
607 DBE_VT_1920_1080_50,
608 /* flags, width, height, fields_sec, cfreq */
609 0, 1920, 1080, 50000, 133200,
610 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
611 2368, 1920, 2368, 1952, 2096,
612 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
613 1125, 1080, 1125, 1083, 1086,
614 /* pll_m, pll_n, pll_p */
615 5, 1, 0
616 },
617
618 {
619 DBE_VT_1920_1080_60,
620 /* flags, width, height, fields_sec, cfreq */
621 0, 1920, 1080, 59940, 159840,
622 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
623 2368, 1920, 2368, 1952, 2096,
624 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
625 1125, 1080, 1125, 1083, 1086,
626 /* pll_m, pll_n, pll_p */
627 6, 1, 0
628 },
629
630 {
631 DBE_VT_1920_1080_72,
632 /* flags, width, height, fields_sec, cfreq */
633 0, 1920, 1080, 72000, 216023,
634 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
635 2560, 1920, 2560, 1968, 2184,
636 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
637 1172, 1080, 1172, 1083, 1086,
638 /* pll_m, pll_n, pll_p */
639 8, 1, 0
640 },
641
642 {
643 DBE_VT_1920_1200_50,
644 /* flags, width, height, fields_sec, cfreq */
645 0, 1920, 1200, 50000, 161500,
646 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
647 2584, 1920, 2584, 1984, 2240,
648 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
649 1250, 1200, 1250, 1203, 1206,
650 /* pll_m, pll_n, pll_p */
651 6, 1, 0
652 },
653
654 {
655 DBE_VT_1920_1200_60,
656 /* flags, width, height, fields_sec, cfreq */
657 0, 1920, 1200, 59940, 193800,
658 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
659 2584, 1920, 2584, 1984, 2240,
660 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
661 1250, 1200, 1250, 1203, 1206,
662 /* pll_m, pll_n, pll_p */
663 29, 4, 0
664 },
665
666 {
667 DBE_VT_1920_1200_66,
668 /* flags, width, height, fields_sec, cfreq */
669 0, 1920, 1200, 66000, 213180,
670 /* htotal, hblank_start, hblank_end, hsync_start, hsync_end */
671 2584, 1920, 2584, 1984, 2240,
672 /* vtotal, vblank_start, vblank_end, vsync_start, vsync_end */
673 1250, 1200, 1250, 1203, 1206,
674 /* pll_m, pll_n, pll_p */
675 8, 1, 0
676 }
677};
678
679#endif // INCLUDE_TIMING_TABLE_DATA
680
681#endif // ! __SGIVWFB_H__
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 1a9640254433..48568fdf847f 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -13,15 +13,6 @@ config SOUND_BCM_CS4297A
13 note that CONFIG_KGDB should not be enabled at the same 13 note that CONFIG_KGDB should not be enabled at the same
14 time, since it also attempts to use this UART port. 14 time, since it also attempts to use this UART port.
15 15
16config SOUND_VWSND
17 tristate "SGI Visual Workstation Sound"
18 depends on X86_VISWS
19 help
20 Say Y or M if you have an SGI Visual Workstation and you want to be
21 able to use its on-board audio. Read
22 <file:Documentation/sound/oss/vwsnd> for more info on this driver's
23 capabilities.
24
25config SOUND_MSNDCLAS 16config SOUND_MSNDCLAS
26 tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey" 17 tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey"
27 depends on (m || !STANDALONE) && ISA 18 depends on (m || !STANDALONE) && ISA
diff --git a/sound/oss/Makefile b/sound/oss/Makefile
index 77f21b68bf0f..9bdbbde2173e 100644
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -24,7 +24,6 @@ obj-$(CONFIG_SOUND_VIDC) += vidc_mod.o
24obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o 24obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o
25obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o 25obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o
26obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o 26obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o
27obj-$(CONFIG_SOUND_VWSND) += vwsnd.o
28obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o 27obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o
29 28
30obj-$(CONFIG_DMASOUND) += dmasound/ 29obj-$(CONFIG_DMASOUND) += dmasound/
diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
deleted file mode 100644
index a077e9c69a5e..000000000000
--- a/sound/oss/vwsnd.c
+++ /dev/null
@@ -1,3506 +0,0 @@
1/*
2 * Sound driver for Silicon Graphics 320 and 540 Visual Workstations'
3 * onboard audio. See notes in Documentation/sound/oss/vwsnd .
4 *
5 * Copyright 1999 Silicon Graphics, Inc. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#undef VWSND_DEBUG /* define for debugging */
23
24/*
25 * XXX to do -
26 *
27 * External sync.
28 * Rename swbuf, hwbuf, u&i, hwptr&swptr to something rational.
29 * Bug - if select() called before read(), pcm_setup() not called.
30 * Bug - output doesn't stop soon enough if process killed.
31 */
32
33/*
34 * Things to test -
35 *
36 * Will readv/writev work? Write a test.
37 *
38 * insmod/rmmod 100 million times.
39 *
40 * Run I/O until int ptrs wrap around (roughly 6.2 hours @ DAT
41 * rate).
42 *
43 * Concurrent threads banging on mixer simultaneously, both UP
44 * and SMP kernels. Especially, watch for thread A changing
45 * OUTSRC while thread B changes gain -- both write to the same
46 * ad1843 register.
47 *
48 * What happens if a client opens /dev/audio then forks?
49 * Do two procs have /dev/audio open? Test.
50 *
51 * Pump audio through the CD, MIC and line inputs and verify that
52 * they mix/mute into the output.
53 *
54 * Apps:
55 * amp
56 * mpg123
57 * x11amp
58 * mxv
59 * kmedia
60 * esound
61 * need more input apps
62 *
63 * Run tests while bombarding with signals. setitimer(2) will do it... */
64
65/*
66 * This driver is organized in nine sections.
67 * The nine sections are:
68 *
69 * debug stuff
70 * low level lithium access
71 * high level lithium access
72 * AD1843 access
73 * PCM I/O
74 * audio driver
75 * mixer driver
76 * probe/attach/unload
77 * initialization and loadable kernel module interface
78 *
79 * That is roughly the order of increasing abstraction, so forward
80 * dependencies are minimal.
81 */
82
83/*
84 * Locking Notes
85 *
86 * INC_USE_COUNT and DEC_USE_COUNT keep track of the number of
87 * open descriptors to this driver. They store it in vwsnd_use_count.
88 * The global device list, vwsnd_dev_list, is immutable when the IN_USE
89 * is true.
90 *
91 * devc->open_lock is a semaphore that is used to enforce the
92 * single reader/single writer rule for /dev/audio. The rule is
93 * that each device may have at most one reader and one writer.
94 * Open will block until the previous client has closed the
95 * device, unless O_NONBLOCK is specified.
96 *
97 * The semaphore devc->io_mutex serializes PCM I/O syscalls. This
98 * is unnecessary in Linux 2.2, because the kernel lock
99 * serializes read, write, and ioctl globally, but it's there,
100 * ready for the brave, new post-kernel-lock world.
101 *
102 * Locking between interrupt and baselevel is handled by the
103 * "lock" spinlock in vwsnd_port (one lock each for read and
104 * write). Each half holds the lock just long enough to see what
105 * area it owns and update its pointers. See pcm_output() and
106 * pcm_input() for most of the gory stuff.
107 *
108 * devc->mix_mutex serializes all mixer ioctls. This is also
109 * redundant because of the kernel lock.
110 *
111 * The lowest level lock is lith->lithium_lock. It is a
112 * spinlock which is held during the two-register tango of
113 * reading/writing an AD1843 register. See
114 * li_{read,write}_ad1843_reg().
115 */
116
117/*
118 * Sample Format Notes
119 *
120 * Lithium's DMA engine has two formats: 16-bit 2's complement
121 * and 8-bit unsigned . 16-bit transfers the data unmodified, 2
122 * bytes per sample. 8-bit unsigned transfers 1 byte per sample
123 * and XORs each byte with 0x80. Lithium can input or output
124 * either mono or stereo in either format.
125 *
126 * The AD1843 has four formats: 16-bit 2's complement, 8-bit
127 * unsigned, 8-bit mu-Law and 8-bit A-Law.
128 *
129 * This driver supports five formats: AFMT_S8, AFMT_U8,
130 * AFMT_MU_LAW, AFMT_A_LAW, and AFMT_S16_LE.
131 *
132 * For AFMT_U8 output, we keep the AD1843 in 16-bit mode, and
133 * rely on Lithium's XOR to translate between U8 and S8.
134 *
135 * For AFMT_S8, AFMT_MU_LAW and AFMT_A_LAW output, we have to XOR
136 * the 0x80 bit in software to compensate for Lithium's XOR.
137 * This happens in pcm_copy_{in,out}().
138 *
139 * Changes:
140 * 11-10-2000 Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
141 * Added some __init/__exit
142 */
143
144#include <linux/module.h>
145#include <linux/init.h>
146
147#include <linux/spinlock.h>
148#include <linux/wait.h>
149#include <linux/interrupt.h>
150#include <linux/mutex.h>
151#include <linux/slab.h>
152#include <linux/delay.h>
153
154#include <asm/visws/cobalt.h>
155
156#include "sound_config.h"
157
158static DEFINE_MUTEX(vwsnd_mutex);
159
160/*****************************************************************************/
161/* debug stuff */
162
163#ifdef VWSND_DEBUG
164
165static int shut_up = 1;
166
167/*
168 * dbgassert - called when an assertion fails.
169 */
170
171static void dbgassert(const char *fcn, int line, const char *expr)
172{
173 if (in_interrupt())
174 panic("ASSERTION FAILED IN INTERRUPT, %s:%s:%d %s\n",
175 __FILE__, fcn, line, expr);
176 else {
177 int x;
178 printk(KERN_ERR "ASSERTION FAILED, %s:%s:%d %s\n",
179 __FILE__, fcn, line, expr);
180 x = * (volatile int *) 0; /* force proc to exit */
181 }
182}
183
184/*
185 * Bunch of useful debug macros:
186 *
187 * ASSERT - print unless e nonzero (panic if in interrupt)
188 * DBGDO - include arbitrary code if debugging
189 * DBGX - debug print raw (w/o function name)
190 * DBGP - debug print w/ function name
191 * DBGE - debug print function entry
192 * DBGC - debug print function call
193 * DBGR - debug print function return
194 * DBGXV - debug print raw when verbose
195 * DBGPV - debug print when verbose
196 * DBGEV - debug print function entry when verbose
197 * DBGRV - debug print function return when verbose
198 */
199
200#define ASSERT(e) ((e) ? (void) 0 : dbgassert(__func__, __LINE__, #e))
201#define DBGDO(x) x
202#define DBGX(fmt, args...) (in_interrupt() ? 0 : printk(KERN_ERR fmt, ##args))
203#define DBGP(fmt, args...) (DBGX("%s: " fmt, __func__ , ##args))
204#define DBGE(fmt, args...) (DBGX("%s" fmt, __func__ , ##args))
205#define DBGC(rtn) (DBGP("calling %s\n", rtn))
206#define DBGR() (DBGP("returning\n"))
207#define DBGXV(fmt, args...) (shut_up ? 0 : DBGX(fmt, ##args))
208#define DBGPV(fmt, args...) (shut_up ? 0 : DBGP(fmt, ##args))
209#define DBGEV(fmt, args...) (shut_up ? 0 : DBGE(fmt, ##args))
210#define DBGCV(rtn) (shut_up ? 0 : DBGC(rtn))
211#define DBGRV() (shut_up ? 0 : DBGR())
212
213#else /* !VWSND_DEBUG */
214
215#define ASSERT(e) ((void) 0)
216#define DBGDO(x) /* don't */
217#define DBGX(fmt, args...) ((void) 0)
218#define DBGP(fmt, args...) ((void) 0)
219#define DBGE(fmt, args...) ((void) 0)
220#define DBGC(rtn) ((void) 0)
221#define DBGR() ((void) 0)
222#define DBGPV(fmt, args...) ((void) 0)
223#define DBGXV(fmt, args...) ((void) 0)
224#define DBGEV(fmt, args...) ((void) 0)
225#define DBGCV(rtn) ((void) 0)
226#define DBGRV() ((void) 0)
227
228#endif /* !VWSND_DEBUG */
229
230/*****************************************************************************/
231/* low level lithium access */
232
233/*
234 * We need to talk to Lithium registers on three pages. Here are
235 * the pages' offsets from the base address (0xFF001000).
236 */
237
238enum {
239 LI_PAGE0_OFFSET = 0x01000 - 0x1000, /* FF001000 */
240 LI_PAGE1_OFFSET = 0x0F000 - 0x1000, /* FF00F000 */
241 LI_PAGE2_OFFSET = 0x10000 - 0x1000, /* FF010000 */
242};
243
244/* low-level lithium data */
245
246typedef struct lithium {
247 void * page0; /* virtual addresses */
248 void * page1;
249 void * page2;
250 spinlock_t lock; /* protects codec and UST/MSC access */
251} lithium_t;
252
253/*
254 * li_destroy destroys the lithium_t structure and vm mappings.
255 */
256
257static void li_destroy(lithium_t *lith)
258{
259 if (lith->page0) {
260 iounmap(lith->page0);
261 lith->page0 = NULL;
262 }
263 if (lith->page1) {
264 iounmap(lith->page1);
265 lith->page1 = NULL;
266 }
267 if (lith->page2) {
268 iounmap(lith->page2);
269 lith->page2 = NULL;
270 }
271}
272
273/*
274 * li_create initializes the lithium_t structure and sets up vm mappings
275 * to access the registers.
276 * Returns 0 on success, -errno on failure.
277 */
278
279static int __init li_create(lithium_t *lith, unsigned long baseaddr)
280{
281 spin_lock_init(&lith->lock);
282 lith->page0 = ioremap_nocache(baseaddr + LI_PAGE0_OFFSET, PAGE_SIZE);
283 lith->page1 = ioremap_nocache(baseaddr + LI_PAGE1_OFFSET, PAGE_SIZE);
284 lith->page2 = ioremap_nocache(baseaddr + LI_PAGE2_OFFSET, PAGE_SIZE);
285 if (!lith->page0 || !lith->page1 || !lith->page2) {
286 li_destroy(lith);
287 return -ENOMEM;
288 }
289 return 0;
290}
291
292/*
293 * basic register accessors - read/write long/byte
294 */
295
296static __inline__ unsigned long li_readl(lithium_t *lith, int off)
297{
298 return * (volatile unsigned long *) (lith->page0 + off);
299}
300
301static __inline__ unsigned char li_readb(lithium_t *lith, int off)
302{
303 return * (volatile unsigned char *) (lith->page0 + off);
304}
305
306static __inline__ void li_writel(lithium_t *lith, int off, unsigned long val)
307{
308 * (volatile unsigned long *) (lith->page0 + off) = val;
309}
310
311static __inline__ void li_writeb(lithium_t *lith, int off, unsigned char val)
312{
313 * (volatile unsigned char *) (lith->page0 + off) = val;
314}
315
316/*****************************************************************************/
317/* High Level Lithium Access */
318
319/*
320 * Lithium DMA Notes
321 *
322 * Lithium has two dedicated DMA channels for audio. They are known
323 * as comm1 and comm2 (communication areas 1 and 2). Comm1 is for
324 * input, and comm2 is for output. Each is controlled by three
325 * registers: BASE (base address), CFG (config) and CCTL
326 * (config/control).
327 *
328 * Each DMA channel points to a physically contiguous ring buffer in
329 * main memory of up to 8 Kbytes. (This driver always uses 8 Kb.)
330 * There are three pointers into the ring buffer: read, write, and
331 * trigger. The pointers are 8 bits each. Each pointer points to
332 * 32-byte "chunks" of data. The DMA engine moves 32 bytes at a time,
333 * so there is no finer-granularity control.
334 *
335 * In comm1, the hardware updates the write ptr, and software updates
336 * the read ptr. In comm2, it's the opposite: hardware updates the
337 * read ptr, and software updates the write ptr. I designate the
338 * hardware-updated ptr as the hwptr, and the software-updated ptr as
339 * the swptr.
340 *
341 * The trigger ptr and trigger mask are used to trigger interrupts.
342 * From the Lithium spec, section 5.6.8, revision of 12/15/1998:
343 *
344 * Trigger Mask Value
345 *
346 * A three bit wide field that represents a power of two mask
347 * that is used whenever the trigger pointer is compared to its
348 * respective read or write pointer. A value of zero here
349 * implies a mask of 0xFF and a value of seven implies a mask
350 * 0x01. This value can be used to sub-divide the ring buffer
351 * into pie sections so that interrupts monitor the progress of
352 * hardware from section to section.
353 *
354 * My interpretation of that is, whenever the hw ptr is updated, it is
355 * compared with the trigger ptr, and the result is masked by the
356 * trigger mask. (Actually, by the complement of the trigger mask.)
357 * If the result is zero, an interrupt is triggered. I.e., interrupt
358 * if ((hwptr & ~mask) == (trptr & ~mask)). The mask is formed from
359 * the trigger register value as mask = (1 << (8 - tmreg)) - 1.
360 *
361 * In yet different words, setting tmreg to 0 causes an interrupt after
362 * every 256 DMA chunks (8192 bytes) or once per traversal of the
363 * ring buffer. Setting it to 7 caues an interrupt every 2 DMA chunks
364 * (64 bytes) or 128 times per traversal of the ring buffer.
365 */
366
367/* Lithium register offsets and bit definitions */
368
369#define LI_HOST_CONTROLLER 0x000
370# define LI_HC_RESET 0x00008000
371# define LI_HC_LINK_ENABLE 0x00004000
372# define LI_HC_LINK_FAILURE 0x00000004
373# define LI_HC_LINK_CODEC 0x00000002
374# define LI_HC_LINK_READY 0x00000001
375
376#define LI_INTR_STATUS 0x010
377#define LI_INTR_MASK 0x014
378# define LI_INTR_LINK_ERR 0x00008000
379# define LI_INTR_COMM2_TRIG 0x00000008
380# define LI_INTR_COMM2_UNDERFLOW 0x00000004
381# define LI_INTR_COMM1_TRIG 0x00000002
382# define LI_INTR_COMM1_OVERFLOW 0x00000001
383
384#define LI_CODEC_COMMAND 0x018
385# define LI_CC_BUSY 0x00008000
386# define LI_CC_DIR 0x00000080
387# define LI_CC_DIR_RD LI_CC_DIR
388# define LI_CC_DIR_WR (!LI_CC_DIR)
389# define LI_CC_ADDR_MASK 0x0000007F
390
391#define LI_CODEC_DATA 0x01C
392
393#define LI_COMM1_BASE 0x100
394#define LI_COMM1_CTL 0x104
395# define LI_CCTL_RESET 0x80000000
396# define LI_CCTL_SIZE 0x70000000
397# define LI_CCTL_DMA_ENABLE 0x08000000
398# define LI_CCTL_TMASK 0x07000000 /* trigger mask */
399# define LI_CCTL_TPTR 0x00FF0000 /* trigger pointer */
400# define LI_CCTL_RPTR 0x0000FF00
401# define LI_CCTL_WPTR 0x000000FF
402#define LI_COMM1_CFG 0x108
403# define LI_CCFG_LOCK 0x00008000
404# define LI_CCFG_SLOT 0x00000070
405# define LI_CCFG_DIRECTION 0x00000008
406# define LI_CCFG_DIR_IN (!LI_CCFG_DIRECTION)
407# define LI_CCFG_DIR_OUT LI_CCFG_DIRECTION
408# define LI_CCFG_MODE 0x00000004
409# define LI_CCFG_MODE_MONO (!LI_CCFG_MODE)
410# define LI_CCFG_MODE_STEREO LI_CCFG_MODE
411# define LI_CCFG_FORMAT 0x00000003
412# define LI_CCFG_FMT_8BIT 0x00000000
413# define LI_CCFG_FMT_16BIT 0x00000001
414#define LI_COMM2_BASE 0x10C
415#define LI_COMM2_CTL 0x110
416 /* bit definitions are the same as LI_COMM1_CTL */
417#define LI_COMM2_CFG 0x114
418 /* bit definitions are the same as LI_COMM1_CFG */
419
420#define LI_UST_LOW 0x200 /* 64-bit Unadjusted System Time is */
421#define LI_UST_HIGH 0x204 /* microseconds since boot */
422
423#define LI_AUDIO1_UST 0x300 /* UST-MSC pairs */
424#define LI_AUDIO1_MSC 0x304 /* MSC (Media Stream Counter) */
425#define LI_AUDIO2_UST 0x308 /* counts samples actually */
426#define LI_AUDIO2_MSC 0x30C /* processed as of time UST */
427
428/*
429 * Lithium's DMA engine operates on chunks of 32 bytes. We call that
430 * a DMACHUNK.
431 */
432
433#define DMACHUNK_SHIFT 5
434#define DMACHUNK_SIZE (1 << DMACHUNK_SHIFT)
435#define BYTES_TO_CHUNKS(bytes) ((bytes) >> DMACHUNK_SHIFT)
436#define CHUNKS_TO_BYTES(chunks) ((chunks) << DMACHUNK_SHIFT)
437
438/*
439 * Two convenient macros to shift bitfields into/out of position.
440 *
441 * Observe that (mask & -mask) is (1 << low_set_bit_of(mask)).
442 * As long as mask is constant, we trust the compiler will change the
443 * multiply and divide into shifts.
444 */
445
446#define SHIFT_FIELD(val, mask) (((val) * ((mask) & -(mask))) & (mask))
447#define UNSHIFT_FIELD(val, mask) (((val) & (mask)) / ((mask) & -(mask)))
448
449/*
450 * dma_chan_desc is invariant information about a Lithium
451 * DMA channel. There are two instances, li_comm1 and li_comm2.
452 *
453 * Note that the CCTL register fields are write ptr and read ptr, but what
454 * we care about are which pointer is updated by software and which by
455 * hardware.
456 */
457
458typedef struct dma_chan_desc {
459 int basereg;
460 int cfgreg;
461 int ctlreg;
462 int hwptrreg;
463 int swptrreg;
464 int ustreg;
465 int mscreg;
466 unsigned long swptrmask;
467 int ad1843_slot;
468 int direction; /* LI_CCTL_DIR_IN/OUT */
469} dma_chan_desc_t;
470
471static const dma_chan_desc_t li_comm1 = {
472 LI_COMM1_BASE, /* base register offset */
473 LI_COMM1_CFG, /* config register offset */
474 LI_COMM1_CTL, /* control register offset */
475 LI_COMM1_CTL + 0, /* hw ptr reg offset (write ptr) */
476 LI_COMM1_CTL + 1, /* sw ptr reg offset (read ptr) */
477 LI_AUDIO1_UST, /* ust reg offset */
478 LI_AUDIO1_MSC, /* msc reg offset */
479 LI_CCTL_RPTR, /* sw ptr bitmask in ctlval */
480 2, /* ad1843 serial slot */
481 LI_CCFG_DIR_IN /* direction */
482};
483
484static const dma_chan_desc_t li_comm2 = {
485 LI_COMM2_BASE, /* base register offset */
486 LI_COMM2_CFG, /* config register offset */
487 LI_COMM2_CTL, /* control register offset */
488 LI_COMM2_CTL + 1, /* hw ptr reg offset (read ptr) */
489 LI_COMM2_CTL + 0, /* sw ptr reg offset (writr ptr) */
490 LI_AUDIO2_UST, /* ust reg offset */
491 LI_AUDIO2_MSC, /* msc reg offset */
492 LI_CCTL_WPTR, /* sw ptr bitmask in ctlval */
493 2, /* ad1843 serial slot */
494 LI_CCFG_DIR_OUT /* direction */
495};
496
497/*
498 * dma_chan is variable information about a Lithium DMA channel.
499 *
500 * The desc field points to invariant information.
501 * The lith field points to a lithium_t which is passed
502 * to li_read* and li_write* to access the registers.
503 * The *val fields shadow the lithium registers' contents.
504 */
505
506typedef struct dma_chan {
507 const dma_chan_desc_t *desc;
508 lithium_t *lith;
509 unsigned long baseval;
510 unsigned long cfgval;
511 unsigned long ctlval;
512} dma_chan_t;
513
514/*
515 * ustmsc is a UST/MSC pair (Unadjusted System Time/Media Stream Counter).
516 * UST is time in microseconds since the system booted, and MSC is a
517 * counter that increments with every audio sample.
518 */
519
520typedef struct ustmsc {
521 unsigned long long ust;
522 unsigned long msc;
523} ustmsc_t;
524
525/*
526 * li_ad1843_wait waits until lithium says the AD1843 register
527 * exchange is not busy. Returns 0 on success, -EBUSY on timeout.
528 *
529 * Locking: must be called with lithium_lock held.
530 */
531
532static int li_ad1843_wait(lithium_t *lith)
533{
534 unsigned long later = jiffies + 2;
535 while (li_readl(lith, LI_CODEC_COMMAND) & LI_CC_BUSY)
536 if (time_after_eq(jiffies, later))
537 return -EBUSY;
538 return 0;
539}
540
541/*
542 * li_read_ad1843_reg returns the current contents of a 16 bit AD1843 register.
543 *
544 * Returns unsigned register value on success, -errno on failure.
545 */
546
547static int li_read_ad1843_reg(lithium_t *lith, int reg)
548{
549 int val;
550
551 ASSERT(!in_interrupt());
552 spin_lock(&lith->lock);
553 {
554 val = li_ad1843_wait(lith);
555 if (val == 0) {
556 li_writel(lith, LI_CODEC_COMMAND, LI_CC_DIR_RD | reg);
557 val = li_ad1843_wait(lith);
558 }
559 if (val == 0)
560 val = li_readl(lith, LI_CODEC_DATA);
561 }
562 spin_unlock(&lith->lock);
563
564 DBGXV("li_read_ad1843_reg(lith=0x%p, reg=%d) returns 0x%04x\n",
565 lith, reg, val);
566
567 return val;
568}
569
570/*
571 * li_write_ad1843_reg writes the specified value to a 16 bit AD1843 register.
572 */
573
574static void li_write_ad1843_reg(lithium_t *lith, int reg, int newval)
575{
576 spin_lock(&lith->lock);
577 {
578 if (li_ad1843_wait(lith) == 0) {
579 li_writel(lith, LI_CODEC_DATA, newval);
580 li_writel(lith, LI_CODEC_COMMAND, LI_CC_DIR_WR | reg);
581 }
582 }
583 spin_unlock(&lith->lock);
584}
585
586/*
587 * li_setup_dma calculates all the register settings for DMA in a particular
588 * mode. It takes too many arguments.
589 */
590
591static void li_setup_dma(dma_chan_t *chan,
592 const dma_chan_desc_t *desc,
593 lithium_t *lith,
594 unsigned long buffer_paddr,
595 int bufshift,
596 int fragshift,
597 int channels,
598 int sampsize)
599{
600 unsigned long mode, format;
601 unsigned long size, tmask;
602
603 DBGEV("(chan=0x%p, desc=0x%p, lith=0x%p, buffer_paddr=0x%lx, "
604 "bufshift=%d, fragshift=%d, channels=%d, sampsize=%d)\n",
605 chan, desc, lith, buffer_paddr,
606 bufshift, fragshift, channels, sampsize);
607
608 /* Reset the channel first. */
609
610 li_writel(lith, desc->ctlreg, LI_CCTL_RESET);
611
612 ASSERT(channels == 1 || channels == 2);
613 if (channels == 2)
614 mode = LI_CCFG_MODE_STEREO;
615 else
616 mode = LI_CCFG_MODE_MONO;
617 ASSERT(sampsize == 1 || sampsize == 2);
618 if (sampsize == 2)
619 format = LI_CCFG_FMT_16BIT;
620 else
621 format = LI_CCFG_FMT_8BIT;
622 chan->desc = desc;
623 chan->lith = lith;
624
625 /*
626 * Lithium DMA address register takes a 40-bit physical
627 * address, right-shifted by 8 so it fits in 32 bits. Bit 37
628 * must be set -- it enables cache coherence.
629 */
630
631 ASSERT(!(buffer_paddr & 0xFF));
632 chan->baseval = (buffer_paddr >> 8) | 1 << (37 - 8);
633
634 chan->cfgval = ((chan->cfgval & ~LI_CCFG_LOCK) |
635 SHIFT_FIELD(desc->ad1843_slot, LI_CCFG_SLOT) |
636 desc->direction |
637 mode |
638 format);
639
640 size = bufshift - 6;
641 tmask = 13 - fragshift; /* See Lithium DMA Notes above. */
642 ASSERT(size >= 2 && size <= 7);
643 ASSERT(tmask >= 1 && tmask <= 7);
644 chan->ctlval = ((chan->ctlval & ~LI_CCTL_RESET) |
645 SHIFT_FIELD(size, LI_CCTL_SIZE) |
646 (chan->ctlval & ~LI_CCTL_DMA_ENABLE) |
647 SHIFT_FIELD(tmask, LI_CCTL_TMASK) |
648 SHIFT_FIELD(0, LI_CCTL_TPTR));
649
650 DBGPV("basereg 0x%x = 0x%lx\n", desc->basereg, chan->baseval);
651 DBGPV("cfgreg 0x%x = 0x%lx\n", desc->cfgreg, chan->cfgval);
652 DBGPV("ctlreg 0x%x = 0x%lx\n", desc->ctlreg, chan->ctlval);
653
654 li_writel(lith, desc->basereg, chan->baseval);
655 li_writel(lith, desc->cfgreg, chan->cfgval);
656 li_writel(lith, desc->ctlreg, chan->ctlval);
657
658 DBGRV();
659}
660
661static void li_shutdown_dma(dma_chan_t *chan)
662{
663 lithium_t *lith = chan->lith;
664 void * lith1 = lith->page1;
665
666 DBGEV("(chan=0x%p)\n", chan);
667
668 chan->ctlval &= ~LI_CCTL_DMA_ENABLE;
669 DBGPV("ctlreg 0x%x = 0x%lx\n", chan->desc->ctlreg, chan->ctlval);
670 li_writel(lith, chan->desc->ctlreg, chan->ctlval);
671
672 /*
673 * Offset 0x500 on Lithium page 1 is an undocumented,
674 * unsupported register that holds the zero sample value.
675 * Lithium is supposed to output zero samples when DMA is
676 * inactive, and repeat the last sample when DMA underflows.
677 * But it has a bug, where, after underflow occurs, the zero
678 * sample is not reset.
679 *
680 * I expect this to break in a future rev of Lithium.
681 */
682
683 if (lith1 && chan->desc->direction == LI_CCFG_DIR_OUT)
684 * (volatile unsigned long *) (lith1 + 0x500) = 0;
685}
686
687/*
688 * li_activate_dma always starts dma at the beginning of the buffer.
689 *
690 * N.B., these may be called from interrupt.
691 */
692
693static __inline__ void li_activate_dma(dma_chan_t *chan)
694{
695 chan->ctlval |= LI_CCTL_DMA_ENABLE;
696 DBGPV("ctlval = 0x%lx\n", chan->ctlval);
697 li_writel(chan->lith, chan->desc->ctlreg, chan->ctlval);
698}
699
700static void li_deactivate_dma(dma_chan_t *chan)
701{
702 lithium_t *lith = chan->lith;
703 void * lith2 = lith->page2;
704
705 chan->ctlval &= ~(LI_CCTL_DMA_ENABLE | LI_CCTL_RPTR | LI_CCTL_WPTR);
706 DBGPV("ctlval = 0x%lx\n", chan->ctlval);
707 DBGPV("ctlreg 0x%x = 0x%lx\n", chan->desc->ctlreg, chan->ctlval);
708 li_writel(lith, chan->desc->ctlreg, chan->ctlval);
709
710 /*
711 * Offsets 0x98 and 0x9C on Lithium page 2 are undocumented,
712 * unsupported registers that are internal copies of the DMA
713 * read and write pointers. Because of a Lithium bug, these
714 * registers aren't zeroed correctly when DMA is shut off. So
715 * we whack them directly.
716 *
717 * I expect this to break in a future rev of Lithium.
718 */
719
720 if (lith2 && chan->desc->direction == LI_CCFG_DIR_OUT) {
721 * (volatile unsigned long *) (lith2 + 0x98) = 0;
722 * (volatile unsigned long *) (lith2 + 0x9C) = 0;
723 }
724}
725
726/*
727 * read/write the ring buffer pointers. These routines' arguments and results
728 * are byte offsets from the beginning of the ring buffer.
729 */
730
731static __inline__ int li_read_swptr(dma_chan_t *chan)
732{
733 const unsigned long mask = chan->desc->swptrmask;
734
735 return CHUNKS_TO_BYTES(UNSHIFT_FIELD(chan->ctlval, mask));
736}
737
738static __inline__ int li_read_hwptr(dma_chan_t *chan)
739{
740 return CHUNKS_TO_BYTES(li_readb(chan->lith, chan->desc->hwptrreg));
741}
742
743static __inline__ void li_write_swptr(dma_chan_t *chan, int val)
744{
745 const unsigned long mask = chan->desc->swptrmask;
746
747 ASSERT(!(val & ~CHUNKS_TO_BYTES(0xFF)));
748 val = BYTES_TO_CHUNKS(val);
749 chan->ctlval = (chan->ctlval & ~mask) | SHIFT_FIELD(val, mask);
750 li_writeb(chan->lith, chan->desc->swptrreg, val);
751}
752
753/* li_read_USTMSC() returns a UST/MSC pair for the given channel. */
754
755static void li_read_USTMSC(dma_chan_t *chan, ustmsc_t *ustmsc)
756{
757 lithium_t *lith = chan->lith;
758 const dma_chan_desc_t *desc = chan->desc;
759 unsigned long now_low, now_high0, now_high1, chan_ust;
760
761 spin_lock(&lith->lock);
762 {
763 /*
764 * retry until we do all five reads without the
765 * high word changing. (High word increments
766 * every 2^32 microseconds, i.e., not often)
767 */
768 do {
769 now_high0 = li_readl(lith, LI_UST_HIGH);
770 now_low = li_readl(lith, LI_UST_LOW);
771
772 /*
773 * Lithium guarantees these two reads will be
774 * atomic -- ust will not increment after msc
775 * is read.
776 */
777
778 ustmsc->msc = li_readl(lith, desc->mscreg);
779 chan_ust = li_readl(lith, desc->ustreg);
780
781 now_high1 = li_readl(lith, LI_UST_HIGH);
782 } while (now_high0 != now_high1);
783 }
784 spin_unlock(&lith->lock);
785 ustmsc->ust = ((unsigned long long) now_high0 << 32 | chan_ust);
786}
787
788static void li_enable_interrupts(lithium_t *lith, unsigned int mask)
789{
790 DBGEV("(lith=0x%p, mask=0x%x)\n", lith, mask);
791
792 /* clear any already-pending interrupts. */
793
794 li_writel(lith, LI_INTR_STATUS, mask);
795
796 /* enable the interrupts. */
797
798 mask |= li_readl(lith, LI_INTR_MASK);
799 li_writel(lith, LI_INTR_MASK, mask);
800}
801
802static void li_disable_interrupts(lithium_t *lith, unsigned int mask)
803{
804 unsigned int keepmask;
805
806 DBGEV("(lith=0x%p, mask=0x%x)\n", lith, mask);
807
808 /* disable the interrupts */
809
810 keepmask = li_readl(lith, LI_INTR_MASK) & ~mask;
811 li_writel(lith, LI_INTR_MASK, keepmask);
812
813 /* clear any pending interrupts. */
814
815 li_writel(lith, LI_INTR_STATUS, mask);
816}
817
818/* Get the interrupt status and clear all pending interrupts. */
819
820static unsigned int li_get_clear_intr_status(lithium_t *lith)
821{
822 unsigned int status;
823
824 status = li_readl(lith, LI_INTR_STATUS);
825 li_writel(lith, LI_INTR_STATUS, ~0);
826 return status & li_readl(lith, LI_INTR_MASK);
827}
828
829static int li_init(lithium_t *lith)
830{
831 /* 1. System power supplies stabilize. */
832
833 /* 2. Assert the ~RESET signal. */
834
835 li_writel(lith, LI_HOST_CONTROLLER, LI_HC_RESET);
836 udelay(1);
837
838 /* 3. Deassert the ~RESET signal and enter a wait period to allow
839 the AD1843 internal clocks and the external crystal oscillator
840 to stabilize. */
841
842 li_writel(lith, LI_HOST_CONTROLLER, LI_HC_LINK_ENABLE);
843 udelay(1);
844
845 return 0;
846}
847
848/*****************************************************************************/
849/* AD1843 access */
850
851/*
852 * AD1843 bitfield definitions. All are named as in the AD1843 data
853 * sheet, with ad1843_ prepended and individual bit numbers removed.
854 *
855 * E.g., bits LSS0 through LSS2 become ad1843_LSS.
856 *
857 * Only the bitfields we need are defined.
858 */
859
860typedef struct ad1843_bitfield {
861 char reg;
862 char lo_bit;
863 char nbits;
864} ad1843_bitfield_t;
865
866static const ad1843_bitfield_t
867 ad1843_PDNO = { 0, 14, 1 }, /* Converter Power-Down Flag */
868 ad1843_INIT = { 0, 15, 1 }, /* Clock Initialization Flag */
869 ad1843_RIG = { 2, 0, 4 }, /* Right ADC Input Gain */
870 ad1843_RMGE = { 2, 4, 1 }, /* Right ADC Mic Gain Enable */
871 ad1843_RSS = { 2, 5, 3 }, /* Right ADC Source Select */
872 ad1843_LIG = { 2, 8, 4 }, /* Left ADC Input Gain */
873 ad1843_LMGE = { 2, 12, 1 }, /* Left ADC Mic Gain Enable */
874 ad1843_LSS = { 2, 13, 3 }, /* Left ADC Source Select */
875 ad1843_RX1M = { 4, 0, 5 }, /* Right Aux 1 Mix Gain/Atten */
876 ad1843_RX1MM = { 4, 7, 1 }, /* Right Aux 1 Mix Mute */
877 ad1843_LX1M = { 4, 8, 5 }, /* Left Aux 1 Mix Gain/Atten */
878 ad1843_LX1MM = { 4, 15, 1 }, /* Left Aux 1 Mix Mute */
879 ad1843_RX2M = { 5, 0, 5 }, /* Right Aux 2 Mix Gain/Atten */
880 ad1843_RX2MM = { 5, 7, 1 }, /* Right Aux 2 Mix Mute */
881 ad1843_LX2M = { 5, 8, 5 }, /* Left Aux 2 Mix Gain/Atten */
882 ad1843_LX2MM = { 5, 15, 1 }, /* Left Aux 2 Mix Mute */
883 ad1843_RMCM = { 7, 0, 5 }, /* Right Mic Mix Gain/Atten */
884 ad1843_RMCMM = { 7, 7, 1 }, /* Right Mic Mix Mute */
885 ad1843_LMCM = { 7, 8, 5 }, /* Left Mic Mix Gain/Atten */
886 ad1843_LMCMM = { 7, 15, 1 }, /* Left Mic Mix Mute */
887 ad1843_HPOS = { 8, 4, 1 }, /* Headphone Output Voltage Swing */
888 ad1843_HPOM = { 8, 5, 1 }, /* Headphone Output Mute */
889 ad1843_RDA1G = { 9, 0, 6 }, /* Right DAC1 Analog/Digital Gain */
890 ad1843_RDA1GM = { 9, 7, 1 }, /* Right DAC1 Analog Mute */
891 ad1843_LDA1G = { 9, 8, 6 }, /* Left DAC1 Analog/Digital Gain */
892 ad1843_LDA1GM = { 9, 15, 1 }, /* Left DAC1 Analog Mute */
893 ad1843_RDA1AM = { 11, 7, 1 }, /* Right DAC1 Digital Mute */
894 ad1843_LDA1AM = { 11, 15, 1 }, /* Left DAC1 Digital Mute */
895 ad1843_ADLC = { 15, 0, 2 }, /* ADC Left Sample Rate Source */
896 ad1843_ADRC = { 15, 2, 2 }, /* ADC Right Sample Rate Source */
897 ad1843_DA1C = { 15, 8, 2 }, /* DAC1 Sample Rate Source */
898 ad1843_C1C = { 17, 0, 16 }, /* Clock 1 Sample Rate Select */
899 ad1843_C2C = { 20, 0, 16 }, /* Clock 1 Sample Rate Select */
900 ad1843_DAADL = { 25, 4, 2 }, /* Digital ADC Left Source Select */
901 ad1843_DAADR = { 25, 6, 2 }, /* Digital ADC Right Source Select */
902 ad1843_DRSFLT = { 25, 15, 1 }, /* Digital Reampler Filter Mode */
903 ad1843_ADLF = { 26, 0, 2 }, /* ADC Left Channel Data Format */
904 ad1843_ADRF = { 26, 2, 2 }, /* ADC Right Channel Data Format */
905 ad1843_ADTLK = { 26, 4, 1 }, /* ADC Transmit Lock Mode Select */
906 ad1843_SCF = { 26, 7, 1 }, /* SCLK Frequency Select */
907 ad1843_DA1F = { 26, 8, 2 }, /* DAC1 Data Format Select */
908 ad1843_DA1SM = { 26, 14, 1 }, /* DAC1 Stereo/Mono Mode Select */
909 ad1843_ADLEN = { 27, 0, 1 }, /* ADC Left Channel Enable */
910 ad1843_ADREN = { 27, 1, 1 }, /* ADC Right Channel Enable */
911 ad1843_AAMEN = { 27, 4, 1 }, /* Analog to Analog Mix Enable */
912 ad1843_ANAEN = { 27, 7, 1 }, /* Analog Channel Enable */
913 ad1843_DA1EN = { 27, 8, 1 }, /* DAC1 Enable */
914 ad1843_DA2EN = { 27, 9, 1 }, /* DAC2 Enable */
915 ad1843_C1EN = { 28, 11, 1 }, /* Clock Generator 1 Enable */
916 ad1843_C2EN = { 28, 12, 1 }, /* Clock Generator 2 Enable */
917 ad1843_PDNI = { 28, 15, 1 }; /* Converter Power Down */
918
919/*
920 * The various registers of the AD1843 use three different formats for
921 * specifying gain. The ad1843_gain structure parameterizes the
922 * formats.
923 */
924
925typedef struct ad1843_gain {
926
927 int negative; /* nonzero if gain is negative. */
928 const ad1843_bitfield_t *lfield;
929 const ad1843_bitfield_t *rfield;
930
931} ad1843_gain_t;
932
933static const ad1843_gain_t ad1843_gain_RECLEV
934 = { 0, &ad1843_LIG, &ad1843_RIG };
935static const ad1843_gain_t ad1843_gain_LINE
936 = { 1, &ad1843_LX1M, &ad1843_RX1M };
937static const ad1843_gain_t ad1843_gain_CD
938 = { 1, &ad1843_LX2M, &ad1843_RX2M };
939static const ad1843_gain_t ad1843_gain_MIC
940 = { 1, &ad1843_LMCM, &ad1843_RMCM };
941static const ad1843_gain_t ad1843_gain_PCM
942 = { 1, &ad1843_LDA1G, &ad1843_RDA1G };
943
944/* read the current value of an AD1843 bitfield. */
945
946static int ad1843_read_bits(lithium_t *lith, const ad1843_bitfield_t *field)
947{
948 int w = li_read_ad1843_reg(lith, field->reg);
949 int val = w >> field->lo_bit & ((1 << field->nbits) - 1);
950
951 DBGXV("ad1843_read_bits(lith=0x%p, field->{%d %d %d}) returns 0x%x\n",
952 lith, field->reg, field->lo_bit, field->nbits, val);
953
954 return val;
955}
956
957/*
958 * write a new value to an AD1843 bitfield and return the old value.
959 */
960
961static int ad1843_write_bits(lithium_t *lith,
962 const ad1843_bitfield_t *field,
963 int newval)
964{
965 int w = li_read_ad1843_reg(lith, field->reg);
966 int mask = ((1 << field->nbits) - 1) << field->lo_bit;
967 int oldval = (w & mask) >> field->lo_bit;
968 int newbits = (newval << field->lo_bit) & mask;
969 w = (w & ~mask) | newbits;
970 (void) li_write_ad1843_reg(lith, field->reg, w);
971
972 DBGXV("ad1843_write_bits(lith=0x%p, field->{%d %d %d}, val=0x%x) "
973 "returns 0x%x\n",
974 lith, field->reg, field->lo_bit, field->nbits, newval,
975 oldval);
976
977 return oldval;
978}
979
980/*
981 * ad1843_read_multi reads multiple bitfields from the same AD1843
982 * register. It uses a single read cycle to do it. (Reading the
983 * ad1843 requires 256 bit times at 12.288 MHz, or nearly 20
984 * microseconds.)
985 *
986 * Called ike this.
987 *
988 * ad1843_read_multi(lith, nfields,
989 * &ad1843_FIELD1, &val1,
990 * &ad1843_FIELD2, &val2, ...);
991 */
992
993static void ad1843_read_multi(lithium_t *lith, int argcount, ...)
994{
995 va_list ap;
996 const ad1843_bitfield_t *fp;
997 int w = 0, mask, *value, reg = -1;
998
999 va_start(ap, argcount);
1000 while (--argcount >= 0) {
1001 fp = va_arg(ap, const ad1843_bitfield_t *);
1002 value = va_arg(ap, int *);
1003 if (reg == -1) {
1004 reg = fp->reg;
1005 w = li_read_ad1843_reg(lith, reg);
1006 }
1007 ASSERT(reg == fp->reg);
1008 mask = (1 << fp->nbits) - 1;
1009 *value = w >> fp->lo_bit & mask;
1010 }
1011 va_end(ap);
1012}
1013
1014/*
1015 * ad1843_write_multi stores multiple bitfields into the same AD1843
1016 * register. It uses one read and one write cycle to do it.
1017 *
1018 * Called like this.
1019 *
1020 * ad1843_write_multi(lith, nfields,
1021 * &ad1843_FIELD1, val1,
1022 * &ad1843_FIELF2, val2, ...);
1023 */
1024
1025static void ad1843_write_multi(lithium_t *lith, int argcount, ...)
1026{
1027 va_list ap;
1028 int reg;
1029 const ad1843_bitfield_t *fp;
1030 int value;
1031 int w, m, mask, bits;
1032
1033 mask = 0;
1034 bits = 0;
1035 reg = -1;
1036
1037 va_start(ap, argcount);
1038 while (--argcount >= 0) {
1039 fp = va_arg(ap, const ad1843_bitfield_t *);
1040 value = va_arg(ap, int);
1041 if (reg == -1)
1042 reg = fp->reg;
1043 ASSERT(fp->reg == reg);
1044 m = ((1 << fp->nbits) - 1) << fp->lo_bit;
1045 mask |= m;
1046 bits |= (value << fp->lo_bit) & m;
1047 }
1048 va_end(ap);
1049 ASSERT(!(bits & ~mask));
1050 if (~mask & 0xFFFF)
1051 w = li_read_ad1843_reg(lith, reg);
1052 else
1053 w = 0;
1054 w = (w & ~mask) | bits;
1055 (void) li_write_ad1843_reg(lith, reg, w);
1056}
1057
1058/*
1059 * ad1843_get_gain reads the specified register and extracts the gain value
1060 * using the supplied gain type. It returns the gain in OSS format.
1061 */
1062
1063static int ad1843_get_gain(lithium_t *lith, const ad1843_gain_t *gp)
1064{
1065 int lg, rg;
1066 unsigned short mask = (1 << gp->lfield->nbits) - 1;
1067
1068 ad1843_read_multi(lith, 2, gp->lfield, &lg, gp->rfield, &rg);
1069 if (gp->negative) {
1070 lg = mask - lg;
1071 rg = mask - rg;
1072 }
1073 lg = (lg * 100 + (mask >> 1)) / mask;
1074 rg = (rg * 100 + (mask >> 1)) / mask;
1075 return lg << 0 | rg << 8;
1076}
1077
1078/*
1079 * Set an audio channel's gain. Converts from OSS format to AD1843's
1080 * format.
1081 *
1082 * Returns the new gain, which may be lower than the old gain.
1083 */
1084
1085static int ad1843_set_gain(lithium_t *lith,
1086 const ad1843_gain_t *gp,
1087 int newval)
1088{
1089 unsigned short mask = (1 << gp->lfield->nbits) - 1;
1090
1091 int lg = newval >> 0 & 0xFF;
1092 int rg = newval >> 8;
1093 if (lg < 0 || lg > 100 || rg < 0 || rg > 100)
1094 return -EINVAL;
1095 lg = (lg * mask + (mask >> 1)) / 100;
1096 rg = (rg * mask + (mask >> 1)) / 100;
1097 if (gp->negative) {
1098 lg = mask - lg;
1099 rg = mask - rg;
1100 }
1101 ad1843_write_multi(lith, 2, gp->lfield, lg, gp->rfield, rg);
1102 return ad1843_get_gain(lith, gp);
1103}
1104
1105/* Returns the current recording source, in OSS format. */
1106
1107static int ad1843_get_recsrc(lithium_t *lith)
1108{
1109 int ls = ad1843_read_bits(lith, &ad1843_LSS);
1110
1111 switch (ls) {
1112 case 1:
1113 return SOUND_MASK_MIC;
1114 case 2:
1115 return SOUND_MASK_LINE;
1116 case 3:
1117 return SOUND_MASK_CD;
1118 case 6:
1119 return SOUND_MASK_PCM;
1120 default:
1121 ASSERT(0);
1122 return -1;
1123 }
1124}
1125
1126/*
1127 * Enable/disable digital resample mode in the AD1843.
1128 *
1129 * The AD1843 requires that ADL, ADR, DA1 and DA2 be powered down
1130 * while switching modes. So we save DA1's state (DA2's state is not
1131 * interesting), power them down, switch into/out of resample mode,
1132 * power them up, and restore state.
1133 *
1134 * This will cause audible glitches if D/A or A/D is going on, so the
1135 * driver disallows that (in mixer_write_ioctl()).
1136 *
1137 * The open question is, is this worth doing? I'm leaving it in,
1138 * because it's written, but...
1139 */
1140
1141static void ad1843_set_resample_mode(lithium_t *lith, int onoff)
1142{
1143 /* Save DA1 mute and gain (addr 9 is DA1 analog gain/attenuation) */
1144 int save_da1 = li_read_ad1843_reg(lith, 9);
1145
1146 /* Power down A/D and D/A. */
1147 ad1843_write_multi(lith, 4,
1148 &ad1843_DA1EN, 0,
1149 &ad1843_DA2EN, 0,
1150 &ad1843_ADLEN, 0,
1151 &ad1843_ADREN, 0);
1152
1153 /* Switch mode */
1154 ASSERT(onoff == 0 || onoff == 1);
1155 ad1843_write_bits(lith, &ad1843_DRSFLT, onoff);
1156
1157 /* Power up A/D and D/A. */
1158 ad1843_write_multi(lith, 3,
1159 &ad1843_DA1EN, 1,
1160 &ad1843_ADLEN, 1,
1161 &ad1843_ADREN, 1);
1162
1163 /* Restore DA1 mute and gain. */
1164 li_write_ad1843_reg(lith, 9, save_da1);
1165}
1166
1167/*
1168 * Set recording source. Arg newsrc specifies an OSS channel mask.
1169 *
1170 * The complication is that when we switch into/out of loopback mode
1171 * (i.e., src = SOUND_MASK_PCM), we change the AD1843 into/out of
1172 * digital resampling mode.
1173 *
1174 * Returns newsrc on success, -errno on failure.
1175 */
1176
1177static int ad1843_set_recsrc(lithium_t *lith, int newsrc)
1178{
1179 int bits;
1180 int oldbits;
1181
1182 switch (newsrc) {
1183 case SOUND_MASK_PCM:
1184 bits = 6;
1185 break;
1186
1187 case SOUND_MASK_MIC:
1188 bits = 1;
1189 break;
1190
1191 case SOUND_MASK_LINE:
1192 bits = 2;
1193 break;
1194
1195 case SOUND_MASK_CD:
1196 bits = 3;
1197 break;
1198
1199 default:
1200 return -EINVAL;
1201 }
1202 oldbits = ad1843_read_bits(lith, &ad1843_LSS);
1203 if (newsrc == SOUND_MASK_PCM && oldbits != 6) {
1204 DBGP("enabling digital resample mode\n");
1205 ad1843_set_resample_mode(lith, 1);
1206 ad1843_write_multi(lith, 2,
1207 &ad1843_DAADL, 2,
1208 &ad1843_DAADR, 2);
1209 } else if (newsrc != SOUND_MASK_PCM && oldbits == 6) {
1210 DBGP("disabling digital resample mode\n");
1211 ad1843_set_resample_mode(lith, 0);
1212 ad1843_write_multi(lith, 2,
1213 &ad1843_DAADL, 0,
1214 &ad1843_DAADR, 0);
1215 }
1216 ad1843_write_multi(lith, 2, &ad1843_LSS, bits, &ad1843_RSS, bits);
1217 return newsrc;
1218}
1219
1220/*
1221 * Return current output sources, in OSS format.
1222 */
1223
1224static int ad1843_get_outsrc(lithium_t *lith)
1225{
1226 int pcm, line, mic, cd;
1227
1228 pcm = ad1843_read_bits(lith, &ad1843_LDA1GM) ? 0 : SOUND_MASK_PCM;
1229 line = ad1843_read_bits(lith, &ad1843_LX1MM) ? 0 : SOUND_MASK_LINE;
1230 cd = ad1843_read_bits(lith, &ad1843_LX2MM) ? 0 : SOUND_MASK_CD;
1231 mic = ad1843_read_bits(lith, &ad1843_LMCMM) ? 0 : SOUND_MASK_MIC;
1232
1233 return pcm | line | cd | mic;
1234}
1235
1236/*
1237 * Set output sources. Arg is a mask of active sources in OSS format.
1238 *
1239 * Returns source mask on success, -errno on failure.
1240 */
1241
1242static int ad1843_set_outsrc(lithium_t *lith, int mask)
1243{
1244 int pcm, line, mic, cd;
1245
1246 if (mask & ~(SOUND_MASK_PCM | SOUND_MASK_LINE |
1247 SOUND_MASK_CD | SOUND_MASK_MIC))
1248 return -EINVAL;
1249 pcm = (mask & SOUND_MASK_PCM) ? 0 : 1;
1250 line = (mask & SOUND_MASK_LINE) ? 0 : 1;
1251 mic = (mask & SOUND_MASK_MIC) ? 0 : 1;
1252 cd = (mask & SOUND_MASK_CD) ? 0 : 1;
1253
1254 ad1843_write_multi(lith, 2, &ad1843_LDA1GM, pcm, &ad1843_RDA1GM, pcm);
1255 ad1843_write_multi(lith, 2, &ad1843_LX1MM, line, &ad1843_RX1MM, line);
1256 ad1843_write_multi(lith, 2, &ad1843_LX2MM, cd, &ad1843_RX2MM, cd);
1257 ad1843_write_multi(lith, 2, &ad1843_LMCMM, mic, &ad1843_RMCMM, mic);
1258
1259 return mask;
1260}
1261
1262/* Setup ad1843 for D/A conversion. */
1263
1264static void ad1843_setup_dac(lithium_t *lith,
1265 int framerate,
1266 int fmt,
1267 int channels)
1268{
1269 int ad_fmt = 0, ad_mode = 0;
1270
1271 DBGEV("(lith=0x%p, framerate=%d, fmt=%d, channels=%d)\n",
1272 lith, framerate, fmt, channels);
1273
1274 switch (fmt) {
1275 case AFMT_S8: ad_fmt = 1; break;
1276 case AFMT_U8: ad_fmt = 1; break;
1277 case AFMT_S16_LE: ad_fmt = 1; break;
1278 case AFMT_MU_LAW: ad_fmt = 2; break;
1279 case AFMT_A_LAW: ad_fmt = 3; break;
1280 default: ASSERT(0);
1281 }
1282
1283 switch (channels) {
1284 case 2: ad_mode = 0; break;
1285 case 1: ad_mode = 1; break;
1286 default: ASSERT(0);
1287 }
1288
1289 DBGPV("ad_mode = %d, ad_fmt = %d\n", ad_mode, ad_fmt);
1290 ASSERT(framerate >= 4000 && framerate <= 49000);
1291 ad1843_write_bits(lith, &ad1843_C1C, framerate);
1292 ad1843_write_multi(lith, 2,
1293 &ad1843_DA1SM, ad_mode, &ad1843_DA1F, ad_fmt);
1294}
1295
1296static void ad1843_shutdown_dac(lithium_t *lith)
1297{
1298 ad1843_write_bits(lith, &ad1843_DA1F, 1);
1299}
1300
1301static void ad1843_setup_adc(lithium_t *lith, int framerate, int fmt, int channels)
1302{
1303 int da_fmt = 0;
1304
1305 DBGEV("(lith=0x%p, framerate=%d, fmt=%d, channels=%d)\n",
1306 lith, framerate, fmt, channels);
1307
1308 switch (fmt) {
1309 case AFMT_S8: da_fmt = 1; break;
1310 case AFMT_U8: da_fmt = 1; break;
1311 case AFMT_S16_LE: da_fmt = 1; break;
1312 case AFMT_MU_LAW: da_fmt = 2; break;
1313 case AFMT_A_LAW: da_fmt = 3; break;
1314 default: ASSERT(0);
1315 }
1316
1317 DBGPV("da_fmt = %d\n", da_fmt);
1318 ASSERT(framerate >= 4000 && framerate <= 49000);
1319 ad1843_write_bits(lith, &ad1843_C2C, framerate);
1320 ad1843_write_multi(lith, 2,
1321 &ad1843_ADLF, da_fmt, &ad1843_ADRF, da_fmt);
1322}
1323
1324static void ad1843_shutdown_adc(lithium_t *lith)
1325{
1326 /* nothing to do */
1327}
1328
1329/*
1330 * Fully initialize the ad1843. As described in the AD1843 data
1331 * sheet, section "START-UP SEQUENCE". The numbered comments are
1332 * subsection headings from the data sheet. See the data sheet, pages
1333 * 52-54, for more info.
1334 *
1335 * return 0 on success, -errno on failure. */
1336
1337static int __init ad1843_init(lithium_t *lith)
1338{
1339 unsigned long later;
1340 int err;
1341
1342 err = li_init(lith);
1343 if (err)
1344 return err;
1345
1346 if (ad1843_read_bits(lith, &ad1843_INIT) != 0) {
1347 printk(KERN_ERR "vwsnd sound: AD1843 won't initialize\n");
1348 return -EIO;
1349 }
1350
1351 ad1843_write_bits(lith, &ad1843_SCF, 1);
1352
1353 /* 4. Put the conversion resources into standby. */
1354
1355 ad1843_write_bits(lith, &ad1843_PDNI, 0);
1356 later = jiffies + HZ / 2; /* roughly half a second */
1357 DBGDO(shut_up++);
1358 while (ad1843_read_bits(lith, &ad1843_PDNO)) {
1359 if (time_after(jiffies, later)) {
1360 printk(KERN_ERR
1361 "vwsnd audio: AD1843 won't power up\n");
1362 return -EIO;
1363 }
1364 schedule();
1365 }
1366 DBGDO(shut_up--);
1367
1368 /* 5. Power up the clock generators and enable clock output pins. */
1369
1370 ad1843_write_multi(lith, 2, &ad1843_C1EN, 1, &ad1843_C2EN, 1);
1371
1372 /* 6. Configure conversion resources while they are in standby. */
1373
1374 /* DAC1 uses clock 1 as source, ADC uses clock 2. Always. */
1375
1376 ad1843_write_multi(lith, 3,
1377 &ad1843_DA1C, 1,
1378 &ad1843_ADLC, 2,
1379 &ad1843_ADRC, 2);
1380
1381 /* 7. Enable conversion resources. */
1382
1383 ad1843_write_bits(lith, &ad1843_ADTLK, 1);
1384 ad1843_write_multi(lith, 5,
1385 &ad1843_ANAEN, 1,
1386 &ad1843_AAMEN, 1,
1387 &ad1843_DA1EN, 1,
1388 &ad1843_ADLEN, 1,
1389 &ad1843_ADREN, 1);
1390
1391 /* 8. Configure conversion resources while they are enabled. */
1392
1393 ad1843_write_bits(lith, &ad1843_DA1C, 1);
1394
1395 /* Unmute all channels. */
1396
1397 ad1843_set_outsrc(lith,
1398 (SOUND_MASK_PCM | SOUND_MASK_LINE |
1399 SOUND_MASK_MIC | SOUND_MASK_CD));
1400 ad1843_write_multi(lith, 2, &ad1843_LDA1AM, 0, &ad1843_RDA1AM, 0);
1401
1402 /* Set default recording source to Line In and set
1403 * mic gain to +20 dB.
1404 */
1405
1406 ad1843_set_recsrc(lith, SOUND_MASK_LINE);
1407 ad1843_write_multi(lith, 2, &ad1843_LMGE, 1, &ad1843_RMGE, 1);
1408
1409 /* Set Speaker Out level to +/- 4V and unmute it. */
1410
1411 ad1843_write_multi(lith, 2, &ad1843_HPOS, 1, &ad1843_HPOM, 0);
1412
1413 return 0;
1414}
1415
1416/*****************************************************************************/
1417/* PCM I/O */
1418
1419#define READ_INTR_MASK (LI_INTR_COMM1_TRIG | LI_INTR_COMM1_OVERFLOW)
1420#define WRITE_INTR_MASK (LI_INTR_COMM2_TRIG | LI_INTR_COMM2_UNDERFLOW)
1421
1422typedef enum vwsnd_port_swstate { /* software state */
1423 SW_OFF,
1424 SW_INITIAL,
1425 SW_RUN,
1426 SW_DRAIN,
1427} vwsnd_port_swstate_t;
1428
1429typedef enum vwsnd_port_hwstate { /* hardware state */
1430 HW_STOPPED,
1431 HW_RUNNING,
1432} vwsnd_port_hwstate_t;
1433
1434/*
1435 * These flags are read by ISR, but only written at baseline.
1436 */
1437
1438typedef enum vwsnd_port_flags {
1439 DISABLED = 1 << 0,
1440 ERFLOWN = 1 << 1, /* overflown or underflown */
1441 HW_BUSY = 1 << 2,
1442} vwsnd_port_flags_t;
1443
1444/*
1445 * vwsnd_port is the per-port data structure. Each device has two
1446 * ports, one for input and one for output.
1447 *
1448 * Locking:
1449 *
1450 * port->lock protects: hwstate, flags, swb_[iu]_avail.
1451 *
1452 * devc->io_mutex protects: swstate, sw_*, swb_[iu]_idx.
1453 *
1454 * everything else is only written by open/release or
1455 * pcm_{setup,shutdown}(), which are serialized by a
1456 * combination of devc->open_mutex and devc->io_mutex.
1457 */
1458
1459typedef struct vwsnd_port {
1460
1461 spinlock_t lock;
1462 wait_queue_head_t queue;
1463 vwsnd_port_swstate_t swstate;
1464 vwsnd_port_hwstate_t hwstate;
1465 vwsnd_port_flags_t flags;
1466
1467 int sw_channels;
1468 int sw_samplefmt;
1469 int sw_framerate;
1470 int sample_size;
1471 int frame_size;
1472 unsigned int zero_word; /* zero for the sample format */
1473
1474 int sw_fragshift;
1475 int sw_fragcount;
1476 int sw_subdivshift;
1477
1478 unsigned int hw_fragshift;
1479 unsigned int hw_fragsize;
1480 unsigned int hw_fragcount;
1481
1482 int hwbuf_size;
1483 unsigned long hwbuf_paddr;
1484 unsigned long hwbuf_vaddr;
1485 void * hwbuf; /* hwbuf == hwbuf_vaddr */
1486 int hwbuf_max; /* max bytes to preload */
1487
1488 void * swbuf;
1489 unsigned int swbuf_size; /* size in bytes */
1490 unsigned int swb_u_idx; /* index of next user byte */
1491 unsigned int swb_i_idx; /* index of next intr byte */
1492 unsigned int swb_u_avail; /* # bytes avail to user */
1493 unsigned int swb_i_avail; /* # bytes avail to intr */
1494
1495 dma_chan_t chan;
1496
1497 /* Accounting */
1498
1499 int byte_count;
1500 int frag_count;
1501 int MSC_offset;
1502
1503} vwsnd_port_t;
1504
1505/* vwsnd_dev is the per-device data structure. */
1506
1507typedef struct vwsnd_dev {
1508 struct vwsnd_dev *next_dev;
1509 int audio_minor; /* minor number of audio device */
1510 int mixer_minor; /* minor number of mixer device */
1511
1512 struct mutex open_mutex;
1513 struct mutex io_mutex;
1514 struct mutex mix_mutex;
1515 fmode_t open_mode;
1516 wait_queue_head_t open_wait;
1517
1518 lithium_t lith;
1519
1520 vwsnd_port_t rport;
1521 vwsnd_port_t wport;
1522} vwsnd_dev_t;
1523
1524static vwsnd_dev_t *vwsnd_dev_list; /* linked list of all devices */
1525
1526static atomic_t vwsnd_use_count = ATOMIC_INIT(0);
1527
1528# define INC_USE_COUNT (atomic_inc(&vwsnd_use_count))
1529# define DEC_USE_COUNT (atomic_dec(&vwsnd_use_count))
1530# define IN_USE (atomic_read(&vwsnd_use_count) != 0)
1531
1532/*
1533 * Lithium can only DMA multiples of 32 bytes. Its DMA buffer may
1534 * be up to 8 Kb. This driver always uses 8 Kb.
1535 *
1536 * Memory bug workaround -- I'm not sure what's going on here, but
1537 * somehow pcm_copy_out() was triggering segv's going on to the next
1538 * page of the hw buffer. So, I make the hw buffer one size bigger
1539 * than we actually use. That way, the following page is allocated
1540 * and mapped, and no error. I suspect that something is broken
1541 * in Cobalt, but haven't really investigated. HBO is the actual
1542 * size of the buffer, and HWBUF_ORDER is what we allocate.
1543 */
1544
1545#define HWBUF_SHIFT 13
1546#define HWBUF_SIZE (1 << HWBUF_SHIFT)
1547# define HBO (HWBUF_SHIFT > PAGE_SHIFT ? HWBUF_SHIFT - PAGE_SHIFT : 0)
1548# define HWBUF_ORDER (HBO + 1) /* next size bigger */
1549#define MIN_SPEED 4000
1550#define MAX_SPEED 49000
1551
1552#define MIN_FRAGSHIFT (DMACHUNK_SHIFT + 1)
1553#define MAX_FRAGSHIFT (PAGE_SHIFT)
1554#define MIN_FRAGSIZE (1 << MIN_FRAGSHIFT)
1555#define MAX_FRAGSIZE (1 << MAX_FRAGSHIFT)
1556#define MIN_FRAGCOUNT(fragsize) 3
1557#define MAX_FRAGCOUNT(fragsize) (32 * PAGE_SIZE / (fragsize))
1558#define DEFAULT_FRAGSHIFT 12
1559#define DEFAULT_FRAGCOUNT 16
1560#define DEFAULT_SUBDIVSHIFT 0
1561
1562/*
1563 * The software buffer (swbuf) is a ring buffer shared between user
1564 * level and interrupt level. Each level owns some of the bytes in
1565 * the buffer, and may give bytes away by calling swb_inc_{u,i}().
1566 * User level calls _u for user, and interrupt level calls _i for
1567 * interrupt.
1568 *
1569 * port->swb_{u,i}_avail is the number of bytes available to that level.
1570 *
1571 * port->swb_{u,i}_idx is the index of the first available byte in the
1572 * buffer.
1573 *
1574 * Each level calls swb_inc_{u,i}() to atomically increment its index,
1575 * recalculate the number of bytes available for both sides, and
1576 * return the number of bytes available. Since each side can only
1577 * give away bytes, the other side can only increase the number of
1578 * bytes available to this side. Each side updates its own index
1579 * variable, swb_{u,i}_idx, so no lock is needed to read it.
1580 *
1581 * To query the number of bytes available, call swb_inc_{u,i} with an
1582 * increment of zero.
1583 */
1584
1585static __inline__ unsigned int __swb_inc_u(vwsnd_port_t *port, int inc)
1586{
1587 if (inc) {
1588 port->swb_u_idx += inc;
1589 port->swb_u_idx %= port->swbuf_size;
1590 port->swb_u_avail -= inc;
1591 port->swb_i_avail += inc;
1592 }
1593 return port->swb_u_avail;
1594}
1595
1596static __inline__ unsigned int swb_inc_u(vwsnd_port_t *port, int inc)
1597{
1598 unsigned long flags;
1599 unsigned int ret;
1600
1601 spin_lock_irqsave(&port->lock, flags);
1602 {
1603 ret = __swb_inc_u(port, inc);
1604 }
1605 spin_unlock_irqrestore(&port->lock, flags);
1606 return ret;
1607}
1608
1609static __inline__ unsigned int __swb_inc_i(vwsnd_port_t *port, int inc)
1610{
1611 if (inc) {
1612 port->swb_i_idx += inc;
1613 port->swb_i_idx %= port->swbuf_size;
1614 port->swb_i_avail -= inc;
1615 port->swb_u_avail += inc;
1616 }
1617 return port->swb_i_avail;
1618}
1619
1620static __inline__ unsigned int swb_inc_i(vwsnd_port_t *port, int inc)
1621{
1622 unsigned long flags;
1623 unsigned int ret;
1624
1625 spin_lock_irqsave(&port->lock, flags);
1626 {
1627 ret = __swb_inc_i(port, inc);
1628 }
1629 spin_unlock_irqrestore(&port->lock, flags);
1630 return ret;
1631}
1632
1633/*
1634 * pcm_setup - this routine initializes all port state after
1635 * mode-setting ioctls have been done, but before the first I/O is
1636 * done.
1637 *
1638 * Locking: called with devc->io_mutex held.
1639 *
1640 * Returns 0 on success, -errno on failure.
1641 */
1642
1643static int pcm_setup(vwsnd_dev_t *devc,
1644 vwsnd_port_t *rport,
1645 vwsnd_port_t *wport)
1646{
1647 vwsnd_port_t *aport = rport ? rport : wport;
1648 int sample_size;
1649 unsigned int zero_word;
1650
1651 DBGEV("(devc=0x%p, rport=0x%p, wport=0x%p)\n", devc, rport, wport);
1652
1653 ASSERT(aport != NULL);
1654 if (aport->swbuf != NULL)
1655 return 0;
1656 switch (aport->sw_samplefmt) {
1657 case AFMT_MU_LAW:
1658 sample_size = 1;
1659 zero_word = 0xFFFFFFFF ^ 0x80808080;
1660 break;
1661
1662 case AFMT_A_LAW:
1663 sample_size = 1;
1664 zero_word = 0xD5D5D5D5 ^ 0x80808080;
1665 break;
1666
1667 case AFMT_U8:
1668 sample_size = 1;
1669 zero_word = 0x80808080;
1670 break;
1671
1672 case AFMT_S8:
1673 sample_size = 1;
1674 zero_word = 0x00000000;
1675 break;
1676
1677 case AFMT_S16_LE:
1678 sample_size = 2;
1679 zero_word = 0x00000000;
1680 break;
1681
1682 default:
1683 sample_size = 0; /* prevent compiler warning */
1684 zero_word = 0;
1685 ASSERT(0);
1686 }
1687 aport->sample_size = sample_size;
1688 aport->zero_word = zero_word;
1689 aport->frame_size = aport->sw_channels * aport->sample_size;
1690 aport->hw_fragshift = aport->sw_fragshift - aport->sw_subdivshift;
1691 aport->hw_fragsize = 1 << aport->hw_fragshift;
1692 aport->hw_fragcount = aport->sw_fragcount << aport->sw_subdivshift;
1693 ASSERT(aport->hw_fragsize >= MIN_FRAGSIZE);
1694 ASSERT(aport->hw_fragsize <= MAX_FRAGSIZE);
1695 ASSERT(aport->hw_fragcount >= MIN_FRAGCOUNT(aport->hw_fragsize));
1696 ASSERT(aport->hw_fragcount <= MAX_FRAGCOUNT(aport->hw_fragsize));
1697 if (rport) {
1698 int hwfrags, swfrags;
1699 rport->hwbuf_max = aport->hwbuf_size - DMACHUNK_SIZE;
1700 hwfrags = rport->hwbuf_max >> aport->hw_fragshift;
1701 swfrags = aport->hw_fragcount - hwfrags;
1702 if (swfrags < 2)
1703 swfrags = 2;
1704 rport->swbuf_size = swfrags * aport->hw_fragsize;
1705 DBGPV("hwfrags = %d, swfrags = %d\n", hwfrags, swfrags);
1706 DBGPV("read hwbuf_max = %d, swbuf_size = %d\n",
1707 rport->hwbuf_max, rport->swbuf_size);
1708 }
1709 if (wport) {
1710 int hwfrags, swfrags;
1711 int total_bytes = aport->hw_fragcount * aport->hw_fragsize;
1712 wport->hwbuf_max = aport->hwbuf_size - DMACHUNK_SIZE;
1713 if (wport->hwbuf_max > total_bytes)
1714 wport->hwbuf_max = total_bytes;
1715 hwfrags = wport->hwbuf_max >> aport->hw_fragshift;
1716 DBGPV("hwfrags = %d\n", hwfrags);
1717 swfrags = aport->hw_fragcount - hwfrags;
1718 if (swfrags < 2)
1719 swfrags = 2;
1720 wport->swbuf_size = swfrags * aport->hw_fragsize;
1721 DBGPV("hwfrags = %d, swfrags = %d\n", hwfrags, swfrags);
1722 DBGPV("write hwbuf_max = %d, swbuf_size = %d\n",
1723 wport->hwbuf_max, wport->swbuf_size);
1724 }
1725
1726 aport->swb_u_idx = 0;
1727 aport->swb_i_idx = 0;
1728 aport->byte_count = 0;
1729
1730 /*
1731 * Is this a Cobalt bug? We need to make this buffer extend
1732 * one page further than we actually use -- somehow memcpy
1733 * causes an exceptoin otherwise. I suspect there's a bug in
1734 * Cobalt (or somewhere) where it's generating a fault on a
1735 * speculative load or something. Obviously, I haven't taken
1736 * the time to track it down.
1737 */
1738
1739 aport->swbuf = vmalloc(aport->swbuf_size + PAGE_SIZE);
1740 if (!aport->swbuf)
1741 return -ENOMEM;
1742 if (rport && wport) {
1743 ASSERT(aport == rport);
1744 ASSERT(wport->swbuf == NULL);
1745 /* One extra page - see comment above. */
1746 wport->swbuf = vmalloc(aport->swbuf_size + PAGE_SIZE);
1747 if (!wport->swbuf) {
1748 vfree(aport->swbuf);
1749 aport->swbuf = NULL;
1750 return -ENOMEM;
1751 }
1752 wport->sample_size = rport->sample_size;
1753 wport->zero_word = rport->zero_word;
1754 wport->frame_size = rport->frame_size;
1755 wport->hw_fragshift = rport->hw_fragshift;
1756 wport->hw_fragsize = rport->hw_fragsize;
1757 wport->hw_fragcount = rport->hw_fragcount;
1758 wport->swbuf_size = rport->swbuf_size;
1759 wport->hwbuf_max = rport->hwbuf_max;
1760 wport->swb_u_idx = rport->swb_u_idx;
1761 wport->swb_i_idx = rport->swb_i_idx;
1762 wport->byte_count = rport->byte_count;
1763 }
1764 if (rport) {
1765 rport->swb_u_avail = 0;
1766 rport->swb_i_avail = rport->swbuf_size;
1767 rport->swstate = SW_RUN;
1768 li_setup_dma(&rport->chan,
1769 &li_comm1,
1770 &devc->lith,
1771 rport->hwbuf_paddr,
1772 HWBUF_SHIFT,
1773 rport->hw_fragshift,
1774 rport->sw_channels,
1775 rport->sample_size);
1776 ad1843_setup_adc(&devc->lith,
1777 rport->sw_framerate,
1778 rport->sw_samplefmt,
1779 rport->sw_channels);
1780 li_enable_interrupts(&devc->lith, READ_INTR_MASK);
1781 if (!(rport->flags & DISABLED)) {
1782 ustmsc_t ustmsc;
1783 rport->hwstate = HW_RUNNING;
1784 li_activate_dma(&rport->chan);
1785 li_read_USTMSC(&rport->chan, &ustmsc);
1786 rport->MSC_offset = ustmsc.msc;
1787 }
1788 }
1789 if (wport) {
1790 if (wport->hwbuf_max > wport->swbuf_size)
1791 wport->hwbuf_max = wport->swbuf_size;
1792 wport->flags &= ~ERFLOWN;
1793 wport->swb_u_avail = wport->swbuf_size;
1794 wport->swb_i_avail = 0;
1795 wport->swstate = SW_RUN;
1796 li_setup_dma(&wport->chan,
1797 &li_comm2,
1798 &devc->lith,
1799 wport->hwbuf_paddr,
1800 HWBUF_SHIFT,
1801 wport->hw_fragshift,
1802 wport->sw_channels,
1803 wport->sample_size);
1804 ad1843_setup_dac(&devc->lith,
1805 wport->sw_framerate,
1806 wport->sw_samplefmt,
1807 wport->sw_channels);
1808 li_enable_interrupts(&devc->lith, WRITE_INTR_MASK);
1809 }
1810 DBGRV();
1811 return 0;
1812}
1813
1814/*
1815 * pcm_shutdown_port - shut down one port (direction) for PCM I/O.
1816 * Only called from pcm_shutdown.
1817 */
1818
1819static void pcm_shutdown_port(vwsnd_dev_t *devc,
1820 vwsnd_port_t *aport,
1821 unsigned int mask)
1822{
1823 unsigned long flags;
1824 vwsnd_port_hwstate_t hwstate;
1825 DECLARE_WAITQUEUE(wait, current);
1826
1827 aport->swstate = SW_INITIAL;
1828 add_wait_queue(&aport->queue, &wait);
1829 while (1) {
1830 set_current_state(TASK_UNINTERRUPTIBLE);
1831 spin_lock_irqsave(&aport->lock, flags);
1832 {
1833 hwstate = aport->hwstate;
1834 }
1835 spin_unlock_irqrestore(&aport->lock, flags);
1836 if (hwstate == HW_STOPPED)
1837 break;
1838 schedule();
1839 }
1840 current->state = TASK_RUNNING;
1841 remove_wait_queue(&aport->queue, &wait);
1842 li_disable_interrupts(&devc->lith, mask);
1843 if (aport == &devc->rport)
1844 ad1843_shutdown_adc(&devc->lith);
1845 else /* aport == &devc->wport) */
1846 ad1843_shutdown_dac(&devc->lith);
1847 li_shutdown_dma(&aport->chan);
1848 vfree(aport->swbuf);
1849 aport->swbuf = NULL;
1850 aport->byte_count = 0;
1851}
1852
1853/*
1854 * pcm_shutdown undoes what pcm_setup did.
1855 * Also sets the ports' swstate to newstate.
1856 */
1857
1858static void pcm_shutdown(vwsnd_dev_t *devc,
1859 vwsnd_port_t *rport,
1860 vwsnd_port_t *wport)
1861{
1862 DBGEV("(devc=0x%p, rport=0x%p, wport=0x%p)\n", devc, rport, wport);
1863
1864 if (rport && rport->swbuf) {
1865 DBGPV("shutting down rport\n");
1866 pcm_shutdown_port(devc, rport, READ_INTR_MASK);
1867 }
1868 if (wport && wport->swbuf) {
1869 DBGPV("shutting down wport\n");
1870 pcm_shutdown_port(devc, wport, WRITE_INTR_MASK);
1871 }
1872 DBGRV();
1873}
1874
1875static void pcm_copy_in(vwsnd_port_t *rport, int swidx, int hwidx, int nb)
1876{
1877 char *src = rport->hwbuf + hwidx;
1878 char *dst = rport->swbuf + swidx;
1879 int fmt = rport->sw_samplefmt;
1880
1881 DBGPV("swidx = %d, hwidx = %d\n", swidx, hwidx);
1882 ASSERT(rport->hwbuf != NULL);
1883 ASSERT(rport->swbuf != NULL);
1884 ASSERT(nb > 0 && (nb % 32) == 0);
1885 ASSERT(swidx % 32 == 0 && hwidx % 32 == 0);
1886 ASSERT(swidx >= 0 && swidx + nb <= rport->swbuf_size);
1887 ASSERT(hwidx >= 0 && hwidx + nb <= rport->hwbuf_size);
1888
1889 if (fmt == AFMT_MU_LAW || fmt == AFMT_A_LAW || fmt == AFMT_S8) {
1890
1891 /* See Sample Format Notes above. */
1892
1893 char *end = src + nb;
1894 while (src < end)
1895 *dst++ = *src++ ^ 0x80;
1896 } else
1897 memcpy(dst, src, nb);
1898}
1899
1900static void pcm_copy_out(vwsnd_port_t *wport, int swidx, int hwidx, int nb)
1901{
1902 char *src = wport->swbuf + swidx;
1903 char *dst = wport->hwbuf + hwidx;
1904 int fmt = wport->sw_samplefmt;
1905
1906 ASSERT(nb > 0 && (nb % 32) == 0);
1907 ASSERT(wport->hwbuf != NULL);
1908 ASSERT(wport->swbuf != NULL);
1909 ASSERT(swidx % 32 == 0 && hwidx % 32 == 0);
1910 ASSERT(swidx >= 0 && swidx + nb <= wport->swbuf_size);
1911 ASSERT(hwidx >= 0 && hwidx + nb <= wport->hwbuf_size);
1912 if (fmt == AFMT_MU_LAW || fmt == AFMT_A_LAW || fmt == AFMT_S8) {
1913
1914 /* See Sample Format Notes above. */
1915
1916 char *end = src + nb;
1917 while (src < end)
1918 *dst++ = *src++ ^ 0x80;
1919 } else
1920 memcpy(dst, src, nb);
1921}
1922
1923/*
1924 * pcm_output() is called both from baselevel and from interrupt level.
1925 * This is where audio frames are copied into the hardware-accessible
1926 * ring buffer.
1927 *
1928 * Locking note: The part of this routine that figures out what to do
1929 * holds wport->lock. The longer part releases wport->lock, but sets
1930 * wport->flags & HW_BUSY. Afterward, it reacquires wport->lock, and
1931 * checks for more work to do.
1932 *
1933 * If another thread calls pcm_output() while HW_BUSY is set, it
1934 * returns immediately, knowing that the thread that set HW_BUSY will
1935 * look for more work to do before returning.
1936 *
1937 * This has the advantage that port->lock is held for several short
1938 * periods instead of one long period. Also, when pcm_output is
1939 * called from base level, it reenables interrupts.
1940 */
1941
1942static void pcm_output(vwsnd_dev_t *devc, int erflown, int nb)
1943{
1944 vwsnd_port_t *wport = &devc->wport;
1945 const int hwmax = wport->hwbuf_max;
1946 const int hwsize = wport->hwbuf_size;
1947 const int swsize = wport->swbuf_size;
1948 const int fragsize = wport->hw_fragsize;
1949 unsigned long iflags;
1950
1951 DBGEV("(devc=0x%p, erflown=%d, nb=%d)\n", devc, erflown, nb);
1952 spin_lock_irqsave(&wport->lock, iflags);
1953 if (erflown)
1954 wport->flags |= ERFLOWN;
1955 (void) __swb_inc_u(wport, nb);
1956 if (wport->flags & HW_BUSY) {
1957 spin_unlock_irqrestore(&wport->lock, iflags);
1958 DBGPV("returning: HW BUSY\n");
1959 return;
1960 }
1961 if (wport->flags & DISABLED) {
1962 spin_unlock_irqrestore(&wport->lock, iflags);
1963 DBGPV("returning: DISABLED\n");
1964 return;
1965 }
1966 wport->flags |= HW_BUSY;
1967 while (1) {
1968 int swptr, hwptr, hw_avail, sw_avail, swidx;
1969 vwsnd_port_hwstate_t hwstate = wport->hwstate;
1970 vwsnd_port_swstate_t swstate = wport->swstate;
1971 int hw_unavail;
1972 ustmsc_t ustmsc;
1973
1974 hwptr = li_read_hwptr(&wport->chan);
1975 swptr = li_read_swptr(&wport->chan);
1976 hw_unavail = (swptr - hwptr + hwsize) % hwsize;
1977 hw_avail = (hwmax - hw_unavail) & -fragsize;
1978 sw_avail = wport->swb_i_avail & -fragsize;
1979 if (sw_avail && swstate == SW_RUN) {
1980 if (wport->flags & ERFLOWN) {
1981 wport->flags &= ~ERFLOWN;
1982 }
1983 } else if (swstate == SW_INITIAL ||
1984 swstate == SW_OFF ||
1985 (swstate == SW_DRAIN &&
1986 !sw_avail &&
1987 (wport->flags & ERFLOWN))) {
1988 DBGP("stopping. hwstate = %d\n", hwstate);
1989 if (hwstate != HW_STOPPED) {
1990 li_deactivate_dma(&wport->chan);
1991 wport->hwstate = HW_STOPPED;
1992 }
1993 wake_up(&wport->queue);
1994 break;
1995 }
1996 if (!sw_avail || !hw_avail)
1997 break;
1998 spin_unlock_irqrestore(&wport->lock, iflags);
1999
2000 /*
2001 * We gave up the port lock, but we have the HW_BUSY flag.
2002 * Proceed without accessing any nonlocal state.
2003 * Do not exit the loop -- must check for more work.
2004 */
2005
2006 swidx = wport->swb_i_idx;
2007 nb = hw_avail;
2008 if (nb > sw_avail)
2009 nb = sw_avail;
2010 if (nb > hwsize - swptr)
2011 nb = hwsize - swptr; /* don't overflow hwbuf */
2012 if (nb > swsize - swidx)
2013 nb = swsize - swidx; /* don't overflow swbuf */
2014 ASSERT(nb > 0);
2015 if (nb % fragsize) {
2016 DBGP("nb = %d, fragsize = %d\n", nb, fragsize);
2017 DBGP("hw_avail = %d\n", hw_avail);
2018 DBGP("sw_avail = %d\n", sw_avail);
2019 DBGP("hwsize = %d, swptr = %d\n", hwsize, swptr);
2020 DBGP("swsize = %d, swidx = %d\n", swsize, swidx);
2021 }
2022 ASSERT(!(nb % fragsize));
2023 DBGPV("copying swb[%d..%d] to hwb[%d..%d]\n",
2024 swidx, swidx + nb, swptr, swptr + nb);
2025 pcm_copy_out(wport, swidx, swptr, nb);
2026 li_write_swptr(&wport->chan, (swptr + nb) % hwsize);
2027 spin_lock_irqsave(&wport->lock, iflags);
2028 if (hwstate == HW_STOPPED) {
2029 DBGPV("starting\n");
2030 li_activate_dma(&wport->chan);
2031 wport->hwstate = HW_RUNNING;
2032 li_read_USTMSC(&wport->chan, &ustmsc);
2033 ASSERT(wport->byte_count % wport->frame_size == 0);
2034 wport->MSC_offset = ustmsc.msc - wport->byte_count / wport->frame_size;
2035 }
2036 __swb_inc_i(wport, nb);
2037 wport->byte_count += nb;
2038 wport->frag_count += nb / fragsize;
2039 ASSERT(nb % fragsize == 0);
2040 wake_up(&wport->queue);
2041 }
2042 wport->flags &= ~HW_BUSY;
2043 spin_unlock_irqrestore(&wport->lock, iflags);
2044 DBGRV();
2045}
2046
2047/*
2048 * pcm_input() is called both from baselevel and from interrupt level.
2049 * This is where audio frames are copied out of the hardware-accessible
2050 * ring buffer.
2051 *
2052 * Locking note: The part of this routine that figures out what to do
2053 * holds rport->lock. The longer part releases rport->lock, but sets
2054 * rport->flags & HW_BUSY. Afterward, it reacquires rport->lock, and
2055 * checks for more work to do.
2056 *
2057 * If another thread calls pcm_input() while HW_BUSY is set, it
2058 * returns immediately, knowing that the thread that set HW_BUSY will
2059 * look for more work to do before returning.
2060 *
2061 * This has the advantage that port->lock is held for several short
2062 * periods instead of one long period. Also, when pcm_input is
2063 * called from base level, it reenables interrupts.
2064 */
2065
2066static void pcm_input(vwsnd_dev_t *devc, int erflown, int nb)
2067{
2068 vwsnd_port_t *rport = &devc->rport;
2069 const int hwmax = rport->hwbuf_max;
2070 const int hwsize = rport->hwbuf_size;
2071 const int swsize = rport->swbuf_size;
2072 const int fragsize = rport->hw_fragsize;
2073 unsigned long iflags;
2074
2075 DBGEV("(devc=0x%p, erflown=%d, nb=%d)\n", devc, erflown, nb);
2076
2077 spin_lock_irqsave(&rport->lock, iflags);
2078 if (erflown)
2079 rport->flags |= ERFLOWN;
2080 (void) __swb_inc_u(rport, nb);
2081 if (rport->flags & HW_BUSY || !rport->swbuf) {
2082 spin_unlock_irqrestore(&rport->lock, iflags);
2083 DBGPV("returning: HW BUSY or !swbuf\n");
2084 return;
2085 }
2086 if (rport->flags & DISABLED) {
2087 spin_unlock_irqrestore(&rport->lock, iflags);
2088 DBGPV("returning: DISABLED\n");
2089 return;
2090 }
2091 rport->flags |= HW_BUSY;
2092 while (1) {
2093 int swptr, hwptr, hw_avail, sw_avail, swidx;
2094 vwsnd_port_hwstate_t hwstate = rport->hwstate;
2095 vwsnd_port_swstate_t swstate = rport->swstate;
2096
2097 hwptr = li_read_hwptr(&rport->chan);
2098 swptr = li_read_swptr(&rport->chan);
2099 hw_avail = (hwptr - swptr + hwsize) % hwsize & -fragsize;
2100 if (hw_avail > hwmax)
2101 hw_avail = hwmax;
2102 sw_avail = rport->swb_i_avail & -fragsize;
2103 if (swstate != SW_RUN) {
2104 DBGP("stopping. hwstate = %d\n", hwstate);
2105 if (hwstate != HW_STOPPED) {
2106 li_deactivate_dma(&rport->chan);
2107 rport->hwstate = HW_STOPPED;
2108 }
2109 wake_up(&rport->queue);
2110 break;
2111 }
2112 if (!sw_avail || !hw_avail)
2113 break;
2114 spin_unlock_irqrestore(&rport->lock, iflags);
2115
2116 /*
2117 * We gave up the port lock, but we have the HW_BUSY flag.
2118 * Proceed without accessing any nonlocal state.
2119 * Do not exit the loop -- must check for more work.
2120 */
2121
2122 swidx = rport->swb_i_idx;
2123 nb = hw_avail;
2124 if (nb > sw_avail)
2125 nb = sw_avail;
2126 if (nb > hwsize - swptr)
2127 nb = hwsize - swptr; /* don't overflow hwbuf */
2128 if (nb > swsize - swidx)
2129 nb = swsize - swidx; /* don't overflow swbuf */
2130 ASSERT(nb > 0);
2131 if (nb % fragsize) {
2132 DBGP("nb = %d, fragsize = %d\n", nb, fragsize);
2133 DBGP("hw_avail = %d\n", hw_avail);
2134 DBGP("sw_avail = %d\n", sw_avail);
2135 DBGP("hwsize = %d, swptr = %d\n", hwsize, swptr);
2136 DBGP("swsize = %d, swidx = %d\n", swsize, swidx);
2137 }
2138 ASSERT(!(nb % fragsize));
2139 DBGPV("copying hwb[%d..%d] to swb[%d..%d]\n",
2140 swptr, swptr + nb, swidx, swidx + nb);
2141 pcm_copy_in(rport, swidx, swptr, nb);
2142 li_write_swptr(&rport->chan, (swptr + nb) % hwsize);
2143 spin_lock_irqsave(&rport->lock, iflags);
2144 __swb_inc_i(rport, nb);
2145 rport->byte_count += nb;
2146 rport->frag_count += nb / fragsize;
2147 ASSERT(nb % fragsize == 0);
2148 wake_up(&rport->queue);
2149 }
2150 rport->flags &= ~HW_BUSY;
2151 spin_unlock_irqrestore(&rport->lock, iflags);
2152 DBGRV();
2153}
2154
2155/*
2156 * pcm_flush_frag() writes zero samples to fill the current fragment,
2157 * then flushes it to the hardware.
2158 *
2159 * It is only meaningful to flush output, not input.
2160 */
2161
2162static void pcm_flush_frag(vwsnd_dev_t *devc)
2163{
2164 vwsnd_port_t *wport = &devc->wport;
2165
2166 DBGPV("swstate = %d\n", wport->swstate);
2167 if (wport->swstate == SW_RUN) {
2168 int idx = wport->swb_u_idx;
2169 int end = (idx + wport->hw_fragsize - 1)
2170 >> wport->hw_fragshift
2171 << wport->hw_fragshift;
2172 int nb = end - idx;
2173 DBGPV("clearing %d bytes\n", nb);
2174 if (nb)
2175 memset(wport->swbuf + idx,
2176 (char) wport->zero_word,
2177 nb);
2178 wport->swstate = SW_DRAIN;
2179 pcm_output(devc, 0, nb);
2180 }
2181 DBGRV();
2182}
2183
2184/*
2185 * Wait for output to drain. This sleeps uninterruptibly because
2186 * there is nothing intelligent we can do if interrupted. This
2187 * means the process will be delayed in responding to the signal.
2188 */
2189
2190static void pcm_write_sync(vwsnd_dev_t *devc)
2191{
2192 vwsnd_port_t *wport = &devc->wport;
2193 DECLARE_WAITQUEUE(wait, current);
2194 unsigned long flags;
2195 vwsnd_port_hwstate_t hwstate;
2196
2197 DBGEV("(devc=0x%p)\n", devc);
2198 add_wait_queue(&wport->queue, &wait);
2199 while (1) {
2200 set_current_state(TASK_UNINTERRUPTIBLE);
2201 spin_lock_irqsave(&wport->lock, flags);
2202 {
2203 hwstate = wport->hwstate;
2204 }
2205 spin_unlock_irqrestore(&wport->lock, flags);
2206 if (hwstate == HW_STOPPED)
2207 break;
2208 schedule();
2209 }
2210 current->state = TASK_RUNNING;
2211 remove_wait_queue(&wport->queue, &wait);
2212 DBGPV("swstate = %d, hwstate = %d\n", wport->swstate, wport->hwstate);
2213 DBGRV();
2214}
2215
2216/*****************************************************************************/
2217/* audio driver */
2218
2219/*
2220 * seek on an audio device always fails.
2221 */
2222
2223static void vwsnd_audio_read_intr(vwsnd_dev_t *devc, unsigned int status)
2224{
2225 int overflown = status & LI_INTR_COMM1_OVERFLOW;
2226
2227 if (status & READ_INTR_MASK)
2228 pcm_input(devc, overflown, 0);
2229}
2230
2231static void vwsnd_audio_write_intr(vwsnd_dev_t *devc, unsigned int status)
2232{
2233 int underflown = status & LI_INTR_COMM2_UNDERFLOW;
2234
2235 if (status & WRITE_INTR_MASK)
2236 pcm_output(devc, underflown, 0);
2237}
2238
2239static irqreturn_t vwsnd_audio_intr(int irq, void *dev_id)
2240{
2241 vwsnd_dev_t *devc = dev_id;
2242 unsigned int status;
2243
2244 DBGEV("(irq=%d, dev_id=0x%p)\n", irq, dev_id);
2245
2246 status = li_get_clear_intr_status(&devc->lith);
2247 vwsnd_audio_read_intr(devc, status);
2248 vwsnd_audio_write_intr(devc, status);
2249 return IRQ_HANDLED;
2250}
2251
2252static ssize_t vwsnd_audio_do_read(struct file *file,
2253 char *buffer,
2254 size_t count,
2255 loff_t *ppos)
2256{
2257 vwsnd_dev_t *devc = file->private_data;
2258 vwsnd_port_t *rport = ((file->f_mode & FMODE_READ) ?
2259 &devc->rport : NULL);
2260 int ret, nb;
2261
2262 DBGEV("(file=0x%p, buffer=0x%p, count=%d, ppos=0x%p)\n",
2263 file, buffer, count, ppos);
2264
2265 if (!rport)
2266 return -EINVAL;
2267
2268 if (rport->swbuf == NULL) {
2269 vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ?
2270 &devc->wport : NULL;
2271 ret = pcm_setup(devc, rport, wport);
2272 if (ret < 0)
2273 return ret;
2274 }
2275
2276 if (!access_ok(VERIFY_READ, buffer, count))
2277 return -EFAULT;
2278 ret = 0;
2279 while (count) {
2280 DECLARE_WAITQUEUE(wait, current);
2281 add_wait_queue(&rport->queue, &wait);
2282 while ((nb = swb_inc_u(rport, 0)) == 0) {
2283 DBGPV("blocking\n");
2284 set_current_state(TASK_INTERRUPTIBLE);
2285 if (rport->flags & DISABLED ||
2286 file->f_flags & O_NONBLOCK) {
2287 current->state = TASK_RUNNING;
2288 remove_wait_queue(&rport->queue, &wait);
2289 return ret ? ret : -EAGAIN;
2290 }
2291 schedule();
2292 if (signal_pending(current)) {
2293 current->state = TASK_RUNNING;
2294 remove_wait_queue(&rport->queue, &wait);
2295 return ret ? ret : -ERESTARTSYS;
2296 }
2297 }
2298 current->state = TASK_RUNNING;
2299 remove_wait_queue(&rport->queue, &wait);
2300 pcm_input(devc, 0, 0);
2301 /* nb bytes are available in userbuf. */
2302 if (nb > count)
2303 nb = count;
2304 DBGPV("nb = %d\n", nb);
2305 if (copy_to_user(buffer, rport->swbuf + rport->swb_u_idx, nb))
2306 return -EFAULT;
2307 (void) swb_inc_u(rport, nb);
2308 buffer += nb;
2309 count -= nb;
2310 ret += nb;
2311 }
2312 DBGPV("returning %d\n", ret);
2313 return ret;
2314}
2315
2316static ssize_t vwsnd_audio_read(struct file *file,
2317 char *buffer,
2318 size_t count,
2319 loff_t *ppos)
2320{
2321 vwsnd_dev_t *devc = file->private_data;
2322 ssize_t ret;
2323
2324 mutex_lock(&devc->io_mutex);
2325 ret = vwsnd_audio_do_read(file, buffer, count, ppos);
2326 mutex_unlock(&devc->io_mutex);
2327 return ret;
2328}
2329
2330static ssize_t vwsnd_audio_do_write(struct file *file,
2331 const char *buffer,
2332 size_t count,
2333 loff_t *ppos)
2334{
2335 vwsnd_dev_t *devc = file->private_data;
2336 vwsnd_port_t *wport = ((file->f_mode & FMODE_WRITE) ?
2337 &devc->wport : NULL);
2338 int ret, nb;
2339
2340 DBGEV("(file=0x%p, buffer=0x%p, count=%d, ppos=0x%p)\n",
2341 file, buffer, count, ppos);
2342
2343 if (!wport)
2344 return -EINVAL;
2345
2346 if (wport->swbuf == NULL) {
2347 vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ?
2348 &devc->rport : NULL;
2349 ret = pcm_setup(devc, rport, wport);
2350 if (ret < 0)
2351 return ret;
2352 }
2353 if (!access_ok(VERIFY_WRITE, buffer, count))
2354 return -EFAULT;
2355 ret = 0;
2356 while (count) {
2357 DECLARE_WAITQUEUE(wait, current);
2358 add_wait_queue(&wport->queue, &wait);
2359 while ((nb = swb_inc_u(wport, 0)) == 0) {
2360 set_current_state(TASK_INTERRUPTIBLE);
2361 if (wport->flags & DISABLED ||
2362 file->f_flags & O_NONBLOCK) {
2363 current->state = TASK_RUNNING;
2364 remove_wait_queue(&wport->queue, &wait);
2365 return ret ? ret : -EAGAIN;
2366 }
2367 schedule();
2368 if (signal_pending(current)) {
2369 current->state = TASK_RUNNING;
2370 remove_wait_queue(&wport->queue, &wait);
2371 return ret ? ret : -ERESTARTSYS;
2372 }
2373 }
2374 current->state = TASK_RUNNING;
2375 remove_wait_queue(&wport->queue, &wait);
2376 /* nb bytes are available in userbuf. */
2377 if (nb > count)
2378 nb = count;
2379 DBGPV("nb = %d\n", nb);
2380 if (copy_from_user(wport->swbuf + wport->swb_u_idx, buffer, nb))
2381 return -EFAULT;
2382 pcm_output(devc, 0, nb);
2383 buffer += nb;
2384 count -= nb;
2385 ret += nb;
2386 }
2387 DBGPV("returning %d\n", ret);
2388 return ret;
2389}
2390
2391static ssize_t vwsnd_audio_write(struct file *file,
2392 const char *buffer,
2393 size_t count,
2394 loff_t *ppos)
2395{
2396 vwsnd_dev_t *devc = file->private_data;
2397 ssize_t ret;
2398
2399 mutex_lock(&devc->io_mutex);
2400 ret = vwsnd_audio_do_write(file, buffer, count, ppos);
2401 mutex_unlock(&devc->io_mutex);
2402 return ret;
2403}
2404
2405/* No kernel lock - fine */
2406static unsigned int vwsnd_audio_poll(struct file *file,
2407 struct poll_table_struct *wait)
2408{
2409 vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
2410 vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ?
2411 &devc->rport : NULL;
2412 vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ?
2413 &devc->wport : NULL;
2414 unsigned int mask = 0;
2415
2416 DBGEV("(file=0x%p, wait=0x%p)\n", file, wait);
2417
2418 ASSERT(rport || wport);
2419 if (rport) {
2420 poll_wait(file, &rport->queue, wait);
2421 if (swb_inc_u(rport, 0))
2422 mask |= (POLLIN | POLLRDNORM);
2423 }
2424 if (wport) {
2425 poll_wait(file, &wport->queue, wait);
2426 if (wport->swbuf == NULL || swb_inc_u(wport, 0))
2427 mask |= (POLLOUT | POLLWRNORM);
2428 }
2429
2430 DBGPV("returning 0x%x\n", mask);
2431 return mask;
2432}
2433
2434static int vwsnd_audio_do_ioctl(struct file *file,
2435 unsigned int cmd,
2436 unsigned long arg)
2437{
2438 vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
2439 vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ?
2440 &devc->rport : NULL;
2441 vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ?
2442 &devc->wport : NULL;
2443 vwsnd_port_t *aport = rport ? rport : wport;
2444 struct audio_buf_info buf_info;
2445 struct count_info info;
2446 unsigned long flags;
2447 int ival;
2448
2449
2450 DBGEV("(file=0x%p, cmd=0x%x, arg=0x%lx)\n",
2451 file, cmd, arg);
2452 switch (cmd) {
2453 case OSS_GETVERSION: /* _SIOR ('M', 118, int) */
2454 DBGX("OSS_GETVERSION\n");
2455 ival = SOUND_VERSION;
2456 return put_user(ival, (int *) arg);
2457
2458 case SNDCTL_DSP_GETCAPS: /* _SIOR ('P',15, int) */
2459 DBGX("SNDCTL_DSP_GETCAPS\n");
2460 ival = DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER;
2461 return put_user(ival, (int *) arg);
2462
2463 case SNDCTL_DSP_GETFMTS: /* _SIOR ('P',11, int) */
2464 DBGX("SNDCTL_DSP_GETFMTS\n");
2465 ival = (AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW |
2466 AFMT_U8 | AFMT_S8);
2467 return put_user(ival, (int *) arg);
2468 break;
2469
2470 case SOUND_PCM_READ_RATE: /* _SIOR ('P', 2, int) */
2471 DBGX("SOUND_PCM_READ_RATE\n");
2472 ival = aport->sw_framerate;
2473 return put_user(ival, (int *) arg);
2474
2475 case SOUND_PCM_READ_CHANNELS: /* _SIOR ('P', 6, int) */
2476 DBGX("SOUND_PCM_READ_CHANNELS\n");
2477 ival = aport->sw_channels;
2478 return put_user(ival, (int *) arg);
2479
2480 case SNDCTL_DSP_SPEED: /* _SIOWR('P', 2, int) */
2481 if (get_user(ival, (int *) arg))
2482 return -EFAULT;
2483 DBGX("SNDCTL_DSP_SPEED %d\n", ival);
2484 if (ival) {
2485 if (aport->swstate != SW_INITIAL) {
2486 DBGX("SNDCTL_DSP_SPEED failed: swstate = %d\n",
2487 aport->swstate);
2488 return -EINVAL;
2489 }
2490 if (ival < MIN_SPEED)
2491 ival = MIN_SPEED;
2492 if (ival > MAX_SPEED)
2493 ival = MAX_SPEED;
2494 if (rport)
2495 rport->sw_framerate = ival;
2496 if (wport)
2497 wport->sw_framerate = ival;
2498 } else
2499 ival = aport->sw_framerate;
2500 return put_user(ival, (int *) arg);
2501
2502 case SNDCTL_DSP_STEREO: /* _SIOWR('P', 3, int) */
2503 if (get_user(ival, (int *) arg))
2504 return -EFAULT;
2505 DBGX("SNDCTL_DSP_STEREO %d\n", ival);
2506 if (ival != 0 && ival != 1)
2507 return -EINVAL;
2508 if (aport->swstate != SW_INITIAL)
2509 return -EINVAL;
2510 if (rport)
2511 rport->sw_channels = ival + 1;
2512 if (wport)
2513 wport->sw_channels = ival + 1;
2514 return put_user(ival, (int *) arg);
2515
2516 case SNDCTL_DSP_CHANNELS: /* _SIOWR('P', 6, int) */
2517 if (get_user(ival, (int *) arg))
2518 return -EFAULT;
2519 DBGX("SNDCTL_DSP_CHANNELS %d\n", ival);
2520 if (ival != 1 && ival != 2)
2521 return -EINVAL;
2522 if (aport->swstate != SW_INITIAL)
2523 return -EINVAL;
2524 if (rport)
2525 rport->sw_channels = ival;
2526 if (wport)
2527 wport->sw_channels = ival;
2528 return put_user(ival, (int *) arg);
2529
2530 case SNDCTL_DSP_GETBLKSIZE: /* _SIOWR('P', 4, int) */
2531 ival = pcm_setup(devc, rport, wport);
2532 if (ival < 0) {
2533 DBGX("SNDCTL_DSP_GETBLKSIZE failed, errno %d\n", ival);
2534 return ival;
2535 }
2536 ival = 1 << aport->sw_fragshift;
2537 DBGX("SNDCTL_DSP_GETBLKSIZE returning %d\n", ival);
2538 return put_user(ival, (int *) arg);
2539
2540 case SNDCTL_DSP_SETFRAGMENT: /* _SIOWR('P',10, int) */
2541 if (get_user(ival, (int *) arg))
2542 return -EFAULT;
2543 DBGX("SNDCTL_DSP_SETFRAGMENT %d:%d\n",
2544 ival >> 16, ival & 0xFFFF);
2545 if (aport->swstate != SW_INITIAL)
2546 return -EINVAL;
2547 {
2548 int sw_fragshift = ival & 0xFFFF;
2549 int sw_subdivshift = aport->sw_subdivshift;
2550 int hw_fragshift = sw_fragshift - sw_subdivshift;
2551 int sw_fragcount = (ival >> 16) & 0xFFFF;
2552 int hw_fragsize;
2553 if (hw_fragshift < MIN_FRAGSHIFT)
2554 hw_fragshift = MIN_FRAGSHIFT;
2555 if (hw_fragshift > MAX_FRAGSHIFT)
2556 hw_fragshift = MAX_FRAGSHIFT;
2557 sw_fragshift = hw_fragshift + aport->sw_subdivshift;
2558 hw_fragsize = 1 << hw_fragshift;
2559 if (sw_fragcount < MIN_FRAGCOUNT(hw_fragsize))
2560 sw_fragcount = MIN_FRAGCOUNT(hw_fragsize);
2561 if (sw_fragcount > MAX_FRAGCOUNT(hw_fragsize))
2562 sw_fragcount = MAX_FRAGCOUNT(hw_fragsize);
2563 DBGPV("sw_fragshift = %d\n", sw_fragshift);
2564 DBGPV("rport = 0x%p, wport = 0x%p\n", rport, wport);
2565 if (rport) {
2566 rport->sw_fragshift = sw_fragshift;
2567 rport->sw_fragcount = sw_fragcount;
2568 }
2569 if (wport) {
2570 wport->sw_fragshift = sw_fragshift;
2571 wport->sw_fragcount = sw_fragcount;
2572 }
2573 ival = sw_fragcount << 16 | sw_fragshift;
2574 }
2575 DBGX("SNDCTL_DSP_SETFRAGMENT returns %d:%d\n",
2576 ival >> 16, ival & 0xFFFF);
2577 return put_user(ival, (int *) arg);
2578
2579 case SNDCTL_DSP_SUBDIVIDE: /* _SIOWR('P', 9, int) */
2580 if (get_user(ival, (int *) arg))
2581 return -EFAULT;
2582 DBGX("SNDCTL_DSP_SUBDIVIDE %d\n", ival);
2583 if (aport->swstate != SW_INITIAL)
2584 return -EINVAL;
2585 {
2586 int subdivshift;
2587 int hw_fragshift, hw_fragsize, hw_fragcount;
2588 switch (ival) {
2589 case 1: subdivshift = 0; break;
2590 case 2: subdivshift = 1; break;
2591 case 4: subdivshift = 2; break;
2592 default: return -EINVAL;
2593 }
2594 hw_fragshift = aport->sw_fragshift - subdivshift;
2595 if (hw_fragshift < MIN_FRAGSHIFT ||
2596 hw_fragshift > MAX_FRAGSHIFT)
2597 return -EINVAL;
2598 hw_fragsize = 1 << hw_fragshift;
2599 hw_fragcount = aport->sw_fragcount >> subdivshift;
2600 if (hw_fragcount < MIN_FRAGCOUNT(hw_fragsize) ||
2601 hw_fragcount > MAX_FRAGCOUNT(hw_fragsize))
2602 return -EINVAL;
2603 if (rport)
2604 rport->sw_subdivshift = subdivshift;
2605 if (wport)
2606 wport->sw_subdivshift = subdivshift;
2607 }
2608 return 0;
2609
2610 case SNDCTL_DSP_SETFMT: /* _SIOWR('P',5, int) */
2611 if (get_user(ival, (int *) arg))
2612 return -EFAULT;
2613 DBGX("SNDCTL_DSP_SETFMT %d\n", ival);
2614 if (ival != AFMT_QUERY) {
2615 if (aport->swstate != SW_INITIAL) {
2616 DBGP("SETFMT failed, swstate = %d\n",
2617 aport->swstate);
2618 return -EINVAL;
2619 }
2620 switch (ival) {
2621 case AFMT_MU_LAW:
2622 case AFMT_A_LAW:
2623 case AFMT_U8:
2624 case AFMT_S8:
2625 case AFMT_S16_LE:
2626 if (rport)
2627 rport->sw_samplefmt = ival;
2628 if (wport)
2629 wport->sw_samplefmt = ival;
2630 break;
2631 default:
2632 return -EINVAL;
2633 }
2634 }
2635 ival = aport->sw_samplefmt;
2636 return put_user(ival, (int *) arg);
2637
2638 case SNDCTL_DSP_GETOSPACE: /* _SIOR ('P',12, audio_buf_info) */
2639 DBGXV("SNDCTL_DSP_GETOSPACE\n");
2640 if (!wport)
2641 return -EINVAL;
2642 ival = pcm_setup(devc, rport, wport);
2643 if (ival < 0)
2644 return ival;
2645 ival = swb_inc_u(wport, 0);
2646 buf_info.fragments = ival >> wport->sw_fragshift;
2647 buf_info.fragstotal = wport->sw_fragcount;
2648 buf_info.fragsize = 1 << wport->sw_fragshift;
2649 buf_info.bytes = ival;
2650 DBGXV("SNDCTL_DSP_GETOSPACE returns { %d %d %d %d }\n",
2651 buf_info.fragments, buf_info.fragstotal,
2652 buf_info.fragsize, buf_info.bytes);
2653 if (copy_to_user((void *) arg, &buf_info, sizeof buf_info))
2654 return -EFAULT;
2655 return 0;
2656
2657 case SNDCTL_DSP_GETISPACE: /* _SIOR ('P',13, audio_buf_info) */
2658 DBGX("SNDCTL_DSP_GETISPACE\n");
2659 if (!rport)
2660 return -EINVAL;
2661 ival = pcm_setup(devc, rport, wport);
2662 if (ival < 0)
2663 return ival;
2664 ival = swb_inc_u(rport, 0);
2665 buf_info.fragments = ival >> rport->sw_fragshift;
2666 buf_info.fragstotal = rport->sw_fragcount;
2667 buf_info.fragsize = 1 << rport->sw_fragshift;
2668 buf_info.bytes = ival;
2669 DBGX("SNDCTL_DSP_GETISPACE returns { %d %d %d %d }\n",
2670 buf_info.fragments, buf_info.fragstotal,
2671 buf_info.fragsize, buf_info.bytes);
2672 if (copy_to_user((void *) arg, &buf_info, sizeof buf_info))
2673 return -EFAULT;
2674 return 0;
2675
2676 case SNDCTL_DSP_NONBLOCK: /* _SIO ('P',14) */
2677 DBGX("SNDCTL_DSP_NONBLOCK\n");
2678 spin_lock(&file->f_lock);
2679 file->f_flags |= O_NONBLOCK;
2680 spin_unlock(&file->f_lock);
2681 return 0;
2682
2683 case SNDCTL_DSP_RESET: /* _SIO ('P', 0) */
2684 DBGX("SNDCTL_DSP_RESET\n");
2685 /*
2686 * Nothing special needs to be done for input. Input
2687 * samples sit in swbuf, but it will be reinitialized
2688 * to empty when pcm_setup() is called.
2689 */
2690 if (wport && wport->swbuf) {
2691 wport->swstate = SW_INITIAL;
2692 pcm_output(devc, 0, 0);
2693 pcm_write_sync(devc);
2694 }
2695 pcm_shutdown(devc, rport, wport);
2696 return 0;
2697
2698 case SNDCTL_DSP_SYNC: /* _SIO ('P', 1) */
2699 DBGX("SNDCTL_DSP_SYNC\n");
2700 if (wport) {
2701 pcm_flush_frag(devc);
2702 pcm_write_sync(devc);
2703 }
2704 pcm_shutdown(devc, rport, wport);
2705 return 0;
2706
2707 case SNDCTL_DSP_POST: /* _SIO ('P', 8) */
2708 DBGX("SNDCTL_DSP_POST\n");
2709 if (!wport)
2710 return -EINVAL;
2711 pcm_flush_frag(devc);
2712 return 0;
2713
2714 case SNDCTL_DSP_GETIPTR: /* _SIOR ('P', 17, count_info) */
2715 DBGX("SNDCTL_DSP_GETIPTR\n");
2716 if (!rport)
2717 return -EINVAL;
2718 spin_lock_irqsave(&rport->lock, flags);
2719 {
2720 ustmsc_t ustmsc;
2721 if (rport->hwstate == HW_RUNNING) {
2722 ASSERT(rport->swstate == SW_RUN);
2723 li_read_USTMSC(&rport->chan, &ustmsc);
2724 info.bytes = ustmsc.msc - rport->MSC_offset;
2725 info.bytes *= rport->frame_size;
2726 } else {
2727 info.bytes = rport->byte_count;
2728 }
2729 info.blocks = rport->frag_count;
2730 info.ptr = 0; /* not implemented */
2731 rport->frag_count = 0;
2732 }
2733 spin_unlock_irqrestore(&rport->lock, flags);
2734 if (copy_to_user((void *) arg, &info, sizeof info))
2735 return -EFAULT;
2736 return 0;
2737
2738 case SNDCTL_DSP_GETOPTR: /* _SIOR ('P',18, count_info) */
2739 DBGX("SNDCTL_DSP_GETOPTR\n");
2740 if (!wport)
2741 return -EINVAL;
2742 spin_lock_irqsave(&wport->lock, flags);
2743 {
2744 ustmsc_t ustmsc;
2745 if (wport->hwstate == HW_RUNNING) {
2746 ASSERT(wport->swstate == SW_RUN);
2747 li_read_USTMSC(&wport->chan, &ustmsc);
2748 info.bytes = ustmsc.msc - wport->MSC_offset;
2749 info.bytes *= wport->frame_size;
2750 } else {
2751 info.bytes = wport->byte_count;
2752 }
2753 info.blocks = wport->frag_count;
2754 info.ptr = 0; /* not implemented */
2755 wport->frag_count = 0;
2756 }
2757 spin_unlock_irqrestore(&wport->lock, flags);
2758 if (copy_to_user((void *) arg, &info, sizeof info))
2759 return -EFAULT;
2760 return 0;
2761
2762 case SNDCTL_DSP_GETODELAY: /* _SIOR ('P', 23, int) */
2763 DBGX("SNDCTL_DSP_GETODELAY\n");
2764 if (!wport)
2765 return -EINVAL;
2766 spin_lock_irqsave(&wport->lock, flags);
2767 {
2768 int fsize = wport->frame_size;
2769 ival = wport->swb_i_avail / fsize;
2770 if (wport->hwstate == HW_RUNNING) {
2771 int swptr, hwptr, hwframes, hwbytes, hwsize;
2772 int totalhwbytes;
2773 ustmsc_t ustmsc;
2774
2775 hwsize = wport->hwbuf_size;
2776 swptr = li_read_swptr(&wport->chan);
2777 li_read_USTMSC(&wport->chan, &ustmsc);
2778 hwframes = ustmsc.msc - wport->MSC_offset;
2779 totalhwbytes = hwframes * fsize;
2780 hwptr = totalhwbytes % hwsize;
2781 hwbytes = (swptr - hwptr + hwsize) % hwsize;
2782 ival += hwbytes / fsize;
2783 }
2784 }
2785 spin_unlock_irqrestore(&wport->lock, flags);
2786 return put_user(ival, (int *) arg);
2787
2788 case SNDCTL_DSP_PROFILE: /* _SIOW ('P', 23, int) */
2789 DBGX("SNDCTL_DSP_PROFILE\n");
2790
2791 /*
2792 * Thomas Sailer explains SNDCTL_DSP_PROFILE
2793 * (private email, March 24, 1999):
2794 *
2795 * This gives the sound driver a hint on what it
2796 * should do with partial fragments
2797 * (i.e. fragments partially filled with write).
2798 * This can direct the driver to zero them or
2799 * leave them alone. But don't ask me what this
2800 * is good for, my driver just zeroes the last
2801 * fragment before the receiver stops, no idea
2802 * what good for any other behaviour could
2803 * be. Implementing it as NOP seems safe.
2804 */
2805
2806 break;
2807
2808 case SNDCTL_DSP_GETTRIGGER: /* _SIOR ('P',16, int) */
2809 DBGX("SNDCTL_DSP_GETTRIGGER\n");
2810 ival = 0;
2811 if (rport) {
2812 spin_lock_irqsave(&rport->lock, flags);
2813 {
2814 if (!(rport->flags & DISABLED))
2815 ival |= PCM_ENABLE_INPUT;
2816 }
2817 spin_unlock_irqrestore(&rport->lock, flags);
2818 }
2819 if (wport) {
2820 spin_lock_irqsave(&wport->lock, flags);
2821 {
2822 if (!(wport->flags & DISABLED))
2823 ival |= PCM_ENABLE_OUTPUT;
2824 }
2825 spin_unlock_irqrestore(&wport->lock, flags);
2826 }
2827 return put_user(ival, (int *) arg);
2828
2829 case SNDCTL_DSP_SETTRIGGER: /* _SIOW ('P',16, int) */
2830 if (get_user(ival, (int *) arg))
2831 return -EFAULT;
2832 DBGX("SNDCTL_DSP_SETTRIGGER %d\n", ival);
2833
2834 /*
2835 * If user is disabling I/O and port is not in initial
2836 * state, fail with EINVAL.
2837 */
2838
2839 if (((rport && !(ival & PCM_ENABLE_INPUT)) ||
2840 (wport && !(ival & PCM_ENABLE_OUTPUT))) &&
2841 aport->swstate != SW_INITIAL)
2842 return -EINVAL;
2843
2844 if (rport) {
2845 vwsnd_port_hwstate_t hwstate;
2846 spin_lock_irqsave(&rport->lock, flags);
2847 {
2848 hwstate = rport->hwstate;
2849 if (ival & PCM_ENABLE_INPUT)
2850 rport->flags &= ~DISABLED;
2851 else
2852 rport->flags |= DISABLED;
2853 }
2854 spin_unlock_irqrestore(&rport->lock, flags);
2855 if (hwstate != HW_RUNNING && ival & PCM_ENABLE_INPUT) {
2856
2857 if (rport->swstate == SW_INITIAL)
2858 pcm_setup(devc, rport, wport);
2859 else
2860 li_activate_dma(&rport->chan);
2861 }
2862 }
2863 if (wport) {
2864 vwsnd_port_flags_t pflags;
2865 spin_lock_irqsave(&wport->lock, flags);
2866 {
2867 pflags = wport->flags;
2868 if (ival & PCM_ENABLE_OUTPUT)
2869 wport->flags &= ~DISABLED;
2870 else
2871 wport->flags |= DISABLED;
2872 }
2873 spin_unlock_irqrestore(&wport->lock, flags);
2874 if (pflags & DISABLED && ival & PCM_ENABLE_OUTPUT) {
2875 if (wport->swstate == SW_RUN)
2876 pcm_output(devc, 0, 0);
2877 }
2878 }
2879 return 0;
2880
2881 default:
2882 DBGP("unknown ioctl 0x%x\n", cmd);
2883 return -EINVAL;
2884 }
2885 DBGP("unimplemented ioctl 0x%x\n", cmd);
2886 return -EINVAL;
2887}
2888
2889static long vwsnd_audio_ioctl(struct file *file,
2890 unsigned int cmd,
2891 unsigned long arg)
2892{
2893 vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
2894 int ret;
2895
2896 mutex_lock(&vwsnd_mutex);
2897 mutex_lock(&devc->io_mutex);
2898 ret = vwsnd_audio_do_ioctl(file, cmd, arg);
2899 mutex_unlock(&devc->io_mutex);
2900 mutex_unlock(&vwsnd_mutex);
2901
2902 return ret;
2903}
2904
2905/* No mmap. */
2906
2907static int vwsnd_audio_mmap(struct file *file, struct vm_area_struct *vma)
2908{
2909 DBGE("(file=0x%p, vma=0x%p)\n", file, vma);
2910 return -ENODEV;
2911}
2912
2913/*
2914 * Open the audio device for read and/or write.
2915 *
2916 * Returns 0 on success, -errno on failure.
2917 */
2918
2919static int vwsnd_audio_open(struct inode *inode, struct file *file)
2920{
2921 vwsnd_dev_t *devc;
2922 int minor = iminor(inode);
2923 int sw_samplefmt;
2924 DEFINE_WAIT(wait);
2925
2926 DBGE("(inode=0x%p, file=0x%p)\n", inode, file);
2927
2928 mutex_lock(&vwsnd_mutex);
2929 INC_USE_COUNT;
2930 for (devc = vwsnd_dev_list; devc; devc = devc->next_dev)
2931 if ((devc->audio_minor & ~0x0F) == (minor & ~0x0F))
2932 break;
2933
2934 if (devc == NULL) {
2935 DEC_USE_COUNT;
2936 mutex_unlock(&vwsnd_mutex);
2937 return -ENODEV;
2938 }
2939
2940 mutex_lock(&devc->open_mutex);
2941 while (1) {
2942 prepare_to_wait(&devc->open_wait, &wait, TASK_INTERRUPTIBLE);
2943 if (!(devc->open_mode & file->f_mode))
2944 break;
2945
2946 mutex_unlock(&devc->open_mutex);
2947 mutex_unlock(&vwsnd_mutex);
2948 if (file->f_flags & O_NONBLOCK) {
2949 DEC_USE_COUNT;
2950 return -EBUSY;
2951 }
2952 schedule();
2953 if (signal_pending(current)) {
2954 DEC_USE_COUNT;
2955 return -ERESTARTSYS;
2956 }
2957 mutex_lock(&vwsnd_mutex);
2958 mutex_lock(&devc->open_mutex);
2959 }
2960 finish_wait(&devc->open_wait, &wait);
2961 devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
2962 mutex_unlock(&devc->open_mutex);
2963
2964 /* get default sample format from minor number. */
2965
2966 sw_samplefmt = 0;
2967 if ((minor & 0xF) == SND_DEV_DSP)
2968 sw_samplefmt = AFMT_U8;
2969 else if ((minor & 0xF) == SND_DEV_AUDIO)
2970 sw_samplefmt = AFMT_MU_LAW;
2971 else if ((minor & 0xF) == SND_DEV_DSP16)
2972 sw_samplefmt = AFMT_S16_LE;
2973 else
2974 ASSERT(0);
2975
2976 /* Initialize vwsnd_ports. */
2977
2978 mutex_lock(&devc->io_mutex);
2979 {
2980 if (file->f_mode & FMODE_READ) {
2981 devc->rport.swstate = SW_INITIAL;
2982 devc->rport.flags = 0;
2983 devc->rport.sw_channels = 1;
2984 devc->rport.sw_samplefmt = sw_samplefmt;
2985 devc->rport.sw_framerate = 8000;
2986 devc->rport.sw_fragshift = DEFAULT_FRAGSHIFT;
2987 devc->rport.sw_fragcount = DEFAULT_FRAGCOUNT;
2988 devc->rport.sw_subdivshift = DEFAULT_SUBDIVSHIFT;
2989 devc->rport.byte_count = 0;
2990 devc->rport.frag_count = 0;
2991 }
2992 if (file->f_mode & FMODE_WRITE) {
2993 devc->wport.swstate = SW_INITIAL;
2994 devc->wport.flags = 0;
2995 devc->wport.sw_channels = 1;
2996 devc->wport.sw_samplefmt = sw_samplefmt;
2997 devc->wport.sw_framerate = 8000;
2998 devc->wport.sw_fragshift = DEFAULT_FRAGSHIFT;
2999 devc->wport.sw_fragcount = DEFAULT_FRAGCOUNT;
3000 devc->wport.sw_subdivshift = DEFAULT_SUBDIVSHIFT;
3001 devc->wport.byte_count = 0;
3002 devc->wport.frag_count = 0;
3003 }
3004 }
3005 mutex_unlock(&devc->io_mutex);
3006
3007 file->private_data = devc;
3008 DBGRV();
3009 mutex_unlock(&vwsnd_mutex);
3010 return 0;
3011}
3012
3013/*
3014 * Release (close) the audio device.
3015 */
3016
3017static int vwsnd_audio_release(struct inode *inode, struct file *file)
3018{
3019 vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
3020 vwsnd_port_t *wport = NULL, *rport = NULL;
3021 int err = 0;
3022
3023 mutex_lock(&vwsnd_mutex);
3024 mutex_lock(&devc->io_mutex);
3025 {
3026 DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
3027
3028 if (file->f_mode & FMODE_READ)
3029 rport = &devc->rport;
3030 if (file->f_mode & FMODE_WRITE) {
3031 wport = &devc->wport;
3032 pcm_flush_frag(devc);
3033 pcm_write_sync(devc);
3034 }
3035 pcm_shutdown(devc, rport, wport);
3036 if (rport)
3037 rport->swstate = SW_OFF;
3038 if (wport)
3039 wport->swstate = SW_OFF;
3040 }
3041 mutex_unlock(&devc->io_mutex);
3042
3043 mutex_lock(&devc->open_mutex);
3044 {
3045 devc->open_mode &= ~file->f_mode;
3046 }
3047 mutex_unlock(&devc->open_mutex);
3048 wake_up(&devc->open_wait);
3049 DEC_USE_COUNT;
3050 DBGR();
3051 mutex_unlock(&vwsnd_mutex);
3052 return err;
3053}
3054
3055static const struct file_operations vwsnd_audio_fops = {
3056 .owner = THIS_MODULE,
3057 .llseek = no_llseek,
3058 .read = vwsnd_audio_read,
3059 .write = vwsnd_audio_write,
3060 .poll = vwsnd_audio_poll,
3061 .unlocked_ioctl = vwsnd_audio_ioctl,
3062 .mmap = vwsnd_audio_mmap,
3063 .open = vwsnd_audio_open,
3064 .release = vwsnd_audio_release,
3065};
3066
3067/*****************************************************************************/
3068/* mixer driver */
3069
3070/* open the mixer device. */
3071
3072static int vwsnd_mixer_open(struct inode *inode, struct file *file)
3073{
3074 vwsnd_dev_t *devc;
3075
3076 DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
3077
3078 INC_USE_COUNT;
3079 mutex_lock(&vwsnd_mutex);
3080 for (devc = vwsnd_dev_list; devc; devc = devc->next_dev)
3081 if (devc->mixer_minor == iminor(inode))
3082 break;
3083
3084 if (devc == NULL) {
3085 DEC_USE_COUNT;
3086 mutex_unlock(&vwsnd_mutex);
3087 return -ENODEV;
3088 }
3089 file->private_data = devc;
3090 mutex_unlock(&vwsnd_mutex);
3091 return 0;
3092}
3093
3094/* release (close) the mixer device. */
3095
3096static int vwsnd_mixer_release(struct inode *inode, struct file *file)
3097{
3098 DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
3099 DEC_USE_COUNT;
3100 return 0;
3101}
3102
3103/* mixer_read_ioctl handles all read ioctls on the mixer device. */
3104
3105static int mixer_read_ioctl(vwsnd_dev_t *devc, unsigned int nr, void __user *arg)
3106{
3107 int val = -1;
3108
3109 DBGEV("(devc=0x%p, nr=0x%x, arg=0x%p)\n", devc, nr, arg);
3110
3111 switch (nr) {
3112 case SOUND_MIXER_CAPS:
3113 val = SOUND_CAP_EXCL_INPUT;
3114 break;
3115
3116 case SOUND_MIXER_DEVMASK:
3117 val = (SOUND_MASK_PCM | SOUND_MASK_LINE |
3118 SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_RECLEV);
3119 break;
3120
3121 case SOUND_MIXER_STEREODEVS:
3122 val = (SOUND_MASK_PCM | SOUND_MASK_LINE |
3123 SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_RECLEV);
3124 break;
3125
3126 case SOUND_MIXER_OUTMASK:
3127 val = (SOUND_MASK_PCM | SOUND_MASK_LINE |
3128 SOUND_MASK_MIC | SOUND_MASK_CD);
3129 break;
3130
3131 case SOUND_MIXER_RECMASK:
3132 val = (SOUND_MASK_PCM | SOUND_MASK_LINE |
3133 SOUND_MASK_MIC | SOUND_MASK_CD);
3134 break;
3135
3136 case SOUND_MIXER_PCM:
3137 val = ad1843_get_gain(&devc->lith, &ad1843_gain_PCM);
3138 break;
3139
3140 case SOUND_MIXER_LINE:
3141 val = ad1843_get_gain(&devc->lith, &ad1843_gain_LINE);
3142 break;
3143
3144 case SOUND_MIXER_MIC:
3145 val = ad1843_get_gain(&devc->lith, &ad1843_gain_MIC);
3146 break;
3147
3148 case SOUND_MIXER_CD:
3149 val = ad1843_get_gain(&devc->lith, &ad1843_gain_CD);
3150 break;
3151
3152 case SOUND_MIXER_RECLEV:
3153 val = ad1843_get_gain(&devc->lith, &ad1843_gain_RECLEV);
3154 break;
3155
3156 case SOUND_MIXER_RECSRC:
3157 val = ad1843_get_recsrc(&devc->lith);
3158 break;
3159
3160 case SOUND_MIXER_OUTSRC:
3161 val = ad1843_get_outsrc(&devc->lith);
3162 break;
3163
3164 default:
3165 return -EINVAL;
3166 }
3167 return put_user(val, (int __user *) arg);
3168}
3169
3170/* mixer_write_ioctl handles all write ioctls on the mixer device. */
3171
3172static int mixer_write_ioctl(vwsnd_dev_t *devc, unsigned int nr, void __user *arg)
3173{
3174 int val;
3175 int err;
3176
3177 DBGEV("(devc=0x%p, nr=0x%x, arg=0x%p)\n", devc, nr, arg);
3178
3179 err = get_user(val, (int __user *) arg);
3180 if (err)
3181 return -EFAULT;
3182 switch (nr) {
3183 case SOUND_MIXER_PCM:
3184 val = ad1843_set_gain(&devc->lith, &ad1843_gain_PCM, val);
3185 break;
3186
3187 case SOUND_MIXER_LINE:
3188 val = ad1843_set_gain(&devc->lith, &ad1843_gain_LINE, val);
3189 break;
3190
3191 case SOUND_MIXER_MIC:
3192 val = ad1843_set_gain(&devc->lith, &ad1843_gain_MIC, val);
3193 break;
3194
3195 case SOUND_MIXER_CD:
3196 val = ad1843_set_gain(&devc->lith, &ad1843_gain_CD, val);
3197 break;
3198
3199 case SOUND_MIXER_RECLEV:
3200 val = ad1843_set_gain(&devc->lith, &ad1843_gain_RECLEV, val);
3201 break;
3202
3203 case SOUND_MIXER_RECSRC:
3204 if (devc->rport.swbuf || devc->wport.swbuf)
3205 return -EBUSY; /* can't change recsrc while running */
3206 val = ad1843_set_recsrc(&devc->lith, val);
3207 break;
3208
3209 case SOUND_MIXER_OUTSRC:
3210 val = ad1843_set_outsrc(&devc->lith, val);
3211 break;
3212
3213 default:
3214 return -EINVAL;
3215 }
3216 if (val < 0)
3217 return val;
3218 return put_user(val, (int __user *) arg);
3219}
3220
3221/* This is the ioctl entry to the mixer driver. */
3222
3223static long vwsnd_mixer_ioctl(struct file *file,
3224 unsigned int cmd,
3225 unsigned long arg)
3226{
3227 vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
3228 const unsigned int nrmask = _IOC_NRMASK << _IOC_NRSHIFT;
3229 const unsigned int nr = (cmd & nrmask) >> _IOC_NRSHIFT;
3230 int retval;
3231
3232 DBGEV("(devc=0x%p, cmd=0x%x, arg=0x%lx)\n", devc, cmd, arg);
3233
3234 mutex_lock(&vwsnd_mutex);
3235 mutex_lock(&devc->mix_mutex);
3236 {
3237 if ((cmd & ~nrmask) == MIXER_READ(0))
3238 retval = mixer_read_ioctl(devc, nr, (void __user *) arg);
3239 else if ((cmd & ~nrmask) == MIXER_WRITE(0))
3240 retval = mixer_write_ioctl(devc, nr, (void __user *) arg);
3241 else
3242 retval = -EINVAL;
3243 }
3244 mutex_unlock(&devc->mix_mutex);
3245 mutex_unlock(&vwsnd_mutex);
3246 return retval;
3247}
3248
3249static const struct file_operations vwsnd_mixer_fops = {
3250 .owner = THIS_MODULE,
3251 .llseek = no_llseek,
3252 .unlocked_ioctl = vwsnd_mixer_ioctl,
3253 .open = vwsnd_mixer_open,
3254 .release = vwsnd_mixer_release,
3255};
3256
3257/*****************************************************************************/
3258/* probe/attach/unload */
3259
3260/* driver probe routine. Return nonzero if hardware is found. */
3261
3262static int __init probe_vwsnd(struct address_info *hw_config)
3263{
3264 lithium_t lith;
3265 int w;
3266 unsigned long later;
3267
3268 DBGEV("(hw_config=0x%p)\n", hw_config);
3269
3270 /* XXX verify lithium present (to prevent crash on non-vw) */
3271
3272 if (li_create(&lith, hw_config->io_base) != 0) {
3273 printk(KERN_WARNING "probe_vwsnd: can't map lithium\n");
3274 return 0;
3275 }
3276 later = jiffies + 2;
3277 li_writel(&lith, LI_HOST_CONTROLLER, LI_HC_LINK_ENABLE);
3278 do {
3279 w = li_readl(&lith, LI_HOST_CONTROLLER);
3280 } while (w == LI_HC_LINK_ENABLE && time_before(jiffies, later));
3281
3282 li_destroy(&lith);
3283
3284 DBGPV("HC = 0x%04x\n", w);
3285
3286 if ((w == LI_HC_LINK_ENABLE) || (w & LI_HC_LINK_CODEC)) {
3287
3288 /* This may indicate a beta machine with no audio,
3289 * or a future machine with different audio.
3290 * On beta-release 320 w/ no audio, HC == 0x4000 */
3291
3292 printk(KERN_WARNING "probe_vwsnd: audio codec not found\n");
3293 return 0;
3294 }
3295
3296 if (w & LI_HC_LINK_FAILURE) {
3297 printk(KERN_WARNING "probe_vwsnd: can't init audio codec\n");
3298 return 0;
3299 }
3300
3301 printk(KERN_INFO "vwsnd: lithium audio at mmio %#x irq %d\n",
3302 hw_config->io_base, hw_config->irq);
3303
3304 return 1;
3305}
3306
3307/*
3308 * driver attach routine. Initialize driver data structures and
3309 * initialize hardware. A new vwsnd_dev_t is allocated and put
3310 * onto the global list, vwsnd_dev_list.
3311 *
3312 * Return +minor_dev on success, -errno on failure.
3313 */
3314
3315static int __init attach_vwsnd(struct address_info *hw_config)
3316{
3317 vwsnd_dev_t *devc = NULL;
3318 int err = -ENOMEM;
3319
3320 DBGEV("(hw_config=0x%p)\n", hw_config);
3321
3322 devc = kmalloc(sizeof (vwsnd_dev_t), GFP_KERNEL);
3323 if (devc == NULL)
3324 goto fail0;
3325
3326 err = li_create(&devc->lith, hw_config->io_base);
3327 if (err)
3328 goto fail1;
3329
3330 init_waitqueue_head(&devc->open_wait);
3331
3332 devc->rport.hwbuf_size = HWBUF_SIZE;
3333 devc->rport.hwbuf_vaddr = __get_free_pages(GFP_KERNEL, HWBUF_ORDER);
3334 if (!devc->rport.hwbuf_vaddr)
3335 goto fail2;
3336 devc->rport.hwbuf = (void *) devc->rport.hwbuf_vaddr;
3337 devc->rport.hwbuf_paddr = virt_to_phys(devc->rport.hwbuf);
3338
3339 /*
3340 * Quote from the NT driver:
3341 *
3342 * // WARNING!!! HACK to setup output dma!!!
3343 * // This is required because even on output there is some data
3344 * // trickling into the input DMA channel. This is a bug in the
3345 * // Lithium microcode.
3346 * // --sde
3347 *
3348 * We set the input side's DMA base address here. It will remain
3349 * valid until the driver is unloaded.
3350 */
3351
3352 li_writel(&devc->lith, LI_COMM1_BASE,
3353 devc->rport.hwbuf_paddr >> 8 | 1 << (37 - 8));
3354
3355 devc->wport.hwbuf_size = HWBUF_SIZE;
3356 devc->wport.hwbuf_vaddr = __get_free_pages(GFP_KERNEL, HWBUF_ORDER);
3357 if (!devc->wport.hwbuf_vaddr)
3358 goto fail3;
3359 devc->wport.hwbuf = (void *) devc->wport.hwbuf_vaddr;
3360 devc->wport.hwbuf_paddr = virt_to_phys(devc->wport.hwbuf);
3361 DBGP("wport hwbuf = 0x%p\n", devc->wport.hwbuf);
3362
3363 DBGDO(shut_up++);
3364 err = ad1843_init(&devc->lith);
3365 DBGDO(shut_up--);
3366 if (err)
3367 goto fail4;
3368
3369 /* install interrupt handler */
3370
3371 err = request_irq(hw_config->irq, vwsnd_audio_intr, 0, "vwsnd", devc);
3372 if (err)
3373 goto fail5;
3374
3375 /* register this device's drivers. */
3376
3377 devc->audio_minor = register_sound_dsp(&vwsnd_audio_fops, -1);
3378 if ((err = devc->audio_minor) < 0) {
3379 DBGDO(printk(KERN_WARNING
3380 "attach_vwsnd: register_sound_dsp error %d\n",
3381 err));
3382 goto fail6;
3383 }
3384 devc->mixer_minor = register_sound_mixer(&vwsnd_mixer_fops,
3385 devc->audio_minor >> 4);
3386 if ((err = devc->mixer_minor) < 0) {
3387 DBGDO(printk(KERN_WARNING
3388 "attach_vwsnd: register_sound_mixer error %d\n",
3389 err));
3390 goto fail7;
3391 }
3392
3393 /* Squirrel away device indices for unload routine. */
3394
3395 hw_config->slots[0] = devc->audio_minor;
3396
3397 /* Initialize as much of *devc as possible */
3398
3399 mutex_init(&devc->open_mutex);
3400 mutex_init(&devc->io_mutex);
3401 mutex_init(&devc->mix_mutex);
3402 devc->open_mode = 0;
3403 spin_lock_init(&devc->rport.lock);
3404 init_waitqueue_head(&devc->rport.queue);
3405 devc->rport.swstate = SW_OFF;
3406 devc->rport.hwstate = HW_STOPPED;
3407 devc->rport.flags = 0;
3408 devc->rport.swbuf = NULL;
3409 spin_lock_init(&devc->wport.lock);
3410 init_waitqueue_head(&devc->wport.queue);
3411 devc->wport.swstate = SW_OFF;
3412 devc->wport.hwstate = HW_STOPPED;
3413 devc->wport.flags = 0;
3414 devc->wport.swbuf = NULL;
3415
3416 /* Success. Link us onto the local device list. */
3417
3418 devc->next_dev = vwsnd_dev_list;
3419 vwsnd_dev_list = devc;
3420 return devc->audio_minor;
3421
3422 /* So many ways to fail. Undo what we did. */
3423
3424 fail7:
3425 unregister_sound_dsp(devc->audio_minor);
3426 fail6:
3427 free_irq(hw_config->irq, devc);
3428 fail5:
3429 fail4:
3430 free_pages(devc->wport.hwbuf_vaddr, HWBUF_ORDER);
3431 fail3:
3432 free_pages(devc->rport.hwbuf_vaddr, HWBUF_ORDER);
3433 fail2:
3434 li_destroy(&devc->lith);
3435 fail1:
3436 kfree(devc);
3437 fail0:
3438 return err;
3439}
3440
3441static int __exit unload_vwsnd(struct address_info *hw_config)
3442{
3443 vwsnd_dev_t *devc, **devcp;
3444
3445 DBGE("()\n");
3446
3447 devcp = &vwsnd_dev_list;
3448 while ((devc = *devcp)) {
3449 if (devc->audio_minor == hw_config->slots[0]) {
3450 *devcp = devc->next_dev;
3451 break;
3452 }
3453 devcp = &devc->next_dev;
3454 }
3455
3456 if (!devc)
3457 return -ENODEV;
3458
3459 unregister_sound_mixer(devc->mixer_minor);
3460 unregister_sound_dsp(devc->audio_minor);
3461 free_irq(hw_config->irq, devc);
3462 free_pages(devc->wport.hwbuf_vaddr, HWBUF_ORDER);
3463 free_pages(devc->rport.hwbuf_vaddr, HWBUF_ORDER);
3464 li_destroy(&devc->lith);
3465 kfree(devc);
3466
3467 return 0;
3468}
3469
3470/*****************************************************************************/
3471/* initialization and loadable kernel module interface */
3472
3473static struct address_info the_hw_config = {
3474 0xFF001000, /* lithium phys addr */
3475 CO_IRQ(CO_APIC_LI_AUDIO) /* irq */
3476};
3477
3478MODULE_DESCRIPTION("SGI Visual Workstation sound module");
3479MODULE_AUTHOR("Bob Miller <kbob@sgi.com>");
3480MODULE_LICENSE("GPL");
3481
3482static int __init init_vwsnd(void)
3483{
3484 int err;
3485
3486 DBGXV("\n");
3487 DBGXV("sound::vwsnd::init_module()\n");
3488
3489 if (!probe_vwsnd(&the_hw_config))
3490 return -ENODEV;
3491
3492 err = attach_vwsnd(&the_hw_config);
3493 if (err < 0)
3494 return err;
3495 return 0;
3496}
3497
3498static void __exit cleanup_vwsnd(void)
3499{
3500 DBGX("sound::vwsnd::cleanup_module()\n");
3501
3502 unload_vwsnd(&the_hw_config);
3503}
3504
3505module_init(init_vwsnd);
3506module_exit(cleanup_vwsnd);