On Mon, Oct 08, 2012 at 02:59:19PM +0100, Jon Medhurst (Tixy) wrote:
> From: Jon Medhurst <t...@linaro.org>
> 
> The A15xA7 models simulate a Cache Coherent Interconnect (CCI) and this
> needs to be initialised correctly for Linux to boot.
> 
> To perform this initiation we add the new function configure_from_fdt()
> which will look in the fdt for devices to initialise. In this first case
> we look for the CCI node and if found then setup this device.

Acked-by: Dave Martin <dave.mar...@linaro.org>

(Commentary below, but the patch looks OK to me.)

> 
> Signed-off-by: Jon Medhurst <t...@linaro.org>
> ---
>  semi_loader.c |   57 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 57 insertions(+)
> 
> diff --git a/semi_loader.c b/semi_loader.c
> index c9750be..b0c064c 100644
> --- a/semi_loader.c
> +++ b/semi_loader.c
> @@ -242,6 +242,61 @@ libfdt_error:
>       fatal("libfdt: ", fdt_strerror(e), ", while updating device tree\n");
>  }
>  
> +/* For accessing 32-bit device ports */
> +#define io32(p) (*(volatile uint32_t *)(p))

I had a vague memory of something like this already existing somewhere,
but I think I may be confusing this with another codebase.

> +
> +static void init_cci(unsigned cci)
> +{
> +     info("Initialising CCI\n");
> +
> +     /*
> +      * Ideally, the CCI device tree binding would include suitable
> +      * information so we can correctly configure the CCI, but for
> +      * now we'll just hard-code settings for the present A15xA7
> +      * models.
> +      */
> +
> +     /* Turn on CCI snoops and DVM messages */
> +     io32(cci+0x4000) = 0x3;   /* A15 cluster */
> +     io32(cci+0x5000) = 0x3;   /* A7 cluster */

We may want to be more sophisticated about this at some point, but
this is a sensible compromise for now.

There is no official CCI binding yet, but this code makes reasonable-
looking, minimal assumptions about its final form.

> +
> +     /* Wait while change pending bit of status register is set */
> +     while(io32(cci+0xc) & 0x1)
> +             {}
> +}
> +
> +static void configure_from_fdt(struct loader_info *info)
> +{
> +     void *fdt = (void *)info->fdt_start;
> +     uint32_t const *p;
> +     int addrcells, sizecells;
> +     int offset, len;
> +
> +     if(!fdt)
> +             return;
> +
> +     _fdt_address_and_size_cells(fdt, &addrcells, &sizecells);
> +
> +     /* See if there is a CCI device to initialise */
> +     offset = fdt_node_offset_by_compatible(fdt, 0, "arm,cci");
> +     if (offset >= 0) {
> +             p = fdt_getprop(fdt, offset, "reg", &len);
> +             if(len != (addrcells + sizecells) * 4)
> +                     info("Failed parsing device-tree node for CCI\n");
> +             else {
> +                     /*
> +                      * p[addrcells - 1] is the least significant 32-bits of
> +                      * the address for the CCI. On 32-bit CPUs any 
> additional
> +                      * address bits had  better be zero otherwise we can't
> +                      * access it as we don't enable the MMU.
> +                      */
> +                     init_cci(fdt32_to_cpu(p[addrcells - 1]));
> +             }
> +     }
> +
> +     return;
> +}
> +
>  static int is_space(char c)
>  {
>       return c == ' ';
> @@ -598,4 +653,6 @@ args_done:
>       atag_append(&atagp, ATAG_NONE, 0, 0);
>  
>       update_fdt(&phys, info);
> +
> +     configure_from_fdt(info);
>  }
> -- 
> 1.7.10.4
> 

_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to