This patch series does cleanup on the msm dma driver, and adds support for two
new targets, msm8660 and msm8960.
Jeff Ohlstein (9):
msm: dma: Add support for flushing dma channels
msm: dma: support using dma from modules
msm: dma: Toggle adm_pclk along with adm_clk
msm: dma: Remove register macros from header file
msm: dma: use a platform device for msm_dmov
msm: dma: Support multiple adms
msm: dma: Handle probe failure in dma function
msm: dma: Support msm8x60 dma
msm: dma: support msm8960 dma
Stepan Moskovchenko (1):
msm: 8960: Split out common initialization code
Subhash Jadavani (1):
msm: dma: Guard for multiple file inclusion
arch/arm/mach-msm/Makefile | 5 +-
arch/arm/mach-msm/board-halibut.c | 1 +
arch/arm/mach-msm/board-mahimahi.c | 1 +
arch/arm/mach-msm/board-msm7x30.c | 1 +
arch/arm/mach-msm/board-msm8960.c | 14 +-
arch/arm/mach-msm/board-msm8x60.c | 9 +-
arch/arm/mach-msm/board-qsd8x50.c | 1 +
arch/arm/mach-msm/board-trout.c | 1 +
arch/arm/mach-msm/devices-msm7x00.c | 21 ++-
arch/arm/mach-msm/devices-msm7x30.c | 21 ++-
arch/arm/mach-msm/devices-msm8960.c | 21 ++
arch/arm/mach-msm/devices-msm8x60.c | 56 ++++
arch/arm/mach-msm/devices-qsd8x50.c | 21 ++-
arch/arm/mach-msm/devices.h | 5 +
arch/arm/mach-msm/dma.c | 391 ++++++++++++++++++-----
arch/arm/mach-msm/include/mach/dma.h | 84 +++---
arch/arm/mach-msm/include/mach/msm_iomap-7x00.h | 5 +-
arch/arm/mach-msm/include/mach/msm_iomap-7x30.h | 5 +-
arch/arm/mach-msm/include/mach/msm_iomap-8960.h | 3 +
arch/arm/mach-msm/include/mach/msm_iomap-8x50.h | 5 +-
arch/arm/mach-msm/include/mach/msm_iomap-8x60.h | 6 +
arch/arm/mach-msm/io.c | 3 -
22 files changed, 545 insertions(+), 135 deletions(-)
create mode 100644 arch/arm/mach-msm/devices-msm8x60.c
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
Sometimes dma channels need to be flushed without having a reference to
a specific command, as in msm_dmov_stop_cmd.
Signed-off-by: Jeff Ohlstein <[email protected]>
---
arch/arm/mach-msm/dma.c | 13 +++++++++++++
arch/arm/mach-msm/include/mach/dma.h | 4 ++++
2 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 02cae5e..8e4d46e 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -1,6 +1,7 @@
/* linux/arch/arm/mach-msm/dma.c
*
* Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -90,6 +91,18 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
}
+void msm_dmov_flush(unsigned int id)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&msm_dmov_lock, flags);
+ /* XXX not checking if flush cmd sent already */
+ if (!list_empty(&active_commands[id])) {
+ PRINT_IO("msm_dmov_flush(%d), send flush cmd\n", id);
+ writel(DMOV_FLUSH_GRACEFUL, DMOV_FLUSH0(id));
+ }
+ spin_unlock_irqrestore(&msm_dmov_lock, flags);
+}
+
struct msm_dmov_exec_cmdptr_cmd {
struct msm_dmov_cmd dmov_cmd;
struct completion complete;
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index ece09e0..41eb4a5 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -38,6 +38,7 @@ struct msm_dmov_cmd {
void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
+void msm_dmov_flush(unsigned int id);
#else
static inline
void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) { }
@@ -45,6 +46,8 @@ static inline
void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful) { }
static inline
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) { return -EIO; }
+static inline
+void msm_dmov_flush(unsigned int id) { }
#endif
@@ -79,6 +82,7 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) { return -EIO; }
#define DMOV_FLUSH3(ch) DMOV_SD_AARM(0x140, ch)
#define DMOV_FLUSH4(ch) DMOV_SD_AARM(0x180, ch)
#define DMOV_FLUSH5(ch) DMOV_SD_AARM(0x1C0, ch)
+#define DMOV_FLUSH_GRACEFUL (1 << 31)
#define DMOV_STATUS(ch) DMOV_SD_AARM(0x200, ch)
#define DMOV_STATUS_RSLT_COUNT(n) (((n) >> 29))
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
There is no reason for anything other than the dma driver to access the
dma registers directly. So, don't provide the register addresses in the
header file.
Signed-off-by: Jeff Ohlstein <[email protected]>
---
arch/arm/mach-msm/dma.c | 23 +++++++++++++++++++++++
arch/arm/mach-msm/include/mach/dma.h | 24 ------------------------
2 files changed, 23 insertions(+), 24 deletions(-)
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 2dc408d..3ff31f9 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -38,6 +38,29 @@ static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
+#define DMOV_SD0(off, ch) (MSM_DMOV_BASE + 0x0000 + (off) + ((ch) << 2))
+#define DMOV_SD1(off, ch) (MSM_DMOV_BASE + 0x0400 + (off) + ((ch) << 2))
+#define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2))
+#define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2))
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define DMOV_SD_AARM DMOV_SD2
+#else
+#define DMOV_SD_AARM DMOV_SD3
+#endif
+
+#define DMOV_CMD_PTR(ch) DMOV_SD_AARM(0x000, ch)
+#define DMOV_RSLT(ch) DMOV_SD_AARM(0x040, ch)
+#define DMOV_FLUSH0(ch) DMOV_SD_AARM(0x080, ch)
+#define DMOV_FLUSH1(ch) DMOV_SD_AARM(0x0C0, ch)
+#define DMOV_FLUSH2(ch) DMOV_SD_AARM(0x100, ch)
+#define DMOV_FLUSH3(ch) DMOV_SD_AARM(0x140, ch)
+#define DMOV_FLUSH4(ch) DMOV_SD_AARM(0x180, ch)
+#define DMOV_FLUSH5(ch) DMOV_SD_AARM(0x1C0, ch)
+#define DMOV_STATUS(ch) DMOV_SD_AARM(0x200, ch)
+#define DMOV_CONFIG(ch) DMOV_SD_AARM(0x300, ch)
+#define DMOV_ISR DMOV_SD_AARM(0x380, 0)
+
#define MSM_DMOV_DPRINTF(mask, format, args...) \
do { \
if ((mask) & msm_dmov_print_mask) \
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 41eb4a5..ae031d2 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -50,49 +50,25 @@ static inline
void msm_dmov_flush(unsigned int id) { }
#endif
-
-#define DMOV_SD0(off, ch) (MSM_DMOV_BASE + 0x0000 + (off) + ((ch) << 2))
-#define DMOV_SD1(off, ch) (MSM_DMOV_BASE + 0x0400 + (off) + ((ch) << 2))
-#define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2))
-#define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2))
-
-#if defined(CONFIG_ARCH_MSM7X30)
-#define DMOV_SD_AARM DMOV_SD2
-#else
-#define DMOV_SD_AARM DMOV_SD3
-#endif
-
-#define DMOV_CMD_PTR(ch) DMOV_SD_AARM(0x000, ch)
#define DMOV_CMD_LIST (0 << 29) /* does not work */
#define DMOV_CMD_PTR_LIST (1 << 29) /* works */
#define DMOV_CMD_INPUT_CFG (2 << 29) /* untested */
#define DMOV_CMD_OUTPUT_CFG (3 << 29) /* untested */
#define DMOV_CMD_ADDR(addr) ((addr) >> 3)
-#define DMOV_RSLT(ch) DMOV_SD_AARM(0x040, ch)
#define DMOV_RSLT_VALID (1 << 31) /* 0 == host has empties result fifo */
#define DMOV_RSLT_ERROR (1 << 3)
#define DMOV_RSLT_FLUSH (1 << 2)
#define DMOV_RSLT_DONE (1 << 1) /* top pointer done */
#define DMOV_RSLT_USER (1 << 0) /* command with FR force result */
-#define DMOV_FLUSH0(ch) DMOV_SD_AARM(0x080, ch)
-#define DMOV_FLUSH1(ch) DMOV_SD_AARM(0x0C0, ch)
-#define DMOV_FLUSH2(ch) DMOV_SD_AARM(0x100, ch)
-#define DMOV_FLUSH3(ch) DMOV_SD_AARM(0x140, ch)
-#define DMOV_FLUSH4(ch) DMOV_SD_AARM(0x180, ch)
-#define DMOV_FLUSH5(ch) DMOV_SD_AARM(0x1C0, ch)
#define DMOV_FLUSH_GRACEFUL (1 << 31)
-#define DMOV_STATUS(ch) DMOV_SD_AARM(0x200, ch)
#define DMOV_STATUS_RSLT_COUNT(n) (((n) >> 29))
#define DMOV_STATUS_CMD_COUNT(n) (((n) >> 27) & 3)
#define DMOV_STATUS_RSLT_VALID (1 << 1)
#define DMOV_STATUS_CMD_PTR_RDY (1 << 0)
-#define DMOV_ISR DMOV_SD_AARM(0x380, 0)
-
-#define DMOV_CONFIG(ch) DMOV_SD_AARM(0x300, ch)
#define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2)
#define DMOV_CONFIG_FORCE_FLUSH_RSLT (1 << 1)
#define DMOV_CONFIG_IRQ_EN (1 << 0)
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
Add support for targets which have more than one ADM present. In the
interest of maintaining the same api as before, map each ADM's channels
sequentially, so adm0 would have channels 0-15, adm1 would have channels
16-31, etc.
Signed-off-by: Jeff Ohlstein <[email protected]>
---
arch/arm/mach-msm/dma.c | 314 +++++++++++++++++++++++++++++------------------
1 files changed, 194 insertions(+), 120 deletions(-)
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 3bafee9..ef543e1 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -21,9 +21,11 @@
#include <linux/completion.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <mach/dma.h>
#define MSM_DMOV_CHANNEL_COUNT 16
+#define MSM_DMOV_MAX_ADMS 2
#define MODULE_NAME "msm_dmov"
@@ -33,20 +35,26 @@ enum {
MSM_DMOV_PRINT_FLOW = 4
};
-static DEFINE_SPINLOCK(msm_dmov_lock);
-static struct clk *msm_dmov_clk;
-static struct clk *msm_dmov_pclk;
-static unsigned int channel_active;
-static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
-static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
-static void __iomem *msm_dmov_base;
-static unsigned msm_dmov_irq;
-#define DMOV_SD0(off, ch) (msm_dmov_base + 0x0000 + (off) + ((ch) << 2))
-#define DMOV_SD1(off, ch) (msm_dmov_base + 0x0400 + (off) + ((ch) << 2))
-#define DMOV_SD2(off, ch) (msm_dmov_base + 0x0800 + (off) + ((ch) << 2))
-#define DMOV_SD3(off, ch) (msm_dmov_base + 0x0C00 + (off) + ((ch) << 2))
+struct msm_dmov_conf {
+ void __iomem *base;
+ int channel_active;
+ struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
+ struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
+ spinlock_t lock;
+ unsigned irq;
+ struct clk *clk;
+ struct clk *pclk;
+};
+
+static struct msm_dmov_conf dmov_conf[MSM_DMOV_MAX_ADMS];
+static int nr_adms;
+
+#define DMOV_SD0(off, ch) (0x0000 + (off) + ((ch) << 2))
+#define DMOV_SD1(off, ch) (0x0400 + (off) + ((ch) << 2))
+#define DMOV_SD2(off, ch) (0x0800 + (off) + ((ch) << 2))
+#define DMOV_SD3(off, ch) (0x0C00 + (off) + ((ch) << 2))
#if defined(CONFIG_ARCH_MSM7X30)
#define DMOV_SD_AARM DMOV_SD2
@@ -78,86 +86,104 @@ static unsigned msm_dmov_irq;
#define PRINT_FLOW(format, args...) \
MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args);
+static inline unsigned dmov_readl(unsigned addr, int adm)
+{
+ return readl(dmov_conf[adm].base + addr);
+}
+
+static inline void dmov_writel(unsigned val, unsigned addr, int adm)
+{
+ writel(val, dmov_conf[adm].base + addr);
+}
+
+#define DMOV_ID_TO_ADM(id) ((id) / MSM_DMOV_CHANNEL_COUNT)
+#define DMOV_ID_TO_CHAN(id) ((id) % MSM_DMOV_CHANNEL_COUNT)
+#define DMOV_CHAN_ADM_TO_ID(ch, adm) ((ch) + (adm) * MSM_DMOV_CHANNEL_COUNT)
+
void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
{
- writel((graceful << 31), DMOV_FLUSH0(id));
+ int adm = DMOV_ID_TO_ADM(id);
+ int ch = DMOV_ID_TO_CHAN(id);
+
+ dmov_writel((graceful << 31), DMOV_FLUSH0(ch), adm);
}
EXPORT_SYMBOL(msm_dmov_stop_cmd);
-static int msm_dmov_clocks_on(void)
+static int msm_dmov_clocks_on(int adm)
{
int ret = 0;
- if (!IS_ERR(msm_dmov_clk)) {
- ret = clk_enable(msm_dmov_clk);
+ if (!IS_ERR(dmov_conf[adm].clk)) {
+ ret = clk_enable(dmov_conf[adm].clk);
if (ret)
return ret;
- if (!IS_ERR(msm_dmov_pclk)) {
- ret = clk_enable(msm_dmov_pclk);
+ if (!IS_ERR(dmov_conf[adm].pclk)) {
+ ret = clk_enable(dmov_conf[adm].pclk);
if (ret)
- clk_disable(msm_dmov_clk);
+ clk_disable(dmov_conf[adm].clk);
}
}
return ret;
}
-static void msm_dmov_clocks_off(void)
+static void msm_dmov_clocks_off(int adm)
{
- if (!IS_ERR(msm_dmov_clk))
- clk_disable(msm_dmov_clk);
- if (!IS_ERR(msm_dmov_pclk))
- clk_disable(msm_dmov_pclk);
+ if (!IS_ERR(dmov_conf[adm].clk))
+ clk_disable(dmov_conf[adm].clk);
+ if (!IS_ERR(dmov_conf[adm].pclk))
+ clk_disable(dmov_conf[adm].pclk);
}
void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
{
unsigned long irq_flags;
unsigned int status;
+ int adm = DMOV_ID_TO_ADM(id);
+ int ch = DMOV_ID_TO_CHAN(id);
- spin_lock_irqsave(&msm_dmov_lock, irq_flags);
- if (!channel_active)
- msm_dmov_clocks_on();
+ spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
+ if (!dmov_conf[adm].channel_active)
+ msm_dmov_clocks_on(adm);
dsb();
- status = readl(DMOV_STATUS(id));
- if (list_empty(&ready_commands[id]) &&
+ status = dmov_readl(DMOV_STATUS(ch), adm);
+ if (list_empty(&dmov_conf[adm].ready_commands[ch]) &&
(status & DMOV_STATUS_CMD_PTR_RDY)) {
-#if 0
- if (list_empty(&active_commands[id])) {
- PRINT_FLOW("msm_dmov_enqueue_cmd(%d), enable interrupt\n", id);
- writel(DMOV_CONFIG_IRQ_EN, DMOV_CONFIG(id));
- }
-#endif
if (cmd->execute_func)
cmd->execute_func(cmd);
- PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", id, status);
- list_add_tail(&cmd->list, &active_commands[id]);
- if (!channel_active)
- enable_irq(msm_dmov_irq);
- channel_active |= 1U << id;
- writel(cmd->cmdptr, DMOV_CMD_PTR(id));
+ PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n",
+ id, status);
+ list_add_tail(&cmd->list, &dmov_conf[adm].active_commands[ch]);
+ if (!dmov_conf[adm].channel_active)
+ enable_irq(dmov_conf[adm].irq);
+ dmov_conf[adm].channel_active |= 1U << ch;
+ dmov_writel(cmd->cmdptr, DMOV_CMD_PTR(ch), adm);
} else {
- if (!channel_active)
- msm_dmov_clocks_off();
- if (list_empty(&active_commands[id]))
- PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status);
-
- PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status %x\n", id, status);
- list_add_tail(&cmd->list, &ready_commands[id]);
+ if (!dmov_conf[adm].channel_active)
+ msm_dmov_clocks_off(adm);
+ if (list_empty(&dmov_conf[adm].active_commands[ch]))
+ PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover "
+ "stalled, status %x\n", id, status);
+ PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status "
+ "%x\n", id, status);
+ list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
}
- spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
+ spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
}
EXPORT_SYMBOL(msm_dmov_enqueue_cmd);
void msm_dmov_flush(unsigned int id)
{
unsigned long flags;
- spin_lock_irqsave(&msm_dmov_lock, flags);
+ int ch = DMOV_ID_TO_CHAN(id);
+ int adm = DMOV_ID_TO_ADM(id);
+
+ spin_lock_irqsave(&dmov_conf[adm].lock, flags);
/* XXX not checking if flush cmd sent already */
- if (!list_empty(&active_commands[id])) {
+ if (!list_empty(&dmov_conf[adm].active_commands[ch])) {
PRINT_IO("msm_dmov_flush(%d), send flush cmd\n", id);
- writel(DMOV_FLUSH_GRACEFUL, DMOV_FLUSH0(id));
+ dmov_writel(DMOV_FLUSH_GRACEFUL, DMOV_FLUSH0(ch), adm);
}
- spin_unlock_irqrestore(&msm_dmov_lock, flags);
+ spin_unlock_irqrestore(&dmov_conf[adm].lock, flags);
}
EXPORT_SYMBOL(msm_dmov_flush);
@@ -208,39 +234,66 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
}
EXPORT_SYMBOL(msm_dmov_exec_cmd);
+static void msm_dmov_fill_errdata(struct msm_dmov_errdata *errdata, int ch,
+ int adm)
+{
+ errdata->flush[0] = dmov_readl(DMOV_FLUSH0(ch), adm);
+ errdata->flush[1] = dmov_readl(DMOV_FLUSH1(ch), adm);
+ errdata->flush[2] = dmov_readl(DMOV_FLUSH2(ch), adm);
+ errdata->flush[3] = dmov_readl(DMOV_FLUSH3(ch), adm);
+ errdata->flush[4] = dmov_readl(DMOV_FLUSH4(ch), adm);
+ errdata->flush[5] = dmov_readl(DMOV_FLUSH5(ch), adm);
+}
+
+static int msm_dmov_irq_to_adm(unsigned irq)
+{
+ int i;
+ for (i = 0; i < nr_adms; i++)
+ if (dmov_conf[i].irq == irq)
+ return i;
+ PRINT_ERROR("msm_dmov_irq_to_adm: can't match ADM to IRQ %d\n", irq);
+ return -EINVAL;
+}
+
static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
{
unsigned int int_status, mask, id;
unsigned long irq_flags;
+ unsigned int ch;
unsigned int ch_status;
unsigned int ch_result;
struct msm_dmov_cmd *cmd;
+ int adm = msm_dmov_irq_to_adm(irq);
- spin_lock_irqsave(&msm_dmov_lock, irq_flags);
+ spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
- int_status = readl(DMOV_ISR); /* read and clear interrupt */
+ int_status = dmov_readl(DMOV_ISR, adm); /* read and clear interrupt */
PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status);
while (int_status) {
mask = int_status & -int_status;
- id = fls(mask) - 1;
+ ch = fls(mask) - 1;
+ id = DMOV_CHAN_ADM_TO_ID(ch, adm);
PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n", int_status, mask, id);
int_status &= ~mask;
- ch_status = readl(DMOV_STATUS(id));
+ ch_status = dmov_readl(DMOV_STATUS(ch), adm);
if (!(ch_status & DMOV_STATUS_RSLT_VALID)) {
PRINT_FLOW("msm_datamover_irq_handler id %d, result not valid %x\n", id, ch_status);
continue;
}
do {
- ch_result = readl(DMOV_RSLT(id));
- if (list_empty(&active_commands[id])) {
+ ch_result = dmov_readl(DMOV_RSLT(ch), adm);
+ if (list_empty(&dmov_conf[adm].active_commands[ch])) {
PRINT_ERROR("msm_datamover_irq_handler id %d, got result "
"with no active command, status %x, result %x\n",
id, ch_status, ch_result);
cmd = NULL;
} else
- cmd = list_entry(active_commands[id].next, typeof(*cmd), list);
- PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result);
+ cmd = list_entry(dmov_conf[adm].
+ active_commands[ch].next, typeof(*cmd),
+ list);
+ PRINT_FLOW("msm_datamover_irq_handler id %d, status %x,"
+ " result %x\n", id, ch_status, ch_result);
if (ch_result & DMOV_RSLT_DONE) {
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n",
id, ch_status);
@@ -255,12 +308,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
if (ch_result & DMOV_RSLT_FLUSH) {
struct msm_dmov_errdata errdata;
- errdata.flush[0] = readl(DMOV_FLUSH0(id));
- errdata.flush[1] = readl(DMOV_FLUSH1(id));
- errdata.flush[2] = readl(DMOV_FLUSH2(id));
- errdata.flush[3] = readl(DMOV_FLUSH3(id));
- errdata.flush[4] = readl(DMOV_FLUSH4(id));
- errdata.flush[5] = readl(DMOV_FLUSH5(id));
+ msm_dmov_fill_errdata(&errdata, ch, adm);
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
if (cmd) {
@@ -272,13 +320,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
if (ch_result & DMOV_RSLT_ERROR) {
struct msm_dmov_errdata errdata;
- errdata.flush[0] = readl(DMOV_FLUSH0(id));
- errdata.flush[1] = readl(DMOV_FLUSH1(id));
- errdata.flush[2] = readl(DMOV_FLUSH2(id));
- errdata.flush[3] = readl(DMOV_FLUSH3(id));
- errdata.flush[4] = readl(DMOV_FLUSH4(id));
- errdata.flush[5] = readl(DMOV_FLUSH5(id));
-
+ msm_dmov_fill_errdata(&errdata, ch, adm);
PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
if (cmd) {
@@ -288,101 +330,133 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
}
/* this does not seem to work, once we get an error */
/* the datamover will no longer accept commands */
- writel(0, DMOV_FLUSH0(id));
+ dmov_writel(0, DMOV_FLUSH0(ch), adm);
}
- ch_status = readl(DMOV_STATUS(id));
+ ch_status = dmov_readl(DMOV_STATUS(ch), adm);
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
- if ((ch_status & DMOV_STATUS_CMD_PTR_RDY) && !list_empty(&ready_commands[id])) {
- cmd = list_entry(ready_commands[id].next, typeof(*cmd), list);
+ if ((ch_status & DMOV_STATUS_CMD_PTR_RDY) &&
+ !list_empty(&dmov_conf[adm].ready_commands[ch])) {
+ cmd = list_entry(dmov_conf[adm].
+ ready_commands[ch].next, typeof(*cmd),
+ list);
list_del(&cmd->list);
- list_add_tail(&cmd->list, &active_commands[id]);
+ list_add_tail(&cmd->list, &dmov_conf[adm].
+ active_commands[ch]);
if (cmd->execute_func)
cmd->execute_func(cmd);
PRINT_FLOW("msm_datamover_irq_handler id %d, start command\n", id);
- writel(cmd->cmdptr, DMOV_CMD_PTR(id));
+ dmov_writel(cmd->cmdptr, DMOV_CMD_PTR(ch), adm);
}
} while (ch_status & DMOV_STATUS_RSLT_VALID);
- if (list_empty(&active_commands[id]) && list_empty(&ready_commands[id]))
- channel_active &= ~(1U << id);
+ if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
+ list_empty(&dmov_conf[adm].ready_commands[ch]))
+ dmov_conf[adm].channel_active &= ~(1U << ch);
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
}
- if (!channel_active) {
- disable_irq_nosync(msm_dmov_irq);
- msm_dmov_clocks_off();
+ if (!dmov_conf[adm].channel_active) {
+ disable_irq_nosync(dmov_conf[adm].irq);
+ msm_dmov_clocks_off(adm);
}
- spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
+ spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
return IRQ_HANDLED;
}
-static void __init msm_dmov_deinit_clocks(void)
+static void __init msm_dmov_deinit_clocks(int adm)
{
- if (!IS_ERR(msm_dmov_clk))
- clk_put(msm_dmov_clk);
- if (!IS_ERR(msm_dmov_pclk))
- clk_put(msm_dmov_pclk);
+ if (!IS_ERR(dmov_conf[adm].clk))
+ clk_put(dmov_conf[adm].clk);
+ if (!IS_ERR(dmov_conf[adm].pclk))
+ clk_put(dmov_conf[adm].pclk);
}
+#define PDEV_TO_ADM(pdev) \
+({ \
+ typeof(pdev) _pdev = pdev; \
+ (_pdev->id == -1) ? 0 : _pdev->id; \
+})
+
static int __devinit msm_dmov_init_clocks(struct platform_device *pdev)
{
int ret = 0;
+ int adm = PDEV_TO_ADM(pdev);
- msm_dmov_clk = clk_get(&pdev->dev, "adm_clk");
- if (IS_ERR(msm_dmov_clk)) {
+ dmov_conf[adm].clk = clk_get(&pdev->dev, "adm_clk");
+ if (IS_ERR(dmov_conf[adm].clk)) {
PRINT_ERROR("%s: Error getting adm_clk\n", __func__);
- ret = PTR_ERR(msm_dmov_clk);
+ ret = PTR_ERR(dmov_conf[adm].clk);
}
- msm_dmov_pclk = clk_get(&pdev->dev, "adm_pclk");
+ dmov_conf[adm].pclk = clk_get(&pdev->dev, "adm_pclk");
/* pclk not present on all SoCs, don't return error on failure */
return ret;
}
-static int __devinit msm_dmov_probe(struct platform_device *pdev)
+static int __devinit msm_dmov_conf_init(struct platform_device *pdev)
{
int i;
- int ret;
- struct resource *res;
+ int adm = PDEV_TO_ADM(pdev);
+ struct resource *irqres =
+ platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ struct resource *memres =
+ platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (!irqres || !memres || !irqres->start)
+ return -EINVAL;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENXIO;
+ dmov_conf[adm].irq = irqres->start;
- msm_dmov_base = ioremap_nocache(res->start, resource_size(res));
- if (!msm_dmov_base)
+ dmov_conf[adm].base =
+ ioremap_nocache(memres->start, resource_size(memres));
+ if (!dmov_conf[adm].base)
return -ENOMEM;
+ dmov_conf[adm].lock = __SPIN_LOCK_UNLOCKED(dmov_lock);
for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
- INIT_LIST_HEAD(&ready_commands[i]);
- INIT_LIST_HEAD(&active_commands[i]);
- writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT |
- DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
+ INIT_LIST_HEAD(&dmov_conf[adm].ready_commands[i]);
+ INIT_LIST_HEAD(&dmov_conf[adm].active_commands[i]);
}
+ return 0;
+}
- ret = msm_dmov_init_clocks(pdev);
+static inline void __devinit msm_dmov_conf_free(int adm)
+{
+ iounmap(dmov_conf[adm].base);
+}
+
+static int __devinit msm_dmov_probe(struct platform_device *pdev)
+{
+ int i;
+ int ret;
+ int adm = PDEV_TO_ADM(pdev);
+
+ ret = msm_dmov_conf_init(pdev);
if (ret)
- goto out_map;
+ return ret;
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
- ret = -EINVAL;
- goto out_clock;
- }
+ for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++)
+ dmov_writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT
+ | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i), adm);
- msm_dmov_irq = res->start;
- ret = request_irq(msm_dmov_irq, msm_datamover_irq_handler, 0,
+ ret = msm_dmov_init_clocks(pdev);
+ if (ret)
+ goto out_conf;
+
+ ret = request_irq(dmov_conf[adm].irq, msm_datamover_irq_handler, 0,
"msmdatamover", NULL);
if (ret)
goto out_clock;
- disable_irq(msm_dmov_irq);
+ disable_irq(dmov_conf[adm].irq);
+ nr_adms++;
return 0;
+
out_clock:
- msm_dmov_deinit_clocks();
-out_map:
- iounmap(msm_dmov_base);
+ msm_dmov_deinit_clocks(adm);
+out_conf:
+ msm_dmov_conf_free(adm);
return ret;
}
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
Unlike previous targets, 8x60 has two different ADMs, which are managed
separately.
Signed-off-by: Jeff Ohlstein <[email protected]>
---
arch/arm/mach-msm/Makefile | 3 +-
arch/arm/mach-msm/board-msm8x60.c | 9 +++-
arch/arm/mach-msm/devices-msm8x60.c | 56 +++++++++++++++++++++++
arch/arm/mach-msm/devices.h | 2 +
arch/arm/mach-msm/dma.c | 17 +++++--
arch/arm/mach-msm/include/mach/dma.h | 55 ++++++++++++++++------
arch/arm/mach-msm/include/mach/msm_iomap-8x60.h | 6 +++
7 files changed, 126 insertions(+), 22 deletions(-)
create mode 100644 arch/arm/mach-msm/devices-msm8x60.c
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 86acfa3..9998f75 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_MSM_IOMMU) += iommu.o iommu_dev.o devices-iommu.o
obj-$(CONFIG_ARCH_MSM7X00A) += dma.o irq.o acpuclock-arm11.o
obj-$(CONFIG_ARCH_MSM7X30) += dma.o
obj-$(CONFIG_ARCH_QSD8X50) += dma.o sirc.o
+obj-$(CONFIG_ARCH_MSM8X60) += dma.o
obj-$(CONFIG_ARCH_MSM8960) += clock-dummy.o
obj-$(CONFIG_MSM_PROC_COMM) += proc_comm.o clock-pcom.o vreg.o
@@ -24,7 +25,7 @@ obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o b
obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
-obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60.o
+obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60.o devices-msm8x60.o
obj-$(CONFIG_ARCH_MSM8960) += board-msm8960.o devices-msm8960.o
obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-v1.o gpiomux.o
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index b3c55f1..92105c4 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -28,12 +28,18 @@
#include <mach/board.h>
#include <mach/msm_iomap.h>
+#include <devices.h>
static void __init msm8x60_map_io(void)
{
msm_map_msm8x60_io();
}
+static struct platform_device *devices[] __initdata = {
+ &msm_device_dmov_adm0,
+ &msm_device_dmov_adm1,
+};
+
static void __init msm8x60_init_irq(void)
{
unsigned int i;
@@ -62,6 +68,7 @@ static void __init msm8x60_init_irq(void)
static void __init msm8x60_init(void)
{
+ platform_add_devices(devices, ARRAY_SIZE(devices));
}
MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
new file mode 100644
index 0000000..33c236c
--- /dev/null
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -0,0 +1,56 @@
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+#include <mach/dma.h>
+
+static struct resource resources_dmov_adm0[] = {
+ {
+ .start = MSM8X60_DMOV_ADM0_PHYS,
+ .end = MSM8X60_DMOV_ADM0_PHYS + MSM8X60_DMOV_ADM0_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_ADM0_AARM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource resources_dmov_adm1[] = {
+ {
+ .start = MSM8X60_DMOV_ADM1_PHYS,
+ .end = MSM8X60_DMOV_ADM1_PHYS + MSM8X60_DMOV_ADM1_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_ADM1_AARM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_dmov_adm0 = {
+ .name = "msm_dmov",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(resources_dmov_adm0),
+ .resource = resources_dmov_adm0,
+};
+
+struct platform_device msm_device_dmov_adm1 = {
+ .name = "msm_dmov",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(resources_dmov_adm1),
+ .resource = resources_dmov_adm1,
+};
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 54ebfee..0abf25f 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -41,6 +41,8 @@ extern struct platform_device msm_device_i2c;
extern struct platform_device msm_device_smd;
extern struct platform_device msm_device_dmov;
+extern struct platform_device msm_device_dmov_adm0;
+extern struct platform_device msm_device_dmov_adm1;
extern struct platform_device msm_device_nand;
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 5510c61..44d9621 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -51,17 +51,24 @@ struct msm_dmov_conf {
static struct msm_dmov_conf dmov_conf[MSM_DMOV_MAX_ADMS];
static int nr_adms;
-#define DMOV_SD0(off, ch) (0x0000 + (off) + ((ch) << 2))
-#define DMOV_SD1(off, ch) (0x0400 + (off) + ((ch) << 2))
-#define DMOV_SD2(off, ch) (0x0800 + (off) + ((ch) << 2))
-#define DMOV_SD3(off, ch) (0x0C00 + (off) + ((ch) << 2))
-
#if defined(CONFIG_ARCH_MSM7X30)
#define DMOV_SD_AARM DMOV_SD2
+#define DMOV_SD_SIZE 0x400
+#elif defined(CONFIG_ARCH_MSM8X60)
+#define DMOV_SD_AARM DMOV_SD1
+#define DMOV_SD_SIZE 0x800
#else
#define DMOV_SD_AARM DMOV_SD3
+#define DMOV_SD_SIZE 0x400
#endif
+#define DMOV_ADDR(sd, off, ch) (((sd) * DMOV_SD_SIZE) + (off) + ((ch) << 2))
+
+#define DMOV_SD0(off, ch) DMOV_ADDR(0, off, ch)
+#define DMOV_SD1(off, ch) DMOV_ADDR(1, off, ch)
+#define DMOV_SD2(off, ch) DMOV_ADDR(2, off, ch)
+#define DMOV_SD3(off, ch) DMOV_ADDR(3, off, ch)
+
#define DMOV_CMD_PTR(ch) DMOV_SD_AARM(0x000, ch)
#define DMOV_RSLT(ch) DMOV_SD_AARM(0x040, ch)
#define DMOV_FLUSH0(ch) DMOV_SD_AARM(0x080, ch)
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 23041c7..3d67773 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -34,24 +34,10 @@ struct msm_dmov_cmd {
void *data;
};
-#ifndef CONFIG_ARCH_MSM8X60
int msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
int msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
int msm_dmov_flush(unsigned int id);
-#else
-static inline
-int msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) { return -EIO; }
-static inline
-int msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
-{
- return -EIO;
-}
-static inline
-int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) { return -EIO; }
-static inline
-int msm_dmov_flush(unsigned int id) { return -EIO; }
-#endif
#define DMOV_CMD_LIST (0 << 29) /* does not work */
#define DMOV_CMD_PTR_LIST (1 << 29) /* works */
@@ -76,8 +62,47 @@ int msm_dmov_flush(unsigned int id) { return -EIO; }
#define DMOV_CONFIG_FORCE_FLUSH_RSLT (1 << 1)
#define DMOV_CONFIG_IRQ_EN (1 << 0)
-/* channel assignments */
+#define DMOV_8X60_GP_CHAN 16
+
+#define DMOV_8X60_CE_IN_CHAN 2
+#define DMOV_8X60_CE_IN_CRCI 4
+
+#define DMOV_8X60_CE_OUT_CHAN 3
+#define DMOV_8X60_CE_OUT_CRCI 5
+
+#define DMOV_8X60_CE_HASH_CRCI 15
+
+#define DMOV_8X60_SDC1_CHAN 18
+#define DMOV_8X60_SDC1_CRCI 1
+
+#define DMOV_8X60_SDC2_CHAN 19
+#define DMOV_8X60_SDC2_CRCI 4
+
+#define DMOV_8X60_SDC3_CHAN 20
+#define DMOV_8X60_SDC3_CRCI 2
+
+#define DMOV_8X60_SDC4_CHAN 21
+#define DMOV_8X60_SDC4_CRCI 5
+
+#define DMOV_8X60_SDC5_CHAN 21
+#define DMOV_8X60_SDC5_CRCI 14
+
+#define DMOV_8X60_TSIF_CHAN 4
+#define DMOV_8X60_TSIF_CRCI 6
+
+#define DMOV_8X60_HSUART1_TX_CHAN 22
+#define DMOV_8X60_HSUART1_TX_CRCI 8
+
+#define DMOV_8X60_HSUART1_RX_CHAN 23
+#define DMOV_8X60_HSUART1_RX_CRCI 9
+
+#define DMOV_8X60_HSUART2_TX_CHAN 8
+#define DMOV_8X60_HSUART2_TX_CRCI 13
+
+#define DMOV_8X60_HSUART2_RX_CHAN 8
+#define DMOV_8X60_HSUART2_RX_CRCI 14
+/* channel assignments before 8x60 */
#define DMOV_NAND_CHAN 7
#define DMOV_NAND_CRCI_CMD 5
#define DMOV_NAND_CRCI_DATA 4
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
index 3b19b8f..87a26c6 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
@@ -56,6 +56,12 @@
#define MSM_SHARED_RAM_BASE IOMEM(0xF0100000)
#define MSM_SHARED_RAM_SIZE SZ_1M
+#define MSM8X60_DMOV_ADM0_PHYS 0x18320000
+#define MSM8X60_DMOV_ADM0_SIZE SZ_1M
+
+#define MSM8X60_DMOV_ADM1_PHYS 0x18420000
+#define MSM8X60_DMOV_ADM1_SIZE SZ_1M
+
#define MSM8X60_TMR_PHYS 0x02000000
#define MSM8X60_TMR_SIZE SZ_4K
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
Signed-off-by: Jeff Ohlstein <[email protected]>
---
arch/arm/mach-msm/Makefile | 2 +-
arch/arm/mach-msm/board-msm8960.c | 5 +++++
arch/arm/mach-msm/devices-msm8960.c | 21 +++++++++++++++++++++
arch/arm/mach-msm/devices.h | 1 +
arch/arm/mach-msm/dma.c | 3 +++
arch/arm/mach-msm/include/mach/msm_iomap-8960.h | 3 +++
6 files changed, 34 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 9998f75..35fd3e8 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_ARCH_MSM7X00A) += dma.o irq.o acpuclock-arm11.o
obj-$(CONFIG_ARCH_MSM7X30) += dma.o
obj-$(CONFIG_ARCH_QSD8X50) += dma.o sirc.o
obj-$(CONFIG_ARCH_MSM8X60) += dma.o
-obj-$(CONFIG_ARCH_MSM8960) += clock-dummy.o
+obj-$(CONFIG_ARCH_MSM8960) += dma.o clock-dummy.o
obj-$(CONFIG_MSM_PROC_COMM) += proc_comm.o clock-pcom.o vreg.o
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index 9511ea6..72ac090 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -65,9 +65,14 @@ static struct platform_device *rumi3_devices[] __initdata = {
&msm8960_device_uart_gsbi5,
};
+static struct platform_device *devices[] __initdata = {
+ &msm8960_device_dmov,
+};
+
static void __init msm8960_init(void)
{
msm_clock_init(msm_clocks_8960, msm_num_clocks_8960);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
}
static void __init msm8960_sim_init(void)
diff --git a/arch/arm/mach-msm/devices-msm8960.c b/arch/arm/mach-msm/devices-msm8960.c
index 894ff98..75dc162 100644
--- a/arch/arm/mach-msm/devices-msm8960.c
+++ b/arch/arm/mach-msm/devices-msm8960.c
@@ -24,6 +24,8 @@
#include <mach/irqs-8960.h>
#include <mach/board.h>
+#include <mach/msm_iomap.h>
+#include <mach/irqs.h>
#include "devices.h"
#include "clock.h"
@@ -89,6 +91,25 @@ struct platform_device msm8960_device_uart_gsbi5 = {
.resource = resources_uart_gsbi5,
};
+static struct resource resources_dmov[] = {
+ {
+ .start = MSM8960_DMOV_PHYS,
+ .end = MSM8960_DMOV_PHYS + MSM8960_DMOV_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_ADM0_SCSS_0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm8960_device_dmov = {
+ .name = "msm_dmov",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_dmov),
+ .resource = resources_dmov,
+};
+
struct clk_lookup msm_clocks_8960[] = {
CLK_DUMMY("ce_clk", CE2_CLK, NULL, OFF),
CLK_DUMMY("gsbi_uart_clk", GSBI1_UART_CLK, NULL, OFF),
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 0abf25f..e38fc86 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -41,6 +41,7 @@ extern struct platform_device msm_device_i2c;
extern struct platform_device msm_device_smd;
extern struct platform_device msm_device_dmov;
+extern struct platform_device msm8960_device_dmov;
extern struct platform_device msm_device_dmov_adm0;
extern struct platform_device msm_device_dmov_adm1;
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 44d9621..16b4034 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -57,6 +57,9 @@ static int nr_adms;
#elif defined(CONFIG_ARCH_MSM8X60)
#define DMOV_SD_AARM DMOV_SD1
#define DMOV_SD_SIZE 0x800
+#elif defined(CONFIG_ARCH_MSM8960)
+#define DMOV_SD_AARM DMOV_SD0
+#define DMOV_SD_SIZE 0x800
#else
#define DMOV_SD_AARM DMOV_SD3
#define DMOV_SD_SIZE 0x400
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
index 3c9d960..b251ba6 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
@@ -45,4 +45,7 @@
#define MSM8960_TMR0_PHYS 0x0208A000
#define MSM8960_TMR0_SIZE SZ_4K
+#define MSM8960_DMOV_PHYS 0x18300000
+#define MSM8960_DMOV_SIZE SZ_1M
+
#endif
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
Previously we just left the pclk in whatever state it was in at boot.
Instead, turn it off and on at the same time that we turn the regular
clock on and off.
Signed-off-by: Jeff Ohlstein <[email protected]>
---
arch/arm/mach-msm/dma.c | 71 +++++++++++++++++++++++++++++++++++++++++------
1 files changed, 62 insertions(+), 9 deletions(-)
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 1f487b8..2dc408d 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -32,6 +32,7 @@ enum {
static DEFINE_SPINLOCK(msm_dmov_lock);
static struct clk *msm_dmov_clk;
+static struct clk *msm_dmov_pclk;
static unsigned int channel_active;
static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
@@ -55,6 +56,31 @@ void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
}
EXPORT_SYMBOL(msm_dmov_stop_cmd);
+static int msm_dmov_clocks_on(void)
+{
+ int ret = 0;
+
+ if (!IS_ERR(msm_dmov_clk)) {
+ ret = clk_enable(msm_dmov_clk);
+ if (ret)
+ return ret;
+ if (!IS_ERR(msm_dmov_pclk)) {
+ ret = clk_enable(msm_dmov_pclk);
+ if (ret)
+ clk_disable(msm_dmov_clk);
+ }
+ }
+ return ret;
+}
+
+static void msm_dmov_clocks_off(void)
+{
+ if (!IS_ERR(msm_dmov_clk))
+ clk_disable(msm_dmov_clk);
+ if (!IS_ERR(msm_dmov_pclk))
+ clk_disable(msm_dmov_pclk);
+}
+
void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
{
unsigned long irq_flags;
@@ -62,7 +88,7 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
spin_lock_irqsave(&msm_dmov_lock, irq_flags);
if (!channel_active)
- clk_enable(msm_dmov_clk);
+ msm_dmov_clocks_on();
dsb();
status = readl(DMOV_STATUS(id));
if (list_empty(&ready_commands[id]) &&
@@ -83,7 +109,7 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
writel(cmd->cmdptr, DMOV_CMD_PTR(id));
} else {
if (!channel_active)
- clk_disable(msm_dmov_clk);
+ msm_dmov_clocks_off();
if (list_empty(&active_commands[id]))
PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status);
@@ -255,31 +281,58 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
if (!channel_active) {
disable_irq_nosync(INT_ADM_AARM);
- clk_disable(msm_dmov_clk);
+ msm_dmov_clocks_off();
}
spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
return IRQ_HANDLED;
}
+static void __init msm_dmov_deinit_clocks(void)
+{
+ if (!IS_ERR(msm_dmov_clk))
+ clk_put(msm_dmov_clk);
+ if (!IS_ERR(msm_dmov_pclk))
+ clk_put(msm_dmov_pclk);
+}
+
+static int __init msm_dmov_init_clocks(void)
+{
+ int ret = 0;
+
+ msm_dmov_clk = clk_get(NULL, "adm_clk");
+ if (IS_ERR(msm_dmov_clk)) {
+ PRINT_ERROR("%s: Error getting adm_clk\n", __func__);
+ ret = PTR_ERR(msm_dmov_clk);
+ }
+
+ msm_dmov_pclk = clk_get(NULL, "adm_pclk");
+ /* pclk not present on all SoCs, don't return error on failure */
+
+ return ret;
+}
+
static int __init msm_init_datamover(void)
{
int i;
int ret;
- struct clk *clk;
for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
INIT_LIST_HEAD(&ready_commands[i]);
INIT_LIST_HEAD(&active_commands[i]);
writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
}
- clk = clk_get(NULL, "adm_clk");
- if (IS_ERR(clk))
- return PTR_ERR(clk);
- msm_dmov_clk = clk;
- ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
+
+ ret = msm_dmov_init_clocks();
if (ret)
return ret;
+
+ ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0,
+ "msmdatamover", NULL);
+ if (ret) {
+ msm_dmov_deinit_clocks();
+ return ret;
+ }
disable_irq(INT_ADM_AARM);
return 0;
}
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
Signed-off-by: Jeff Ohlstein <[email protected]>
---
arch/arm/mach-msm/dma.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 8e4d46e..1f487b8 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -19,6 +19,7 @@
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
+#include <linux/module.h>
#include <mach/dma.h>
#define MSM_DMOV_CHANNEL_COUNT 16
@@ -52,6 +53,7 @@ void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
{
writel((graceful << 31), DMOV_FLUSH0(id));
}
+EXPORT_SYMBOL(msm_dmov_stop_cmd);
void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
{
@@ -90,6 +92,7 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
}
spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
}
+EXPORT_SYMBOL(msm_dmov_enqueue_cmd);
void msm_dmov_flush(unsigned int id)
{
@@ -102,6 +105,7 @@ void msm_dmov_flush(unsigned int id)
}
spin_unlock_irqrestore(&msm_dmov_lock, flags);
}
+EXPORT_SYMBOL(msm_dmov_flush);
struct msm_dmov_exec_cmdptr_cmd {
struct msm_dmov_cmd dmov_cmd;
@@ -148,7 +152,7 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr);
return 0;
}
-
+EXPORT_SYMBOL(msm_dmov_exec_cmd);
static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
{
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
From: Subhash Jadavani <[email protected]>
The include guard was missing the #define, leading to errors if one
included dma.h twice.
Signed-off-by: Subhash Jadavani <[email protected]>
---
arch/arm/mach-msm/include/mach/dma.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 05583f5..ece09e0 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -1,6 +1,7 @@
/* linux/include/asm-arm/arch-msm/dma.h
*
* Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -14,6 +15,7 @@
*/
#ifndef __ASM_ARCH_MSM_DMA_H
+#define __ASM_ARCH_MSM_DMA_H
#include <linux/list.h>
#include <mach/msm_iomap.h>
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
From: Stepan Moskovchenko <[email protected]>
Move common initialization code into a separate function in
preparation for adding devices that are common to multiple
8960 targets.
Signed-off-by: Stepan Moskovchenko <[email protected]>
---
arch/arm/mach-msm/board-msm8960.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index 052cb35..9511ea6 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -65,15 +65,20 @@ static struct platform_device *rumi3_devices[] __initdata = {
&msm8960_device_uart_gsbi5,
};
-static void __init msm8960_sim_init(void)
+static void __init msm8960_init(void)
{
msm_clock_init(msm_clocks_8960, msm_num_clocks_8960);
+}
+
+static void __init msm8960_sim_init(void)
+{
+ msm8960_init();
platform_add_devices(sim_devices, ARRAY_SIZE(sim_devices));
}
static void __init msm8960_rumi3_init(void)
{
- msm_clock_init(msm_clocks_8960, msm_num_clocks_8960);
+ msm8960_init();
platform_add_devices(rumi3_devices, ARRAY_SIZE(rumi3_devices));
}
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
It is not safe to call the existing functions if dma fails to probe. So,
check for probe failure at the start of each externally facing function.
Signed-off-by: Jeff Ohlstein <[email protected]>
---
arch/arm/mach-msm/dma.c | 26 +++++++++++++++++++++++---
arch/arm/mach-msm/include/mach/dma.h | 15 +++++++++------
2 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index ef543e1..5510c61 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -100,12 +100,17 @@ static inline void dmov_writel(unsigned val, unsigned addr, int adm)
#define DMOV_ID_TO_CHAN(id) ((id) % MSM_DMOV_CHANNEL_COUNT)
#define DMOV_CHAN_ADM_TO_ID(ch, adm) ((ch) + (adm) * MSM_DMOV_CHANNEL_COUNT)
-void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
+int msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
{
int adm = DMOV_ID_TO_ADM(id);
int ch = DMOV_ID_TO_CHAN(id);
+ if (!dmov_conf[adm].base)
+ return -ENODEV;
+
dmov_writel((graceful << 31), DMOV_FLUSH0(ch), adm);
+
+ return 0;
}
EXPORT_SYMBOL(msm_dmov_stop_cmd);
@@ -134,13 +139,16 @@ static void msm_dmov_clocks_off(int adm)
clk_disable(dmov_conf[adm].pclk);
}
-void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
+int msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
{
unsigned long irq_flags;
unsigned int status;
int adm = DMOV_ID_TO_ADM(id);
int ch = DMOV_ID_TO_CHAN(id);
+ if (!dmov_conf[adm].base)
+ return -ENODEV;
+
spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
if (!dmov_conf[adm].channel_active)
msm_dmov_clocks_on(adm);
@@ -168,15 +176,20 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
}
spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
+
+ return 0;
}
EXPORT_SYMBOL(msm_dmov_enqueue_cmd);
-void msm_dmov_flush(unsigned int id)
+int msm_dmov_flush(unsigned int id)
{
unsigned long flags;
int ch = DMOV_ID_TO_CHAN(id);
int adm = DMOV_ID_TO_ADM(id);
+ if (!dmov_conf[adm].base)
+ return -ENODEV;
+
spin_lock_irqsave(&dmov_conf[adm].lock, flags);
/* XXX not checking if flush cmd sent already */
if (!list_empty(&dmov_conf[adm].active_commands[ch])) {
@@ -184,6 +197,8 @@ void msm_dmov_flush(unsigned int id)
dmov_writel(DMOV_FLUSH_GRACEFUL, DMOV_FLUSH0(ch), adm);
}
spin_unlock_irqrestore(&dmov_conf[adm].lock, flags);
+
+ return 0;
}
EXPORT_SYMBOL(msm_dmov_flush);
@@ -211,6 +226,10 @@ dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd,
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
{
struct msm_dmov_exec_cmdptr_cmd cmd;
+ int adm = DMOV_ID_TO_ADM(id);
+
+ if (!dmov_conf[adm].base)
+ return -ENODEV;
PRINT_FLOW("dmov_exec_cmdptr(%d, %x)\n", id, cmdptr);
@@ -424,6 +443,7 @@ static int __devinit msm_dmov_conf_init(struct platform_device *pdev)
static inline void __devinit msm_dmov_conf_free(int adm)
{
iounmap(dmov_conf[adm].base);
+ dmov_conf[adm].base = NULL;
}
static int __devinit msm_dmov_probe(struct platform_device *pdev)
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index ae031d2..23041c7 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -35,19 +35,22 @@ struct msm_dmov_cmd {
};
#ifndef CONFIG_ARCH_MSM8X60
-void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
-void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
+int msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
+int msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
-void msm_dmov_flush(unsigned int id);
+int msm_dmov_flush(unsigned int id);
#else
static inline
-void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) { }
+int msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) { return -EIO; }
static inline
-void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful) { }
+int msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
+{
+ return -EIO;
+}
static inline
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) { return -EIO; }
static inline
-void msm_dmov_flush(unsigned int id) { }
+int msm_dmov_flush(unsigned int id) { return -EIO; }
#endif
#define DMOV_CMD_LIST (0 << 29) /* does not work */
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
Switching to a platform device allows us to add hooks for power
management, along with providing a way to do per-SoC configuration of
the device.
Signed-off-by: Jeff Ohlstein <[email protected]>
---
arch/arm/mach-msm/board-halibut.c | 1 +
arch/arm/mach-msm/board-mahimahi.c | 1 +
arch/arm/mach-msm/board-msm7x30.c | 1 +
arch/arm/mach-msm/board-qsd8x50.c | 1 +
arch/arm/mach-msm/board-trout.c | 1 +
arch/arm/mach-msm/devices-msm7x00.c | 21 ++++++-
arch/arm/mach-msm/devices-msm7x30.c | 21 ++++++-
arch/arm/mach-msm/devices-qsd8x50.c | 21 ++++++-
arch/arm/mach-msm/devices.h | 2 +
arch/arm/mach-msm/dma.c | 78 +++++++++++++++++------
arch/arm/mach-msm/include/mach/msm_iomap-7x00.h | 5 +-
arch/arm/mach-msm/include/mach/msm_iomap-7x30.h | 5 +-
arch/arm/mach-msm/include/mach/msm_iomap-8x50.h | 5 +-
arch/arm/mach-msm/io.c | 3 -
14 files changed, 131 insertions(+), 35 deletions(-)
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c
index 18a3c97..4d264eb 100644
--- a/arch/arm/mach-msm/board-halibut.c
+++ b/arch/arm/mach-msm/board-halibut.c
@@ -59,6 +59,7 @@ static struct platform_device smc91x_device = {
static struct platform_device *devices[] __initdata = {
&msm_device_uart3,
+ &msm_device_dmov,
&msm_device_smd,
&msm_device_nand,
&msm_device_hsusb,
diff --git a/arch/arm/mach-msm/board-mahimahi.c b/arch/arm/mach-msm/board-mahimahi.c
index 7a9a03e..db3201a 100644
--- a/arch/arm/mach-msm/board-mahimahi.c
+++ b/arch/arm/mach-msm/board-mahimahi.c
@@ -44,6 +44,7 @@ static struct platform_device *devices[] __initdata = {
#if !defined(CONFIG_MSM_SERIAL_DEBUGGER)
&msm_device_uart1,
#endif
+ &msm_device_dmov,
&msm_device_uart_dm1,
&msm_device_nand,
};
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index cf15889..cfd6172 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -79,6 +79,7 @@ static struct platform_device *devices[] __initdata = {
#if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER)
&msm_device_uart2,
#endif
+ &msm_device_dmov,
&msm_device_smd,
&msm_device_otg,
&msm_device_hsusb,
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index 127ee6d..50b9dd0 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -93,6 +93,7 @@ static struct msm_otg_platform_data msm_otg_pdata = {
static struct platform_device *devices[] __initdata = {
&msm_device_uart3,
+ &msm_device_dmov,
&msm_device_smd,
&msm_device_otg,
&msm_device_hsusb,
diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c
index 8143867..5831ce5 100644
--- a/arch/arm/mach-msm/board-trout.c
+++ b/arch/arm/mach-msm/board-trout.c
@@ -35,6 +35,7 @@ extern int trout_init_mmc(unsigned int);
static struct platform_device *devices[] __initdata = {
&msm_device_uart3,
+ &msm_device_dmov,
&msm_device_smd,
&msm_device_nand,
&msm_device_hsusb,
diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c
index c4f5e26..3ef38a5 100644
--- a/arch/arm/mach-msm/devices-msm7x00.c
+++ b/arch/arm/mach-msm/devices-msm7x00.c
@@ -418,8 +418,27 @@ struct platform_device msm_device_mdp = {
.resource = resources_mdp,
};
+static struct resource resources_dmov[] = {
+ {
+ .start = MSM7X00_DMOV_PHYS,
+ .end = MSM7X00_DMOV_PHYS + MSM7X00_DMOV_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_ADM_AARM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_dmov = {
+ .name = "msm_dmov",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_dmov),
+ .resource = resources_dmov,
+};
+
struct clk_lookup msm_clocks_7x01a[] = {
- CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
+ CLK_PCOM("adm_clk", ADM_CLK, "msm_dmov", 0),
CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, 0),
CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0),
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index 09b4f14..f803fcd 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -130,8 +130,27 @@ struct platform_device msm_device_hsusb_host = {
},
};
+static struct resource resources_dmov[] = {
+ {
+ .start = MSM7X30_DMOV_PHYS,
+ .end = MSM7X30_DMOV_PHYS + MSM7X30_DMOV_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_ADM_AARM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_dmov = {
+ .name = "msm_dmov",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_dmov),
+ .resource = resources_dmov,
+};
+
struct clk_lookup msm_clocks_7x30[] = {
- CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
+ CLK_PCOM("adm_clk", ADM_CLK, "msm_dmov", 0),
CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
CLK_PCOM("cam_m_clk", CAM_M_CLK, NULL, 0),
CLK_PCOM("camif_pad_pclk", CAMIF_PAD_P_CLK, NULL, OFF),
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c
index 12d8deb..730982f 100644
--- a/arch/arm/mach-msm/devices-qsd8x50.c
+++ b/arch/arm/mach-msm/devices-qsd8x50.c
@@ -315,8 +315,27 @@ int __init msm_add_sdcc(unsigned int controller,
return platform_device_register(pdev);
}
+static struct resource resources_dmov[] = {
+ {
+ .start = QSD8X50_DMOV_PHYS,
+ .end = QSD8X50_DMOV_PHYS + QSD8X50_DMOV_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_ADM_AARM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_dmov = {
+ .name = "msm_dmov",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_dmov),
+ .resource = resources_dmov,
+};
+
struct clk_lookup msm_clocks_8x50[] = {
- CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
+ CLK_PCOM("adm_clk", ADM_CLK, "msm_dmov", 0),
CLK_PCOM("ce_clk", CE_CLK, NULL, 0),
CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN),
CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0),
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index e7a0cb0..54ebfee 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -40,6 +40,8 @@ extern struct platform_device msm_device_i2c;
extern struct platform_device msm_device_smd;
+extern struct platform_device msm_device_dmov;
+
extern struct platform_device msm_device_nand;
extern struct platform_device msm_device_mddi0;
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 3ff31f9..3bafee9 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -20,10 +20,13 @@
#include <linux/interrupt.h>
#include <linux/completion.h>
#include <linux/module.h>
+#include <linux/platform_device.h>
#include <mach/dma.h>
#define MSM_DMOV_CHANNEL_COUNT 16
+#define MODULE_NAME "msm_dmov"
+
enum {
MSM_DMOV_PRINT_ERRORS = 1,
MSM_DMOV_PRINT_IO = 2,
@@ -37,11 +40,13 @@ static unsigned int channel_active;
static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
+static void __iomem *msm_dmov_base;
+static unsigned msm_dmov_irq;
-#define DMOV_SD0(off, ch) (MSM_DMOV_BASE + 0x0000 + (off) + ((ch) << 2))
-#define DMOV_SD1(off, ch) (MSM_DMOV_BASE + 0x0400 + (off) + ((ch) << 2))
-#define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2))
-#define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2))
+#define DMOV_SD0(off, ch) (msm_dmov_base + 0x0000 + (off) + ((ch) << 2))
+#define DMOV_SD1(off, ch) (msm_dmov_base + 0x0400 + (off) + ((ch) << 2))
+#define DMOV_SD2(off, ch) (msm_dmov_base + 0x0800 + (off) + ((ch) << 2))
+#define DMOV_SD3(off, ch) (msm_dmov_base + 0x0C00 + (off) + ((ch) << 2))
#if defined(CONFIG_ARCH_MSM7X30)
#define DMOV_SD_AARM DMOV_SD2
@@ -127,7 +132,7 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", id, status);
list_add_tail(&cmd->list, &active_commands[id]);
if (!channel_active)
- enable_irq(INT_ADM_AARM);
+ enable_irq(msm_dmov_irq);
channel_active |= 1U << id;
writel(cmd->cmdptr, DMOV_CMD_PTR(id));
} else {
@@ -303,7 +308,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
}
if (!channel_active) {
- disable_irq_nosync(INT_ADM_AARM);
+ disable_irq_nosync(msm_dmov_irq);
msm_dmov_clocks_off();
}
@@ -319,46 +324,79 @@ static void __init msm_dmov_deinit_clocks(void)
clk_put(msm_dmov_pclk);
}
-static int __init msm_dmov_init_clocks(void)
+static int __devinit msm_dmov_init_clocks(struct platform_device *pdev)
{
int ret = 0;
- msm_dmov_clk = clk_get(NULL, "adm_clk");
+ msm_dmov_clk = clk_get(&pdev->dev, "adm_clk");
if (IS_ERR(msm_dmov_clk)) {
PRINT_ERROR("%s: Error getting adm_clk\n", __func__);
ret = PTR_ERR(msm_dmov_clk);
}
- msm_dmov_pclk = clk_get(NULL, "adm_pclk");
+ msm_dmov_pclk = clk_get(&pdev->dev, "adm_pclk");
/* pclk not present on all SoCs, don't return error on failure */
return ret;
}
-static int __init msm_init_datamover(void)
+static int __devinit msm_dmov_probe(struct platform_device *pdev)
{
int i;
int ret;
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENXIO;
+
+ msm_dmov_base = ioremap_nocache(res->start, resource_size(res));
+ if (!msm_dmov_base)
+ return -ENOMEM;
for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
INIT_LIST_HEAD(&ready_commands[i]);
INIT_LIST_HEAD(&active_commands[i]);
- writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
+ writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT |
+ DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
}
- ret = msm_dmov_init_clocks();
+ ret = msm_dmov_init_clocks(pdev);
if (ret)
- return ret;
+ goto out_map;
- ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0,
- "msmdatamover", NULL);
- if (ret) {
- msm_dmov_deinit_clocks();
- return ret;
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ ret = -EINVAL;
+ goto out_clock;
}
- disable_irq(INT_ADM_AARM);
+
+ msm_dmov_irq = res->start;
+ ret = request_irq(msm_dmov_irq, msm_datamover_irq_handler, 0,
+ "msmdatamover", NULL);
+ if (ret)
+ goto out_clock;
+ disable_irq(msm_dmov_irq);
+
return 0;
+out_clock:
+ msm_dmov_deinit_clocks();
+out_map:
+ iounmap(msm_dmov_base);
+ return ret;
}
-arch_initcall(msm_init_datamover);
+static struct platform_driver msm_dmov_driver = {
+ .probe = msm_dmov_probe,
+ .driver = {
+ .name = MODULE_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init msm_init_datamover(void)
+{
+ return platform_driver_register(&msm_dmov_driver);
+}
+arch_initcall(msm_init_datamover);
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
index 8f99d97..d6540e1 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
@@ -51,9 +51,8 @@
#define MSM7X00_CSR_PHYS 0xC0100000
#define MSM7X00_CSR_SIZE SZ_4K
-#define MSM_DMOV_BASE IOMEM(0xE0002000)
-#define MSM_DMOV_PHYS 0xA9700000
-#define MSM_DMOV_SIZE SZ_4K
+#define MSM7X00_DMOV_PHYS 0xA9700000
+#define MSM7X00_DMOV_SIZE SZ_4K
#define MSM_GPIO1_BASE IOMEM(0xE0003000)
#define MSM_GPIO1_PHYS 0xA9200000
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
index 4d84be1..23912e5 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
@@ -42,9 +42,8 @@
#define MSM7X30_CSR_PHYS 0xC0100000
#define MSM7X30_CSR_SIZE SZ_4K
-#define MSM_DMOV_BASE IOMEM(0xE0002000)
-#define MSM_DMOV_PHYS 0xAC400000
-#define MSM_DMOV_SIZE SZ_4K
+#define MSM7X30_DMOV_PHYS 0xAC400000
+#define MSM7X30_DMOV_SIZE SZ_4K
#define MSM_GPIO1_BASE IOMEM(0xE0003000)
#define MSM_GPIO1_PHYS 0xAC001000
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
index d414320..fc36b82 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
@@ -42,9 +42,8 @@
#define QSD8X50_CSR_PHYS 0xAC100000
#define QSD8X50_CSR_SIZE SZ_4K
-#define MSM_DMOV_BASE IOMEM(0xE0002000)
-#define MSM_DMOV_PHYS 0xA9700000
-#define MSM_DMOV_SIZE SZ_4K
+#define QSD8X50_DMOV_PHYS 0xA9700000
+#define QSD8X50_DMOV_SIZE SZ_4K
#define MSM_GPIO1_BASE IOMEM(0xE0003000)
#define MSM_GPIO1_PHYS 0xA9000000
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index cec6ed1..1c86cda 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -42,7 +42,6 @@
static struct map_desc msm_io_desc[] __initdata = {
MSM_DEVICE(VIC),
MSM_CHIP_DEVICE(CSR, MSM7X00),
- MSM_DEVICE(DMOV),
MSM_DEVICE(GPIO1),
MSM_DEVICE(GPIO2),
MSM_DEVICE(CLK_CTL),
@@ -75,7 +74,6 @@ void __init msm_map_common_io(void)
static struct map_desc qsd8x50_io_desc[] __initdata = {
MSM_DEVICE(VIC),
MSM_CHIP_DEVICE(CSR, QSD8X50),
- MSM_DEVICE(DMOV),
MSM_DEVICE(GPIO1),
MSM_DEVICE(GPIO2),
MSM_DEVICE(CLK_CTL),
@@ -134,7 +132,6 @@ void __init msm_map_msm8960_io(void)
static struct map_desc msm7x30_io_desc[] __initdata = {
MSM_DEVICE(VIC),
MSM_CHIP_DEVICE(CSR, MSM7X30),
- MSM_DEVICE(DMOV),
MSM_DEVICE(GPIO1),
MSM_DEVICE(GPIO2),
MSM_DEVICE(CLK_CTL),
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.