diff options
author | Scott Wood <scottwood@freescale.com> | 2007-09-28 14:06:16 -0500 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2007-10-04 15:47:05 -0500 |
commit | 15f8c604a79c4840ed76eecf3af5d88b7c1dee9e (patch) | |
tree | d86815bc2daf835fee081ee7dac92cef8784f6a3 /arch/powerpc/boot/cpm-serial.c | |
parent | 3c5df5c26ed17828760945d59653a2e22e3fb63f (diff) | |
download | op-kernel-dev-15f8c604a79c4840ed76eecf3af5d88b7c1dee9e.zip op-kernel-dev-15f8c604a79c4840ed76eecf3af5d88b7c1dee9e.tar.gz |
[POWERPC] cpm: Describe multi-user ram in its own device node.
The way the current CPM binding describes available multi-user (a.k.a.
dual-ported) RAM doesn't work well when there are multiple free regions,
and it doesn't work at all if the region doesn't begin at the start of
the muram area (as the hardware needs to be programmed with offsets into
this area). The latter situation can happen with SMC UARTs on CPM2, as its
parameter RAM is relocatable, u-boot puts it at zero, and the kernel doesn't
support moving it.
It is now described with a muram node, similar to QE. The current CPM
binding is sufficiently recent (i.e. never appeared in an official release)
that compatibility with existing device trees is not an issue.
The code supporting the new binding is shared between cpm1 and cpm2, rather
than remain separated. QE should be able to use this code as well, once
minor fixes are made to its device trees.
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/boot/cpm-serial.c')
-rw-r--r-- | arch/powerpc/boot/cpm-serial.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/arch/powerpc/boot/cpm-serial.c b/arch/powerpc/boot/cpm-serial.c index fcb8b5e..28296fa 100644 --- a/arch/powerpc/boot/cpm-serial.c +++ b/arch/powerpc/boot/cpm-serial.c @@ -56,7 +56,8 @@ static struct cpm_smc *smc; static struct cpm_scc *scc; struct cpm_bd *tbdf, *rbdf; static u32 cpm_cmd; -static u8 *dpram_start; +static u8 *muram_start; +static u32 muram_offset; static void (*do_cmd)(int op); static void (*enable_port)(void); @@ -114,13 +115,12 @@ static void scc_enable_port(void) static int cpm_serial_open(void) { - int dpaddr = 0x800; disable_port(); out_8(¶m->rfcr, 0x10); out_8(¶m->tfcr, 0x10); - rbdf = (struct cpm_bd *)(dpram_start + dpaddr); + rbdf = (struct cpm_bd *)muram_start; rbdf->addr = (u8 *)(rbdf + 2); rbdf->sc = 0xa000; rbdf->len = 1; @@ -131,8 +131,8 @@ static int cpm_serial_open(void) tbdf->len = 1; sync(); - out_be16(¶m->rbase, dpaddr); - out_be16(¶m->tbase, dpaddr + sizeof(struct cpm_bd)); + out_be16(¶m->rbase, muram_offset); + out_be16(¶m->tbase, muram_offset + sizeof(struct cpm_bd)); do_cmd(CPM_CMD_INIT_RX_TX); @@ -178,7 +178,7 @@ int cpm_console_init(void *devp, struct serial_console_data *scdp) void *reg_virt[2]; int is_smc = 0, is_cpm2 = 0, n; unsigned long reg_phys; - void *parent; + void *parent, *muram; if (dt_is_compatible(devp, "fsl,cpm1-smc-uart")) { is_smc = 1; @@ -229,16 +229,36 @@ int cpm_console_init(void *devp, struct serial_console_data *scdp) n = getprop(parent, "virtual-reg", reg_virt, sizeof(reg_virt)); if (n < (int)sizeof(reg_virt)) { - for (n = 0; n < 2; n++) { - if (!dt_xlate_reg(parent, n, ®_phys, NULL)) - return -1; + if (!dt_xlate_reg(parent, 0, ®_phys, NULL)) + return -1; - reg_virt[n] = (void *)reg_phys; - } + reg_virt[0] = (void *)reg_phys; } cpcr = reg_virt[0]; - dpram_start = reg_virt[1]; + + muram = finddevice("/soc/cpm/muram/data"); + if (!muram) + return -1; + + /* For bootwrapper-compatible device trees, we assume that the first + * entry has at least 18 bytes, and that #address-cells/#data-cells + * is one for both parent and child. + */ + + n = getprop(muram, "virtual-reg", reg_virt, sizeof(reg_virt)); + if (n < (int)sizeof(reg_virt)) { + if (!dt_xlate_reg(muram, 0, ®_phys, NULL)) + return -1; + + reg_virt[0] = (void *)reg_phys; + } + + muram_start = reg_virt[0]; + + n = getprop(muram, "reg", &muram_offset, 4); + if (n < 4) + return -1; scdp->open = cpm_serial_open; scdp->putc = cpm_serial_putc; |