[PATCH 14/19] powerpc: SPU support routines for Celleb
Ishizaki Kou
kou.ishizaki at toshiba.co.jp
Fri Jan 26 13:10:22 EST 2007
Arnd-san,
Thank you for your comments.
> On Friday 12 January 2007 02:13, Ishizaki Kou wrote:
> > SPU support routines for Celleb platform.
>
> Mostly looks good. I'm sorry I did reply to you when you asked
> for details about the new style device tree layout though.
> Your spu-manage.c file basically implements what the old generation
> of IBM cell blades requires, which we're now trying to phase out.
We have a plan to change our DT to new-style. Our next patch will
support both styles.
> My feeling is that we should try to consolidate this again into
> a common manage.c file for both celleb and ibm blades, as opposed
> to the ps3 platform that needs to do this in a completely different
> way.
We agree to try to consolidate. There are some differences between the
private data structures. We need abstraction to resolve them.
> I'll try to do a write a version that should run on both celleb
> and the blades, using either version of the device tree layout,
> so you can convert your device trees in future releases.
>
> If you send a patch that leaves out manage.c in the meantime,
> I'll Ack that one.
>
> Arnd <><
>
> > +static int __init find_spu_node_id(struct device_node *spe)
> > +{
> > + const unsigned int *id;
> > + struct device_node *cpu;
> > + cpu = spe->parent->parent;
> > + id = get_property(cpu, "node-id", NULL);
> > + return id ? *id : 0;
> > +}
>
> This breaks when the SPE is not a child of a child of a CPU
> node. The new model would put it into a /be node.
>
> The right solution is to replace this function with a call to
> of_node_to_nid(), which does the right thing everywhere.
This is imported from *old* cell/spu_priv1_mmio.c. We will refresh it.
> > +static u64 __init find_spu_unit_number(struct device_node *spe)
> > +{
> > + const unsigned int *reg;
> > + reg = get_property(spe, "reg", NULL);
> > + return reg ? (u64)*reg : 0ul;
> > +}
>
> This is the bigger problem, since the "reg" property changed its meaning.
> It should probably check the "unit-id" property first, and only
> use the "reg" property if in backwards-compatible mode.
Yes. To support both styles, we will change to use "unit-id" first.
> > +static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
> > + const char *prop)
> > +{
> > + static DEFINE_MUTEX(add_spumem_mutex);
> > +
> > + const struct address_prop {
> > + unsigned long address;
> > + unsigned int len;
> > + } __attribute__((packed)) *p;
> > + int proplen;
> > +
> > + unsigned long start_pfn, nr_pages;
> > + struct pglist_data *pgdata;
> > + struct zone *zone;
> > + int ret;
> > +
> > + p = get_property(spe, prop, &proplen);
> > + WARN_ON(proplen != sizeof (*p));
> > +
> > + start_pfn = p->address >> PAGE_SHIFT;
> > + nr_pages = ((unsigned long)p->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
> > +
> > + pgdata = NODE_DATA(spu_get_pdata(spu)->nid);
> > + zone = pgdata->node_zones;
> > +
> > + /* XXX rethink locking here */
> > + mutex_lock(&add_spumem_mutex);
> > + ret = __add_pages(zone, start_pfn, nr_pages);
> > + mutex_unlock(&add_spumem_mutex);
> > +
> > + return ret;
> > +}
>
> This should be the same as the other, existing, function of the
> same name.
To consolidate easily, our patch uses same name on functions that are
imported and not changed.
> > +static void __iomem * __init map_spe_prop(struct spu *spu,
> > + struct device_node *n, const char *name)
> > +{
> > + const struct address_prop {
> > + unsigned long address;
> > + unsigned int len;
> > + } __attribute__((packed)) *prop;
> > +
> > + const void *p;
> > + int proplen;
> > + void __iomem *ret = NULL;
> > + int err = 0;
> > +
> > + p = get_property(n, name, &proplen);
> > + if (proplen != sizeof (struct address_prop))
> > + return NULL;
> > +
> > + prop = p;
> > +
> > + err = cell_spuprop_present(spu, n, name);
> > + if (err && (err != -EEXIST))
> > + goto out;
> > +
> > + ret = ioremap(prop->address, prop->len);
> > +
> > + out:
> > + return ret;
> > +}
> > +
> > +static void spu_unmap_beat(struct spu *spu)
> > +{
> > + iounmap(spu->priv2);
> > + iounmap(spu->problem);
> > + iounmap((__force u8 __iomem *)spu->local_store);
> > +}
> > +
> > +static int __init spu_map_device_beat(struct spu *spu,
> > + struct device_node *node)
> > +{
> > + const char *prop;
> > + int ret;
> > +
> > + ret = -ENODEV;
> > + spu->name = get_property(node, "name", NULL);
> > + if (!spu->name)
> > + goto out;
> > +
> > + prop = get_property(node, "local-store", NULL);
> > + if (!prop)
> > + goto out;
> > + spu->local_store_phys = *(unsigned long *)prop;
> > +
> > + /* we use local store as ram, not io memory */
> > + spu->local_store = (void __force *)
> > + map_spe_prop(spu, node, "local-store");
> > + if (!spu->local_store)
> > + goto out;
> > +
> > + prop = get_property(node, "problem", NULL);
> > + if (!prop)
> > + goto out_unmap;
> > + spu->problem_phys = *(unsigned long *)prop;
> > +
> > + spu->problem= map_spe_prop(spu, node, "problem");
> > + if (!spu->problem)
> > + goto out_unmap;
> > +
> > + spu->priv2= map_spe_prop(spu, node, "priv2");
> > + if (!spu->priv2)
> > + goto out_unmap;
> > + ret = 0;
> > + goto out;
> > +
> > +out_unmap:
> > + spu_unmap_beat(spu);
> > +out:
> > + return ret;
> > +}
>
> In the new model, the information comes from the 'reg' property,
> instead of individual ones. "priv1" is intentionally kept last in
> that list, so it can be left out for the hv case.
>
> Arnd <><
Best regards,
Kou Ishizaki
More information about the Linuxppc-dev
mailing list