diff options
-rw-r--r-- | arch/powerpc/Kconfig | 16 | ||||
-rw-r--r-- | arch/powerpc/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/Makefile | 3 | ||||
-rw-r--r-- | arch/powerpc/sysdev/dcr-low.S | 39 | ||||
-rw-r--r-- | arch/powerpc/sysdev/dcr.c | 137 | ||||
-rw-r--r-- | arch/ppc/Kconfig | 11 | ||||
-rw-r--r-- | include/asm-powerpc/dcr-mmio.h | 51 | ||||
-rw-r--r-- | include/asm-powerpc/dcr-native.h | 39 | ||||
-rw-r--r-- | include/asm-powerpc/dcr.h | 42 |
9 files changed, 337 insertions, 2 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 96316c866107..0e564d30fc46 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -160,9 +160,11 @@ config PPC_86xx | |||
160 | 160 | ||
161 | config 40x | 161 | config 40x |
162 | bool "AMCC 40x" | 162 | bool "AMCC 40x" |
163 | select PPC_DCR_NATIVE | ||
163 | 164 | ||
164 | config 44x | 165 | config 44x |
165 | bool "AMCC 44x" | 166 | bool "AMCC 44x" |
167 | select PPC_DCR_NATIVE | ||
166 | 168 | ||
167 | config 8xx | 169 | config 8xx |
168 | bool "Freescale 8xx" | 170 | bool "Freescale 8xx" |
@@ -208,6 +210,19 @@ config PPC_FPU | |||
208 | bool | 210 | bool |
209 | default y if PPC64 | 211 | default y if PPC64 |
210 | 212 | ||
213 | config PPC_DCR_NATIVE | ||
214 | bool | ||
215 | default n | ||
216 | |||
217 | config PPC_DCR_MMIO | ||
218 | bool | ||
219 | default n | ||
220 | |||
221 | config PPC_DCR | ||
222 | bool | ||
223 | depends on PPC_DCR_NATIVE || PPC_DCR_MMIO | ||
224 | default y | ||
225 | |||
211 | config BOOKE | 226 | config BOOKE |
212 | bool | 227 | bool |
213 | depends on E200 || E500 | 228 | depends on E200 || E500 |
@@ -453,6 +468,7 @@ config PPC_CELL | |||
453 | config PPC_CELL_NATIVE | 468 | config PPC_CELL_NATIVE |
454 | bool | 469 | bool |
455 | select PPC_CELL | 470 | select PPC_CELL |
471 | select PPC_DCR_MMIO | ||
456 | default n | 472 | default n |
457 | 473 | ||
458 | config PPC_IBM_CELL_BLADE | 474 | config PPC_IBM_CELL_BLADE |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index d8240ce22120..f34d158b9628 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -58,6 +58,7 @@ obj-$(CONFIG_BOOTX_TEXT) += btext.o | |||
58 | obj-$(CONFIG_SMP) += smp.o | 58 | obj-$(CONFIG_SMP) += smp.o |
59 | obj-$(CONFIG_KPROBES) += kprobes.o | 59 | obj-$(CONFIG_KPROBES) += kprobes.o |
60 | obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o | 60 | obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o |
61 | |||
61 | module-$(CONFIG_PPC64) += module_64.o | 62 | module-$(CONFIG_PPC64) += module_64.o |
62 | obj-$(CONFIG_MODULES) += $(module-y) | 63 | obj-$(CONFIG_MODULES) += $(module-y) |
63 | 64 | ||
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 5b87f7b42a1f..8ba11ab5e614 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
@@ -5,8 +5,7 @@ endif | |||
5 | obj-$(CONFIG_MPIC) += mpic.o | 5 | obj-$(CONFIG_MPIC) += mpic.o |
6 | obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o | 6 | obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o |
7 | obj-$(CONFIG_PPC_MPC106) += grackle.o | 7 | obj-$(CONFIG_PPC_MPC106) += grackle.o |
8 | obj-$(CONFIG_BOOKE) += dcr.o | 8 | obj-$(CONFIG_PPC_DCR) += dcr.o dcr-low.o |
9 | obj-$(CONFIG_40x) += dcr.o | ||
10 | obj-$(CONFIG_U3_DART) += dart_iommu.o | 9 | obj-$(CONFIG_U3_DART) += dart_iommu.o |
11 | obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o | 10 | obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o |
12 | obj-$(CONFIG_FSL_SOC) += fsl_soc.o | 11 | obj-$(CONFIG_FSL_SOC) += fsl_soc.o |
diff --git a/arch/powerpc/sysdev/dcr-low.S b/arch/powerpc/sysdev/dcr-low.S new file mode 100644 index 000000000000..2078f39e2f17 --- /dev/null +++ b/arch/powerpc/sysdev/dcr-low.S | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * "Indirect" DCR access | ||
3 | * | ||
4 | * Copyright (c) 2004 Eugene Surovegin <ebs@ebshome.net> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <asm/ppc_asm.h> | ||
13 | #include <asm/processor.h> | ||
14 | |||
15 | #define DCR_ACCESS_PROLOG(table) \ | ||
16 | rlwinm r3,r3,4,18,27; \ | ||
17 | lis r5,table@h; \ | ||
18 | ori r5,r5,table@l; \ | ||
19 | add r3,r3,r5; \ | ||
20 | mtctr r3; \ | ||
21 | bctr | ||
22 | |||
23 | _GLOBAL(__mfdcr) | ||
24 | DCR_ACCESS_PROLOG(__mfdcr_table) | ||
25 | |||
26 | _GLOBAL(__mtdcr) | ||
27 | DCR_ACCESS_PROLOG(__mtdcr_table) | ||
28 | |||
29 | __mfdcr_table: | ||
30 | mfdcr r3,0; blr | ||
31 | __mtdcr_table: | ||
32 | mtdcr 0,r4; blr | ||
33 | |||
34 | dcr = 1 | ||
35 | .rept 1023 | ||
36 | mfdcr r3,dcr; blr | ||
37 | mtdcr dcr,r4; blr | ||
38 | dcr = dcr + 1 | ||
39 | .endr | ||
diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c new file mode 100644 index 000000000000..dffeeaeca1d9 --- /dev/null +++ b/arch/powerpc/sysdev/dcr.c | |||
@@ -0,0 +1,137 @@ | |||
1 | /* | ||
2 | * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp. | ||
3 | * <benh@kernel.crashing.org> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
13 | * the GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
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 | ||
18 | */ | ||
19 | |||
20 | #undef DEBUG | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <asm/prom.h> | ||
24 | #include <asm/dcr.h> | ||
25 | |||
26 | unsigned int dcr_resource_start(struct device_node *np, unsigned int index) | ||
27 | { | ||
28 | unsigned int ds; | ||
29 | const u32 *dr = get_property(np, "dcr-reg", &ds); | ||
30 | |||
31 | if (dr == NULL || ds & 1 || index >= (ds / 8)) | ||
32 | return 0; | ||
33 | |||
34 | return dr[index * 2]; | ||
35 | } | ||
36 | |||
37 | unsigned int dcr_resource_len(struct device_node *np, unsigned int index) | ||
38 | { | ||
39 | unsigned int ds; | ||
40 | const u32 *dr = get_property(np, "dcr-reg", &ds); | ||
41 | |||
42 | if (dr == NULL || ds & 1 || index >= (ds / 8)) | ||
43 | return 0; | ||
44 | |||
45 | return dr[index * 2 + 1]; | ||
46 | } | ||
47 | |||
48 | #ifndef CONFIG_PPC_DCR_NATIVE | ||
49 | |||
50 | static struct device_node * find_dcr_parent(struct device_node * node) | ||
51 | { | ||
52 | struct device_node *par, *tmp; | ||
53 | const u32 *p; | ||
54 | |||
55 | for (par = of_node_get(node); par;) { | ||
56 | if (get_property(par, "dcr-controller", NULL)) | ||
57 | break; | ||
58 | p = get_property(par, "dcr-parent", NULL); | ||
59 | tmp = par; | ||
60 | if (p == NULL) | ||
61 | par = of_get_parent(par); | ||
62 | else | ||
63 | par = of_find_node_by_phandle(*p); | ||
64 | of_node_put(tmp); | ||
65 | } | ||
66 | return par; | ||
67 | } | ||
68 | |||
69 | u64 of_translate_dcr_address(struct device_node *dev, | ||
70 | unsigned int dcr_n, | ||
71 | unsigned int *out_stride) | ||
72 | { | ||
73 | struct device_node *dp; | ||
74 | const u32 *p; | ||
75 | unsigned int stride; | ||
76 | u64 ret; | ||
77 | |||
78 | dp = find_dcr_parent(dev); | ||
79 | if (dp == NULL) | ||
80 | return OF_BAD_ADDR; | ||
81 | |||
82 | /* Stride is not properly defined yet, default to 0x10 for Axon */ | ||
83 | p = get_property(dp, "dcr-mmio-stride", NULL); | ||
84 | stride = (p == NULL) ? 0x10 : *p; | ||
85 | |||
86 | /* XXX FIXME: Which property name is to use of the 2 following ? */ | ||
87 | p = get_property(dp, "dcr-mmio-range", NULL); | ||
88 | if (p == NULL) | ||
89 | p = get_property(dp, "dcr-mmio-space", NULL); | ||
90 | if (p == NULL) | ||
91 | return OF_BAD_ADDR; | ||
92 | |||
93 | /* Maybe could do some better range checking here */ | ||
94 | ret = of_translate_address(dp, p); | ||
95 | if (ret != OF_BAD_ADDR) | ||
96 | ret += (u64)(stride) * (u64)dcr_n; | ||
97 | if (out_stride) | ||
98 | *out_stride = stride; | ||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n, | ||
103 | unsigned int dcr_c) | ||
104 | { | ||
105 | dcr_host_t ret = { .token = NULL, .stride = 0 }; | ||
106 | u64 addr; | ||
107 | |||
108 | pr_debug("dcr_map(%s, 0x%x, 0x%x)\n", | ||
109 | dev->full_name, dcr_n, dcr_c); | ||
110 | |||
111 | addr = of_translate_dcr_address(dev, dcr_n, &ret.stride); | ||
112 | pr_debug("translates to addr: 0x%lx, stride: 0x%x\n", | ||
113 | addr, ret.stride); | ||
114 | if (addr == OF_BAD_ADDR) | ||
115 | return ret; | ||
116 | pr_debug("mapping 0x%x bytes\n", dcr_c * ret.stride); | ||
117 | ret.token = ioremap(addr, dcr_c * ret.stride); | ||
118 | if (ret.token == NULL) | ||
119 | return ret; | ||
120 | pr_debug("mapped at 0x%p -> base is 0x%p\n", | ||
121 | ret.token, ret.token - dcr_n * ret.stride); | ||
122 | ret.token -= dcr_n * ret.stride; | ||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c) | ||
127 | { | ||
128 | dcr_host_t h = host; | ||
129 | |||
130 | if (h.token == NULL) | ||
131 | return; | ||
132 | h.token -= dcr_n * h.stride; | ||
133 | iounmap(h.token); | ||
134 | h.token = NULL; | ||
135 | } | ||
136 | |||
137 | #endif /* !defined(CONFIG_PPC_DCR_NATIVE) */ | ||
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index ef018e25fb07..edf71a4ecc95 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig | |||
@@ -77,9 +77,11 @@ config 6xx | |||
77 | 77 | ||
78 | config 40x | 78 | config 40x |
79 | bool "40x" | 79 | bool "40x" |
80 | select PPC_DCR_NATIVE | ||
80 | 81 | ||
81 | config 44x | 82 | config 44x |
82 | bool "44x" | 83 | bool "44x" |
84 | select PPC_DCR_NATIVE | ||
83 | 85 | ||
84 | config 8xx | 86 | config 8xx |
85 | bool "8xx" | 87 | bool "8xx" |
@@ -95,6 +97,15 @@ endchoice | |||
95 | config PPC_FPU | 97 | config PPC_FPU |
96 | bool | 98 | bool |
97 | 99 | ||
100 | config PPC_DCR_NATIVE | ||
101 | bool | ||
102 | default n | ||
103 | |||
104 | config PPC_DCR | ||
105 | bool | ||
106 | depends on PPC_DCR_NATIVE | ||
107 | default y | ||
108 | |||
98 | config BOOKE | 109 | config BOOKE |
99 | bool | 110 | bool |
100 | depends on E200 || E500 | 111 | depends on E200 || E500 |
diff --git a/include/asm-powerpc/dcr-mmio.h b/include/asm-powerpc/dcr-mmio.h new file mode 100644 index 000000000000..5dbfca8dde36 --- /dev/null +++ b/include/asm-powerpc/dcr-mmio.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp. | ||
3 | * <benh@kernel.crashing.org> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
13 | * the GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
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 | ||
18 | */ | ||
19 | |||
20 | #ifndef _ASM_POWERPC_DCR_MMIO_H | ||
21 | #define _ASM_POWERPC_DCR_MMIO_H | ||
22 | #ifdef __KERNEL__ | ||
23 | |||
24 | #include <asm/io.h> | ||
25 | |||
26 | typedef struct { void __iomem *token; unsigned int stride; } dcr_host_t; | ||
27 | |||
28 | #define DCR_MAP_OK(host) ((host).token != NULL) | ||
29 | |||
30 | extern dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n, | ||
31 | unsigned int dcr_c); | ||
32 | extern void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c); | ||
33 | |||
34 | static inline u32 dcr_read(dcr_host_t host, unsigned int dcr_n) | ||
35 | { | ||
36 | return in_be32(host.token + dcr_n * host.stride); | ||
37 | } | ||
38 | |||
39 | static inline void dcr_write(dcr_host_t host, unsigned int dcr_n, u32 value) | ||
40 | { | ||
41 | out_be32(host.token + dcr_n * host.stride, value); | ||
42 | } | ||
43 | |||
44 | extern u64 of_translate_dcr_address(struct device_node *dev, | ||
45 | unsigned int dcr_n, | ||
46 | unsigned int *stride); | ||
47 | |||
48 | #endif /* __KERNEL__ */ | ||
49 | #endif /* _ASM_POWERPC_DCR_MMIO_H */ | ||
50 | |||
51 | |||
diff --git a/include/asm-powerpc/dcr-native.h b/include/asm-powerpc/dcr-native.h new file mode 100644 index 000000000000..fd4a5f5e33d1 --- /dev/null +++ b/include/asm-powerpc/dcr-native.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp. | ||
3 | * <benh@kernel.crashing.org> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
13 | * the GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
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 | ||
18 | */ | ||
19 | |||
20 | #ifndef _ASM_POWERPC_DCR_NATIVE_H | ||
21 | #define _ASM_POWERPC_DCR_NATIVE_H | ||
22 | #ifdef __KERNEL__ | ||
23 | |||
24 | #include <asm/reg.h> | ||
25 | |||
26 | typedef struct {} dcr_host_t; | ||
27 | |||
28 | #define DCR_MAP_OK(host) (1) | ||
29 | |||
30 | #define dcr_map(dev, dcr_n, dcr_c) {} | ||
31 | #define dcr_unmap(host, dcr_n, dcr_c) {} | ||
32 | #define dcr_read(host, dcr_n) mfdcr(dcr_n) | ||
33 | #define dcr_write(host, dcr_n, value) mtdcr(dcr_n, value) | ||
34 | |||
35 | |||
36 | #endif /* __KERNEL__ */ | ||
37 | #endif /* _ASM_POWERPC_DCR_NATIVE_H */ | ||
38 | |||
39 | |||
diff --git a/include/asm-powerpc/dcr.h b/include/asm-powerpc/dcr.h new file mode 100644 index 000000000000..473f2c7fd892 --- /dev/null +++ b/include/asm-powerpc/dcr.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp. | ||
3 | * <benh@kernel.crashing.org> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
13 | * the GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
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 | ||
18 | */ | ||
19 | |||
20 | #ifndef _ASM_POWERPC_DCR_H | ||
21 | #define _ASM_POWERPC_DCR_H | ||
22 | #ifdef __KERNEL__ | ||
23 | |||
24 | #ifdef CONFIG_PPC_DCR_NATIVE | ||
25 | #include <asm/dcr-native.h> | ||
26 | #else | ||
27 | #include <asm/dcr-mmio.h> | ||
28 | #endif | ||
29 | |||
30 | /* | ||
31 | * On CONFIG_PPC_MERGE, we have additional helpers to read the DCR | ||
32 | * base from the device-tree | ||
33 | */ | ||
34 | #ifdef CONFIG_PPC_MERGE | ||
35 | extern unsigned int dcr_resource_start(struct device_node *np, | ||
36 | unsigned int index); | ||
37 | extern unsigned int dcr_resource_len(struct device_node *np, | ||
38 | unsigned int index); | ||
39 | #endif /* CONFIG_PPC_MERGE */ | ||
40 | |||
41 | #endif /* __KERNEL__ */ | ||
42 | #endif /* _ASM_POWERPC_DCR_H */ | ||