Skip to content

Commit

Permalink
[POWERPC] cpm: Describe multi-user ram in its own device node.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Scott Wood authored and kumargala committed Oct 4, 2007
1 parent 3c5df5c commit 15f8c60
Show file tree
Hide file tree
Showing 14 changed files with 337 additions and 48 deletions.
40 changes: 36 additions & 4 deletions Documentation/powerpc/booting-without-of.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1861,17 +1861,15 @@ platforms are moved over to use the flattened-device-tree model.

Properties:
- compatible : "fsl,cpm1", "fsl,cpm2", or "fsl,qe".
- reg : The first resource is a 48-byte region beginning with
CPCR. The second is the available general-purpose
DPRAM.
- reg : A 48-byte region beginning with CPCR.

Example:
cpm@119c0 {
#address-cells = <1>;
#size-cells = <1>;
#interrupt-cells = <2>;
compatible = "fsl,mpc8272-cpm", "fsl,cpm2";
reg = <119c0 30 0 2000>;
reg = <119c0 30>;
}

ii) Properties common to mulitple CPM/QE devices
Expand Down Expand Up @@ -2017,6 +2015,40 @@ platforms are moved over to use the flattened-device-tree model.
fsl,cpm-command = <2e600000>;
};

viii) Multi-User RAM (MURAM)

The multi-user/dual-ported RAM is expressed as a bus under the CPM node.

Ranges must be set up subject to the following restrictions:

- Children's reg nodes must be offsets from the start of all muram, even
if the user-data area does not begin at zero.
- If multiple range entries are used, the difference between the parent
address and the child address must be the same in all, so that a single
mapping can cover them all while maintaining the ability to determine
CPM-side offsets with pointer subtraction. It is recommended that
multiple range entries not be used.
- A child address of zero must be translatable, even if no reg resources
contain it.

A child "data" node must exist, compatible with "fsl,cpm-muram-data", to
indicate the portion of muram that is usable by the OS for arbitrary
purposes. The data node may have an arbitrary number of reg resources,
all of which contribute to the allocatable muram pool.

Example, based on mpc8272:

muram@0 {
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0 10000>;

data@0 {
compatible = "fsl,cpm-muram-data";
reg = <0 2000 9800 800>;
};
};

m) Chipselect/Local Bus

Properties:
Expand Down
6 changes: 3 additions & 3 deletions arch/powerpc/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,9 @@ config PPC_EARLY_DEBUG_44x_PHYSHIGH
config PPC_EARLY_DEBUG_CPM_ADDR
hex "CPM UART early debug transmit descriptor address"
depends on PPC_EARLY_DEBUG_CPM
default "0xfa202808" if PPC_EP88XC
default "0xf0000808" if CPM2
default "0xff002808" if CPM1
default "0xfa202008" if PPC_EP88XC
default "0xf0000008" if CPM2
default "0xff002008" if CPM1
help
This specifies the address of the transmit descriptor
used for early debug output. Because it is needed before
Expand Down
44 changes: 32 additions & 12 deletions arch/powerpc/boot/cpm-serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -114,13 +115,12 @@ static void scc_enable_port(void)

static int cpm_serial_open(void)
{
int dpaddr = 0x800;
disable_port();

out_8(&param->rfcr, 0x10);
out_8(&param->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;
Expand All @@ -131,8 +131,8 @@ static int cpm_serial_open(void)
tbdf->len = 1;

sync();
out_be16(&param->rbase, dpaddr);
out_be16(&param->tbase, dpaddr + sizeof(struct cpm_bd));
out_be16(&param->rbase, muram_offset);
out_be16(&param->tbase, muram_offset + sizeof(struct cpm_bd));

do_cmd(CPM_CMD_INIT_RX_TX);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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, &reg_phys, NULL))
return -1;
if (!dt_xlate_reg(parent, 0, &reg_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, &reg_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;
Expand Down
13 changes: 12 additions & 1 deletion arch/powerpc/boot/dts/ep88xc.dts
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,20 @@
command-proc = <9c0>;
interrupts = <0>; // cpm error interrupt
interrupt-parent = <&CPM_PIC>;
reg = <9c0 40 2000 1c00>;
reg = <9c0 40>;
ranges;

muram@2000 {
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 2000 2000>;

data@0 {
compatible = "fsl,cpm-muram-data";
reg = <0 1c00>;
};
};

brg@9f0 {
compatible = "fsl,mpc885-brg",
"fsl,cpm1-brg",
Expand Down
11 changes: 11 additions & 0 deletions arch/powerpc/boot/dts/mpc8272ads.dts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,17 @@
reg = <119c0 30 0 2000>;
ranges;

muram@0 {
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0 10000>;

data@0 {
compatible = "fsl,cpm-muram-data";
reg = <0 2000 9800 800>;
};
};

brg@119f0 {
compatible = "fsl,mpc8272-brg",
"fsl,cpm2-brg",
Expand Down
13 changes: 12 additions & 1 deletion arch/powerpc/boot/dts/mpc885ads.dts
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,20 @@
command-proc = <9c0>;
interrupts = <0>; // cpm error interrupt
interrupt-parent = <&CPM_PIC>;
reg = <9c0 40 2000 1c00>;
reg = <9c0 40>;
ranges;

muram@2000 {
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 2000 2000>;

data@0 {
compatible = "fsl,cpm-muram-data";
reg = <0 1c00>;
};
};

brg@9f0 {
compatible = "fsl,mpc885-brg",
"fsl,cpm1-brg",
Expand Down
13 changes: 12 additions & 1 deletion arch/powerpc/boot/dts/pq2fads.dts
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,20 @@
#size-cells = <1>;
#interrupt-cells = <2>;
compatible = "fsl,mpc8280-cpm", "fsl,cpm2";
reg = <119c0 30 0 2000>;
reg = <119c0 30>;
ranges;

muram@0 {
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0 10000>;

data@0 {
compatible = "fsl,cpm-muram-data";
reg = <0 2000 9800 800>;
};
};

brg@119f0 {
compatible = "fsl,mpc8280-brg",
"fsl,cpm2-brg",
Expand Down
11 changes: 10 additions & 1 deletion arch/powerpc/sysdev/commproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,15 @@
#include <asm/tlbflush.h>
#include <asm/rheap.h>
#include <asm/prom.h>
#include <asm/cpm.h>

#include <asm/fs_pd.h>

#define CPM_MAP_SIZE (0x4000)

#ifndef CONFIG_PPC_CPM_NEW_BINDING
static void m8xx_cpm_dpinit(void);
#endif
static uint host_buffer; /* One page of host buffer */
static uint host_end; /* end + 1 */
cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */
Expand Down Expand Up @@ -193,7 +196,7 @@ unsigned int cpm_pic_init(void)
return sirq;
}

void cpm_reset(void)
void __init cpm_reset(void)
{
sysconf8xx_t __iomem *siu_conf;

Expand Down Expand Up @@ -229,8 +232,12 @@ void cpm_reset(void)
out_be32(&siu_conf->sc_sdcr, 1);
immr_unmap(siu_conf);

#ifdef CONFIG_PPC_CPM_NEW_BINDING
cpm_muram_init();
#else
/* Reclaim the DP memory for our use. */
m8xx_cpm_dpinit();
#endif
}

/* We used to do this earlier, but have to postpone as long as possible
Expand Down Expand Up @@ -296,6 +303,7 @@ cpm_setbrg(uint brg, uint rate)
CPM_BRG_EN | CPM_BRG_DIV16);
}

#ifndef CONFIG_PPC_CPM_NEW_BINDING
/*
* dpalloc / dpfree bits.
*/
Expand Down Expand Up @@ -397,6 +405,7 @@ uint cpm_dpram_phys(u8 *addr)
return (dpram_pbase + (uint)(addr - dpram_vbase));
}
EXPORT_SYMBOL(cpm_dpram_phys);
#endif /* !CONFIG_PPC_CPM_NEW_BINDING */

struct cpm_ioport16 {
__be16 dir, par, sor, dat, intr;
Expand Down
35 changes: 12 additions & 23 deletions arch/powerpc/sysdev/cpm2_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@

#include <sysdev/fsl_soc.h>

#ifndef CONFIG_PPC_CPM_NEW_BINDING
static void cpm2_dpinit(void);
#endif

cpm_cpm2_t __iomem *cpmp; /* Pointer to comm processor space */

/* We allocate this here because it is used almost exclusively for
Expand All @@ -69,7 +72,11 @@ cpm2_reset(void)

/* Reclaim the DP memory for our use.
*/
#ifdef CONFIG_PPC_CPM_NEW_BINDING
cpm_muram_init();
#else
cpm2_dpinit();
#endif

/* Tell everyone where the comm processor resides.
*/
Expand Down Expand Up @@ -316,6 +323,7 @@ int cpm2_smc_clk_setup(enum cpm_clk_target target, int clock)
return ret;
}

#ifndef CONFIG_PPC_CPM_NEW_BINDING
/*
* dpalloc / dpfree bits.
*/
Expand All @@ -328,28 +336,6 @@ static u8 __iomem *im_dprambase;

static void cpm2_dpinit(void)
{
struct resource r;

#ifdef CONFIG_PPC_CPM_NEW_BINDING
struct device_node *np;

np = of_find_compatible_node(NULL, NULL, "fsl,cpm2");
if (!np)
panic("Cannot find CPM2 node");

if (of_address_to_resource(np, 1, &r))
panic("Cannot get CPM2 resource 1");

of_node_put(np);
#else
r.start = CPM_MAP_ADDR;
r.end = r.start + CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE - 1;
#endif

im_dprambase = ioremap(r.start, r.end - r.start + 1);
if (!im_dprambase)
panic("Cannot map DPRAM");

spin_lock_init(&cpm_dpmem_lock);

/* initialize the info header */
Expand All @@ -358,13 +344,15 @@ static void cpm2_dpinit(void)
sizeof(cpm_boot_dpmem_rh_block[0]),
cpm_boot_dpmem_rh_block);

im_dprambase = cpm2_immr;

/* Attach the usable dpmem area */
/* XXX: This is actually crap. CPM_DATAONLY_BASE and
* CPM_DATAONLY_SIZE is only a subset of the available dpram. It
* varies with the processor and the microcode patches activated.
* But the following should be at least safe.
*/
rh_attach_region(&cpm_dpmem_info, 0, r.end - r.start + 1);
rh_attach_region(&cpm_dpmem_info, CPM_DATAONLY_BASE, CPM_DATAONLY_SIZE);
}

/* This function returns an index into the DPRAM area.
Expand Down Expand Up @@ -422,6 +410,7 @@ void *cpm_dpram_addr(unsigned long offset)
return (void *)(im_dprambase + offset);
}
EXPORT_SYMBOL(cpm_dpram_addr);
#endif /* !CONFIG_PPC_CPM_NEW_BINDING */

struct cpm2_ioports {
u32 dir, par, sor, odr, dat;
Expand Down
Loading

0 comments on commit 15f8c60

Please sign in to comment.