Commit f2d11858 authored by Tero Kristo's avatar Tero Kristo Committed by Kevin Hilman
Browse files

OMAP: PM: DMA context save/restore for off-mode support



For HS/EMU devices, these additional features are also used:

- DMA interrupt disable routine added
- Added DMA controller reset to DMA context restore

Signed-off-by: default avatarTero Kristo <tero.kristo@nokia.com>
Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent 2f5939c3
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <plat/sdrc.h>
#include <plat/prcm.h>
#include <plat/gpmc.h>
#include <plat/dma.h>

#include <asm/tlbflush.h>

@@ -95,6 +96,7 @@ static void omap3_core_save_context(void)
	omap3_gpmc_save_context();
	/* Save the system control module context, padconf already save above*/
	omap3_control_save_context();
	omap_dma_global_context_save();
}

static void omap3_core_restore_context(void)
@@ -105,6 +107,7 @@ static void omap3_core_restore_context(void)
	omap3_gpmc_restore_context();
	/* Restore the interrupt controller context */
	omap_intc_restore_context();
	omap_dma_global_context_restore();
}

/*
+39 −0
Original line number Diff line number Diff line
@@ -54,6 +54,12 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };

static int enable_1510_mode;

static struct omap_dma_global_context_registers {
	u32 dma_irqenable_l0;
	u32 dma_ocp_sysconfig;
	u32 dma_gcr;
} omap_dma_global_context;

struct omap_dma_lch {
	int next_lch;
	int dev_id;
@@ -2341,6 +2347,39 @@ void omap_stop_lcd_dma(void)
}
EXPORT_SYMBOL(omap_stop_lcd_dma);

void omap_dma_global_context_save(void)
{
	omap_dma_global_context.dma_irqenable_l0 =
		dma_read(IRQENABLE_L0);
	omap_dma_global_context.dma_ocp_sysconfig =
		dma_read(OCP_SYSCONFIG);
	omap_dma_global_context.dma_gcr = dma_read(GCR);
}

void omap_dma_global_context_restore(void)
{
	dma_write(0x2, OCP_SYSCONFIG);
	while (!__raw_readl(omap_dma_base + OMAP_DMA4_SYSSTATUS))
		;
	dma_write(omap_dma_global_context.dma_gcr, GCR);
	dma_write(omap_dma_global_context.dma_ocp_sysconfig,
		OCP_SYSCONFIG);
	dma_write(omap_dma_global_context.dma_irqenable_l0,
		IRQENABLE_L0);
}

void omap_dma_disable_irq(int lch)
{
	u32 val;

	if (cpu_class_is_omap2()) {
		/* Disable interrupts */
		val = dma_read(IRQENABLE_L0);
		val &= ~(1 << lch);
		dma_write(val, IRQENABLE_L0);
	}
}

/*----------------------------------------------------------------------------*/

static int __init omap_init_dma(void)
+5 −0
Original line number Diff line number Diff line
@@ -633,6 +633,11 @@ extern void omap_set_dma_dst_endian_type(int lch, enum end_type etype);
extern void omap_set_dma_src_endian_type(int lch, enum end_type etype);
extern int omap_get_dma_index(int lch, int *ei, int *fi);

void omap_dma_global_context_save(void);
void omap_dma_global_context_restore(void);

extern void omap_dma_disable_irq(int lch);

/* Chaining APIs */
#ifndef CONFIG_ARCH_OMAP1
extern int omap_request_dma_chain(int dev_id, const char *dev_name,