[linux-yocto] [PATCH 24/28] LSI AXM55xx: DDR retention fixes
Bruce Ashfield
bruce.ashfield at windriver.com
Fri May 2 13:19:24 PDT 2014
On 14-05-02 03:17 PM, Charlie Paul wrote:
> From: Gary McGee <gary.mcgee at lsi.com>
>
> Added the functions to support the DDR shutdown
> Fixed the quiesce TODO and added the vp engine calls
> Added the calls to the DDR shutdown
Another list of changes .. this says "three commits" to me.
Bruce
>
> Signed-off-by: Gary McGee <gary.mcgee at lsi.com>
> ---
> arch/arm/mach-axxia/Makefile | 2 +-
> arch/arm/mach-axxia/ddr_retention.c | 231 ++++++++++++------------
> arch/arm/mach-axxia/ddr_shutdown.c | 332 +++++++++++++++++++++++++++++++++++
> 3 files changed, 446 insertions(+), 119 deletions(-)
> create mode 100644 arch/arm/mach-axxia/ddr_shutdown.c
>
> diff --git a/arch/arm/mach-axxia/Makefile b/arch/arm/mach-axxia/Makefile
> index 47e386b..1352c37d 100644
> --- a/arch/arm/mach-axxia/Makefile
> +++ b/arch/arm/mach-axxia/Makefile
> @@ -7,7 +7,7 @@ obj-y += io.o
> obj-y += ncr.o
> obj-y += timers.o
> obj-y += pci.o
> -obj-y += ddr_retention.o
> +obj-y += ddr_retention.o ddr_shutdown.o
> obj-$(CONFIG_I2C) += i2c.o
> obj-$(CONFIG_AXXIA_RIO) += rapidio.o
> obj-$(CONFIG_SMP) += platsmp.o headsmp.o
> diff --git a/arch/arm/mach-axxia/ddr_retention.c b/arch/arm/mach-axxia/ddr_retention.c
> index 7e4687d..6429151 100644
> --- a/arch/arm/mach-axxia/ddr_retention.c
> +++ b/arch/arm/mach-axxia/ddr_retention.c
> @@ -26,7 +26,9 @@
> #include <linux/syscore_ops.h>
> #include <linux/proc_fs.h>
> #include <linux/delay.h>
> +#include <linux/prefetch.h>
> #include <linux/of.h>
> +
> #include <asm/io.h>
> #include <asm/cacheflush.h>
> #include <mach/ncr.h>
> @@ -36,7 +38,13 @@ static void __iomem *apb;
> static void __iomem *dickens;
> static int ddr_retention_enabled;
>
> -unsigned long ncp_caal_regions_acp55xx[] = {
> +enum {
> + AXXIA_ENGINE_CAAL,
> + AXXIA_ENGINE_CNAL
> +};
> +
> +unsigned long
> +ncp_caal_regions_acp55xx[] = {
> NCP_REGION_ID(0x0b, 0x05), /* SPPV2 */
> NCP_REGION_ID(0x0c, 0x05), /* SED */
> NCP_REGION_ID(0x0e, 0x05), /* DPI_HFA */
> @@ -54,16 +62,22 @@ unsigned long ncp_caal_regions_acp55xx[] = {
> NCP_REGION_ID(0x1c, 0x05), /* PAB */
> NCP_REGION_ID(0x1f, 0x05), /* EIOAM0 */
> NCP_REGION_ID(0x31, 0x05), /* ISB */
> - NCP_REGION_ID(0x28, 0x05), /* EIOASM0 */
> - NCP_REGION_ID(0x29, 0x05), /* EIOASM1 */
> - NCP_REGION_ID(0x2a, 0x05), /* EIOAS2 */
> - NCP_REGION_ID(0x2b, 0x05), /* EIOAS3 */
> - NCP_REGION_ID(0x2c, 0x05), /* EIOAS4 */
> - NCP_REGION_ID(0x2d, 0x05), /* EIOAS5 */
> - NCP_REGION_ID(0x32, 0x05), /* ISBS */
> NCP_REGION_ID(0xff, 0xff)
> };
>
> +unsigned long
> +ncp_cnal_regions_acp55xx[] = {
> + NCP_REGION_ID(0x28, 0x05), /* EIOASM0 */
> + NCP_REGION_ID(0x29, 0x05), /* EIOASM1 */
> + NCP_REGION_ID(0x2a, 0x05), /* EIOAS2 */
> + NCP_REGION_ID(0x2b, 0x05), /* EIOAS3 */
> + NCP_REGION_ID(0x2c, 0x05), /* EIOAS4 */
> + NCP_REGION_ID(0x2d, 0x05), /* EIOAS5 */
> + NCP_REGION_ID(0x32, 0x05), /* ISBS */
> + NCP_REGION_ID(0xff, 0xff)
> +};
> +
> +
> /*
> ------------------------------------------------------------------------------
> flush_l3
> @@ -120,23 +134,41 @@ flush_l3(void)
> }
>
> asm volatile ("dsb" : : : "memory");
> - asm volatile ("dmb" : : : "memory");
>
> return;
> }
>
> static void
> -quiesce_vp_engine(void)
> +quiesce_vp_engine(int engineType)
> {
> - unsigned long *pCnalRegions = ncp_caal_regions_acp55xx;
> + unsigned long *pEngineRegions;
> unsigned long *pRegion;
> + unsigned long ortOff, owtOff;
> unsigned ort, owt;
> unsigned long buf = 0;
> unsigned short node, target;
> int loop;
>
> printk(KERN_INFO "quiescing VP engines...\n");
> - pRegion = pCnalRegions;
> +
> + switch (engineType) {
> + case AXXIA_ENGINE_CNAL:
> + pEngineRegions = ncp_cnal_regions_acp55xx;
> + ortOff = 0x1c0;
> + owtOff = 0x1c4;
> + break;
> +
> + case AXXIA_ENGINE_CAAL:
> + pEngineRegions = ncp_caal_regions_acp55xx;
> + ortOff = 0xf8;
> + owtOff = 0xfc;
> + break;
> +
> + default:
> + return;
> + }
> +
> + pRegion = pEngineRegions;
>
> while (*pRegion != NCP_REGION_ID(0xff, 0xff)) {
> /* set read/write transaction limits to zero */
> @@ -145,15 +177,15 @@ quiesce_vp_engine(void)
> pRegion++;
> }
>
> - pRegion = pCnalRegions;
> + pRegion = pEngineRegions;
> loop = 0;
>
> while (*pRegion != NCP_REGION_ID(0xff, 0xff)) {
> node = (*pRegion & 0xffff0000) >> 16;
> target = *pRegion & 0x0000ffff;
> /* read the number of outstanding read/write transactions */
> - ncr_read(*pRegion, 0xf8, 4, &ort);
> - ncr_read(*pRegion, 0xfc, 4, &owt);
> + ncr_read(*pRegion, ortOff, 4, &ort);
> + ncr_read(*pRegion, owtOff, 4, &owt);
>
> if ((ort == 0) && (owt == 0)) {
> /* this engine has been quiesced, move on to the next */
> @@ -173,86 +205,54 @@ quiesce_vp_engine(void)
> return;
> }
>
> -static inline void
> -ncp_ddr_shutdown(void)
> +static inline void cpu_disable_l2_prefetch(void)
> {
> - unsigned long value;
> - int loop = 1;
> - unsigned long cdr2[2] = {0x00002200, 0x00000f00};
> - int smId;
> -
> -
> - /*
> - * Most of the PIO command has already been set up.
> - * issue config ring write - enter DDR self-refresh mode
> - */
> -
> - for (smId = 0; smId < 2; smId++) {
> - /* CDR2 - Node.target */
> - ncr_register_write(cdr2[smId], (unsigned *) (nca + 0xf8));
> - /* CDR0 - */
> - ncr_register_write(0x80050003, (unsigned *) (nca + 0xf0));
> - do {
> - value = ncr_register_read((unsigned *)
> - (nca + 0xf0));
> - } while ((0x80000000UL & value));
> - }
> -
> - /* check interrupt status for completion */
> - /* CDR1 - word offset 0x104 (byte offset 0x410) */
> - ncr_register_write(0x00000104, (unsigned *) (nca + 0xf4));
> + unsigned int v;
> +
> + /*
> + * MRC p15, 1, <Rt>, c15, c0, 3; Read L2 Prefetch Control Register
> + * MCR p15, 1, <Rt>, c15, c0, 3; Write L2 Prefetch Control Register
> + *
> + */
> + asm volatile(
> + " mrc p15, 1, %0, c15, c0, 3\n"
> + " and %0, %0, #0x0000\n"
> + " mcr p15, 1, %0, c15, c0, 3\n"
> + : "=&r" (v)
> + :
> + : "cc");
> +
> + isb();
> +}
>
> - for (smId = 0; smId < 2; smId++) {
> - /* CDR2 - Node.target */
> - ncr_register_write(cdr2[smId], (unsigned *) (nca + 0xf8));
> - do {
> - ncr_register_write(loop, (unsigned *)
> - (nca + 0x11f0));
> -
> - /* issue config ring read */
> - ncr_register_write(0x80040003, (unsigned *)
> - (nca + 0xf0));
> - do {
> - value = ncr_register_read((unsigned *)
> - (nca + 0xf0));
> - } while ((0x80000000UL & value));
> -
> - value = ncr_register_read((unsigned *)
> - (nca + 0x1000));
> - ncr_register_write(value, (unsigned *)
> - (nca + 0x1200));
> -
> - loop++;
> - } while ((value & 0x0200) == 0);
> - }
> +static inline void
> +reset_elm_trace(void)
> +{
> + /* reset and disable ELM trace */
> + ncr_register_write(htonl(0x000fff04), (unsigned *) (apb + 0x68000));
> + ncr_register_write(htonl(0x000fff04), (unsigned *) (apb + 0x78000));
>
> - /*
> - Indicate DDR Retention Reset
> - */
> + /* reset ELM statistics */
> + ncr_register_write(htonl(0x00001), (unsigned *) (apb + 0x60230));
> + ncr_register_write(htonl(0x00001), (unsigned *) (apb + 0x70230));
>
> - /* set bit 0 of persist_scratch */
> - writel(0x00000001, apb + 0x300dc);
> + /* enable ELM trace */
> + ncr_register_write(htonl(0x000fff01), (unsigned *) (apb + 0x68000));
> + ncr_register_write(htonl(0x000fff01), (unsigned *) (apb + 0x78000));
> +}
>
> - /*
> - Issue Chip Reset
> - */
>
> - /* Intrnl Boot, 0xffff0000 Target */
> - writel(0x00000040, apb + 0x31004);
> - /* Set ResetReadDone */
> - writel(0x80000000, apb + 0x3180c);
> - /* Chip Reset */
> - writel(0x00080802, apb + 0x31008);
> +extern void ncp_ddr_shutdown(void *, void *, unsigned long);
>
> - return;
> -}
>
> void
> initiate_retention_reset(void)
> {
> unsigned long ctl_244 = 0;
> unsigned long value;
> - unsigned long delay;
> + unsigned cpu_id ;
> + volatile long tmp;
> + volatile long *ptmp;
>
> if (0 == ddr_retention_enabled) {
> pr_info("DDR Retention Reset is Not Enabled\n");
> @@ -262,27 +262,25 @@ initiate_retention_reset(void)
> if (NULL == nca || NULL == apb || NULL == dickens)
> BUG();
>
> - system_state = SYSTEM_RESTART;
> + preempt_disable();
> + cpu_id = smp_processor_id();
> +
> + /* send stop message to other CPUs */
> + local_irq_disable();
> + local_fiq_disable();
> asm volatile ("dsb" : : : "memory");
> asm volatile ("dmb" : : : "memory");
> - device_shutdown();
> - syscore_shutdown();
> + system_state = SYSTEM_RESTART;
> smp_send_stop();
>
> - for (delay = 0; delay < 10000; ++delay)
> - udelay(1000);
> + udelay(1000);
>
> flush_cache_all();
> flush_l3();
>
> - /* TODO - quiesce VP engines */
> - quiesce_vp_engine();
> -
> - /* disable sysmem interrupts */
> - printk(KERN_INFO "disabling sysmem interrupts\n");
> - value = 0;
> - ncr_write(NCP_REGION_ID(34, 0), 0x414, 4, &value);
> - ncr_write(NCP_REGION_ID(15, 0), 0x414, 4, &value);
> + /* quiesce VP engines */
> + quiesce_vp_engine(AXXIA_ENGINE_CAAL);
> + quiesce_vp_engine(AXXIA_ENGINE_CNAL);
>
> /* unlock reset register for later */
> writel(0x000000ab, apb + 0x31000); /* Access Key */
> @@ -292,27 +290,27 @@ initiate_retention_reset(void)
> ncr_read(NCP_REGION_ID(34, 0), 0x3d0, 4, &ctl_244);
> ctl_244 |= 0x000a0000;
>
> - /*
> - * set up for CRBW operation
> - */
> - /* write register value into CDAR[0] */
> - ncr_register_write(ctl_244, (unsigned *) (nca + 0x1000));
> + /* belts & braces: put secondary CPUs into reset */
> + value = ~(1 << cpu_id);
> + value &= 0xffff;
> + ncr_register_write(htonl(value), (unsigned *) (apb + 0x31030));
>
> - /* CDR2 - Node.target = 34.0 */
> - ncr_register_write(0x00002200, (unsigned *) (nca + 0xf8));
> + /* load entire ddr_shutdown function into L2 cache */
> + ptmp = (long *) ncp_ddr_shutdown;
> + do {
> + tmp += *ptmp++;
> + } while (ptmp < (long *) (ncp_ddr_shutdown + 0x1000));
>
> - /* CDR1 - word offset 0xf4 (byte offset 0x3d0) */
> - ncr_register_write(0x000000f4, (unsigned *) (nca + 0xf4));
> + asm volatile ("isb" : : : "memory");
>
> - /*
> - * issue instruction barrier
> - * this should cause the next few instructions to be fetched
> - * into cache
> - */
> - asm volatile ("dsb" : : : "memory");
> - prefetch(ncp_ddr_shutdown);
> + /* disable L2 prefetching */
> + cpu_disable_l2_prefetch();
>
> - ncp_ddr_shutdown();
> + /* reset ELM DDR access trace buffer */
> + reset_elm_trace();
> +
> + /* call cache resident ddr shutdown function */
> + ncp_ddr_shutdown(nca, apb, ctl_244);
>
> return;
> }
> @@ -326,13 +324,11 @@ axxia_ddr_retention_trigger(struct file *file, const char __user *buf,
> return 0;
> }
>
> -static const struct file_operations proc_ops = {
> +static const struct file_operations axxia_ddr_retention_proc_ops = {
> .write = axxia_ddr_retention_trigger,
> .llseek = noop_llseek,
> };
>
> -#define PROC_PATH "driver/axxia_ddr_retention_reset"
> -
> void
> axxia_ddr_retention_init(void)
> {
> @@ -343,11 +339,10 @@ axxia_ddr_retention_init(void)
> if (of_find_compatible_node(NULL, NULL, "lsi,axm5516")) {
> /* Create /proc entry. */
> if (!proc_create("driver/axxia_ddr_retention_reset",
> - S_IWUSR, NULL,
> - &proc_ops)) {
> + S_IWUSR, NULL, &axxia_ddr_retention_proc_ops)) {
> pr_info("Failed to register DDR retention proc entry\n");
> } else {
> - apb = ioremap(0x2010000000, 0x40000);
> + apb = ioremap(0x2010000000, 0x80000);
> nca = ioremap(0x002020100000ULL, 0x20000);
> dickens = ioremap(0x2000000000, 0x1000000);
> ddr_retention_enabled = 1;
> diff --git a/arch/arm/mach-axxia/ddr_shutdown.c b/arch/arm/mach-axxia/ddr_shutdown.c
> new file mode 100644
> index 0000000..a10a4cb
> --- /dev/null
> +++ b/arch/arm/mach-axxia/ddr_shutdown.c
> @@ -0,0 +1,332 @@
> +
> +#include <asm/io.h>
> +
> +/*
> + * private copies of the ioread/write macros
> + * These are defined with a different barrier
> + * to avoid the outer_sync() call that's part
> + * of the normal barrier.
> + */
> +#define pvt_ioread32be(p) ({ unsigned int __v = be32_to_cpu((__force __be32)__raw_readl(p)); dsb(); __v; })
> +#define pvt_iowrite32be(v, p) ({ dsb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
> +
> +#define pvt_ioread32(p) ({ unsigned int __v = (__raw_readl(p)); dsb(); __v; })
> +#define pvt_iowrite32(v, p) ({ dsb(); __raw_writel((__force __u32)(v), p); })
> +
> +/* #define DDR_SHUTDOWN_DEBUG */
> +#ifdef DDR_SHUTDOWN_DEBUG
> +#define dbg_write(v, p) pvt_iowrite32be(v, p)
> +#else
> +#define dbg_write(v, p)
> +#endif
> +
> +/*
> + * Wait For Completion timeout
> + * how many loops to wait for the config ring access to complete
> + */
> +#define WFC_TIMEOUT (400000)
> +
> +/*
> + * DDR status timeout
> + * how many times we read the DDR status waiting for self refresh complete
> + */
> +#define DDR_TIMEOUT (1000)
> +
> +void ncp_ddr_shutdown(void *nca, void *apb, unsigned long ctl_244)
> +{
> + unsigned long value;
> + int two_elms = 0;
> + int wfc_loop = 0;
> + int ddr_loop = 0;
> +
> + /* determine if we are in one or two ELM/SMEM mode */
> + value = pvt_ioread32(apb + 0x60004);
> + two_elms = (value & 0x00000200);
> +
> + /*
> + * Issue command to put SMEM0 into self-refresh mode
> + *
> + * ncpWrite 0x22.0.0x3d0
> + */
> + dbg_write(0xaaaa0001, (unsigned *)(nca + 0x1200));
> +
> + /* write register value into CDAR[0] */
> + pvt_iowrite32be(ctl_244, (unsigned *)(nca + 0x1000));
> + /* CDR2 - Node.target */
> + pvt_iowrite32be(0x00002200, (unsigned *)(nca + 0xf8));
> + /* CDR1 - word offset 0xf4 (byte offset 0x3d0) */
> + pvt_iowrite32be(0x000000f4, (unsigned *)(nca + 0xf4));
> + /* CDR0 - write command */
> + pvt_iowrite32be(0x80050003, (unsigned *)(nca + 0xf0));
> + wfc_loop = 0;
> + do {
> + if (wfc_loop++ > WFC_TIMEOUT) {
> + dbg_write(value, (unsigned *)(nca + 0x11fc));
> + dbg_write(0xffff0001, (unsigned *)(nca + 0x1200));
> + goto do_reset;
> + }
> + dbg_write(wfc_loop, (unsigned *)(nca + 0x11f8));
> + value = pvt_ioread32be((unsigned *)
> + (nca + 0xf0));
> + } while ((0x80000000UL & value));
> + dbg_write(0xaaaa0002, (unsigned *)(nca + 0x1200));
> +
> + if (two_elms) {
> + /*
> + * Issue command to put SMEM1 into self-refresh mode
> + *
> + * ncpWrite 0x0f.0.0x3d0
> + */
> + /* CDR2 - Node.target */
> + pvt_iowrite32be(0x00000f00, (unsigned *)(nca + 0xf8));
> + /* CDR0 - write command */
> + pvt_iowrite32be(0x80050003, (unsigned *)(nca + 0xf0));
> + wfc_loop = 0;
> + do {
> + if (wfc_loop++ > WFC_TIMEOUT) {
> + dbg_write(value, (unsigned *)(nca + 0x11fc));
> + dbg_write(0xffff0002,
> + (unsigned *)(nca + 0x1200));
> + goto do_reset;
> + }
> + value = pvt_ioread32be((unsigned *)
> + (nca + 0xf0));
> + } while ((0x80000000UL & value));
> + }
> +
> + dbg_write(0xaaaa0003, (unsigned *)(nca + 0x1200));
> +
> + /*
> + * Poll for SMEM0 refresh-mode command completion
> + */
> + /* CDR1 - word offset 0x104 (byte offset 0x410) */
> + pvt_iowrite32be(0x00000104, (unsigned *)(nca + 0xf4));
> + /* CDR2 - Node.target */
> + pvt_iowrite32be(0x00002200, (unsigned *)(nca + 0xf8));
> + ddr_loop = 0;
> + do {
> + if (ddr_loop++ > DDR_TIMEOUT) {
> + dbg_write(value, (unsigned *)(nca + 0x11fc));
> + dbg_write(0xffff0003, (unsigned *)(nca + 0x1200));
> + goto do_reset;
> + }
> + pvt_iowrite32be(wfc_loop, (unsigned *)
> + (nca + 0x11f0));
> +
> + /* issue config ring read */
> + pvt_iowrite32be(0x80040003, (unsigned *)
> + (nca + 0xf0));
> + wfc_loop = 0;
> + do {
> + if (wfc_loop++ > WFC_TIMEOUT) {
> + dbg_write(value, (unsigned *)(nca + 0x11fc));
> + dbg_write(0xffff0004,
> + (unsigned *)(nca + 0x1200));
> + goto do_reset;
> + }
> + value = pvt_ioread32be((unsigned *)
> + (nca + 0xf0));
> + } while ((0x80000000UL & value));
> +
> + value = pvt_ioread32be((unsigned *)
> + (nca + 0x1000));
> +
> + } while ((value & 0x0200) == 0);
> + dbg_write(0xaaaa0004, (unsigned *)(nca + 0x1200));
> +
> + if (two_elms) {
> + /*
> + * Poll for SMEM1 refresh-mode command completion
> + */
> + /* CDR2 - Node.target */
> + pvt_iowrite32be(0x00000f00, (unsigned *)(nca + 0xf8));
> + ddr_loop = 0;
> + do {
> + if (ddr_loop++ > DDR_TIMEOUT) {
> + dbg_write(value, (unsigned *)(nca + 0x11fc));
> + dbg_write(0xffff0005,
> + (unsigned *)(nca + 0x1200));
> + goto do_reset;
> + }
> +
> + /* issue config ring read */
> + pvt_iowrite32be(0x80040003, (unsigned *)(nca + 0xf0));
> + wfc_loop = 0;
> + do {
> + if (wfc_loop++ > WFC_TIMEOUT) {
> + dbg_write(value,
> + (unsigned *)(nca + 0x11fc));
> + dbg_write(0xffff0006,
> + (unsigned *)(nca + 0x1200));
> + goto do_reset;
> + }
> + value =
> + pvt_ioread32be((unsigned *)(nca + 0xf0));
> + } while ((0x80000000UL & value));
> +
> + value = pvt_ioread32be((unsigned *)
> + (nca + 0x1000));
> + wfc_loop++;
> + } while ((value & 0x0200) == 0);
> + }
> +
> + dbg_write(0xaaaa0005, (unsigned *)(nca + 0x1200));
> +
> + /*
> + * Tell U-Boot to do a DDR retention-reset
> + * (i.e. set bit 0 of persist_scratch register)
> + */
> + pvt_iowrite32(0x00000001, apb + 0x300dc);
> +
> + dbg_write(0xaaaa0006, (unsigned *)(nca + 0x1200));
> +do_reset:
> + /*
> + * Issue Chip reset
> + */
> + /* Intrnl Boot, 0xffff0000 Target */
> + pvt_iowrite32(0x00000040, apb + 0x31004);
> + /* Set ResetReadDone */
> + pvt_iowrite32(0x80000000, apb + 0x3180c);
> + /* Chip Reset */
> + pvt_iowrite32(0x00080802, apb + 0x31008);
> +
> + while (1)
> + ;
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> +
> + return;
> +}
> +
> +void ncp_ddr_shutdown_dummy(void)
> +{
> + wfi();
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> + __asm__ __volatile__(" nop\n\t");
> +}
>
More information about the linux-yocto
mailing list