* Re: [PATCH v7 2/5] powerpc/85xx: add HOTPLUG_CPU support
From: Kumar Gala @ 2012-07-13 12:15 UTC (permalink / raw)
To: Zhao Chenhui; +Cc: scottwood, linuxppc-dev, linux-kernel
In-Reply-To: <1341310879-5468-2-git-send-email-chenhui.zhao@freescale.com>
On Jul 3, 2012, at 5:21 AM, Zhao Chenhui wrote:
> From: Li Yang <leoli@freescale.com>
>=20
> Add support to disable and re-enable individual cores at runtime
> on MPC85xx/QorIQ SMP machines. Currently support e500v1/e500v2 core.
>=20
> MPC85xx machines use ePAPR spin-table in boot page for CPU kick-off.
> This patch uses the boot page from bootloader to boot core at runtime.
> It supports 32-bit and 36-bit physical address.
>=20
> Add generic_set_cpu_up() to set cpu_state as CPU_UP_PREPARE in =
kick_cpu().
Shouldn't the generic_setup_cpu_up() be a separate patch, and refactor =
smp_generic_kick_cpu() to use it.
Also, we should pull the conversion of the spintable from #defines to =
struct into a separate patch before this one.
>=20
> Signed-off-by: Li Yang <leoli@freescale.com>
> Signed-off-by: Jin Qing <b24347@freescale.com>
> Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
> ---
> v7:
> * removed CONFIG_85xx_TB_SYNC
> no change to the rest of the patch set
>=20
> arch/powerpc/Kconfig | 6 +-
> arch/powerpc/include/asm/cacheflush.h | 2 +
> arch/powerpc/include/asm/smp.h | 2 +
> arch/powerpc/kernel/head_fsl_booke.S | 28 +++++++
> arch/powerpc/kernel/smp.c | 10 +++
> arch/powerpc/platforms/85xx/smp.c | 137 =
++++++++++++++++++++++++---------
> 6 files changed, 146 insertions(+), 39 deletions(-)
>=20
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 38786c8..d6bacbe 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -220,7 +220,8 @@ config ARCH_HIBERNATION_POSSIBLE
> config ARCH_SUSPEND_POSSIBLE
> def_bool y
> depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
> - (PPC_85xx && !SMP) || PPC_86xx || PPC_PSERIES || 44x =
|| 40x
> + (PPC_85xx && !PPC_E500MC) || PPC_86xx || PPC_PSERIES =
\
> + || 44x || 40x
>=20
> config PPC_DCR_NATIVE
> bool
> @@ -331,7 +332,8 @@ config SWIOTLB
>=20
> config HOTPLUG_CPU
> bool "Support for enabling/disabling CPUs"
> - depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || =
PPC_PMAC || PPC_POWERNV)
> + depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || \
> + PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC))
> ---help---
> Say Y here to be able to disable and re-enable individual
> CPUs at runtime on SMP machines.
> diff --git a/arch/powerpc/include/asm/cacheflush.h =
b/arch/powerpc/include/asm/cacheflush.h
> index ab9e402..b843e35 100644
> --- a/arch/powerpc/include/asm/cacheflush.h
> +++ b/arch/powerpc/include/asm/cacheflush.h
> @@ -30,6 +30,8 @@ extern void flush_dcache_page(struct page *page);
> #define flush_dcache_mmap_lock(mapping) do { } while (0)
> #define flush_dcache_mmap_unlock(mapping) do { } while (0)
>=20
> +extern void __flush_disable_L1(void);
> +
> extern void __flush_icache_range(unsigned long, unsigned long);
> static inline void flush_icache_range(unsigned long start, unsigned =
long stop)
> {
> diff --git a/arch/powerpc/include/asm/smp.h =
b/arch/powerpc/include/asm/smp.h
> index ebc24dc..e807e9d 100644
> --- a/arch/powerpc/include/asm/smp.h
> +++ b/arch/powerpc/include/asm/smp.h
> @@ -65,6 +65,7 @@ int generic_cpu_disable(void);
> void generic_cpu_die(unsigned int cpu);
> void generic_mach_cpu_die(void);
> void generic_set_cpu_dead(unsigned int cpu);
> +void generic_set_cpu_up(unsigned int cpu);
> int generic_check_cpu_restart(unsigned int cpu);
> #endif
>=20
> @@ -190,6 +191,7 @@ extern unsigned long __secondary_hold_spinloop;
> extern unsigned long __secondary_hold_acknowledge;
> extern char __secondary_hold;
>=20
> +extern void __early_start(void);
> #endif /* __ASSEMBLY__ */
>=20
> #endif /* __KERNEL__ */
> diff --git a/arch/powerpc/kernel/head_fsl_booke.S =
b/arch/powerpc/kernel/head_fsl_booke.S
> index de80e0f..be0261b 100644
> --- a/arch/powerpc/kernel/head_fsl_booke.S
> +++ b/arch/powerpc/kernel/head_fsl_booke.S
> @@ -996,6 +996,34 @@ _GLOBAL(flush_dcache_L1)
>=20
> blr
>=20
> +/* Flush L1 d-cache, invalidate and disable d-cache and i-cache */
> +_GLOBAL(__flush_disable_L1)
> + mflr r10
> + bl flush_dcache_L1 /* Flush L1 d-cache */
> + mtlr r10
> +
> + mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */
> + li r5, 2
> + rlwimi r4, r5, 0, 3
> +
> + msync
> + isync
> + mtspr SPRN_L1CSR0, r4
> + isync
> +
> +1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */
> + andi. r4, r4, 2
> + bne 1b
> +
> + mfspr r4, SPRN_L1CSR1 /* Invalidate and disable i-cache */
> + li r5, 2
> + rlwimi r4, r5, 0, 3
> +
> + mtspr SPRN_L1CSR1, r4
> + isync
> +
> + blr
> +
> #ifdef CONFIG_SMP
> /* When we get here, r24 needs to hold the CPU # */
> .globl __secondary_start
> diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
> index d9f9441..e0ffe03 100644
> --- a/arch/powerpc/kernel/smp.c
> +++ b/arch/powerpc/kernel/smp.c
> @@ -423,6 +423,16 @@ void generic_set_cpu_dead(unsigned int cpu)
> per_cpu(cpu_state, cpu) =3D CPU_DEAD;
> }
>=20
> +/*
> + * The cpu_state should be set to CPU_UP_PREPARE in kick_cpu(), =
otherwise
> + * the cpu_state is always CPU_DEAD after calling =
generic_set_cpu_dead(),
> + * which makes the delay in generic_cpu_die() not happen.
> + */
> +void generic_set_cpu_up(unsigned int cpu)
> +{
> + per_cpu(cpu_state, cpu) =3D CPU_UP_PREPARE;
> +}
> +
> int generic_check_cpu_restart(unsigned int cpu)
> {
> return per_cpu(cpu_state, cpu) =3D=3D CPU_UP_PREPARE;
> diff --git a/arch/powerpc/platforms/85xx/smp.c =
b/arch/powerpc/platforms/85xx/smp.c
> index 2e65fe8..925e678 100644
> --- a/arch/powerpc/platforms/85xx/smp.c
> +++ b/arch/powerpc/platforms/85xx/smp.c
> @@ -2,7 +2,7 @@
> * Author: Andy Fleming <afleming@freescale.com>
> * Kumar Gala <galak@kernel.crashing.org>
> *
> - * Copyright 2006-2008, 2011 Freescale Semiconductor Inc.
> + * Copyright 2006-2008, 2011-2012 Freescale Semiconductor Inc.
> *
> * This program is free software; you can redistribute it and/or =
modify it
> * under the terms of the GNU General Public License as published =
by the
> @@ -17,6 +17,7 @@
> #include <linux/of.h>
> #include <linux/kexec.h>
> #include <linux/highmem.h>
> +#include <linux/cpu.h>
>=20
> #include <asm/machdep.h>
> #include <asm/pgtable.h>
> @@ -30,18 +31,14 @@
> #include <sysdev/mpic.h>
> #include "smp.h"
>=20
> -extern void __early_start(void);
> -
> -#define BOOT_ENTRY_ADDR_UPPER 0
> -#define BOOT_ENTRY_ADDR_LOWER 1
> -#define BOOT_ENTRY_R3_UPPER 2
> -#define BOOT_ENTRY_R3_LOWER 3
> -#define BOOT_ENTRY_RESV 4
> -#define BOOT_ENTRY_PIR 5
> -#define BOOT_ENTRY_R6_UPPER 6
> -#define BOOT_ENTRY_R6_LOWER 7
> -#define NUM_BOOT_ENTRY 8
> -#define SIZE_BOOT_ENTRY (NUM_BOOT_ENTRY * sizeof(u32))
> +struct epapr_spin_table {
> + u32 addr_h;
> + u32 addr_l;
> + u32 r3_h;
> + u32 r3_l;
> + u32 reserved;
> + u32 pir;
> +};
>=20
> static struct ccsr_guts __iomem *guts;
> static u64 timebase;
> @@ -101,15 +98,45 @@ static void mpc85xx_take_timebase(void)
> local_irq_restore(flags);
> }
>=20
> -static int __init
> -smp_85xx_kick_cpu(int nr)
> +#ifdef CONFIG_HOTPLUG_CPU
> +static void __cpuinit smp_85xx_mach_cpu_die(void)
> +{
> + unsigned int cpu =3D smp_processor_id();
> + u32 tmp;
> +
> + local_irq_disable();
> + idle_task_exit();
> + generic_set_cpu_dead(cpu);
> + mb();
> +
> + mtspr(SPRN_TCR, 0);
> +
> + __flush_disable_L1();
> + tmp =3D (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP;
> + mtspr(SPRN_HID0, tmp);
> + isync();
> +
> + /* Enter NAP mode. */
> + tmp =3D mfmsr();
> + tmp |=3D MSR_WE;
> + mb();
> + mtmsr(tmp);
> + isync();
> +
> + while (1)
> + ;
> +}
> +#endif
> +
> +static int __cpuinit smp_85xx_kick_cpu(int nr)
> {
> unsigned long flags;
> const u64 *cpu_rel_addr;
> - __iomem u32 *bptr_vaddr;
> + __iomem struct epapr_spin_table *spin_table;
> struct device_node *np;
> - int n =3D 0, hw_cpu =3D get_hard_smp_processor_id(nr);
> + int hw_cpu =3D get_hard_smp_processor_id(nr);
> int ioremappable;
> + int ret =3D 0;
>=20
> WARN_ON(nr < 0 || nr >=3D NR_CPUS);
> WARN_ON(hw_cpu < 0 || hw_cpu >=3D NR_CPUS);
> @@ -134,46 +161,80 @@ smp_85xx_kick_cpu(int nr)
>=20
> /* Map the spin table */
> if (ioremappable)
> - bptr_vaddr =3D ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY);
> + spin_table =3D ioremap(*cpu_rel_addr,
> + sizeof(struct epapr_spin_table));
> else
> - bptr_vaddr =3D phys_to_virt(*cpu_rel_addr);
> + spin_table =3D phys_to_virt(*cpu_rel_addr);
>=20
> local_irq_save(flags);
> -
> - out_be32(bptr_vaddr + BOOT_ENTRY_PIR, hw_cpu);
> #ifdef CONFIG_PPC32
> - out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, =
__pa(__early_start));
> +#ifdef CONFIG_HOTPLUG_CPU
> + /* Corresponding to generic_set_cpu_dead() */
> + generic_set_cpu_up(nr);
> +
> + if (system_state =3D=3D SYSTEM_RUNNING) {
> + out_be32(&spin_table->addr_l, 0);
> +
> + /*
> + * We don't set the BPTR register here since it already =
points
> + * to the boot page properly.
> + */
> + mpic_reset_core(hw_cpu);
> +
> + /* wait until core is ready... */
> + if (!spin_event_timeout(in_be32(&spin_table->addr_l) =3D=3D=
1,
> + 10000, 100)) {
> + pr_err("%s: timeout waiting for core %d to =
reset\n",
> + __func__, =
hw_cpu);
> + ret =3D -ENOENT;
> + goto out;
> + }
> +
> + /* clear the acknowledge status */
> + __secondary_hold_acknowledge =3D -1;
> + }
> +#endif
> + out_be32(&spin_table->pir, hw_cpu);
> + out_be32(&spin_table->addr_l, __pa(__early_start));
>=20
> if (!ioremappable)
> - flush_dcache_range((ulong)bptr_vaddr,
> - (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY));
> + flush_dcache_range((ulong)spin_table,
> + (ulong)spin_table + sizeof(struct =
epapr_spin_table));
>=20
> /* Wait a bit for the CPU to ack. */
> - while ((__secondary_hold_acknowledge !=3D hw_cpu) && (++n < =
1000))
> - mdelay(1);
> + if (!spin_event_timeout(__secondary_hold_acknowledge =3D=3D =
hw_cpu,
> + 10000, 100)) {
> + pr_err("%s: timeout waiting for core %d to ack\n",
> + __func__, hw_cpu);
> + ret =3D -ENOENT;
> + goto out;
> + }
> +out:
> #else
> smp_generic_kick_cpu(nr);
>=20
> - out_be64((u64 *)(bptr_vaddr + BOOT_ENTRY_ADDR_UPPER),
> - __pa((u64)*((unsigned long long *) =
generic_secondary_smp_init)));
> + out_be32(&spin_table->pir, hw_cpu);
> + out_be64((u64 *)(&spin_table->addr_h),
> + __pa((u64)*((unsigned long long =
*)generic_secondary_smp_init)));
>=20
> if (!ioremappable)
> - flush_dcache_range((ulong)bptr_vaddr,
> - (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY));
> + flush_dcache_range((ulong)spin_table,
> + (ulong)spin_table + sizeof(struct =
epapr_spin_table));
> #endif
> -
> local_irq_restore(flags);
>=20
> if (ioremappable)
> - iounmap(bptr_vaddr);
> + iounmap(spin_table);
>=20
> - pr_debug("waited %d msecs for CPU #%d.\n", n, nr);
> -
> - return 0;
> + return ret;
> }
>=20
> struct smp_ops_t smp_85xx_ops =3D {
> .kick_cpu =3D smp_85xx_kick_cpu,
> +#ifdef CONFIG_HOTPLUG_CPU
> + .cpu_disable =3D generic_cpu_disable,
> + .cpu_die =3D generic_cpu_die,
> +#endif
> #ifdef CONFIG_KEXEC
> .give_timebase =3D smp_generic_give_timebase,
> .take_timebase =3D smp_generic_take_timebase,
> @@ -277,8 +338,7 @@ static void mpc85xx_smp_machine_kexec(struct =
kimage *image)
> }
> #endif /* CONFIG_KEXEC */
>=20
> -static void __init
> -smp_85xx_setup_cpu(int cpu_nr)
> +static void __cpuinit smp_85xx_setup_cpu(int cpu_nr)
> {
> if (smp_85xx_ops.probe =3D=3D smp_mpic_probe)
> mpic_setup_this_cpu();
> @@ -329,6 +389,9 @@ void __init mpc85xx_smp_init(void)
> }
> smp_85xx_ops.give_timebase =3D mpc85xx_give_timebase;
> smp_85xx_ops.take_timebase =3D mpc85xx_take_timebase;
> +#ifdef CONFIG_HOTPLUG_CPU
> + ppc_md.cpu_die =3D smp_85xx_mach_cpu_die;
> +#endif
> }
>=20
> smp_ops =3D &smp_85xx_ops;
> --=20
> 1.6.4.1
>=20
^ permalink raw reply
* Re: [PATCH] ppc44x/watchdog: Select WATCHDOG_NOWAYOUT option
From: Josh Boyer @ 2012-07-13 12:25 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, Jiang Lu
In-Reply-To: <D5792F52-7BE6-4B86-A3FD-B756DE3A165D@kernel.crashing.org>
On Fri, Jul 13, 2012 at 7:50 AM, Kumar Gala <galak@kernel.crashing.org> wrote:
>
> On Jul 12, 2012, at 9:44 PM, Jiang Lu wrote:
>
>> On PPC44x core, the WRC(Watchdog-timer Reset Control) field of TCR
>> of timer can not reset by software after set to a non-zero value.
>> Which means software can not reset the timeout behaviour of watchdog timer.
>>
>> This patch selects WATCHDOG_NOWAYOUT option for 44x platforms to
>> indicate the watchdog timer can not be disabled once fired.
>>
>> Signed-off-by: Jiang Lu <lu.jiang@windriver.com>
>> ---
>> drivers/watchdog/Kconfig | 1 +
>> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> I believe this is not 44x specific, but how Book-E watchdog is architected.
That is my understanding as well.
>> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
>> index 3709624..41f3dff 100644
>> --- a/drivers/watchdog/Kconfig
>> +++ b/drivers/watchdog/Kconfig
>> @@ -1084,6 +1084,7 @@ config PIKA_WDT
>> config BOOKE_WDT
>> tristate "PowerPC Book-E Watchdog Timer"
>> depends on BOOKE || 4xx
>> + select WATCHDOG_NOWAYOUT if 44x
>
> This should probably be 'select WATCHDOG_NOWAYOUT if BOOKE'
I kind of disagree with this change. It's a user selectable option for
a reason.
Right now, if the option is not set we call booke_wdt_disable which
indeed does not actually _disable_ the WDT, but it does set the timer
period to the maxium value. We could go one step further and implement
a simple timer that pops and calls booke_wdt_ping if WATCHDOG_NOWAYOUT
is not set, then rearms itself. That would leave the user with the
ability to perform recovery of the userspace process that exited or
died and was responsible for pinging the watchdog.
josh
^ permalink raw reply
* Re: [PATCH v6 3/5] powerpc/85xx: add sleep and deep sleep support
From: Kumar Gala @ 2012-07-13 12:27 UTC (permalink / raw)
To: Zhao Chenhui; +Cc: scottwood, linuxppc-dev, linux-kernel
In-Reply-To: <1340706359-9455-3-git-send-email-chenhui.zhao@freescale.com>
On Jun 26, 2012, at 5:25 AM, Zhao Chenhui wrote:
> From: Li Yang <leoli@freescale.com>
>=20
> In sleep PM mode, the clocks of e500 core and unused IP blocks is
> turned off. IP blocks which are allowed to wake up the processor
> are still running.
>=20
> Some Freescale chips like MPC8536 and P1022 has deep sleep PM mode
> in addtion to the sleep PM mode.
>=20
> While in deep sleep PM mode, additionally, the power supply is
> removed from e500 core and most IP blocks. Only the blocks needed
> to wake up the chip out of deep sleep are ON.
>=20
> This patch supports 32-bit and 36-bit address space.
>=20
> The sleep mode is equal to the Standby state in Linux. The deep sleep
> mode is equal to the Suspend-to-RAM state of Linux Power Management.
>=20
> Command to enter sleep mode.
> echo standby > /sys/power/state
> Command to enter deep sleep mode.
> echo mem > /sys/power/state
>=20
> Signed-off-by: Dave Liu <daveliu@freescale.com>
> Signed-off-by: Li Yang <leoli@freescale.com>
> Signed-off-by: Jin Qing <b24347@freescale.com>
> Signed-off-by: Jerry Huang <Chang-Ming.Huang@freescale.com>
> Cc: Scott Wood <scottwood@freescale.com>
> Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com>
> ---
> Changes for v6:
> * changed the declaration of flush_dcache_L1()
> * some minor changes
>=20
> arch/powerpc/Kconfig | 2 +-
> arch/powerpc/include/asm/cacheflush.h | 2 +
> arch/powerpc/kernel/Makefile | 3 +
> arch/powerpc/kernel/l2cache_85xx.S | 53 +++
> arch/powerpc/platforms/85xx/Makefile | 2 +-
> arch/powerpc/platforms/85xx/sleep.S | 609 =
+++++++++++++++++++++++++++++++++
> arch/powerpc/sysdev/fsl_pmc.c | 98 +++++-
> arch/powerpc/sysdev/fsl_soc.h | 5 +
> 8 files changed, 754 insertions(+), 20 deletions(-)
> create mode 100644 arch/powerpc/kernel/l2cache_85xx.S
> create mode 100644 arch/powerpc/platforms/85xx/sleep.S
>=20
> diff --git a/arch/powerpc/kernel/l2cache_85xx.S =
b/arch/powerpc/kernel/l2cache_85xx.S
> new file mode 100644
> index 0000000..b0b7d1c
> --- /dev/null
> +++ b/arch/powerpc/kernel/l2cache_85xx.S
> @@ -0,0 +1,53 @@
> +/*
> + * Copyright (C) 2009-2012 Freescale Semiconductor, Inc. All rights =
reserved.
> + * Scott Wood <scottwood@freescale.com>
> + * Dave Liu <daveliu@freescale.com>
> + * implement the L2 cache operations of e500 based L2 controller
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include <asm/reg.h>
> +#include <asm/cputable.h>
> +#include <asm/ppc_asm.h>
> +#include <asm/asm-offsets.h>
> +
> + .section .text
> +
> + /* r3 =3D virtual address of L2 controller, WIMG =3D 01xx */
> +_GLOBAL(flush_disable_L2)
> + /* It's a write-through cache, so only invalidation is needed. =
*/
> + mbar
> + isync
> + lwz r4, 0(r3)
> + li r5, 1
> + rlwimi r4, r5, 30, 0xc0000000
Can 0xc0000000 be a #define for what I'm guessing is L2E and L2I?
> + stw r4, 0(r3)
> +
> + /* Wait for the invalidate to finish */
> +1: lwz r4, 0(r3)
> + andis. r4, r4, 0x4000
#define for 0x4000 -> L2I@h
> + bne 1b
> + mbar
> +
> + blr
> +
> + /* r3 =3D virtual address of L2 controller, WIMG =3D 01xx */
> +_GLOBAL(invalidate_enable_L2)
> + mbar
> + isync
> + lwz r4, 0(r3)
> + li r5, 3
> + rlwimi r4, r5, 30, 0xc0000000
> + stw r4, 0(r3)
> +
> + /* Wait for the invalidate to finish */
> +1: lwz r4, 0(r3)
> + andis. r4, r4, 0x4000
same comments as above about #defines.
> + bne 1b
> + mbar
> +
> + blr
> diff --git a/arch/powerpc/platforms/85xx/Makefile =
b/arch/powerpc/platforms/85xx/Makefile
> index 2125d4c..d154e39 100644
> --- a/arch/powerpc/platforms/85xx/Makefile
> +++ b/arch/powerpc/platforms/85xx/Makefile
> @@ -3,7 +3,7 @@
> #
> obj-$(CONFIG_SMP) +=3D smp.o
>=20
> -obj-y +=3D common.o
> +obj-y +=3D common.o sleep.o
>=20
> obj-$(CONFIG_MPC8540_ADS) +=3D mpc85xx_ads.o
> obj-$(CONFIG_MPC8560_ADS) +=3D mpc85xx_ads.o
> diff --git a/arch/powerpc/platforms/85xx/sleep.S =
b/arch/powerpc/platforms/85xx/sleep.S
> new file mode 100644
> index 0000000..b272f0c
> --- /dev/null
> +++ b/arch/powerpc/platforms/85xx/sleep.S
> @@ -0,0 +1,609 @@
> +/*
> + * Enter and leave deep sleep/sleep state on MPC85xx
> + *
> + * Author: Scott Wood <scottwood@freescale.com>
> + *
> + * Copyright (C) 2006-2012 Freescale Semiconductor, Inc. All rights =
reserved.
> + *
> + * This program is free software; you can redistribute it and/or =
modify it
> + * under the terms of the GNU General Public License version 2 as =
published
> + * by the Free Software Foundation.
> + */
> +
> +#include <asm/page.h>
> +#include <asm/ppc_asm.h>
> +#include <asm/reg.h>
> +#include <asm/asm-offsets.h>
> +
> +#define SS_TB 0x00
> +#define SS_HID 0x08 /* 2 HIDs */
> +#define SS_IAC 0x10 /* 2 IACs */
> +#define SS_DAC 0x18 /* 2 DACs */
> +#define SS_DBCR 0x20 /* 3 DBCRs */
> +#define SS_PID 0x2c /* 3 PIDs */
> +#define SS_SPRG 0x38 /* 8 SPRGs */
> +#define SS_IVOR 0x58 /* 20 interrupt vectors */
> +#define SS_TCR 0xa8
> +#define SS_BUCSR 0xac
> +#define SS_L1CSR 0xb0 /* 2 L1CSRs */
> +#define SS_MSR 0xb8
> +#define SS_USPRG 0xbc
> +#define SS_GPREG 0xc0 /* r12-r31 */
> +#define SS_LR 0x110
> +#define SS_CR 0x114
> +#define SS_SP 0x118
> +#define SS_CURRENT 0x11c
> +#define SS_IVPR 0x120
> +#define SS_BPTR 0x124
> +
> +
> +#define STATE_SAVE_SIZE 0x128
> +
> + .section .data
> + .align 5
> +mpc85xx_sleep_save_area:
> + .space STATE_SAVE_SIZE
> +ccsrbase_low:
> + .long 0
> +ccsrbase_high:
> + .long 0
> +powmgtreq:
> + .long 0
> +
> + .section .text
> + .align 12
> +
> + /*
> + * r3 =3D high word of physical address of CCSR
> + * r4 =3D low word of physical address of CCSR
> + * r5 =3D JOG or deep sleep request
> + * JOG-0x00200000, deep sleep-0x00100000
> + */
> +_GLOBAL(mpc85xx_enter_deep_sleep)
> + lis r6, ccsrbase_low@ha
> + stw r4, ccsrbase_low@l(r6)
> + lis r6, ccsrbase_high@ha
> + stw r3, ccsrbase_high@l(r6)
> +
> + lis r6, powmgtreq@ha
> + stw r5, powmgtreq@l(r6)
> +
> + lis r10, mpc85xx_sleep_save_area@h
> + ori r10, r10, mpc85xx_sleep_save_area@l
> +
> + mfspr r5, SPRN_HID0
> + mfspr r6, SPRN_HID1
> +
> + stw r5, SS_HID+0(r10)
> + stw r6, SS_HID+4(r10)
> +
> + mfspr r4, SPRN_IAC1
> + mfspr r5, SPRN_IAC2
> + mfspr r6, SPRN_DAC1
> + mfspr r7, SPRN_DAC2
> +
> + stw r4, SS_IAC+0(r10)
> + stw r5, SS_IAC+4(r10)
> + stw r6, SS_DAC+0(r10)
> + stw r7, SS_DAC+4(r10)
> +
> + mfspr r4, SPRN_DBCR0
> + mfspr r5, SPRN_DBCR1
> + mfspr r6, SPRN_DBCR2
> +
> + stw r4, SS_DBCR+0(r10)
> + stw r5, SS_DBCR+4(r10)
> + stw r6, SS_DBCR+8(r10)
> +
> + mfspr r4, SPRN_PID0
> + mfspr r5, SPRN_PID1
> + mfspr r6, SPRN_PID2
> +
> + stw r4, SS_PID+0(r10)
> + stw r5, SS_PID+4(r10)
> + stw r6, SS_PID+8(r10)
> +
> + mfspr r4, SPRN_SPRG0
> + mfspr r5, SPRN_SPRG1
> + mfspr r6, SPRN_SPRG2
> + mfspr r7, SPRN_SPRG3
> +
> + stw r4, SS_SPRG+0x00(r10)
> + stw r5, SS_SPRG+0x04(r10)
> + stw r6, SS_SPRG+0x08(r10)
> + stw r7, SS_SPRG+0x0c(r10)
> +
> + mfspr r4, SPRN_SPRG4
> + mfspr r5, SPRN_SPRG5
> + mfspr r6, SPRN_SPRG6
> + mfspr r7, SPRN_SPRG7
> +
> + stw r4, SS_SPRG+0x10(r10)
> + stw r5, SS_SPRG+0x14(r10)
> + stw r6, SS_SPRG+0x18(r10)
> + stw r7, SS_SPRG+0x1c(r10)
> +
> + mfspr r4, SPRN_IVPR
> + stw r4, SS_IVPR(r10)
> +
> + mfspr r4, SPRN_IVOR0
> + mfspr r5, SPRN_IVOR1
> + mfspr r6, SPRN_IVOR2
> + mfspr r7, SPRN_IVOR3
> +
> + stw r4, SS_IVOR+0x00(r10)
> + stw r5, SS_IVOR+0x04(r10)
> + stw r6, SS_IVOR+0x08(r10)
> + stw r7, SS_IVOR+0x0c(r10)
> +
> + mfspr r4, SPRN_IVOR4
> + mfspr r5, SPRN_IVOR5
> + mfspr r6, SPRN_IVOR6
> + mfspr r7, SPRN_IVOR7
> +
> + stw r4, SS_IVOR+0x10(r10)
> + stw r5, SS_IVOR+0x14(r10)
> + stw r6, SS_IVOR+0x18(r10)
> + stw r7, SS_IVOR+0x1c(r10)
> +
> + mfspr r4, SPRN_IVOR8
> + mfspr r5, SPRN_IVOR9
> + mfspr r6, SPRN_IVOR10
> + mfspr r7, SPRN_IVOR11
> +
> + stw r4, SS_IVOR+0x20(r10)
> + stw r5, SS_IVOR+0x24(r10)
> + stw r6, SS_IVOR+0x28(r10)
> + stw r7, SS_IVOR+0x2c(r10)
> +
> + mfspr r4, SPRN_IVOR12
> + mfspr r5, SPRN_IVOR13
> + mfspr r6, SPRN_IVOR14
> + mfspr r7, SPRN_IVOR15
> +
> + stw r4, SS_IVOR+0x30(r10)
> + stw r5, SS_IVOR+0x34(r10)
> + stw r6, SS_IVOR+0x38(r10)
> + stw r7, SS_IVOR+0x3c(r10)
> +
> + mfspr r4, SPRN_IVOR32
> + mfspr r5, SPRN_IVOR33
> + mfspr r6, SPRN_IVOR34
> + mfspr r7, SPRN_IVOR35
> +
> + stw r4, SS_IVOR+0x40(r10)
> + stw r5, SS_IVOR+0x44(r10)
> + stw r6, SS_IVOR+0x48(r10)
> + stw r7, SS_IVOR+0x4c(r10)
> +
> + mfspr r4, SPRN_TCR
> + mfspr r5, SPRN_BUCSR
> + mfspr r6, SPRN_L1CSR0
> + mfspr r7, SPRN_L1CSR1
> + mfspr r8, SPRN_USPRG0
> +
> + stw r4, SS_TCR(r10)
> + stw r5, SS_BUCSR(r10)
> + stw r6, SS_L1CSR+0(r10)
> + stw r7, SS_L1CSR+4(r10)
> + stw r8, SS_USPRG+0(r10)
> +
> + stmw r12, SS_GPREG(r10)
> +
> + mfmsr r4
> + mflr r5
> + mfcr r6
> +
> + stw r4, SS_MSR(r10)
> + stw r5, SS_LR(r10)
> + stw r6, SS_CR(r10)
> + stw r1, SS_SP(r10)
> + stw r2, SS_CURRENT(r10)
> +
> +1: mftbu r4
> + mftb r5
> + mftbu r6
> + cmpw r4, r6
> + bne 1b
> +
> + stw r4, SS_TB+0(r10)
> + stw r5, SS_TB+4(r10)
> +
> + lis r5, ccsrbase_low@ha
> + lwz r4, ccsrbase_low@l(r5)
> + lis r5, ccsrbase_high@ha
> + lwz r3, ccsrbase_high@l(r5)
> +
> + /* Disable machine checks and critical exceptions */
> + mfmsr r5
> + rlwinm r5, r5, 0, ~MSR_CE
> + rlwinm r5, r5, 0, ~MSR_ME
> + mtmsr r5
> + isync
> +
> + /* Use TLB1[15] to map the CCSR at 0xf0000000 */
> + lis r5, 0x100f
> + mtspr SPRN_MAS0, r5
> + lis r5, 0xc000
> + ori r5, r5, 0x0500
> + mtspr SPRN_MAS1, r5
> + lis r5, 0xf000
> + ori r5, r5, 0x000a
> + mtspr SPRN_MAS2, r5
> + rlwinm r5, r4, 0, 0xfffff000
> + ori r5, r5, 0x0005
We have #defines that should be used instead of magic numbers for MAS =
defines/fields.
> + mtspr SPRN_MAS3, r5
> + mtspr SPRN_MAS7, r3
> + isync
> + tlbwe
> + isync
> +
> + lis r3, 0xf000
> + lwz r4, 0x20(r3)
> + stw r4, SS_BPTR(r10)
> +
> + lis r3, 0xf002 /* L2 cache controller at CCSR+0x20000 =
*/
> + bl flush_disable_L2
> + bl __flush_disable_L1
> +
> + /* Enable I-cache, so as not to upset the bus
> + * with our loop.
> + */
> +
> + mfspr r4, SPRN_L1CSR1
> + ori r4, r4, 1
> + mtspr SPRN_L1CSR1, r4
> + isync
> +
> + /* Set boot page translation */
> + lis r3, 0xf000
> + lis r4, (mpc85xx_deep_resume - PAGE_OFFSET)@h
> + ori r4, r4, (mpc85xx_deep_resume - PAGE_OFFSET)@l
> + rlwinm r4, r4, 20, 0x000fffff
> + oris r4, r4, 0x8000
> + stw r4, 0x20(r3)
> + lwz r4, 0x20(r3) /* read-back to flush write */
> + twi 0, r4, 0
> + isync
> +
> + /* Disable the decrementer */
> + mfspr r4, SPRN_TCR
> + rlwinm r4, r4, 0, ~TCR_DIE
> + mtspr SPRN_TCR, r4
> +
> + mfspr r4, SPRN_TSR
> + oris r4, r4, TSR_DIS@h
> + mtspr SPRN_TSR, r4
> +
> + /* set PMRCCR[VRCNT] to wait power stable for 40ms */
> + lis r3, 0xf00e
> + lwz r4, 0x84(r3)
> + clrlwi r4, r4, 16
> + oris r4, r4, 0x12a3
> + stw r4, 0x84(r3)
> + lwz r4, 0x84(r3)
#defines here for magic numbers?
> +
> + /* set deep sleep bit in POWMGTSCR */
> + lis r3, powmgtreq@ha
> + lwz r8, powmgtreq@l(r3)
> +
> + lis r3, 0xf00e
> + lwz r4, 0x80(r3)
> + or r4, r4, r8
> + stw r4, 0x80(r3)
> + lwz r4, 0x80(r3) /* read-back to flush write */
> + twi 0, r4, 0
> + isync
#defines here for magic numbers?
> +
> + mftb r5
> +1: /* spin until either we enter deep sleep, or the sleep process =
is
> + * aborted due to a pending wakeup event. Wait some time =
between
> + * accesses, so we don't flood the bus and prevent the pmc from
> + * detecting an idle system.
> + */
> +
> + mftb r4
> + subf r7, r5, r4
> + cmpwi r7, 1000
> + blt 1b
> + mr r5, r4
> +
> + lwz r6, 0x80(r3)
> + andis. r6, r6, 0x0010
> + bne 1b
> + b 2f
#defines here for magic numbers?
> +
> +2: mfspr r4, SPRN_PIR
> + andi. r4, r4, 1
> +99: bne 99b
> +
> + /* Establish a temporary 64MB 0->0 mapping in TLB1[1]. */
> + lis r4, 0x1001
> + mtspr SPRN_MAS0, r4
> + lis r4, 0xc000
> + ori r4, r4, 0x0800
> + mtspr SPRN_MAS1, r4
> + li r4, 0
> + mtspr SPRN_MAS2, r4
> + li r4, 0x0015
> + mtspr SPRN_MAS3, r4
> + li r4, 0
> + mtspr SPRN_MAS7, r4
Same comment as above about #defines for MAS regs
> + isync
> + tlbwe
> + isync
> +
> + lis r3, (3f - PAGE_OFFSET)@h
> + ori r3, r3, (3f - PAGE_OFFSET)@l
> + mtctr r3
> + bctr
> +
> + /* Locate the resume vector in the last word of the current =
page. */
> + . =3D mpc85xx_enter_deep_sleep + 0xffc
> +mpc85xx_deep_resume:
> + b 2b
> +
> +3:
> + /* Restore the contents of TLB1[0]. It is assumed that it =
covers
> + * the currently executing code and the sleep save area, and =
that
> + * it does not alias our temporary mapping (which is at virtual =
zero).
> + */
> + lis r3, (TLBCAM - PAGE_OFFSET)@h
> + ori r3, r3, (TLBCAM - PAGE_OFFSET)@l
> +
> + lwz r4, 0(r3)
> + lwz r5, 4(r3)
> + lwz r6, 8(r3)
> + lwz r7, 12(r3)
> + lwz r8, 16(r3)
> +
> + mtspr SPRN_MAS0, r4
> + mtspr SPRN_MAS1, r5
> + mtspr SPRN_MAS2, r6
> + mtspr SPRN_MAS3, r7
> + mtspr SPRN_MAS7, r8
> +
> + isync
> + tlbwe
> + isync
> +
> + /* Access the ccsrbase address with TLB1[0] */
> + lis r5, ccsrbase_low@ha
> + lwz r4, ccsrbase_low@l(r5)
> + lis r5, ccsrbase_high@ha
> + lwz r3, ccsrbase_high@l(r5)
> +
> + /* Use TLB1[15] to map the CCSR at 0xf0000000 */
> + lis r5, 0x100f
> + mtspr SPRN_MAS0, r5
> + lis r5, 0xc000
> + ori r5, r5, 0x0500
> + mtspr SPRN_MAS1, r5
> + lis r5, 0xf000
> + ori r5, r5, 0x000a
> + mtspr SPRN_MAS2, r5
> + rlwinm r5, r4, 0, 0xfffff000
> + ori r5, r5, 0x0005
> + mtspr SPRN_MAS3, r5
> + mtspr SPRN_MAS7, r3
Same comment as above about #defines for MAS regs
> + isync
> + tlbwe
> + isync
> +
> + lis r3, 0xf002 /* L2 cache controller at CCSR+0x20000 =
*/
> + bl invalidate_enable_L2
> +
> + /* Access the MEM(r10) with TLB1[0] */
> + lis r10, mpc85xx_sleep_save_area@h
> + ori r10, r10, mpc85xx_sleep_save_area@l
> +
> + lis r3, 0xf000
> + lwz r4, SS_BPTR(r10)
> + stw r4, 0x20(r3) /* restore BPTR */
> +
> + /* Program shift running space to PAGE_OFFSET */
> + mfmsr r3
> + lis r4, 1f@h
> + ori r4, r4, 1f@l
> +
> + mtsrr1 r3
> + mtsrr0 r4
> + rfi
> +
> +1: /* Restore the rest of TLB1, in ascending order so that
> + * the TLB1[1] gets invalidated first.
> + *
> + * XXX: It's better to invalidate the temporary mapping
> + * TLB1[15] for CCSR before restore any TLB1 entry include 0.
> + */
> + lis r4, 0x100f
> + mtspr SPRN_MAS0, r4
> + lis r4, 0
> + mtspr SPRN_MAS1, r4
> + isync
> + tlbwe
> + isync
> +
> + lis r3, (TLBCAM + 5*4 - 4)@h
> + ori r3, r3, (TLBCAM + 5*4 - 4)@l
> + li r4, 15
> + mtctr r4
> +
> +2:
> + lwz r5, 4(r3)
> + lwz r6, 8(r3)
> + lwz r7, 12(r3)
> + lwz r8, 16(r3)
> + lwzu r9, 20(r3)
> +
> + mtspr SPRN_MAS0, r5
> + mtspr SPRN_MAS1, r6
> + mtspr SPRN_MAS2, r7
> + mtspr SPRN_MAS3, r8
> + mtspr SPRN_MAS7, r9
> +
> + isync
> + tlbwe
> + isync
> + bdnz 2b
> +
> + lis r10, mpc85xx_sleep_save_area@h
> + ori r10, r10, mpc85xx_sleep_save_area@l
> +
> + lwz r5, SS_HID+0(r10)
> + lwz r6, SS_HID+4(r10)
> +
> + isync
> + mtspr SPRN_HID0, r5
> + isync
> +
> + msync
> + mtspr SPRN_HID1, r6
> + isync
> +
> + lwz r4, SS_IAC+0(r10)
> + lwz r5, SS_IAC+4(r10)
> + lwz r6, SS_DAC+0(r10)
> + lwz r7, SS_DAC+4(r10)
> +
> + mtspr SPRN_IAC1, r4
> + mtspr SPRN_IAC2, r5
> + mtspr SPRN_DAC1, r6
> + mtspr SPRN_DAC2, r7
> +
> + lwz r4, SS_DBCR+0(r10)
> + lwz r5, SS_DBCR+4(r10)
> + lwz r6, SS_DBCR+8(r10)
> +
> + mtspr SPRN_DBCR0, r4
> + mtspr SPRN_DBCR1, r5
> + mtspr SPRN_DBCR2, r6
> +
> + lwz r4, SS_PID+0(r10)
> + lwz r5, SS_PID+4(r10)
> + lwz r6, SS_PID+8(r10)
> +
> + mtspr SPRN_PID0, r4
> + mtspr SPRN_PID1, r5
> + mtspr SPRN_PID2, r6
> +
> + lwz r4, SS_SPRG+0x00(r10)
> + lwz r5, SS_SPRG+0x04(r10)
> + lwz r6, SS_SPRG+0x08(r10)
> + lwz r7, SS_SPRG+0x0c(r10)
> +
> + mtspr SPRN_SPRG0, r4
> + mtspr SPRN_SPRG1, r5
> + mtspr SPRN_SPRG2, r6
> + mtspr SPRN_SPRG3, r7
> +
> + lwz r4, SS_SPRG+0x10(r10)
> + lwz r5, SS_SPRG+0x14(r10)
> + lwz r6, SS_SPRG+0x18(r10)
> + lwz r7, SS_SPRG+0x1c(r10)
> +
> + mtspr SPRN_SPRG4, r4
> + mtspr SPRN_SPRG5, r5
> + mtspr SPRN_SPRG6, r6
> + mtspr SPRN_SPRG7, r7
> +
> + lwz r4, SS_IVPR(r10)
> + mtspr SPRN_IVPR, r4
> +
> + lwz r4, SS_IVOR+0x00(r10)
> + lwz r5, SS_IVOR+0x04(r10)
> + lwz r6, SS_IVOR+0x08(r10)
> + lwz r7, SS_IVOR+0x0c(r10)
> +
> + mtspr SPRN_IVOR0, r4
> + mtspr SPRN_IVOR1, r5
> + mtspr SPRN_IVOR2, r6
> + mtspr SPRN_IVOR3, r7
> +
> + lwz r4, SS_IVOR+0x10(r10)
> + lwz r5, SS_IVOR+0x14(r10)
> + lwz r6, SS_IVOR+0x18(r10)
> + lwz r7, SS_IVOR+0x1c(r10)
> +
> + mtspr SPRN_IVOR4, r4
> + mtspr SPRN_IVOR5, r5
> + mtspr SPRN_IVOR6, r6
> + mtspr SPRN_IVOR7, r7
> +
> + lwz r4, SS_IVOR+0x20(r10)
> + lwz r5, SS_IVOR+0x24(r10)
> + lwz r6, SS_IVOR+0x28(r10)
> + lwz r7, SS_IVOR+0x2c(r10)
> +
> + mtspr SPRN_IVOR8, r4
> + mtspr SPRN_IVOR9, r5
> + mtspr SPRN_IVOR10, r6
> + mtspr SPRN_IVOR11, r7
> +
> + lwz r4, SS_IVOR+0x30(r10)
> + lwz r5, SS_IVOR+0x34(r10)
> + lwz r6, SS_IVOR+0x38(r10)
> + lwz r7, SS_IVOR+0x3c(r10)
> +
> + mtspr SPRN_IVOR12, r4
> + mtspr SPRN_IVOR13, r5
> + mtspr SPRN_IVOR14, r6
> + mtspr SPRN_IVOR15, r7
> +
> + lwz r4, SS_IVOR+0x40(r10)
> + lwz r5, SS_IVOR+0x44(r10)
> + lwz r6, SS_IVOR+0x48(r10)
> + lwz r7, SS_IVOR+0x4c(r10)
> +
> + mtspr SPRN_IVOR32, r4
> + mtspr SPRN_IVOR33, r5
> + mtspr SPRN_IVOR34, r6
> + mtspr SPRN_IVOR35, r7
> +
> + lwz r4, SS_TCR(r10)
> + lwz r5, SS_BUCSR(r10)
> + lwz r6, SS_L1CSR+0(r10)
> + lwz r7, SS_L1CSR+4(r10)
> + lwz r8, SS_USPRG+0(r10)
> +
> + mtspr SPRN_TCR, r4
> + mtspr SPRN_BUCSR, r5
> +
> + msync
> + isync
> + mtspr SPRN_L1CSR0, r6
> + isync
> +
> + mtspr SPRN_L1CSR1, r7
> + isync
> +
> + mtspr SPRN_USPRG0, r8
> +
> + lmw r12, SS_GPREG(r10)
> +
> + lwz r1, SS_SP(r10)
> + lwz r2, SS_CURRENT(r10)
> + lwz r4, SS_MSR(r10)
> + lwz r5, SS_LR(r10)
> + lwz r6, SS_CR(r10)
> +
> + msync
> + mtmsr r4
> + isync
> +
> + mtlr r5
> + mtcr r6
> +
> + li r4, 0
> + mtspr SPRN_TBWL, r4
> +
> + lwz r4, SS_TB+0(r10)
> + lwz r5, SS_TB+4(r10)
> +
> + mtspr SPRN_TBWU, r4
> + mtspr SPRN_TBWL, r5
> +
> + lis r3, 1
> + mtdec r3
> +
> + blr
^ permalink raw reply
* Re: [PATCH] ppc44x/watchdog: Select WATCHDOG_NOWAYOUT option
From: Kumar Gala @ 2012-07-13 12:52 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev, Jiang Lu
In-Reply-To: <CA+5PVA6RG1m8c2OUL2g0gBK7dRCrmeu47rZfoqAjxODm1zcNRg@mail.gmail.com>
On Jul 13, 2012, at 7:25 AM, Josh Boyer wrote:
> On Fri, Jul 13, 2012 at 7:50 AM, Kumar Gala =
<galak@kernel.crashing.org> wrote:
>>=20
>> On Jul 12, 2012, at 9:44 PM, Jiang Lu wrote:
>>=20
>>> On PPC44x core, the WRC(Watchdog-timer Reset Control) field of TCR
>>> of timer can not reset by software after set to a non-zero value.
>>> Which means software can not reset the timeout behaviour of watchdog =
timer.
>>>=20
>>> This patch selects WATCHDOG_NOWAYOUT option for 44x platforms to
>>> indicate the watchdog timer can not be disabled once fired.
>>>=20
>>> Signed-off-by: Jiang Lu <lu.jiang@windriver.com>
>>> ---
>>> drivers/watchdog/Kconfig | 1 +
>>> 1 files changed, 1 insertions(+), 0 deletions(-)
>>=20
>> I believe this is not 44x specific, but how Book-E watchdog is =
architected.
>=20
> That is my understanding as well.
>=20
>>> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
>>> index 3709624..41f3dff 100644
>>> --- a/drivers/watchdog/Kconfig
>>> +++ b/drivers/watchdog/Kconfig
>>> @@ -1084,6 +1084,7 @@ config PIKA_WDT
>>> config BOOKE_WDT
>>> tristate "PowerPC Book-E Watchdog Timer"
>>> depends on BOOKE || 4xx
>>> + select WATCHDOG_NOWAYOUT if 44x
>>=20
>> This should probably be 'select WATCHDOG_NOWAYOUT if BOOKE'
>=20
> I kind of disagree with this change. It's a user selectable option =
for
> a reason.
>=20
> Right now, if the option is not set we call booke_wdt_disable which
> indeed does not actually _disable_ the WDT, but it does set the timer
> period to the maxium value. We could go one step further and =
implement
> a simple timer that pops and calls booke_wdt_ping if WATCHDOG_NOWAYOUT
> is not set, then rearms itself. That would leave the user with the
> ability to perform recovery of the userspace process that exited or
> died and was responsible for pinging the watchdog.
>=20
> josh
My only care was about it being Book-E and not 44x. Otherwise I'm happy =
to defer to your take on this.
- k
^ permalink raw reply
* RE: Standalone SRIO Driver for Linux
From: Bounine, Alexandre @ 2012-07-13 12:48 UTC (permalink / raw)
To: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <CAEqOc-QpXcwbLuJXLbGv3VgccKnkMrdGV+ZdwFaFZCzjG3K7Mw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1451 bytes --]
This should work. We use similar approach to test our mport HW drivers.
Alex.
From: Linuxppc-dev [mailto:linuxppc-dev-bounces+alexandre.bounine=idt.com@lists.ozlabs.org] On Behalf Of Saravanan S
Sent: Friday, July 13, 2012 2:16 AM
To: linuxppc-dev@lists.ozlabs.org
Subject: Standalone SRIO Driver for Linux
Hi ,
Iam currently working on the GE make DSP230 board consisting of Quad PowerPC8640 nodes interconnected by SRIO with Linux 2.6.34 . However the only way to access the SRIO is through rionet facility . Our requirement is to use the SRIO interconnect without the Ethernet overheads. This would definitely enable higher speeds (though I cant find any throughput figures for SRIO in Linux on the net ??? ). My query is that whether any attempt has been made to develop a standalone driver and API to access the messaging and doorbell services of SRIO . If no then request you to please provide inputs on the same. From my study I have the following thoughts for the driver :
a) Have a character device interface for user .
b) Basically use the rio support functions provided in rio.c like rio_add_inb_buffer , rio_add_outb_message to transfer and receive messages and add buffers .
c) Maintain a dedicated ring of buffers in the driver and transfer data to and from the buffer to user space .
Is this the right direction . Would really appreciate any inputs . thanks in advance.
Regards,
S.Saravanan
[-- Attachment #2: Type: text/html, Size: 4340 bytes --]
^ permalink raw reply
* P1022DS board support upstream?
From: Kumar Gala @ 2012-07-13 13:01 UTC (permalink / raw)
To: linuxppc-dev@lists.ozlabs.org list; +Cc: Timur Tabi
Is the functionality of all of these SDK patches upstream now?
[ ignore commit id's ]
b257909 powerpc/85xx: p1022ds: disable the NAND flash node if video is =
enabled
ee260f4 powerpc/mpc85xx: p1022ds support the MTD for NOR and NAND flash
4be8bb6 powerpc/mpc85xx: 32bit address support for p1022ds
25f9408 powerpc/85xx: fix PCI and localbus properties in p1022ds.dts
1bcb442 powerpc/p1022ds/DTS: Add RTC support
05e5bc8 powerpc/85xx: create 32-bit DTS for the P1022DS
79111f3 powerpc/85xx: p1022ds: disable the NOR flash node if video is =
enabled
- k=
^ permalink raw reply
* Re: P1022DS board support upstream?
From: Kumar Gala @ 2012-07-13 13:36 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev@lists.ozlabs.org list, Timur Tabi
In-Reply-To: <1F81EF77-1E39-4D16-BB8B-24D5CA53F929@freescale.com>
On Jul 13, 2012, at 8:01 AM, Kumar Gala wrote:
> Is the functionality of all of these SDK patches upstream now?
>=20
> [ ignore commit id's ]
>=20
> b257909 powerpc/85xx: p1022ds: disable the NAND flash node if video is =
enabled
> ee260f4 powerpc/mpc85xx: p1022ds support the MTD for NOR and NAND =
flash
> 4be8bb6 powerpc/mpc85xx: 32bit address support for p1022ds
> 25f9408 powerpc/85xx: fix PCI and localbus properties in p1022ds.dts
> 1bcb442 powerpc/p1022ds/DTS: Add RTC support
> 05e5bc8 powerpc/85xx: create 32-bit DTS for the P1022DS
> 79111f3 powerpc/85xx: p1022ds: disable the NOR flash node if video is =
enabled
>=20
> - k
Please ignore, this was meant for out internal list.
Sorry for the noise.
- k
^ permalink raw reply
* Re: [PATCH] powerpc/85xx: L2sram: Add compatible string to the device id list
From: Kumar Gala @ 2012-07-13 13:54 UTC (permalink / raw)
To: <b29983@freescale.com>; +Cc: Tang Yuantian, linuxppc-dev
In-Reply-To: <1342146455-27729-1-git-send-email-b29983@freescale.com>
On Jul 12, 2012, at 9:27 PM, <b29983@freescale.com> =
<b29983@freescale.com> wrote:
> From: Tang Yuantian <Yuantian.Tang@freescale.com>
>=20
> The following platforms are supported:
> mpc8544, mpc8572, mpc8536, p1021, p1025, p1024, p1010.
>=20
> Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> ---
> arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | 10 ++++++++++
> 1 files changed, 10 insertions(+), 0 deletions(-)
applied to next
- k=
^ permalink raw reply
* Re: [PATCH] powerpc/85xx: Fix pci base address error for p2020rdb-pc in dts
From: Kumar Gala @ 2012-07-13 13:55 UTC (permalink / raw)
To: <b29983@freescale.com>; +Cc: Tang Yuantian, linuxppc-dev
In-Reply-To: <1342146455-27729-2-git-send-email-b29983@freescale.com>
On Jul 12, 2012, at 9:27 PM, <b29983@freescale.com> =
<b29983@freescale.com> wrote:
> From: Tang Yuantian <Yuantian.Tang@freescale.com>
>=20
> Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> ---
> arch/powerpc/boot/dts/p2020rdb-pc_32b.dts | 4 ++--
> arch/powerpc/boot/dts/p2020rdb-pc_36b.dts | 4 ++--
> 2 files changed, 4 insertions(+), 4 deletions(-)
applied to next
- k=
^ permalink raw reply
* [PATCH] powerpc/85xx: p1022ds: disable the NAND flash node if video is enabled
From: Timur Tabi @ 2012-07-13 19:28 UTC (permalink / raw)
To: Kumar Gala, linuxppc-dev
The Freescale P1022 has a unique pin muxing "feature" where the DIU video
controller's video signals are muxed with 24 of the local bus address signals.
When the DIU is enabled, the bulk of the local bus is disabled, preventing
access to memory-mapped devices like NAND flash and the pixis FPGA.
Therefore, if the DIU is going to be enabled, then memory-mapped devices on
the localbus, like NAND flash, need to be disabled.
This patch is similar to "powerpc/85xx: p1022ds: disable the NOR flash node
if video is enabled", except that it disables the NAND flash node instead.
This PIXIS node needs to remain enabled because it is used by platform code
to switch into indirect mode.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
arch/powerpc/platforms/85xx/p1022_ds.c | 58 +++++++++++++++++++++-----------
1 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index 89ee02c..5ca2823a 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -419,18 +419,6 @@ void __init p1022_ds_pic_init(void)
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
-/*
- * Disables a node in the device tree.
- *
- * This function is called before kmalloc() is available, so the 'new' object
- * should be allocated in the global area. The easiest way is to do that is
- * to allocate one static local variable for each call to this function.
- */
-static void __init disable_one_node(struct device_node *np, struct property *new)
-{
- prom_update_property(np, new);
-}
-
/* TRUE if there is a "video=fslfb" command-line parameter. */
static bool fslfb;
@@ -493,28 +481,58 @@ static void __init p1022_ds_setup_arch(void)
diu_ops.valid_monitor_port = p1022ds_valid_monitor_port;
/*
- * Disable the NOR flash node if there is video=fslfb... command-line
- * parameter. When the DIU is active, NOR flash is unavailable, so we
- * have to disable the node before the MTD driver loads.
+ * Disable the NOR and NAND flash nodes if there is video=fslfb...
+ * command-line parameter. When the DIU is active, the localbus is
+ * unavailable, so we have to disable these nodes before the MTD
+ * driver loads.
*/
if (fslfb) {
struct device_node *np =
of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc");
if (np) {
- np = of_find_compatible_node(np, NULL, "cfi-flash");
- if (np) {
+ struct device_node *np2;
+
+ of_node_get(np);
+ np2 = of_find_compatible_node(np, NULL, "cfi-flash");
+ if (np2) {
static struct property nor_status = {
.name = "status",
.value = "disabled",
.length = sizeof("disabled"),
};
+ /*
+ * prom_update_property() is called before
+ * kmalloc() is available, so the 'new' object
+ * should be allocated in the global area.
+ * The easiest way is to do that is to
+ * allocate one static local variable for each
+ * call to this function.
+ */
+ pr_info("p1022ds: disabling %s node",
+ np2->full_name);
+ prom_update_property(np2, &nor_status);
+ of_node_put(np2);
+ }
+
+ of_node_get(np);
+ np2 = of_find_compatible_node(np, NULL,
+ "fsl,elbc-fcm-nand");
+ if (np2) {
+ static struct property nand_status = {
+ .name = "status",
+ .value = "disabled",
+ .length = sizeof("disabled"),
+ };
+
pr_info("p1022ds: disabling %s node",
- np->full_name);
- disable_one_node(np, &nor_status);
- of_node_put(np);
+ np2->full_name);
+ prom_update_property(np2, &nand_status);
+ of_node_put(np2);
}
+
+ of_node_put(np);
}
}
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH 5/7] pci: minimal alignment for bars of P2P bridges
From: Bjorn Helgaas @ 2012-07-13 20:12 UTC (permalink / raw)
To: Gavin Shan; +Cc: linux-pci, yinghai, linuxram, linuxppc-dev
In-Reply-To: <878dcc914319fd110ceda936c2ce5b6bb7a449ab.1340949637.git.shangw@linux.vnet.ibm.com>
On Fri, Jun 29, 2012 at 02:47:48PM +0800, Gavin Shan wrote:
> On some powerpc platforms, device BARs need to be assigned to separate
> "segments" of the address space in order for the error isolation and HW
> virtualization mechanisms (EEH) to work properly. Those "segments" have
> a minimum size that can be fairly large (16M). In order to be able to
> use the generic resource assignment code rather than re-inventing our
> own, we chose to group devices by bus. That way, a simple change of the
> minimum alignment requirements of resources assigned to PCI to PCI (P2P)
> bridges is enough to ensure that all BARs for devices below those bridges
> will fit into contiguous sets of segments and there will be no overlap.
If I understand correctly, you might have something like this:
PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [mem 0xc0000000-0xcfffffff]
0000:00:01.0: PCI bridge to [bus 10-1f]
0000:00:01.0: bridge window [mem 0xc1000000-0xc1ffffff]
0000:00:02.0: PCI bridge to [bus 20-2f]
0000:00:02.0: bridge window [mem 0xc2000000-0xc2ffffff]
where everything under bridge 00:01.0 is in one EEH segment, and
everything under 00:02.0 is in another. In this case, each EEH
segment is 16MB.
I think your proposal is basically that when we add up resources required
below the P2P bridges, we round up to the default 1MB (the minimum P2P
bridge memory aperture size per spec) *or* to a larger value, e.g., 16MB,
if the architecture requires it.
That makes sense to me, but I have some implementation questions.
Your patches make the required alignment a property of the host bridge.
But don't you want to do this rounding up only at certain levels of the
hierarchy? For example, what if you had another P2P bridge:
0000:10:01.0: PCI bridge to [bus 18-1f]
I assume the devices on bus 0000:18 would still be in the first EEH
segment, and you wouldn't necessarily want to round up the 10:01.0
apertures to 16MB.
Maybe there should be an interface like this:
resource_size_t __weak pcibios_window_alignment(struct pci_bus *bus,
unsigned long type)
{
if (type & IORESOURCE_MEM)
return 1024*1024; /* mem windows must be 1MB aligned */
if (bus->self->io_window_1k)
return 1024;
return 4*1024; /* I/O windows default to 4K alignment */
}
that the arch could override? Then you could return the 16MB alignment
for the top-level P2P bridge leading to an EEH segment, and use the
default alignment for P2P bridges *inside* the segment.
> This patch provides a way for the host bridge to override the default
> alignment values used by the resource allocation code for that purpose.
>
> Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
> Reviewed-by: Ram Pai <linuxram@us.ibm.com>
> Reviewed-by: Richard Yang <weiyang@linux.vnet.ibm.com>
> ---
> drivers/pci/probe.c | 5 +++++
> include/linux/pci.h | 8 ++++++++
> 2 files changed, 13 insertions(+)
>
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 658ac97..a196529 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -431,6 +431,11 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
> if (bridge) {
> INIT_LIST_HEAD(&bridge->windows);
> bridge->bus = b;
> +
> + /* Set minimal alignment shift of P2P bridges */
> + bridge->io_align_shift = PCI_DEFAULT_IO_ALIGN_SHIFT;
> + bridge->mem_align_shift = PCI_DEFAULT_MEM_ALIGN_SHIFT;
> + bridge->pmem_align_shift = PCI_DEFAULT_PMEM_ALIGN_SHIFT;
> }
>
> return bridge;
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index e66f4b2..2b2b38d 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -376,9 +376,17 @@ struct pci_host_bridge_window {
> resource_size_t offset; /* bus address + offset = CPU address */
> };
>
> +/* Default shits for P2P I/O and MMIO bar minimal alignment shifts */
> +#define PCI_DEFAULT_IO_ALIGN_SHIFT 12 /* 4KB */
> +#define PCI_DEFAULT_MEM_ALIGN_SHIFT 20 /* 1MB */
> +#define PCI_DEFAULT_PMEM_ALIGN_SHIFT 20 /* 1MB */
> +
> struct pci_host_bridge {
> struct device dev;
> struct pci_bus *bus; /* root bus */
> + int io_align_shift; /* P2P I/O bar minimal alignment shift */
> + int mem_align_shift; /* P2P MMIO bar minimal alignment shift */
> + int pmem_align_shift; /* P2P prefetchable MMIO bar minimal alignment shift */
> struct list_head windows; /* pci_host_bridge_windows */
> void (*release_fn)(struct pci_host_bridge *);
> void *release_data;
> --
> 1.7.9.5
>
^ permalink raw reply
* [PATCH] powerpc/85xx: remove P1020RDB and P2020RDB CAMP device trees
From: Timur Tabi @ 2012-07-13 22:40 UTC (permalink / raw)
To: Kumar Gala, linuxppc-dev
We only need two examples of CAMP device trees in the upstream kernel.
Co-operative Asymmetric Multi-Processing (CAMP) is a technique where two
or more operating systems (typically multiple copies of the same Linux kernel)
are loaded into memory, and each kernel is given a subset of the available
cores to execute on. For example, on a four-core system, one kernel runs on
cores 0 and 1, and the other runs on cores 2 and 3.
The devices are also partitioned among the operating systems, and this is
done with customized device trees. Each kernel gets its own device tree
that has only the devices that it should know about.
Unfortunately, this approach is very hackish. The kernels are trusted to
only access devices in their respective device trees, and the partitioning
only works for devices that can be handled. Crafting the device trees is a
tricky process, and getting U-Boot to load and start all kernels is cumbersome.
But most importantly, each CAMP setup is very application-specific, since
the actual partitioning of resources is done in the DTS by the system
designer. Therefore, it doesn't make a lot of sense to have a lot of CAMP
device trees, since we only expect them to be used as examples.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
arch/powerpc/boot/dts/p1020rdb_camp_core0.dts | 63 -----------
arch/powerpc/boot/dts/p1020rdb_camp_core1.dts | 141 -------------------------
arch/powerpc/boot/dts/p2020rdb_camp_core0.dts | 67 ------------
arch/powerpc/boot/dts/p2020rdb_camp_core1.dts | 125 ----------------------
4 files changed, 0 insertions(+), 396 deletions(-)
delete mode 100644 arch/powerpc/boot/dts/p1020rdb_camp_core0.dts
delete mode 100644 arch/powerpc/boot/dts/p1020rdb_camp_core1.dts
delete mode 100644 arch/powerpc/boot/dts/p2020rdb_camp_core0.dts
delete mode 100644 arch/powerpc/boot/dts/p2020rdb_camp_core1.dts
diff --git a/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts b/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts
deleted file mode 100644
index 41b4585..0000000
--- a/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * P1020 RDB Core0 Device Tree Source in CAMP mode.
- *
- * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
- * can be shared, all the other devices must be assigned to one core only.
- * This dts file allows core0 to have memory, l2, i2c, spi, gpio, tdm, dma, usb,
- * eth1, eth2, sdhc, crypto, global-util, message, pci0, pci1, msi.
- *
- * Please note to add "-b 0" for core0's dts compiling.
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "p1020rdb.dts"
-
-/ {
- model = "fsl,P1020RDB";
- compatible = "fsl,P1020RDB", "fsl,MPC85XXRDB-CAMP";
-
- aliases {
- ethernet1 = &enet1;
- ethernet2 = &enet2;
- serial0 = &serial0;
- pci0 = &pci0;
- pci1 = &pci1;
- };
-
- cpus {
- PowerPC,P1020@1 {
- status = "disabled";
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- localbus@ffe05000 {
- status = "disabled";
- };
-
- soc@ffe00000 {
- serial1: serial@4600 {
- status = "disabled";
- };
-
- enet0: ethernet@b0000 {
- status = "disabled";
- };
-
- mpic: pic@40000 {
- protected-sources = <
- 42 29 30 34 /* serial1, enet0-queue-group0 */
- 17 18 24 45 /* enet0-queue-group1, crypto */
- >;
- };
- };
-};
diff --git a/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts b/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts
deleted file mode 100644
index 5174538..0000000
--- a/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * P1020 RDB Core1 Device Tree Source in CAMP mode.
- *
- * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
- * can be shared, all the other devices must be assigned to one core only.
- * This dts allows core1 to have l2, eth0, crypto.
- *
- * Please note to add "-b 1" for core1's dts compiling.
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "p1020rdb.dts"
-
-/ {
- model = "fsl,P1020RDB";
- compatible = "fsl,P1020RDB", "fsl,MPC85XXRDB-CAMP";
-
- aliases {
- ethernet0 = &enet0;
- serial0 = &serial1;
- };
-
- cpus {
- PowerPC,P1020@0 {
- status = "disabled";
- };
- };
-
- memory {
- device_type = "memory";
- };
-
- localbus@ffe05000 {
- status = "disabled";
- };
-
- soc@ffe00000 {
- ecm-law@0 {
- status = "disabled";
- };
-
- ecm@1000 {
- status = "disabled";
- };
-
- memory-controller@2000 {
- status = "disabled";
- };
-
- i2c@3000 {
- status = "disabled";
- };
-
- i2c@3100 {
- status = "disabled";
- };
-
- serial0: serial@4500 {
- status = "disabled";
- };
-
- spi@7000 {
- status = "disabled";
- };
-
- gpio: gpio-controller@f000 {
- status = "disabled";
- };
-
- dma@21300 {
- status = "disabled";
- };
-
- mdio@24000 {
- status = "disabled";
- };
-
- mdio@25000 {
- status = "disabled";
- };
-
- enet1: ethernet@b1000 {
- status = "disabled";
- };
-
- enet2: ethernet@b2000 {
- status = "disabled";
- };
-
- usb@22000 {
- status = "disabled";
- };
-
- sdhci@2e000 {
- status = "disabled";
- };
-
- mpic: pic@40000 {
- protected-sources = <
- 16 /* ecm, mem, L2, pci0, pci1 */
- 43 42 59 /* i2c, serial0, spi */
- 47 63 62 /* gpio, tdm */
- 20 21 22 23 /* dma */
- 03 02 /* mdio */
- 35 36 40 /* enet1-queue-group0 */
- 51 52 67 /* enet1-queue-group1 */
- 31 32 33 /* enet2-queue-group0 */
- 25 26 27 /* enet2-queue-group1 */
- 28 72 58 /* usb, sdhci, crypto */
- 0xb0 0xb1 0xb2 /* message */
- 0xb3 0xb4 0xb5
- 0xb6 0xb7
- 0xe0 0xe1 0xe2 /* msi */
- 0xe3 0xe4 0xe5
- 0xe6 0xe7 /* sdhci, crypto , pci */
- >;
- };
-
- msi@41600 {
- status = "disabled";
- };
-
- global-utilities@e0000 { //global utilities block
- status = "disabled";
- };
- };
-
- pci0: pcie@ffe09000 {
- status = "disabled";
- };
-
- pci1: pcie@ffe0a000 {
- status = "disabled";
- };
-};
diff --git a/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts b/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts
deleted file mode 100644
index 66aac86..0000000
--- a/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * P2020 RDB Core0 Device Tree Source in CAMP mode.
- *
- * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
- * can be shared, all the other devices must be assigned to one core only.
- * This dts file allows core0 to have memory, l2, i2c, spi, gpio, dma1, usb,
- * eth1, eth2, sdhc, crypto, global-util, pci0.
- *
- * Copyright 2009-2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "p2020rdb.dts"
-
-/ {
- model = "fsl,P2020RDB";
- compatible = "fsl,P2020RDB", "fsl,MPC85XXRDB-CAMP";
-
- cpus {
- PowerPC,P2020@1 {
- status = "disabled";
- };
- };
-
- localbus@ffe05000 {
- status = "disabled";
- };
-
- soc@ffe00000 {
- serial1: serial@4600 {
- status = "disabled";
- };
-
- dma@c300 {
- status = "disabled";
- };
-
- enet0: ethernet@24000 {
- status = "disabled";
- };
-
- mpic: pic@40000 {
- protected-sources = <
- 42 76 77 78 79 /* serial1 , dma2 */
- 29 30 34 26 /* enet0, pci1 */
- 0xe0 0xe1 0xe2 0xe3 /* msi */
- 0xe4 0xe5 0xe6 0xe7
- >;
- };
-
- msi@41600 {
- status = "disabled";
- };
- };
-
- pci0: pcie@ffe08000 {
- status = "disabled";
- };
-
- pci2: pcie@ffe0a000 {
- status = "disabled";
- };
-};
diff --git a/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts b/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts
deleted file mode 100644
index 9bd8ef4..0000000
--- a/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * P2020 RDB Core1 Device Tree Source in CAMP mode.
- *
- * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
- * can be shared, all the other devices must be assigned to one core only.
- * This dts allows core1 to have l2, dma2, eth0, pci1, msi.
- *
- * Please note to add "-b 1" for core1's dts compiling.
- *
- * Copyright 2009-2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-/include/ "p2020rdb.dts"
-
-/ {
- model = "fsl,P2020RDB";
- compatible = "fsl,P2020RDB", "fsl,MPC85XXRDB-CAMP";
-
- cpus {
- PowerPC,P2020@0 {
- status = "disabled";
- };
- };
-
- localbus@ffe05000 {
- status = "disabled";
- };
-
- soc@ffe00000 {
- ecm-law@0 {
- status = "disabled";
- };
-
- ecm@1000 {
- status = "disabled";
- };
-
- memory-controller@2000 {
- status = "disabled";
- };
-
- i2c@3000 {
- status = "disabled";
- };
-
- i2c@3100 {
- status = "disabled";
- };
-
- serial0: serial@4500 {
- status = "disabled";
- };
-
- spi@7000 {
- status = "disabled";
- };
-
- gpio: gpio-controller@f000 {
- status = "disabled";
- };
-
- dma@21300 {
- status = "disabled";
- };
-
- usb@22000 {
- status = "disabled";
- };
-
- mdio@24520 {
- status = "disabled";
- };
-
- mdio@25520 {
- status = "disabled";
- };
-
- mdio@26520 {
- status = "disabled";
- };
-
- enet1: ethernet@25000 {
- status = "disabled";
- };
-
- enet2: ethernet@26000 {
- status = "disabled";
- };
-
- sdhci@2e000 {
- status = "disabled";
- };
-
- crypto@30000 {
- status = "disabled";
- };
-
- mpic: pic@40000 {
- protected-sources = <
- 17 18 43 42 59 47 /*ecm, mem, i2c, serial0, spi,gpio */
- 16 20 21 22 23 28 /* L2, dma1, USB */
- 03 35 36 40 31 32 33 /* mdio, enet1, enet2 */
- 72 45 58 25 /* sdhci, crypto , pci */
- >;
- };
-
- global-utilities@e0000 { //global utilities block
- status = "disabled";
- };
-
- };
-
- pci0: pcie@ffe08000 {
- status = "disabled";
- };
-
- pci1: pcie@ffe09000 {
- status = "disabled";
- };
-};
--
1.7.3.4
^ permalink raw reply related
* Re: Standalone SRIO Driver for Linux
From: Saravanan S @ 2012-07-14 6:24 UTC (permalink / raw)
To: Bounine, Alexandre; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <8D983423E7EDF846BB3056827B8CC5D10285E9@corpmail1.na.ads.idt.com>
[-- Attachment #1: Type: text/plain, Size: 1939 bytes --]
Hi ,
Thanks for the reply . i will try to share some of my code later .
Looking forward to ur ideas.
Regards,
S.Saravanan
On Fri, Jul 13, 2012 at 6:18 PM, Bounine, Alexandre <
Alexandre.Bounine@idt.com> wrote:
> This should work. We use similar approach to test our mport HW drivers.**
> **
>
> ** **
>
> Alex.****
>
> ** **
>
> *From:* Linuxppc-dev [mailto:linuxppc-dev-bounces+alexandre.bounine=
> idt.com@lists.ozlabs.org] *On Behalf Of *Saravanan S
> *Sent:* Friday, July 13, 2012 2:16 AM
> *To:* linuxppc-dev@lists.ozlabs.org
> *Subject:* Standalone SRIO Driver for Linux****
>
> ** **
>
> Hi ,
>
> Iam currently working on the GE make DSP230 board consisting of Quad
> PowerPC8640 nodes interconnected by SRIO with Linux 2.6.34 . However the
> only way to access the SRIO is through rionet facility . Our requirement is
> to use the SRIO interconnect without the Ethernet overheads. This would
> definitely enable higher speeds (though I cant find any throughput figures
> for SRIO in Linux on the net ??? ). My query is that whether any attempt
> has been made to develop a standalone driver and API to access the
> messaging and doorbell services of SRIO . If no then request you to please
> provide inputs on the same. From my study I have the following thoughts for
> the driver :
>
> a) Have a character device interface for user .
> b) Basically use the rio support functions provided in rio.c like
> rio_add_inb_buffer , rio_add_outb_message to transfer and receive messages
> and add buffers .
> c) Maintain a dedicated ring of buffers in the driver and transfer data
> to and from the buffer to user space .
>
>
> Is this the right direction . Would really appreciate any inputs . thanks
> in advance.
>
> Regards,
>
> S.Saravanan****
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
[-- Attachment #2: Type: text/html, Size: 3843 bytes --]
^ permalink raw reply
* [PATCH] powerpc: SMT priority (PPR) save and restore
From: Haren Myneni @ 2012-07-14 9:43 UTC (permalink / raw)
To: benh, paulus, anton; +Cc: linuxppc-dev
powerpc: SMT priority (PPR) save and restore
On P7 systems, users can define SMT priority levels 2,3 and 4 for
processes so that some can run higher priority than the other ones.
In the current kernel, the default priority is set to 4 which prohibits
processes to use higher priority. Also the kernel boosts the priority to
4 during exception without saving the user defined priority values when
the task enters the kernel. So we will be loosing the process PPR value
and can not be restored it back when the task exits the kernel.
This patch sets the default priority to 3 when tasks are created such
that users can use 4 for higher priority tasks. It also provides to save
and restore the user defined priorities for all tasks.
When the task enters in to kernel space, the user defined priority (PPR)
will be saved in to PACA at the beginning of first level exception
vector and then copy from PACA to thread_info in second level vector.
PPR will be restored from thread_info before exits the kernel space.
P7 temporarily raises the thread priority to higher level during
exception until the program executes HMT_* calls. But it will not modify
PPR register. So we saves PPR value whenever some register is available
to use and then calls HMT_MEDIUM to increase the priority. This feature
supports on P7 or later processors.
Signed-off-by: Haren Myneni <hbabu@us.ibm.com>
diff --git a/arch/powerpc/include/asm/cputable.h
b/arch/powerpc/include/asm/cputable.h
index 50d82c8..e7b80d6 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -203,6 +203,7 @@ extern const char *powerpc_base_platform;
#define CPU_FTR_POPCNTD LONG_ASM_CONST(0x0800000000000000)
#define CPU_FTR_ICSWX LONG_ASM_CONST(0x1000000000000000)
#define CPU_FTR_VMX_COPY LONG_ASM_CONST(0x2000000000000000)
+#define CPU_FTR_HAS_PPR LONG_ASM_CONST(0x4000000000000000)
#ifndef __ASSEMBLY__
@@ -432,7 +433,8 @@ extern const char *powerpc_base_platform;
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD |
\
- CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY)
+ CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY |
\
+ CPU_FTR_HAS_PPR)
#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
diff --git a/arch/powerpc/include/asm/exception-64s.h
b/arch/powerpc/include/asm/exception-64s.h
index d58fc4e..1fae8aa 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -47,6 +47,7 @@
#define EX_R3 64
#define EX_LR 72
#define EX_CFAR 80
+#define EX_PPR 88 /* SMT thread status register (priority) */
/*
* We're short on space and time in the exception prolog, so we can't
@@ -61,10 +62,46 @@
#define EXC_HV H
#define EXC_STD
+/*
+ * PPR save/restore macros - Used only on P7 or later processors
+ */
+#define SAVE_PPR(area, ra, rb)
\
+BEGIN_FTR_SECTION_NESTED(940)
\
+ ld ra,area+EX_PPR(r13); /* Read PPR from paca */
\
+ clrrdi rb,r1,THREAD_SHIFT; /* thread_info struct */
\
+ std ra,TI_PPR(rb); /* Save PPR in thread_info */
\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,940)
+
+#define RESTORE_PPR(ra,rb)
\
+BEGIN_FTR_SECTION_NESTED(941)
\
+ clrrdi ra,r1,THREAD_SHIFT;
\
+ ld rb,TI_PPR(ra); /* Read PPR from thread_info */
\
+ mtspr SPRN_PPR,rb; /* Restore PPR */
\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,941)
+
+#define RESTORE_PPR_PACA(area,ra)
\
+BEGIN_FTR_SECTION_NESTED(942)
\
+ ld ra,area+EX_PPR(r13);
\
+ mtspr SPRN_PPR,ra;
\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,942)
+
+#define HMT_FTR_NO_PPR
\
+BEGIN_FTR_SECTION_NESTED(944) \
+ HMT_MEDIUM;
\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,0,944) /*non P7*/
+
+#define HMT_FTR_HAS_PPR(area, ra)
\
+BEGIN_FTR_SECTION_NESTED(943)
\
+ mfspr ra,SPRN_PPR; /* Read PPR */
\
+ std ra,area+EX_PPR(r13); /* Save PPR in paca */
\
+ HMT_MEDIUM;
\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,943) /* P7 */
+
#define __EXCEPTION_PROLOG_1(area, extra, vec) \
GET_PACA(r13); \
- std r9,area+EX_R9(r13); /* save r9 - r12 */ \
- std r10,area+EX_R10(r13); \
+ std r9,area+EX_R9(r13); /* save r9 */ \
+ HMT_FTR_HAS_PPR(area,r9); \
+ std r10,area+EX_R10(r13); /* save r10 - r12 */ \
BEGIN_FTR_SECTION_NESTED(66); \
mfspr r10,SPRN_CFAR; \
std r10,area+EX_CFAR(r13); \
@@ -176,8 +213,10 @@ do_kvm_##n: \
std r10,0(r1); /* make stack chain pointer */ \
std r0,GPR0(r1); /* save r0 in stackframe */ \
std r10,GPR1(r1); /* save r1 in stackframe */ \
+ beq 4f; \
ACCOUNT_CPU_USER_ENTRY(r9, r10); \
- std r2,GPR2(r1); /* save r2 in stackframe */ \
+ SAVE_PPR(area, r9, r10); \
+4: std r2,GPR2(r1); /* save r2 in stackframe */ \
SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \
SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \
ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \
@@ -218,7 +257,7 @@ do_kvm_##n: \
. = loc; \
.globl label##_pSeries; \
label##_pSeries: \
- HMT_MEDIUM; \
+ HMT_FTR_NO_PPR; \
SET_SCRATCH0(r13); /* save r13 */ \
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
EXC_STD, KVMTEST_PR, vec)
@@ -227,7 +266,7 @@ label##_pSeries: \
. = loc; \
.globl label##_hv; \
label##_hv: \
- HMT_MEDIUM; \
+ HMT_FTR_NO_PPR; \
SET_SCRATCH0(r13); /* save r13 */ \
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
EXC_HV, KVMTEST, vec)
@@ -258,7 +297,7 @@ label##_hv: \
_SOFTEN_TEST(EXC_STD, vec)
#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \
- HMT_MEDIUM; \
+ HMT_FTR_NO_PPR; \
SET_SCRATCH0(r13); /* save r13 */ \
__EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \
EXCEPTION_PROLOG_PSERIES_1(label##_common, h);
diff --git a/arch/powerpc/include/asm/paca.h
b/arch/powerpc/include/asm/paca.h
index daf813f..d32b1e5 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -93,9 +93,9 @@ struct paca_struct {
* Now, starting in cacheline 2, the exception save areas
*/
/* used for most interrupts/exceptions */
- u64 exgen[11] __attribute__((aligned(0x80)));
- u64 exmc[11]; /* used for machine checks */
- u64 exslb[11]; /* used for SLB/segment table misses
+ u64 exgen[12] __attribute__((aligned(0x80)));
+ u64 exmc[12]; /* used for machine checks */
+ u64 exslb[12]; /* used for SLB/segment table misses
* on the linear mapping */
/* SLB related definitions */
u16 vmalloc_sllp;
diff --git a/arch/powerpc/include/asm/ppc_asm.h
b/arch/powerpc/include/asm/ppc_asm.h
index 1544420..b5437a2 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -30,7 +30,6 @@
#define ACCOUNT_STOLEN_TIME
#else
#define ACCOUNT_CPU_USER_ENTRY(ra, rb) \
- beq 2f; /* if from kernel mode */ \
MFTB(ra); /* get timebase */ \
ld rb,PACA_STARTTIME_USER(r13); \
std ra,PACA_STARTTIME(r13); \
@@ -38,7 +37,6 @@
ld ra,PACA_USER_TIME(r13); \
add ra,ra,rb; /* add on to user time */ \
std ra,PACA_USER_TIME(r13); \
-2:
#define ACCOUNT_CPU_USER_EXIT(ra, rb) \
MFTB(ra); /* get timebase */ \
diff --git a/arch/powerpc/include/asm/reg.h
b/arch/powerpc/include/asm/reg.h
index f0cb7f4..1e61116 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -284,6 +284,7 @@
#define SPRN_DBAT6U 0x23C /* Data BAT 6 Upper Register */
#define SPRN_DBAT7L 0x23F /* Data BAT 7 Lower Register */
#define SPRN_DBAT7U 0x23E /* Data BAT 7 Upper Register */
+#define SPRN_PPR 0x380 /* Local SMT Thread status resgiter */
#define SPRN_DEC 0x016 /* Decrement Register */
#define SPRN_DER 0x095 /* Debug Enable Regsiter */
diff --git a/arch/powerpc/include/asm/thread_info.h
b/arch/powerpc/include/asm/thread_info.h
index 68831e9..618e35c 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -40,10 +40,22 @@ struct thread_info {
struct restart_block restart_block;
unsigned long local_flags; /* private flags for thread */
+#ifdef CONFIG_PPC64
+ unsigned long ppr; /* SMT Thread status register */
+#endif
/* low level flags - has atomic operations done on it */
unsigned long flags ____cacheline_aligned_in_smp;
};
+#ifdef CONFIG_PPC64
+/* Default SMT priority to (11- 13bits). */
+/* .ppr is Used to save/restore only on P7 or later */
+#define INIT_PPR \
+ .ppr = (3ull << 50),
+#else
+#define INIT_PPR
+#endif
+
/*
* macros/functions for gaining access to the thread information
structure
*/
@@ -56,6 +68,7 @@ struct thread_info {
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
+ INIT_PPR \
.flags = 0, \
}
diff --git a/arch/powerpc/kernel/asm-offsets.c
b/arch/powerpc/kernel/asm-offsets.c
index 52c7ad7..0b3a5fe 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -127,6 +127,7 @@ int main(void)
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
#ifdef CONFIG_PPC64
+ DEFINE(TI_PPR, offsetof(struct thread_info, ppr));
DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches,
log_dline_size));
DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches,
dlines_per_page));
diff --git a/arch/powerpc/kernel/entry_64.S
b/arch/powerpc/kernel/entry_64.S
index 5971c85..671a3db 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -33,6 +33,7 @@
#include <asm/irqflags.h>
#include <asm/ftrace.h>
#include <asm/hw_irq.h>
+#include <asm/exception-64s.h> /* SAVE_PPR and RESTORE_PPR */
/*
* System calls.
@@ -62,8 +63,10 @@ system_call_common:
std r12,_MSR(r1)
std r0,GPR0(r1)
std r10,GPR1(r1)
+ beq 2f
ACCOUNT_CPU_USER_ENTRY(r10, r11)
- std r2,GPR2(r1)
+ SAVE_PPR(PACA_EXGEN, r10, r11)
+2: std r2,GPR2(r1)
std r3,GPR3(r1)
mfcr r2
std r4,GPR4(r1)
@@ -228,6 +231,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
beq- 1f
ACCOUNT_CPU_USER_EXIT(r11, r12)
+ RESTORE_PPR(r11, r12)
ld r13,GPR13(r1) /* only restore r13 if returning to usermode */
1: ld r2,GPR2(r1)
ld r1,GPR1(r1)
@@ -698,6 +702,7 @@ fast_exception_return:
andi. r0,r3,MSR_PR
beq 1f
ACCOUNT_CPU_USER_EXIT(r2, r4)
+ RESTORE_PPR(r2, r4)
REST_GPR(13, r1)
1:
mtspr SPRN_SRR1,r3
diff --git a/arch/powerpc/kernel/exceptions-64s.S
b/arch/powerpc/kernel/exceptions-64s.S
index 1c06d29..c3bddf8 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -40,7 +40,7 @@ __start_interrupts:
.globl system_reset_pSeries;
system_reset_pSeries:
- HMT_MEDIUM;
+ HMT_FTR_NO_PPR
SET_SCRATCH0(r13)
#ifdef CONFIG_PPC_P7_NAP
BEGIN_FTR_SECTION
@@ -94,7 +94,7 @@ machine_check_pSeries_1:
. = 0x300
.globl data_access_pSeries
data_access_pSeries:
- HMT_MEDIUM
+ HMT_FTR_NO_PPR
SET_SCRATCH0(r13)
BEGIN_FTR_SECTION
b data_access_check_stab
@@ -106,7 +106,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB)
. = 0x380
.globl data_access_slb_pSeries
data_access_slb_pSeries:
- HMT_MEDIUM
+ HMT_FTR_NO_PPR
SET_SCRATCH0(r13)
EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x380)
std r3,PACA_EXSLB+EX_R3(r13)
@@ -137,7 +137,7 @@ data_access_slb_pSeries:
. = 0x480
.globl instruction_access_slb_pSeries
instruction_access_slb_pSeries:
- HMT_MEDIUM
+ HMT_FTR_NO_PPR
SET_SCRATCH0(r13)
EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480)
std r3,PACA_EXSLB+EX_R3(r13)
@@ -197,7 +197,7 @@ hardware_interrupt_hv:
. = 0xc00
.globl system_call_pSeries
system_call_pSeries:
- HMT_MEDIUM
+ HMT_FTR_NO_PPR
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
SET_SCRATCH0(r13)
GET_PACA(r13)
@@ -213,6 +213,7 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
mr r9,r13
GET_PACA(r13)
+ HMT_FTR_HAS_PPR(PACA_EXGEN,r10)
mfspr r11,SPRN_SRR0
mfspr r12,SPRN_SRR1
ld r10,PACAKBASE(r13)
@@ -295,7 +296,7 @@ vsx_unavailable_pSeries_1:
machine_check_pSeries:
.globl machine_check_fwnmi
machine_check_fwnmi:
- HMT_MEDIUM
+ HMT_FTR_NO_PPR
SET_SCRATCH0(r13) /* save r13 */
EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common,
EXC_STD, KVMTEST, 0x200)
@@ -417,7 +418,7 @@ _GLOBAL(__replay_interrupt)
.globl system_reset_fwnmi
.align 7
system_reset_fwnmi:
- HMT_MEDIUM
+ HMT_FTR_NO_PPR
SET_SCRATCH0(r13) /* save r13 */
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
NOTEST, 0x100)
@@ -717,7 +718,8 @@ _GLOBAL(slb_miss_realmode)
mtcrf 0x80,r9
mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
.machine pop
-
+
+ RESTORE_PPR_PACA(PACA_EXSLB,r9)
ld r9,PACA_EXSLB+EX_R9(r13)
ld r10,PACA_EXSLB+EX_R10(r13)
ld r11,PACA_EXSLB+EX_R11(r13)
@@ -1048,7 +1050,7 @@ initial_stab:
#ifdef CONFIG_PPC_POWERNV
_GLOBAL(opal_mc_secondary_handler)
- HMT_MEDIUM
+ HMT_FTR_NO_PPR
SET_SCRATCH0(r13)
GET_PACA(r13)
clrldi r3,r3,2
^ permalink raw reply related
* Re: [PATCH 6/6] hrtimer: Update hrtimer base offsets each hrtimer_interrupt
From: Andreas Schwab @ 2012-07-15 15:22 UTC (permalink / raw)
To: John Stultz
Cc: Prarit Bhargava, Peter Zijlstra, Linux Kernel, stable,
Thomas Gleixner, linuxppc-dev, Ingo Molnar
In-Reply-To: <1341960205-56738-8-git-send-email-johnstul@us.ibm.com>
This breaks resume on the iBook G4 (PowerBook6,7). Apparently during or
before noirq resume the system is hanging by the same amount of time as
the system was sleeping.
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply
* Re: [PATCH 6/6] hrtimer: Update hrtimer base offsets each hrtimer_interrupt
From: Andreas Schwab @ 2012-07-15 16:02 UTC (permalink / raw)
To: John Stultz
Cc: Prarit Bhargava, Peter Zijlstra, Linux Kernel, stable,
Thomas Gleixner, linuxppc-dev, Ingo Molnar
In-Reply-To: <m2y5mlnj5z.fsf__49536.0585897744$1342365803$gmane$org@igel.home>
Andreas Schwab <schwab@linux-m68k.org> writes:
> This breaks resume on the iBook G4 (PowerBook6,7). Apparently during or
> before noirq resume the system is hanging by the same amount of time as
> the system was sleeping.
The point where the time is wasted actually appears to be _after_ resume
(the elapsed time for the resume itself isn't affected).
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply
* Re: [PATCH 6/6] hrtimer: Update hrtimer base offsets each hrtimer_interrupt
From: Rafael J. Wysocki @ 2012-07-15 20:28 UTC (permalink / raw)
To: Andreas Schwab, John Stultz
Cc: Prarit Bhargava, Peter Zijlstra, Linux PM list, Linux Kernel,
stable, Thomas Gleixner, linuxppc-dev, Ingo Molnar
In-Reply-To: <m2y5mlnj5z.fsf@igel.home>
On Sunday, July 15, 2012, Andreas Schwab wrote:
> This breaks resume on the iBook G4 (PowerBook6,7). Apparently during or
> before noirq resume the system is hanging by the same amount of time as
> the system was sleeping.
I'm able to reproduce this problem on Toshiba Portege R500 with similar
symptoms, although that box sometimes hangs hard during resume from system
suspend with the "caps lock" LED blinking.
Reverting the patch fixes the problem 100% of the time.
Thanks,
Rafael
^ permalink raw reply
* Re: [PATCH] ppc44x/watchdog: Select WATCHDOG_NOWAYOUT option
From: Lu.Jiang @ 2012-07-16 2:07 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <D5792F52-7BE6-4B86-A3FD-B756DE3A165D@kernel.crashing.org>
于 2012年07月13日 19:50, Kumar Gala 写道:
> On Jul 12, 2012, at 9:44 PM, Jiang Lu wrote:
>
>> On PPC44x core, the WRC(Watchdog-timer Reset Control) field of TCR
>> of timer can not reset by software after set to a non-zero value.
>> Which means software can not reset the timeout behaviour of watchdog timer.
>>
>> This patch selects WATCHDOG_NOWAYOUT option for 44x platforms to
>> indicate the watchdog timer can not be disabled once fired.
>>
>> Signed-off-by: Jiang Lu <lu.jiang@windriver.com>
>> ---
>> drivers/watchdog/Kconfig | 1 +
>> 1 files changed, 1 insertions(+), 0 deletions(-)
> I believe this is not 44x specific, but how Book-E watchdog is architected.
>
>> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
>> index 3709624..41f3dff 100644
>> --- a/drivers/watchdog/Kconfig
>> +++ b/drivers/watchdog/Kconfig
>> @@ -1084,6 +1084,7 @@ config PIKA_WDT
>> config BOOKE_WDT
>> tristate "PowerPC Book-E Watchdog Timer"
>> depends on BOOKE || 4xx
>> + select WATCHDOG_NOWAYOUT if 44x
> This should probably be 'select WATCHDOG_NOWAYOUT if BOOKE'
On ppc44x's processor, if we disabled 'WATCHDOG_NOWAYOUT ' option. The
driver's release routine will try to disable the watchdog , by clearing
the WIE & WTDP field in TCR.
Since the ppc44x's watch dog can not reset by software, such operation
only set the timeout value(WDTP) to minimum, and cause the system reboot
immediately.
I checked ppc 476, 405 & 450's manual, these document said the
WRC(Watchdog-timer Reset Control) field of TCR of timer
can not reset by software after set to a non-zero value. I think all
ppc44x core should got same limitation.
While on FSL's platform, we did not met such issue. So I think we should
select 'WATCHDOG_NOWAYOUT' option for 44x platform.
Regards,
Jiang Lu
>
>> ---help---
>> Watchdog driver for PowerPC Book-E chips, such as the Freescale
>> MPC85xx SOCs and the IBM PowerPC 440.
>> --
>> 1.7.7
>>
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
^ permalink raw reply
* Re: [RFC PATCH v3 4/13] memory-hotplug : remove /sys/firmware/memmap/X sysfs
From: Wen Congyang @ 2012-07-16 2:32 UTC (permalink / raw)
To: Yasuaki Ishimatsu
Cc: len.brown, linux-acpi, linux-kernel, linux-mm, paulus,
minchan.kim, kosaki.motohiro, rientjes, cl, linuxppc-dev, akpm,
liuj97
In-Reply-To: <4FFAB1BA.9040801@jp.fujitsu.com>
At 07/09/2012 06:26 PM, Yasuaki Ishimatsu Wrote:
> When (hot)adding memory into system, /sys/firmware/memmap/X/{end, start, type}
> sysfs files are created. But there is no code to remove these files. The patch
> implements the function to remove them.
>
> Note : The code does not free firmware_map_entry since there is no way to free
> memory which is allocated by bootmem.
>
> CC: David Rientjes <rientjes@google.com>
> CC: Jiang Liu <liuj97@gmail.com>
> CC: Len Brown <len.brown@intel.com>
> CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> CC: Paul Mackerras <paulus@samba.org>
> CC: Christoph Lameter <cl@linux.com>
> Cc: Minchan Kim <minchan.kim@gmail.com>
> CC: Andrew Morton <akpm@linux-foundation.org>
> CC: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
> CC: Wen Congyang <wency@cn.fujitsu.com>
> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>
> ---
> drivers/firmware/memmap.c | 78 ++++++++++++++++++++++++++++++++++++++++++-
> include/linux/firmware-map.h | 6 +++
> mm/memory_hotplug.c | 6 ++-
> 3 files changed, 88 insertions(+), 2 deletions(-)
>
> Index: linux-3.5-rc6/mm/memory_hotplug.c
> ===================================================================
> --- linux-3.5-rc6.orig/mm/memory_hotplug.c 2012-07-09 18:23:13.323844923 +0900
> +++ linux-3.5-rc6/mm/memory_hotplug.c 2012-07-09 18:23:19.522767424 +0900
> @@ -661,7 +661,11 @@ EXPORT_SYMBOL_GPL(add_memory);
>
> int remove_memory(int nid, u64 start, u64 size)
> {
> - return -EBUSY;
> + lock_memory_hotplug();
> + /* remove memmap entry */
> + firmware_map_remove(start, start + size - 1, "System RAM");
> + unlock_memory_hotplug();
> + return 0;
>
> }
> EXPORT_SYMBOL_GPL(remove_memory);
> Index: linux-3.5-rc6/include/linux/firmware-map.h
> ===================================================================
> --- linux-3.5-rc6.orig/include/linux/firmware-map.h 2012-07-09 18:23:09.532892314 +0900
> +++ linux-3.5-rc6/include/linux/firmware-map.h 2012-07-09 18:23:19.523767412 +0900
> @@ -25,6 +25,7 @@
>
> int firmware_map_add_early(u64 start, u64 end, const char *type);
> int firmware_map_add_hotplug(u64 start, u64 end, const char *type);
> +int firmware_map_remove(u64 start, u64 end, const char *type);
>
> #else /* CONFIG_FIRMWARE_MEMMAP */
>
> @@ -38,6 +39,11 @@ static inline int firmware_map_add_hotpl
> return 0;
> }
>
> +static inline int firmware_map_remove(u64 start, u64 end, const char *type)
> +{
> + return 0;
> +}
> +
> #endif /* CONFIG_FIRMWARE_MEMMAP */
>
> #endif /* _LINUX_FIRMWARE_MAP_H */
> Index: linux-3.5-rc6/drivers/firmware/memmap.c
> ===================================================================
> --- linux-3.5-rc6.orig/drivers/firmware/memmap.c 2012-07-09 18:23:09.532892314 +0900
> +++ linux-3.5-rc6/drivers/firmware/memmap.c 2012-07-09 18:25:46.371931554 +0900
> @@ -21,6 +21,7 @@
> #include <linux/types.h>
> #include <linux/bootmem.h>
> #include <linux/slab.h>
> +#include <linux/mm.h>
>
> /*
> * Data types ------------------------------------------------------------------
> @@ -79,7 +80,22 @@ static const struct sysfs_ops memmap_att
> .show = memmap_attr_show,
> };
>
> +#define to_memmap_entry(obj) container_of(obj, struct firmware_map_entry, kobj)
> +
> +static void release_firmware_map_entry(struct kobject *kobj)
> +{
> + struct firmware_map_entry *entry = to_memmap_entry(kobj);
> + struct page *head_page;
> +
> + head_page = virt_to_head_page(entry);
> + if (PageSlab(head_page))
> + kfree(entry);
> +
> + /* There is no way to free memory allocated from bootmem*/
> +}
> +
> static struct kobj_type memmap_ktype = {
> + .release = release_firmware_map_entry,
> .sysfs_ops = &memmap_attr_ops,
> .default_attrs = def_attrs,
> };
> @@ -123,6 +139,16 @@ static int firmware_map_add_entry(u64 st
> return 0;
> }
>
> +/**
> + * firmware_map_remove_entry() - Does the real work to remove a firmware
> + * memmap entry.
> + * @entry: removed entry.
> + **/
> +static inline void firmware_map_remove_entry(struct firmware_map_entry *entry)
> +{
> + list_del(&entry->list);
> +}
> +
> /*
> * Add memmap entry on sysfs
> */
> @@ -144,6 +170,31 @@ static int add_sysfs_fw_map_entry(struct
> return 0;
> }
>
> +/*
> + * Remove memmap entry on sysfs
> + */
> +static inline void remove_sysfs_fw_map_entry(struct firmware_map_entry *entry)
> +{
> + kobject_put(&entry->kobj);
> +}
> +
> +/*
> + * Search memmap entry
> + */
> +
> +struct firmware_map_entry * __meminit
> +find_firmware_map_entry(u64 start, u64 end, const char *type)
> +{
> + struct firmware_map_entry *entry;
> +
> + list_for_each_entry(entry, &map_entries, list)
> + if ((entry->start == start) && (entry->end == end) &&
> + (!strcmp(entry->type, type)))
> + return entry;
> +
> + return NULL;
> +}
> +
> /**
> * firmware_map_add_hotplug() - Adds a firmware mapping entry when we do
> * memory hotplug.
> @@ -196,6 +247,32 @@ int __init firmware_map_add_early(u64 st
> return firmware_map_add_entry(start, end, type, entry);
> }
>
> +/**
> + * firmware_map_remove() - remove a firmware mapping entry
> + * @start: Start of the memory range.
> + * @end: End of the memory range (inclusive).
> + * @type: Type of the memory range.
> + *
> + * removes a firmware mapping entry.
> + *
> + * Returns 0 on success, or -EINVAL if no entry.
> + **/
> +int __meminit firmware_map_remove(u64 start, u64 end, const char *type)
> +{
> + struct firmware_map_entry *entry;
> +
> + entry = find_firmware_map_entry(start, end, type);
> + if (!entry)
> + return -EINVAL;
> +
> + /* remove the memmap entry */
> + remove_sysfs_fw_map_entry(entry);
> +
> + firmware_map_remove_entry(entry);
You should call firmware_map_remove_entry() before remove_sysfs_fw_map_entry(),
otherwise it will cause kernel panicked(entry may be freed in remove_sysfs_fw_map_entry()).
Thanks
Wen Congyang
> +
> + return 0;
> +}
> +
> /*
> * Sysfs functions -------------------------------------------------------------
> */
> @@ -218,7 +295,6 @@ static ssize_t type_show(struct firmware
> }
>
> #define to_memmap_attr(_attr) container_of(_attr, struct memmap_attribute, attr)
> -#define to_memmap_entry(obj) container_of(obj, struct firmware_map_entry, kobj)
>
> static ssize_t memmap_attr_show(struct kobject *kobj,
> struct attribute *attr, char *buf)
>
>
^ permalink raw reply
* [PATCH V3] powerpc/85xx: Add machine check handler to fix PCIe erratum on mpc85xx
From: Jia Hongtao @ 2012-07-16 2:45 UTC (permalink / raw)
To: linuxppc-dev, galak; +Cc: b38951
A PCIe erratum of mpc85xx may causes a core hang when a link of PCIe
goes down. when the link goes down, Non-posted transactions issued
via the ATMU requiring completion result in an instruction stall.
At the same time a machine-check exception is generated to the core
to allow further processing by the handler. We implements the handler
which skips the instruction caused the stall.
Signed-off-by: Zhao Chenhui <b35336@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Liu Shuo <soniccat.liu@gmail.com>
Signed-off-by: Jia Hongtao <B38951@freescale.com>
---
V3 changed: Just rebase the patch.
arch/powerpc/kernel/cpu_setup_fsl_booke.S | 2 +-
arch/powerpc/kernel/traps.c | 3 ++
arch/powerpc/sysdev/fsl_pci.c | 39 +++++++++++++++++++++++++++++
arch/powerpc/sysdev/fsl_pci.h | 6 ++++
4 files changed, 49 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index 69fdd23..9c4b768 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -64,7 +64,7 @@ _GLOBAL(__setup_cpu_e500v2)
bl __e500_icache_setup
bl __e500_dcache_setup
bl __setup_e500_ivors
-#ifdef CONFIG_FSL_RIO
+#if defined(CONFIG_FSL_RIO) || defined(CONFIG_FSL_PCI)
/* Ensure that RFXE is set */
mfspr r3,SPRN_HID1
oris r3,r3,HID1_RFXE@h
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 1589723..096a1a1 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -59,6 +59,7 @@
#include <asm/fadump.h>
#include <asm/switch_to.h>
#include <asm/debug.h>
+#include <sysdev/fsl_pci.h>
#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
int (*__debugger)(struct pt_regs *regs) __read_mostly;
@@ -555,6 +556,8 @@ int machine_check_e500(struct pt_regs *regs)
if (reason & MCSR_BUS_RBERR) {
if (fsl_rio_mcheck_exception(regs))
return 1;
+ if (fsl_pci_mcheck_exception(regs))
+ return 1;
}
printk("Machine check in kernel mode.\n");
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index a7b2a60..52f3b5d 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -30,6 +30,7 @@
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
#include <asm/machdep.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
@@ -808,6 +809,44 @@ u64 fsl_pci_immrbar_base(struct pci_controller *hose)
return 0;
}
+static int is_in_pci_mem_space(phys_addr_t addr)
+{
+ struct pci_controller *hose;
+ struct resource *res;
+ int i;
+
+ list_for_each_entry(hose, &hose_list, list_node) {
+ if (!early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP))
+ continue;
+
+ for (i = 0; i < 3; i++) {
+ res = &hose->mem_resources[i];
+ if ((res->flags & IORESOURCE_MEM) &&
+ addr >= res->start && addr <= res->end)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int fsl_pci_mcheck_exception(struct pt_regs *regs)
+{
+ phys_addr_t addr = 0;
+
+#ifdef CONFIG_PHYS_64BIT
+ addr = mfspr(SPRN_MCARU);
+ addr <<= 32;
+#endif
+ addr += mfspr(SPRN_MCAR);
+
+ if (is_in_pci_mem_space(addr)) {
+ regs->nip += 4;
+ return 1;
+ }
+
+ return 0;
+}
+
#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
static const struct of_device_id pci_ids[] = {
{ .compatible = "fsl,mpc8540-pci", },
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index baa0fd1..efd1907 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -101,5 +101,11 @@ void fsl_pci_init(void);
static inline void fsl_pci_init(void) {}
#endif
+#ifdef CONFIG_FSL_PCI
+extern int fsl_pci_mcheck_exception(struct pt_regs *);
+#else
+static inline int fsl_pci_mcheck_exception(struct pt_regs *regs) {return 0; }
+#endif
+
#endif /* __POWERPC_FSL_PCI_H */
#endif /* __KERNEL__ */
--
1.7.5.1
^ permalink raw reply related
* [PATCH V3] powerpc/85xx: Add machine check handler to fix PCIe erratum on mpc85xx
From: Jia Hongtao @ 2012-07-16 2:59 UTC (permalink / raw)
To: linuxppc-dev, galak; +Cc: b38951
A PCIe erratum of mpc85xx may causes a core hang when a link of PCIe
goes down. when the link goes down, Non-posted transactions issued
via the ATMU requiring completion result in an instruction stall.
At the same time a machine-check exception is generated to the core
to allow further processing by the handler. We implements the handler
which skips the instruction caused the stall.
Signed-off-by: Zhao Chenhui <b35336@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Liu Shuo <soniccat.liu@gmail.com>
Signed-off-by: Jia Hongtao <B38951@freescale.com>
---
V3 changed:
1. Rebased the patch.
2. Only build fsl_pci_mcheck_exception on e500
arch/powerpc/kernel/cpu_setup_fsl_booke.S | 2 +-
arch/powerpc/kernel/traps.c | 3 ++
arch/powerpc/sysdev/fsl_pci.c | 41 +++++++++++++++++++++++++++++
arch/powerpc/sysdev/fsl_pci.h | 6 ++++
4 files changed, 51 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index 69fdd23..9c4b768 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -64,7 +64,7 @@ _GLOBAL(__setup_cpu_e500v2)
bl __e500_icache_setup
bl __e500_dcache_setup
bl __setup_e500_ivors
-#ifdef CONFIG_FSL_RIO
+#if defined(CONFIG_FSL_RIO) || defined(CONFIG_FSL_PCI)
/* Ensure that RFXE is set */
mfspr r3,SPRN_HID1
oris r3,r3,HID1_RFXE@h
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 1589723..096a1a1 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -59,6 +59,7 @@
#include <asm/fadump.h>
#include <asm/switch_to.h>
#include <asm/debug.h>
+#include <sysdev/fsl_pci.h>
#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
int (*__debugger)(struct pt_regs *regs) __read_mostly;
@@ -555,6 +556,8 @@ int machine_check_e500(struct pt_regs *regs)
if (reason & MCSR_BUS_RBERR) {
if (fsl_rio_mcheck_exception(regs))
return 1;
+ if (fsl_pci_mcheck_exception(regs))
+ return 1;
}
printk("Machine check in kernel mode.\n");
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index a7b2a60..3a3e9c8 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -30,6 +30,7 @@
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
#include <asm/machdep.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
@@ -808,6 +809,46 @@ u64 fsl_pci_immrbar_base(struct pci_controller *hose)
return 0;
}
+#ifdef CONFIG_E500
+static int is_in_pci_mem_space(phys_addr_t addr)
+{
+ struct pci_controller *hose;
+ struct resource *res;
+ int i;
+
+ list_for_each_entry(hose, &hose_list, list_node) {
+ if (!early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP))
+ continue;
+
+ for (i = 0; i < 3; i++) {
+ res = &hose->mem_resources[i];
+ if ((res->flags & IORESOURCE_MEM) &&
+ addr >= res->start && addr <= res->end)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int fsl_pci_mcheck_exception(struct pt_regs *regs)
+{
+ phys_addr_t addr = 0;
+
+#ifdef CONFIG_PHYS_64BIT
+ addr = mfspr(SPRN_MCARU);
+ addr <<= 32;
+#endif
+ addr += mfspr(SPRN_MCAR);
+
+ if (is_in_pci_mem_space(addr)) {
+ regs->nip += 4;
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+
#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
static const struct of_device_id pci_ids[] = {
{ .compatible = "fsl,mpc8540-pci", },
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index baa0fd1..efd1907 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -101,5 +101,11 @@ void fsl_pci_init(void);
static inline void fsl_pci_init(void) {}
#endif
+#ifdef CONFIG_FSL_PCI
+extern int fsl_pci_mcheck_exception(struct pt_regs *);
+#else
+static inline int fsl_pci_mcheck_exception(struct pt_regs *regs) {return 0; }
+#endif
+
#endif /* __POWERPC_FSL_PCI_H */
#endif /* __KERNEL__ */
--
1.7.5.1
^ permalink raw reply related
* Re: [PATCH] powerpc: SMT priority (PPR) save and restore
From: Michael Neuling @ 2012-07-16 3:41 UTC (permalink / raw)
To: Haren Myneni; +Cc: linuxppc-dev, paulus, anton
In-Reply-To: <1342259024.11305.38.camel@hbabu-laptop>
Heaven Myneni <haren@linux.vnet.ibm.com> wrote:
> powerpc: SMT priority (PPR) save and restore
>
> On P7 systems, users can define SMT priority levels 2,3 and 4 for
> processes so that some can run higher priority than the other ones.
> In the current kernel, the default priority is set to 4 which prohibits
> processes to use higher priority. Also the kernel boosts the priority to
> 4 during exception without saving the user defined priority values when
> the task enters the kernel. So we will be loosing the process PPR value
> and can not be restored it back when the task exits the kernel.
>
> This patch sets the default priority to 3 when tasks are created such
> that users can use 4 for higher priority tasks. It also provides to save
> and restore the user defined priorities for all tasks.
>
> When the task enters in to kernel space, the user defined priority (PPR)
> will be saved in to PACA at the beginning of first level exception
> vector and then copy from PACA to thread_info in second level vector.
> PPR will be restored from thread_info before exits the kernel space.
>
> P7 temporarily raises the thread priority to higher level during
> exception until the program executes HMT_* calls. But it will not modify
> PPR register. So we saves PPR value whenever some register is available
> to use and then calls HMT_MEDIUM to increase the priority. This feature
> supports on P7 or later processors.
>
> Signed-off-by: Haren Myneni <hbabu@us.ibm.com>
Can you break this patch into a few parts that are easier to review than
one giant patch. Start by adding the PPR ftr bits, then the extra space
in the paca, then the new macros, then use the new infrastructure. I'm
sure you can get 5 or so patches which will be much easier to review.
Also this has been white space munged. See here:
http://patchwork.ozlabs.org/patch/170993/
All the #defines are broken.
Also, do you know what the impacts of this are on null syscall/page
faults etc on machines which need the PPR switched? If it's big, we
might want to have this as a CONFIG option for those who don't care and
want the speed bump.
More comments below.
>
> diff --git a/arch/powerpc/include/asm/cputable.h
> b/arch/powerpc/include/asm/cputable.h
> index 50d82c8..e7b80d6 100644
> --- a/arch/powerpc/include/asm/cputable.h
> +++ b/arch/powerpc/include/asm/cputable.h
> @@ -203,6 +203,7 @@ extern const char *powerpc_base_platform;
> #define CPU_FTR_POPCNTD LONG_ASM_CONST(0x0800000000000000)
> #define CPU_FTR_ICSWX LONG_ASM_CONST(0x1000000000000000)
> #define CPU_FTR_VMX_COPY LONG_ASM_CONST(0x2000000000000000)
> +#define CPU_FTR_HAS_PPR LONG_ASM_CONST(0x4000000000000000)
>
> #ifndef __ASSEMBLY__
>
> @@ -432,7 +433,8 @@ extern const char *powerpc_base_platform;
> CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
> CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \
> CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD |
> \
> - CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY)
> + CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY |
> \
> + CPU_FTR_HAS_PPR)
Add CPU_FTR_HAS_PPR to CPU_FTRS_POSSIBLE as well.
> #define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
> CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
> CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
> diff --git a/arch/powerpc/include/asm/exception-64s.h
> b/arch/powerpc/include/asm/exception-64s.h
> index d58fc4e..1fae8aa 100644
> --- a/arch/powerpc/include/asm/exception-64s.h
> +++ b/arch/powerpc/include/asm/exception-64s.h
> @@ -47,6 +47,7 @@
> #define EX_R3 64
> #define EX_LR 72
> #define EX_CFAR 80
> +#define EX_PPR 88 /* SMT thread status register (priority) */
>
> /*
> * We're short on space and time in the exception prolog, so we can't
> @@ -61,10 +62,46 @@
> #define EXC_HV H
> #define EXC_STD
>
> +/*
> + * PPR save/restore macros - Used only on P7 or later processors
> + */
> +#define SAVE_PPR(area, ra, rb)
> \
> +BEGIN_FTR_SECTION_NESTED(940)
> \
> + ld ra,area+EX_PPR(r13); /* Read PPR from paca */
> \
> + clrrdi rb,r1,THREAD_SHIFT; /* thread_info struct */
> \
> + std ra,TI_PPR(rb); /* Save PPR in thread_info */
> \
> +END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,940)
> +
> +#define RESTORE_PPR(ra,rb)
> \
> +BEGIN_FTR_SECTION_NESTED(941)
> \
> + clrrdi ra,r1,THREAD_SHIFT;
> \
> + ld rb,TI_PPR(ra); /* Read PPR from thread_info */
> \
> + mtspr SPRN_PPR,rb; /* Restore PPR */
> \
> +END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,941)
> +
> +#define RESTORE_PPR_PACA(area,ra)
> \
> +BEGIN_FTR_SECTION_NESTED(942)
> \
> + ld ra,area+EX_PPR(r13);
> \
> + mtspr SPRN_PPR,ra;
> \
> +END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,942)
> +
> +#define HMT_FTR_NO_PPR
> \
> +BEGIN_FTR_SECTION_NESTED(944) \
> + HMT_MEDIUM;
> \
> +END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,0,944) /*non P7*/
> +
> +#define HMT_FTR_HAS_PPR(area, ra)
> \
> +BEGIN_FTR_SECTION_NESTED(943)
> \
> + mfspr ra,SPRN_PPR; /* Read PPR */
> \
> + std ra,area+EX_PPR(r13); /* Save PPR in paca */
> \
> + HMT_MEDIUM;
> \
> +END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,943) /* P7 */
all munged.
> +
> #define __EXCEPTION_PROLOG_1(area, extra, vec) \
> GET_PACA(r13); \
> - std r9,area+EX_R9(r13); /* save r9 - r12 */ \
> - std r10,area+EX_R10(r13); \
> + std r9,area+EX_R9(r13); /* save r9 */ \
> + HMT_FTR_HAS_PPR(area,r9); \
> + std r10,area+EX_R10(r13); /* save r10 - r12 */ \
> BEGIN_FTR_SECTION_NESTED(66); \
> mfspr r10,SPRN_CFAR; \
> std r10,area+EX_CFAR(r13); \
> @@ -176,8 +213,10 @@ do_kvm_##n: \
> std r10,0(r1); /* make stack chain pointer */ \
> std r0,GPR0(r1); /* save r0 in stackframe */ \
> std r10,GPR1(r1); /* save r1 in stackframe */ \
> + beq 4f; \
> ACCOUNT_CPU_USER_ENTRY(r9, r10); \
> - std r2,GPR2(r1); /* save r2 in stackframe */ \
> + SAVE_PPR(area, r9, r10); \
> +4: std r2,GPR2(r1); /* save r2 in stackframe */ \
why are we no longer doing ACCOUNT_CPU_USER_ENTRY here?
> SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \
> SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \
> ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \
> @@ -218,7 +257,7 @@ do_kvm_##n: \
> . = loc; \
> .globl label##_pSeries; \
> label##_pSeries: \
> - HMT_MEDIUM; \
> + HMT_FTR_NO_PPR; \
> SET_SCRATCH0(r13); /* save r13 */ \
> EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
> EXC_STD, KVMTEST_PR, vec)
> @@ -227,7 +266,7 @@ label##_pSeries: \
> . = loc; \
> .globl label##_hv; \
> label##_hv: \
> - HMT_MEDIUM; \
> + HMT_FTR_NO_PPR; \
> SET_SCRATCH0(r13); /* save r13 */ \
> EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
> EXC_HV, KVMTEST, vec)
> @@ -258,7 +297,7 @@ label##_hv: \
> _SOFTEN_TEST(EXC_STD, vec)
>
> #define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \
> - HMT_MEDIUM; \
> + HMT_FTR_NO_PPR; \
> SET_SCRATCH0(r13); /* save r13 */ \
> __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \
> EXCEPTION_PROLOG_PSERIES_1(label##_common, h);
> diff --git a/arch/powerpc/include/asm/paca.h
> b/arch/powerpc/include/asm/paca.h
> index daf813f..d32b1e5 100644
> --- a/arch/powerpc/include/asm/paca.h
> +++ b/arch/powerpc/include/asm/paca.h
> @@ -93,9 +93,9 @@ struct paca_struct {
> * Now, starting in cacheline 2, the exception save areas
> */
> /* used for most interrupts/exceptions */
> - u64 exgen[11] __attribute__((aligned(0x80)));
> - u64 exmc[11]; /* used for machine checks */
> - u64 exslb[11]; /* used for SLB/segment table misses
> + u64 exgen[12] __attribute__((aligned(0x80)));
> + u64 exmc[12]; /* used for machine checks */
> + u64 exslb[12]; /* used for SLB/segment table misses
> * on the linear mapping */
> /* SLB related definitions */
> u16 vmalloc_sllp;
> diff --git a/arch/powerpc/include/asm/ppc_asm.h
> b/arch/powerpc/include/asm/ppc_asm.h
> index 1544420..b5437a2 100644
> --- a/arch/powerpc/include/asm/ppc_asm.h
> +++ b/arch/powerpc/include/asm/ppc_asm.h
> @@ -30,7 +30,6 @@
> #define ACCOUNT_STOLEN_TIME
> #else
> #define ACCOUNT_CPU_USER_ENTRY(ra, rb) \
> - beq 2f; /* if from kernel mode */ \
> MFTB(ra); /* get timebase */ \
> ld rb,PACA_STARTTIME_USER(r13); \
> std ra,PACA_STARTTIME(r13); \
> @@ -38,7 +37,6 @@
> ld ra,PACA_USER_TIME(r13); \
> add ra,ra,rb; /* add on to user time */ \
> std ra,PACA_USER_TIME(r13); \
> -2:
Why are you doing this?
>
> #define ACCOUNT_CPU_USER_EXIT(ra, rb) \
> MFTB(ra); /* get timebase */ \
> diff --git a/arch/powerpc/include/asm/reg.h
> b/arch/powerpc/include/asm/reg.h
> index f0cb7f4..1e61116 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -284,6 +284,7 @@
> #define SPRN_DBAT6U 0x23C /* Data BAT 6 Upper Register */
> #define SPRN_DBAT7L 0x23F /* Data BAT 7 Lower Register */
> #define SPRN_DBAT7U 0x23E /* Data BAT 7 Upper Register */
> +#define SPRN_PPR 0x380 /* Local SMT Thread status resgiter */
spelling mistake here
>
> #define SPRN_DEC 0x016 /* Decrement Register */
> #define SPRN_DER 0x095 /* Debug Enable Regsiter */
> diff --git a/arch/powerpc/include/asm/thread_info.h
> b/arch/powerpc/include/asm/thread_info.h
> index 68831e9..618e35c 100644
> --- a/arch/powerpc/include/asm/thread_info.h
> +++ b/arch/powerpc/include/asm/thread_info.h
> @@ -40,10 +40,22 @@ struct thread_info {
> struct restart_block restart_block;
> unsigned long local_flags; /* private flags for thread */
>
> +#ifdef CONFIG_PPC64
> + unsigned long ppr; /* SMT Thread status register */
> +#endif
> /* low level flags - has atomic operations done on it */
> unsigned long flags ____cacheline_aligned_in_smp;
> };
>
> +#ifdef CONFIG_PPC64
> +/* Default SMT priority to (11- 13bits). */
> +/* .ppr is Used to save/restore only on P7 or later */
> +#define INIT_PPR \
> + .ppr = (3ull << 50),
> +#else
> +#define INIT_PPR
> +#endif
> +
> /*
> * macros/functions for gaining access to the thread information
> structure
> */
> @@ -56,6 +68,7 @@ struct thread_info {
> .restart_block = { \
> .fn = do_no_restart_syscall, \
> }, \
> + INIT_PPR \
> .flags = 0, \
> }
>
> diff --git a/arch/powerpc/kernel/asm-offsets.c
> b/arch/powerpc/kernel/asm-offsets.c
> index 52c7ad7..0b3a5fe 100644
> --- a/arch/powerpc/kernel/asm-offsets.c
> +++ b/arch/powerpc/kernel/asm-offsets.c
> @@ -127,6 +127,7 @@ int main(void)
> DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
>
> #ifdef CONFIG_PPC64
> + DEFINE(TI_PPR, offsetof(struct thread_info, ppr));
> DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
> DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches,
> log_dline_size));
> DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches,
> dlines_per_page));
> diff --git a/arch/powerpc/kernel/entry_64.S
> b/arch/powerpc/kernel/entry_64.S
> index 5971c85..671a3db 100644
> --- a/arch/powerpc/kernel/entry_64.S
> +++ b/arch/powerpc/kernel/entry_64.S
> @@ -33,6 +33,7 @@
> #include <asm/irqflags.h>
> #include <asm/ftrace.h>
> #include <asm/hw_irq.h>
> +#include <asm/exception-64s.h> /* SAVE_PPR and RESTORE_PPR */
No need for the comment here
>
> /*
> * System calls.
> @@ -62,8 +63,10 @@ system_call_common:
> std r12,_MSR(r1)
> std r0,GPR0(r1)
> std r10,GPR1(r1)
> + beq 2f
> ACCOUNT_CPU_USER_ENTRY(r10, r11)
> - std r2,GPR2(r1)
> + SAVE_PPR(PACA_EXGEN, r10, r11)
> +2: std r2,GPR2(r1)
anyway, why are we skipping this code
> std r3,GPR3(r1)
> mfcr r2
> std r4,GPR4(r1)
> @@ -228,6 +231,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
>
> beq- 1f
> ACCOUNT_CPU_USER_EXIT(r11, r12)
> + RESTORE_PPR(r11, r12)
> ld r13,GPR13(r1) /* only restore r13 if returning to usermode */
> 1: ld r2,GPR2(r1)
> ld r1,GPR1(r1)
> @@ -698,6 +702,7 @@ fast_exception_return:
> andi. r0,r3,MSR_PR
> beq 1f
> ACCOUNT_CPU_USER_EXIT(r2, r4)
> + RESTORE_PPR(r2, r4)
> REST_GPR(13, r1)
> 1:
> mtspr SPRN_SRR1,r3
> diff --git a/arch/powerpc/kernel/exceptions-64s.S
> b/arch/powerpc/kernel/exceptions-64s.S
> index 1c06d29..c3bddf8 100644
> --- a/arch/powerpc/kernel/exceptions-64s.S
> +++ b/arch/powerpc/kernel/exceptions-64s.S
> @@ -40,7 +40,7 @@ __start_interrupts:
>
> .globl system_reset_pSeries;
> system_reset_pSeries:
> - HMT_MEDIUM;
> + HMT_FTR_NO_PPR
Can we call this something else like HMT_MEDIUM_NO_PPR?
> SET_SCRATCH0(r13)
> #ifdef CONFIG_PPC_P7_NAP
> BEGIN_FTR_SECTION
> @@ -94,7 +94,7 @@ machine_check_pSeries_1:
> . = 0x300
> .globl data_access_pSeries
> data_access_pSeries:
> - HMT_MEDIUM
> + HMT_FTR_NO_PPR
> SET_SCRATCH0(r13)
> BEGIN_FTR_SECTION
> b data_access_check_stab
> @@ -106,7 +106,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB)
> . = 0x380
> .globl data_access_slb_pSeries
> data_access_slb_pSeries:
> - HMT_MEDIUM
> + HMT_FTR_NO_PPR
> SET_SCRATCH0(r13)
> EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x380)
> std r3,PACA_EXSLB+EX_R3(r13)
> @@ -137,7 +137,7 @@ data_access_slb_pSeries:
> . = 0x480
> .globl instruction_access_slb_pSeries
> instruction_access_slb_pSeries:
> - HMT_MEDIUM
> + HMT_FTR_NO_PPR
> SET_SCRATCH0(r13)
> EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480)
> std r3,PACA_EXSLB+EX_R3(r13)
> @@ -197,7 +197,7 @@ hardware_interrupt_hv:
> . = 0xc00
> .globl system_call_pSeries
> system_call_pSeries:
> - HMT_MEDIUM
> + HMT_FTR_NO_PPR
> #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
> SET_SCRATCH0(r13)
> GET_PACA(r13)
> @@ -213,6 +213,7 @@ BEGIN_FTR_SECTION
> END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
> mr r9,r13
> GET_PACA(r13)
> + HMT_FTR_HAS_PPR(PACA_EXGEN,r10)
> mfspr r11,SPRN_SRR0
> mfspr r12,SPRN_SRR1
> ld r10,PACAKBASE(r13)
> @@ -295,7 +296,7 @@ vsx_unavailable_pSeries_1:
> machine_check_pSeries:
> .globl machine_check_fwnmi
> machine_check_fwnmi:
> - HMT_MEDIUM
> + HMT_FTR_NO_PPR
> SET_SCRATCH0(r13) /* save r13 */
> EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common,
> EXC_STD, KVMTEST, 0x200)
> @@ -417,7 +418,7 @@ _GLOBAL(__replay_interrupt)
> .globl system_reset_fwnmi
> .align 7
> system_reset_fwnmi:
> - HMT_MEDIUM
> + HMT_FTR_NO_PPR
> SET_SCRATCH0(r13) /* save r13 */
> EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
> NOTEST, 0x100)
> @@ -717,7 +718,8 @@ _GLOBAL(slb_miss_realmode)
> mtcrf 0x80,r9
> mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
> .machine pop
> -
> +
Random whitespace change.
> + RESTORE_PPR_PACA(PACA_EXSLB,r9)
> ld r9,PACA_EXSLB+EX_R9(r13)
> ld r10,PACA_EXSLB+EX_R10(r13)
> ld r11,PACA_EXSLB+EX_R11(r13)
> @@ -1048,7 +1050,7 @@ initial_stab:
>
> #ifdef CONFIG_PPC_POWERNV
> _GLOBAL(opal_mc_secondary_handler)
> - HMT_MEDIUM
> + HMT_FTR_NO_PPR
> SET_SCRATCH0(r13)
> GET_PACA(r13)
> clrldi r3,r3,2
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
^ permalink raw reply
* [PATCH 1/2 v2] PCI: Add PCI_DEV_FLAGS_USE_NON_MSI_INTX_IRQ to enable non MSI/INTx interrupt
From: Shengzhou Liu @ 2012-07-16 3:31 UTC (permalink / raw)
To: bhelgaas, linux-pci; +Cc: linuxppc-dev, Shengzhou Liu
On some platforms, in RC mode, root port has neither MSI/MSI-X nor INTx
interrupt generated, which are available only in EP mode on those platform.
In this case, we try to use other interrupt for port service driver to have
AER, Hot-plug, etc, services to work.
Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
---
v2: separated platform-specific part to arch/powerpc/sysdev.
drivers/pci/pcie/portdrv_core.c | 10 ++++++++--
drivers/pci/quirks.c | 9 +++++++++
include/linux/pci.h | 5 +++++
3 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 75915b3..837ad15 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -212,8 +212,14 @@ static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
if (!pcie_port_enable_msix(dev, irqs, mask))
return 0;
- /* We're not going to use MSI-X, so try MSI and fall back to INTx */
- if (!pci_enable_msi(dev) || dev->pin)
+ /*
+ * We're not going to use MSI-X, so try MSI and fall back to INTx.
+ * Eventually, if neither MSI/MSI-X nor INTx available, try other
+ * interrupt. (On some platforms, root port doesn't support generating
+ * MSI/MSI-X/INTx in RC mode)
+ */
+ if (!pci_enable_msi(dev) || dev->pin || ((dev->dev_flags &
+ PCI_DEV_FLAGS_USE_NON_MSI_INTX_IRQ) && dev->irq))
irq = dev->irq;
no_msi:
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 2a75216..2922cb8 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2640,6 +2640,15 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1083,
quirk_msi_intx_disable_bug);
#endif /* CONFIG_PCI_MSI */
+/*
+ * Under some circumstances, root port has neither MSI/MSI-X nor INTx generated,
+ * so try other interrupt if supported.
+ */
+void __devinit quirk_enable_non_msi_intx_interrupt(struct pci_dev *dev)
+{
+ dev->dev_flags |= PCI_DEV_FLAGS_USE_NON_MSI_INTX_IRQ;
+}
+
/* Allow manual resource allocation for PCI hotplug bridges
* via pci=hpmemsize=nnM and pci=hpiosize=nnM parameters. For
* some PCI-PCI hotplug bridges, like PLX 6254 (former HINT HB6),
diff --git a/include/linux/pci.h b/include/linux/pci.h
index d8c379d..f051a66 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -176,6 +176,11 @@ enum pci_dev_flags {
PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2,
/* Provide indication device is assigned by a Virtual Machine Manager */
PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) 4,
+ /*
+ * Use other interrupt (i.e. system shared interrupt) when MSI/MSI-X
+ * and INTx are not supported in RC mode on some platforms.
+ */
+ PCI_DEV_FLAGS_USE_NON_MSI_INTX_IRQ = (__force pci_dev_flags_t) 8,
};
enum pci_irq_reroute_variant {
--
1.6.4
^ permalink raw reply related
* [PATCH 2/2 v2] powerpc/fsl: PCI: add quirk_enable_non_msi_intx_interrupt
From: Shengzhou Liu @ 2012-07-16 3:31 UTC (permalink / raw)
To: bhelgaas, linux-pci; +Cc: linuxppc-dev, Shengzhou Liu
In-Reply-To: <1342409487-28256-1-git-send-email-Shengzhou.Liu@freescale.com>
On current fsl powerpc platforms, the PCIe root port doesn't support
generating MSI/MSI-X and INTx interrupt in RC mode (those interrupts
are supported only in EP mode). So we use the shared error interrupt
by flag PCI_DEV_FLAGS_USE_NON_MSI_INTX_IRQ for PCIe port driver to
support AER, Hot-plug etc, services.
Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
---
v2: separated platform-specific part to arch/powerpc/sysdev.
arch/powerpc/sysdev/fsl_pci.c | 2 ++
arch/powerpc/sysdev/fsl_pci.h | 1 +
2 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 6073288..fb8862f 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -498,6 +498,8 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID,
+ quirk_enable_non_msi_intx_interrupt);
#if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
struct mpc83xx_pcie_priv {
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index a39ed5c..a98c6d8 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -91,6 +91,7 @@ struct ccsr_pci {
extern int fsl_add_bridge(struct device_node *dev, int is_primary);
extern void fsl_pcibios_fixup_bus(struct pci_bus *bus);
extern int mpc83xx_add_bridge(struct device_node *dev);
+extern void __devinit quirk_enable_non_msi_intx_interrupt(struct pci_dev *dev);
u64 fsl_pci_immrbar_base(struct pci_controller *hose);
#endif /* __POWERPC_FSL_PCI_H */
--
1.6.4
^ permalink raw reply related
* [PATCH] powerpc/85xx: workaround for chips with MSI hareware errata to support MSI-X
From: Jia Hongtao @ 2012-07-16 3:35 UTC (permalink / raw)
To: linuxppc-dev, galak; +Cc: soniccat.liu, b38951
From: Liu Shuo <soniccat.liu@gmail.com>
The MPIC chip with version 2.0 has a MSI errata (errata PIC1 of mpc8544),
It causes that neither MSI nor MSI-X can work fine. There is a workaround
to allow MSI-X to function properly.
Signed-off-by: Liu Shuo <soniccat.liu@gmail.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
arch/powerpc/include/asm/mpic.h | 3 ++
arch/powerpc/sysdev/fsl_msi.c | 63 +++++++++++++++++++++++++++++++++++++-
arch/powerpc/sysdev/fsl_msi.h | 3 ++
3 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index c9f698a..a9e4f937 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -110,6 +110,9 @@
#define MPIC_VECPRI_SENSE_MASK 0x00400000
#define MPIC_IRQ_DESTINATION 0x00010
+#define MPIC_FSL_BRR1 0x00000
+#define MPIC_FSL_BRR1_VER 0x0000ffff
+
#define MPIC_MAX_IRQ_SOURCES 2048
#define MPIC_MAX_CPUS 32
#define MPIC_MAX_ISU 32
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 6e097de..f2d340a 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -98,8 +98,23 @@ static int fsl_msi_init_allocator(struct fsl_msi *msi_data)
static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type)
{
+ struct fsl_msi *msi;
+
if (type == PCI_CAP_ID_MSIX)
pr_debug("fslmsi: MSI-X untested, trying anyway.\n");
+ else if (type == PCI_CAP_ID_MSI) {
+ /*
+ * MPIC chip with 2.0 version has erratum PIC1. It
+ * causes that neither MSI nor MSI-X can work fine.
+ * There is a workaround to allow MSI-X to function
+ * properly.
+ */
+ list_for_each_entry(msi, &msi_head, list) {
+ if ((msi->feature & MSI_HW_ERRATA_MASK)
+ == MSI_HW_ERRATA_ENDIAN)
+ return -EINVAL;
+ }
+ }
return 0;
}
@@ -142,7 +157,11 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
msg->address_lo = lower_32_bits(address);
msg->address_hi = upper_32_bits(address);
- msg->data = hwirq;
+ /* See the comment in fsl_msi_check_device() */
+ if ((msi_data->feature & MSI_HW_ERRATA_MASK) == MSI_HW_ERRATA_ENDIAN)
+ msg->data = __swab32(hwirq);
+ else
+ msg->data = hwirq;
pr_debug("%s: allocated srs: %d, ibs: %d\n",
__func__, hwirq / IRQS_PER_MSI_REG, hwirq % IRQS_PER_MSI_REG);
@@ -359,13 +378,43 @@ static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi,
return 0;
}
+/* MPIC chip with 2.0 version has erratum PIC1 */
+static int mpic_has_errata(struct platform_device *dev)
+{
+ struct device_node *mpic_node;
+
+ mpic_node = of_irq_find_parent(dev->dev.of_node);
+ if (mpic_node) {
+ u32 *reg_base, brr1 = 0;
+ /* Get the PIC reg base */
+ reg_base = of_iomap(mpic_node, 0);
+ of_node_put(mpic_node);
+ if (!reg_base) {
+ dev_err(&dev->dev, "ioremap problem failed.\n");
+ return -EIO;
+ }
+
+ /* Get the mpic chip version from block revision register 1 */
+ brr1 = in_be32(reg_base + MPIC_FSL_BRR1);
+ iounmap(reg_base);
+ if ((brr1 & MPIC_FSL_BRR1_VER) == 0x0200)
+ return 1;
+ } else {
+ dev_err(&dev->dev, "MSI can't find his parent mpic node.\n");
+ of_node_put(mpic_node);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static const struct of_device_id fsl_of_msi_ids[];
static int __devinit fsl_of_msi_probe(struct platform_device *dev)
{
const struct of_device_id *match;
struct fsl_msi *msi;
struct resource res;
- int err, i, j, irq_index, count;
+ int err, i, j, irq_index, count, errata;
int rc;
const u32 *p;
struct fsl_msi_feature *features;
@@ -421,6 +470,16 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
msi->feature = features->fsl_pic_ip;
+ if ((features->fsl_pic_ip & FSL_PIC_IP_MASK) == FSL_PIC_IP_MPIC) {
+ errata = mpic_has_errata(dev);
+ if (errata > 0) {
+ msi->feature |= MSI_HW_ERRATA_ENDIAN;
+ } else if (errata < 0) {
+ err = errata;
+ goto error_out;
+ }
+ }
+
/*
* Remember the phandle, so that we can match with any PCI nodes
* that have an "fsl,msi" property.
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h
index 8225f86..354d546 100644
--- a/arch/powerpc/sysdev/fsl_msi.h
+++ b/arch/powerpc/sysdev/fsl_msi.h
@@ -25,6 +25,9 @@
#define FSL_PIC_IP_IPIC 0x00000002
#define FSL_PIC_IP_VMPIC 0x00000003
+#define MSI_HW_ERRATA_MASK 0x000000F0
+#define MSI_HW_ERRATA_ENDIAN 0x00000010
+
struct fsl_msi {
struct irq_domain *irqhost;
--
1.7.5.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox