summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/host/host1x/host1x_intr.c
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2012-05-30 15:28:19 +0300
committerSimone Willett <swillett@nvidia.com>2012-06-14 16:29:58 -0700
commitf2dd85f69f329f372db29d2e20d71f7e0e0f85bb (patch)
tree5c5d9cc279844dc31a5b4346c4f45b9d9c9ac790 /drivers/video/tegra/host/host1x/host1x_intr.c
parent9774bbe31a0741ad71929156f59afdb2aba4eae5 (diff)
video: tegra: host: Parametrize host1x
Add parameters in host1x nvhost_device on * number of sync points * number of wait bases * number of channels * number of mlocks * client managed bitmask * naming of sync points Add automatically generated headers and use symbols from them to access hardware. Move host1x device definition from generic host1x to SoC specific source files t20.c and t30.c. Bug 982965 Change-Id: Ibec84be22d75b363900d10bcbd59d4d8321d54a1 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/104974 Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/host/host1x/host1x_intr.c')
-rw-r--r--drivers/video/tegra/host/host1x/host1x_intr.c110
1 files changed, 66 insertions, 44 deletions
diff --git a/drivers/video/tegra/host/host1x/host1x_intr.c b/drivers/video/tegra/host/host1x/host1x_intr.c
index e8d1a81c49bb..6ec6dd394ebb 100644
--- a/drivers/video/tegra/host/host1x/host1x_intr.c
+++ b/drivers/video/tegra/host/host1x/host1x_intr.c
@@ -29,6 +29,9 @@
#include "host1x_hardware.h"
#include "chip_support.h"
+/* Spacing between sync registers */
+#define REGISTER_STRIDE 4
+
/*** HW host sync management ***/
static void syncpt_thresh_mask(struct irq_data *data)
@@ -43,17 +46,23 @@ static void syncpt_thresh_unmask(struct irq_data *data)
static void syncpt_thresh_cascade(unsigned int irq, struct irq_desc *desc)
{
- void __iomem *sync_regs = irq_desc_get_handler_data(desc);
+ struct nvhost_master *dev = irq_desc_get_handler_data(desc);
+ void __iomem *sync_regs = dev->sync_aperture;
unsigned long reg;
- int id;
+ int i, id;
struct irq_chip *chip = irq_desc_get_chip(desc);
chained_irq_enter(chip, desc);
- reg = readl(sync_regs + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS);
-
- for_each_set_bit(id, &reg, 32)
- generic_handle_irq(id + INT_SYNCPT_THRESH_BASE);
+ for (i = 0; i < dev->info.nb_pts / BITS_PER_LONG; i++) {
+ reg = readl(sync_regs +
+ host1x_sync_syncpt_thresh_cpu0_int_status_r() +
+ i * REGISTER_STRIDE);
+ for_each_set_bit(id, &reg, BITS_PER_LONG)
+ generic_handle_irq(id +
+ dev->intr.host_syncpt_irq_base +
+ i * BITS_PER_LONG);
+ }
chained_irq_exit(chip, desc);
}
@@ -71,12 +80,12 @@ static void t20_intr_init_host_sync(struct nvhost_intr *intr)
int i, irq;
writel(0xffffffffUL,
- sync_regs + HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE);
+ sync_regs + host1x_sync_syncpt_thresh_int_disable_r());
writel(0xffffffffUL,
- sync_regs + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS);
+ sync_regs + host1x_sync_syncpt_thresh_cpu0_int_status_r());
- for (i = 0; i < INT_SYNCPT_THRESH_NR; i++) {
- irq = INT_SYNCPT_THRESH_BASE + i;
+ for (i = 0; i < dev->info.nb_pts; i++) {
+ irq = intr->host_syncpt_irq_base + i;
irq_set_chip_and_handler(irq, &syncpt_thresh_irq,
handle_simple_irq);
irq_set_chip_data(irq, sync_regs);
@@ -84,16 +93,16 @@ static void t20_intr_init_host_sync(struct nvhost_intr *intr)
}
irq_set_chained_handler(INT_HOST1X_MPCORE_SYNCPT,
syncpt_thresh_cascade);
- irq_set_handler_data(INT_HOST1X_MPCORE_SYNCPT, sync_regs);
+ irq_set_handler_data(INT_HOST1X_MPCORE_SYNCPT, dev);
/* disable the ip_busy_timeout. this prevents write drops, etc.
* there's no real way to recover from a hung client anyway.
*/
- writel(0, sync_regs + HOST1X_SYNC_IP_BUSY_TIMEOUT);
+ writel(0, sync_regs + host1x_sync_ip_busy_timeout_r());
/* increase the auto-ack timout to the maximum value. 2d will hang
* otherwise on ap20.
*/
- writel(0xff, sync_regs + HOST1X_SYNC_CTXSW_TIMEOUT_CFG);
+ writel(0xff, sync_regs + host1x_sync_ctxsw_timeout_cfg_r());
}
static void t20_intr_set_host_clocks_per_usec(struct nvhost_intr *intr, u32 cpm)
@@ -101,7 +110,7 @@ static void t20_intr_set_host_clocks_per_usec(struct nvhost_intr *intr, u32 cpm)
struct nvhost_master *dev = intr_to_dev(intr);
void __iomem *sync_regs = dev->sync_aperture;
/* write microsecond clock register */
- writel(cpm, sync_regs + HOST1X_SYNC_USEC_CLK);
+ writel(cpm, sync_regs + host1x_sync_usec_clk_r());
}
static void t20_intr_set_syncpt_threshold(struct nvhost_intr *intr,
@@ -110,28 +119,39 @@ static void t20_intr_set_syncpt_threshold(struct nvhost_intr *intr,
struct nvhost_master *dev = intr_to_dev(intr);
void __iomem *sync_regs = dev->sync_aperture;
thresh &= 0xffff;
- writel(thresh, sync_regs + (HOST1X_SYNC_SYNCPT_INT_THRESH_0 + id * 4));
+ writel(thresh, sync_regs +
+ (host1x_sync_syncpt_int_thresh_0_r() + id * REGISTER_STRIDE));
}
static void t20_intr_enable_syncpt_intr(struct nvhost_intr *intr, u32 id)
{
struct nvhost_master *dev = intr_to_dev(intr);
void __iomem *sync_regs = dev->sync_aperture;
- writel(BIT(id), sync_regs + HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0);
+
+ writel(BIT_MASK(id), sync_regs +
+ host1x_sync_syncpt_thresh_int_enable_cpu0_r() +
+ BIT_WORD(id) * REGISTER_STRIDE);
}
static void t20_intr_disable_all_syncpt_intrs(struct nvhost_intr *intr)
{
struct nvhost_master *dev = intr_to_dev(intr);
void __iomem *sync_regs = dev->sync_aperture;
- /* disable interrupts for both cpu's */
- writel(0, sync_regs + HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE);
-
- /* clear status for both cpu's */
- writel(0xffffffffu, sync_regs +
- HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS);
- writel(0xffffffffu, sync_regs +
- HOST1X_SYNC_SYNCPT_THRESH_CPU1_INT_STATUS);
+ u32 reg;
+
+ for (reg = 0; reg <= BIT_WORD(dev->info.nb_pts) * REGISTER_STRIDE;
+ reg += REGISTER_STRIDE) {
+ /* disable interrupts for both cpu's */
+ writel(0, sync_regs +
+ host1x_sync_syncpt_thresh_int_disable_r() +
+ reg);
+
+ /* clear status for both cpu's */
+ writel(0xffffffffu, sync_regs +
+ host1x_sync_syncpt_thresh_cpu0_int_status_r() + reg);
+ writel(0xffffffffu, sync_regs +
+ host1x_sync_syncpt_thresh_cpu1_int_status_r() + reg);
+ }
}
/**
@@ -146,10 +166,12 @@ irqreturn_t t20_intr_syncpt_thresh_isr(int irq, void *dev_id)
void __iomem *sync_regs = intr_to_dev(intr)->sync_aperture;
- writel(BIT(id),
- sync_regs + HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE);
- writel(BIT(id),
- sync_regs + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS);
+ u32 reg = BIT_WORD(id) * REGISTER_STRIDE;
+
+ writel(BIT_MASK(id), sync_regs +
+ host1x_sync_syncpt_thresh_int_disable_r() + reg);
+ writel(BIT_MASK(id), sync_regs +
+ host1x_sync_syncpt_thresh_cpu0_int_status_r() + reg);
return IRQ_WAKE_THREAD;
}
@@ -166,21 +188,21 @@ static irqreturn_t t20_intr_host1x_isr(int irq, void *dev_id)
u32 ext_stat;
u32 addr;
- stat = readl(sync_regs + HOST1X_SYNC_HINTSTATUS);
- ext_stat = readl(sync_regs + HOST1X_SYNC_HINTSTATUS_EXT);
+ stat = readl(sync_regs + host1x_sync_hintstatus_r());
+ ext_stat = readl(sync_regs + host1x_sync_hintstatus_ext_r());
- if (HOST1X_VAL(SYNC_HINTSTATUS_EXT, IP_READ_INT, ext_stat)) {
- addr = readl(sync_regs + HOST1X_SYNC_IP_READ_TIMEOUT_ADDR);
+ if (host1x_sync_hintstatus_ext_ip_read_int_v(ext_stat)) {
+ addr = readl(sync_regs + host1x_sync_ip_read_timeout_addr_r());
pr_err("Host read timeout at address %x\n", addr);
}
- if (HOST1X_VAL(SYNC_HINTSTATUS_EXT, IP_WRITE_INT, ext_stat)) {
- addr = readl(sync_regs + HOST1X_SYNC_IP_WRITE_TIMEOUT_ADDR);
+ if (host1x_sync_hintstatus_ext_ip_write_int_v(ext_stat)) {
+ addr = readl(sync_regs + host1x_sync_ip_write_timeout_addr_r());
pr_err("Host write timeout at address %x\n", addr);
}
- writel(ext_stat, sync_regs + HOST1X_SYNC_HINTSTATUS_EXT);
- writel(stat, sync_regs + HOST1X_SYNC_HINTSTATUS);
+ writel(ext_stat, sync_regs + host1x_sync_hintstatus_ext_r());
+ writel(stat, sync_regs + host1x_sync_hintstatus_r());
return IRQ_HANDLED;
}
@@ -193,11 +215,11 @@ static int t20_intr_request_host_general_irq(struct nvhost_intr *intr)
return 0;
/* master disable for general (not syncpt) host interrupts */
- writel(0, sync_regs + HOST1X_SYNC_INTMASK);
+ writel(0, sync_regs + host1x_sync_intmask_r());
/* clear status & extstatus */
- writel(0xfffffffful, sync_regs + HOST1X_SYNC_HINTSTATUS_EXT);
- writel(0xfffffffful, sync_regs + HOST1X_SYNC_HINTSTATUS);
+ writel(0xfffffffful, sync_regs + host1x_sync_hintstatus_ext_r());
+ writel(0xfffffffful, sync_regs + host1x_sync_hintstatus_r());
err = request_irq(intr->host_general_irq, t20_intr_host1x_isr, 0,
"host_status", intr);
@@ -205,16 +227,16 @@ static int t20_intr_request_host_general_irq(struct nvhost_intr *intr)
return err;
/* enable extra interrupt sources IP_READ_INT and IP_WRITE_INT */
- writel(BIT(30) | BIT(31), sync_regs + HOST1X_SYNC_HINTMASK_EXT);
+ writel(BIT(30) | BIT(31), sync_regs + host1x_sync_hintmask_ext_r());
/* enable extra interrupt sources */
- writel(BIT(31), sync_regs + HOST1X_SYNC_HINTMASK);
+ writel(BIT(31), sync_regs + host1x_sync_hintmask_r());
/* enable host module interrupt to CPU0 */
- writel(BIT(0), sync_regs + HOST1X_SYNC_INTC0MASK);
+ writel(BIT(0), sync_regs + host1x_sync_intc0mask_r());
/* master enable for general (not syncpt) host interrupts */
- writel(BIT(0), sync_regs + HOST1X_SYNC_INTMASK);
+ writel(BIT(0), sync_regs + host1x_sync_intmask_r());
intr->host_general_irq_requested = true;
@@ -227,7 +249,7 @@ static void t20_intr_free_host_general_irq(struct nvhost_intr *intr)
void __iomem *sync_regs = intr_to_dev(intr)->sync_aperture;
/* master disable for general (not syncpt) host interrupts */
- writel(0, sync_regs + HOST1X_SYNC_INTMASK);
+ writel(0, sync_regs + host1x_sync_intmask_r());
free_irq(intr->host_general_irq, intr);
intr->host_general_irq_requested = false;