[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