]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
gpu: host1x: Set up stream ID table
authorThierry Reding <treding@nvidia.com>
Fri, 1 Feb 2019 13:28:22 +0000 (14:28 +0100)
committerThierry Reding <treding@nvidia.com>
Mon, 4 Feb 2019 07:35:55 +0000 (08:35 +0100)
In order to enable the MMIO path stream ID protection provided by the
incarnation of host1x found in Tegra186 and later, the host1x must be
provided with the list of stream ID register offsets for each of its
clients. Some clients (such as VIC) have multiple stream ID registers
that are assumed to be contiguous. The host1x is programmed with the
base offset and a limit which provide the range of registers that the
host1x needs to monitor for writes.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/gpu/host1x/dev.c
drivers/gpu/host1x/dev.h

index 419d8929a98f8f7ca2abf13d00ab3b8f3373f6b7..4c044ee54fe6f3261a959ccf024dd805dd22edf5 100644 (file)
@@ -120,6 +120,15 @@ static const struct host1x_info host1x05_info = {
        .dma_mask = DMA_BIT_MASK(34),
 };
 
+static const struct host1x_sid_entry tegra186_sid_table[] = {
+       {
+               /* VIC */
+               .base = 0x1af0,
+               .offset = 0x30,
+               .limit = 0x34
+       },
+};
+
 static const struct host1x_info host1x06_info = {
        .nb_channels = 63,
        .nb_pts = 576,
@@ -129,6 +138,17 @@ static const struct host1x_info host1x06_info = {
        .sync_offset = 0x0,
        .dma_mask = DMA_BIT_MASK(34),
        .has_hypervisor = true,
+       .num_sid_entries = ARRAY_SIZE(tegra186_sid_table),
+       .sid_table = tegra186_sid_table,
+};
+
+static const struct host1x_sid_entry tegra194_sid_table[] = {
+       {
+               /* VIC */
+               .base = 0x1af0,
+               .offset = 0x30,
+               .limit = 0x34
+       },
 };
 
 static const struct host1x_info host1x07_info = {
@@ -140,6 +160,8 @@ static const struct host1x_info host1x07_info = {
        .sync_offset = 0x0,
        .dma_mask = DMA_BIT_MASK(40),
        .has_hypervisor = true,
+       .num_sid_entries = ARRAY_SIZE(tegra194_sid_table),
+       .sid_table = tegra194_sid_table,
 };
 
 static const struct of_device_id host1x_of_match[] = {
@@ -154,6 +176,19 @@ static const struct of_device_id host1x_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, host1x_of_match);
 
+static void host1x_setup_sid_table(struct host1x *host)
+{
+       const struct host1x_info *info = host->info;
+       unsigned int i;
+
+       for (i = 0; i < info->num_sid_entries; i++) {
+               const struct host1x_sid_entry *entry = &info->sid_table[i];
+
+               host1x_hypervisor_writel(host, entry->offset, entry->base);
+               host1x_hypervisor_writel(host, entry->limit, entry->base + 4);
+       }
+}
+
 static int host1x_probe(struct platform_device *pdev)
 {
        struct host1x *host;
@@ -316,6 +351,9 @@ static int host1x_probe(struct platform_device *pdev)
 
        host1x_debug_init(host);
 
+       if (host->info->has_hypervisor)
+               host1x_setup_sid_table(host);
+
        err = host1x_register(host);
        if (err < 0)
                goto fail_deinit_intr;
index 36f44ffebe739a98d8195f611bdafa2b07318676..05216a7e4830936021677d01a6cee6903db6324c 100644 (file)
@@ -94,6 +94,12 @@ struct host1x_intr_ops {
        int (*free_syncpt_irq)(struct host1x *host);
 };
 
+struct host1x_sid_entry {
+       unsigned int base;
+       unsigned int offset;
+       unsigned int limit;
+};
+
 struct host1x_info {
        unsigned int nb_channels; /* host1x: number of channels supported */
        unsigned int nb_pts; /* host1x: number of syncpoints supported */
@@ -103,6 +109,8 @@ struct host1x_info {
        unsigned int sync_offset; /* offset of syncpoint registers */
        u64 dma_mask; /* mask of addressable memory */
        bool has_hypervisor; /* has hypervisor registers */
+       unsigned int num_sid_entries;
+       const struct host1x_sid_entry *sid_table;
 };
 
 struct host1x {