Initial commit; kernel source import

This commit is contained in:
Nathan
2025-04-06 23:50:55 -05:00
commit 25c6d769f4
45093 changed files with 18199410 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
/*
* drivers/video/tegra/host/t124/3dctx_t124.c
*
* Tegra Graphics Host 3d hardware context
*
* Copyright (c) 2011-2013, NVIDIA Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
*/
#include "../nvhost_hwctx.h"
#include "../dev.h"
#include "t124.h"
#include "hardware_t124.h"
#include "../gk20a/gk20a.h"
static void t124_ctx3d_free(struct kref *ref)
{
struct nvhost_hwctx *ctx = container_of(ref, struct nvhost_hwctx, ref);
#if defined(CONFIG_TEGRA_GK20A)
gk20a_free_channel(ctx, true);
#endif
kfree(ctx);
}
struct nvhost_hwctx *t124_3dctx_alloc(struct nvhost_hwctx_handler *h,
struct nvhost_channel *ch)
{
struct nvhost_hwctx *ctx;
nvhost_dbg_fn("");
/* it seems odd to be allocating a channel here but the
* t20/t30 notion of a channel is mapped on top of gk20a's
* channel. this works because there is only one module
* under gk20a's host (gr).
*/
/* call gk20a_channel_alloc */
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return NULL;
kref_init(&ctx->ref);
#if defined(CONFIG_TEGRA_GK20A)
return gk20a_open_channel(ch, ctx);
#else
return ctx;
#endif
}
void t124_3dctx_get(struct nvhost_hwctx *hwctx)
{
nvhost_dbg_fn("");
kref_get(&hwctx->ref);
}
void t124_3dctx_put(struct nvhost_hwctx *hwctx)
{
nvhost_dbg_fn("");
kref_put(&hwctx->ref, t124_ctx3d_free);
}
void t124_3dctx_save_push(struct nvhost_hwctx *ctx, struct nvhost_cdma *cdma)
{
nvhost_dbg_fn("");
}
int __init t124_nvhost_3dctx_handler_init(struct nvhost_hwctx_handler *h)
{
nvhost_dbg_fn("");
h->alloc = t124_3dctx_alloc;
h->get = t124_3dctx_get;
h->put = t124_3dctx_put;
h->save_push = t124_3dctx_save_push;
return 0;
}
int __init t124_nvhost_mpectx_handler_init(struct nvhost_hwctx_handler *h)
{
nvhost_dbg_fn("");
return 0;
}

View File

@@ -0,0 +1,11 @@
GCOV_PROFILE := y
ccflags-y += -Idrivers/video/tegra/host
ccflags-y += -Idrivers/video/tegra/camera
ccflags-y += -Wno-multichar
nvhost-t124-objs = \
t124.o \
3dctx_t124.o \
debug_t124.o
obj-$(CONFIG_TEGRA_GRHOST) += nvhost-t124.o

View File

@@ -0,0 +1,59 @@
/*
* drivers/video/tegra/host/t124/cpuaccess_t124.c
*
* Tegra Graphics Host Cpu Register Access
*
* Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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 "../nvhost_cpuaccess.h"
#include "../dev.h"
#include "t124.h"
#include "hardware_t124.h"
static int t124_cpuaccess_mutex_try_lock(struct nvhost_cpuaccess *ctx,
unsigned int idx)
{
struct nvhost_master *dev = cpuaccess_to_dev(ctx);
void __iomem *sync_regs = dev->sync_aperture;
nvhost_dbg_fn("");
/* mlock registers returns 0 when the lock is aquired.
* writing 0 clears the lock. */
return !!readl(sync_regs + (host1x_sync_mlock_0_0_r() + idx * 4));
}
static void t124_cpuaccess_mutex_unlock(struct nvhost_cpuaccess *ctx,
unsigned int idx)
{
struct nvhost_master *dev = cpuaccess_to_dev(ctx);
void __iomem *sync_regs = dev->sync_aperture;
nvhost_dbg_fn("");
writel(0, sync_regs + (host1x_sync_mlock_0_0_r() + idx * 4));
}
int nvhost_init_t124_cpuaccess_support(struct nvhost_master *host,
struct nvhost_chip_support *op)
{
host->nb_modules = NVHOST_MODULE_NUM;
op->cpuaccess.mutex_try_lock = t124_cpuaccess_mutex_try_lock;
op->cpuaccess.mutex_unlock = t124_cpuaccess_mutex_unlock;
return 0;
}

View File

@@ -0,0 +1,89 @@
/*
* drivers/video/tegra/host/t124/debug_t124.c
*
* Copyright (c) 2011-2012, NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
*/
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/io.h>
#include "dev.h"
#include "debug.h"
#include "nvhost_cdma.h"
#include "t124.h"
#include "hardware_t124.h"
#include "gk20a/gk20a.h"
#include "gk20a/debug_gk20a.h"
#include "chip_support.h"
#include "host1x/host1x_debug.c"
static void t124_debug_show_channel_cdma(struct nvhost_master *m,
struct nvhost_channel *ch, struct output *o, int chid)
{
nvhost_dbg_fn("");
#if defined(CONFIG_TEGRA_GK20A)
if (is_gk20a_module(ch->dev))
gk20a_debug_show_channel_cdma(m, ch, o, chid);
else
#endif
t20_debug_show_channel_cdma(m, ch, o, chid);
}
void t124_debug_show_channel_fifo(struct nvhost_master *m,
struct nvhost_channel *ch, struct output *o, int chid)
{
nvhost_dbg_fn("");
#if defined(CONFIG_TEGRA_GK20A)
if (is_gk20a_module(ch->dev))
gk20a_debug_show_channel_fifo(m, ch, o, chid);
else
#endif
t20_debug_show_channel_fifo(m, ch, o, chid);
}
static void t124_debug_show_mlocks(struct nvhost_master *m, struct output *o)
{
u32 __iomem *mlo_regs = m->sync_aperture +
host1x_sync_mlock_owner_0_r();
int i;
nvhost_debug_output(o, "---- mlocks ----\n");
for (i = 0; i < NV_HOST1X_NB_MLOCKS; i++) {
u32 owner = readl(mlo_regs + i * 4);
if (owner & 0x1)
nvhost_debug_output(o, "%d: locked by channel %d\n",
i, (owner >> 8) & 0xf);
else if (owner & 0x2)
nvhost_debug_output(o, "%d: locked by cpu\n", i);
else
nvhost_debug_output(o, "%d: unlocked\n", i);
}
nvhost_debug_output(o, "\n");
}
int nvhost_init_t124_debug_support(struct nvhost_chip_support *op)
{
op->debug.show_channel_cdma = t124_debug_show_channel_cdma;
op->debug.show_channel_fifo = t124_debug_show_channel_fifo;
op->debug.show_mlocks = t124_debug_show_mlocks;
return 0;
}

View File

@@ -0,0 +1,174 @@
/*
* drivers/video/tegra/host/t124/hardware_t124.h
*
* Tegra T124 HOST1X Register Definitions
*
* Copyright (c) 2011-2013, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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 __NVHOST_HARDWARE_T124_H
#define __NVHOST_HARDWARE_T124_H
#include "host1x/hw_host1x04_sync.h"
#include "host1x/hw_host1x04_uclass.h"
#include "host1x/hw_host1x04_channel.h"
#include "host1x/hw_host1x04_actmon.h"
#define NV_HOST1X_CHANNELS 9
#define NV_HOST1X_SYNC_MLOCK_NUM 16
/* sync registers */
#define NV_HOST1X_SYNCPT_NB_PTS 192
#define NV_HOST1X_SYNCPT_NB_BASES 64
#define NV_HOST1X_NB_MLOCKS 16
#define HOST1X_CHANNEL_SYNC_REG_BASE 0x2100
#define NV_HOST1X_CHANNEL_MAP_SIZE_BYTES 16384
/* actmon regs */
#define HOST1X_CHANNEL_ACTMON1_REG_BASE 8192
#define HOST1X_CHANNEL_ACTMON2_REG_BASE 8256
/* Generic support */
static inline u32 nvhost_class_host_wait_syncpt(
unsigned indx, unsigned threshold)
{
return (indx << 24) | (threshold & 0xffffff);
}
static inline u32 nvhost_class_host_load_syncpt_base(
unsigned indx, unsigned threshold)
{
return host1x_uclass_wait_syncpt_indx_f(indx)
| host1x_uclass_wait_syncpt_thresh_f(threshold);
}
static inline u32 nvhost_class_host_wait_syncpt_base(
unsigned indx, unsigned base_indx, unsigned offset)
{
return host1x_uclass_wait_syncpt_base_indx_f(indx)
| host1x_uclass_wait_syncpt_base_base_indx_f(base_indx)
| host1x_uclass_wait_syncpt_base_offset_f(offset);
}
static inline u32 nvhost_class_host_incr_syncpt_base(
unsigned base_indx, unsigned offset)
{
return host1x_uclass_incr_syncpt_base_base_indx_f(base_indx)
| host1x_uclass_incr_syncpt_base_offset_f(offset);
}
static inline u32 nvhost_class_host_incr_syncpt(
unsigned cond, unsigned indx)
{
return host1x_uclass_incr_syncpt_cond_f(cond)
| host1x_uclass_incr_syncpt_indx_f(indx);
}
enum {
NV_HOST_MODULE_HOST1X = 0,
NV_HOST_MODULE_MPE = 1,
NV_HOST_MODULE_GR3D = 6
};
static inline u32 nvhost_class_host_indoff_reg_write(
unsigned mod_id, unsigned offset, bool auto_inc)
{
u32 v = host1x_uclass_indoff_indbe_f(0xf)
| host1x_uclass_indoff_indmodid_f(mod_id)
| host1x_uclass_indoff_indroffset_f(offset);
if (auto_inc)
v |= host1x_uclass_indoff_autoinc_f(1);
return v;
}
static inline u32 nvhost_class_host_indoff_reg_read(
unsigned mod_id, unsigned offset, bool auto_inc)
{
u32 v = host1x_uclass_indoff_indmodid_f(mod_id)
| host1x_uclass_indoff_indroffset_f(offset)
| host1x_uclass_indoff_rwn_read_v();
if (auto_inc)
v |= host1x_uclass_indoff_autoinc_f(1);
return v;
}
/* cdma opcodes */
static inline u32 nvhost_opcode_setclass(
unsigned class_id, unsigned offset, unsigned mask)
{
return (0 << 28) | (offset << 16) | (class_id << 6) | mask;
}
static inline u32 nvhost_opcode_incr(unsigned offset, unsigned count)
{
return (1 << 28) | (offset << 16) | count;
}
static inline u32 nvhost_opcode_nonincr(unsigned offset, unsigned count)
{
return (2 << 28) | (offset << 16) | count;
}
static inline u32 nvhost_opcode_mask(unsigned offset, unsigned mask)
{
return (3 << 28) | (offset << 16) | mask;
}
static inline u32 nvhost_opcode_imm(unsigned offset, unsigned value)
{
return (4 << 28) | (offset << 16) | value;
}
static inline u32 nvhost_opcode_imm_incr_syncpt(unsigned cond, unsigned indx)
{
return nvhost_opcode_imm(host1x_uclass_incr_syncpt_r(),
nvhost_class_host_incr_syncpt(cond, indx));
}
static inline u32 nvhost_opcode_restart(unsigned address)
{
return (5 << 28) | (address >> 4);
}
static inline u32 nvhost_opcode_gather(unsigned count)
{
return (6 << 28) | count;
}
static inline u32 nvhost_opcode_gather_nonincr(unsigned offset, unsigned count)
{
return (6 << 28) | (offset << 16) | BIT(15) | count;
}
static inline u32 nvhost_opcode_gather_incr(unsigned offset, unsigned count)
{
return (6 << 28) | (offset << 16) | BIT(15) | BIT(14) | count;
}
static inline u32 nvhost_opcode_gather_insert(unsigned offset, unsigned incr,
unsigned count)
{
return (6 << 28) | (offset << 16) | BIT(15) | (incr << 14) | count;
}
#define NVHOST_OPCODE_NOOP nvhost_opcode_nonincr(0, 0)
static inline u32 nvhost_mask2(unsigned x, unsigned y)
{
return 1 | (1 << (y - x));
}
#endif /* __NVHOST_HARDWARE_T124_H */

View File

@@ -0,0 +1,61 @@
/*
* drivers/video/tegra/host/t124/syncpt_t124.h
*
* Tegra Graphics Host Syncpoints for T124
*
* Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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 __NVHOST_SYNCPT_T124_H
#define __NVHOST_SYNCPT_T124_H
#include <linux/nvhost.h>
#define NVSYNCPT_GK20A_BASE 64
/* following is base + number of gk20a channels. TODO: remove magic */
#define NVSYNCPT_GK20A_LAST (NVSYNCPT_GK20A_BASE + 127)
#define NV_VI_0_SYNCPTS { \
NVSYNCPT_VI_0_0, \
NVSYNCPT_VI_0_1, \
NVSYNCPT_VI_0_2, \
NVSYNCPT_VI_0_3, \
NVSYNCPT_VI_0_4}
#define NV_VI_1_SYNCPTS { \
NVSYNCPT_VI_1_0, \
NVSYNCPT_VI_1_1, \
NVSYNCPT_VI_1_2, \
NVSYNCPT_VI_1_3, \
NVSYNCPT_VI_1_4}
#define NV_ISP_0_SYNCPTS {\
NVSYNCPT_ISP_0_0, \
NVSYNCPT_ISP_0_1, \
NVSYNCPT_ISP_0_2, \
NVSYNCPT_ISP_0_3}
#define NV_ISP_1_SYNCPTS {\
NVSYNCPT_ISP_1_0, \
NVSYNCPT_ISP_1_1, \
NVSYNCPT_ISP_1_2, \
NVSYNCPT_ISP_1_3}
#define NVWAITBASE_3D (3)
#define NVWAITBASE_MSENC (4)
#define NVWAITBASE_TSEC (5)
#endif /* __NVHOST_SYNCPT_T124_H */

View File

@@ -0,0 +1,520 @@
/*
* drivers/video/tegra/host/t124/t124.c
*
* Tegra Graphics Init for T124 Architecture Chips
*
* Copyright (c) 2011-2013, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
*/
#include <linux/slab.h>
#include <linux/tegra-powergate.h>
#include <linux/platform_data/tegra_mc.h>
#include "dev.h"
#include "nvhost_job.h"
#include "class_ids.h"
#include "t124.h"
#include "host1x/host1x.h"
#include "hardware_t124.h"
#include "syncpt_t124.h"
#include "gk20a/gk20a.h"
#include "gk20a/gk20a_scale.h"
#include "vic03/vic03.h"
#include "msenc/msenc.h"
#include "tsec/tsec.h"
#include "isp/isp.h"
#include "gr3d/pod_scaling.h"
#include "gr3d/scale3d.h"
#include "nvhost_memmgr.h"
#include "chip_support.h"
#include "nvhost_scale.h"
static int t124_num_alloc_channels;
#define HOST_EMC_FLOOR 300000000
#define VI_CLOCKGATE_DELAY 60
#define VI_POWERGATE_DELAY 500
#define ISP_CLOCKGATE_DELAY 60
#define ISP_POWERGATE_DELAY 500
#define TSEC_POWERGATE_DELAY 500
#define GK20A_DEV_NAME_SIZE 5
#define BIT64(nr) (1ULL << (nr))
#define NVSYNCPTS_CLIENT_MANAGED_T124 ( \
BIT64(NVSYNCPT_DISP0_A) | BIT64(NVSYNCPT_DISP1_A) | \
BIT64(NVSYNCPT_DISP0_B) | BIT64(NVSYNCPT_DISP1_B) | \
BIT64(NVSYNCPT_DISP0_C) | BIT64(NVSYNCPT_DISP1_C) | \
BIT(NVSYNCPT_DISP0_D) | \
BIT(NVSYNCPT_DISP0_H) | BIT(NVSYNCPT_DISP1_H) | \
BIT64(NVSYNCPT_DSI) | \
BIT64(NVSYNCPT_VBLANK0) | BIT64(NVSYNCPT_VBLANK1) | \
BIT64(NVSYNCPT_AVP_0))
/* Host1x driver matches module IDs while setting a
* particular clock, This ID is used for EMC module.
*/
#define TEGRA_HOST1X_EMC_MODULE_ID 75
static const char *s_syncpt_names[NV_HOST1X_SYNCPT_NB_PTS] = {
[NVSYNCPT_ISP_0_0] = "ispa_memory",
[NVSYNCPT_ISP_0_1] = "ispa_stats",
[NVSYNCPT_ISP_0_2] = "ispa_stream",
[NVSYNCPT_ISP_0_3] = "ispa_loadv",
[NVSYNCPT_ISP_1_0] = "ispb_memory",
[NVSYNCPT_ISP_1_1] = "ispb_stats",
[NVSYNCPT_ISP_1_2] = "ispb_stream",
[NVSYNCPT_ISP_1_3] = "ispb_loadv",
[NVSYNCPT_VI_0_0] = "vi0_ispa",
[NVSYNCPT_VI_0_1] = "vi0_ispb",
[NVSYNCPT_VI_0_2] = "vi0_stream",
[NVSYNCPT_VI_0_3] = "vi0_memory",
[NVSYNCPT_VI_0_4] = "vi0_flash",
[NVSYNCPT_VI_1_0] = "vi1_ispa",
[NVSYNCPT_VI_1_1] = "vi1_ispb",
[NVSYNCPT_VI_1_2] = "vi1_stream",
[NVSYNCPT_VI_1_3] = "vi1_memory",
[NVSYNCPT_VI_1_4] = "vi1_flash",
[NVSYNCPT_3D] = "3d",
[NVSYNCPT_MPE] = "mpe",
[NVSYNCPT_MPE_EBM_EOF] = "mpe_ebm_eof",
[NVSYNCPT_MPE_WR_SAFE] = "mpe_wr_safe",
[NVSYNCPT_VIC] = "vic",
[NVSYNCPT_TSEC] = "tsec",
[NVSYNCPT_DISP0_A] = "disp0",
[NVSYNCPT_DISP1_A] = "disp1",
[NVSYNCPT_AVP_0] = "avp",
[NVSYNCPT_DISP0_B] = "disp0b",
[NVSYNCPT_DISP1_B] = "disp1b",
[NVSYNCPT_DISP0_C] = "disp0c",
[NVSYNCPT_DISP1_C] = "disp1c",
[NVSYNCPT_DISP0_D] = "disp0d",
[NVSYNCPT_DISP0_H] = "disp0h",
[NVSYNCPT_DISP1_H] = "disp1h",
[NVSYNCPT_VBLANK0] = "vblank0",
[NVSYNCPT_VBLANK1] = "vblank1",
[NVSYNCPT_DSI] = "dsi",
};
static struct host1x_device_info host1x04_info = {
.nb_channels = T124_NVHOST_NUMCHANNELS,
.nb_pts = NV_HOST1X_SYNCPT_NB_PTS,
.nb_mlocks = NV_HOST1X_NB_MLOCKS,
.nb_bases = NV_HOST1X_SYNCPT_NB_BASES,
.syncpt_names = s_syncpt_names,
.client_managed = NVSYNCPTS_CLIENT_MANAGED_T124,
};
struct nvhost_device_data t124_host1x_info = {
.clocks = {{"host1x", 81600000}, {"actmon", UINT_MAX} },
NVHOST_MODULE_NO_POWERGATE_IDS,
.private_data = &host1x04_info,
.finalize_poweron = nvhost_host1x_finalize_poweron,
.prepare_poweroff = nvhost_host1x_prepare_poweroff,
};
struct nvhost_device_data t124_isp_info = {
/* FIXME: control clocks from user space instead of hard-coding here */
.syncpts = NV_ISP_0_SYNCPTS,
.moduleid = NVHOST_MODULE_ISP,
.modulemutexes = {NVMODMUTEX_ISP_0},
.exclusive = true,
.keepalive = true,
.powergate_ids = {TEGRA_POWERGATE_VENC, -1},
.can_powergate = true,
.clockgate_delay = ISP_CLOCKGATE_DELAY,
.powergate_delay = ISP_POWERGATE_DELAY,
.clocks = {
{"isp", UINT_MAX, 0, TEGRA_MC_CLIENT_ISP},
{"emc", 0, TEGRA_HOST1X_EMC_MODULE_ID} },
.finalize_poweron = nvhost_isp_t124_finalize_poweron,
};
struct nvhost_device_data t124_ispb_info = {
/* FIXME: control clocks from user space instead of hard-coding here */
.syncpts = NV_ISP_1_SYNCPTS,
.moduleid = (1 << 16) | NVHOST_MODULE_ISP,
.modulemutexes = {NVMODMUTEX_ISP_1},
.exclusive = true,
.keepalive = true,
.powergate_ids = {TEGRA_POWERGATE_VENC, -1},
.can_powergate = true,
.clockgate_delay = ISP_CLOCKGATE_DELAY,
.powergate_delay = ISP_POWERGATE_DELAY,
.clocks = {
{"isp", UINT_MAX, 0, TEGRA_MC_CLIENT_ISPB},
{"emc", 0, TEGRA_HOST1X_EMC_MODULE_ID} },
.finalize_poweron = nvhost_isp_t124_finalize_poweron,
};
struct nvhost_device_data t124_msenc_info = {
.version = NVHOST_ENCODE_MSENC_VER(3, 1),
.syncpts = {NVSYNCPT_MSENC, NVSYNCPT_MSENC_SLICE},
.waitbases = {NVWAITBASE_MSENC},
.class = NV_VIDEO_ENCODE_MSENC_CLASS_ID,
.clocks = {{"cbus", UINT_MAX, 0, TEGRA_MC_CLIENT_MSENC},
{"emc", HOST_EMC_FLOOR} },
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.moduleid = NVHOST_MODULE_MSENC,
.powergate_ids = { TEGRA_POWERGATE_MPE, -1 },
.powergate_delay = 100,
.can_powergate = true,
.init = nvhost_msenc_init,
.deinit = nvhost_msenc_deinit,
.finalize_poweron = nvhost_msenc_finalize_poweron,
.scaling_init = nvhost_scale_init,
.scaling_deinit = nvhost_scale_deinit,
.actmon_regs = HOST1X_CHANNEL_ACTMON1_REG_BASE,
.actmon_enabled = true,
};
struct nvhost_device_data t124_tsec_info = {
.version = NVHOST_ENCODE_TSEC_VER(1, 0),
.syncpts = {NVSYNCPT_TSEC},
.waitbases = {NVWAITBASE_TSEC},
.class = NV_TSEC_CLASS_ID,
.exclusive = true,
.clocks = {{"tsec", UINT_MAX, 0, TEGRA_MC_CLIENT_TSEC},
{"emc", HOST_EMC_FLOOR} },
NVHOST_MODULE_NO_POWERGATE_IDS,
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.can_powergate = true,
.powergate_delay = TSEC_POWERGATE_DELAY,
.keepalive = true,
.moduleid = NVHOST_MODULE_TSEC,
.init = nvhost_tsec_init,
.deinit = nvhost_tsec_deinit,
.finalize_poweron = nvhost_tsec_finalize_poweron,
.prepare_poweroff = nvhost_tsec_prepare_poweroff,
};
#ifdef CONFIG_ARCH_TEGRA_VIC
struct nvhost_device_data t124_vic_info = {
.syncpts = {NVSYNCPT_VIC},
.modulemutexes = {NVMODMUTEX_VIC},
.clocks = {{"cbus", UINT_MAX, 0, TEGRA_MC_CLIENT_VIC},
{"emc", UINT_MAX} },
.version = NVHOST_ENCODE_VIC_VER(3, 0),
NVHOST_MODULE_NO_POWERGATE_IDS,
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.moduleid = NVHOST_MODULE_VIC,
.alloc_hwctx_handler = nvhost_vic03_alloc_hwctx_handler,
.can_powergate = true,
.powergate_delay = 500,
.powergate_ids = { TEGRA_POWERGATE_VIC, -1 },
.init = nvhost_vic03_init,
.deinit = nvhost_vic03_deinit,
.alloc_hwctx_handler = nvhost_vic03_alloc_hwctx_handler,
.finalize_poweron = nvhost_vic03_finalize_poweron,
.prepare_poweroff = nvhost_vic03_prepare_poweroff,
.scaling_init = nvhost_scale3d_init,
.scaling_deinit = nvhost_scale3d_deinit,
.busy = nvhost_scale_notify_busy,
.idle = nvhost_scale_notify_idle,
.suspend_ndev = nvhost_scale3d_suspend,
.scaling_post_cb = &nvhost_scale3d_callback,
.devfreq_governor = "nvhost_podgov",
.actmon_regs = HOST1X_CHANNEL_ACTMON2_REG_BASE,
.actmon_enabled = true,
.linear_emc = true,
};
#endif
#if defined(CONFIG_TEGRA_GK20A)
struct nvhost_device_data tegra_gk20a_info = {
.syncpts = {NVSYNCPT_GK20A_BASE},
.syncpt_base = NVSYNCPT_GK20A_BASE,
.class = NV_GRAPHICS_GPU_CLASS_ID,
.clocks = {{"gpu", UINT_MAX},
{"pwr", 204000000},
{"emc", UINT_MAX},
{} },
.powergate_ids = { TEGRA_POWERGATE_3D, -1 },
NVHOST_DEFAULT_CLOCKGATE_DELAY,
.powergate_delay = 500,
.can_powergate = true,
.alloc_hwctx_handler = nvhost_gk20a_alloc_hwctx_handler,
.ctrl_ops = &tegra_gk20a_ctrl_ops,
#ifdef CONFIG_TEGRA_GK20A_DEBUG_SESSION
.dbg_ops = &tegra_gk20a_dbg_gpu_ops,
.prof_ops = &tegra_gk20a_prof_gpu_ops,
#endif
.as_ops = &tegra_gk20a_as_ops,
.moduleid = NVHOST_MODULE_GPU,
.init = nvhost_gk20a_init,
.deinit = nvhost_gk20a_deinit,
.alloc_hwctx_handler = nvhost_gk20a_alloc_hwctx_handler,
.prepare_poweroff = nvhost_gk20a_prepare_poweroff,
.finalize_poweron = nvhost_gk20a_finalize_poweron,
#ifdef CONFIG_TEGRA_GK20A_DEVFREQ
.busy = nvhost_gk20a_scale_notify_busy,
.idle = nvhost_gk20a_scale_notify_idle,
.scaling_init = nvhost_gk20a_scale_init,
.scaling_deinit = nvhost_gk20a_scale_deinit,
.suspend_ndev = nvhost_scale3d_suspend,
.devfreq_governor = "nvhost_podgov",
.scaling_post_cb = nvhost_gk20a_scale_callback,
#endif
};
#endif
#include "host1x/host1x_channel.c"
#if defined(CONFIG_TEGRA_GK20A)
static int t124_channel_alloc_obj(struct nvhost_hwctx *hwctx,
struct nvhost_alloc_obj_ctx_args *args)
{
nvhost_dbg_fn("");
return gk20a_alloc_obj_ctx(hwctx->priv, args);
}
static int t124_channel_free_obj(struct nvhost_hwctx *hwctx,
struct nvhost_free_obj_ctx_args *args)
{
nvhost_dbg_fn("");
return gk20a_free_obj_ctx(hwctx->priv, args);
}
static int t124_channel_alloc_gpfifo(struct nvhost_hwctx *hwctx,
struct nvhost_alloc_gpfifo_args *args)
{
nvhost_dbg_fn("");
return gk20a_alloc_channel_gpfifo(hwctx->priv, args);
}
static int t124_channel_set_error_notifier(struct nvhost_hwctx *hwctx,
struct nvhost_set_error_notifier *args) {
return gk20a_init_error_notifier(hwctx, args->mem, args->offset);
}
static int t124_channel_submit_gpfifo(struct nvhost_hwctx *hwctx,
struct nvhost_gpfifo *gpfifo, u32 num_entries,
struct nvhost_fence *fence, u32 flags)
{
struct channel_gk20a *ch = hwctx->priv;
struct nvhost_channel *nvhost_ch = hwctx->channel;
void *completed_waiter = NULL;
int err, ret;
nvhost_dbg_fn("");
if (hwctx->has_timedout || !ch)
return -ETIMEDOUT;
completed_waiter = nvhost_intr_alloc_waiter();
if (!completed_waiter)
return -ENOMEM;
nvhost_module_busy(nvhost_ch->dev);
ret = gk20a_submit_channel_gpfifo(hwctx->priv, gpfifo, num_entries,
fence, flags);
if (!ret) {
err = nvhost_intr_add_action(
&nvhost_get_host(nvhost_ch->dev)->intr,
fence->syncpt_id, fence->value,
NVHOST_INTR_ACTION_GPFIFO_SUBMIT_COMPLETE,
ch,
completed_waiter,
NULL);
WARN(err, "Failed to set submit complete interrupt");
} else {
pr_err("submit error %d\n", ret);
kfree(completed_waiter);
}
return ret;
}
static int t124_channel_wait(struct nvhost_hwctx *hwctx,
struct nvhost_wait_args *args)
{
nvhost_dbg_fn("");
return gk20a_channel_wait(hwctx->priv, args);
}
static int t124_channel_set_priority(struct nvhost_hwctx *hwctx,
struct nvhost_set_priority_args *args)
{
nvhost_dbg_fn("");
return gk20a_channel_set_priority(hwctx->priv, args->priority);
}
#if defined(CONFIG_TEGRA_GPU_CYCLE_STATS)
static int t124_channel_cycle_stats(struct nvhost_hwctx *hwctx,
struct nvhost_cycle_stats_args *args)
{
nvhost_dbg_fn("");
return gk20a_channel_cycle_stats(hwctx->priv, args);
}
#endif
static int t124_channel_zcull_bind(struct nvhost_hwctx *hwctx,
struct nvhost_zcull_bind_args *args)
{
nvhost_dbg_fn("");
return gk20a_channel_zcull_bind(hwctx->priv, args);
}
#endif /* CONFIG_TEGRA_GK20A */
static void t124_free_nvhost_channel(struct nvhost_channel *ch)
{
nvhost_dbg_fn("");
nvhost_free_channel_internal(ch, &t124_num_alloc_channels);
}
static struct nvhost_channel *t124_alloc_nvhost_channel(
struct platform_device *dev)
{
struct nvhost_device_data *pdata = nvhost_get_devdata(dev);
struct nvhost_channel *ch;
nvhost_dbg_fn("");
ch = nvhost_alloc_channel_internal(pdata->index,
nvhost_get_host(dev)->info.nb_channels,
&t124_num_alloc_channels);
if (ch) {
#if defined(CONFIG_TEGRA_GK20A)
if (strstr(dev->name, "gk20a")) {
ch->ops.init = host1x_channel_ops.init;
ch->ops.alloc_obj = t124_channel_alloc_obj;
ch->ops.free_obj = t124_channel_free_obj;
ch->ops.alloc_gpfifo = t124_channel_alloc_gpfifo;
ch->ops.submit_gpfifo = t124_channel_submit_gpfifo;
ch->ops.set_priority = t124_channel_set_priority;
ch->ops.wait = t124_channel_wait;
ch->ops.set_error_notifier =
t124_channel_set_error_notifier;
#if defined(CONFIG_TEGRA_GPU_CYCLE_STATS)
ch->ops.cycle_stats = t124_channel_cycle_stats;
#endif
ch->ops.zcull.bind = t124_channel_zcull_bind;
} else
#endif
ch->ops = host1x_channel_ops;
}
return ch;
}
static struct nvhost_device_data *t124_pdatas[] = {
&t124_isp_info,
&t124_ispb_info,
&t124_msenc_info,
&t124_tsec_info,
#if defined(CONFIG_TEGRA_GK20A)
&tegra_gk20a_info,
#endif
#if defined(CONFIG_ARCH_TEGRA_VIC)
&t124_vic_info,
#endif
};
int nvhost_init_t124_channel_support(struct nvhost_master *host,
struct nvhost_chip_support *op)
{
int i, num_channels;
/* Set indices dynamically as we can have
* missing/non-static devices above (e.g.: vic, gk20a).
*/
for (num_channels = i = 0; i < ARRAY_SIZE(t124_pdatas); i++) {
struct nvhost_device_data *pdata =
(struct nvhost_device_data *)t124_pdatas[i];
pdata->index = num_channels++;
if (pdata->slave) {
struct nvhost_device_data *slave_pdata =
(struct nvhost_device_data *)
pdata->slave->dev.platform_data;
slave_pdata->index = num_channels++;
}
}
nvhost_dbg_fn("max channels=%d num channels=%zd",
NV_HOST1X_CHANNELS, num_channels);
if (num_channels > T124_NVHOST_NUMCHANNELS) {
WARN(-ENODEV, "too many channel devices");
return -ENODEV;
}
op->nvhost_dev.alloc_nvhost_channel = t124_alloc_nvhost_channel;
op->nvhost_dev.free_nvhost_channel = t124_free_nvhost_channel;
return 0;
}
static void t124_remove_support(struct nvhost_chip_support *op)
{
kfree(op->priv);
op->priv = 0;
}
#include "host1x/host1x_cdma.c"
#include "host1x/host1x_syncpt.c"
#include "host1x/host1x_intr.c"
#include "host1x/host1x_actmon_t124.c"
int nvhost_init_t124_support(struct nvhost_master *host,
struct nvhost_chip_support *op)
{
int i = 0;
int err;
struct t124 *t124 = 0;
for (i = NVSYNCPT_GK20A_BASE; i <= NVSYNCPT_GK20A_LAST; i++)
s_syncpt_names[i] = "gk20a";
/* don't worry about cleaning up on failure... "remove" does it. */
err = nvhost_init_t124_channel_support(host, op);
if (err)
return err;
op->cdma = host1x_cdma_ops;
op->push_buffer = host1x_pushbuffer_ops;
err = nvhost_init_t124_debug_support(op);
if (err)
return err;
host->sync_aperture = host->aperture + HOST1X_CHANNEL_SYNC_REG_BASE;
op->syncpt = host1x_syncpt_ops;
op->intr = host1x_intr_ops;
op->actmon = host1x_actmon_ops;
err = nvhost_memmgr_init(op);
if (err)
return err;
t124 = kzalloc(sizeof(struct t124), GFP_KERNEL);
if (!t124) {
err = -ENOMEM;
goto err;
}
t124->host = host;
op->priv = t124;
op->remove_support = t124_remove_support;
return 0;
err:
kfree(t124);
op->priv = 0;
op->remove_support = 0;
return err;
}

View File

@@ -0,0 +1,69 @@
/*
* drivers/video/tegra/host/t124/t124.h
*
* Tegra Graphics Chip support for T124
*
* Copyright (c) 2011-2013, NVIDIA Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef _NVHOST_T124_H_
#define _NVHOST_T124_H_
#include "chip_support.h"
/* HACK. Get this from auto-generated hardware def'n instead... */
#define T124_NVHOST_NUMCHANNELS 12
#define NVHOST_CHANNEL_BASE 0
struct nvhost_chip_support;
#ifdef TEGRA_12X_OR_HIGHER_CONFIG
int nvhost_init_t124_support(struct nvhost_master *,
struct nvhost_chip_support *);
#else
static inline int nvhost_init_t124_support(struct nvhost_master *host,
struct nvhost_chip_support *op)
{
return -ENODEV;
}
#endif
int nvhost_init_t124_channel_support(struct nvhost_master *,
struct nvhost_chip_support *);
int nvhost_init_t124_cdma_support(struct nvhost_chip_support *);
int nvhost_init_t124_debug_support(struct nvhost_chip_support *);
int nvhost_init_t124_syncpt_support(struct nvhost_master *,
struct nvhost_chip_support *);
int nvhost_init_t124_intr_support(struct nvhost_chip_support *);
int nvhost_init_t124_cpuaccess_support(struct nvhost_master *,
struct nvhost_chip_support *);
int nvhost_init_t124_as_support(struct nvhost_chip_support *);
/* these sort of stick out, per module support */
int t124_nvhost_hwctx_handler_init(struct nvhost_channel *ch);
struct gk20a;
struct t124 {
struct nvhost_master *host;
struct gk20a *gk20a;
};
extern struct nvhost_device_data t124_host1x_info;
extern struct nvhost_device_data t124_isp_info;
extern struct nvhost_device_data t124_ispb_info;
extern struct nvhost_device_data t124_msenc_info;
extern struct nvhost_device_data t124_tsec_info;
extern struct nvhost_device_data t124_vic_info;
#endif /* _NVHOST_T124_H_ */