diff options
Diffstat (limited to 'drivers/video/tegra/host/host1x/host1x_syncpt.c')
-rw-r--r-- | drivers/video/tegra/host/host1x/host1x_syncpt.c | 154 |
1 files changed, 42 insertions, 112 deletions
diff --git a/drivers/video/tegra/host/host1x/host1x_syncpt.c b/drivers/video/tegra/host/host1x/host1x_syncpt.c index b431fa350638..8cca9dbbbc08 100644 --- a/drivers/video/tegra/host/host1x/host1x_syncpt.c +++ b/drivers/video/tegra/host/host1x/host1x_syncpt.c @@ -19,10 +19,12 @@ */ #include <linux/nvhost_ioctl.h> +#include <linux/io.h> +#include <trace/events/nvhost.h> #include "nvhost_syncpt.h" -#include "dev.h" -#include "host1x_syncpt.h" -#include "host1x_hardware.h" +#include "nvhost_acm.h" +#include "host1x.h" +#include "chip_support.h" /** * Write the current syncpoint value back to hw. @@ -31,7 +33,7 @@ static void t20_syncpt_reset(struct nvhost_syncpt *sp, u32 id) { struct nvhost_master *dev = syncpt_to_dev(sp); int min = nvhost_syncpt_read_min(sp, id); - writel(min, dev->sync_aperture + (HOST1X_SYNC_SYNCPT_0 + id * 4)); + writel(min, dev->sync_aperture + (host1x_sync_syncpt_0_r() + id * 4)); } /** @@ -41,7 +43,7 @@ static void t20_syncpt_reset_wait_base(struct nvhost_syncpt *sp, u32 id) { struct nvhost_master *dev = syncpt_to_dev(sp); writel(sp->base_val[id], - dev->sync_aperture + (HOST1X_SYNC_SYNCPT_BASE_0 + id * 4)); + dev->sync_aperture + (host1x_sync_syncpt_base_0_r() + id * 4)); } /** @@ -51,7 +53,7 @@ static void t20_syncpt_read_wait_base(struct nvhost_syncpt *sp, u32 id) { struct nvhost_master *dev = syncpt_to_dev(sp); sp->base_val[id] = readl(dev->sync_aperture + - (HOST1X_SYNC_SYNCPT_BASE_0 + id * 4)); + (host1x_sync_syncpt_base_0_r() + id * 4)); } /** @@ -66,7 +68,7 @@ static u32 t20_syncpt_update_min(struct nvhost_syncpt *sp, u32 id) do { old = nvhost_syncpt_read_min(sp, id); - live = readl(sync_regs + (HOST1X_SYNC_SYNCPT_0 + id * 4)); + live = readl(sync_regs + (host1x_sync_syncpt_0_r() + id * 4)); } while ((u32)atomic_cmpxchg(&sp->min_val[id], old, live) != old); if (!nvhost_syncpt_check_max(sp, id, live)) @@ -87,114 +89,55 @@ static u32 t20_syncpt_update_min(struct nvhost_syncpt *sp, u32 id) static void t20_syncpt_cpu_incr(struct nvhost_syncpt *sp, u32 id) { struct nvhost_master *dev = syncpt_to_dev(sp); + u32 reg_offset = id / 32; + BUG_ON(!nvhost_module_powered(dev->dev)); - if (!client_managed(id) && nvhost_syncpt_min_eq_max(sp, id)) { + if (!nvhost_syncpt_client_managed(sp, id) + && nvhost_syncpt_min_eq_max(sp, id)) { dev_err(&syncpt_to_dev(sp)->dev->dev, "Trying to increment syncpoint id %d beyond max\n", id); nvhost_debug_dump(syncpt_to_dev(sp)); return; } - writel(BIT(id), dev->sync_aperture + HOST1X_SYNC_SYNCPT_CPU_INCR); + writel(BIT_MASK(id), dev->sync_aperture + + host1x_sync_syncpt_cpu_incr_r() + reg_offset * 4); wmb(); } -/* check for old WAITs to be removed (avoiding a wrap) */ -static int t20_syncpt_wait_check(struct nvhost_syncpt *sp, - struct nvmap_client *nvmap, - u32 waitchk_mask, - struct nvhost_waitchk *wait, - int num_waitchk) +/* remove a wait pointed to by patch_addr */ +static int host1x_syncpt_patch_wait(struct nvhost_syncpt *sp, + void *patch_addr) { - u32 idx; - int err = 0; - - /* get current syncpt values */ - for (idx = 0; idx < NV_HOST1X_SYNCPT_NB_PTS; idx++) { - if (BIT(idx) & waitchk_mask) - nvhost_syncpt_update_min(sp, idx); - } - - BUG_ON(!wait && !num_waitchk); - - /* compare syncpt vs wait threshold */ - while (num_waitchk) { - u32 override; - - BUG_ON(wait->syncpt_id >= NV_HOST1X_SYNCPT_NB_PTS); - if (nvhost_syncpt_is_expired(sp, - wait->syncpt_id, wait->thresh)) { - /* - * NULL an already satisfied WAIT_SYNCPT host method, - * by patching its args in the command stream. The - * method data is changed to reference a reserved - * (never given out or incr) NVSYNCPT_GRAPHICS_HOST - * syncpt with a matching threshold value of 0, so - * is guaranteed to be popped by the host HW. - */ - dev_dbg(&syncpt_to_dev(sp)->dev->dev, - "drop WAIT id %d (%s) thresh 0x%x, min 0x%x\n", - wait->syncpt_id, - syncpt_op(sp).name(sp, wait->syncpt_id), - wait->thresh, - nvhost_syncpt_read_min(sp, wait->syncpt_id)); - - /* patch the wait */ - override = nvhost_class_host_wait_syncpt( - NVSYNCPT_GRAPHICS_HOST, 0); - err = nvmap_patch_word(nvmap, - (struct nvmap_handle *)wait->mem, - wait->offset, override); - if (err) - break; - } - - wait++; - num_waitchk--; - } - return err; + u32 override = nvhost_class_host_wait_syncpt( + NVSYNCPT_GRAPHICS_HOST, 0); + __raw_writel(override, patch_addr); + return 0; } -static const char *s_syncpt_names[32] = { - "gfx_host", - "", "", "", "", "", "", "", - "disp0_a", "disp1_a", "avp_0", - "csi_vi_0", "csi_vi_1", - "vi_isp_0", "vi_isp_1", "vi_isp_2", "vi_isp_3", "vi_isp_4", - "2d_0", "2d_1", - "disp0_b", "disp1_b", - "3d", - "mpe", - "disp0_c", "disp1_c", - "vblank0", "vblank1", - "mpe_ebm_eof", "mpe_wr_safe", - "2d_tinyblt", - "dsi" -}; - -static const char *t20_syncpt_name(struct nvhost_syncpt *s, u32 id) +static const char *t20_syncpt_name(struct nvhost_syncpt *sp, u32 id) { - BUG_ON(id >= ARRAY_SIZE(s_syncpt_names)); - return s_syncpt_names[id]; + struct host1x_device_info *info = &syncpt_to_dev(sp)->info; + return (id >= info->nb_pts) ? NULL : info->syncpt_names[id]; } static void t20_syncpt_debug(struct nvhost_syncpt *sp) { u32 i; - for (i = 0; i < NV_HOST1X_SYNCPT_NB_PTS; i++) { + for (i = 0; i < nvhost_syncpt_nb_pts(sp); i++) { u32 max = nvhost_syncpt_read_max(sp, i); u32 min = nvhost_syncpt_update_min(sp, i); if (!max && !min) continue; dev_info(&syncpt_to_dev(sp)->dev->dev, "id %d (%s) min %d max %d\n", - i, syncpt_op(sp).name(sp, i), + i, syncpt_op().name(sp, i), min, max); } - for (i = 0; i < NV_HOST1X_SYNCPT_NB_BASES; i++) { + for (i = 0; i < nvhost_syncpt_nb_bases(sp); i++) { u32 base_val; t20_syncpt_read_wait_base(sp, i); base_val = sp->base_val[i]; @@ -212,7 +155,7 @@ static int syncpt_mutex_try_lock(struct nvhost_syncpt *sp, void __iomem *sync_regs = syncpt_to_dev(sp)->sync_aperture; /* mlock registers returns 0 when the lock is aquired. * writing 0 clears the lock. */ - return !!readl(sync_regs + (HOST1X_SYNC_MLOCK_0 + idx * 4)); + return !!readl(sync_regs + (host1x_sync_mlock_0_r() + idx * 4)); } static void syncpt_mutex_unlock(struct nvhost_syncpt *sp, @@ -220,31 +163,18 @@ static void syncpt_mutex_unlock(struct nvhost_syncpt *sp, { void __iomem *sync_regs = syncpt_to_dev(sp)->sync_aperture; - writel(0, sync_regs + (HOST1X_SYNC_MLOCK_0 + idx * 4)); + writel(0, sync_regs + (host1x_sync_mlock_0_r() + idx * 4)); } -int host1x_init_syncpt_support(struct nvhost_master *host) -{ - - host->sync_aperture = host->aperture + - (NV_HOST1X_CHANNEL0_BASE + - HOST1X_CHANNEL_SYNC_REG_BASE); - - host->op.syncpt.reset = t20_syncpt_reset; - host->op.syncpt.reset_wait_base = t20_syncpt_reset_wait_base; - host->op.syncpt.read_wait_base = t20_syncpt_read_wait_base; - host->op.syncpt.update_min = t20_syncpt_update_min; - host->op.syncpt.cpu_incr = t20_syncpt_cpu_incr; - host->op.syncpt.wait_check = t20_syncpt_wait_check; - host->op.syncpt.debug = t20_syncpt_debug; - host->op.syncpt.name = t20_syncpt_name; - host->op.syncpt.mutex_try_lock = syncpt_mutex_try_lock; - host->op.syncpt.mutex_unlock = syncpt_mutex_unlock; - - host->syncpt.nb_pts = NV_HOST1X_SYNCPT_NB_PTS; - host->syncpt.nb_bases = NV_HOST1X_SYNCPT_NB_BASES; - host->syncpt.client_managed = NVSYNCPTS_CLIENT_MANAGED; - host->syncpt.nb_mlocks = NV_HOST1X_SYNC_MLOCK_NUM; - - return 0; -} +static const struct nvhost_syncpt_ops host1x_syncpt_ops = { + .reset = t20_syncpt_reset, + .reset_wait_base = t20_syncpt_reset_wait_base, + .read_wait_base = t20_syncpt_read_wait_base, + .update_min = t20_syncpt_update_min, + .cpu_incr = t20_syncpt_cpu_incr, + .patch_wait = host1x_syncpt_patch_wait, + .debug = t20_syncpt_debug, + .name = t20_syncpt_name, + .mutex_try_lock = syncpt_mutex_try_lock, + .mutex_unlock = syncpt_mutex_unlock, +}; |