diff options
-rw-r--r-- | Documentation/powerpc/booting-without-of.txt | 40 | ||||
-rw-r--r-- | arch/powerpc/Kconfig.debug | 6 | ||||
-rw-r--r-- | arch/powerpc/boot/cpm-serial.c | 44 | ||||
-rw-r--r-- | arch/powerpc/boot/dts/ep88xc.dts | 13 | ||||
-rw-r--r-- | arch/powerpc/boot/dts/mpc8272ads.dts | 11 | ||||
-rw-r--r-- | arch/powerpc/boot/dts/mpc885ads.dts | 13 | ||||
-rw-r--r-- | arch/powerpc/boot/dts/pq2fads.dts | 13 | ||||
-rw-r--r-- | arch/powerpc/sysdev/commproc.c | 11 | ||||
-rw-r--r-- | arch/powerpc/sysdev/cpm2_common.c | 35 | ||||
-rw-r--r-- | arch/powerpc/sysdev/cpm_common.c | 159 | ||||
-rw-r--r-- | drivers/serial/cpm_uart/cpm_uart_cpm2.c | 4 | ||||
-rw-r--r-- | include/asm-powerpc/commproc.h | 12 | ||||
-rw-r--r-- | include/asm-powerpc/cpm.h | 14 | ||||
-rw-r--r-- | include/asm-powerpc/cpm2.h | 10 |
14 files changed, 337 insertions, 48 deletions
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index c36dcd2fbdc4..ce5d67f5cb5c 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt | |||
@@ -1861,9 +1861,7 @@ platforms are moved over to use the flattened-device-tree model. | |||
1861 | 1861 | ||
1862 | Properties: | 1862 | Properties: |
1863 | - compatible : "fsl,cpm1", "fsl,cpm2", or "fsl,qe". | 1863 | - compatible : "fsl,cpm1", "fsl,cpm2", or "fsl,qe". |
1864 | - reg : The first resource is a 48-byte region beginning with | 1864 | - reg : A 48-byte region beginning with CPCR. |
1865 | CPCR. The second is the available general-purpose | ||
1866 | DPRAM. | ||
1867 | 1865 | ||
1868 | Example: | 1866 | Example: |
1869 | cpm@119c0 { | 1867 | cpm@119c0 { |
@@ -1871,7 +1869,7 @@ platforms are moved over to use the flattened-device-tree model. | |||
1871 | #size-cells = <1>; | 1869 | #size-cells = <1>; |
1872 | #interrupt-cells = <2>; | 1870 | #interrupt-cells = <2>; |
1873 | compatible = "fsl,mpc8272-cpm", "fsl,cpm2"; | 1871 | compatible = "fsl,mpc8272-cpm", "fsl,cpm2"; |
1874 | reg = <119c0 30 0 2000>; | 1872 | reg = <119c0 30>; |
1875 | } | 1873 | } |
1876 | 1874 | ||
1877 | ii) Properties common to mulitple CPM/QE devices | 1875 | ii) Properties common to mulitple CPM/QE devices |
@@ -2017,6 +2015,40 @@ platforms are moved over to use the flattened-device-tree model. | |||
2017 | fsl,cpm-command = <2e600000>; | 2015 | fsl,cpm-command = <2e600000>; |
2018 | }; | 2016 | }; |
2019 | 2017 | ||
2018 | viii) Multi-User RAM (MURAM) | ||
2019 | |||
2020 | The multi-user/dual-ported RAM is expressed as a bus under the CPM node. | ||
2021 | |||
2022 | Ranges must be set up subject to the following restrictions: | ||
2023 | |||
2024 | - Children's reg nodes must be offsets from the start of all muram, even | ||
2025 | if the user-data area does not begin at zero. | ||
2026 | - If multiple range entries are used, the difference between the parent | ||
2027 | address and the child address must be the same in all, so that a single | ||
2028 | mapping can cover them all while maintaining the ability to determine | ||
2029 | CPM-side offsets with pointer subtraction. It is recommended that | ||
2030 | multiple range entries not be used. | ||
2031 | - A child address of zero must be translatable, even if no reg resources | ||
2032 | contain it. | ||
2033 | |||
2034 | A child "data" node must exist, compatible with "fsl,cpm-muram-data", to | ||
2035 | indicate the portion of muram that is usable by the OS for arbitrary | ||
2036 | purposes. The data node may have an arbitrary number of reg resources, | ||
2037 | all of which contribute to the allocatable muram pool. | ||
2038 | |||
2039 | Example, based on mpc8272: | ||
2040 | |||
2041 | muram@0 { | ||
2042 | #address-cells = <1>; | ||
2043 | #size-cells = <1>; | ||
2044 | ranges = <0 0 10000>; | ||
2045 | |||
2046 | data@0 { | ||
2047 | compatible = "fsl,cpm-muram-data"; | ||
2048 | reg = <0 2000 9800 800>; | ||
2049 | }; | ||
2050 | }; | ||
2051 | |||
2020 | m) Chipselect/Local Bus | 2052 | m) Chipselect/Local Bus |
2021 | 2053 | ||
2022 | Properties: | 2054 | Properties: |
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index f4e5d22312a0..464f9b4b3169 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug | |||
@@ -245,9 +245,9 @@ config PPC_EARLY_DEBUG_44x_PHYSHIGH | |||
245 | config PPC_EARLY_DEBUG_CPM_ADDR | 245 | config PPC_EARLY_DEBUG_CPM_ADDR |
246 | hex "CPM UART early debug transmit descriptor address" | 246 | hex "CPM UART early debug transmit descriptor address" |
247 | depends on PPC_EARLY_DEBUG_CPM | 247 | depends on PPC_EARLY_DEBUG_CPM |
248 | default "0xfa202808" if PPC_EP88XC | 248 | default "0xfa202008" if PPC_EP88XC |
249 | default "0xf0000808" if CPM2 | 249 | default "0xf0000008" if CPM2 |
250 | default "0xff002808" if CPM1 | 250 | default "0xff002008" if CPM1 |
251 | help | 251 | help |
252 | This specifies the address of the transmit descriptor | 252 | This specifies the address of the transmit descriptor |
253 | used for early debug output. Because it is needed before | 253 | used for early debug output. Because it is needed before |
diff --git a/arch/powerpc/boot/cpm-serial.c b/arch/powerpc/boot/cpm-serial.c index fcb8b5e956bd..28296facb2ae 100644 --- a/arch/powerpc/boot/cpm-serial.c +++ b/arch/powerpc/boot/cpm-serial.c | |||
@@ -56,7 +56,8 @@ static struct cpm_smc *smc; | |||
56 | static struct cpm_scc *scc; | 56 | static struct cpm_scc *scc; |
57 | struct cpm_bd *tbdf, *rbdf; | 57 | struct cpm_bd *tbdf, *rbdf; |
58 | static u32 cpm_cmd; | 58 | static u32 cpm_cmd; |
59 | static u8 *dpram_start; | 59 | static u8 *muram_start; |
60 | static u32 muram_offset; | ||
60 | 61 | ||
61 | static void (*do_cmd)(int op); | 62 | static void (*do_cmd)(int op); |
62 | static void (*enable_port)(void); | 63 | static void (*enable_port)(void); |
@@ -114,13 +115,12 @@ static void scc_enable_port(void) | |||
114 | 115 | ||
115 | static int cpm_serial_open(void) | 116 | static int cpm_serial_open(void) |
116 | { | 117 | { |
117 | int dpaddr = 0x800; | ||
118 | disable_port(); | 118 | disable_port(); |
119 | 119 | ||
120 | out_8(¶m->rfcr, 0x10); | 120 | out_8(¶m->rfcr, 0x10); |
121 | out_8(¶m->tfcr, 0x10); | 121 | out_8(¶m->tfcr, 0x10); |
122 | 122 | ||
123 | rbdf = (struct cpm_bd *)(dpram_start + dpaddr); | 123 | rbdf = (struct cpm_bd *)muram_start; |
124 | rbdf->addr = (u8 *)(rbdf + 2); | 124 | rbdf->addr = (u8 *)(rbdf + 2); |
125 | rbdf->sc = 0xa000; | 125 | rbdf->sc = 0xa000; |
126 | rbdf->len = 1; | 126 | rbdf->len = 1; |
@@ -131,8 +131,8 @@ static int cpm_serial_open(void) | |||
131 | tbdf->len = 1; | 131 | tbdf->len = 1; |
132 | 132 | ||
133 | sync(); | 133 | sync(); |
134 | out_be16(¶m->rbase, dpaddr); | 134 | out_be16(¶m->rbase, muram_offset); |
135 | out_be16(¶m->tbase, dpaddr + sizeof(struct cpm_bd)); | 135 | out_be16(¶m->tbase, muram_offset + sizeof(struct cpm_bd)); |
136 | 136 | ||
137 | do_cmd(CPM_CMD_INIT_RX_TX); | 137 | do_cmd(CPM_CMD_INIT_RX_TX); |
138 | 138 | ||
@@ -178,7 +178,7 @@ int cpm_console_init(void *devp, struct serial_console_data *scdp) | |||
178 | void *reg_virt[2]; | 178 | void *reg_virt[2]; |
179 | int is_smc = 0, is_cpm2 = 0, n; | 179 | int is_smc = 0, is_cpm2 = 0, n; |
180 | unsigned long reg_phys; | 180 | unsigned long reg_phys; |
181 | void *parent; | 181 | void *parent, *muram; |
182 | 182 | ||
183 | if (dt_is_compatible(devp, "fsl,cpm1-smc-uart")) { | 183 | if (dt_is_compatible(devp, "fsl,cpm1-smc-uart")) { |
184 | is_smc = 1; | 184 | is_smc = 1; |
@@ -229,16 +229,36 @@ int cpm_console_init(void *devp, struct serial_console_data *scdp) | |||
229 | 229 | ||
230 | n = getprop(parent, "virtual-reg", reg_virt, sizeof(reg_virt)); | 230 | n = getprop(parent, "virtual-reg", reg_virt, sizeof(reg_virt)); |
231 | if (n < (int)sizeof(reg_virt)) { | 231 | if (n < (int)sizeof(reg_virt)) { |
232 | for (n = 0; n < 2; n++) { | 232 | if (!dt_xlate_reg(parent, 0, ®_phys, NULL)) |
233 | if (!dt_xlate_reg(parent, n, ®_phys, NULL)) | 233 | return -1; |
234 | return -1; | ||
235 | 234 | ||
236 | reg_virt[n] = (void *)reg_phys; | 235 | reg_virt[0] = (void *)reg_phys; |
237 | } | ||
238 | } | 236 | } |
239 | 237 | ||
240 | cpcr = reg_virt[0]; | 238 | cpcr = reg_virt[0]; |
241 | dpram_start = reg_virt[1]; | 239 | |
240 | muram = finddevice("/soc/cpm/muram/data"); | ||
241 | if (!muram) | ||
242 | return -1; | ||
243 | |||
244 | /* For bootwrapper-compatible device trees, we assume that the first | ||
245 | * entry has at least 18 bytes, and that #address-cells/#data-cells | ||
246 | * is one for both parent and child. | ||
247 | */ | ||
248 | |||
249 | n = getprop(muram, "virtual-reg", reg_virt, sizeof(reg_virt)); | ||
250 | if (n < (int)sizeof(reg_virt)) { | ||
251 | if (!dt_xlate_reg(muram, 0, ®_phys, NULL)) | ||
252 | return -1; | ||
253 | |||
254 | reg_virt[0] = (void *)reg_phys; | ||
255 | } | ||
256 | |||
257 | muram_start = reg_virt[0]; | ||
258 | |||
259 | n = getprop(muram, "reg", &muram_offset, 4); | ||
260 | if (n < 4) | ||
261 | return -1; | ||
242 | 262 | ||
243 | scdp->open = cpm_serial_open; | 263 | scdp->open = cpm_serial_open; |
244 | scdp->putc = cpm_serial_putc; | 264 | scdp->putc = cpm_serial_putc; |
diff --git a/arch/powerpc/boot/dts/ep88xc.dts b/arch/powerpc/boot/dts/ep88xc.dts index 0406fc50b2af..02705f299790 100644 --- a/arch/powerpc/boot/dts/ep88xc.dts +++ b/arch/powerpc/boot/dts/ep88xc.dts | |||
@@ -142,9 +142,20 @@ | |||
142 | command-proc = <9c0>; | 142 | command-proc = <9c0>; |
143 | interrupts = <0>; // cpm error interrupt | 143 | interrupts = <0>; // cpm error interrupt |
144 | interrupt-parent = <&CPM_PIC>; | 144 | interrupt-parent = <&CPM_PIC>; |
145 | reg = <9c0 40 2000 1c00>; | 145 | reg = <9c0 40>; |
146 | ranges; | 146 | ranges; |
147 | 147 | ||
148 | muram@2000 { | ||
149 | #address-cells = <1>; | ||
150 | #size-cells = <1>; | ||
151 | ranges = <0 2000 2000>; | ||
152 | |||
153 | data@0 { | ||
154 | compatible = "fsl,cpm-muram-data"; | ||
155 | reg = <0 1c00>; | ||
156 | }; | ||
157 | }; | ||
158 | |||
148 | brg@9f0 { | 159 | brg@9f0 { |
149 | compatible = "fsl,mpc885-brg", | 160 | compatible = "fsl,mpc885-brg", |
150 | "fsl,cpm1-brg", | 161 | "fsl,cpm1-brg", |
diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts index 3fe991d4cb03..188179df0845 100644 --- a/arch/powerpc/boot/dts/mpc8272ads.dts +++ b/arch/powerpc/boot/dts/mpc8272ads.dts | |||
@@ -124,6 +124,17 @@ | |||
124 | reg = <119c0 30 0 2000>; | 124 | reg = <119c0 30 0 2000>; |
125 | ranges; | 125 | ranges; |
126 | 126 | ||
127 | muram@0 { | ||
128 | #address-cells = <1>; | ||
129 | #size-cells = <1>; | ||
130 | ranges = <0 0 10000>; | ||
131 | |||
132 | data@0 { | ||
133 | compatible = "fsl,cpm-muram-data"; | ||
134 | reg = <0 2000 9800 800>; | ||
135 | }; | ||
136 | }; | ||
137 | |||
127 | brg@119f0 { | 138 | brg@119f0 { |
128 | compatible = "fsl,mpc8272-brg", | 139 | compatible = "fsl,mpc8272-brg", |
129 | "fsl,cpm2-brg", | 140 | "fsl,cpm2-brg", |
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts index cbcd16f74c45..8848e637293e 100644 --- a/arch/powerpc/boot/dts/mpc885ads.dts +++ b/arch/powerpc/boot/dts/mpc885ads.dts | |||
@@ -148,9 +148,20 @@ | |||
148 | command-proc = <9c0>; | 148 | command-proc = <9c0>; |
149 | interrupts = <0>; // cpm error interrupt | 149 | interrupts = <0>; // cpm error interrupt |
150 | interrupt-parent = <&CPM_PIC>; | 150 | interrupt-parent = <&CPM_PIC>; |
151 | reg = <9c0 40 2000 1c00>; | 151 | reg = <9c0 40>; |
152 | ranges; | 152 | ranges; |
153 | 153 | ||
154 | muram@2000 { | ||
155 | #address-cells = <1>; | ||
156 | #size-cells = <1>; | ||
157 | ranges = <0 2000 2000>; | ||
158 | |||
159 | data@0 { | ||
160 | compatible = "fsl,cpm-muram-data"; | ||
161 | reg = <0 1c00>; | ||
162 | }; | ||
163 | }; | ||
164 | |||
154 | brg@9f0 { | 165 | brg@9f0 { |
155 | compatible = "fsl,mpc885-brg", | 166 | compatible = "fsl,mpc885-brg", |
156 | "fsl,cpm1-brg", | 167 | "fsl,cpm1-brg", |
diff --git a/arch/powerpc/boot/dts/pq2fads.dts b/arch/powerpc/boot/dts/pq2fads.dts index 54e8bd1ae22f..2d564921897a 100644 --- a/arch/powerpc/boot/dts/pq2fads.dts +++ b/arch/powerpc/boot/dts/pq2fads.dts | |||
@@ -119,9 +119,20 @@ | |||
119 | #size-cells = <1>; | 119 | #size-cells = <1>; |
120 | #interrupt-cells = <2>; | 120 | #interrupt-cells = <2>; |
121 | compatible = "fsl,mpc8280-cpm", "fsl,cpm2"; | 121 | compatible = "fsl,mpc8280-cpm", "fsl,cpm2"; |
122 | reg = <119c0 30 0 2000>; | 122 | reg = <119c0 30>; |
123 | ranges; | 123 | ranges; |
124 | 124 | ||
125 | muram@0 { | ||
126 | #address-cells = <1>; | ||
127 | #size-cells = <1>; | ||
128 | ranges = <0 0 10000>; | ||
129 | |||
130 | data@0 { | ||
131 | compatible = "fsl,cpm-muram-data"; | ||
132 | reg = <0 2000 9800 800>; | ||
133 | }; | ||
134 | }; | ||
135 | |||
125 | brg@119f0 { | 136 | brg@119f0 { |
126 | compatible = "fsl,mpc8280-brg", | 137 | compatible = "fsl,mpc8280-brg", |
127 | "fsl,cpm2-brg", | 138 | "fsl,cpm2-brg", |
diff --git a/arch/powerpc/sysdev/commproc.c b/arch/powerpc/sysdev/commproc.c index 428eb8c151b9..f6a63780bbde 100644 --- a/arch/powerpc/sysdev/commproc.c +++ b/arch/powerpc/sysdev/commproc.c | |||
@@ -39,12 +39,15 @@ | |||
39 | #include <asm/tlbflush.h> | 39 | #include <asm/tlbflush.h> |
40 | #include <asm/rheap.h> | 40 | #include <asm/rheap.h> |
41 | #include <asm/prom.h> | 41 | #include <asm/prom.h> |
42 | #include <asm/cpm.h> | ||
42 | 43 | ||
43 | #include <asm/fs_pd.h> | 44 | #include <asm/fs_pd.h> |
44 | 45 | ||
45 | #define CPM_MAP_SIZE (0x4000) | 46 | #define CPM_MAP_SIZE (0x4000) |
46 | 47 | ||
48 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
47 | static void m8xx_cpm_dpinit(void); | 49 | static void m8xx_cpm_dpinit(void); |
50 | #endif | ||
48 | static uint host_buffer; /* One page of host buffer */ | 51 | static uint host_buffer; /* One page of host buffer */ |
49 | static uint host_end; /* end + 1 */ | 52 | static uint host_end; /* end + 1 */ |
50 | cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */ | 53 | cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */ |
@@ -193,7 +196,7 @@ end: | |||
193 | return sirq; | 196 | return sirq; |
194 | } | 197 | } |
195 | 198 | ||
196 | void cpm_reset(void) | 199 | void __init cpm_reset(void) |
197 | { | 200 | { |
198 | sysconf8xx_t __iomem *siu_conf; | 201 | sysconf8xx_t __iomem *siu_conf; |
199 | 202 | ||
@@ -229,8 +232,12 @@ void cpm_reset(void) | |||
229 | out_be32(&siu_conf->sc_sdcr, 1); | 232 | out_be32(&siu_conf->sc_sdcr, 1); |
230 | immr_unmap(siu_conf); | 233 | immr_unmap(siu_conf); |
231 | 234 | ||
235 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
236 | cpm_muram_init(); | ||
237 | #else | ||
232 | /* Reclaim the DP memory for our use. */ | 238 | /* Reclaim the DP memory for our use. */ |
233 | m8xx_cpm_dpinit(); | 239 | m8xx_cpm_dpinit(); |
240 | #endif | ||
234 | } | 241 | } |
235 | 242 | ||
236 | /* We used to do this earlier, but have to postpone as long as possible | 243 | /* We used to do this earlier, but have to postpone as long as possible |
@@ -296,6 +303,7 @@ cpm_setbrg(uint brg, uint rate) | |||
296 | CPM_BRG_EN | CPM_BRG_DIV16); | 303 | CPM_BRG_EN | CPM_BRG_DIV16); |
297 | } | 304 | } |
298 | 305 | ||
306 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
299 | /* | 307 | /* |
300 | * dpalloc / dpfree bits. | 308 | * dpalloc / dpfree bits. |
301 | */ | 309 | */ |
@@ -397,6 +405,7 @@ uint cpm_dpram_phys(u8 *addr) | |||
397 | return (dpram_pbase + (uint)(addr - dpram_vbase)); | 405 | return (dpram_pbase + (uint)(addr - dpram_vbase)); |
398 | } | 406 | } |
399 | EXPORT_SYMBOL(cpm_dpram_phys); | 407 | EXPORT_SYMBOL(cpm_dpram_phys); |
408 | #endif /* !CONFIG_PPC_CPM_NEW_BINDING */ | ||
400 | 409 | ||
401 | struct cpm_ioport16 { | 410 | struct cpm_ioport16 { |
402 | __be16 dir, par, sor, dat, intr; | 411 | __be16 dir, par, sor, dat, intr; |
diff --git a/arch/powerpc/sysdev/cpm2_common.c b/arch/powerpc/sysdev/cpm2_common.c index fc4c99565381..859362fecb7c 100644 --- a/arch/powerpc/sysdev/cpm2_common.c +++ b/arch/powerpc/sysdev/cpm2_common.c | |||
@@ -46,7 +46,10 @@ | |||
46 | 46 | ||
47 | #include <sysdev/fsl_soc.h> | 47 | #include <sysdev/fsl_soc.h> |
48 | 48 | ||
49 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
49 | static void cpm2_dpinit(void); | 50 | static void cpm2_dpinit(void); |
51 | #endif | ||
52 | |||
50 | cpm_cpm2_t __iomem *cpmp; /* Pointer to comm processor space */ | 53 | cpm_cpm2_t __iomem *cpmp; /* Pointer to comm processor space */ |
51 | 54 | ||
52 | /* We allocate this here because it is used almost exclusively for | 55 | /* We allocate this here because it is used almost exclusively for |
@@ -69,7 +72,11 @@ cpm2_reset(void) | |||
69 | 72 | ||
70 | /* Reclaim the DP memory for our use. | 73 | /* Reclaim the DP memory for our use. |
71 | */ | 74 | */ |
75 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
76 | cpm_muram_init(); | ||
77 | #else | ||
72 | cpm2_dpinit(); | 78 | cpm2_dpinit(); |
79 | #endif | ||
73 | 80 | ||
74 | /* Tell everyone where the comm processor resides. | 81 | /* Tell everyone where the comm processor resides. |
75 | */ | 82 | */ |
@@ -316,6 +323,7 @@ int cpm2_smc_clk_setup(enum cpm_clk_target target, int clock) | |||
316 | return ret; | 323 | return ret; |
317 | } | 324 | } |
318 | 325 | ||
326 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
319 | /* | 327 | /* |
320 | * dpalloc / dpfree bits. | 328 | * dpalloc / dpfree bits. |
321 | */ | 329 | */ |
@@ -328,28 +336,6 @@ static u8 __iomem *im_dprambase; | |||
328 | 336 | ||
329 | static void cpm2_dpinit(void) | 337 | static void cpm2_dpinit(void) |
330 | { | 338 | { |
331 | struct resource r; | ||
332 | |||
333 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
334 | struct device_node *np; | ||
335 | |||
336 | np = of_find_compatible_node(NULL, NULL, "fsl,cpm2"); | ||
337 | if (!np) | ||
338 | panic("Cannot find CPM2 node"); | ||
339 | |||
340 | if (of_address_to_resource(np, 1, &r)) | ||
341 | panic("Cannot get CPM2 resource 1"); | ||
342 | |||
343 | of_node_put(np); | ||
344 | #else | ||
345 | r.start = CPM_MAP_ADDR; | ||
346 | r.end = r.start + CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE - 1; | ||
347 | #endif | ||
348 | |||
349 | im_dprambase = ioremap(r.start, r.end - r.start + 1); | ||
350 | if (!im_dprambase) | ||
351 | panic("Cannot map DPRAM"); | ||
352 | |||
353 | spin_lock_init(&cpm_dpmem_lock); | 339 | spin_lock_init(&cpm_dpmem_lock); |
354 | 340 | ||
355 | /* initialize the info header */ | 341 | /* initialize the info header */ |
@@ -358,13 +344,15 @@ static void cpm2_dpinit(void) | |||
358 | sizeof(cpm_boot_dpmem_rh_block[0]), | 344 | sizeof(cpm_boot_dpmem_rh_block[0]), |
359 | cpm_boot_dpmem_rh_block); | 345 | cpm_boot_dpmem_rh_block); |
360 | 346 | ||
347 | im_dprambase = cpm2_immr; | ||
348 | |||
361 | /* Attach the usable dpmem area */ | 349 | /* Attach the usable dpmem area */ |
362 | /* XXX: This is actually crap. CPM_DATAONLY_BASE and | 350 | /* XXX: This is actually crap. CPM_DATAONLY_BASE and |
363 | * CPM_DATAONLY_SIZE is only a subset of the available dpram. It | 351 | * CPM_DATAONLY_SIZE is only a subset of the available dpram. It |
364 | * varies with the processor and the microcode patches activated. | 352 | * varies with the processor and the microcode patches activated. |
365 | * But the following should be at least safe. | 353 | * But the following should be at least safe. |
366 | */ | 354 | */ |
367 | rh_attach_region(&cpm_dpmem_info, 0, r.end - r.start + 1); | 355 | rh_attach_region(&cpm_dpmem_info, CPM_DATAONLY_BASE, CPM_DATAONLY_SIZE); |
368 | } | 356 | } |
369 | 357 | ||
370 | /* This function returns an index into the DPRAM area. | 358 | /* This function returns an index into the DPRAM area. |
@@ -422,6 +410,7 @@ void *cpm_dpram_addr(unsigned long offset) | |||
422 | return (void *)(im_dprambase + offset); | 410 | return (void *)(im_dprambase + offset); |
423 | } | 411 | } |
424 | EXPORT_SYMBOL(cpm_dpram_addr); | 412 | EXPORT_SYMBOL(cpm_dpram_addr); |
413 | #endif /* !CONFIG_PPC_CPM_NEW_BINDING */ | ||
425 | 414 | ||
426 | struct cpm2_ioports { | 415 | struct cpm2_ioports { |
427 | u32 dir, par, sor, odr, dat; | 416 | u32 dir, par, sor, odr, dat; |
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 9daa6ac67676..66c8ad4cfce6 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c | |||
@@ -5,15 +5,27 @@ | |||
5 | * | 5 | * |
6 | * Copyright 2007 Freescale Semiconductor, Inc. | 6 | * Copyright 2007 Freescale Semiconductor, Inc. |
7 | * | 7 | * |
8 | * Some parts derived from commproc.c/cpm2_common.c, which is: | ||
9 | * Copyright (c) 1997 Dan error_act (dmalek@jlc.net) | ||
10 | * Copyright (c) 1999-2001 Dan Malek <dan@embeddedalley.com> | ||
11 | * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com) | ||
12 | * 2006 (c) MontaVista Software, Inc. | ||
13 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
14 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | 15 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of version 2 of the GNU General Public License as | 16 | * it under the terms of version 2 of the GNU General Public License as |
10 | * published by the Free Software Foundation. | 17 | * published by the Free Software Foundation. |
11 | */ | 18 | */ |
12 | 19 | ||
13 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/of_device.h> | ||
22 | |||
14 | #include <asm/udbg.h> | 23 | #include <asm/udbg.h> |
15 | #include <asm/io.h> | 24 | #include <asm/io.h> |
16 | #include <asm/system.h> | 25 | #include <asm/system.h> |
26 | #include <asm/rheap.h> | ||
27 | #include <asm/cpm.h> | ||
28 | |||
17 | #include <mm/mmu_decl.h> | 29 | #include <mm/mmu_decl.h> |
18 | 30 | ||
19 | #ifdef CONFIG_PPC_EARLY_DEBUG_CPM | 31 | #ifdef CONFIG_PPC_EARLY_DEBUG_CPM |
@@ -41,6 +53,153 @@ void __init udbg_init_cpm(void) | |||
41 | setbat(1, 0xf0000000, 0xf0000000, 1024*1024, _PAGE_IO); | 53 | setbat(1, 0xf0000000, 0xf0000000, 1024*1024, _PAGE_IO); |
42 | #endif | 54 | #endif |
43 | udbg_putc = udbg_putc_cpm; | 55 | udbg_putc = udbg_putc_cpm; |
56 | udbg_putc('X'); | ||
44 | } | 57 | } |
45 | } | 58 | } |
46 | #endif | 59 | #endif |
60 | |||
61 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
62 | static spinlock_t cpm_muram_lock; | ||
63 | static rh_block_t cpm_boot_muram_rh_block[16]; | ||
64 | static rh_info_t cpm_muram_info; | ||
65 | static u8 __iomem *muram_vbase; | ||
66 | static phys_addr_t muram_pbase; | ||
67 | |||
68 | /* Max address size we deal with */ | ||
69 | #define OF_MAX_ADDR_CELLS 4 | ||
70 | |||
71 | int __init cpm_muram_init(void) | ||
72 | { | ||
73 | struct device_node *np; | ||
74 | struct resource r; | ||
75 | u32 zero[OF_MAX_ADDR_CELLS] = {}; | ||
76 | resource_size_t max = 0; | ||
77 | int i = 0; | ||
78 | int ret = 0; | ||
79 | |||
80 | printk("cpm_muram_init\n"); | ||
81 | |||
82 | spin_lock_init(&cpm_muram_lock); | ||
83 | /* initialize the info header */ | ||
84 | rh_init(&cpm_muram_info, 1, | ||
85 | sizeof(cpm_boot_muram_rh_block) / | ||
86 | sizeof(cpm_boot_muram_rh_block[0]), | ||
87 | cpm_boot_muram_rh_block); | ||
88 | |||
89 | np = of_find_compatible_node(NULL, NULL, "fsl,cpm-muram-data"); | ||
90 | if (!np) { | ||
91 | printk(KERN_ERR "Cannot find CPM muram data node"); | ||
92 | ret = -ENODEV; | ||
93 | goto out; | ||
94 | } | ||
95 | |||
96 | muram_pbase = of_translate_address(np, zero); | ||
97 | if (muram_pbase == (phys_addr_t)OF_BAD_ADDR) { | ||
98 | printk(KERN_ERR "Cannot translate zero through CPM muram node"); | ||
99 | ret = -ENODEV; | ||
100 | goto out; | ||
101 | } | ||
102 | |||
103 | while (of_address_to_resource(np, i++, &r) == 0) { | ||
104 | if (r.end > max) | ||
105 | max = r.end; | ||
106 | |||
107 | rh_attach_region(&cpm_muram_info, r.start - muram_pbase, | ||
108 | r.end - r.start + 1); | ||
109 | } | ||
110 | |||
111 | muram_vbase = ioremap(muram_pbase, max - muram_pbase + 1); | ||
112 | if (!muram_vbase) { | ||
113 | printk(KERN_ERR "Cannot map CPM muram"); | ||
114 | ret = -ENOMEM; | ||
115 | } | ||
116 | |||
117 | out: | ||
118 | of_node_put(np); | ||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | /** | ||
123 | * cpm_muram_alloc - allocate the requested size worth of multi-user ram | ||
124 | * @size: number of bytes to allocate | ||
125 | * @align: requested alignment, in bytes | ||
126 | * | ||
127 | * This function returns an offset into the muram area. | ||
128 | * Use cpm_dpram_addr() to get the virtual address of the area. | ||
129 | * Use cpm_muram_free() to free the allocation. | ||
130 | */ | ||
131 | unsigned long cpm_muram_alloc(unsigned long size, unsigned long align) | ||
132 | { | ||
133 | unsigned long start; | ||
134 | unsigned long flags; | ||
135 | |||
136 | spin_lock_irqsave(&cpm_muram_lock, flags); | ||
137 | cpm_muram_info.alignment = align; | ||
138 | start = rh_alloc(&cpm_muram_info, size, "commproc"); | ||
139 | spin_unlock_irqrestore(&cpm_muram_lock, flags); | ||
140 | |||
141 | return start; | ||
142 | } | ||
143 | EXPORT_SYMBOL(cpm_muram_alloc); | ||
144 | |||
145 | /** | ||
146 | * cpm_muram_free - free a chunk of multi-user ram | ||
147 | * @offset: The beginning of the chunk as returned by cpm_muram_alloc(). | ||
148 | */ | ||
149 | int cpm_muram_free(unsigned long offset) | ||
150 | { | ||
151 | int ret; | ||
152 | unsigned long flags; | ||
153 | |||
154 | spin_lock_irqsave(&cpm_muram_lock, flags); | ||
155 | ret = rh_free(&cpm_muram_info, offset); | ||
156 | spin_unlock_irqrestore(&cpm_muram_lock, flags); | ||
157 | |||
158 | return ret; | ||
159 | } | ||
160 | EXPORT_SYMBOL(cpm_muram_free); | ||
161 | |||
162 | /** | ||
163 | * cpm_muram_alloc_fixed - reserve a specific region of multi-user ram | ||
164 | * @offset: the offset into the muram area to reserve | ||
165 | * @size: the number of bytes to reserve | ||
166 | * | ||
167 | * This function returns "start" on success, -ENOMEM on failure. | ||
168 | * Use cpm_dpram_addr() to get the virtual address of the area. | ||
169 | * Use cpm_muram_free() to free the allocation. | ||
170 | */ | ||
171 | unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size) | ||
172 | { | ||
173 | unsigned long start; | ||
174 | unsigned long flags; | ||
175 | |||
176 | spin_lock_irqsave(&cpm_muram_lock, flags); | ||
177 | cpm_muram_info.alignment = 1; | ||
178 | start = rh_alloc_fixed(&cpm_muram_info, offset, size, "commproc"); | ||
179 | spin_unlock_irqrestore(&cpm_muram_lock, flags); | ||
180 | |||
181 | return start; | ||
182 | } | ||
183 | EXPORT_SYMBOL(cpm_muram_alloc_fixed); | ||
184 | |||
185 | /** | ||
186 | * cpm_muram_addr - turn a muram offset into a virtual address | ||
187 | * @offset: muram offset to convert | ||
188 | */ | ||
189 | void __iomem *cpm_muram_addr(unsigned long offset) | ||
190 | { | ||
191 | return muram_vbase + offset; | ||
192 | } | ||
193 | EXPORT_SYMBOL(cpm_muram_addr); | ||
194 | |||
195 | /** | ||
196 | * cpm_muram_phys - turn a muram virtual address into a DMA address | ||
197 | * @offset: virtual address from cpm_muram_addr() to convert | ||
198 | */ | ||
199 | dma_addr_t cpm_muram_dma(void __iomem *addr) | ||
200 | { | ||
201 | return muram_pbase + ((u8 __iomem *)addr - muram_vbase); | ||
202 | } | ||
203 | EXPORT_SYMBOL(cpm_muram_dma); | ||
204 | |||
205 | #endif /* CONFIG_PPC_CPM_NEW_BINDING */ | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index 5bd4508ce3c1..882dbc17d590 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c | |||
@@ -235,7 +235,7 @@ void scc4_lineif(struct uart_cpm_port *pinfo) | |||
235 | int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) | 235 | int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) |
236 | { | 236 | { |
237 | int dpmemsz, memsz; | 237 | int dpmemsz, memsz; |
238 | u8 *dp_mem; | 238 | u8 __iomem *dp_mem; |
239 | unsigned long dp_offset; | 239 | unsigned long dp_offset; |
240 | u8 *mem_addr; | 240 | u8 *mem_addr; |
241 | dma_addr_t dma_addr = 0; | 241 | dma_addr_t dma_addr = 0; |
@@ -278,7 +278,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) | |||
278 | pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos | 278 | pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos |
279 | * pinfo->rx_fifosize); | 279 | * pinfo->rx_fifosize); |
280 | 280 | ||
281 | pinfo->rx_bd_base = (cbd_t __iomem __force *)dp_mem; | 281 | pinfo->rx_bd_base = (cbd_t __iomem *)dp_mem; |
282 | pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; | 282 | pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; |
283 | 283 | ||
284 | return 0; | 284 | return 0; |
diff --git a/include/asm-powerpc/commproc.h b/include/asm-powerpc/commproc.h index 5dec32404fa2..0307c84a5c1d 100644 --- a/include/asm-powerpc/commproc.h +++ b/include/asm-powerpc/commproc.h | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <asm/8xx_immap.h> | 20 | #include <asm/8xx_immap.h> |
21 | #include <asm/ptrace.h> | 21 | #include <asm/ptrace.h> |
22 | #include <asm/cpm.h> | ||
22 | 23 | ||
23 | /* CPM Command register. | 24 | /* CPM Command register. |
24 | */ | 25 | */ |
@@ -54,6 +55,7 @@ | |||
54 | 55 | ||
55 | #define mk_cr_cmd(CH, CMD) ((CMD << 8) | (CH << 4)) | 56 | #define mk_cr_cmd(CH, CMD) ((CMD << 8) | (CH << 4)) |
56 | 57 | ||
58 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
57 | /* The dual ported RAM is multi-functional. Some areas can be (and are | 59 | /* The dual ported RAM is multi-functional. Some areas can be (and are |
58 | * being) used for microcode. There is an area that can only be used | 60 | * being) used for microcode. There is an area that can only be used |
59 | * as data ram for buffer descriptors, which is all we use right now. | 61 | * as data ram for buffer descriptors, which is all we use right now. |
@@ -62,17 +64,27 @@ | |||
62 | #define CPM_DATAONLY_BASE ((uint)0x0800) | 64 | #define CPM_DATAONLY_BASE ((uint)0x0800) |
63 | #define CPM_DATAONLY_SIZE ((uint)0x0700) | 65 | #define CPM_DATAONLY_SIZE ((uint)0x0700) |
64 | #define CPM_DP_NOSPACE ((uint)0x7fffffff) | 66 | #define CPM_DP_NOSPACE ((uint)0x7fffffff) |
67 | #endif | ||
65 | 68 | ||
66 | /* Export the base address of the communication processor registers | 69 | /* Export the base address of the communication processor registers |
67 | * and dual port ram. | 70 | * and dual port ram. |
68 | */ | 71 | */ |
69 | extern cpm8xx_t __iomem *cpmp; /* Pointer to comm processor */ | 72 | extern cpm8xx_t __iomem *cpmp; /* Pointer to comm processor */ |
73 | |||
74 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
75 | #define cpm_dpalloc cpm_muram_alloc | ||
76 | #define cpm_dpfree cpm_muram_free | ||
77 | #define cpm_dpram_addr cpm_muram_addr | ||
78 | #define cpm_dpram_phys cpm_muram_dma | ||
79 | #else | ||
70 | extern unsigned long cpm_dpalloc(uint size, uint align); | 80 | extern unsigned long cpm_dpalloc(uint size, uint align); |
71 | extern int cpm_dpfree(unsigned long offset); | 81 | extern int cpm_dpfree(unsigned long offset); |
72 | extern unsigned long cpm_dpalloc_fixed(unsigned long offset, uint size, uint align); | 82 | extern unsigned long cpm_dpalloc_fixed(unsigned long offset, uint size, uint align); |
73 | extern void cpm_dpdump(void); | 83 | extern void cpm_dpdump(void); |
74 | extern void *cpm_dpram_addr(unsigned long offset); | 84 | extern void *cpm_dpram_addr(unsigned long offset); |
75 | extern uint cpm_dpram_phys(u8* addr); | 85 | extern uint cpm_dpram_phys(u8* addr); |
86 | #endif | ||
87 | |||
76 | extern void cpm_setbrg(uint brg, uint rate); | 88 | extern void cpm_setbrg(uint brg, uint rate); |
77 | 89 | ||
78 | extern uint m8xx_cpm_hostalloc(uint size); | 90 | extern uint m8xx_cpm_hostalloc(uint size); |
diff --git a/include/asm-powerpc/cpm.h b/include/asm-powerpc/cpm.h new file mode 100644 index 000000000000..48df9f330e76 --- /dev/null +++ b/include/asm-powerpc/cpm.h | |||
@@ -0,0 +1,14 @@ | |||
1 | #ifndef __CPM_H | ||
2 | #define __CPM_H | ||
3 | |||
4 | #include <linux/compiler.h> | ||
5 | #include <linux/types.h> | ||
6 | |||
7 | int cpm_muram_init(void); | ||
8 | unsigned long cpm_muram_alloc(unsigned long size, unsigned long align); | ||
9 | int cpm_muram_free(unsigned long offset); | ||
10 | unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); | ||
11 | void __iomem *cpm_muram_addr(unsigned long offset); | ||
12 | dma_addr_t cpm_muram_dma(void __iomem *addr); | ||
13 | |||
14 | #endif | ||
diff --git a/include/asm-powerpc/cpm2.h b/include/asm-powerpc/cpm2.h index d7b57ac55892..e698b1d09dcf 100644 --- a/include/asm-powerpc/cpm2.h +++ b/include/asm-powerpc/cpm2.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #define __CPM2__ | 11 | #define __CPM2__ |
12 | 12 | ||
13 | #include <asm/immap_cpm2.h> | 13 | #include <asm/immap_cpm2.h> |
14 | #include <asm/cpm.h> | ||
14 | 15 | ||
15 | /* CPM Command register. | 16 | /* CPM Command register. |
16 | */ | 17 | */ |
@@ -82,6 +83,7 @@ | |||
82 | #define mk_cr_cmd(PG, SBC, MCN, OP) \ | 83 | #define mk_cr_cmd(PG, SBC, MCN, OP) \ |
83 | ((PG << 26) | (SBC << 21) | (MCN << 6) | OP) | 84 | ((PG << 26) | (SBC << 21) | (MCN << 6) | OP) |
84 | 85 | ||
86 | #ifndef CONFIG_PPC_CPM_NEW_BINDING | ||
85 | /* Dual Port RAM addresses. The first 16K is available for almost | 87 | /* Dual Port RAM addresses. The first 16K is available for almost |
86 | * any CPM use, so we put the BDs there. The first 128 bytes are | 88 | * any CPM use, so we put the BDs there. The first 128 bytes are |
87 | * used for SMC1 and SMC2 parameter RAM, so we start allocating | 89 | * used for SMC1 and SMC2 parameter RAM, so we start allocating |
@@ -97,6 +99,7 @@ | |||
97 | #define CPM_DATAONLY_SIZE ((uint)(16 * 1024) - CPM_DATAONLY_BASE) | 99 | #define CPM_DATAONLY_SIZE ((uint)(16 * 1024) - CPM_DATAONLY_BASE) |
98 | #define CPM_FCC_SPECIAL_BASE ((uint)0x0000b000) | 100 | #define CPM_FCC_SPECIAL_BASE ((uint)0x0000b000) |
99 | #endif | 101 | #endif |
102 | #endif | ||
100 | 103 | ||
101 | /* The number of pages of host memory we allocate for CPM. This is | 104 | /* The number of pages of host memory we allocate for CPM. This is |
102 | * done early in kernel initialization to get physically contiguous | 105 | * done early in kernel initialization to get physically contiguous |
@@ -109,11 +112,18 @@ | |||
109 | */ | 112 | */ |
110 | extern cpm_cpm2_t __iomem *cpmp; /* Pointer to comm processor */ | 113 | extern cpm_cpm2_t __iomem *cpmp; /* Pointer to comm processor */ |
111 | 114 | ||
115 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
116 | #define cpm_dpalloc cpm_muram_alloc | ||
117 | #define cpm_dpfree cpm_muram_free | ||
118 | #define cpm_dpram_addr cpm_muram_addr | ||
119 | #else | ||
112 | extern unsigned long cpm_dpalloc(uint size, uint align); | 120 | extern unsigned long cpm_dpalloc(uint size, uint align); |
113 | extern int cpm_dpfree(unsigned long offset); | 121 | extern int cpm_dpfree(unsigned long offset); |
114 | extern unsigned long cpm_dpalloc_fixed(unsigned long offset, uint size, uint align); | 122 | extern unsigned long cpm_dpalloc_fixed(unsigned long offset, uint size, uint align); |
115 | extern void cpm_dpdump(void); | 123 | extern void cpm_dpdump(void); |
116 | extern void *cpm_dpram_addr(unsigned long offset); | 124 | extern void *cpm_dpram_addr(unsigned long offset); |
125 | #endif | ||
126 | |||
117 | extern void cpm_setbrg(uint brg, uint rate); | 127 | extern void cpm_setbrg(uint brg, uint rate); |
118 | extern void cpm2_fastbrg(uint brg, uint rate, int div16); | 128 | extern void cpm2_fastbrg(uint brg, uint rate, int div16); |
119 | extern void cpm2_reset(void); | 129 | extern void cpm2_reset(void); |