diff options
Diffstat (limited to 'arch/powerpc/sysdev')
-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 |
3 files changed, 181 insertions, 24 deletions
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 */ | ||