aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/powerpc/booting-without-of.txt40
-rw-r--r--arch/powerpc/Kconfig.debug6
-rw-r--r--arch/powerpc/boot/cpm-serial.c44
-rw-r--r--arch/powerpc/boot/dts/ep88xc.dts13
-rw-r--r--arch/powerpc/boot/dts/mpc8272ads.dts11
-rw-r--r--arch/powerpc/boot/dts/mpc885ads.dts13
-rw-r--r--arch/powerpc/boot/dts/pq2fads.dts13
-rw-r--r--arch/powerpc/sysdev/commproc.c11
-rw-r--r--arch/powerpc/sysdev/cpm2_common.c35
-rw-r--r--arch/powerpc/sysdev/cpm_common.c159
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c4
-rw-r--r--include/asm-powerpc/commproc.h12
-rw-r--r--include/asm-powerpc/cpm.h14
-rw-r--r--include/asm-powerpc/cpm2.h10
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
245config PPC_EARLY_DEBUG_CPM_ADDR 245config 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;
56static struct cpm_scc *scc; 56static struct cpm_scc *scc;
57struct cpm_bd *tbdf, *rbdf; 57struct cpm_bd *tbdf, *rbdf;
58static u32 cpm_cmd; 58static u32 cpm_cmd;
59static u8 *dpram_start; 59static u8 *muram_start;
60static u32 muram_offset;
60 61
61static void (*do_cmd)(int op); 62static void (*do_cmd)(int op);
62static void (*enable_port)(void); 63static void (*enable_port)(void);
@@ -114,13 +115,12 @@ static void scc_enable_port(void)
114 115
115static int cpm_serial_open(void) 116static int cpm_serial_open(void)
116{ 117{
117 int dpaddr = 0x800;
118 disable_port(); 118 disable_port();
119 119
120 out_8(&param->rfcr, 0x10); 120 out_8(&param->rfcr, 0x10);
121 out_8(&param->tfcr, 0x10); 121 out_8(&param->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(&param->rbase, dpaddr); 134 out_be16(&param->rbase, muram_offset);
135 out_be16(&param->tbase, dpaddr + sizeof(struct cpm_bd)); 135 out_be16(&param->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, &reg_phys, NULL))
233 if (!dt_xlate_reg(parent, n, &reg_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, &reg_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
47static void m8xx_cpm_dpinit(void); 49static void m8xx_cpm_dpinit(void);
50#endif
48static uint host_buffer; /* One page of host buffer */ 51static uint host_buffer; /* One page of host buffer */
49static uint host_end; /* end + 1 */ 52static uint host_end; /* end + 1 */
50cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */ 53cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */
@@ -193,7 +196,7 @@ end:
193 return sirq; 196 return sirq;
194} 197}
195 198
196void cpm_reset(void) 199void __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}
399EXPORT_SYMBOL(cpm_dpram_phys); 407EXPORT_SYMBOL(cpm_dpram_phys);
408#endif /* !CONFIG_PPC_CPM_NEW_BINDING */
400 409
401struct cpm_ioport16 { 410struct 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
49static void cpm2_dpinit(void); 50static void cpm2_dpinit(void);
51#endif
52
50cpm_cpm2_t __iomem *cpmp; /* Pointer to comm processor space */ 53cpm_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
329static void cpm2_dpinit(void) 337static 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}
424EXPORT_SYMBOL(cpm_dpram_addr); 412EXPORT_SYMBOL(cpm_dpram_addr);
413#endif /* !CONFIG_PPC_CPM_NEW_BINDING */
425 414
426struct cpm2_ioports { 415struct 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
62static spinlock_t cpm_muram_lock;
63static rh_block_t cpm_boot_muram_rh_block[16];
64static rh_info_t cpm_muram_info;
65static u8 __iomem *muram_vbase;
66static phys_addr_t muram_pbase;
67
68/* Max address size we deal with */
69#define OF_MAX_ADDR_CELLS 4
70
71int __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
117out:
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 */
131unsigned 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}
143EXPORT_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 */
149int 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}
160EXPORT_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 */
171unsigned 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}
183EXPORT_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 */
189void __iomem *cpm_muram_addr(unsigned long offset)
190{
191 return muram_vbase + offset;
192}
193EXPORT_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 */
199dma_addr_t cpm_muram_dma(void __iomem *addr)
200{
201 return muram_pbase + ((u8 __iomem *)addr - muram_vbase);
202}
203EXPORT_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)
235int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) 235int 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 */
69extern cpm8xx_t __iomem *cpmp; /* Pointer to comm processor */ 72extern 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
70extern unsigned long cpm_dpalloc(uint size, uint align); 80extern unsigned long cpm_dpalloc(uint size, uint align);
71extern int cpm_dpfree(unsigned long offset); 81extern int cpm_dpfree(unsigned long offset);
72extern unsigned long cpm_dpalloc_fixed(unsigned long offset, uint size, uint align); 82extern unsigned long cpm_dpalloc_fixed(unsigned long offset, uint size, uint align);
73extern void cpm_dpdump(void); 83extern void cpm_dpdump(void);
74extern void *cpm_dpram_addr(unsigned long offset); 84extern void *cpm_dpram_addr(unsigned long offset);
75extern uint cpm_dpram_phys(u8* addr); 85extern uint cpm_dpram_phys(u8* addr);
86#endif
87
76extern void cpm_setbrg(uint brg, uint rate); 88extern void cpm_setbrg(uint brg, uint rate);
77 89
78extern uint m8xx_cpm_hostalloc(uint size); 90extern 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
7int cpm_muram_init(void);
8unsigned long cpm_muram_alloc(unsigned long size, unsigned long align);
9int cpm_muram_free(unsigned long offset);
10unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size);
11void __iomem *cpm_muram_addr(unsigned long offset);
12dma_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 */
110extern cpm_cpm2_t __iomem *cpmp; /* Pointer to comm processor */ 113extern 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
112extern unsigned long cpm_dpalloc(uint size, uint align); 120extern unsigned long cpm_dpalloc(uint size, uint align);
113extern int cpm_dpfree(unsigned long offset); 121extern int cpm_dpfree(unsigned long offset);
114extern unsigned long cpm_dpalloc_fixed(unsigned long offset, uint size, uint align); 122extern unsigned long cpm_dpalloc_fixed(unsigned long offset, uint size, uint align);
115extern void cpm_dpdump(void); 123extern void cpm_dpdump(void);
116extern void *cpm_dpram_addr(unsigned long offset); 124extern void *cpm_dpram_addr(unsigned long offset);
125#endif
126
117extern void cpm_setbrg(uint brg, uint rate); 127extern void cpm_setbrg(uint brg, uint rate);
118extern void cpm2_fastbrg(uint brg, uint rate, int div16); 128extern void cpm2_fastbrg(uint brg, uint rate, int div16);
119extern void cpm2_reset(void); 129extern void cpm2_reset(void);