summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2011-08-17 14:36:51 +0300
committerVarun Colbert <vcolbert@nvidia.com>2011-10-06 16:59:51 -0700
commit1b12dbd994338535fd45501243c791659f09cdcd (patch)
treeca50f14830cb6edb1806bd53c3ad51a77186b687 /drivers
parent334cfb4331ab5d7252863b2fa9d2e2ae4ce3f6b6 (diff)
tegra: nvhost: Retrieve phys address from nvmap
Debug code used to rely on being able to calculate the base address of a pinned page by masking it. Now we always retrieve the physical address from nvmap and find the correct command buffer using that. Bug 840976 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/48105 Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com> Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com> Reviewed-by: Scott Williams <scwilliams@nvidia.com> (cherry picked from commit 0ef5f2d4d94464b8d5562327c9cf5b56fe93fff5) Change-Id: I1a17665cf19d8758f154d4fd05f6a5ec6c07caff Reviewed-on: http://git-master/r/56266 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/tegra/host/chip_support.h1
-rw-r--r--drivers/video/tegra/host/nvhost_cdma.c5
-rw-r--r--drivers/video/tegra/host/nvhost_cdma.h8
-rw-r--r--drivers/video/tegra/host/t20/3dctx_t20.c1
-rw-r--r--drivers/video/tegra/host/t20/cdma_t20.c20
-rw-r--r--drivers/video/tegra/host/t20/channel_t20.c2
-rw-r--r--drivers/video/tegra/host/t20/debug_t20.c17
-rw-r--r--drivers/video/tegra/host/t30/3dctx_t30.c4
8 files changed, 38 insertions, 20 deletions
diff --git a/drivers/video/tegra/host/chip_support.h b/drivers/video/tegra/host/chip_support.h
index cdd26fa8147f..1b141798c157 100644
--- a/drivers/video/tegra/host/chip_support.h
+++ b/drivers/video/tegra/host/chip_support.h
@@ -93,6 +93,7 @@ struct nvhost_chip_support {
int (*init)(struct push_buffer *);
void (*destroy)(struct push_buffer *);
void (*push_to)(struct push_buffer *,
+ struct nvmap_client *,
struct nvmap_handle *,
u32 op1, u32 op2);
void (*pop_from)(struct push_buffer *,
diff --git a/drivers/video/tegra/host/nvhost_cdma.c b/drivers/video/tegra/host/nvhost_cdma.c
index b125f76414cc..5c04e5838d2a 100644
--- a/drivers/video/tegra/host/nvhost_cdma.c
+++ b/drivers/video/tegra/host/nvhost_cdma.c
@@ -691,7 +691,7 @@ int nvhost_cdma_begin(struct nvhost_cdma *cdma,
*/
void nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2)
{
- nvhost_cdma_push_gather(cdma, NULL, op1, op2);
+ nvhost_cdma_push_gather(cdma, NULL, NULL, op1, op2);
}
/**
@@ -699,6 +699,7 @@ void nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2)
* Blocks as necessary if the push buffer is full.
*/
void nvhost_cdma_push_gather(struct nvhost_cdma *cdma,
+ struct nvmap_client *client,
struct nvmap_handle *handle, u32 op1, u32 op2)
{
u32 slots_free = cdma->slots_free;
@@ -712,7 +713,7 @@ void nvhost_cdma_push_gather(struct nvhost_cdma *cdma,
}
cdma->slots_free = slots_free - 1;
cdma->slots_used++;
- cdma_pb_op(cdma).push_to(pb, handle, op1, op2);
+ cdma_pb_op(cdma).push_to(pb, client, handle, op1, op2);
}
/**
diff --git a/drivers/video/tegra/host/nvhost_cdma.h b/drivers/video/tegra/host/nvhost_cdma.h
index 8bdc18b90220..e5e1d5f88701 100644
--- a/drivers/video/tegra/host/nvhost_cdma.h
+++ b/drivers/video/tegra/host/nvhost_cdma.h
@@ -48,6 +48,10 @@ struct nvhost_userctx_timeout;
* update - call to update sync queue and push buffer, unpin memory
*/
+struct nvmap_client_handle {
+ struct nvmap_client *client;
+ struct nvmap_handle *handle;
+};
struct push_buffer {
struct nvmap_handle_ref *mem; /* handle to pushbuffer memory */
@@ -55,7 +59,8 @@ struct push_buffer {
u32 phys; /* physical address of pushbuffer */
u32 fence; /* index we've written */
u32 cur; /* index to write to */
- struct nvmap_handle **handles; /* nvmap handle for each opcode pair */
+ struct nvmap_client_handle *nvmap;
+ /* nvmap handle for each opcode pair */
};
struct syncpt_buffer {
@@ -131,6 +136,7 @@ int nvhost_cdma_begin(struct nvhost_cdma *cdma,
struct nvhost_userctx_timeout *timeout);
void nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2);
void nvhost_cdma_push_gather(struct nvhost_cdma *cdma,
+ struct nvmap_client *client,
struct nvmap_handle *handle, u32 op1, u32 op2);
void nvhost_cdma_end(struct nvhost_cdma *cdma,
struct nvmap_client *user_nvmap,
diff --git a/drivers/video/tegra/host/t20/3dctx_t20.c b/drivers/video/tegra/host/t20/3dctx_t20.c
index ebf6c73d2693..7ac1b5e118cd 100644
--- a/drivers/video/tegra/host/t20/3dctx_t20.c
+++ b/drivers/video/tegra/host/t20/3dctx_t20.c
@@ -138,6 +138,7 @@ static void save_push_v0(struct nvhost_cdma *cdma,
struct nvhost_hwctx *ctx)
{
nvhost_cdma_push_gather(cdma,
+ cdma_to_channel(cdma)->dev->nvmap,
nvmap_ref_to_handle(nvhost_3dctx_save_buf),
nvhost_opcode_gather(save_size),
save_phys);
diff --git a/drivers/video/tegra/host/t20/cdma_t20.c b/drivers/video/tegra/host/t20/cdma_t20.c
index 130cf08e8c6c..98b9e1dd0040 100644
--- a/drivers/video/tegra/host/t20/cdma_t20.c
+++ b/drivers/video/tegra/host/t20/cdma_t20.c
@@ -57,7 +57,7 @@ static int t20_push_buffer_init(struct push_buffer *pb)
pb->mem = NULL;
pb->mapped = NULL;
pb->phys = 0;
- pb->handles = NULL;
+ pb->nvmap = NULL;
BUG_ON(!cdma_pb_op(cdma).reset);
cdma_pb_op(cdma).reset(pb);
@@ -80,9 +80,11 @@ static int t20_push_buffer_init(struct push_buffer *pb)
goto fail;
}
- /* memory for storing nvmap handles for each opcode pair */
- pb->handles = kzalloc(PUSH_BUFFER_SIZE/2, GFP_KERNEL);
- if (!pb->handles)
+ /* memory for storing nvmap client and handles for each opcode pair */
+ pb->nvmap = kzalloc(PUSH_BUFFER_SIZE/2 *
+ sizeof(struct nvmap_client_handle),
+ GFP_KERNEL);
+ if (!pb->nvmap)
goto fail;
/* put the restart at the end of pushbuffer memory */
@@ -111,12 +113,12 @@ static void t20_push_buffer_destroy(struct push_buffer *pb)
if (pb->mem)
nvmap_free(nvmap, pb->mem);
- kfree(pb->handles);
+ kfree(pb->nvmap);
pb->mem = NULL;
pb->mapped = NULL;
pb->phys = 0;
- pb->handles = 0;
+ pb->nvmap = 0;
}
/**
@@ -124,14 +126,16 @@ static void t20_push_buffer_destroy(struct push_buffer *pb)
* Caller must ensure push buffer is not full
*/
static void t20_push_buffer_push_to(struct push_buffer *pb,
- struct nvmap_handle *handle, u32 op1, u32 op2)
+ struct nvmap_client *client,
+ struct nvmap_handle *handle, u32 op1, u32 op2)
{
u32 cur = pb->cur;
u32 *p = (u32 *)((u32)pb->mapped + cur);
BUG_ON(cur == pb->fence);
*(p++) = op1;
*(p++) = op2;
- pb->handles[cur/8] = handle;
+ pb->nvmap[cur/8].client = client;
+ pb->nvmap[cur/8].handle = handle;
pb->cur = (cur + 8) & (PUSH_BUFFER_SIZE - 1);
/* printk("push_to_push_buffer: op1=%08x; op2=%08x; cur=%x\n", op1, op2, pb->cur); */
}
diff --git a/drivers/video/tegra/host/t20/channel_t20.c b/drivers/video/tegra/host/t20/channel_t20.c
index d1c0b1f72066..e446034a7cb4 100644
--- a/drivers/video/tegra/host/t20/channel_t20.c
+++ b/drivers/video/tegra/host/t20/channel_t20.c
@@ -239,6 +239,7 @@ static int t20_channel_submit(struct nvhost_channel *channel,
/* gather restore buffer */
if (need_restore)
nvhost_cdma_push_gather(&channel->cdma,
+ channel->dev->nvmap,
nvmap_ref_to_handle(channel->cur_ctx->restore),
nvhost_opcode_gather(channel->cur_ctx->restore_size),
channel->cur_ctx->restore_phys);
@@ -278,6 +279,7 @@ static int t20_channel_submit(struct nvhost_channel *channel,
int i = 0;
for ( ; i < gather_end-gather; i += 2) {
nvhost_cdma_push_gather(&channel->cdma,
+ user_nvmap,
unpins[i/2],
nvhost_opcode_gather(gather[i]),
gather[i+1]);
diff --git a/drivers/video/tegra/host/t20/debug_t20.c b/drivers/video/tegra/host/t20/debug_t20.c
index fb101230cd8b..ed4a5e1de21c 100644
--- a/drivers/video/tegra/host/t20/debug_t20.c
+++ b/drivers/video/tegra/host/t20/debug_t20.c
@@ -146,32 +146,33 @@ static void show_channel_gather(struct output *o, u32 addr,
phys_addr_t phys_addr,
u32 words, struct nvhost_cdma *cdma)
{
- /* Calculate page boundary and offset */
- phys_addr_t map_base = phys_addr & PAGE_MASK;
- phys_addr_t map_offset = phys_addr - map_base;
-
/* Map dmaget cursor to corresponding nvmap_handle */
struct push_buffer *pb = &cdma->push_buffer;
u32 cur = addr - pb->phys;
- struct nvmap_handle *h = pb->handles[cur/8];
+ struct nvmap_client_handle *nvmap = &pb->nvmap[cur/8];
/* Create a fake nvmap_handle_ref - nvmap_mmap requires it
* but accesses only the first field - nvmap_handle */
- struct nvmap_handle_ref ref = {.handle = h};
+ struct nvmap_handle_ref ref = {.handle = nvmap->handle};
- u32 *map_addr;
+ u32 *map_addr, pin_addr, offset;
int state, count, i;
map_addr = nvmap_mmap(&ref);
if (!map_addr)
return;
+ /* Get base address from nvmap */
+ pin_addr = nvmap_pin(nvmap->client, &ref);
+ offset = phys_addr - pin_addr;
+ nvmap_unpin(nvmap->client, &ref);
+
/* GATHER buffer starts always with commands */
state = NVHOST_DBG_STATE_CMD;
for (i = 0; i < words; i++)
show_channel_word(o, &state, &count,
phys_addr + i * 4,
- *(map_addr + map_offset/4 + i), cdma);
+ *(map_addr + offset/4 + i), cdma);
nvmap_munmap(&ref, map_addr);
}
diff --git a/drivers/video/tegra/host/t30/3dctx_t30.c b/drivers/video/tegra/host/t30/3dctx_t30.c
index 264e7c144285..614d079e904e 100644
--- a/drivers/video/tegra/host/t30/3dctx_t30.c
+++ b/drivers/video/tegra/host/t30/3dctx_t30.c
@@ -150,7 +150,9 @@ static void save_push_v1(struct nvhost_cdma *cdma,
nvhost_opcode_nonincr(0x904, 1),
ctx->restore_phys);
/* gather the save buffer */
- nvhost_cdma_push(cdma,
+ nvhost_cdma_push_gather(cdma,
+ cdma_to_channel(cdma)->dev->nvmap,
+ nvmap_ref_to_handle(nvhost_3dctx_save_buf),
nvhost_opcode_gather(save_size),
save_phys);
}