/* * drivers/video/tegra/host/t30/t30.c * * Tegra Graphics Init for T30 Architecture Chips * * 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 . */ #include #include #include #include "t20/t20.h" #include "t30.h" #include "gr3d/gr3d_t30.h" #include "gr3d/scale3d.h" #include "mpe/mpe.h" #include "host1x/host1x.h" #include "host1x/host1x01_hardware.h" #include "chip_support.h" #include "nvhost_channel.h" #include "nvhost_memmgr.h" #include "host1x/host1x_syncpt.h" #define NVMODMUTEX_2D_FULL (1) #define NVMODMUTEX_2D_SIMPLE (2) #define NVMODMUTEX_2D_SB_A (3) #define NVMODMUTEX_2D_SB_B (4) #define NVMODMUTEX_3D (5) #define NVMODMUTEX_DISPLAYA (6) #define NVMODMUTEX_DISPLAYB (7) #define NVMODMUTEX_VI (8) #define NVMODMUTEX_DSI (9) static int t30_num_alloc_channels = 0; static struct resource tegra_host1x01_resources[] = { { .start = TEGRA_HOST1X_BASE, .end = TEGRA_HOST1X_BASE + TEGRA_HOST1X_SIZE - 1, .flags = IORESOURCE_MEM, }, { .start = INT_SYNCPT_THRESH_BASE, .end = INT_SYNCPT_THRESH_BASE + INT_SYNCPT_THRESH_NR - 1, .flags = IORESOURCE_IRQ, }, { .start = INT_HOST1X_MPCORE_GENERAL, .end = INT_HOST1X_MPCORE_GENERAL, .flags = IORESOURCE_IRQ, }, }; 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 struct host1x_device_info host1x01_info = { .nb_channels = 8, .nb_pts = 32, .nb_mlocks = 16, .nb_bases = 8, .syncpt_names = s_syncpt_names, .client_managed = NVSYNCPTS_CLIENT_MANAGED, }; static struct nvhost_device tegra_host1x01_device = { .dev = {.platform_data = &host1x01_info}, .name = "host1x", .id = -1, .resource = tegra_host1x01_resources, .num_resources = ARRAY_SIZE(tegra_host1x01_resources), .clocks = {{"host1x", UINT_MAX}, {} }, NVHOST_MODULE_NO_POWERGATE_IDS, }; static struct nvhost_device tegra_display01_device = { .name = "display", .id = -1, .index = 0, .syncpts = BIT(NVSYNCPT_DISP0_A) | BIT(NVSYNCPT_DISP1_A) | BIT(NVSYNCPT_DISP0_B) | BIT(NVSYNCPT_DISP1_B) | BIT(NVSYNCPT_DISP0_C) | BIT(NVSYNCPT_DISP1_C) | BIT(NVSYNCPT_VBLANK0) | BIT(NVSYNCPT_VBLANK1), .modulemutexes = BIT(NVMODMUTEX_DISPLAYA) | BIT(NVMODMUTEX_DISPLAYB), NVHOST_MODULE_NO_POWERGATE_IDS, NVHOST_DEFAULT_CLOCKGATE_DELAY, .moduleid = NVHOST_MODULE_NONE, }; static struct nvhost_device tegra_gr3d02_device = { .name = "gr3d", .version = 2, .id = -1, .index = 1, .syncpts = BIT(NVSYNCPT_3D), .waitbases = BIT(NVWAITBASE_3D), .modulemutexes = BIT(NVMODMUTEX_3D), .class = NV_GRAPHICS_3D_CLASS_ID, .clocks = { {"gr3d", UINT_MAX}, {"gr3d2", UINT_MAX}, {"emc", UINT_MAX} }, .powergate_ids = { TEGRA_POWERGATE_3D, TEGRA_POWERGATE_3D1 }, NVHOST_DEFAULT_CLOCKGATE_DELAY, .can_powergate = true, .powerup_reset = true, .powergate_delay = 250, .moduleid = NVHOST_MODULE_NONE, }; static struct nvhost_device tegra_gr2d02_device = { .name = "gr2d", .id = -1, .index = 2, .syncpts = BIT(NVSYNCPT_2D_0) | BIT(NVSYNCPT_2D_1), .waitbases = BIT(NVWAITBASE_2D_0) | BIT(NVWAITBASE_2D_1), .modulemutexes = BIT(NVMODMUTEX_2D_FULL) | BIT(NVMODMUTEX_2D_SIMPLE) | BIT(NVMODMUTEX_2D_SB_A) | BIT(NVMODMUTEX_2D_SB_B), .clocks = { {"gr2d", 0}, {"epp", 0}, {"emc", 300000000} }, NVHOST_MODULE_NO_POWERGATE_IDS, .clockgate_delay = 0, .moduleid = NVHOST_MODULE_NONE, .serialize = true, }; static struct resource isp_resources_t20[] = { { .name = "regs", .start = TEGRA_ISP_BASE, .end = TEGRA_ISP_BASE + TEGRA_ISP_SIZE - 1, .flags = IORESOURCE_MEM, } }; static struct nvhost_device tegra_isp01_device = { .name = "isp", .id = -1, .resource = isp_resources_t20, .num_resources = ARRAY_SIZE(isp_resources_t20), .index = 3, .syncpts = BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) | BIT(NVSYNCPT_VI_ISP_4), .clocks = { {"epp", 0} }, .keepalive = true, NVHOST_MODULE_NO_POWERGATE_IDS, NVHOST_DEFAULT_CLOCKGATE_DELAY, .moduleid = NVHOST_MODULE_ISP, }; static struct resource vi_resources[] = { { .name = "regs", .start = TEGRA_VI_BASE, .end = TEGRA_VI_BASE + TEGRA_VI_SIZE - 1, .flags = IORESOURCE_MEM, }, }; static struct nvhost_device tegra_vi01_device = { .name = "vi", .resource = vi_resources, .num_resources = ARRAY_SIZE(vi_resources), .id = -1, .index = 4, .syncpts = BIT(NVSYNCPT_CSI_VI_0) | BIT(NVSYNCPT_CSI_VI_1) | BIT(NVSYNCPT_VI_ISP_0) | BIT(NVSYNCPT_VI_ISP_1) | BIT(NVSYNCPT_VI_ISP_2) | BIT(NVSYNCPT_VI_ISP_3) | BIT(NVSYNCPT_VI_ISP_4), .modulemutexes = BIT(NVMODMUTEX_VI), .exclusive = true, NVHOST_MODULE_NO_POWERGATE_IDS, NVHOST_DEFAULT_CLOCKGATE_DELAY, .moduleid = NVHOST_MODULE_VI, }; static struct resource tegra_mpe01_resources[] = { { .name = "regs", .start = TEGRA_MPE_BASE, .end = TEGRA_MPE_BASE + TEGRA_MPE_SIZE - 1, .flags = IORESOURCE_MEM, }, }; static struct nvhost_device tegra_mpe02_device = { .name = "mpe", .version = 2, .id = -1, .resource = tegra_mpe01_resources, .num_resources = ARRAY_SIZE(tegra_mpe01_resources), .index = 5, .syncpts = BIT(NVSYNCPT_MPE) | BIT(NVSYNCPT_MPE_EBM_EOF) | BIT(NVSYNCPT_MPE_WR_SAFE), .waitbases = BIT(NVWAITBASE_MPE), .class = NV_VIDEO_ENCODE_MPEG_CLASS_ID, .waitbasesync = true, .keepalive = true, .clocks = { {"mpe", UINT_MAX}, {"emc", UINT_MAX} }, .powergate_ids = {TEGRA_POWERGATE_MPE, -1}, NVHOST_DEFAULT_CLOCKGATE_DELAY, .can_powergate = true, .powergate_delay = 100, .moduleid = NVHOST_MODULE_MPE, }; static struct nvhost_device tegra_dsi01_device = { .name = "dsi", .id = -1, .index = 6, .syncpts = BIT(NVSYNCPT_DSI), .modulemutexes = BIT(NVMODMUTEX_DSI), NVHOST_MODULE_NO_POWERGATE_IDS, NVHOST_DEFAULT_CLOCKGATE_DELAY, .moduleid = NVHOST_MODULE_NONE, }; static struct nvhost_device *t30_devices[] = { &tegra_host1x01_device, &tegra_display01_device, &tegra_gr3d02_device, &tegra_gr2d02_device, &tegra_isp01_device, &tegra_vi01_device, &tegra_mpe02_device, &tegra_dsi01_device, }; int tegra3_register_host1x_devices(void) { return nvhost_add_devices(t30_devices, ARRAY_SIZE(t30_devices)); } static void t30_free_nvhost_channel(struct nvhost_channel *ch) { nvhost_free_channel_internal(ch, &t30_num_alloc_channels); } static struct nvhost_channel *t30_alloc_nvhost_channel( struct nvhost_device *dev) { return nvhost_alloc_channel_internal(dev->index, nvhost_get_host(dev)->info.nb_channels, &t30_num_alloc_channels); } #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" int nvhost_init_t30_support(struct nvhost_master *host, struct nvhost_chip_support *op) { int err; op->channel = host1x_channel_ops; op->cdma = host1x_cdma_ops; op->push_buffer = host1x_pushbuffer_ops; op->debug = host1x_debug_ops; op->debug.debug_init = nvhost_scale3d_debug_init; 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 = t30_alloc_nvhost_channel; op->nvhost_dev.free_nvhost_channel = t30_free_nvhost_channel; return 0; }