diff mbox

ARM: mm: cache-l2x0: Add support for re-enabling l2x0

Message ID 1307926019-28958-1-git-send-email-ccross@android.com (mailing list archive)
State New, archived
Headers show

Commit Message

Colin Cross June 13, 2011, 12:46 a.m. UTC
Remove __init annotation from l2x0_init so it can be used to
reinitialize the l2x0 after it has been reset during suspend.

Only print the init messages the first time l2x0_init is called.

Add l2x0_enable to re-enable the l2x0 after l2x0_disable if
the l2x0 was not reset.

l2x0_disable cannot use writel, as writel calls wmb(), and wmb()
may call outer_cache_sync, which takes the same spinlock as
l2x0_disable.

Signed-off-by: Colin Cross <ccross@android.com>
---
 arch/arm/include/asm/hardware/cache-l2x0.h |    3 ++-
 arch/arm/mm/cache-l2x0.c                   |   18 ++++++++++++++----
 2 files changed, 16 insertions(+), 5 deletions(-)

Comments

Lorenzo Pieralisi June 13, 2011, 10:19 a.m. UTC | #1
On Mon, Jun 13, 2011 at 01:46:58AM +0100, Colin Cross wrote:
> Remove __init annotation from l2x0_init so it can be used to
> reinitialize the l2x0 after it has been reset during suspend.
> 
> Only print the init messages the first time l2x0_init is called.
> 
> Add l2x0_enable to re-enable the l2x0 after l2x0_disable if
> the l2x0 was not reset.
> 
> l2x0_disable cannot use writel, as writel calls wmb(), and wmb()
> may call outer_cache_sync, which takes the same spinlock as
> l2x0_disable.
> 
> Signed-off-by: Colin Cross <ccross@android.com>
> ---
>  arch/arm/include/asm/hardware/cache-l2x0.h |    3 ++-
>  arch/arm/mm/cache-l2x0.c                   |   18 ++++++++++++++----
>  2 files changed, 16 insertions(+), 5 deletions(-)
>

[...]

> +/* enables l2x0 after l2x0_disable, does not invalidate */
> +void l2x0_enable(void)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&l2x0_lock, flags);
> +	writel_relaxed(1, l2x0_base + L2X0_CTRL);
> +	spin_unlock_irqrestore(&l2x0_lock, flags);
> +}
> +
>  static void l2x0_disable(void)
>  {
>  	unsigned long flags;
>  
>  	spin_lock_irqsave(&l2x0_lock, flags);
> -	writel(0, l2x0_base + L2X0_CTRL);
> +	writel_relaxed(0, l2x0_base + L2X0_CTRL);
>  	spin_unlock_irqrestore(&l2x0_lock, flags);
>  }

This function is still dodgy to use, since we are disabling L2
possibly with current function stack lines allocated, which might wreak havoc.

>  
> -void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
> +void l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
>  {
>  	__u32 aux;
>  	__u32 cache_id;
> @@ -340,7 +350,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
>  	outer_cache.disable = l2x0_disable;
>  	outer_cache.set_debug = l2x0_set_debug;
>  
> -	printk(KERN_INFO "%s cache controller enabled\n", type);
> -	printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
> +	pr_info_once("%s cache controller enabled\n", type);
> +	pr_info_once("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
>  			ways, cache_id, aux, l2x0_size);
>  }

We might still need hooks to save/restore PL310 context since registers
like tag and data RAM control are gone on reset. Furthermore, on L2 RAM
retention we want to reinit L2 without having to invalidate L2 RAM(s),
which means we cannot use l2x0_init as it is. I added a couple of hooks to
outer_cache in order to carry out this task, patch coming.

Lorenzo
Colin Cross June 13, 2011, 6:20 p.m. UTC | #2
On Mon, Jun 13, 2011 at 3:19 AM, Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
> On Mon, Jun 13, 2011 at 01:46:58AM +0100, Colin Cross wrote:
>> Remove __init annotation from l2x0_init so it can be used to
>> reinitialize the l2x0 after it has been reset during suspend.
>>
>> Only print the init messages the first time l2x0_init is called.
>>
>> Add l2x0_enable to re-enable the l2x0 after l2x0_disable if
>> the l2x0 was not reset.
>>
>> l2x0_disable cannot use writel, as writel calls wmb(), and wmb()
>> may call outer_cache_sync, which takes the same spinlock as
>> l2x0_disable.
>>
>> Signed-off-by: Colin Cross <ccross@android.com>
>> ---
>>  arch/arm/include/asm/hardware/cache-l2x0.h |    3 ++-
>>  arch/arm/mm/cache-l2x0.c                   |   18 ++++++++++++++----
>>  2 files changed, 16 insertions(+), 5 deletions(-)
>>
>
> [...]
>
>> +/* enables l2x0 after l2x0_disable, does not invalidate */
>> +void l2x0_enable(void)
>> +{
>> +     unsigned long flags;
>> +
>> +     spin_lock_irqsave(&l2x0_lock, flags);
>> +     writel_relaxed(1, l2x0_base + L2X0_CTRL);
>> +     spin_unlock_irqrestore(&l2x0_lock, flags);
>> +}
>> +
>>  static void l2x0_disable(void)
>>  {
>>       unsigned long flags;
>>
>>       spin_lock_irqsave(&l2x0_lock, flags);
>> -     writel(0, l2x0_base + L2X0_CTRL);
>> +     writel_relaxed(0, l2x0_base + L2X0_CTRL);
>>       spin_unlock_irqrestore(&l2x0_lock, flags);
>>  }
>
> This function is still dodgy to use, since we are disabling L2
> possibly with current function stack lines allocated, which might wreak havoc.

From my JTAG debugging, I think the PL310 (at least the one I'm
working with) flushes on disable.  I had a problem where reads with
the cache disabled were getting incorrect data because the data was
stuck in the cache.  With the CPU paused, I disabled the PL310 with
the L2X0_CTRL register, and my data appeared in memory.  I'll try to
find some documentation to support this.

Otherwise, wouldn't a flush_cache_all() and l2x0_flush_all() in
l2x0_disable() ensure the stack lines were flushed out?  Probably
needs a readl_releaxed as well, to ensure the disable has taken
effect.

>>
>> -void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
>> +void l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
>>  {
>>       __u32 aux;
>>       __u32 cache_id;
>> @@ -340,7 +350,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
>>       outer_cache.disable = l2x0_disable;
>>       outer_cache.set_debug = l2x0_set_debug;
>>
>> -     printk(KERN_INFO "%s cache controller enabled\n", type);
>> -     printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
>> +     pr_info_once("%s cache controller enabled\n", type);
>> +     pr_info_once("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
>>                       ways, cache_id, aux, l2x0_size);
>>  }
>
> We might still need hooks to save/restore PL310 context since registers
> like tag and data RAM control are gone on reset. Furthermore, on L2 RAM
> retention we want to reinit L2 without having to invalidate L2 RAM(s),
> which means we cannot use l2x0_init as it is. I added a couple of hooks to
> outer_cache in order to carry out this task, patch coming.

I'm assuming that every platform has a function to set up the tag ram
control the way they want them, which then calls l2x0_init.  That
platform cache init function can be called instead of directly calling
l2x0_init from the resume path.

Calling l2x0_enable instead of l2x0_init solves the retention problem.

> Lorenzo
>
>
Lorenzo Pieralisi June 14, 2011, 5:30 p.m. UTC | #3
On Mon, Jun 13, 2011 at 07:20:34PM +0100, Colin Cross wrote:
> On Mon, Jun 13, 2011 at 3:19 AM, Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com> wrote:
> > On Mon, Jun 13, 2011 at 01:46:58AM +0100, Colin Cross wrote:
> >> Remove __init annotation from l2x0_init so it can be used to
> >> reinitialize the l2x0 after it has been reset during suspend.
> >>
> >> Only print the init messages the first time l2x0_init is called.
> >>
> >> Add l2x0_enable to re-enable the l2x0 after l2x0_disable if
> >> the l2x0 was not reset.
> >>
> >> l2x0_disable cannot use writel, as writel calls wmb(), and wmb()
> >> may call outer_cache_sync, which takes the same spinlock as
> >> l2x0_disable.
> >>
> >> Signed-off-by: Colin Cross <ccross@android.com>
> >> ---
> >> ?arch/arm/include/asm/hardware/cache-l2x0.h | ? ?3 ++-
> >> ?arch/arm/mm/cache-l2x0.c ? ? ? ? ? ? ? ? ? | ? 18 ++++++++++++++----
> >> ?2 files changed, 16 insertions(+), 5 deletions(-)
> >>
> >
> > [...]
> >
> >> +/* enables l2x0 after l2x0_disable, does not invalidate */
> >> +void l2x0_enable(void)
> >> +{
> >> + ? ? unsigned long flags;
> >> +
> >> + ? ? spin_lock_irqsave(&l2x0_lock, flags);
> >> + ? ? writel_relaxed(1, l2x0_base + L2X0_CTRL);
> >> + ? ? spin_unlock_irqrestore(&l2x0_lock, flags);
> >> +}
> >> +
> >> ?static void l2x0_disable(void)
> >> ?{
> >> ? ? ? unsigned long flags;
> >>
> >> ? ? ? spin_lock_irqsave(&l2x0_lock, flags);
> >> - ? ? writel(0, l2x0_base + L2X0_CTRL);
> >> + ? ? writel_relaxed(0, l2x0_base + L2X0_CTRL);
> >> ? ? ? spin_unlock_irqrestore(&l2x0_lock, flags);
> >> ?}
> >
> > This function is still dodgy to use, since we are disabling L2
> > possibly with current function stack lines allocated, which might wreak havoc.
> 
> From my JTAG debugging, I think the PL310 (at least the one I'm
> working with) flushes on disable.  I had a problem where reads with
> the cache disabled were getting incorrect data because the data was
> stuck in the cache.  With the CPU paused, I disabled the PL310 with
> the L2X0_CTRL register, and my data appeared in memory.  I'll try to
> find some documentation to support this.
> 

According to the PL310 TRM (r3p2 3-9) on disable the PL310 syncs, which means
it flushes internal buffers, but it is not supposed to clean dirty lines.
It seems unsafe to me to use the stack and other cacheable data right before
disabling.

> Otherwise, wouldn't a flush_cache_all() and l2x0_flush_all() in
> l2x0_disable() ensure the stack lines were flushed out?  Probably
> needs a readl_releaxed as well, to ensure the disable has taken
> effect.
> 

I reckon the safest option is to clean and disable in one C
function. Moreover at that point in time spinlocks might not be an option
anymore (CPU out of coherency), which makes those functions unusable.

> >>
> >> -void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
> >> +void l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
> >> ?{
> >> ? ? ? __u32 aux;
> >> ? ? ? __u32 cache_id;
> >> @@ -340,7 +350,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
> >> ? ? ? outer_cache.disable = l2x0_disable;
> >> ? ? ? outer_cache.set_debug = l2x0_set_debug;
> >>
> >> - ? ? printk(KERN_INFO "%s cache controller enabled\n", type);
> >> - ? ? printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
> >> + ? ? pr_info_once("%s cache controller enabled\n", type);
> >> + ? ? pr_info_once("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
> >> ? ? ? ? ? ? ? ? ? ? ? ways, cache_id, aux, l2x0_size);
> >> ?}
> >
> > We might still need hooks to save/restore PL310 context since registers
> > like tag and data RAM control are gone on reset. Furthermore, on L2 RAM
> > retention we want to reinit L2 without having to invalidate L2 RAM(s),
> > which means we cannot use l2x0_init as it is. I added a couple of hooks to
> > outer_cache in order to carry out this task, patch coming.
> 
> I'm assuming that every platform has a function to set up the tag ram
> control the way they want them, which then calls l2x0_init.  That
> platform cache init function can be called instead of directly calling
> l2x0_init from the resume path.

I agree that it might solve the problem, and I understand that it allows
to reuse some code, but this will force us to call into platform code
to reinit L2 (which goes against the grain of platform notifiers);
if we manage to write a function doing the whole thing in
a single place it might be easier to use and factor out some replicated
code in the process.

Lorenzo
Santosh Shilimkar June 15, 2011, 6:35 a.m. UTC | #4
On 6/14/2011 11:00 PM, Lorenzo Pieralisi wrote:
> On Mon, Jun 13, 2011 at 07:20:34PM +0100, Colin Cross wrote:
>> On Mon, Jun 13, 2011 at 3:19 AM, Lorenzo Pieralisi
>> <lorenzo.pieralisi@arm.com>  wrote:
>>> On Mon, Jun 13, 2011 at 01:46:58AM +0100, Colin Cross wrote:
>>>> Remove __init annotation from l2x0_init so it can be used to
>>>> reinitialize the l2x0 after it has been reset during suspend.
>>>>
>>>> Only print the init messages the first time l2x0_init is called.
>>>>
>>>> Add l2x0_enable to re-enable the l2x0 after l2x0_disable if
>>>> the l2x0 was not reset.
>>>>
>>>> l2x0_disable cannot use writel, as writel calls wmb(), and wmb()
>>>> may call outer_cache_sync, which takes the same spinlock as
>>>> l2x0_disable.
>>>>
>>>> Signed-off-by: Colin Cross<ccross@android.com>
>>>> ---
>>>> ?arch/arm/include/asm/hardware/cache-l2x0.h | ? ?3 ++-
>>>> ?arch/arm/mm/cache-l2x0.c ? ? ? ? ? ? ? ? ? | ? 18 ++++++++++++++----
>>>> ?2 files changed, 16 insertions(+), 5 deletions(-)
>>>>
>>>
>>> [...]
>>>
>>>> +/* enables l2x0 after l2x0_disable, does not invalidate */
>>>> +void l2x0_enable(void)
>>>> +{
>>>> + ? ? unsigned long flags;
>>>> +
>>>> + ? ? spin_lock_irqsave(&l2x0_lock, flags);
>>>> + ? ? writel_relaxed(1, l2x0_base + L2X0_CTRL);
>>>> + ? ? spin_unlock_irqrestore(&l2x0_lock, flags);
>>>> +}
>>>> +
>>>> ?static void l2x0_disable(void)
>>>> ?{
>>>> ? ? ? unsigned long flags;
>>>>
>>>> ? ? ? spin_lock_irqsave(&l2x0_lock, flags);
>>>> - ? ? writel(0, l2x0_base + L2X0_CTRL);
>>>> + ? ? writel_relaxed(0, l2x0_base + L2X0_CTRL);
>>>> ? ? ? spin_unlock_irqrestore(&l2x0_lock, flags);
>>>> ?}
>>>
>>> This function is still dodgy to use, since we are disabling L2
>>> possibly with current function stack lines allocated, which might wreak havoc.
>>
>>  From my JTAG debugging, I think the PL310 (at least the one I'm
>> working with) flushes on disable.  I had a problem where reads with
>> the cache disabled were getting incorrect data because the data was
>> stuck in the cache.  With the CPU paused, I disabled the PL310 with
>> the L2X0_CTRL register, and my data appeared in memory.  I'll try to
>> find some documentation to support this.
>>
>
> According to the PL310 TRM (r3p2 3-9) on disable the PL310 syncs, which means
> it flushes internal buffers, but it is not supposed to clean dirty lines.
> It seems unsafe to me to use the stack and other cacheable data right before
> disabling.
>
That's right. Disabling L2 won't clean the cache lines. They need
to be cleaned before entering low power state where you loose
it.
Though, cleaning of L2 cache would work even with L2 enable
is not set.
Will Deacon June 15, 2011, 9:02 a.m. UTC | #5
Hi guys,

On Tue, Jun 14, 2011 at 06:30:19PM +0100, Lorenzo Pieralisi wrote:
> On Mon, Jun 13, 2011 at 07:20:34PM +0100, Colin Cross wrote:
>
> According to the PL310 TRM (r3p2 3-9) on disable the PL310 syncs, which means
> it flushes internal buffers, but it is not supposed to clean dirty lines.
> It seems unsafe to me to use the stack and other cacheable data right before
> disabling.
> 
> > Otherwise, wouldn't a flush_cache_all() and l2x0_flush_all() in
> > l2x0_disable() ensure the stack lines were flushed out?  Probably
> > needs a readl_releaxed as well, to ensure the disable has taken
> > effect.
> > 
> 
> I reckon the safest option is to clean and disable in one C
> function. Moreover at that point in time spinlocks might not be an option
> anymore (CPU out of coherency), which makes those functions unusable.

I was planning to add this functionality as part of my kexec patches since
otherwise the l2x0_lock gets blown away on disable. I initially attributed
this to loss of coherency, but that's clearly not the case as I still had L1
running.

Colin - I'll add you to CC for v3 of that series.

Will
Barry Song July 28, 2011, 7:43 a.m. UTC | #6
2011/6/13 Colin Cross <ccross@android.com>:
> Remove __init annotation from l2x0_init so it can be used to
> reinitialize the l2x0 after it has been reset during suspend.

__init before l2x0_init can be deleted and make it available after resume.

We just tried the following flow for l2 cache on CSR SiRFprimaII, it
seems to be working:

suspend: sync and invalidate l2 cache, then disable L2

        v7_flush_kern_cache_all

#ifdef CONFIG_CACHE_L2X0
        ldr     r0, =SIRFSOC_L2CC_VA_BASE
        ldr     r1, =L2X0_CLEAN_INV_WAY
        mov     r2, #0xff
        str     r2, [r0,r1]
        mov     r2, #0
1:
        ldr     r3, [r0,r1]
        cmp     r2,r3
        bne     1b
        ldr     r1, =L2X0_CACHE_SYNC
        mov     r2, #0
        str     r2, [r0,r1]

        ldr     r1, =L2X0_CTRL
        mov     r2, #0
        str     r2, [r0,r1]
#endif

resume:  re-initilized l2x:

 l2x0_init((void __iomem *)SIRFSOC_L2CC_VA_BASE, 0x00040000, 0x00000000);

>
> Only print the init messages the first time l2x0_init is called.
>
> Add l2x0_enable to re-enable the l2x0 after l2x0_disable if
> the l2x0 was not reset.
>
> l2x0_disable cannot use writel, as writel calls wmb(), and wmb()
> may call outer_cache_sync, which takes the same spinlock as
> l2x0_disable.
>
> Signed-off-by: Colin Cross <ccross@android.com>
> ---
>  arch/arm/include/asm/hardware/cache-l2x0.h |    3 ++-
>  arch/arm/mm/cache-l2x0.c                   |   18 ++++++++++++++----
>  2 files changed, 16 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
> index 16bd480..8fd87fe 100644
> --- a/arch/arm/include/asm/hardware/cache-l2x0.h
> +++ b/arch/arm/include/asm/hardware/cache-l2x0.h
> @@ -73,7 +73,8 @@
>  #define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT                30
>
>  #ifndef __ASSEMBLY__
> -extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
> +extern void l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
> +extern void l2x0_enable(void);
>  #endif
>
>  #endif
> diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
> index ef59099..4db0d9c 100644
> --- a/arch/arm/mm/cache-l2x0.c
> +++ b/arch/arm/mm/cache-l2x0.c
> @@ -261,16 +261,26 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
>        spin_unlock_irqrestore(&l2x0_lock, flags);
>  }
>
> +/* enables l2x0 after l2x0_disable, does not invalidate */
> +void l2x0_enable(void)
> +{
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&l2x0_lock, flags);
> +       writel_relaxed(1, l2x0_base + L2X0_CTRL);
> +       spin_unlock_irqrestore(&l2x0_lock, flags);
> +}
> +
>  static void l2x0_disable(void)
>  {
>        unsigned long flags;
>
>        spin_lock_irqsave(&l2x0_lock, flags);
> -       writel(0, l2x0_base + L2X0_CTRL);
> +       writel_relaxed(0, l2x0_base + L2X0_CTRL);
>        spin_unlock_irqrestore(&l2x0_lock, flags);
>  }
>

can you show your context calling l2x0_disable and l2x0_enable?

-barry
diff mbox

Patch

diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 16bd480..8fd87fe 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -73,7 +73,8 @@ 
 #define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT		30
 
 #ifndef __ASSEMBLY__
-extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
+extern void l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
+extern void l2x0_enable(void);
 #endif
 
 #endif
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index ef59099..4db0d9c 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -261,16 +261,26 @@  static void l2x0_flush_range(unsigned long start, unsigned long end)
 	spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
+/* enables l2x0 after l2x0_disable, does not invalidate */
+void l2x0_enable(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&l2x0_lock, flags);
+	writel_relaxed(1, l2x0_base + L2X0_CTRL);
+	spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
 static void l2x0_disable(void)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&l2x0_lock, flags);
-	writel(0, l2x0_base + L2X0_CTRL);
+	writel_relaxed(0, l2x0_base + L2X0_CTRL);
 	spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
-void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
+void l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
 {
 	__u32 aux;
 	__u32 cache_id;
@@ -340,7 +350,7 @@  void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
 	outer_cache.disable = l2x0_disable;
 	outer_cache.set_debug = l2x0_set_debug;
 
-	printk(KERN_INFO "%s cache controller enabled\n", type);
-	printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
+	pr_info_once("%s cache controller enabled\n", type);
+	pr_info_once("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
 			ways, cache_id, aux, l2x0_size);
 }