diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-11-25 02:45:43 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-11-25 02:45:43 -0500 |
commit | 1ad2096c4eba144522d87541c4024b8c84e95051 (patch) | |
tree | a149d469a4da72a7b6e6b777879b740046c4ebc9 | |
parent | c4d73e7d75a54451d6e073c118ba2b8d87bd350d (diff) | |
parent | df73af86b6e737f357aae85e0b5e621516117780 (diff) |
Merge branch 'rmobile/mmcif' into rmobile-latest
116 files changed, 8336 insertions, 1942 deletions
diff --git a/Documentation/DocBook/sh.tmpl b/Documentation/DocBook/sh.tmpl index d858d92cf6d9..4a38f604fa66 100644 --- a/Documentation/DocBook/sh.tmpl +++ b/Documentation/DocBook/sh.tmpl | |||
@@ -79,10 +79,6 @@ | |||
79 | </sect2> | 79 | </sect2> |
80 | </sect1> | 80 | </sect1> |
81 | </chapter> | 81 | </chapter> |
82 | <chapter id="clk"> | ||
83 | <title>Clock Framework Extensions</title> | ||
84 | !Iinclude/linux/sh_clk.h | ||
85 | </chapter> | ||
86 | <chapter id="mach"> | 82 | <chapter id="mach"> |
87 | <title>Machine Specific Interfaces</title> | 83 | <title>Machine Specific Interfaces</title> |
88 | <sect1 id="dreamcast"> | 84 | <sect1 id="dreamcast"> |
diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX index a618fd99c9f0..30a70542e823 100644 --- a/Documentation/fb/00-INDEX +++ b/Documentation/fb/00-INDEX | |||
@@ -4,33 +4,41 @@ please mail me. | |||
4 | Geert Uytterhoeven <geert@linux-m68k.org> | 4 | Geert Uytterhoeven <geert@linux-m68k.org> |
5 | 5 | ||
6 | 00-INDEX | 6 | 00-INDEX |
7 | - this file | 7 | - this file. |
8 | arkfb.txt | 8 | arkfb.txt |
9 | - info on the fbdev driver for ARK Logic chips. | 9 | - info on the fbdev driver for ARK Logic chips. |
10 | aty128fb.txt | 10 | aty128fb.txt |
11 | - info on the ATI Rage128 frame buffer driver. | 11 | - info on the ATI Rage128 frame buffer driver. |
12 | cirrusfb.txt | 12 | cirrusfb.txt |
13 | - info on the driver for Cirrus Logic chipsets. | 13 | - info on the driver for Cirrus Logic chipsets. |
14 | cmap_xfbdev.txt | ||
15 | - an introduction to fbdev's cmap structures. | ||
14 | deferred_io.txt | 16 | deferred_io.txt |
15 | - an introduction to deferred IO. | 17 | - an introduction to deferred IO. |
18 | efifb.txt | ||
19 | - info on the EFI platform driver for Intel based Apple computers. | ||
20 | ep93xx-fb.txt | ||
21 | - info on the driver for EP93xx LCD controller. | ||
16 | fbcon.txt | 22 | fbcon.txt |
17 | - intro to and usage guide for the framebuffer console (fbcon). | 23 | - intro to and usage guide for the framebuffer console (fbcon). |
18 | framebuffer.txt | 24 | framebuffer.txt |
19 | - introduction to frame buffer devices. | 25 | - introduction to frame buffer devices. |
20 | imacfb.txt | 26 | gxfb.txt |
21 | - info on the generic EFI platform driver for Intel based Macs. | 27 | - info on the framebuffer driver for AMD Geode GX2 based processors. |
22 | intel810.txt | 28 | intel810.txt |
23 | - documentation for the Intel 810/815 framebuffer driver. | 29 | - documentation for the Intel 810/815 framebuffer driver. |
24 | intelfb.txt | 30 | intelfb.txt |
25 | - docs for Intel 830M/845G/852GM/855GM/865G/915G/945G fb driver. | 31 | - docs for Intel 830M/845G/852GM/855GM/865G/915G/945G fb driver. |
26 | internals.txt | 32 | internals.txt |
27 | - quick overview of frame buffer device internals. | 33 | - quick overview of frame buffer device internals. |
34 | lxfb.txt | ||
35 | - info on the framebuffer driver for AMD Geode LX based processors. | ||
28 | matroxfb.txt | 36 | matroxfb.txt |
29 | - info on the Matrox framebuffer driver for Alpha, Intel and PPC. | 37 | - info on the Matrox framebuffer driver for Alpha, Intel and PPC. |
38 | metronomefb.txt | ||
39 | - info on the driver for the Metronome display controller. | ||
30 | modedb.txt | 40 | modedb.txt |
31 | - info on the video mode database. | 41 | - info on the video mode database. |
32 | matroxfb.txt | ||
33 | - info on the Matrox frame buffer driver. | ||
34 | pvr2fb.txt | 42 | pvr2fb.txt |
35 | - info on the PowerVR 2 frame buffer driver. | 43 | - info on the PowerVR 2 frame buffer driver. |
36 | pxafb.txt | 44 | pxafb.txt |
@@ -39,13 +47,23 @@ s3fb.txt | |||
39 | - info on the fbdev driver for S3 Trio/Virge chips. | 47 | - info on the fbdev driver for S3 Trio/Virge chips. |
40 | sa1100fb.txt | 48 | sa1100fb.txt |
41 | - information about the driver for the SA-1100 LCD controller. | 49 | - information about the driver for the SA-1100 LCD controller. |
50 | sh7760fb.txt | ||
51 | - info on the SH7760/SH7763 integrated LCDC Framebuffer driver. | ||
42 | sisfb.txt | 52 | sisfb.txt |
43 | - info on the framebuffer device driver for various SiS chips. | 53 | - info on the framebuffer device driver for various SiS chips. |
44 | sstfb.txt | 54 | sstfb.txt |
45 | - info on the frame buffer driver for 3dfx' Voodoo Graphics boards. | 55 | - info on the frame buffer driver for 3dfx' Voodoo Graphics boards. |
46 | tgafb.txt | 56 | tgafb.txt |
47 | - info on the TGA (DECChip 21030) frame buffer driver | 57 | - info on the TGA (DECChip 21030) frame buffer driver. |
58 | tridentfb.txt | ||
59 | info on the framebuffer driver for some Trident chip based cards. | ||
60 | uvesafb.txt | ||
61 | - info on the userspace VESA (VBE2+ compliant) frame buffer device. | ||
48 | vesafb.txt | 62 | vesafb.txt |
49 | - info on the VESA frame buffer device | 63 | - info on the VESA frame buffer device. |
64 | viafb.modes | ||
65 | - list of modes for VIA Integration Graphic Chip. | ||
66 | viafb.txt | ||
67 | - info on the VIA Integration Graphic Chip console framebuffer driver. | ||
50 | vt8623fb.txt | 68 | vt8623fb.txt |
51 | - info on the fb driver for the graphics core in VIA VT8623 chipsets. | 69 | - info on the fb driver for the graphics core in VIA VT8623 chipsets. |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 92e83e53148f..cdd2a6e8a3b7 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2385,6 +2385,11 @@ and is between 256 and 4096 characters. It is defined in the file | |||
2385 | improve throughput, but will also increase the | 2385 | improve throughput, but will also increase the |
2386 | amount of memory reserved for use by the client. | 2386 | amount of memory reserved for use by the client. |
2387 | 2387 | ||
2388 | swapaccount[=0|1] | ||
2389 | [KNL] Enable accounting of swap in memory resource | ||
2390 | controller if no parameter or 1 is given or disable | ||
2391 | it if 0 is given (See Documentation/cgroups/memory.txt) | ||
2392 | |||
2388 | swiotlb= [IA-64] Number of I/O TLB slabs | 2393 | swiotlb= [IA-64] Number of I/O TLB slabs |
2389 | 2394 | ||
2390 | switches= [HW,M68k] | 2395 | switches= [HW,M68k] |
diff --git a/Documentation/sh/clk.txt b/Documentation/sh/clk.txt deleted file mode 100644 index 114b595cfa97..000000000000 --- a/Documentation/sh/clk.txt +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | Clock framework on SuperH architecture | ||
2 | |||
3 | The framework on SH extends existing API by the function clk_set_rate_ex, | ||
4 | which prototype is as follows: | ||
5 | |||
6 | clk_set_rate_ex (struct clk *clk, unsigned long rate, int algo_id) | ||
7 | |||
8 | The algo_id parameter is used to specify algorithm used to recalculate clocks, | ||
9 | adjanced to clock, specified as first argument. It is assumed that algo_id==0 | ||
10 | means no changes to adjanced clock | ||
11 | |||
12 | Internally, the clk_set_rate_ex forwards request to clk->ops->set_rate method, | ||
13 | if it is present in ops structure. The method should set the clock rate and adjust | ||
14 | all needed clocks according to the passed algo_id. | ||
15 | Exact values for algo_id are machine-dependent. For the sh7722, the following | ||
16 | values are defined: | ||
17 | |||
18 | NO_CHANGE = 0, | ||
19 | IUS_N1_N1, /* I:U = N:1, U:Sh = N:1 */ | ||
20 | IUS_322, /* I:U:Sh = 3:2:2 */ | ||
21 | IUS_522, /* I:U:Sh = 5:2:2 */ | ||
22 | IUS_N11, /* I:U:Sh = N:1:1 */ | ||
23 | SB_N1, /* Sh:B = N:1 */ | ||
24 | SB3_N1, /* Sh:B3 = N:1 */ | ||
25 | SB3_32, /* Sh:B3 = 3:2 */ | ||
26 | SB3_43, /* Sh:B3 = 4:3 */ | ||
27 | SB3_54, /* Sh:B3 = 5:4 */ | ||
28 | BP_N1, /* B:P = N:1 */ | ||
29 | IP_N1 /* I:P = N:1 */ | ||
30 | |||
31 | Each of these constants means relation between clocks that can be set via the FRQCR | ||
32 | register | ||
diff --git a/MAINTAINERS b/MAINTAINERS index b49ba9a43bf8..b3be8b3d0437 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2444,10 +2444,12 @@ F: drivers/net/wan/sdla.c | |||
2444 | FRAMEBUFFER LAYER | 2444 | FRAMEBUFFER LAYER |
2445 | L: linux-fbdev@vger.kernel.org | 2445 | L: linux-fbdev@vger.kernel.org |
2446 | W: http://linux-fbdev.sourceforge.net/ | 2446 | W: http://linux-fbdev.sourceforge.net/ |
2447 | Q: http://patchwork.kernel.org/project/linux-fbdev/list/ | ||
2447 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6.git | 2448 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6.git |
2448 | S: Orphan | 2449 | S: Orphan |
2449 | F: Documentation/fb/ | 2450 | F: Documentation/fb/ |
2450 | F: drivers/video/fb* | 2451 | F: drivers/video/ |
2452 | F: include/video/ | ||
2451 | F: include/linux/fb.h | 2453 | F: include/linux/fb.h |
2452 | 2454 | ||
2453 | FREESCALE DMA DRIVER | 2455 | FREESCALE DMA DRIVER |
@@ -5837,6 +5839,8 @@ M: Chris Metcalf <cmetcalf@tilera.com> | |||
5837 | W: http://www.tilera.com/scm/ | 5839 | W: http://www.tilera.com/scm/ |
5838 | S: Supported | 5840 | S: Supported |
5839 | F: arch/tile/ | 5841 | F: arch/tile/ |
5842 | F: drivers/char/hvc_tile.c | ||
5843 | F: drivers/net/tile/ | ||
5840 | 5844 | ||
5841 | TLAN NETWORK DRIVER | 5845 | TLAN NETWORK DRIVER |
5842 | M: Samuel Chessman <chessman@tux.org> | 5846 | M: Samuel Chessman <chessman@tux.org> |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 6825c34646d4..9be21ba648cd 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -1084,6 +1084,6 @@ memdump: mov r12, r0 | |||
1084 | reloc_end: | 1084 | reloc_end: |
1085 | 1085 | ||
1086 | .align | 1086 | .align |
1087 | .section ".stack", "w" | 1087 | .section ".stack", "aw", %nobits |
1088 | user_stack: .space 4096 | 1088 | user_stack: .space 4096 |
1089 | user_stack_end: | 1089 | user_stack_end: |
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in index d08168941bd6..366a924019ac 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.in +++ b/arch/arm/boot/compressed/vmlinux.lds.in | |||
@@ -57,7 +57,7 @@ SECTIONS | |||
57 | .bss : { *(.bss) } | 57 | .bss : { *(.bss) } |
58 | _end = .; | 58 | _end = .; |
59 | 59 | ||
60 | .stack (NOLOAD) : { *(.stack) } | 60 | .stack : { *(.stack) } |
61 | 61 | ||
62 | .stab 0 : { *(.stab) } | 62 | .stab 0 : { *(.stab) } |
63 | .stabstr 0 : { *(.stabstr) } | 63 | .stabstr 0 : { *(.stabstr) } |
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 062b58c029ab..749bb6622404 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h | |||
@@ -238,7 +238,7 @@ | |||
238 | @ Slightly optimised to avoid incrementing the pointer twice | 238 | @ Slightly optimised to avoid incrementing the pointer twice |
239 | usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort | 239 | usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort |
240 | .if \rept == 2 | 240 | .if \rept == 2 |
241 | usraccoff \instr, \reg, \ptr, \inc, 4, \cond, \abort | 241 | usraccoff \instr, \reg, \ptr, \inc, \inc, \cond, \abort |
242 | .endif | 242 | .endif |
243 | 243 | ||
244 | add\cond \ptr, #\rept * \inc | 244 | add\cond \ptr, #\rept * \inc |
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h index 68870c776671..b4ffe9d5b526 100644 --- a/arch/arm/include/asm/mmu.h +++ b/arch/arm/include/asm/mmu.h | |||
@@ -13,6 +13,10 @@ typedef struct { | |||
13 | 13 | ||
14 | #ifdef CONFIG_CPU_HAS_ASID | 14 | #ifdef CONFIG_CPU_HAS_ASID |
15 | #define ASID(mm) ((mm)->context.id & 255) | 15 | #define ASID(mm) ((mm)->context.id & 255) |
16 | |||
17 | /* init_mm.context.id_lock should be initialized. */ | ||
18 | #define INIT_MM_CONTEXT(name) \ | ||
19 | .context.id_lock = __SPIN_LOCK_UNLOCKED(name.context.id_lock), | ||
16 | #else | 20 | #else |
17 | #define ASID(mm) (0) | 21 | #define ASID(mm) (0) |
18 | #endif | 22 | #endif |
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index b155414192da..53d1d5deb111 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
@@ -374,6 +374,9 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd) | |||
374 | 374 | ||
375 | #define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd))) | 375 | #define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd))) |
376 | 376 | ||
377 | /* we don't need complex calculations here as the pmd is folded into the pgd */ | ||
378 | #define pmd_addr_end(addr,end) (end) | ||
379 | |||
377 | /* | 380 | /* |
378 | * Conversion functions: convert a page and protection to a page entry, | 381 | * Conversion functions: convert a page and protection to a page entry, |
379 | * and a page entry and page directory to the page they refer to. | 382 | * and a page entry and page directory to the page they refer to. |
diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S index 1e4cbd4e7be9..64f6bc1a9132 100644 --- a/arch/arm/lib/findbit.S +++ b/arch/arm/lib/findbit.S | |||
@@ -174,8 +174,8 @@ ENDPROC(_find_next_bit_be) | |||
174 | */ | 174 | */ |
175 | .L_found: | 175 | .L_found: |
176 | #if __LINUX_ARM_ARCH__ >= 5 | 176 | #if __LINUX_ARM_ARCH__ >= 5 |
177 | rsb r1, r3, #0 | 177 | rsb r0, r3, #0 |
178 | and r3, r3, r1 | 178 | and r3, r3, r0 |
179 | clz r3, r3 | 179 | clz r3, r3 |
180 | rsb r3, r3, #31 | 180 | rsb r3, r3, #31 |
181 | add r0, r2, r3 | 181 | add r0, r2, r3 |
@@ -190,5 +190,7 @@ ENDPROC(_find_next_bit_be) | |||
190 | addeq r2, r2, #1 | 190 | addeq r2, r2, #1 |
191 | mov r0, r2 | 191 | mov r0, r2 |
192 | #endif | 192 | #endif |
193 | cmp r1, r0 @ Clamp to maxbit | ||
194 | movlo r0, r1 | ||
193 | mov pc, lr | 195 | mov pc, lr |
194 | 196 | ||
diff --git a/arch/arm/mach-aaec2000/include/mach/vmalloc.h b/arch/arm/mach-aaec2000/include/mach/vmalloc.h index cff4e0a996ce..a6299e8321bd 100644 --- a/arch/arm/mach-aaec2000/include/mach/vmalloc.h +++ b/arch/arm/mach-aaec2000/include/mach/vmalloc.h | |||
@@ -11,6 +11,6 @@ | |||
11 | #ifndef __ASM_ARCH_VMALLOC_H | 11 | #ifndef __ASM_ARCH_VMALLOC_H |
12 | #define __ASM_ARCH_VMALLOC_H | 12 | #define __ASM_ARCH_VMALLOC_H |
13 | 13 | ||
14 | #define VMALLOC_END 0xd0000000 | 14 | #define VMALLOC_END 0xd0000000UL |
15 | 15 | ||
16 | #endif /* __ASM_ARCH_VMALLOC_H */ | 16 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/arch/arm/mach-bcmring/include/mach/vmalloc.h b/arch/arm/mach-bcmring/include/mach/vmalloc.h index 3db3a09fd398..7397bd7817d9 100644 --- a/arch/arm/mach-bcmring/include/mach/vmalloc.h +++ b/arch/arm/mach-bcmring/include/mach/vmalloc.h | |||
@@ -22,4 +22,4 @@ | |||
22 | * 0xe0000000 to 0xefffffff. This gives us 256 MB of vm space and handles | 22 | * 0xe0000000 to 0xefffffff. This gives us 256 MB of vm space and handles |
23 | * larger physical memory designs better. | 23 | * larger physical memory designs better. |
24 | */ | 24 | */ |
25 | #define VMALLOC_END 0xf0000000 | 25 | #define VMALLOC_END 0xf0000000UL |
diff --git a/arch/arm/mach-clps711x/include/mach/vmalloc.h b/arch/arm/mach-clps711x/include/mach/vmalloc.h index 30b3a287ed88..467b96137e47 100644 --- a/arch/arm/mach-clps711x/include/mach/vmalloc.h +++ b/arch/arm/mach-clps711x/include/mach/vmalloc.h | |||
@@ -17,4 +17,4 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | #define VMALLOC_END 0xd0000000 | 20 | #define VMALLOC_END 0xd0000000UL |
diff --git a/arch/arm/mach-ebsa110/include/mach/vmalloc.h b/arch/arm/mach-ebsa110/include/mach/vmalloc.h index 60bde56fba4c..ea141b7a3e03 100644 --- a/arch/arm/mach-ebsa110/include/mach/vmalloc.h +++ b/arch/arm/mach-ebsa110/include/mach/vmalloc.h | |||
@@ -7,4 +7,4 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #define VMALLOC_END 0xdf000000 | 10 | #define VMALLOC_END 0xdf000000UL |
diff --git a/arch/arm/mach-footbridge/include/mach/vmalloc.h b/arch/arm/mach-footbridge/include/mach/vmalloc.h index 0ffbb7c85e59..40ba78e5782b 100644 --- a/arch/arm/mach-footbridge/include/mach/vmalloc.h +++ b/arch/arm/mach-footbridge/include/mach/vmalloc.h | |||
@@ -7,4 +7,4 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | 9 | ||
10 | #define VMALLOC_END 0xf0000000 | 10 | #define VMALLOC_END 0xf0000000UL |
diff --git a/arch/arm/mach-h720x/include/mach/vmalloc.h b/arch/arm/mach-h720x/include/mach/vmalloc.h index a45915b88756..8520b4a4d4e6 100644 --- a/arch/arm/mach-h720x/include/mach/vmalloc.h +++ b/arch/arm/mach-h720x/include/mach/vmalloc.h | |||
@@ -5,6 +5,6 @@ | |||
5 | #ifndef __ARCH_ARM_VMALLOC_H | 5 | #ifndef __ARCH_ARM_VMALLOC_H |
6 | #define __ARCH_ARM_VMALLOC_H | 6 | #define __ARCH_ARM_VMALLOC_H |
7 | 7 | ||
8 | #define VMALLOC_END 0xd0000000 | 8 | #define VMALLOC_END 0xd0000000UL |
9 | 9 | ||
10 | #endif | 10 | #endif |
diff --git a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c index 026263c665ca..7e1e9dc2c8fc 100644 --- a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c +++ b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c | |||
@@ -250,9 +250,6 @@ static const struct imxuart_platform_data uart_pdata __initconst = { | |||
250 | .flags = IMXUART_HAVE_RTSCTS, | 250 | .flags = IMXUART_HAVE_RTSCTS, |
251 | }; | 251 | }; |
252 | 252 | ||
253 | #if defined(CONFIG_TOUCHSCREEN_ADS7846) \ | ||
254 | || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) | ||
255 | |||
256 | #define ADS7846_PENDOWN (GPIO_PORTD | 25) | 253 | #define ADS7846_PENDOWN (GPIO_PORTD | 25) |
257 | 254 | ||
258 | static void ads7846_dev_init(void) | 255 | static void ads7846_dev_init(void) |
@@ -273,9 +270,7 @@ static struct ads7846_platform_data ads7846_config __initdata = { | |||
273 | .get_pendown_state = ads7846_get_pendown_state, | 270 | .get_pendown_state = ads7846_get_pendown_state, |
274 | .keep_vref_on = 1, | 271 | .keep_vref_on = 1, |
275 | }; | 272 | }; |
276 | #endif | ||
277 | 273 | ||
278 | #if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) | ||
279 | static struct spi_board_info eukrea_mbimx27_spi_board_info[] __initdata = { | 274 | static struct spi_board_info eukrea_mbimx27_spi_board_info[] __initdata = { |
280 | [0] = { | 275 | [0] = { |
281 | .modalias = "ads7846", | 276 | .modalias = "ads7846", |
@@ -294,7 +289,6 @@ static const struct spi_imx_master eukrea_mbimx27_spi0_data __initconst = { | |||
294 | .chipselect = eukrea_mbimx27_spi_cs, | 289 | .chipselect = eukrea_mbimx27_spi_cs, |
295 | .num_chipselect = ARRAY_SIZE(eukrea_mbimx27_spi_cs), | 290 | .num_chipselect = ARRAY_SIZE(eukrea_mbimx27_spi_cs), |
296 | }; | 291 | }; |
297 | #endif | ||
298 | 292 | ||
299 | static struct i2c_board_info eukrea_mbimx27_i2c_devices[] = { | 293 | static struct i2c_board_info eukrea_mbimx27_i2c_devices[] = { |
300 | { | 294 | { |
diff --git a/arch/arm/mach-integrator/include/mach/vmalloc.h b/arch/arm/mach-integrator/include/mach/vmalloc.h index e056e7cf5645..2f5a2bafb11f 100644 --- a/arch/arm/mach-integrator/include/mach/vmalloc.h +++ b/arch/arm/mach-integrator/include/mach/vmalloc.h | |||
@@ -17,4 +17,4 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | #define VMALLOC_END 0xd0000000 | 20 | #define VMALLOC_END 0xd0000000UL |
diff --git a/arch/arm/mach-msm/include/mach/vmalloc.h b/arch/arm/mach-msm/include/mach/vmalloc.h index 31a32ad062dc..d138448eff16 100644 --- a/arch/arm/mach-msm/include/mach/vmalloc.h +++ b/arch/arm/mach-msm/include/mach/vmalloc.h | |||
@@ -16,7 +16,7 @@ | |||
16 | #ifndef __ASM_ARCH_MSM_VMALLOC_H | 16 | #ifndef __ASM_ARCH_MSM_VMALLOC_H |
17 | #define __ASM_ARCH_MSM_VMALLOC_H | 17 | #define __ASM_ARCH_MSM_VMALLOC_H |
18 | 18 | ||
19 | #define VMALLOC_END 0xd0000000 | 19 | #define VMALLOC_END 0xd0000000UL |
20 | 20 | ||
21 | #endif | 21 | #endif |
22 | 22 | ||
diff --git a/arch/arm/mach-mx25/devices-imx25.h b/arch/arm/mach-mx25/devices-imx25.h index 93afa10b13cf..d94d282fa676 100644 --- a/arch/arm/mach-mx25/devices-imx25.h +++ b/arch/arm/mach-mx25/devices-imx25.h | |||
@@ -42,9 +42,9 @@ extern const struct imx_mxc_nand_data imx25_mxc_nand_data __initconst; | |||
42 | #define imx25_add_mxc_nand(pdata) \ | 42 | #define imx25_add_mxc_nand(pdata) \ |
43 | imx_add_mxc_nand(&imx25_mxc_nand_data, pdata) | 43 | imx_add_mxc_nand(&imx25_mxc_nand_data, pdata) |
44 | 44 | ||
45 | extern const struct imx_spi_imx_data imx25_spi_imx_data[] __initconst; | 45 | extern const struct imx_spi_imx_data imx25_cspi_data[] __initconst; |
46 | #define imx25_add_spi_imx(id, pdata) \ | 46 | #define imx25_add_spi_imx(id, pdata) \ |
47 | imx_add_spi_imx(&imx25_spi_imx_data[id], pdata) | 47 | imx_add_spi_imx(&imx25_cspi_data[id], pdata) |
48 | #define imx25_add_spi_imx0(pdata) imx25_add_spi_imx(0, pdata) | 48 | #define imx25_add_spi_imx0(pdata) imx25_add_spi_imx(0, pdata) |
49 | #define imx25_add_spi_imx1(pdata) imx25_add_spi_imx(1, pdata) | 49 | #define imx25_add_spi_imx1(pdata) imx25_add_spi_imx(1, pdata) |
50 | #define imx25_add_spi_imx2(pdata) imx25_add_spi_imx(2, pdata) | 50 | #define imx25_add_spi_imx2(pdata) imx25_add_spi_imx(2, pdata) |
diff --git a/arch/arm/mach-mx3/mach-pcm037_eet.c b/arch/arm/mach-mx3/mach-pcm037_eet.c index 99e0894e07db..fda56545d2fd 100644 --- a/arch/arm/mach-mx3/mach-pcm037_eet.c +++ b/arch/arm/mach-mx3/mach-pcm037_eet.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include <mach/common.h> | 15 | #include <mach/common.h> |
16 | #include <mach/iomux-mx3.h> | 16 | #include <mach/iomux-mx3.h> |
17 | #include <mach/spi.h> | ||
17 | 18 | ||
18 | #include <asm/mach-types.h> | 19 | #include <asm/mach-types.h> |
19 | 20 | ||
@@ -59,14 +60,12 @@ static struct spi_board_info pcm037_spi_dev[] = { | |||
59 | }; | 60 | }; |
60 | 61 | ||
61 | /* Platform Data for MXC CSPI */ | 62 | /* Platform Data for MXC CSPI */ |
62 | #if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) | ||
63 | static int pcm037_spi1_cs[] = {MXC_SPI_CS(1), IOMUX_TO_GPIO(MX31_PIN_KEY_COL7)}; | 63 | static int pcm037_spi1_cs[] = {MXC_SPI_CS(1), IOMUX_TO_GPIO(MX31_PIN_KEY_COL7)}; |
64 | 64 | ||
65 | static const struct spi_imx_master pcm037_spi1_pdata __initconst = { | 65 | static const struct spi_imx_master pcm037_spi1_pdata __initconst = { |
66 | .chipselect = pcm037_spi1_cs, | 66 | .chipselect = pcm037_spi1_cs, |
67 | .num_chipselect = ARRAY_SIZE(pcm037_spi1_cs), | 67 | .num_chipselect = ARRAY_SIZE(pcm037_spi1_cs), |
68 | }; | 68 | }; |
69 | #endif | ||
70 | 69 | ||
71 | /* GPIO-keys input device */ | 70 | /* GPIO-keys input device */ |
72 | static struct gpio_keys_button pcm037_gpio_keys[] = { | 71 | static struct gpio_keys_button pcm037_gpio_keys[] = { |
@@ -171,7 +170,7 @@ static struct platform_device pcm037_gpio_keys_device = { | |||
171 | }, | 170 | }, |
172 | }; | 171 | }; |
173 | 172 | ||
174 | static int eet_init_devices(void) | 173 | static int __init eet_init_devices(void) |
175 | { | 174 | { |
176 | if (!machine_is_pcm037() || pcm037_variant() != PCM037_EET) | 175 | if (!machine_is_pcm037() || pcm037_variant() != PCM037_EET) |
177 | return 0; | 176 | return 0; |
diff --git a/arch/arm/mach-netx/include/mach/vmalloc.h b/arch/arm/mach-netx/include/mach/vmalloc.h index 7cca3574308f..871f1ef7bff5 100644 --- a/arch/arm/mach-netx/include/mach/vmalloc.h +++ b/arch/arm/mach-netx/include/mach/vmalloc.h | |||
@@ -16,4 +16,4 @@ | |||
16 | * along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | */ | 18 | */ |
19 | #define VMALLOC_END 0xd0000000 | 19 | #define VMALLOC_END 0xd0000000UL |
diff --git a/arch/arm/mach-omap1/include/mach/vmalloc.h b/arch/arm/mach-omap1/include/mach/vmalloc.h index b001f67d695b..22ec4a479577 100644 --- a/arch/arm/mach-omap1/include/mach/vmalloc.h +++ b/arch/arm/mach-omap1/include/mach/vmalloc.h | |||
@@ -17,4 +17,4 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | #define VMALLOC_END 0xd8000000 | 20 | #define VMALLOC_END 0xd8000000UL |
diff --git a/arch/arm/mach-omap2/include/mach/vmalloc.h b/arch/arm/mach-omap2/include/mach/vmalloc.h index 4da31e997efe..866319947760 100644 --- a/arch/arm/mach-omap2/include/mach/vmalloc.h +++ b/arch/arm/mach-omap2/include/mach/vmalloc.h | |||
@@ -17,4 +17,4 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | #define VMALLOC_END 0xf8000000 | 20 | #define VMALLOC_END 0xf8000000UL |
diff --git a/arch/arm/mach-pnx4008/include/mach/vmalloc.h b/arch/arm/mach-pnx4008/include/mach/vmalloc.h index 31b65ee07b0b..184913c71141 100644 --- a/arch/arm/mach-pnx4008/include/mach/vmalloc.h +++ b/arch/arm/mach-pnx4008/include/mach/vmalloc.h | |||
@@ -17,4 +17,4 @@ | |||
17 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | 17 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced |
18 | * area for the same reason. ;) | 18 | * area for the same reason. ;) |
19 | */ | 19 | */ |
20 | #define VMALLOC_END 0xd0000000 | 20 | #define VMALLOC_END 0xd0000000UL |
diff --git a/arch/arm/mach-rpc/include/mach/vmalloc.h b/arch/arm/mach-rpc/include/mach/vmalloc.h index 3bcd86fadb81..fb700228637a 100644 --- a/arch/arm/mach-rpc/include/mach/vmalloc.h +++ b/arch/arm/mach-rpc/include/mach/vmalloc.h | |||
@@ -7,4 +7,4 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #define VMALLOC_END 0xdc000000 | 10 | #define VMALLOC_END 0xdc000000UL |
diff --git a/arch/arm/mach-shark/include/mach/vmalloc.h b/arch/arm/mach-shark/include/mach/vmalloc.h index 8e845b6a7cb5..b10df988526d 100644 --- a/arch/arm/mach-shark/include/mach/vmalloc.h +++ b/arch/arm/mach-shark/include/mach/vmalloc.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arm/mach-shark/include/mach/vmalloc.h | 2 | * arch/arm/mach-shark/include/mach/vmalloc.h |
3 | */ | 3 | */ |
4 | #define VMALLOC_END 0xd0000000 | 4 | #define VMALLOC_END 0xd0000000UL |
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index d440e5f456ad..5b079529c948 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
@@ -272,6 +272,15 @@ static struct resource sh_mmcif_resources[] = { | |||
272 | }, | 272 | }, |
273 | }; | 273 | }; |
274 | 274 | ||
275 | static struct sh_mmcif_dma sh_mmcif_dma = { | ||
276 | .chan_priv_rx = { | ||
277 | .slave_id = SHDMA_SLAVE_MMCIF_RX, | ||
278 | }, | ||
279 | .chan_priv_tx = { | ||
280 | .slave_id = SHDMA_SLAVE_MMCIF_TX, | ||
281 | }, | ||
282 | }; | ||
283 | |||
275 | static struct sh_mmcif_plat_data sh_mmcif_plat = { | 284 | static struct sh_mmcif_plat_data sh_mmcif_plat = { |
276 | .sup_pclk = 0, | 285 | .sup_pclk = 0, |
277 | .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, | 286 | .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, |
@@ -279,6 +288,7 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = { | |||
279 | MMC_CAP_8_BIT_DATA | | 288 | MMC_CAP_8_BIT_DATA | |
280 | MMC_CAP_NEEDS_POLL, | 289 | MMC_CAP_NEEDS_POLL, |
281 | .get_cd = slot_cn7_get_cd, | 290 | .get_cd = slot_cn7_get_cd, |
291 | .dma = &sh_mmcif_dma, | ||
282 | }; | 292 | }; |
283 | 293 | ||
284 | static struct platform_device sh_mmcif_device = { | 294 | static struct platform_device sh_mmcif_device = { |
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index e18a1241a95e..eb92fefc084d 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c | |||
@@ -220,8 +220,7 @@ static void pllc2_disable(struct clk *clk) | |||
220 | __raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR); | 220 | __raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR); |
221 | } | 221 | } |
222 | 222 | ||
223 | static int pllc2_set_rate(struct clk *clk, | 223 | static int pllc2_set_rate(struct clk *clk, unsigned long rate) |
224 | unsigned long rate, int algo_id) | ||
225 | { | 224 | { |
226 | unsigned long value; | 225 | unsigned long value; |
227 | int idx; | 226 | int idx; |
@@ -453,8 +452,7 @@ static int fsidiv_enable(struct clk *clk) | |||
453 | return 0; | 452 | return 0; |
454 | } | 453 | } |
455 | 454 | ||
456 | static int fsidiv_set_rate(struct clk *clk, | 455 | static int fsidiv_set_rate(struct clk *clk, unsigned long rate) |
457 | unsigned long rate, int algo_id) | ||
458 | { | 456 | { |
459 | int idx; | 457 | int idx; |
460 | 458 | ||
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index e4f9004e7103..5736efcca60c 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h | |||
@@ -455,6 +455,8 @@ enum { | |||
455 | SHDMA_SLAVE_SDHI1_TX, | 455 | SHDMA_SLAVE_SDHI1_TX, |
456 | SHDMA_SLAVE_SDHI2_RX, | 456 | SHDMA_SLAVE_SDHI2_RX, |
457 | SHDMA_SLAVE_SDHI2_TX, | 457 | SHDMA_SLAVE_SDHI2_TX, |
458 | SHDMA_SLAVE_MMCIF_RX, | ||
459 | SHDMA_SLAVE_MMCIF_TX, | ||
458 | }; | 460 | }; |
459 | 461 | ||
460 | extern struct clk sh7372_extal1_clk; | 462 | extern struct clk sh7372_extal1_clk; |
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 564a6d0be473..2e3e11ee7c43 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c | |||
@@ -416,6 +416,16 @@ static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = { | |||
416 | .addr = 0xe6870030, | 416 | .addr = 0xe6870030, |
417 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), | 417 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), |
418 | .mid_rid = 0xce, | 418 | .mid_rid = 0xce, |
419 | }, { | ||
420 | .slave_id = SHDMA_SLAVE_MMCIF_TX, | ||
421 | .addr = 0xe6bd0034, | ||
422 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT), | ||
423 | .mid_rid = 0xd1, | ||
424 | }, { | ||
425 | .slave_id = SHDMA_SLAVE_MMCIF_RX, | ||
426 | .addr = 0xe6bd0034, | ||
427 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT), | ||
428 | .mid_rid = 0xd2, | ||
419 | }, | 429 | }, |
420 | }; | 430 | }; |
421 | 431 | ||
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index 73fb1a551ec6..608a1372b172 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c | |||
@@ -75,14 +75,14 @@ void __init ux500_init_irq(void) | |||
75 | static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask) | 75 | static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask) |
76 | { | 76 | { |
77 | /* wait for the operation to complete */ | 77 | /* wait for the operation to complete */ |
78 | while (readl(reg) & mask) | 78 | while (readl_relaxed(reg) & mask) |
79 | ; | 79 | ; |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline void ux500_cache_sync(void) | 82 | static inline void ux500_cache_sync(void) |
83 | { | 83 | { |
84 | void __iomem *base = __io_address(UX500_L2CC_BASE); | 84 | void __iomem *base = __io_address(UX500_L2CC_BASE); |
85 | writel(0, base + L2X0_CACHE_SYNC); | 85 | writel_relaxed(0, base + L2X0_CACHE_SYNC); |
86 | ux500_cache_wait(base + L2X0_CACHE_SYNC, 1); | 86 | ux500_cache_wait(base + L2X0_CACHE_SYNC, 1); |
87 | } | 87 | } |
88 | 88 | ||
@@ -107,7 +107,7 @@ static void ux500_l2x0_inv_all(void) | |||
107 | uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */ | 107 | uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */ |
108 | 108 | ||
109 | /* invalidate all ways */ | 109 | /* invalidate all ways */ |
110 | writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY); | 110 | writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY); |
111 | ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); | 111 | ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); |
112 | ux500_cache_sync(); | 112 | ux500_cache_sync(); |
113 | } | 113 | } |
diff --git a/arch/arm/mach-versatile/include/mach/vmalloc.h b/arch/arm/mach-versatile/include/mach/vmalloc.h index ebd8a2543d3b..7d8e069ad51b 100644 --- a/arch/arm/mach-versatile/include/mach/vmalloc.h +++ b/arch/arm/mach-versatile/include/mach/vmalloc.h | |||
@@ -18,4 +18,4 @@ | |||
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | #define VMALLOC_END 0xd8000000 | 21 | #define VMALLOC_END 0xd8000000UL |
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 17e7b0b57e49..55c17a6fb22f 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c | |||
@@ -206,8 +206,8 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn, | |||
206 | */ | 206 | */ |
207 | if (pfn_valid(pfn)) { | 207 | if (pfn_valid(pfn)) { |
208 | printk(KERN_WARNING "BUG: Your driver calls ioremap() on system memory. This leads\n" | 208 | printk(KERN_WARNING "BUG: Your driver calls ioremap() on system memory. This leads\n" |
209 | KERN_WARNING "to architecturally unpredictable behaviour on ARMv6+, and ioremap()\n" | 209 | "to architecturally unpredictable behaviour on ARMv6+, and ioremap()\n" |
210 | KERN_WARNING "will fail in the next kernel release. Please fix your driver.\n"); | 210 | "will fail in the next kernel release. Please fix your driver.\n"); |
211 | WARN_ON(1); | 211 | WARN_ON(1); |
212 | } | 212 | } |
213 | 213 | ||
diff --git a/arch/arm/plat-mxc/devices/platform-imx-dma.c b/arch/arm/plat-mxc/devices/platform-imx-dma.c index 02d989018059..3a705c7877dd 100644 --- a/arch/arm/plat-mxc/devices/platform-imx-dma.c +++ b/arch/arm/plat-mxc/devices/platform-imx-dma.c | |||
@@ -12,15 +12,7 @@ | |||
12 | 12 | ||
13 | #include <mach/hardware.h> | 13 | #include <mach/hardware.h> |
14 | #include <mach/devices-common.h> | 14 | #include <mach/devices-common.h> |
15 | #ifdef SDMA_IS_MERGED | ||
16 | #include <mach/sdma.h> | 15 | #include <mach/sdma.h> |
17 | #else | ||
18 | struct sdma_platform_data { | ||
19 | int sdma_version; | ||
20 | char *cpu_name; | ||
21 | int to_version; | ||
22 | }; | ||
23 | #endif | ||
24 | 16 | ||
25 | struct imx_imx_sdma_data { | 17 | struct imx_imx_sdma_data { |
26 | resource_size_t iobase; | 18 | resource_size_t iobase; |
diff --git a/arch/arm/plat-mxc/devices/platform-spi_imx.c b/arch/arm/plat-mxc/devices/platform-spi_imx.c index e48340ec331e..17f724c9452d 100644 --- a/arch/arm/plat-mxc/devices/platform-spi_imx.c +++ b/arch/arm/plat-mxc/devices/platform-spi_imx.c | |||
@@ -27,6 +27,7 @@ const struct imx_spi_imx_data imx21_cspi_data[] __initconst = { | |||
27 | imx_spi_imx_data_entry(MX21, CSPI, "imx21-cspi", _id, _hwid, SZ_4K) | 27 | imx_spi_imx_data_entry(MX21, CSPI, "imx21-cspi", _id, _hwid, SZ_4K) |
28 | imx21_cspi_data_entry(0, 1), | 28 | imx21_cspi_data_entry(0, 1), |
29 | imx21_cspi_data_entry(1, 2), | 29 | imx21_cspi_data_entry(1, 2), |
30 | }; | ||
30 | #endif | 31 | #endif |
31 | 32 | ||
32 | #ifdef CONFIG_ARCH_MX25 | 33 | #ifdef CONFIG_ARCH_MX25 |
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c index aedf9c1d645e..63cdc6025bd7 100644 --- a/arch/arm/plat-nomadik/timer.c +++ b/arch/arm/plat-nomadik/timer.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2008 STMicroelectronics | 4 | * Copyright (C) 2008 STMicroelectronics |
5 | * Copyright (C) 2010 Alessandro Rubini | 5 | * Copyright (C) 2010 Alessandro Rubini |
6 | * Copyright (C) 2010 Linus Walleij for ST-Ericsson | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2, as | 9 | * it under the terms of the GNU General Public License version 2, as |
@@ -16,11 +17,13 @@ | |||
16 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
17 | #include <linux/jiffies.h> | 18 | #include <linux/jiffies.h> |
18 | #include <linux/err.h> | 19 | #include <linux/err.h> |
20 | #include <linux/cnt32_to_63.h> | ||
21 | #include <linux/timer.h> | ||
19 | #include <asm/mach/time.h> | 22 | #include <asm/mach/time.h> |
20 | 23 | ||
21 | #include <plat/mtu.h> | 24 | #include <plat/mtu.h> |
22 | 25 | ||
23 | void __iomem *mtu_base; /* ssigned by machine code */ | 26 | void __iomem *mtu_base; /* Assigned by machine code */ |
24 | 27 | ||
25 | /* | 28 | /* |
26 | * Kernel assumes that sched_clock can be called early | 29 | * Kernel assumes that sched_clock can be called early |
@@ -48,16 +51,82 @@ static struct clocksource nmdk_clksrc = { | |||
48 | /* | 51 | /* |
49 | * Override the global weak sched_clock symbol with this | 52 | * Override the global weak sched_clock symbol with this |
50 | * local implementation which uses the clocksource to get some | 53 | * local implementation which uses the clocksource to get some |
51 | * better resolution when scheduling the kernel. We accept that | 54 | * better resolution when scheduling the kernel. |
52 | * this wraps around for now, since it is just a relative time | 55 | * |
53 | * stamp. (Inspired by OMAP implementation.) | 56 | * Because the hardware timer period may be quite short |
57 | * (32.3 secs on the 133 MHz MTU timer selection on ux500) | ||
58 | * and because cnt32_to_63() needs to be called at least once per | ||
59 | * half period to work properly, a kernel keepwarm() timer is set up | ||
60 | * to ensure this requirement is always met. | ||
61 | * | ||
62 | * Also the sched_clock timer will wrap around at some point, | ||
63 | * here we set it to run continously for a year. | ||
54 | */ | 64 | */ |
65 | #define SCHED_CLOCK_MIN_WRAP 3600*24*365 | ||
66 | static struct timer_list cnt32_to_63_keepwarm_timer; | ||
67 | static u32 sched_mult; | ||
68 | static u32 sched_shift; | ||
69 | |||
55 | unsigned long long notrace sched_clock(void) | 70 | unsigned long long notrace sched_clock(void) |
56 | { | 71 | { |
57 | return clocksource_cyc2ns(nmdk_clksrc.read( | 72 | u64 cycles; |
58 | &nmdk_clksrc), | 73 | |
59 | nmdk_clksrc.mult, | 74 | if (unlikely(!mtu_base)) |
60 | nmdk_clksrc.shift); | 75 | return 0; |
76 | |||
77 | cycles = cnt32_to_63(-readl(mtu_base + MTU_VAL(0))); | ||
78 | /* | ||
79 | * sched_mult is guaranteed to be even so will | ||
80 | * shift out bit 63 | ||
81 | */ | ||
82 | return (cycles * sched_mult) >> sched_shift; | ||
83 | } | ||
84 | |||
85 | /* Just kick sched_clock every so often */ | ||
86 | static void cnt32_to_63_keepwarm(unsigned long data) | ||
87 | { | ||
88 | mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data)); | ||
89 | (void) sched_clock(); | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * Set up a timer to keep sched_clock():s 32_to_63 algorithm warm | ||
94 | * once in half a 32bit timer wrap interval. | ||
95 | */ | ||
96 | static void __init nmdk_sched_clock_init(unsigned long rate) | ||
97 | { | ||
98 | u32 v; | ||
99 | unsigned long delta; | ||
100 | u64 days; | ||
101 | |||
102 | /* Find the apropriate mult and shift factors */ | ||
103 | clocks_calc_mult_shift(&sched_mult, &sched_shift, | ||
104 | rate, NSEC_PER_SEC, SCHED_CLOCK_MIN_WRAP); | ||
105 | /* We need to multiply by an even number to get rid of bit 63 */ | ||
106 | if (sched_mult & 1) | ||
107 | sched_mult++; | ||
108 | |||
109 | /* Let's see what we get, take max counter and scale it */ | ||
110 | days = (0xFFFFFFFFFFFFFFFFLLU * sched_mult) >> sched_shift; | ||
111 | do_div(days, NSEC_PER_SEC); | ||
112 | do_div(days, (3600*24)); | ||
113 | |||
114 | pr_info("sched_clock: using %d bits @ %lu Hz wrap in %lu days\n", | ||
115 | (64 - sched_shift), rate, (unsigned long) days); | ||
116 | |||
117 | /* | ||
118 | * Program a timer to kick us at half 32bit wraparound | ||
119 | * Formula: seconds per wrap = (2^32) / f | ||
120 | */ | ||
121 | v = 0xFFFFFFFFUL / rate; | ||
122 | /* We want half of the wrap time to keep cnt32_to_63 warm */ | ||
123 | v /= 2; | ||
124 | pr_debug("sched_clock: prescaled timer rate: %lu Hz, " | ||
125 | "initialize keepwarm timer every %d seconds\n", rate, v); | ||
126 | /* Convert seconds to jiffies */ | ||
127 | delta = msecs_to_jiffies(v*1000); | ||
128 | setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, delta); | ||
129 | mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + delta)); | ||
61 | } | 130 | } |
62 | 131 | ||
63 | /* Clockevent device: use one-shot mode */ | 132 | /* Clockevent device: use one-shot mode */ |
@@ -161,13 +230,15 @@ void __init nmdk_timer_init(void) | |||
161 | writel(0, mtu_base + MTU_BGLR(0)); | 230 | writel(0, mtu_base + MTU_BGLR(0)); |
162 | writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); | 231 | writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); |
163 | 232 | ||
164 | /* Now the scheduling clock is ready */ | 233 | /* Now the clock source is ready */ |
165 | nmdk_clksrc.read = nmdk_read_timer; | 234 | nmdk_clksrc.read = nmdk_read_timer; |
166 | 235 | ||
167 | if (clocksource_register(&nmdk_clksrc)) | 236 | if (clocksource_register(&nmdk_clksrc)) |
168 | pr_err("timer: failed to initialize clock source %s\n", | 237 | pr_err("timer: failed to initialize clock source %s\n", |
169 | nmdk_clksrc.name); | 238 | nmdk_clksrc.name); |
170 | 239 | ||
240 | nmdk_sched_clock_init(rate); | ||
241 | |||
171 | /* Timer 1 is used for events */ | 242 | /* Timer 1 is used for events */ |
172 | 243 | ||
173 | clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); | 244 | clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); |
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index 46d5179c9f49..e3c73cdd8c90 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h | |||
@@ -199,10 +199,13 @@ extern unsigned long get_wchan(struct task_struct *p); | |||
199 | #define ARCH_HAS_PREFETCHW | 199 | #define ARCH_HAS_PREFETCHW |
200 | static inline void prefetch(void *x) | 200 | static inline void prefetch(void *x) |
201 | { | 201 | { |
202 | __asm__ __volatile__ ("pref @%0\n\t" : : "r" (x) : "memory"); | 202 | __builtin_prefetch(x, 0, 3); |
203 | } | 203 | } |
204 | 204 | ||
205 | #define prefetchw(x) prefetch(x) | 205 | static inline void prefetchw(void *x) |
206 | { | ||
207 | __builtin_prefetch(x, 1, 3); | ||
208 | } | ||
206 | #endif | 209 | #endif |
207 | 210 | ||
208 | #endif /* __KERNEL__ */ | 211 | #endif /* __KERNEL__ */ |
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index 4eabc68cd753..b601fa3978d1 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c | |||
@@ -110,7 +110,7 @@ static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate) | |||
110 | return 0; | 110 | return 0; |
111 | } | 111 | } |
112 | 112 | ||
113 | static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id) | 113 | static int shoc_clk_set_rate(struct clk *clk, unsigned long rate) |
114 | { | 114 | { |
115 | unsigned long frqcr3; | 115 | unsigned long frqcr3; |
116 | unsigned int tmp; | 116 | unsigned int tmp; |
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index 81f58371613d..8c6a350df751 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c | |||
@@ -88,7 +88,7 @@ asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op) | |||
88 | } | 88 | } |
89 | 89 | ||
90 | if (op & CACHEFLUSH_I) | 90 | if (op & CACHEFLUSH_I) |
91 | flush_cache_all(); | 91 | flush_icache_range(addr, addr+len); |
92 | 92 | ||
93 | up_read(¤t->mm->mmap_sem); | 93 | up_read(¤t->mm->mmap_sem); |
94 | return 0; | 94 | return 0; |
diff --git a/arch/sh/kernel/vsyscall/vsyscall-trapa.S b/arch/sh/kernel/vsyscall/vsyscall-trapa.S index 3b6eb34c43fa..3e70f851cdc6 100644 --- a/arch/sh/kernel/vsyscall/vsyscall-trapa.S +++ b/arch/sh/kernel/vsyscall/vsyscall-trapa.S | |||
@@ -8,9 +8,9 @@ __kernel_vsyscall: | |||
8 | * fill out .eh_frame -- PFM. */ | 8 | * fill out .eh_frame -- PFM. */ |
9 | .LEND_vsyscall: | 9 | .LEND_vsyscall: |
10 | .size __kernel_vsyscall,.-.LSTART_vsyscall | 10 | .size __kernel_vsyscall,.-.LSTART_vsyscall |
11 | .previous | ||
12 | 11 | ||
13 | .section .eh_frame,"a",@progbits | 12 | .section .eh_frame,"a",@progbits |
13 | .previous | ||
14 | .LCIE: | 14 | .LCIE: |
15 | .ualong .LCIE_end - .LCIE_start | 15 | .ualong .LCIE_end - .LCIE_start |
16 | .LCIE_start: | 16 | .LCIE_start: |
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 07ec8a865c1d..e11b5fcb70eb 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig | |||
@@ -329,6 +329,18 @@ endmenu # Tilera-specific configuration | |||
329 | 329 | ||
330 | menu "Bus options" | 330 | menu "Bus options" |
331 | 331 | ||
332 | config PCI | ||
333 | bool "PCI support" | ||
334 | default y | ||
335 | select PCI_DOMAINS | ||
336 | ---help--- | ||
337 | Enable PCI root complex support, so PCIe endpoint devices can | ||
338 | be attached to the Tile chip. Many, but not all, PCI devices | ||
339 | are supported under Tilera's root complex driver. | ||
340 | |||
341 | config PCI_DOMAINS | ||
342 | bool | ||
343 | |||
332 | config NO_IOMEM | 344 | config NO_IOMEM |
333 | def_bool !PCI | 345 | def_bool !PCI |
334 | 346 | ||
diff --git a/arch/tile/include/asm/cacheflush.h b/arch/tile/include/asm/cacheflush.h index c5741da4eeac..14a3f8556ace 100644 --- a/arch/tile/include/asm/cacheflush.h +++ b/arch/tile/include/asm/cacheflush.h | |||
@@ -137,4 +137,56 @@ static inline void finv_buffer(void *buffer, size_t size) | |||
137 | mb_incoherent(); | 137 | mb_incoherent(); |
138 | } | 138 | } |
139 | 139 | ||
140 | /* | ||
141 | * Flush & invalidate a VA range that is homed remotely on a single core, | ||
142 | * waiting until the memory controller holds the flushed values. | ||
143 | */ | ||
144 | static inline void finv_buffer_remote(void *buffer, size_t size) | ||
145 | { | ||
146 | char *p; | ||
147 | int i; | ||
148 | |||
149 | /* | ||
150 | * Flush and invalidate the buffer out of the local L1/L2 | ||
151 | * and request the home cache to flush and invalidate as well. | ||
152 | */ | ||
153 | __finv_buffer(buffer, size); | ||
154 | |||
155 | /* | ||
156 | * Wait for the home cache to acknowledge that it has processed | ||
157 | * all the flush-and-invalidate requests. This does not mean | ||
158 | * that the flushed data has reached the memory controller yet, | ||
159 | * but it does mean the home cache is processing the flushes. | ||
160 | */ | ||
161 | __insn_mf(); | ||
162 | |||
163 | /* | ||
164 | * Issue a load to the last cache line, which can't complete | ||
165 | * until all the previously-issued flushes to the same memory | ||
166 | * controller have also completed. If we weren't striping | ||
167 | * memory, that one load would be sufficient, but since we may | ||
168 | * be, we also need to back up to the last load issued to | ||
169 | * another memory controller, which would be the point where | ||
170 | * we crossed an 8KB boundary (the granularity of striping | ||
171 | * across memory controllers). Keep backing up and doing this | ||
172 | * until we are before the beginning of the buffer, or have | ||
173 | * hit all the controllers. | ||
174 | */ | ||
175 | for (i = 0, p = (char *)buffer + size - 1; | ||
176 | i < (1 << CHIP_LOG_NUM_MSHIMS()) && p >= (char *)buffer; | ||
177 | ++i) { | ||
178 | const unsigned long STRIPE_WIDTH = 8192; | ||
179 | |||
180 | /* Force a load instruction to issue. */ | ||
181 | *(volatile char *)p; | ||
182 | |||
183 | /* Jump to end of previous stripe. */ | ||
184 | p -= STRIPE_WIDTH; | ||
185 | p = (char *)((unsigned long)p | (STRIPE_WIDTH - 1)); | ||
186 | } | ||
187 | |||
188 | /* Wait for the loads (and thus flushes) to have completed. */ | ||
189 | __insn_mf(); | ||
190 | } | ||
191 | |||
140 | #endif /* _ASM_TILE_CACHEFLUSH_H */ | 192 | #endif /* _ASM_TILE_CACHEFLUSH_H */ |
diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h index ee43328713ab..d3cbb9b14cbe 100644 --- a/arch/tile/include/asm/io.h +++ b/arch/tile/include/asm/io.h | |||
@@ -55,9 +55,6 @@ extern void iounmap(volatile void __iomem *addr); | |||
55 | #define ioremap_writethrough(physaddr, size) ioremap(physaddr, size) | 55 | #define ioremap_writethrough(physaddr, size) ioremap(physaddr, size) |
56 | #define ioremap_fullcache(physaddr, size) ioremap(physaddr, size) | 56 | #define ioremap_fullcache(physaddr, size) ioremap(physaddr, size) |
57 | 57 | ||
58 | void __iomem *ioport_map(unsigned long port, unsigned int len); | ||
59 | extern inline void ioport_unmap(void __iomem *addr) {} | ||
60 | |||
61 | #define mmiowb() | 58 | #define mmiowb() |
62 | 59 | ||
63 | /* Conversion between virtual and physical mappings. */ | 60 | /* Conversion between virtual and physical mappings. */ |
@@ -189,12 +186,22 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, | |||
189 | * we never run, uses them unconditionally. | 186 | * we never run, uses them unconditionally. |
190 | */ | 187 | */ |
191 | 188 | ||
192 | static inline int ioport_panic(void) | 189 | static inline long ioport_panic(void) |
193 | { | 190 | { |
194 | panic("inb/outb and friends do not exist on tile"); | 191 | panic("inb/outb and friends do not exist on tile"); |
195 | return 0; | 192 | return 0; |
196 | } | 193 | } |
197 | 194 | ||
195 | static inline void __iomem *ioport_map(unsigned long port, unsigned int len) | ||
196 | { | ||
197 | return (void __iomem *) ioport_panic(); | ||
198 | } | ||
199 | |||
200 | static inline void ioport_unmap(void __iomem *addr) | ||
201 | { | ||
202 | ioport_panic(); | ||
203 | } | ||
204 | |||
198 | static inline u8 inb(unsigned long addr) | 205 | static inline u8 inb(unsigned long addr) |
199 | { | 206 | { |
200 | return ioport_panic(); | 207 | return ioport_panic(); |
diff --git a/arch/tile/include/asm/pci-bridge.h b/arch/tile/include/asm/pci-bridge.h deleted file mode 100644 index e853b0e2793b..000000000000 --- a/arch/tile/include/asm/pci-bridge.h +++ /dev/null | |||
@@ -1,117 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2010 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef _ASM_TILE_PCI_BRIDGE_H | ||
16 | #define _ASM_TILE_PCI_BRIDGE_H | ||
17 | |||
18 | #include <linux/ioport.h> | ||
19 | #include <linux/pci.h> | ||
20 | |||
21 | struct device_node; | ||
22 | struct pci_controller; | ||
23 | |||
24 | /* | ||
25 | * pci_io_base returns the memory address at which you can access | ||
26 | * the I/O space for PCI bus number `bus' (or NULL on error). | ||
27 | */ | ||
28 | extern void __iomem *pci_bus_io_base(unsigned int bus); | ||
29 | extern unsigned long pci_bus_io_base_phys(unsigned int bus); | ||
30 | extern unsigned long pci_bus_mem_base_phys(unsigned int bus); | ||
31 | |||
32 | /* Allocate a new PCI host bridge structure */ | ||
33 | extern struct pci_controller *pcibios_alloc_controller(void); | ||
34 | |||
35 | /* Helper function for setting up resources */ | ||
36 | extern void pci_init_resource(struct resource *res, unsigned long start, | ||
37 | unsigned long end, int flags, char *name); | ||
38 | |||
39 | /* Get the PCI host controller for a bus */ | ||
40 | extern struct pci_controller *pci_bus_to_hose(int bus); | ||
41 | |||
42 | /* | ||
43 | * Structure of a PCI controller (host bridge) | ||
44 | */ | ||
45 | struct pci_controller { | ||
46 | int index; /* PCI domain number */ | ||
47 | struct pci_bus *root_bus; | ||
48 | |||
49 | int first_busno; | ||
50 | int last_busno; | ||
51 | |||
52 | int hv_cfg_fd[2]; /* config{0,1} fds for this PCIe controller */ | ||
53 | int hv_mem_fd; /* fd to Hypervisor for MMIO operations */ | ||
54 | |||
55 | struct pci_ops *ops; | ||
56 | |||
57 | int irq_base; /* Base IRQ from the Hypervisor */ | ||
58 | int plx_gen1; /* flag for PLX Gen 1 configuration */ | ||
59 | |||
60 | /* Address ranges that are routed to this controller/bridge. */ | ||
61 | struct resource mem_resources[3]; | ||
62 | }; | ||
63 | |||
64 | static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus) | ||
65 | { | ||
66 | return bus->sysdata; | ||
67 | } | ||
68 | |||
69 | extern void setup_indirect_pci_nomap(struct pci_controller *hose, | ||
70 | void __iomem *cfg_addr, void __iomem *cfg_data); | ||
71 | extern void setup_indirect_pci(struct pci_controller *hose, | ||
72 | u32 cfg_addr, u32 cfg_data); | ||
73 | extern void setup_grackle(struct pci_controller *hose); | ||
74 | |||
75 | extern unsigned char common_swizzle(struct pci_dev *, unsigned char *); | ||
76 | |||
77 | /* | ||
78 | * The following code swizzles for exactly one bridge. The routine | ||
79 | * common_swizzle below handles multiple bridges. But there are a | ||
80 | * some boards that don't follow the PCI spec's suggestion so we | ||
81 | * break this piece out separately. | ||
82 | */ | ||
83 | static inline unsigned char bridge_swizzle(unsigned char pin, | ||
84 | unsigned char idsel) | ||
85 | { | ||
86 | return (((pin-1) + idsel) % 4) + 1; | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * The following macro is used to lookup irqs in a standard table | ||
91 | * format for those PPC systems that do not already have PCI | ||
92 | * interrupts properly routed. | ||
93 | */ | ||
94 | /* FIXME - double check this */ | ||
95 | #define PCI_IRQ_TABLE_LOOKUP ({ \ | ||
96 | long _ctl_ = -1; \ | ||
97 | if (idsel >= min_idsel && idsel <= max_idsel && pin <= irqs_per_slot) \ | ||
98 | _ctl_ = pci_irq_table[idsel - min_idsel][pin-1]; \ | ||
99 | _ctl_; \ | ||
100 | }) | ||
101 | |||
102 | /* | ||
103 | * Scan the buses below a given PCI host bridge and assign suitable | ||
104 | * resources to all devices found. | ||
105 | */ | ||
106 | extern int pciauto_bus_scan(struct pci_controller *, int); | ||
107 | |||
108 | #ifdef CONFIG_PCI | ||
109 | extern unsigned long pci_address_to_pio(phys_addr_t address); | ||
110 | #else | ||
111 | static inline unsigned long pci_address_to_pio(phys_addr_t address) | ||
112 | { | ||
113 | return (unsigned long)-1; | ||
114 | } | ||
115 | #endif | ||
116 | |||
117 | #endif /* _ASM_TILE_PCI_BRIDGE_H */ | ||
diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h index b0c15da2d5d5..c3fc458a0d32 100644 --- a/arch/tile/include/asm/pci.h +++ b/arch/tile/include/asm/pci.h | |||
@@ -15,7 +15,29 @@ | |||
15 | #ifndef _ASM_TILE_PCI_H | 15 | #ifndef _ASM_TILE_PCI_H |
16 | #define _ASM_TILE_PCI_H | 16 | #define _ASM_TILE_PCI_H |
17 | 17 | ||
18 | #include <asm/pci-bridge.h> | 18 | #include <linux/pci.h> |
19 | |||
20 | /* | ||
21 | * Structure of a PCI controller (host bridge) | ||
22 | */ | ||
23 | struct pci_controller { | ||
24 | int index; /* PCI domain number */ | ||
25 | struct pci_bus *root_bus; | ||
26 | |||
27 | int first_busno; | ||
28 | int last_busno; | ||
29 | |||
30 | int hv_cfg_fd[2]; /* config{0,1} fds for this PCIe controller */ | ||
31 | int hv_mem_fd; /* fd to Hypervisor for MMIO operations */ | ||
32 | |||
33 | struct pci_ops *ops; | ||
34 | |||
35 | int irq_base; /* Base IRQ from the Hypervisor */ | ||
36 | int plx_gen1; /* flag for PLX Gen 1 configuration */ | ||
37 | |||
38 | /* Address ranges that are routed to this controller/bridge. */ | ||
39 | struct resource mem_resources[3]; | ||
40 | }; | ||
19 | 41 | ||
20 | /* | 42 | /* |
21 | * The hypervisor maps the entirety of CPA-space as bus addresses, so | 43 | * The hypervisor maps the entirety of CPA-space as bus addresses, so |
@@ -24,56 +46,12 @@ | |||
24 | */ | 46 | */ |
25 | #define PCI_DMA_BUS_IS_PHYS 1 | 47 | #define PCI_DMA_BUS_IS_PHYS 1 |
26 | 48 | ||
27 | struct pci_controller *pci_bus_to_hose(int bus); | ||
28 | unsigned char __init common_swizzle(struct pci_dev *dev, unsigned char *pinp); | ||
29 | int __init tile_pci_init(void); | 49 | int __init tile_pci_init(void); |
30 | void pci_iounmap(struct pci_dev *dev, void __iomem *addr); | ||
31 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); | ||
32 | void __devinit pcibios_fixup_bus(struct pci_bus *bus); | ||
33 | 50 | ||
34 | int __devinit _tile_cfg_read(struct pci_controller *hose, | 51 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); |
35 | int bus, | 52 | static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} |
36 | int slot, | ||
37 | int function, | ||
38 | int offset, | ||
39 | int size, | ||
40 | u32 *val); | ||
41 | int __devinit _tile_cfg_write(struct pci_controller *hose, | ||
42 | int bus, | ||
43 | int slot, | ||
44 | int function, | ||
45 | int offset, | ||
46 | int size, | ||
47 | u32 val); | ||
48 | 53 | ||
49 | /* | 54 | void __devinit pcibios_fixup_bus(struct pci_bus *bus); |
50 | * These are used to to config reads and writes in the early stages of | ||
51 | * setup before the driver infrastructure has been set up enough to be | ||
52 | * able to do config reads and writes. | ||
53 | */ | ||
54 | #define early_cfg_read(where, size, value) \ | ||
55 | _tile_cfg_read(controller, \ | ||
56 | current_bus, \ | ||
57 | pci_slot, \ | ||
58 | pci_fn, \ | ||
59 | where, \ | ||
60 | size, \ | ||
61 | value) | ||
62 | |||
63 | #define early_cfg_write(where, size, value) \ | ||
64 | _tile_cfg_write(controller, \ | ||
65 | current_bus, \ | ||
66 | pci_slot, \ | ||
67 | pci_fn, \ | ||
68 | where, \ | ||
69 | size, \ | ||
70 | value) | ||
71 | |||
72 | |||
73 | |||
74 | #define PCICFG_BYTE 1 | ||
75 | #define PCICFG_WORD 2 | ||
76 | #define PCICFG_DWORD 4 | ||
77 | 55 | ||
78 | #define TILE_NUM_PCIE 2 | 56 | #define TILE_NUM_PCIE 2 |
79 | 57 | ||
@@ -88,33 +66,33 @@ static inline int pci_proc_domain(struct pci_bus *bus) | |||
88 | } | 66 | } |
89 | 67 | ||
90 | /* | 68 | /* |
91 | * I/O space is currently not supported. | 69 | * pcibios_assign_all_busses() tells whether or not the bus numbers |
70 | * should be reassigned, in case the BIOS didn't do it correctly, or | ||
71 | * in case we don't have a BIOS and we want to let Linux do it. | ||
92 | */ | 72 | */ |
73 | static inline int pcibios_assign_all_busses(void) | ||
74 | { | ||
75 | return 1; | ||
76 | } | ||
93 | 77 | ||
94 | #define TILE_PCIE_LOWER_IO 0x0 | 78 | /* |
95 | #define TILE_PCIE_UPPER_IO 0x10000 | 79 | * No special bus mastering setup handling. |
96 | #define TILE_PCIE_PCIE_IO_SIZE 0x0000FFFF | 80 | */ |
97 | |||
98 | #define _PAGE_NO_CACHE 0 | ||
99 | #define _PAGE_GUARDED 0 | ||
100 | |||
101 | |||
102 | #define pcibios_assign_all_busses() pci_assign_all_buses | ||
103 | extern int pci_assign_all_buses; | ||
104 | |||
105 | static inline void pcibios_set_master(struct pci_dev *dev) | 81 | static inline void pcibios_set_master(struct pci_dev *dev) |
106 | { | 82 | { |
107 | /* No special bus mastering setup handling */ | ||
108 | } | 83 | } |
109 | 84 | ||
110 | #define PCIBIOS_MIN_MEM 0 | 85 | #define PCIBIOS_MIN_MEM 0 |
111 | #define PCIBIOS_MIN_IO TILE_PCIE_LOWER_IO | 86 | #define PCIBIOS_MIN_IO 0 |
112 | 87 | ||
113 | /* | 88 | /* |
114 | * This flag tells if the platform is TILEmpower that needs | 89 | * This flag tells if the platform is TILEmpower that needs |
115 | * special configuration for the PLX switch chip. | 90 | * special configuration for the PLX switch chip. |
116 | */ | 91 | */ |
117 | extern int blade_pci; | 92 | extern int tile_plx_gen1; |
93 | |||
94 | /* Use any cpu for PCI. */ | ||
95 | #define cpumask_of_pcibus(bus) cpu_online_mask | ||
118 | 96 | ||
119 | /* implement the pci_ DMA API in terms of the generic device dma_ one */ | 97 | /* implement the pci_ DMA API in terms of the generic device dma_ one */ |
120 | #include <asm-generic/pci-dma-compat.h> | 98 | #include <asm-generic/pci-dma-compat.h> |
@@ -122,7 +100,4 @@ extern int blade_pci; | |||
122 | /* generic pci stuff */ | 100 | /* generic pci stuff */ |
123 | #include <asm-generic/pci.h> | 101 | #include <asm-generic/pci.h> |
124 | 102 | ||
125 | /* Use any cpu for PCI. */ | ||
126 | #define cpumask_of_pcibus(bus) cpu_online_mask | ||
127 | |||
128 | #endif /* _ASM_TILE_PCI_H */ | 103 | #endif /* _ASM_TILE_PCI_H */ |
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h index 1747ff3946b2..a9e7c8760334 100644 --- a/arch/tile/include/asm/processor.h +++ b/arch/tile/include/asm/processor.h | |||
@@ -292,8 +292,18 @@ extern int kstack_hash; | |||
292 | /* Are we using huge pages in the TLB for kernel data? */ | 292 | /* Are we using huge pages in the TLB for kernel data? */ |
293 | extern int kdata_huge; | 293 | extern int kdata_huge; |
294 | 294 | ||
295 | /* Support standard Linux prefetching. */ | ||
296 | #define ARCH_HAS_PREFETCH | ||
297 | #define prefetch(x) __builtin_prefetch(x) | ||
295 | #define PREFETCH_STRIDE CHIP_L2_LINE_SIZE() | 298 | #define PREFETCH_STRIDE CHIP_L2_LINE_SIZE() |
296 | 299 | ||
300 | /* Bring a value into the L1D, faulting the TLB if necessary. */ | ||
301 | #ifdef __tilegx__ | ||
302 | #define prefetch_L1(x) __insn_prefetch_l1_fault((void *)(x)) | ||
303 | #else | ||
304 | #define prefetch_L1(x) __insn_prefetch_L1((void *)(x)) | ||
305 | #endif | ||
306 | |||
297 | #else /* __ASSEMBLY__ */ | 307 | #else /* __ASSEMBLY__ */ |
298 | 308 | ||
299 | /* Do some slow action (e.g. read a slow SPR). */ | 309 | /* Do some slow action (e.g. read a slow SPR). */ |
diff --git a/arch/tile/include/hv/drv_xgbe_impl.h b/arch/tile/include/hv/drv_xgbe_impl.h new file mode 100644 index 000000000000..3a73b2b44913 --- /dev/null +++ b/arch/tile/include/hv/drv_xgbe_impl.h | |||
@@ -0,0 +1,300 @@ | |||
1 | /* | ||
2 | * Copyright 2010 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | /** | ||
16 | * @file drivers/xgbe/impl.h | ||
17 | * Implementation details for the NetIO library. | ||
18 | */ | ||
19 | |||
20 | #ifndef __DRV_XGBE_IMPL_H__ | ||
21 | #define __DRV_XGBE_IMPL_H__ | ||
22 | |||
23 | #include <hv/netio_errors.h> | ||
24 | #include <hv/netio_intf.h> | ||
25 | #include <hv/drv_xgbe_intf.h> | ||
26 | |||
27 | |||
28 | /** How many groups we have (log2). */ | ||
29 | #define LOG2_NUM_GROUPS (12) | ||
30 | /** How many groups we have. */ | ||
31 | #define NUM_GROUPS (1 << LOG2_NUM_GROUPS) | ||
32 | |||
33 | /** Number of output requests we'll buffer per tile. */ | ||
34 | #define EPP_REQS_PER_TILE (32) | ||
35 | |||
36 | /** Words used in an eDMA command without checksum acceleration. */ | ||
37 | #define EDMA_WDS_NO_CSUM 8 | ||
38 | /** Words used in an eDMA command with checksum acceleration. */ | ||
39 | #define EDMA_WDS_CSUM 10 | ||
40 | /** Total available words in the eDMA command FIFO. */ | ||
41 | #define EDMA_WDS_TOTAL 128 | ||
42 | |||
43 | |||
44 | /* | ||
45 | * FIXME: These definitions are internal and should have underscores! | ||
46 | * NOTE: The actual numeric values here are intentional and allow us to | ||
47 | * optimize the concept "if small ... else if large ... else ...", by | ||
48 | * checking for the low bit being set, and then for non-zero. | ||
49 | * These are used as array indices, so they must have the values (0, 1, 2) | ||
50 | * in some order. | ||
51 | */ | ||
52 | #define SIZE_SMALL (1) /**< Small packet queue. */ | ||
53 | #define SIZE_LARGE (2) /**< Large packet queue. */ | ||
54 | #define SIZE_JUMBO (0) /**< Jumbo packet queue. */ | ||
55 | |||
56 | /** The number of "SIZE_xxx" values. */ | ||
57 | #define NETIO_NUM_SIZES 3 | ||
58 | |||
59 | |||
60 | /* | ||
61 | * Default numbers of packets for IPP drivers. These values are chosen | ||
62 | * such that CIPP1 will not overflow its L2 cache. | ||
63 | */ | ||
64 | |||
65 | /** The default number of small packets. */ | ||
66 | #define NETIO_DEFAULT_SMALL_PACKETS 2750 | ||
67 | /** The default number of large packets. */ | ||
68 | #define NETIO_DEFAULT_LARGE_PACKETS 2500 | ||
69 | /** The default number of jumbo packets. */ | ||
70 | #define NETIO_DEFAULT_JUMBO_PACKETS 250 | ||
71 | |||
72 | |||
73 | /** Log2 of the size of a memory arena. */ | ||
74 | #define NETIO_ARENA_SHIFT 24 /* 16 MB */ | ||
75 | /** Size of a memory arena. */ | ||
76 | #define NETIO_ARENA_SIZE (1 << NETIO_ARENA_SHIFT) | ||
77 | |||
78 | |||
79 | /** A queue of packets. | ||
80 | * | ||
81 | * This structure partially defines a queue of packets waiting to be | ||
82 | * processed. The queue as a whole is written to by an interrupt handler and | ||
83 | * read by non-interrupt code; this data structure is what's touched by the | ||
84 | * interrupt handler. The other part of the queue state, the read offset, is | ||
85 | * kept in user space, not in hypervisor space, so it is in a separate data | ||
86 | * structure. | ||
87 | * | ||
88 | * The read offset (__packet_receive_read in the user part of the queue | ||
89 | * structure) points to the next packet to be read. When the read offset is | ||
90 | * equal to the write offset, the queue is empty; therefore the queue must | ||
91 | * contain one more slot than the required maximum queue size. | ||
92 | * | ||
93 | * Here's an example of all 3 state variables and what they mean. All | ||
94 | * pointers move left to right. | ||
95 | * | ||
96 | * @code | ||
97 | * I I V V V V I I I I | ||
98 | * 0 1 2 3 4 5 6 7 8 9 10 | ||
99 | * ^ ^ ^ ^ | ||
100 | * | | | | ||
101 | * | | __last_packet_plus_one | ||
102 | * | __buffer_write | ||
103 | * __packet_receive_read | ||
104 | * @endcode | ||
105 | * | ||
106 | * This queue has 10 slots, and thus can hold 9 packets (_last_packet_plus_one | ||
107 | * = 10). The read pointer is at 2, and the write pointer is at 6; thus, | ||
108 | * there are valid, unread packets in slots 2, 3, 4, and 5. The remaining | ||
109 | * slots are invalid (do not contain a packet). | ||
110 | */ | ||
111 | typedef struct { | ||
112 | /** Byte offset of the next notify packet to be written: zero for the first | ||
113 | * packet on the queue, sizeof (netio_pkt_t) for the second packet on the | ||
114 | * queue, etc. */ | ||
115 | volatile uint32_t __packet_write; | ||
116 | |||
117 | /** Offset of the packet after the last valid packet (i.e., when any | ||
118 | * pointer is incremented to this value, it wraps back to zero). */ | ||
119 | uint32_t __last_packet_plus_one; | ||
120 | } | ||
121 | __netio_packet_queue_t; | ||
122 | |||
123 | |||
124 | /** A queue of buffers. | ||
125 | * | ||
126 | * This structure partially defines a queue of empty buffers which have been | ||
127 | * obtained via requests to the IPP. (The elements of the queue are packet | ||
128 | * handles, which are transformed into a full netio_pkt_t when the buffer is | ||
129 | * retrieved.) The queue as a whole is written to by an interrupt handler and | ||
130 | * read by non-interrupt code; this data structure is what's touched by the | ||
131 | * interrupt handler. The other parts of the queue state, the read offset and | ||
132 | * requested write offset, are kept in user space, not in hypervisor space, so | ||
133 | * they are in a separate data structure. | ||
134 | * | ||
135 | * The read offset (__buffer_read in the user part of the queue structure) | ||
136 | * points to the next buffer to be read. When the read offset is equal to the | ||
137 | * write offset, the queue is empty; therefore the queue must contain one more | ||
138 | * slot than the required maximum queue size. | ||
139 | * | ||
140 | * The requested write offset (__buffer_requested_write in the user part of | ||
141 | * the queue structure) points to the slot which will hold the next buffer we | ||
142 | * request from the IPP, once we get around to sending such a request. When | ||
143 | * the requested write offset is equal to the write offset, no requests for | ||
144 | * new buffers are outstanding; when the requested write offset is one greater | ||
145 | * than the read offset, no more requests may be sent. | ||
146 | * | ||
147 | * Note that, unlike the packet_queue, the buffer_queue places incoming | ||
148 | * buffers at decreasing addresses. This makes the check for "is it time to | ||
149 | * wrap the buffer pointer" cheaper in the assembly code which receives new | ||
150 | * buffers, and means that the value which defines the queue size, | ||
151 | * __last_buffer, is different than in the packet queue. Also, the offset | ||
152 | * used in the packet_queue is already scaled by the size of a packet; here we | ||
153 | * use unscaled slot indices for the offsets. (These differences are | ||
154 | * historical, and in the future it's possible that the packet_queue will look | ||
155 | * more like this queue.) | ||
156 | * | ||
157 | * @code | ||
158 | * Here's an example of all 4 state variables and what they mean. Remember: | ||
159 | * all pointers move right to left. | ||
160 | * | ||
161 | * V V V I I R R V V V | ||
162 | * 0 1 2 3 4 5 6 7 8 9 | ||
163 | * ^ ^ ^ ^ | ||
164 | * | | | | | ||
165 | * | | | __last_buffer | ||
166 | * | | __buffer_write | ||
167 | * | __buffer_requested_write | ||
168 | * __buffer_read | ||
169 | * @endcode | ||
170 | * | ||
171 | * This queue has 10 slots, and thus can hold 9 buffers (_last_buffer = 9). | ||
172 | * The read pointer is at 2, and the write pointer is at 6; thus, there are | ||
173 | * valid, unread buffers in slots 2, 1, 0, 9, 8, and 7. The requested write | ||
174 | * pointer is at 4; thus, requests have been made to the IPP for buffers which | ||
175 | * will be placed in slots 6 and 5 when they arrive. Finally, the remaining | ||
176 | * slots are invalid (do not contain a buffer). | ||
177 | */ | ||
178 | typedef struct | ||
179 | { | ||
180 | /** Ordinal number of the next buffer to be written: 0 for the first slot in | ||
181 | * the queue, 1 for the second slot in the queue, etc. */ | ||
182 | volatile uint32_t __buffer_write; | ||
183 | |||
184 | /** Ordinal number of the last buffer (i.e., when any pointer is decremented | ||
185 | * below zero, it is reloaded with this value). */ | ||
186 | uint32_t __last_buffer; | ||
187 | } | ||
188 | __netio_buffer_queue_t; | ||
189 | |||
190 | |||
191 | /** | ||
192 | * An object for providing Ethernet packets to a process. | ||
193 | */ | ||
194 | typedef struct __netio_queue_impl_t | ||
195 | { | ||
196 | /** The queue of packets waiting to be received. */ | ||
197 | __netio_packet_queue_t __packet_receive_queue; | ||
198 | /** The intr bit mask that IDs this device. */ | ||
199 | unsigned int __intr_id; | ||
200 | /** Offset to queues of empty buffers, one per size. */ | ||
201 | uint32_t __buffer_queue[NETIO_NUM_SIZES]; | ||
202 | /** The address of the first EPP tile, or -1 if no EPP. */ | ||
203 | /* ISSUE: Actually this is always "0" or "~0". */ | ||
204 | uint32_t __epp_location; | ||
205 | /** The queue ID that this queue represents. */ | ||
206 | unsigned int __queue_id; | ||
207 | /** Number of acknowledgements received. */ | ||
208 | volatile uint32_t __acks_received; | ||
209 | /** Last completion number received for packet_sendv. */ | ||
210 | volatile uint32_t __last_completion_rcv; | ||
211 | /** Number of packets allowed to be outstanding. */ | ||
212 | uint32_t __max_outstanding; | ||
213 | /** First VA available for packets. */ | ||
214 | void* __va_0; | ||
215 | /** First VA in second range available for packets. */ | ||
216 | void* __va_1; | ||
217 | /** Padding to align the "__packets" field to the size of a netio_pkt_t. */ | ||
218 | uint32_t __padding[3]; | ||
219 | /** The packets themselves. */ | ||
220 | netio_pkt_t __packets[0]; | ||
221 | } | ||
222 | netio_queue_impl_t; | ||
223 | |||
224 | |||
225 | /** | ||
226 | * An object for managing the user end of a NetIO queue. | ||
227 | */ | ||
228 | typedef struct __netio_queue_user_impl_t | ||
229 | { | ||
230 | /** The next incoming packet to be read. */ | ||
231 | uint32_t __packet_receive_read; | ||
232 | /** The next empty buffers to be read, one index per size. */ | ||
233 | uint8_t __buffer_read[NETIO_NUM_SIZES]; | ||
234 | /** Where the empty buffer we next request from the IPP will go, one index | ||
235 | * per size. */ | ||
236 | uint8_t __buffer_requested_write[NETIO_NUM_SIZES]; | ||
237 | /** PCIe interface flag. */ | ||
238 | uint8_t __pcie; | ||
239 | /** Number of packets left to be received before we send a credit update. */ | ||
240 | uint32_t __receive_credit_remaining; | ||
241 | /** Value placed in __receive_credit_remaining when it reaches zero. */ | ||
242 | uint32_t __receive_credit_interval; | ||
243 | /** First fast I/O routine index. */ | ||
244 | uint32_t __fastio_index; | ||
245 | /** Number of acknowledgements expected. */ | ||
246 | uint32_t __acks_outstanding; | ||
247 | /** Last completion number requested. */ | ||
248 | uint32_t __last_completion_req; | ||
249 | /** File descriptor for driver. */ | ||
250 | int __fd; | ||
251 | } | ||
252 | netio_queue_user_impl_t; | ||
253 | |||
254 | |||
255 | #define NETIO_GROUP_CHUNK_SIZE 64 /**< Max # groups in one IPP request */ | ||
256 | #define NETIO_BUCKET_CHUNK_SIZE 64 /**< Max # buckets in one IPP request */ | ||
257 | |||
258 | |||
259 | /** Internal structure used to convey packet send information to the | ||
260 | * hypervisor. FIXME: Actually, it's not used for that anymore, but | ||
261 | * netio_packet_send() still uses it internally. | ||
262 | */ | ||
263 | typedef struct | ||
264 | { | ||
265 | uint16_t flags; /**< Packet flags (__NETIO_SEND_FLG_xxx) */ | ||
266 | uint16_t transfer_size; /**< Size of packet */ | ||
267 | uint32_t va; /**< VA of start of packet */ | ||
268 | __netio_pkt_handle_t handle; /**< Packet handle */ | ||
269 | uint32_t csum0; /**< First checksum word */ | ||
270 | uint32_t csum1; /**< Second checksum word */ | ||
271 | } | ||
272 | __netio_send_cmd_t; | ||
273 | |||
274 | |||
275 | /** Flags used in two contexts: | ||
276 | * - As the "flags" member in the __netio_send_cmd_t, above; used only | ||
277 | * for netio_pkt_send_{prepare,commit}. | ||
278 | * - As part of the flags passed to the various send packet fast I/O calls. | ||
279 | */ | ||
280 | |||
281 | /** Need acknowledgement on this packet. Note that some code in the | ||
282 | * normal send_pkt fast I/O handler assumes that this is equal to 1. */ | ||
283 | #define __NETIO_SEND_FLG_ACK 0x1 | ||
284 | |||
285 | /** Do checksum on this packet. (Only used with the __netio_send_cmd_t; | ||
286 | * normal packet sends use a special fast I/O index to denote checksumming, | ||
287 | * and multi-segment sends test the checksum descriptor.) */ | ||
288 | #define __NETIO_SEND_FLG_CSUM 0x2 | ||
289 | |||
290 | /** Get a completion on this packet. Only used with multi-segment sends. */ | ||
291 | #define __NETIO_SEND_FLG_COMPLETION 0x4 | ||
292 | |||
293 | /** Position of the number-of-extra-segments value in the flags word. | ||
294 | Only used with multi-segment sends. */ | ||
295 | #define __NETIO_SEND_FLG_XSEG_SHIFT 3 | ||
296 | |||
297 | /** Width of the number-of-extra-segments value in the flags word. */ | ||
298 | #define __NETIO_SEND_FLG_XSEG_WIDTH 2 | ||
299 | |||
300 | #endif /* __DRV_XGBE_IMPL_H__ */ | ||
diff --git a/arch/tile/include/hv/drv_xgbe_intf.h b/arch/tile/include/hv/drv_xgbe_intf.h new file mode 100644 index 000000000000..146e47d5334b --- /dev/null +++ b/arch/tile/include/hv/drv_xgbe_intf.h | |||
@@ -0,0 +1,615 @@ | |||
1 | /* | ||
2 | * Copyright 2010 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | /** | ||
16 | * @file drv_xgbe_intf.h | ||
17 | * Interface to the hypervisor XGBE driver. | ||
18 | */ | ||
19 | |||
20 | #ifndef __DRV_XGBE_INTF_H__ | ||
21 | #define __DRV_XGBE_INTF_H__ | ||
22 | |||
23 | /** | ||
24 | * An object for forwarding VAs and PAs to the hypervisor. | ||
25 | * @ingroup types | ||
26 | * | ||
27 | * This allows the supervisor to specify a number of areas of memory to | ||
28 | * store packet buffers. | ||
29 | */ | ||
30 | typedef struct | ||
31 | { | ||
32 | /** The physical address of the memory. */ | ||
33 | HV_PhysAddr pa; | ||
34 | /** Page table entry for the memory. This is only used to derive the | ||
35 | * memory's caching mode; the PA bits are ignored. */ | ||
36 | HV_PTE pte; | ||
37 | /** The virtual address of the memory. */ | ||
38 | HV_VirtAddr va; | ||
39 | /** Size (in bytes) of the memory area. */ | ||
40 | int size; | ||
41 | |||
42 | } | ||
43 | netio_ipp_address_t; | ||
44 | |||
45 | /** The various pread/pwrite offsets into the hypervisor-level driver. | ||
46 | * @ingroup types | ||
47 | */ | ||
48 | typedef enum | ||
49 | { | ||
50 | /** Inform the Linux driver of the address of the NetIO arena memory. | ||
51 | * This offset is actually only used to convey information from netio | ||
52 | * to the Linux driver; it never makes it from there to the hypervisor. | ||
53 | * Write-only; takes a uint32_t specifying the VA address. */ | ||
54 | NETIO_FIXED_ADDR = 0x5000000000000000ULL, | ||
55 | |||
56 | /** Inform the Linux driver of the size of the NetIO arena memory. | ||
57 | * This offset is actually only used to convey information from netio | ||
58 | * to the Linux driver; it never makes it from there to the hypervisor. | ||
59 | * Write-only; takes a uint32_t specifying the VA size. */ | ||
60 | NETIO_FIXED_SIZE = 0x5100000000000000ULL, | ||
61 | |||
62 | /** Register current tile with IPP. Write then read: write, takes a | ||
63 | * netio_input_config_t, read returns a pointer to a netio_queue_impl_t. */ | ||
64 | NETIO_IPP_INPUT_REGISTER_OFF = 0x6000000000000000ULL, | ||
65 | |||
66 | /** Unregister current tile from IPP. Write-only, takes a dummy argument. */ | ||
67 | NETIO_IPP_INPUT_UNREGISTER_OFF = 0x6100000000000000ULL, | ||
68 | |||
69 | /** Start packets flowing. Write-only, takes a dummy argument. */ | ||
70 | NETIO_IPP_INPUT_INIT_OFF = 0x6200000000000000ULL, | ||
71 | |||
72 | /** Stop packets flowing. Write-only, takes a dummy argument. */ | ||
73 | NETIO_IPP_INPUT_UNINIT_OFF = 0x6300000000000000ULL, | ||
74 | |||
75 | /** Configure group (typically we group on VLAN). Write-only: takes an | ||
76 | * array of netio_group_t's, low 24 bits of the offset is the base group | ||
77 | * number times the size of a netio_group_t. */ | ||
78 | NETIO_IPP_INPUT_GROUP_CFG_OFF = 0x6400000000000000ULL, | ||
79 | |||
80 | /** Configure bucket. Write-only: takes an array of netio_bucket_t's, low | ||
81 | * 24 bits of the offset is the base bucket number times the size of a | ||
82 | * netio_bucket_t. */ | ||
83 | NETIO_IPP_INPUT_BUCKET_CFG_OFF = 0x6500000000000000ULL, | ||
84 | |||
85 | /** Get/set a parameter. Read or write: read or write data is the parameter | ||
86 | * value, low 32 bits of the offset is a __netio_getset_offset_t. */ | ||
87 | NETIO_IPP_PARAM_OFF = 0x6600000000000000ULL, | ||
88 | |||
89 | /** Get fast I/O index. Read-only; returns a 4-byte base index value. */ | ||
90 | NETIO_IPP_GET_FASTIO_OFF = 0x6700000000000000ULL, | ||
91 | |||
92 | /** Configure hijack IP address. Packets with this IPv4 dest address | ||
93 | * go to bucket NETIO_NUM_BUCKETS - 1. Write-only: takes an IP address | ||
94 | * in some standard form. FIXME: Define the form! */ | ||
95 | NETIO_IPP_INPUT_HIJACK_CFG_OFF = 0x6800000000000000ULL, | ||
96 | |||
97 | /** | ||
98 | * Offsets beyond this point are reserved for the supervisor (although that | ||
99 | * enforcement must be done by the supervisor driver itself). | ||
100 | */ | ||
101 | NETIO_IPP_USER_MAX_OFF = 0x6FFFFFFFFFFFFFFFULL, | ||
102 | |||
103 | /** Register I/O memory. Write-only, takes a netio_ipp_address_t. */ | ||
104 | NETIO_IPP_IOMEM_REGISTER_OFF = 0x7000000000000000ULL, | ||
105 | |||
106 | /** Unregister I/O memory. Write-only, takes a netio_ipp_address_t. */ | ||
107 | NETIO_IPP_IOMEM_UNREGISTER_OFF = 0x7100000000000000ULL, | ||
108 | |||
109 | /* Offsets greater than 0x7FFFFFFF can't be used directly from Linux | ||
110 | * userspace code due to limitations in the pread/pwrite syscalls. */ | ||
111 | |||
112 | /** Drain LIPP buffers. */ | ||
113 | NETIO_IPP_DRAIN_OFF = 0xFA00000000000000ULL, | ||
114 | |||
115 | /** Supply a netio_ipp_address_t to be used as shared memory for the | ||
116 | * LEPP command queue. */ | ||
117 | NETIO_EPP_SHM_OFF = 0xFB00000000000000ULL, | ||
118 | |||
119 | /* 0xFC... is currently unused. */ | ||
120 | |||
121 | /** Stop IPP/EPP tiles. Write-only, takes a dummy argument. */ | ||
122 | NETIO_IPP_STOP_SHIM_OFF = 0xFD00000000000000ULL, | ||
123 | |||
124 | /** Start IPP/EPP tiles. Write-only, takes a dummy argument. */ | ||
125 | NETIO_IPP_START_SHIM_OFF = 0xFE00000000000000ULL, | ||
126 | |||
127 | /** Supply packet arena. Write-only, takes an array of | ||
128 | * netio_ipp_address_t values. */ | ||
129 | NETIO_IPP_ADDRESS_OFF = 0xFF00000000000000ULL, | ||
130 | } netio_hv_offset_t; | ||
131 | |||
132 | /** Extract the base offset from an offset */ | ||
133 | #define NETIO_BASE_OFFSET(off) ((off) & 0xFF00000000000000ULL) | ||
134 | /** Extract the local offset from an offset */ | ||
135 | #define NETIO_LOCAL_OFFSET(off) ((off) & 0x00FFFFFFFFFFFFFFULL) | ||
136 | |||
137 | |||
138 | /** | ||
139 | * Get/set offset. | ||
140 | */ | ||
141 | typedef union | ||
142 | { | ||
143 | struct | ||
144 | { | ||
145 | uint64_t addr:48; /**< Class-specific address */ | ||
146 | unsigned int class:8; /**< Class (e.g., NETIO_PARAM) */ | ||
147 | unsigned int opcode:8; /**< High 8 bits of NETIO_IPP_PARAM_OFF */ | ||
148 | } | ||
149 | bits; /**< Bitfields */ | ||
150 | uint64_t word; /**< Aggregated value to use as the offset */ | ||
151 | } | ||
152 | __netio_getset_offset_t; | ||
153 | |||
154 | /** | ||
155 | * Fast I/O index offsets (must be contiguous). | ||
156 | */ | ||
157 | typedef enum | ||
158 | { | ||
159 | NETIO_FASTIO_ALLOCATE = 0, /**< Get empty packet buffer */ | ||
160 | NETIO_FASTIO_FREE_BUFFER = 1, /**< Give buffer back to IPP */ | ||
161 | NETIO_FASTIO_RETURN_CREDITS = 2, /**< Give credits to IPP */ | ||
162 | NETIO_FASTIO_SEND_PKT_NOCK = 3, /**< Send a packet, no checksum */ | ||
163 | NETIO_FASTIO_SEND_PKT_CK = 4, /**< Send a packet, with checksum */ | ||
164 | NETIO_FASTIO_SEND_PKT_VEC = 5, /**< Send a vector of packets */ | ||
165 | NETIO_FASTIO_SENDV_PKT = 6, /**< Sendv one packet */ | ||
166 | NETIO_FASTIO_NUM_INDEX = 7, /**< Total number of fast I/O indices */ | ||
167 | } netio_fastio_index_t; | ||
168 | |||
169 | /** 3-word return type for Fast I/O call. */ | ||
170 | typedef struct | ||
171 | { | ||
172 | int err; /**< Error code. */ | ||
173 | uint32_t val0; /**< Value. Meaning depends upon the specific call. */ | ||
174 | uint32_t val1; /**< Value. Meaning depends upon the specific call. */ | ||
175 | } netio_fastio_rv3_t; | ||
176 | |||
177 | /** 0-argument fast I/O call */ | ||
178 | int __netio_fastio0(uint32_t fastio_index); | ||
179 | /** 1-argument fast I/O call */ | ||
180 | int __netio_fastio1(uint32_t fastio_index, uint32_t arg0); | ||
181 | /** 3-argument fast I/O call, 2-word return value */ | ||
182 | netio_fastio_rv3_t __netio_fastio3_rv3(uint32_t fastio_index, uint32_t arg0, | ||
183 | uint32_t arg1, uint32_t arg2); | ||
184 | /** 4-argument fast I/O call */ | ||
185 | int __netio_fastio4(uint32_t fastio_index, uint32_t arg0, uint32_t arg1, | ||
186 | uint32_t arg2, uint32_t arg3); | ||
187 | /** 6-argument fast I/O call */ | ||
188 | int __netio_fastio6(uint32_t fastio_index, uint32_t arg0, uint32_t arg1, | ||
189 | uint32_t arg2, uint32_t arg3, uint32_t arg4, uint32_t arg5); | ||
190 | /** 9-argument fast I/O call */ | ||
191 | int __netio_fastio9(uint32_t fastio_index, uint32_t arg0, uint32_t arg1, | ||
192 | uint32_t arg2, uint32_t arg3, uint32_t arg4, uint32_t arg5, | ||
193 | uint32_t arg6, uint32_t arg7, uint32_t arg8); | ||
194 | |||
195 | /** Allocate an empty packet. | ||
196 | * @param fastio_index Fast I/O index. | ||
197 | * @param size Size of the packet to allocate. | ||
198 | */ | ||
199 | #define __netio_fastio_allocate(fastio_index, size) \ | ||
200 | __netio_fastio1((fastio_index) + NETIO_FASTIO_ALLOCATE, size) | ||
201 | |||
202 | /** Free a buffer. | ||
203 | * @param fastio_index Fast I/O index. | ||
204 | * @param handle Handle for the packet to free. | ||
205 | */ | ||
206 | #define __netio_fastio_free_buffer(fastio_index, handle) \ | ||
207 | __netio_fastio1((fastio_index) + NETIO_FASTIO_FREE_BUFFER, handle) | ||
208 | |||
209 | /** Increment our receive credits. | ||
210 | * @param fastio_index Fast I/O index. | ||
211 | * @param credits Number of credits to add. | ||
212 | */ | ||
213 | #define __netio_fastio_return_credits(fastio_index, credits) \ | ||
214 | __netio_fastio1((fastio_index) + NETIO_FASTIO_RETURN_CREDITS, credits) | ||
215 | |||
216 | /** Send packet, no checksum. | ||
217 | * @param fastio_index Fast I/O index. | ||
218 | * @param ackflag Nonzero if we want an ack. | ||
219 | * @param size Size of the packet. | ||
220 | * @param va Virtual address of start of packet. | ||
221 | * @param handle Packet handle. | ||
222 | */ | ||
223 | #define __netio_fastio_send_pkt_nock(fastio_index, ackflag, size, va, handle) \ | ||
224 | __netio_fastio4((fastio_index) + NETIO_FASTIO_SEND_PKT_NOCK, ackflag, \ | ||
225 | size, va, handle) | ||
226 | |||
227 | /** Send packet, calculate checksum. | ||
228 | * @param fastio_index Fast I/O index. | ||
229 | * @param ackflag Nonzero if we want an ack. | ||
230 | * @param size Size of the packet. | ||
231 | * @param va Virtual address of start of packet. | ||
232 | * @param handle Packet handle. | ||
233 | * @param csum0 Shim checksum header. | ||
234 | * @param csum1 Checksum seed. | ||
235 | */ | ||
236 | #define __netio_fastio_send_pkt_ck(fastio_index, ackflag, size, va, handle, \ | ||
237 | csum0, csum1) \ | ||
238 | __netio_fastio6((fastio_index) + NETIO_FASTIO_SEND_PKT_CK, ackflag, \ | ||
239 | size, va, handle, csum0, csum1) | ||
240 | |||
241 | |||
242 | /** Format for the "csum0" argument to the __netio_fastio_send routines | ||
243 | * and LEPP. Note that this is currently exactly identical to the | ||
244 | * ShimProtocolOffloadHeader. | ||
245 | */ | ||
246 | typedef union | ||
247 | { | ||
248 | struct | ||
249 | { | ||
250 | unsigned int start_byte:7; /**< The first byte to be checksummed */ | ||
251 | unsigned int count:14; /**< Number of bytes to be checksummed. */ | ||
252 | unsigned int destination_byte:7; /**< The byte to write the checksum to. */ | ||
253 | unsigned int reserved:4; /**< Reserved. */ | ||
254 | } bits; /**< Decomposed method of access. */ | ||
255 | unsigned int word; /**< To send out the IDN. */ | ||
256 | } __netio_checksum_header_t; | ||
257 | |||
258 | |||
259 | /** Sendv packet with 1 or 2 segments. | ||
260 | * @param fastio_index Fast I/O index. | ||
261 | * @param flags Ack/csum/notify flags in low 3 bits; number of segments minus | ||
262 | * 1 in next 2 bits; expected checksum in high 16 bits. | ||
263 | * @param confno Confirmation number to request, if notify flag set. | ||
264 | * @param csum0 Checksum descriptor; if zero, no checksum. | ||
265 | * @param va_F Virtual address of first segment. | ||
266 | * @param va_L Virtual address of last segment, if 2 segments. | ||
267 | * @param len_F_L Length of first segment in low 16 bits; length of last | ||
268 | * segment, if 2 segments, in high 16 bits. | ||
269 | */ | ||
270 | #define __netio_fastio_sendv_pkt_1_2(fastio_index, flags, confno, csum0, \ | ||
271 | va_F, va_L, len_F_L) \ | ||
272 | __netio_fastio6((fastio_index) + NETIO_FASTIO_SENDV_PKT, flags, confno, \ | ||
273 | csum0, va_F, va_L, len_F_L) | ||
274 | |||
275 | /** Send packet on PCIe interface. | ||
276 | * @param fastio_index Fast I/O index. | ||
277 | * @param flags Ack/csum/notify flags in low 3 bits. | ||
278 | * @param confno Confirmation number to request, if notify flag set. | ||
279 | * @param csum0 Checksum descriptor; Hard wired 0, not needed for PCIe. | ||
280 | * @param va_F Virtual address of the packet buffer. | ||
281 | * @param va_L Virtual address of last segment, if 2 segments. Hard wired 0. | ||
282 | * @param len_F_L Length of the packet buffer in low 16 bits. | ||
283 | */ | ||
284 | #define __netio_fastio_send_pcie_pkt(fastio_index, flags, confno, csum0, \ | ||
285 | va_F, va_L, len_F_L) \ | ||
286 | __netio_fastio6((fastio_index) + PCIE_FASTIO_SENDV_PKT, flags, confno, \ | ||
287 | csum0, va_F, va_L, len_F_L) | ||
288 | |||
289 | /** Sendv packet with 3 or 4 segments. | ||
290 | * @param fastio_index Fast I/O index. | ||
291 | * @param flags Ack/csum/notify flags in low 3 bits; number of segments minus | ||
292 | * 1 in next 2 bits; expected checksum in high 16 bits. | ||
293 | * @param confno Confirmation number to request, if notify flag set. | ||
294 | * @param csum0 Checksum descriptor; if zero, no checksum. | ||
295 | * @param va_F Virtual address of first segment. | ||
296 | * @param va_L Virtual address of last segment (third segment if 3 segments, | ||
297 | * fourth segment if 4 segments). | ||
298 | * @param len_F_L Length of first segment in low 16 bits; length of last | ||
299 | * segment in high 16 bits. | ||
300 | * @param va_M0 Virtual address of "middle 0" segment; this segment is sent | ||
301 | * second when there are three segments, and third if there are four. | ||
302 | * @param va_M1 Virtual address of "middle 1" segment; this segment is sent | ||
303 | * second when there are four segments. | ||
304 | * @param len_M0_M1 Length of middle 0 segment in low 16 bits; length of middle | ||
305 | * 1 segment, if 4 segments, in high 16 bits. | ||
306 | */ | ||
307 | #define __netio_fastio_sendv_pkt_3_4(fastio_index, flags, confno, csum0, va_F, \ | ||
308 | va_L, len_F_L, va_M0, va_M1, len_M0_M1) \ | ||
309 | __netio_fastio9((fastio_index) + NETIO_FASTIO_SENDV_PKT, flags, confno, \ | ||
310 | csum0, va_F, va_L, len_F_L, va_M0, va_M1, len_M0_M1) | ||
311 | |||
312 | /** Send vector of packets. | ||
313 | * @param fastio_index Fast I/O index. | ||
314 | * @param seqno Number of packets transmitted so far on this interface; | ||
315 | * used to decide which packets should be acknowledged. | ||
316 | * @param nentries Number of entries in vector. | ||
317 | * @param va Virtual address of start of vector entry array. | ||
318 | * @return 3-word netio_fastio_rv3_t structure. The structure's err member | ||
319 | * is an error code, or zero if no error. The val0 member is the | ||
320 | * updated value of seqno; it has been incremented by 1 for each | ||
321 | * packet sent. That increment may be less than nentries if an | ||
322 | * error occured, or if some of the entries in the vector contain | ||
323 | * handles equal to NETIO_PKT_HANDLE_NONE. The val1 member is the | ||
324 | * updated value of nentries; it has been decremented by 1 for each | ||
325 | * vector entry processed. Again, that decrement may be less than | ||
326 | * nentries (leaving the returned value positive) if an error | ||
327 | * occurred. | ||
328 | */ | ||
329 | #define __netio_fastio_send_pkt_vec(fastio_index, seqno, nentries, va) \ | ||
330 | __netio_fastio3_rv3((fastio_index) + NETIO_FASTIO_SEND_PKT_VEC, seqno, \ | ||
331 | nentries, va) | ||
332 | |||
333 | |||
334 | /** An egress DMA command for LEPP. */ | ||
335 | typedef struct | ||
336 | { | ||
337 | /** Is this a TSO transfer? | ||
338 | * | ||
339 | * NOTE: This field is always 0, to distinguish it from | ||
340 | * lepp_tso_cmd_t. It must come first! | ||
341 | */ | ||
342 | uint8_t tso : 1; | ||
343 | |||
344 | /** Unused padding bits. */ | ||
345 | uint8_t _unused : 3; | ||
346 | |||
347 | /** Should this packet be sent directly from caches instead of DRAM, | ||
348 | * using hash-for-home to locate the packet data? | ||
349 | */ | ||
350 | uint8_t hash_for_home : 1; | ||
351 | |||
352 | /** Should we compute a checksum? */ | ||
353 | uint8_t compute_checksum : 1; | ||
354 | |||
355 | /** Is this the final buffer for this packet? | ||
356 | * | ||
357 | * A single packet can be split over several input buffers (a "gather" | ||
358 | * operation). This flag indicates that this is the last buffer | ||
359 | * in a packet. | ||
360 | */ | ||
361 | uint8_t end_of_packet : 1; | ||
362 | |||
363 | /** Should LEPP advance 'comp_busy' when this DMA is fully finished? */ | ||
364 | uint8_t send_completion : 1; | ||
365 | |||
366 | /** High bits of Client Physical Address of the start of the buffer | ||
367 | * to be egressed. | ||
368 | * | ||
369 | * NOTE: Only 6 bits are actually needed here, as CPAs are | ||
370 | * currently 38 bits. So two bits could be scavenged from this. | ||
371 | */ | ||
372 | uint8_t cpa_hi; | ||
373 | |||
374 | /** The number of bytes to be egressed. */ | ||
375 | uint16_t length; | ||
376 | |||
377 | /** Low 32 bits of Client Physical Address of the start of the buffer | ||
378 | * to be egressed. | ||
379 | */ | ||
380 | uint32_t cpa_lo; | ||
381 | |||
382 | /** Checksum information (only used if 'compute_checksum'). */ | ||
383 | __netio_checksum_header_t checksum_data; | ||
384 | |||
385 | } lepp_cmd_t; | ||
386 | |||
387 | |||
388 | /** A chunk of physical memory for a TSO egress. */ | ||
389 | typedef struct | ||
390 | { | ||
391 | /** The low bits of the CPA. */ | ||
392 | uint32_t cpa_lo; | ||
393 | /** The high bits of the CPA. */ | ||
394 | uint16_t cpa_hi : 15; | ||
395 | /** Should this packet be sent directly from caches instead of DRAM, | ||
396 | * using hash-for-home to locate the packet data? | ||
397 | */ | ||
398 | uint16_t hash_for_home : 1; | ||
399 | /** The length in bytes. */ | ||
400 | uint16_t length; | ||
401 | } lepp_frag_t; | ||
402 | |||
403 | |||
404 | /** An LEPP command that handles TSO. */ | ||
405 | typedef struct | ||
406 | { | ||
407 | /** Is this a TSO transfer? | ||
408 | * | ||
409 | * NOTE: This field is always 1, to distinguish it from | ||
410 | * lepp_cmd_t. It must come first! | ||
411 | */ | ||
412 | uint8_t tso : 1; | ||
413 | |||
414 | /** Unused padding bits. */ | ||
415 | uint8_t _unused : 7; | ||
416 | |||
417 | /** Size of the header[] array in bytes. It must be in the range | ||
418 | * [40, 127], which are the smallest header for a TCP packet over | ||
419 | * Ethernet and the maximum possible prepend size supported by | ||
420 | * hardware, respectively. Note that the array storage must be | ||
421 | * padded out to a multiple of four bytes so that the following | ||
422 | * LEPP command is aligned properly. | ||
423 | */ | ||
424 | uint8_t header_size; | ||
425 | |||
426 | /** Byte offset of the IP header in header[]. */ | ||
427 | uint8_t ip_offset; | ||
428 | |||
429 | /** Byte offset of the TCP header in header[]. */ | ||
430 | uint8_t tcp_offset; | ||
431 | |||
432 | /** The number of bytes to use for the payload of each packet, | ||
433 | * except of course the last one, which may not have enough bytes. | ||
434 | * This means that each Ethernet packet except the last will have a | ||
435 | * size of header_size + payload_size. | ||
436 | */ | ||
437 | uint16_t payload_size; | ||
438 | |||
439 | /** The length of the 'frags' array that follows this struct. */ | ||
440 | uint16_t num_frags; | ||
441 | |||
442 | /** The actual frags. */ | ||
443 | lepp_frag_t frags[0 /* Variable-sized; num_frags entries. */]; | ||
444 | |||
445 | /* | ||
446 | * The packet header template logically follows frags[], | ||
447 | * but you can't declare that in C. | ||
448 | * | ||
449 | * uint32_t header[header_size_in_words_rounded_up]; | ||
450 | */ | ||
451 | |||
452 | } lepp_tso_cmd_t; | ||
453 | |||
454 | |||
455 | /** An LEPP completion ring entry. */ | ||
456 | typedef void* lepp_comp_t; | ||
457 | |||
458 | |||
459 | /** Maximum number of frags for one TSO command. This is adapted from | ||
460 | * linux's "MAX_SKB_FRAGS", and presumably over-estimates by one, for | ||
461 | * our page size of exactly 65536. We add one for a "body" fragment. | ||
462 | */ | ||
463 | #define LEPP_MAX_FRAGS (65536 / HV_PAGE_SIZE_SMALL + 2 + 1) | ||
464 | |||
465 | /** Total number of bytes needed for an lepp_tso_cmd_t. */ | ||
466 | #define LEPP_TSO_CMD_SIZE(num_frags, header_size) \ | ||
467 | (sizeof(lepp_tso_cmd_t) + \ | ||
468 | (num_frags) * sizeof(lepp_frag_t) + \ | ||
469 | (((header_size) + 3) & -4)) | ||
470 | |||
471 | /** The size of the lepp "cmd" queue. */ | ||
472 | #define LEPP_CMD_QUEUE_BYTES \ | ||
473 | (((CHIP_L2_CACHE_SIZE() - 2 * CHIP_L2_LINE_SIZE()) / \ | ||
474 | (sizeof(lepp_cmd_t) + sizeof(lepp_comp_t))) * sizeof(lepp_cmd_t)) | ||
475 | |||
476 | /** The largest possible command that can go in lepp_queue_t::cmds[]. */ | ||
477 | #define LEPP_MAX_CMD_SIZE LEPP_TSO_CMD_SIZE(LEPP_MAX_FRAGS, 128) | ||
478 | |||
479 | /** The largest possible value of lepp_queue_t::cmd_{head, tail} (inclusive). | ||
480 | */ | ||
481 | #define LEPP_CMD_LIMIT \ | ||
482 | (LEPP_CMD_QUEUE_BYTES - LEPP_MAX_CMD_SIZE) | ||
483 | |||
484 | /** The maximum number of completions in an LEPP queue. */ | ||
485 | #define LEPP_COMP_QUEUE_SIZE \ | ||
486 | ((LEPP_CMD_LIMIT + sizeof(lepp_cmd_t) - 1) / sizeof(lepp_cmd_t)) | ||
487 | |||
488 | /** Increment an index modulo the queue size. */ | ||
489 | #define LEPP_QINC(var) \ | ||
490 | (var = __insn_mnz(var - (LEPP_COMP_QUEUE_SIZE - 1), var + 1)) | ||
491 | |||
492 | /** A queue used to convey egress commands from the client to LEPP. */ | ||
493 | typedef struct | ||
494 | { | ||
495 | /** Index of first completion not yet processed by user code. | ||
496 | * If this is equal to comp_busy, there are no such completions. | ||
497 | * | ||
498 | * NOTE: This is only read/written by the user. | ||
499 | */ | ||
500 | unsigned int comp_head; | ||
501 | |||
502 | /** Index of first completion record not yet completed. | ||
503 | * If this is equal to comp_tail, there are no such completions. | ||
504 | * This index gets advanced (modulo LEPP_QUEUE_SIZE) whenever | ||
505 | * a command with the 'completion' bit set is finished. | ||
506 | * | ||
507 | * NOTE: This is only written by LEPP, only read by the user. | ||
508 | */ | ||
509 | volatile unsigned int comp_busy; | ||
510 | |||
511 | /** Index of the first empty slot in the completion ring. | ||
512 | * Entries from this up to but not including comp_head (in ring order) | ||
513 | * can be filled in with completion data. | ||
514 | * | ||
515 | * NOTE: This is only read/written by the user. | ||
516 | */ | ||
517 | unsigned int comp_tail; | ||
518 | |||
519 | /** Byte index of first command enqueued for LEPP but not yet processed. | ||
520 | * | ||
521 | * This is always divisible by sizeof(void*) and always <= LEPP_CMD_LIMIT. | ||
522 | * | ||
523 | * NOTE: LEPP advances this counter as soon as it no longer needs | ||
524 | * the cmds[] storage for this entry, but the transfer is not actually | ||
525 | * complete (i.e. the buffer pointed to by the command is no longer | ||
526 | * needed) until comp_busy advances. | ||
527 | * | ||
528 | * If this is equal to cmd_tail, the ring is empty. | ||
529 | * | ||
530 | * NOTE: This is only written by LEPP, only read by the user. | ||
531 | */ | ||
532 | volatile unsigned int cmd_head; | ||
533 | |||
534 | /** Byte index of first empty slot in the command ring. This field can | ||
535 | * be incremented up to but not equal to cmd_head (because that would | ||
536 | * mean the ring is empty). | ||
537 | * | ||
538 | * This is always divisible by sizeof(void*) and always <= LEPP_CMD_LIMIT. | ||
539 | * | ||
540 | * NOTE: This is read/written by the user, only read by LEPP. | ||
541 | */ | ||
542 | volatile unsigned int cmd_tail; | ||
543 | |||
544 | /** A ring of variable-sized egress DMA commands. | ||
545 | * | ||
546 | * NOTE: Only written by the user, only read by LEPP. | ||
547 | */ | ||
548 | char cmds[LEPP_CMD_QUEUE_BYTES] | ||
549 | __attribute__((aligned(CHIP_L2_LINE_SIZE()))); | ||
550 | |||
551 | /** A ring of user completion data. | ||
552 | * NOTE: Only read/written by the user. | ||
553 | */ | ||
554 | lepp_comp_t comps[LEPP_COMP_QUEUE_SIZE] | ||
555 | __attribute__((aligned(CHIP_L2_LINE_SIZE()))); | ||
556 | } lepp_queue_t; | ||
557 | |||
558 | |||
559 | /** An internal helper function for determining the number of entries | ||
560 | * available in a ring buffer, given that there is one sentinel. | ||
561 | */ | ||
562 | static inline unsigned int | ||
563 | _lepp_num_free_slots(unsigned int head, unsigned int tail) | ||
564 | { | ||
565 | /* | ||
566 | * One entry is reserved for use as a sentinel, to distinguish | ||
567 | * "empty" from "full". So we compute | ||
568 | * (head - tail - 1) % LEPP_QUEUE_SIZE, but without using a slow % operation. | ||
569 | */ | ||
570 | return (head - tail - 1) + ((head <= tail) ? LEPP_COMP_QUEUE_SIZE : 0); | ||
571 | } | ||
572 | |||
573 | |||
574 | /** Returns how many new comp entries can be enqueued. */ | ||
575 | static inline unsigned int | ||
576 | lepp_num_free_comp_slots(const lepp_queue_t* q) | ||
577 | { | ||
578 | return _lepp_num_free_slots(q->comp_head, q->comp_tail); | ||
579 | } | ||
580 | |||
581 | static inline int | ||
582 | lepp_qsub(int v1, int v2) | ||
583 | { | ||
584 | int delta = v1 - v2; | ||
585 | return delta + ((delta >> 31) & LEPP_COMP_QUEUE_SIZE); | ||
586 | } | ||
587 | |||
588 | |||
589 | /** FIXME: Check this from linux, via a new "pwrite()" call. */ | ||
590 | #define LIPP_VERSION 1 | ||
591 | |||
592 | |||
593 | /** We use exactly two bytes of alignment padding. */ | ||
594 | #define LIPP_PACKET_PADDING 2 | ||
595 | |||
596 | /** The minimum size of a "small" buffer (including the padding). */ | ||
597 | #define LIPP_SMALL_PACKET_SIZE 128 | ||
598 | |||
599 | /* | ||
600 | * NOTE: The following two values should total to less than around | ||
601 | * 13582, to keep the total size used for "lipp_state_t" below 64K. | ||
602 | */ | ||
603 | |||
604 | /** The maximum number of "small" buffers. | ||
605 | * This is enough for 53 network cpus with 128 credits. Note that | ||
606 | * if these are exhausted, we will fall back to using large buffers. | ||
607 | */ | ||
608 | #define LIPP_SMALL_BUFFERS 6785 | ||
609 | |||
610 | /** The maximum number of "large" buffers. | ||
611 | * This is enough for 53 network cpus with 128 credits. | ||
612 | */ | ||
613 | #define LIPP_LARGE_BUFFERS 6785 | ||
614 | |||
615 | #endif /* __DRV_XGBE_INTF_H__ */ | ||
diff --git a/arch/tile/include/hv/netio_errors.h b/arch/tile/include/hv/netio_errors.h new file mode 100644 index 000000000000..e1591bff61b5 --- /dev/null +++ b/arch/tile/include/hv/netio_errors.h | |||
@@ -0,0 +1,122 @@ | |||
1 | /* | ||
2 | * Copyright 2010 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | /** | ||
16 | * Error codes returned from NetIO routines. | ||
17 | */ | ||
18 | |||
19 | #ifndef __NETIO_ERRORS_H__ | ||
20 | #define __NETIO_ERRORS_H__ | ||
21 | |||
22 | /** | ||
23 | * @addtogroup error | ||
24 | * | ||
25 | * @brief The error codes returned by NetIO functions. | ||
26 | * | ||
27 | * NetIO functions return 0 (defined as ::NETIO_NO_ERROR) on success, and | ||
28 | * a negative value if an error occurs. | ||
29 | * | ||
30 | * In cases where a NetIO function failed due to a error reported by | ||
31 | * system libraries, the error code will be the negation of the | ||
32 | * system errno at the time of failure. The @ref netio_strerror() | ||
33 | * function will deliver error strings for both NetIO and system error | ||
34 | * codes. | ||
35 | * | ||
36 | * @{ | ||
37 | */ | ||
38 | |||
39 | /** The set of all NetIO errors. */ | ||
40 | typedef enum | ||
41 | { | ||
42 | /** Operation successfully completed. */ | ||
43 | NETIO_NO_ERROR = 0, | ||
44 | |||
45 | /** A packet was successfully retrieved from an input queue. */ | ||
46 | NETIO_PKT = 0, | ||
47 | |||
48 | /** Largest NetIO error number. */ | ||
49 | NETIO_ERR_MAX = -701, | ||
50 | |||
51 | /** The tile is not registered with the IPP. */ | ||
52 | NETIO_NOT_REGISTERED = -701, | ||
53 | |||
54 | /** No packet was available to retrieve from the input queue. */ | ||
55 | NETIO_NOPKT = -702, | ||
56 | |||
57 | /** The requested function is not implemented. */ | ||
58 | NETIO_NOT_IMPLEMENTED = -703, | ||
59 | |||
60 | /** On a registration operation, the target queue already has the maximum | ||
61 | * number of tiles registered for it, and no more may be added. On a | ||
62 | * packet send operation, the output queue is full and nothing more can | ||
63 | * be queued until some of the queued packets are actually transmitted. */ | ||
64 | NETIO_QUEUE_FULL = -704, | ||
65 | |||
66 | /** The calling process or thread is not bound to exactly one CPU. */ | ||
67 | NETIO_BAD_AFFINITY = -705, | ||
68 | |||
69 | /** Cannot allocate memory on requested controllers. */ | ||
70 | NETIO_CANNOT_HOME = -706, | ||
71 | |||
72 | /** On a registration operation, the IPP specified is not configured | ||
73 | * to support the options requested; for instance, the application | ||
74 | * wants a specific type of tagged headers which the configured IPP | ||
75 | * doesn't support. Or, the supplied configuration information is | ||
76 | * not self-consistent, or is out of range; for instance, specifying | ||
77 | * both NETIO_RECV and NETIO_NO_RECV, or asking for more than | ||
78 | * NETIO_MAX_SEND_BUFFERS to be preallocated. On a VLAN or bucket | ||
79 | * configure operation, the number of items, or the base item, was | ||
80 | * out of range. | ||
81 | */ | ||
82 | NETIO_BAD_CONFIG = -707, | ||
83 | |||
84 | /** Too many tiles have registered to transmit packets. */ | ||
85 | NETIO_TOOMANY_XMIT = -708, | ||
86 | |||
87 | /** Packet transmission was attempted on a queue which was registered | ||
88 | with transmit disabled. */ | ||
89 | NETIO_UNREG_XMIT = -709, | ||
90 | |||
91 | /** This tile is already registered with the IPP. */ | ||
92 | NETIO_ALREADY_REGISTERED = -710, | ||
93 | |||
94 | /** The Ethernet link is down. The application should try again later. */ | ||
95 | NETIO_LINK_DOWN = -711, | ||
96 | |||
97 | /** An invalid memory buffer has been specified. This may be an unmapped | ||
98 | * virtual address, or one which does not meet alignment requirements. | ||
99 | * For netio_input_register(), this error may be returned when multiple | ||
100 | * processes specify different memory regions to be used for NetIO | ||
101 | * buffers. That can happen if these processes specify explicit memory | ||
102 | * regions with the ::NETIO_FIXED_BUFFER_VA flag, or if tmc_cmem_init() | ||
103 | * has not been called by a common ancestor of the processes. | ||
104 | */ | ||
105 | NETIO_FAULT = -712, | ||
106 | |||
107 | /** Cannot combine user-managed shared memory and cache coherence. */ | ||
108 | NETIO_BAD_CACHE_CONFIG = -713, | ||
109 | |||
110 | /** Smallest NetIO error number. */ | ||
111 | NETIO_ERR_MIN = -713, | ||
112 | |||
113 | #ifndef __DOXYGEN__ | ||
114 | /** Used internally to mean that no response is needed; never returned to | ||
115 | * an application. */ | ||
116 | NETIO_NO_RESPONSE = 1 | ||
117 | #endif | ||
118 | } netio_error_t; | ||
119 | |||
120 | /** @} */ | ||
121 | |||
122 | #endif /* __NETIO_ERRORS_H__ */ | ||
diff --git a/arch/tile/include/hv/netio_intf.h b/arch/tile/include/hv/netio_intf.h new file mode 100644 index 000000000000..8d20972aba2c --- /dev/null +++ b/arch/tile/include/hv/netio_intf.h | |||
@@ -0,0 +1,2975 @@ | |||
1 | /* | ||
2 | * Copyright 2010 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | /** | ||
16 | * NetIO interface structures and macros. | ||
17 | */ | ||
18 | |||
19 | #ifndef __NETIO_INTF_H__ | ||
20 | #define __NETIO_INTF_H__ | ||
21 | |||
22 | #include <hv/netio_errors.h> | ||
23 | |||
24 | #ifdef __KERNEL__ | ||
25 | #include <linux/types.h> | ||
26 | #else | ||
27 | #include <stdint.h> | ||
28 | #endif | ||
29 | |||
30 | #if !defined(__HV__) && !defined(__BOGUX__) && !defined(__KERNEL__) | ||
31 | #include <assert.h> | ||
32 | #define netio_assert assert /**< Enable assertions from macros */ | ||
33 | #else | ||
34 | #define netio_assert(...) ((void)(0)) /**< Disable assertions from macros */ | ||
35 | #endif | ||
36 | |||
37 | /* | ||
38 | * If none of these symbols are defined, we're building libnetio in an | ||
39 | * environment where we have pthreads, so we'll enable locking. | ||
40 | */ | ||
41 | #if !defined(__HV__) && !defined(__BOGUX__) && !defined(__KERNEL__) && \ | ||
42 | !defined(__NEWLIB__) | ||
43 | #define _NETIO_PTHREAD /**< Include a mutex in netio_queue_t below */ | ||
44 | |||
45 | /* | ||
46 | * If NETIO_UNLOCKED is defined, we don't do use per-cpu locks on | ||
47 | * per-packet NetIO operations. We still do pthread locking on things | ||
48 | * like netio_input_register, though. This is used for building | ||
49 | * libnetio_unlocked. | ||
50 | */ | ||
51 | #ifndef NETIO_UNLOCKED | ||
52 | |||
53 | /* Avoid PLT overhead by using our own inlined per-cpu lock. */ | ||
54 | #include <sched.h> | ||
55 | typedef int _netio_percpu_mutex_t; | ||
56 | |||
57 | static __inline int | ||
58 | _netio_percpu_mutex_init(_netio_percpu_mutex_t* lock) | ||
59 | { | ||
60 | *lock = 0; | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static __inline int | ||
65 | _netio_percpu_mutex_lock(_netio_percpu_mutex_t* lock) | ||
66 | { | ||
67 | while (__builtin_expect(__insn_tns(lock), 0)) | ||
68 | sched_yield(); | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static __inline int | ||
73 | _netio_percpu_mutex_unlock(_netio_percpu_mutex_t* lock) | ||
74 | { | ||
75 | *lock = 0; | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | #else /* NETIO_UNLOCKED */ | ||
80 | |||
81 | /* Don't do any locking for per-packet NetIO operations. */ | ||
82 | typedef int _netio_percpu_mutex_t; | ||
83 | #define _netio_percpu_mutex_init(L) | ||
84 | #define _netio_percpu_mutex_lock(L) | ||
85 | #define _netio_percpu_mutex_unlock(L) | ||
86 | |||
87 | #endif /* NETIO_UNLOCKED */ | ||
88 | #endif /* !__HV__, !__BOGUX, !__KERNEL__, !__NEWLIB__ */ | ||
89 | |||
90 | /** How many tiles can register for a given queue. | ||
91 | * @ingroup setup */ | ||
92 | #define NETIO_MAX_TILES_PER_QUEUE 64 | ||
93 | |||
94 | |||
95 | /** Largest permissible queue identifier. | ||
96 | * @ingroup setup */ | ||
97 | #define NETIO_MAX_QUEUE_ID 255 | ||
98 | |||
99 | |||
100 | #ifndef __DOXYGEN__ | ||
101 | |||
102 | /* Metadata packet checksum/ethertype flags. */ | ||
103 | |||
104 | /** The L4 checksum has not been calculated. */ | ||
105 | #define _NETIO_PKT_NO_L4_CSUM_SHIFT 0 | ||
106 | #define _NETIO_PKT_NO_L4_CSUM_RMASK 1 | ||
107 | #define _NETIO_PKT_NO_L4_CSUM_MASK \ | ||
108 | (_NETIO_PKT_NO_L4_CSUM_RMASK << _NETIO_PKT_NO_L4_CSUM_SHIFT) | ||
109 | |||
110 | /** The L3 checksum has not been calculated. */ | ||
111 | #define _NETIO_PKT_NO_L3_CSUM_SHIFT 1 | ||
112 | #define _NETIO_PKT_NO_L3_CSUM_RMASK 1 | ||
113 | #define _NETIO_PKT_NO_L3_CSUM_MASK \ | ||
114 | (_NETIO_PKT_NO_L3_CSUM_RMASK << _NETIO_PKT_NO_L3_CSUM_SHIFT) | ||
115 | |||
116 | /** The L3 checksum is incorrect (or perhaps has not been calculated). */ | ||
117 | #define _NETIO_PKT_BAD_L3_CSUM_SHIFT 2 | ||
118 | #define _NETIO_PKT_BAD_L3_CSUM_RMASK 1 | ||
119 | #define _NETIO_PKT_BAD_L3_CSUM_MASK \ | ||
120 | (_NETIO_PKT_BAD_L3_CSUM_RMASK << _NETIO_PKT_BAD_L3_CSUM_SHIFT) | ||
121 | |||
122 | /** The Ethernet packet type is unrecognized. */ | ||
123 | #define _NETIO_PKT_TYPE_UNRECOGNIZED_SHIFT 3 | ||
124 | #define _NETIO_PKT_TYPE_UNRECOGNIZED_RMASK 1 | ||
125 | #define _NETIO_PKT_TYPE_UNRECOGNIZED_MASK \ | ||
126 | (_NETIO_PKT_TYPE_UNRECOGNIZED_RMASK << \ | ||
127 | _NETIO_PKT_TYPE_UNRECOGNIZED_SHIFT) | ||
128 | |||
129 | /* Metadata packet type flags. */ | ||
130 | |||
131 | /** Where the packet type bits are; this field is the index into | ||
132 | * _netio_pkt_info. */ | ||
133 | #define _NETIO_PKT_TYPE_SHIFT 4 | ||
134 | #define _NETIO_PKT_TYPE_RMASK 0x3F | ||
135 | |||
136 | /** How many VLAN tags the packet has, and, if we have two, which one we | ||
137 | * actually grouped on. A VLAN within a proprietary (Marvell or Broadcom) | ||
138 | * tag is counted here. */ | ||
139 | #define _NETIO_PKT_VLAN_SHIFT 4 | ||
140 | #define _NETIO_PKT_VLAN_RMASK 0x3 | ||
141 | #define _NETIO_PKT_VLAN_MASK \ | ||
142 | (_NETIO_PKT_VLAN_RMASK << _NETIO_PKT_VLAN_SHIFT) | ||
143 | #define _NETIO_PKT_VLAN_NONE 0 /* No VLAN tag. */ | ||
144 | #define _NETIO_PKT_VLAN_ONE 1 /* One VLAN tag. */ | ||
145 | #define _NETIO_PKT_VLAN_TWO_OUTER 2 /* Two VLAN tags, outer one used. */ | ||
146 | #define _NETIO_PKT_VLAN_TWO_INNER 3 /* Two VLAN tags, inner one used. */ | ||
147 | |||
148 | /** Which proprietary tags the packet has. */ | ||
149 | #define _NETIO_PKT_TAG_SHIFT 6 | ||
150 | #define _NETIO_PKT_TAG_RMASK 0x3 | ||
151 | #define _NETIO_PKT_TAG_MASK \ | ||
152 | (_NETIO_PKT_TAG_RMASK << _NETIO_PKT_TAG_SHIFT) | ||
153 | #define _NETIO_PKT_TAG_NONE 0 /* No proprietary tags. */ | ||
154 | #define _NETIO_PKT_TAG_MRVL 1 /* Marvell HyperG.Stack tags. */ | ||
155 | #define _NETIO_PKT_TAG_MRVL_EXT 2 /* HyperG.Stack extended tags. */ | ||
156 | #define _NETIO_PKT_TAG_BRCM 3 /* Broadcom HiGig tags. */ | ||
157 | |||
158 | /** Whether a packet has an LLC + SNAP header. */ | ||
159 | #define _NETIO_PKT_SNAP_SHIFT 8 | ||
160 | #define _NETIO_PKT_SNAP_RMASK 0x1 | ||
161 | #define _NETIO_PKT_SNAP_MASK \ | ||
162 | (_NETIO_PKT_SNAP_RMASK << _NETIO_PKT_SNAP_SHIFT) | ||
163 | |||
164 | /* NOTE: Bits 9 and 10 are unused. */ | ||
165 | |||
166 | /** Length of any custom data before the L2 header, in words. */ | ||
167 | #define _NETIO_PKT_CUSTOM_LEN_SHIFT 11 | ||
168 | #define _NETIO_PKT_CUSTOM_LEN_RMASK 0x1F | ||
169 | #define _NETIO_PKT_CUSTOM_LEN_MASK \ | ||
170 | (_NETIO_PKT_CUSTOM_LEN_RMASK << _NETIO_PKT_CUSTOM_LEN_SHIFT) | ||
171 | |||
172 | /** The L4 checksum is incorrect (or perhaps has not been calculated). */ | ||
173 | #define _NETIO_PKT_BAD_L4_CSUM_SHIFT 16 | ||
174 | #define _NETIO_PKT_BAD_L4_CSUM_RMASK 0x1 | ||
175 | #define _NETIO_PKT_BAD_L4_CSUM_MASK \ | ||
176 | (_NETIO_PKT_BAD_L4_CSUM_RMASK << _NETIO_PKT_BAD_L4_CSUM_SHIFT) | ||
177 | |||
178 | /** Length of the L2 header, in words. */ | ||
179 | #define _NETIO_PKT_L2_LEN_SHIFT 17 | ||
180 | #define _NETIO_PKT_L2_LEN_RMASK 0x1F | ||
181 | #define _NETIO_PKT_L2_LEN_MASK \ | ||
182 | (_NETIO_PKT_L2_LEN_RMASK << _NETIO_PKT_L2_LEN_SHIFT) | ||
183 | |||
184 | |||
185 | /* Flags in minimal packet metadata. */ | ||
186 | |||
187 | /** We need an eDMA checksum on this packet. */ | ||
188 | #define _NETIO_PKT_NEED_EDMA_CSUM_SHIFT 0 | ||
189 | #define _NETIO_PKT_NEED_EDMA_CSUM_RMASK 1 | ||
190 | #define _NETIO_PKT_NEED_EDMA_CSUM_MASK \ | ||
191 | (_NETIO_PKT_NEED_EDMA_CSUM_RMASK << _NETIO_PKT_NEED_EDMA_CSUM_SHIFT) | ||
192 | |||
193 | /* Data within the packet information table. */ | ||
194 | |||
195 | /* Note that, for efficiency, code which uses these fields assumes that none | ||
196 | * of the shift values below are zero. See uses below for an explanation. */ | ||
197 | |||
198 | /** Offset within the L2 header of the innermost ethertype (in halfwords). */ | ||
199 | #define _NETIO_PKT_INFO_ETYPE_SHIFT 6 | ||
200 | #define _NETIO_PKT_INFO_ETYPE_RMASK 0x1F | ||
201 | |||
202 | /** Offset within the L2 header of the VLAN tag (in halfwords). */ | ||
203 | #define _NETIO_PKT_INFO_VLAN_SHIFT 11 | ||
204 | #define _NETIO_PKT_INFO_VLAN_RMASK 0x1F | ||
205 | |||
206 | #endif | ||
207 | |||
208 | |||
209 | /** The size of a memory buffer representing a small packet. | ||
210 | * @ingroup egress */ | ||
211 | #define SMALL_PACKET_SIZE 256 | ||
212 | |||
213 | /** The size of a memory buffer representing a large packet. | ||
214 | * @ingroup egress */ | ||
215 | #define LARGE_PACKET_SIZE 2048 | ||
216 | |||
217 | /** The size of a memory buffer representing a jumbo packet. | ||
218 | * @ingroup egress */ | ||
219 | #define JUMBO_PACKET_SIZE (12 * 1024) | ||
220 | |||
221 | |||
222 | /* Common ethertypes. | ||
223 | * @ingroup ingress */ | ||
224 | /** @{ */ | ||
225 | /** The ethertype of IPv4. */ | ||
226 | #define ETHERTYPE_IPv4 (0x0800) | ||
227 | /** The ethertype of ARP. */ | ||
228 | #define ETHERTYPE_ARP (0x0806) | ||
229 | /** The ethertype of VLANs. */ | ||
230 | #define ETHERTYPE_VLAN (0x8100) | ||
231 | /** The ethertype of a Q-in-Q header. */ | ||
232 | #define ETHERTYPE_Q_IN_Q (0x9100) | ||
233 | /** The ethertype of IPv6. */ | ||
234 | #define ETHERTYPE_IPv6 (0x86DD) | ||
235 | /** The ethertype of MPLS. */ | ||
236 | #define ETHERTYPE_MPLS (0x8847) | ||
237 | /** @} */ | ||
238 | |||
239 | |||
240 | /** The possible return values of NETIO_PKT_STATUS. | ||
241 | * @ingroup ingress | ||
242 | */ | ||
243 | typedef enum | ||
244 | { | ||
245 | /** No problems were detected with this packet. */ | ||
246 | NETIO_PKT_STATUS_OK, | ||
247 | /** The packet is undersized; this is expected behavior if the packet's | ||
248 | * ethertype is unrecognized, but otherwise the packet is likely corrupt. */ | ||
249 | NETIO_PKT_STATUS_UNDERSIZE, | ||
250 | /** The packet is oversized and some trailing bytes have been discarded. | ||
251 | This is expected behavior for short packets, since it's impossible to | ||
252 | precisely determine the amount of padding which may have been added to | ||
253 | them to make them meet the minimum Ethernet packet size. */ | ||
254 | NETIO_PKT_STATUS_OVERSIZE, | ||
255 | /** The packet was judged to be corrupt by hardware (for instance, it had | ||
256 | a bad CRC, or part of it was discarded due to lack of buffer space in | ||
257 | the I/O shim) and should be discarded. */ | ||
258 | NETIO_PKT_STATUS_BAD | ||
259 | } netio_pkt_status_t; | ||
260 | |||
261 | |||
262 | /** Log2 of how many buckets we have. */ | ||
263 | #define NETIO_LOG2_NUM_BUCKETS (10) | ||
264 | |||
265 | /** How many buckets we have. | ||
266 | * @ingroup ingress */ | ||
267 | #define NETIO_NUM_BUCKETS (1 << NETIO_LOG2_NUM_BUCKETS) | ||
268 | |||
269 | |||
270 | /** | ||
271 | * @brief A group-to-bucket identifier. | ||
272 | * | ||
273 | * @ingroup setup | ||
274 | * | ||
275 | * This tells us what to do with a given group. | ||
276 | */ | ||
277 | typedef union { | ||
278 | /** The header broken down into bits. */ | ||
279 | struct { | ||
280 | /** Whether we should balance on L4, if available */ | ||
281 | unsigned int __balance_on_l4:1; | ||
282 | /** Whether we should balance on L3, if available */ | ||
283 | unsigned int __balance_on_l3:1; | ||
284 | /** Whether we should balance on L2, if available */ | ||
285 | unsigned int __balance_on_l2:1; | ||
286 | /** Reserved for future use */ | ||
287 | unsigned int __reserved:1; | ||
288 | /** The base bucket to use to send traffic */ | ||
289 | unsigned int __bucket_base:NETIO_LOG2_NUM_BUCKETS; | ||
290 | /** The mask to apply to the balancing value. This must be one less | ||
291 | * than a power of two, e.g. 0x3 or 0xFF. | ||
292 | */ | ||
293 | unsigned int __bucket_mask:NETIO_LOG2_NUM_BUCKETS; | ||
294 | /** Pad to 32 bits */ | ||
295 | unsigned int __padding:(32 - 4 - 2 * NETIO_LOG2_NUM_BUCKETS); | ||
296 | } bits; | ||
297 | /** To send out the IDN. */ | ||
298 | unsigned int word; | ||
299 | } | ||
300 | netio_group_t; | ||
301 | |||
302 | |||
303 | /** | ||
304 | * @brief A VLAN-to-bucket identifier. | ||
305 | * | ||
306 | * @ingroup setup | ||
307 | * | ||
308 | * This tells us what to do with a given VLAN. | ||
309 | */ | ||
310 | typedef netio_group_t netio_vlan_t; | ||
311 | |||
312 | |||
313 | /** | ||
314 | * A bucket-to-queue mapping. | ||
315 | * @ingroup setup | ||
316 | */ | ||
317 | typedef unsigned char netio_bucket_t; | ||
318 | |||
319 | |||
320 | /** | ||
321 | * A packet size can always fit in a netio_size_t. | ||
322 | * @ingroup setup | ||
323 | */ | ||
324 | typedef unsigned int netio_size_t; | ||
325 | |||
326 | |||
327 | /** | ||
328 | * @brief Ethernet standard (ingress) packet metadata. | ||
329 | * | ||
330 | * @ingroup ingress | ||
331 | * | ||
332 | * This is additional data associated with each packet. | ||
333 | * This structure is opaque and accessed through the @ref ingress. | ||
334 | * | ||
335 | * Also, the buffer population operation currently assumes that standard | ||
336 | * metadata is at least as large as minimal metadata, and will need to be | ||
337 | * modified if that is no longer the case. | ||
338 | */ | ||
339 | typedef struct | ||
340 | { | ||
341 | #ifdef __DOXYGEN__ | ||
342 | /** This structure is opaque. */ | ||
343 | unsigned char opaque[24]; | ||
344 | #else | ||
345 | /** The overall ordinal of the packet */ | ||
346 | unsigned int __packet_ordinal; | ||
347 | /** The ordinal of the packet within the group */ | ||
348 | unsigned int __group_ordinal; | ||
349 | /** The best flow hash IPP could compute. */ | ||
350 | unsigned int __flow_hash; | ||
351 | /** Flags pertaining to checksum calculation, packet type, etc. */ | ||
352 | unsigned int __flags; | ||
353 | /** The first word of "user data". */ | ||
354 | unsigned int __user_data_0; | ||
355 | /** The second word of "user data". */ | ||
356 | unsigned int __user_data_1; | ||
357 | #endif | ||
358 | } | ||
359 | netio_pkt_metadata_t; | ||
360 | |||
361 | |||
362 | /** To ensure that the L3 header is aligned mod 4, the L2 header should be | ||
363 | * aligned mod 4 plus 2, since every supported L2 header is 4n + 2 bytes | ||
364 | * long. The standard way to do this is to simply add 2 bytes of padding | ||
365 | * before the L2 header. | ||
366 | */ | ||
367 | #define NETIO_PACKET_PADDING 2 | ||
368 | |||
369 | |||
370 | |||
371 | /** | ||
372 | * @brief Ethernet minimal (egress) packet metadata. | ||
373 | * | ||
374 | * @ingroup egress | ||
375 | * | ||
376 | * This structure represents information about packets which have | ||
377 | * been processed by @ref netio_populate_buffer() or | ||
378 | * @ref netio_populate_prepend_buffer(). This structure is opaque | ||
379 | * and accessed through the @ref egress. | ||
380 | * | ||
381 | * @internal This structure is actually copied into the memory used by | ||
382 | * standard metadata, which is assumed to be large enough. | ||
383 | */ | ||
384 | typedef struct | ||
385 | { | ||
386 | #ifdef __DOXYGEN__ | ||
387 | /** This structure is opaque. */ | ||
388 | unsigned char opaque[14]; | ||
389 | #else | ||
390 | /** The offset of the L2 header from the start of the packet data. */ | ||
391 | unsigned short l2_offset; | ||
392 | /** The offset of the L3 header from the start of the packet data. */ | ||
393 | unsigned short l3_offset; | ||
394 | /** Where to write the checksum. */ | ||
395 | unsigned char csum_location; | ||
396 | /** Where to start checksumming from. */ | ||
397 | unsigned char csum_start; | ||
398 | /** Flags pertaining to checksum calculation etc. */ | ||
399 | unsigned short flags; | ||
400 | /** The L2 length of the packet. */ | ||
401 | unsigned short l2_length; | ||
402 | /** The checksum with which to seed the checksum generator. */ | ||
403 | unsigned short csum_seed; | ||
404 | /** How much to checksum. */ | ||
405 | unsigned short csum_length; | ||
406 | #endif | ||
407 | } | ||
408 | netio_pkt_minimal_metadata_t; | ||
409 | |||
410 | |||
411 | #ifndef __DOXYGEN__ | ||
412 | |||
413 | /** | ||
414 | * @brief An I/O notification header. | ||
415 | * | ||
416 | * This is the first word of data received from an I/O shim in a notification | ||
417 | * packet. It contains framing and status information. | ||
418 | */ | ||
419 | typedef union | ||
420 | { | ||
421 | unsigned int word; /**< The whole word. */ | ||
422 | /** The various fields. */ | ||
423 | struct | ||
424 | { | ||
425 | unsigned int __channel:7; /**< Resource channel. */ | ||
426 | unsigned int __type:4; /**< Type. */ | ||
427 | unsigned int __ack:1; /**< Whether an acknowledgement is needed. */ | ||
428 | unsigned int __reserved:1; /**< Reserved. */ | ||
429 | unsigned int __protocol:1; /**< A protocol-specific word is added. */ | ||
430 | unsigned int __status:2; /**< Status of the transfer. */ | ||
431 | unsigned int __framing:2; /**< Framing of the transfer. */ | ||
432 | unsigned int __transfer_size:14; /**< Transfer size in bytes (total). */ | ||
433 | } bits; | ||
434 | } | ||
435 | __netio_pkt_notif_t; | ||
436 | |||
437 | |||
438 | /** | ||
439 | * Returns the base address of the packet. | ||
440 | */ | ||
441 | #define _NETIO_PKT_HANDLE_BASE(p) \ | ||
442 | ((unsigned char*)((p).word & 0xFFFFFFC0)) | ||
443 | |||
444 | /** | ||
445 | * Returns the base address of the packet. | ||
446 | */ | ||
447 | #define _NETIO_PKT_BASE(p) \ | ||
448 | _NETIO_PKT_HANDLE_BASE(p->__packet) | ||
449 | |||
450 | /** | ||
451 | * @brief An I/O notification packet (second word) | ||
452 | * | ||
453 | * This is the second word of data received from an I/O shim in a notification | ||
454 | * packet. This is the virtual address of the packet buffer, plus some flag | ||
455 | * bits. (The virtual address of the packet is always 256-byte aligned so we | ||
456 | * have room for 8 bits' worth of flags in the low 8 bits.) | ||
457 | * | ||
458 | * @internal | ||
459 | * NOTE: The low two bits must contain "__queue", so the "packet size" | ||
460 | * (SIZE_SMALL, SIZE_LARGE, or SIZE_JUMBO) can be determined quickly. | ||
461 | * | ||
462 | * If __addr or __offset are moved, _NETIO_PKT_BASE | ||
463 | * (defined right below this) must be changed. | ||
464 | */ | ||
465 | typedef union | ||
466 | { | ||
467 | unsigned int word; /**< The whole word. */ | ||
468 | /** The various fields. */ | ||
469 | struct | ||
470 | { | ||
471 | /** Which queue the packet will be returned to once it is sent back to | ||
472 | the IPP. This is one of the SIZE_xxx values. */ | ||
473 | unsigned int __queue:2; | ||
474 | |||
475 | /** The IPP handle of the sending IPP. */ | ||
476 | unsigned int __ipp_handle:2; | ||
477 | |||
478 | /** Reserved for future use. */ | ||
479 | unsigned int __reserved:1; | ||
480 | |||
481 | /** If 1, this packet has minimal (egress) metadata; otherwise, it | ||
482 | has standard (ingress) metadata. */ | ||
483 | unsigned int __minimal:1; | ||
484 | |||
485 | /** Offset of the metadata within the packet. This value is multiplied | ||
486 | * by 64 and added to the base packet address to get the metadata | ||
487 | * address. Note that this field is aligned within the word such that | ||
488 | * you can easily extract the metadata address with a 26-bit mask. */ | ||
489 | unsigned int __offset:2; | ||
490 | |||
491 | /** The top 24 bits of the packet's virtual address. */ | ||
492 | unsigned int __addr:24; | ||
493 | } bits; | ||
494 | } | ||
495 | __netio_pkt_handle_t; | ||
496 | |||
497 | #endif /* !__DOXYGEN__ */ | ||
498 | |||
499 | |||
500 | /** | ||
501 | * @brief A handle for an I/O packet's storage. | ||
502 | * @ingroup ingress | ||
503 | * | ||
504 | * netio_pkt_handle_t encodes the concept of a ::netio_pkt_t with its | ||
505 | * packet metadata removed. It is a much smaller type that exists to | ||
506 | * facilitate applications where the full ::netio_pkt_t type is too | ||
507 | * large, such as those that cache enormous numbers of packets or wish | ||
508 | * to transmit packet descriptors over the UDN. | ||
509 | * | ||
510 | * Because there is no metadata, most ::netio_pkt_t operations cannot be | ||
511 | * performed on a netio_pkt_handle_t. It supports only | ||
512 | * netio_free_handle() (to free the buffer) and | ||
513 | * NETIO_PKT_CUSTOM_DATA_H() (to access a pointer to its contents). | ||
514 | * The application must acquire any additional metadata it wants from the | ||
515 | * original ::netio_pkt_t and record it separately. | ||
516 | * | ||
517 | * A netio_pkt_handle_t can be extracted from a ::netio_pkt_t by calling | ||
518 | * NETIO_PKT_HANDLE(). An invalid handle (analogous to NULL) can be | ||
519 | * created by assigning the value ::NETIO_PKT_HANDLE_NONE. A handle can | ||
520 | * be tested for validity with NETIO_PKT_HANDLE_IS_VALID(). | ||
521 | */ | ||
522 | typedef struct | ||
523 | { | ||
524 | unsigned int word; /**< Opaque bits. */ | ||
525 | } netio_pkt_handle_t; | ||
526 | |||
527 | /** | ||
528 | * @brief A packet descriptor. | ||
529 | * | ||
530 | * @ingroup ingress | ||
531 | * @ingroup egress | ||
532 | * | ||
533 | * This data structure represents a packet. The structure is manipulated | ||
534 | * through the @ref ingress and the @ref egress. | ||
535 | * | ||
536 | * While the contents of a netio_pkt_t are opaque, the structure itself is | ||
537 | * portable. This means that it may be shared between all tiles which have | ||
538 | * done a netio_input_register() call for the interface on which the pkt_t | ||
539 | * was initially received (via netio_get_packet()) or retrieved (via | ||
540 | * netio_get_buffer()). The contents of a netio_pkt_t can be transmitted to | ||
541 | * another tile via shared memory, or via a UDN message, or by other means. | ||
542 | * The destination tile may then use the pkt_t as if it had originally been | ||
543 | * received locally; it may read or write the packet's data, read its | ||
544 | * metadata, free the packet, send the packet, transfer the netio_pkt_t to | ||
545 | * yet another tile, and so forth. | ||
546 | * | ||
547 | * Once a netio_pkt_t has been transferred to a second tile, the first tile | ||
548 | * should not reference the original copy; in particular, if more than one | ||
549 | * tile frees or sends the same netio_pkt_t, the IPP's packet free lists will | ||
550 | * become corrupted. Note also that each tile which reads or modifies | ||
551 | * packet data must obey the memory coherency rules outlined in @ref input. | ||
552 | */ | ||
553 | typedef struct | ||
554 | { | ||
555 | #ifdef __DOXYGEN__ | ||
556 | /** This structure is opaque. */ | ||
557 | unsigned char opaque[32]; | ||
558 | #else | ||
559 | /** For an ingress packet (one with standard metadata), this is the | ||
560 | * notification header we got from the I/O shim. For an egress packet | ||
561 | * (one with minimal metadata), this word is zero if the packet has not | ||
562 | * been populated, and nonzero if it has. */ | ||
563 | __netio_pkt_notif_t __notif_header; | ||
564 | |||
565 | /** Virtual address of the packet buffer, plus state flags. */ | ||
566 | __netio_pkt_handle_t __packet; | ||
567 | |||
568 | /** Metadata associated with the packet. */ | ||
569 | netio_pkt_metadata_t __metadata; | ||
570 | #endif | ||
571 | } | ||
572 | netio_pkt_t; | ||
573 | |||
574 | |||
575 | #ifndef __DOXYGEN__ | ||
576 | |||
577 | #define __NETIO_PKT_NOTIF_HEADER(pkt) ((pkt)->__notif_header) | ||
578 | #define __NETIO_PKT_IPP_HANDLE(pkt) ((pkt)->__packet.bits.__ipp_handle) | ||
579 | #define __NETIO_PKT_QUEUE(pkt) ((pkt)->__packet.bits.__queue) | ||
580 | #define __NETIO_PKT_NOTIF_HEADER_M(mda, pkt) ((pkt)->__notif_header) | ||
581 | #define __NETIO_PKT_IPP_HANDLE_M(mda, pkt) ((pkt)->__packet.bits.__ipp_handle) | ||
582 | #define __NETIO_PKT_MINIMAL(pkt) ((pkt)->__packet.bits.__minimal) | ||
583 | #define __NETIO_PKT_QUEUE_M(mda, pkt) ((pkt)->__packet.bits.__queue) | ||
584 | #define __NETIO_PKT_FLAGS_M(mda, pkt) ((mda)->__flags) | ||
585 | |||
586 | /* Packet information table, used by the attribute access functions below. */ | ||
587 | extern const uint16_t _netio_pkt_info[]; | ||
588 | |||
589 | #endif /* __DOXYGEN__ */ | ||
590 | |||
591 | |||
592 | #ifndef __DOXYGEN__ | ||
593 | /* These macros are deprecated and will disappear in a future MDE release. */ | ||
594 | #define NETIO_PKT_GOOD_CHECKSUM(pkt) \ | ||
595 | NETIO_PKT_L4_CSUM_CORRECT(pkt) | ||
596 | #define NETIO_PKT_GOOD_CHECKSUM_M(mda, pkt) \ | ||
597 | NETIO_PKT_L4_CSUM_CORRECT_M(mda, pkt) | ||
598 | #endif /* __DOXYGEN__ */ | ||
599 | |||
600 | |||
601 | /* Packet attribute access functions. */ | ||
602 | |||
603 | /** Return a pointer to the metadata for a packet. | ||
604 | * @ingroup ingress | ||
605 | * | ||
606 | * Calling this function once and passing the result to other retrieval | ||
607 | * functions with a "_M" suffix usually improves performance. This | ||
608 | * function must be called on an 'ingress' packet (i.e. one retrieved | ||
609 | * by @ref netio_get_packet(), on which @ref netio_populate_buffer() or | ||
610 | * @ref netio_populate_prepend_buffer have not been called). Use of this | ||
611 | * function on an 'egress' packet will cause an assertion failure. | ||
612 | * | ||
613 | * @param[in] pkt Packet on which to operate. | ||
614 | * @return A pointer to the packet's standard metadata. | ||
615 | */ | ||
616 | static __inline netio_pkt_metadata_t* | ||
617 | NETIO_PKT_METADATA(netio_pkt_t* pkt) | ||
618 | { | ||
619 | netio_assert(!pkt->__packet.bits.__minimal); | ||
620 | return &pkt->__metadata; | ||
621 | } | ||
622 | |||
623 | |||
624 | /** Return a pointer to the minimal metadata for a packet. | ||
625 | * @ingroup egress | ||
626 | * | ||
627 | * Calling this function once and passing the result to other retrieval | ||
628 | * functions with a "_MM" suffix usually improves performance. This | ||
629 | * function must be called on an 'egress' packet (i.e. one on which | ||
630 | * @ref netio_populate_buffer() or @ref netio_populate_prepend_buffer() | ||
631 | * have been called, or one retrieved by @ref netio_get_buffer()). Use of | ||
632 | * this function on an 'ingress' packet will cause an assertion failure. | ||
633 | * | ||
634 | * @param[in] pkt Packet on which to operate. | ||
635 | * @return A pointer to the packet's standard metadata. | ||
636 | */ | ||
637 | static __inline netio_pkt_minimal_metadata_t* | ||
638 | NETIO_PKT_MINIMAL_METADATA(netio_pkt_t* pkt) | ||
639 | { | ||
640 | netio_assert(pkt->__packet.bits.__minimal); | ||
641 | return (netio_pkt_minimal_metadata_t*) &pkt->__metadata; | ||
642 | } | ||
643 | |||
644 | |||
645 | /** Determine whether a packet has 'minimal' metadata. | ||
646 | * @ingroup pktfuncs | ||
647 | * | ||
648 | * This function will return nonzero if the packet is an 'egress' | ||
649 | * packet (i.e. one on which @ref netio_populate_buffer() or | ||
650 | * @ref netio_populate_prepend_buffer() have been called, or one | ||
651 | * retrieved by @ref netio_get_buffer()), and zero if the packet | ||
652 | * is an 'ingress' packet (i.e. one retrieved by @ref netio_get_packet(), | ||
653 | * which has not been converted into an 'egress' packet). | ||
654 | * | ||
655 | * @param[in] pkt Packet on which to operate. | ||
656 | * @return Nonzero if the packet has minimal metadata. | ||
657 | */ | ||
658 | static __inline unsigned int | ||
659 | NETIO_PKT_IS_MINIMAL(netio_pkt_t* pkt) | ||
660 | { | ||
661 | return pkt->__packet.bits.__minimal; | ||
662 | } | ||
663 | |||
664 | |||
665 | /** Return a handle for a packet's storage. | ||
666 | * @ingroup pktfuncs | ||
667 | * | ||
668 | * @param[in] pkt Packet on which to operate. | ||
669 | * @return A handle for the packet's storage. | ||
670 | */ | ||
671 | static __inline netio_pkt_handle_t | ||
672 | NETIO_PKT_HANDLE(netio_pkt_t* pkt) | ||
673 | { | ||
674 | netio_pkt_handle_t h; | ||
675 | h.word = pkt->__packet.word; | ||
676 | return h; | ||
677 | } | ||
678 | |||
679 | |||
680 | /** A special reserved value indicating the absence of a packet handle. | ||
681 | * | ||
682 | * @ingroup pktfuncs | ||
683 | */ | ||
684 | #define NETIO_PKT_HANDLE_NONE ((netio_pkt_handle_t) { 0 }) | ||
685 | |||
686 | |||
687 | /** Test whether a packet handle is valid. | ||
688 | * | ||
689 | * Applications may wish to use the reserved value NETIO_PKT_HANDLE_NONE | ||
690 | * to indicate no packet at all. This function tests to see if a packet | ||
691 | * handle is a real handle, not this special reserved value. | ||
692 | * | ||
693 | * @ingroup pktfuncs | ||
694 | * | ||
695 | * @param[in] handle Handle on which to operate. | ||
696 | * @return One if the packet handle is valid, else zero. | ||
697 | */ | ||
698 | static __inline unsigned int | ||
699 | NETIO_PKT_HANDLE_IS_VALID(netio_pkt_handle_t handle) | ||
700 | { | ||
701 | return handle.word != 0; | ||
702 | } | ||
703 | |||
704 | |||
705 | |||
706 | /** Return a pointer to the start of the packet's custom header. | ||
707 | * A custom header may or may not be present, depending upon the IPP; its | ||
708 | * contents and alignment are also IPP-dependent. Currently, none of the | ||
709 | * standard IPPs supplied by Tilera produce a custom header. If present, | ||
710 | * the custom header precedes the L2 header in the packet buffer. | ||
711 | * @ingroup ingress | ||
712 | * | ||
713 | * @param[in] handle Handle on which to operate. | ||
714 | * @return A pointer to start of the packet. | ||
715 | */ | ||
716 | static __inline unsigned char* | ||
717 | NETIO_PKT_CUSTOM_DATA_H(netio_pkt_handle_t handle) | ||
718 | { | ||
719 | return _NETIO_PKT_HANDLE_BASE(handle) + NETIO_PACKET_PADDING; | ||
720 | } | ||
721 | |||
722 | |||
723 | /** Return the length of the packet's custom header. | ||
724 | * A custom header may or may not be present, depending upon the IPP; its | ||
725 | * contents and alignment are also IPP-dependent. Currently, none of the | ||
726 | * standard IPPs supplied by Tilera produce a custom header. If present, | ||
727 | * the custom header precedes the L2 header in the packet buffer. | ||
728 | * | ||
729 | * @ingroup ingress | ||
730 | * | ||
731 | * @param[in] mda Pointer to packet's standard metadata. | ||
732 | * @param[in] pkt Packet on which to operate. | ||
733 | * @return The length of the packet's custom header, in bytes. | ||
734 | */ | ||
735 | static __inline netio_size_t | ||
736 | NETIO_PKT_CUSTOM_HEADER_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
737 | { | ||
738 | /* | ||
739 | * Note that we effectively need to extract a quantity from the flags word | ||
740 | * which is measured in words, and then turn it into bytes by shifting | ||
741 | * it left by 2. We do this all at once by just shifting right two less | ||
742 | * bits, and shifting the mask up two bits. | ||
743 | */ | ||
744 | return ((mda->__flags >> (_NETIO_PKT_CUSTOM_LEN_SHIFT - 2)) & | ||
745 | (_NETIO_PKT_CUSTOM_LEN_RMASK << 2)); | ||
746 | } | ||
747 | |||
748 | |||
749 | /** Return the length of the packet, starting with the custom header. | ||
750 | * A custom header may or may not be present, depending upon the IPP; its | ||
751 | * contents and alignment are also IPP-dependent. Currently, none of the | ||
752 | * standard IPPs supplied by Tilera produce a custom header. If present, | ||
753 | * the custom header precedes the L2 header in the packet buffer. | ||
754 | * @ingroup ingress | ||
755 | * | ||
756 | * @param[in] mda Pointer to packet's standard metadata. | ||
757 | * @param[in] pkt Packet on which to operate. | ||
758 | * @return The length of the packet, in bytes. | ||
759 | */ | ||
760 | static __inline netio_size_t | ||
761 | NETIO_PKT_CUSTOM_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
762 | { | ||
763 | return (__NETIO_PKT_NOTIF_HEADER(pkt).bits.__transfer_size - | ||
764 | NETIO_PACKET_PADDING); | ||
765 | } | ||
766 | |||
767 | |||
768 | /** Return a pointer to the start of the packet's custom header. | ||
769 | * A custom header may or may not be present, depending upon the IPP; its | ||
770 | * contents and alignment are also IPP-dependent. Currently, none of the | ||
771 | * standard IPPs supplied by Tilera produce a custom header. If present, | ||
772 | * the custom header precedes the L2 header in the packet buffer. | ||
773 | * @ingroup ingress | ||
774 | * | ||
775 | * @param[in] mda Pointer to packet's standard metadata. | ||
776 | * @param[in] pkt Packet on which to operate. | ||
777 | * @return A pointer to start of the packet. | ||
778 | */ | ||
779 | static __inline unsigned char* | ||
780 | NETIO_PKT_CUSTOM_DATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
781 | { | ||
782 | return NETIO_PKT_CUSTOM_DATA_H(NETIO_PKT_HANDLE(pkt)); | ||
783 | } | ||
784 | |||
785 | |||
786 | /** Return the length of the packet's L2 (Ethernet plus VLAN or SNAP) header. | ||
787 | * @ingroup ingress | ||
788 | * | ||
789 | * @param[in] mda Pointer to packet's standard metadata. | ||
790 | * @param[in] pkt Packet on which to operate. | ||
791 | * @return The length of the packet's L2 header, in bytes. | ||
792 | */ | ||
793 | static __inline netio_size_t | ||
794 | NETIO_PKT_L2_HEADER_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
795 | { | ||
796 | /* | ||
797 | * Note that we effectively need to extract a quantity from the flags word | ||
798 | * which is measured in words, and then turn it into bytes by shifting | ||
799 | * it left by 2. We do this all at once by just shifting right two less | ||
800 | * bits, and shifting the mask up two bits. We then add two bytes. | ||
801 | */ | ||
802 | return ((mda->__flags >> (_NETIO_PKT_L2_LEN_SHIFT - 2)) & | ||
803 | (_NETIO_PKT_L2_LEN_RMASK << 2)) + 2; | ||
804 | } | ||
805 | |||
806 | |||
807 | /** Return the length of the packet, starting with the L2 (Ethernet) header. | ||
808 | * @ingroup ingress | ||
809 | * | ||
810 | * @param[in] mda Pointer to packet's standard metadata. | ||
811 | * @param[in] pkt Packet on which to operate. | ||
812 | * @return The length of the packet, in bytes. | ||
813 | */ | ||
814 | static __inline netio_size_t | ||
815 | NETIO_PKT_L2_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
816 | { | ||
817 | return (NETIO_PKT_CUSTOM_LENGTH_M(mda, pkt) - | ||
818 | NETIO_PKT_CUSTOM_HEADER_LENGTH_M(mda,pkt)); | ||
819 | } | ||
820 | |||
821 | |||
822 | /** Return a pointer to the start of the packet's L2 (Ethernet) header. | ||
823 | * @ingroup ingress | ||
824 | * | ||
825 | * @param[in] mda Pointer to packet's standard metadata. | ||
826 | * @param[in] pkt Packet on which to operate. | ||
827 | * @return A pointer to start of the packet. | ||
828 | */ | ||
829 | static __inline unsigned char* | ||
830 | NETIO_PKT_L2_DATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
831 | { | ||
832 | return (NETIO_PKT_CUSTOM_DATA_M(mda, pkt) + | ||
833 | NETIO_PKT_CUSTOM_HEADER_LENGTH_M(mda, pkt)); | ||
834 | } | ||
835 | |||
836 | |||
837 | /** Retrieve the length of the packet, starting with the L3 (generally, | ||
838 | * the IP) header. | ||
839 | * @ingroup ingress | ||
840 | * | ||
841 | * @param[in] mda Pointer to packet's standard metadata. | ||
842 | * @param[in] pkt Packet on which to operate. | ||
843 | * @return Length of the packet's L3 header and data, in bytes. | ||
844 | */ | ||
845 | static __inline netio_size_t | ||
846 | NETIO_PKT_L3_LENGTH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
847 | { | ||
848 | return (NETIO_PKT_L2_LENGTH_M(mda, pkt) - | ||
849 | NETIO_PKT_L2_HEADER_LENGTH_M(mda,pkt)); | ||
850 | } | ||
851 | |||
852 | |||
853 | /** Return a pointer to the packet's L3 (generally, the IP) header. | ||
854 | * @ingroup ingress | ||
855 | * | ||
856 | * Note that we guarantee word alignment of the L3 header. | ||
857 | * | ||
858 | * @param[in] mda Pointer to packet's standard metadata. | ||
859 | * @param[in] pkt Packet on which to operate. | ||
860 | * @return A pointer to the packet's L3 header. | ||
861 | */ | ||
862 | static __inline unsigned char* | ||
863 | NETIO_PKT_L3_DATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
864 | { | ||
865 | return (NETIO_PKT_L2_DATA_M(mda, pkt) + | ||
866 | NETIO_PKT_L2_HEADER_LENGTH_M(mda, pkt)); | ||
867 | } | ||
868 | |||
869 | |||
870 | /** Return the ordinal of the packet. | ||
871 | * @ingroup ingress | ||
872 | * | ||
873 | * Each packet is given an ordinal number when it is delivered by the IPP. | ||
874 | * In the medium term, the ordinal is unique and monotonically increasing, | ||
875 | * being incremented by 1 for each packet; the ordinal of the first packet | ||
876 | * delivered after the IPP starts is zero. (Since the ordinal is of finite | ||
877 | * size, given enough input packets, it will eventually wrap around to zero; | ||
878 | * in the long term, therefore, ordinals are not unique.) The ordinals | ||
879 | * handed out by different IPPs are not disjoint, so two packets from | ||
880 | * different IPPs may have identical ordinals. Packets dropped by the | ||
881 | * IPP or by the I/O shim are not assigned ordinals. | ||
882 | * | ||
883 | * @param[in] mda Pointer to packet's standard metadata. | ||
884 | * @param[in] pkt Packet on which to operate. | ||
885 | * @return The packet's per-IPP packet ordinal. | ||
886 | */ | ||
887 | static __inline unsigned int | ||
888 | NETIO_PKT_ORDINAL_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
889 | { | ||
890 | return mda->__packet_ordinal; | ||
891 | } | ||
892 | |||
893 | |||
894 | /** Return the per-group ordinal of the packet. | ||
895 | * @ingroup ingress | ||
896 | * | ||
897 | * Each packet is given a per-group ordinal number when it is | ||
898 | * delivered by the IPP. By default, the group is the packet's VLAN, | ||
899 | * although IPP can be recompiled to use different values. In | ||
900 | * the medium term, the ordinal is unique and monotonically | ||
901 | * increasing, being incremented by 1 for each packet; the ordinal of | ||
902 | * the first packet distributed to a particular group is zero. | ||
903 | * (Since the ordinal is of finite size, given enough input packets, | ||
904 | * it will eventually wrap around to zero; in the long term, | ||
905 | * therefore, ordinals are not unique.) The ordinals handed out by | ||
906 | * different IPPs are not disjoint, so two packets from different IPPs | ||
907 | * may have identical ordinals; similarly, packets distributed to | ||
908 | * different groups may have identical ordinals. Packets dropped by | ||
909 | * the IPP or by the I/O shim are not assigned ordinals. | ||
910 | * | ||
911 | * @param[in] mda Pointer to packet's standard metadata. | ||
912 | * @param[in] pkt Packet on which to operate. | ||
913 | * @return The packet's per-IPP, per-group ordinal. | ||
914 | */ | ||
915 | static __inline unsigned int | ||
916 | NETIO_PKT_GROUP_ORDINAL_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
917 | { | ||
918 | return mda->__group_ordinal; | ||
919 | } | ||
920 | |||
921 | |||
922 | /** Return the VLAN ID assigned to the packet. | ||
923 | * @ingroup ingress | ||
924 | * | ||
925 | * This value is usually contained within the packet header. | ||
926 | * | ||
927 | * This value will be zero if the packet does not have a VLAN tag, or if | ||
928 | * this value was not extracted from the packet. | ||
929 | * | ||
930 | * @param[in] mda Pointer to packet's standard metadata. | ||
931 | * @param[in] pkt Packet on which to operate. | ||
932 | * @return The packet's VLAN ID. | ||
933 | */ | ||
934 | static __inline unsigned short | ||
935 | NETIO_PKT_VLAN_ID_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
936 | { | ||
937 | int vl = (mda->__flags >> _NETIO_PKT_VLAN_SHIFT) & _NETIO_PKT_VLAN_RMASK; | ||
938 | unsigned short* pkt_p; | ||
939 | int index; | ||
940 | unsigned short val; | ||
941 | |||
942 | if (vl == _NETIO_PKT_VLAN_NONE) | ||
943 | return 0; | ||
944 | |||
945 | pkt_p = (unsigned short*) NETIO_PKT_L2_DATA_M(mda, pkt); | ||
946 | index = (mda->__flags >> _NETIO_PKT_TYPE_SHIFT) & _NETIO_PKT_TYPE_RMASK; | ||
947 | |||
948 | val = pkt_p[(_netio_pkt_info[index] >> _NETIO_PKT_INFO_VLAN_SHIFT) & | ||
949 | _NETIO_PKT_INFO_VLAN_RMASK]; | ||
950 | |||
951 | #ifdef __TILECC__ | ||
952 | return (__insn_bytex(val) >> 16) & 0xFFF; | ||
953 | #else | ||
954 | return (__builtin_bswap32(val) >> 16) & 0xFFF; | ||
955 | #endif | ||
956 | } | ||
957 | |||
958 | |||
959 | /** Return the ethertype of the packet. | ||
960 | * @ingroup ingress | ||
961 | * | ||
962 | * This value is usually contained within the packet header. | ||
963 | * | ||
964 | * This value is reliable if @ref NETIO_PKT_ETHERTYPE_RECOGNIZED_M() | ||
965 | * returns true, and otherwise, may not be well defined. | ||
966 | * | ||
967 | * @param[in] mda Pointer to packet's standard metadata. | ||
968 | * @param[in] pkt Packet on which to operate. | ||
969 | * @return The packet's ethertype. | ||
970 | */ | ||
971 | static __inline unsigned short | ||
972 | NETIO_PKT_ETHERTYPE_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
973 | { | ||
974 | unsigned short* pkt_p = (unsigned short*) NETIO_PKT_L2_DATA_M(mda, pkt); | ||
975 | int index = (mda->__flags >> _NETIO_PKT_TYPE_SHIFT) & _NETIO_PKT_TYPE_RMASK; | ||
976 | |||
977 | unsigned short val = | ||
978 | pkt_p[(_netio_pkt_info[index] >> _NETIO_PKT_INFO_ETYPE_SHIFT) & | ||
979 | _NETIO_PKT_INFO_ETYPE_RMASK]; | ||
980 | |||
981 | return __builtin_bswap32(val) >> 16; | ||
982 | } | ||
983 | |||
984 | |||
985 | /** Return the flow hash computed on the packet. | ||
986 | * @ingroup ingress | ||
987 | * | ||
988 | * For TCP and UDP packets, this hash is calculated by hashing together | ||
989 | * the "5-tuple" values, specifically the source IP address, destination | ||
990 | * IP address, protocol type, source port and destination port. | ||
991 | * The hash value is intended to be helpful for millions of distinct | ||
992 | * flows. | ||
993 | * | ||
994 | * For IPv4 or IPv6 packets which are neither TCP nor UDP, the flow hash is | ||
995 | * derived by hashing together the source and destination IP addresses. | ||
996 | * | ||
997 | * For MPLS-encapsulated packets, the flow hash is derived by hashing | ||
998 | * the first MPLS label. | ||
999 | * | ||
1000 | * For all other packets the flow hash is computed from the source | ||
1001 | * and destination Ethernet addresses. | ||
1002 | * | ||
1003 | * The hash is symmetric, meaning it produces the same value if the | ||
1004 | * source and destination are swapped. The only exceptions are | ||
1005 | * tunneling protocols 0x04 (IP in IP Encapsulation), 0x29 (Simple | ||
1006 | * Internet Protocol), 0x2F (General Routing Encapsulation) and 0x32 | ||
1007 | * (Encap Security Payload), which use only the destination address | ||
1008 | * since the source address is not meaningful. | ||
1009 | * | ||
1010 | * @param[in] mda Pointer to packet's standard metadata. | ||
1011 | * @param[in] pkt Packet on which to operate. | ||
1012 | * @return The packet's 32-bit flow hash. | ||
1013 | */ | ||
1014 | static __inline unsigned int | ||
1015 | NETIO_PKT_FLOW_HASH_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
1016 | { | ||
1017 | return mda->__flow_hash; | ||
1018 | } | ||
1019 | |||
1020 | |||
1021 | /** Return the first word of "user data" for the packet. | ||
1022 | * | ||
1023 | * The contents of the user data words depend on the IPP. | ||
1024 | * | ||
1025 | * When using the standard ipp1, ipp2, or ipp4 sub-drivers, the first | ||
1026 | * word of user data contains the least significant bits of the 64-bit | ||
1027 | * arrival cycle count (see @c get_cycle_count_low()). | ||
1028 | * | ||
1029 | * See the <em>System Programmer's Guide</em> for details. | ||
1030 | * | ||
1031 | * @ingroup ingress | ||
1032 | * | ||
1033 | * @param[in] mda Pointer to packet's standard metadata. | ||
1034 | * @param[in] pkt Packet on which to operate. | ||
1035 | * @return The packet's first word of "user data". | ||
1036 | */ | ||
1037 | static __inline unsigned int | ||
1038 | NETIO_PKT_USER_DATA_0_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
1039 | { | ||
1040 | return mda->__user_data_0; | ||
1041 | } | ||
1042 | |||
1043 | |||
1044 | /** Return the second word of "user data" for the packet. | ||
1045 | * | ||
1046 | * The contents of the user data words depend on the IPP. | ||
1047 | * | ||
1048 | * When using the standard ipp1, ipp2, or ipp4 sub-drivers, the second | ||
1049 | * word of user data contains the most significant bits of the 64-bit | ||
1050 | * arrival cycle count (see @c get_cycle_count_high()). | ||
1051 | * | ||
1052 | * See the <em>System Programmer's Guide</em> for details. | ||
1053 | * | ||
1054 | * @ingroup ingress | ||
1055 | * | ||
1056 | * @param[in] mda Pointer to packet's standard metadata. | ||
1057 | * @param[in] pkt Packet on which to operate. | ||
1058 | * @return The packet's second word of "user data". | ||
1059 | */ | ||
1060 | static __inline unsigned int | ||
1061 | NETIO_PKT_USER_DATA_1_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
1062 | { | ||
1063 | return mda->__user_data_1; | ||
1064 | } | ||
1065 | |||
1066 | |||
1067 | /** Determine whether the L4 (TCP/UDP) checksum was calculated. | ||
1068 | * @ingroup ingress | ||
1069 | * | ||
1070 | * @param[in] mda Pointer to packet's standard metadata. | ||
1071 | * @param[in] pkt Packet on which to operate. | ||
1072 | * @return Nonzero if the L4 checksum was calculated. | ||
1073 | */ | ||
1074 | static __inline unsigned int | ||
1075 | NETIO_PKT_L4_CSUM_CALCULATED_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
1076 | { | ||
1077 | return !(mda->__flags & _NETIO_PKT_NO_L4_CSUM_MASK); | ||
1078 | } | ||
1079 | |||
1080 | |||
1081 | /** Determine whether the L4 (TCP/UDP) checksum was calculated and found to | ||
1082 | * be correct. | ||
1083 | * @ingroup ingress | ||
1084 | * | ||
1085 | * @param[in] mda Pointer to packet's standard metadata. | ||
1086 | * @param[in] pkt Packet on which to operate. | ||
1087 | * @return Nonzero if the checksum was calculated and is correct. | ||
1088 | */ | ||
1089 | static __inline unsigned int | ||
1090 | NETIO_PKT_L4_CSUM_CORRECT_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
1091 | { | ||
1092 | return !(mda->__flags & | ||
1093 | (_NETIO_PKT_BAD_L4_CSUM_MASK | _NETIO_PKT_NO_L4_CSUM_MASK)); | ||
1094 | } | ||
1095 | |||
1096 | |||
1097 | /** Determine whether the L3 (IP) checksum was calculated. | ||
1098 | * @ingroup ingress | ||
1099 | * | ||
1100 | * @param[in] mda Pointer to packet's standard metadata. | ||
1101 | * @param[in] pkt Packet on which to operate. | ||
1102 | * @return Nonzero if the L3 (IP) checksum was calculated. | ||
1103 | */ | ||
1104 | static __inline unsigned int | ||
1105 | NETIO_PKT_L3_CSUM_CALCULATED_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
1106 | { | ||
1107 | return !(mda->__flags & _NETIO_PKT_NO_L3_CSUM_MASK); | ||
1108 | } | ||
1109 | |||
1110 | |||
1111 | /** Determine whether the L3 (IP) checksum was calculated and found to be | ||
1112 | * correct. | ||
1113 | * @ingroup ingress | ||
1114 | * | ||
1115 | * @param[in] mda Pointer to packet's standard metadata. | ||
1116 | * @param[in] pkt Packet on which to operate. | ||
1117 | * @return Nonzero if the checksum was calculated and is correct. | ||
1118 | */ | ||
1119 | static __inline unsigned int | ||
1120 | NETIO_PKT_L3_CSUM_CORRECT_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
1121 | { | ||
1122 | return !(mda->__flags & | ||
1123 | (_NETIO_PKT_BAD_L3_CSUM_MASK | _NETIO_PKT_NO_L3_CSUM_MASK)); | ||
1124 | } | ||
1125 | |||
1126 | |||
1127 | /** Determine whether the ethertype was recognized and L3 packet data was | ||
1128 | * processed. | ||
1129 | * @ingroup ingress | ||
1130 | * | ||
1131 | * @param[in] mda Pointer to packet's standard metadata. | ||
1132 | * @param[in] pkt Packet on which to operate. | ||
1133 | * @return Nonzero if the ethertype was recognized and L3 packet data was | ||
1134 | * processed. | ||
1135 | */ | ||
1136 | static __inline unsigned int | ||
1137 | NETIO_PKT_ETHERTYPE_RECOGNIZED_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
1138 | { | ||
1139 | return !(mda->__flags & _NETIO_PKT_TYPE_UNRECOGNIZED_MASK); | ||
1140 | } | ||
1141 | |||
1142 | |||
1143 | /** Retrieve the status of a packet and any errors that may have occurred | ||
1144 | * during ingress processing (length mismatches, CRC errors, etc.). | ||
1145 | * @ingroup ingress | ||
1146 | * | ||
1147 | * Note that packets for which @ref NETIO_PKT_ETHERTYPE_RECOGNIZED() | ||
1148 | * returns zero are always reported as underlength, as there is no a priori | ||
1149 | * means to determine their length. Normally, applications should use | ||
1150 | * @ref NETIO_PKT_BAD_M() instead of explicitly checking status with this | ||
1151 | * function. | ||
1152 | * | ||
1153 | * @param[in] mda Pointer to packet's standard metadata. | ||
1154 | * @param[in] pkt Packet on which to operate. | ||
1155 | * @return The packet's status. | ||
1156 | */ | ||
1157 | static __inline netio_pkt_status_t | ||
1158 | NETIO_PKT_STATUS_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
1159 | { | ||
1160 | return (netio_pkt_status_t) __NETIO_PKT_NOTIF_HEADER(pkt).bits.__status; | ||
1161 | } | ||
1162 | |||
1163 | |||
1164 | /** Report whether a packet is bad (i.e., was shorter than expected based on | ||
1165 | * its headers, or had a bad CRC). | ||
1166 | * @ingroup ingress | ||
1167 | * | ||
1168 | * Note that this function does not verify L3 or L4 checksums. | ||
1169 | * | ||
1170 | * @param[in] mda Pointer to packet's standard metadata. | ||
1171 | * @param[in] pkt Packet on which to operate. | ||
1172 | * @return Nonzero if the packet is bad and should be discarded. | ||
1173 | */ | ||
1174 | static __inline unsigned int | ||
1175 | NETIO_PKT_BAD_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
1176 | { | ||
1177 | return ((NETIO_PKT_STATUS_M(mda, pkt) & 1) && | ||
1178 | (NETIO_PKT_ETHERTYPE_RECOGNIZED_M(mda, pkt) || | ||
1179 | NETIO_PKT_STATUS_M(mda, pkt) == NETIO_PKT_STATUS_BAD)); | ||
1180 | } | ||
1181 | |||
1182 | |||
1183 | /** Return the length of the packet, starting with the L2 (Ethernet) header. | ||
1184 | * @ingroup egress | ||
1185 | * | ||
1186 | * @param[in] mmd Pointer to packet's minimal metadata. | ||
1187 | * @param[in] pkt Packet on which to operate. | ||
1188 | * @return The length of the packet, in bytes. | ||
1189 | */ | ||
1190 | static __inline netio_size_t | ||
1191 | NETIO_PKT_L2_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt) | ||
1192 | { | ||
1193 | return mmd->l2_length; | ||
1194 | } | ||
1195 | |||
1196 | |||
1197 | /** Return the length of the L2 (Ethernet) header. | ||
1198 | * @ingroup egress | ||
1199 | * | ||
1200 | * @param[in] mmd Pointer to packet's minimal metadata. | ||
1201 | * @param[in] pkt Packet on which to operate. | ||
1202 | * @return The length of the packet's L2 header, in bytes. | ||
1203 | */ | ||
1204 | static __inline netio_size_t | ||
1205 | NETIO_PKT_L2_HEADER_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd, | ||
1206 | netio_pkt_t* pkt) | ||
1207 | { | ||
1208 | return mmd->l3_offset - mmd->l2_offset; | ||
1209 | } | ||
1210 | |||
1211 | |||
1212 | /** Return the length of the packet, starting with the L3 (IP) header. | ||
1213 | * @ingroup egress | ||
1214 | * | ||
1215 | * @param[in] mmd Pointer to packet's minimal metadata. | ||
1216 | * @param[in] pkt Packet on which to operate. | ||
1217 | * @return Length of the packet's L3 header and data, in bytes. | ||
1218 | */ | ||
1219 | static __inline netio_size_t | ||
1220 | NETIO_PKT_L3_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt) | ||
1221 | { | ||
1222 | return (NETIO_PKT_L2_LENGTH_MM(mmd, pkt) - | ||
1223 | NETIO_PKT_L2_HEADER_LENGTH_MM(mmd, pkt)); | ||
1224 | } | ||
1225 | |||
1226 | |||
1227 | /** Return a pointer to the packet's L3 (generally, the IP) header. | ||
1228 | * @ingroup egress | ||
1229 | * | ||
1230 | * Note that we guarantee word alignment of the L3 header. | ||
1231 | * | ||
1232 | * @param[in] mmd Pointer to packet's minimal metadata. | ||
1233 | * @param[in] pkt Packet on which to operate. | ||
1234 | * @return A pointer to the packet's L3 header. | ||
1235 | */ | ||
1236 | static __inline unsigned char* | ||
1237 | NETIO_PKT_L3_DATA_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt) | ||
1238 | { | ||
1239 | return _NETIO_PKT_BASE(pkt) + mmd->l3_offset; | ||
1240 | } | ||
1241 | |||
1242 | |||
1243 | /** Return a pointer to the packet's L2 (Ethernet) header. | ||
1244 | * @ingroup egress | ||
1245 | * | ||
1246 | * @param[in] mmd Pointer to packet's minimal metadata. | ||
1247 | * @param[in] pkt Packet on which to operate. | ||
1248 | * @return A pointer to start of the packet. | ||
1249 | */ | ||
1250 | static __inline unsigned char* | ||
1251 | NETIO_PKT_L2_DATA_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt) | ||
1252 | { | ||
1253 | return _NETIO_PKT_BASE(pkt) + mmd->l2_offset; | ||
1254 | } | ||
1255 | |||
1256 | |||
1257 | /** Retrieve the status of a packet and any errors that may have occurred | ||
1258 | * during ingress processing (length mismatches, CRC errors, etc.). | ||
1259 | * @ingroup ingress | ||
1260 | * | ||
1261 | * Note that packets for which @ref NETIO_PKT_ETHERTYPE_RECOGNIZED() | ||
1262 | * returns zero are always reported as underlength, as there is no a priori | ||
1263 | * means to determine their length. Normally, applications should use | ||
1264 | * @ref NETIO_PKT_BAD() instead of explicitly checking status with this | ||
1265 | * function. | ||
1266 | * | ||
1267 | * @param[in] pkt Packet on which to operate. | ||
1268 | * @return The packet's status. | ||
1269 | */ | ||
1270 | static __inline netio_pkt_status_t | ||
1271 | NETIO_PKT_STATUS(netio_pkt_t* pkt) | ||
1272 | { | ||
1273 | netio_assert(!pkt->__packet.bits.__minimal); | ||
1274 | |||
1275 | return (netio_pkt_status_t) __NETIO_PKT_NOTIF_HEADER(pkt).bits.__status; | ||
1276 | } | ||
1277 | |||
1278 | |||
1279 | /** Report whether a packet is bad (i.e., was shorter than expected based on | ||
1280 | * its headers, or had a bad CRC). | ||
1281 | * @ingroup ingress | ||
1282 | * | ||
1283 | * Note that this function does not verify L3 or L4 checksums. | ||
1284 | * | ||
1285 | * @param[in] pkt Packet on which to operate. | ||
1286 | * @return Nonzero if the packet is bad and should be discarded. | ||
1287 | */ | ||
1288 | static __inline unsigned int | ||
1289 | NETIO_PKT_BAD(netio_pkt_t* pkt) | ||
1290 | { | ||
1291 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1292 | |||
1293 | return NETIO_PKT_BAD_M(mda, pkt); | ||
1294 | } | ||
1295 | |||
1296 | |||
1297 | /** Return the length of the packet's custom header. | ||
1298 | * A custom header may or may not be present, depending upon the IPP; its | ||
1299 | * contents and alignment are also IPP-dependent. Currently, none of the | ||
1300 | * standard IPPs supplied by Tilera produce a custom header. If present, | ||
1301 | * the custom header precedes the L2 header in the packet buffer. | ||
1302 | * @ingroup pktfuncs | ||
1303 | * | ||
1304 | * @param[in] pkt Packet on which to operate. | ||
1305 | * @return The length of the packet's custom header, in bytes. | ||
1306 | */ | ||
1307 | static __inline netio_size_t | ||
1308 | NETIO_PKT_CUSTOM_HEADER_LENGTH(netio_pkt_t* pkt) | ||
1309 | { | ||
1310 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1311 | |||
1312 | return NETIO_PKT_CUSTOM_HEADER_LENGTH_M(mda, pkt); | ||
1313 | } | ||
1314 | |||
1315 | |||
1316 | /** Return the length of the packet, starting with the custom header. | ||
1317 | * A custom header may or may not be present, depending upon the IPP; its | ||
1318 | * contents and alignment are also IPP-dependent. Currently, none of the | ||
1319 | * standard IPPs supplied by Tilera produce a custom header. If present, | ||
1320 | * the custom header precedes the L2 header in the packet buffer. | ||
1321 | * @ingroup pktfuncs | ||
1322 | * | ||
1323 | * @param[in] pkt Packet on which to operate. | ||
1324 | * @return The length of the packet, in bytes. | ||
1325 | */ | ||
1326 | static __inline netio_size_t | ||
1327 | NETIO_PKT_CUSTOM_LENGTH(netio_pkt_t* pkt) | ||
1328 | { | ||
1329 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1330 | |||
1331 | return NETIO_PKT_CUSTOM_LENGTH_M(mda, pkt); | ||
1332 | } | ||
1333 | |||
1334 | |||
1335 | /** Return a pointer to the packet's custom header. | ||
1336 | * A custom header may or may not be present, depending upon the IPP; its | ||
1337 | * contents and alignment are also IPP-dependent. Currently, none of the | ||
1338 | * standard IPPs supplied by Tilera produce a custom header. If present, | ||
1339 | * the custom header precedes the L2 header in the packet buffer. | ||
1340 | * @ingroup pktfuncs | ||
1341 | * | ||
1342 | * @param[in] pkt Packet on which to operate. | ||
1343 | * @return A pointer to start of the packet. | ||
1344 | */ | ||
1345 | static __inline unsigned char* | ||
1346 | NETIO_PKT_CUSTOM_DATA(netio_pkt_t* pkt) | ||
1347 | { | ||
1348 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1349 | |||
1350 | return NETIO_PKT_CUSTOM_DATA_M(mda, pkt); | ||
1351 | } | ||
1352 | |||
1353 | |||
1354 | /** Return the length of the packet's L2 (Ethernet plus VLAN or SNAP) header. | ||
1355 | * @ingroup pktfuncs | ||
1356 | * | ||
1357 | * @param[in] pkt Packet on which to operate. | ||
1358 | * @return The length of the packet's L2 header, in bytes. | ||
1359 | */ | ||
1360 | static __inline netio_size_t | ||
1361 | NETIO_PKT_L2_HEADER_LENGTH(netio_pkt_t* pkt) | ||
1362 | { | ||
1363 | if (NETIO_PKT_IS_MINIMAL(pkt)) | ||
1364 | { | ||
1365 | netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt); | ||
1366 | |||
1367 | return NETIO_PKT_L2_HEADER_LENGTH_MM(mmd, pkt); | ||
1368 | } | ||
1369 | else | ||
1370 | { | ||
1371 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1372 | |||
1373 | return NETIO_PKT_L2_HEADER_LENGTH_M(mda, pkt); | ||
1374 | } | ||
1375 | } | ||
1376 | |||
1377 | |||
1378 | /** Return the length of the packet, starting with the L2 (Ethernet) header. | ||
1379 | * @ingroup pktfuncs | ||
1380 | * | ||
1381 | * @param[in] pkt Packet on which to operate. | ||
1382 | * @return The length of the packet, in bytes. | ||
1383 | */ | ||
1384 | static __inline netio_size_t | ||
1385 | NETIO_PKT_L2_LENGTH(netio_pkt_t* pkt) | ||
1386 | { | ||
1387 | if (NETIO_PKT_IS_MINIMAL(pkt)) | ||
1388 | { | ||
1389 | netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt); | ||
1390 | |||
1391 | return NETIO_PKT_L2_LENGTH_MM(mmd, pkt); | ||
1392 | } | ||
1393 | else | ||
1394 | { | ||
1395 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1396 | |||
1397 | return NETIO_PKT_L2_LENGTH_M(mda, pkt); | ||
1398 | } | ||
1399 | } | ||
1400 | |||
1401 | |||
1402 | /** Return a pointer to the packet's L2 (Ethernet) header. | ||
1403 | * @ingroup pktfuncs | ||
1404 | * | ||
1405 | * @param[in] pkt Packet on which to operate. | ||
1406 | * @return A pointer to start of the packet. | ||
1407 | */ | ||
1408 | static __inline unsigned char* | ||
1409 | NETIO_PKT_L2_DATA(netio_pkt_t* pkt) | ||
1410 | { | ||
1411 | if (NETIO_PKT_IS_MINIMAL(pkt)) | ||
1412 | { | ||
1413 | netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt); | ||
1414 | |||
1415 | return NETIO_PKT_L2_DATA_MM(mmd, pkt); | ||
1416 | } | ||
1417 | else | ||
1418 | { | ||
1419 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1420 | |||
1421 | return NETIO_PKT_L2_DATA_M(mda, pkt); | ||
1422 | } | ||
1423 | } | ||
1424 | |||
1425 | |||
1426 | /** Retrieve the length of the packet, starting with the L3 (generally, the IP) | ||
1427 | * header. | ||
1428 | * @ingroup pktfuncs | ||
1429 | * | ||
1430 | * @param[in] pkt Packet on which to operate. | ||
1431 | * @return Length of the packet's L3 header and data, in bytes. | ||
1432 | */ | ||
1433 | static __inline netio_size_t | ||
1434 | NETIO_PKT_L3_LENGTH(netio_pkt_t* pkt) | ||
1435 | { | ||
1436 | if (NETIO_PKT_IS_MINIMAL(pkt)) | ||
1437 | { | ||
1438 | netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt); | ||
1439 | |||
1440 | return NETIO_PKT_L3_LENGTH_MM(mmd, pkt); | ||
1441 | } | ||
1442 | else | ||
1443 | { | ||
1444 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1445 | |||
1446 | return NETIO_PKT_L3_LENGTH_M(mda, pkt); | ||
1447 | } | ||
1448 | } | ||
1449 | |||
1450 | |||
1451 | /** Return a pointer to the packet's L3 (generally, the IP) header. | ||
1452 | * @ingroup pktfuncs | ||
1453 | * | ||
1454 | * Note that we guarantee word alignment of the L3 header. | ||
1455 | * | ||
1456 | * @param[in] pkt Packet on which to operate. | ||
1457 | * @return A pointer to the packet's L3 header. | ||
1458 | */ | ||
1459 | static __inline unsigned char* | ||
1460 | NETIO_PKT_L3_DATA(netio_pkt_t* pkt) | ||
1461 | { | ||
1462 | if (NETIO_PKT_IS_MINIMAL(pkt)) | ||
1463 | { | ||
1464 | netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt); | ||
1465 | |||
1466 | return NETIO_PKT_L3_DATA_MM(mmd, pkt); | ||
1467 | } | ||
1468 | else | ||
1469 | { | ||
1470 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1471 | |||
1472 | return NETIO_PKT_L3_DATA_M(mda, pkt); | ||
1473 | } | ||
1474 | } | ||
1475 | |||
1476 | |||
1477 | /** Return the ordinal of the packet. | ||
1478 | * @ingroup ingress | ||
1479 | * | ||
1480 | * Each packet is given an ordinal number when it is delivered by the IPP. | ||
1481 | * In the medium term, the ordinal is unique and monotonically increasing, | ||
1482 | * being incremented by 1 for each packet; the ordinal of the first packet | ||
1483 | * delivered after the IPP starts is zero. (Since the ordinal is of finite | ||
1484 | * size, given enough input packets, it will eventually wrap around to zero; | ||
1485 | * in the long term, therefore, ordinals are not unique.) The ordinals | ||
1486 | * handed out by different IPPs are not disjoint, so two packets from | ||
1487 | * different IPPs may have identical ordinals. Packets dropped by the | ||
1488 | * IPP or by the I/O shim are not assigned ordinals. | ||
1489 | * | ||
1490 | * | ||
1491 | * @param[in] pkt Packet on which to operate. | ||
1492 | * @return The packet's per-IPP packet ordinal. | ||
1493 | */ | ||
1494 | static __inline unsigned int | ||
1495 | NETIO_PKT_ORDINAL(netio_pkt_t* pkt) | ||
1496 | { | ||
1497 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1498 | |||
1499 | return NETIO_PKT_ORDINAL_M(mda, pkt); | ||
1500 | } | ||
1501 | |||
1502 | |||
1503 | /** Return the per-group ordinal of the packet. | ||
1504 | * @ingroup ingress | ||
1505 | * | ||
1506 | * Each packet is given a per-group ordinal number when it is | ||
1507 | * delivered by the IPP. By default, the group is the packet's VLAN, | ||
1508 | * although IPP can be recompiled to use different values. In | ||
1509 | * the medium term, the ordinal is unique and monotonically | ||
1510 | * increasing, being incremented by 1 for each packet; the ordinal of | ||
1511 | * the first packet distributed to a particular group is zero. | ||
1512 | * (Since the ordinal is of finite size, given enough input packets, | ||
1513 | * it will eventually wrap around to zero; in the long term, | ||
1514 | * therefore, ordinals are not unique.) The ordinals handed out by | ||
1515 | * different IPPs are not disjoint, so two packets from different IPPs | ||
1516 | * may have identical ordinals; similarly, packets distributed to | ||
1517 | * different groups may have identical ordinals. Packets dropped by | ||
1518 | * the IPP or by the I/O shim are not assigned ordinals. | ||
1519 | * | ||
1520 | * @param[in] pkt Packet on which to operate. | ||
1521 | * @return The packet's per-IPP, per-group ordinal. | ||
1522 | */ | ||
1523 | static __inline unsigned int | ||
1524 | NETIO_PKT_GROUP_ORDINAL(netio_pkt_t* pkt) | ||
1525 | { | ||
1526 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1527 | |||
1528 | return NETIO_PKT_GROUP_ORDINAL_M(mda, pkt); | ||
1529 | } | ||
1530 | |||
1531 | |||
1532 | /** Return the VLAN ID assigned to the packet. | ||
1533 | * @ingroup ingress | ||
1534 | * | ||
1535 | * This is usually also contained within the packet header. If the packet | ||
1536 | * does not have a VLAN tag, the VLAN ID returned by this function is zero. | ||
1537 | * | ||
1538 | * @param[in] pkt Packet on which to operate. | ||
1539 | * @return The packet's VLAN ID. | ||
1540 | */ | ||
1541 | static __inline unsigned short | ||
1542 | NETIO_PKT_VLAN_ID(netio_pkt_t* pkt) | ||
1543 | { | ||
1544 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1545 | |||
1546 | return NETIO_PKT_VLAN_ID_M(mda, pkt); | ||
1547 | } | ||
1548 | |||
1549 | |||
1550 | /** Return the ethertype of the packet. | ||
1551 | * @ingroup ingress | ||
1552 | * | ||
1553 | * This value is reliable if @ref NETIO_PKT_ETHERTYPE_RECOGNIZED() | ||
1554 | * returns true, and otherwise, may not be well defined. | ||
1555 | * | ||
1556 | * @param[in] pkt Packet on which to operate. | ||
1557 | * @return The packet's ethertype. | ||
1558 | */ | ||
1559 | static __inline unsigned short | ||
1560 | NETIO_PKT_ETHERTYPE(netio_pkt_t* pkt) | ||
1561 | { | ||
1562 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1563 | |||
1564 | return NETIO_PKT_ETHERTYPE_M(mda, pkt); | ||
1565 | } | ||
1566 | |||
1567 | |||
1568 | /** Return the flow hash computed on the packet. | ||
1569 | * @ingroup ingress | ||
1570 | * | ||
1571 | * For TCP and UDP packets, this hash is calculated by hashing together | ||
1572 | * the "5-tuple" values, specifically the source IP address, destination | ||
1573 | * IP address, protocol type, source port and destination port. | ||
1574 | * The hash value is intended to be helpful for millions of distinct | ||
1575 | * flows. | ||
1576 | * | ||
1577 | * For IPv4 or IPv6 packets which are neither TCP nor UDP, the flow hash is | ||
1578 | * derived by hashing together the source and destination IP addresses. | ||
1579 | * | ||
1580 | * For MPLS-encapsulated packets, the flow hash is derived by hashing | ||
1581 | * the first MPLS label. | ||
1582 | * | ||
1583 | * For all other packets the flow hash is computed from the source | ||
1584 | * and destination Ethernet addresses. | ||
1585 | * | ||
1586 | * The hash is symmetric, meaning it produces the same value if the | ||
1587 | * source and destination are swapped. The only exceptions are | ||
1588 | * tunneling protocols 0x04 (IP in IP Encapsulation), 0x29 (Simple | ||
1589 | * Internet Protocol), 0x2F (General Routing Encapsulation) and 0x32 | ||
1590 | * (Encap Security Payload), which use only the destination address | ||
1591 | * since the source address is not meaningful. | ||
1592 | * | ||
1593 | * @param[in] pkt Packet on which to operate. | ||
1594 | * @return The packet's 32-bit flow hash. | ||
1595 | */ | ||
1596 | static __inline unsigned int | ||
1597 | NETIO_PKT_FLOW_HASH(netio_pkt_t* pkt) | ||
1598 | { | ||
1599 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1600 | |||
1601 | return NETIO_PKT_FLOW_HASH_M(mda, pkt); | ||
1602 | } | ||
1603 | |||
1604 | |||
1605 | /** Return the first word of "user data" for the packet. | ||
1606 | * | ||
1607 | * The contents of the user data words depend on the IPP. | ||
1608 | * | ||
1609 | * When using the standard ipp1, ipp2, or ipp4 sub-drivers, the first | ||
1610 | * word of user data contains the least significant bits of the 64-bit | ||
1611 | * arrival cycle count (see @c get_cycle_count_low()). | ||
1612 | * | ||
1613 | * See the <em>System Programmer's Guide</em> for details. | ||
1614 | * | ||
1615 | * @ingroup ingress | ||
1616 | * | ||
1617 | * @param[in] pkt Packet on which to operate. | ||
1618 | * @return The packet's first word of "user data". | ||
1619 | */ | ||
1620 | static __inline unsigned int | ||
1621 | NETIO_PKT_USER_DATA_0(netio_pkt_t* pkt) | ||
1622 | { | ||
1623 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1624 | |||
1625 | return NETIO_PKT_USER_DATA_0_M(mda, pkt); | ||
1626 | } | ||
1627 | |||
1628 | |||
1629 | /** Return the second word of "user data" for the packet. | ||
1630 | * | ||
1631 | * The contents of the user data words depend on the IPP. | ||
1632 | * | ||
1633 | * When using the standard ipp1, ipp2, or ipp4 sub-drivers, the second | ||
1634 | * word of user data contains the most significant bits of the 64-bit | ||
1635 | * arrival cycle count (see @c get_cycle_count_high()). | ||
1636 | * | ||
1637 | * See the <em>System Programmer's Guide</em> for details. | ||
1638 | * | ||
1639 | * @ingroup ingress | ||
1640 | * | ||
1641 | * @param[in] pkt Packet on which to operate. | ||
1642 | * @return The packet's second word of "user data". | ||
1643 | */ | ||
1644 | static __inline unsigned int | ||
1645 | NETIO_PKT_USER_DATA_1(netio_pkt_t* pkt) | ||
1646 | { | ||
1647 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1648 | |||
1649 | return NETIO_PKT_USER_DATA_1_M(mda, pkt); | ||
1650 | } | ||
1651 | |||
1652 | |||
1653 | /** Determine whether the L4 (TCP/UDP) checksum was calculated. | ||
1654 | * @ingroup ingress | ||
1655 | * | ||
1656 | * @param[in] pkt Packet on which to operate. | ||
1657 | * @return Nonzero if the L4 checksum was calculated. | ||
1658 | */ | ||
1659 | static __inline unsigned int | ||
1660 | NETIO_PKT_L4_CSUM_CALCULATED(netio_pkt_t* pkt) | ||
1661 | { | ||
1662 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1663 | |||
1664 | return NETIO_PKT_L4_CSUM_CALCULATED_M(mda, pkt); | ||
1665 | } | ||
1666 | |||
1667 | |||
1668 | /** Determine whether the L4 (TCP/UDP) checksum was calculated and found to | ||
1669 | * be correct. | ||
1670 | * @ingroup ingress | ||
1671 | * | ||
1672 | * @param[in] pkt Packet on which to operate. | ||
1673 | * @return Nonzero if the checksum was calculated and is correct. | ||
1674 | */ | ||
1675 | static __inline unsigned int | ||
1676 | NETIO_PKT_L4_CSUM_CORRECT(netio_pkt_t* pkt) | ||
1677 | { | ||
1678 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1679 | |||
1680 | return NETIO_PKT_L4_CSUM_CORRECT_M(mda, pkt); | ||
1681 | } | ||
1682 | |||
1683 | |||
1684 | /** Determine whether the L3 (IP) checksum was calculated. | ||
1685 | * @ingroup ingress | ||
1686 | * | ||
1687 | * @param[in] pkt Packet on which to operate. | ||
1688 | * @return Nonzero if the L3 (IP) checksum was calculated. | ||
1689 | */ | ||
1690 | static __inline unsigned int | ||
1691 | NETIO_PKT_L3_CSUM_CALCULATED(netio_pkt_t* pkt) | ||
1692 | { | ||
1693 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1694 | |||
1695 | return NETIO_PKT_L3_CSUM_CALCULATED_M(mda, pkt); | ||
1696 | } | ||
1697 | |||
1698 | |||
1699 | /** Determine whether the L3 (IP) checksum was calculated and found to be | ||
1700 | * correct. | ||
1701 | * @ingroup ingress | ||
1702 | * | ||
1703 | * @param[in] pkt Packet on which to operate. | ||
1704 | * @return Nonzero if the checksum was calculated and is correct. | ||
1705 | */ | ||
1706 | static __inline unsigned int | ||
1707 | NETIO_PKT_L3_CSUM_CORRECT(netio_pkt_t* pkt) | ||
1708 | { | ||
1709 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1710 | |||
1711 | return NETIO_PKT_L3_CSUM_CORRECT_M(mda, pkt); | ||
1712 | } | ||
1713 | |||
1714 | |||
1715 | /** Determine whether the Ethertype was recognized and L3 packet data was | ||
1716 | * processed. | ||
1717 | * @ingroup ingress | ||
1718 | * | ||
1719 | * @param[in] pkt Packet on which to operate. | ||
1720 | * @return Nonzero if the Ethertype was recognized and L3 packet data was | ||
1721 | * processed. | ||
1722 | */ | ||
1723 | static __inline unsigned int | ||
1724 | NETIO_PKT_ETHERTYPE_RECOGNIZED(netio_pkt_t* pkt) | ||
1725 | { | ||
1726 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1727 | |||
1728 | return NETIO_PKT_ETHERTYPE_RECOGNIZED_M(mda, pkt); | ||
1729 | } | ||
1730 | |||
1731 | |||
1732 | /** Set an egress packet's L2 length, using a metadata pointer to speed the | ||
1733 | * computation. | ||
1734 | * @ingroup egress | ||
1735 | * | ||
1736 | * @param[in,out] mmd Pointer to packet's minimal metadata. | ||
1737 | * @param[in] pkt Packet on which to operate. | ||
1738 | * @param[in] len Packet L2 length, in bytes. | ||
1739 | */ | ||
1740 | static __inline void | ||
1741 | NETIO_PKT_SET_L2_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt, | ||
1742 | int len) | ||
1743 | { | ||
1744 | mmd->l2_length = len; | ||
1745 | } | ||
1746 | |||
1747 | |||
1748 | /** Set an egress packet's L2 length. | ||
1749 | * @ingroup egress | ||
1750 | * | ||
1751 | * @param[in,out] pkt Packet on which to operate. | ||
1752 | * @param[in] len Packet L2 length, in bytes. | ||
1753 | */ | ||
1754 | static __inline void | ||
1755 | NETIO_PKT_SET_L2_LENGTH(netio_pkt_t* pkt, int len) | ||
1756 | { | ||
1757 | netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt); | ||
1758 | |||
1759 | NETIO_PKT_SET_L2_LENGTH_MM(mmd, pkt, len); | ||
1760 | } | ||
1761 | |||
1762 | |||
1763 | /** Set an egress packet's L2 header length, using a metadata pointer to | ||
1764 | * speed the computation. | ||
1765 | * @ingroup egress | ||
1766 | * | ||
1767 | * It is not normally necessary to call this routine; only the L2 length, | ||
1768 | * not the header length, is needed to transmit a packet. It may be useful if | ||
1769 | * the egress packet will later be processed by code which expects to use | ||
1770 | * functions like @ref NETIO_PKT_L3_DATA() to get a pointer to the L3 payload. | ||
1771 | * | ||
1772 | * @param[in,out] mmd Pointer to packet's minimal metadata. | ||
1773 | * @param[in] pkt Packet on which to operate. | ||
1774 | * @param[in] len Packet L2 header length, in bytes. | ||
1775 | */ | ||
1776 | static __inline void | ||
1777 | NETIO_PKT_SET_L2_HEADER_LENGTH_MM(netio_pkt_minimal_metadata_t* mmd, | ||
1778 | netio_pkt_t* pkt, int len) | ||
1779 | { | ||
1780 | mmd->l3_offset = mmd->l2_offset + len; | ||
1781 | } | ||
1782 | |||
1783 | |||
1784 | /** Set an egress packet's L2 header length. | ||
1785 | * @ingroup egress | ||
1786 | * | ||
1787 | * It is not normally necessary to call this routine; only the L2 length, | ||
1788 | * not the header length, is needed to transmit a packet. It may be useful if | ||
1789 | * the egress packet will later be processed by code which expects to use | ||
1790 | * functions like @ref NETIO_PKT_L3_DATA() to get a pointer to the L3 payload. | ||
1791 | * | ||
1792 | * @param[in,out] pkt Packet on which to operate. | ||
1793 | * @param[in] len Packet L2 header length, in bytes. | ||
1794 | */ | ||
1795 | static __inline void | ||
1796 | NETIO_PKT_SET_L2_HEADER_LENGTH(netio_pkt_t* pkt, int len) | ||
1797 | { | ||
1798 | netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt); | ||
1799 | |||
1800 | NETIO_PKT_SET_L2_HEADER_LENGTH_MM(mmd, pkt, len); | ||
1801 | } | ||
1802 | |||
1803 | |||
1804 | /** Set up an egress packet for hardware checksum computation, using a | ||
1805 | * metadata pointer to speed the operation. | ||
1806 | * @ingroup egress | ||
1807 | * | ||
1808 | * NetIO provides the ability to automatically calculate a standard | ||
1809 | * 16-bit Internet checksum on transmitted packets. The application | ||
1810 | * may specify the point in the packet where the checksum starts, the | ||
1811 | * number of bytes to be checksummed, and the two bytes in the packet | ||
1812 | * which will be replaced with the completed checksum. (If the range | ||
1813 | * of bytes to be checksummed includes the bytes to be replaced, the | ||
1814 | * initial values of those bytes will be included in the checksum.) | ||
1815 | * | ||
1816 | * For some protocols, the packet checksum covers data which is not present | ||
1817 | * in the packet, or is at least not contiguous to the main data payload. | ||
1818 | * For instance, the TCP checksum includes a "pseudo-header" which includes | ||
1819 | * the source and destination IP addresses of the packet. To accommodate | ||
1820 | * this, the checksum engine may be "seeded" with an initial value, which | ||
1821 | * the application would need to compute based on the specific protocol's | ||
1822 | * requirements. Note that the seed is given in host byte order (little- | ||
1823 | * endian), not network byte order (big-endian); code written to compute a | ||
1824 | * pseudo-header checksum in network byte order will need to byte-swap it | ||
1825 | * before use as the seed. | ||
1826 | * | ||
1827 | * Note that the checksum is computed as part of the transmission process, | ||
1828 | * so it will not be present in the packet upon completion of this routine. | ||
1829 | * | ||
1830 | * @param[in,out] mmd Pointer to packet's minimal metadata. | ||
1831 | * @param[in] pkt Packet on which to operate. | ||
1832 | * @param[in] start Offset within L2 packet of the first byte to include in | ||
1833 | * the checksum. | ||
1834 | * @param[in] length Number of bytes to include in the checksum. | ||
1835 | * the checksum. | ||
1836 | * @param[in] location Offset within L2 packet of the first of the two bytes | ||
1837 | * to be replaced with the calculated checksum. | ||
1838 | * @param[in] seed Initial value of the running checksum before any of the | ||
1839 | * packet data is added. | ||
1840 | */ | ||
1841 | static __inline void | ||
1842 | NETIO_PKT_DO_EGRESS_CSUM_MM(netio_pkt_minimal_metadata_t* mmd, | ||
1843 | netio_pkt_t* pkt, int start, int length, | ||
1844 | int location, uint16_t seed) | ||
1845 | { | ||
1846 | mmd->csum_start = start; | ||
1847 | mmd->csum_length = length; | ||
1848 | mmd->csum_location = location; | ||
1849 | mmd->csum_seed = seed; | ||
1850 | mmd->flags |= _NETIO_PKT_NEED_EDMA_CSUM_MASK; | ||
1851 | } | ||
1852 | |||
1853 | |||
1854 | /** Set up an egress packet for hardware checksum computation. | ||
1855 | * @ingroup egress | ||
1856 | * | ||
1857 | * NetIO provides the ability to automatically calculate a standard | ||
1858 | * 16-bit Internet checksum on transmitted packets. The application | ||
1859 | * may specify the point in the packet where the checksum starts, the | ||
1860 | * number of bytes to be checksummed, and the two bytes in the packet | ||
1861 | * which will be replaced with the completed checksum. (If the range | ||
1862 | * of bytes to be checksummed includes the bytes to be replaced, the | ||
1863 | * initial values of those bytes will be included in the checksum.) | ||
1864 | * | ||
1865 | * For some protocols, the packet checksum covers data which is not present | ||
1866 | * in the packet, or is at least not contiguous to the main data payload. | ||
1867 | * For instance, the TCP checksum includes a "pseudo-header" which includes | ||
1868 | * the source and destination IP addresses of the packet. To accommodate | ||
1869 | * this, the checksum engine may be "seeded" with an initial value, which | ||
1870 | * the application would need to compute based on the specific protocol's | ||
1871 | * requirements. Note that the seed is given in host byte order (little- | ||
1872 | * endian), not network byte order (big-endian); code written to compute a | ||
1873 | * pseudo-header checksum in network byte order will need to byte-swap it | ||
1874 | * before use as the seed. | ||
1875 | * | ||
1876 | * Note that the checksum is computed as part of the transmission process, | ||
1877 | * so it will not be present in the packet upon completion of this routine. | ||
1878 | * | ||
1879 | * @param[in,out] pkt Packet on which to operate. | ||
1880 | * @param[in] start Offset within L2 packet of the first byte to include in | ||
1881 | * the checksum. | ||
1882 | * @param[in] length Number of bytes to include in the checksum. | ||
1883 | * the checksum. | ||
1884 | * @param[in] location Offset within L2 packet of the first of the two bytes | ||
1885 | * to be replaced with the calculated checksum. | ||
1886 | * @param[in] seed Initial value of the running checksum before any of the | ||
1887 | * packet data is added. | ||
1888 | */ | ||
1889 | static __inline void | ||
1890 | NETIO_PKT_DO_EGRESS_CSUM(netio_pkt_t* pkt, int start, int length, | ||
1891 | int location, uint16_t seed) | ||
1892 | { | ||
1893 | netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt); | ||
1894 | |||
1895 | NETIO_PKT_DO_EGRESS_CSUM_MM(mmd, pkt, start, length, location, seed); | ||
1896 | } | ||
1897 | |||
1898 | |||
1899 | /** Return the number of bytes which could be prepended to a packet, using a | ||
1900 | * metadata pointer to speed the operation. | ||
1901 | * See @ref netio_populate_prepend_buffer() to get a full description of | ||
1902 | * prepending. | ||
1903 | * | ||
1904 | * @param[in,out] mda Pointer to packet's standard metadata. | ||
1905 | * @param[in] pkt Packet on which to operate. | ||
1906 | */ | ||
1907 | static __inline int | ||
1908 | NETIO_PKT_PREPEND_AVAIL_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
1909 | { | ||
1910 | return (pkt->__packet.bits.__offset << 6) + | ||
1911 | NETIO_PKT_CUSTOM_HEADER_LENGTH_M(mda, pkt); | ||
1912 | } | ||
1913 | |||
1914 | |||
1915 | /** Return the number of bytes which could be prepended to a packet, using a | ||
1916 | * metadata pointer to speed the operation. | ||
1917 | * See @ref netio_populate_prepend_buffer() to get a full description of | ||
1918 | * prepending. | ||
1919 | * @ingroup egress | ||
1920 | * | ||
1921 | * @param[in,out] mmd Pointer to packet's minimal metadata. | ||
1922 | * @param[in] pkt Packet on which to operate. | ||
1923 | */ | ||
1924 | static __inline int | ||
1925 | NETIO_PKT_PREPEND_AVAIL_MM(netio_pkt_minimal_metadata_t* mmd, netio_pkt_t* pkt) | ||
1926 | { | ||
1927 | return (pkt->__packet.bits.__offset << 6) + mmd->l2_offset; | ||
1928 | } | ||
1929 | |||
1930 | |||
1931 | /** Return the number of bytes which could be prepended to a packet. | ||
1932 | * See @ref netio_populate_prepend_buffer() to get a full description of | ||
1933 | * prepending. | ||
1934 | * @ingroup egress | ||
1935 | * | ||
1936 | * @param[in] pkt Packet on which to operate. | ||
1937 | */ | ||
1938 | static __inline int | ||
1939 | NETIO_PKT_PREPEND_AVAIL(netio_pkt_t* pkt) | ||
1940 | { | ||
1941 | if (NETIO_PKT_IS_MINIMAL(pkt)) | ||
1942 | { | ||
1943 | netio_pkt_minimal_metadata_t* mmd = NETIO_PKT_MINIMAL_METADATA(pkt); | ||
1944 | |||
1945 | return NETIO_PKT_PREPEND_AVAIL_MM(mmd, pkt); | ||
1946 | } | ||
1947 | else | ||
1948 | { | ||
1949 | netio_pkt_metadata_t* mda = NETIO_PKT_METADATA(pkt); | ||
1950 | |||
1951 | return NETIO_PKT_PREPEND_AVAIL_M(mda, pkt); | ||
1952 | } | ||
1953 | } | ||
1954 | |||
1955 | |||
1956 | /** Flush a packet's minimal metadata from the cache, using a metadata pointer | ||
1957 | * to speed the operation. | ||
1958 | * @ingroup egress | ||
1959 | * | ||
1960 | * @param[in] mmd Pointer to packet's minimal metadata. | ||
1961 | * @param[in] pkt Packet on which to operate. | ||
1962 | */ | ||
1963 | static __inline void | ||
1964 | NETIO_PKT_FLUSH_MINIMAL_METADATA_MM(netio_pkt_minimal_metadata_t* mmd, | ||
1965 | netio_pkt_t* pkt) | ||
1966 | { | ||
1967 | } | ||
1968 | |||
1969 | |||
1970 | /** Invalidate a packet's minimal metadata from the cache, using a metadata | ||
1971 | * pointer to speed the operation. | ||
1972 | * @ingroup egress | ||
1973 | * | ||
1974 | * @param[in] mmd Pointer to packet's minimal metadata. | ||
1975 | * @param[in] pkt Packet on which to operate. | ||
1976 | */ | ||
1977 | static __inline void | ||
1978 | NETIO_PKT_INV_MINIMAL_METADATA_MM(netio_pkt_minimal_metadata_t* mmd, | ||
1979 | netio_pkt_t* pkt) | ||
1980 | { | ||
1981 | } | ||
1982 | |||
1983 | |||
1984 | /** Flush and then invalidate a packet's minimal metadata from the cache, | ||
1985 | * using a metadata pointer to speed the operation. | ||
1986 | * @ingroup egress | ||
1987 | * | ||
1988 | * @param[in] mmd Pointer to packet's minimal metadata. | ||
1989 | * @param[in] pkt Packet on which to operate. | ||
1990 | */ | ||
1991 | static __inline void | ||
1992 | NETIO_PKT_FLUSH_INV_MINIMAL_METADATA_MM(netio_pkt_minimal_metadata_t* mmd, | ||
1993 | netio_pkt_t* pkt) | ||
1994 | { | ||
1995 | } | ||
1996 | |||
1997 | |||
1998 | /** Flush a packet's metadata from the cache, using a metadata pointer | ||
1999 | * to speed the operation. | ||
2000 | * @ingroup ingress | ||
2001 | * | ||
2002 | * @param[in] mda Pointer to packet's minimal metadata. | ||
2003 | * @param[in] pkt Packet on which to operate. | ||
2004 | */ | ||
2005 | static __inline void | ||
2006 | NETIO_PKT_FLUSH_METADATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
2007 | { | ||
2008 | } | ||
2009 | |||
2010 | |||
2011 | /** Invalidate a packet's metadata from the cache, using a metadata | ||
2012 | * pointer to speed the operation. | ||
2013 | * @ingroup ingress | ||
2014 | * | ||
2015 | * @param[in] mda Pointer to packet's metadata. | ||
2016 | * @param[in] pkt Packet on which to operate. | ||
2017 | */ | ||
2018 | static __inline void | ||
2019 | NETIO_PKT_INV_METADATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
2020 | { | ||
2021 | } | ||
2022 | |||
2023 | |||
2024 | /** Flush and then invalidate a packet's metadata from the cache, | ||
2025 | * using a metadata pointer to speed the operation. | ||
2026 | * @ingroup ingress | ||
2027 | * | ||
2028 | * @param[in] mda Pointer to packet's metadata. | ||
2029 | * @param[in] pkt Packet on which to operate. | ||
2030 | */ | ||
2031 | static __inline void | ||
2032 | NETIO_PKT_FLUSH_INV_METADATA_M(netio_pkt_metadata_t* mda, netio_pkt_t* pkt) | ||
2033 | { | ||
2034 | } | ||
2035 | |||
2036 | |||
2037 | /** Flush a packet's minimal metadata from the cache. | ||
2038 | * @ingroup egress | ||
2039 | * | ||
2040 | * @param[in] pkt Packet on which to operate. | ||
2041 | */ | ||
2042 | static __inline void | ||
2043 | NETIO_PKT_FLUSH_MINIMAL_METADATA(netio_pkt_t* pkt) | ||
2044 | { | ||
2045 | } | ||
2046 | |||
2047 | |||
2048 | /** Invalidate a packet's minimal metadata from the cache. | ||
2049 | * @ingroup egress | ||
2050 | * | ||
2051 | * @param[in] pkt Packet on which to operate. | ||
2052 | */ | ||
2053 | static __inline void | ||
2054 | NETIO_PKT_INV_MINIMAL_METADATA(netio_pkt_t* pkt) | ||
2055 | { | ||
2056 | } | ||
2057 | |||
2058 | |||
2059 | /** Flush and then invalidate a packet's minimal metadata from the cache. | ||
2060 | * @ingroup egress | ||
2061 | * | ||
2062 | * @param[in] pkt Packet on which to operate. | ||
2063 | */ | ||
2064 | static __inline void | ||
2065 | NETIO_PKT_FLUSH_INV_MINIMAL_METADATA(netio_pkt_t* pkt) | ||
2066 | { | ||
2067 | } | ||
2068 | |||
2069 | |||
2070 | /** Flush a packet's metadata from the cache. | ||
2071 | * @ingroup ingress | ||
2072 | * | ||
2073 | * @param[in] pkt Packet on which to operate. | ||
2074 | */ | ||
2075 | static __inline void | ||
2076 | NETIO_PKT_FLUSH_METADATA(netio_pkt_t* pkt) | ||
2077 | { | ||
2078 | } | ||
2079 | |||
2080 | |||
2081 | /** Invalidate a packet's metadata from the cache. | ||
2082 | * @ingroup ingress | ||
2083 | * | ||
2084 | * @param[in] pkt Packet on which to operate. | ||
2085 | */ | ||
2086 | static __inline void | ||
2087 | NETIO_PKT_INV_METADATA(netio_pkt_t* pkt) | ||
2088 | { | ||
2089 | } | ||
2090 | |||
2091 | |||
2092 | /** Flush and then invalidate a packet's metadata from the cache. | ||
2093 | * @ingroup ingress | ||
2094 | * | ||
2095 | * @param[in] pkt Packet on which to operate. | ||
2096 | */ | ||
2097 | static __inline void | ||
2098 | NETIO_PKT_FLUSH_INV_METADATA(netio_pkt_t* pkt) | ||
2099 | { | ||
2100 | } | ||
2101 | |||
2102 | /** Number of NUMA nodes we can distribute buffers to. | ||
2103 | * @ingroup setup */ | ||
2104 | #define NETIO_NUM_NODE_WEIGHTS 16 | ||
2105 | |||
2106 | /** | ||
2107 | * @brief An object for specifying the characteristics of NetIO communication | ||
2108 | * endpoint. | ||
2109 | * | ||
2110 | * @ingroup setup | ||
2111 | * | ||
2112 | * The @ref netio_input_register() function uses this structure to define | ||
2113 | * how an application tile will communicate with an IPP. | ||
2114 | * | ||
2115 | * | ||
2116 | * Future updates to NetIO may add new members to this structure, | ||
2117 | * which can affect the success of the registration operation. Thus, | ||
2118 | * if dynamically initializing the structure, applications are urged to | ||
2119 | * zero it out first, for example: | ||
2120 | * | ||
2121 | * @code | ||
2122 | * netio_input_config_t config; | ||
2123 | * memset(&config, 0, sizeof (config)); | ||
2124 | * config.flags = NETIO_RECV | NETIO_XMIT_CSUM | NETIO_TAG_NONE; | ||
2125 | * config.num_receive_packets = NETIO_MAX_RECEIVE_PKTS; | ||
2126 | * config.queue_id = 0; | ||
2127 | * . | ||
2128 | * . | ||
2129 | * . | ||
2130 | * @endcode | ||
2131 | * | ||
2132 | * since that guarantees that any unused structure members, including | ||
2133 | * members which did not exist when the application was first developed, | ||
2134 | * will not have unexpected values. | ||
2135 | * | ||
2136 | * If statically initializing the structure, we strongly recommend use of | ||
2137 | * C99-style named initializers, for example: | ||
2138 | * | ||
2139 | * @code | ||
2140 | * netio_input_config_t config = { | ||
2141 | * .flags = NETIO_RECV | NETIO_XMIT_CSUM | NETIO_TAG_NONE, | ||
2142 | * .num_receive_packets = NETIO_MAX_RECEIVE_PKTS, | ||
2143 | * .queue_id = 0, | ||
2144 | * }, | ||
2145 | * @endcode | ||
2146 | * | ||
2147 | * instead of the old-style structure initialization: | ||
2148 | * | ||
2149 | * @code | ||
2150 | * // Bad example! Currently equivalent to the above, but don't do this. | ||
2151 | * netio_input_config_t config = { | ||
2152 | * NETIO_RECV | NETIO_XMIT_CSUM | NETIO_TAG_NONE, NETIO_MAX_RECEIVE_PKTS, 0 | ||
2153 | * }, | ||
2154 | * @endcode | ||
2155 | * | ||
2156 | * since the C99 style requires no changes to the code if elements of the | ||
2157 | * config structure are rearranged. (It also makes the initialization much | ||
2158 | * easier to understand.) | ||
2159 | * | ||
2160 | * Except for items which address a particular tile's transmit or receive | ||
2161 | * characteristics, such as the ::NETIO_RECV flag, applications are advised | ||
2162 | * to specify the same set of configuration data on all registrations. | ||
2163 | * This prevents differing results if multiple tiles happen to do their | ||
2164 | * registration operations in a different order on different invocations of | ||
2165 | * the application. This is particularly important for things like link | ||
2166 | * management flags, and buffer size and homing specifications. | ||
2167 | * | ||
2168 | * Unless the ::NETIO_FIXED_BUFFER_VA flag is specified in flags, the NetIO | ||
2169 | * buffer pool is automatically created and mapped into the application's | ||
2170 | * virtual address space at an address chosen by the operating system, | ||
2171 | * using the common memory (cmem) facility in the Tilera Multicore | ||
2172 | * Components library. The cmem facility allows multiple processes to gain | ||
2173 | * access to shared memory which is mapped into each process at an | ||
2174 | * identical virtual address. In order for this to work, the processes | ||
2175 | * must have a common ancestor, which must create the common memory using | ||
2176 | * tmc_cmem_init(). | ||
2177 | * | ||
2178 | * In programs using the iLib process creation API, or in programs which use | ||
2179 | * only one process (which include programs using the pthreads library), | ||
2180 | * tmc_cmem_init() is called automatically. All other applications | ||
2181 | * must call it explicitly, before any child processes which might call | ||
2182 | * netio_input_register() are created. | ||
2183 | */ | ||
2184 | typedef struct | ||
2185 | { | ||
2186 | /** Registration characteristics. | ||
2187 | |||
2188 | This value determines several characteristics of the registration; | ||
2189 | flags for different types of behavior are ORed together to make the | ||
2190 | final flag value. Generally applications should specify exactly | ||
2191 | one flag from each of the following categories: | ||
2192 | |||
2193 | - Whether the application will be receiving packets on this queue | ||
2194 | (::NETIO_RECV or ::NETIO_NO_RECV). | ||
2195 | |||
2196 | - Whether the application will be transmitting packets on this queue, | ||
2197 | and if so, whether it will request egress checksum calculation | ||
2198 | (::NETIO_XMIT, ::NETIO_XMIT_CSUM, or ::NETIO_NO_XMIT). It is | ||
2199 | legal to call netio_get_buffer() without one of the XMIT flags, | ||
2200 | as long as ::NETIO_RECV is specified; in this case, the retrieved | ||
2201 | buffers must be passed to another tile for transmission. | ||
2202 | |||
2203 | - Whether the application expects any vendor-specific tags in | ||
2204 | its packets' L2 headers (::NETIO_TAG_NONE, ::NETIO_TAG_BRCM, | ||
2205 | or ::NETIO_TAG_MRVL). This must match the configuration of the | ||
2206 | target IPP. | ||
2207 | |||
2208 | To accommodate applications written to previous versions of the NetIO | ||
2209 | interface, none of the flags above are currently required; if omitted, | ||
2210 | NetIO behaves more or less as if ::NETIO_RECV | ::NETIO_XMIT_CSUM | | ||
2211 | ::NETIO_TAG_NONE were used. However, explicit specification of | ||
2212 | the relevant flags allows NetIO to do a better job of resource | ||
2213 | allocation, allows earlier detection of certain configuration errors, | ||
2214 | and may enable advanced features or higher performance in the future, | ||
2215 | so their use is strongly recommended. | ||
2216 | |||
2217 | Note that specifying ::NETIO_NO_RECV along with ::NETIO_NO_XMIT | ||
2218 | is a special case, intended primarily for use by programs which | ||
2219 | retrieve network statistics or do link management operations. | ||
2220 | When these flags are both specified, the resulting queue may not | ||
2221 | be used with NetIO routines other than netio_get(), netio_set(), | ||
2222 | and netio_input_unregister(). See @ref link for more information | ||
2223 | on link management. | ||
2224 | |||
2225 | Other flags are optional; their use is described below. | ||
2226 | */ | ||
2227 | int flags; | ||
2228 | |||
2229 | /** Interface name. This is a string which identifies the specific | ||
2230 | Ethernet controller hardware to be used. The format of the string | ||
2231 | is a device type and a device index, separated by a slash; so, | ||
2232 | the first 10 Gigabit Ethernet controller is named "xgbe/0", while | ||
2233 | the second 10/100/1000 Megabit Ethernet controller is named "gbe/1". | ||
2234 | */ | ||
2235 | const char* interface; | ||
2236 | |||
2237 | /** Receive packet queue size. This specifies the maximum number | ||
2238 | of ingress packets that can be received on this queue without | ||
2239 | being retrieved by @ref netio_get_packet(). If the IPP's distribution | ||
2240 | algorithm calls for a packet to be sent to this queue, and this | ||
2241 | number of packets are already pending there, the new packet | ||
2242 | will either be discarded, or sent to another tile registered | ||
2243 | for the same queue_id (see @ref drops). This value must | ||
2244 | be at least ::NETIO_MIN_RECEIVE_PKTS, can always be at least | ||
2245 | ::NETIO_MAX_RECEIVE_PKTS, and may be larger than that on certain | ||
2246 | interfaces. | ||
2247 | */ | ||
2248 | int num_receive_packets; | ||
2249 | |||
2250 | /** The queue ID being requested. Legal values for this range from 0 | ||
2251 | to ::NETIO_MAX_QUEUE_ID, inclusive. ::NETIO_MAX_QUEUE_ID is always | ||
2252 | greater than or equal to the number of tiles; this allows one queue | ||
2253 | for each tile, plus at least one additional queue. Some applications | ||
2254 | may wish to use the additional queue as a destination for unwanted | ||
2255 | packets, since packets delivered to queues for which no tiles have | ||
2256 | registered are discarded. | ||
2257 | */ | ||
2258 | unsigned int queue_id; | ||
2259 | |||
2260 | /** Maximum number of small send buffers to be held in the local empty | ||
2261 | buffer cache. This specifies the size of the area which holds | ||
2262 | empty small egress buffers requested from the IPP but not yet | ||
2263 | retrieved via @ref netio_get_buffer(). This value must be greater | ||
2264 | than zero if the application will ever use @ref netio_get_buffer() | ||
2265 | to allocate empty small egress buffers; it may be no larger than | ||
2266 | ::NETIO_MAX_SEND_BUFFERS. See @ref epp for more details on empty | ||
2267 | buffer caching. | ||
2268 | */ | ||
2269 | int num_send_buffers_small_total; | ||
2270 | |||
2271 | /** Number of small send buffers to be preallocated at registration. | ||
2272 | If this value is nonzero, the specified number of empty small egress | ||
2273 | buffers will be requested from the IPP during the netio_input_register | ||
2274 | operation; this may speed the execution of @ref netio_get_buffer(). | ||
2275 | This may be no larger than @ref num_send_buffers_small_total. See @ref | ||
2276 | epp for more details on empty buffer caching. | ||
2277 | */ | ||
2278 | int num_send_buffers_small_prealloc; | ||
2279 | |||
2280 | /** Maximum number of large send buffers to be held in the local empty | ||
2281 | buffer cache. This specifies the size of the area which holds empty | ||
2282 | large egress buffers requested from the IPP but not yet retrieved via | ||
2283 | @ref netio_get_buffer(). This value must be greater than zero if the | ||
2284 | application will ever use @ref netio_get_buffer() to allocate empty | ||
2285 | large egress buffers; it may be no larger than ::NETIO_MAX_SEND_BUFFERS. | ||
2286 | See @ref epp for more details on empty buffer caching. | ||
2287 | */ | ||
2288 | int num_send_buffers_large_total; | ||
2289 | |||
2290 | /** Number of large send buffers to be preallocated at registration. | ||
2291 | If this value is nonzero, the specified number of empty large egress | ||
2292 | buffers will be requested from the IPP during the netio_input_register | ||
2293 | operation; this may speed the execution of @ref netio_get_buffer(). | ||
2294 | This may be no larger than @ref num_send_buffers_large_total. See @ref | ||
2295 | epp for more details on empty buffer caching. | ||
2296 | */ | ||
2297 | int num_send_buffers_large_prealloc; | ||
2298 | |||
2299 | /** Maximum number of jumbo send buffers to be held in the local empty | ||
2300 | buffer cache. This specifies the size of the area which holds empty | ||
2301 | jumbo egress buffers requested from the IPP but not yet retrieved via | ||
2302 | @ref netio_get_buffer(). This value must be greater than zero if the | ||
2303 | application will ever use @ref netio_get_buffer() to allocate empty | ||
2304 | jumbo egress buffers; it may be no larger than ::NETIO_MAX_SEND_BUFFERS. | ||
2305 | See @ref epp for more details on empty buffer caching. | ||
2306 | */ | ||
2307 | int num_send_buffers_jumbo_total; | ||
2308 | |||
2309 | /** Number of jumbo send buffers to be preallocated at registration. | ||
2310 | If this value is nonzero, the specified number of empty jumbo egress | ||
2311 | buffers will be requested from the IPP during the netio_input_register | ||
2312 | operation; this may speed the execution of @ref netio_get_buffer(). | ||
2313 | This may be no larger than @ref num_send_buffers_jumbo_total. See @ref | ||
2314 | epp for more details on empty buffer caching. | ||
2315 | */ | ||
2316 | int num_send_buffers_jumbo_prealloc; | ||
2317 | |||
2318 | /** Total packet buffer size. This determines the total size, in bytes, | ||
2319 | of the NetIO buffer pool. Note that the maximum number of available | ||
2320 | buffers of each size is determined during hypervisor configuration | ||
2321 | (see the <em>System Programmer's Guide</em> for details); this just | ||
2322 | influences how much host memory is allocated for those buffers. | ||
2323 | |||
2324 | The buffer pool is allocated from common memory, which will be | ||
2325 | automatically initialized if needed. If your buffer pool is larger | ||
2326 | than 240 MB, you might need to explicitly call @c tmc_cmem_init(), | ||
2327 | as described in the Application Libraries Reference Manual (UG227). | ||
2328 | |||
2329 | Packet buffers are currently allocated in chunks of 16 MB; this | ||
2330 | value will be rounded up to the next larger multiple of 16 MB. | ||
2331 | If this value is zero, a default of 32 MB will be used; this was | ||
2332 | the value used by previous versions of NetIO. Note that taking this | ||
2333 | default also affects the placement of buffers on Linux NUMA nodes. | ||
2334 | See @ref buffer_node_weights for an explanation of buffer placement. | ||
2335 | |||
2336 | In order to successfully allocate packet buffers, Linux must have | ||
2337 | available huge pages on the relevant Linux NUMA nodes. See the | ||
2338 | <em>System Programmer's Guide</em> for information on configuring | ||
2339 | huge page support in Linux. | ||
2340 | */ | ||
2341 | uint64_t total_buffer_size; | ||
2342 | |||
2343 | /** Buffer placement weighting factors. | ||
2344 | |||
2345 | This array specifies the relative amount of buffering to place | ||
2346 | on each of the available Linux NUMA nodes. This array is | ||
2347 | indexed by the NUMA node, and the values in the array are | ||
2348 | proportional to the amount of buffer space to allocate on that | ||
2349 | node. | ||
2350 | |||
2351 | If memory striping is enabled in the Hypervisor, then there is | ||
2352 | only one logical NUMA node (node 0). In that case, NetIO will by | ||
2353 | default ignore the suggested buffer node weights, and buffers | ||
2354 | will be striped across the physical memory controllers. See | ||
2355 | UG209 System Programmer's Guide for a description of the | ||
2356 | hypervisor option that controls memory striping. | ||
2357 | |||
2358 | If memory striping is disabled, then there are up to four NUMA | ||
2359 | nodes, corresponding to the four DDRAM controllers in the TILE | ||
2360 | processor architecture. See UG100 Tile Processor Architecture | ||
2361 | Overview for a diagram showing the location of each of the DDRAM | ||
2362 | controllers relative to the tile array. | ||
2363 | |||
2364 | For instance, if memory striping is disabled, the following | ||
2365 | configuration strucure: | ||
2366 | |||
2367 | @code | ||
2368 | netio_input_config_t config = { | ||
2369 | . | ||
2370 | . | ||
2371 | . | ||
2372 | .total_buffer_size = 4 * 16 * 1024 * 1024; | ||
2373 | .buffer_node_weights = { 1, 0, 1, 0 }, | ||
2374 | }, | ||
2375 | @endcode | ||
2376 | |||
2377 | would result in 32 MB of buffers being placed on controller 0, and | ||
2378 | 32 MB on controller 2. (Since buffers are allocated in units of | ||
2379 | 16 MB, some sets of weights will not be able to be matched exactly.) | ||
2380 | |||
2381 | For the weights to be effective, @ref total_buffer_size must be | ||
2382 | nonzero. If @ref total_buffer_size is zero, causing the default | ||
2383 | 32 MB of buffer space to be used, then any specified weights will | ||
2384 | be ignored, and buffers will positioned as they were in previous | ||
2385 | versions of NetIO: | ||
2386 | |||
2387 | - For xgbe/0 and gbe/0, 16 MB of buffers will be placed on controller 1, | ||
2388 | and the other 16 MB will be placed on controller 2. | ||
2389 | |||
2390 | - For xgbe/1 and gbe/1, 16 MB of buffers will be placed on controller 2, | ||
2391 | and the other 16 MB will be placed on controller 3. | ||
2392 | |||
2393 | If @ref total_buffer_size is nonzero, but all weights are zero, | ||
2394 | then all buffer space will be allocated on Linux NUMA node zero. | ||
2395 | |||
2396 | By default, the specified buffer placement is treated as a hint; | ||
2397 | if sufficient free memory is not available on the specified | ||
2398 | controllers, the buffers will be allocated elsewhere. However, | ||
2399 | if the ::NETIO_STRICT_HOMING flag is specified in @ref flags, then a | ||
2400 | failure to allocate buffer space exactly as requested will cause the | ||
2401 | registration operation to fail with an error of ::NETIO_CANNOT_HOME. | ||
2402 | |||
2403 | Note that maximal network performance cannot be achieved with | ||
2404 | only one memory controller. | ||
2405 | */ | ||
2406 | uint8_t buffer_node_weights[NETIO_NUM_NODE_WEIGHTS]; | ||
2407 | |||
2408 | /** Fixed virtual address for packet buffers. Only valid when | ||
2409 | ::NETIO_FIXED_BUFFER_VA is specified in @ref flags; see the | ||
2410 | description of that flag for details. | ||
2411 | */ | ||
2412 | void* fixed_buffer_va; | ||
2413 | |||
2414 | /** | ||
2415 | Maximum number of outstanding send packet requests. This value is | ||
2416 | only relevant when an EPP is in use; it determines the number of | ||
2417 | slots in the EPP's outgoing packet queue which this tile is allowed | ||
2418 | to consume, and thus the number of packets which may be sent before | ||
2419 | the sending tile must wait for an acknowledgment from the EPP. | ||
2420 | Modifying this value is generally only helpful when using @ref | ||
2421 | netio_send_packet_vector(), where it can help improve performance by | ||
2422 | allowing a single vector send operation to process more packets. | ||
2423 | Typically it is not specified, and the default, which divides the | ||
2424 | outgoing packet slots evenly between all tiles on the chip, is used. | ||
2425 | |||
2426 | If a registration asks for more outgoing packet queue slots than are | ||
2427 | available, ::NETIO_TOOMANY_XMIT will be returned. The total number | ||
2428 | of packet queue slots which are available for all tiles for each EPP | ||
2429 | is subject to change, but is currently ::NETIO_TOTAL_SENDS_OUTSTANDING. | ||
2430 | |||
2431 | |||
2432 | This value is ignored if ::NETIO_XMIT is not specified in flags. | ||
2433 | If you want to specify a large value here for a specific tile, you are | ||
2434 | advised to specify NETIO_NO_XMIT on other, non-transmitting tiles so | ||
2435 | that they do not consume a default number of packet slots. Any tile | ||
2436 | transmitting is required to have at least ::NETIO_MIN_SENDS_OUTSTANDING | ||
2437 | slots allocated to it; values less than that will be silently | ||
2438 | increased by the NetIO library. | ||
2439 | */ | ||
2440 | int num_sends_outstanding; | ||
2441 | } | ||
2442 | netio_input_config_t; | ||
2443 | |||
2444 | |||
2445 | /** Registration flags; used in the @ref netio_input_config_t structure. | ||
2446 | * @addtogroup setup | ||
2447 | */ | ||
2448 | /** @{ */ | ||
2449 | |||
2450 | /** Fail a registration request if we can't put packet buffers | ||
2451 | on the specified memory controllers. */ | ||
2452 | #define NETIO_STRICT_HOMING 0x00000002 | ||
2453 | |||
2454 | /** This application expects no tags on its L2 headers. */ | ||
2455 | #define NETIO_TAG_NONE 0x00000004 | ||
2456 | |||
2457 | /** This application expects Marvell extended tags on its L2 headers. */ | ||
2458 | #define NETIO_TAG_MRVL 0x00000008 | ||
2459 | |||
2460 | /** This application expects Broadcom tags on its L2 headers. */ | ||
2461 | #define NETIO_TAG_BRCM 0x00000010 | ||
2462 | |||
2463 | /** This registration may call routines which receive packets. */ | ||
2464 | #define NETIO_RECV 0x00000020 | ||
2465 | |||
2466 | /** This registration may not call routines which receive packets. */ | ||
2467 | #define NETIO_NO_RECV 0x00000040 | ||
2468 | |||
2469 | /** This registration may call routines which transmit packets. */ | ||
2470 | #define NETIO_XMIT 0x00000080 | ||
2471 | |||
2472 | /** This registration may call routines which transmit packets with | ||
2473 | checksum acceleration. */ | ||
2474 | #define NETIO_XMIT_CSUM 0x00000100 | ||
2475 | |||
2476 | /** This registration may not call routines which transmit packets. */ | ||
2477 | #define NETIO_NO_XMIT 0x00000200 | ||
2478 | |||
2479 | /** This registration wants NetIO buffers mapped at an application-specified | ||
2480 | virtual address. | ||
2481 | |||
2482 | NetIO buffers are by default created by the TMC common memory facility, | ||
2483 | which must be configured by a common ancestor of all processes sharing | ||
2484 | a network interface. When this flag is specified, NetIO buffers are | ||
2485 | instead mapped at an address chosen by the application (and specified | ||
2486 | in @ref netio_input_config_t::fixed_buffer_va). This allows multiple | ||
2487 | unrelated but cooperating processes to share a NetIO interface. | ||
2488 | All processes sharing the same interface must specify this flag, | ||
2489 | and all must specify the same fixed virtual address. | ||
2490 | |||
2491 | @ref netio_input_config_t::fixed_buffer_va must be a | ||
2492 | multiple of 16 MB, and the packet buffers will occupy @ref | ||
2493 | netio_input_config_t::total_buffer_size bytes of virtual address | ||
2494 | space, beginning at that address. If any of those virtual addresses | ||
2495 | are currently occupied by other memory objects, like application or | ||
2496 | shared library code or data, @ref netio_input_register() will return | ||
2497 | ::NETIO_FAULT. While it is impossible to provide a fixed_buffer_va | ||
2498 | which will work for all applications, a good first guess might be to | ||
2499 | use 0xb0000000 minus @ref netio_input_config_t::total_buffer_size. | ||
2500 | If that fails, it might be helpful to consult the running application's | ||
2501 | virtual address description file (/proc/<em>pid</em>/maps) to see | ||
2502 | which regions of virtual address space are available. | ||
2503 | */ | ||
2504 | #define NETIO_FIXED_BUFFER_VA 0x00000400 | ||
2505 | |||
2506 | /** This registration call will not complete unless the network link | ||
2507 | is up. The process will wait several seconds for this to happen (the | ||
2508 | precise interval is link-dependent), but if the link does not come up, | ||
2509 | ::NETIO_LINK_DOWN will be returned. This flag is the default if | ||
2510 | ::NETIO_NOREQUIRE_LINK_UP is not specified. Note that this flag by | ||
2511 | itself does not request that the link be brought up; that can be done | ||
2512 | with the ::NETIO_AUTO_LINK_UPDN or ::NETIO_AUTO_LINK_UP flags (the | ||
2513 | latter is the default if no NETIO_AUTO_LINK_xxx flags are specified), | ||
2514 | or by explicitly setting the link's desired state via netio_set(). | ||
2515 | If the link is not brought up by one of those methods, and this flag | ||
2516 | is specified, the registration operation will return ::NETIO_LINK_DOWN. | ||
2517 | This flag is ignored if it is specified along with ::NETIO_NO_XMIT and | ||
2518 | ::NETIO_NO_RECV. See @ref link for more information on link | ||
2519 | management. | ||
2520 | */ | ||
2521 | #define NETIO_REQUIRE_LINK_UP 0x00000800 | ||
2522 | |||
2523 | /** This registration call will complete even if the network link is not up. | ||
2524 | Whenever the link is not up, packets will not be sent or received: | ||
2525 | netio_get_packet() will return ::NETIO_NOPKT once all queued packets | ||
2526 | have been drained, and netio_send_packet() and similar routines will | ||
2527 | return NETIO_QUEUE_FULL once the outgoing packet queue in the EPP | ||
2528 | or the I/O shim is full. See @ref link for more information on link | ||
2529 | management. | ||
2530 | */ | ||
2531 | #define NETIO_NOREQUIRE_LINK_UP 0x00001000 | ||
2532 | |||
2533 | #ifndef __DOXYGEN__ | ||
2534 | /* | ||
2535 | * These are part of the implementation of the NETIO_AUTO_LINK_xxx flags, | ||
2536 | * but should not be used directly by applications, and are thus not | ||
2537 | * documented. | ||
2538 | */ | ||
2539 | #define _NETIO_AUTO_UP 0x00002000 | ||
2540 | #define _NETIO_AUTO_DN 0x00004000 | ||
2541 | #define _NETIO_AUTO_PRESENT 0x00008000 | ||
2542 | #endif | ||
2543 | |||
2544 | /** Set the desired state of the link to up, allowing any speeds which are | ||
2545 | supported by the link hardware, as part of this registration operation. | ||
2546 | Do not take down the link automatically. This is the default if | ||
2547 | no other NETIO_AUTO_LINK_xxx flags are specified. This flag is ignored | ||
2548 | if it is specified along with ::NETIO_NO_XMIT and ::NETIO_NO_RECV. | ||
2549 | See @ref link for more information on link management. | ||
2550 | */ | ||
2551 | #define NETIO_AUTO_LINK_UP (_NETIO_AUTO_PRESENT | _NETIO_AUTO_UP) | ||
2552 | |||
2553 | /** Set the desired state of the link to up, allowing any speeds which are | ||
2554 | supported by the link hardware, as part of this registration operation. | ||
2555 | Set the desired state of the link to down the next time no tiles are | ||
2556 | registered for packet reception or transmission. This flag is ignored | ||
2557 | if it is specified along with ::NETIO_NO_XMIT and ::NETIO_NO_RECV. | ||
2558 | See @ref link for more information on link management. | ||
2559 | */ | ||
2560 | #define NETIO_AUTO_LINK_UPDN (_NETIO_AUTO_PRESENT | _NETIO_AUTO_UP | \ | ||
2561 | _NETIO_AUTO_DN) | ||
2562 | |||
2563 | /** Set the desired state of the link to down the next time no tiles are | ||
2564 | registered for packet reception or transmission. This flag is ignored | ||
2565 | if it is specified along with ::NETIO_NO_XMIT and ::NETIO_NO_RECV. | ||
2566 | See @ref link for more information on link management. | ||
2567 | */ | ||
2568 | #define NETIO_AUTO_LINK_DN (_NETIO_AUTO_PRESENT | _NETIO_AUTO_DN) | ||
2569 | |||
2570 | /** Do not bring up the link automatically as part of this registration | ||
2571 | operation. Do not take down the link automatically. This flag | ||
2572 | is ignored if it is specified along with ::NETIO_NO_XMIT and | ||
2573 | ::NETIO_NO_RECV. See @ref link for more information on link management. | ||
2574 | */ | ||
2575 | #define NETIO_AUTO_LINK_NONE _NETIO_AUTO_PRESENT | ||
2576 | |||
2577 | |||
2578 | /** Minimum number of receive packets. */ | ||
2579 | #define NETIO_MIN_RECEIVE_PKTS 16 | ||
2580 | |||
2581 | /** Lower bound on the maximum number of receive packets; may be higher | ||
2582 | than this on some interfaces. */ | ||
2583 | #define NETIO_MAX_RECEIVE_PKTS 128 | ||
2584 | |||
2585 | /** Maximum number of send buffers, per packet size. */ | ||
2586 | #define NETIO_MAX_SEND_BUFFERS 16 | ||
2587 | |||
2588 | /** Number of EPP queue slots, and thus outstanding sends, per EPP. */ | ||
2589 | #define NETIO_TOTAL_SENDS_OUTSTANDING 2015 | ||
2590 | |||
2591 | /** Minimum number of EPP queue slots, and thus outstanding sends, per | ||
2592 | * transmitting tile. */ | ||
2593 | #define NETIO_MIN_SENDS_OUTSTANDING 16 | ||
2594 | |||
2595 | |||
2596 | /**@}*/ | ||
2597 | |||
2598 | #ifndef __DOXYGEN__ | ||
2599 | |||
2600 | /** | ||
2601 | * An object for providing Ethernet packets to a process. | ||
2602 | */ | ||
2603 | struct __netio_queue_impl_t; | ||
2604 | |||
2605 | /** | ||
2606 | * An object for managing the user end of a NetIO queue. | ||
2607 | */ | ||
2608 | struct __netio_queue_user_impl_t; | ||
2609 | |||
2610 | #endif /* !__DOXYGEN__ */ | ||
2611 | |||
2612 | |||
2613 | /** A netio_queue_t describes a NetIO communications endpoint. | ||
2614 | * @ingroup setup | ||
2615 | */ | ||
2616 | typedef struct | ||
2617 | { | ||
2618 | #ifdef __DOXYGEN__ | ||
2619 | uint8_t opaque[8]; /**< This is an opaque structure. */ | ||
2620 | #else | ||
2621 | struct __netio_queue_impl_t* __system_part; /**< The system part. */ | ||
2622 | struct __netio_queue_user_impl_t* __user_part; /**< The user part. */ | ||
2623 | #ifdef _NETIO_PTHREAD | ||
2624 | _netio_percpu_mutex_t lock; /**< Queue lock. */ | ||
2625 | #endif | ||
2626 | #endif | ||
2627 | } | ||
2628 | netio_queue_t; | ||
2629 | |||
2630 | |||
2631 | /** | ||
2632 | * @brief Packet send context. | ||
2633 | * | ||
2634 | * @ingroup egress | ||
2635 | * | ||
2636 | * Packet send context for use with netio_send_packet_prepare and _commit. | ||
2637 | */ | ||
2638 | typedef struct | ||
2639 | { | ||
2640 | #ifdef __DOXYGEN__ | ||
2641 | uint8_t opaque[44]; /**< This is an opaque structure. */ | ||
2642 | #else | ||
2643 | uint8_t flags; /**< Defined below */ | ||
2644 | uint8_t datalen; /**< Number of valid words pointed to by data. */ | ||
2645 | uint32_t request[9]; /**< Request to be sent to the EPP or shim. Note | ||
2646 | that this is smaller than the 11-word maximum | ||
2647 | request size, since some constant values are | ||
2648 | not saved in the context. */ | ||
2649 | uint32_t *data; /**< Data to be sent to the EPP or shim via IDN. */ | ||
2650 | #endif | ||
2651 | } | ||
2652 | netio_send_pkt_context_t; | ||
2653 | |||
2654 | |||
2655 | #ifndef __DOXYGEN__ | ||
2656 | #define SEND_PKT_CTX_USE_EPP 1 /**< We're sending to an EPP. */ | ||
2657 | #define SEND_PKT_CTX_SEND_CSUM 2 /**< Request includes a checksum. */ | ||
2658 | #endif | ||
2659 | |||
2660 | /** | ||
2661 | * @brief Packet vector entry. | ||
2662 | * | ||
2663 | * @ingroup egress | ||
2664 | * | ||
2665 | * This data structure is used with netio_send_packet_vector() to send multiple | ||
2666 | * packets with one NetIO call. The structure should be initialized by | ||
2667 | * calling netio_pkt_vector_set(), rather than by setting the fields | ||
2668 | * directly. | ||
2669 | * | ||
2670 | * This structure is guaranteed to be a power of two in size, no | ||
2671 | * bigger than one L2 cache line, and to be aligned modulo its size. | ||
2672 | */ | ||
2673 | typedef struct | ||
2674 | #ifndef __DOXYGEN__ | ||
2675 | __attribute__((aligned(8))) | ||
2676 | #endif | ||
2677 | { | ||
2678 | /** Reserved for use by the user application. When initialized with | ||
2679 | * the netio_set_pkt_vector_entry() function, this field is guaranteed | ||
2680 | * to be visible to readers only after all other fields are already | ||
2681 | * visible. This way it can be used as a valid flag or generation | ||
2682 | * counter. */ | ||
2683 | uint8_t user_data; | ||
2684 | |||
2685 | /* Structure members below this point should not be accessed directly by | ||
2686 | * applications, as they may change in the future. */ | ||
2687 | |||
2688 | /** Low 8 bits of the packet address to send. The high bits are | ||
2689 | * acquired from the 'handle' field. */ | ||
2690 | uint8_t buffer_address_low; | ||
2691 | |||
2692 | /** Number of bytes to transmit. */ | ||
2693 | uint16_t size; | ||
2694 | |||
2695 | /** The raw handle from a netio_pkt_t. If this is NETIO_PKT_HANDLE_NONE, | ||
2696 | * this vector entry will be skipped and no packet will be transmitted. */ | ||
2697 | netio_pkt_handle_t handle; | ||
2698 | } | ||
2699 | netio_pkt_vector_entry_t; | ||
2700 | |||
2701 | |||
2702 | /** | ||
2703 | * @brief Initialize fields in a packet vector entry. | ||
2704 | * | ||
2705 | * @ingroup egress | ||
2706 | * | ||
2707 | * @param[out] v Pointer to the vector entry to be initialized. | ||
2708 | * @param[in] pkt Packet to be transmitted when the vector entry is passed to | ||
2709 | * netio_send_packet_vector(). Note that the packet's attributes | ||
2710 | * (e.g., its L2 offset and length) are captured at the time this | ||
2711 | * routine is called; subsequent changes in those attributes will not | ||
2712 | * be reflected in the packet which is actually transmitted. | ||
2713 | * Changes in the packet's contents, however, will be so reflected. | ||
2714 | * If this is NULL, no packet will be transmitted. | ||
2715 | * @param[in] user_data User data to be set in the vector entry. | ||
2716 | * This function guarantees that the "user_data" field will become | ||
2717 | * visible to a reader only after all other fields have become visible. | ||
2718 | * This allows a structure in a ring buffer to be written and read | ||
2719 | * by a polling reader without any locks or other synchronization. | ||
2720 | */ | ||
2721 | static __inline void | ||
2722 | netio_pkt_vector_set(volatile netio_pkt_vector_entry_t* v, netio_pkt_t* pkt, | ||
2723 | uint8_t user_data) | ||
2724 | { | ||
2725 | if (pkt) | ||
2726 | { | ||
2727 | if (NETIO_PKT_IS_MINIMAL(pkt)) | ||
2728 | { | ||
2729 | netio_pkt_minimal_metadata_t* mmd = | ||
2730 | (netio_pkt_minimal_metadata_t*) &pkt->__metadata; | ||
2731 | v->buffer_address_low = (uintptr_t) NETIO_PKT_L2_DATA_MM(mmd, pkt) & 0xFF; | ||
2732 | v->size = NETIO_PKT_L2_LENGTH_MM(mmd, pkt); | ||
2733 | } | ||
2734 | else | ||
2735 | { | ||
2736 | netio_pkt_metadata_t* mda = &pkt->__metadata; | ||
2737 | v->buffer_address_low = (uintptr_t) NETIO_PKT_L2_DATA_M(mda, pkt) & 0xFF; | ||
2738 | v->size = NETIO_PKT_L2_LENGTH_M(mda, pkt); | ||
2739 | } | ||
2740 | v->handle.word = pkt->__packet.word; | ||
2741 | } | ||
2742 | else | ||
2743 | { | ||
2744 | v->handle.word = 0; /* Set handle to NETIO_PKT_HANDLE_NONE. */ | ||
2745 | } | ||
2746 | |||
2747 | __asm__("" : : : "memory"); | ||
2748 | |||
2749 | v->user_data = user_data; | ||
2750 | } | ||
2751 | |||
2752 | |||
2753 | /** | ||
2754 | * Flags and structures for @ref netio_get() and @ref netio_set(). | ||
2755 | * @ingroup config | ||
2756 | */ | ||
2757 | |||
2758 | /** @{ */ | ||
2759 | /** Parameter class; addr is a NETIO_PARAM_xxx value. */ | ||
2760 | #define NETIO_PARAM 0 | ||
2761 | /** Interface MAC address. This address is only valid with @ref netio_get(). | ||
2762 | * The value is a 6-byte MAC address. Depending upon the overall system | ||
2763 | * design, a MAC address may or may not be available for each interface. */ | ||
2764 | #define NETIO_PARAM_MAC 0 | ||
2765 | |||
2766 | /** Determine whether to suspend output on the receipt of pause frames. | ||
2767 | * If the value is nonzero, the I/O shim will suspend output when a pause | ||
2768 | * frame is received. If the value is zero, pause frames will be ignored. */ | ||
2769 | #define NETIO_PARAM_PAUSE_IN 1 | ||
2770 | |||
2771 | /** Determine whether to send pause frames if the I/O shim packet FIFOs are | ||
2772 | * nearly full. If the value is zero, pause frames are not sent. If | ||
2773 | * the value is nonzero, it is the delay value which will be sent in any | ||
2774 | * pause frames which are output, in units of 512 bit times. */ | ||
2775 | #define NETIO_PARAM_PAUSE_OUT 2 | ||
2776 | |||
2777 | /** Jumbo frame support. The value is a 4-byte integer. If the value is | ||
2778 | * nonzero, the MAC will accept frames of up to 10240 bytes. If the value | ||
2779 | * is zero, the MAC will only accept frames of up to 1544 bytes. */ | ||
2780 | #define NETIO_PARAM_JUMBO 3 | ||
2781 | |||
2782 | /** I/O shim's overflow statistics register. The value is two 16-bit integers. | ||
2783 | * The first 16-bit value (or the low 16 bits, if the value is treated as a | ||
2784 | * 32-bit number) is the count of packets which were completely dropped and | ||
2785 | * not delivered by the shim. The second 16-bit value (or the high 16 bits, | ||
2786 | * if the value is treated as a 32-bit number) is the count of packets | ||
2787 | * which were truncated and thus only partially delivered by the shim. This | ||
2788 | * register is automatically reset to zero after it has been read. | ||
2789 | */ | ||
2790 | #define NETIO_PARAM_OVERFLOW 4 | ||
2791 | |||
2792 | /** IPP statistics. This address is only valid with @ref netio_get(). The | ||
2793 | * value is a netio_stat_t structure. Unlike the I/O shim statistics, the | ||
2794 | * IPP statistics are not all reset to zero on read; see the description | ||
2795 | * of the netio_stat_t for details. */ | ||
2796 | #define NETIO_PARAM_STAT 5 | ||
2797 | |||
2798 | /** Possible link state. The value is a combination of "NETIO_LINK_xxx" | ||
2799 | * flags. With @ref netio_get(), this will indicate which flags are | ||
2800 | * actually supported by the hardware. | ||
2801 | * | ||
2802 | * For historical reasons, specifying this value to netio_set() will have | ||
2803 | * the same behavior as using ::NETIO_PARAM_LINK_CONFIG, but this usage is | ||
2804 | * discouraged. | ||
2805 | */ | ||
2806 | #define NETIO_PARAM_LINK_POSSIBLE_STATE 6 | ||
2807 | |||
2808 | /** Link configuration. The value is a combination of "NETIO_LINK_xxx" flags. | ||
2809 | * With @ref netio_set(), this will attempt to immediately bring up the | ||
2810 | * link using whichever of the requested flags are supported by the | ||
2811 | * hardware, or take down the link if the flags are zero; if this is | ||
2812 | * not possible, an error will be returned. Many programs will want | ||
2813 | * to use ::NETIO_PARAM_LINK_DESIRED_STATE instead. | ||
2814 | * | ||
2815 | * For historical reasons, specifying this value to netio_get() will | ||
2816 | * have the same behavior as using ::NETIO_PARAM_LINK_POSSIBLE_STATE, | ||
2817 | * but this usage is discouraged. | ||
2818 | */ | ||
2819 | #define NETIO_PARAM_LINK_CONFIG NETIO_PARAM_LINK_POSSIBLE_STATE | ||
2820 | |||
2821 | /** Current link state. This address is only valid with @ref netio_get(). | ||
2822 | * The value is zero or more of the "NETIO_LINK_xxx" flags, ORed together. | ||
2823 | * If the link is down, the value ANDed with NETIO_LINK_SPEED will be | ||
2824 | * zero; if the link is up, the value ANDed with NETIO_LINK_SPEED will | ||
2825 | * result in exactly one of the NETIO_LINK_xxx values, indicating the | ||
2826 | * current speed. */ | ||
2827 | #define NETIO_PARAM_LINK_CURRENT_STATE 7 | ||
2828 | |||
2829 | /** Variant symbol for current state, retained for compatibility with | ||
2830 | * pre-MDE-2.1 programs. */ | ||
2831 | #define NETIO_PARAM_LINK_STATUS NETIO_PARAM_LINK_CURRENT_STATE | ||
2832 | |||
2833 | /** Packet Coherence protocol. This address is only valid with @ref netio_get(). | ||
2834 | * The value is nonzero if the interface is configured for cache-coherent DMA. | ||
2835 | */ | ||
2836 | #define NETIO_PARAM_COHERENT 8 | ||
2837 | |||
2838 | /** Desired link state. The value is a conbination of "NETIO_LINK_xxx" | ||
2839 | * flags, which specify the desired state for the link. With @ref | ||
2840 | * netio_set(), this will, in the background, attempt to bring up the link | ||
2841 | * using whichever of the requested flags are reasonable, or take down the | ||
2842 | * link if the flags are zero. The actual link up or down operation may | ||
2843 | * happen after this call completes. If the link state changes in the | ||
2844 | * future, the system will continue to try to get back to the desired link | ||
2845 | * state; for instance, if the link is brought up successfully, and then | ||
2846 | * the network cable is disconnected, the link will go down. However, the | ||
2847 | * desired state of the link is still up, so if the cable is reconnected, | ||
2848 | * the link will be brought up again. | ||
2849 | * | ||
2850 | * With @ref netio_get(), this will indicate the desired state for the | ||
2851 | * link, as set with a previous netio_set() call, or implicitly by a | ||
2852 | * netio_input_register() or netio_input_unregister() operation. This may | ||
2853 | * not reflect the current state of the link; to get that, use | ||
2854 | * ::NETIO_PARAM_LINK_CURRENT_STATE. */ | ||
2855 | #define NETIO_PARAM_LINK_DESIRED_STATE 9 | ||
2856 | |||
2857 | /** NetIO statistics structure. Retrieved using the ::NETIO_PARAM_STAT | ||
2858 | * address passed to @ref netio_get(). */ | ||
2859 | typedef struct | ||
2860 | { | ||
2861 | /** Number of packets which have been received by the IPP and forwarded | ||
2862 | * to a tile's receive queue for processing. This value wraps at its | ||
2863 | * maximum, and is not cleared upon read. */ | ||
2864 | uint32_t packets_received; | ||
2865 | |||
2866 | /** Number of packets which have been dropped by the IPP, because they could | ||
2867 | * not be received, or could not be forwarded to a tile. The former happens | ||
2868 | * when the IPP does not have a free packet buffer of suitable size for an | ||
2869 | * incoming frame. The latter happens when all potential destination tiles | ||
2870 | * for a packet, as defined by the group, bucket, and queue configuration, | ||
2871 | * have full receive queues. This value wraps at its maximum, and is not | ||
2872 | * cleared upon read. */ | ||
2873 | uint32_t packets_dropped; | ||
2874 | |||
2875 | /* | ||
2876 | * Note: the #defines after each of the following four one-byte values | ||
2877 | * denote their location within the third word of the netio_stat_t. They | ||
2878 | * are intended for use only by the IPP implementation and are thus omitted | ||
2879 | * from the Doxygen output. | ||
2880 | */ | ||
2881 | |||
2882 | /** Number of packets dropped because no worker was able to accept a new | ||
2883 | * packet. This value saturates at its maximum, and is cleared upon | ||
2884 | * read. */ | ||
2885 | uint8_t drops_no_worker; | ||
2886 | #ifndef __DOXYGEN__ | ||
2887 | #define NETIO_STAT_DROPS_NO_WORKER 0 | ||
2888 | #endif | ||
2889 | |||
2890 | /** Number of packets dropped because no small buffers were available. | ||
2891 | * This value saturates at its maximum, and is cleared upon read. */ | ||
2892 | uint8_t drops_no_smallbuf; | ||
2893 | #ifndef __DOXYGEN__ | ||
2894 | #define NETIO_STAT_DROPS_NO_SMALLBUF 1 | ||
2895 | #endif | ||
2896 | |||
2897 | /** Number of packets dropped because no large buffers were available. | ||
2898 | * This value saturates at its maximum, and is cleared upon read. */ | ||
2899 | uint8_t drops_no_largebuf; | ||
2900 | #ifndef __DOXYGEN__ | ||
2901 | #define NETIO_STAT_DROPS_NO_LARGEBUF 2 | ||
2902 | #endif | ||
2903 | |||
2904 | /** Number of packets dropped because no jumbo buffers were available. | ||
2905 | * This value saturates at its maximum, and is cleared upon read. */ | ||
2906 | uint8_t drops_no_jumbobuf; | ||
2907 | #ifndef __DOXYGEN__ | ||
2908 | #define NETIO_STAT_DROPS_NO_JUMBOBUF 3 | ||
2909 | #endif | ||
2910 | } | ||
2911 | netio_stat_t; | ||
2912 | |||
2913 | |||
2914 | /** Link can run, should run, or is running at 10 Mbps. */ | ||
2915 | #define NETIO_LINK_10M 0x01 | ||
2916 | |||
2917 | /** Link can run, should run, or is running at 100 Mbps. */ | ||
2918 | #define NETIO_LINK_100M 0x02 | ||
2919 | |||
2920 | /** Link can run, should run, or is running at 1 Gbps. */ | ||
2921 | #define NETIO_LINK_1G 0x04 | ||
2922 | |||
2923 | /** Link can run, should run, or is running at 10 Gbps. */ | ||
2924 | #define NETIO_LINK_10G 0x08 | ||
2925 | |||
2926 | /** Link should run at the highest speed supported by the link and by | ||
2927 | * the device connected to the link. Only usable as a value for | ||
2928 | * the link's desired state; never returned as a value for the current | ||
2929 | * or possible states. */ | ||
2930 | #define NETIO_LINK_ANYSPEED 0x10 | ||
2931 | |||
2932 | /** All legal link speeds. */ | ||
2933 | #define NETIO_LINK_SPEED (NETIO_LINK_10M | \ | ||
2934 | NETIO_LINK_100M | \ | ||
2935 | NETIO_LINK_1G | \ | ||
2936 | NETIO_LINK_10G | \ | ||
2937 | NETIO_LINK_ANYSPEED) | ||
2938 | |||
2939 | |||
2940 | /** MAC register class. Addr is a register offset within the MAC. | ||
2941 | * Registers within the XGbE and GbE MACs are documented in the Tile | ||
2942 | * Processor I/O Device Guide (UG104). MAC registers start at address | ||
2943 | * 0x4000, and do not include the MAC_INTERFACE registers. */ | ||
2944 | #define NETIO_MAC 1 | ||
2945 | |||
2946 | /** MDIO register class (IEEE 802.3 clause 22 format). Addr is the "addr" | ||
2947 | * member of a netio_mdio_addr_t structure. */ | ||
2948 | #define NETIO_MDIO 2 | ||
2949 | |||
2950 | /** MDIO register class (IEEE 802.3 clause 45 format). Addr is the "addr" | ||
2951 | * member of a netio_mdio_addr_t structure. */ | ||
2952 | #define NETIO_MDIO_CLAUSE45 3 | ||
2953 | |||
2954 | /** NetIO MDIO address type. Retrieved or provided using the ::NETIO_MDIO | ||
2955 | * address passed to @ref netio_get() or @ref netio_set(). */ | ||
2956 | typedef union | ||
2957 | { | ||
2958 | struct | ||
2959 | { | ||
2960 | unsigned int reg:16; /**< MDIO register offset. For clause 22 access, | ||
2961 | must be less than 32. */ | ||
2962 | unsigned int phy:5; /**< Which MDIO PHY to access. */ | ||
2963 | unsigned int dev:5; /**< Which MDIO device to access within that PHY. | ||
2964 | Applicable for clause 45 access only; ignored | ||
2965 | for clause 22 access. */ | ||
2966 | } | ||
2967 | bits; /**< Container for bitfields. */ | ||
2968 | uint64_t addr; /**< Value to pass to @ref netio_get() or | ||
2969 | * @ref netio_set(). */ | ||
2970 | } | ||
2971 | netio_mdio_addr_t; | ||
2972 | |||
2973 | /** @} */ | ||
2974 | |||
2975 | #endif /* __NETIO_INTF_H__ */ | ||
diff --git a/arch/tile/kernel/Makefile b/arch/tile/kernel/Makefile index 112b1e248f05..b4c8e8ec45dc 100644 --- a/arch/tile/kernel/Makefile +++ b/arch/tile/kernel/Makefile | |||
@@ -15,3 +15,4 @@ obj-$(CONFIG_SMP) += smpboot.o smp.o tlb.o | |||
15 | obj-$(CONFIG_MODULES) += module.o | 15 | obj-$(CONFIG_MODULES) += module.o |
16 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 16 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
17 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o | 17 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o |
18 | obj-$(CONFIG_PCI) += pci.o | ||
diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c new file mode 100644 index 000000000000..a1ee25be9ad9 --- /dev/null +++ b/arch/tile/kernel/pci.c | |||
@@ -0,0 +1,621 @@ | |||
1 | /* | ||
2 | * Copyright 2010 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/pci.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/string.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/capability.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/errno.h> | ||
23 | #include <linux/bootmem.h> | ||
24 | #include <linux/irq.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/uaccess.h> | ||
27 | |||
28 | #include <asm/processor.h> | ||
29 | #include <asm/sections.h> | ||
30 | #include <asm/byteorder.h> | ||
31 | #include <asm/hv_driver.h> | ||
32 | #include <hv/drv_pcie_rc_intf.h> | ||
33 | |||
34 | |||
35 | /* | ||
36 | * Initialization flow and process | ||
37 | * ------------------------------- | ||
38 | * | ||
39 | * This files containes the routines to search for PCI buses, | ||
40 | * enumerate the buses, and configure any attached devices. | ||
41 | * | ||
42 | * There are two entry points here: | ||
43 | * 1) tile_pci_init | ||
44 | * This sets up the pci_controller structs, and opens the | ||
45 | * FDs to the hypervisor. This is called from setup_arch() early | ||
46 | * in the boot process. | ||
47 | * 2) pcibios_init | ||
48 | * This probes the PCI bus(es) for any attached hardware. It's | ||
49 | * called by subsys_initcall. All of the real work is done by the | ||
50 | * generic Linux PCI layer. | ||
51 | * | ||
52 | */ | ||
53 | |||
54 | /* | ||
55 | * This flag tells if the platform is TILEmpower that needs | ||
56 | * special configuration for the PLX switch chip. | ||
57 | */ | ||
58 | int __write_once tile_plx_gen1; | ||
59 | |||
60 | static struct pci_controller controllers[TILE_NUM_PCIE]; | ||
61 | static int num_controllers; | ||
62 | |||
63 | static struct pci_ops tile_cfg_ops; | ||
64 | |||
65 | |||
66 | /* | ||
67 | * We don't need to worry about the alignment of resources. | ||
68 | */ | ||
69 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, | ||
70 | resource_size_t size, resource_size_t align) | ||
71 | { | ||
72 | return res->start; | ||
73 | } | ||
74 | EXPORT_SYMBOL(pcibios_align_resource); | ||
75 | |||
76 | /* | ||
77 | * Open a FD to the hypervisor PCI device. | ||
78 | * | ||
79 | * controller_id is the controller number, config type is 0 or 1 for | ||
80 | * config0 or config1 operations. | ||
81 | */ | ||
82 | static int __init tile_pcie_open(int controller_id, int config_type) | ||
83 | { | ||
84 | char filename[32]; | ||
85 | int fd; | ||
86 | |||
87 | sprintf(filename, "pcie/%d/config%d", controller_id, config_type); | ||
88 | |||
89 | fd = hv_dev_open((HV_VirtAddr)filename, 0); | ||
90 | |||
91 | return fd; | ||
92 | } | ||
93 | |||
94 | |||
95 | /* | ||
96 | * Get the IRQ numbers from the HV and set up the handlers for them. | ||
97 | */ | ||
98 | static int __init tile_init_irqs(int controller_id, | ||
99 | struct pci_controller *controller) | ||
100 | { | ||
101 | char filename[32]; | ||
102 | int fd; | ||
103 | int ret; | ||
104 | int x; | ||
105 | struct pcie_rc_config rc_config; | ||
106 | |||
107 | sprintf(filename, "pcie/%d/ctl", controller_id); | ||
108 | fd = hv_dev_open((HV_VirtAddr)filename, 0); | ||
109 | if (fd < 0) { | ||
110 | pr_err("PCI: hv_dev_open(%s) failed\n", filename); | ||
111 | return -1; | ||
112 | } | ||
113 | ret = hv_dev_pread(fd, 0, (HV_VirtAddr)(&rc_config), | ||
114 | sizeof(rc_config), PCIE_RC_CONFIG_MASK_OFF); | ||
115 | hv_dev_close(fd); | ||
116 | if (ret != sizeof(rc_config)) { | ||
117 | pr_err("PCI: wanted %zd bytes, got %d\n", | ||
118 | sizeof(rc_config), ret); | ||
119 | return -1; | ||
120 | } | ||
121 | /* Record irq_base so that we can map INTx to IRQ # later. */ | ||
122 | controller->irq_base = rc_config.intr; | ||
123 | |||
124 | for (x = 0; x < 4; x++) | ||
125 | tile_irq_activate(rc_config.intr + x, | ||
126 | TILE_IRQ_HW_CLEAR); | ||
127 | |||
128 | if (rc_config.plx_gen1) | ||
129 | controller->plx_gen1 = 1; | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | * First initialization entry point, called from setup_arch(). | ||
136 | * | ||
137 | * Find valid controllers and fill in pci_controller structs for each | ||
138 | * of them. | ||
139 | * | ||
140 | * Returns the number of controllers discovered. | ||
141 | */ | ||
142 | int __init tile_pci_init(void) | ||
143 | { | ||
144 | int i; | ||
145 | |||
146 | pr_info("PCI: Searching for controllers...\n"); | ||
147 | |||
148 | /* Do any configuration we need before using the PCIe */ | ||
149 | |||
150 | for (i = 0; i < TILE_NUM_PCIE; i++) { | ||
151 | int hv_cfg_fd0 = -1; | ||
152 | int hv_cfg_fd1 = -1; | ||
153 | int hv_mem_fd = -1; | ||
154 | char name[32]; | ||
155 | struct pci_controller *controller; | ||
156 | |||
157 | /* | ||
158 | * Open the fd to the HV. If it fails then this | ||
159 | * device doesn't exist. | ||
160 | */ | ||
161 | hv_cfg_fd0 = tile_pcie_open(i, 0); | ||
162 | if (hv_cfg_fd0 < 0) | ||
163 | continue; | ||
164 | hv_cfg_fd1 = tile_pcie_open(i, 1); | ||
165 | if (hv_cfg_fd1 < 0) { | ||
166 | pr_err("PCI: Couldn't open config fd to HV " | ||
167 | "for controller %d\n", i); | ||
168 | goto err_cont; | ||
169 | } | ||
170 | |||
171 | sprintf(name, "pcie/%d/mem", i); | ||
172 | hv_mem_fd = hv_dev_open((HV_VirtAddr)name, 0); | ||
173 | if (hv_mem_fd < 0) { | ||
174 | pr_err("PCI: Could not open mem fd to HV!\n"); | ||
175 | goto err_cont; | ||
176 | } | ||
177 | |||
178 | pr_info("PCI: Found PCI controller #%d\n", i); | ||
179 | |||
180 | controller = &controllers[num_controllers]; | ||
181 | |||
182 | if (tile_init_irqs(i, controller)) { | ||
183 | pr_err("PCI: Could not initialize " | ||
184 | "IRQs, aborting.\n"); | ||
185 | goto err_cont; | ||
186 | } | ||
187 | |||
188 | controller->index = num_controllers; | ||
189 | controller->hv_cfg_fd[0] = hv_cfg_fd0; | ||
190 | controller->hv_cfg_fd[1] = hv_cfg_fd1; | ||
191 | controller->hv_mem_fd = hv_mem_fd; | ||
192 | controller->first_busno = 0; | ||
193 | controller->last_busno = 0xff; | ||
194 | controller->ops = &tile_cfg_ops; | ||
195 | |||
196 | num_controllers++; | ||
197 | continue; | ||
198 | |||
199 | err_cont: | ||
200 | if (hv_cfg_fd0 >= 0) | ||
201 | hv_dev_close(hv_cfg_fd0); | ||
202 | if (hv_cfg_fd1 >= 0) | ||
203 | hv_dev_close(hv_cfg_fd1); | ||
204 | if (hv_mem_fd >= 0) | ||
205 | hv_dev_close(hv_mem_fd); | ||
206 | continue; | ||
207 | } | ||
208 | |||
209 | /* | ||
210 | * Before using the PCIe, see if we need to do any platform-specific | ||
211 | * configuration, such as the PLX switch Gen 1 issue on TILEmpower. | ||
212 | */ | ||
213 | for (i = 0; i < num_controllers; i++) { | ||
214 | struct pci_controller *controller = &controllers[i]; | ||
215 | |||
216 | if (controller->plx_gen1) | ||
217 | tile_plx_gen1 = 1; | ||
218 | } | ||
219 | |||
220 | return num_controllers; | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * (pin - 1) converts from the PCI standard's [1:4] convention to | ||
225 | * a normal [0:3] range. | ||
226 | */ | ||
227 | static int tile_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
228 | { | ||
229 | struct pci_controller *controller = | ||
230 | (struct pci_controller *)dev->sysdata; | ||
231 | return (pin - 1) + controller->irq_base; | ||
232 | } | ||
233 | |||
234 | |||
235 | static void __init fixup_read_and_payload_sizes(void) | ||
236 | { | ||
237 | struct pci_dev *dev = NULL; | ||
238 | int smallest_max_payload = 0x1; /* Tile maxes out at 256 bytes. */ | ||
239 | int max_read_size = 0x2; /* Limit to 512 byte reads. */ | ||
240 | u16 new_values; | ||
241 | |||
242 | /* Scan for the smallest maximum payload size. */ | ||
243 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | ||
244 | int pcie_caps_offset; | ||
245 | u32 devcap; | ||
246 | int max_payload; | ||
247 | |||
248 | pcie_caps_offset = pci_find_capability(dev, PCI_CAP_ID_EXP); | ||
249 | if (pcie_caps_offset == 0) | ||
250 | continue; | ||
251 | |||
252 | pci_read_config_dword(dev, pcie_caps_offset + PCI_EXP_DEVCAP, | ||
253 | &devcap); | ||
254 | max_payload = devcap & PCI_EXP_DEVCAP_PAYLOAD; | ||
255 | if (max_payload < smallest_max_payload) | ||
256 | smallest_max_payload = max_payload; | ||
257 | } | ||
258 | |||
259 | /* Now, set the max_payload_size for all devices to that value. */ | ||
260 | new_values = (max_read_size << 12) | (smallest_max_payload << 5); | ||
261 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | ||
262 | int pcie_caps_offset; | ||
263 | u16 devctl; | ||
264 | |||
265 | pcie_caps_offset = pci_find_capability(dev, PCI_CAP_ID_EXP); | ||
266 | if (pcie_caps_offset == 0) | ||
267 | continue; | ||
268 | |||
269 | pci_read_config_word(dev, pcie_caps_offset + PCI_EXP_DEVCTL, | ||
270 | &devctl); | ||
271 | devctl &= ~(PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ); | ||
272 | devctl |= new_values; | ||
273 | pci_write_config_word(dev, pcie_caps_offset + PCI_EXP_DEVCTL, | ||
274 | devctl); | ||
275 | } | ||
276 | } | ||
277 | |||
278 | |||
279 | /* | ||
280 | * Second PCI initialization entry point, called by subsys_initcall. | ||
281 | * | ||
282 | * The controllers have been set up by the time we get here, by a call to | ||
283 | * tile_pci_init. | ||
284 | */ | ||
285 | static int __init pcibios_init(void) | ||
286 | { | ||
287 | int i; | ||
288 | |||
289 | pr_info("PCI: Probing PCI hardware\n"); | ||
290 | |||
291 | /* | ||
292 | * Delay a bit in case devices aren't ready. Some devices are | ||
293 | * known to require at least 20ms here, but we use a more | ||
294 | * conservative value. | ||
295 | */ | ||
296 | mdelay(250); | ||
297 | |||
298 | /* Scan all of the recorded PCI controllers. */ | ||
299 | for (i = 0; i < num_controllers; i++) { | ||
300 | struct pci_controller *controller = &controllers[i]; | ||
301 | struct pci_bus *bus; | ||
302 | |||
303 | pr_info("PCI: initializing controller #%d\n", i); | ||
304 | |||
305 | /* | ||
306 | * This comes from the generic Linux PCI driver. | ||
307 | * | ||
308 | * It reads the PCI tree for this bus into the Linux | ||
309 | * data structures. | ||
310 | * | ||
311 | * This is inlined in linux/pci.h and calls into | ||
312 | * pci_scan_bus_parented() in probe.c. | ||
313 | */ | ||
314 | bus = pci_scan_bus(0, controller->ops, controller); | ||
315 | controller->root_bus = bus; | ||
316 | controller->last_busno = bus->subordinate; | ||
317 | |||
318 | } | ||
319 | |||
320 | /* Do machine dependent PCI interrupt routing */ | ||
321 | pci_fixup_irqs(pci_common_swizzle, tile_map_irq); | ||
322 | |||
323 | /* | ||
324 | * This comes from the generic Linux PCI driver. | ||
325 | * | ||
326 | * It allocates all of the resources (I/O memory, etc) | ||
327 | * associated with the devices read in above. | ||
328 | */ | ||
329 | |||
330 | pci_assign_unassigned_resources(); | ||
331 | |||
332 | /* Configure the max_read_size and max_payload_size values. */ | ||
333 | fixup_read_and_payload_sizes(); | ||
334 | |||
335 | /* Record the I/O resources in the PCI controller structure. */ | ||
336 | for (i = 0; i < num_controllers; i++) { | ||
337 | struct pci_bus *root_bus = controllers[i].root_bus; | ||
338 | struct pci_bus *next_bus; | ||
339 | struct pci_dev *dev; | ||
340 | |||
341 | list_for_each_entry(dev, &root_bus->devices, bus_list) { | ||
342 | /* Find the PCI host controller, ie. the 1st bridge. */ | ||
343 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && | ||
344 | (PCI_SLOT(dev->devfn) == 0)) { | ||
345 | next_bus = dev->subordinate; | ||
346 | controllers[i].mem_resources[0] = | ||
347 | *next_bus->resource[0]; | ||
348 | controllers[i].mem_resources[1] = | ||
349 | *next_bus->resource[1]; | ||
350 | controllers[i].mem_resources[2] = | ||
351 | *next_bus->resource[2]; | ||
352 | |||
353 | break; | ||
354 | } | ||
355 | } | ||
356 | |||
357 | } | ||
358 | |||
359 | return 0; | ||
360 | } | ||
361 | subsys_initcall(pcibios_init); | ||
362 | |||
363 | /* | ||
364 | * No bus fixups needed. | ||
365 | */ | ||
366 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) | ||
367 | { | ||
368 | /* Nothing needs to be done. */ | ||
369 | } | ||
370 | |||
371 | /* | ||
372 | * This can be called from the generic PCI layer, but doesn't need to | ||
373 | * do anything. | ||
374 | */ | ||
375 | char __devinit *pcibios_setup(char *str) | ||
376 | { | ||
377 | /* Nothing needs to be done. */ | ||
378 | return str; | ||
379 | } | ||
380 | |||
381 | /* | ||
382 | * This is called from the generic Linux layer. | ||
383 | */ | ||
384 | void __init pcibios_update_irq(struct pci_dev *dev, int irq) | ||
385 | { | ||
386 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | ||
387 | } | ||
388 | |||
389 | /* | ||
390 | * Enable memory and/or address decoding, as appropriate, for the | ||
391 | * device described by the 'dev' struct. | ||
392 | * | ||
393 | * This is called from the generic PCI layer, and can be called | ||
394 | * for bridges or endpoints. | ||
395 | */ | ||
396 | int pcibios_enable_device(struct pci_dev *dev, int mask) | ||
397 | { | ||
398 | u16 cmd, old_cmd; | ||
399 | u8 header_type; | ||
400 | int i; | ||
401 | struct resource *r; | ||
402 | |||
403 | pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type); | ||
404 | |||
405 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
406 | old_cmd = cmd; | ||
407 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { | ||
408 | /* | ||
409 | * For bridges, we enable both memory and I/O decoding | ||
410 | * in call cases. | ||
411 | */ | ||
412 | cmd |= PCI_COMMAND_IO; | ||
413 | cmd |= PCI_COMMAND_MEMORY; | ||
414 | } else { | ||
415 | /* | ||
416 | * For endpoints, we enable memory and/or I/O decoding | ||
417 | * only if they have a memory resource of that type. | ||
418 | */ | ||
419 | for (i = 0; i < 6; i++) { | ||
420 | r = &dev->resource[i]; | ||
421 | if (r->flags & IORESOURCE_UNSET) { | ||
422 | pr_err("PCI: Device %s not available " | ||
423 | "because of resource collisions\n", | ||
424 | pci_name(dev)); | ||
425 | return -EINVAL; | ||
426 | } | ||
427 | if (r->flags & IORESOURCE_IO) | ||
428 | cmd |= PCI_COMMAND_IO; | ||
429 | if (r->flags & IORESOURCE_MEM) | ||
430 | cmd |= PCI_COMMAND_MEMORY; | ||
431 | } | ||
432 | } | ||
433 | |||
434 | /* | ||
435 | * We only write the command if it changed. | ||
436 | */ | ||
437 | if (cmd != old_cmd) | ||
438 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max) | ||
443 | { | ||
444 | unsigned long start = pci_resource_start(dev, bar); | ||
445 | unsigned long len = pci_resource_len(dev, bar); | ||
446 | unsigned long flags = pci_resource_flags(dev, bar); | ||
447 | |||
448 | if (!len) | ||
449 | return NULL; | ||
450 | if (max && len > max) | ||
451 | len = max; | ||
452 | |||
453 | if (!(flags & IORESOURCE_MEM)) { | ||
454 | pr_info("PCI: Trying to map invalid resource %#lx\n", flags); | ||
455 | start = 0; | ||
456 | } | ||
457 | |||
458 | return (void __iomem *)start; | ||
459 | } | ||
460 | EXPORT_SYMBOL(pci_iomap); | ||
461 | |||
462 | |||
463 | /**************************************************************** | ||
464 | * | ||
465 | * Tile PCI config space read/write routines | ||
466 | * | ||
467 | ****************************************************************/ | ||
468 | |||
469 | /* | ||
470 | * These are the normal read and write ops | ||
471 | * These are expanded with macros from pci_bus_read_config_byte() etc. | ||
472 | * | ||
473 | * devfn is the combined PCI slot & function. | ||
474 | * | ||
475 | * offset is in bytes, from the start of config space for the | ||
476 | * specified bus & slot. | ||
477 | */ | ||
478 | |||
479 | static int __devinit tile_cfg_read(struct pci_bus *bus, | ||
480 | unsigned int devfn, | ||
481 | int offset, | ||
482 | int size, | ||
483 | u32 *val) | ||
484 | { | ||
485 | struct pci_controller *controller = bus->sysdata; | ||
486 | int busnum = bus->number & 0xff; | ||
487 | int slot = (devfn >> 3) & 0x1f; | ||
488 | int function = devfn & 0x7; | ||
489 | u32 addr; | ||
490 | int config_mode = 1; | ||
491 | |||
492 | /* | ||
493 | * There is no bridge between the Tile and bus 0, so we | ||
494 | * use config0 to talk to bus 0. | ||
495 | * | ||
496 | * If we're talking to a bus other than zero then we | ||
497 | * must have found a bridge. | ||
498 | */ | ||
499 | if (busnum == 0) { | ||
500 | /* | ||
501 | * We fake an empty slot for (busnum == 0) && (slot > 0), | ||
502 | * since there is only one slot on bus 0. | ||
503 | */ | ||
504 | if (slot) { | ||
505 | *val = 0xFFFFFFFF; | ||
506 | return 0; | ||
507 | } | ||
508 | config_mode = 0; | ||
509 | } | ||
510 | |||
511 | addr = busnum << 20; /* Bus in 27:20 */ | ||
512 | addr |= slot << 15; /* Slot (device) in 19:15 */ | ||
513 | addr |= function << 12; /* Function is in 14:12 */ | ||
514 | addr |= (offset & 0xFFF); /* byte address in 0:11 */ | ||
515 | |||
516 | return hv_dev_pread(controller->hv_cfg_fd[config_mode], 0, | ||
517 | (HV_VirtAddr)(val), size, addr); | ||
518 | } | ||
519 | |||
520 | |||
521 | /* | ||
522 | * See tile_cfg_read() for relevent comments. | ||
523 | * Note that "val" is the value to write, not a pointer to that value. | ||
524 | */ | ||
525 | static int __devinit tile_cfg_write(struct pci_bus *bus, | ||
526 | unsigned int devfn, | ||
527 | int offset, | ||
528 | int size, | ||
529 | u32 val) | ||
530 | { | ||
531 | struct pci_controller *controller = bus->sysdata; | ||
532 | int busnum = bus->number & 0xff; | ||
533 | int slot = (devfn >> 3) & 0x1f; | ||
534 | int function = devfn & 0x7; | ||
535 | u32 addr; | ||
536 | int config_mode = 1; | ||
537 | HV_VirtAddr valp = (HV_VirtAddr)&val; | ||
538 | |||
539 | /* | ||
540 | * For bus 0 slot 0 we use config 0 accesses. | ||
541 | */ | ||
542 | if (busnum == 0) { | ||
543 | /* | ||
544 | * We fake an empty slot for (busnum == 0) && (slot > 0), | ||
545 | * since there is only one slot on bus 0. | ||
546 | */ | ||
547 | if (slot) | ||
548 | return 0; | ||
549 | config_mode = 0; | ||
550 | } | ||
551 | |||
552 | addr = busnum << 20; /* Bus in 27:20 */ | ||
553 | addr |= slot << 15; /* Slot (device) in 19:15 */ | ||
554 | addr |= function << 12; /* Function is in 14:12 */ | ||
555 | addr |= (offset & 0xFFF); /* byte address in 0:11 */ | ||
556 | |||
557 | #ifdef __BIG_ENDIAN | ||
558 | /* Point to the correct part of the 32-bit "val". */ | ||
559 | valp += 4 - size; | ||
560 | #endif | ||
561 | |||
562 | return hv_dev_pwrite(controller->hv_cfg_fd[config_mode], 0, | ||
563 | valp, size, addr); | ||
564 | } | ||
565 | |||
566 | |||
567 | static struct pci_ops tile_cfg_ops = { | ||
568 | .read = tile_cfg_read, | ||
569 | .write = tile_cfg_write, | ||
570 | }; | ||
571 | |||
572 | |||
573 | /* | ||
574 | * In the following, each PCI controller's mem_resources[1] | ||
575 | * represents its (non-prefetchable) PCI memory resource. | ||
576 | * mem_resources[0] and mem_resources[2] refer to its PCI I/O and | ||
577 | * prefetchable PCI memory resources, respectively. | ||
578 | * For more details, see pci_setup_bridge() in setup-bus.c. | ||
579 | * By comparing the target PCI memory address against the | ||
580 | * end address of controller 0, we can determine the controller | ||
581 | * that should accept the PCI memory access. | ||
582 | */ | ||
583 | #define TILE_READ(size, type) \ | ||
584 | type _tile_read##size(unsigned long addr) \ | ||
585 | { \ | ||
586 | type val; \ | ||
587 | int idx = 0; \ | ||
588 | if (addr > controllers[0].mem_resources[1].end && \ | ||
589 | addr > controllers[0].mem_resources[2].end) \ | ||
590 | idx = 1; \ | ||
591 | if (hv_dev_pread(controllers[idx].hv_mem_fd, 0, \ | ||
592 | (HV_VirtAddr)(&val), sizeof(type), addr)) \ | ||
593 | pr_err("PCI: read %zd bytes at 0x%lX failed\n", \ | ||
594 | sizeof(type), addr); \ | ||
595 | return val; \ | ||
596 | } \ | ||
597 | EXPORT_SYMBOL(_tile_read##size) | ||
598 | |||
599 | TILE_READ(b, u8); | ||
600 | TILE_READ(w, u16); | ||
601 | TILE_READ(l, u32); | ||
602 | TILE_READ(q, u64); | ||
603 | |||
604 | #define TILE_WRITE(size, type) \ | ||
605 | void _tile_write##size(type val, unsigned long addr) \ | ||
606 | { \ | ||
607 | int idx = 0; \ | ||
608 | if (addr > controllers[0].mem_resources[1].end && \ | ||
609 | addr > controllers[0].mem_resources[2].end) \ | ||
610 | idx = 1; \ | ||
611 | if (hv_dev_pwrite(controllers[idx].hv_mem_fd, 0, \ | ||
612 | (HV_VirtAddr)(&val), sizeof(type), addr)) \ | ||
613 | pr_err("PCI: write %zd bytes at 0x%lX failed\n", \ | ||
614 | sizeof(type), addr); \ | ||
615 | } \ | ||
616 | EXPORT_SYMBOL(_tile_write##size) | ||
617 | |||
618 | TILE_WRITE(b, u8); | ||
619 | TILE_WRITE(w, u16); | ||
620 | TILE_WRITE(l, u32); | ||
621 | TILE_WRITE(q, u64); | ||
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index fb0b3cbeae14..f18573643ed1 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c | |||
@@ -840,7 +840,7 @@ static int __init topology_init(void) | |||
840 | for_each_online_node(i) | 840 | for_each_online_node(i) |
841 | register_one_node(i); | 841 | register_one_node(i); |
842 | 842 | ||
843 | for_each_present_cpu(i) | 843 | for (i = 0; i < smp_height * smp_width; ++i) |
844 | register_cpu(&cpu_devices[i], i); | 844 | register_cpu(&cpu_devices[i], i); |
845 | 845 | ||
846 | return 0; | 846 | return 0; |
diff --git a/arch/tile/lib/memchr_32.c b/arch/tile/lib/memchr_32.c index 6235283b4859..cc3d9badf030 100644 --- a/arch/tile/lib/memchr_32.c +++ b/arch/tile/lib/memchr_32.c | |||
@@ -18,12 +18,24 @@ | |||
18 | 18 | ||
19 | void *memchr(const void *s, int c, size_t n) | 19 | void *memchr(const void *s, int c, size_t n) |
20 | { | 20 | { |
21 | const uint32_t *last_word_ptr; | ||
22 | const uint32_t *p; | ||
23 | const char *last_byte_ptr; | ||
24 | uintptr_t s_int; | ||
25 | uint32_t goal, before_mask, v, bits; | ||
26 | char *ret; | ||
27 | |||
28 | if (__builtin_expect(n == 0, 0)) { | ||
29 | /* Don't dereference any memory if the array is empty. */ | ||
30 | return NULL; | ||
31 | } | ||
32 | |||
21 | /* Get an aligned pointer. */ | 33 | /* Get an aligned pointer. */ |
22 | const uintptr_t s_int = (uintptr_t) s; | 34 | s_int = (uintptr_t) s; |
23 | const uint32_t *p = (const uint32_t *)(s_int & -4); | 35 | p = (const uint32_t *)(s_int & -4); |
24 | 36 | ||
25 | /* Create four copies of the byte for which we are looking. */ | 37 | /* Create four copies of the byte for which we are looking. */ |
26 | const uint32_t goal = 0x01010101 * (uint8_t) c; | 38 | goal = 0x01010101 * (uint8_t) c; |
27 | 39 | ||
28 | /* Read the first word, but munge it so that bytes before the array | 40 | /* Read the first word, but munge it so that bytes before the array |
29 | * will not match goal. | 41 | * will not match goal. |
@@ -31,23 +43,14 @@ void *memchr(const void *s, int c, size_t n) | |||
31 | * Note that this shift count expression works because we know | 43 | * Note that this shift count expression works because we know |
32 | * shift counts are taken mod 32. | 44 | * shift counts are taken mod 32. |
33 | */ | 45 | */ |
34 | const uint32_t before_mask = (1 << (s_int << 3)) - 1; | 46 | before_mask = (1 << (s_int << 3)) - 1; |
35 | uint32_t v = (*p | before_mask) ^ (goal & before_mask); | 47 | v = (*p | before_mask) ^ (goal & before_mask); |
36 | 48 | ||
37 | /* Compute the address of the last byte. */ | 49 | /* Compute the address of the last byte. */ |
38 | const char *const last_byte_ptr = (const char *)s + n - 1; | 50 | last_byte_ptr = (const char *)s + n - 1; |
39 | 51 | ||
40 | /* Compute the address of the word containing the last byte. */ | 52 | /* Compute the address of the word containing the last byte. */ |
41 | const uint32_t *const last_word_ptr = | 53 | last_word_ptr = (const uint32_t *)((uintptr_t) last_byte_ptr & -4); |
42 | (const uint32_t *)((uintptr_t) last_byte_ptr & -4); | ||
43 | |||
44 | uint32_t bits; | ||
45 | char *ret; | ||
46 | |||
47 | if (__builtin_expect(n == 0, 0)) { | ||
48 | /* Don't dereference any memory if the array is empty. */ | ||
49 | return NULL; | ||
50 | } | ||
51 | 54 | ||
52 | while ((bits = __insn_seqb(v, goal)) == 0) { | 55 | while ((bits = __insn_seqb(v, goal)) == 0) { |
53 | if (__builtin_expect(p == last_word_ptr, 0)) { | 56 | if (__builtin_expect(p == last_word_ptr, 0)) { |
diff --git a/arch/tile/lib/spinlock_32.c b/arch/tile/lib/spinlock_32.c index 485e24d62c6b..5cd1c4004eca 100644 --- a/arch/tile/lib/spinlock_32.c +++ b/arch/tile/lib/spinlock_32.c | |||
@@ -167,23 +167,30 @@ void arch_write_lock_slow(arch_rwlock_t *rwlock, u32 val) | |||
167 | * when we compare them. | 167 | * when we compare them. |
168 | */ | 168 | */ |
169 | u32 my_ticket_; | 169 | u32 my_ticket_; |
170 | u32 iterations = 0; | ||
170 | 171 | ||
171 | /* Take out the next ticket; this will also stop would-be readers. */ | 172 | /* |
172 | if (val & 1) | 173 | * Wait until there are no readers, then bump up the next |
173 | val = get_rwlock(rwlock); | 174 | * field and capture the ticket value. |
174 | rwlock->lock = __insn_addb(val, 1 << WR_NEXT_SHIFT); | 175 | */ |
176 | for (;;) { | ||
177 | if (!(val & 1)) { | ||
178 | if ((val >> RD_COUNT_SHIFT) == 0) | ||
179 | break; | ||
180 | rwlock->lock = val; | ||
181 | } | ||
182 | delay_backoff(iterations++); | ||
183 | val = __insn_tns((int *)&rwlock->lock); | ||
184 | } | ||
175 | 185 | ||
176 | /* Extract my ticket value from the original word. */ | 186 | /* Take out the next ticket and extract my ticket value. */ |
187 | rwlock->lock = __insn_addb(val, 1 << WR_NEXT_SHIFT); | ||
177 | my_ticket_ = val >> WR_NEXT_SHIFT; | 188 | my_ticket_ = val >> WR_NEXT_SHIFT; |
178 | 189 | ||
179 | /* | 190 | /* Wait until the "current" field matches our ticket. */ |
180 | * Wait until the "current" field matches our ticket, and | ||
181 | * there are no remaining readers. | ||
182 | */ | ||
183 | for (;;) { | 191 | for (;;) { |
184 | u32 curr_ = val >> WR_CURR_SHIFT; | 192 | u32 curr_ = val >> WR_CURR_SHIFT; |
185 | u32 readers = val >> RD_COUNT_SHIFT; | 193 | u32 delta = ((my_ticket_ - curr_) & WR_MASK); |
186 | u32 delta = ((my_ticket_ - curr_) & WR_MASK) + !!readers; | ||
187 | if (likely(delta == 0)) | 194 | if (likely(delta == 0)) |
188 | break; | 195 | break; |
189 | 196 | ||
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 7f7338c90784..1664cce7b0ac 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -727,6 +727,9 @@ struct winch { | |||
727 | 727 | ||
728 | static void free_winch(struct winch *winch, int free_irq_ok) | 728 | static void free_winch(struct winch *winch, int free_irq_ok) |
729 | { | 729 | { |
730 | if (free_irq_ok) | ||
731 | free_irq(WINCH_IRQ, winch); | ||
732 | |||
730 | list_del(&winch->list); | 733 | list_del(&winch->list); |
731 | 734 | ||
732 | if (winch->pid != -1) | 735 | if (winch->pid != -1) |
@@ -735,8 +738,6 @@ static void free_winch(struct winch *winch, int free_irq_ok) | |||
735 | os_close_file(winch->fd); | 738 | os_close_file(winch->fd); |
736 | if (winch->stack != 0) | 739 | if (winch->stack != 0) |
737 | free_stack(winch->stack, 0); | 740 | free_stack(winch->stack, 0); |
738 | if (free_irq_ok) | ||
739 | free_irq(WINCH_IRQ, winch); | ||
740 | kfree(winch); | 741 | kfree(winch); |
741 | } | 742 | } |
742 | 743 | ||
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index 4d293dced62f..9479a037419f 100644 --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h | |||
@@ -216,8 +216,8 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | /* Return an pointer with offset calculated */ | 218 | /* Return an pointer with offset calculated */ |
219 | static inline unsigned long __set_fixmap_offset(enum fixed_addresses idx, | 219 | static __always_inline unsigned long |
220 | phys_addr_t phys, pgprot_t flags) | 220 | __set_fixmap_offset(enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags) |
221 | { | 221 | { |
222 | __set_fixmap(idx, phys, flags); | 222 | __set_fixmap(idx, phys, flags); |
223 | return fix_to_virt(idx) + (phys & (PAGE_SIZE - 1)); | 223 | return fix_to_virt(idx) + (phys & (PAGE_SIZE - 1)); |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 7250bef7f49e..02c710bebf7a 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -1200,8 +1200,6 @@ asmlinkage void __init xen_start_kernel(void) | |||
1200 | /* Allocate and initialize top and mid mfn levels for p2m structure */ | 1200 | /* Allocate and initialize top and mid mfn levels for p2m structure */ |
1201 | xen_build_mfn_list_list(); | 1201 | xen_build_mfn_list_list(); |
1202 | 1202 | ||
1203 | init_mm.pgd = pgd; | ||
1204 | |||
1205 | /* keep using Xen gdt for now; no urgent need to change it */ | 1203 | /* keep using Xen gdt for now; no urgent need to change it */ |
1206 | 1204 | ||
1207 | #ifdef CONFIG_X86_32 | 1205 | #ifdef CONFIG_X86_32 |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 790af908284e..a1feff9e59b6 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -2133,44 +2133,83 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, | |||
2133 | return pgd; | 2133 | return pgd; |
2134 | } | 2134 | } |
2135 | #else /* !CONFIG_X86_64 */ | 2135 | #else /* !CONFIG_X86_64 */ |
2136 | static RESERVE_BRK_ARRAY(pmd_t, level2_kernel_pgt, PTRS_PER_PMD); | 2136 | static RESERVE_BRK_ARRAY(pmd_t, initial_kernel_pmd, PTRS_PER_PMD); |
2137 | static RESERVE_BRK_ARRAY(pmd_t, swapper_kernel_pmd, PTRS_PER_PMD); | ||
2138 | |||
2139 | static __init void xen_write_cr3_init(unsigned long cr3) | ||
2140 | { | ||
2141 | unsigned long pfn = PFN_DOWN(__pa(swapper_pg_dir)); | ||
2142 | |||
2143 | BUG_ON(read_cr3() != __pa(initial_page_table)); | ||
2144 | BUG_ON(cr3 != __pa(swapper_pg_dir)); | ||
2145 | |||
2146 | /* | ||
2147 | * We are switching to swapper_pg_dir for the first time (from | ||
2148 | * initial_page_table) and therefore need to mark that page | ||
2149 | * read-only and then pin it. | ||
2150 | * | ||
2151 | * Xen disallows sharing of kernel PMDs for PAE | ||
2152 | * guests. Therefore we must copy the kernel PMD from | ||
2153 | * initial_page_table into a new kernel PMD to be used in | ||
2154 | * swapper_pg_dir. | ||
2155 | */ | ||
2156 | swapper_kernel_pmd = | ||
2157 | extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE); | ||
2158 | memcpy(swapper_kernel_pmd, initial_kernel_pmd, | ||
2159 | sizeof(pmd_t) * PTRS_PER_PMD); | ||
2160 | swapper_pg_dir[KERNEL_PGD_BOUNDARY] = | ||
2161 | __pgd(__pa(swapper_kernel_pmd) | _PAGE_PRESENT); | ||
2162 | set_page_prot(swapper_kernel_pmd, PAGE_KERNEL_RO); | ||
2163 | |||
2164 | set_page_prot(swapper_pg_dir, PAGE_KERNEL_RO); | ||
2165 | xen_write_cr3(cr3); | ||
2166 | pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, pfn); | ||
2167 | |||
2168 | pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, | ||
2169 | PFN_DOWN(__pa(initial_page_table))); | ||
2170 | set_page_prot(initial_page_table, PAGE_KERNEL); | ||
2171 | set_page_prot(initial_kernel_pmd, PAGE_KERNEL); | ||
2172 | |||
2173 | pv_mmu_ops.write_cr3 = &xen_write_cr3; | ||
2174 | } | ||
2137 | 2175 | ||
2138 | __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, | 2176 | __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, |
2139 | unsigned long max_pfn) | 2177 | unsigned long max_pfn) |
2140 | { | 2178 | { |
2141 | pmd_t *kernel_pmd; | 2179 | pmd_t *kernel_pmd; |
2142 | 2180 | ||
2143 | level2_kernel_pgt = extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE); | 2181 | initial_kernel_pmd = |
2182 | extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE); | ||
2144 | 2183 | ||
2145 | max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) + | 2184 | max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) + |
2146 | xen_start_info->nr_pt_frames * PAGE_SIZE + | 2185 | xen_start_info->nr_pt_frames * PAGE_SIZE + |
2147 | 512*1024); | 2186 | 512*1024); |
2148 | 2187 | ||
2149 | kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd); | 2188 | kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd); |
2150 | memcpy(level2_kernel_pgt, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD); | 2189 | memcpy(initial_kernel_pmd, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD); |
2151 | 2190 | ||
2152 | xen_map_identity_early(level2_kernel_pgt, max_pfn); | 2191 | xen_map_identity_early(initial_kernel_pmd, max_pfn); |
2153 | 2192 | ||
2154 | memcpy(swapper_pg_dir, pgd, sizeof(pgd_t) * PTRS_PER_PGD); | 2193 | memcpy(initial_page_table, pgd, sizeof(pgd_t) * PTRS_PER_PGD); |
2155 | set_pgd(&swapper_pg_dir[KERNEL_PGD_BOUNDARY], | 2194 | initial_page_table[KERNEL_PGD_BOUNDARY] = |
2156 | __pgd(__pa(level2_kernel_pgt) | _PAGE_PRESENT)); | 2195 | __pgd(__pa(initial_kernel_pmd) | _PAGE_PRESENT); |
2157 | 2196 | ||
2158 | set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO); | 2197 | set_page_prot(initial_kernel_pmd, PAGE_KERNEL_RO); |
2159 | set_page_prot(swapper_pg_dir, PAGE_KERNEL_RO); | 2198 | set_page_prot(initial_page_table, PAGE_KERNEL_RO); |
2160 | set_page_prot(empty_zero_page, PAGE_KERNEL_RO); | 2199 | set_page_prot(empty_zero_page, PAGE_KERNEL_RO); |
2161 | 2200 | ||
2162 | pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd))); | 2201 | pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd))); |
2163 | 2202 | ||
2164 | xen_write_cr3(__pa(swapper_pg_dir)); | 2203 | pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, |
2165 | 2204 | PFN_DOWN(__pa(initial_page_table))); | |
2166 | pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(swapper_pg_dir))); | 2205 | xen_write_cr3(__pa(initial_page_table)); |
2167 | 2206 | ||
2168 | memblock_x86_reserve_range(__pa(xen_start_info->pt_base), | 2207 | memblock_x86_reserve_range(__pa(xen_start_info->pt_base), |
2169 | __pa(xen_start_info->pt_base + | 2208 | __pa(xen_start_info->pt_base + |
2170 | xen_start_info->nr_pt_frames * PAGE_SIZE), | 2209 | xen_start_info->nr_pt_frames * PAGE_SIZE), |
2171 | "XEN PAGETABLES"); | 2210 | "XEN PAGETABLES"); |
2172 | 2211 | ||
2173 | return swapper_pg_dir; | 2212 | return initial_page_table; |
2174 | } | 2213 | } |
2175 | #endif /* CONFIG_X86_64 */ | 2214 | #endif /* CONFIG_X86_64 */ |
2176 | 2215 | ||
@@ -2304,7 +2343,11 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = { | |||
2304 | .write_cr2 = xen_write_cr2, | 2343 | .write_cr2 = xen_write_cr2, |
2305 | 2344 | ||
2306 | .read_cr3 = xen_read_cr3, | 2345 | .read_cr3 = xen_read_cr3, |
2346 | #ifdef CONFIG_X86_32 | ||
2347 | .write_cr3 = xen_write_cr3_init, | ||
2348 | #else | ||
2307 | .write_cr3 = xen_write_cr3, | 2349 | .write_cr3 = xen_write_cr3, |
2350 | #endif | ||
2308 | 2351 | ||
2309 | .flush_tlb_user = xen_flush_tlb, | 2352 | .flush_tlb_user = xen_flush_tlb, |
2310 | .flush_tlb_kernel = xen_flush_tlb, | 2353 | .flush_tlb_kernel = xen_flush_tlb, |
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 38fdffaa71d3..01afd8a94607 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <xen/interface/callback.h> | 23 | #include <xen/interface/callback.h> |
24 | #include <xen/interface/memory.h> | 24 | #include <xen/interface/memory.h> |
25 | #include <xen/interface/physdev.h> | 25 | #include <xen/interface/physdev.h> |
26 | #include <xen/interface/memory.h> | ||
27 | #include <xen/features.h> | 26 | #include <xen/features.h> |
28 | 27 | ||
29 | #include "xen-ops.h" | 28 | #include "xen-ops.h" |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 6c1b676643a9..896a2ced1d27 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -1547,31 +1547,16 @@ static int init_vqs(struct ports_device *portdev) | |||
1547 | nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2; | 1547 | nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2; |
1548 | 1548 | ||
1549 | vqs = kmalloc(nr_queues * sizeof(struct virtqueue *), GFP_KERNEL); | 1549 | vqs = kmalloc(nr_queues * sizeof(struct virtqueue *), GFP_KERNEL); |
1550 | if (!vqs) { | ||
1551 | err = -ENOMEM; | ||
1552 | goto fail; | ||
1553 | } | ||
1554 | io_callbacks = kmalloc(nr_queues * sizeof(vq_callback_t *), GFP_KERNEL); | 1550 | io_callbacks = kmalloc(nr_queues * sizeof(vq_callback_t *), GFP_KERNEL); |
1555 | if (!io_callbacks) { | ||
1556 | err = -ENOMEM; | ||
1557 | goto free_vqs; | ||
1558 | } | ||
1559 | io_names = kmalloc(nr_queues * sizeof(char *), GFP_KERNEL); | 1551 | io_names = kmalloc(nr_queues * sizeof(char *), GFP_KERNEL); |
1560 | if (!io_names) { | ||
1561 | err = -ENOMEM; | ||
1562 | goto free_callbacks; | ||
1563 | } | ||
1564 | portdev->in_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *), | 1552 | portdev->in_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *), |
1565 | GFP_KERNEL); | 1553 | GFP_KERNEL); |
1566 | if (!portdev->in_vqs) { | ||
1567 | err = -ENOMEM; | ||
1568 | goto free_names; | ||
1569 | } | ||
1570 | portdev->out_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *), | 1554 | portdev->out_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *), |
1571 | GFP_KERNEL); | 1555 | GFP_KERNEL); |
1572 | if (!portdev->out_vqs) { | 1556 | if (!vqs || !io_callbacks || !io_names || !portdev->in_vqs || |
1557 | !portdev->out_vqs) { | ||
1573 | err = -ENOMEM; | 1558 | err = -ENOMEM; |
1574 | goto free_invqs; | 1559 | goto free; |
1575 | } | 1560 | } |
1576 | 1561 | ||
1577 | /* | 1562 | /* |
@@ -1605,7 +1590,7 @@ static int init_vqs(struct ports_device *portdev) | |||
1605 | io_callbacks, | 1590 | io_callbacks, |
1606 | (const char **)io_names); | 1591 | (const char **)io_names); |
1607 | if (err) | 1592 | if (err) |
1608 | goto free_outvqs; | 1593 | goto free; |
1609 | 1594 | ||
1610 | j = 0; | 1595 | j = 0; |
1611 | portdev->in_vqs[0] = vqs[0]; | 1596 | portdev->in_vqs[0] = vqs[0]; |
@@ -1621,23 +1606,19 @@ static int init_vqs(struct ports_device *portdev) | |||
1621 | portdev->out_vqs[i] = vqs[j + 1]; | 1606 | portdev->out_vqs[i] = vqs[j + 1]; |
1622 | } | 1607 | } |
1623 | } | 1608 | } |
1624 | kfree(io_callbacks); | ||
1625 | kfree(io_names); | 1609 | kfree(io_names); |
1610 | kfree(io_callbacks); | ||
1626 | kfree(vqs); | 1611 | kfree(vqs); |
1627 | 1612 | ||
1628 | return 0; | 1613 | return 0; |
1629 | 1614 | ||
1630 | free_names: | 1615 | free: |
1631 | kfree(io_names); | ||
1632 | free_callbacks: | ||
1633 | kfree(io_callbacks); | ||
1634 | free_outvqs: | ||
1635 | kfree(portdev->out_vqs); | 1616 | kfree(portdev->out_vqs); |
1636 | free_invqs: | ||
1637 | kfree(portdev->in_vqs); | 1617 | kfree(portdev->in_vqs); |
1638 | free_vqs: | 1618 | kfree(io_names); |
1619 | kfree(io_callbacks); | ||
1639 | kfree(vqs); | 1620 | kfree(vqs); |
1640 | fail: | 1621 | |
1641 | return err; | 1622 | return err; |
1642 | } | 1623 | } |
1643 | 1624 | ||
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index 937983407e2a..c4c40be0edbf 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c | |||
@@ -497,12 +497,14 @@ static unsigned long chipset_ids[] = { | |||
497 | 0 | 497 | 0 |
498 | }; | 498 | }; |
499 | 499 | ||
500 | #ifdef MODULE | ||
500 | static struct pci_device_id i5k_amb_ids[] __devinitdata = { | 501 | static struct pci_device_id i5k_amb_ids[] __devinitdata = { |
501 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) }, | 502 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) }, |
502 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR) }, | 503 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR) }, |
503 | { 0, } | 504 | { 0, } |
504 | }; | 505 | }; |
505 | MODULE_DEVICE_TABLE(pci, i5k_amb_ids); | 506 | MODULE_DEVICE_TABLE(pci, i5k_amb_ids); |
507 | #endif | ||
506 | 508 | ||
507 | static int __devinit i5k_amb_probe(struct platform_device *pdev) | 509 | static int __devinit i5k_amb_probe(struct platform_device *pdev) |
508 | { | 510 | { |
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c index 9f4bae07f719..8853afce85ce 100644 --- a/drivers/hwmon/lis3lv02d_i2c.c +++ b/drivers/hwmon/lis3lv02d_i2c.c | |||
@@ -186,7 +186,7 @@ static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client) | |||
186 | return 0; | 186 | return 0; |
187 | } | 187 | } |
188 | 188 | ||
189 | #ifdef CONFIG_PM | 189 | #ifdef CONFIG_PM_SLEEP |
190 | static int lis3lv02d_i2c_suspend(struct device *dev) | 190 | static int lis3lv02d_i2c_suspend(struct device *dev) |
191 | { | 191 | { |
192 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); | 192 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); |
@@ -213,12 +213,9 @@ static int lis3lv02d_i2c_resume(struct device *dev) | |||
213 | 213 | ||
214 | return 0; | 214 | return 0; |
215 | } | 215 | } |
216 | #else | 216 | #endif /* CONFIG_PM_SLEEP */ |
217 | #define lis3lv02d_i2c_suspend NULL | ||
218 | #define lis3lv02d_i2c_resume NULL | ||
219 | #define lis3lv02d_i2c_shutdown NULL | ||
220 | #endif | ||
221 | 217 | ||
218 | #ifdef CONFIG_PM_RUNTIME | ||
222 | static int lis3_i2c_runtime_suspend(struct device *dev) | 219 | static int lis3_i2c_runtime_suspend(struct device *dev) |
223 | { | 220 | { |
224 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); | 221 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); |
@@ -236,6 +233,7 @@ static int lis3_i2c_runtime_resume(struct device *dev) | |||
236 | lis3lv02d_poweron(lis3); | 233 | lis3lv02d_poweron(lis3); |
237 | return 0; | 234 | return 0; |
238 | } | 235 | } |
236 | #endif /* CONFIG_PM_RUNTIME */ | ||
239 | 237 | ||
240 | static const struct i2c_device_id lis3lv02d_id[] = { | 238 | static const struct i2c_device_id lis3lv02d_id[] = { |
241 | {"lis3lv02d", 0 }, | 239 | {"lis3lv02d", 0 }, |
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c index 3782f31f06d2..33facd0c45d1 100644 --- a/drivers/leds/leds-lp5521.c +++ b/drivers/leds/leds-lp5521.c | |||
@@ -125,11 +125,22 @@ struct lp5521_chip { | |||
125 | u8 num_leds; | 125 | u8 num_leds; |
126 | }; | 126 | }; |
127 | 127 | ||
128 | #define cdev_to_led(c) container_of(c, struct lp5521_led, cdev) | 128 | static inline struct lp5521_led *cdev_to_led(struct led_classdev *cdev) |
129 | #define engine_to_lp5521(eng) container_of((eng), struct lp5521_chip, \ | 129 | { |
130 | engines[(eng)->id - 1]) | 130 | return container_of(cdev, struct lp5521_led, cdev); |
131 | #define led_to_lp5521(led) container_of((led), struct lp5521_chip, \ | 131 | } |
132 | leds[(led)->id]) | 132 | |
133 | static inline struct lp5521_chip *engine_to_lp5521(struct lp5521_engine *engine) | ||
134 | { | ||
135 | return container_of(engine, struct lp5521_chip, | ||
136 | engines[engine->id - 1]); | ||
137 | } | ||
138 | |||
139 | static inline struct lp5521_chip *led_to_lp5521(struct lp5521_led *led) | ||
140 | { | ||
141 | return container_of(led, struct lp5521_chip, | ||
142 | leds[led->id]); | ||
143 | } | ||
133 | 144 | ||
134 | static void lp5521_led_brightness_work(struct work_struct *work); | 145 | static void lp5521_led_brightness_work(struct work_struct *work); |
135 | 146 | ||
@@ -185,14 +196,17 @@ static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern) | |||
185 | 196 | ||
186 | /* move current engine to direct mode and remember the state */ | 197 | /* move current engine to direct mode and remember the state */ |
187 | ret = lp5521_set_engine_mode(eng, LP5521_CMD_DIRECT); | 198 | ret = lp5521_set_engine_mode(eng, LP5521_CMD_DIRECT); |
188 | usleep_range(1000, 10000); | 199 | /* Mode change requires min 500 us delay. 1 - 2 ms with margin */ |
200 | usleep_range(1000, 2000); | ||
189 | ret |= lp5521_read(client, LP5521_REG_OP_MODE, &mode); | 201 | ret |= lp5521_read(client, LP5521_REG_OP_MODE, &mode); |
190 | 202 | ||
191 | /* For loading, all the engines to load mode */ | 203 | /* For loading, all the engines to load mode */ |
192 | lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT); | 204 | lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT); |
193 | usleep_range(1000, 10000); | 205 | /* Mode change requires min 500 us delay. 1 - 2 ms with margin */ |
206 | usleep_range(1000, 2000); | ||
194 | lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_LOAD); | 207 | lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_LOAD); |
195 | usleep_range(1000, 10000); | 208 | /* Mode change requires min 500 us delay. 1 - 2 ms with margin */ |
209 | usleep_range(1000, 2000); | ||
196 | 210 | ||
197 | addr = LP5521_PROG_MEM_BASE + eng->prog_page * LP5521_PROG_MEM_SIZE; | 211 | addr = LP5521_PROG_MEM_BASE + eng->prog_page * LP5521_PROG_MEM_SIZE; |
198 | i2c_smbus_write_i2c_block_data(client, | 212 | i2c_smbus_write_i2c_block_data(client, |
@@ -231,10 +245,6 @@ static int lp5521_configure(struct i2c_client *client, | |||
231 | 245 | ||
232 | lp5521_init_engine(chip, attr_group); | 246 | lp5521_init_engine(chip, attr_group); |
233 | 247 | ||
234 | lp5521_write(client, LP5521_REG_RESET, 0xff); | ||
235 | |||
236 | usleep_range(10000, 20000); | ||
237 | |||
238 | /* Set all PWMs to direct control mode */ | 248 | /* Set all PWMs to direct control mode */ |
239 | ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F); | 249 | ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F); |
240 | 250 | ||
@@ -251,8 +261,8 @@ static int lp5521_configure(struct i2c_client *client, | |||
251 | ret |= lp5521_write(client, LP5521_REG_ENABLE, | 261 | ret |= lp5521_write(client, LP5521_REG_ENABLE, |
252 | LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM | | 262 | LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM | |
253 | LP5521_EXEC_RUN); | 263 | LP5521_EXEC_RUN); |
254 | /* enable takes 500us */ | 264 | /* enable takes 500us. 1 - 2 ms leaves some margin */ |
255 | usleep_range(500, 20000); | 265 | usleep_range(1000, 2000); |
256 | 266 | ||
257 | return ret; | 267 | return ret; |
258 | } | 268 | } |
@@ -305,7 +315,8 @@ static int lp5521_detect(struct i2c_client *client) | |||
305 | LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM); | 315 | LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM); |
306 | if (ret) | 316 | if (ret) |
307 | return ret; | 317 | return ret; |
308 | usleep_range(1000, 10000); | 318 | /* enable takes 500us. 1 - 2 ms leaves some margin */ |
319 | usleep_range(1000, 2000); | ||
309 | ret = lp5521_read(client, LP5521_REG_ENABLE, &buf); | 320 | ret = lp5521_read(client, LP5521_REG_ENABLE, &buf); |
310 | if (ret) | 321 | if (ret) |
311 | return ret; | 322 | return ret; |
@@ -693,11 +704,16 @@ static int lp5521_probe(struct i2c_client *client, | |||
693 | 704 | ||
694 | if (pdata->enable) { | 705 | if (pdata->enable) { |
695 | pdata->enable(0); | 706 | pdata->enable(0); |
696 | usleep_range(1000, 10000); | 707 | usleep_range(1000, 2000); /* Keep enable down at least 1ms */ |
697 | pdata->enable(1); | 708 | pdata->enable(1); |
698 | usleep_range(1000, 10000); /* Spec says min 500us */ | 709 | usleep_range(1000, 2000); /* 500us abs min. */ |
699 | } | 710 | } |
700 | 711 | ||
712 | lp5521_write(client, LP5521_REG_RESET, 0xff); | ||
713 | usleep_range(10000, 20000); /* | ||
714 | * Exact value is not available. 10 - 20ms | ||
715 | * appears to be enough for reset. | ||
716 | */ | ||
701 | ret = lp5521_detect(client); | 717 | ret = lp5521_detect(client); |
702 | 718 | ||
703 | if (ret) { | 719 | if (ret) { |
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c index 1e11fcc08b28..0cc4ead2fd8b 100644 --- a/drivers/leds/leds-lp5523.c +++ b/drivers/leds/leds-lp5523.c | |||
@@ -134,15 +134,18 @@ struct lp5523_chip { | |||
134 | u8 num_leds; | 134 | u8 num_leds; |
135 | }; | 135 | }; |
136 | 136 | ||
137 | #define cdev_to_led(c) container_of(c, struct lp5523_led, cdev) | 137 | static inline struct lp5523_led *cdev_to_led(struct led_classdev *cdev) |
138 | { | ||
139 | return container_of(cdev, struct lp5523_led, cdev); | ||
140 | } | ||
138 | 141 | ||
139 | static struct lp5523_chip *engine_to_lp5523(struct lp5523_engine *engine) | 142 | static inline struct lp5523_chip *engine_to_lp5523(struct lp5523_engine *engine) |
140 | { | 143 | { |
141 | return container_of(engine, struct lp5523_chip, | 144 | return container_of(engine, struct lp5523_chip, |
142 | engines[engine->id - 1]); | 145 | engines[engine->id - 1]); |
143 | } | 146 | } |
144 | 147 | ||
145 | static struct lp5523_chip *led_to_lp5523(struct lp5523_led *led) | 148 | static inline struct lp5523_chip *led_to_lp5523(struct lp5523_led *led) |
146 | { | 149 | { |
147 | return container_of(led, struct lp5523_chip, | 150 | return container_of(led, struct lp5523_chip, |
148 | leds[led->id]); | 151 | leds[led->id]); |
@@ -200,13 +203,9 @@ static int lp5523_configure(struct i2c_client *client) | |||
200 | { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0}, | 203 | { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0}, |
201 | }; | 204 | }; |
202 | 205 | ||
203 | lp5523_write(client, LP5523_REG_RESET, 0xff); | ||
204 | |||
205 | usleep_range(10000, 100000); | ||
206 | |||
207 | ret |= lp5523_write(client, LP5523_REG_ENABLE, LP5523_ENABLE); | 206 | ret |= lp5523_write(client, LP5523_REG_ENABLE, LP5523_ENABLE); |
208 | /* Chip startup time after reset is 500 us */ | 207 | /* Chip startup time is 500 us, 1 - 2 ms gives some margin */ |
209 | usleep_range(1000, 10000); | 208 | usleep_range(1000, 2000); |
210 | 209 | ||
211 | ret |= lp5523_write(client, LP5523_REG_CONFIG, | 210 | ret |= lp5523_write(client, LP5523_REG_CONFIG, |
212 | LP5523_AUTO_INC | LP5523_PWR_SAVE | | 211 | LP5523_AUTO_INC | LP5523_PWR_SAVE | |
@@ -243,8 +242,8 @@ static int lp5523_configure(struct i2c_client *client) | |||
243 | return -1; | 242 | return -1; |
244 | } | 243 | } |
245 | 244 | ||
246 | /* Wait 3ms and check the engine status */ | 245 | /* Let the programs run for couple of ms and check the engine status */ |
247 | usleep_range(3000, 20000); | 246 | usleep_range(3000, 6000); |
248 | lp5523_read(client, LP5523_REG_STATUS, &status); | 247 | lp5523_read(client, LP5523_REG_STATUS, &status); |
249 | status &= LP5523_ENG_STATUS_MASK; | 248 | status &= LP5523_ENG_STATUS_MASK; |
250 | 249 | ||
@@ -449,10 +448,10 @@ static ssize_t lp5523_selftest(struct device *dev, | |||
449 | /* Measure VDD (i.e. VBAT) first (channel 16 corresponds to VDD) */ | 448 | /* Measure VDD (i.e. VBAT) first (channel 16 corresponds to VDD) */ |
450 | lp5523_write(chip->client, LP5523_REG_LED_TEST_CTRL, | 449 | lp5523_write(chip->client, LP5523_REG_LED_TEST_CTRL, |
451 | LP5523_EN_LEDTEST | 16); | 450 | LP5523_EN_LEDTEST | 16); |
452 | usleep_range(3000, 10000); | 451 | usleep_range(3000, 6000); /* ADC conversion time is typically 2.7 ms */ |
453 | ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); | 452 | ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); |
454 | if (!(status & LP5523_LEDTEST_DONE)) | 453 | if (!(status & LP5523_LEDTEST_DONE)) |
455 | usleep_range(3000, 10000); | 454 | usleep_range(3000, 6000); /* Was not ready. Wait little bit */ |
456 | 455 | ||
457 | ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &vdd); | 456 | ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &vdd); |
458 | vdd--; /* There may be some fluctuation in measurement */ | 457 | vdd--; /* There may be some fluctuation in measurement */ |
@@ -468,16 +467,16 @@ static ssize_t lp5523_selftest(struct device *dev, | |||
468 | chip->pdata->led_config[i].led_current); | 467 | chip->pdata->led_config[i].led_current); |
469 | 468 | ||
470 | lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0xff); | 469 | lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0xff); |
471 | /* let current stabilize 2ms before measurements start */ | 470 | /* let current stabilize 2 - 4ms before measurements start */ |
472 | usleep_range(2000, 10000); | 471 | usleep_range(2000, 4000); |
473 | lp5523_write(chip->client, | 472 | lp5523_write(chip->client, |
474 | LP5523_REG_LED_TEST_CTRL, | 473 | LP5523_REG_LED_TEST_CTRL, |
475 | LP5523_EN_LEDTEST | i); | 474 | LP5523_EN_LEDTEST | i); |
476 | /* ledtest takes 2.7ms */ | 475 | /* ADC conversion time is 2.7 ms typically */ |
477 | usleep_range(3000, 10000); | 476 | usleep_range(3000, 6000); |
478 | ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); | 477 | ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); |
479 | if (!(status & LP5523_LEDTEST_DONE)) | 478 | if (!(status & LP5523_LEDTEST_DONE)) |
480 | usleep_range(3000, 10000); | 479 | usleep_range(3000, 6000);/* Was not ready. Wait. */ |
481 | ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &adc); | 480 | ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &adc); |
482 | 481 | ||
483 | if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM) | 482 | if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM) |
@@ -930,11 +929,16 @@ static int lp5523_probe(struct i2c_client *client, | |||
930 | 929 | ||
931 | if (pdata->enable) { | 930 | if (pdata->enable) { |
932 | pdata->enable(0); | 931 | pdata->enable(0); |
933 | usleep_range(1000, 10000); | 932 | usleep_range(1000, 2000); /* Keep enable down at least 1ms */ |
934 | pdata->enable(1); | 933 | pdata->enable(1); |
935 | usleep_range(1000, 10000); /* Spec says min 500us */ | 934 | usleep_range(1000, 2000); /* 500us abs min. */ |
936 | } | 935 | } |
937 | 936 | ||
937 | lp5523_write(client, LP5523_REG_RESET, 0xff); | ||
938 | usleep_range(10000, 20000); /* | ||
939 | * Exact value is not available. 10 - 20ms | ||
940 | * appears to be enough for reset. | ||
941 | */ | ||
938 | ret = lp5523_detect(client); | 942 | ret = lp5523_detect(client); |
939 | if (ret) | 943 | if (ret) |
940 | goto fail2; | 944 | goto fail2; |
diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c index a688293abd0b..614ebebaaa28 100644 --- a/drivers/leds/leds-ss4200.c +++ b/drivers/leds/leds-ss4200.c | |||
@@ -102,6 +102,7 @@ static struct dmi_system_id __initdata nas_led_whitelist[] = { | |||
102 | DMI_MATCH(DMI_PRODUCT_VERSION, "1.00.00") | 102 | DMI_MATCH(DMI_PRODUCT_VERSION, "1.00.00") |
103 | } | 103 | } |
104 | }, | 104 | }, |
105 | {} | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | /* | 108 | /* |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 324a3663fcda..84c46a161927 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1337,7 +1337,7 @@ super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) | |||
1337 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, | 1337 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, |
1338 | rdev->sb_page); | 1338 | rdev->sb_page); |
1339 | md_super_wait(rdev->mddev); | 1339 | md_super_wait(rdev->mddev); |
1340 | return num_sectors / 2; /* kB for sysfs */ | 1340 | return num_sectors; |
1341 | } | 1341 | } |
1342 | 1342 | ||
1343 | 1343 | ||
@@ -1704,7 +1704,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) | |||
1704 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, | 1704 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, |
1705 | rdev->sb_page); | 1705 | rdev->sb_page); |
1706 | md_super_wait(rdev->mddev); | 1706 | md_super_wait(rdev->mddev); |
1707 | return num_sectors / 2; /* kB for sysfs */ | 1707 | return num_sectors; |
1708 | } | 1708 | } |
1709 | 1709 | ||
1710 | static struct super_type super_types[] = { | 1710 | static struct super_type super_types[] = { |
@@ -4338,6 +4338,8 @@ static int md_alloc(dev_t dev, char *name) | |||
4338 | if (mddev->kobj.sd && | 4338 | if (mddev->kobj.sd && |
4339 | sysfs_create_group(&mddev->kobj, &md_bitmap_group)) | 4339 | sysfs_create_group(&mddev->kobj, &md_bitmap_group)) |
4340 | printk(KERN_DEBUG "pointless warning\n"); | 4340 | printk(KERN_DEBUG "pointless warning\n"); |
4341 | |||
4342 | blk_queue_flush(mddev->queue, REQ_FLUSH | REQ_FUA); | ||
4341 | abort: | 4343 | abort: |
4342 | mutex_unlock(&disks_mutex); | 4344 | mutex_unlock(&disks_mutex); |
4343 | if (!error && mddev->kobj.sd) { | 4345 | if (!error && mddev->kobj.sd) { |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 45f8324196ec..845cf95b612c 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1161,6 +1161,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number) | |||
1161 | * is not possible. | 1161 | * is not possible. |
1162 | */ | 1162 | */ |
1163 | if (!test_bit(Faulty, &rdev->flags) && | 1163 | if (!test_bit(Faulty, &rdev->flags) && |
1164 | !mddev->recovery_disabled && | ||
1164 | mddev->degraded < conf->raid_disks) { | 1165 | mddev->degraded < conf->raid_disks) { |
1165 | err = -EBUSY; | 1166 | err = -EBUSY; |
1166 | goto abort; | 1167 | goto abort; |
diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c index ca47e6285075..307aada5fffe 100644 --- a/drivers/misc/isl29020.c +++ b/drivers/misc/isl29020.c | |||
@@ -183,9 +183,7 @@ static int isl29020_probe(struct i2c_client *client, | |||
183 | 183 | ||
184 | static int isl29020_remove(struct i2c_client *client) | 184 | static int isl29020_remove(struct i2c_client *client) |
185 | { | 185 | { |
186 | struct als_data *data = i2c_get_clientdata(client); | ||
187 | sysfs_remove_group(&client->dev.kobj, &m_als_gr); | 186 | sysfs_remove_group(&client->dev.kobj, &m_als_gr); |
188 | kfree(data); | ||
189 | return 0; | 187 | return 0; |
190 | } | 188 | } |
191 | 189 | ||
@@ -245,6 +243,6 @@ static void __exit sensor_isl29020_exit(void) | |||
245 | module_init(sensor_isl29020_init); | 243 | module_init(sensor_isl29020_init); |
246 | module_exit(sensor_isl29020_exit); | 244 | module_exit(sensor_isl29020_exit); |
247 | 245 | ||
248 | MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com"); | 246 | MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com>"); |
249 | MODULE_DESCRIPTION("Intersil isl29020 ALS Driver"); | 247 | MODULE_DESCRIPTION("Intersil isl29020 ALS Driver"); |
250 | MODULE_LICENSE("GPL v2"); | 248 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c index d551f09ccb79..6956f7e7d439 100644 --- a/drivers/misc/sgi-xp/xpc_partition.c +++ b/drivers/misc/sgi-xp/xpc_partition.c | |||
@@ -439,18 +439,23 @@ xpc_discovery(void) | |||
439 | * nodes that can comprise an access protection grouping. The access | 439 | * nodes that can comprise an access protection grouping. The access |
440 | * protection is in regards to memory, IOI and IPI. | 440 | * protection is in regards to memory, IOI and IPI. |
441 | */ | 441 | */ |
442 | max_regions = 64; | ||
443 | region_size = xp_region_size; | 442 | region_size = xp_region_size; |
444 | 443 | ||
445 | switch (region_size) { | 444 | if (is_uv()) |
446 | case 128: | 445 | max_regions = 256; |
447 | max_regions *= 2; | 446 | else { |
448 | case 64: | 447 | max_regions = 64; |
449 | max_regions *= 2; | 448 | |
450 | case 32: | 449 | switch (region_size) { |
451 | max_regions *= 2; | 450 | case 128: |
452 | region_size = 16; | 451 | max_regions *= 2; |
453 | DBUG_ON(!is_shub2()); | 452 | case 64: |
453 | max_regions *= 2; | ||
454 | case 32: | ||
455 | max_regions *= 2; | ||
456 | region_size = 16; | ||
457 | DBUG_ON(!is_shub2()); | ||
458 | } | ||
454 | } | 459 | } |
455 | 460 | ||
456 | for (region = 0; region < max_regions; region++) { | 461 | for (region = 0; region < max_regions; region++) { |
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index d618e8673996..859e352d0b5f 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -466,6 +466,12 @@ config MMC_SH_MMCIF | |||
466 | 466 | ||
467 | This driver supports MMCIF in sh7724/sh7757/sh7372. | 467 | This driver supports MMCIF in sh7724/sh7757/sh7372. |
468 | 468 | ||
469 | config SH_MMCIF_DMA | ||
470 | bool "Use DMA for MMCIF" | ||
471 | depends on MMC_SH_MMCIF | ||
472 | help | ||
473 | Use SH dma-engine driver for data transfer | ||
474 | |||
469 | config MMC_JZ4740 | 475 | config MMC_JZ4740 |
470 | tristate "JZ4740 SD/Multimedia Card Interface support" | 476 | tristate "JZ4740 SD/Multimedia Card Interface support" |
471 | depends on MACH_JZ4740 | 477 | depends on MACH_JZ4740 |
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index ddd09840520b..d09a2b38eeeb 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c | |||
@@ -16,16 +16,19 @@ | |||
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/clk.h> | ||
20 | #include <linux/completion.h> | ||
21 | #include <linux/delay.h> | ||
19 | #include <linux/dma-mapping.h> | 22 | #include <linux/dma-mapping.h> |
20 | #include <linux/mmc/host.h> | 23 | #include <linux/dmaengine.h> |
21 | #include <linux/mmc/card.h> | 24 | #include <linux/mmc/card.h> |
22 | #include <linux/mmc/core.h> | 25 | #include <linux/mmc/core.h> |
26 | #include <linux/mmc/host.h> | ||
23 | #include <linux/mmc/mmc.h> | 27 | #include <linux/mmc/mmc.h> |
24 | #include <linux/mmc/sdio.h> | 28 | #include <linux/mmc/sdio.h> |
25 | #include <linux/delay.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/clk.h> | ||
28 | #include <linux/mmc/sh_mmcif.h> | 29 | #include <linux/mmc/sh_mmcif.h> |
30 | #include <linux/pagemap.h> | ||
31 | #include <linux/platform_device.h> | ||
29 | 32 | ||
30 | #define DRIVER_NAME "sh_mmcif" | 33 | #define DRIVER_NAME "sh_mmcif" |
31 | #define DRIVER_VERSION "2010-04-28" | 34 | #define DRIVER_VERSION "2010-04-28" |
@@ -62,25 +65,6 @@ | |||
62 | /* CE_BLOCK_SET */ | 65 | /* CE_BLOCK_SET */ |
63 | #define BLOCK_SIZE_MASK 0x0000ffff | 66 | #define BLOCK_SIZE_MASK 0x0000ffff |
64 | 67 | ||
65 | /* CE_CLK_CTRL */ | ||
66 | #define CLK_ENABLE (1 << 24) /* 1: output mmc clock */ | ||
67 | #define CLK_CLEAR ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16)) | ||
68 | #define CLK_SUP_PCLK ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16)) | ||
69 | #define SRSPTO_256 ((1 << 13) | (0 << 12)) /* resp timeout */ | ||
70 | #define SRBSYTO_29 ((1 << 11) | (1 << 10) | \ | ||
71 | (1 << 9) | (1 << 8)) /* resp busy timeout */ | ||
72 | #define SRWDTO_29 ((1 << 7) | (1 << 6) | \ | ||
73 | (1 << 5) | (1 << 4)) /* read/write timeout */ | ||
74 | #define SCCSTO_29 ((1 << 3) | (1 << 2) | \ | ||
75 | (1 << 1) | (1 << 0)) /* ccs timeout */ | ||
76 | |||
77 | /* CE_BUF_ACC */ | ||
78 | #define BUF_ACC_DMAWEN (1 << 25) | ||
79 | #define BUF_ACC_DMAREN (1 << 24) | ||
80 | #define BUF_ACC_BUSW_32 (0 << 17) | ||
81 | #define BUF_ACC_BUSW_16 (1 << 17) | ||
82 | #define BUF_ACC_ATYP (1 << 16) | ||
83 | |||
84 | /* CE_INT */ | 68 | /* CE_INT */ |
85 | #define INT_CCSDE (1 << 29) | 69 | #define INT_CCSDE (1 << 29) |
86 | #define INT_CMD12DRE (1 << 26) | 70 | #define INT_CMD12DRE (1 << 26) |
@@ -165,10 +149,6 @@ | |||
165 | STS2_AC12BSYTO | STS2_RSPBSYTO | \ | 149 | STS2_AC12BSYTO | STS2_RSPBSYTO | \ |
166 | STS2_AC12RSPTO | STS2_RSPTO) | 150 | STS2_AC12RSPTO | STS2_RSPTO) |
167 | 151 | ||
168 | /* CE_VERSION */ | ||
169 | #define SOFT_RST_ON (1 << 31) | ||
170 | #define SOFT_RST_OFF (0 << 31) | ||
171 | |||
172 | #define CLKDEV_EMMC_DATA 52000000 /* 52MHz */ | 152 | #define CLKDEV_EMMC_DATA 52000000 /* 52MHz */ |
173 | #define CLKDEV_MMC_DATA 20000000 /* 20MHz */ | 153 | #define CLKDEV_MMC_DATA 20000000 /* 20MHz */ |
174 | #define CLKDEV_INIT 400000 /* 400 KHz */ | 154 | #define CLKDEV_INIT 400000 /* 400 KHz */ |
@@ -176,18 +156,21 @@ | |||
176 | struct sh_mmcif_host { | 156 | struct sh_mmcif_host { |
177 | struct mmc_host *mmc; | 157 | struct mmc_host *mmc; |
178 | struct mmc_data *data; | 158 | struct mmc_data *data; |
179 | struct mmc_command *cmd; | ||
180 | struct platform_device *pd; | 159 | struct platform_device *pd; |
181 | struct clk *hclk; | 160 | struct clk *hclk; |
182 | unsigned int clk; | 161 | unsigned int clk; |
183 | int bus_width; | 162 | int bus_width; |
184 | u16 wait_int; | 163 | bool sd_error; |
185 | u16 sd_error; | ||
186 | long timeout; | 164 | long timeout; |
187 | void __iomem *addr; | 165 | void __iomem *addr; |
188 | wait_queue_head_t intr_wait; | 166 | struct completion intr_wait; |
189 | }; | ||
190 | 167 | ||
168 | /* DMA support */ | ||
169 | struct dma_chan *chan_rx; | ||
170 | struct dma_chan *chan_tx; | ||
171 | struct completion dma_complete; | ||
172 | unsigned int dma_sglen; | ||
173 | }; | ||
191 | 174 | ||
192 | static inline void sh_mmcif_bitset(struct sh_mmcif_host *host, | 175 | static inline void sh_mmcif_bitset(struct sh_mmcif_host *host, |
193 | unsigned int reg, u32 val) | 176 | unsigned int reg, u32 val) |
@@ -201,6 +184,208 @@ static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host, | |||
201 | writel(~val & readl(host->addr + reg), host->addr + reg); | 184 | writel(~val & readl(host->addr + reg), host->addr + reg); |
202 | } | 185 | } |
203 | 186 | ||
187 | #ifdef CONFIG_SH_MMCIF_DMA | ||
188 | static void mmcif_dma_complete(void *arg) | ||
189 | { | ||
190 | struct sh_mmcif_host *host = arg; | ||
191 | dev_dbg(&host->pd->dev, "Command completed\n"); | ||
192 | |||
193 | if (WARN(!host->data, "%s: NULL data in DMA completion!\n", | ||
194 | dev_name(&host->pd->dev))) | ||
195 | return; | ||
196 | |||
197 | if (host->data->flags & MMC_DATA_READ) | ||
198 | dma_unmap_sg(&host->pd->dev, host->data->sg, host->dma_sglen, | ||
199 | DMA_FROM_DEVICE); | ||
200 | else | ||
201 | dma_unmap_sg(&host->pd->dev, host->data->sg, host->dma_sglen, | ||
202 | DMA_TO_DEVICE); | ||
203 | |||
204 | complete(&host->dma_complete); | ||
205 | } | ||
206 | |||
207 | static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host) | ||
208 | { | ||
209 | struct scatterlist *sg = host->data->sg; | ||
210 | struct dma_async_tx_descriptor *desc = NULL; | ||
211 | struct dma_chan *chan = host->chan_rx; | ||
212 | dma_cookie_t cookie = -EINVAL; | ||
213 | int ret; | ||
214 | |||
215 | ret = dma_map_sg(&host->pd->dev, sg, host->data->sg_len, DMA_FROM_DEVICE); | ||
216 | if (ret > 0) { | ||
217 | host->dma_sglen = ret; | ||
218 | desc = chan->device->device_prep_slave_sg(chan, sg, ret, | ||
219 | DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
220 | } | ||
221 | |||
222 | if (desc) { | ||
223 | desc->callback = mmcif_dma_complete; | ||
224 | desc->callback_param = host; | ||
225 | cookie = desc->tx_submit(desc); | ||
226 | if (cookie < 0) { | ||
227 | desc = NULL; | ||
228 | ret = cookie; | ||
229 | } else { | ||
230 | sh_mmcif_bitset(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAREN); | ||
231 | chan->device->device_issue_pending(chan); | ||
232 | } | ||
233 | } | ||
234 | dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n", | ||
235 | __func__, host->data->sg_len, ret, cookie); | ||
236 | |||
237 | if (!desc) { | ||
238 | /* DMA failed, fall back to PIO */ | ||
239 | if (ret >= 0) | ||
240 | ret = -EIO; | ||
241 | host->chan_rx = NULL; | ||
242 | host->dma_sglen = 0; | ||
243 | dma_release_channel(chan); | ||
244 | /* Free the Tx channel too */ | ||
245 | chan = host->chan_tx; | ||
246 | if (chan) { | ||
247 | host->chan_tx = NULL; | ||
248 | dma_release_channel(chan); | ||
249 | } | ||
250 | dev_warn(&host->pd->dev, | ||
251 | "DMA failed: %d, falling back to PIO\n", ret); | ||
252 | sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAREN | BUF_ACC_DMAWEN); | ||
253 | } | ||
254 | |||
255 | dev_dbg(&host->pd->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__, | ||
256 | desc, cookie, host->data->sg_len); | ||
257 | } | ||
258 | |||
259 | static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host) | ||
260 | { | ||
261 | struct scatterlist *sg = host->data->sg; | ||
262 | struct dma_async_tx_descriptor *desc = NULL; | ||
263 | struct dma_chan *chan = host->chan_tx; | ||
264 | dma_cookie_t cookie = -EINVAL; | ||
265 | int ret; | ||
266 | |||
267 | ret = dma_map_sg(&host->pd->dev, sg, host->data->sg_len, DMA_TO_DEVICE); | ||
268 | if (ret > 0) { | ||
269 | host->dma_sglen = ret; | ||
270 | desc = chan->device->device_prep_slave_sg(chan, sg, ret, | ||
271 | DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
272 | } | ||
273 | |||
274 | if (desc) { | ||
275 | desc->callback = mmcif_dma_complete; | ||
276 | desc->callback_param = host; | ||
277 | cookie = desc->tx_submit(desc); | ||
278 | if (cookie < 0) { | ||
279 | desc = NULL; | ||
280 | ret = cookie; | ||
281 | } else { | ||
282 | sh_mmcif_bitset(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAWEN); | ||
283 | chan->device->device_issue_pending(chan); | ||
284 | } | ||
285 | } | ||
286 | dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n", | ||
287 | __func__, host->data->sg_len, ret, cookie); | ||
288 | |||
289 | if (!desc) { | ||
290 | /* DMA failed, fall back to PIO */ | ||
291 | if (ret >= 0) | ||
292 | ret = -EIO; | ||
293 | host->chan_tx = NULL; | ||
294 | host->dma_sglen = 0; | ||
295 | dma_release_channel(chan); | ||
296 | /* Free the Rx channel too */ | ||
297 | chan = host->chan_rx; | ||
298 | if (chan) { | ||
299 | host->chan_rx = NULL; | ||
300 | dma_release_channel(chan); | ||
301 | } | ||
302 | dev_warn(&host->pd->dev, | ||
303 | "DMA failed: %d, falling back to PIO\n", ret); | ||
304 | sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAREN | BUF_ACC_DMAWEN); | ||
305 | } | ||
306 | |||
307 | dev_dbg(&host->pd->dev, "%s(): desc %p, cookie %d\n", __func__, | ||
308 | desc, cookie); | ||
309 | } | ||
310 | |||
311 | static bool sh_mmcif_filter(struct dma_chan *chan, void *arg) | ||
312 | { | ||
313 | dev_dbg(chan->device->dev, "%s: slave data %p\n", __func__, arg); | ||
314 | chan->private = arg; | ||
315 | return true; | ||
316 | } | ||
317 | |||
318 | static void sh_mmcif_request_dma(struct sh_mmcif_host *host, | ||
319 | struct sh_mmcif_plat_data *pdata) | ||
320 | { | ||
321 | host->dma_sglen = 0; | ||
322 | |||
323 | /* We can only either use DMA for both Tx and Rx or not use it at all */ | ||
324 | if (pdata->dma) { | ||
325 | dma_cap_mask_t mask; | ||
326 | |||
327 | dma_cap_zero(mask); | ||
328 | dma_cap_set(DMA_SLAVE, mask); | ||
329 | |||
330 | host->chan_tx = dma_request_channel(mask, sh_mmcif_filter, | ||
331 | &pdata->dma->chan_priv_tx); | ||
332 | dev_dbg(&host->pd->dev, "%s: TX: got channel %p\n", __func__, | ||
333 | host->chan_tx); | ||
334 | |||
335 | if (!host->chan_tx) | ||
336 | return; | ||
337 | |||
338 | host->chan_rx = dma_request_channel(mask, sh_mmcif_filter, | ||
339 | &pdata->dma->chan_priv_rx); | ||
340 | dev_dbg(&host->pd->dev, "%s: RX: got channel %p\n", __func__, | ||
341 | host->chan_rx); | ||
342 | |||
343 | if (!host->chan_rx) { | ||
344 | dma_release_channel(host->chan_tx); | ||
345 | host->chan_tx = NULL; | ||
346 | return; | ||
347 | } | ||
348 | |||
349 | init_completion(&host->dma_complete); | ||
350 | } | ||
351 | } | ||
352 | |||
353 | static void sh_mmcif_release_dma(struct sh_mmcif_host *host) | ||
354 | { | ||
355 | sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAREN | BUF_ACC_DMAWEN); | ||
356 | /* Descriptors are freed automatically */ | ||
357 | if (host->chan_tx) { | ||
358 | struct dma_chan *chan = host->chan_tx; | ||
359 | host->chan_tx = NULL; | ||
360 | dma_release_channel(chan); | ||
361 | } | ||
362 | if (host->chan_rx) { | ||
363 | struct dma_chan *chan = host->chan_rx; | ||
364 | host->chan_rx = NULL; | ||
365 | dma_release_channel(chan); | ||
366 | } | ||
367 | |||
368 | host->dma_sglen = 0; | ||
369 | } | ||
370 | #else | ||
371 | static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host) | ||
372 | { | ||
373 | } | ||
374 | |||
375 | static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host) | ||
376 | { | ||
377 | } | ||
378 | |||
379 | static void sh_mmcif_request_dma(struct sh_mmcif_host *host, | ||
380 | struct sh_mmcif_plat_data *pdata) | ||
381 | { | ||
382 | /* host->chan_tx, host->chan_tx and host->dma_sglen are all zero */ | ||
383 | } | ||
384 | |||
385 | static void sh_mmcif_release_dma(struct sh_mmcif_host *host) | ||
386 | { | ||
387 | } | ||
388 | #endif | ||
204 | 389 | ||
205 | static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk) | 390 | static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk) |
206 | { | 391 | { |
@@ -239,13 +424,12 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host) | |||
239 | u32 state1, state2; | 424 | u32 state1, state2; |
240 | int ret, timeout = 10000000; | 425 | int ret, timeout = 10000000; |
241 | 426 | ||
242 | host->sd_error = 0; | 427 | host->sd_error = false; |
243 | host->wait_int = 0; | ||
244 | 428 | ||
245 | state1 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1); | 429 | state1 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1); |
246 | state2 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS2); | 430 | state2 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS2); |
247 | pr_debug("%s: ERR HOST_STS1 = %08x\n", DRIVER_NAME, state1); | 431 | dev_dbg(&host->pd->dev, "ERR HOST_STS1 = %08x\n", state1); |
248 | pr_debug("%s: ERR HOST_STS2 = %08x\n", DRIVER_NAME, state2); | 432 | dev_dbg(&host->pd->dev, "ERR HOST_STS2 = %08x\n", state2); |
249 | 433 | ||
250 | if (state1 & STS1_CMDSEQ) { | 434 | if (state1 & STS1_CMDSEQ) { |
251 | sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK); | 435 | sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK); |
@@ -253,8 +437,8 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host) | |||
253 | while (1) { | 437 | while (1) { |
254 | timeout--; | 438 | timeout--; |
255 | if (timeout < 0) { | 439 | if (timeout < 0) { |
256 | pr_err(DRIVER_NAME": Forceed end of " \ | 440 | dev_err(&host->pd->dev, |
257 | "command sequence timeout err\n"); | 441 | "Forceed end of command sequence timeout err\n"); |
258 | return -EIO; | 442 | return -EIO; |
259 | } | 443 | } |
260 | if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1) | 444 | if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1) |
@@ -263,18 +447,18 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host) | |||
263 | mdelay(1); | 447 | mdelay(1); |
264 | } | 448 | } |
265 | sh_mmcif_sync_reset(host); | 449 | sh_mmcif_sync_reset(host); |
266 | pr_debug(DRIVER_NAME": Forced end of command sequence\n"); | 450 | dev_dbg(&host->pd->dev, "Forced end of command sequence\n"); |
267 | return -EIO; | 451 | return -EIO; |
268 | } | 452 | } |
269 | 453 | ||
270 | if (state2 & STS2_CRC_ERR) { | 454 | if (state2 & STS2_CRC_ERR) { |
271 | pr_debug(DRIVER_NAME": Happened CRC error\n"); | 455 | dev_dbg(&host->pd->dev, ": Happened CRC error\n"); |
272 | ret = -EIO; | 456 | ret = -EIO; |
273 | } else if (state2 & STS2_TIMEOUT_ERR) { | 457 | } else if (state2 & STS2_TIMEOUT_ERR) { |
274 | pr_debug(DRIVER_NAME": Happened Timeout error\n"); | 458 | dev_dbg(&host->pd->dev, ": Happened Timeout error\n"); |
275 | ret = -ETIMEDOUT; | 459 | ret = -ETIMEDOUT; |
276 | } else { | 460 | } else { |
277 | pr_debug(DRIVER_NAME": Happened End/Index error\n"); | 461 | dev_dbg(&host->pd->dev, ": Happened End/Index error\n"); |
278 | ret = -EIO; | 462 | ret = -EIO; |
279 | } | 463 | } |
280 | return ret; | 464 | return ret; |
@@ -287,17 +471,13 @@ static int sh_mmcif_single_read(struct sh_mmcif_host *host, | |||
287 | long time; | 471 | long time; |
288 | u32 blocksize, i, *p = sg_virt(data->sg); | 472 | u32 blocksize, i, *p = sg_virt(data->sg); |
289 | 473 | ||
290 | host->wait_int = 0; | ||
291 | |||
292 | /* buf read enable */ | 474 | /* buf read enable */ |
293 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); | 475 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); |
294 | time = wait_event_interruptible_timeout(host->intr_wait, | 476 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, |
295 | host->wait_int == 1 || | 477 | host->timeout); |
296 | host->sd_error == 1, host->timeout); | 478 | if (time <= 0 || host->sd_error) |
297 | if (host->wait_int != 1 && (time == 0 || host->sd_error != 0)) | ||
298 | return sh_mmcif_error_manage(host); | 479 | return sh_mmcif_error_manage(host); |
299 | 480 | ||
300 | host->wait_int = 0; | ||
301 | blocksize = (BLOCK_SIZE_MASK & | 481 | blocksize = (BLOCK_SIZE_MASK & |
302 | sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3; | 482 | sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3; |
303 | for (i = 0; i < blocksize / 4; i++) | 483 | for (i = 0; i < blocksize / 4; i++) |
@@ -305,13 +485,11 @@ static int sh_mmcif_single_read(struct sh_mmcif_host *host, | |||
305 | 485 | ||
306 | /* buffer read end */ | 486 | /* buffer read end */ |
307 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE); | 487 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE); |
308 | time = wait_event_interruptible_timeout(host->intr_wait, | 488 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, |
309 | host->wait_int == 1 || | 489 | host->timeout); |
310 | host->sd_error == 1, host->timeout); | 490 | if (time <= 0 || host->sd_error) |
311 | if (host->wait_int != 1 && (time == 0 || host->sd_error != 0)) | ||
312 | return sh_mmcif_error_manage(host); | 491 | return sh_mmcif_error_manage(host); |
313 | 492 | ||
314 | host->wait_int = 0; | ||
315 | return 0; | 493 | return 0; |
316 | } | 494 | } |
317 | 495 | ||
@@ -326,19 +504,15 @@ static int sh_mmcif_multi_read(struct sh_mmcif_host *host, | |||
326 | MMCIF_CE_BLOCK_SET); | 504 | MMCIF_CE_BLOCK_SET); |
327 | for (j = 0; j < data->sg_len; j++) { | 505 | for (j = 0; j < data->sg_len; j++) { |
328 | p = sg_virt(data->sg); | 506 | p = sg_virt(data->sg); |
329 | host->wait_int = 0; | ||
330 | for (sec = 0; sec < data->sg->length / blocksize; sec++) { | 507 | for (sec = 0; sec < data->sg->length / blocksize; sec++) { |
331 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); | 508 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); |
332 | /* buf read enable */ | 509 | /* buf read enable */ |
333 | time = wait_event_interruptible_timeout(host->intr_wait, | 510 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, |
334 | host->wait_int == 1 || | 511 | host->timeout); |
335 | host->sd_error == 1, host->timeout); | ||
336 | 512 | ||
337 | if (host->wait_int != 1 && | 513 | if (time <= 0 || host->sd_error) |
338 | (time == 0 || host->sd_error != 0)) | ||
339 | return sh_mmcif_error_manage(host); | 514 | return sh_mmcif_error_manage(host); |
340 | 515 | ||
341 | host->wait_int = 0; | ||
342 | for (i = 0; i < blocksize / 4; i++) | 516 | for (i = 0; i < blocksize / 4; i++) |
343 | *p++ = sh_mmcif_readl(host->addr, | 517 | *p++ = sh_mmcif_readl(host->addr, |
344 | MMCIF_CE_DATA); | 518 | MMCIF_CE_DATA); |
@@ -356,17 +530,14 @@ static int sh_mmcif_single_write(struct sh_mmcif_host *host, | |||
356 | long time; | 530 | long time; |
357 | u32 blocksize, i, *p = sg_virt(data->sg); | 531 | u32 blocksize, i, *p = sg_virt(data->sg); |
358 | 532 | ||
359 | host->wait_int = 0; | ||
360 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); | 533 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); |
361 | 534 | ||
362 | /* buf write enable */ | 535 | /* buf write enable */ |
363 | time = wait_event_interruptible_timeout(host->intr_wait, | 536 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, |
364 | host->wait_int == 1 || | 537 | host->timeout); |
365 | host->sd_error == 1, host->timeout); | 538 | if (time <= 0 || host->sd_error) |
366 | if (host->wait_int != 1 && (time == 0 || host->sd_error != 0)) | ||
367 | return sh_mmcif_error_manage(host); | 539 | return sh_mmcif_error_manage(host); |
368 | 540 | ||
369 | host->wait_int = 0; | ||
370 | blocksize = (BLOCK_SIZE_MASK & | 541 | blocksize = (BLOCK_SIZE_MASK & |
371 | sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3; | 542 | sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3; |
372 | for (i = 0; i < blocksize / 4; i++) | 543 | for (i = 0; i < blocksize / 4; i++) |
@@ -375,13 +546,11 @@ static int sh_mmcif_single_write(struct sh_mmcif_host *host, | |||
375 | /* buffer write end */ | 546 | /* buffer write end */ |
376 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE); | 547 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE); |
377 | 548 | ||
378 | time = wait_event_interruptible_timeout(host->intr_wait, | 549 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, |
379 | host->wait_int == 1 || | 550 | host->timeout); |
380 | host->sd_error == 1, host->timeout); | 551 | if (time <= 0 || host->sd_error) |
381 | if (host->wait_int != 1 && (time == 0 || host->sd_error != 0)) | ||
382 | return sh_mmcif_error_manage(host); | 552 | return sh_mmcif_error_manage(host); |
383 | 553 | ||
384 | host->wait_int = 0; | ||
385 | return 0; | 554 | return 0; |
386 | } | 555 | } |
387 | 556 | ||
@@ -397,19 +566,15 @@ static int sh_mmcif_multi_write(struct sh_mmcif_host *host, | |||
397 | 566 | ||
398 | for (j = 0; j < data->sg_len; j++) { | 567 | for (j = 0; j < data->sg_len; j++) { |
399 | p = sg_virt(data->sg); | 568 | p = sg_virt(data->sg); |
400 | host->wait_int = 0; | ||
401 | for (sec = 0; sec < data->sg->length / blocksize; sec++) { | 569 | for (sec = 0; sec < data->sg->length / blocksize; sec++) { |
402 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); | 570 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); |
403 | /* buf write enable*/ | 571 | /* buf write enable*/ |
404 | time = wait_event_interruptible_timeout(host->intr_wait, | 572 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, |
405 | host->wait_int == 1 || | 573 | host->timeout); |
406 | host->sd_error == 1, host->timeout); | ||
407 | 574 | ||
408 | if (host->wait_int != 1 && | 575 | if (time <= 0 || host->sd_error) |
409 | (time == 0 || host->sd_error != 0)) | ||
410 | return sh_mmcif_error_manage(host); | 576 | return sh_mmcif_error_manage(host); |
411 | 577 | ||
412 | host->wait_int = 0; | ||
413 | for (i = 0; i < blocksize / 4; i++) | 578 | for (i = 0; i < blocksize / 4; i++) |
414 | sh_mmcif_writel(host->addr, | 579 | sh_mmcif_writel(host->addr, |
415 | MMCIF_CE_DATA, *p++); | 580 | MMCIF_CE_DATA, *p++); |
@@ -457,7 +622,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, | |||
457 | tmp |= CMD_SET_RTYP_17B; | 622 | tmp |= CMD_SET_RTYP_17B; |
458 | break; | 623 | break; |
459 | default: | 624 | default: |
460 | pr_err(DRIVER_NAME": Not support type response.\n"); | 625 | dev_err(&host->pd->dev, "Unsupported response type.\n"); |
461 | break; | 626 | break; |
462 | } | 627 | } |
463 | switch (opc) { | 628 | switch (opc) { |
@@ -485,7 +650,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, | |||
485 | tmp |= CMD_SET_DATW_8; | 650 | tmp |= CMD_SET_DATW_8; |
486 | break; | 651 | break; |
487 | default: | 652 | default: |
488 | pr_err(DRIVER_NAME": Not support bus width.\n"); | 653 | dev_err(&host->pd->dev, "Unsupported bus width.\n"); |
489 | break; | 654 | break; |
490 | } | 655 | } |
491 | } | 656 | } |
@@ -513,10 +678,10 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, | |||
513 | return opc = ((opc << 24) | tmp); | 678 | return opc = ((opc << 24) | tmp); |
514 | } | 679 | } |
515 | 680 | ||
516 | static u32 sh_mmcif_data_trans(struct sh_mmcif_host *host, | 681 | static int sh_mmcif_data_trans(struct sh_mmcif_host *host, |
517 | struct mmc_request *mrq, u32 opc) | 682 | struct mmc_request *mrq, u32 opc) |
518 | { | 683 | { |
519 | u32 ret; | 684 | int ret; |
520 | 685 | ||
521 | switch (opc) { | 686 | switch (opc) { |
522 | case MMC_READ_MULTIPLE_BLOCK: | 687 | case MMC_READ_MULTIPLE_BLOCK: |
@@ -533,7 +698,7 @@ static u32 sh_mmcif_data_trans(struct sh_mmcif_host *host, | |||
533 | ret = sh_mmcif_single_read(host, mrq); | 698 | ret = sh_mmcif_single_read(host, mrq); |
534 | break; | 699 | break; |
535 | default: | 700 | default: |
536 | pr_err(DRIVER_NAME": NOT SUPPORT CMD = d'%08d\n", opc); | 701 | dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc); |
537 | ret = -EINVAL; | 702 | ret = -EINVAL; |
538 | break; | 703 | break; |
539 | } | 704 | } |
@@ -547,8 +712,6 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host, | |||
547 | int ret = 0, mask = 0; | 712 | int ret = 0, mask = 0; |
548 | u32 opc = cmd->opcode; | 713 | u32 opc = cmd->opcode; |
549 | 714 | ||
550 | host->cmd = cmd; | ||
551 | |||
552 | switch (opc) { | 715 | switch (opc) { |
553 | /* respons busy check */ | 716 | /* respons busy check */ |
554 | case MMC_SWITCH: | 717 | case MMC_SWITCH: |
@@ -579,13 +742,12 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host, | |||
579 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask); | 742 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask); |
580 | /* set arg */ | 743 | /* set arg */ |
581 | sh_mmcif_writel(host->addr, MMCIF_CE_ARG, cmd->arg); | 744 | sh_mmcif_writel(host->addr, MMCIF_CE_ARG, cmd->arg); |
582 | host->wait_int = 0; | ||
583 | /* set cmd */ | 745 | /* set cmd */ |
584 | sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc); | 746 | sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc); |
585 | 747 | ||
586 | time = wait_event_interruptible_timeout(host->intr_wait, | 748 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, |
587 | host->wait_int == 1 || host->sd_error == 1, host->timeout); | 749 | host->timeout); |
588 | if (host->wait_int != 1 && time == 0) { | 750 | if (time <= 0) { |
589 | cmd->error = sh_mmcif_error_manage(host); | 751 | cmd->error = sh_mmcif_error_manage(host); |
590 | return; | 752 | return; |
591 | } | 753 | } |
@@ -597,26 +759,34 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host, | |||
597 | cmd->error = -ETIMEDOUT; | 759 | cmd->error = -ETIMEDOUT; |
598 | break; | 760 | break; |
599 | default: | 761 | default: |
600 | pr_debug("%s: Cmd(d'%d) err\n", | 762 | dev_dbg(&host->pd->dev, "Cmd(d'%d) err\n", |
601 | DRIVER_NAME, cmd->opcode); | 763 | cmd->opcode); |
602 | cmd->error = sh_mmcif_error_manage(host); | 764 | cmd->error = sh_mmcif_error_manage(host); |
603 | break; | 765 | break; |
604 | } | 766 | } |
605 | host->sd_error = 0; | 767 | host->sd_error = false; |
606 | host->wait_int = 0; | ||
607 | return; | 768 | return; |
608 | } | 769 | } |
609 | if (!(cmd->flags & MMC_RSP_PRESENT)) { | 770 | if (!(cmd->flags & MMC_RSP_PRESENT)) { |
610 | cmd->error = ret; | 771 | cmd->error = 0; |
611 | host->wait_int = 0; | ||
612 | return; | 772 | return; |
613 | } | 773 | } |
614 | if (host->wait_int == 1) { | 774 | sh_mmcif_get_response(host, cmd); |
615 | sh_mmcif_get_response(host, cmd); | ||
616 | host->wait_int = 0; | ||
617 | } | ||
618 | if (host->data) { | 775 | if (host->data) { |
619 | ret = sh_mmcif_data_trans(host, mrq, cmd->opcode); | 776 | if (!host->dma_sglen) { |
777 | ret = sh_mmcif_data_trans(host, mrq, cmd->opcode); | ||
778 | } else { | ||
779 | long time = | ||
780 | wait_for_completion_interruptible_timeout(&host->dma_complete, | ||
781 | host->timeout); | ||
782 | if (!time) | ||
783 | ret = -ETIMEDOUT; | ||
784 | else if (time < 0) | ||
785 | ret = time; | ||
786 | sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC, | ||
787 | BUF_ACC_DMAREN | BUF_ACC_DMAWEN); | ||
788 | host->dma_sglen = 0; | ||
789 | } | ||
620 | if (ret < 0) | 790 | if (ret < 0) |
621 | mrq->data->bytes_xfered = 0; | 791 | mrq->data->bytes_xfered = 0; |
622 | else | 792 | else |
@@ -636,20 +806,18 @@ static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host, | |||
636 | else if (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK) | 806 | else if (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK) |
637 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); | 807 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); |
638 | else { | 808 | else { |
639 | pr_err(DRIVER_NAME": not support stop cmd\n"); | 809 | dev_err(&host->pd->dev, "unsupported stop cmd\n"); |
640 | cmd->error = sh_mmcif_error_manage(host); | 810 | cmd->error = sh_mmcif_error_manage(host); |
641 | return; | 811 | return; |
642 | } | 812 | } |
643 | 813 | ||
644 | time = wait_event_interruptible_timeout(host->intr_wait, | 814 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, |
645 | host->wait_int == 1 || | 815 | host->timeout); |
646 | host->sd_error == 1, host->timeout); | 816 | if (time <= 0 || host->sd_error) { |
647 | if (host->wait_int != 1 && (time == 0 || host->sd_error != 0)) { | ||
648 | cmd->error = sh_mmcif_error_manage(host); | 817 | cmd->error = sh_mmcif_error_manage(host); |
649 | return; | 818 | return; |
650 | } | 819 | } |
651 | sh_mmcif_get_cmd12response(host, cmd); | 820 | sh_mmcif_get_cmd12response(host, cmd); |
652 | host->wait_int = 0; | ||
653 | cmd->error = 0; | 821 | cmd->error = 0; |
654 | } | 822 | } |
655 | 823 | ||
@@ -676,6 +844,15 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
676 | break; | 844 | break; |
677 | } | 845 | } |
678 | host->data = mrq->data; | 846 | host->data = mrq->data; |
847 | if (mrq->data) { | ||
848 | if (mrq->data->flags & MMC_DATA_READ) { | ||
849 | if (host->chan_rx) | ||
850 | sh_mmcif_start_dma_rx(host); | ||
851 | } else { | ||
852 | if (host->chan_tx) | ||
853 | sh_mmcif_start_dma_tx(host); | ||
854 | } | ||
855 | } | ||
679 | sh_mmcif_start_cmd(host, mrq, mrq->cmd); | 856 | sh_mmcif_start_cmd(host, mrq, mrq->cmd); |
680 | host->data = NULL; | 857 | host->data = NULL; |
681 | 858 | ||
@@ -735,7 +912,7 @@ static void sh_mmcif_detect(struct mmc_host *mmc) | |||
735 | static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) | 912 | static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) |
736 | { | 913 | { |
737 | struct sh_mmcif_host *host = dev_id; | 914 | struct sh_mmcif_host *host = dev_id; |
738 | u32 state = 0; | 915 | u32 state; |
739 | int err = 0; | 916 | int err = 0; |
740 | 917 | ||
741 | state = sh_mmcif_readl(host->addr, MMCIF_CE_INT); | 918 | state = sh_mmcif_readl(host->addr, MMCIF_CE_INT); |
@@ -774,17 +951,19 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) | |||
774 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); | 951 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); |
775 | err = 1; | 952 | err = 1; |
776 | } else { | 953 | } else { |
777 | pr_debug("%s: Not support int\n", DRIVER_NAME); | 954 | dev_dbg(&host->pd->dev, "Not support int\n"); |
778 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state); | 955 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state); |
779 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); | 956 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); |
780 | err = 1; | 957 | err = 1; |
781 | } | 958 | } |
782 | if (err) { | 959 | if (err) { |
783 | host->sd_error = 1; | 960 | host->sd_error = true; |
784 | pr_debug("%s: int err state = %08x\n", DRIVER_NAME, state); | 961 | dev_dbg(&host->pd->dev, "int err state = %08x\n", state); |
785 | } | 962 | } |
786 | host->wait_int = 1; | 963 | if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) |
787 | wake_up(&host->intr_wait); | 964 | complete(&host->intr_wait); |
965 | else | ||
966 | dev_dbg(&host->pd->dev, "Unexpected IRQ 0x%x\n", state); | ||
788 | 967 | ||
789 | return IRQ_HANDLED; | 968 | return IRQ_HANDLED; |
790 | } | 969 | } |
@@ -793,8 +972,8 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) | |||
793 | { | 972 | { |
794 | int ret = 0, irq[2]; | 973 | int ret = 0, irq[2]; |
795 | struct mmc_host *mmc; | 974 | struct mmc_host *mmc; |
796 | struct sh_mmcif_host *host = NULL; | 975 | struct sh_mmcif_host *host; |
797 | struct sh_mmcif_plat_data *pd = NULL; | 976 | struct sh_mmcif_plat_data *pd; |
798 | struct resource *res; | 977 | struct resource *res; |
799 | void __iomem *reg; | 978 | void __iomem *reg; |
800 | char clk_name[8]; | 979 | char clk_name[8]; |
@@ -802,7 +981,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) | |||
802 | irq[0] = platform_get_irq(pdev, 0); | 981 | irq[0] = platform_get_irq(pdev, 0); |
803 | irq[1] = platform_get_irq(pdev, 1); | 982 | irq[1] = platform_get_irq(pdev, 1); |
804 | if (irq[0] < 0 || irq[1] < 0) { | 983 | if (irq[0] < 0 || irq[1] < 0) { |
805 | pr_err(DRIVER_NAME": Get irq error\n"); | 984 | dev_err(&pdev->dev, "Get irq error\n"); |
806 | return -ENXIO; | 985 | return -ENXIO; |
807 | } | 986 | } |
808 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 987 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -815,7 +994,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) | |||
815 | dev_err(&pdev->dev, "ioremap error.\n"); | 994 | dev_err(&pdev->dev, "ioremap error.\n"); |
816 | return -ENOMEM; | 995 | return -ENOMEM; |
817 | } | 996 | } |
818 | pd = (struct sh_mmcif_plat_data *)(pdev->dev.platform_data); | 997 | pd = pdev->dev.platform_data; |
819 | if (!pd) { | 998 | if (!pd) { |
820 | dev_err(&pdev->dev, "sh_mmcif plat data error.\n"); | 999 | dev_err(&pdev->dev, "sh_mmcif plat data error.\n"); |
821 | ret = -ENXIO; | 1000 | ret = -ENXIO; |
@@ -842,7 +1021,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) | |||
842 | host->clk = clk_get_rate(host->hclk); | 1021 | host->clk = clk_get_rate(host->hclk); |
843 | host->pd = pdev; | 1022 | host->pd = pdev; |
844 | 1023 | ||
845 | init_waitqueue_head(&host->intr_wait); | 1024 | init_completion(&host->intr_wait); |
846 | 1025 | ||
847 | mmc->ops = &sh_mmcif_ops; | 1026 | mmc->ops = &sh_mmcif_ops; |
848 | mmc->f_max = host->clk; | 1027 | mmc->f_max = host->clk; |
@@ -858,33 +1037,37 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) | |||
858 | mmc->caps = MMC_CAP_MMC_HIGHSPEED; | 1037 | mmc->caps = MMC_CAP_MMC_HIGHSPEED; |
859 | if (pd->caps) | 1038 | if (pd->caps) |
860 | mmc->caps |= pd->caps; | 1039 | mmc->caps |= pd->caps; |
861 | mmc->max_segs = 128; | 1040 | mmc->max_segs = 32; |
862 | mmc->max_blk_size = 512; | 1041 | mmc->max_blk_size = 512; |
863 | mmc->max_blk_count = 65535; | 1042 | mmc->max_req_size = PAGE_CACHE_SIZE * mmc->max_segs; |
864 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; | 1043 | mmc->max_blk_count = mmc->max_req_size / mmc->max_blk_size; |
865 | mmc->max_seg_size = mmc->max_req_size; | 1044 | mmc->max_seg_size = mmc->max_req_size; |
866 | 1045 | ||
867 | sh_mmcif_sync_reset(host); | 1046 | sh_mmcif_sync_reset(host); |
868 | platform_set_drvdata(pdev, host); | 1047 | platform_set_drvdata(pdev, host); |
1048 | |||
1049 | /* See if we also get DMA */ | ||
1050 | sh_mmcif_request_dma(host, pd); | ||
1051 | |||
869 | mmc_add_host(mmc); | 1052 | mmc_add_host(mmc); |
870 | 1053 | ||
871 | ret = request_irq(irq[0], sh_mmcif_intr, 0, "sh_mmc:error", host); | 1054 | ret = request_irq(irq[0], sh_mmcif_intr, 0, "sh_mmc:error", host); |
872 | if (ret) { | 1055 | if (ret) { |
873 | pr_err(DRIVER_NAME": request_irq error (sh_mmc:error)\n"); | 1056 | dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n"); |
874 | goto clean_up2; | 1057 | goto clean_up2; |
875 | } | 1058 | } |
876 | ret = request_irq(irq[1], sh_mmcif_intr, 0, "sh_mmc:int", host); | 1059 | ret = request_irq(irq[1], sh_mmcif_intr, 0, "sh_mmc:int", host); |
877 | if (ret) { | 1060 | if (ret) { |
878 | free_irq(irq[0], host); | 1061 | free_irq(irq[0], host); |
879 | pr_err(DRIVER_NAME": request_irq error (sh_mmc:int)\n"); | 1062 | dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n"); |
880 | goto clean_up2; | 1063 | goto clean_up2; |
881 | } | 1064 | } |
882 | 1065 | ||
883 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); | 1066 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); |
884 | sh_mmcif_detect(host->mmc); | 1067 | sh_mmcif_detect(host->mmc); |
885 | 1068 | ||
886 | pr_info("%s: driver version %s\n", DRIVER_NAME, DRIVER_VERSION); | 1069 | dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION); |
887 | pr_debug("%s: chip ver H'%04x\n", DRIVER_NAME, | 1070 | dev_dbg(&pdev->dev, "chip ver H'%04x\n", |
888 | sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff); | 1071 | sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff); |
889 | return ret; | 1072 | return ret; |
890 | 1073 | ||
@@ -903,20 +1086,22 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev) | |||
903 | struct sh_mmcif_host *host = platform_get_drvdata(pdev); | 1086 | struct sh_mmcif_host *host = platform_get_drvdata(pdev); |
904 | int irq[2]; | 1087 | int irq[2]; |
905 | 1088 | ||
906 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); | 1089 | mmc_remove_host(host->mmc); |
907 | 1090 | sh_mmcif_release_dma(host); | |
908 | irq[0] = platform_get_irq(pdev, 0); | ||
909 | irq[1] = platform_get_irq(pdev, 1); | ||
910 | 1091 | ||
911 | if (host->addr) | 1092 | if (host->addr) |
912 | iounmap(host->addr); | 1093 | iounmap(host->addr); |
913 | 1094 | ||
914 | platform_set_drvdata(pdev, NULL); | 1095 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); |
915 | mmc_remove_host(host->mmc); | 1096 | |
1097 | irq[0] = platform_get_irq(pdev, 0); | ||
1098 | irq[1] = platform_get_irq(pdev, 1); | ||
916 | 1099 | ||
917 | free_irq(irq[0], host); | 1100 | free_irq(irq[0], host); |
918 | free_irq(irq[1], host); | 1101 | free_irq(irq[1], host); |
919 | 1102 | ||
1103 | platform_set_drvdata(pdev, NULL); | ||
1104 | |||
920 | clk_disable(host->hclk); | 1105 | clk_disable(host->hclk); |
921 | mmc_free_host(host->mmc); | 1106 | mmc_free_host(host->mmc); |
922 | 1107 | ||
@@ -947,5 +1132,5 @@ module_exit(sh_mmcif_exit); | |||
947 | 1132 | ||
948 | MODULE_DESCRIPTION("SuperH on-chip MMC/eMMC interface driver"); | 1133 | MODULE_DESCRIPTION("SuperH on-chip MMC/eMMC interface driver"); |
949 | MODULE_LICENSE("GPL"); | 1134 | MODULE_LICENSE("GPL"); |
950 | MODULE_ALIAS(DRIVER_NAME); | 1135 | MODULE_ALIAS("platform:" DRIVER_NAME); |
951 | MODULE_AUTHOR("Yusuke Goda <yusuke.goda.sx@renesas.com>"); | 1136 | MODULE_AUTHOR("Yusuke Goda <yusuke.goda.sx@renesas.com>"); |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f6668cdaac85..43db398437b7 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -2945,6 +2945,18 @@ source "drivers/s390/net/Kconfig" | |||
2945 | 2945 | ||
2946 | source "drivers/net/caif/Kconfig" | 2946 | source "drivers/net/caif/Kconfig" |
2947 | 2947 | ||
2948 | config TILE_NET | ||
2949 | tristate "Tilera GBE/XGBE network driver support" | ||
2950 | depends on TILE | ||
2951 | default y | ||
2952 | select CRC32 | ||
2953 | help | ||
2954 | This is a standard Linux network device driver for the | ||
2955 | on-chip Tilera Gigabit Ethernet and XAUI interfaces. | ||
2956 | |||
2957 | To compile this driver as a module, choose M here: the module | ||
2958 | will be called tile_net. | ||
2959 | |||
2948 | config XEN_NETDEV_FRONTEND | 2960 | config XEN_NETDEV_FRONTEND |
2949 | tristate "Xen network device frontend driver" | 2961 | tristate "Xen network device frontend driver" |
2950 | depends on XEN | 2962 | depends on XEN |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 652fc6b98039..b90738d13994 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -301,3 +301,4 @@ obj-$(CONFIG_CAIF) += caif/ | |||
301 | 301 | ||
302 | obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/ | 302 | obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/ |
303 | obj-$(CONFIG_PCH_GBE) += pch_gbe/ | 303 | obj-$(CONFIG_PCH_GBE) += pch_gbe/ |
304 | obj-$(CONFIG_TILE_NET) += tile/ | ||
diff --git a/drivers/net/tile/Makefile b/drivers/net/tile/Makefile new file mode 100644 index 000000000000..f634f142cab4 --- /dev/null +++ b/drivers/net/tile/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # | ||
2 | # Makefile for the TILE on-chip networking support. | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_TILE_NET) += tile_net.o | ||
6 | ifdef CONFIG_TILEGX | ||
7 | tile_net-objs := tilegx.o mpipe.o iorpc_mpipe.o dma_queue.o | ||
8 | else | ||
9 | tile_net-objs := tilepro.o | ||
10 | endif | ||
diff --git a/drivers/net/tile/tilepro.c b/drivers/net/tile/tilepro.c new file mode 100644 index 000000000000..0e6bac5ec65b --- /dev/null +++ b/drivers/net/tile/tilepro.c | |||
@@ -0,0 +1,2406 @@ | |||
1 | /* | ||
2 | * Copyright 2010 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/moduleparam.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/kernel.h> /* printk() */ | ||
20 | #include <linux/slab.h> /* kmalloc() */ | ||
21 | #include <linux/errno.h> /* error codes */ | ||
22 | #include <linux/types.h> /* size_t */ | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/in.h> | ||
25 | #include <linux/netdevice.h> /* struct device, and other headers */ | ||
26 | #include <linux/etherdevice.h> /* eth_type_trans */ | ||
27 | #include <linux/skbuff.h> | ||
28 | #include <linux/ioctl.h> | ||
29 | #include <linux/cdev.h> | ||
30 | #include <linux/hugetlb.h> | ||
31 | #include <linux/in6.h> | ||
32 | #include <linux/timer.h> | ||
33 | #include <linux/io.h> | ||
34 | #include <asm/checksum.h> | ||
35 | #include <asm/homecache.h> | ||
36 | |||
37 | #include <hv/drv_xgbe_intf.h> | ||
38 | #include <hv/drv_xgbe_impl.h> | ||
39 | #include <hv/hypervisor.h> | ||
40 | #include <hv/netio_intf.h> | ||
41 | |||
42 | /* For TSO */ | ||
43 | #include <linux/ip.h> | ||
44 | #include <linux/tcp.h> | ||
45 | |||
46 | |||
47 | /* There is no singlethread_cpu, so schedule work on the current cpu. */ | ||
48 | #define singlethread_cpu -1 | ||
49 | |||
50 | |||
51 | /* | ||
52 | * First, "tile_net_init_module()" initializes all four "devices" which | ||
53 | * can be used by linux. | ||
54 | * | ||
55 | * Then, "ifconfig DEVICE up" calls "tile_net_open()", which analyzes | ||
56 | * the network cpus, then uses "tile_net_open_aux()" to initialize | ||
57 | * LIPP/LEPP, and then uses "tile_net_open_inner()" to register all | ||
58 | * the tiles, provide buffers to LIPP, allow ingress to start, and | ||
59 | * turn on hypervisor interrupt handling (and NAPI) on all tiles. | ||
60 | * | ||
61 | * If registration fails due to the link being down, then "retry_work" | ||
62 | * is used to keep calling "tile_net_open_inner()" until it succeeds. | ||
63 | * | ||
64 | * If "ifconfig DEVICE down" is called, it uses "tile_net_stop()" to | ||
65 | * stop egress, drain the LIPP buffers, unregister all the tiles, stop | ||
66 | * LIPP/LEPP, and wipe the LEPP queue. | ||
67 | * | ||
68 | * We start out with the ingress interrupt enabled on each CPU. When | ||
69 | * this interrupt fires, we disable it, and call "napi_schedule()". | ||
70 | * This will cause "tile_net_poll()" to be called, which will pull | ||
71 | * packets from the netio queue, filtering them out, or passing them | ||
72 | * to "netif_receive_skb()". If our budget is exhausted, we will | ||
73 | * return, knowing we will be called again later. Otherwise, we | ||
74 | * reenable the ingress interrupt, and call "napi_complete()". | ||
75 | * | ||
76 | * | ||
77 | * NOTE: The use of "native_driver" ensures that EPP exists, and that | ||
78 | * "epp_sendv" is legal, and that "LIPP" is being used. | ||
79 | * | ||
80 | * NOTE: Failing to free completions for an arbitrarily long time | ||
81 | * (which is defined to be illegal) does in fact cause bizarre | ||
82 | * problems. The "egress_timer" helps prevent this from happening. | ||
83 | * | ||
84 | * NOTE: The egress code can be interrupted by the interrupt handler. | ||
85 | */ | ||
86 | |||
87 | |||
88 | /* HACK: Allow use of "jumbo" packets. */ | ||
89 | /* This should be 1500 if "jumbo" is not set in LIPP. */ | ||
90 | /* This should be at most 10226 (10240 - 14) if "jumbo" is set in LIPP. */ | ||
91 | /* ISSUE: This has not been thoroughly tested (except at 1500). */ | ||
92 | #define TILE_NET_MTU 1500 | ||
93 | |||
94 | /* HACK: Define to support GSO. */ | ||
95 | /* ISSUE: This may actually hurt performance of the TCP blaster. */ | ||
96 | /* #define TILE_NET_GSO */ | ||
97 | |||
98 | /* Define this to collapse "duplicate" acks. */ | ||
99 | /* #define IGNORE_DUP_ACKS */ | ||
100 | |||
101 | /* HACK: Define this to verify incoming packets. */ | ||
102 | /* #define TILE_NET_VERIFY_INGRESS */ | ||
103 | |||
104 | /* Use 3000 to enable the Linux Traffic Control (QoS) layer, else 0. */ | ||
105 | #define TILE_NET_TX_QUEUE_LEN 0 | ||
106 | |||
107 | /* Define to dump packets (prints out the whole packet on tx and rx). */ | ||
108 | /* #define TILE_NET_DUMP_PACKETS */ | ||
109 | |||
110 | /* Define to enable debug spew (all PDEBUG's are enabled). */ | ||
111 | /* #define TILE_NET_DEBUG */ | ||
112 | |||
113 | |||
114 | /* Define to activate paranoia checks. */ | ||
115 | /* #define TILE_NET_PARANOIA */ | ||
116 | |||
117 | /* Default transmit lockup timeout period, in jiffies. */ | ||
118 | #define TILE_NET_TIMEOUT (5 * HZ) | ||
119 | |||
120 | /* Default retry interval for bringing up the NetIO interface, in jiffies. */ | ||
121 | #define TILE_NET_RETRY_INTERVAL (5 * HZ) | ||
122 | |||
123 | /* Number of ports (xgbe0, xgbe1, gbe0, gbe1). */ | ||
124 | #define TILE_NET_DEVS 4 | ||
125 | |||
126 | |||
127 | |||
128 | /* Paranoia. */ | ||
129 | #if NET_IP_ALIGN != LIPP_PACKET_PADDING | ||
130 | #error "NET_IP_ALIGN must match LIPP_PACKET_PADDING." | ||
131 | #endif | ||
132 | |||
133 | |||
134 | /* Debug print. */ | ||
135 | #ifdef TILE_NET_DEBUG | ||
136 | #define PDEBUG(fmt, args...) net_printk(fmt, ## args) | ||
137 | #else | ||
138 | #define PDEBUG(fmt, args...) | ||
139 | #endif | ||
140 | |||
141 | |||
142 | MODULE_AUTHOR("Tilera"); | ||
143 | MODULE_LICENSE("GPL"); | ||
144 | |||
145 | |||
146 | #define IS_MULTICAST(mac_addr) \ | ||
147 | (((u8 *)(mac_addr))[0] & 0x01) | ||
148 | |||
149 | #define IS_BROADCAST(mac_addr) \ | ||
150 | (((u16 *)(mac_addr))[0] == 0xffff) | ||
151 | |||
152 | |||
153 | /* | ||
154 | * Queue of incoming packets for a specific cpu and device. | ||
155 | * | ||
156 | * Includes a pointer to the "system" data, and the actual "user" data. | ||
157 | */ | ||
158 | struct tile_netio_queue { | ||
159 | netio_queue_impl_t *__system_part; | ||
160 | netio_queue_user_impl_t __user_part; | ||
161 | |||
162 | }; | ||
163 | |||
164 | |||
165 | /* | ||
166 | * Statistics counters for a specific cpu and device. | ||
167 | */ | ||
168 | struct tile_net_stats_t { | ||
169 | u32 rx_packets; | ||
170 | u32 rx_bytes; | ||
171 | u32 tx_packets; | ||
172 | u32 tx_bytes; | ||
173 | }; | ||
174 | |||
175 | |||
176 | /* | ||
177 | * Info for a specific cpu and device. | ||
178 | * | ||
179 | * ISSUE: There is a "dev" pointer in "napi" as well. | ||
180 | */ | ||
181 | struct tile_net_cpu { | ||
182 | /* The NAPI struct. */ | ||
183 | struct napi_struct napi; | ||
184 | /* Packet queue. */ | ||
185 | struct tile_netio_queue queue; | ||
186 | /* Statistics. */ | ||
187 | struct tile_net_stats_t stats; | ||
188 | /* ISSUE: Is this needed? */ | ||
189 | bool napi_enabled; | ||
190 | /* True if this tile has succcessfully registered with the IPP. */ | ||
191 | bool registered; | ||
192 | /* True if the link was down last time we tried to register. */ | ||
193 | bool link_down; | ||
194 | /* True if "egress_timer" is scheduled. */ | ||
195 | bool egress_timer_scheduled; | ||
196 | /* Number of small sk_buffs which must still be provided. */ | ||
197 | unsigned int num_needed_small_buffers; | ||
198 | /* Number of large sk_buffs which must still be provided. */ | ||
199 | unsigned int num_needed_large_buffers; | ||
200 | /* A timer for handling egress completions. */ | ||
201 | struct timer_list egress_timer; | ||
202 | }; | ||
203 | |||
204 | |||
205 | /* | ||
206 | * Info for a specific device. | ||
207 | */ | ||
208 | struct tile_net_priv { | ||
209 | /* Our network device. */ | ||
210 | struct net_device *dev; | ||
211 | /* The actual egress queue. */ | ||
212 | lepp_queue_t *epp_queue; | ||
213 | /* Protects "epp_queue->cmd_tail" and "epp_queue->comp_tail" */ | ||
214 | spinlock_t cmd_lock; | ||
215 | /* Protects "epp_queue->comp_head". */ | ||
216 | spinlock_t comp_lock; | ||
217 | /* The hypervisor handle for this interface. */ | ||
218 | int hv_devhdl; | ||
219 | /* The intr bit mask that IDs this device. */ | ||
220 | u32 intr_id; | ||
221 | /* True iff "tile_net_open_aux()" has succeeded. */ | ||
222 | int partly_opened; | ||
223 | /* True iff "tile_net_open_inner()" has succeeded. */ | ||
224 | int fully_opened; | ||
225 | /* Effective network cpus. */ | ||
226 | struct cpumask network_cpus_map; | ||
227 | /* Number of network cpus. */ | ||
228 | int network_cpus_count; | ||
229 | /* Credits per network cpu. */ | ||
230 | int network_cpus_credits; | ||
231 | /* Network stats. */ | ||
232 | struct net_device_stats stats; | ||
233 | /* For NetIO bringup retries. */ | ||
234 | struct delayed_work retry_work; | ||
235 | /* Quick access to per cpu data. */ | ||
236 | struct tile_net_cpu *cpu[NR_CPUS]; | ||
237 | }; | ||
238 | |||
239 | |||
240 | /* | ||
241 | * The actual devices (xgbe0, xgbe1, gbe0, gbe1). | ||
242 | */ | ||
243 | static struct net_device *tile_net_devs[TILE_NET_DEVS]; | ||
244 | |||
245 | /* | ||
246 | * The "tile_net_cpu" structures for each device. | ||
247 | */ | ||
248 | static DEFINE_PER_CPU(struct tile_net_cpu, hv_xgbe0); | ||
249 | static DEFINE_PER_CPU(struct tile_net_cpu, hv_xgbe1); | ||
250 | static DEFINE_PER_CPU(struct tile_net_cpu, hv_gbe0); | ||
251 | static DEFINE_PER_CPU(struct tile_net_cpu, hv_gbe1); | ||
252 | |||
253 | |||
254 | /* | ||
255 | * True if "network_cpus" was specified. | ||
256 | */ | ||
257 | static bool network_cpus_used; | ||
258 | |||
259 | /* | ||
260 | * The actual cpus in "network_cpus". | ||
261 | */ | ||
262 | static struct cpumask network_cpus_map; | ||
263 | |||
264 | |||
265 | |||
266 | #ifdef TILE_NET_DEBUG | ||
267 | /* | ||
268 | * printk with extra stuff. | ||
269 | * | ||
270 | * We print the CPU we're running in brackets. | ||
271 | */ | ||
272 | static void net_printk(char *fmt, ...) | ||
273 | { | ||
274 | int i; | ||
275 | int len; | ||
276 | va_list args; | ||
277 | static char buf[256]; | ||
278 | |||
279 | len = sprintf(buf, "tile_net[%2.2d]: ", smp_processor_id()); | ||
280 | va_start(args, fmt); | ||
281 | i = vscnprintf(buf + len, sizeof(buf) - len - 1, fmt, args); | ||
282 | va_end(args); | ||
283 | buf[255] = '\0'; | ||
284 | pr_notice(buf); | ||
285 | } | ||
286 | #endif | ||
287 | |||
288 | |||
289 | #ifdef TILE_NET_DUMP_PACKETS | ||
290 | /* | ||
291 | * Dump a packet. | ||
292 | */ | ||
293 | static void dump_packet(unsigned char *data, unsigned long length, char *s) | ||
294 | { | ||
295 | unsigned long i; | ||
296 | static unsigned int count; | ||
297 | |||
298 | pr_info("dump_packet(data %p, length 0x%lx s %s count 0x%x)\n", | ||
299 | data, length, s, count++); | ||
300 | |||
301 | pr_info("\n"); | ||
302 | |||
303 | for (i = 0; i < length; i++) { | ||
304 | if ((i & 0xf) == 0) | ||
305 | sprintf(buf, "%8.8lx:", i); | ||
306 | sprintf(buf + strlen(buf), " %2.2x", data[i]); | ||
307 | if ((i & 0xf) == 0xf || i == length - 1) | ||
308 | pr_info("%s\n", buf); | ||
309 | } | ||
310 | } | ||
311 | #endif | ||
312 | |||
313 | |||
314 | /* | ||
315 | * Provide support for the __netio_fastio1() swint | ||
316 | * (see <hv/drv_xgbe_intf.h> for how it is used). | ||
317 | * | ||
318 | * The fastio swint2 call may clobber all the caller-saved registers. | ||
319 | * It rarely clobbers memory, but we allow for the possibility in | ||
320 | * the signature just to be on the safe side. | ||
321 | * | ||
322 | * Also, gcc doesn't seem to allow an input operand to be | ||
323 | * clobbered, so we fake it with dummy outputs. | ||
324 | * | ||
325 | * This function can't be static because of the way it is declared | ||
326 | * in the netio header. | ||
327 | */ | ||
328 | inline int __netio_fastio1(u32 fastio_index, u32 arg0) | ||
329 | { | ||
330 | long result, clobber_r1, clobber_r10; | ||
331 | asm volatile("swint2" | ||
332 | : "=R00" (result), | ||
333 | "=R01" (clobber_r1), "=R10" (clobber_r10) | ||
334 | : "R10" (fastio_index), "R01" (arg0) | ||
335 | : "memory", "r2", "r3", "r4", | ||
336 | "r5", "r6", "r7", "r8", "r9", | ||
337 | "r11", "r12", "r13", "r14", | ||
338 | "r15", "r16", "r17", "r18", "r19", | ||
339 | "r20", "r21", "r22", "r23", "r24", | ||
340 | "r25", "r26", "r27", "r28", "r29"); | ||
341 | return result; | ||
342 | } | ||
343 | |||
344 | |||
345 | /* | ||
346 | * Provide a linux buffer to LIPP. | ||
347 | */ | ||
348 | static void tile_net_provide_linux_buffer(struct tile_net_cpu *info, | ||
349 | void *va, bool small) | ||
350 | { | ||
351 | struct tile_netio_queue *queue = &info->queue; | ||
352 | |||
353 | /* Convert "va" and "small" to "linux_buffer_t". */ | ||
354 | unsigned int buffer = ((unsigned int)(__pa(va) >> 7) << 1) + small; | ||
355 | |||
356 | __netio_fastio_free_buffer(queue->__user_part.__fastio_index, buffer); | ||
357 | } | ||
358 | |||
359 | |||
360 | /* | ||
361 | * Provide a linux buffer for LIPP. | ||
362 | */ | ||
363 | static bool tile_net_provide_needed_buffer(struct tile_net_cpu *info, | ||
364 | bool small) | ||
365 | { | ||
366 | /* ISSUE: What should we use here? */ | ||
367 | unsigned int large_size = NET_IP_ALIGN + TILE_NET_MTU + 100; | ||
368 | |||
369 | /* Round up to ensure to avoid "false sharing" with last cache line. */ | ||
370 | unsigned int buffer_size = | ||
371 | (((small ? LIPP_SMALL_PACKET_SIZE : large_size) + | ||
372 | CHIP_L2_LINE_SIZE() - 1) & -CHIP_L2_LINE_SIZE()); | ||
373 | |||
374 | /* | ||
375 | * ISSUE: Since CPAs are 38 bits, and we can only encode the | ||
376 | * high 31 bits in a "linux_buffer_t", the low 7 bits must be | ||
377 | * zero, and thus, we must align the actual "va" mod 128. | ||
378 | */ | ||
379 | const unsigned long align = 128; | ||
380 | |||
381 | struct sk_buff *skb; | ||
382 | void *va; | ||
383 | |||
384 | struct sk_buff **skb_ptr; | ||
385 | |||
386 | /* Note that "dev_alloc_skb()" adds NET_SKB_PAD more bytes, */ | ||
387 | /* and also "reserves" that many bytes. */ | ||
388 | /* ISSUE: Can we "share" the NET_SKB_PAD bytes with "skb_ptr"? */ | ||
389 | int len = sizeof(*skb_ptr) + align + buffer_size; | ||
390 | |||
391 | while (1) { | ||
392 | |||
393 | /* Allocate (or fail). */ | ||
394 | skb = dev_alloc_skb(len); | ||
395 | if (skb == NULL) | ||
396 | return false; | ||
397 | |||
398 | /* Make room for a back-pointer to 'skb'. */ | ||
399 | skb_reserve(skb, sizeof(*skb_ptr)); | ||
400 | |||
401 | /* Make sure we are aligned. */ | ||
402 | skb_reserve(skb, -(long)skb->data & (align - 1)); | ||
403 | |||
404 | /* This address is given to IPP. */ | ||
405 | va = skb->data; | ||
406 | |||
407 | if (small) | ||
408 | break; | ||
409 | |||
410 | /* ISSUE: This has never been observed! */ | ||
411 | /* Large buffers must not span a huge page. */ | ||
412 | if (((((long)va & ~HPAGE_MASK) + 1535) & HPAGE_MASK) == 0) | ||
413 | break; | ||
414 | pr_err("Leaking unaligned linux buffer at %p.\n", va); | ||
415 | } | ||
416 | |||
417 | /* Skip two bytes to satisfy LIPP assumptions. */ | ||
418 | /* Note that this aligns IP on a 16 byte boundary. */ | ||
419 | /* ISSUE: Do this when the packet arrives? */ | ||
420 | skb_reserve(skb, NET_IP_ALIGN); | ||
421 | |||
422 | /* Save a back-pointer to 'skb'. */ | ||
423 | skb_ptr = va - sizeof(*skb_ptr); | ||
424 | *skb_ptr = skb; | ||
425 | |||
426 | /* Invalidate the packet buffer. */ | ||
427 | if (!hash_default) | ||
428 | __inv_buffer(skb->data, buffer_size); | ||
429 | |||
430 | /* Make sure "skb_ptr" has been flushed. */ | ||
431 | __insn_mf(); | ||
432 | |||
433 | #ifdef TILE_NET_PARANOIA | ||
434 | #if CHIP_HAS_CBOX_HOME_MAP() | ||
435 | if (hash_default) { | ||
436 | HV_PTE pte = *virt_to_pte(current->mm, (unsigned long)va); | ||
437 | if (hv_pte_get_mode(pte) != HV_PTE_MODE_CACHE_HASH_L3) | ||
438 | panic("Non-coherent ingress buffer!"); | ||
439 | } | ||
440 | #endif | ||
441 | #endif | ||
442 | |||
443 | /* Provide the new buffer. */ | ||
444 | tile_net_provide_linux_buffer(info, va, small); | ||
445 | |||
446 | return true; | ||
447 | } | ||
448 | |||
449 | |||
450 | /* | ||
451 | * Provide linux buffers for LIPP. | ||
452 | */ | ||
453 | static void tile_net_provide_needed_buffers(struct tile_net_cpu *info) | ||
454 | { | ||
455 | while (info->num_needed_small_buffers != 0) { | ||
456 | if (!tile_net_provide_needed_buffer(info, true)) | ||
457 | goto oops; | ||
458 | info->num_needed_small_buffers--; | ||
459 | } | ||
460 | |||
461 | while (info->num_needed_large_buffers != 0) { | ||
462 | if (!tile_net_provide_needed_buffer(info, false)) | ||
463 | goto oops; | ||
464 | info->num_needed_large_buffers--; | ||
465 | } | ||
466 | |||
467 | return; | ||
468 | |||
469 | oops: | ||
470 | |||
471 | /* Add a description to the page allocation failure dump. */ | ||
472 | pr_notice("Could not provide a linux buffer to LIPP.\n"); | ||
473 | } | ||
474 | |||
475 | |||
476 | /* | ||
477 | * Grab some LEPP completions, and store them in "comps", of size | ||
478 | * "comps_size", and return the number of completions which were | ||
479 | * stored, so the caller can free them. | ||
480 | * | ||
481 | * If "pending" is not NULL, it will be set to true if there might | ||
482 | * still be some pending completions caused by this tile, else false. | ||
483 | */ | ||
484 | static unsigned int tile_net_lepp_grab_comps(struct net_device *dev, | ||
485 | struct sk_buff *comps[], | ||
486 | unsigned int comps_size, | ||
487 | bool *pending) | ||
488 | { | ||
489 | struct tile_net_priv *priv = netdev_priv(dev); | ||
490 | |||
491 | lepp_queue_t *eq = priv->epp_queue; | ||
492 | |||
493 | unsigned int n = 0; | ||
494 | |||
495 | unsigned int comp_head; | ||
496 | unsigned int comp_busy; | ||
497 | unsigned int comp_tail; | ||
498 | |||
499 | spin_lock(&priv->comp_lock); | ||
500 | |||
501 | comp_head = eq->comp_head; | ||
502 | comp_busy = eq->comp_busy; | ||
503 | comp_tail = eq->comp_tail; | ||
504 | |||
505 | while (comp_head != comp_busy && n < comps_size) { | ||
506 | comps[n++] = eq->comps[comp_head]; | ||
507 | LEPP_QINC(comp_head); | ||
508 | } | ||
509 | |||
510 | if (pending != NULL) | ||
511 | *pending = (comp_head != comp_tail); | ||
512 | |||
513 | eq->comp_head = comp_head; | ||
514 | |||
515 | spin_unlock(&priv->comp_lock); | ||
516 | |||
517 | return n; | ||
518 | } | ||
519 | |||
520 | |||
521 | /* | ||
522 | * Make sure the egress timer is scheduled. | ||
523 | * | ||
524 | * Note that we use "schedule if not scheduled" logic instead of the more | ||
525 | * obvious "reschedule" logic, because "reschedule" is fairly expensive. | ||
526 | */ | ||
527 | static void tile_net_schedule_egress_timer(struct tile_net_cpu *info) | ||
528 | { | ||
529 | if (!info->egress_timer_scheduled) { | ||
530 | mod_timer_pinned(&info->egress_timer, jiffies + 1); | ||
531 | info->egress_timer_scheduled = true; | ||
532 | } | ||
533 | } | ||
534 | |||
535 | |||
536 | /* | ||
537 | * The "function" for "info->egress_timer". | ||
538 | * | ||
539 | * This timer will reschedule itself as long as there are any pending | ||
540 | * completions expected (on behalf of any tile). | ||
541 | * | ||
542 | * ISSUE: Realistically, will the timer ever stop scheduling itself? | ||
543 | * | ||
544 | * ISSUE: This timer is almost never actually needed, so just use a global | ||
545 | * timer that can run on any tile. | ||
546 | * | ||
547 | * ISSUE: Maybe instead track number of expected completions, and free | ||
548 | * only that many, resetting to zero if "pending" is ever false. | ||
549 | */ | ||
550 | static void tile_net_handle_egress_timer(unsigned long arg) | ||
551 | { | ||
552 | struct tile_net_cpu *info = (struct tile_net_cpu *)arg; | ||
553 | struct net_device *dev = info->napi.dev; | ||
554 | |||
555 | struct sk_buff *olds[32]; | ||
556 | unsigned int wanted = 32; | ||
557 | unsigned int i, nolds = 0; | ||
558 | bool pending; | ||
559 | |||
560 | /* The timer is no longer scheduled. */ | ||
561 | info->egress_timer_scheduled = false; | ||
562 | |||
563 | nolds = tile_net_lepp_grab_comps(dev, olds, wanted, &pending); | ||
564 | |||
565 | for (i = 0; i < nolds; i++) | ||
566 | kfree_skb(olds[i]); | ||
567 | |||
568 | /* Reschedule timer if needed. */ | ||
569 | if (pending) | ||
570 | tile_net_schedule_egress_timer(info); | ||
571 | } | ||
572 | |||
573 | |||
574 | #ifdef IGNORE_DUP_ACKS | ||
575 | |||
576 | /* | ||
577 | * Help detect "duplicate" ACKs. These are sequential packets (for a | ||
578 | * given flow) which are exactly 66 bytes long, sharing everything but | ||
579 | * ID=2@0x12, Hsum=2@0x18, Ack=4@0x2a, WinSize=2@0x30, Csum=2@0x32, | ||
580 | * Tstamps=10@0x38. The ID's are +1, the Hsum's are -1, the Ack's are | ||
581 | * +N, and the Tstamps are usually identical. | ||
582 | * | ||
583 | * NOTE: Apparently truly duplicate acks (with identical "ack" values), | ||
584 | * should not be collapsed, as they are used for some kind of flow control. | ||
585 | */ | ||
586 | static bool is_dup_ack(char *s1, char *s2, unsigned int len) | ||
587 | { | ||
588 | int i; | ||
589 | |||
590 | unsigned long long ignorable = 0; | ||
591 | |||
592 | /* Identification. */ | ||
593 | ignorable |= (1ULL << 0x12); | ||
594 | ignorable |= (1ULL << 0x13); | ||
595 | |||
596 | /* Header checksum. */ | ||
597 | ignorable |= (1ULL << 0x18); | ||
598 | ignorable |= (1ULL << 0x19); | ||
599 | |||
600 | /* ACK. */ | ||
601 | ignorable |= (1ULL << 0x2a); | ||
602 | ignorable |= (1ULL << 0x2b); | ||
603 | ignorable |= (1ULL << 0x2c); | ||
604 | ignorable |= (1ULL << 0x2d); | ||
605 | |||
606 | /* WinSize. */ | ||
607 | ignorable |= (1ULL << 0x30); | ||
608 | ignorable |= (1ULL << 0x31); | ||
609 | |||
610 | /* Checksum. */ | ||
611 | ignorable |= (1ULL << 0x32); | ||
612 | ignorable |= (1ULL << 0x33); | ||
613 | |||
614 | for (i = 0; i < len; i++, ignorable >>= 1) { | ||
615 | |||
616 | if ((ignorable & 1) || (s1[i] == s2[i])) | ||
617 | continue; | ||
618 | |||
619 | #ifdef TILE_NET_DEBUG | ||
620 | /* HACK: Mention non-timestamp diffs. */ | ||
621 | if (i < 0x38 && i != 0x2f && | ||
622 | net_ratelimit()) | ||
623 | pr_info("Diff at 0x%x\n", i); | ||
624 | #endif | ||
625 | |||
626 | return false; | ||
627 | } | ||
628 | |||
629 | #ifdef TILE_NET_NO_SUPPRESS_DUP_ACKS | ||
630 | /* HACK: Do not suppress truly duplicate ACKs. */ | ||
631 | /* ISSUE: Is this actually necessary or helpful? */ | ||
632 | if (s1[0x2a] == s2[0x2a] && | ||
633 | s1[0x2b] == s2[0x2b] && | ||
634 | s1[0x2c] == s2[0x2c] && | ||
635 | s1[0x2d] == s2[0x2d]) { | ||
636 | return false; | ||
637 | } | ||
638 | #endif | ||
639 | |||
640 | return true; | ||
641 | } | ||
642 | |||
643 | #endif | ||
644 | |||
645 | |||
646 | |||
647 | /* | ||
648 | * Like "tile_net_handle_packets()", but just discard packets. | ||
649 | */ | ||
650 | static void tile_net_discard_packets(struct net_device *dev) | ||
651 | { | ||
652 | struct tile_net_priv *priv = netdev_priv(dev); | ||
653 | int my_cpu = smp_processor_id(); | ||
654 | struct tile_net_cpu *info = priv->cpu[my_cpu]; | ||
655 | struct tile_netio_queue *queue = &info->queue; | ||
656 | netio_queue_impl_t *qsp = queue->__system_part; | ||
657 | netio_queue_user_impl_t *qup = &queue->__user_part; | ||
658 | |||
659 | while (qup->__packet_receive_read != | ||
660 | qsp->__packet_receive_queue.__packet_write) { | ||
661 | |||
662 | int index = qup->__packet_receive_read; | ||
663 | |||
664 | int index2_aux = index + sizeof(netio_pkt_t); | ||
665 | int index2 = | ||
666 | ((index2_aux == | ||
667 | qsp->__packet_receive_queue.__last_packet_plus_one) ? | ||
668 | 0 : index2_aux); | ||
669 | |||
670 | netio_pkt_t *pkt = (netio_pkt_t *) | ||
671 | ((unsigned long) &qsp[1] + index); | ||
672 | |||
673 | /* Extract the "linux_buffer_t". */ | ||
674 | unsigned int buffer = pkt->__packet.word; | ||
675 | |||
676 | /* Convert "linux_buffer_t" to "va". */ | ||
677 | void *va = __va((phys_addr_t)(buffer >> 1) << 7); | ||
678 | |||
679 | /* Acquire the associated "skb". */ | ||
680 | struct sk_buff **skb_ptr = va - sizeof(*skb_ptr); | ||
681 | struct sk_buff *skb = *skb_ptr; | ||
682 | |||
683 | kfree_skb(skb); | ||
684 | |||
685 | /* Consume this packet. */ | ||
686 | qup->__packet_receive_read = index2; | ||
687 | } | ||
688 | } | ||
689 | |||
690 | |||
691 | /* | ||
692 | * Handle the next packet. Return true if "processed", false if "filtered". | ||
693 | */ | ||
694 | static bool tile_net_poll_aux(struct tile_net_cpu *info, int index) | ||
695 | { | ||
696 | struct net_device *dev = info->napi.dev; | ||
697 | |||
698 | struct tile_netio_queue *queue = &info->queue; | ||
699 | netio_queue_impl_t *qsp = queue->__system_part; | ||
700 | netio_queue_user_impl_t *qup = &queue->__user_part; | ||
701 | struct tile_net_stats_t *stats = &info->stats; | ||
702 | |||
703 | int filter; | ||
704 | |||
705 | int index2_aux = index + sizeof(netio_pkt_t); | ||
706 | int index2 = | ||
707 | ((index2_aux == | ||
708 | qsp->__packet_receive_queue.__last_packet_plus_one) ? | ||
709 | 0 : index2_aux); | ||
710 | |||
711 | netio_pkt_t *pkt = (netio_pkt_t *)((unsigned long) &qsp[1] + index); | ||
712 | |||
713 | netio_pkt_metadata_t *metadata = NETIO_PKT_METADATA(pkt); | ||
714 | |||
715 | /* Extract the packet size. */ | ||
716 | unsigned long len = | ||
717 | (NETIO_PKT_CUSTOM_LENGTH(pkt) + | ||
718 | NET_IP_ALIGN - NETIO_PACKET_PADDING); | ||
719 | |||
720 | /* Extract the "linux_buffer_t". */ | ||
721 | unsigned int buffer = pkt->__packet.word; | ||
722 | |||
723 | /* Extract "small" (vs "large"). */ | ||
724 | bool small = ((buffer & 1) != 0); | ||
725 | |||
726 | /* Convert "linux_buffer_t" to "va". */ | ||
727 | void *va = __va((phys_addr_t)(buffer >> 1) << 7); | ||
728 | |||
729 | /* Extract the packet data pointer. */ | ||
730 | /* Compare to "NETIO_PKT_CUSTOM_DATA(pkt)". */ | ||
731 | unsigned char *buf = va + NET_IP_ALIGN; | ||
732 | |||
733 | #ifdef IGNORE_DUP_ACKS | ||
734 | |||
735 | static int other; | ||
736 | static int final; | ||
737 | static int keep; | ||
738 | static int skip; | ||
739 | |||
740 | #endif | ||
741 | |||
742 | /* Invalidate the packet buffer. */ | ||
743 | if (!hash_default) | ||
744 | __inv_buffer(buf, len); | ||
745 | |||
746 | /* ISSUE: Is this needed? */ | ||
747 | dev->last_rx = jiffies; | ||
748 | |||
749 | #ifdef TILE_NET_DUMP_PACKETS | ||
750 | dump_packet(buf, len, "rx"); | ||
751 | #endif /* TILE_NET_DUMP_PACKETS */ | ||
752 | |||
753 | #ifdef TILE_NET_VERIFY_INGRESS | ||
754 | if (!NETIO_PKT_L4_CSUM_CORRECT_M(metadata, pkt) && | ||
755 | NETIO_PKT_L4_CSUM_CALCULATED_M(metadata, pkt)) { | ||
756 | /* | ||
757 | * FIXME: This complains about UDP packets | ||
758 | * with a "zero" checksum (bug 6624). | ||
759 | */ | ||
760 | #ifdef TILE_NET_PANIC_ON_BAD | ||
761 | dump_packet(buf, len, "rx"); | ||
762 | panic("Bad L4 checksum."); | ||
763 | #else | ||
764 | pr_warning("Bad L4 checksum on %d byte packet.\n", len); | ||
765 | #endif | ||
766 | } | ||
767 | if (!NETIO_PKT_L3_CSUM_CORRECT_M(metadata, pkt) && | ||
768 | NETIO_PKT_L3_CSUM_CALCULATED_M(metadata, pkt)) { | ||
769 | dump_packet(buf, len, "rx"); | ||
770 | panic("Bad L3 checksum."); | ||
771 | } | ||
772 | switch (NETIO_PKT_STATUS_M(metadata, pkt)) { | ||
773 | case NETIO_PKT_STATUS_OVERSIZE: | ||
774 | if (len >= 64) { | ||
775 | dump_packet(buf, len, "rx"); | ||
776 | panic("Unexpected OVERSIZE."); | ||
777 | } | ||
778 | break; | ||
779 | case NETIO_PKT_STATUS_BAD: | ||
780 | #ifdef TILE_NET_PANIC_ON_BAD | ||
781 | dump_packet(buf, len, "rx"); | ||
782 | panic("Unexpected BAD packet."); | ||
783 | #else | ||
784 | pr_warning("Unexpected BAD %d byte packet.\n", len); | ||
785 | #endif | ||
786 | } | ||
787 | #endif | ||
788 | |||
789 | filter = 0; | ||
790 | |||
791 | if (!(dev->flags & IFF_UP)) { | ||
792 | /* Filter packets received before we're up. */ | ||
793 | filter = 1; | ||
794 | } else if (!(dev->flags & IFF_PROMISC)) { | ||
795 | /* | ||
796 | * FIXME: Implement HW multicast filter. | ||
797 | */ | ||
798 | if (!IS_MULTICAST(buf) && !IS_BROADCAST(buf)) { | ||
799 | /* Filter packets not for our address. */ | ||
800 | const u8 *mine = dev->dev_addr; | ||
801 | filter = compare_ether_addr(mine, buf); | ||
802 | } | ||
803 | } | ||
804 | |||
805 | #ifdef IGNORE_DUP_ACKS | ||
806 | |||
807 | if (len != 66) { | ||
808 | /* FIXME: Must check "is_tcp_ack(buf, len)" somehow. */ | ||
809 | |||
810 | other++; | ||
811 | |||
812 | } else if (index2 == | ||
813 | qsp->__packet_receive_queue.__packet_write) { | ||
814 | |||
815 | final++; | ||
816 | |||
817 | } else { | ||
818 | |||
819 | netio_pkt_t *pkt2 = (netio_pkt_t *) | ||
820 | ((unsigned long) &qsp[1] + index2); | ||
821 | |||
822 | netio_pkt_metadata_t *metadata2 = | ||
823 | NETIO_PKT_METADATA(pkt2); | ||
824 | |||
825 | /* Extract the packet size. */ | ||
826 | unsigned long len2 = | ||
827 | (NETIO_PKT_CUSTOM_LENGTH(pkt2) + | ||
828 | NET_IP_ALIGN - NETIO_PACKET_PADDING); | ||
829 | |||
830 | if (len2 == 66 && | ||
831 | NETIO_PKT_FLOW_HASH_M(metadata, pkt) == | ||
832 | NETIO_PKT_FLOW_HASH_M(metadata2, pkt2)) { | ||
833 | |||
834 | /* Extract the "linux_buffer_t". */ | ||
835 | unsigned int buffer2 = pkt2->__packet.word; | ||
836 | |||
837 | /* Convert "linux_buffer_t" to "va". */ | ||
838 | void *va2 = | ||
839 | __va((phys_addr_t)(buffer2 >> 1) << 7); | ||
840 | |||
841 | /* Extract the packet data pointer. */ | ||
842 | /* Compare to "NETIO_PKT_CUSTOM_DATA(pkt)". */ | ||
843 | unsigned char *buf2 = va2 + NET_IP_ALIGN; | ||
844 | |||
845 | /* Invalidate the packet buffer. */ | ||
846 | if (!hash_default) | ||
847 | __inv_buffer(buf2, len2); | ||
848 | |||
849 | if (is_dup_ack(buf, buf2, len)) { | ||
850 | skip++; | ||
851 | filter = 1; | ||
852 | } else { | ||
853 | keep++; | ||
854 | } | ||
855 | } | ||
856 | } | ||
857 | |||
858 | if (net_ratelimit()) | ||
859 | pr_info("Other %d Final %d Keep %d Skip %d.\n", | ||
860 | other, final, keep, skip); | ||
861 | |||
862 | #endif | ||
863 | |||
864 | if (filter) { | ||
865 | |||
866 | /* ISSUE: Update "drop" statistics? */ | ||
867 | |||
868 | tile_net_provide_linux_buffer(info, va, small); | ||
869 | |||
870 | } else { | ||
871 | |||
872 | /* Acquire the associated "skb". */ | ||
873 | struct sk_buff **skb_ptr = va - sizeof(*skb_ptr); | ||
874 | struct sk_buff *skb = *skb_ptr; | ||
875 | |||
876 | /* Paranoia. */ | ||
877 | if (skb->data != buf) | ||
878 | panic("Corrupt linux buffer from LIPP! " | ||
879 | "VA=%p, skb=%p, skb->data=%p\n", | ||
880 | va, skb, skb->data); | ||
881 | |||
882 | /* Encode the actual packet length. */ | ||
883 | skb_put(skb, len); | ||
884 | |||
885 | /* NOTE: This call also sets "skb->dev = dev". */ | ||
886 | skb->protocol = eth_type_trans(skb, dev); | ||
887 | |||
888 | /* ISSUE: Discard corrupt packets? */ | ||
889 | /* ISSUE: Discard packets with bad checksums? */ | ||
890 | |||
891 | /* Avoid recomputing TCP/UDP checksums. */ | ||
892 | if (NETIO_PKT_L4_CSUM_CORRECT_M(metadata, pkt)) | ||
893 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
894 | |||
895 | netif_receive_skb(skb); | ||
896 | |||
897 | stats->rx_packets++; | ||
898 | stats->rx_bytes += len; | ||
899 | |||
900 | if (small) | ||
901 | info->num_needed_small_buffers++; | ||
902 | else | ||
903 | info->num_needed_large_buffers++; | ||
904 | } | ||
905 | |||
906 | /* Return four credits after every fourth packet. */ | ||
907 | if (--qup->__receive_credit_remaining == 0) { | ||
908 | u32 interval = qup->__receive_credit_interval; | ||
909 | qup->__receive_credit_remaining = interval; | ||
910 | __netio_fastio_return_credits(qup->__fastio_index, interval); | ||
911 | } | ||
912 | |||
913 | /* Consume this packet. */ | ||
914 | qup->__packet_receive_read = index2; | ||
915 | |||
916 | return !filter; | ||
917 | } | ||
918 | |||
919 | |||
920 | /* | ||
921 | * Handle some packets for the given device on the current CPU. | ||
922 | * | ||
923 | * ISSUE: The "rotting packet" race condition occurs if a packet | ||
924 | * arrives after the queue appears to be empty, and before the | ||
925 | * hypervisor interrupt is re-enabled. | ||
926 | */ | ||
927 | static int tile_net_poll(struct napi_struct *napi, int budget) | ||
928 | { | ||
929 | struct net_device *dev = napi->dev; | ||
930 | struct tile_net_priv *priv = netdev_priv(dev); | ||
931 | int my_cpu = smp_processor_id(); | ||
932 | struct tile_net_cpu *info = priv->cpu[my_cpu]; | ||
933 | struct tile_netio_queue *queue = &info->queue; | ||
934 | netio_queue_impl_t *qsp = queue->__system_part; | ||
935 | netio_queue_user_impl_t *qup = &queue->__user_part; | ||
936 | |||
937 | unsigned int work = 0; | ||
938 | |||
939 | while (1) { | ||
940 | int index = qup->__packet_receive_read; | ||
941 | if (index == qsp->__packet_receive_queue.__packet_write) | ||
942 | break; | ||
943 | |||
944 | if (tile_net_poll_aux(info, index)) { | ||
945 | if (++work >= budget) | ||
946 | goto done; | ||
947 | } | ||
948 | } | ||
949 | |||
950 | napi_complete(&info->napi); | ||
951 | |||
952 | /* Re-enable hypervisor interrupts. */ | ||
953 | enable_percpu_irq(priv->intr_id); | ||
954 | |||
955 | /* HACK: Avoid the "rotting packet" problem. */ | ||
956 | if (qup->__packet_receive_read != | ||
957 | qsp->__packet_receive_queue.__packet_write) | ||
958 | napi_schedule(&info->napi); | ||
959 | |||
960 | /* ISSUE: Handle completions? */ | ||
961 | |||
962 | done: | ||
963 | |||
964 | tile_net_provide_needed_buffers(info); | ||
965 | |||
966 | return work; | ||
967 | } | ||
968 | |||
969 | |||
970 | /* | ||
971 | * Handle an ingress interrupt for the given device on the current cpu. | ||
972 | */ | ||
973 | static irqreturn_t tile_net_handle_ingress_interrupt(int irq, void *dev_ptr) | ||
974 | { | ||
975 | struct net_device *dev = (struct net_device *)dev_ptr; | ||
976 | struct tile_net_priv *priv = netdev_priv(dev); | ||
977 | int my_cpu = smp_processor_id(); | ||
978 | struct tile_net_cpu *info = priv->cpu[my_cpu]; | ||
979 | |||
980 | /* Disable hypervisor interrupt. */ | ||
981 | disable_percpu_irq(priv->intr_id); | ||
982 | |||
983 | napi_schedule(&info->napi); | ||
984 | |||
985 | return IRQ_HANDLED; | ||
986 | } | ||
987 | |||
988 | |||
989 | /* | ||
990 | * One time initialization per interface. | ||
991 | */ | ||
992 | static int tile_net_open_aux(struct net_device *dev) | ||
993 | { | ||
994 | struct tile_net_priv *priv = netdev_priv(dev); | ||
995 | |||
996 | int ret; | ||
997 | int dummy; | ||
998 | unsigned int epp_lotar; | ||
999 | |||
1000 | /* | ||
1001 | * Find out where EPP memory should be homed. | ||
1002 | */ | ||
1003 | ret = hv_dev_pread(priv->hv_devhdl, 0, | ||
1004 | (HV_VirtAddr)&epp_lotar, sizeof(epp_lotar), | ||
1005 | NETIO_EPP_SHM_OFF); | ||
1006 | if (ret < 0) { | ||
1007 | pr_err("could not read epp_shm_queue lotar.\n"); | ||
1008 | return -EIO; | ||
1009 | } | ||
1010 | |||
1011 | /* | ||
1012 | * Home the page on the EPP. | ||
1013 | */ | ||
1014 | { | ||
1015 | int epp_home = hv_lotar_to_cpu(epp_lotar); | ||
1016 | struct page *page = virt_to_page(priv->epp_queue); | ||
1017 | homecache_change_page_home(page, 0, epp_home); | ||
1018 | } | ||
1019 | |||
1020 | /* | ||
1021 | * Register the EPP shared memory queue. | ||
1022 | */ | ||
1023 | { | ||
1024 | netio_ipp_address_t ea = { | ||
1025 | .va = 0, | ||
1026 | .pa = __pa(priv->epp_queue), | ||
1027 | .pte = hv_pte(0), | ||
1028 | .size = PAGE_SIZE, | ||
1029 | }; | ||
1030 | ea.pte = hv_pte_set_lotar(ea.pte, epp_lotar); | ||
1031 | ea.pte = hv_pte_set_mode(ea.pte, HV_PTE_MODE_CACHE_TILE_L3); | ||
1032 | ret = hv_dev_pwrite(priv->hv_devhdl, 0, | ||
1033 | (HV_VirtAddr)&ea, | ||
1034 | sizeof(ea), | ||
1035 | NETIO_EPP_SHM_OFF); | ||
1036 | if (ret < 0) | ||
1037 | return -EIO; | ||
1038 | } | ||
1039 | |||
1040 | /* | ||
1041 | * Start LIPP/LEPP. | ||
1042 | */ | ||
1043 | if (hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy, | ||
1044 | sizeof(dummy), NETIO_IPP_START_SHIM_OFF) < 0) { | ||
1045 | pr_warning("Failed to start LIPP/LEPP.\n"); | ||
1046 | return -EIO; | ||
1047 | } | ||
1048 | |||
1049 | return 0; | ||
1050 | } | ||
1051 | |||
1052 | |||
1053 | /* | ||
1054 | * Register with hypervisor on each CPU. | ||
1055 | * | ||
1056 | * Strangely, this function does important things even if it "fails", | ||
1057 | * which is especially common if the link is not up yet. Hopefully | ||
1058 | * these things are all "harmless" if done twice! | ||
1059 | */ | ||
1060 | static void tile_net_register(void *dev_ptr) | ||
1061 | { | ||
1062 | struct net_device *dev = (struct net_device *)dev_ptr; | ||
1063 | struct tile_net_priv *priv = netdev_priv(dev); | ||
1064 | int my_cpu = smp_processor_id(); | ||
1065 | struct tile_net_cpu *info; | ||
1066 | |||
1067 | struct tile_netio_queue *queue; | ||
1068 | |||
1069 | /* Only network cpus can receive packets. */ | ||
1070 | int queue_id = | ||
1071 | cpumask_test_cpu(my_cpu, &priv->network_cpus_map) ? 0 : 255; | ||
1072 | |||
1073 | netio_input_config_t config = { | ||
1074 | .flags = 0, | ||
1075 | .num_receive_packets = priv->network_cpus_credits, | ||
1076 | .queue_id = queue_id | ||
1077 | }; | ||
1078 | |||
1079 | int ret = 0; | ||
1080 | netio_queue_impl_t *queuep; | ||
1081 | |||
1082 | PDEBUG("tile_net_register(queue_id %d)\n", queue_id); | ||
1083 | |||
1084 | if (!strcmp(dev->name, "xgbe0")) | ||
1085 | info = &__get_cpu_var(hv_xgbe0); | ||
1086 | else if (!strcmp(dev->name, "xgbe1")) | ||
1087 | info = &__get_cpu_var(hv_xgbe1); | ||
1088 | else if (!strcmp(dev->name, "gbe0")) | ||
1089 | info = &__get_cpu_var(hv_gbe0); | ||
1090 | else if (!strcmp(dev->name, "gbe1")) | ||
1091 | info = &__get_cpu_var(hv_gbe1); | ||
1092 | else | ||
1093 | BUG(); | ||
1094 | |||
1095 | /* Initialize the egress timer. */ | ||
1096 | init_timer(&info->egress_timer); | ||
1097 | info->egress_timer.data = (long)info; | ||
1098 | info->egress_timer.function = tile_net_handle_egress_timer; | ||
1099 | |||
1100 | priv->cpu[my_cpu] = info; | ||
1101 | |||
1102 | /* | ||
1103 | * Register ourselves with the IPP. | ||
1104 | */ | ||
1105 | ret = hv_dev_pwrite(priv->hv_devhdl, 0, | ||
1106 | (HV_VirtAddr)&config, | ||
1107 | sizeof(netio_input_config_t), | ||
1108 | NETIO_IPP_INPUT_REGISTER_OFF); | ||
1109 | PDEBUG("hv_dev_pwrite(NETIO_IPP_INPUT_REGISTER_OFF) returned %d\n", | ||
1110 | ret); | ||
1111 | if (ret < 0) { | ||
1112 | printk(KERN_DEBUG "hv_dev_pwrite NETIO_IPP_INPUT_REGISTER_OFF" | ||
1113 | " failure %d\n", ret); | ||
1114 | info->link_down = (ret == NETIO_LINK_DOWN); | ||
1115 | return; | ||
1116 | } | ||
1117 | |||
1118 | /* | ||
1119 | * Get the pointer to our queue's system part. | ||
1120 | */ | ||
1121 | |||
1122 | ret = hv_dev_pread(priv->hv_devhdl, 0, | ||
1123 | (HV_VirtAddr)&queuep, | ||
1124 | sizeof(netio_queue_impl_t *), | ||
1125 | NETIO_IPP_INPUT_REGISTER_OFF); | ||
1126 | PDEBUG("hv_dev_pread(NETIO_IPP_INPUT_REGISTER_OFF) returned %d\n", | ||
1127 | ret); | ||
1128 | PDEBUG("queuep %p\n", queuep); | ||
1129 | if (ret <= 0) { | ||
1130 | /* ISSUE: Shouldn't this be a fatal error? */ | ||
1131 | pr_err("hv_dev_pread NETIO_IPP_INPUT_REGISTER_OFF failure\n"); | ||
1132 | return; | ||
1133 | } | ||
1134 | |||
1135 | queue = &info->queue; | ||
1136 | |||
1137 | queue->__system_part = queuep; | ||
1138 | |||
1139 | memset(&queue->__user_part, 0, sizeof(netio_queue_user_impl_t)); | ||
1140 | |||
1141 | /* This is traditionally "config.num_receive_packets / 2". */ | ||
1142 | queue->__user_part.__receive_credit_interval = 4; | ||
1143 | queue->__user_part.__receive_credit_remaining = | ||
1144 | queue->__user_part.__receive_credit_interval; | ||
1145 | |||
1146 | /* | ||
1147 | * Get a fastio index from the hypervisor. | ||
1148 | * ISSUE: Shouldn't this check the result? | ||
1149 | */ | ||
1150 | ret = hv_dev_pread(priv->hv_devhdl, 0, | ||
1151 | (HV_VirtAddr)&queue->__user_part.__fastio_index, | ||
1152 | sizeof(queue->__user_part.__fastio_index), | ||
1153 | NETIO_IPP_GET_FASTIO_OFF); | ||
1154 | PDEBUG("hv_dev_pread(NETIO_IPP_GET_FASTIO_OFF) returned %d\n", ret); | ||
1155 | |||
1156 | netif_napi_add(dev, &info->napi, tile_net_poll, 64); | ||
1157 | |||
1158 | /* Now we are registered. */ | ||
1159 | info->registered = true; | ||
1160 | } | ||
1161 | |||
1162 | |||
1163 | /* | ||
1164 | * Unregister with hypervisor on each CPU. | ||
1165 | */ | ||
1166 | static void tile_net_unregister(void *dev_ptr) | ||
1167 | { | ||
1168 | struct net_device *dev = (struct net_device *)dev_ptr; | ||
1169 | struct tile_net_priv *priv = netdev_priv(dev); | ||
1170 | int my_cpu = smp_processor_id(); | ||
1171 | struct tile_net_cpu *info = priv->cpu[my_cpu]; | ||
1172 | |||
1173 | int ret = 0; | ||
1174 | int dummy = 0; | ||
1175 | |||
1176 | /* Do nothing if never registered. */ | ||
1177 | if (info == NULL) | ||
1178 | return; | ||
1179 | |||
1180 | /* Do nothing if already unregistered. */ | ||
1181 | if (!info->registered) | ||
1182 | return; | ||
1183 | |||
1184 | /* | ||
1185 | * Unregister ourselves with LIPP. | ||
1186 | */ | ||
1187 | ret = hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy, | ||
1188 | sizeof(dummy), NETIO_IPP_INPUT_UNREGISTER_OFF); | ||
1189 | PDEBUG("hv_dev_pwrite(NETIO_IPP_INPUT_UNREGISTER_OFF) returned %d\n", | ||
1190 | ret); | ||
1191 | if (ret < 0) { | ||
1192 | /* FIXME: Just panic? */ | ||
1193 | pr_err("hv_dev_pwrite NETIO_IPP_INPUT_UNREGISTER_OFF" | ||
1194 | " failure %d\n", ret); | ||
1195 | } | ||
1196 | |||
1197 | /* | ||
1198 | * Discard all packets still in our NetIO queue. Hopefully, | ||
1199 | * once the unregister call is complete, there will be no | ||
1200 | * packets still in flight on the IDN. | ||
1201 | */ | ||
1202 | tile_net_discard_packets(dev); | ||
1203 | |||
1204 | /* Reset state. */ | ||
1205 | info->num_needed_small_buffers = 0; | ||
1206 | info->num_needed_large_buffers = 0; | ||
1207 | |||
1208 | /* Cancel egress timer. */ | ||
1209 | del_timer(&info->egress_timer); | ||
1210 | info->egress_timer_scheduled = false; | ||
1211 | |||
1212 | netif_napi_del(&info->napi); | ||
1213 | |||
1214 | /* Now we are unregistered. */ | ||
1215 | info->registered = false; | ||
1216 | } | ||
1217 | |||
1218 | |||
1219 | /* | ||
1220 | * Helper function for "tile_net_stop()". | ||
1221 | * | ||
1222 | * Also used to handle registration failure in "tile_net_open_inner()", | ||
1223 | * when "fully_opened" is known to be false, and the various extra | ||
1224 | * steps in "tile_net_stop()" are not necessary. ISSUE: It might be | ||
1225 | * simpler if we could just call "tile_net_stop()" anyway. | ||
1226 | */ | ||
1227 | static void tile_net_stop_aux(struct net_device *dev) | ||
1228 | { | ||
1229 | struct tile_net_priv *priv = netdev_priv(dev); | ||
1230 | |||
1231 | int dummy = 0; | ||
1232 | |||
1233 | /* Unregister all tiles, so LIPP will stop delivering packets. */ | ||
1234 | on_each_cpu(tile_net_unregister, (void *)dev, 1); | ||
1235 | |||
1236 | /* Stop LIPP/LEPP. */ | ||
1237 | if (hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy, | ||
1238 | sizeof(dummy), NETIO_IPP_STOP_SHIM_OFF) < 0) | ||
1239 | panic("Failed to stop LIPP/LEPP!\n"); | ||
1240 | |||
1241 | priv->partly_opened = 0; | ||
1242 | } | ||
1243 | |||
1244 | |||
1245 | /* | ||
1246 | * Disable ingress interrupts for the given device on the current cpu. | ||
1247 | */ | ||
1248 | static void tile_net_disable_intr(void *dev_ptr) | ||
1249 | { | ||
1250 | struct net_device *dev = (struct net_device *)dev_ptr; | ||
1251 | struct tile_net_priv *priv = netdev_priv(dev); | ||
1252 | int my_cpu = smp_processor_id(); | ||
1253 | struct tile_net_cpu *info = priv->cpu[my_cpu]; | ||
1254 | |||
1255 | /* Disable hypervisor interrupt. */ | ||
1256 | disable_percpu_irq(priv->intr_id); | ||
1257 | |||
1258 | /* Disable NAPI if needed. */ | ||
1259 | if (info != NULL && info->napi_enabled) { | ||
1260 | napi_disable(&info->napi); | ||
1261 | info->napi_enabled = false; | ||
1262 | } | ||
1263 | } | ||
1264 | |||
1265 | |||
1266 | /* | ||
1267 | * Enable ingress interrupts for the given device on the current cpu. | ||
1268 | */ | ||
1269 | static void tile_net_enable_intr(void *dev_ptr) | ||
1270 | { | ||
1271 | struct net_device *dev = (struct net_device *)dev_ptr; | ||
1272 | struct tile_net_priv *priv = netdev_priv(dev); | ||
1273 | int my_cpu = smp_processor_id(); | ||
1274 | struct tile_net_cpu *info = priv->cpu[my_cpu]; | ||
1275 | |||
1276 | /* Enable hypervisor interrupt. */ | ||
1277 | enable_percpu_irq(priv->intr_id); | ||
1278 | |||
1279 | /* Enable NAPI. */ | ||
1280 | napi_enable(&info->napi); | ||
1281 | info->napi_enabled = true; | ||
1282 | } | ||
1283 | |||
1284 | |||
1285 | /* | ||
1286 | * tile_net_open_inner does most of the work of bringing up the interface. | ||
1287 | * It's called from tile_net_open(), and also from tile_net_retry_open(). | ||
1288 | * The return value is 0 if the interface was brought up, < 0 if | ||
1289 | * tile_net_open() should return the return value as an error, and > 0 if | ||
1290 | * tile_net_open() should return success and schedule a work item to | ||
1291 | * periodically retry the bringup. | ||
1292 | */ | ||
1293 | static int tile_net_open_inner(struct net_device *dev) | ||
1294 | { | ||
1295 | struct tile_net_priv *priv = netdev_priv(dev); | ||
1296 | int my_cpu = smp_processor_id(); | ||
1297 | struct tile_net_cpu *info; | ||
1298 | struct tile_netio_queue *queue; | ||
1299 | unsigned int irq; | ||
1300 | int i; | ||
1301 | |||
1302 | /* | ||
1303 | * First try to register just on the local CPU, and handle any | ||
1304 | * semi-expected "link down" failure specially. Note that we | ||
1305 | * do NOT call "tile_net_stop_aux()", unlike below. | ||
1306 | */ | ||
1307 | tile_net_register(dev); | ||
1308 | info = priv->cpu[my_cpu]; | ||
1309 | if (!info->registered) { | ||
1310 | if (info->link_down) | ||
1311 | return 1; | ||
1312 | return -EAGAIN; | ||
1313 | } | ||
1314 | |||
1315 | /* | ||
1316 | * Now register everywhere else. If any registration fails, | ||
1317 | * even for "link down" (which might not be possible), we | ||
1318 | * clean up using "tile_net_stop_aux()". | ||
1319 | */ | ||
1320 | smp_call_function(tile_net_register, (void *)dev, 1); | ||
1321 | for_each_online_cpu(i) { | ||
1322 | if (!priv->cpu[i]->registered) { | ||
1323 | tile_net_stop_aux(dev); | ||
1324 | return -EAGAIN; | ||
1325 | } | ||
1326 | } | ||
1327 | |||
1328 | queue = &info->queue; | ||
1329 | |||
1330 | /* | ||
1331 | * Set the device intr bit mask. | ||
1332 | * The tile_net_register above sets per tile __intr_id. | ||
1333 | */ | ||
1334 | priv->intr_id = queue->__system_part->__intr_id; | ||
1335 | BUG_ON(!priv->intr_id); | ||
1336 | |||
1337 | /* | ||
1338 | * Register the device interrupt handler. | ||
1339 | * The __ffs() function returns the index into the interrupt handler | ||
1340 | * table from the interrupt bit mask which should have one bit | ||
1341 | * and one bit only set. | ||
1342 | */ | ||
1343 | irq = __ffs(priv->intr_id); | ||
1344 | tile_irq_activate(irq, TILE_IRQ_PERCPU); | ||
1345 | BUG_ON(request_irq(irq, tile_net_handle_ingress_interrupt, | ||
1346 | 0, dev->name, (void *)dev) != 0); | ||
1347 | |||
1348 | /* ISSUE: How could "priv->fully_opened" ever be "true" here? */ | ||
1349 | |||
1350 | if (!priv->fully_opened) { | ||
1351 | |||
1352 | int dummy = 0; | ||
1353 | |||
1354 | /* Allocate initial buffers. */ | ||
1355 | |||
1356 | int max_buffers = | ||
1357 | priv->network_cpus_count * priv->network_cpus_credits; | ||
1358 | |||
1359 | info->num_needed_small_buffers = | ||
1360 | min(LIPP_SMALL_BUFFERS, max_buffers); | ||
1361 | |||
1362 | info->num_needed_large_buffers = | ||
1363 | min(LIPP_LARGE_BUFFERS, max_buffers); | ||
1364 | |||
1365 | tile_net_provide_needed_buffers(info); | ||
1366 | |||
1367 | if (info->num_needed_small_buffers != 0 || | ||
1368 | info->num_needed_large_buffers != 0) | ||
1369 | panic("Insufficient memory for buffer stack!"); | ||
1370 | |||
1371 | /* Start LIPP/LEPP and activate "ingress" at the shim. */ | ||
1372 | if (hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy, | ||
1373 | sizeof(dummy), NETIO_IPP_INPUT_INIT_OFF) < 0) | ||
1374 | panic("Failed to activate the LIPP Shim!\n"); | ||
1375 | |||
1376 | priv->fully_opened = 1; | ||
1377 | } | ||
1378 | |||
1379 | /* On each tile, enable the hypervisor to trigger interrupts. */ | ||
1380 | /* ISSUE: Do this before starting LIPP/LEPP? */ | ||
1381 | on_each_cpu(tile_net_enable_intr, (void *)dev, 1); | ||
1382 | |||
1383 | /* Start our transmit queue. */ | ||
1384 | netif_start_queue(dev); | ||
1385 | |||
1386 | return 0; | ||
1387 | } | ||
1388 | |||
1389 | |||
1390 | /* | ||
1391 | * Called periodically to retry bringing up the NetIO interface, | ||
1392 | * if it doesn't come up cleanly during tile_net_open(). | ||
1393 | */ | ||
1394 | static void tile_net_open_retry(struct work_struct *w) | ||
1395 | { | ||
1396 | struct delayed_work *dw = | ||
1397 | container_of(w, struct delayed_work, work); | ||
1398 | |||
1399 | struct tile_net_priv *priv = | ||
1400 | container_of(dw, struct tile_net_priv, retry_work); | ||
1401 | |||
1402 | /* | ||
1403 | * Try to bring the NetIO interface up. If it fails, reschedule | ||
1404 | * ourselves to try again later; otherwise, tell Linux we now have | ||
1405 | * a working link. ISSUE: What if the return value is negative? | ||
1406 | */ | ||
1407 | if (tile_net_open_inner(priv->dev)) | ||
1408 | schedule_delayed_work_on(singlethread_cpu, &priv->retry_work, | ||
1409 | TILE_NET_RETRY_INTERVAL); | ||
1410 | else | ||
1411 | netif_carrier_on(priv->dev); | ||
1412 | } | ||
1413 | |||
1414 | |||
1415 | /* | ||
1416 | * Called when a network interface is made active. | ||
1417 | * | ||
1418 | * Returns 0 on success, negative value on failure. | ||
1419 | * | ||
1420 | * The open entry point is called when a network interface is made | ||
1421 | * active by the system (IFF_UP). At this point all resources needed | ||
1422 | * for transmit and receive operations are allocated, the interrupt | ||
1423 | * handler is registered with the OS, the watchdog timer is started, | ||
1424 | * and the stack is notified that the interface is ready. | ||
1425 | * | ||
1426 | * If the actual link is not available yet, then we tell Linux that | ||
1427 | * we have no carrier, and we keep checking until the link comes up. | ||
1428 | */ | ||
1429 | static int tile_net_open(struct net_device *dev) | ||
1430 | { | ||
1431 | int ret = 0; | ||
1432 | struct tile_net_priv *priv = netdev_priv(dev); | ||
1433 | |||
1434 | /* | ||
1435 | * We rely on priv->partly_opened to tell us if this is the | ||
1436 | * first time this interface is being brought up. If it is | ||
1437 | * set, the IPP was already initialized and should not be | ||
1438 | * initialized again. | ||
1439 | */ | ||
1440 | if (!priv->partly_opened) { | ||
1441 | |||
1442 | int count; | ||
1443 | int credits; | ||
1444 | |||
1445 | /* Initialize LIPP/LEPP, and start the Shim. */ | ||
1446 | ret = tile_net_open_aux(dev); | ||
1447 | if (ret < 0) { | ||
1448 | pr_err("tile_net_open_aux failed: %d\n", ret); | ||
1449 | return ret; | ||
1450 | } | ||
1451 | |||
1452 | /* Analyze the network cpus. */ | ||
1453 | |||
1454 | if (network_cpus_used) | ||
1455 | cpumask_copy(&priv->network_cpus_map, | ||
1456 | &network_cpus_map); | ||
1457 | else | ||
1458 | cpumask_copy(&priv->network_cpus_map, cpu_online_mask); | ||
1459 | |||
1460 | |||
1461 | count = cpumask_weight(&priv->network_cpus_map); | ||
1462 | |||
1463 | /* Limit credits to available buffers, and apply min. */ | ||
1464 | credits = max(16, (LIPP_LARGE_BUFFERS / count) & ~1); | ||
1465 | |||
1466 | /* Apply "GBE" max limit. */ | ||
1467 | /* ISSUE: Use higher limit for XGBE? */ | ||
1468 | credits = min(NETIO_MAX_RECEIVE_PKTS, credits); | ||
1469 | |||
1470 | priv->network_cpus_count = count; | ||
1471 | priv->network_cpus_credits = credits; | ||
1472 | |||
1473 | #ifdef TILE_NET_DEBUG | ||
1474 | pr_info("Using %d network cpus, with %d credits each\n", | ||
1475 | priv->network_cpus_count, priv->network_cpus_credits); | ||
1476 | #endif | ||
1477 | |||
1478 | priv->partly_opened = 1; | ||
1479 | } | ||
1480 | |||
1481 | /* | ||
1482 | * Attempt to bring up the link. | ||
1483 | */ | ||
1484 | ret = tile_net_open_inner(dev); | ||
1485 | if (ret <= 0) { | ||
1486 | if (ret == 0) | ||
1487 | netif_carrier_on(dev); | ||
1488 | return ret; | ||
1489 | } | ||
1490 | |||
1491 | /* | ||
1492 | * We were unable to bring up the NetIO interface, but we want to | ||
1493 | * try again in a little bit. Tell Linux that we have no carrier | ||
1494 | * so it doesn't try to use the interface before the link comes up | ||
1495 | * and then remember to try again later. | ||
1496 | */ | ||
1497 | netif_carrier_off(dev); | ||
1498 | schedule_delayed_work_on(singlethread_cpu, &priv->retry_work, | ||
1499 | TILE_NET_RETRY_INTERVAL); | ||
1500 | |||
1501 | return 0; | ||
1502 | } | ||
1503 | |||
1504 | |||
1505 | /* | ||
1506 | * Disables a network interface. | ||
1507 | * | ||
1508 | * Returns 0, this is not allowed to fail. | ||
1509 | * | ||
1510 | * The close entry point is called when an interface is de-activated | ||
1511 | * by the OS. The hardware is still under the drivers control, but | ||
1512 | * needs to be disabled. A global MAC reset is issued to stop the | ||
1513 | * hardware, and all transmit and receive resources are freed. | ||
1514 | * | ||
1515 | * ISSUE: Can this can be called while "tile_net_poll()" is running? | ||
1516 | */ | ||
1517 | static int tile_net_stop(struct net_device *dev) | ||
1518 | { | ||
1519 | struct tile_net_priv *priv = netdev_priv(dev); | ||
1520 | |||
1521 | bool pending = true; | ||
1522 | |||
1523 | PDEBUG("tile_net_stop()\n"); | ||
1524 | |||
1525 | /* ISSUE: Only needed if not yet fully open. */ | ||
1526 | cancel_delayed_work_sync(&priv->retry_work); | ||
1527 | |||
1528 | /* Can't transmit any more. */ | ||
1529 | netif_stop_queue(dev); | ||
1530 | |||
1531 | /* | ||
1532 | * Disable hypervisor interrupts on each tile. | ||
1533 | */ | ||
1534 | on_each_cpu(tile_net_disable_intr, (void *)dev, 1); | ||
1535 | |||
1536 | /* | ||
1537 | * Unregister the interrupt handler. | ||
1538 | * The __ffs() function returns the index into the interrupt handler | ||
1539 | * table from the interrupt bit mask which should have one bit | ||
1540 | * and one bit only set. | ||
1541 | */ | ||
1542 | if (priv->intr_id) | ||
1543 | free_irq(__ffs(priv->intr_id), dev); | ||
1544 | |||
1545 | /* | ||
1546 | * Drain all the LIPP buffers. | ||
1547 | */ | ||
1548 | |||
1549 | while (true) { | ||
1550 | int buffer; | ||
1551 | |||
1552 | /* NOTE: This should never fail. */ | ||
1553 | if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&buffer, | ||
1554 | sizeof(buffer), NETIO_IPP_DRAIN_OFF) < 0) | ||
1555 | break; | ||
1556 | |||
1557 | /* Stop when done. */ | ||
1558 | if (buffer == 0) | ||
1559 | break; | ||
1560 | |||
1561 | { | ||
1562 | /* Convert "linux_buffer_t" to "va". */ | ||
1563 | void *va = __va((phys_addr_t)(buffer >> 1) << 7); | ||
1564 | |||
1565 | /* Acquire the associated "skb". */ | ||
1566 | struct sk_buff **skb_ptr = va - sizeof(*skb_ptr); | ||
1567 | struct sk_buff *skb = *skb_ptr; | ||
1568 | |||
1569 | kfree_skb(skb); | ||
1570 | } | ||
1571 | } | ||
1572 | |||
1573 | /* Stop LIPP/LEPP. */ | ||
1574 | tile_net_stop_aux(dev); | ||
1575 | |||
1576 | |||
1577 | priv->fully_opened = 0; | ||
1578 | |||
1579 | |||
1580 | /* | ||
1581 | * XXX: ISSUE: It appears that, in practice anyway, by the | ||
1582 | * time we get here, there are no pending completions. | ||
1583 | */ | ||
1584 | while (pending) { | ||
1585 | |||
1586 | struct sk_buff *olds[32]; | ||
1587 | unsigned int wanted = 32; | ||
1588 | unsigned int i, nolds = 0; | ||
1589 | |||
1590 | nolds = tile_net_lepp_grab_comps(dev, olds, | ||
1591 | wanted, &pending); | ||
1592 | |||
1593 | /* ISSUE: We have never actually seen this debug spew. */ | ||
1594 | if (nolds != 0) | ||
1595 | pr_info("During tile_net_stop(), grabbed %d comps.\n", | ||
1596 | nolds); | ||
1597 | |||
1598 | for (i = 0; i < nolds; i++) | ||
1599 | kfree_skb(olds[i]); | ||
1600 | } | ||
1601 | |||
1602 | |||
1603 | /* Wipe the EPP queue. */ | ||
1604 | memset(priv->epp_queue, 0, sizeof(lepp_queue_t)); | ||
1605 | |||
1606 | /* Evict the EPP queue. */ | ||
1607 | finv_buffer(priv->epp_queue, PAGE_SIZE); | ||
1608 | |||
1609 | return 0; | ||
1610 | } | ||
1611 | |||
1612 | |||
1613 | /* | ||
1614 | * Prepare the "frags" info for the resulting LEPP command. | ||
1615 | * | ||
1616 | * If needed, flush the memory used by the frags. | ||
1617 | */ | ||
1618 | static unsigned int tile_net_tx_frags(lepp_frag_t *frags, | ||
1619 | struct sk_buff *skb, | ||
1620 | void *b_data, unsigned int b_len) | ||
1621 | { | ||
1622 | unsigned int i, n = 0; | ||
1623 | |||
1624 | struct skb_shared_info *sh = skb_shinfo(skb); | ||
1625 | |||
1626 | phys_addr_t cpa; | ||
1627 | |||
1628 | if (b_len != 0) { | ||
1629 | |||
1630 | if (!hash_default) | ||
1631 | finv_buffer_remote(b_data, b_len); | ||
1632 | |||
1633 | cpa = __pa(b_data); | ||
1634 | frags[n].cpa_lo = cpa; | ||
1635 | frags[n].cpa_hi = cpa >> 32; | ||
1636 | frags[n].length = b_len; | ||
1637 | frags[n].hash_for_home = hash_default; | ||
1638 | n++; | ||
1639 | } | ||
1640 | |||
1641 | for (i = 0; i < sh->nr_frags; i++) { | ||
1642 | |||
1643 | skb_frag_t *f = &sh->frags[i]; | ||
1644 | unsigned long pfn = page_to_pfn(f->page); | ||
1645 | |||
1646 | /* FIXME: Compute "hash_for_home" properly. */ | ||
1647 | /* ISSUE: The hypervisor checks CHIP_HAS_REV1_DMA_PACKETS(). */ | ||
1648 | int hash_for_home = hash_default; | ||
1649 | |||
1650 | /* FIXME: Hmmm. */ | ||
1651 | if (!hash_default) { | ||
1652 | void *va = pfn_to_kaddr(pfn) + f->page_offset; | ||
1653 | BUG_ON(PageHighMem(f->page)); | ||
1654 | finv_buffer_remote(va, f->size); | ||
1655 | } | ||
1656 | |||
1657 | cpa = ((phys_addr_t)pfn << PAGE_SHIFT) + f->page_offset; | ||
1658 | frags[n].cpa_lo = cpa; | ||
1659 | frags[n].cpa_hi = cpa >> 32; | ||
1660 | frags[n].length = f->size; | ||
1661 | frags[n].hash_for_home = hash_for_home; | ||
1662 | n++; | ||
1663 | } | ||
1664 | |||
1665 | return n; | ||
1666 | } | ||
1667 | |||
1668 | |||
1669 | /* | ||
1670 | * This function takes "skb", consisting of a header template and a | ||
1671 | * payload, and hands it to LEPP, to emit as one or more segments, | ||
1672 | * each consisting of a possibly modified header, plus a piece of the | ||
1673 | * payload, via a process known as "tcp segmentation offload". | ||
1674 | * | ||
1675 | * Usually, "data" will contain the header template, of size "sh_len", | ||
1676 | * and "sh->frags" will contain "skb->data_len" bytes of payload, and | ||
1677 | * there will be "sh->gso_segs" segments. | ||
1678 | * | ||
1679 | * Sometimes, if "sendfile()" requires copying, we will be called with | ||
1680 | * "data" containing the header and payload, with "frags" being empty. | ||
1681 | * | ||
1682 | * In theory, "sh->nr_frags" could be 3, but in practice, it seems | ||
1683 | * that this will never actually happen. | ||
1684 | * | ||
1685 | * See "emulate_large_send_offload()" for some reference code, which | ||
1686 | * does not handle checksumming. | ||
1687 | * | ||
1688 | * ISSUE: How do we make sure that high memory DMA does not migrate? | ||
1689 | */ | ||
1690 | static int tile_net_tx_tso(struct sk_buff *skb, struct net_device *dev) | ||
1691 | { | ||
1692 | struct tile_net_priv *priv = netdev_priv(dev); | ||
1693 | int my_cpu = smp_processor_id(); | ||
1694 | struct tile_net_cpu *info = priv->cpu[my_cpu]; | ||
1695 | struct tile_net_stats_t *stats = &info->stats; | ||
1696 | |||
1697 | struct skb_shared_info *sh = skb_shinfo(skb); | ||
1698 | |||
1699 | unsigned char *data = skb->data; | ||
1700 | |||
1701 | /* The ip header follows the ethernet header. */ | ||
1702 | struct iphdr *ih = ip_hdr(skb); | ||
1703 | unsigned int ih_len = ih->ihl * 4; | ||
1704 | |||
1705 | /* Note that "nh == ih", by definition. */ | ||
1706 | unsigned char *nh = skb_network_header(skb); | ||
1707 | unsigned int eh_len = nh - data; | ||
1708 | |||
1709 | /* The tcp header follows the ip header. */ | ||
1710 | struct tcphdr *th = (struct tcphdr *)(nh + ih_len); | ||
1711 | unsigned int th_len = th->doff * 4; | ||
1712 | |||
1713 | /* The total number of header bytes. */ | ||
1714 | /* NOTE: This may be less than skb_headlen(skb). */ | ||
1715 | unsigned int sh_len = eh_len + ih_len + th_len; | ||
1716 | |||
1717 | /* The number of payload bytes at "skb->data + sh_len". */ | ||
1718 | /* This is non-zero for sendfile() without HIGHDMA. */ | ||
1719 | unsigned int b_len = skb_headlen(skb) - sh_len; | ||
1720 | |||
1721 | /* The total number of payload bytes. */ | ||
1722 | unsigned int d_len = b_len + skb->data_len; | ||
1723 | |||
1724 | /* The maximum payload size. */ | ||
1725 | unsigned int p_len = sh->gso_size; | ||
1726 | |||
1727 | /* The total number of segments. */ | ||
1728 | unsigned int num_segs = sh->gso_segs; | ||
1729 | |||
1730 | /* The temporary copy of the command. */ | ||
1731 | u32 cmd_body[(LEPP_MAX_CMD_SIZE + 3) / 4]; | ||
1732 | lepp_tso_cmd_t *cmd = (lepp_tso_cmd_t *)cmd_body; | ||
1733 | |||
1734 | /* Analyze the "frags". */ | ||
1735 | unsigned int num_frags = | ||
1736 | tile_net_tx_frags(cmd->frags, skb, data + sh_len, b_len); | ||
1737 | |||
1738 | /* The size of the command, including frags and header. */ | ||
1739 | size_t cmd_size = LEPP_TSO_CMD_SIZE(num_frags, sh_len); | ||
1740 | |||
1741 | /* The command header. */ | ||
1742 | lepp_tso_cmd_t cmd_init = { | ||
1743 | .tso = true, | ||
1744 | .header_size = sh_len, | ||
1745 | .ip_offset = eh_len, | ||
1746 | .tcp_offset = eh_len + ih_len, | ||
1747 | .payload_size = p_len, | ||
1748 | .num_frags = num_frags, | ||
1749 | }; | ||
1750 | |||
1751 | unsigned long irqflags; | ||
1752 | |||
1753 | lepp_queue_t *eq = priv->epp_queue; | ||
1754 | |||
1755 | struct sk_buff *olds[4]; | ||
1756 | unsigned int wanted = 4; | ||
1757 | unsigned int i, nolds = 0; | ||
1758 | |||
1759 | unsigned int cmd_head, cmd_tail, cmd_next; | ||
1760 | unsigned int comp_tail; | ||
1761 | |||
1762 | unsigned int free_slots; | ||
1763 | |||
1764 | |||
1765 | /* Paranoia. */ | ||
1766 | BUG_ON(skb->protocol != htons(ETH_P_IP)); | ||
1767 | BUG_ON(ih->protocol != IPPROTO_TCP); | ||
1768 | BUG_ON(skb->ip_summed != CHECKSUM_PARTIAL); | ||
1769 | BUG_ON(num_frags > LEPP_MAX_FRAGS); | ||
1770 | /*--BUG_ON(num_segs != (d_len + (p_len - 1)) / p_len); */ | ||
1771 | BUG_ON(num_segs <= 1); | ||
1772 | |||
1773 | |||
1774 | /* Finish preparing the command. */ | ||
1775 | |||
1776 | /* Copy the command header. */ | ||
1777 | *cmd = cmd_init; | ||
1778 | |||
1779 | /* Copy the "header". */ | ||
1780 | memcpy(&cmd->frags[num_frags], data, sh_len); | ||
1781 | |||
1782 | |||
1783 | /* Prefetch and wait, to minimize time spent holding the spinlock. */ | ||
1784 | prefetch_L1(&eq->comp_tail); | ||
1785 | prefetch_L1(&eq->cmd_tail); | ||
1786 | mb(); | ||
1787 | |||
1788 | |||
1789 | /* Enqueue the command. */ | ||
1790 | |||
1791 | spin_lock_irqsave(&priv->cmd_lock, irqflags); | ||
1792 | |||
1793 | /* | ||
1794 | * Handle completions if needed to make room. | ||
1795 | * HACK: Spin until there is sufficient room. | ||
1796 | */ | ||
1797 | free_slots = lepp_num_free_comp_slots(eq); | ||
1798 | if (free_slots < 1) { | ||
1799 | spin: | ||
1800 | nolds += tile_net_lepp_grab_comps(dev, olds + nolds, | ||
1801 | wanted - nolds, NULL); | ||
1802 | if (lepp_num_free_comp_slots(eq) < 1) | ||
1803 | goto spin; | ||
1804 | } | ||
1805 | |||
1806 | cmd_head = eq->cmd_head; | ||
1807 | cmd_tail = eq->cmd_tail; | ||
1808 | |||
1809 | /* NOTE: The "gotos" below are untested. */ | ||
1810 | |||
1811 | /* Prepare to advance, detecting full queue. */ | ||
1812 | cmd_next = cmd_tail + cmd_size; | ||
1813 | if (cmd_tail < cmd_head && cmd_next >= cmd_head) | ||
1814 | goto spin; | ||
1815 | if (cmd_next > LEPP_CMD_LIMIT) { | ||
1816 | cmd_next = 0; | ||
1817 | if (cmd_next == cmd_head) | ||
1818 | goto spin; | ||
1819 | } | ||
1820 | |||
1821 | /* Copy the command. */ | ||
1822 | memcpy(&eq->cmds[cmd_tail], cmd, cmd_size); | ||
1823 | |||
1824 | /* Advance. */ | ||
1825 | cmd_tail = cmd_next; | ||
1826 | |||
1827 | /* Record "skb" for eventual freeing. */ | ||
1828 | comp_tail = eq->comp_tail; | ||
1829 | eq->comps[comp_tail] = skb; | ||
1830 | LEPP_QINC(comp_tail); | ||
1831 | eq->comp_tail = comp_tail; | ||
1832 | |||
1833 | /* Flush before allowing LEPP to handle the command. */ | ||
1834 | __insn_mf(); | ||
1835 | |||
1836 | eq->cmd_tail = cmd_tail; | ||
1837 | |||
1838 | spin_unlock_irqrestore(&priv->cmd_lock, irqflags); | ||
1839 | |||
1840 | if (nolds == 0) | ||
1841 | nolds = tile_net_lepp_grab_comps(dev, olds, wanted, NULL); | ||
1842 | |||
1843 | /* Handle completions. */ | ||
1844 | for (i = 0; i < nolds; i++) | ||
1845 | kfree_skb(olds[i]); | ||
1846 | |||
1847 | /* Update stats. */ | ||
1848 | stats->tx_packets += num_segs; | ||
1849 | stats->tx_bytes += (num_segs * sh_len) + d_len; | ||
1850 | |||
1851 | /* Make sure the egress timer is scheduled. */ | ||
1852 | tile_net_schedule_egress_timer(info); | ||
1853 | |||
1854 | return NETDEV_TX_OK; | ||
1855 | } | ||
1856 | |||
1857 | |||
1858 | /* | ||
1859 | * Transmit a packet (called by the kernel via "hard_start_xmit" hook). | ||
1860 | */ | ||
1861 | static int tile_net_tx(struct sk_buff *skb, struct net_device *dev) | ||
1862 | { | ||
1863 | struct tile_net_priv *priv = netdev_priv(dev); | ||
1864 | int my_cpu = smp_processor_id(); | ||
1865 | struct tile_net_cpu *info = priv->cpu[my_cpu]; | ||
1866 | struct tile_net_stats_t *stats = &info->stats; | ||
1867 | |||
1868 | unsigned long irqflags; | ||
1869 | |||
1870 | struct skb_shared_info *sh = skb_shinfo(skb); | ||
1871 | |||
1872 | unsigned int len = skb->len; | ||
1873 | unsigned char *data = skb->data; | ||
1874 | |||
1875 | unsigned int csum_start = skb->csum_start - skb_headroom(skb); | ||
1876 | |||
1877 | lepp_frag_t frags[LEPP_MAX_FRAGS]; | ||
1878 | |||
1879 | unsigned int num_frags; | ||
1880 | |||
1881 | lepp_queue_t *eq = priv->epp_queue; | ||
1882 | |||
1883 | struct sk_buff *olds[4]; | ||
1884 | unsigned int wanted = 4; | ||
1885 | unsigned int i, nolds = 0; | ||
1886 | |||
1887 | unsigned int cmd_size = sizeof(lepp_cmd_t); | ||
1888 | |||
1889 | unsigned int cmd_head, cmd_tail, cmd_next; | ||
1890 | unsigned int comp_tail; | ||
1891 | |||
1892 | lepp_cmd_t cmds[LEPP_MAX_FRAGS]; | ||
1893 | |||
1894 | unsigned int free_slots; | ||
1895 | |||
1896 | |||
1897 | /* | ||
1898 | * This is paranoia, since we think that if the link doesn't come | ||
1899 | * up, telling Linux we have no carrier will keep it from trying | ||
1900 | * to transmit. If it does, though, we can't execute this routine, | ||
1901 | * since data structures we depend on aren't set up yet. | ||
1902 | */ | ||
1903 | if (!info->registered) | ||
1904 | return NETDEV_TX_BUSY; | ||
1905 | |||
1906 | |||
1907 | /* Save the timestamp. */ | ||
1908 | dev->trans_start = jiffies; | ||
1909 | |||
1910 | |||
1911 | #ifdef TILE_NET_PARANOIA | ||
1912 | #if CHIP_HAS_CBOX_HOME_MAP() | ||
1913 | if (hash_default) { | ||
1914 | HV_PTE pte = *virt_to_pte(current->mm, (unsigned long)data); | ||
1915 | if (hv_pte_get_mode(pte) != HV_PTE_MODE_CACHE_HASH_L3) | ||
1916 | panic("Non-coherent egress buffer!"); | ||
1917 | } | ||
1918 | #endif | ||
1919 | #endif | ||
1920 | |||
1921 | |||
1922 | #ifdef TILE_NET_DUMP_PACKETS | ||
1923 | /* ISSUE: Does not dump the "frags". */ | ||
1924 | dump_packet(data, skb_headlen(skb), "tx"); | ||
1925 | #endif /* TILE_NET_DUMP_PACKETS */ | ||
1926 | |||
1927 | |||
1928 | if (sh->gso_size != 0) | ||
1929 | return tile_net_tx_tso(skb, dev); | ||
1930 | |||
1931 | |||
1932 | /* Prepare the commands. */ | ||
1933 | |||
1934 | num_frags = tile_net_tx_frags(frags, skb, data, skb_headlen(skb)); | ||
1935 | |||
1936 | for (i = 0; i < num_frags; i++) { | ||
1937 | |||
1938 | bool final = (i == num_frags - 1); | ||
1939 | |||
1940 | lepp_cmd_t cmd = { | ||
1941 | .cpa_lo = frags[i].cpa_lo, | ||
1942 | .cpa_hi = frags[i].cpa_hi, | ||
1943 | .length = frags[i].length, | ||
1944 | .hash_for_home = frags[i].hash_for_home, | ||
1945 | .send_completion = final, | ||
1946 | .end_of_packet = final | ||
1947 | }; | ||
1948 | |||
1949 | if (i == 0 && skb->ip_summed == CHECKSUM_PARTIAL) { | ||
1950 | cmd.compute_checksum = 1; | ||
1951 | cmd.checksum_data.bits.start_byte = csum_start; | ||
1952 | cmd.checksum_data.bits.count = len - csum_start; | ||
1953 | cmd.checksum_data.bits.destination_byte = | ||
1954 | csum_start + skb->csum_offset; | ||
1955 | } | ||
1956 | |||
1957 | cmds[i] = cmd; | ||
1958 | } | ||
1959 | |||
1960 | |||
1961 | /* Prefetch and wait, to minimize time spent holding the spinlock. */ | ||
1962 | prefetch_L1(&eq->comp_tail); | ||
1963 | prefetch_L1(&eq->cmd_tail); | ||
1964 | mb(); | ||
1965 | |||
1966 | |||
1967 | /* Enqueue the commands. */ | ||
1968 | |||
1969 | spin_lock_irqsave(&priv->cmd_lock, irqflags); | ||
1970 | |||
1971 | /* | ||
1972 | * Handle completions if needed to make room. | ||
1973 | * HACK: Spin until there is sufficient room. | ||
1974 | */ | ||
1975 | free_slots = lepp_num_free_comp_slots(eq); | ||
1976 | if (free_slots < 1) { | ||
1977 | spin: | ||
1978 | nolds += tile_net_lepp_grab_comps(dev, olds + nolds, | ||
1979 | wanted - nolds, NULL); | ||
1980 | if (lepp_num_free_comp_slots(eq) < 1) | ||
1981 | goto spin; | ||
1982 | } | ||
1983 | |||
1984 | cmd_head = eq->cmd_head; | ||
1985 | cmd_tail = eq->cmd_tail; | ||
1986 | |||
1987 | /* NOTE: The "gotos" below are untested. */ | ||
1988 | |||
1989 | /* Copy the commands, or fail. */ | ||
1990 | for (i = 0; i < num_frags; i++) { | ||
1991 | |||
1992 | /* Prepare to advance, detecting full queue. */ | ||
1993 | cmd_next = cmd_tail + cmd_size; | ||
1994 | if (cmd_tail < cmd_head && cmd_next >= cmd_head) | ||
1995 | goto spin; | ||
1996 | if (cmd_next > LEPP_CMD_LIMIT) { | ||
1997 | cmd_next = 0; | ||
1998 | if (cmd_next == cmd_head) | ||
1999 | goto spin; | ||
2000 | } | ||
2001 | |||
2002 | /* Copy the command. */ | ||
2003 | *(lepp_cmd_t *)&eq->cmds[cmd_tail] = cmds[i]; | ||
2004 | |||
2005 | /* Advance. */ | ||
2006 | cmd_tail = cmd_next; | ||
2007 | } | ||
2008 | |||
2009 | /* Record "skb" for eventual freeing. */ | ||
2010 | comp_tail = eq->comp_tail; | ||
2011 | eq->comps[comp_tail] = skb; | ||
2012 | LEPP_QINC(comp_tail); | ||
2013 | eq->comp_tail = comp_tail; | ||
2014 | |||
2015 | /* Flush before allowing LEPP to handle the command. */ | ||
2016 | __insn_mf(); | ||
2017 | |||
2018 | eq->cmd_tail = cmd_tail; | ||
2019 | |||
2020 | spin_unlock_irqrestore(&priv->cmd_lock, irqflags); | ||
2021 | |||
2022 | if (nolds == 0) | ||
2023 | nolds = tile_net_lepp_grab_comps(dev, olds, wanted, NULL); | ||
2024 | |||
2025 | /* Handle completions. */ | ||
2026 | for (i = 0; i < nolds; i++) | ||
2027 | kfree_skb(olds[i]); | ||
2028 | |||
2029 | /* HACK: Track "expanded" size for short packets (e.g. 42 < 60). */ | ||
2030 | stats->tx_packets++; | ||
2031 | stats->tx_bytes += ((len >= ETH_ZLEN) ? len : ETH_ZLEN); | ||
2032 | |||
2033 | /* Make sure the egress timer is scheduled. */ | ||
2034 | tile_net_schedule_egress_timer(info); | ||
2035 | |||
2036 | return NETDEV_TX_OK; | ||
2037 | } | ||
2038 | |||
2039 | |||
2040 | /* | ||
2041 | * Deal with a transmit timeout. | ||
2042 | */ | ||
2043 | static void tile_net_tx_timeout(struct net_device *dev) | ||
2044 | { | ||
2045 | PDEBUG("tile_net_tx_timeout()\n"); | ||
2046 | PDEBUG("Transmit timeout at %ld, latency %ld\n", jiffies, | ||
2047 | jiffies - dev->trans_start); | ||
2048 | |||
2049 | /* XXX: ISSUE: This doesn't seem useful for us. */ | ||
2050 | netif_wake_queue(dev); | ||
2051 | } | ||
2052 | |||
2053 | |||
2054 | /* | ||
2055 | * Ioctl commands. | ||
2056 | */ | ||
2057 | static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | ||
2058 | { | ||
2059 | return -EOPNOTSUPP; | ||
2060 | } | ||
2061 | |||
2062 | |||
2063 | /* | ||
2064 | * Get System Network Statistics. | ||
2065 | * | ||
2066 | * Returns the address of the device statistics structure. | ||
2067 | */ | ||
2068 | static struct net_device_stats *tile_net_get_stats(struct net_device *dev) | ||
2069 | { | ||
2070 | struct tile_net_priv *priv = netdev_priv(dev); | ||
2071 | u32 rx_packets = 0; | ||
2072 | u32 tx_packets = 0; | ||
2073 | u32 rx_bytes = 0; | ||
2074 | u32 tx_bytes = 0; | ||
2075 | int i; | ||
2076 | |||
2077 | for_each_online_cpu(i) { | ||
2078 | if (priv->cpu[i]) { | ||
2079 | rx_packets += priv->cpu[i]->stats.rx_packets; | ||
2080 | rx_bytes += priv->cpu[i]->stats.rx_bytes; | ||
2081 | tx_packets += priv->cpu[i]->stats.tx_packets; | ||
2082 | tx_bytes += priv->cpu[i]->stats.tx_bytes; | ||
2083 | } | ||
2084 | } | ||
2085 | |||
2086 | priv->stats.rx_packets = rx_packets; | ||
2087 | priv->stats.rx_bytes = rx_bytes; | ||
2088 | priv->stats.tx_packets = tx_packets; | ||
2089 | priv->stats.tx_bytes = tx_bytes; | ||
2090 | |||
2091 | return &priv->stats; | ||
2092 | } | ||
2093 | |||
2094 | |||
2095 | /* | ||
2096 | * Change the "mtu". | ||
2097 | * | ||
2098 | * The "change_mtu" method is usually not needed. | ||
2099 | * If you need it, it must be like this. | ||
2100 | */ | ||
2101 | static int tile_net_change_mtu(struct net_device *dev, int new_mtu) | ||
2102 | { | ||
2103 | PDEBUG("tile_net_change_mtu()\n"); | ||
2104 | |||
2105 | /* Check ranges. */ | ||
2106 | if ((new_mtu < 68) || (new_mtu > 1500)) | ||
2107 | return -EINVAL; | ||
2108 | |||
2109 | /* Accept the value. */ | ||
2110 | dev->mtu = new_mtu; | ||
2111 | |||
2112 | return 0; | ||
2113 | } | ||
2114 | |||
2115 | |||
2116 | /* | ||
2117 | * Change the Ethernet Address of the NIC. | ||
2118 | * | ||
2119 | * The hypervisor driver does not support changing MAC address. However, | ||
2120 | * the IPP does not do anything with the MAC address, so the address which | ||
2121 | * gets used on outgoing packets, and which is accepted on incoming packets, | ||
2122 | * is completely up to the NetIO program or kernel driver which is actually | ||
2123 | * handling them. | ||
2124 | * | ||
2125 | * Returns 0 on success, negative on failure. | ||
2126 | */ | ||
2127 | static int tile_net_set_mac_address(struct net_device *dev, void *p) | ||
2128 | { | ||
2129 | struct sockaddr *addr = p; | ||
2130 | |||
2131 | if (!is_valid_ether_addr(addr->sa_data)) | ||
2132 | return -EINVAL; | ||
2133 | |||
2134 | /* ISSUE: Note that "dev_addr" is now a pointer. */ | ||
2135 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | ||
2136 | |||
2137 | return 0; | ||
2138 | } | ||
2139 | |||
2140 | |||
2141 | /* | ||
2142 | * Obtain the MAC address from the hypervisor. | ||
2143 | * This must be done before opening the device. | ||
2144 | */ | ||
2145 | static int tile_net_get_mac(struct net_device *dev) | ||
2146 | { | ||
2147 | struct tile_net_priv *priv = netdev_priv(dev); | ||
2148 | |||
2149 | char hv_dev_name[32]; | ||
2150 | int len; | ||
2151 | |||
2152 | __netio_getset_offset_t offset = { .word = NETIO_IPP_PARAM_OFF }; | ||
2153 | |||
2154 | int ret; | ||
2155 | |||
2156 | /* For example, "xgbe0". */ | ||
2157 | strcpy(hv_dev_name, dev->name); | ||
2158 | len = strlen(hv_dev_name); | ||
2159 | |||
2160 | /* For example, "xgbe/0". */ | ||
2161 | hv_dev_name[len] = hv_dev_name[len - 1]; | ||
2162 | hv_dev_name[len - 1] = '/'; | ||
2163 | len++; | ||
2164 | |||
2165 | /* For example, "xgbe/0/native_hash". */ | ||
2166 | strcpy(hv_dev_name + len, hash_default ? "/native_hash" : "/native"); | ||
2167 | |||
2168 | /* Get the hypervisor handle for this device. */ | ||
2169 | priv->hv_devhdl = hv_dev_open((HV_VirtAddr)hv_dev_name, 0); | ||
2170 | PDEBUG("hv_dev_open(%s) returned %d %p\n", | ||
2171 | hv_dev_name, priv->hv_devhdl, &priv->hv_devhdl); | ||
2172 | if (priv->hv_devhdl < 0) { | ||
2173 | if (priv->hv_devhdl == HV_ENODEV) | ||
2174 | printk(KERN_DEBUG "Ignoring unconfigured device %s\n", | ||
2175 | hv_dev_name); | ||
2176 | else | ||
2177 | printk(KERN_DEBUG "hv_dev_open(%s) returned %d\n", | ||
2178 | hv_dev_name, priv->hv_devhdl); | ||
2179 | return -1; | ||
2180 | } | ||
2181 | |||
2182 | /* | ||
2183 | * Read the hardware address from the hypervisor. | ||
2184 | * ISSUE: Note that "dev_addr" is now a pointer. | ||
2185 | */ | ||
2186 | offset.bits.class = NETIO_PARAM; | ||
2187 | offset.bits.addr = NETIO_PARAM_MAC; | ||
2188 | ret = hv_dev_pread(priv->hv_devhdl, 0, | ||
2189 | (HV_VirtAddr)dev->dev_addr, dev->addr_len, | ||
2190 | offset.word); | ||
2191 | PDEBUG("hv_dev_pread(NETIO_PARAM_MAC) returned %d\n", ret); | ||
2192 | if (ret <= 0) { | ||
2193 | printk(KERN_DEBUG "hv_dev_pread(NETIO_PARAM_MAC) %s failed\n", | ||
2194 | dev->name); | ||
2195 | /* | ||
2196 | * Since the device is configured by the hypervisor but we | ||
2197 | * can't get its MAC address, we are most likely running | ||
2198 | * the simulator, so let's generate a random MAC address. | ||
2199 | */ | ||
2200 | random_ether_addr(dev->dev_addr); | ||
2201 | } | ||
2202 | |||
2203 | return 0; | ||
2204 | } | ||
2205 | |||
2206 | |||
2207 | static struct net_device_ops tile_net_ops = { | ||
2208 | .ndo_open = tile_net_open, | ||
2209 | .ndo_stop = tile_net_stop, | ||
2210 | .ndo_start_xmit = tile_net_tx, | ||
2211 | .ndo_do_ioctl = tile_net_ioctl, | ||
2212 | .ndo_get_stats = tile_net_get_stats, | ||
2213 | .ndo_change_mtu = tile_net_change_mtu, | ||
2214 | .ndo_tx_timeout = tile_net_tx_timeout, | ||
2215 | .ndo_set_mac_address = tile_net_set_mac_address | ||
2216 | }; | ||
2217 | |||
2218 | |||
2219 | /* | ||
2220 | * The setup function. | ||
2221 | * | ||
2222 | * This uses ether_setup() to assign various fields in dev, including | ||
2223 | * setting IFF_BROADCAST and IFF_MULTICAST, then sets some extra fields. | ||
2224 | */ | ||
2225 | static void tile_net_setup(struct net_device *dev) | ||
2226 | { | ||
2227 | PDEBUG("tile_net_setup()\n"); | ||
2228 | |||
2229 | ether_setup(dev); | ||
2230 | |||
2231 | dev->netdev_ops = &tile_net_ops; | ||
2232 | |||
2233 | dev->watchdog_timeo = TILE_NET_TIMEOUT; | ||
2234 | |||
2235 | /* We want lockless xmit. */ | ||
2236 | dev->features |= NETIF_F_LLTX; | ||
2237 | |||
2238 | /* We support hardware tx checksums. */ | ||
2239 | dev->features |= NETIF_F_HW_CSUM; | ||
2240 | |||
2241 | /* We support scatter/gather. */ | ||
2242 | dev->features |= NETIF_F_SG; | ||
2243 | |||
2244 | /* We support TSO. */ | ||
2245 | dev->features |= NETIF_F_TSO; | ||
2246 | |||
2247 | #ifdef TILE_NET_GSO | ||
2248 | /* We support GSO. */ | ||
2249 | dev->features |= NETIF_F_GSO; | ||
2250 | #endif | ||
2251 | |||
2252 | if (hash_default) | ||
2253 | dev->features |= NETIF_F_HIGHDMA; | ||
2254 | |||
2255 | /* ISSUE: We should support NETIF_F_UFO. */ | ||
2256 | |||
2257 | dev->tx_queue_len = TILE_NET_TX_QUEUE_LEN; | ||
2258 | |||
2259 | dev->mtu = TILE_NET_MTU; | ||
2260 | } | ||
2261 | |||
2262 | |||
2263 | /* | ||
2264 | * Allocate the device structure, register the device, and obtain the | ||
2265 | * MAC address from the hypervisor. | ||
2266 | */ | ||
2267 | static struct net_device *tile_net_dev_init(const char *name) | ||
2268 | { | ||
2269 | int ret; | ||
2270 | struct net_device *dev; | ||
2271 | struct tile_net_priv *priv; | ||
2272 | struct page *page; | ||
2273 | |||
2274 | /* | ||
2275 | * Allocate the device structure. This allocates "priv", calls | ||
2276 | * tile_net_setup(), and saves "name". Normally, "name" is a | ||
2277 | * template, instantiated by register_netdev(), but not for us. | ||
2278 | */ | ||
2279 | dev = alloc_netdev(sizeof(*priv), name, tile_net_setup); | ||
2280 | if (!dev) { | ||
2281 | pr_err("alloc_netdev(%s) failed\n", name); | ||
2282 | return NULL; | ||
2283 | } | ||
2284 | |||
2285 | priv = netdev_priv(dev); | ||
2286 | |||
2287 | /* Initialize "priv". */ | ||
2288 | |||
2289 | memset(priv, 0, sizeof(*priv)); | ||
2290 | |||
2291 | /* Save "dev" for "tile_net_open_retry()". */ | ||
2292 | priv->dev = dev; | ||
2293 | |||
2294 | INIT_DELAYED_WORK(&priv->retry_work, tile_net_open_retry); | ||
2295 | |||
2296 | spin_lock_init(&priv->cmd_lock); | ||
2297 | spin_lock_init(&priv->comp_lock); | ||
2298 | |||
2299 | /* Allocate "epp_queue". */ | ||
2300 | BUG_ON(get_order(sizeof(lepp_queue_t)) != 0); | ||
2301 | page = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0); | ||
2302 | if (!page) { | ||
2303 | free_netdev(dev); | ||
2304 | return NULL; | ||
2305 | } | ||
2306 | priv->epp_queue = page_address(page); | ||
2307 | |||
2308 | /* Register the network device. */ | ||
2309 | ret = register_netdev(dev); | ||
2310 | if (ret) { | ||
2311 | pr_err("register_netdev %s failed %d\n", dev->name, ret); | ||
2312 | free_page((unsigned long)priv->epp_queue); | ||
2313 | free_netdev(dev); | ||
2314 | return NULL; | ||
2315 | } | ||
2316 | |||
2317 | /* Get the MAC address. */ | ||
2318 | ret = tile_net_get_mac(dev); | ||
2319 | if (ret < 0) { | ||
2320 | unregister_netdev(dev); | ||
2321 | free_page((unsigned long)priv->epp_queue); | ||
2322 | free_netdev(dev); | ||
2323 | return NULL; | ||
2324 | } | ||
2325 | |||
2326 | return dev; | ||
2327 | } | ||
2328 | |||
2329 | |||
2330 | /* | ||
2331 | * Module cleanup. | ||
2332 | */ | ||
2333 | static void tile_net_cleanup(void) | ||
2334 | { | ||
2335 | int i; | ||
2336 | |||
2337 | for (i = 0; i < TILE_NET_DEVS; i++) { | ||
2338 | if (tile_net_devs[i]) { | ||
2339 | struct net_device *dev = tile_net_devs[i]; | ||
2340 | struct tile_net_priv *priv = netdev_priv(dev); | ||
2341 | unregister_netdev(dev); | ||
2342 | finv_buffer(priv->epp_queue, PAGE_SIZE); | ||
2343 | free_page((unsigned long)priv->epp_queue); | ||
2344 | free_netdev(dev); | ||
2345 | } | ||
2346 | } | ||
2347 | } | ||
2348 | |||
2349 | |||
2350 | /* | ||
2351 | * Module initialization. | ||
2352 | */ | ||
2353 | static int tile_net_init_module(void) | ||
2354 | { | ||
2355 | pr_info("Tilera IPP Net Driver\n"); | ||
2356 | |||
2357 | tile_net_devs[0] = tile_net_dev_init("xgbe0"); | ||
2358 | tile_net_devs[1] = tile_net_dev_init("xgbe1"); | ||
2359 | tile_net_devs[2] = tile_net_dev_init("gbe0"); | ||
2360 | tile_net_devs[3] = tile_net_dev_init("gbe1"); | ||
2361 | |||
2362 | return 0; | ||
2363 | } | ||
2364 | |||
2365 | |||
2366 | #ifndef MODULE | ||
2367 | /* | ||
2368 | * The "network_cpus" boot argument specifies the cpus that are dedicated | ||
2369 | * to handle ingress packets. | ||
2370 | * | ||
2371 | * The parameter should be in the form "network_cpus=m-n[,x-y]", where | ||
2372 | * m, n, x, y are integer numbers that represent the cpus that can be | ||
2373 | * neither a dedicated cpu nor a dataplane cpu. | ||
2374 | */ | ||
2375 | static int __init network_cpus_setup(char *str) | ||
2376 | { | ||
2377 | int rc = cpulist_parse_crop(str, &network_cpus_map); | ||
2378 | if (rc != 0) { | ||
2379 | pr_warning("network_cpus=%s: malformed cpu list\n", | ||
2380 | str); | ||
2381 | } else { | ||
2382 | |||
2383 | /* Remove dedicated cpus. */ | ||
2384 | cpumask_and(&network_cpus_map, &network_cpus_map, | ||
2385 | cpu_possible_mask); | ||
2386 | |||
2387 | |||
2388 | if (cpumask_empty(&network_cpus_map)) { | ||
2389 | pr_warning("Ignoring network_cpus='%s'.\n", | ||
2390 | str); | ||
2391 | } else { | ||
2392 | char buf[1024]; | ||
2393 | cpulist_scnprintf(buf, sizeof(buf), &network_cpus_map); | ||
2394 | pr_info("Linux network CPUs: %s\n", buf); | ||
2395 | network_cpus_used = true; | ||
2396 | } | ||
2397 | } | ||
2398 | |||
2399 | return 0; | ||
2400 | } | ||
2401 | __setup("network_cpus=", network_cpus_setup); | ||
2402 | #endif | ||
2403 | |||
2404 | |||
2405 | module_init(tile_net_init_module); | ||
2406 | module_exit(tile_net_cleanup); | ||
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index f01e344cf4bd..98e6fdf34d30 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -49,6 +49,7 @@ obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o | |||
49 | obj-$(CONFIG_X86_VISWS) += setup-irq.o | 49 | obj-$(CONFIG_X86_VISWS) += setup-irq.o |
50 | obj-$(CONFIG_MN10300) += setup-bus.o | 50 | obj-$(CONFIG_MN10300) += setup-bus.o |
51 | obj-$(CONFIG_MICROBLAZE) += setup-bus.o | 51 | obj-$(CONFIG_MICROBLAZE) += setup-bus.o |
52 | obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o | ||
52 | 53 | ||
53 | # | 54 | # |
54 | # ACPI Related PCI FW Functions | 55 | # ACPI Related PCI FW Functions |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f5c63fe9db5c..6f9350cabbd5 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -2136,6 +2136,24 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, | |||
2136 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB, | 2136 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB, |
2137 | quirk_unhide_mch_dev6); | 2137 | quirk_unhide_mch_dev6); |
2138 | 2138 | ||
2139 | #ifdef CONFIG_TILE | ||
2140 | /* | ||
2141 | * The Tilera TILEmpower platform needs to set the link speed | ||
2142 | * to 2.5GT(Giga-Transfers)/s (Gen 1). The default link speed | ||
2143 | * setting is 5GT/s (Gen 2). 0x98 is the Link Control2 PCIe | ||
2144 | * capability register of the PEX8624 PCIe switch. The switch | ||
2145 | * supports link speed auto negotiation, but falsely sets | ||
2146 | * the link speed to 5GT/s. | ||
2147 | */ | ||
2148 | static void __devinit quirk_tile_plx_gen1(struct pci_dev *dev) | ||
2149 | { | ||
2150 | if (tile_plx_gen1) { | ||
2151 | pci_write_config_dword(dev, 0x98, 0x1); | ||
2152 | mdelay(50); | ||
2153 | } | ||
2154 | } | ||
2155 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8624, quirk_tile_plx_gen1); | ||
2156 | #endif /* CONFIG_TILE */ | ||
2139 | 2157 | ||
2140 | #ifdef CONFIG_PCI_MSI | 2158 | #ifdef CONFIG_PCI_MSI |
2141 | /* Some chipsets do not support MSI. We cannot easily rely on setting | 2159 | /* Some chipsets do not support MSI. We cannot easily rely on setting |
diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h index 377cfb72cc66..f30f8d659dc4 100644 --- a/drivers/scsi/arm/fas216.h +++ b/drivers/scsi/arm/fas216.h | |||
@@ -345,7 +345,7 @@ extern int fas216_queue_command(struct Scsi_Host *h, struct scsi_cmnd *SCpnt); | |||
345 | * : SCpnt - Command to queue | 345 | * : SCpnt - Command to queue |
346 | * Returns : 0 - success, else error | 346 | * Returns : 0 - success, else error |
347 | */ | 347 | */ |
348 | extern int fas216_noqueue_command(struct Scsi_Host *, struct scsi_cmnd *) | 348 | extern int fas216_noqueue_command(struct Scsi_Host *, struct scsi_cmnd *); |
349 | 349 | ||
350 | /* Function: irqreturn_t fas216_intr (FAS216_Info *info) | 350 | /* Function: irqreturn_t fas216_intr (FAS216_Info *info) |
351 | * Purpose : handle interrupts from the interface to progress a command | 351 | * Purpose : handle interrupts from the interface to progress a command |
diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c index cb12a8e1466b..3f5e387ed564 100644 --- a/drivers/sh/clk/core.c +++ b/drivers/sh/clk/core.c | |||
@@ -418,8 +418,11 @@ int clk_register(struct clk *clk) | |||
418 | list_add(&clk->sibling, &root_clks); | 418 | list_add(&clk->sibling, &root_clks); |
419 | 419 | ||
420 | list_add(&clk->node, &clock_list); | 420 | list_add(&clk->node, &clock_list); |
421 | |||
422 | #ifdef CONFIG_SH_CLK_CPG_LEGACY | ||
421 | if (clk->ops && clk->ops->init) | 423 | if (clk->ops && clk->ops->init) |
422 | clk->ops->init(clk); | 424 | clk->ops->init(clk); |
425 | #endif | ||
423 | 426 | ||
424 | out_unlock: | 427 | out_unlock: |
425 | mutex_unlock(&clock_list_sem); | 428 | mutex_unlock(&clock_list_sem); |
@@ -455,19 +458,13 @@ EXPORT_SYMBOL_GPL(clk_get_rate); | |||
455 | 458 | ||
456 | int clk_set_rate(struct clk *clk, unsigned long rate) | 459 | int clk_set_rate(struct clk *clk, unsigned long rate) |
457 | { | 460 | { |
458 | return clk_set_rate_ex(clk, rate, 0); | ||
459 | } | ||
460 | EXPORT_SYMBOL_GPL(clk_set_rate); | ||
461 | |||
462 | int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) | ||
463 | { | ||
464 | int ret = -EOPNOTSUPP; | 461 | int ret = -EOPNOTSUPP; |
465 | unsigned long flags; | 462 | unsigned long flags; |
466 | 463 | ||
467 | spin_lock_irqsave(&clock_lock, flags); | 464 | spin_lock_irqsave(&clock_lock, flags); |
468 | 465 | ||
469 | if (likely(clk->ops && clk->ops->set_rate)) { | 466 | if (likely(clk->ops && clk->ops->set_rate)) { |
470 | ret = clk->ops->set_rate(clk, rate, algo_id); | 467 | ret = clk->ops->set_rate(clk, rate); |
471 | if (ret != 0) | 468 | if (ret != 0) |
472 | goto out_unlock; | 469 | goto out_unlock; |
473 | } else { | 470 | } else { |
@@ -485,7 +482,7 @@ out_unlock: | |||
485 | 482 | ||
486 | return ret; | 483 | return ret; |
487 | } | 484 | } |
488 | EXPORT_SYMBOL_GPL(clk_set_rate_ex); | 485 | EXPORT_SYMBOL_GPL(clk_set_rate); |
489 | 486 | ||
490 | int clk_set_parent(struct clk *clk, struct clk *parent) | 487 | int clk_set_parent(struct clk *clk, struct clk *parent) |
491 | { | 488 | { |
@@ -653,8 +650,7 @@ static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) | |||
653 | clkp->ops->set_parent(clkp, | 650 | clkp->ops->set_parent(clkp, |
654 | clkp->parent); | 651 | clkp->parent); |
655 | if (likely(clkp->ops->set_rate)) | 652 | if (likely(clkp->ops->set_rate)) |
656 | clkp->ops->set_rate(clkp, | 653 | clkp->ops->set_rate(clkp, rate); |
657 | rate, NO_CHANGE); | ||
658 | else if (likely(clkp->ops->recalc)) | 654 | else if (likely(clkp->ops->recalc)) |
659 | clkp->rate = clkp->ops->recalc(clkp); | 655 | clkp->rate = clkp->ops->recalc(clkp); |
660 | } | 656 | } |
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 3aea5f0ceb09..6172335ae323 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c | |||
@@ -110,8 +110,7 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) | |||
110 | return 0; | 110 | return 0; |
111 | } | 111 | } |
112 | 112 | ||
113 | static int sh_clk_div6_set_rate(struct clk *clk, | 113 | static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate) |
114 | unsigned long rate, int algo_id) | ||
115 | { | 114 | { |
116 | unsigned long value; | 115 | unsigned long value; |
117 | int idx; | 116 | int idx; |
@@ -132,7 +131,7 @@ static int sh_clk_div6_enable(struct clk *clk) | |||
132 | unsigned long value; | 131 | unsigned long value; |
133 | int ret; | 132 | int ret; |
134 | 133 | ||
135 | ret = sh_clk_div6_set_rate(clk, clk->rate, 0); | 134 | ret = sh_clk_div6_set_rate(clk, clk->rate); |
136 | if (ret == 0) { | 135 | if (ret == 0) { |
137 | value = __raw_readl(clk->enable_reg); | 136 | value = __raw_readl(clk->enable_reg); |
138 | value &= ~0x100; /* clear stop bit to enable clock */ | 137 | value &= ~0x100; /* clear stop bit to enable clock */ |
@@ -253,7 +252,7 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) | |||
253 | return 0; | 252 | return 0; |
254 | } | 253 | } |
255 | 254 | ||
256 | static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id) | 255 | static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate) |
257 | { | 256 | { |
258 | struct clk_div4_table *d4t = clk->priv; | 257 | struct clk_div4_table *d4t = clk->priv; |
259 | unsigned long value; | 258 | unsigned long value; |
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index e207810bba3c..08703299ef61 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
@@ -197,12 +197,12 @@ static int backlight_suspend(struct device *dev, pm_message_t state) | |||
197 | { | 197 | { |
198 | struct backlight_device *bd = to_backlight_device(dev); | 198 | struct backlight_device *bd = to_backlight_device(dev); |
199 | 199 | ||
200 | if (bd->ops->options & BL_CORE_SUSPENDRESUME) { | 200 | mutex_lock(&bd->ops_lock); |
201 | mutex_lock(&bd->ops_lock); | 201 | if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) { |
202 | bd->props.state |= BL_CORE_SUSPENDED; | 202 | bd->props.state |= BL_CORE_SUSPENDED; |
203 | backlight_update_status(bd); | 203 | backlight_update_status(bd); |
204 | mutex_unlock(&bd->ops_lock); | ||
205 | } | 204 | } |
205 | mutex_unlock(&bd->ops_lock); | ||
206 | 206 | ||
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
@@ -211,12 +211,12 @@ static int backlight_resume(struct device *dev) | |||
211 | { | 211 | { |
212 | struct backlight_device *bd = to_backlight_device(dev); | 212 | struct backlight_device *bd = to_backlight_device(dev); |
213 | 213 | ||
214 | if (bd->ops->options & BL_CORE_SUSPENDRESUME) { | 214 | mutex_lock(&bd->ops_lock); |
215 | mutex_lock(&bd->ops_lock); | 215 | if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) { |
216 | bd->props.state &= ~BL_CORE_SUSPENDED; | 216 | bd->props.state &= ~BL_CORE_SUSPENDED; |
217 | backlight_update_status(bd); | 217 | backlight_update_status(bd); |
218 | mutex_unlock(&bd->ops_lock); | ||
219 | } | 218 | } |
219 | mutex_unlock(&bd->ops_lock); | ||
220 | 220 | ||
221 | return 0; | 221 | return 0; |
222 | } | 222 | } |
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c index f53b9f1d6aba..affdf3e32cf3 100644 --- a/drivers/video/fbcmap.c +++ b/drivers/video/fbcmap.c | |||
@@ -88,34 +88,48 @@ static const struct fb_cmap default_16_colors = { | |||
88 | * | 88 | * |
89 | */ | 89 | */ |
90 | 90 | ||
91 | int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp) | 91 | int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags) |
92 | { | 92 | { |
93 | int size = len*sizeof(u16); | 93 | int size = len * sizeof(u16); |
94 | 94 | int ret = -ENOMEM; | |
95 | if (cmap->len != len) { | 95 | |
96 | fb_dealloc_cmap(cmap); | 96 | if (cmap->len != len) { |
97 | if (!len) | 97 | fb_dealloc_cmap(cmap); |
98 | return 0; | 98 | if (!len) |
99 | if (!(cmap->red = kmalloc(size, GFP_ATOMIC))) | 99 | return 0; |
100 | goto fail; | 100 | |
101 | if (!(cmap->green = kmalloc(size, GFP_ATOMIC))) | 101 | cmap->red = kmalloc(size, flags); |
102 | goto fail; | 102 | if (!cmap->red) |
103 | if (!(cmap->blue = kmalloc(size, GFP_ATOMIC))) | 103 | goto fail; |
104 | goto fail; | 104 | cmap->green = kmalloc(size, flags); |
105 | if (transp) { | 105 | if (!cmap->green) |
106 | if (!(cmap->transp = kmalloc(size, GFP_ATOMIC))) | 106 | goto fail; |
107 | cmap->blue = kmalloc(size, flags); | ||
108 | if (!cmap->blue) | ||
109 | goto fail; | ||
110 | if (transp) { | ||
111 | cmap->transp = kmalloc(size, flags); | ||
112 | if (!cmap->transp) | ||
113 | goto fail; | ||
114 | } else { | ||
115 | cmap->transp = NULL; | ||
116 | } | ||
117 | } | ||
118 | cmap->start = 0; | ||
119 | cmap->len = len; | ||
120 | ret = fb_copy_cmap(fb_default_cmap(len), cmap); | ||
121 | if (ret) | ||
107 | goto fail; | 122 | goto fail; |
108 | } else | 123 | return 0; |
109 | cmap->transp = NULL; | ||
110 | } | ||
111 | cmap->start = 0; | ||
112 | cmap->len = len; | ||
113 | fb_copy_cmap(fb_default_cmap(len), cmap); | ||
114 | return 0; | ||
115 | 124 | ||
116 | fail: | 125 | fail: |
117 | fb_dealloc_cmap(cmap); | 126 | fb_dealloc_cmap(cmap); |
118 | return -ENOMEM; | 127 | return ret; |
128 | } | ||
129 | |||
130 | int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp) | ||
131 | { | ||
132 | return fb_alloc_cmap_gfp(cmap, len, transp, GFP_ATOMIC); | ||
119 | } | 133 | } |
120 | 134 | ||
121 | /** | 135 | /** |
@@ -250,8 +264,12 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) | |||
250 | int rc, size = cmap->len * sizeof(u16); | 264 | int rc, size = cmap->len * sizeof(u16); |
251 | struct fb_cmap umap; | 265 | struct fb_cmap umap; |
252 | 266 | ||
267 | if (size < 0 || size < cmap->len) | ||
268 | return -E2BIG; | ||
269 | |||
253 | memset(&umap, 0, sizeof(struct fb_cmap)); | 270 | memset(&umap, 0, sizeof(struct fb_cmap)); |
254 | rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL); | 271 | rc = fb_alloc_cmap_gfp(&umap, cmap->len, cmap->transp != NULL, |
272 | GFP_KERNEL); | ||
255 | if (rc) | 273 | if (rc) |
256 | return rc; | 274 | return rc; |
257 | if (copy_from_user(umap.red, cmap->red, size) || | 275 | if (copy_from_user(umap.red, cmap->red, size) || |
diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/geode/lxfb_ops.c index bc35a95e59d4..85ec7f64c42a 100644 --- a/drivers/video/geode/lxfb_ops.c +++ b/drivers/video/geode/lxfb_ops.c | |||
@@ -276,10 +276,10 @@ static void lx_graphics_enable(struct fb_info *info) | |||
276 | write_fp(par, FP_PT1, 0); | 276 | write_fp(par, FP_PT1, 0); |
277 | temp = FP_PT2_SCRC; | 277 | temp = FP_PT2_SCRC; |
278 | 278 | ||
279 | if (info->var.sync & FB_SYNC_HOR_HIGH_ACT) | 279 | if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT)) |
280 | temp |= FP_PT2_HSP; | 280 | temp |= FP_PT2_HSP; |
281 | 281 | ||
282 | if (info->var.sync & FB_SYNC_VERT_HIGH_ACT) | 282 | if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT)) |
283 | temp |= FP_PT2_VSP; | 283 | temp |= FP_PT2_VSP; |
284 | 284 | ||
285 | write_fp(par, FP_PT2, temp); | 285 | write_fp(par, FP_PT2, temp); |
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index 7cfc170bce19..ca0f6be9d12e 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
28 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
29 | 29 | ||
30 | #include <mach/dma.h> | ||
30 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
31 | #include <mach/ipu.h> | 32 | #include <mach/ipu.h> |
32 | #include <mach/mx3fb.h> | 33 | #include <mach/mx3fb.h> |
@@ -1420,6 +1421,9 @@ static bool chan_filter(struct dma_chan *chan, void *arg) | |||
1420 | struct device *dev; | 1421 | struct device *dev; |
1421 | struct mx3fb_platform_data *mx3fb_pdata; | 1422 | struct mx3fb_platform_data *mx3fb_pdata; |
1422 | 1423 | ||
1424 | if (!imx_dma_is_ipu(chan)) | ||
1425 | return false; | ||
1426 | |||
1423 | if (!rq) | 1427 | if (!rq) |
1424 | return false; | 1428 | return false; |
1425 | 1429 | ||
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 9b1364723c65..b02d97a879d6 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -860,7 +860,7 @@ static void sh_mobile_fb_reconfig(struct fb_info *info) | |||
860 | /* Couldn't reconfigure, hopefully, can continue as before */ | 860 | /* Couldn't reconfigure, hopefully, can continue as before */ |
861 | return; | 861 | return; |
862 | 862 | ||
863 | info->fix.line_length = mode2.xres * (ch->cfg.bpp / 8); | 863 | info->fix.line_length = mode1.xres * (ch->cfg.bpp / 8); |
864 | 864 | ||
865 | /* | 865 | /* |
866 | * fb_set_var() calls the notifier change internally, only if | 866 | * fb_set_var() calls the notifier change internally, only if |
@@ -868,7 +868,7 @@ static void sh_mobile_fb_reconfig(struct fb_info *info) | |||
868 | * user event, we have to call the chain ourselves. | 868 | * user event, we have to call the chain ourselves. |
869 | */ | 869 | */ |
870 | event.info = info; | 870 | event.info = info; |
871 | event.data = &mode2; | 871 | event.data = &mode1; |
872 | fb_notifier_call_chain(evnt, &event); | 872 | fb_notifier_call_chain(evnt, &event); |
873 | } | 873 | } |
874 | 874 | ||
diff --git a/drivers/video/sis/init.c b/drivers/video/sis/init.c index c311ad3c3687..31137adc8fba 100644 --- a/drivers/video/sis/init.c +++ b/drivers/video/sis/init.c | |||
@@ -62,11 +62,11 @@ | |||
62 | 62 | ||
63 | #include "init.h" | 63 | #include "init.h" |
64 | 64 | ||
65 | #ifdef SIS300 | 65 | #ifdef CONFIG_FB_SIS_300 |
66 | #include "300vtbl.h" | 66 | #include "300vtbl.h" |
67 | #endif | 67 | #endif |
68 | 68 | ||
69 | #ifdef SIS315H | 69 | #ifdef CONFIG_FB_SIS_315 |
70 | #include "310vtbl.h" | 70 | #include "310vtbl.h" |
71 | #endif | 71 | #endif |
72 | 72 | ||
@@ -78,7 +78,7 @@ | |||
78 | /* POINTER INITIALIZATION */ | 78 | /* POINTER INITIALIZATION */ |
79 | /*********************************************/ | 79 | /*********************************************/ |
80 | 80 | ||
81 | #if defined(SIS300) || defined(SIS315H) | 81 | #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) |
82 | static void | 82 | static void |
83 | InitCommonPointer(struct SiS_Private *SiS_Pr) | 83 | InitCommonPointer(struct SiS_Private *SiS_Pr) |
84 | { | 84 | { |
@@ -160,7 +160,7 @@ InitCommonPointer(struct SiS_Private *SiS_Pr) | |||
160 | } | 160 | } |
161 | #endif | 161 | #endif |
162 | 162 | ||
163 | #ifdef SIS300 | 163 | #ifdef CONFIG_FB_SIS_300 |
164 | static void | 164 | static void |
165 | InitTo300Pointer(struct SiS_Private *SiS_Pr) | 165 | InitTo300Pointer(struct SiS_Private *SiS_Pr) |
166 | { | 166 | { |
@@ -237,7 +237,7 @@ InitTo300Pointer(struct SiS_Private *SiS_Pr) | |||
237 | } | 237 | } |
238 | #endif | 238 | #endif |
239 | 239 | ||
240 | #ifdef SIS315H | 240 | #ifdef CONFIG_FB_SIS_315 |
241 | static void | 241 | static void |
242 | InitTo310Pointer(struct SiS_Private *SiS_Pr) | 242 | InitTo310Pointer(struct SiS_Private *SiS_Pr) |
243 | { | 243 | { |
@@ -321,13 +321,13 @@ bool | |||
321 | SiSInitPtr(struct SiS_Private *SiS_Pr) | 321 | SiSInitPtr(struct SiS_Private *SiS_Pr) |
322 | { | 322 | { |
323 | if(SiS_Pr->ChipType < SIS_315H) { | 323 | if(SiS_Pr->ChipType < SIS_315H) { |
324 | #ifdef SIS300 | 324 | #ifdef CONFIG_FB_SIS_300 |
325 | InitTo300Pointer(SiS_Pr); | 325 | InitTo300Pointer(SiS_Pr); |
326 | #else | 326 | #else |
327 | return false; | 327 | return false; |
328 | #endif | 328 | #endif |
329 | } else { | 329 | } else { |
330 | #ifdef SIS315H | 330 | #ifdef CONFIG_FB_SIS_315 |
331 | InitTo310Pointer(SiS_Pr); | 331 | InitTo310Pointer(SiS_Pr); |
332 | #else | 332 | #else |
333 | return false; | 333 | return false; |
@@ -340,9 +340,7 @@ SiSInitPtr(struct SiS_Private *SiS_Pr) | |||
340 | /* HELPER: Get ModeID */ | 340 | /* HELPER: Get ModeID */ |
341 | /*********************************************/ | 341 | /*********************************************/ |
342 | 342 | ||
343 | #ifndef SIS_XORG_XF86 | ||
344 | static | 343 | static |
345 | #endif | ||
346 | unsigned short | 344 | unsigned short |
347 | SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, | 345 | SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, |
348 | int Depth, bool FSTN, int LCDwidth, int LCDheight) | 346 | int Depth, bool FSTN, int LCDwidth, int LCDheight) |
@@ -884,51 +882,51 @@ SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDispl | |||
884 | void | 882 | void |
885 | SiS_SetReg(SISIOADDRESS port, unsigned short index, unsigned short data) | 883 | SiS_SetReg(SISIOADDRESS port, unsigned short index, unsigned short data) |
886 | { | 884 | { |
887 | OutPortByte(port, index); | 885 | outb((u8)index, port); |
888 | OutPortByte(port + 1, data); | 886 | outb((u8)data, port + 1); |
889 | } | 887 | } |
890 | 888 | ||
891 | void | 889 | void |
892 | SiS_SetRegByte(SISIOADDRESS port, unsigned short data) | 890 | SiS_SetRegByte(SISIOADDRESS port, unsigned short data) |
893 | { | 891 | { |
894 | OutPortByte(port, data); | 892 | outb((u8)data, port); |
895 | } | 893 | } |
896 | 894 | ||
897 | void | 895 | void |
898 | SiS_SetRegShort(SISIOADDRESS port, unsigned short data) | 896 | SiS_SetRegShort(SISIOADDRESS port, unsigned short data) |
899 | { | 897 | { |
900 | OutPortWord(port, data); | 898 | outw((u16)data, port); |
901 | } | 899 | } |
902 | 900 | ||
903 | void | 901 | void |
904 | SiS_SetRegLong(SISIOADDRESS port, unsigned int data) | 902 | SiS_SetRegLong(SISIOADDRESS port, unsigned int data) |
905 | { | 903 | { |
906 | OutPortLong(port, data); | 904 | outl((u32)data, port); |
907 | } | 905 | } |
908 | 906 | ||
909 | unsigned char | 907 | unsigned char |
910 | SiS_GetReg(SISIOADDRESS port, unsigned short index) | 908 | SiS_GetReg(SISIOADDRESS port, unsigned short index) |
911 | { | 909 | { |
912 | OutPortByte(port, index); | 910 | outb((u8)index, port); |
913 | return(InPortByte(port + 1)); | 911 | return inb(port + 1); |
914 | } | 912 | } |
915 | 913 | ||
916 | unsigned char | 914 | unsigned char |
917 | SiS_GetRegByte(SISIOADDRESS port) | 915 | SiS_GetRegByte(SISIOADDRESS port) |
918 | { | 916 | { |
919 | return(InPortByte(port)); | 917 | return inb(port); |
920 | } | 918 | } |
921 | 919 | ||
922 | unsigned short | 920 | unsigned short |
923 | SiS_GetRegShort(SISIOADDRESS port) | 921 | SiS_GetRegShort(SISIOADDRESS port) |
924 | { | 922 | { |
925 | return(InPortWord(port)); | 923 | return inw(port); |
926 | } | 924 | } |
927 | 925 | ||
928 | unsigned int | 926 | unsigned int |
929 | SiS_GetRegLong(SISIOADDRESS port) | 927 | SiS_GetRegLong(SISIOADDRESS port) |
930 | { | 928 | { |
931 | return(InPortLong(port)); | 929 | return inl(port); |
932 | } | 930 | } |
933 | 931 | ||
934 | void | 932 | void |
@@ -1089,7 +1087,7 @@ static void | |||
1089 | SiSInitPCIetc(struct SiS_Private *SiS_Pr) | 1087 | SiSInitPCIetc(struct SiS_Private *SiS_Pr) |
1090 | { | 1088 | { |
1091 | switch(SiS_Pr->ChipType) { | 1089 | switch(SiS_Pr->ChipType) { |
1092 | #ifdef SIS300 | 1090 | #ifdef CONFIG_FB_SIS_300 |
1093 | case SIS_300: | 1091 | case SIS_300: |
1094 | case SIS_540: | 1092 | case SIS_540: |
1095 | case SIS_630: | 1093 | case SIS_630: |
@@ -1108,7 +1106,7 @@ SiSInitPCIetc(struct SiS_Private *SiS_Pr) | |||
1108 | SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A); | 1106 | SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A); |
1109 | break; | 1107 | break; |
1110 | #endif | 1108 | #endif |
1111 | #ifdef SIS315H | 1109 | #ifdef CONFIG_FB_SIS_315 |
1112 | case SIS_315H: | 1110 | case SIS_315H: |
1113 | case SIS_315: | 1111 | case SIS_315: |
1114 | case SIS_315PRO: | 1112 | case SIS_315PRO: |
@@ -1152,9 +1150,7 @@ SiSInitPCIetc(struct SiS_Private *SiS_Pr) | |||
1152 | /* HELPER: SetLVDSetc */ | 1150 | /* HELPER: SetLVDSetc */ |
1153 | /*********************************************/ | 1151 | /*********************************************/ |
1154 | 1152 | ||
1155 | #ifdef SIS_LINUX_KERNEL | ||
1156 | static | 1153 | static |
1157 | #endif | ||
1158 | void | 1154 | void |
1159 | SiSSetLVDSetc(struct SiS_Private *SiS_Pr) | 1155 | SiSSetLVDSetc(struct SiS_Private *SiS_Pr) |
1160 | { | 1156 | { |
@@ -1174,7 +1170,7 @@ SiSSetLVDSetc(struct SiS_Private *SiS_Pr) | |||
1174 | if((temp == 1) || (temp == 2)) return; | 1170 | if((temp == 1) || (temp == 2)) return; |
1175 | 1171 | ||
1176 | switch(SiS_Pr->ChipType) { | 1172 | switch(SiS_Pr->ChipType) { |
1177 | #ifdef SIS300 | 1173 | #ifdef CONFIG_FB_SIS_300 |
1178 | case SIS_540: | 1174 | case SIS_540: |
1179 | case SIS_630: | 1175 | case SIS_630: |
1180 | case SIS_730: | 1176 | case SIS_730: |
@@ -1188,7 +1184,7 @@ SiSSetLVDSetc(struct SiS_Private *SiS_Pr) | |||
1188 | } | 1184 | } |
1189 | break; | 1185 | break; |
1190 | #endif | 1186 | #endif |
1191 | #ifdef SIS315H | 1187 | #ifdef CONFIG_FB_SIS_315 |
1192 | case SIS_550: | 1188 | case SIS_550: |
1193 | case SIS_650: | 1189 | case SIS_650: |
1194 | case SIS_740: | 1190 | case SIS_740: |
@@ -1420,9 +1416,7 @@ SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr) | |||
1420 | /* HELPER: GetVBType */ | 1416 | /* HELPER: GetVBType */ |
1421 | /*********************************************/ | 1417 | /*********************************************/ |
1422 | 1418 | ||
1423 | #ifdef SIS_LINUX_KERNEL | ||
1424 | static | 1419 | static |
1425 | #endif | ||
1426 | void | 1420 | void |
1427 | SiS_GetVBType(struct SiS_Private *SiS_Pr) | 1421 | SiS_GetVBType(struct SiS_Private *SiS_Pr) |
1428 | { | 1422 | { |
@@ -1487,7 +1481,6 @@ SiS_GetVBType(struct SiS_Private *SiS_Pr) | |||
1487 | /* HELPER: Check RAM size */ | 1481 | /* HELPER: Check RAM size */ |
1488 | /*********************************************/ | 1482 | /*********************************************/ |
1489 | 1483 | ||
1490 | #ifdef SIS_LINUX_KERNEL | ||
1491 | static bool | 1484 | static bool |
1492 | SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 1485 | SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
1493 | unsigned short ModeIdIndex) | 1486 | unsigned short ModeIdIndex) |
@@ -1501,13 +1494,12 @@ SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
1501 | if(AdapterMemSize < memorysize) return false; | 1494 | if(AdapterMemSize < memorysize) return false; |
1502 | return true; | 1495 | return true; |
1503 | } | 1496 | } |
1504 | #endif | ||
1505 | 1497 | ||
1506 | /*********************************************/ | 1498 | /*********************************************/ |
1507 | /* HELPER: Get DRAM type */ | 1499 | /* HELPER: Get DRAM type */ |
1508 | /*********************************************/ | 1500 | /*********************************************/ |
1509 | 1501 | ||
1510 | #ifdef SIS315H | 1502 | #ifdef CONFIG_FB_SIS_315 |
1511 | static unsigned char | 1503 | static unsigned char |
1512 | SiS_Get310DRAMType(struct SiS_Private *SiS_Pr) | 1504 | SiS_Get310DRAMType(struct SiS_Private *SiS_Pr) |
1513 | { | 1505 | { |
@@ -1574,7 +1566,6 @@ SiS_GetMCLK(struct SiS_Private *SiS_Pr) | |||
1574 | /* HELPER: ClearBuffer */ | 1566 | /* HELPER: ClearBuffer */ |
1575 | /*********************************************/ | 1567 | /*********************************************/ |
1576 | 1568 | ||
1577 | #ifdef SIS_LINUX_KERNEL | ||
1578 | static void | 1569 | static void |
1579 | SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | 1570 | SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo) |
1580 | { | 1571 | { |
@@ -1587,7 +1578,7 @@ SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
1587 | 1578 | ||
1588 | if(SiS_Pr->SiS_ModeType >= ModeEGA) { | 1579 | if(SiS_Pr->SiS_ModeType >= ModeEGA) { |
1589 | if(ModeNo > 0x13) { | 1580 | if(ModeNo > 0x13) { |
1590 | SiS_SetMemory(memaddr, memsize, 0); | 1581 | memset_io(memaddr, 0, memsize); |
1591 | } else { | 1582 | } else { |
1592 | pBuffer = (unsigned short SISIOMEMTYPE *)memaddr; | 1583 | pBuffer = (unsigned short SISIOMEMTYPE *)memaddr; |
1593 | for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]); | 1584 | for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]); |
@@ -1596,10 +1587,9 @@ SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
1596 | pBuffer = (unsigned short SISIOMEMTYPE *)memaddr; | 1587 | pBuffer = (unsigned short SISIOMEMTYPE *)memaddr; |
1597 | for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]); | 1588 | for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]); |
1598 | } else { | 1589 | } else { |
1599 | SiS_SetMemory(memaddr, 0x8000, 0); | 1590 | memset_io(memaddr, 0, 0x8000); |
1600 | } | 1591 | } |
1601 | } | 1592 | } |
1602 | #endif | ||
1603 | 1593 | ||
1604 | /*********************************************/ | 1594 | /*********************************************/ |
1605 | /* HELPER: SearchModeID */ | 1595 | /* HELPER: SearchModeID */ |
@@ -2132,7 +2122,7 @@ SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
2132 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F); | 2122 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F); |
2133 | } | 2123 | } |
2134 | 2124 | ||
2135 | #ifdef SIS315H | 2125 | #ifdef CONFIG_FB_SIS_315 |
2136 | if(SiS_Pr->ChipType == XGI_20) { | 2126 | if(SiS_Pr->ChipType == XGI_20) { |
2137 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x04,crt1data[4] - 1); | 2127 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x04,crt1data[4] - 1); |
2138 | if(!(temp = crt1data[5] & 0x1f)) { | 2128 | if(!(temp = crt1data[5] & 0x1f)) { |
@@ -2215,7 +2205,7 @@ SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
2215 | SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb); | 2205 | SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb); |
2216 | 2206 | ||
2217 | if(SiS_Pr->ChipType >= SIS_315H) { | 2207 | if(SiS_Pr->ChipType >= SIS_315H) { |
2218 | #ifdef SIS315H | 2208 | #ifdef CONFIG_FB_SIS_315 |
2219 | SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01); | 2209 | SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01); |
2220 | if(SiS_Pr->ChipType == XGI_20) { | 2210 | if(SiS_Pr->ChipType == XGI_20) { |
2221 | unsigned short mf = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); | 2211 | unsigned short mf = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); |
@@ -2236,7 +2226,7 @@ SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
2236 | /* FIFO */ | 2226 | /* FIFO */ |
2237 | /*********************************************/ | 2227 | /*********************************************/ |
2238 | 2228 | ||
2239 | #ifdef SIS300 | 2229 | #ifdef CONFIG_FB_SIS_300 |
2240 | void | 2230 | void |
2241 | SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1, | 2231 | SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1, |
2242 | unsigned short *idx2) | 2232 | unsigned short *idx2) |
@@ -2506,11 +2496,7 @@ SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
2506 | SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data); | 2496 | SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data); |
2507 | 2497 | ||
2508 | /* Write foreground and background queue */ | 2498 | /* Write foreground and background queue */ |
2509 | #ifdef SIS_LINUX_KERNEL | ||
2510 | templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50); | 2499 | templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50); |
2511 | #else | ||
2512 | templ = pciReadLong(0x00000000, 0x50); | ||
2513 | #endif | ||
2514 | 2500 | ||
2515 | if(SiS_Pr->ChipType == SIS_730) { | 2501 | if(SiS_Pr->ChipType == SIS_730) { |
2516 | 2502 | ||
@@ -2530,13 +2516,8 @@ SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
2530 | 2516 | ||
2531 | } | 2517 | } |
2532 | 2518 | ||
2533 | #ifdef SIS_LINUX_KERNEL | ||
2534 | sisfb_write_nbridge_pci_dword(SiS_Pr, 0x50, templ); | 2519 | sisfb_write_nbridge_pci_dword(SiS_Pr, 0x50, templ); |
2535 | templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xA0); | 2520 | templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xA0); |
2536 | #else | ||
2537 | pciWriteLong(0x00000000, 0x50, templ); | ||
2538 | templ = pciReadLong(0x00000000, 0xA0); | ||
2539 | #endif | ||
2540 | 2521 | ||
2541 | /* GUI grant timer (PCI config 0xA3) */ | 2522 | /* GUI grant timer (PCI config 0xA3) */ |
2542 | if(SiS_Pr->ChipType == SIS_730) { | 2523 | if(SiS_Pr->ChipType == SIS_730) { |
@@ -2552,15 +2533,11 @@ SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
2552 | 2533 | ||
2553 | } | 2534 | } |
2554 | 2535 | ||
2555 | #ifdef SIS_LINUX_KERNEL | ||
2556 | sisfb_write_nbridge_pci_dword(SiS_Pr, 0xA0, templ); | 2536 | sisfb_write_nbridge_pci_dword(SiS_Pr, 0xA0, templ); |
2557 | #else | ||
2558 | pciWriteLong(0x00000000, 0xA0, templ); | ||
2559 | #endif | ||
2560 | } | 2537 | } |
2561 | #endif /* SIS300 */ | 2538 | #endif /* CONFIG_FB_SIS_300 */ |
2562 | 2539 | ||
2563 | #ifdef SIS315H | 2540 | #ifdef CONFIG_FB_SIS_315 |
2564 | static void | 2541 | static void |
2565 | SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) | 2542 | SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) |
2566 | { | 2543 | { |
@@ -2612,7 +2589,7 @@ SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
2612 | } | 2589 | } |
2613 | 2590 | ||
2614 | if(SiS_Pr->ChipType < SIS_315H) { | 2591 | if(SiS_Pr->ChipType < SIS_315H) { |
2615 | #ifdef SIS300 | 2592 | #ifdef CONFIG_FB_SIS_300 |
2616 | if(VCLK > 150) data |= 0x80; | 2593 | if(VCLK > 150) data |= 0x80; |
2617 | SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data); | 2594 | SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data); |
2618 | 2595 | ||
@@ -2621,7 +2598,7 @@ SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
2621 | SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data); | 2598 | SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data); |
2622 | #endif | 2599 | #endif |
2623 | } else if(SiS_Pr->ChipType < XGI_20) { | 2600 | } else if(SiS_Pr->ChipType < XGI_20) { |
2624 | #ifdef SIS315H | 2601 | #ifdef CONFIG_FB_SIS_315 |
2625 | if(VCLK >= 166) data |= 0x0c; | 2602 | if(VCLK >= 166) data |= 0x0c; |
2626 | SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data); | 2603 | SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data); |
2627 | 2604 | ||
@@ -2630,7 +2607,7 @@ SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
2630 | } | 2607 | } |
2631 | #endif | 2608 | #endif |
2632 | } else { | 2609 | } else { |
2633 | #ifdef SIS315H | 2610 | #ifdef CONFIG_FB_SIS_315 |
2634 | if(VCLK >= 200) data |= 0x0c; | 2611 | if(VCLK >= 200) data |= 0x0c; |
2635 | if(SiS_Pr->ChipType == XGI_20) data &= ~0x04; | 2612 | if(SiS_Pr->ChipType == XGI_20) data &= ~0x04; |
2636 | SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data); | 2613 | SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data); |
@@ -2675,7 +2652,7 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
2675 | unsigned short ModeIdIndex, unsigned short RRTI) | 2652 | unsigned short ModeIdIndex, unsigned short RRTI) |
2676 | { | 2653 | { |
2677 | unsigned short data, infoflag = 0, modeflag, resindex; | 2654 | unsigned short data, infoflag = 0, modeflag, resindex; |
2678 | #ifdef SIS315H | 2655 | #ifdef CONFIG_FB_SIS_315 |
2679 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; | 2656 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; |
2680 | unsigned short data2, data3; | 2657 | unsigned short data2, data3; |
2681 | #endif | 2658 | #endif |
@@ -2736,7 +2713,7 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
2736 | SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data); | 2713 | SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data); |
2737 | } | 2714 | } |
2738 | 2715 | ||
2739 | #ifdef SIS315H | 2716 | #ifdef CONFIG_FB_SIS_315 |
2740 | if(SiS_Pr->ChipType >= SIS_315H) { | 2717 | if(SiS_Pr->ChipType >= SIS_315H) { |
2741 | SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb); | 2718 | SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb); |
2742 | } | 2719 | } |
@@ -2826,7 +2803,7 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
2826 | 2803 | ||
2827 | SiS_SetVCLKState(SiS_Pr, ModeNo, RRTI, ModeIdIndex); | 2804 | SiS_SetVCLKState(SiS_Pr, ModeNo, RRTI, ModeIdIndex); |
2828 | 2805 | ||
2829 | #ifdef SIS315H | 2806 | #ifdef CONFIG_FB_SIS_315 |
2830 | if(((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) || | 2807 | if(((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) || |
2831 | (SiS_Pr->ChipType == XGI_40)) { | 2808 | (SiS_Pr->ChipType == XGI_40)) { |
2832 | if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) { | 2809 | if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) { |
@@ -2845,7 +2822,7 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
2845 | #endif | 2822 | #endif |
2846 | } | 2823 | } |
2847 | 2824 | ||
2848 | #ifdef SIS315H | 2825 | #ifdef CONFIG_FB_SIS_315 |
2849 | static void | 2826 | static void |
2850 | SiS_SetupDualChip(struct SiS_Private *SiS_Pr) | 2827 | SiS_SetupDualChip(struct SiS_Private *SiS_Pr) |
2851 | { | 2828 | { |
@@ -2999,11 +2976,6 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho | |||
2999 | SiS_Pr->SiS_SelectCRT2Rate = 0; | 2976 | SiS_Pr->SiS_SelectCRT2Rate = 0; |
3000 | SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); | 2977 | SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); |
3001 | 2978 | ||
3002 | #ifdef SIS_XORG_XF86 | ||
3003 | xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n", | ||
3004 | SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo); | ||
3005 | #endif | ||
3006 | |||
3007 | if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) { | 2979 | if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) { |
3008 | if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { | 2980 | if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { |
3009 | SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; | 2981 | SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; |
@@ -3028,7 +3000,7 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho | |||
3028 | } | 3000 | } |
3029 | 3001 | ||
3030 | switch(SiS_Pr->ChipType) { | 3002 | switch(SiS_Pr->ChipType) { |
3031 | #ifdef SIS300 | 3003 | #ifdef CONFIG_FB_SIS_300 |
3032 | case SIS_300: | 3004 | case SIS_300: |
3033 | SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo, RefreshRateTableIndex); | 3005 | SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo, RefreshRateTableIndex); |
3034 | break; | 3006 | break; |
@@ -3039,7 +3011,7 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho | |||
3039 | break; | 3011 | break; |
3040 | #endif | 3012 | #endif |
3041 | default: | 3013 | default: |
3042 | #ifdef SIS315H | 3014 | #ifdef CONFIG_FB_SIS_315 |
3043 | if(SiS_Pr->ChipType == XGI_20) { | 3015 | if(SiS_Pr->ChipType == XGI_20) { |
3044 | unsigned char sr2b = 0, sr2c = 0; | 3016 | unsigned char sr2b = 0, sr2c = 0; |
3045 | switch(ModeNo) { | 3017 | switch(ModeNo) { |
@@ -3062,7 +3034,7 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho | |||
3062 | 3034 | ||
3063 | SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); | 3035 | SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); |
3064 | 3036 | ||
3065 | #ifdef SIS315H | 3037 | #ifdef CONFIG_FB_SIS_315 |
3066 | if(SiS_Pr->ChipType == XGI_40) { | 3038 | if(SiS_Pr->ChipType == XGI_40) { |
3067 | SiS_SetupDualChip(SiS_Pr); | 3039 | SiS_SetupDualChip(SiS_Pr); |
3068 | } | 3040 | } |
@@ -3070,11 +3042,9 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho | |||
3070 | 3042 | ||
3071 | SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex); | 3043 | SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex); |
3072 | 3044 | ||
3073 | #ifdef SIS_LINUX_KERNEL | ||
3074 | if(SiS_Pr->SiS_flag_clearbuffer) { | 3045 | if(SiS_Pr->SiS_flag_clearbuffer) { |
3075 | SiS_ClearBuffer(SiS_Pr, ModeNo); | 3046 | SiS_ClearBuffer(SiS_Pr, ModeNo); |
3076 | } | 3047 | } |
3077 | #endif | ||
3078 | 3048 | ||
3079 | if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) { | 3049 | if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) { |
3080 | SiS_WaitRetrace1(SiS_Pr); | 3050 | SiS_WaitRetrace1(SiS_Pr); |
@@ -3104,7 +3074,7 @@ SiS_InitVB(struct SiS_Private *SiS_Pr) | |||
3104 | static void | 3074 | static void |
3105 | SiS_ResetVB(struct SiS_Private *SiS_Pr) | 3075 | SiS_ResetVB(struct SiS_Private *SiS_Pr) |
3106 | { | 3076 | { |
3107 | #ifdef SIS315H | 3077 | #ifdef CONFIG_FB_SIS_315 |
3108 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; | 3078 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; |
3109 | unsigned short temp; | 3079 | unsigned short temp; |
3110 | 3080 | ||
@@ -3139,7 +3109,7 @@ SiS_StrangeStuff(struct SiS_Private *SiS_Pr) | |||
3139 | * which locks CRT2 in some way to CRT1 timing. Disable | 3109 | * which locks CRT2 in some way to CRT1 timing. Disable |
3140 | * this here. | 3110 | * this here. |
3141 | */ | 3111 | */ |
3142 | #ifdef SIS315H | 3112 | #ifdef CONFIG_FB_SIS_315 |
3143 | if((IS_SIS651) || (IS_SISM650) || | 3113 | if((IS_SIS651) || (IS_SISM650) || |
3144 | SiS_Pr->ChipType == SIS_340 || | 3114 | SiS_Pr->ChipType == SIS_340 || |
3145 | SiS_Pr->ChipType == XGI_40) { | 3115 | SiS_Pr->ChipType == XGI_40) { |
@@ -3160,7 +3130,7 @@ SiS_StrangeStuff(struct SiS_Private *SiS_Pr) | |||
3160 | static void | 3130 | static void |
3161 | SiS_Handle760(struct SiS_Private *SiS_Pr) | 3131 | SiS_Handle760(struct SiS_Private *SiS_Pr) |
3162 | { | 3132 | { |
3163 | #ifdef SIS315H | 3133 | #ifdef CONFIG_FB_SIS_315 |
3164 | unsigned int somebase; | 3134 | unsigned int somebase; |
3165 | unsigned char temp1, temp2, temp3; | 3135 | unsigned char temp1, temp2, temp3; |
3166 | 3136 | ||
@@ -3170,11 +3140,7 @@ SiS_Handle760(struct SiS_Private *SiS_Pr) | |||
3170 | (!(SiS_Pr->SiS_SysFlags & SF_760UMA)) ) | 3140 | (!(SiS_Pr->SiS_SysFlags & SF_760UMA)) ) |
3171 | return; | 3141 | return; |
3172 | 3142 | ||
3173 | #ifdef SIS_LINUX_KERNEL | ||
3174 | somebase = sisfb_read_mio_pci_word(SiS_Pr, 0x74); | 3143 | somebase = sisfb_read_mio_pci_word(SiS_Pr, 0x74); |
3175 | #else | ||
3176 | somebase = pciReadWord(0x00001000, 0x74); | ||
3177 | #endif | ||
3178 | somebase &= 0xffff; | 3144 | somebase &= 0xffff; |
3179 | 3145 | ||
3180 | if(somebase == 0) return; | 3146 | if(somebase == 0) return; |
@@ -3190,105 +3156,34 @@ SiS_Handle760(struct SiS_Private *SiS_Pr) | |||
3190 | temp2 = 0x0b; | 3156 | temp2 = 0x0b; |
3191 | } | 3157 | } |
3192 | 3158 | ||
3193 | #ifdef SIS_LINUX_KERNEL | ||
3194 | sisfb_write_nbridge_pci_byte(SiS_Pr, 0x7e, temp1); | 3159 | sisfb_write_nbridge_pci_byte(SiS_Pr, 0x7e, temp1); |
3195 | sisfb_write_nbridge_pci_byte(SiS_Pr, 0x8d, temp2); | 3160 | sisfb_write_nbridge_pci_byte(SiS_Pr, 0x8d, temp2); |
3196 | #else | ||
3197 | pciWriteByte(0x00000000, 0x7e, temp1); | ||
3198 | pciWriteByte(0x00000000, 0x8d, temp2); | ||
3199 | #endif | ||
3200 | 3161 | ||
3201 | SiS_SetRegByte((somebase + 0x85), temp3); | 3162 | SiS_SetRegByte((somebase + 0x85), temp3); |
3202 | #endif | 3163 | #endif |
3203 | } | 3164 | } |
3204 | 3165 | ||
3205 | /*********************************************/ | 3166 | /*********************************************/ |
3206 | /* X.org/XFree86: SET SCREEN PITCH */ | ||
3207 | /*********************************************/ | ||
3208 | |||
3209 | #ifdef SIS_XORG_XF86 | ||
3210 | static void | ||
3211 | SiS_SetPitchCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn) | ||
3212 | { | ||
3213 | SISPtr pSiS = SISPTR(pScrn); | ||
3214 | unsigned short HDisplay = pSiS->scrnPitch >> 3; | ||
3215 | |||
3216 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,(HDisplay & 0xFF)); | ||
3217 | SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay >> 8)); | ||
3218 | } | ||
3219 | |||
3220 | static void | ||
3221 | SiS_SetPitchCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn) | ||
3222 | { | ||
3223 | SISPtr pSiS = SISPTR(pScrn); | ||
3224 | unsigned short HDisplay = pSiS->scrnPitch2 >> 3; | ||
3225 | |||
3226 | /* Unlock CRT2 */ | ||
3227 | if(pSiS->VGAEngine == SIS_315_VGA) | ||
3228 | SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01); | ||
3229 | else | ||
3230 | SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01); | ||
3231 | |||
3232 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(HDisplay & 0xFF)); | ||
3233 | SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0xF0,(HDisplay >> 8)); | ||
3234 | } | ||
3235 | |||
3236 | static void | ||
3237 | SiS_SetPitch(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn) | ||
3238 | { | ||
3239 | SISPtr pSiS = SISPTR(pScrn); | ||
3240 | bool isslavemode = false; | ||
3241 | |||
3242 | if( (pSiS->VBFlags2 & VB2_VIDEOBRIDGE) && | ||
3243 | ( ((pSiS->VGAEngine == SIS_300_VGA) && | ||
3244 | (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) || | ||
3245 | ((pSiS->VGAEngine == SIS_315_VGA) && | ||
3246 | (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) { | ||
3247 | isslavemode = true; | ||
3248 | } | ||
3249 | |||
3250 | /* We need to set pitch for CRT1 if bridge is in slave mode, too */ | ||
3251 | if((pSiS->VBFlags & DISPTYPE_DISP1) || (isslavemode)) { | ||
3252 | SiS_SetPitchCRT1(SiS_Pr, pScrn); | ||
3253 | } | ||
3254 | /* We must not set the pitch for CRT2 if bridge is in slave mode */ | ||
3255 | if((pSiS->VBFlags & DISPTYPE_DISP2) && (!isslavemode)) { | ||
3256 | SiS_SetPitchCRT2(SiS_Pr, pScrn); | ||
3257 | } | ||
3258 | } | ||
3259 | #endif | ||
3260 | |||
3261 | /*********************************************/ | ||
3262 | /* SiSSetMode() */ | 3167 | /* SiSSetMode() */ |
3263 | /*********************************************/ | 3168 | /*********************************************/ |
3264 | 3169 | ||
3265 | #ifdef SIS_XORG_XF86 | ||
3266 | /* We need pScrn for setting the pitch correctly */ | ||
3267 | bool | ||
3268 | SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo, bool dosetpitch) | ||
3269 | #else | ||
3270 | bool | 3170 | bool |
3271 | SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | 3171 | SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) |
3272 | #endif | ||
3273 | { | 3172 | { |
3274 | SISIOADDRESS BaseAddr = SiS_Pr->IOAddress; | 3173 | SISIOADDRESS BaseAddr = SiS_Pr->IOAddress; |
3275 | unsigned short RealModeNo, ModeIdIndex; | 3174 | unsigned short RealModeNo, ModeIdIndex; |
3276 | unsigned char backupreg = 0; | 3175 | unsigned char backupreg = 0; |
3277 | #ifdef SIS_LINUX_KERNEL | ||
3278 | unsigned short KeepLockReg; | 3176 | unsigned short KeepLockReg; |
3279 | 3177 | ||
3280 | SiS_Pr->UseCustomMode = false; | 3178 | SiS_Pr->UseCustomMode = false; |
3281 | SiS_Pr->CRT1UsesCustomMode = false; | 3179 | SiS_Pr->CRT1UsesCustomMode = false; |
3282 | #endif | ||
3283 | 3180 | ||
3284 | SiS_Pr->SiS_flag_clearbuffer = 0; | 3181 | SiS_Pr->SiS_flag_clearbuffer = 0; |
3285 | 3182 | ||
3286 | if(SiS_Pr->UseCustomMode) { | 3183 | if(SiS_Pr->UseCustomMode) { |
3287 | ModeNo = 0xfe; | 3184 | ModeNo = 0xfe; |
3288 | } else { | 3185 | } else { |
3289 | #ifdef SIS_LINUX_KERNEL | ||
3290 | if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1; | 3186 | if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1; |
3291 | #endif | ||
3292 | ModeNo &= 0x7f; | 3187 | ModeNo &= 0x7f; |
3293 | } | 3188 | } |
3294 | 3189 | ||
@@ -3301,13 +3196,8 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
3301 | SiS_GetSysFlags(SiS_Pr); | 3196 | SiS_GetSysFlags(SiS_Pr); |
3302 | 3197 | ||
3303 | SiS_Pr->SiS_VGAINFO = 0x11; | 3198 | SiS_Pr->SiS_VGAINFO = 0x11; |
3304 | #if defined(SIS_XORG_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)) | ||
3305 | if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); | ||
3306 | #endif | ||
3307 | 3199 | ||
3308 | #ifdef SIS_LINUX_KERNEL | ||
3309 | KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05); | 3200 | KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05); |
3310 | #endif | ||
3311 | SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); | 3201 | SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); |
3312 | 3202 | ||
3313 | SiSInitPCIetc(SiS_Pr); | 3203 | SiSInitPCIetc(SiS_Pr); |
@@ -3344,12 +3234,10 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
3344 | SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex); | 3234 | SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex); |
3345 | SiS_SetLowModeTest(SiS_Pr, ModeNo); | 3235 | SiS_SetLowModeTest(SiS_Pr, ModeNo); |
3346 | 3236 | ||
3347 | #ifdef SIS_LINUX_KERNEL | ||
3348 | /* Check memory size (kernel framebuffer driver only) */ | 3237 | /* Check memory size (kernel framebuffer driver only) */ |
3349 | if(!SiS_CheckMemorySize(SiS_Pr, ModeNo, ModeIdIndex)) { | 3238 | if(!SiS_CheckMemorySize(SiS_Pr, ModeNo, ModeIdIndex)) { |
3350 | return false; | 3239 | return false; |
3351 | } | 3240 | } |
3352 | #endif | ||
3353 | 3241 | ||
3354 | SiS_OpenCRTC(SiS_Pr); | 3242 | SiS_OpenCRTC(SiS_Pr); |
3355 | 3243 | ||
@@ -3384,7 +3272,7 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
3384 | SiS_DisplayOn(SiS_Pr); | 3272 | SiS_DisplayOn(SiS_Pr); |
3385 | SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); | 3273 | SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); |
3386 | 3274 | ||
3387 | #ifdef SIS315H | 3275 | #ifdef CONFIG_FB_SIS_315 |
3388 | if(SiS_Pr->ChipType >= SIS_315H) { | 3276 | if(SiS_Pr->ChipType >= SIS_315H) { |
3389 | if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { | 3277 | if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { |
3390 | if(!(SiS_IsDualEdge(SiS_Pr))) { | 3278 | if(!(SiS_IsDualEdge(SiS_Pr))) { |
@@ -3396,7 +3284,7 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
3396 | 3284 | ||
3397 | if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { | 3285 | if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { |
3398 | if(SiS_Pr->ChipType >= SIS_315H) { | 3286 | if(SiS_Pr->ChipType >= SIS_315H) { |
3399 | #ifdef SIS315H | 3287 | #ifdef CONFIG_FB_SIS_315 |
3400 | if(!SiS_Pr->SiS_ROMNew) { | 3288 | if(!SiS_Pr->SiS_ROMNew) { |
3401 | if(SiS_IsVAMode(SiS_Pr)) { | 3289 | if(SiS_IsVAMode(SiS_Pr)) { |
3402 | SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); | 3290 | SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); |
@@ -3424,424 +3312,16 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
3424 | } | 3312 | } |
3425 | } | 3313 | } |
3426 | 3314 | ||
3427 | #ifdef SIS_XORG_XF86 | ||
3428 | if(pScrn) { | ||
3429 | /* SetPitch: Adapt to virtual size & position */ | ||
3430 | if((ModeNo > 0x13) && (dosetpitch)) { | ||
3431 | SiS_SetPitch(SiS_Pr, pScrn); | ||
3432 | } | ||
3433 | |||
3434 | /* Backup/Set ModeNo in BIOS scratch area */ | ||
3435 | SiS_GetSetModeID(pScrn, ModeNo); | ||
3436 | } | ||
3437 | #endif | ||
3438 | |||
3439 | SiS_CloseCRTC(SiS_Pr); | 3315 | SiS_CloseCRTC(SiS_Pr); |
3440 | 3316 | ||
3441 | SiS_Handle760(SiS_Pr); | 3317 | SiS_Handle760(SiS_Pr); |
3442 | 3318 | ||
3443 | #ifdef SIS_LINUX_KERNEL | ||
3444 | /* We never lock registers in XF86 */ | 3319 | /* We never lock registers in XF86 */ |
3445 | if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00); | 3320 | if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00); |
3446 | #endif | ||
3447 | 3321 | ||
3448 | return true; | 3322 | return true; |
3449 | } | 3323 | } |
3450 | 3324 | ||
3451 | /*********************************************/ | ||
3452 | /* X.org/XFree86: SiSBIOSSetMode() */ | ||
3453 | /* for non-Dual-Head mode */ | ||
3454 | /*********************************************/ | ||
3455 | |||
3456 | #ifdef SIS_XORG_XF86 | ||
3457 | bool | ||
3458 | SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, | ||
3459 | DisplayModePtr mode, bool IsCustom) | ||
3460 | { | ||
3461 | SISPtr pSiS = SISPTR(pScrn); | ||
3462 | unsigned short ModeNo = 0; | ||
3463 | |||
3464 | SiS_Pr->UseCustomMode = false; | ||
3465 | |||
3466 | if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { | ||
3467 | |||
3468 | xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n", | ||
3469 | SiS_Pr->CHDisplay, | ||
3470 | (mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 : | ||
3471 | (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 : | ||
3472 | SiS_Pr->CVDisplay))); | ||
3473 | |||
3474 | } else { | ||
3475 | |||
3476 | /* Don't need vbflags here; checks done earlier */ | ||
3477 | ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags); | ||
3478 | if(!ModeNo) return false; | ||
3479 | |||
3480 | xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo); | ||
3481 | |||
3482 | } | ||
3483 | |||
3484 | return(SiSSetMode(SiS_Pr, pScrn, ModeNo, true)); | ||
3485 | } | ||
3486 | |||
3487 | /*********************************************/ | ||
3488 | /* X.org/XFree86: SiSBIOSSetModeCRT2() */ | ||
3489 | /* for Dual-Head modes */ | ||
3490 | /*********************************************/ | ||
3491 | |||
3492 | bool | ||
3493 | SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, | ||
3494 | DisplayModePtr mode, bool IsCustom) | ||
3495 | { | ||
3496 | SISIOADDRESS BaseAddr = SiS_Pr->IOAddress; | ||
3497 | SISPtr pSiS = SISPTR(pScrn); | ||
3498 | #ifdef SISDUALHEAD | ||
3499 | SISEntPtr pSiSEnt = pSiS->entityPrivate; | ||
3500 | #endif | ||
3501 | unsigned short ModeIdIndex; | ||
3502 | unsigned short ModeNo = 0; | ||
3503 | unsigned char backupreg = 0; | ||
3504 | |||
3505 | SiS_Pr->UseCustomMode = false; | ||
3506 | |||
3507 | /* Remember: Custom modes for CRT2 are ONLY supported | ||
3508 | * -) on the 30x/B/C, and | ||
3509 | * -) if CRT2 is LCD or VGA, or CRT1 is LCDA | ||
3510 | */ | ||
3511 | |||
3512 | if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { | ||
3513 | |||
3514 | ModeNo = 0xfe; | ||
3515 | |||
3516 | } else { | ||
3517 | |||
3518 | ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags); | ||
3519 | if(!ModeNo) return false; | ||
3520 | |||
3521 | } | ||
3522 | |||
3523 | SiSRegInit(SiS_Pr, BaseAddr); | ||
3524 | SiSInitPtr(SiS_Pr); | ||
3525 | SiS_GetSysFlags(SiS_Pr); | ||
3526 | #if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__) | ||
3527 | SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); | ||
3528 | #else | ||
3529 | SiS_Pr->SiS_VGAINFO = 0x11; | ||
3530 | #endif | ||
3531 | |||
3532 | SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); | ||
3533 | |||
3534 | SiSInitPCIetc(SiS_Pr); | ||
3535 | SiSSetLVDSetc(SiS_Pr); | ||
3536 | SiSDetermineROMUsage(SiS_Pr); | ||
3537 | |||
3538 | /* Save mode info so we can set it from within SetMode for CRT1 */ | ||
3539 | #ifdef SISDUALHEAD | ||
3540 | if(pSiS->DualHeadMode) { | ||
3541 | pSiSEnt->CRT2ModeNo = ModeNo; | ||
3542 | pSiSEnt->CRT2DMode = mode; | ||
3543 | pSiSEnt->CRT2IsCustom = IsCustom; | ||
3544 | pSiSEnt->CRT2CR30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); | ||
3545 | pSiSEnt->CRT2CR31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31); | ||
3546 | pSiSEnt->CRT2CR35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); | ||
3547 | pSiSEnt->CRT2CR38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); | ||
3548 | #if 0 | ||
3549 | /* We can't set CRT2 mode before CRT1 mode is set - says who...? */ | ||
3550 | if(pSiSEnt->CRT1ModeNo == -1) { | ||
3551 | xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, | ||
3552 | "Setting CRT2 mode delayed until after setting CRT1 mode\n"); | ||
3553 | return true; | ||
3554 | } | ||
3555 | #endif | ||
3556 | pSiSEnt->CRT2ModeSet = true; | ||
3557 | } | ||
3558 | #endif | ||
3559 | |||
3560 | if(SiS_Pr->UseCustomMode) { | ||
3561 | |||
3562 | unsigned short temptemp = SiS_Pr->CVDisplay; | ||
3563 | |||
3564 | if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1; | ||
3565 | else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1; | ||
3566 | |||
3567 | xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, | ||
3568 | "Setting custom mode %dx%d on CRT2\n", | ||
3569 | SiS_Pr->CHDisplay, temptemp); | ||
3570 | |||
3571 | } else { | ||
3572 | |||
3573 | xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, | ||
3574 | "Setting standard mode 0x%x on CRT2\n", ModeNo); | ||
3575 | |||
3576 | } | ||
3577 | |||
3578 | SiS_UnLockCRT2(SiS_Pr); | ||
3579 | |||
3580 | if(!SiS_Pr->UseCustomMode) { | ||
3581 | if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false; | ||
3582 | } else { | ||
3583 | ModeIdIndex = 0; | ||
3584 | } | ||
3585 | |||
3586 | SiS_GetVBType(SiS_Pr); | ||
3587 | |||
3588 | SiS_InitVB(SiS_Pr); | ||
3589 | if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { | ||
3590 | if(SiS_Pr->ChipType >= SIS_315H) { | ||
3591 | SiS_ResetVB(SiS_Pr); | ||
3592 | SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10); | ||
3593 | SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c); | ||
3594 | backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); | ||
3595 | } else { | ||
3596 | backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); | ||
3597 | } | ||
3598 | } | ||
3599 | |||
3600 | /* Get VB information (connectors, connected devices) */ | ||
3601 | if(!SiS_Pr->UseCustomMode) { | ||
3602 | SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 1); | ||
3603 | } else { | ||
3604 | /* If this is a custom mode, we don't check the modeflag for CRT2Mode */ | ||
3605 | SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0); | ||
3606 | } | ||
3607 | SiS_SetYPbPr(SiS_Pr); | ||
3608 | SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex); | ||
3609 | SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex); | ||
3610 | SiS_SetLowModeTest(SiS_Pr, ModeNo); | ||
3611 | |||
3612 | SiS_ResetSegmentRegisters(SiS_Pr); | ||
3613 | |||
3614 | /* Set mode on CRT2 */ | ||
3615 | if( (SiS_Pr->SiS_VBType & VB_SISVB) || | ||
3616 | (SiS_Pr->SiS_IF_DEF_LVDS == 1) || | ||
3617 | (SiS_Pr->SiS_IF_DEF_CH70xx != 0) || | ||
3618 | (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) { | ||
3619 | SiS_SetCRT2Group(SiS_Pr, ModeNo); | ||
3620 | } | ||
3621 | |||
3622 | SiS_StrangeStuff(SiS_Pr); | ||
3623 | |||
3624 | SiS_DisplayOn(SiS_Pr); | ||
3625 | SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); | ||
3626 | |||
3627 | if(SiS_Pr->ChipType >= SIS_315H) { | ||
3628 | if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { | ||
3629 | if(!(SiS_IsDualEdge(SiS_Pr))) { | ||
3630 | SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); | ||
3631 | } | ||
3632 | } | ||
3633 | } | ||
3634 | |||
3635 | if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { | ||
3636 | if(SiS_Pr->ChipType >= SIS_315H) { | ||
3637 | if(!SiS_Pr->SiS_ROMNew) { | ||
3638 | if(SiS_IsVAMode(SiS_Pr)) { | ||
3639 | SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); | ||
3640 | } else { | ||
3641 | SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE); | ||
3642 | } | ||
3643 | } | ||
3644 | |||
3645 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg); | ||
3646 | |||
3647 | if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) { | ||
3648 | SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); | ||
3649 | } | ||
3650 | } else if((SiS_Pr->ChipType == SIS_630) || | ||
3651 | (SiS_Pr->ChipType == SIS_730)) { | ||
3652 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg); | ||
3653 | } | ||
3654 | } | ||
3655 | |||
3656 | /* SetPitch: Adapt to virtual size & position */ | ||
3657 | SiS_SetPitchCRT2(SiS_Pr, pScrn); | ||
3658 | |||
3659 | SiS_Handle760(SiS_Pr); | ||
3660 | |||
3661 | return true; | ||
3662 | } | ||
3663 | |||
3664 | /*********************************************/ | ||
3665 | /* X.org/XFree86: SiSBIOSSetModeCRT1() */ | ||
3666 | /* for Dual-Head modes */ | ||
3667 | /*********************************************/ | ||
3668 | |||
3669 | bool | ||
3670 | SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, | ||
3671 | DisplayModePtr mode, bool IsCustom) | ||
3672 | { | ||
3673 | SISIOADDRESS BaseAddr = SiS_Pr->IOAddress; | ||
3674 | SISPtr pSiS = SISPTR(pScrn); | ||
3675 | unsigned short ModeIdIndex, ModeNo = 0; | ||
3676 | unsigned char backupreg = 0; | ||
3677 | #ifdef SISDUALHEAD | ||
3678 | SISEntPtr pSiSEnt = pSiS->entityPrivate; | ||
3679 | unsigned char backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0; | ||
3680 | bool backupcustom; | ||
3681 | #endif | ||
3682 | |||
3683 | SiS_Pr->UseCustomMode = false; | ||
3684 | |||
3685 | if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { | ||
3686 | |||
3687 | unsigned short temptemp = SiS_Pr->CVDisplay; | ||
3688 | |||
3689 | if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1; | ||
3690 | else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1; | ||
3691 | |||
3692 | xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, | ||
3693 | "Setting custom mode %dx%d on CRT1\n", | ||
3694 | SiS_Pr->CHDisplay, temptemp); | ||
3695 | ModeNo = 0xfe; | ||
3696 | |||
3697 | } else { | ||
3698 | |||
3699 | ModeNo = SiS_GetModeNumber(pScrn, mode, 0); /* don't give VBFlags */ | ||
3700 | if(!ModeNo) return false; | ||
3701 | |||
3702 | xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, | ||
3703 | "Setting standard mode 0x%x on CRT1\n", ModeNo); | ||
3704 | } | ||
3705 | |||
3706 | SiSInitPtr(SiS_Pr); | ||
3707 | SiSRegInit(SiS_Pr, BaseAddr); | ||
3708 | SiS_GetSysFlags(SiS_Pr); | ||
3709 | #if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__) | ||
3710 | SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); | ||
3711 | #else | ||
3712 | SiS_Pr->SiS_VGAINFO = 0x11; | ||
3713 | #endif | ||
3714 | |||
3715 | SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); | ||
3716 | |||
3717 | SiSInitPCIetc(SiS_Pr); | ||
3718 | SiSSetLVDSetc(SiS_Pr); | ||
3719 | SiSDetermineROMUsage(SiS_Pr); | ||
3720 | |||
3721 | SiS_UnLockCRT2(SiS_Pr); | ||
3722 | |||
3723 | if(!SiS_Pr->UseCustomMode) { | ||
3724 | if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false; | ||
3725 | } else { | ||
3726 | ModeIdIndex = 0; | ||
3727 | } | ||
3728 | |||
3729 | /* Determine VBType */ | ||
3730 | SiS_GetVBType(SiS_Pr); | ||
3731 | |||
3732 | SiS_InitVB(SiS_Pr); | ||
3733 | if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { | ||
3734 | if(SiS_Pr->ChipType >= SIS_315H) { | ||
3735 | backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); | ||
3736 | } else { | ||
3737 | backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); | ||
3738 | } | ||
3739 | } | ||
3740 | |||
3741 | /* Get VB information (connectors, connected devices) */ | ||
3742 | /* (We don't care if the current mode is a CRT2 mode) */ | ||
3743 | SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0); | ||
3744 | SiS_SetYPbPr(SiS_Pr); | ||
3745 | SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex); | ||
3746 | SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex); | ||
3747 | SiS_SetLowModeTest(SiS_Pr, ModeNo); | ||
3748 | |||
3749 | SiS_OpenCRTC(SiS_Pr); | ||
3750 | |||
3751 | /* Set mode on CRT1 */ | ||
3752 | SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex); | ||
3753 | if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { | ||
3754 | SiS_SetCRT2Group(SiS_Pr, ModeNo); | ||
3755 | } | ||
3756 | |||
3757 | /* SetPitch: Adapt to virtual size & position */ | ||
3758 | SiS_SetPitchCRT1(SiS_Pr, pScrn); | ||
3759 | |||
3760 | SiS_HandleCRT1(SiS_Pr); | ||
3761 | |||
3762 | SiS_StrangeStuff(SiS_Pr); | ||
3763 | |||
3764 | SiS_CloseCRTC(SiS_Pr); | ||
3765 | |||
3766 | #ifdef SISDUALHEAD | ||
3767 | if(pSiS->DualHeadMode) { | ||
3768 | pSiSEnt->CRT1ModeNo = ModeNo; | ||
3769 | pSiSEnt->CRT1DMode = mode; | ||
3770 | } | ||
3771 | #endif | ||
3772 | |||
3773 | if(SiS_Pr->UseCustomMode) { | ||
3774 | SiS_Pr->CRT1UsesCustomMode = true; | ||
3775 | SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock; | ||
3776 | SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag; | ||
3777 | } else { | ||
3778 | SiS_Pr->CRT1UsesCustomMode = false; | ||
3779 | } | ||
3780 | |||
3781 | /* Reset CRT2 if changing mode on CRT1 */ | ||
3782 | #ifdef SISDUALHEAD | ||
3783 | if(pSiS->DualHeadMode) { | ||
3784 | if(pSiSEnt->CRT2ModeNo != -1) { | ||
3785 | xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, | ||
3786 | "(Re-)Setting mode for CRT2\n"); | ||
3787 | backupcustom = SiS_Pr->UseCustomMode; | ||
3788 | backupcr30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); | ||
3789 | backupcr31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31); | ||
3790 | backupcr35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); | ||
3791 | backupcr38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); | ||
3792 | if(SiS_Pr->SiS_VBType & VB_SISVB) { | ||
3793 | /* Backup LUT-enable */ | ||
3794 | if(pSiSEnt->CRT2ModeSet) { | ||
3795 | backupp40d = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0d) & 0x08; | ||
3796 | } | ||
3797 | } | ||
3798 | if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { | ||
3799 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,pSiSEnt->CRT2CR30); | ||
3800 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,pSiSEnt->CRT2CR31); | ||
3801 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,pSiSEnt->CRT2CR35); | ||
3802 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,pSiSEnt->CRT2CR38); | ||
3803 | } | ||
3804 | |||
3805 | SiSBIOSSetModeCRT2(SiS_Pr, pSiSEnt->pScrn_1, | ||
3806 | pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom); | ||
3807 | |||
3808 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,backupcr30); | ||
3809 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,backupcr31); | ||
3810 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupcr35); | ||
3811 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupcr38); | ||
3812 | if(SiS_Pr->SiS_VBType & VB_SISVB) { | ||
3813 | SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d, ~0x08, backupp40d); | ||
3814 | } | ||
3815 | SiS_Pr->UseCustomMode = backupcustom; | ||
3816 | } | ||
3817 | } | ||
3818 | #endif | ||
3819 | |||
3820 | /* Warning: From here, the custom mode entries in SiS_Pr are | ||
3821 | * possibly overwritten | ||
3822 | */ | ||
3823 | |||
3824 | SiS_DisplayOn(SiS_Pr); | ||
3825 | SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); | ||
3826 | |||
3827 | if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { | ||
3828 | if(SiS_Pr->ChipType >= SIS_315H) { | ||
3829 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg); | ||
3830 | } else if((SiS_Pr->ChipType == SIS_630) || | ||
3831 | (SiS_Pr->ChipType == SIS_730)) { | ||
3832 | SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg); | ||
3833 | } | ||
3834 | } | ||
3835 | |||
3836 | SiS_Handle760(SiS_Pr); | ||
3837 | |||
3838 | /* Backup/Set ModeNo in BIOS scratch area */ | ||
3839 | SiS_GetSetModeID(pScrn,ModeNo); | ||
3840 | |||
3841 | return true; | ||
3842 | } | ||
3843 | #endif /* Linux_XF86 */ | ||
3844 | |||
3845 | #ifndef GETBITSTR | 3325 | #ifndef GETBITSTR |
3846 | #define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l)) | 3326 | #define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l)) |
3847 | #define GENMASK(mask) BITMASK(1?mask,0?mask) | 3327 | #define GENMASK(mask) BITMASK(1?mask,0?mask) |
@@ -3927,7 +3407,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
3927 | SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE; | 3407 | SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE; |
3928 | 3408 | ||
3929 | if(SiS_Pr->ChipType < SIS_315H) { | 3409 | if(SiS_Pr->ChipType < SIS_315H) { |
3930 | #ifdef SIS300 | 3410 | #ifdef CONFIG_FB_SIS_300 |
3931 | tempbx = SiS_Pr->SiS_VGAHT; | 3411 | tempbx = SiS_Pr->SiS_VGAHT; |
3932 | if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { | 3412 | if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { |
3933 | tempbx = SiS_Pr->PanelHT; | 3413 | tempbx = SiS_Pr->PanelHT; |
@@ -3936,7 +3416,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
3936 | remaining = tempbx % 8; | 3416 | remaining = tempbx % 8; |
3937 | #endif | 3417 | #endif |
3938 | } else { | 3418 | } else { |
3939 | #ifdef SIS315H | 3419 | #ifdef CONFIG_FB_SIS_315 |
3940 | /* OK for LCDA, LVDS */ | 3420 | /* OK for LCDA, LVDS */ |
3941 | tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes; | 3421 | tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes; |
3942 | tempax = SiS_Pr->SiS_VGAHDE; /* not /2 ! */ | 3422 | tempax = SiS_Pr->SiS_VGAHDE; /* not /2 ! */ |
@@ -3950,7 +3430,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
3950 | SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx; | 3430 | SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx; |
3951 | 3431 | ||
3952 | if(SiS_Pr->ChipType < SIS_315H) { | 3432 | if(SiS_Pr->ChipType < SIS_315H) { |
3953 | #ifdef SIS300 | 3433 | #ifdef CONFIG_FB_SIS_300 |
3954 | if(SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) { | 3434 | if(SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) { |
3955 | SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE + ((SiS_Pr->PanelHRS + 1) & ~1); | 3435 | SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE + ((SiS_Pr->PanelHRS + 1) & ~1); |
3956 | SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + SiS_Pr->PanelHRE; | 3436 | SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + SiS_Pr->PanelHRE; |
@@ -3982,7 +3462,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
3982 | } | 3462 | } |
3983 | #endif | 3463 | #endif |
3984 | } else { | 3464 | } else { |
3985 | #ifdef SIS315H | 3465 | #ifdef CONFIG_FB_SIS_315 |
3986 | tempax = VGAHDE; | 3466 | tempax = VGAHDE; |
3987 | if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { | 3467 | if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { |
3988 | tempbx = SiS_Pr->PanelXRes; | 3468 | tempbx = SiS_Pr->PanelXRes; |
@@ -4001,7 +3481,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
4001 | if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { | 3481 | if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { |
4002 | tempax = SiS_Pr->PanelYRes; | 3482 | tempax = SiS_Pr->PanelYRes; |
4003 | } else if(SiS_Pr->ChipType < SIS_315H) { | 3483 | } else if(SiS_Pr->ChipType < SIS_315H) { |
4004 | #ifdef SIS300 | 3484 | #ifdef CONFIG_FB_SIS_300 |
4005 | /* Stupid hack for 640x400/320x200 */ | 3485 | /* Stupid hack for 640x400/320x200 */ |
4006 | if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { | 3486 | if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { |
4007 | if((tempax + tempbx) == 438) tempbx += 16; | 3487 | if((tempax + tempbx) == 438) tempbx += 16; |
@@ -4054,36 +3534,12 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
4054 | if(modeflag & DoubleScanMode) tempax |= 0x80; | 3534 | if(modeflag & DoubleScanMode) tempax |= 0x80; |
4055 | SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax); | 3535 | SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax); |
4056 | 3536 | ||
4057 | #ifdef SIS_XORG_XF86 | ||
4058 | #ifdef TWDEBUG | ||
4059 | xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n", | ||
4060 | SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal, | ||
4061 | SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal, | ||
4062 | SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd); | ||
4063 | xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", | ||
4064 | SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1], | ||
4065 | SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3], | ||
4066 | SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5], | ||
4067 | SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]); | ||
4068 | xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", | ||
4069 | SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9], | ||
4070 | SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11], | ||
4071 | SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13], | ||
4072 | SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]); | ||
4073 | xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]); | ||
4074 | #endif | ||
4075 | #endif | ||
4076 | } | 3537 | } |
4077 | 3538 | ||
4078 | void | 3539 | void |
4079 | SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, | 3540 | SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, |
4080 | int xres, int yres, | 3541 | int xres, int yres, |
4081 | #ifdef SIS_XORG_XF86 | ||
4082 | DisplayModePtr current | ||
4083 | #endif | ||
4084 | #ifdef SIS_LINUX_KERNEL | ||
4085 | struct fb_var_screeninfo *var, bool writeres | 3542 | struct fb_var_screeninfo *var, bool writeres |
4086 | #endif | ||
4087 | ) | 3543 | ) |
4088 | { | 3544 | { |
4089 | unsigned short HRE, HBE, HRS, HBS, HDE, HT; | 3545 | unsigned short HRE, HBE, HRS, HBS, HDE, HT; |
@@ -4127,25 +3583,10 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, | |||
4127 | 3583 | ||
4128 | D = B - F - C; | 3584 | D = B - F - C; |
4129 | 3585 | ||
4130 | #ifdef SIS_XORG_XF86 | ||
4131 | current->HDisplay = (E * 8); | ||
4132 | current->HSyncStart = (E * 8) + (F * 8); | ||
4133 | current->HSyncEnd = (E * 8) + (F * 8) + (C * 8); | ||
4134 | current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8); | ||
4135 | #ifdef TWDEBUG | ||
4136 | xf86DrvMsg(0, X_INFO, | ||
4137 | "H: A %d B %d C %d D %d E %d F %d HT %d HDE %d HRS %d HBS %d HBE %d HRE %d\n", | ||
4138 | A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE); | ||
4139 | #else | ||
4140 | (void)VBS; (void)HBS; (void)A; | ||
4141 | #endif | ||
4142 | #endif | ||
4143 | #ifdef SIS_LINUX_KERNEL | ||
4144 | if(writeres) var->xres = xres = E * 8; | 3586 | if(writeres) var->xres = xres = E * 8; |
4145 | var->left_margin = D * 8; | 3587 | var->left_margin = D * 8; |
4146 | var->right_margin = F * 8; | 3588 | var->right_margin = F * 8; |
4147 | var->hsync_len = C * 8; | 3589 | var->hsync_len = C * 8; |
4148 | #endif | ||
4149 | 3590 | ||
4150 | /* Vertical */ | 3591 | /* Vertical */ |
4151 | sr_data = crdata[13]; | 3592 | sr_data = crdata[13]; |
@@ -4192,30 +3633,10 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, | |||
4192 | 3633 | ||
4193 | D = B - F - C; | 3634 | D = B - F - C; |
4194 | 3635 | ||
4195 | #ifdef SIS_XORG_XF86 | ||
4196 | current->VDisplay = VDE + 1; | ||
4197 | current->VSyncStart = VRS + 1; | ||
4198 | current->VSyncEnd = ((VRS & ~0x1f) | VRE) + 1; | ||
4199 | if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32; | ||
4200 | current->VTotal = E + D + C + F; | ||
4201 | #if 0 | ||
4202 | current->VDisplay = E; | ||
4203 | current->VSyncStart = E + D; | ||
4204 | current->VSyncEnd = E + D + C; | ||
4205 | current->VTotal = E + D + C + F; | ||
4206 | #endif | ||
4207 | #ifdef TWDEBUG | ||
4208 | xf86DrvMsg(0, X_INFO, | ||
4209 | "V: A %d B %d C %d D %d E %d F %d VT %d VDE %d VRS %d VBS %d VBE %d VRE %d\n", | ||
4210 | A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE); | ||
4211 | #endif | ||
4212 | #endif | ||
4213 | #ifdef SIS_LINUX_KERNEL | ||
4214 | if(writeres) var->yres = yres = E; | 3636 | if(writeres) var->yres = yres = E; |
4215 | var->upper_margin = D; | 3637 | var->upper_margin = D; |
4216 | var->lower_margin = F; | 3638 | var->lower_margin = F; |
4217 | var->vsync_len = C; | 3639 | var->vsync_len = C; |
4218 | #endif | ||
4219 | 3640 | ||
4220 | if((xres == 320) && ((yres == 200) || (yres == 240))) { | 3641 | if((xres == 320) && ((yres == 200) || (yres == 240))) { |
4221 | /* Terrible hack, but correct CRTC data for | 3642 | /* Terrible hack, but correct CRTC data for |
@@ -4224,17 +3645,9 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, | |||
4224 | * a negative D. The CRT controller does not | 3645 | * a negative D. The CRT controller does not |
4225 | * seem to like correcting HRE to 50) | 3646 | * seem to like correcting HRE to 50) |
4226 | */ | 3647 | */ |
4227 | #ifdef SIS_XORG_XF86 | ||
4228 | current->HDisplay = 320; | ||
4229 | current->HSyncStart = 328; | ||
4230 | current->HSyncEnd = 376; | ||
4231 | current->HTotal = 400; | ||
4232 | #endif | ||
4233 | #ifdef SIS_LINUX_KERNEL | ||
4234 | var->left_margin = (400 - 376); | 3648 | var->left_margin = (400 - 376); |
4235 | var->right_margin = (328 - 320); | 3649 | var->right_margin = (328 - 320); |
4236 | var->hsync_len = (376 - 328); | 3650 | var->hsync_len = (376 - 328); |
4237 | #endif | ||
4238 | 3651 | ||
4239 | } | 3652 | } |
4240 | 3653 | ||
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h index b96005c39c67..ee8ed3c203da 100644 --- a/drivers/video/sis/init.h +++ b/drivers/video/sis/init.h | |||
@@ -53,21 +53,8 @@ | |||
53 | #ifndef _INIT_H_ | 53 | #ifndef _INIT_H_ |
54 | #define _INIT_H_ | 54 | #define _INIT_H_ |
55 | 55 | ||
56 | #include "osdef.h" | ||
57 | #include "initdef.h" | 56 | #include "initdef.h" |
58 | 57 | ||
59 | #ifdef SIS_XORG_XF86 | ||
60 | #include "sis.h" | ||
61 | #define SIS_NEED_inSISREG | ||
62 | #define SIS_NEED_inSISREGW | ||
63 | #define SIS_NEED_inSISREGL | ||
64 | #define SIS_NEED_outSISREG | ||
65 | #define SIS_NEED_outSISREGW | ||
66 | #define SIS_NEED_outSISREGL | ||
67 | #include "sis_regs.h" | ||
68 | #endif | ||
69 | |||
70 | #ifdef SIS_LINUX_KERNEL | ||
71 | #include "vgatypes.h" | 58 | #include "vgatypes.h" |
72 | #include "vstruct.h" | 59 | #include "vstruct.h" |
73 | #ifdef SIS_CP | 60 | #ifdef SIS_CP |
@@ -78,7 +65,6 @@ | |||
78 | #include <linux/fb.h> | 65 | #include <linux/fb.h> |
79 | #include "sis.h" | 66 | #include "sis.h" |
80 | #include <video/sisfb.h> | 67 | #include <video/sisfb.h> |
81 | #endif | ||
82 | 68 | ||
83 | /* Mode numbers */ | 69 | /* Mode numbers */ |
84 | static const unsigned short ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f}; | 70 | static const unsigned short ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f}; |
@@ -286,7 +272,7 @@ static const struct SiS_ModeResInfo_S SiS_ModeResInfo[] = | |||
286 | { 1280, 854, 8,16} /* 0x22 */ | 272 | { 1280, 854, 8,16} /* 0x22 */ |
287 | }; | 273 | }; |
288 | 274 | ||
289 | #if defined(SIS300) || defined(SIS315H) | 275 | #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) |
290 | static const struct SiS_StandTable_S SiS_StandTable[]= | 276 | static const struct SiS_StandTable_S SiS_StandTable[]= |
291 | { | 277 | { |
292 | /* 0x00: MD_0_200 */ | 278 | /* 0x00: MD_0_200 */ |
@@ -1521,10 +1507,6 @@ static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1640x480_1_H[] = | |||
1521 | }; | 1507 | }; |
1522 | 1508 | ||
1523 | bool SiSInitPtr(struct SiS_Private *SiS_Pr); | 1509 | bool SiSInitPtr(struct SiS_Private *SiS_Pr); |
1524 | #ifdef SIS_XORG_XF86 | ||
1525 | unsigned short SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, | ||
1526 | int Depth, bool FSTN, int LCDwith, int LCDheight); | ||
1527 | #endif | ||
1528 | unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, | 1510 | unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, |
1529 | int VDisplay, int Depth, bool FSTN, | 1511 | int VDisplay, int Depth, bool FSTN, |
1530 | unsigned short CustomT, int LCDwith, int LCDheight, | 1512 | unsigned short CustomT, int LCDwith, int LCDheight, |
@@ -1550,17 +1532,11 @@ void SiS_SetRegOR(SISIOADDRESS Port,unsigned short Index, unsigned short DataOR | |||
1550 | void SiS_DisplayOn(struct SiS_Private *SiS_Pr); | 1532 | void SiS_DisplayOn(struct SiS_Private *SiS_Pr); |
1551 | void SiS_DisplayOff(struct SiS_Private *SiS_Pr); | 1533 | void SiS_DisplayOff(struct SiS_Private *SiS_Pr); |
1552 | void SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr); | 1534 | void SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr); |
1553 | #ifndef SIS_LINUX_KERNEL | ||
1554 | void SiSSetLVDSetc(struct SiS_Private *SiS_Pr); | ||
1555 | #endif | ||
1556 | void SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable); | 1535 | void SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable); |
1557 | void SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable); | 1536 | void SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable); |
1558 | unsigned short SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 1537 | unsigned short SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
1559 | unsigned short ModeIdIndex); | 1538 | unsigned short ModeIdIndex); |
1560 | bool SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr); | 1539 | bool SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr); |
1561 | #ifndef SIS_LINUX_KERNEL | ||
1562 | void SiS_GetVBType(struct SiS_Private *SiS_Pr); | ||
1563 | #endif | ||
1564 | 1540 | ||
1565 | bool SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, | 1541 | bool SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, |
1566 | unsigned short *ModeIdIndex); | 1542 | unsigned short *ModeIdIndex); |
@@ -1572,37 +1548,19 @@ unsigned short SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short Mode | |||
1572 | unsigned short ModeIdIndex); | 1548 | unsigned short ModeIdIndex); |
1573 | unsigned short SiS_GetOffset(struct SiS_Private *SiS_Pr,unsigned short ModeNo, | 1549 | unsigned short SiS_GetOffset(struct SiS_Private *SiS_Pr,unsigned short ModeNo, |
1574 | unsigned short ModeIdIndex, unsigned short RRTI); | 1550 | unsigned short ModeIdIndex, unsigned short RRTI); |
1575 | #ifdef SIS300 | 1551 | #ifdef CONFIG_FB_SIS_300 |
1576 | void SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1, | 1552 | void SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1, |
1577 | unsigned short *idx2); | 1553 | unsigned short *idx2); |
1578 | unsigned short SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2); | 1554 | unsigned short SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2); |
1579 | unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index); | 1555 | unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index); |
1580 | #endif | 1556 | #endif |
1581 | void SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex); | 1557 | void SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex); |
1582 | #ifdef SIS_XORG_XF86 | ||
1583 | bool SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo, | ||
1584 | bool dosetpitch); | ||
1585 | bool SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, | ||
1586 | DisplayModePtr mode, bool IsCustom); | ||
1587 | bool SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, | ||
1588 | DisplayModePtr mode, bool IsCustom); | ||
1589 | bool SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, | ||
1590 | DisplayModePtr mode, bool IsCustom); | ||
1591 | #endif | ||
1592 | #ifdef SIS_LINUX_KERNEL | ||
1593 | bool SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); | 1558 | bool SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); |
1594 | #endif | ||
1595 | void SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth); | 1559 | void SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth); |
1596 | void SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 1560 | void SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
1597 | unsigned short ModeIdIndex); | 1561 | unsigned short ModeIdIndex); |
1598 | #ifdef SIS_XORG_XF86 | ||
1599 | void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres, | ||
1600 | int yres, DisplayModePtr current); | ||
1601 | #endif | ||
1602 | #ifdef SIS_LINUX_KERNEL | ||
1603 | void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres, | 1562 | void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres, |
1604 | int yres, struct fb_var_screeninfo *var, bool writeres); | 1563 | int yres, struct fb_var_screeninfo *var, bool writeres); |
1605 | #endif | ||
1606 | 1564 | ||
1607 | /* From init301.c: */ | 1565 | /* From init301.c: */ |
1608 | extern void SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 1566 | extern void SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
@@ -1626,29 +1584,16 @@ extern unsigned short SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short | |||
1626 | extern bool SiS_IsVAMode(struct SiS_Private *); | 1584 | extern bool SiS_IsVAMode(struct SiS_Private *); |
1627 | extern bool SiS_IsDualEdge(struct SiS_Private *); | 1585 | extern bool SiS_IsDualEdge(struct SiS_Private *); |
1628 | 1586 | ||
1629 | #ifdef SIS_XORG_XF86 | 1587 | #ifdef CONFIG_FB_SIS_300 |
1630 | /* From other modules: */ | ||
1631 | extern unsigned short SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, | ||
1632 | unsigned int VBFlags); | ||
1633 | extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, unsigned short offset, | ||
1634 | unsigned char value); | ||
1635 | extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id); | ||
1636 | extern unsigned short SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, | ||
1637 | unsigned int VBFlags); | ||
1638 | #endif | ||
1639 | |||
1640 | #ifdef SIS_LINUX_KERNEL | ||
1641 | #ifdef SIS300 | ||
1642 | extern unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg); | 1588 | extern unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg); |
1643 | extern void sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg, | 1589 | extern void sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg, |
1644 | unsigned int val); | 1590 | unsigned int val); |
1645 | #endif | 1591 | #endif |
1646 | #ifdef SIS315H | 1592 | #ifdef CONFIG_FB_SIS_315 |
1647 | extern void sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg, | 1593 | extern void sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg, |
1648 | unsigned char val); | 1594 | unsigned char val); |
1649 | extern unsigned int sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg); | 1595 | extern unsigned int sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg); |
1650 | #endif | 1596 | #endif |
1651 | #endif | ||
1652 | 1597 | ||
1653 | #endif | 1598 | #endif |
1654 | 1599 | ||
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c index da33d801c22e..9fa66fd4052a 100644 --- a/drivers/video/sis/init301.c +++ b/drivers/video/sis/init301.c | |||
@@ -75,11 +75,11 @@ | |||
75 | 75 | ||
76 | #include "init301.h" | 76 | #include "init301.h" |
77 | 77 | ||
78 | #ifdef SIS300 | 78 | #ifdef CONFIG_FB_SIS_300 |
79 | #include "oem300.h" | 79 | #include "oem300.h" |
80 | #endif | 80 | #endif |
81 | 81 | ||
82 | #ifdef SIS315H | 82 | #ifdef CONFIG_FB_SIS_315 |
83 | #include "oem310.h" | 83 | #include "oem310.h" |
84 | #endif | 84 | #endif |
85 | 85 | ||
@@ -87,9 +87,7 @@ | |||
87 | #define SiS_I2CDELAYSHORT 150 | 87 | #define SiS_I2CDELAYSHORT 150 |
88 | 88 | ||
89 | static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr); | 89 | static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr); |
90 | #ifdef SIS_LINUX_KERNEL | ||
91 | static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val); | 90 | static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val); |
92 | #endif | ||
93 | 91 | ||
94 | /*********************************************/ | 92 | /*********************************************/ |
95 | /* HELPER: Lock/Unlock CRT2 */ | 93 | /* HELPER: Lock/Unlock CRT2 */ |
@@ -106,9 +104,7 @@ SiS_UnLockCRT2(struct SiS_Private *SiS_Pr) | |||
106 | SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01); | 104 | SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01); |
107 | } | 105 | } |
108 | 106 | ||
109 | #ifdef SIS_LINUX_KERNEL | ||
110 | static | 107 | static |
111 | #endif | ||
112 | void | 108 | void |
113 | SiS_LockCRT2(struct SiS_Private *SiS_Pr) | 109 | SiS_LockCRT2(struct SiS_Private *SiS_Pr) |
114 | { | 110 | { |
@@ -138,7 +134,7 @@ SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned | |||
138 | /* HELPER: Get Pointer to LCD structure */ | 134 | /* HELPER: Get Pointer to LCD structure */ |
139 | /*********************************************/ | 135 | /*********************************************/ |
140 | 136 | ||
141 | #ifdef SIS315H | 137 | #ifdef CONFIG_FB_SIS_315 |
142 | static unsigned char * | 138 | static unsigned char * |
143 | GetLCDStructPtr661(struct SiS_Private *SiS_Pr) | 139 | GetLCDStructPtr661(struct SiS_Private *SiS_Pr) |
144 | { | 140 | { |
@@ -404,7 +400,7 @@ SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
404 | /* HELPER: GET SOME DATA FROM BIOS ROM */ | 400 | /* HELPER: GET SOME DATA FROM BIOS ROM */ |
405 | /*********************************************/ | 401 | /*********************************************/ |
406 | 402 | ||
407 | #ifdef SIS300 | 403 | #ifdef CONFIG_FB_SIS_300 |
408 | static bool | 404 | static bool |
409 | SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr) | 405 | SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr) |
410 | { | 406 | { |
@@ -449,7 +445,7 @@ SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime) | |||
449 | SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05); | 445 | SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05); |
450 | } | 446 | } |
451 | 447 | ||
452 | #if defined(SIS300) || defined(SIS315H) | 448 | #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) |
453 | static void | 449 | static void |
454 | SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay) | 450 | SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay) |
455 | { | 451 | { |
@@ -457,7 +453,7 @@ SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay) | |||
457 | } | 453 | } |
458 | #endif | 454 | #endif |
459 | 455 | ||
460 | #ifdef SIS315H | 456 | #ifdef CONFIG_FB_SIS_315 |
461 | static void | 457 | static void |
462 | SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay) | 458 | SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay) |
463 | { | 459 | { |
@@ -467,7 +463,7 @@ SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay) | |||
467 | } | 463 | } |
468 | #endif | 464 | #endif |
469 | 465 | ||
470 | #if defined(SIS300) || defined(SIS315H) | 466 | #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) |
471 | static void | 467 | static void |
472 | SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay) | 468 | SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay) |
473 | { | 469 | { |
@@ -480,14 +476,14 @@ SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay) | |||
480 | static void | 476 | static void |
481 | SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime) | 477 | SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime) |
482 | { | 478 | { |
483 | #if defined(SIS300) || defined(SIS315H) | 479 | #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) |
484 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; | 480 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; |
485 | unsigned short PanelID, DelayIndex, Delay=0; | 481 | unsigned short PanelID, DelayIndex, Delay=0; |
486 | #endif | 482 | #endif |
487 | 483 | ||
488 | if(SiS_Pr->ChipType < SIS_315H) { | 484 | if(SiS_Pr->ChipType < SIS_315H) { |
489 | 485 | ||
490 | #ifdef SIS300 | 486 | #ifdef CONFIG_FB_SIS_300 |
491 | 487 | ||
492 | PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); | 488 | PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); |
493 | if(SiS_Pr->SiS_VBType & VB_SISVB) { | 489 | if(SiS_Pr->SiS_VBType & VB_SISVB) { |
@@ -513,11 +509,11 @@ SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime) | |||
513 | } | 509 | } |
514 | SiS_ShortDelay(SiS_Pr, Delay); | 510 | SiS_ShortDelay(SiS_Pr, Delay); |
515 | 511 | ||
516 | #endif /* SIS300 */ | 512 | #endif /* CONFIG_FB_SIS_300 */ |
517 | 513 | ||
518 | } else { | 514 | } else { |
519 | 515 | ||
520 | #ifdef SIS315H | 516 | #ifdef CONFIG_FB_SIS_315 |
521 | 517 | ||
522 | if((SiS_Pr->ChipType >= SIS_661) || | 518 | if((SiS_Pr->ChipType >= SIS_661) || |
523 | (SiS_Pr->ChipType <= SIS_315PRO) || | 519 | (SiS_Pr->ChipType <= SIS_315PRO) || |
@@ -579,12 +575,12 @@ SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime) | |||
579 | 575 | ||
580 | } | 576 | } |
581 | 577 | ||
582 | #endif /* SIS315H */ | 578 | #endif /* CONFIG_FB_SIS_315 */ |
583 | 579 | ||
584 | } | 580 | } |
585 | } | 581 | } |
586 | 582 | ||
587 | #ifdef SIS315H | 583 | #ifdef CONFIG_FB_SIS_315 |
588 | static void | 584 | static void |
589 | SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop) | 585 | SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop) |
590 | { | 586 | { |
@@ -613,7 +609,7 @@ SiS_WaitRetrace1(struct SiS_Private *SiS_Pr) | |||
613 | while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog); | 609 | while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog); |
614 | } | 610 | } |
615 | 611 | ||
616 | #if defined(SIS300) || defined(SIS315H) | 612 | #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) |
617 | static void | 613 | static void |
618 | SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg) | 614 | SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg) |
619 | { | 615 | { |
@@ -630,7 +626,7 @@ static void | |||
630 | SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr) | 626 | SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr) |
631 | { | 627 | { |
632 | if(SiS_Pr->ChipType < SIS_315H) { | 628 | if(SiS_Pr->ChipType < SIS_315H) { |
633 | #ifdef SIS300 | 629 | #ifdef CONFIG_FB_SIS_300 |
634 | if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { | 630 | if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { |
635 | if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return; | 631 | if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return; |
636 | } | 632 | } |
@@ -641,7 +637,7 @@ SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr) | |||
641 | } | 637 | } |
642 | #endif | 638 | #endif |
643 | } else { | 639 | } else { |
644 | #ifdef SIS315H | 640 | #ifdef CONFIG_FB_SIS_315 |
645 | if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) { | 641 | if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) { |
646 | SiS_WaitRetrace1(SiS_Pr); | 642 | SiS_WaitRetrace1(SiS_Pr); |
647 | } else { | 643 | } else { |
@@ -686,7 +682,7 @@ SiS_VBLongWait(struct SiS_Private *SiS_Pr) | |||
686 | /* HELPER: MISC */ | 682 | /* HELPER: MISC */ |
687 | /*********************************************/ | 683 | /*********************************************/ |
688 | 684 | ||
689 | #ifdef SIS300 | 685 | #ifdef CONFIG_FB_SIS_300 |
690 | static bool | 686 | static bool |
691 | SiS_Is301B(struct SiS_Private *SiS_Pr) | 687 | SiS_Is301B(struct SiS_Private *SiS_Pr) |
692 | { | 688 | { |
@@ -708,7 +704,7 @@ SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr) | |||
708 | bool | 704 | bool |
709 | SiS_IsDualEdge(struct SiS_Private *SiS_Pr) | 705 | SiS_IsDualEdge(struct SiS_Private *SiS_Pr) |
710 | { | 706 | { |
711 | #ifdef SIS315H | 707 | #ifdef CONFIG_FB_SIS_315 |
712 | if(SiS_Pr->ChipType >= SIS_315H) { | 708 | if(SiS_Pr->ChipType >= SIS_315H) { |
713 | if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) { | 709 | if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) { |
714 | if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true; | 710 | if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true; |
@@ -721,7 +717,7 @@ SiS_IsDualEdge(struct SiS_Private *SiS_Pr) | |||
721 | bool | 717 | bool |
722 | SiS_IsVAMode(struct SiS_Private *SiS_Pr) | 718 | SiS_IsVAMode(struct SiS_Private *SiS_Pr) |
723 | { | 719 | { |
724 | #ifdef SIS315H | 720 | #ifdef CONFIG_FB_SIS_315 |
725 | unsigned short flag; | 721 | unsigned short flag; |
726 | 722 | ||
727 | if(SiS_Pr->ChipType >= SIS_315H) { | 723 | if(SiS_Pr->ChipType >= SIS_315H) { |
@@ -732,7 +728,7 @@ SiS_IsVAMode(struct SiS_Private *SiS_Pr) | |||
732 | return false; | 728 | return false; |
733 | } | 729 | } |
734 | 730 | ||
735 | #ifdef SIS315H | 731 | #ifdef CONFIG_FB_SIS_315 |
736 | static bool | 732 | static bool |
737 | SiS_IsVAorLCD(struct SiS_Private *SiS_Pr) | 733 | SiS_IsVAorLCD(struct SiS_Private *SiS_Pr) |
738 | { | 734 | { |
@@ -745,7 +741,7 @@ SiS_IsVAorLCD(struct SiS_Private *SiS_Pr) | |||
745 | static bool | 741 | static bool |
746 | SiS_IsDualLink(struct SiS_Private *SiS_Pr) | 742 | SiS_IsDualLink(struct SiS_Private *SiS_Pr) |
747 | { | 743 | { |
748 | #ifdef SIS315H | 744 | #ifdef CONFIG_FB_SIS_315 |
749 | if(SiS_Pr->ChipType >= SIS_315H) { | 745 | if(SiS_Pr->ChipType >= SIS_315H) { |
750 | if((SiS_CRT2IsLCD(SiS_Pr)) || | 746 | if((SiS_CRT2IsLCD(SiS_Pr)) || |
751 | (SiS_IsVAMode(SiS_Pr))) { | 747 | (SiS_IsVAMode(SiS_Pr))) { |
@@ -756,7 +752,7 @@ SiS_IsDualLink(struct SiS_Private *SiS_Pr) | |||
756 | return false; | 752 | return false; |
757 | } | 753 | } |
758 | 754 | ||
759 | #ifdef SIS315H | 755 | #ifdef CONFIG_FB_SIS_315 |
760 | static bool | 756 | static bool |
761 | SiS_TVEnabled(struct SiS_Private *SiS_Pr) | 757 | SiS_TVEnabled(struct SiS_Private *SiS_Pr) |
762 | { | 758 | { |
@@ -768,7 +764,7 @@ SiS_TVEnabled(struct SiS_Private *SiS_Pr) | |||
768 | } | 764 | } |
769 | #endif | 765 | #endif |
770 | 766 | ||
771 | #ifdef SIS315H | 767 | #ifdef CONFIG_FB_SIS_315 |
772 | static bool | 768 | static bool |
773 | SiS_LCDAEnabled(struct SiS_Private *SiS_Pr) | 769 | SiS_LCDAEnabled(struct SiS_Private *SiS_Pr) |
774 | { | 770 | { |
@@ -777,7 +773,7 @@ SiS_LCDAEnabled(struct SiS_Private *SiS_Pr) | |||
777 | } | 773 | } |
778 | #endif | 774 | #endif |
779 | 775 | ||
780 | #ifdef SIS315H | 776 | #ifdef CONFIG_FB_SIS_315 |
781 | static bool | 777 | static bool |
782 | SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr) | 778 | SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr) |
783 | { | 779 | { |
@@ -788,7 +784,7 @@ SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr) | |||
788 | } | 784 | } |
789 | #endif | 785 | #endif |
790 | 786 | ||
791 | #ifdef SIS315H | 787 | #ifdef CONFIG_FB_SIS_315 |
792 | static bool | 788 | static bool |
793 | SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr) | 789 | SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr) |
794 | { | 790 | { |
@@ -804,7 +800,7 @@ SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr) | |||
804 | } | 800 | } |
805 | #endif | 801 | #endif |
806 | 802 | ||
807 | #ifdef SIS315H | 803 | #ifdef CONFIG_FB_SIS_315 |
808 | static bool | 804 | static bool |
809 | SiS_IsYPbPr(struct SiS_Private *SiS_Pr) | 805 | SiS_IsYPbPr(struct SiS_Private *SiS_Pr) |
810 | { | 806 | { |
@@ -816,7 +812,7 @@ SiS_IsYPbPr(struct SiS_Private *SiS_Pr) | |||
816 | } | 812 | } |
817 | #endif | 813 | #endif |
818 | 814 | ||
819 | #ifdef SIS315H | 815 | #ifdef CONFIG_FB_SIS_315 |
820 | static bool | 816 | static bool |
821 | SiS_IsChScart(struct SiS_Private *SiS_Pr) | 817 | SiS_IsChScart(struct SiS_Private *SiS_Pr) |
822 | { | 818 | { |
@@ -828,7 +824,7 @@ SiS_IsChScart(struct SiS_Private *SiS_Pr) | |||
828 | } | 824 | } |
829 | #endif | 825 | #endif |
830 | 826 | ||
831 | #ifdef SIS315H | 827 | #ifdef CONFIG_FB_SIS_315 |
832 | static bool | 828 | static bool |
833 | SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr) | 829 | SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr) |
834 | { | 830 | { |
@@ -848,7 +844,7 @@ SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr) | |||
848 | } | 844 | } |
849 | #endif | 845 | #endif |
850 | 846 | ||
851 | #ifdef SIS315H | 847 | #ifdef CONFIG_FB_SIS_315 |
852 | static bool | 848 | static bool |
853 | SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr) | 849 | SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr) |
854 | { | 850 | { |
@@ -914,7 +910,7 @@ SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr) | |||
914 | /*********************************************/ | 910 | /*********************************************/ |
915 | 911 | ||
916 | /* Setup general purpose IO for Chrontel communication */ | 912 | /* Setup general purpose IO for Chrontel communication */ |
917 | #ifdef SIS300 | 913 | #ifdef CONFIG_FB_SIS_300 |
918 | void | 914 | void |
919 | SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo) | 915 | SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo) |
920 | { | 916 | { |
@@ -923,11 +919,7 @@ SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo) | |||
923 | 919 | ||
924 | if(!(SiS_Pr->SiS_ChSW)) return; | 920 | if(!(SiS_Pr->SiS_ChSW)) return; |
925 | 921 | ||
926 | #ifdef SIS_LINUX_KERNEL | ||
927 | acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74); | 922 | acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74); |
928 | #else | ||
929 | acpibase = pciReadLong(0x00000800, 0x74); | ||
930 | #endif | ||
931 | acpibase &= 0xFFFF; | 923 | acpibase &= 0xFFFF; |
932 | if(!acpibase) return; | 924 | if(!acpibase) return; |
933 | temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */ | 925 | temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */ |
@@ -969,7 +961,7 @@ SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
969 | tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV); | 961 | tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV); |
970 | tempbx |= tempax; | 962 | tempbx |= tempax; |
971 | 963 | ||
972 | #ifdef SIS315H | 964 | #ifdef CONFIG_FB_SIS_315 |
973 | if(SiS_Pr->ChipType >= SIS_315H) { | 965 | if(SiS_Pr->ChipType >= SIS_315H) { |
974 | if(SiS_Pr->SiS_VBType & VB_SISLCDA) { | 966 | if(SiS_Pr->SiS_VBType & VB_SISLCDA) { |
975 | if(ModeNo == 0x03) { | 967 | if(ModeNo == 0x03) { |
@@ -1019,7 +1011,7 @@ SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
1019 | } | 1011 | } |
1020 | } | 1012 | } |
1021 | 1013 | ||
1022 | #endif /* SIS315H */ | 1014 | #endif /* CONFIG_FB_SIS_315 */ |
1023 | 1015 | ||
1024 | if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) { | 1016 | if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) { |
1025 | tempbx &= ~(SetCRT2ToRAMDAC); | 1017 | tempbx &= ~(SetCRT2ToRAMDAC); |
@@ -1154,24 +1146,16 @@ SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
1154 | 1146 | ||
1155 | SiS_Pr->SiS_VBInfo = tempbx; | 1147 | SiS_Pr->SiS_VBInfo = tempbx; |
1156 | 1148 | ||
1157 | #ifdef SIS300 | 1149 | #ifdef CONFIG_FB_SIS_300 |
1158 | if(SiS_Pr->ChipType == SIS_630) { | 1150 | if(SiS_Pr->ChipType == SIS_630) { |
1159 | SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo); | 1151 | SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo); |
1160 | } | 1152 | } |
1161 | #endif | 1153 | #endif |
1162 | 1154 | ||
1163 | #ifdef SIS_LINUX_KERNEL | ||
1164 | #if 0 | 1155 | #if 0 |
1165 | printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n", | 1156 | printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n", |
1166 | SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag); | 1157 | SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag); |
1167 | #endif | 1158 | #endif |
1168 | #endif | ||
1169 | #ifdef SIS_XORG_XF86 | ||
1170 | #ifdef TWDEBUG | ||
1171 | xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n", | ||
1172 | SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag); | ||
1173 | #endif | ||
1174 | #endif | ||
1175 | } | 1159 | } |
1176 | 1160 | ||
1177 | /*********************************************/ | 1161 | /*********************************************/ |
@@ -1415,12 +1399,6 @@ SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
1415 | } | 1399 | } |
1416 | 1400 | ||
1417 | SiS_Pr->SiS_VBInfo &= ~SetPALTV; | 1401 | SiS_Pr->SiS_VBInfo &= ~SetPALTV; |
1418 | |||
1419 | #ifdef SIS_XORG_XF86 | ||
1420 | #ifdef TWDEBUG | ||
1421 | xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo); | ||
1422 | #endif | ||
1423 | #endif | ||
1424 | } | 1402 | } |
1425 | 1403 | ||
1426 | /*********************************************/ | 1404 | /*********************************************/ |
@@ -1443,22 +1421,10 @@ SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr) | |||
1443 | static void | 1421 | static void |
1444 | SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr) | 1422 | SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr) |
1445 | { | 1423 | { |
1446 | #ifdef SIS315H | 1424 | #ifdef CONFIG_FB_SIS_315 |
1447 | unsigned char *ROMAddr; | 1425 | unsigned char *ROMAddr; |
1448 | unsigned short temp; | 1426 | unsigned short temp; |
1449 | 1427 | ||
1450 | #ifdef SIS_XORG_XF86 | ||
1451 | #ifdef TWDEBUG | ||
1452 | xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n", | ||
1453 | SiS_Pr->PanelHT, SiS_Pr->PanelVT, | ||
1454 | SiS_Pr->PanelHRS, SiS_Pr->PanelHRE, | ||
1455 | SiS_Pr->PanelVRS, SiS_Pr->PanelVRE, | ||
1456 | SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK, | ||
1457 | SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A, | ||
1458 | SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B); | ||
1459 | #endif | ||
1460 | #endif | ||
1461 | |||
1462 | if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) { | 1428 | if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) { |
1463 | if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) { | 1429 | if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) { |
1464 | SiS_Pr->SiS_NeedRomModeData = true; | 1430 | SiS_Pr->SiS_NeedRomModeData = true; |
@@ -1480,18 +1446,6 @@ SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr) | |||
1480 | SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C = | 1446 | SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C = |
1481 | SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20]; | 1447 | SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20]; |
1482 | 1448 | ||
1483 | #ifdef SIS_XORG_XF86 | ||
1484 | #ifdef TWDEBUG | ||
1485 | xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n", | ||
1486 | SiS_Pr->PanelHT, SiS_Pr->PanelVT, | ||
1487 | SiS_Pr->PanelHRS, SiS_Pr->PanelHRE, | ||
1488 | SiS_Pr->PanelVRS, SiS_Pr->PanelVRE, | ||
1489 | SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK, | ||
1490 | SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A, | ||
1491 | SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B); | ||
1492 | #endif | ||
1493 | #endif | ||
1494 | |||
1495 | } | 1449 | } |
1496 | #endif | 1450 | #endif |
1497 | } | 1451 | } |
@@ -1517,13 +1471,13 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh | |||
1517 | { | 1471 | { |
1518 | unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0; | 1472 | unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0; |
1519 | bool panelcanscale = false; | 1473 | bool panelcanscale = false; |
1520 | #ifdef SIS300 | 1474 | #ifdef CONFIG_FB_SIS_300 |
1521 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; | 1475 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; |
1522 | static const unsigned char SiS300SeriesLCDRes[] = | 1476 | static const unsigned char SiS300SeriesLCDRes[] = |
1523 | { 0, 1, 2, 3, 7, 4, 5, 8, | 1477 | { 0, 1, 2, 3, 7, 4, 5, 8, |
1524 | 0, 0, 10, 0, 0, 0, 0, 15 }; | 1478 | 0, 0, 10, 0, 0, 0, 0, 15 }; |
1525 | #endif | 1479 | #endif |
1526 | #ifdef SIS315H | 1480 | #ifdef CONFIG_FB_SIS_315 |
1527 | unsigned char *myptr = NULL; | 1481 | unsigned char *myptr = NULL; |
1528 | #endif | 1482 | #endif |
1529 | 1483 | ||
@@ -1562,7 +1516,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh | |||
1562 | SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1; | 1516 | SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1; |
1563 | } | 1517 | } |
1564 | temp &= 0x0f; | 1518 | temp &= 0x0f; |
1565 | #ifdef SIS300 | 1519 | #ifdef CONFIG_FB_SIS_300 |
1566 | if(SiS_Pr->ChipType < SIS_315H) { | 1520 | if(SiS_Pr->ChipType < SIS_315H) { |
1567 | /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */ | 1521 | /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */ |
1568 | if(SiS_Pr->SiS_VBType & VB_SIS301) { | 1522 | if(SiS_Pr->SiS_VBType & VB_SIS301) { |
@@ -1574,7 +1528,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh | |||
1574 | #endif | 1528 | #endif |
1575 | 1529 | ||
1576 | /* Translate to our internal types */ | 1530 | /* Translate to our internal types */ |
1577 | #ifdef SIS315H | 1531 | #ifdef CONFIG_FB_SIS_315 |
1578 | if(SiS_Pr->ChipType == SIS_550) { | 1532 | if(SiS_Pr->ChipType == SIS_550) { |
1579 | if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */ | 1533 | if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */ |
1580 | else if(temp == Panel310_320x240_2) temp = Panel_320x240_2; | 1534 | else if(temp == Panel310_320x240_2) temp = Panel_320x240_2; |
@@ -1597,7 +1551,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh | |||
1597 | 1551 | ||
1598 | SiS_Pr->SiS_LCDResInfo = temp; | 1552 | SiS_Pr->SiS_LCDResInfo = temp; |
1599 | 1553 | ||
1600 | #ifdef SIS300 | 1554 | #ifdef CONFIG_FB_SIS_300 |
1601 | if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { | 1555 | if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { |
1602 | if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { | 1556 | if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { |
1603 | SiS_Pr->SiS_LCDResInfo = Panel_Barco1366; | 1557 | SiS_Pr->SiS_LCDResInfo = Panel_Barco1366; |
@@ -1639,7 +1593,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh | |||
1639 | else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD; | 1593 | else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD; |
1640 | 1594 | ||
1641 | /* Dual link, Pass 1:1 BIOS default, etc. */ | 1595 | /* Dual link, Pass 1:1 BIOS default, etc. */ |
1642 | #ifdef SIS315H | 1596 | #ifdef CONFIG_FB_SIS_315 |
1643 | if(SiS_Pr->ChipType >= SIS_661) { | 1597 | if(SiS_Pr->ChipType >= SIS_661) { |
1644 | if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { | 1598 | if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { |
1645 | if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11; | 1599 | if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11; |
@@ -2076,7 +2030,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh | |||
2076 | } | 2030 | } |
2077 | } | 2031 | } |
2078 | 2032 | ||
2079 | #ifdef SIS300 | 2033 | #ifdef CONFIG_FB_SIS_300 |
2080 | if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { | 2034 | if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { |
2081 | if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) { | 2035 | if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) { |
2082 | SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */ | 2036 | SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */ |
@@ -2186,17 +2140,10 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh | |||
2186 | SiS_Pr->SiS_SetFlag |= LCDVESATiming; | 2140 | SiS_Pr->SiS_SetFlag |= LCDVESATiming; |
2187 | } | 2141 | } |
2188 | 2142 | ||
2189 | #ifdef SIS_LINUX_KERNEL | ||
2190 | #if 0 | 2143 | #if 0 |
2191 | printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n", | 2144 | printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n", |
2192 | SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo); | 2145 | SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo); |
2193 | #endif | 2146 | #endif |
2194 | #endif | ||
2195 | #ifdef SIS_XORG_XF86 | ||
2196 | xf86DrvMsgVerb(0, X_PROBED, 4, | ||
2197 | "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n", | ||
2198 | SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag); | ||
2199 | #endif | ||
2200 | } | 2147 | } |
2201 | 2148 | ||
2202 | /*********************************************/ | 2149 | /*********************************************/ |
@@ -2359,7 +2306,7 @@ SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor | |||
2359 | VCLKIndex = SiS_Pr->PanelVCLKIdx315; | 2306 | VCLKIndex = SiS_Pr->PanelVCLKIdx315; |
2360 | } | 2307 | } |
2361 | 2308 | ||
2362 | #ifdef SIS300 | 2309 | #ifdef CONFIG_FB_SIS_300 |
2363 | /* Special Timing: Barco iQ Pro R series */ | 2310 | /* Special Timing: Barco iQ Pro R series */ |
2364 | if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44; | 2311 | if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44; |
2365 | 2312 | ||
@@ -2410,12 +2357,6 @@ SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor | |||
2410 | 2357 | ||
2411 | } | 2358 | } |
2412 | 2359 | ||
2413 | #ifdef SIS_XORG_XF86 | ||
2414 | #ifdef TWDEBUG | ||
2415 | xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex); | ||
2416 | #endif | ||
2417 | #endif | ||
2418 | |||
2419 | return VCLKIndex; | 2360 | return VCLKIndex; |
2420 | } | 2361 | } |
2421 | 2362 | ||
@@ -2428,10 +2369,10 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned | |||
2428 | { | 2369 | { |
2429 | unsigned short i, j, modeflag, tempah=0; | 2370 | unsigned short i, j, modeflag, tempah=0; |
2430 | short tempcl; | 2371 | short tempcl; |
2431 | #if defined(SIS300) || defined(SIS315H) | 2372 | #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) |
2432 | unsigned short tempbl; | 2373 | unsigned short tempbl; |
2433 | #endif | 2374 | #endif |
2434 | #ifdef SIS315H | 2375 | #ifdef CONFIG_FB_SIS_315 |
2435 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; | 2376 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; |
2436 | unsigned short tempah2, tempbl2; | 2377 | unsigned short tempah2, tempbl2; |
2437 | #endif | 2378 | #endif |
@@ -2454,7 +2395,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned | |||
2454 | 2395 | ||
2455 | if(SiS_Pr->ChipType < SIS_315H) { | 2396 | if(SiS_Pr->ChipType < SIS_315H) { |
2456 | 2397 | ||
2457 | #ifdef SIS300 /* ---- 300 series ---- */ | 2398 | #ifdef CONFIG_FB_SIS_300 /* ---- 300 series ---- */ |
2458 | 2399 | ||
2459 | /* For 301BDH: (with LCD via LVDS) */ | 2400 | /* For 301BDH: (with LCD via LVDS) */ |
2460 | if(SiS_Pr->SiS_VBType & VB_NoLCD) { | 2401 | if(SiS_Pr->SiS_VBType & VB_NoLCD) { |
@@ -2477,11 +2418,11 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned | |||
2477 | 2418 | ||
2478 | if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0; | 2419 | if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0; |
2479 | 2420 | ||
2480 | #endif /* SIS300 */ | 2421 | #endif /* CONFIG_FB_SIS_300 */ |
2481 | 2422 | ||
2482 | } else { | 2423 | } else { |
2483 | 2424 | ||
2484 | #ifdef SIS315H /* ------- 315/330 series ------ */ | 2425 | #ifdef CONFIG_FB_SIS_315 /* ------- 315/330 series ------ */ |
2485 | 2426 | ||
2486 | if(ModeNo > 0x13) { | 2427 | if(ModeNo > 0x13) { |
2487 | tempcl -= ModeVGA; | 2428 | tempcl -= ModeVGA; |
@@ -2494,7 +2435,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned | |||
2494 | 2435 | ||
2495 | if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50; | 2436 | if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50; |
2496 | 2437 | ||
2497 | #endif /* SIS315H */ | 2438 | #endif /* CONFIG_FB_SIS_315 */ |
2498 | 2439 | ||
2499 | } | 2440 | } |
2500 | 2441 | ||
@@ -2503,7 +2444,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned | |||
2503 | if(SiS_Pr->ChipType < SIS_315H) { | 2444 | if(SiS_Pr->ChipType < SIS_315H) { |
2504 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah); | 2445 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah); |
2505 | } else { | 2446 | } else { |
2506 | #ifdef SIS315H | 2447 | #ifdef CONFIG_FB_SIS_315 |
2507 | if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { | 2448 | if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { |
2508 | SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah); | 2449 | SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah); |
2509 | } else if(SiS_Pr->SiS_VBType & VB_SISVB) { | 2450 | } else if(SiS_Pr->SiS_VBType & VB_SISVB) { |
@@ -2584,7 +2525,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned | |||
2584 | 2525 | ||
2585 | if(SiS_Pr->ChipType >= SIS_315H) { | 2526 | if(SiS_Pr->ChipType >= SIS_315H) { |
2586 | 2527 | ||
2587 | #ifdef SIS315H | 2528 | #ifdef CONFIG_FB_SIS_315 |
2588 | /* LVDS can only be slave in 8bpp modes */ | 2529 | /* LVDS can only be slave in 8bpp modes */ |
2589 | tempah = 0x80; | 2530 | tempah = 0x80; |
2590 | if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) { | 2531 | if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) { |
@@ -2604,7 +2545,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned | |||
2604 | 2545 | ||
2605 | } else { | 2546 | } else { |
2606 | 2547 | ||
2607 | #ifdef SIS300 | 2548 | #ifdef CONFIG_FB_SIS_300 |
2608 | tempah = 0; | 2549 | tempah = 0; |
2609 | if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) { | 2550 | if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) { |
2610 | tempah |= 0x02; | 2551 | tempah |= 0x02; |
@@ -2626,7 +2567,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned | |||
2626 | 2567 | ||
2627 | if(SiS_Pr->ChipType >= SIS_315H) { | 2568 | if(SiS_Pr->ChipType >= SIS_315H) { |
2628 | 2569 | ||
2629 | #ifdef SIS315H | 2570 | #ifdef CONFIG_FB_SIS_315 |
2630 | /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */ | 2571 | /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */ |
2631 | 2572 | ||
2632 | /* The following is nearly unpreditable and varies from machine | 2573 | /* The following is nearly unpreditable and varies from machine |
@@ -2718,11 +2659,11 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned | |||
2718 | SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah); | 2659 | SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah); |
2719 | } | 2660 | } |
2720 | 2661 | ||
2721 | #endif /* SIS315H */ | 2662 | #endif /* CONFIG_FB_SIS_315 */ |
2722 | 2663 | ||
2723 | } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { | 2664 | } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { |
2724 | 2665 | ||
2725 | #ifdef SIS300 | 2666 | #ifdef CONFIG_FB_SIS_300 |
2726 | SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f); | 2667 | SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f); |
2727 | 2668 | ||
2728 | if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) || | 2669 | if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) || |
@@ -2745,7 +2686,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned | |||
2745 | 2686 | ||
2746 | } else { /* LVDS */ | 2687 | } else { /* LVDS */ |
2747 | 2688 | ||
2748 | #ifdef SIS315H | 2689 | #ifdef CONFIG_FB_SIS_315 |
2749 | if(SiS_Pr->ChipType >= SIS_315H) { | 2690 | if(SiS_Pr->ChipType >= SIS_315H) { |
2750 | 2691 | ||
2751 | if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { | 2692 | if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { |
@@ -2931,7 +2872,7 @@ SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
2931 | } | 2872 | } |
2932 | } | 2873 | } |
2933 | 2874 | ||
2934 | #ifdef SIS315H | 2875 | #ifdef CONFIG_FB_SIS_315 |
2935 | if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { | 2876 | if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { |
2936 | if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { | 2877 | if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { |
2937 | if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { | 2878 | if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { |
@@ -3036,7 +2977,7 @@ SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
3036 | case Panel_1280x1024: tempbx = 24; break; | 2977 | case Panel_1280x1024: tempbx = 24; break; |
3037 | case Panel_1400x1050: tempbx = 26; break; | 2978 | case Panel_1400x1050: tempbx = 26; break; |
3038 | case Panel_1600x1200: tempbx = 28; break; | 2979 | case Panel_1600x1200: tempbx = 28; break; |
3039 | #ifdef SIS300 | 2980 | #ifdef CONFIG_FB_SIS_300 |
3040 | case Panel_Barco1366: tempbx = 80; break; | 2981 | case Panel_Barco1366: tempbx = 80; break; |
3041 | #endif | 2982 | #endif |
3042 | } | 2983 | } |
@@ -3053,7 +2994,7 @@ SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
3053 | 2994 | ||
3054 | if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30; | 2995 | if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30; |
3055 | 2996 | ||
3056 | #ifdef SIS300 | 2997 | #ifdef CONFIG_FB_SIS_300 |
3057 | if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { | 2998 | if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { |
3058 | tempbx = 82; | 2999 | tempbx = 82; |
3059 | if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; | 3000 | if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; |
@@ -3189,7 +3130,7 @@ SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned | |||
3189 | 3130 | ||
3190 | if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { | 3131 | if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { |
3191 | 3132 | ||
3192 | #ifdef SIS315H | 3133 | #ifdef CONFIG_FB_SIS_315 |
3193 | SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); | 3134 | SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); |
3194 | SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex); | 3135 | SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex); |
3195 | #endif | 3136 | #endif |
@@ -3214,7 +3155,7 @@ SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned | |||
3214 | case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break; | 3155 | case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break; |
3215 | case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break; | 3156 | case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break; |
3216 | case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break; | 3157 | case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break; |
3217 | #ifdef SIS300 | 3158 | #ifdef CONFIG_FB_SIS_300 |
3218 | case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break; | 3159 | case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break; |
3219 | case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break; | 3160 | case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break; |
3220 | case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break; | 3161 | case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break; |
@@ -3248,7 +3189,7 @@ SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned | |||
3248 | (SiS_Pr->SiS_SetFlag & SetDOSMode) ) { | 3189 | (SiS_Pr->SiS_SetFlag & SetDOSMode) ) { |
3249 | SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes; | 3190 | SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes; |
3250 | SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes; | 3191 | SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes; |
3251 | #ifdef SIS300 | 3192 | #ifdef CONFIG_FB_SIS_300 |
3252 | if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { | 3193 | if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { |
3253 | if(ResIndex < 0x08) { | 3194 | if(ResIndex < 0x08) { |
3254 | SiS_Pr->SiS_HDE = 1280; | 3195 | SiS_Pr->SiS_HDE = 1280; |
@@ -3270,7 +3211,7 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
3270 | unsigned short resinfo, CRT2Index, ResIndex; | 3211 | unsigned short resinfo, CRT2Index, ResIndex; |
3271 | const struct SiS_LCDData *LCDPtr = NULL; | 3212 | const struct SiS_LCDData *LCDPtr = NULL; |
3272 | const struct SiS_TVData *TVPtr = NULL; | 3213 | const struct SiS_TVData *TVPtr = NULL; |
3273 | #ifdef SIS315H | 3214 | #ifdef CONFIG_FB_SIS_315 |
3274 | short resinfo661; | 3215 | short resinfo661; |
3275 | #endif | 3216 | #endif |
3276 | 3217 | ||
@@ -3283,7 +3224,7 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
3283 | } else { | 3224 | } else { |
3284 | modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; | 3225 | modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; |
3285 | resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; | 3226 | resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; |
3286 | #ifdef SIS315H | 3227 | #ifdef CONFIG_FB_SIS_315 |
3287 | resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661; | 3228 | resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661; |
3288 | if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && | 3229 | if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && |
3289 | (SiS_Pr->SiS_SetFlag & LCDVESATiming) && | 3230 | (SiS_Pr->SiS_SetFlag & LCDVESATiming) && |
@@ -3460,7 +3401,7 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
3460 | 3401 | ||
3461 | } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) { | 3402 | } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) { |
3462 | 3403 | ||
3463 | #ifdef SIS315H | 3404 | #ifdef CONFIG_FB_SIS_315 |
3464 | SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr]; | 3405 | SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr]; |
3465 | SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1]; | 3406 | SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1]; |
3466 | SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8); | 3407 | SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8); |
@@ -3520,19 +3461,13 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
3520 | case Panel_1680x1050 : | 3461 | case Panel_1680x1050 : |
3521 | case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break; | 3462 | case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break; |
3522 | case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break; | 3463 | case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break; |
3523 | #ifdef SIS315H | 3464 | #ifdef CONFIG_FB_SIS_315 |
3524 | case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break; | 3465 | case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break; |
3525 | case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; | 3466 | case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; |
3526 | #endif | 3467 | #endif |
3527 | default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; | 3468 | default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; |
3528 | } | 3469 | } |
3529 | 3470 | ||
3530 | #ifdef SIS_XORG_XF86 | ||
3531 | #ifdef TWDEBUG | ||
3532 | xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex); | ||
3533 | #endif | ||
3534 | #endif | ||
3535 | |||
3536 | SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX; | 3471 | SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX; |
3537 | SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT; | 3472 | SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT; |
3538 | SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT; | 3473 | SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT; |
@@ -3624,7 +3559,7 @@ SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr) | |||
3624 | { | 3559 | { |
3625 | const struct SiS_LVDSDes *PanelDesPtr = NULL; | 3560 | const struct SiS_LVDSDes *PanelDesPtr = NULL; |
3626 | 3561 | ||
3627 | #ifdef SIS300 | 3562 | #ifdef CONFIG_FB_SIS_300 |
3628 | if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { | 3563 | if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { |
3629 | 3564 | ||
3630 | if(SiS_Pr->ChipType < SIS_315H) { | 3565 | if(SiS_Pr->ChipType < SIS_315H) { |
@@ -3696,7 +3631,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
3696 | 3631 | ||
3697 | if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { | 3632 | if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { |
3698 | 3633 | ||
3699 | #ifdef SIS315H | 3634 | #ifdef CONFIG_FB_SIS_315 |
3700 | if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { | 3635 | if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { |
3701 | /* non-pass 1:1 only, see above */ | 3636 | /* non-pass 1:1 only, see above */ |
3702 | if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) { | 3637 | if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) { |
@@ -3771,7 +3706,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
3771 | } else { | 3706 | } else { |
3772 | 3707 | ||
3773 | if(SiS_Pr->ChipType < SIS_315H) { | 3708 | if(SiS_Pr->ChipType < SIS_315H) { |
3774 | #ifdef SIS300 | 3709 | #ifdef CONFIG_FB_SIS_300 |
3775 | switch(SiS_Pr->SiS_LCDResInfo) { | 3710 | switch(SiS_Pr->SiS_LCDResInfo) { |
3776 | case Panel_800x600: | 3711 | case Panel_800x600: |
3777 | if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { | 3712 | if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { |
@@ -3816,7 +3751,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
3816 | } | 3751 | } |
3817 | #endif | 3752 | #endif |
3818 | } else { | 3753 | } else { |
3819 | #ifdef SIS315H | 3754 | #ifdef CONFIG_FB_SIS_315 |
3820 | switch(SiS_Pr->SiS_LCDResInfo) { | 3755 | switch(SiS_Pr->SiS_LCDResInfo) { |
3821 | case Panel_1024x768: | 3756 | case Panel_1024x768: |
3822 | case Panel_1280x1024: | 3757 | case Panel_1280x1024: |
@@ -3844,7 +3779,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
3844 | if(SiS_Pr->ChipType < SIS_315H) { | 3779 | if(SiS_Pr->ChipType < SIS_315H) { |
3845 | if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320; | 3780 | if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320; |
3846 | } else { | 3781 | } else { |
3847 | #ifdef SIS315H | 3782 | #ifdef CONFIG_FB_SIS_315 |
3848 | if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480; | 3783 | if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480; |
3849 | if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804; | 3784 | if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804; |
3850 | if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704; | 3785 | if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704; |
@@ -3866,7 +3801,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
3866 | /* DISABLE VIDEO BRIDGE */ | 3801 | /* DISABLE VIDEO BRIDGE */ |
3867 | /*********************************************/ | 3802 | /*********************************************/ |
3868 | 3803 | ||
3869 | #ifdef SIS315H | 3804 | #ifdef CONFIG_FB_SIS_315 |
3870 | static int | 3805 | static int |
3871 | SiS_HandlePWD(struct SiS_Private *SiS_Pr) | 3806 | SiS_HandlePWD(struct SiS_Private *SiS_Pr) |
3872 | { | 3807 | { |
@@ -3891,11 +3826,6 @@ SiS_HandlePWD(struct SiS_Private *SiS_Pr) | |||
3891 | ret = 1; | 3826 | ret = 1; |
3892 | } | 3827 | } |
3893 | SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp); | 3828 | SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp); |
3894 | #ifdef SIS_XORG_XF86 | ||
3895 | #ifdef TWDEBUG | ||
3896 | xf86DrvMsg(0, 0, "Setting PWD %x\n", temp); | ||
3897 | #endif | ||
3898 | #endif | ||
3899 | } | 3829 | } |
3900 | #endif | 3830 | #endif |
3901 | return ret; | 3831 | return ret; |
@@ -3909,7 +3839,7 @@ SiS_HandlePWD(struct SiS_Private *SiS_Pr) | |||
3909 | void | 3839 | void |
3910 | SiS_DisableBridge(struct SiS_Private *SiS_Pr) | 3840 | SiS_DisableBridge(struct SiS_Private *SiS_Pr) |
3911 | { | 3841 | { |
3912 | #ifdef SIS315H | 3842 | #ifdef CONFIG_FB_SIS_315 |
3913 | unsigned short tempah, pushax=0, modenum; | 3843 | unsigned short tempah, pushax=0, modenum; |
3914 | #endif | 3844 | #endif |
3915 | unsigned short temp=0; | 3845 | unsigned short temp=0; |
@@ -3920,7 +3850,7 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr) | |||
3920 | 3850 | ||
3921 | if(SiS_Pr->ChipType < SIS_315H) { | 3851 | if(SiS_Pr->ChipType < SIS_315H) { |
3922 | 3852 | ||
3923 | #ifdef SIS300 /* 300 series */ | 3853 | #ifdef CONFIG_FB_SIS_300 /* 300 series */ |
3924 | 3854 | ||
3925 | if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { | 3855 | if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { |
3926 | if(SiS_Pr->SiS_VBType & VB_SISLVDS) { | 3856 | if(SiS_Pr->SiS_VBType & VB_SISLVDS) { |
@@ -3953,11 +3883,11 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr) | |||
3953 | } | 3883 | } |
3954 | } | 3884 | } |
3955 | 3885 | ||
3956 | #endif /* SIS300 */ | 3886 | #endif /* CONFIG_FB_SIS_300 */ |
3957 | 3887 | ||
3958 | } else { | 3888 | } else { |
3959 | 3889 | ||
3960 | #ifdef SIS315H /* 315 series */ | 3890 | #ifdef CONFIG_FB_SIS_315 /* 315 series */ |
3961 | 3891 | ||
3962 | int didpwd = 0; | 3892 | int didpwd = 0; |
3963 | bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) || | 3893 | bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) || |
@@ -4081,14 +4011,14 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr) | |||
4081 | 4011 | ||
4082 | } | 4012 | } |
4083 | 4013 | ||
4084 | #endif /* SIS315H */ | 4014 | #endif /* CONFIG_FB_SIS_315 */ |
4085 | 4015 | ||
4086 | } | 4016 | } |
4087 | 4017 | ||
4088 | } else { /* ============ For 301 ================ */ | 4018 | } else { /* ============ For 301 ================ */ |
4089 | 4019 | ||
4090 | if(SiS_Pr->ChipType < SIS_315H) { | 4020 | if(SiS_Pr->ChipType < SIS_315H) { |
4091 | #ifdef SIS300 | 4021 | #ifdef CONFIG_FB_SIS_300 |
4092 | if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { | 4022 | if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { |
4093 | SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); | 4023 | SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); |
4094 | SiS_PanelDelay(SiS_Pr, 3); | 4024 | SiS_PanelDelay(SiS_Pr, 3); |
@@ -4111,7 +4041,7 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr) | |||
4111 | SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); | 4041 | SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); |
4112 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp); | 4042 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp); |
4113 | } else { | 4043 | } else { |
4114 | #ifdef SIS300 | 4044 | #ifdef CONFIG_FB_SIS_300 |
4115 | SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */ | 4045 | SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */ |
4116 | if( (!(SiS_CRT2IsLCD(SiS_Pr))) || | 4046 | if( (!(SiS_CRT2IsLCD(SiS_Pr))) || |
4117 | (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) { | 4047 | (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) { |
@@ -4127,7 +4057,7 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr) | |||
4127 | 4057 | ||
4128 | if(SiS_Pr->ChipType < SIS_315H) { | 4058 | if(SiS_Pr->ChipType < SIS_315H) { |
4129 | 4059 | ||
4130 | #ifdef SIS300 /* 300 series */ | 4060 | #ifdef CONFIG_FB_SIS_300 /* 300 series */ |
4131 | 4061 | ||
4132 | if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { | 4062 | if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { |
4133 | SiS_SetCH700x(SiS_Pr,0x0E,0x09); | 4063 | SiS_SetCH700x(SiS_Pr,0x0E,0x09); |
@@ -4171,11 +4101,11 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr) | |||
4171 | SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04); | 4101 | SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04); |
4172 | } | 4102 | } |
4173 | 4103 | ||
4174 | #endif /* SIS300 */ | 4104 | #endif /* CONFIG_FB_SIS_300 */ |
4175 | 4105 | ||
4176 | } else { | 4106 | } else { |
4177 | 4107 | ||
4178 | #ifdef SIS315H /* 315 series */ | 4108 | #ifdef CONFIG_FB_SIS_315 /* 315 series */ |
4179 | 4109 | ||
4180 | if(!(SiS_IsNotM650orLater(SiS_Pr))) { | 4110 | if(!(SiS_IsNotM650orLater(SiS_Pr))) { |
4181 | /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */ | 4111 | /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */ |
@@ -4288,7 +4218,7 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr) | |||
4288 | } | 4218 | } |
4289 | } | 4219 | } |
4290 | 4220 | ||
4291 | #endif /* SIS315H */ | 4221 | #endif /* CONFIG_FB_SIS_315 */ |
4292 | 4222 | ||
4293 | } /* 315 series */ | 4223 | } /* 315 series */ |
4294 | 4224 | ||
@@ -4304,14 +4234,12 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr) | |||
4304 | * from outside the context of a mode switch! | 4234 | * from outside the context of a mode switch! |
4305 | * MUST call getVBType before calling this | 4235 | * MUST call getVBType before calling this |
4306 | */ | 4236 | */ |
4307 | #ifdef SIS_LINUX_KERNEL | ||
4308 | static | 4237 | static |
4309 | #endif | ||
4310 | void | 4238 | void |
4311 | SiS_EnableBridge(struct SiS_Private *SiS_Pr) | 4239 | SiS_EnableBridge(struct SiS_Private *SiS_Pr) |
4312 | { | 4240 | { |
4313 | unsigned short temp=0, tempah; | 4241 | unsigned short temp=0, tempah; |
4314 | #ifdef SIS315H | 4242 | #ifdef CONFIG_FB_SIS_315 |
4315 | unsigned short temp1, pushax=0; | 4243 | unsigned short temp1, pushax=0; |
4316 | bool delaylong = false; | 4244 | bool delaylong = false; |
4317 | #endif | 4245 | #endif |
@@ -4322,7 +4250,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr) | |||
4322 | 4250 | ||
4323 | if(SiS_Pr->ChipType < SIS_315H) { | 4251 | if(SiS_Pr->ChipType < SIS_315H) { |
4324 | 4252 | ||
4325 | #ifdef SIS300 /* 300 series */ | 4253 | #ifdef CONFIG_FB_SIS_300 /* 300 series */ |
4326 | 4254 | ||
4327 | if(SiS_CRT2IsLCD(SiS_Pr)) { | 4255 | if(SiS_CRT2IsLCD(SiS_Pr)) { |
4328 | if(SiS_Pr->SiS_VBType & VB_SISLVDS) { | 4256 | if(SiS_Pr->SiS_VBType & VB_SISLVDS) { |
@@ -4385,11 +4313,11 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr) | |||
4385 | } | 4313 | } |
4386 | 4314 | ||
4387 | 4315 | ||
4388 | #endif /* SIS300 */ | 4316 | #endif /* CONFIG_FB_SIS_300 */ |
4389 | 4317 | ||
4390 | } else { | 4318 | } else { |
4391 | 4319 | ||
4392 | #ifdef SIS315H /* 315 series */ | 4320 | #ifdef CONFIG_FB_SIS_315 /* 315 series */ |
4393 | 4321 | ||
4394 | #ifdef SET_EMI | 4322 | #ifdef SET_EMI |
4395 | unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0; | 4323 | unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0; |
@@ -4688,7 +4616,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr) | |||
4688 | SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); | 4616 | SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); |
4689 | } | 4617 | } |
4690 | 4618 | ||
4691 | #endif /* SIS315H */ | 4619 | #endif /* CONFIG_FB_SIS_315 */ |
4692 | 4620 | ||
4693 | } | 4621 | } |
4694 | 4622 | ||
@@ -4739,7 +4667,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr) | |||
4739 | 4667 | ||
4740 | if(SiS_Pr->ChipType < SIS_315H) { | 4668 | if(SiS_Pr->ChipType < SIS_315H) { |
4741 | 4669 | ||
4742 | #ifdef SIS300 /* 300 series */ | 4670 | #ifdef CONFIG_FB_SIS_300 /* 300 series */ |
4743 | 4671 | ||
4744 | if(SiS_CRT2IsLCD(SiS_Pr)) { | 4672 | if(SiS_CRT2IsLCD(SiS_Pr)) { |
4745 | if(SiS_Pr->ChipType == SIS_730) { | 4673 | if(SiS_Pr->ChipType == SIS_730) { |
@@ -4783,11 +4711,11 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr) | |||
4783 | } | 4711 | } |
4784 | } | 4712 | } |
4785 | 4713 | ||
4786 | #endif /* SIS300 */ | 4714 | #endif /* CONFIG_FB_SIS_300 */ |
4787 | 4715 | ||
4788 | } else { | 4716 | } else { |
4789 | 4717 | ||
4790 | #ifdef SIS315H /* 315 series */ | 4718 | #ifdef CONFIG_FB_SIS_315 /* 315 series */ |
4791 | 4719 | ||
4792 | if(!(SiS_IsNotM650orLater(SiS_Pr))) { | 4720 | if(!(SiS_IsNotM650orLater(SiS_Pr))) { |
4793 | /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */ | 4721 | /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */ |
@@ -4881,7 +4809,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr) | |||
4881 | } | 4809 | } |
4882 | } | 4810 | } |
4883 | 4811 | ||
4884 | #endif /* SIS315H */ | 4812 | #endif /* CONFIG_FB_SIS_315 */ |
4885 | 4813 | ||
4886 | } /* 310 series */ | 4814 | } /* 310 series */ |
4887 | 4815 | ||
@@ -4971,7 +4899,7 @@ SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor | |||
4971 | 4899 | ||
4972 | if(SiS_Pr->ChipType < SIS_315H) { | 4900 | if(SiS_Pr->ChipType < SIS_315H) { |
4973 | 4901 | ||
4974 | #ifdef SIS300 /* ---- 300 series --- */ | 4902 | #ifdef CONFIG_FB_SIS_300 /* ---- 300 series --- */ |
4975 | 4903 | ||
4976 | if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */ | 4904 | if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */ |
4977 | 4905 | ||
@@ -5000,11 +4928,11 @@ SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor | |||
5000 | 4928 | ||
5001 | } | 4929 | } |
5002 | 4930 | ||
5003 | #endif /* SIS300 */ | 4931 | #endif /* CONFIG_FB_SIS_300 */ |
5004 | 4932 | ||
5005 | } else { | 4933 | } else { |
5006 | 4934 | ||
5007 | #ifdef SIS315H /* ------- 315 series ------ */ | 4935 | #ifdef CONFIG_FB_SIS_315 /* ------- 315 series ------ */ |
5008 | 4936 | ||
5009 | if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */ | 4937 | if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */ |
5010 | 4938 | ||
@@ -5076,13 +5004,13 @@ SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor | |||
5076 | } | 5004 | } |
5077 | 5005 | ||
5078 | } | 5006 | } |
5079 | #endif /* SIS315H */ | 5007 | #endif /* CONFIG_FB_SIS_315 */ |
5080 | } | 5008 | } |
5081 | } | 5009 | } |
5082 | } | 5010 | } |
5083 | 5011 | ||
5084 | /* Set CRT2 FIFO on 300/540/630/730 */ | 5012 | /* Set CRT2 FIFO on 300/540/630/730 */ |
5085 | #ifdef SIS300 | 5013 | #ifdef CONFIG_FB_SIS_300 |
5086 | static void | 5014 | static void |
5087 | SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo) | 5015 | SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo) |
5088 | { | 5016 | { |
@@ -5154,13 +5082,8 @@ SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo) | |||
5154 | 5082 | ||
5155 | } else { | 5083 | } else { |
5156 | 5084 | ||
5157 | #ifdef SIS_LINUX_KERNEL | ||
5158 | pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50); | 5085 | pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50); |
5159 | pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0); | 5086 | pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0); |
5160 | #else | ||
5161 | pci50 = pciReadLong(0x00000000, 0x50); | ||
5162 | pciA0 = pciReadLong(0x00000000, 0xA0); | ||
5163 | #endif | ||
5164 | 5087 | ||
5165 | if(SiS_Pr->ChipType == SIS_730) { | 5088 | if(SiS_Pr->ChipType == SIS_730) { |
5166 | 5089 | ||
@@ -5262,7 +5185,7 @@ SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo) | |||
5262 | #endif | 5185 | #endif |
5263 | 5186 | ||
5264 | /* Set CRT2 FIFO on 315/330 series */ | 5187 | /* Set CRT2 FIFO on 315/330 series */ |
5265 | #ifdef SIS315H | 5188 | #ifdef CONFIG_FB_SIS_315 |
5266 | static void | 5189 | static void |
5267 | SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr) | 5190 | SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr) |
5268 | { | 5191 | { |
@@ -5420,27 +5343,6 @@ SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned sho | |||
5420 | 5343 | ||
5421 | temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)); | 5344 | temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)); |
5422 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */ | 5345 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */ |
5423 | |||
5424 | #ifdef SIS_XORG_XF86 | ||
5425 | #ifdef TWDEBUG | ||
5426 | xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n", | ||
5427 | SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal, | ||
5428 | SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal, | ||
5429 | SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd); | ||
5430 | |||
5431 | xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", | ||
5432 | SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1], | ||
5433 | SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3], | ||
5434 | SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5], | ||
5435 | SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]); | ||
5436 | xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", | ||
5437 | SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9], | ||
5438 | SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11], | ||
5439 | SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13], | ||
5440 | SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]); | ||
5441 | xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]); | ||
5442 | #endif | ||
5443 | #endif | ||
5444 | } | 5346 | } |
5445 | 5347 | ||
5446 | /* Setup panel link | 5348 | /* Setup panel link |
@@ -5455,17 +5357,17 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
5455 | unsigned short push2, tempax, tempbx, tempcx, temp; | 5357 | unsigned short push2, tempax, tempbx, tempcx, temp; |
5456 | unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0; | 5358 | unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0; |
5457 | bool islvds = false, issis = false, chkdclkfirst = false; | 5359 | bool islvds = false, issis = false, chkdclkfirst = false; |
5458 | #ifdef SIS300 | 5360 | #ifdef CONFIG_FB_SIS_300 |
5459 | unsigned short crt2crtc = 0; | 5361 | unsigned short crt2crtc = 0; |
5460 | #endif | 5362 | #endif |
5461 | #ifdef SIS315H | 5363 | #ifdef CONFIG_FB_SIS_315 |
5462 | unsigned short pushcx; | 5364 | unsigned short pushcx; |
5463 | #endif | 5365 | #endif |
5464 | 5366 | ||
5465 | if(ModeNo <= 0x13) { | 5367 | if(ModeNo <= 0x13) { |
5466 | modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; | 5368 | modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; |
5467 | resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; | 5369 | resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; |
5468 | #ifdef SIS300 | 5370 | #ifdef CONFIG_FB_SIS_300 |
5469 | crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; | 5371 | crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; |
5470 | #endif | 5372 | #endif |
5471 | } else if(SiS_Pr->UseCustomMode) { | 5373 | } else if(SiS_Pr->UseCustomMode) { |
@@ -5473,7 +5375,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
5473 | } else { | 5375 | } else { |
5474 | modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; | 5376 | modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; |
5475 | resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; | 5377 | resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; |
5476 | #ifdef SIS300 | 5378 | #ifdef CONFIG_FB_SIS_300 |
5477 | crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; | 5379 | crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; |
5478 | #endif | 5380 | #endif |
5479 | } | 5381 | } |
@@ -5494,7 +5396,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
5494 | } | 5396 | } |
5495 | } | 5397 | } |
5496 | 5398 | ||
5497 | #ifdef SIS315H | 5399 | #ifdef CONFIG_FB_SIS_315 |
5498 | if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { | 5400 | if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { |
5499 | if(IS_SIS330) { | 5401 | if(IS_SIS330) { |
5500 | SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); | 5402 | SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); |
@@ -5744,7 +5646,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
5744 | 5646 | ||
5745 | if(SiS_Pr->ChipType < SIS_315H) { | 5647 | if(SiS_Pr->ChipType < SIS_315H) { |
5746 | 5648 | ||
5747 | #ifdef SIS300 /* 300 series */ | 5649 | #ifdef CONFIG_FB_SIS_300 /* 300 series */ |
5748 | tempeax = SiS_Pr->SiS_VGAVDE << 6; | 5650 | tempeax = SiS_Pr->SiS_VGAVDE << 6; |
5749 | temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE); | 5651 | temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE); |
5750 | tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE; | 5652 | tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE; |
@@ -5755,11 +5657,11 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
5755 | temp = (unsigned short)(tempeax & 0x00FF); | 5657 | temp = (unsigned short)(tempeax & 0x00FF); |
5756 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */ | 5658 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */ |
5757 | tempvcfact = temp; | 5659 | tempvcfact = temp; |
5758 | #endif /* SIS300 */ | 5660 | #endif /* CONFIG_FB_SIS_300 */ |
5759 | 5661 | ||
5760 | } else { | 5662 | } else { |
5761 | 5663 | ||
5762 | #ifdef SIS315H /* 315 series */ | 5664 | #ifdef CONFIG_FB_SIS_315 /* 315 series */ |
5763 | tempeax = SiS_Pr->SiS_VGAVDE << 18; | 5665 | tempeax = SiS_Pr->SiS_VGAVDE << 18; |
5764 | tempebx = SiS_Pr->SiS_VDE; | 5666 | tempebx = SiS_Pr->SiS_VDE; |
5765 | temp = (tempeax % tempebx); | 5667 | temp = (tempeax % tempebx); |
@@ -5845,7 +5747,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
5845 | temp = (unsigned short)(tempecx & 0x00FF); | 5747 | temp = (unsigned short)(tempecx & 0x00FF); |
5846 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp); | 5748 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp); |
5847 | 5749 | ||
5848 | #ifdef SIS315H | 5750 | #ifdef CONFIG_FB_SIS_315 |
5849 | if(SiS_Pr->ChipType >= SIS_315H) { | 5751 | if(SiS_Pr->ChipType >= SIS_315H) { |
5850 | if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { | 5752 | if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { |
5851 | if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) { | 5753 | if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) { |
@@ -5863,7 +5765,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
5863 | } | 5765 | } |
5864 | #endif | 5766 | #endif |
5865 | 5767 | ||
5866 | #ifdef SIS300 | 5768 | #ifdef CONFIG_FB_SIS_300 |
5867 | if(SiS_Pr->SiS_IF_DEF_TRUMPION) { | 5769 | if(SiS_Pr->SiS_IF_DEF_TRUMPION) { |
5868 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; | 5770 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; |
5869 | unsigned char *trumpdata; | 5771 | unsigned char *trumpdata; |
@@ -5899,7 +5801,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
5899 | } | 5801 | } |
5900 | #endif | 5802 | #endif |
5901 | 5803 | ||
5902 | #ifdef SIS315H | 5804 | #ifdef CONFIG_FB_SIS_315 |
5903 | if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) { | 5805 | if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) { |
5904 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00); | 5806 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00); |
5905 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00); | 5807 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00); |
@@ -5999,7 +5901,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s | |||
5999 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a); | 5901 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a); |
6000 | } | 5902 | } |
6001 | } | 5903 | } |
6002 | #endif /* SIS315H */ | 5904 | #endif /* CONFIG_FB_SIS_315 */ |
6003 | } | 5905 | } |
6004 | 5906 | ||
6005 | /* Set Part 1 */ | 5907 | /* Set Part 1 */ |
@@ -6007,12 +5909,12 @@ static void | |||
6007 | SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, | 5909 | SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, |
6008 | unsigned short RefreshRateTableIndex) | 5910 | unsigned short RefreshRateTableIndex) |
6009 | { | 5911 | { |
6010 | #if defined(SIS300) || defined(SIS315H) | 5912 | #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) |
6011 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; | 5913 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; |
6012 | #endif | 5914 | #endif |
6013 | unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0; | 5915 | unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0; |
6014 | unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0; | 5916 | unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0; |
6015 | #ifdef SIS315H | 5917 | #ifdef CONFIG_FB_SIS_315 |
6016 | unsigned short tempbl=0; | 5918 | unsigned short tempbl=0; |
6017 | #endif | 5919 | #endif |
6018 | 5920 | ||
@@ -6038,11 +5940,11 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
6038 | (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) { | 5940 | (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) { |
6039 | 5941 | ||
6040 | if(SiS_Pr->ChipType < SIS_315H ) { | 5942 | if(SiS_Pr->ChipType < SIS_315H ) { |
6041 | #ifdef SIS300 | 5943 | #ifdef CONFIG_FB_SIS_300 |
6042 | SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo); | 5944 | SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo); |
6043 | #endif | 5945 | #endif |
6044 | } else { | 5946 | } else { |
6045 | #ifdef SIS315H | 5947 | #ifdef CONFIG_FB_SIS_315 |
6046 | SiS_SetCRT2FIFO_310(SiS_Pr); | 5948 | SiS_SetCRT2FIFO_310(SiS_Pr); |
6047 | #endif | 5949 | #endif |
6048 | } | 5950 | } |
@@ -6051,7 +5953,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
6051 | 5953 | ||
6052 | if(SiS_Pr->ChipType < SIS_315H ) { | 5954 | if(SiS_Pr->ChipType < SIS_315H ) { |
6053 | 5955 | ||
6054 | #ifdef SIS300 /* ------------- 300 series --------------*/ | 5956 | #ifdef CONFIG_FB_SIS_300 /* ------------- 300 series --------------*/ |
6055 | 5957 | ||
6056 | temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ | 5958 | temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ |
6057 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */ | 5959 | SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */ |
@@ -6070,11 +5972,11 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
6070 | 5972 | ||
6071 | bridgeadd = 12; | 5973 | bridgeadd = 12; |
6072 | 5974 | ||
6073 | #endif /* SIS300 */ | 5975 | #endif /* CONFIG_FB_SIS_300 */ |
6074 | 5976 | ||
6075 | } else { | 5977 | } else { |
6076 | 5978 | ||
6077 | #ifdef SIS315H /* ------------------- 315/330 series --------------- */ | 5979 | #ifdef CONFIG_FB_SIS_315 /* ------------------- 315/330 series --------------- */ |
6078 | 5980 | ||
6079 | tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */ | 5981 | tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */ |
6080 | if(modeflag & HalfDCLK) { | 5982 | if(modeflag & HalfDCLK) { |
@@ -6125,7 +6027,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
6125 | } | 6027 | } |
6126 | } | 6028 | } |
6127 | 6029 | ||
6128 | #endif /* SIS315H */ | 6030 | #endif /* CONFIG_FB_SIS_315 */ |
6129 | 6031 | ||
6130 | } /* 315/330 series */ | 6032 | } /* 315/330 series */ |
6131 | 6033 | ||
@@ -6256,7 +6158,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
6256 | 6158 | ||
6257 | if(SiS_Pr->ChipType < SIS_315H) { | 6159 | if(SiS_Pr->ChipType < SIS_315H) { |
6258 | 6160 | ||
6259 | #ifdef SIS300 /* ---------- 300 series -------------- */ | 6161 | #ifdef CONFIG_FB_SIS_300 /* ---------- 300 series -------------- */ |
6260 | 6162 | ||
6261 | if(SiS_Pr->SiS_VBType & VB_SISVB) { | 6163 | if(SiS_Pr->SiS_VBType & VB_SISVB) { |
6262 | temp = 0x20; | 6164 | temp = 0x20; |
@@ -6310,11 +6212,11 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
6310 | 6212 | ||
6311 | SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */ | 6213 | SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */ |
6312 | 6214 | ||
6313 | #endif /* SIS300 */ | 6215 | #endif /* CONFIG_FB_SIS_300 */ |
6314 | 6216 | ||
6315 | } else { | 6217 | } else { |
6316 | 6218 | ||
6317 | #ifdef SIS315H /* --------------- 315/330 series ---------------*/ | 6219 | #ifdef CONFIG_FB_SIS_315 /* --------------- 315/330 series ---------------*/ |
6318 | 6220 | ||
6319 | if(SiS_Pr->ChipType < SIS_661) { | 6221 | if(SiS_Pr->ChipType < SIS_661) { |
6320 | 6222 | ||
@@ -6349,7 +6251,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
6349 | if(modeflag & HalfDCLK) tempax |= 0x40; | 6251 | if(modeflag & HalfDCLK) tempax |= 0x40; |
6350 | SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax); | 6252 | SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax); |
6351 | 6253 | ||
6352 | #endif /* SIS315H */ | 6254 | #endif /* CONFIG_FB_SIS_315 */ |
6353 | 6255 | ||
6354 | } | 6256 | } |
6355 | 6257 | ||
@@ -6381,7 +6283,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
6381 | /* SET PART 2 REGISTER GROUP */ | 6283 | /* SET PART 2 REGISTER GROUP */ |
6382 | /*********************************************/ | 6284 | /*********************************************/ |
6383 | 6285 | ||
6384 | #ifdef SIS315H | 6286 | #ifdef CONFIG_FB_SIS_315 |
6385 | static unsigned char * | 6287 | static unsigned char * |
6386 | SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype) | 6288 | SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype) |
6387 | { | 6289 | { |
@@ -6478,7 +6380,7 @@ SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned sh | |||
6478 | } | 6380 | } |
6479 | #endif | 6381 | #endif |
6480 | 6382 | ||
6481 | #ifdef SIS300 | 6383 | #ifdef CONFIG_FB_SIS_300 |
6482 | static void | 6384 | static void |
6483 | SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc) | 6385 | SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc) |
6484 | { | 6386 | { |
@@ -6690,7 +6592,7 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
6690 | unsigned int longtemp, PhaseIndex; | 6592 | unsigned int longtemp, PhaseIndex; |
6691 | bool newtvphase; | 6593 | bool newtvphase; |
6692 | const unsigned char *TimingPoint; | 6594 | const unsigned char *TimingPoint; |
6693 | #ifdef SIS315H | 6595 | #ifdef CONFIG_FB_SIS_315 |
6694 | unsigned short resindex, CRT2Index; | 6596 | unsigned short resindex, CRT2Index; |
6695 | const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL; | 6597 | const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL; |
6696 | 6598 | ||
@@ -7069,7 +6971,7 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
7069 | SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB); | 6971 | SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB); |
7070 | SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF); | 6972 | SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF); |
7071 | 6973 | ||
7072 | #ifdef SIS315H | 6974 | #ifdef CONFIG_FB_SIS_315 |
7073 | if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, | 6975 | if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, |
7074 | &CRT2Index, &resindex)) { | 6976 | &CRT2Index, &resindex)) { |
7075 | switch(CRT2Index) { | 6977 | switch(CRT2Index) { |
@@ -7130,12 +7032,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
7130 | 7032 | ||
7131 | /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */ | 7033 | /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */ |
7132 | 7034 | ||
7133 | #ifdef SIS_XORG_XF86 | ||
7134 | #ifdef TWDEBUG | ||
7135 | xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx); | ||
7136 | #endif | ||
7137 | #endif | ||
7138 | |||
7139 | SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */ | 7035 | SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */ |
7140 | SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */ | 7036 | SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */ |
7141 | 7037 | ||
@@ -7184,12 +7080,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
7184 | tempbx = SiS_Pr->CVSyncStart; | 7080 | tempbx = SiS_Pr->CVSyncStart; |
7185 | } | 7081 | } |
7186 | 7082 | ||
7187 | #ifdef SIS_XORG_XF86 | ||
7188 | #ifdef TWDEBUG | ||
7189 | xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx); | ||
7190 | #endif | ||
7191 | #endif | ||
7192 | |||
7193 | SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */ | 7083 | SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */ |
7194 | 7084 | ||
7195 | temp = (tempbx >> 4) & 0xF0; | 7085 | temp = (tempbx >> 4) & 0xF0; |
@@ -7201,15 +7091,9 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
7201 | temp |= (SiS_Pr->CVSyncEnd & 0x0f); | 7091 | temp |= (SiS_Pr->CVSyncEnd & 0x0f); |
7202 | } | 7092 | } |
7203 | 7093 | ||
7204 | #ifdef SIS_XORG_XF86 | ||
7205 | #ifdef TWDEBUG | ||
7206 | xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f)); | ||
7207 | #endif | ||
7208 | #endif | ||
7209 | |||
7210 | SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp); | 7094 | SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp); |
7211 | 7095 | ||
7212 | #ifdef SIS300 | 7096 | #ifdef CONFIG_FB_SIS_300 |
7213 | SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc); | 7097 | SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc); |
7214 | #endif | 7098 | #endif |
7215 | 7099 | ||
@@ -7245,12 +7129,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
7245 | tempax >>= 1; | 7129 | tempax >>= 1; |
7246 | } | 7130 | } |
7247 | 7131 | ||
7248 | #ifdef SIS_XORG_XF86 | ||
7249 | #ifdef TWDEBUG | ||
7250 | xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx); | ||
7251 | #endif | ||
7252 | #endif | ||
7253 | |||
7254 | tempbx += bridgeoffset; | 7132 | tempbx += bridgeoffset; |
7255 | 7133 | ||
7256 | SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */ | 7134 | SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */ |
@@ -7276,12 +7154,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
7276 | tempbx += bridgeoffset; | 7154 | tempbx += bridgeoffset; |
7277 | } | 7155 | } |
7278 | 7156 | ||
7279 | #ifdef SIS_XORG_XF86 | ||
7280 | #ifdef TWDEBUG | ||
7281 | xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx); | ||
7282 | #endif | ||
7283 | #endif | ||
7284 | |||
7285 | SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */ | 7157 | SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */ |
7286 | SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0)); | 7158 | SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0)); |
7287 | 7159 | ||
@@ -7300,20 +7172,14 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
7300 | tempbx += bridgeoffset; | 7172 | tempbx += bridgeoffset; |
7301 | } | 7173 | } |
7302 | 7174 | ||
7303 | #ifdef SIS_XORG_XF86 | ||
7304 | #ifdef TWDEBUG | ||
7305 | xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx); | ||
7306 | #endif | ||
7307 | #endif | ||
7308 | |||
7309 | SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */ | 7175 | SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */ |
7310 | 7176 | ||
7311 | SiS_SetGroup2_Tail(SiS_Pr, ModeNo); | 7177 | SiS_SetGroup2_Tail(SiS_Pr, ModeNo); |
7312 | 7178 | ||
7313 | #ifdef SIS300 | 7179 | #ifdef CONFIG_FB_SIS_300 |
7314 | SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo); | 7180 | SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo); |
7315 | #endif | 7181 | #endif |
7316 | #ifdef SIS315H | 7182 | #ifdef CONFIG_FB_SIS_315 |
7317 | } /* CRT2-LCD from table */ | 7183 | } /* CRT2-LCD from table */ |
7318 | #endif | 7184 | #endif |
7319 | } | 7185 | } |
@@ -7382,7 +7248,7 @@ SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
7382 | /* SET PART 4 REGISTER GROUP */ | 7248 | /* SET PART 4 REGISTER GROUP */ |
7383 | /*********************************************/ | 7249 | /*********************************************/ |
7384 | 7250 | ||
7385 | #ifdef SIS315H | 7251 | #ifdef CONFIG_FB_SIS_315 |
7386 | #if 0 | 7252 | #if 0 |
7387 | static void | 7253 | static void |
7388 | SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift) | 7254 | SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift) |
@@ -8011,7 +7877,7 @@ SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
8011 | 7877 | ||
8012 | if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { | 7878 | if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { |
8013 | 7879 | ||
8014 | #ifdef SIS300 | 7880 | #ifdef CONFIG_FB_SIS_300 |
8015 | 7881 | ||
8016 | /* Chrontel 7005 - I assume that it does not come with a 315 series chip */ | 7882 | /* Chrontel 7005 - I assume that it does not come with a 315 series chip */ |
8017 | 7883 | ||
@@ -8124,7 +7990,7 @@ SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
8124 | 7990 | ||
8125 | /* Chrontel 7019 - assumed that it does not come with a 300 series chip */ | 7991 | /* Chrontel 7019 - assumed that it does not come with a 300 series chip */ |
8126 | 7992 | ||
8127 | #ifdef SIS315H | 7993 | #ifdef CONFIG_FB_SIS_315 |
8128 | 7994 | ||
8129 | unsigned short temp; | 7995 | unsigned short temp; |
8130 | 7996 | ||
@@ -8175,7 +8041,7 @@ SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short | |||
8175 | 8041 | ||
8176 | } | 8042 | } |
8177 | 8043 | ||
8178 | #ifdef SIS315H /* ----------- 315 series only ---------- */ | 8044 | #ifdef CONFIG_FB_SIS_315 /* ----------- 315 series only ---------- */ |
8179 | 8045 | ||
8180 | void | 8046 | void |
8181 | SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr) | 8047 | SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr) |
@@ -8657,7 +8523,7 @@ SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr) | |||
8657 | bool | 8523 | bool |
8658 | SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | 8524 | SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo) |
8659 | { | 8525 | { |
8660 | #ifdef SIS300 | 8526 | #ifdef CONFIG_FB_SIS_300 |
8661 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; | 8527 | unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; |
8662 | #endif | 8528 | #endif |
8663 | unsigned short ModeIdIndex, RefreshRateTableIndex; | 8529 | unsigned short ModeIdIndex, RefreshRateTableIndex; |
@@ -8703,16 +8569,6 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
8703 | SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); | 8569 | SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); |
8704 | } | 8570 | } |
8705 | 8571 | ||
8706 | #ifdef SIS_XORG_XF86 | ||
8707 | #ifdef TWDEBUG | ||
8708 | xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES); | ||
8709 | xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE); | ||
8710 | xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE); | ||
8711 | xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT); | ||
8712 | xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT); | ||
8713 | #endif | ||
8714 | #endif | ||
8715 | |||
8716 | if(SiS_Pr->SiS_SetFlag & LowModeTests) { | 8572 | if(SiS_Pr->SiS_SetFlag & LowModeTests) { |
8717 | SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); | 8573 | SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); |
8718 | } | 8574 | } |
@@ -8722,12 +8578,12 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
8722 | if(SiS_Pr->SiS_SetFlag & LowModeTests) { | 8578 | if(SiS_Pr->SiS_SetFlag & LowModeTests) { |
8723 | 8579 | ||
8724 | SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); | 8580 | SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); |
8725 | #ifdef SIS315H | 8581 | #ifdef CONFIG_FB_SIS_315 |
8726 | SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); | 8582 | SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); |
8727 | #endif | 8583 | #endif |
8728 | SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex); | 8584 | SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex); |
8729 | SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); | 8585 | SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); |
8730 | #ifdef SIS315H | 8586 | #ifdef CONFIG_FB_SIS_315 |
8731 | SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex); | 8587 | SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex); |
8732 | #endif | 8588 | #endif |
8733 | SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex); | 8589 | SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex); |
@@ -8758,7 +8614,7 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
8758 | if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { | 8614 | if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { |
8759 | if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { | 8615 | if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { |
8760 | if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { | 8616 | if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { |
8761 | #ifdef SIS315H | 8617 | #ifdef CONFIG_FB_SIS_315 |
8762 | SiS_SetCH701xForLCD(SiS_Pr); | 8618 | SiS_SetCH701xForLCD(SiS_Pr); |
8763 | #endif | 8619 | #endif |
8764 | } | 8620 | } |
@@ -8771,7 +8627,7 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
8771 | 8627 | ||
8772 | } | 8628 | } |
8773 | 8629 | ||
8774 | #ifdef SIS300 | 8630 | #ifdef CONFIG_FB_SIS_300 |
8775 | if(SiS_Pr->ChipType < SIS_315H) { | 8631 | if(SiS_Pr->ChipType < SIS_315H) { |
8776 | if(SiS_Pr->SiS_SetFlag & LowModeTests) { | 8632 | if(SiS_Pr->SiS_SetFlag & LowModeTests) { |
8777 | if(SiS_Pr->SiS_UseOEM) { | 8633 | if(SiS_Pr->SiS_UseOEM) { |
@@ -8794,7 +8650,7 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
8794 | } | 8650 | } |
8795 | #endif | 8651 | #endif |
8796 | 8652 | ||
8797 | #ifdef SIS315H | 8653 | #ifdef CONFIG_FB_SIS_315 |
8798 | if(SiS_Pr->ChipType >= SIS_315H) { | 8654 | if(SiS_Pr->ChipType >= SIS_315H) { |
8799 | if(SiS_Pr->SiS_SetFlag & LowModeTests) { | 8655 | if(SiS_Pr->SiS_SetFlag & LowModeTests) { |
8800 | if(SiS_Pr->ChipType < SIS_661) { | 8656 | if(SiS_Pr->ChipType < SIS_661) { |
@@ -8873,7 +8729,7 @@ SiS_SetupDDCN(struct SiS_Private *SiS_Pr) | |||
8873 | } | 8729 | } |
8874 | } | 8730 | } |
8875 | 8731 | ||
8876 | #ifdef SIS300 | 8732 | #ifdef CONFIG_FB_SIS_300 |
8877 | static unsigned char * | 8733 | static unsigned char * |
8878 | SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr) | 8734 | SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr) |
8879 | { | 8735 | { |
@@ -8923,11 +8779,6 @@ SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr) | |||
8923 | dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr); | 8779 | dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr); |
8924 | if(!dataptr) return false; | 8780 | if(!dataptr) return false; |
8925 | } | 8781 | } |
8926 | #ifdef SIS_XORG_XF86 | ||
8927 | #ifdef TWDEBUG | ||
8928 | xf86DrvMsg(0, X_INFO, "Trumpion block success\n"); | ||
8929 | #endif | ||
8930 | #endif | ||
8931 | return true; | 8782 | return true; |
8932 | } | 8783 | } |
8933 | #endif | 8784 | #endif |
@@ -9002,9 +8853,7 @@ SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val) | |||
9002 | SiS_SetChReg(SiS_Pr, reg, val, 0); | 8853 | SiS_SetChReg(SiS_Pr, reg, val, 0); |
9003 | } | 8854 | } |
9004 | 8855 | ||
9005 | #ifdef SIS_LINUX_KERNEL | ||
9006 | static | 8856 | static |
9007 | #endif | ||
9008 | void | 8857 | void |
9009 | SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val) | 8858 | SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val) |
9010 | { | 8859 | { |
@@ -9091,9 +8940,7 @@ SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx) | |||
9091 | 8940 | ||
9092 | /* Read from Chrontel 70xx */ | 8941 | /* Read from Chrontel 70xx */ |
9093 | /* Parameter is [Register no (S7-S0)] */ | 8942 | /* Parameter is [Register no (S7-S0)] */ |
9094 | #ifdef SIS_LINUX_KERNEL | ||
9095 | static | 8943 | static |
9096 | #endif | ||
9097 | unsigned short | 8944 | unsigned short |
9098 | SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx) | 8945 | SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx) |
9099 | { | 8946 | { |
@@ -9114,9 +8961,7 @@ SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg, | |||
9114 | } | 8961 | } |
9115 | 8962 | ||
9116 | /* Our own DDC functions */ | 8963 | /* Our own DDC functions */ |
9117 | #ifndef SIS_XORG_XF86 | ||
9118 | static | 8964 | static |
9119 | #endif | ||
9120 | unsigned short | 8965 | unsigned short |
9121 | SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine, | 8966 | SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine, |
9122 | unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32, | 8967 | unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32, |
@@ -9224,12 +9069,6 @@ SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine, | |||
9224 | 9069 | ||
9225 | SiS_SetupDDCN(SiS_Pr); | 9070 | SiS_SetupDDCN(SiS_Pr); |
9226 | 9071 | ||
9227 | #ifdef SIS_XORG_XF86 | ||
9228 | #ifdef TWDEBUG | ||
9229 | xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n", | ||
9230 | SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp); | ||
9231 | #endif | ||
9232 | #endif | ||
9233 | return 0; | 9072 | return 0; |
9234 | } | 9073 | } |
9235 | 9074 | ||
@@ -9292,11 +9131,6 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr) | |||
9292 | SiS_SetSwitchDDC2(SiS_Pr); | 9131 | SiS_SetSwitchDDC2(SiS_Pr); |
9293 | if(SiS_PrepareDDC(SiS_Pr)) { | 9132 | if(SiS_PrepareDDC(SiS_Pr)) { |
9294 | SiS_SetStop(SiS_Pr); | 9133 | SiS_SetStop(SiS_Pr); |
9295 | #ifdef SIS_XORG_XF86 | ||
9296 | #ifdef TWDEBUG | ||
9297 | xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n"); | ||
9298 | #endif | ||
9299 | #endif | ||
9300 | return 0xFFFF; | 9134 | return 0xFFFF; |
9301 | } | 9135 | } |
9302 | mask = 0xf0; | 9136 | mask = 0xf0; |
@@ -9310,11 +9144,6 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr) | |||
9310 | } else { | 9144 | } else { |
9311 | failed = true; | 9145 | failed = true; |
9312 | ret = 0xFFFF; | 9146 | ret = 0xFFFF; |
9313 | #ifdef SIS_XORG_XF86 | ||
9314 | #ifdef TWDEBUG | ||
9315 | xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n"); | ||
9316 | #endif | ||
9317 | #endif | ||
9318 | } | 9147 | } |
9319 | } | 9148 | } |
9320 | if(!failed) { | 9149 | if(!failed) { |
@@ -9324,11 +9153,6 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr) | |||
9324 | if(temp == value) ret = 0; | 9153 | if(temp == value) ret = 0; |
9325 | else { | 9154 | else { |
9326 | ret = 0xFFFF; | 9155 | ret = 0xFFFF; |
9327 | #ifdef SIS_XORG_XF86 | ||
9328 | #ifdef TWDEBUG | ||
9329 | xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n"); | ||
9330 | #endif | ||
9331 | #endif | ||
9332 | if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) { | 9156 | if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) { |
9333 | if(temp == 0x30) ret = 0; | 9157 | if(temp == 0x30) ret = 0; |
9334 | } | 9158 | } |
@@ -9338,9 +9162,7 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr) | |||
9338 | return ret; | 9162 | return ret; |
9339 | } | 9163 | } |
9340 | 9164 | ||
9341 | #ifndef SIS_XORG_XF86 | ||
9342 | static | 9165 | static |
9343 | #endif | ||
9344 | unsigned short | 9166 | unsigned short |
9345 | SiS_ProbeDDC(struct SiS_Private *SiS_Pr) | 9167 | SiS_ProbeDDC(struct SiS_Private *SiS_Pr) |
9346 | { | 9168 | { |
@@ -9357,9 +9179,7 @@ SiS_ProbeDDC(struct SiS_Private *SiS_Pr) | |||
9357 | return flag; | 9179 | return flag; |
9358 | } | 9180 | } |
9359 | 9181 | ||
9360 | #ifndef SIS_XORG_XF86 | ||
9361 | static | 9182 | static |
9362 | #endif | ||
9363 | unsigned short | 9183 | unsigned short |
9364 | SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer) | 9184 | SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer) |
9365 | { | 9185 | { |
@@ -9606,11 +9426,6 @@ SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr) | |||
9606 | temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); | 9426 | temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); |
9607 | } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog); | 9427 | } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog); |
9608 | if (!watchdog) { | 9428 | if (!watchdog) { |
9609 | #ifdef SIS_XORG_XF86 | ||
9610 | #ifdef TWDEBUG | ||
9611 | xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n"); | ||
9612 | #endif | ||
9613 | #endif | ||
9614 | return 0xFFFF; | 9429 | return 0xFFFF; |
9615 | } | 9430 | } |
9616 | SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); | 9431 | SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); |
@@ -9641,7 +9456,7 @@ SiS_CheckACK(struct SiS_Private *SiS_Pr) | |||
9641 | 9456 | ||
9642 | /* =============== SiS 315/330 O.E.M. ================= */ | 9457 | /* =============== SiS 315/330 O.E.M. ================= */ |
9643 | 9458 | ||
9644 | #ifdef SIS315H | 9459 | #ifdef CONFIG_FB_SIS_315 |
9645 | 9460 | ||
9646 | static unsigned short | 9461 | static unsigned short |
9647 | GetRAMDACromptr(struct SiS_Private *SiS_Pr) | 9462 | GetRAMDACromptr(struct SiS_Private *SiS_Pr) |
@@ -10829,7 +10644,7 @@ SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor | |||
10829 | 10644 | ||
10830 | /* ================= SiS 300 O.E.M. ================== */ | 10645 | /* ================= SiS 300 O.E.M. ================== */ |
10831 | 10646 | ||
10832 | #ifdef SIS300 | 10647 | #ifdef CONFIG_FB_SIS_300 |
10833 | 10648 | ||
10834 | static void | 10649 | static void |
10835 | SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex, | 10650 | SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex, |
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h index 51d99222375d..e1fd31d0fddf 100644 --- a/drivers/video/sis/init301.h +++ b/drivers/video/sis/init301.h | |||
@@ -53,15 +53,8 @@ | |||
53 | #ifndef _INIT301_H_ | 53 | #ifndef _INIT301_H_ |
54 | #define _INIT301_H_ | 54 | #define _INIT301_H_ |
55 | 55 | ||
56 | #include "osdef.h" | ||
57 | #include "initdef.h" | 56 | #include "initdef.h" |
58 | 57 | ||
59 | #ifdef SIS_XORG_XF86 | ||
60 | #include "sis.h" | ||
61 | #include "sis_regs.h" | ||
62 | #endif | ||
63 | |||
64 | #ifdef SIS_LINUX_KERNEL | ||
65 | #include "vgatypes.h" | 58 | #include "vgatypes.h" |
66 | #include "vstruct.h" | 59 | #include "vstruct.h" |
67 | #ifdef SIS_CP | 60 | #ifdef SIS_CP |
@@ -72,7 +65,6 @@ | |||
72 | #include <linux/fb.h> | 65 | #include <linux/fb.h> |
73 | #include "sis.h" | 66 | #include "sis.h" |
74 | #include <video/sisfb.h> | 67 | #include <video/sisfb.h> |
75 | #endif | ||
76 | 68 | ||
77 | static const unsigned char SiS_YPbPrTable[3][64] = { | 69 | static const unsigned char SiS_YPbPrTable[3][64] = { |
78 | { | 70 | { |
@@ -237,7 +229,7 @@ static const unsigned char SiS_Part2CLVX_6[] = { /* 1080i */ | |||
237 | 0xFF,0xFF, | 229 | 0xFF,0xFF, |
238 | }; | 230 | }; |
239 | 231 | ||
240 | #ifdef SIS315H | 232 | #ifdef CONFIG_FB_SIS_315 |
241 | /* 661 et al LCD data structure (2.03.00) */ | 233 | /* 661 et al LCD data structure (2.03.00) */ |
242 | static const unsigned char SiS_LCDStruct661[] = { | 234 | static const unsigned char SiS_LCDStruct661[] = { |
243 | /* 1024x768 */ | 235 | /* 1024x768 */ |
@@ -279,7 +271,7 @@ static const unsigned char SiS_LCDStruct661[] = { | |||
279 | }; | 271 | }; |
280 | #endif | 272 | #endif |
281 | 273 | ||
282 | #ifdef SIS300 | 274 | #ifdef CONFIG_FB_SIS_300 |
283 | static unsigned char SiS300_TrumpionData[14][80] = { | 275 | static unsigned char SiS300_TrumpionData[14][80] = { |
284 | { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02, | 276 | { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02, |
285 | 0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23, | 277 | 0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23, |
@@ -356,9 +348,6 @@ static unsigned char SiS300_TrumpionData[14][80] = { | |||
356 | #endif | 348 | #endif |
357 | 349 | ||
358 | void SiS_UnLockCRT2(struct SiS_Private *SiS_Pr); | 350 | void SiS_UnLockCRT2(struct SiS_Private *SiS_Pr); |
359 | #ifndef SIS_LINUX_KERNEL | ||
360 | void SiS_LockCRT2(struct SiS_Private *SiS_Pr); | ||
361 | #endif | ||
362 | void SiS_EnableCRT2(struct SiS_Private *SiS_Pr); | 351 | void SiS_EnableCRT2(struct SiS_Private *SiS_Pr); |
363 | unsigned short SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex); | 352 | unsigned short SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex); |
364 | void SiS_WaitRetrace1(struct SiS_Private *SiS_Pr); | 353 | void SiS_WaitRetrace1(struct SiS_Private *SiS_Pr); |
@@ -375,9 +364,6 @@ unsigned short SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo | |||
375 | unsigned short RefreshRateTableIndex); | 364 | unsigned short RefreshRateTableIndex); |
376 | unsigned short SiS_GetResInfo(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex); | 365 | unsigned short SiS_GetResInfo(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex); |
377 | void SiS_DisableBridge(struct SiS_Private *SiS_Pr); | 366 | void SiS_DisableBridge(struct SiS_Private *SiS_Pr); |
378 | #ifndef SIS_LINUX_KERNEL | ||
379 | void SiS_EnableBridge(struct SiS_Private *SiS_Pr); | ||
380 | #endif | ||
381 | bool SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo); | 367 | bool SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo); |
382 | void SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr); | 368 | void SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr); |
383 | void SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr); | 369 | void SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr); |
@@ -386,13 +372,9 @@ void SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned cha | |||
386 | unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempax); | 372 | unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempax); |
387 | void SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val); | 373 | void SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val); |
388 | unsigned short SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempax); | 374 | unsigned short SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempax); |
389 | #ifndef SIS_LINUX_KERNEL | ||
390 | void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val); | ||
391 | unsigned short SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempax); | ||
392 | #endif | ||
393 | void SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg, | 375 | void SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg, |
394 | unsigned char orval,unsigned short andval); | 376 | unsigned char orval,unsigned short andval); |
395 | #ifdef SIS315H | 377 | #ifdef CONFIG_FB_SIS_315 |
396 | static void SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr); | 378 | static void SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr); |
397 | static void SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr); | 379 | static void SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr); |
398 | static void SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr); | 380 | static void SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr); |
@@ -401,7 +383,7 @@ void SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr); | |||
401 | void SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr); | 383 | void SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr); |
402 | #endif /* 315 */ | 384 | #endif /* 315 */ |
403 | 385 | ||
404 | #ifdef SIS300 | 386 | #ifdef CONFIG_FB_SIS_300 |
405 | static bool SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr); | 387 | static bool SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr); |
406 | void SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo); | 388 | void SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo); |
407 | #endif | 389 | #endif |
@@ -412,21 +394,12 @@ unsigned short SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, i | |||
412 | unsigned short adaptnum, unsigned short DDCdatatype, | 394 | unsigned short adaptnum, unsigned short DDCdatatype, |
413 | unsigned char *buffer, unsigned int VBFlags2); | 395 | unsigned char *buffer, unsigned int VBFlags2); |
414 | 396 | ||
415 | #ifdef SIS_XORG_XF86 | ||
416 | unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, | ||
417 | int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype, | ||
418 | bool checkcr32, unsigned int VBFlags2); | ||
419 | unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr); | ||
420 | unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, | ||
421 | unsigned char *buffer); | ||
422 | #else | ||
423 | static unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, | 397 | static unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, |
424 | int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype, | 398 | int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype, |
425 | bool checkcr32, unsigned int VBFlags2); | 399 | bool checkcr32, unsigned int VBFlags2); |
426 | static unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr); | 400 | static unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr); |
427 | static unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, | 401 | static unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, |
428 | unsigned char *buffer); | 402 | unsigned char *buffer); |
429 | #endif | ||
430 | static void SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr); | 403 | static void SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr); |
431 | static unsigned short SiS_SetStart(struct SiS_Private *SiS_Pr); | 404 | static unsigned short SiS_SetStart(struct SiS_Private *SiS_Pr); |
432 | static unsigned short SiS_SetStop(struct SiS_Private *SiS_Pr); | 405 | static unsigned short SiS_SetStop(struct SiS_Private *SiS_Pr); |
@@ -441,13 +414,13 @@ static unsigned short SiS_PrepareDDC(struct SiS_Private *SiS_Pr); | |||
441 | static void SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno); | 414 | static void SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno); |
442 | static unsigned short SiS_DoProbeDDC(struct SiS_Private *SiS_Pr); | 415 | static unsigned short SiS_DoProbeDDC(struct SiS_Private *SiS_Pr); |
443 | 416 | ||
444 | #ifdef SIS300 | 417 | #ifdef CONFIG_FB_SIS_300 |
445 | static void SiS_OEM300Setting(struct SiS_Private *SiS_Pr, | 418 | static void SiS_OEM300Setting(struct SiS_Private *SiS_Pr, |
446 | unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex); | 419 | unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex); |
447 | static void SetOEMLCDData2(struct SiS_Private *SiS_Pr, | 420 | static void SetOEMLCDData2(struct SiS_Private *SiS_Pr, |
448 | unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex); | 421 | unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex); |
449 | #endif | 422 | #endif |
450 | #ifdef SIS315H | 423 | #ifdef CONFIG_FB_SIS_315 |
451 | static void SiS_OEM310Setting(struct SiS_Private *SiS_Pr, | 424 | static void SiS_OEM310Setting(struct SiS_Private *SiS_Pr, |
452 | unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI); | 425 | unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI); |
453 | static void SiS_OEM661Setting(struct SiS_Private *SiS_Pr, | 426 | static void SiS_OEM661Setting(struct SiS_Private *SiS_Pr, |
@@ -482,15 +455,13 @@ extern void SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short M | |||
482 | extern void SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth); | 455 | extern void SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth); |
483 | extern unsigned short SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide); | 456 | extern unsigned short SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide); |
484 | extern unsigned short SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide); | 457 | extern unsigned short SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide); |
485 | #ifdef SIS300 | 458 | #ifdef CONFIG_FB_SIS_300 |
486 | extern void SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *tempbx, | 459 | extern void SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *tempbx, |
487 | unsigned short *tempcl); | 460 | unsigned short *tempcl); |
488 | extern unsigned short SiS_GetFIFOThresholdB300(unsigned short tempbx, unsigned short tempcl); | 461 | extern unsigned short SiS_GetFIFOThresholdB300(unsigned short tempbx, unsigned short tempcl); |
489 | extern unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index); | 462 | extern unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index); |
490 | #ifdef SIS_LINUX_KERNEL | ||
491 | extern unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg); | 463 | extern unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg); |
492 | extern unsigned int sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg); | 464 | extern unsigned int sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg); |
493 | #endif | 465 | #endif |
494 | #endif | ||
495 | 466 | ||
496 | #endif | 467 | #endif |
diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c index 99c04a4855d1..9dec64da4015 100644 --- a/drivers/video/sis/initextlfb.c +++ b/drivers/video/sis/initextlfb.c | |||
@@ -25,7 +25,6 @@ | |||
25 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | 25 | * Author: Thomas Winischhofer <thomas@winischhofer.net> |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include "osdef.h" | ||
29 | #include "initdef.h" | 28 | #include "initdef.h" |
30 | #include "vgatypes.h" | 29 | #include "vgatypes.h" |
31 | #include "vstruct.h" | 30 | #include "vstruct.h" |
@@ -59,7 +58,7 @@ sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno, | |||
59 | 58 | ||
60 | if(rateindex > 0) rateindex--; | 59 | if(rateindex > 0) rateindex--; |
61 | 60 | ||
62 | #ifdef SIS315H | 61 | #ifdef CONFIG_FB_SIS_315 |
63 | switch(ModeNo) { | 62 | switch(ModeNo) { |
64 | case 0x5a: ModeNo = 0x50; break; | 63 | case 0x5a: ModeNo = 0x50; break; |
65 | case 0x5b: ModeNo = 0x56; | 64 | case 0x5b: ModeNo = 0x56; |
@@ -103,7 +102,7 @@ sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno, | |||
103 | 102 | ||
104 | if(rateindex > 0) rateindex--; | 103 | if(rateindex > 0) rateindex--; |
105 | 104 | ||
106 | #ifdef SIS315H | 105 | #ifdef CONFIG_FB_SIS_315 |
107 | switch(ModeNo) { | 106 | switch(ModeNo) { |
108 | case 0x5a: ModeNo = 0x50; break; | 107 | case 0x5a: ModeNo = 0x50; break; |
109 | case 0x5b: ModeNo = 0x56; | 108 | case 0x5b: ModeNo = 0x56; |
@@ -187,7 +186,7 @@ sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *ht | |||
187 | 186 | ||
188 | if(rateindex > 0) rateindex--; | 187 | if(rateindex > 0) rateindex--; |
189 | 188 | ||
190 | #ifdef SIS315H | 189 | #ifdef CONFIG_FB_SIS_315 |
191 | switch(ModeNo) { | 190 | switch(ModeNo) { |
192 | case 0x5a: ModeNo = 0x50; break; | 191 | case 0x5a: ModeNo = 0x50; break; |
193 | case 0x5b: ModeNo = 0x56; | 192 | case 0x5b: ModeNo = 0x56; |
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h deleted file mode 100644 index 6ff8f988a1a7..000000000000 --- a/drivers/video/sis/osdef.h +++ /dev/null | |||
@@ -1,133 +0,0 @@ | |||
1 | /* $XFree86$ */ | ||
2 | /* $XdotOrg$ */ | ||
3 | /* | ||
4 | * OS depending defines | ||
5 | * | ||
6 | * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria | ||
7 | * | ||
8 | * If distributed as part of the Linux kernel, the following license terms | ||
9 | * apply: | ||
10 | * | ||
11 | * * This program is free software; you can redistribute it and/or modify | ||
12 | * * it under the terms of the GNU General Public License as published by | ||
13 | * * the Free Software Foundation; either version 2 of the named License, | ||
14 | * * or any later version. | ||
15 | * * | ||
16 | * * This program is distributed in the hope that it will be useful, | ||
17 | * * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * * GNU General Public License for more 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA | ||
24 | * | ||
25 | * Otherwise, the following license terms apply: | ||
26 | * | ||
27 | * * Redistribution and use in source and binary forms, with or without | ||
28 | * * modification, are permitted provided that the following conditions | ||
29 | * * are met: | ||
30 | * * 1) Redistributions of source code must retain the above copyright | ||
31 | * * notice, this list of conditions and the following disclaimer. | ||
32 | * * 2) Redistributions in binary form must reproduce the above copyright | ||
33 | * * notice, this list of conditions and the following disclaimer in the | ||
34 | * * documentation and/or other materials provided with the distribution. | ||
35 | * * 3) The name of the author may not be used to endorse or promote products | ||
36 | * * derived from this software without specific prior written permission. | ||
37 | * * | ||
38 | * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
39 | * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
40 | * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
41 | * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
42 | * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
43 | * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
44 | * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
45 | * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
46 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
47 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * | ||
49 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | ||
50 | * Silicon Integrated Systems, Inc. (used by permission) | ||
51 | * | ||
52 | */ | ||
53 | |||
54 | #ifndef _SIS_OSDEF_H_ | ||
55 | #define _SIS_OSDEF_H_ | ||
56 | |||
57 | /* The choices are: */ | ||
58 | #define SIS_LINUX_KERNEL /* Linux kernel framebuffer */ | ||
59 | #undef SIS_XORG_XF86 /* XFree86/X.org */ | ||
60 | |||
61 | #ifdef OutPortByte | ||
62 | #undef OutPortByte | ||
63 | #endif | ||
64 | |||
65 | #ifdef OutPortWord | ||
66 | #undef OutPortWord | ||
67 | #endif | ||
68 | |||
69 | #ifdef OutPortLong | ||
70 | #undef OutPortLong | ||
71 | #endif | ||
72 | |||
73 | #ifdef InPortByte | ||
74 | #undef InPortByte | ||
75 | #endif | ||
76 | |||
77 | #ifdef InPortWord | ||
78 | #undef InPortWord | ||
79 | #endif | ||
80 | |||
81 | #ifdef InPortLong | ||
82 | #undef InPortLong | ||
83 | #endif | ||
84 | |||
85 | /**********************************************************************/ | ||
86 | /* LINUX KERNEL */ | ||
87 | /**********************************************************************/ | ||
88 | |||
89 | #ifdef SIS_LINUX_KERNEL | ||
90 | |||
91 | #ifdef CONFIG_FB_SIS_300 | ||
92 | #define SIS300 | ||
93 | #endif | ||
94 | |||
95 | #ifdef CONFIG_FB_SIS_315 | ||
96 | #define SIS315H | ||
97 | #endif | ||
98 | |||
99 | #if !defined(SIS300) && !defined(SIS315H) | ||
100 | #warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set | ||
101 | #warning sisfb will not work! | ||
102 | #endif | ||
103 | |||
104 | #define OutPortByte(p,v) outb((u8)(v),(SISIOADDRESS)(p)) | ||
105 | #define OutPortWord(p,v) outw((u16)(v),(SISIOADDRESS)(p)) | ||
106 | #define OutPortLong(p,v) outl((u32)(v),(SISIOADDRESS)(p)) | ||
107 | #define InPortByte(p) inb((SISIOADDRESS)(p)) | ||
108 | #define InPortWord(p) inw((SISIOADDRESS)(p)) | ||
109 | #define InPortLong(p) inl((SISIOADDRESS)(p)) | ||
110 | #define SiS_SetMemory(MemoryAddress,MemorySize,value) memset_io(MemoryAddress, value, MemorySize) | ||
111 | |||
112 | #endif /* LINUX_KERNEL */ | ||
113 | |||
114 | /**********************************************************************/ | ||
115 | /* XFree86/X.org */ | ||
116 | /**********************************************************************/ | ||
117 | |||
118 | #ifdef SIS_XORG_XF86 | ||
119 | |||
120 | #define SIS300 | ||
121 | #define SIS315H | ||
122 | |||
123 | #define OutPortByte(p,v) outSISREG((IOADDRESS)(p),(CARD8)(v)) | ||
124 | #define OutPortWord(p,v) outSISREGW((IOADDRESS)(p),(CARD16)(v)) | ||
125 | #define OutPortLong(p,v) outSISREGL((IOADDRESS)(p),(CARD32)(v)) | ||
126 | #define InPortByte(p) inSISREG((IOADDRESS)(p)) | ||
127 | #define InPortWord(p) inSISREGW((IOADDRESS)(p)) | ||
128 | #define InPortLong(p) inSISREGL((IOADDRESS)(p)) | ||
129 | #define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize) | ||
130 | |||
131 | #endif /* XF86 */ | ||
132 | |||
133 | #endif /* _OSDEF_H_ */ | ||
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h index 7c5710e3fb56..80d89d37c414 100644 --- a/drivers/video/sis/sis.h +++ b/drivers/video/sis/sis.h | |||
@@ -24,7 +24,6 @@ | |||
24 | #ifndef _SIS_H_ | 24 | #ifndef _SIS_H_ |
25 | #define _SIS_H_ | 25 | #define _SIS_H_ |
26 | 26 | ||
27 | #include "osdef.h" | ||
28 | #include <video/sisfb.h> | 27 | #include <video/sisfb.h> |
29 | 28 | ||
30 | #include "vgatypes.h" | 29 | #include "vgatypes.h" |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 3dde12b0ab06..7e3370f115b6 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -60,6 +60,11 @@ | |||
60 | #include "sis.h" | 60 | #include "sis.h" |
61 | #include "sis_main.h" | 61 | #include "sis_main.h" |
62 | 62 | ||
63 | #if !defined(CONFIG_FB_SIS_300) && !defined(CONFIG_FB_SIS_315) | ||
64 | #warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set | ||
65 | #warning sisfb will not work! | ||
66 | #endif | ||
67 | |||
63 | static void sisfb_handle_command(struct sis_video_info *ivideo, | 68 | static void sisfb_handle_command(struct sis_video_info *ivideo, |
64 | struct sisfb_cmd *sisfb_command); | 69 | struct sisfb_cmd *sisfb_command); |
65 | 70 | ||
@@ -4114,14 +4119,6 @@ sisfb_find_rom(struct pci_dev *pdev) | |||
4114 | if(sisfb_check_rom(rom_base, ivideo)) { | 4119 | if(sisfb_check_rom(rom_base, ivideo)) { |
4115 | 4120 | ||
4116 | if((myrombase = vmalloc(65536))) { | 4121 | if((myrombase = vmalloc(65536))) { |
4117 | |||
4118 | /* Work around bug in pci/rom.c: Folks forgot to check | ||
4119 | * whether the size retrieved from the BIOS image eventually | ||
4120 | * is larger than the mapped size | ||
4121 | */ | ||
4122 | if(pci_resource_len(pdev, PCI_ROM_RESOURCE) < romsize) | ||
4123 | romsize = pci_resource_len(pdev, PCI_ROM_RESOURCE); | ||
4124 | |||
4125 | memcpy_fromio(myrombase, rom_base, | 4122 | memcpy_fromio(myrombase, rom_base, |
4126 | (romsize > 65536) ? 65536 : romsize); | 4123 | (romsize > 65536) ? 65536 : romsize); |
4127 | } | 4124 | } |
@@ -4155,23 +4152,6 @@ sisfb_find_rom(struct pci_dev *pdev) | |||
4155 | 4152 | ||
4156 | } | 4153 | } |
4157 | 4154 | ||
4158 | #else | ||
4159 | |||
4160 | pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &temp); | ||
4161 | pci_write_config_dword(pdev, PCI_ROM_ADDRESS, | ||
4162 | (ivideo->video_base & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE); | ||
4163 | |||
4164 | rom_base = ioremap(ivideo->video_base, 65536); | ||
4165 | if(rom_base) { | ||
4166 | if(sisfb_check_rom(rom_base, ivideo)) { | ||
4167 | if((myrombase = vmalloc(65536))) | ||
4168 | memcpy_fromio(myrombase, rom_base, 65536); | ||
4169 | } | ||
4170 | iounmap(rom_base); | ||
4171 | } | ||
4172 | |||
4173 | pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp); | ||
4174 | |||
4175 | #endif | 4155 | #endif |
4176 | 4156 | ||
4177 | return myrombase; | 4157 | return myrombase; |
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h index 81a22eaabfde..12c0dfaf2518 100644 --- a/drivers/video/sis/vgatypes.h +++ b/drivers/video/sis/vgatypes.h | |||
@@ -55,21 +55,10 @@ | |||
55 | 55 | ||
56 | #define SISIOMEMTYPE | 56 | #define SISIOMEMTYPE |
57 | 57 | ||
58 | #ifdef SIS_LINUX_KERNEL | ||
59 | typedef unsigned long SISIOADDRESS; | 58 | typedef unsigned long SISIOADDRESS; |
60 | #include <linux/types.h> /* Need __iomem */ | 59 | #include <linux/types.h> /* Need __iomem */ |
61 | #undef SISIOMEMTYPE | 60 | #undef SISIOMEMTYPE |
62 | #define SISIOMEMTYPE __iomem | 61 | #define SISIOMEMTYPE __iomem |
63 | #endif | ||
64 | |||
65 | #ifdef SIS_XORG_XF86 | ||
66 | #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0) | ||
67 | typedef unsigned long IOADDRESS; | ||
68 | typedef unsigned long SISIOADDRESS; | ||
69 | #else | ||
70 | typedef IOADDRESS SISIOADDRESS; | ||
71 | #endif | ||
72 | #endif | ||
73 | 62 | ||
74 | typedef enum _SIS_CHIP_TYPE { | 63 | typedef enum _SIS_CHIP_TYPE { |
75 | SIS_VGALegacy = 0, | 64 | SIS_VGALegacy = 0, |
diff --git a/drivers/video/sis/vstruct.h b/drivers/video/sis/vstruct.h index bef4aae388d0..ea94d214dcff 100644 --- a/drivers/video/sis/vstruct.h +++ b/drivers/video/sis/vstruct.h | |||
@@ -233,24 +233,15 @@ struct SiS_Private | |||
233 | { | 233 | { |
234 | unsigned char ChipType; | 234 | unsigned char ChipType; |
235 | unsigned char ChipRevision; | 235 | unsigned char ChipRevision; |
236 | #ifdef SIS_XORG_XF86 | ||
237 | PCITAG PciTag; | ||
238 | #endif | ||
239 | #ifdef SIS_LINUX_KERNEL | ||
240 | void *ivideo; | 236 | void *ivideo; |
241 | #endif | ||
242 | unsigned char *VirtualRomBase; | 237 | unsigned char *VirtualRomBase; |
243 | bool UseROM; | 238 | bool UseROM; |
244 | #ifdef SIS_LINUX_KERNEL | ||
245 | unsigned char SISIOMEMTYPE *VideoMemoryAddress; | 239 | unsigned char SISIOMEMTYPE *VideoMemoryAddress; |
246 | unsigned int VideoMemorySize; | 240 | unsigned int VideoMemorySize; |
247 | #endif | ||
248 | SISIOADDRESS IOAddress; | 241 | SISIOADDRESS IOAddress; |
249 | SISIOADDRESS IOAddress2; /* For dual chip XGI volari */ | 242 | SISIOADDRESS IOAddress2; /* For dual chip XGI volari */ |
250 | 243 | ||
251 | #ifdef SIS_LINUX_KERNEL | ||
252 | SISIOADDRESS RelIO; | 244 | SISIOADDRESS RelIO; |
253 | #endif | ||
254 | SISIOADDRESS SiS_P3c4; | 245 | SISIOADDRESS SiS_P3c4; |
255 | SISIOADDRESS SiS_P3d4; | 246 | SISIOADDRESS SiS_P3d4; |
256 | SISIOADDRESS SiS_P3c0; | 247 | SISIOADDRESS SiS_P3c0; |
@@ -280,9 +271,6 @@ struct SiS_Private | |||
280 | unsigned short SiS_IF_DEF_FSTN; | 271 | unsigned short SiS_IF_DEF_FSTN; |
281 | unsigned short SiS_SysFlags; | 272 | unsigned short SiS_SysFlags; |
282 | unsigned char SiS_VGAINFO; | 273 | unsigned char SiS_VGAINFO; |
283 | #ifdef SIS_XORG_XF86 | ||
284 | unsigned short SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4; | ||
285 | #endif | ||
286 | bool SiS_UseROM; | 274 | bool SiS_UseROM; |
287 | bool SiS_ROMNew; | 275 | bool SiS_ROMNew; |
288 | bool SiS_XGIROM; | 276 | bool SiS_XGIROM; |
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 3a43ebf83a49..efb35aa8309a 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c | |||
@@ -9,19 +9,19 @@ static ssize_t device_show(struct device *_d, | |||
9 | struct device_attribute *attr, char *buf) | 9 | struct device_attribute *attr, char *buf) |
10 | { | 10 | { |
11 | struct virtio_device *dev = container_of(_d,struct virtio_device,dev); | 11 | struct virtio_device *dev = container_of(_d,struct virtio_device,dev); |
12 | return sprintf(buf, "%hu", dev->id.device); | 12 | return sprintf(buf, "0x%04x\n", dev->id.device); |
13 | } | 13 | } |
14 | static ssize_t vendor_show(struct device *_d, | 14 | static ssize_t vendor_show(struct device *_d, |
15 | struct device_attribute *attr, char *buf) | 15 | struct device_attribute *attr, char *buf) |
16 | { | 16 | { |
17 | struct virtio_device *dev = container_of(_d,struct virtio_device,dev); | 17 | struct virtio_device *dev = container_of(_d,struct virtio_device,dev); |
18 | return sprintf(buf, "%hu", dev->id.vendor); | 18 | return sprintf(buf, "0x%04x\n", dev->id.vendor); |
19 | } | 19 | } |
20 | static ssize_t status_show(struct device *_d, | 20 | static ssize_t status_show(struct device *_d, |
21 | struct device_attribute *attr, char *buf) | 21 | struct device_attribute *attr, char *buf) |
22 | { | 22 | { |
23 | struct virtio_device *dev = container_of(_d,struct virtio_device,dev); | 23 | struct virtio_device *dev = container_of(_d,struct virtio_device,dev); |
24 | return sprintf(buf, "0x%08x", dev->config->get_status(dev)); | 24 | return sprintf(buf, "0x%08x\n", dev->config->get_status(dev)); |
25 | } | 25 | } |
26 | static ssize_t modalias_show(struct device *_d, | 26 | static ssize_t modalias_show(struct device *_d, |
27 | struct device_attribute *attr, char *buf) | 27 | struct device_attribute *attr, char *buf) |
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 1475ed6b575f..cc2f73e03475 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -230,9 +230,6 @@ add_head: | |||
230 | pr_debug("Added buffer head %i to %p\n", head, vq); | 230 | pr_debug("Added buffer head %i to %p\n", head, vq); |
231 | END_USE(vq); | 231 | END_USE(vq); |
232 | 232 | ||
233 | /* If we're indirect, we can fit many (assuming not OOM). */ | ||
234 | if (vq->indirect) | ||
235 | return vq->num_free ? vq->vring.num : 0; | ||
236 | return vq->num_free; | 233 | return vq->num_free; |
237 | } | 234 | } |
238 | EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp); | 235 | EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp); |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index c8224587123f..9242d294fe90 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -134,6 +134,7 @@ EXPORT_SYMBOL_GPL(fuse_do_open); | |||
134 | void fuse_finish_open(struct inode *inode, struct file *file) | 134 | void fuse_finish_open(struct inode *inode, struct file *file) |
135 | { | 135 | { |
136 | struct fuse_file *ff = file->private_data; | 136 | struct fuse_file *ff = file->private_data; |
137 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
137 | 138 | ||
138 | if (ff->open_flags & FOPEN_DIRECT_IO) | 139 | if (ff->open_flags & FOPEN_DIRECT_IO) |
139 | file->f_op = &fuse_direct_io_file_operations; | 140 | file->f_op = &fuse_direct_io_file_operations; |
@@ -141,6 +142,15 @@ void fuse_finish_open(struct inode *inode, struct file *file) | |||
141 | invalidate_inode_pages2(inode->i_mapping); | 142 | invalidate_inode_pages2(inode->i_mapping); |
142 | if (ff->open_flags & FOPEN_NONSEEKABLE) | 143 | if (ff->open_flags & FOPEN_NONSEEKABLE) |
143 | nonseekable_open(inode, file); | 144 | nonseekable_open(inode, file); |
145 | if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC)) { | ||
146 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
147 | |||
148 | spin_lock(&fc->lock); | ||
149 | fi->attr_version = ++fc->attr_version; | ||
150 | i_size_write(inode, 0); | ||
151 | spin_unlock(&fc->lock); | ||
152 | fuse_invalidate_attr(inode); | ||
153 | } | ||
144 | } | 154 | } |
145 | 155 | ||
146 | int fuse_open_common(struct inode *inode, struct file *file, bool isdir) | 156 | int fuse_open_common(struct inode *inode, struct file *file, bool isdir) |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index da6b01d70f01..c126c83b9a45 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -706,6 +706,7 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask, | |||
706 | * skip over unmapped regions. | 706 | * skip over unmapped regions. |
707 | */ | 707 | */ |
708 | #define PAGEMAP_WALK_SIZE (PMD_SIZE) | 708 | #define PAGEMAP_WALK_SIZE (PMD_SIZE) |
709 | #define PAGEMAP_WALK_MASK (PMD_MASK) | ||
709 | static ssize_t pagemap_read(struct file *file, char __user *buf, | 710 | static ssize_t pagemap_read(struct file *file, char __user *buf, |
710 | size_t count, loff_t *ppos) | 711 | size_t count, loff_t *ppos) |
711 | { | 712 | { |
@@ -776,7 +777,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, | |||
776 | unsigned long end; | 777 | unsigned long end; |
777 | 778 | ||
778 | pm.pos = 0; | 779 | pm.pos = 0; |
779 | end = start_vaddr + PAGEMAP_WALK_SIZE; | 780 | end = (start_vaddr + PAGEMAP_WALK_SIZE) & PAGEMAP_WALK_MASK; |
780 | /* overflow ? */ | 781 | /* overflow ? */ |
781 | if (end < start_vaddr || end > end_vaddr) | 782 | if (end < start_vaddr || end > end_vaddr) |
782 | end = end_vaddr; | 783 | end = end_vaddr; |
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index bd9763e76bae..79265fdc317a 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c | |||
@@ -183,12 +183,11 @@ int reiserfs_unpack(struct inode *inode, struct file *filp) | |||
183 | return 0; | 183 | return 0; |
184 | } | 184 | } |
185 | 185 | ||
186 | /* we need to make sure nobody is changing the file size beneath | ||
187 | ** us | ||
188 | */ | ||
189 | reiserfs_mutex_lock_safe(&inode->i_mutex, inode->i_sb); | ||
190 | depth = reiserfs_write_lock_once(inode->i_sb); | 186 | depth = reiserfs_write_lock_once(inode->i_sb); |
191 | 187 | ||
188 | /* we need to make sure nobody is changing the file size beneath us */ | ||
189 | reiserfs_mutex_lock_safe(&inode->i_mutex, inode->i_sb); | ||
190 | |||
192 | write_from = inode->i_size & (blocksize - 1); | 191 | write_from = inode->i_size & (blocksize - 1); |
193 | /* if we are on a block boundary, we are already unpacked. */ | 192 | /* if we are on a block boundary, we are already unpacked. */ |
194 | if (write_from == 0) { | 193 | if (write_from == 0) { |
diff --git a/include/linux/fb.h b/include/linux/fb.h index 7fca3dc4e475..d1631d37e9e0 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h | |||
@@ -1122,6 +1122,7 @@ extern const struct fb_videomode *fb_find_best_display(const struct fb_monspecs | |||
1122 | 1122 | ||
1123 | /* drivers/video/fbcmap.c */ | 1123 | /* drivers/video/fbcmap.c */ |
1124 | extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp); | 1124 | extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp); |
1125 | extern int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags); | ||
1125 | extern void fb_dealloc_cmap(struct fb_cmap *cmap); | 1126 | extern void fb_dealloc_cmap(struct fb_cmap *cmap); |
1126 | extern int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to); | 1127 | extern int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to); |
1127 | extern int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to); | 1128 | extern int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index eedc00b7b1ee..c9e06cc70dad 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -34,9 +34,9 @@ | |||
34 | #define SEEK_MAX SEEK_END | 34 | #define SEEK_MAX SEEK_END |
35 | 35 | ||
36 | struct fstrim_range { | 36 | struct fstrim_range { |
37 | uint64_t start; | 37 | __u64 start; |
38 | uint64_t len; | 38 | __u64 len; |
39 | uint64_t minlen; | 39 | __u64 minlen; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | /* And dynamically-tunable limits and defaults: */ | 42 | /* And dynamically-tunable limits and defaults: */ |
diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h index 5c99da1078aa..f216a8879b58 100644 --- a/include/linux/mmc/sh_mmcif.h +++ b/include/linux/mmc/sh_mmcif.h | |||
@@ -14,8 +14,9 @@ | |||
14 | #ifndef __SH_MMCIF_H__ | 14 | #ifndef __SH_MMCIF_H__ |
15 | #define __SH_MMCIF_H__ | 15 | #define __SH_MMCIF_H__ |
16 | 16 | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/sh_dma.h> | ||
19 | 20 | ||
20 | /* | 21 | /* |
21 | * MMCIF : CE_CLK_CTRL [19:16] | 22 | * MMCIF : CE_CLK_CTRL [19:16] |
@@ -31,13 +32,19 @@ | |||
31 | * 1111 : Peripheral clock (sup_pclk set '1') | 32 | * 1111 : Peripheral clock (sup_pclk set '1') |
32 | */ | 33 | */ |
33 | 34 | ||
35 | struct sh_mmcif_dma { | ||
36 | struct sh_dmae_slave chan_priv_tx; | ||
37 | struct sh_dmae_slave chan_priv_rx; | ||
38 | }; | ||
39 | |||
34 | struct sh_mmcif_plat_data { | 40 | struct sh_mmcif_plat_data { |
35 | void (*set_pwr)(struct platform_device *pdev, int state); | 41 | void (*set_pwr)(struct platform_device *pdev, int state); |
36 | void (*down_pwr)(struct platform_device *pdev); | 42 | void (*down_pwr)(struct platform_device *pdev); |
37 | int (*get_cd)(struct platform_device *pdef); | 43 | int (*get_cd)(struct platform_device *pdef); |
38 | u8 sup_pclk; /* 1 :SH7757, 0: SH7724/SH7372 */ | 44 | struct sh_mmcif_dma *dma; |
39 | unsigned long caps; | 45 | u8 sup_pclk; /* 1 :SH7757, 0: SH7724/SH7372 */ |
40 | u32 ocr; | 46 | unsigned long caps; |
47 | u32 ocr; | ||
41 | }; | 48 | }; |
42 | 49 | ||
43 | #define MMCIF_CE_CMD_SET 0x00000000 | 50 | #define MMCIF_CE_CMD_SET 0x00000000 |
@@ -59,6 +66,29 @@ struct sh_mmcif_plat_data { | |||
59 | #define MMCIF_CE_HOST_STS2 0x0000004C | 66 | #define MMCIF_CE_HOST_STS2 0x0000004C |
60 | #define MMCIF_CE_VERSION 0x0000007C | 67 | #define MMCIF_CE_VERSION 0x0000007C |
61 | 68 | ||
69 | /* CE_BUF_ACC */ | ||
70 | #define BUF_ACC_DMAWEN (1 << 25) | ||
71 | #define BUF_ACC_DMAREN (1 << 24) | ||
72 | #define BUF_ACC_BUSW_32 (0 << 17) | ||
73 | #define BUF_ACC_BUSW_16 (1 << 17) | ||
74 | #define BUF_ACC_ATYP (1 << 16) | ||
75 | |||
76 | /* CE_CLK_CTRL */ | ||
77 | #define CLK_ENABLE (1 << 24) /* 1: output mmc clock */ | ||
78 | #define CLK_CLEAR ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16)) | ||
79 | #define CLK_SUP_PCLK ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16)) | ||
80 | #define SRSPTO_256 ((1 << 13) | (0 << 12)) /* resp timeout */ | ||
81 | #define SRBSYTO_29 ((1 << 11) | (1 << 10) | \ | ||
82 | (1 << 9) | (1 << 8)) /* resp busy timeout */ | ||
83 | #define SRWDTO_29 ((1 << 7) | (1 << 6) | \ | ||
84 | (1 << 5) | (1 << 4)) /* read/write timeout */ | ||
85 | #define SCCSTO_29 ((1 << 3) | (1 << 2) | \ | ||
86 | (1 << 1) | (1 << 0)) /* ccs timeout */ | ||
87 | |||
88 | /* CE_VERSION */ | ||
89 | #define SOFT_RST_ON (1 << 31) | ||
90 | #define SOFT_RST_OFF ~SOFT_RST_ON | ||
91 | |||
62 | static inline u32 sh_mmcif_readl(void __iomem *addr, int reg) | 92 | static inline u32 sh_mmcif_readl(void __iomem *addr, int reg) |
63 | { | 93 | { |
64 | return readl(addr + reg); | 94 | return readl(addr + reg); |
@@ -149,17 +179,23 @@ static inline void sh_mmcif_boot_init(void __iomem *base) | |||
149 | 179 | ||
150 | /* reset */ | 180 | /* reset */ |
151 | tmp = sh_mmcif_readl(base, MMCIF_CE_VERSION); | 181 | tmp = sh_mmcif_readl(base, MMCIF_CE_VERSION); |
152 | sh_mmcif_writel(base, MMCIF_CE_VERSION, tmp | 0x80000000); | 182 | sh_mmcif_writel(base, MMCIF_CE_VERSION, tmp | SOFT_RST_ON); |
153 | sh_mmcif_writel(base, MMCIF_CE_VERSION, tmp & ~0x80000000); | 183 | sh_mmcif_writel(base, MMCIF_CE_VERSION, tmp & SOFT_RST_OFF); |
154 | 184 | ||
155 | /* byte swap */ | 185 | /* byte swap */ |
156 | sh_mmcif_writel(base, MMCIF_CE_BUF_ACC, 0x00010000); | 186 | sh_mmcif_writel(base, MMCIF_CE_BUF_ACC, BUF_ACC_ATYP); |
157 | 187 | ||
158 | /* Set block size in MMCIF hardware */ | 188 | /* Set block size in MMCIF hardware */ |
159 | sh_mmcif_writel(base, MMCIF_CE_BLOCK_SET, SH_MMCIF_BBS); | 189 | sh_mmcif_writel(base, MMCIF_CE_BLOCK_SET, SH_MMCIF_BBS); |
160 | 190 | ||
161 | /* Enable the clock, set it to Bus clock/256 (about 325Khz)*/ | 191 | /* Enable the clock, set it to Bus clock/256 (about 325Khz). |
162 | sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL, 0x01072fff); | 192 | * It is unclear where 0x70000 comes from or if it is even needed. |
193 | * It is there for byte-compatibility with code that is known to | ||
194 | * work. | ||
195 | */ | ||
196 | sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL, | ||
197 | CLK_ENABLE | SRSPTO_256 | SRBSYTO_29 | SRWDTO_29 | | ||
198 | SCCSTO_29 | 0x70000); | ||
163 | 199 | ||
164 | /* CMD0 */ | 200 | /* CMD0 */ |
165 | sh_mmcif_boot_cmd(base, 0x00000040, 0); | 201 | sh_mmcif_boot_cmd(base, 0x00000040, 0); |
diff --git a/include/linux/module.h b/include/linux/module.h index b29e7458b966..7575bbbdf2a2 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -517,7 +517,7 @@ static inline void __module_get(struct module *module) | |||
517 | #define symbol_put_addr(p) do { } while(0) | 517 | #define symbol_put_addr(p) do { } while(0) |
518 | 518 | ||
519 | #endif /* CONFIG_MODULE_UNLOAD */ | 519 | #endif /* CONFIG_MODULE_UNLOAD */ |
520 | int use_module(struct module *a, struct module *b); | 520 | int ref_module(struct module *a, struct module *b); |
521 | 521 | ||
522 | /* This is a #define so the string doesn't get put in every .o file */ | 522 | /* This is a #define so the string doesn't get put in every .o file */ |
523 | #define module_name(mod) \ | 523 | #define module_name(mod) \ |
diff --git a/include/linux/page_cgroup.h b/include/linux/page_cgroup.h index 5bb13b3db84d..b02195dfc1b0 100644 --- a/include/linux/page_cgroup.h +++ b/include/linux/page_cgroup.h | |||
@@ -59,8 +59,6 @@ static inline void ClearPageCgroup##uname(struct page_cgroup *pc) \ | |||
59 | static inline int TestClearPageCgroup##uname(struct page_cgroup *pc) \ | 59 | static inline int TestClearPageCgroup##uname(struct page_cgroup *pc) \ |
60 | { return test_and_clear_bit(PCG_##lname, &pc->flags); } | 60 | { return test_and_clear_bit(PCG_##lname, &pc->flags); } |
61 | 61 | ||
62 | TESTPCGFLAG(Locked, LOCK) | ||
63 | |||
64 | /* Cache flag is set only once (at allocation) */ | 62 | /* Cache flag is set only once (at allocation) */ |
65 | TESTPCGFLAG(Cache, CACHE) | 63 | TESTPCGFLAG(Cache, CACHE) |
66 | CLEARPCGFLAG(Cache, CACHE) | 64 | CLEARPCGFLAG(Cache, CACHE) |
@@ -104,6 +102,11 @@ static inline void unlock_page_cgroup(struct page_cgroup *pc) | |||
104 | bit_spin_unlock(PCG_LOCK, &pc->flags); | 102 | bit_spin_unlock(PCG_LOCK, &pc->flags); |
105 | } | 103 | } |
106 | 104 | ||
105 | static inline int page_is_cgroup_locked(struct page_cgroup *pc) | ||
106 | { | ||
107 | return bit_spin_is_locked(PCG_LOCK, &pc->flags); | ||
108 | } | ||
109 | |||
107 | #else /* CONFIG_CGROUP_MEM_RES_CTLR */ | 110 | #else /* CONFIG_CGROUP_MEM_RES_CTLR */ |
108 | struct page_cgroup; | 111 | struct page_cgroup; |
109 | 112 | ||
diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index cea0c38e7a63..9a52f72527dc 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h | |||
@@ -19,11 +19,13 @@ struct clk_mapping { | |||
19 | }; | 19 | }; |
20 | 20 | ||
21 | struct clk_ops { | 21 | struct clk_ops { |
22 | #ifdef CONFIG_SH_CLK_CPG_LEGACY | ||
22 | void (*init)(struct clk *clk); | 23 | void (*init)(struct clk *clk); |
24 | #endif | ||
23 | int (*enable)(struct clk *clk); | 25 | int (*enable)(struct clk *clk); |
24 | void (*disable)(struct clk *clk); | 26 | void (*disable)(struct clk *clk); |
25 | unsigned long (*recalc)(struct clk *clk); | 27 | unsigned long (*recalc)(struct clk *clk); |
26 | int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id); | 28 | int (*set_rate)(struct clk *clk, unsigned long rate); |
27 | int (*set_parent)(struct clk *clk, struct clk *parent); | 29 | int (*set_parent)(struct clk *clk, struct clk *parent); |
28 | long (*round_rate)(struct clk *clk, unsigned long rate); | 30 | long (*round_rate)(struct clk *clk, unsigned long rate); |
29 | }; | 31 | }; |
@@ -67,36 +69,6 @@ int clk_register(struct clk *); | |||
67 | void clk_unregister(struct clk *); | 69 | void clk_unregister(struct clk *); |
68 | void clk_enable_init_clocks(void); | 70 | void clk_enable_init_clocks(void); |
69 | 71 | ||
70 | /** | ||
71 | * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter | ||
72 | * @clk: clock source | ||
73 | * @rate: desired clock rate in Hz | ||
74 | * @algo_id: algorithm id to be passed down to ops->set_rate | ||
75 | * | ||
76 | * Returns success (0) or negative errno. | ||
77 | */ | ||
78 | int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id); | ||
79 | |||
80 | enum clk_sh_algo_id { | ||
81 | NO_CHANGE = 0, | ||
82 | |||
83 | IUS_N1_N1, | ||
84 | IUS_322, | ||
85 | IUS_522, | ||
86 | IUS_N11, | ||
87 | |||
88 | SB_N1, | ||
89 | |||
90 | SB3_N1, | ||
91 | SB3_32, | ||
92 | SB3_43, | ||
93 | SB3_54, | ||
94 | |||
95 | BP_N1, | ||
96 | |||
97 | IP_N1, | ||
98 | }; | ||
99 | |||
100 | struct clk_div_mult_table { | 72 | struct clk_div_mult_table { |
101 | unsigned int *divisors; | 73 | unsigned int *divisors; |
102 | unsigned int nr_divisors; | 74 | unsigned int nr_divisors; |
diff --git a/include/video/da8xx-fb.h b/include/video/da8xx-fb.h index 6316cdabf73f..89d43b3d4cb9 100644 --- a/include/video/da8xx-fb.h +++ b/include/video/da8xx-fb.h | |||
@@ -99,7 +99,6 @@ struct lcd_sync_arg { | |||
99 | #define FBIPUT_COLOR _IOW('F', 6, int) | 99 | #define FBIPUT_COLOR _IOW('F', 6, int) |
100 | #define FBIPUT_HSYNC _IOW('F', 9, int) | 100 | #define FBIPUT_HSYNC _IOW('F', 9, int) |
101 | #define FBIPUT_VSYNC _IOW('F', 10, int) | 101 | #define FBIPUT_VSYNC _IOW('F', 10, int) |
102 | #define FBIO_WAITFORVSYNC _IOW('F', 0x20, u_int32_t) | ||
103 | 102 | ||
104 | #endif /* ifndef DA8XX_FB_H */ | 103 | #endif /* ifndef DA8XX_FB_H */ |
105 | 104 | ||
diff --git a/init/Kconfig b/init/Kconfig index 88c10468db46..c9728992a776 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -613,6 +613,19 @@ config CGROUP_MEM_RES_CTLR_SWAP | |||
613 | if boot option "noswapaccount" is set, swap will not be accounted. | 613 | if boot option "noswapaccount" is set, swap will not be accounted. |
614 | Now, memory usage of swap_cgroup is 2 bytes per entry. If swap page | 614 | Now, memory usage of swap_cgroup is 2 bytes per entry. If swap page |
615 | size is 4096bytes, 512k per 1Gbytes of swap. | 615 | size is 4096bytes, 512k per 1Gbytes of swap. |
616 | config CGROUP_MEM_RES_CTLR_SWAP_ENABLED | ||
617 | bool "Memory Resource Controller Swap Extension enabled by default" | ||
618 | depends on CGROUP_MEM_RES_CTLR_SWAP | ||
619 | default y | ||
620 | help | ||
621 | Memory Resource Controller Swap Extension comes with its price in | ||
622 | a bigger memory consumption. General purpose distribution kernels | ||
623 | which want to enable the feautre but keep it disabled by default | ||
624 | and let the user enable it by swapaccount boot command line | ||
625 | parameter should have this option unselected. | ||
626 | For those who want to have the feature enabled by default should | ||
627 | select this option (if, for some reason, they need to disable it | ||
628 | then noswapaccount does the trick). | ||
616 | 629 | ||
617 | menuconfig CGROUP_SCHED | 630 | menuconfig CGROUP_SCHED |
618 | bool "Group CPU scheduler" | 631 | bool "Group CPU scheduler" |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 2efa8ea07ff7..7a22b4129211 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -61,7 +61,14 @@ struct mem_cgroup *root_mem_cgroup __read_mostly; | |||
61 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP | 61 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP |
62 | /* Turned on only when memory cgroup is enabled && really_do_swap_account = 1 */ | 62 | /* Turned on only when memory cgroup is enabled && really_do_swap_account = 1 */ |
63 | int do_swap_account __read_mostly; | 63 | int do_swap_account __read_mostly; |
64 | static int really_do_swap_account __initdata = 1; /* for remember boot option*/ | 64 | |
65 | /* for remember boot option*/ | ||
66 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED | ||
67 | static int really_do_swap_account __initdata = 1; | ||
68 | #else | ||
69 | static int really_do_swap_account __initdata = 0; | ||
70 | #endif | ||
71 | |||
65 | #else | 72 | #else |
66 | #define do_swap_account (0) | 73 | #define do_swap_account (0) |
67 | #endif | 74 | #endif |
@@ -278,13 +285,14 @@ enum move_type { | |||
278 | 285 | ||
279 | /* "mc" and its members are protected by cgroup_mutex */ | 286 | /* "mc" and its members are protected by cgroup_mutex */ |
280 | static struct move_charge_struct { | 287 | static struct move_charge_struct { |
281 | spinlock_t lock; /* for from, to, moving_task */ | 288 | spinlock_t lock; /* for from, to */ |
282 | struct mem_cgroup *from; | 289 | struct mem_cgroup *from; |
283 | struct mem_cgroup *to; | 290 | struct mem_cgroup *to; |
284 | unsigned long precharge; | 291 | unsigned long precharge; |
285 | unsigned long moved_charge; | 292 | unsigned long moved_charge; |
286 | unsigned long moved_swap; | 293 | unsigned long moved_swap; |
287 | struct task_struct *moving_task; /* a task moving charges */ | 294 | struct task_struct *moving_task; /* a task moving charges */ |
295 | struct mm_struct *mm; | ||
288 | wait_queue_head_t waitq; /* a waitq for other context */ | 296 | wait_queue_head_t waitq; /* a waitq for other context */ |
289 | } mc = { | 297 | } mc = { |
290 | .lock = __SPIN_LOCK_UNLOCKED(mc.lock), | 298 | .lock = __SPIN_LOCK_UNLOCKED(mc.lock), |
@@ -2152,7 +2160,7 @@ static void __mem_cgroup_move_account(struct page_cgroup *pc, | |||
2152 | { | 2160 | { |
2153 | VM_BUG_ON(from == to); | 2161 | VM_BUG_ON(from == to); |
2154 | VM_BUG_ON(PageLRU(pc->page)); | 2162 | VM_BUG_ON(PageLRU(pc->page)); |
2155 | VM_BUG_ON(!PageCgroupLocked(pc)); | 2163 | VM_BUG_ON(!page_is_cgroup_locked(pc)); |
2156 | VM_BUG_ON(!PageCgroupUsed(pc)); | 2164 | VM_BUG_ON(!PageCgroupUsed(pc)); |
2157 | VM_BUG_ON(pc->mem_cgroup != from); | 2165 | VM_BUG_ON(pc->mem_cgroup != from); |
2158 | 2166 | ||
@@ -4631,7 +4639,7 @@ static unsigned long mem_cgroup_count_precharge(struct mm_struct *mm) | |||
4631 | unsigned long precharge; | 4639 | unsigned long precharge; |
4632 | struct vm_area_struct *vma; | 4640 | struct vm_area_struct *vma; |
4633 | 4641 | ||
4634 | down_read(&mm->mmap_sem); | 4642 | /* We've already held the mmap_sem */ |
4635 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | 4643 | for (vma = mm->mmap; vma; vma = vma->vm_next) { |
4636 | struct mm_walk mem_cgroup_count_precharge_walk = { | 4644 | struct mm_walk mem_cgroup_count_precharge_walk = { |
4637 | .pmd_entry = mem_cgroup_count_precharge_pte_range, | 4645 | .pmd_entry = mem_cgroup_count_precharge_pte_range, |
@@ -4643,7 +4651,6 @@ static unsigned long mem_cgroup_count_precharge(struct mm_struct *mm) | |||
4643 | walk_page_range(vma->vm_start, vma->vm_end, | 4651 | walk_page_range(vma->vm_start, vma->vm_end, |
4644 | &mem_cgroup_count_precharge_walk); | 4652 | &mem_cgroup_count_precharge_walk); |
4645 | } | 4653 | } |
4646 | up_read(&mm->mmap_sem); | ||
4647 | 4654 | ||
4648 | precharge = mc.precharge; | 4655 | precharge = mc.precharge; |
4649 | mc.precharge = 0; | 4656 | mc.precharge = 0; |
@@ -4694,11 +4701,16 @@ static void mem_cgroup_clear_mc(void) | |||
4694 | 4701 | ||
4695 | mc.moved_swap = 0; | 4702 | mc.moved_swap = 0; |
4696 | } | 4703 | } |
4704 | if (mc.mm) { | ||
4705 | up_read(&mc.mm->mmap_sem); | ||
4706 | mmput(mc.mm); | ||
4707 | } | ||
4697 | spin_lock(&mc.lock); | 4708 | spin_lock(&mc.lock); |
4698 | mc.from = NULL; | 4709 | mc.from = NULL; |
4699 | mc.to = NULL; | 4710 | mc.to = NULL; |
4700 | mc.moving_task = NULL; | ||
4701 | spin_unlock(&mc.lock); | 4711 | spin_unlock(&mc.lock); |
4712 | mc.moving_task = NULL; | ||
4713 | mc.mm = NULL; | ||
4702 | mem_cgroup_end_move(from); | 4714 | mem_cgroup_end_move(from); |
4703 | memcg_oom_recover(from); | 4715 | memcg_oom_recover(from); |
4704 | memcg_oom_recover(to); | 4716 | memcg_oom_recover(to); |
@@ -4724,12 +4736,21 @@ static int mem_cgroup_can_attach(struct cgroup_subsys *ss, | |||
4724 | return 0; | 4736 | return 0; |
4725 | /* We move charges only when we move a owner of the mm */ | 4737 | /* We move charges only when we move a owner of the mm */ |
4726 | if (mm->owner == p) { | 4738 | if (mm->owner == p) { |
4739 | /* | ||
4740 | * We do all the move charge works under one mmap_sem to | ||
4741 | * avoid deadlock with down_write(&mmap_sem) | ||
4742 | * -> try_charge() -> if (mc.moving_task) -> sleep. | ||
4743 | */ | ||
4744 | down_read(&mm->mmap_sem); | ||
4745 | |||
4727 | VM_BUG_ON(mc.from); | 4746 | VM_BUG_ON(mc.from); |
4728 | VM_BUG_ON(mc.to); | 4747 | VM_BUG_ON(mc.to); |
4729 | VM_BUG_ON(mc.precharge); | 4748 | VM_BUG_ON(mc.precharge); |
4730 | VM_BUG_ON(mc.moved_charge); | 4749 | VM_BUG_ON(mc.moved_charge); |
4731 | VM_BUG_ON(mc.moved_swap); | 4750 | VM_BUG_ON(mc.moved_swap); |
4732 | VM_BUG_ON(mc.moving_task); | 4751 | VM_BUG_ON(mc.moving_task); |
4752 | VM_BUG_ON(mc.mm); | ||
4753 | |||
4733 | mem_cgroup_start_move(from); | 4754 | mem_cgroup_start_move(from); |
4734 | spin_lock(&mc.lock); | 4755 | spin_lock(&mc.lock); |
4735 | mc.from = from; | 4756 | mc.from = from; |
@@ -4737,14 +4758,16 @@ static int mem_cgroup_can_attach(struct cgroup_subsys *ss, | |||
4737 | mc.precharge = 0; | 4758 | mc.precharge = 0; |
4738 | mc.moved_charge = 0; | 4759 | mc.moved_charge = 0; |
4739 | mc.moved_swap = 0; | 4760 | mc.moved_swap = 0; |
4740 | mc.moving_task = current; | ||
4741 | spin_unlock(&mc.lock); | 4761 | spin_unlock(&mc.lock); |
4762 | mc.moving_task = current; | ||
4763 | mc.mm = mm; | ||
4742 | 4764 | ||
4743 | ret = mem_cgroup_precharge_mc(mm); | 4765 | ret = mem_cgroup_precharge_mc(mm); |
4744 | if (ret) | 4766 | if (ret) |
4745 | mem_cgroup_clear_mc(); | 4767 | mem_cgroup_clear_mc(); |
4746 | } | 4768 | /* We call up_read() and mmput() in clear_mc(). */ |
4747 | mmput(mm); | 4769 | } else |
4770 | mmput(mm); | ||
4748 | } | 4771 | } |
4749 | return ret; | 4772 | return ret; |
4750 | } | 4773 | } |
@@ -4832,7 +4855,7 @@ static void mem_cgroup_move_charge(struct mm_struct *mm) | |||
4832 | struct vm_area_struct *vma; | 4855 | struct vm_area_struct *vma; |
4833 | 4856 | ||
4834 | lru_add_drain_all(); | 4857 | lru_add_drain_all(); |
4835 | down_read(&mm->mmap_sem); | 4858 | /* We've already held the mmap_sem */ |
4836 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | 4859 | for (vma = mm->mmap; vma; vma = vma->vm_next) { |
4837 | int ret; | 4860 | int ret; |
4838 | struct mm_walk mem_cgroup_move_charge_walk = { | 4861 | struct mm_walk mem_cgroup_move_charge_walk = { |
@@ -4851,7 +4874,6 @@ static void mem_cgroup_move_charge(struct mm_struct *mm) | |||
4851 | */ | 4874 | */ |
4852 | break; | 4875 | break; |
4853 | } | 4876 | } |
4854 | up_read(&mm->mmap_sem); | ||
4855 | } | 4877 | } |
4856 | 4878 | ||
4857 | static void mem_cgroup_move_task(struct cgroup_subsys *ss, | 4879 | static void mem_cgroup_move_task(struct cgroup_subsys *ss, |
@@ -4860,17 +4882,11 @@ static void mem_cgroup_move_task(struct cgroup_subsys *ss, | |||
4860 | struct task_struct *p, | 4882 | struct task_struct *p, |
4861 | bool threadgroup) | 4883 | bool threadgroup) |
4862 | { | 4884 | { |
4863 | struct mm_struct *mm; | 4885 | if (!mc.mm) |
4864 | |||
4865 | if (!mc.to) | ||
4866 | /* no need to move charge */ | 4886 | /* no need to move charge */ |
4867 | return; | 4887 | return; |
4868 | 4888 | ||
4869 | mm = get_task_mm(p); | 4889 | mem_cgroup_move_charge(mc.mm); |
4870 | if (mm) { | ||
4871 | mem_cgroup_move_charge(mm); | ||
4872 | mmput(mm); | ||
4873 | } | ||
4874 | mem_cgroup_clear_mc(); | 4890 | mem_cgroup_clear_mc(); |
4875 | } | 4891 | } |
4876 | #else /* !CONFIG_MMU */ | 4892 | #else /* !CONFIG_MMU */ |
@@ -4911,10 +4927,20 @@ struct cgroup_subsys mem_cgroup_subsys = { | |||
4911 | }; | 4927 | }; |
4912 | 4928 | ||
4913 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP | 4929 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP |
4930 | static int __init enable_swap_account(char *s) | ||
4931 | { | ||
4932 | /* consider enabled if no parameter or 1 is given */ | ||
4933 | if (!s || !strcmp(s, "1")) | ||
4934 | really_do_swap_account = 1; | ||
4935 | else if (!strcmp(s, "0")) | ||
4936 | really_do_swap_account = 0; | ||
4937 | return 1; | ||
4938 | } | ||
4939 | __setup("swapaccount", enable_swap_account); | ||
4914 | 4940 | ||
4915 | static int __init disable_swap_account(char *s) | 4941 | static int __init disable_swap_account(char *s) |
4916 | { | 4942 | { |
4917 | really_do_swap_account = 0; | 4943 | enable_swap_account("0"); |
4918 | return 1; | 4944 | return 1; |
4919 | } | 4945 | } |
4920 | __setup("noswapaccount", disable_swap_account); | 4946 | __setup("noswapaccount", disable_swap_account); |
diff --git a/mm/nommu.c b/mm/nommu.c index 3613517c7592..27a9ac588516 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -1717,6 +1717,7 @@ void exit_mmap(struct mm_struct *mm) | |||
1717 | mm->mmap = vma->vm_next; | 1717 | mm->mmap = vma->vm_next; |
1718 | delete_vma_from_mm(vma); | 1718 | delete_vma_from_mm(vma); |
1719 | delete_vma(mm, vma); | 1719 | delete_vma(mm, vma); |
1720 | cond_resched(); | ||
1720 | } | 1721 | } |
1721 | 1722 | ||
1722 | kleave(""); | 1723 | kleave(""); |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 07a654486f75..e4092704c1a9 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -3008,14 +3008,6 @@ static __init_refok int __build_all_zonelists(void *data) | |||
3008 | build_zonelist_cache(pgdat); | 3008 | build_zonelist_cache(pgdat); |
3009 | } | 3009 | } |
3010 | 3010 | ||
3011 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
3012 | /* Setup real pagesets for the new zone */ | ||
3013 | if (data) { | ||
3014 | struct zone *zone = data; | ||
3015 | setup_zone_pageset(zone); | ||
3016 | } | ||
3017 | #endif | ||
3018 | |||
3019 | /* | 3011 | /* |
3020 | * Initialize the boot_pagesets that are going to be used | 3012 | * Initialize the boot_pagesets that are going to be used |
3021 | * for bootstrapping processors. The real pagesets for | 3013 | * for bootstrapping processors. The real pagesets for |
@@ -3064,7 +3056,11 @@ void build_all_zonelists(void *data) | |||
3064 | } else { | 3056 | } else { |
3065 | /* we have to stop all cpus to guarantee there is no user | 3057 | /* we have to stop all cpus to guarantee there is no user |
3066 | of zonelist */ | 3058 | of zonelist */ |
3067 | stop_machine(__build_all_zonelists, data, NULL); | 3059 | #ifdef CONFIG_MEMORY_HOTPLUG |
3060 | if (data) | ||
3061 | setup_zone_pageset((struct zone *)data); | ||
3062 | #endif | ||
3063 | stop_machine(__build_all_zonelists, NULL, NULL); | ||
3068 | /* cpuset refresh routine should be here */ | 3064 | /* cpuset refresh routine should be here */ |
3069 | } | 3065 | } |
3070 | vm_total_pages = nr_free_pagecache_pages(); | 3066 | vm_total_pages = nr_free_pagecache_pages(); |
diff --git a/mm/pagewalk.c b/mm/pagewalk.c index 8b1a2ce21ee5..38cc58b8b2b0 100644 --- a/mm/pagewalk.c +++ b/mm/pagewalk.c | |||
@@ -139,7 +139,6 @@ int walk_page_range(unsigned long addr, unsigned long end, | |||
139 | pgd_t *pgd; | 139 | pgd_t *pgd; |
140 | unsigned long next; | 140 | unsigned long next; |
141 | int err = 0; | 141 | int err = 0; |
142 | struct vm_area_struct *vma; | ||
143 | 142 | ||
144 | if (addr >= end) | 143 | if (addr >= end) |
145 | return err; | 144 | return err; |
@@ -149,15 +148,17 @@ int walk_page_range(unsigned long addr, unsigned long end, | |||
149 | 148 | ||
150 | pgd = pgd_offset(walk->mm, addr); | 149 | pgd = pgd_offset(walk->mm, addr); |
151 | do { | 150 | do { |
151 | struct vm_area_struct *uninitialized_var(vma); | ||
152 | |||
152 | next = pgd_addr_end(addr, end); | 153 | next = pgd_addr_end(addr, end); |
153 | 154 | ||
155 | #ifdef CONFIG_HUGETLB_PAGE | ||
154 | /* | 156 | /* |
155 | * handle hugetlb vma individually because pagetable walk for | 157 | * handle hugetlb vma individually because pagetable walk for |
156 | * the hugetlb page is dependent on the architecture and | 158 | * the hugetlb page is dependent on the architecture and |
157 | * we can't handled it in the same manner as non-huge pages. | 159 | * we can't handled it in the same manner as non-huge pages. |
158 | */ | 160 | */ |
159 | vma = find_vma(walk->mm, addr); | 161 | vma = find_vma(walk->mm, addr); |
160 | #ifdef CONFIG_HUGETLB_PAGE | ||
161 | if (vma && is_vm_hugetlb_page(vma)) { | 162 | if (vma && is_vm_hugetlb_page(vma)) { |
162 | if (vma->vm_end < next) | 163 | if (vma->vm_end < next) |
163 | next = vma->vm_end; | 164 | next = vma->vm_end; |
diff --git a/scripts/gfp-translate b/scripts/gfp-translate index d81b968d864e..c9230e158a8f 100644 --- a/scripts/gfp-translate +++ b/scripts/gfp-translate | |||
@@ -63,7 +63,12 @@ fi | |||
63 | 63 | ||
64 | # Extract GFP flags from the kernel source | 64 | # Extract GFP flags from the kernel source |
65 | TMPFILE=`mktemp -t gfptranslate-XXXXXX` || exit 1 | 65 | TMPFILE=`mktemp -t gfptranslate-XXXXXX` || exit 1 |
66 | grep "^#define __GFP" $SOURCE/include/linux/gfp.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE | 66 | grep -q ___GFP $SOURCE/include/linux/gfp.h |
67 | if [ $? -eq 0 ]; then | ||
68 | grep "^#define ___GFP" $SOURCE/include/linux/gfp.h | sed -e 's/u$//' | grep -v GFP_BITS > $TMPFILE | ||
69 | else | ||
70 | grep "^#define __GFP" $SOURCE/include/linux/gfp.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE | ||
71 | fi | ||
67 | 72 | ||
68 | # Parse the flags | 73 | # Parse the flags |
69 | IFS=" | 74 | IFS=" |