247 lines
7.2 KiB
C
247 lines
7.2 KiB
C
/*
|
|
* drivers/video/tegra/host/t114/t114.c
|
|
*
|
|
* Tegra Graphics Init for Tegra11 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/export.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/nvhost_ioctl.h>
|
|
#include <linux/tegra-powergate.h>
|
|
#include <linux/platform_data/tegra_mc.h>
|
|
|
|
#include "class_ids.h"
|
|
#include "t114.h"
|
|
#include "gr2d/gr2d_t114.h"
|
|
#include "gr3d/gr3d_t114.h"
|
|
#include "gr3d/gr3d.h"
|
|
#include "gr3d/scale3d.h"
|
|
#include "nvhost_scale.h"
|
|
#include "gr3d/scale3d.h"
|
|
#include "host1x/host1x02_hardware.h"
|
|
#include "msenc/msenc.h"
|
|
#include "tsec/tsec.h"
|
|
#include "host1x/host1x.h"
|
|
#include "chip_support.h"
|
|
#include "nvhost_channel.h"
|
|
#include "nvhost_memmgr.h"
|
|
#include "chip_support.h"
|
|
#include "gr3d/pod_scaling.h"
|
|
#include "class_ids.h"
|
|
|
|
#define TSEC_POWERGATE_DELAY 500
|
|
|
|
static int t114_num_alloc_channels;
|
|
|
|
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",
|
|
"msenc",
|
|
"disp0_c", "disp1_c",
|
|
"vblank0", "vblank1",
|
|
"tsec", "msenc_unused",
|
|
"2d_tinyblt",
|
|
"dsi"
|
|
};
|
|
|
|
static struct host1x_device_info host1x02_info = {
|
|
.nb_channels = 9,
|
|
.nb_pts = 32,
|
|
.nb_mlocks = 16,
|
|
.nb_bases = 12,
|
|
.syncpt_names = s_syncpt_names,
|
|
.client_managed = NVSYNCPTS_CLIENT_MANAGED,
|
|
};
|
|
|
|
struct nvhost_device_data t11_host1x_info = {
|
|
.clocks = { {"host1x", 136000000} },
|
|
NVHOST_MODULE_NO_POWERGATE_IDS,
|
|
.private_data = &host1x02_info,
|
|
.prepare_poweroff = nvhost_host1x_prepare_poweroff,
|
|
.finalize_poweron = nvhost_host1x_finalize_poweron,
|
|
};
|
|
|
|
struct nvhost_device_data t11_gr3d_info = {
|
|
.version = 3,
|
|
.index = 1,
|
|
.syncpts = {NVSYNCPT_3D},
|
|
.waitbases = {NVWAITBASE_3D},
|
|
.modulemutexes = {NVMODMUTEX_3D},
|
|
.class = NV_GRAPHICS_3D_CLASS_ID,
|
|
.clocks = { {"gr3d", UINT_MAX, 8, TEGRA_MC_CLIENT_NV},
|
|
{"emc", UINT_MAX, 75} },
|
|
.powergate_ids = { TEGRA_POWERGATE_3D, -1 },
|
|
NVHOST_DEFAULT_CLOCKGATE_DELAY,
|
|
.can_powergate = true,
|
|
.powergate_delay = 250,
|
|
.powerup_reset = true,
|
|
.moduleid = NVHOST_MODULE_NONE,
|
|
|
|
.busy = nvhost_scale_notify_busy,
|
|
.idle = nvhost_scale_notify_idle,
|
|
.init = nvhost_scale_hw_init,
|
|
.deinit = nvhost_scale_hw_deinit,
|
|
.scaling_init = nvhost_scale3d_init,
|
|
.scaling_deinit = nvhost_scale3d_deinit,
|
|
.scaling_post_cb = &nvhost_scale3d_callback,
|
|
.devfreq_governor = "nvhost_podgov",
|
|
.actmon_enabled = true,
|
|
|
|
.suspend_ndev = nvhost_scale3d_suspend,
|
|
.prepare_poweroff = nvhost_gr3d_t114_prepare_power_off,
|
|
.finalize_poweron = nvhost_gr3d_t114_finalize_power_on,
|
|
.alloc_hwctx_handler = nvhost_gr3d_t114_ctxhandler_init,
|
|
};
|
|
|
|
struct nvhost_device_data t11_gr2d_info = {
|
|
.version = 2,
|
|
.index = 2,
|
|
.syncpts = {NVSYNCPT_2D_0, NVSYNCPT_2D_1},
|
|
.waitbases = {NVWAITBASE_2D_0, NVWAITBASE_2D_1},
|
|
.modulemutexes = {NVMODMUTEX_2D_FULL, NVMODMUTEX_2D_SIMPLE,
|
|
NVMODMUTEX_2D_SB_A, NVMODMUTEX_2D_SB_B},
|
|
.clocks = { {"gr2d", 0, 7, TEGRA_MC_CLIENT_G2},
|
|
{"epp", 0, 10, TEGRA_MC_CLIENT_EPP},
|
|
{"emc", 300000000, 75 } },
|
|
.powergate_ids = { TEGRA_POWERGATE_HEG, -1 },
|
|
.clockgate_delay = 0,
|
|
.can_powergate = true,
|
|
.powergate_delay = 100,
|
|
.moduleid = NVHOST_MODULE_NONE,
|
|
.serialize = true,
|
|
.finalize_poweron = nvhost_gr2d_t114_finalize_poweron,
|
|
};
|
|
|
|
struct nvhost_device_data t11_isp_info = {
|
|
.index = 3,
|
|
.syncpts = {NVSYNCPT_VI_ISP_2, NVSYNCPT_VI_ISP_3,
|
|
NVSYNCPT_VI_ISP_4},
|
|
.keepalive = true,
|
|
NVHOST_MODULE_NO_POWERGATE_IDS,
|
|
NVHOST_DEFAULT_CLOCKGATE_DELAY,
|
|
.moduleid = NVHOST_MODULE_ISP,
|
|
};
|
|
|
|
struct nvhost_device_data t11_vi_info = {
|
|
.index = 4,
|
|
.syncpts = {NVSYNCPT_CSI_VI_0, NVSYNCPT_CSI_VI_1,
|
|
NVSYNCPT_VI_ISP_0, NVSYNCPT_VI_ISP_1,
|
|
NVSYNCPT_VI_ISP_2, NVSYNCPT_VI_ISP_3,
|
|
NVSYNCPT_VI_ISP_4},
|
|
.modulemutexes = {NVMODMUTEX_VI},
|
|
.clocks = { {"host1x", 136000000, 6} },
|
|
.exclusive = true,
|
|
NVHOST_MODULE_NO_POWERGATE_IDS,
|
|
NVHOST_DEFAULT_CLOCKGATE_DELAY,
|
|
.moduleid = NVHOST_MODULE_VI,
|
|
.update_clk = nvhost_host1x_update_clk,
|
|
};
|
|
EXPORT_SYMBOL(t11_vi_info);
|
|
|
|
struct nvhost_device_data t11_msenc_info = {
|
|
.version = NVHOST_ENCODE_MSENC_VER(2, 0),
|
|
.index = 5,
|
|
.syncpts = {NVSYNCPT_MSENC},
|
|
.waitbases = {NVWAITBASE_MSENC},
|
|
.class = NV_VIDEO_ENCODE_MSENC_CLASS_ID,
|
|
.clocks = { {"msenc", UINT_MAX, 107, TEGRA_MC_CLIENT_MSENC},
|
|
{"emc", 300000000, 75} },
|
|
.powergate_ids = { TEGRA_POWERGATE_MPE, -1 },
|
|
NVHOST_DEFAULT_CLOCKGATE_DELAY,
|
|
.powergate_delay = 100,
|
|
.can_powergate = true,
|
|
.moduleid = NVHOST_MODULE_MSENC,
|
|
.init = nvhost_msenc_init,
|
|
.deinit = nvhost_msenc_deinit,
|
|
.finalize_poweron = nvhost_msenc_finalize_poweron,
|
|
};
|
|
|
|
struct nvhost_device_data t11_tsec_info = {
|
|
.version = NVHOST_ENCODE_TSEC_VER(1, 0),
|
|
.index = 7,
|
|
.syncpts = {NVSYNCPT_TSEC},
|
|
.waitbases = {NVWAITBASE_TSEC},
|
|
.class = NV_TSEC_CLASS_ID,
|
|
.exclusive = false,
|
|
.clocks = { {"tsec", UINT_MAX, 108, TEGRA_MC_CLIENT_TSEC},
|
|
{"emc", 300000000, 75} },
|
|
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,
|
|
};
|
|
|
|
#include "host1x/host1x_channel.c"
|
|
#include "host1x/host1x_cdma.c"
|
|
#include "host1x/host1x_debug.c"
|
|
#include "host1x/host1x_syncpt.c"
|
|
#include "host1x/host1x_intr.c"
|
|
#include "host1x/host1x_actmon_t114.c"
|
|
#include "host1x/host1x_tickctrl.c"
|
|
|
|
static void t114_free_nvhost_channel(struct nvhost_channel *ch)
|
|
{
|
|
nvhost_free_channel_internal(ch, &t114_num_alloc_channels);
|
|
}
|
|
|
|
static struct nvhost_channel *t114_alloc_nvhost_channel(
|
|
struct platform_device *dev)
|
|
{
|
|
struct nvhost_device_data *pdata = platform_get_drvdata(dev);
|
|
struct nvhost_channel *ch = nvhost_alloc_channel_internal(pdata->index,
|
|
nvhost_get_host(dev)->info.nb_channels,
|
|
&t114_num_alloc_channels);
|
|
if (ch)
|
|
ch->ops = host1x_channel_ops;
|
|
return ch;
|
|
}
|
|
|
|
int nvhost_init_t114_support(struct nvhost_master *host,
|
|
struct nvhost_chip_support *op)
|
|
{
|
|
int err;
|
|
|
|
op->cdma = host1x_cdma_ops;
|
|
op->push_buffer = host1x_pushbuffer_ops;
|
|
op->debug = host1x_debug_ops;
|
|
host->sync_aperture = host->aperture + HOST1X_CHANNEL_SYNC_REG_BASE;
|
|
op->syncpt = host1x_syncpt_ops;
|
|
op->intr = host1x_intr_ops;
|
|
err = nvhost_memmgr_init(op);
|
|
if (err)
|
|
return err;
|
|
op->nvhost_dev.alloc_nvhost_channel = t114_alloc_nvhost_channel;
|
|
op->nvhost_dev.free_nvhost_channel = t114_free_nvhost_channel;
|
|
op->actmon = host1x_actmon_ops;
|
|
op->tickctrl = host1x_tickctrl_ops;
|
|
|
|
return 0;
|
|
}
|