Message ID | 1307456541-11026-4-git-send-email-robherring2@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Jun 7, 2011 at 7:22 AM, Rob Herring <robherring2@gmail.com> wrote: > +- aux-value : Value to set the Auxillary Control register to. Setting masked > + bits is undefined. Default value is 0. > +- aux-mask : Mask of bits to preserve in the Auxillary Control register. > + Default value is 0xffffffff. The device tree should describe the hardware, not the way the linux kernel drives the hardware. In the case of the AUX register, it's mostly a collection of options that are either turned on or off. I don't think they should necessarily be described as an opaque 32-bit word, but instead as separate attributes. At least the geometry should be specified that way. For feature enable bits, it depends on what features should be enabled and from the kernel side. I'm not sure that belongs in the device tree at all. -Olof
Olof, On 06/07/2011 11:20 AM, Olof Johansson wrote: > On Tue, Jun 7, 2011 at 7:22 AM, Rob Herring<robherring2@gmail.com> wrote: > >> +- aux-value : Value to set the Auxillary Control register to. Setting masked >> + bits is undefined. Default value is 0. >> +- aux-mask : Mask of bits to preserve in the Auxillary Control register. >> + Default value is 0xffffffff. > > The device tree should describe the hardware, not the way the linux > kernel drives the hardware. In the case of the AUX register, it's > mostly a collection of options that are either turned on or off. I > don't think they should necessarily be described as an opaque 32-bit > word, but instead as separate attributes. Unfortunately, the meaning of the bits depends on the model and there doesn't seem to be any commonality or subset of options as to what each platform is setting up. > > At least the geometry should be specified that way. That's probably the only part that doesn't get changed. :) > > For feature enable bits, it depends on what features should be enabled > and from the kernel side. I'm not sure that belongs in the device tree > at all. I don't think it can be decided what the kernel needs to setup by the device tree. The main reason it's needed in the kernel at all is probably because the bootloader didn't setup aux_ctrl or set it up incorrectly. Perhaps the magic values should just be left in the platforms and continue to be passed into the OF init function: l2x0_of_init(__u32 aux_val, __u32 aux_mask); Rob
Hi, On Tue, Jun 7, 2011 at 9:54 AM, Rob Herring <robherring2@gmail.com> wrote: > Olof, > > On 06/07/2011 11:20 AM, Olof Johansson wrote: >> >> On Tue, Jun 7, 2011 at 7:22 AM, Rob Herring<robherring2@gmail.com> wrote: >> >>> +- aux-value : Value to set the Auxillary Control register to. Setting >>> masked >>> + bits is undefined. Default value is 0. >>> +- aux-mask : Mask of bits to preserve in the Auxillary Control register. >>> + Default value is 0xffffffff. >> >> The device tree should describe the hardware, not the way the linux >> kernel drives the hardware. In the case of the AUX register, it's >> mostly a collection of options that are either turned on or off. I >> don't think they should necessarily be described as an opaque 32-bit >> word, but instead as separate attributes. > > Unfortunately, the meaning of the bits depends on the model and there > doesn't seem to be any commonality or subset of options as to what each > platform is setting up. Luckily, the meaning of the bits can be derived from the most-specific compatible string, but yeah, it seems like many SoC vendors choose to enable different settings. Likely because of either what has been verified to work well, or what worked well for some benchmarks that they cared about enough to optimize the default case for. >> >> At least the geometry should be specified that way. > > That's probably the only part that doesn't get changed. :) Yep, it should ideally still be described though. >> For feature enable bits, it depends on what features should be enabled >> and from the kernel side. I'm not sure that belongs in the device tree >> at all. > > I don't think it can be decided what the kernel needs to setup by the device > tree. The main reason it's needed in the kernel at all is probably because > the bootloader didn't setup aux_ctrl or set it up incorrectly. > > Perhaps the magic values should just be left in the platforms and continue > to be passed into the OF init function: > > l2x0_of_init(__u32 aux_val, __u32 aux_mask); This might be the least painful way to do it, agreed. If a specific platform wants to have firmware pass in the preferred values, they could do so through /chosen or similar. -Olof
diff --git a/Documentation/devicetree/bindings/arm/l2cc.txt b/Documentation/devicetree/bindings/arm/l2cc.txt new file mode 100644 index 0000000..17082be --- /dev/null +++ b/Documentation/devicetree/bindings/arm/l2cc.txt @@ -0,0 +1,35 @@ +* ARM L2 Cache Controller + +ARM cores often have a separate level 2 cache controller. There are various +implementations of the L2 cache controller with compatible programming models. +The ARM L2 cache representation in the device tree should be done as under:- + +Required properties: + +- compatible : should be one of + "arm,pl310-cache" + "arm,l220-cache" + "arm,l210-cache" +- cache-unified : Specifies the cache is a unified cache. +- cache-level : Should be set to 2 for a level 2 cache. +- reg : Physical base address and size of cache controller's memory mapped + registers. + +Optional properties: + +- aux-value : Value to set the Auxillary Control register to. Setting masked + bits is undefined. Default value is 0. +- aux-mask : Mask of bits to preserve in the Auxillary Control register. + Default value is 0xffffffff. + +Example: + +L2: l2-cache { + compatible = "arm,pl310-cache", "cache"; + reg = <0xfff12000 0x1000>; + aux-value = <0>; + aux-mask = <0xffffffff>; + cache-unified; + cache-level = <2>; +}; + diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index 16bd480..1d36632 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -74,6 +74,7 @@ #ifndef __ASSEMBLY__ extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); +extern int l2x0_of_init(void); #endif #endif diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index ef59099..910f530 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -16,9 +16,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <linux/err.h> #include <linux/init.h> #include <linux/spinlock.h> #include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> #include <asm/cacheflush.h> #include <asm/hardware/cache-l2x0.h> @@ -344,3 +347,38 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n", ways, cache_id, aux, l2x0_size); } + +#ifdef CONFIG_OF +static struct of_device_id l2x0_ids[] __initdata = { + { .compatible = "arm,pl310-cache" }, + { .compatible = "arm,l220-cache" }, + { .compatible = "arm,l210-cache" }, +}; + +int __init l2x0_of_init(void) +{ + struct device_node *np; + void __iomem *l2_base; + __u32 aux_val = 0; + __u32 aux_mask = ~0UL; + const __be32 *val; + + np = of_find_matching_node(NULL, l2x0_ids); + if (!np) + return -ENODEV; + l2_base = of_iomap(np, 0); + if (!l2_base) + return -ENOMEM; + + val = of_get_property(np, "aux-value", NULL); + if (val != NULL) + aux_val = of_read_ulong(val, 1); + + val = of_get_property(np, "aux-mask", NULL); + if (val != NULL) + aux_mask = of_read_ulong(val, 1); + + l2x0_init(l2_base, aux_val, aux_mask); + return 0; +} +#endif