]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
ARM: OMAP: Add DSP common code
authorToshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
Fri, 8 Dec 2006 00:20:22 +0000 (16:20 -0800)
committerTony Lindgren <tony@atomide.com>
Wed, 4 Apr 2007 14:42:14 +0000 (10:42 -0400)
Add DSP common code for OMAP. This patch adds code to idle the
OMAP DSP.

Signed-off-by: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/plat-omap/Makefile
arch/arm/plat-omap/dsp/Kconfig [new file with mode: 0644]
arch/arm/plat-omap/dsp/Makefile [new file with mode: 0644]
arch/arm/plat-omap/dsp/dsp_common.c [new file with mode: 0644]
arch/arm/plat-omap/dsp/dsp_common.h [new file with mode: 0644]
arch/arm/plat-omap/dsp/hardware_dsp.h [new file with mode: 0644]
arch/arm/plat-omap/dsp/omap1_dsp.h [new file with mode: 0644]
arch/arm/plat-omap/dsp/omap2_dsp.h [new file with mode: 0644]
arch/arm/plat-omap/mcbsp.c

index cc2900f3e6616340e2f66f195ce40a86d999735e..17656b6688c4b7a3c69ca96f252e0d733446491e 100644 (file)
@@ -27,4 +27,5 @@ obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
 obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
 
 # DSP subsystem
+obj-y += dsp/
 obj-$(CONFIG_OMAP_DSP) += mailbox.o
diff --git a/arch/arm/plat-omap/dsp/Kconfig b/arch/arm/plat-omap/dsp/Kconfig
new file mode 100644 (file)
index 0000000..0d62bee
--- /dev/null
@@ -0,0 +1,31 @@
+
+config OMAP_DSP
+       tristate "OMAP DSP driver (DSP Gateway)"
+       depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP24XX
+       select OMAP_MMU_FWK
+       select OMAP_MBOX_FWK
+       help
+         This enables OMAP DSP driver, DSP Gateway.
+
+config OMAP_DSP_MBCMD_VERBOSE
+       bool "Mailbox Command Verbose LOG"
+       depends on OMAP_DSP
+       help
+          This enables kernel log output in the Mailbox command exchanges
+         in the DSP Gateway driver.
+
+config OMAP_DSP_TASK_MULTIOPEN
+       bool "DSP Task Multiopen Capability"
+       depends on OMAP_DSP
+       help
+          This enables DSP tasks to be opened by multiple times at a time.
+         Otherwise, they can be opened only once at a time.
+
+config OMAP_DSP_FBEXPORT
+       bool "Framebuffer export to DSP"
+       depends on OMAP_DSP && FB
+       help
+          This enables to map the frame buffer to DSP.
+         By doing this, DSP can access the frame buffer directly without
+         bothering ARM.
+
diff --git a/arch/arm/plat-omap/dsp/Makefile b/arch/arm/plat-omap/dsp/Makefile
new file mode 100644 (file)
index 0000000..c7d86f3
--- /dev/null
@@ -0,0 +1,15 @@
+#
+# Makefile for the OMAP DSP driver.
+#
+
+# The target object and module list name.
+
+obj-y := dsp_common.o
+
+obj-$(CONFIG_OMAP_DSP) += dsp.o
+
+# Declare multi-part drivers
+
+dsp-objs       := dsp_core.o ipbuf.o mblog.o task.o \
+                  dsp_ctl_core.o dsp_ctl.o taskwatch.o error.o dsp_mem.o \
+                  uaccess_dsp.o
diff --git a/arch/arm/plat-omap/dsp/dsp_common.c b/arch/arm/plat-omap/dsp/dsp_common.c
new file mode 100644 (file)
index 0000000..cfb2bbc
--- /dev/null
@@ -0,0 +1,617 @@
+/*
+ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
+ *
+ * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <asm/tlbflush.h>
+#include <asm/irq.h>
+#ifdef CONFIG_ARCH_OMAP1
+#include <asm/arch/tc.h>
+#endif
+#include "dsp_common.h"
+
+#if defined(CONFIG_ARCH_OMAP1)
+#define dsp_boot_config(mode)  omap_writew((mode), MPUI_DSP_BOOT_CONFIG)
+#elif defined(CONFIG_ARCH_OMAP2)
+#define dsp_boot_config(mode)  writel((mode), DSP_IPI_DSPBOOTCONFIG)
+#endif
+
+struct omap_dsp *omap_dsp;
+
+#if defined(CONFIG_ARCH_OMAP1)
+struct clk *dsp_ck_handle;
+struct clk *api_ck_handle;
+#elif defined(CONFIG_ARCH_OMAP2)
+struct clk *dsp_fck_handle;
+struct clk *dsp_ick_handle;
+#endif
+dsp_long_t dspmem_base, dspmem_size,
+          daram_base, daram_size,
+          saram_base, saram_size;
+
+static struct cpustat {
+       struct mutex lock;
+       enum cpustat_e stat;
+       enum cpustat_e req;
+       u16 icrmask;
+#ifdef CONFIG_ARCH_OMAP1
+       struct {
+               int mpui;
+               int mem;
+               int mem_delayed;
+       } usecount;
+       int (*mem_req_cb)(void);
+       void (*mem_rel_cb)(void);
+#endif
+} cpustat = {
+       .stat = CPUSTAT_RESET,
+       .icrmask = 0xffff,
+};
+
+int dsp_set_rstvect(dsp_long_t adr)
+{
+       unsigned long *dst_adr;
+
+       if (adr >= DSPSPACE_SIZE)
+               return -EINVAL;
+
+       dst_adr = dspbyte_to_virt(DSP_BOOT_ADR_DIRECT);
+       /* word swap */
+       *dst_adr = ((adr & 0xffff) << 16) | (adr >> 16);
+       /* fill 8 bytes! */
+       *(dst_adr + 1) = 0;
+       /* direct boot */
+       dsp_boot_config(DSP_BOOT_CONFIG_DIRECT);
+
+       return 0;
+}
+
+dsp_long_t dsp_get_rstvect(void)
+{
+       unsigned long *dst_adr;
+
+       dst_adr = dspbyte_to_virt(DSP_BOOT_ADR_DIRECT);
+       return ((*dst_adr & 0xffff) << 16) | (*dst_adr >> 16);
+}
+
+#ifdef CONFIG_ARCH_OMAP1
+static void simple_load_code(unsigned char *src_c, u16 *dst, int len)
+{
+       int i;
+       u16 *src = (u16 *)src_c;
+       int len_w;
+
+       /* len must be multiple of 2. */
+       if (len & 1)
+               BUG();
+
+       len_w = len / 2;
+       for (i = 0; i < len_w; i++) {
+               /* byte swap copy */
+               *dst = ((*src & 0x00ff) << 8) |
+                      ((*src & 0xff00) >> 8);
+               src++;
+               dst++;
+       }
+}
+
+/* program size must be multiple of 2 */
+#define GBL_IDLE_TEXT_SIZE     52
+#define GBL_IDLE_TEXT_INIT { \
+       /* SAM */ \
+       0x3c, 0x4a,                     /* 0x3c4a:     MOV 0x4, AR2 */ \
+       0xf4, 0x41, 0xfc, 0xff,         /* 0xf441fcff: AND 0xfcff, *AR2 */ \
+       /* disable WDT */ \
+       0x76, 0x34, 0x04, 0xb8,         /* 0x763404b8: MOV 0x3404, AR3 */ \
+       0xfb, 0x61, 0x00, 0xf5,         /* 0xfb6100f5: MOV 0x00f5, *AR3 */ \
+       0x9a,                           /* 0x9a:       PORT */ \
+       0xfb, 0x61, 0x00, 0xa0,         /* 0xfb6100a0: MOV 0x00a0, *AR3 */ \
+       0x9a,                           /* 0x9a:       PORT */ \
+       /* *IER0 = 0, *IER1 = 0 */ \
+       0x3c, 0x0b,                     /* 0x3c0b:     MOV 0x0, AR3 */ \
+       0xe6, 0x61, 0x00,               /* 0xe66100:   MOV 0, *AR3 */ \
+       0x76, 0x00, 0x45, 0xb8,         /* 0x76004508: MOV 0x45, AR3 */ \
+       0xe6, 0x61, 0x00,               /* 0xe66100:   MOV 0, *AR3 */ \
+       /* *ICR = 0xffff */ \
+       0x3c, 0x1b,                     /* 0x3c1b:     MOV 0x1, AR3 */ \
+       0xfb, 0x61, 0xff, 0xff,         /* 0xfb61ffff: MOV 0xffff, *AR3 */ \
+       0x9a,                           /* 0x9a:       PORT */ \
+       /* HOM */ \
+       0xf5, 0x41, 0x03, 0x00,         /* 0xf5410300: OR 0x0300, *AR2 */ \
+       /* idle and loop forever */ \
+       0x7a, 0x00, 0x00, 0x0c,         /* 0x7a00000c: IDLE */ \
+       0x4a, 0x7a,                     /* 0x4a7a:     B -6 (infinite loop) */ \
+       0x20, 0x20, 0x20,               /* 0x20:       NOP */ \
+}
+
+/* program size must be multiple of 2 */
+#define CPU_IDLE_TEXT_SIZE     48
+#define CPU_IDLE_TEXT_INIT(icrh, icrl) { \
+       /* SAM */ \
+       0x3c, 0x4b,                     /* 0x3c4b:     MOV 0x4, AR3 */ \
+       0xf4, 0x61, 0xfc, 0xff,         /* 0xf461fcff: AND 0xfcff, *AR3 */ \
+       /* disable WDT */ \
+       0x76, 0x34, 0x04, 0xb8,         /* 0x763404b8: MOV 0x3404, AR3 */ \
+       0xfb, 0x61, 0x00, 0xf5,         /* 0xfb6100f5: MOV 0x00f5, *AR3 */ \
+       0x9a,                           /* 0x9a:       PORT */ \
+       0xfb, 0x61, 0x00, 0xa0,         /* 0xfb6100a0: MOV 0x00a0, *AR3 */ \
+       0x9a,                           /* 0x9a:       PORT */ \
+       /* *IER0 = 0, *IER1 = 0 */ \
+       0x3c, 0x0b,                     /* 0x3c0b:     MOV 0x0, AR3 */ \
+       0xe6, 0x61, 0x00,               /* 0xe66100:   MOV 0, *AR3 */ \
+       0x76, 0x00, 0x45, 0xb8,         /* 0x76004508: MOV 0x45, AR3 */ \
+       0xe6, 0x61, 0x00,               /* 0xe66100:   MOV 0, *AR3 */ \
+       /* set ICR = icr */ \
+       0x3c, 0x1b,                     /* 0x3c1b:     MOV AR3 0x1 */ \
+       0xfb, 0x61, (icrh), (icrl),     /* 0xfb61****: MOV *AR3, icr */ \
+       0x9a,                           /* 0x9a:       PORT */ \
+       /* idle and loop forever */ \
+       0x7a, 0x00, 0x00, 0x0c,         /* 0x7a00000c: IDLE */ \
+       0x4a, 0x7a,                     /* 0x4a7a:     B -6 (infinite loop) */ \
+       0x20, 0x20, 0x20                /* 0x20: nop */ \
+}
+
+/*
+ * idle_boot base:
+ * Initialized with DSP_BOOT_ADR_MPUI (=0x010000).
+ * This value is used before DSP Gateway driver is initialized.
+ * DSP Gateway driver will overwrite this value with other value,
+ * to avoid confliction with the user program.
+ */
+static dsp_long_t idle_boot_base = DSP_BOOT_ADR_MPUI;
+
+static void dsp_gbl_idle(void)
+{
+       unsigned char idle_text[GBL_IDLE_TEXT_SIZE] = GBL_IDLE_TEXT_INIT;
+
+       __dsp_reset();
+       clk_enable(api_ck_handle);
+
+#if 0
+       dsp_boot_config(DSP_BOOT_CONFIG_IDLE);
+#endif
+       simple_load_code(idle_text, dspbyte_to_virt(idle_boot_base),
+                        GBL_IDLE_TEXT_SIZE);
+       if (idle_boot_base == DSP_BOOT_ADR_MPUI)
+               dsp_boot_config(DSP_BOOT_CONFIG_MPUI);
+       else
+               dsp_set_rstvect(idle_boot_base);
+
+       __dsp_run();
+       udelay(100);    /* to make things stable */
+       clk_disable(api_ck_handle);
+}
+
+static void dsp_cpu_idle(void)
+{
+       u16 icr_tmp;
+       unsigned char icrh, icrl;
+
+       __dsp_reset();
+       clk_enable(api_ck_handle);
+
+       /*
+        * icr settings:
+        * DMA should not sleep for DARAM/SARAM access
+        * DPLL should not sleep while any other domain is active
+        */
+       icr_tmp = cpustat.icrmask & ~(DSPREG_ICR_DMA | DSPREG_ICR_DPLL);
+       icrh = icr_tmp >> 8;
+       icrl = icr_tmp & 0xff;
+       {
+               unsigned char idle_text[CPU_IDLE_TEXT_SIZE] = CPU_IDLE_TEXT_INIT(icrh, icrl);
+               simple_load_code(idle_text, dspbyte_to_virt(idle_boot_base),
+                                CPU_IDLE_TEXT_SIZE);
+       }
+       if (idle_boot_base == DSP_BOOT_ADR_MPUI)
+               dsp_boot_config(DSP_BOOT_CONFIG_MPUI);
+       else
+               dsp_set_rstvect(idle_boot_base);
+       __dsp_run();
+       udelay(100);    /* to make things stable */
+       clk_disable(api_ck_handle);
+}
+
+void dsp_set_idle_boot_base(dsp_long_t adr, size_t size)
+{
+       if (adr == idle_boot_base)
+               return;
+       idle_boot_base = adr;
+       if ((size < GBL_IDLE_TEXT_SIZE) ||
+           (size < CPU_IDLE_TEXT_SIZE)) {
+               printk(KERN_ERR
+                      "omapdsp: size for idle program is not enough!\n");
+               BUG();
+       }
+
+       /* restart idle program with new base address */
+       if (cpustat.stat == CPUSTAT_GBL_IDLE)
+               dsp_gbl_idle();
+       if (cpustat.stat == CPUSTAT_CPU_IDLE)
+               dsp_cpu_idle();
+}
+
+void dsp_reset_idle_boot_base(void)
+{
+       idle_boot_base = DSP_BOOT_ADR_MPUI;
+}
+#else
+void dsp_reset_idle_boot_base(void) { }
+#endif /* CONFIG_ARCH_OMAP1 */
+
+static int init_done;
+
+static int __init omap_dsp_init(void)
+{
+       mutex_init(&cpustat.lock);
+
+       dspmem_size = 0;
+#ifdef CONFIG_ARCH_OMAP15XX
+       if (cpu_is_omap15xx()) {
+               dspmem_base = OMAP1510_DSP_BASE;
+               dspmem_size = OMAP1510_DSP_SIZE;
+               daram_base = OMAP1510_DARAM_BASE;
+               daram_size = OMAP1510_DARAM_SIZE;
+               saram_base = OMAP1510_SARAM_BASE;
+               saram_size = OMAP1510_SARAM_SIZE;
+       }
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+       if (cpu_is_omap16xx()) {
+               dspmem_base = OMAP16XX_DSP_BASE;
+               dspmem_size = OMAP16XX_DSP_SIZE;
+               daram_base = OMAP16XX_DARAM_BASE;
+               daram_size = OMAP16XX_DARAM_SIZE;
+               saram_base = OMAP16XX_SARAM_BASE;
+               saram_size = OMAP16XX_SARAM_SIZE;
+       }
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
+       if (cpu_is_omap24xx()) {
+               dspmem_base = DSP_MEM_24XX_VIRT;
+               dspmem_size = DSP_MEM_24XX_SIZE;
+               daram_base = OMAP24XX_DARAM_BASE;
+               daram_size = OMAP24XX_DARAM_SIZE;
+               saram_base = OMAP24XX_SARAM_BASE;
+               saram_size = OMAP24XX_SARAM_SIZE;
+       }
+#endif
+       if (dspmem_size == 0) {
+               printk(KERN_ERR "omapdsp: unsupported omap architecture.\n");
+               return -ENODEV;
+       }
+
+#if defined(CONFIG_ARCH_OMAP1)
+       dsp_ck_handle = clk_get(NULL, "dsp_ck");
+       if (IS_ERR(dsp_ck_handle)) {
+               printk(KERN_ERR "omapdsp: could not acquire dsp_ck handle.\n");
+               return PTR_ERR(dsp_ck_handle);
+       }
+
+       api_ck_handle = clk_get(NULL, "api_ck");
+       if (IS_ERR(api_ck_handle)) {
+               printk(KERN_ERR "omapdsp: could not acquire api_ck handle.\n");
+               if (dsp_ck_handle != NULL)
+                       clk_put(dsp_ck_handle);
+               return PTR_ERR(api_ck_handle);
+       }
+
+       /* This is needed for McBSP init, released in late_initcall */
+       clk_enable(api_ck_handle);
+
+       __dsp_enable();
+       mpui_byteswap_off();
+       mpui_wordswap_on();
+       tc_wordswap();
+#elif defined(CONFIG_ARCH_OMAP2)
+       dsp_fck_handle = clk_get(NULL, "dsp_fck");
+       if (IS_ERR(dsp_fck_handle)) {
+               printk(KERN_ERR "omapdsp: could not acquire dsp_fck handle.\n");
+               return PTR_ERR(dsp_fck_handle);
+       }
+
+       dsp_ick_handle = clk_get(NULL, "dsp_ick");
+       if (IS_ERR(dsp_ick_handle)) {
+               printk(KERN_ERR "omapdsp: could not acquire dsp_ick handle.\n");
+               if (dsp_fck_handle != NULL)
+                       clk_put(dsp_fck_handle);
+               return PTR_ERR(dsp_ick_handle);
+       }
+#endif
+
+       init_done = 1;
+       pr_info("omap_dsp_init() done\n");
+       return 0;
+}
+
+#if defined(CONFIG_ARCH_OMAP1)
+static int __dsp_late_init(void)
+{
+       clk_disable(api_ck_handle);
+       return 0;
+}
+late_initcall(__dsp_late_init);
+#endif
+
+static void dsp_cpustat_update(void)
+{
+       if (!init_done)
+               omap_dsp_init();
+
+       if (cpustat.req == CPUSTAT_RUN) {
+               if (cpustat.stat < CPUSTAT_RUN) {
+#if defined(CONFIG_ARCH_OMAP1)
+                       __dsp_reset();
+                       clk_enable(api_ck_handle);
+                       udelay(10);
+                       __dsp_run();
+#elif defined(CONFIG_ARCH_OMAP2)
+                       __dsp_core_disable();
+                       udelay(10);
+                       __dsp_core_enable();
+#endif
+                       cpustat.stat = CPUSTAT_RUN;
+               }
+               return;
+       }
+
+       /* cpustat.req < CPUSTAT_RUN */
+
+       if (cpustat.stat == CPUSTAT_RUN) {
+#ifdef CONFIG_ARCH_OMAP1
+               clk_disable(api_ck_handle);
+#endif
+       }
+
+#ifdef CONFIG_ARCH_OMAP1
+       /*
+        * (1) when ARM wants DARAM access, MPUI should be SAM and
+        *     DSP needs to be on.
+        * (2) if any bits of icr is masked, we can not enter global idle.
+        */
+       if ((cpustat.req == CPUSTAT_CPU_IDLE) ||
+           (cpustat.usecount.mem > 0) ||
+           (cpustat.usecount.mem_delayed > 0) ||
+           ((cpustat.usecount.mpui > 0) && (cpustat.icrmask != 0xffff))) {
+               if (cpustat.stat != CPUSTAT_CPU_IDLE) {
+                       dsp_cpu_idle();
+                       cpustat.stat = CPUSTAT_CPU_IDLE;
+               }
+               return;
+       }
+
+       /*
+        * when ARM only needs MPUI access, MPUI can be HOM and
+        * DSP can be idling.
+        */
+       if ((cpustat.req == CPUSTAT_GBL_IDLE) ||
+           (cpustat.usecount.mpui > 0)) {
+               if (cpustat.stat != CPUSTAT_GBL_IDLE) {
+                       dsp_gbl_idle();
+                       cpustat.stat = CPUSTAT_GBL_IDLE;
+               }
+               return;
+       }
+#endif /* CONFIG_ARCH_OMAP1 */
+
+       /*
+        * no user, no request
+        */
+       if (cpustat.stat != CPUSTAT_RESET) {
+#if defined(CONFIG_ARCH_OMAP1)
+               __dsp_reset();
+#elif defined(CONFIG_ARCH_OMAP2)
+               __dsp_core_disable();
+#endif
+               cpustat.stat = CPUSTAT_RESET;
+       }
+}
+
+void dsp_cpustat_request(enum cpustat_e req)
+{
+       mutex_lock(&cpustat.lock);
+       cpustat.req = req;
+       dsp_cpustat_update();
+       mutex_unlock(&cpustat.lock);
+}
+
+enum cpustat_e dsp_cpustat_get_stat(void)
+{
+       return cpustat.stat;
+}
+
+u16 dsp_cpustat_get_icrmask(void)
+{
+       return cpustat.icrmask;
+}
+
+void dsp_cpustat_set_icrmask(u16 mask)
+{
+       mutex_lock(&cpustat.lock);
+       cpustat.icrmask = mask;
+       dsp_cpustat_update();
+       mutex_unlock(&cpustat.lock);
+}
+
+#ifdef CONFIG_ARCH_OMAP1
+void omap_dsp_request_mpui(void)
+{
+       mutex_lock(&cpustat.lock);
+       if (cpustat.usecount.mpui++ == 0)
+               dsp_cpustat_update();
+       mutex_unlock(&cpustat.lock);
+}
+
+void omap_dsp_release_mpui(void)
+{
+       mutex_lock(&cpustat.lock);
+       if (cpustat.usecount.mpui-- == 0) {
+               printk(KERN_ERR
+                      "omapdsp: unbalanced mpui request/release detected.\n"
+                      "         cpustat.usecount.mpui is going to be "
+                      "less than zero! ... fixed to be zero.\n");
+               cpustat.usecount.mpui = 0;
+       }
+       if (cpustat.usecount.mpui == 0)
+               dsp_cpustat_update();
+       mutex_unlock(&cpustat.lock);
+}
+
+int omap_dsp_request_mem(void)
+{
+       int ret = 0;
+
+       mutex_lock(&cpustat.lock);
+       if ((cpustat.usecount.mem++ == 0) &&
+           (cpustat.usecount.mem_delayed == 0)) {
+               if (cpustat.mem_req_cb) {
+                       if ((ret = cpustat.mem_req_cb()) < 0) {
+                               cpustat.usecount.mem--;
+                               goto out;
+                       }
+               }
+               dsp_cpustat_update();
+       }
+out:
+       mutex_unlock(&cpustat.lock);
+
+       return ret;
+}
+
+/*
+ * release_mem will be delayed.
+ */
+static void do_release_mem(struct work_struct *dummy)
+{
+       mutex_lock(&cpustat.lock);
+       cpustat.usecount.mem_delayed = 0;
+       if (cpustat.usecount.mem == 0) {
+               dsp_cpustat_update();
+               if (cpustat.mem_rel_cb)
+                       cpustat.mem_rel_cb();
+       }
+       mutex_unlock(&cpustat.lock);
+}
+
+static DECLARE_DELAYED_WORK(mem_rel_work, do_release_mem);
+
+int omap_dsp_release_mem(void)
+{
+       mutex_lock(&cpustat.lock);
+
+       /* cancel previous release work */
+       cancel_delayed_work(&mem_rel_work);
+       cpustat.usecount.mem_delayed = 0;
+
+       if (cpustat.usecount.mem-- == 0) {
+               printk(KERN_ERR
+                      "omapdsp: unbalanced memory request/release detected.\n"
+                      "         cpustat.usecount.mem is going to be "
+                      "less than zero! ... fixed to be zero.\n");
+               cpustat.usecount.mem = 0;
+       }
+       if (cpustat.usecount.mem == 0) {
+               cpustat.usecount.mem_delayed = 1;
+               schedule_delayed_work(&mem_rel_work, HZ);
+       }
+
+       mutex_unlock(&cpustat.lock);
+
+       return 0;
+}
+
+void dsp_register_mem_cb(int (*req_cb)(void), void (*rel_cb)(void))
+{
+       mutex_lock(&cpustat.lock);
+
+       cpustat.mem_req_cb = req_cb;
+       cpustat.mem_rel_cb = rel_cb;
+
+       /*
+        * This function must be called while mem is enabled!
+        */
+       BUG_ON(cpustat.usecount.mem == 0);
+
+       mutex_unlock(&cpustat.lock);
+}
+
+void dsp_unregister_mem_cb(void)
+{
+       mutex_lock(&cpustat.lock);
+       cpustat.mem_req_cb = NULL;
+       cpustat.mem_rel_cb = NULL;
+       mutex_unlock(&cpustat.lock);
+}
+#else
+void dsp_register_mem_cb(int (*req_cb)(void), void (*rel_cb)(void)) { }
+void dsp_unregister_mem_cb(void) { }
+#endif /* CONFIG_ARCH_OMAP1 */
+
+arch_initcall(omap_dsp_init);
+
+#ifdef CONFIG_ARCH_OMAP1
+EXPORT_SYMBOL(omap_dsp_request_mpui);
+EXPORT_SYMBOL(omap_dsp_release_mpui);
+EXPORT_SYMBOL(omap_dsp_request_mem);
+EXPORT_SYMBOL(omap_dsp_release_mem);
+#endif /* CONFIG_ARCH_OMAP1 */
+
+#ifdef CONFIG_OMAP_DSP_MODULE
+#if defined(CONFIG_ARCH_OMAP1)
+EXPORT_SYMBOL(dsp_ck_handle);
+EXPORT_SYMBOL(api_ck_handle);
+#elif defined(CONFIG_ARCH_OMAP2)
+EXPORT_SYMBOL(dsp_fck_handle);
+EXPORT_SYMBOL(dsp_ick_handle);
+#endif
+EXPORT_SYMBOL(omap_dsp);
+EXPORT_SYMBOL(dspmem_base);
+EXPORT_SYMBOL(dspmem_size);
+EXPORT_SYMBOL(daram_base);
+EXPORT_SYMBOL(daram_size);
+EXPORT_SYMBOL(saram_base);
+EXPORT_SYMBOL(saram_size);
+EXPORT_SYMBOL(dsp_set_rstvect);
+EXPORT_SYMBOL(dsp_get_rstvect);
+#ifdef CONFIG_ARCH_OMAP1
+EXPORT_SYMBOL(dsp_set_idle_boot_base);
+EXPORT_SYMBOL(dsp_reset_idle_boot_base);
+#endif /* CONFIG_ARCH_OMAP1 */
+EXPORT_SYMBOL(dsp_cpustat_request);
+EXPORT_SYMBOL(dsp_cpustat_get_stat);
+EXPORT_SYMBOL(dsp_cpustat_get_icrmask);
+EXPORT_SYMBOL(dsp_cpustat_set_icrmask);
+EXPORT_SYMBOL(dsp_register_mem_cb);
+EXPORT_SYMBOL(dsp_unregister_mem_cb);
+
+EXPORT_SYMBOL(__cpu_flush_kern_tlb_range);
+EXPORT_SYMBOL(cpu_architecture);
+EXPORT_SYMBOL(pmd_clear_bad);
+#endif
diff --git a/arch/arm/plat-omap/dsp/dsp_common.h b/arch/arm/plat-omap/dsp/dsp_common.h
new file mode 100644 (file)
index 0000000..898c9ea
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
+ *
+ * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef DRIVER_DSP_COMMON_H
+#define DRIVER_DSP_COMMON_H
+
+#include <linux/clk.h>
+#include <asm/arch/mmu.h>
+#include "hardware_dsp.h"
+
+#define DSPSPACE_SIZE  0x1000000
+
+#define omap_set_bit_regw(b,r) \
+       do { omap_writew(omap_readw(r) | (b), (r)); } while(0)
+#define omap_clr_bit_regw(b,r) \
+       do { omap_writew(omap_readw(r) & ~(b), (r)); } while(0)
+#define omap_set_bit_regl(b,r) \
+       do { omap_writel(omap_readl(r) | (b), (r)); } while(0)
+#define omap_clr_bit_regl(b,r) \
+       do { omap_writel(omap_readl(r) & ~(b), (r)); } while(0)
+#define omap_set_bits_regl(val,mask,r) \
+       do { omap_writel((omap_readl(r) & ~(mask)) | (val), (r)); } while(0)
+
+#define dspword_to_virt(dw)    ((void *)(dspmem_base + ((dw) << 1)))
+#define dspbyte_to_virt(db)    ((void *)(dspmem_base + (db)))
+#define virt_to_dspword(va) \
+       ((dsp_long_t)(((unsigned long)(va) - dspmem_base) >> 1))
+#define virt_to_dspbyte(va) \
+       ((dsp_long_t)((unsigned long)(va) - dspmem_base))
+#define is_dsp_internal_mem(va) \
+       (((unsigned long)(va) >= dspmem_base) &&  \
+        ((unsigned long)(va) < dspmem_base + dspmem_size))
+#define is_dspbyte_internal_mem(db)    ((db) < dspmem_size)
+#define is_dspword_internal_mem(dw)    (((dw) << 1) < dspmem_size)
+
+#ifdef CONFIG_ARCH_OMAP1
+/*
+ * MPUI byteswap/wordswap on/off
+ *   default setting: wordswap = all, byteswap = APIMEM only
+ */
+#define mpui_wordswap_on() \
+       omap_set_bits_regl(MPUI_CTRL_WORDSWAP_ALL, MPUI_CTRL_WORDSWAP_MASK, \
+                          MPUI_CTRL)
+
+#define mpui_wordswap_off() \
+       omap_set_bits_regl(MPUI_CTRL_WORDSWAP_NONE, MPUI_CTRL_WORDSWAP_MASK, \
+                          MPUI_CTRL)
+
+#define mpui_byteswap_on() \
+       omap_set_bits_regl(MPUI_CTRL_BYTESWAP_API, MPUI_CTRL_BYTESWAP_MASK, \
+                          MPUI_CTRL)
+
+#define mpui_byteswap_off() \
+       omap_set_bits_regl(MPUI_CTRL_BYTESWAP_NONE, MPUI_CTRL_BYTESWAP_MASK, \
+                          MPUI_CTRL)
+
+/*
+ * TC wordswap on / off
+ */
+#define tc_wordswap() \
+       do { \
+               omap_writel(TC_ENDIANISM_SWAP_WORD | TC_ENDIANISM_EN, \
+                           TC_ENDIANISM); \
+       } while(0)
+
+#define tc_noswap()    omap_clr_bit_regl(TC_ENDIANISM_EN, TC_ENDIANISM)
+
+/*
+ * enable priority registers, EMIF, MPUI control logic
+ */
+#define __dsp_enable() omap_set_bit_regw(ARM_RSTCT1_DSP_RST, ARM_RSTCT1)
+#define __dsp_disable()        omap_clr_bit_regw(ARM_RSTCT1_DSP_RST, ARM_RSTCT1)
+#define __dsp_run()    omap_set_bit_regw(ARM_RSTCT1_DSP_EN, ARM_RSTCT1)
+#define __dsp_reset()  omap_clr_bit_regw(ARM_RSTCT1_DSP_EN, ARM_RSTCT1)
+#endif /* CONFIG_ARCH_OMAP1 */
+
+#ifdef CONFIG_ARCH_OMAP2
+/*
+ * PRCM / IPI control logic
+ */
+#define RSTCTRL_RST1_DSP       0x00000001
+#define RSTCTRL_RST2_DSP       0x00000002
+#define __dsp_core_enable() \
+       do { RM_RSTCTRL_DSP &= ~RSTCTRL_RST1_DSP; } while (0)
+#define __dsp_core_disable() \
+       do { RM_RSTCTRL_DSP |= RSTCTRL_RST1_DSP; } while (0)
+#define __dsp_per_enable() \
+       do { RM_RSTCTRL_DSP &= ~RSTCTRL_RST2_DSP; } while (0)
+#define __dsp_per_disable() \
+       do { RM_RSTCTRL_DSP |= RSTCTRL_RST2_DSP; } while (0)
+#endif /* CONFIG_ARCH_OMAP2 */
+
+typedef u32 dsp_long_t;        /* must have ability to carry TADD_ABORTADR */
+
+#if defined(CONFIG_ARCH_OMAP1)
+extern struct clk *dsp_ck_handle;
+extern struct clk *api_ck_handle;
+#elif defined(CONFIG_ARCH_OMAP2)
+extern struct clk *dsp_fck_handle;
+extern struct clk *dsp_ick_handle;
+#endif
+extern dsp_long_t dspmem_base, dspmem_size,
+                 daram_base, daram_size,
+                 saram_base, saram_size;
+
+enum cpustat_e {
+       CPUSTAT_RESET = 0,
+#ifdef CONFIG_ARCH_OMAP1
+       CPUSTAT_GBL_IDLE,
+       CPUSTAT_CPU_IDLE,
+#endif
+       CPUSTAT_RUN,
+       CPUSTAT_MAX
+};
+
+int dsp_set_rstvect(dsp_long_t adr);
+dsp_long_t dsp_get_rstvect(void);
+void dsp_set_idle_boot_base(dsp_long_t adr, size_t size);
+void dsp_reset_idle_boot_base(void);
+void dsp_cpustat_request(enum cpustat_e req);
+enum cpustat_e dsp_cpustat_get_stat(void);
+u16 dsp_cpustat_get_icrmask(void);
+void dsp_cpustat_set_icrmask(u16 mask);
+void dsp_register_mem_cb(int (*req_cb)(void), void (*rel_cb)(void));
+void dsp_unregister_mem_cb(void);
+
+#if defined(CONFIG_ARCH_OMAP1)
+static inline void dsp_clk_enable(void) {}
+static inline void dsp_clk_disable(void) {}
+#elif defined(CONFIG_ARCH_OMAP2)
+static inline void dsp_clk_enable(void)
+{
+       /*XXX should be handled in mach-omap[1,2] XXX*/
+       PM_PWSTCTRL_DSP = (1 << 18) | (1 << 0);
+       CM_AUTOIDLE_DSP |= (1 << 1);
+       CM_CLKSTCTRL_DSP |= (1 << 0);
+
+       clk_enable(dsp_fck_handle);
+       clk_enable(dsp_ick_handle);
+       __dsp_per_enable();
+}
+static inline void dsp_clk_disable(void)
+{
+       __dsp_per_disable();
+       clk_disable(dsp_ick_handle);
+       clk_disable(dsp_fck_handle);
+
+       PM_PWSTCTRL_DSP = (1 << 18) | (3 << 0);
+}
+#endif
+
+struct dsp_kfunc_device {
+       char            *name;
+       struct clk      *fck;
+       struct clk      *ick;;
+       spinlock_t       lock;
+       int              enabled;
+       int              type;
+#define DSP_KFUNC_DEV_TYPE_COMMON      1
+#define DSP_KFUNC_DEV_TYPE_AUDIO       2
+
+       struct list_head        entry;
+
+       int     (*probe)(struct dsp_kfunc_device *, int);
+       int     (*remove)(struct dsp_kfunc_device *, int);
+       int     (*enable)(struct dsp_kfunc_device *, int);
+       int     (*disable)(struct dsp_kfunc_device *, int);
+};
+
+extern int dsp_kfunc_device_register(struct dsp_kfunc_device *);
+
+struct dsp_platform_data {
+       struct list_head kdev_list;
+};
+
+struct omap_dsp {
+       struct mutex            lock;
+       int                     enabled;        /* stored peripheral status */
+       struct omap_mmu         *mmu;
+       struct omap_mbox        *mbox;
+       struct device           *dev;
+       struct list_head        *kdev_list;
+       int                     initialized;
+};
+
+#if defined(CONFIG_ARCH_OMAP1)
+#define command_dvfs_stop(m) (0)
+#define command_dvfs_start(m) (0)
+#elif defined(CONFIG_ARCH_OMAP2)
+#define command_dvfs_stop(m) \
+       (((m)->cmd_l == KFUNC_POWER) && ((m)->data == DVFS_STOP))
+#define command_dvfs_start(m) \
+       (((m)->cmd_l == KFUNC_POWER) && ((m)->data == DVFS_START))
+#endif
+
+extern struct omap_dsp *omap_dsp;
+
+extern int dsp_late_init(void);
+
+#endif /* DRIVER_DSP_COMMON_H */
diff --git a/arch/arm/plat-omap/dsp/hardware_dsp.h b/arch/arm/plat-omap/dsp/hardware_dsp.h
new file mode 100644 (file)
index 0000000..a15d9af
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
+ *
+ * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __OMAP_DSP_HARDWARE_DSP_H
+#define __OMAP_DSP_HARDWARE_DSP_H
+
+#ifdef CONFIG_ARCH_OMAP1
+#include "omap1_dsp.h"
+#endif
+#ifdef CONFIG_ARCH_OMAP2
+#include "omap2_dsp.h"
+#endif
+
+#endif /* __OMAP_DSP_HARDWARE_DSP_H */
diff --git a/arch/arm/plat-omap/dsp/omap1_dsp.h b/arch/arm/plat-omap/dsp/omap1_dsp.h
new file mode 100644 (file)
index 0000000..45fdb50
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
+ *
+ * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __OMAP_DSP_OMAP1_DSP_H
+#define __OMAP_DSP_OMAP1_DSP_H
+
+#ifdef CONFIG_ARCH_OMAP15XX
+#define OMAP1510_DARAM_BASE    (OMAP1510_DSP_BASE + 0x0)
+#define OMAP1510_DARAM_SIZE    0x10000
+#define OMAP1510_SARAM_BASE    (OMAP1510_DSP_BASE + 0x10000)
+#define OMAP1510_SARAM_SIZE    0x18000
+#endif
+
+#ifdef CONFIG_ARCH_OMAP16XX
+#define OMAP16XX_DARAM_BASE    (OMAP16XX_DSP_BASE + 0x0)
+#define OMAP16XX_DARAM_SIZE    0x10000
+#define OMAP16XX_SARAM_BASE    (OMAP16XX_DSP_BASE + 0x10000)
+#define OMAP16XX_SARAM_SIZE    0x18000
+#endif
+
+/*
+ * Reset Control
+ */
+#define ARM_RSTCT1_SW_RST              0x0008
+#define ARM_RSTCT1_DSP_RST             0x0004
+#define ARM_RSTCT1_DSP_EN              0x0002
+#define ARM_RSTCT1_ARM_RST             0x0001
+
+/*
+ * MPUI
+ */
+#define MPUI_CTRL_WORDSWAP_MASK                0x00600000
+#define MPUI_CTRL_WORDSWAP_ALL         0x00000000
+#define MPUI_CTRL_WORDSWAP_NONAPI      0x00200000
+#define MPUI_CTRL_WORDSWAP_API         0x00400000
+#define MPUI_CTRL_WORDSWAP_NONE                0x00600000
+#define MPUI_CTRL_AP_MASK              0x001c0000
+#define MPUI_CTRL_AP_MDH               0x00000000
+#define MPUI_CTRL_AP_MHD               0x00040000
+#define MPUI_CTRL_AP_DMH               0x00080000
+#define MPUI_CTRL_AP_HMD               0x000c0000
+#define MPUI_CTRL_AP_DHM               0x00100000
+#define MPUI_CTRL_AP_HDM               0x00140000
+#define MPUI_CTRL_BYTESWAP_MASK                0x00030000
+#define MPUI_CTRL_BYTESWAP_NONE                0x00000000
+#define MPUI_CTRL_BYTESWAP_NONAPI      0x00010000
+#define MPUI_CTRL_BYTESWAP_ALL         0x00020000
+#define MPUI_CTRL_BYTESWAP_API         0x00030000
+#define MPUI_CTRL_TIMEOUT_MASK         0x0000ff00
+#define MPUI_CTRL_APIF_HNSTB_DIV_MASK  0x000000f0
+#define MPUI_CTRL_S_NABORT_GL          0x00000008
+#define MPUI_CTRL_S_NABORT_32BIT       0x00000004
+#define MPUI_CTRL_EN_TIMEOUT           0x00000002
+#define MPUI_CTRL_HF_MCUCLK            0x00000001
+#define DSP_BOOT_CONFIG_DIRECT         0x00000000
+#define DSP_BOOT_CONFIG_PSD_DIRECT     0x00000001
+#define DSP_BOOT_CONFIG_IDLE           0x00000002
+#define DSP_BOOT_CONFIG_DL16           0x00000003
+#define DSP_BOOT_CONFIG_DL32           0x00000004
+#define DSP_BOOT_CONFIG_MPUI           0x00000005
+#define DSP_BOOT_CONFIG_INTERNAL       0x00000006
+
+/*
+ * DSP boot mode
+ *   direct:        0xffff00
+ *   pseudo direct: 0x080000
+ *   MPUI:          branch 0x010000
+ *   internel:      branch 0x024000
+ */
+#define DSP_BOOT_ADR_DIRECT            0xffff00
+#define DSP_BOOT_ADR_PSD_DIRECT                0x080000
+#define DSP_BOOT_ADR_MPUI              0x010000
+#define DSP_BOOT_ADR_INTERNAL          0x024000
+
+/*
+ * TC
+ */
+#define TC_ENDIANISM_SWAP              0x00000002
+#define TC_ENDIANISM_SWAP_WORD         0x00000002
+#define TC_ENDIANISM_SWAP_BYTE         0x00000000
+#define TC_ENDIANISM_EN                        0x00000001
+
+/*
+ * DSP MMU
+ */
+#define DSP_MMU_BASE                   (0xfefed200)
+#define DSP_MMU_PREFETCH               (DSP_MMU_BASE + 0x00)
+#define DSP_MMU_WALKING_ST             (DSP_MMU_BASE + 0x04)
+#define DSP_MMU_CNTL                   (DSP_MMU_BASE + 0x08)
+#define DSP_MMU_FAULT_AD_H             (DSP_MMU_BASE + 0x0c)
+#define DSP_MMU_FAULT_AD_L             (DSP_MMU_BASE + 0x10)
+#define DSP_MMU_FAULT_ST               (DSP_MMU_BASE + 0x14)
+#define DSP_MMU_IT_ACK                 (DSP_MMU_BASE + 0x18)
+#define DSP_MMU_TTB_H                  (DSP_MMU_BASE + 0x1c)
+#define DSP_MMU_TTB_L                  (DSP_MMU_BASE + 0x20)
+#define DSP_MMU_LOCK                   (DSP_MMU_BASE + 0x24)
+#define DSP_MMU_LD_TLB                 (DSP_MMU_BASE + 0x28)
+#define DSP_MMU_CAM_H                  (DSP_MMU_BASE + 0x2c)
+#define DSP_MMU_CAM_L                  (DSP_MMU_BASE + 0x30)
+#define DSP_MMU_RAM_H                  (DSP_MMU_BASE + 0x34)
+#define DSP_MMU_RAM_L                  (DSP_MMU_BASE + 0x38)
+#define DSP_MMU_GFLUSH                 (DSP_MMU_BASE + 0x3c)
+#define DSP_MMU_FLUSH_ENTRY            (DSP_MMU_BASE + 0x40)
+#define DSP_MMU_READ_CAM_H             (DSP_MMU_BASE + 0x44)
+#define DSP_MMU_READ_CAM_L             (DSP_MMU_BASE + 0x48)
+#define DSP_MMU_READ_RAM_H             (DSP_MMU_BASE + 0x4c)
+#define DSP_MMU_READ_RAM_L             (DSP_MMU_BASE + 0x50)
+
+#define DSP_MMU_CNTL_BURST_16MNGT_EN   0x0020
+#define DSP_MMU_CNTL_WTL_EN            0x0004
+#define DSP_MMU_CNTL_MMU_EN            0x0002
+#define DSP_MMU_CNTL_RESET_SW          0x0001
+
+#define DSP_MMU_FAULT_AD_H_DP          0x0100
+#define DSP_MMU_FAULT_AD_H_ADR_MASK    0x00ff
+
+#define DSP_MMU_FAULT_ST_PREF          0x0008
+#define DSP_MMU_FAULT_ST_PERM          0x0004
+#define DSP_MMU_FAULT_ST_TLB_MISS      0x0002
+#define DSP_MMU_FAULT_ST_TRANS         0x0001
+
+#define DSP_MMU_IT_ACK_IT_ACK          0x0001
+
+#define DSP_MMU_LOCK_BASE_MASK         0xfc00
+#define DSP_MMU_LOCK_BASE_SHIFT                10
+#define DSP_MMU_LOCK_VICTIM_MASK       0x03f0
+#define DSP_MMU_LOCK_VICTIM_SHIFT      4
+
+#define DSP_MMU_CAM_H_VA_TAG_H_MASK            0x0003
+
+#define DSP_MMU_CAM_L_VA_TAG_L1_MASK           0xc000
+#define DSP_MMU_CAM_L_VA_TAG_L2_MASK_1MB       0x0000
+#define DSP_MMU_CAM_L_VA_TAG_L2_MASK_64KB      0x3c00
+#define DSP_MMU_CAM_L_VA_TAG_L2_MASK_4KB       0x3fc0
+#define DSP_MMU_CAM_L_VA_TAG_L2_MASK_1KB       0x3ff0
+#define DSP_MMU_CAM_L_P                                0x0008
+#define DSP_MMU_CAM_L_V                                0x0004
+#define DSP_MMU_CAM_L_PAGESIZE_MASK            0x0003
+#define DSP_MMU_CAM_L_PAGESIZE_1MB             0x0000
+#define DSP_MMU_CAM_L_PAGESIZE_64KB            0x0001
+#define DSP_MMU_CAM_L_PAGESIZE_4KB             0x0002
+#define DSP_MMU_CAM_L_PAGESIZE_1KB             0x0003
+
+#define DSP_MMU_RAM_L_RAM_LSB_MASK     0xfc00
+#define DSP_MMU_RAM_L_AP_MASK          0x0300
+#define DSP_MMU_RAM_L_AP_NA            0x0000
+#define DSP_MMU_RAM_L_AP_RO            0x0200
+#define DSP_MMU_RAM_L_AP_FA            0x0300
+
+#define DSP_MMU_GFLUSH_GFLUSH          0x0001
+
+#define DSP_MMU_FLUSH_ENTRY_FLUSH_ENTRY        0x0001
+
+#define DSP_MMU_LD_TLB_RD              0x0002
+#define DSP_MMU_LD_TLB_LD              0x0001
+
+/*
+ * DSP ICR
+ */
+#define DSPREG_ICR_RESERVED_BITS       0xffc0
+#define DSPREG_ICR_EMIF                        0x0020
+#define DSPREG_ICR_DPLL                        0x0010
+#define DSPREG_ICR_PER                 0x0008
+#define DSPREG_ICR_CACHE               0x0004
+#define DSPREG_ICR_DMA                 0x0002
+#define DSPREG_ICR_CPU                 0x0001
+
+#endif /* __OMAP_DSP_OMAP1_DSP_H */
diff --git a/arch/arm/plat-omap/dsp/omap2_dsp.h b/arch/arm/plat-omap/dsp/omap2_dsp.h
new file mode 100644 (file)
index 0000000..28a98ad
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
+ *
+ * Copyright (C) 2006 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __OMAP_DSP_OMAP2_DSP_H
+#define __OMAP_DSP_OMAP2_DSP_H
+
+#ifdef CONFIG_ARCH_OMAP24XX
+#define OMAP24XX_DARAM_BASE    (DSP_MEM_24XX_VIRT + 0x0)
+#define OMAP24XX_DARAM_SIZE    0x10000
+#define OMAP24XX_SARAM_BASE    (DSP_MEM_24XX_VIRT + 0x10000)
+#define OMAP24XX_SARAM_SIZE    0x18000
+#endif
+
+#include <asm/arch/hardware.h>
+#include "../../mach-omap2/prcm-regs.h"
+
+/*
+ * DSP IPI registers: mapped to 0xe1000000 -- use readX(), writeX()
+ */
+#define DSP_IPI_BASE                   DSP_IPI_24XX_VIRT
+#define DSP_IPI_REVISION               (DSP_IPI_BASE + 0x00)
+#define DSP_IPI_SYSCONFIG              (DSP_IPI_BASE + 0x10)
+#define DSP_IPI_INDEX                  (DSP_IPI_BASE + 0x40)
+#define DSP_IPI_ENTRY                  (DSP_IPI_BASE + 0x44)
+#define DSP_IPI_ENABLE                 (DSP_IPI_BASE + 0x48)
+#define DSP_IPI_IOMAP                  (DSP_IPI_BASE + 0x4c)
+#define DSP_IPI_DSPBOOTCONFIG          (DSP_IPI_BASE + 0x50)
+
+#define DSP_IPI_ENTRY_ELMSIZEVALUE_MASK        0x00000003
+#define DSP_IPI_ENTRY_ELMSIZEVALUE_8   0x00000000
+#define DSP_IPI_ENTRY_ELMSIZEVALUE_16  0x00000001
+#define DSP_IPI_ENTRY_ELMSIZEVALUE_32  0x00000002
+
+#define DSP_BOOT_CONFIG_DIRECT         0x00000000
+#define DSP_BOOT_CONFIG_PSD_DIRECT     0x00000001
+#define DSP_BOOT_CONFIG_IDLE           0x00000002
+#define DSP_BOOT_CONFIG_DL16           0x00000003
+#define DSP_BOOT_CONFIG_DL32           0x00000004
+#define DSP_BOOT_CONFIG_API            0x00000005
+#define DSP_BOOT_CONFIG_INTERNAL       0x00000006
+
+/*
+ * DSP boot mode
+ *   direct:        0xffff00
+ *   pseudo direct: 0x080000
+ *   API:           branch 0x010000
+ *   internel:      branch 0x024000
+ */
+#define DSP_BOOT_ADR_DIRECT            0xffff00
+#define DSP_BOOT_ADR_PSD_DIRECT                0x080000
+#define DSP_BOOT_ADR_API               0x010000
+#define DSP_BOOT_ADR_INTERNAL          0x024000
+
+/*
+ * DSP MMU: mapped to 0xe2000000 -- use readX(), writeX()
+ */
+#define DSP_MMU_BASE                   DSP_MMU_24XX_VIRT
+#define DSP_MMU_REVISION               (DSP_MMU_BASE + 0x00)
+#define DSP_MMU_SYSCONFIG              (DSP_MMU_BASE + 0x10)
+#define DSP_MMU_SYSSTATUS              (DSP_MMU_BASE + 0x14)
+#define DSP_MMU_IRQSTATUS              (DSP_MMU_BASE + 0x18)
+#define DSP_MMU_IRQENABLE              (DSP_MMU_BASE + 0x1c)
+#define DSP_MMU_WALKING_ST             (DSP_MMU_BASE + 0x40)
+#define DSP_MMU_CNTL                   (DSP_MMU_BASE + 0x44)
+#define DSP_MMU_FAULT_AD               (DSP_MMU_BASE + 0x48)
+#define DSP_MMU_TTB                    (DSP_MMU_BASE + 0x4c)
+#define DSP_MMU_LOCK                   (DSP_MMU_BASE + 0x50)
+#define DSP_MMU_LD_TLB                 (DSP_MMU_BASE + 0x54)
+#define DSP_MMU_CAM                    (DSP_MMU_BASE + 0x58)
+#define DSP_MMU_RAM                    (DSP_MMU_BASE + 0x5c)
+#define DSP_MMU_GFLUSH                 (DSP_MMU_BASE + 0x60)
+#define DSP_MMU_FLUSH_ENTRY            (DSP_MMU_BASE + 0x64)
+#define DSP_MMU_READ_CAM               (DSP_MMU_BASE + 0x68)
+#define DSP_MMU_READ_RAM               (DSP_MMU_BASE + 0x6c)
+#define DSP_MMU_EMU_FAULT_AD           (DSP_MMU_BASE + 0x70)
+
+#define DSP_MMU_SYSCONFIG_CLOCKACTIVITY_MASK   0x00000300
+#define DSP_MMU_SYSCONFIG_IDLEMODE_MASK                0x00000018
+#define DSP_MMU_SYSCONFIG_SOFTRESET            0x00000002
+#define DSP_MMU_SYSCONFIG_AUTOIDLE             0x00000001
+
+#define DSP_MMU_IRQ_MULTIHITFAULT      0x00000010
+#define DSP_MMU_IRQ_TABLEWALKFAULT     0x00000008
+#define DSP_MMU_IRQ_EMUMISS            0x00000004
+#define DSP_MMU_IRQ_TRANSLATIONFAULT   0x00000002
+#define DSP_MMU_IRQ_TLBMISS            0x00000001
+
+#define DSP_MMU_CNTL_EMUTLBUPDATE      0x00000008
+#define DSP_MMU_CNTL_TWLENABLE         0x00000004
+#define DSP_MMU_CNTL_MMUENABLE         0x00000002
+
+#define DSP_MMU_LOCK_BASE_MASK         0x00007c00
+#define DSP_MMU_LOCK_BASE_SHIFT                10
+#define DSP_MMU_LOCK_VICTIM_MASK       0x000001f0
+#define DSP_MMU_LOCK_VICTIM_SHIFT      4
+
+#define DSP_MMU_CAM_VATAG_MASK         0xfffff000
+#define DSP_MMU_CAM_P                  0x00000008
+#define DSP_MMU_CAM_V                  0x00000004
+#define DSP_MMU_CAM_PAGESIZE_MASK      0x00000003
+#define DSP_MMU_CAM_PAGESIZE_1MB       0x00000000
+#define DSP_MMU_CAM_PAGESIZE_64KB      0x00000001
+#define DSP_MMU_CAM_PAGESIZE_4KB       0x00000002
+#define DSP_MMU_CAM_PAGESIZE_16MB      0x00000003
+
+#define DSP_MMU_RAM_PADDR_MASK         0xfffff000
+#define DSP_MMU_RAM_ENDIANNESS         0x00000200
+#define DSP_MMU_RAM_ENDIANNESS_BIG     0x00000200
+#define DSP_MMU_RAM_ENDIANNESS_LITTLE  0x00000000
+#define DSP_MMU_RAM_ELEMENTSIZE_MASK   0x00000180
+#define DSP_MMU_RAM_ELEMENTSIZE_8      0x00000000
+#define DSP_MMU_RAM_ELEMENTSIZE_16     0x00000080
+#define DSP_MMU_RAM_ELEMENTSIZE_32     0x00000100
+#define DSP_MMU_RAM_ELEMENTSIZE_NONE   0x00000180
+#define DSP_MMU_RAM_MIXED              0x00000040
+
+#define DSP_MMU_GFLUSH_GFLUSH          0x00000001
+
+#define DSP_MMU_FLUSH_ENTRY_FLUSH_ENTRY        0x00000001
+
+#define DSP_MMU_LD_TLB_LD              0x00000001
+
+/*
+ * DSP ICR
+ */
+#define DSPREG_ICR_RESERVED_BITS       0xfc00
+#define DSPREG_ICR_HWA                 0x0200
+#define DSPREG_ICR_IPORT               0x0100
+#define DSPREG_ICR_MPORT               0x0080
+#define DSPREG_ICR_XPORT               0x0040
+#define DSPREG_ICR_DPORT               0x0020
+#define DSPREG_ICR_DPLL                        0x0010
+#define DSPREG_ICR_PER                 0x0008
+#define DSPREG_ICR_CACHE               0x0004
+#define DSPREG_ICR_DMA                 0x0002
+#define DSPREG_ICR_CPU                 0x0001
+
+#endif /* __OMAP_DSP_OMAP2_DSP_H */
index f7b9ccdaacbcff0c0a446488f1436fa10ff236c3..4221b464ca17976a2d9ac7346f754fd127a45973 100644 (file)
@@ -197,6 +197,7 @@ static int omap_mcbsp_check(unsigned int id)
 static void omap_mcbsp_dsp_request(void)
 {
        if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
+               omap_dsp_request_mem();
                clk_enable(mcbsp_dsp_ck);
                clk_enable(mcbsp_api_ck);
 
@@ -215,6 +216,7 @@ static void omap_mcbsp_dsp_request(void)
 static void omap_mcbsp_dsp_free(void)
 {
        if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
+               omap_dsp_release_mem();
                clk_disable(mcbsp_dspxor_ck);
                clk_disable(mcbsp_dsp_ck);
                clk_disable(mcbsp_api_ck);