Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions arch/riscv/boot/dts/thead/th1520.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,13 @@
#clock-cells = <0>;
};

gc620_cclk: clk-gc620-fake {
compatible = "fixed-clock";
clock-frequency = <264000000>;
clock-output-names = "gc620_cclk";
#clock-cells = <0>;
};

stmmac_axi_config: stmmac-axi-config {
snps,wr_osr_lmt = <15>;
snps,rd_osr_lmt = <15>;
Expand Down Expand Up @@ -493,6 +500,18 @@
status = "disabled";
};

/* Vivante GC620, 2D only */
g2d: gpu@ffecc80000 {
compatible = "vivante,gc";
reg = <0xff 0xecc80000 0x0 0x40000>;
interrupt-parent = <&plic>;
interrupts = <101 IRQ_TYPE_LEVEL_HIGH>;

clocks = <&gc620_cclk>;
clock-names = "core";
status = "okay";
};

clk: clock-controller@ffef010000 {
compatible = "thead,th1520-clk-ap";
reg = <0xff 0xef010000 0x0 0x1000>;
Expand Down
19 changes: 16 additions & 3 deletions drivers/gpu/drm/etnaviv/etnaviv_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,11 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu)
control |= VIVS_HI_CLOCK_CONTROL_ISOLATE_GPU;
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control);

if (gpu->sec_mode == ETNA_SEC_KERNEL) {
if (etnaviv_is_model_rev(gpu, 0x620, 0x5552)) {
gpu_write(gpu, VIVS_DEC400EX_UNK00800, 0x10);
}

if (gpu->identity.minor_features7 & chipMinorFeatures7_BIT_SECURITY) {
gpu_write(gpu, VIVS_MMUv2_AHB_CONTROL,
VIVS_MMUv2_AHB_CONTROL_RESET);
} else {
Expand Down Expand Up @@ -797,7 +801,16 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
gpu_write(gpu, VIVS_MC_BUS_CONFIG, bus_config);
}

if (gpu->sec_mode == ETNA_SEC_KERNEL) {
/*
* FIXME: Required by GC620 r5552 as a bug workaround, but might be
* useful on other GPUs with G2D_DEC400EX feature too.
*/
if (etnaviv_is_model_rev(gpu, 0x620, 0x5552)) {
gpu_write(gpu, VIVS_DEC400EX_UNK00800, 0x2010188);
gpu_write(gpu, VIVS_DEC400EX_UNK00808, 0x3fc104);
}

if (gpu->identity.minor_features7 & chipMinorFeatures7_BIT_SECURITY) {
u32 val = gpu_read(gpu, VIVS_MMUv2_AHB_CONTROL);
val |= VIVS_MMUv2_AHB_CONTROL_NONSEC_ACCESS;
gpu_write(gpu, VIVS_MMUv2_AHB_CONTROL, val);
Expand Down Expand Up @@ -853,7 +866,7 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
* On cores with security features supported, we claim control over the
* security states.
*/
if ((gpu->identity.minor_features7 & chipMinorFeatures7_BIT_SECURITY) &&
if ((gpu->identity.minor_features7 & chipMinorFeatures7_BIT_SECURITY) ||
(gpu->identity.minor_features10 & chipMinorFeatures10_SECURITY_AHB))
gpu->sec_mode = ETNA_SEC_KERNEL;

Expand Down
31 changes: 31 additions & 0 deletions drivers/gpu/drm/etnaviv/etnaviv_hwdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,37 @@ static const struct etnaviv_chip_identity etnaviv_chip_identities[] = {
.minor_features10 = 0x00000000,
.minor_features11 = 0x00000000,
},
{
.model = 0x620,
.revision = 0x5552,
.product_id = 0x6200,
.customer_id = 0x20b,
.eco_id = 0,
.stream_count = 1,
.register_max = 64,
.thread_count = 256,
.shader_core_count = 1,
.vertex_cache_size = 8,
.vertex_output_buffer_size = 512,
.pixel_pipes = 1,
.instruction_count = 256,
.num_constants = 168,
.buffer_size = 0,
.varyings_count = 8,
.features = 0x001b4a40,
.minor_features0 = 0xa0600080,
.minor_features1 = 0x18050000,
.minor_features2 = 0x04f30000,
.minor_features3 = 0x00060005,
.minor_features4 = 0x20629000,
.minor_features5 = 0x0003380c,
.minor_features6 = 0x00000000,
.minor_features7 = 0x00001000,
.minor_features8 = 0x00000000,
.minor_features9 = 0x00000180,
.minor_features10 = 0x00004000,
.minor_features11 = 0x00000000,
},
{
.model = 0x7000,
.revision = 0x6202,
Expand Down
8 changes: 4 additions & 4 deletions drivers/gpu/drm/etnaviv/etnaviv_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static void etnaviv_iommuv1_free(struct etnaviv_iommu_context *context)
dma_free_wc(context->global->dev, PT_SIZE, v1_context->pgtable_cpu,
v1_context->pgtable_dma);

context->global->v1.shared_context = NULL;
context->global->shared_context = NULL;

kfree(v1_context);
}
Expand Down Expand Up @@ -136,8 +136,8 @@ etnaviv_iommuv1_context_alloc(struct etnaviv_iommu_global *global)
* a stop the world operation, so we only support a single shared
* context with this version.
*/
if (global->v1.shared_context) {
context = global->v1.shared_context;
if (global->shared_context) {
context = global->shared_context;
etnaviv_iommu_context_get(context);
mutex_unlock(&global->lock);
return context;
Expand All @@ -163,7 +163,7 @@ etnaviv_iommuv1_context_alloc(struct etnaviv_iommu_global *global)
mutex_init(&context->lock);
INIT_LIST_HEAD(&context->mappings);
drm_mm_init(&context->mm, GPU_MEM_START, PT_ENTRIES * SZ_4K);
context->global->v1.shared_context = context;
context->global->shared_context = context;

mutex_unlock(&global->lock);

Expand Down
23 changes: 16 additions & 7 deletions drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,20 +272,24 @@ etnaviv_iommuv2_context_alloc(struct etnaviv_iommu_global *global)
struct etnaviv_iommuv2_context *v2_context;
struct etnaviv_iommu_context *context;

mutex_lock(&global->lock);
if (global->shared_context) {
context = global->shared_context;
etnaviv_iommu_context_get(context);
mutex_unlock(&global->lock);
return context;
}

v2_context = vzalloc(sizeof(*v2_context));
if (!v2_context)
return NULL;
goto out_mutex_unlock;

mutex_lock(&global->lock);
v2_context->id = find_first_zero_bit(global->v2.pta_alloc,
ETNAVIV_PTA_ENTRIES);
if (v2_context->id < ETNAVIV_PTA_ENTRIES) {
if (v2_context->id < ETNAVIV_PTA_ENTRIES)
set_bit(v2_context->id, global->v2.pta_alloc);
} else {
mutex_unlock(&global->lock);
else
goto out_free;
}
mutex_unlock(&global->lock);

v2_context->mtlb_cpu = dma_alloc_wc(global->dev, SZ_4K,
&v2_context->mtlb_dma, GFP_KERNEL);
Expand All @@ -303,12 +307,17 @@ etnaviv_iommuv2_context_alloc(struct etnaviv_iommu_global *global)
mutex_init(&context->lock);
INIT_LIST_HEAD(&context->mappings);
drm_mm_init(&context->mm, SZ_4K, (u64)SZ_1G * 4 - SZ_4K);
if (global->v2.broken_pta)
global->shared_context = context;

mutex_unlock(&global->lock);
return context;

out_free_id:
clear_bit(v2_context->id, global->v2.pta_alloc);
out_free:
vfree(v2_context);
out_mutex_unlock:
mutex_unlock(&global->lock);
return NULL;
}
1 change: 1 addition & 0 deletions drivers/gpu/drm/etnaviv/etnaviv_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ int etnaviv_iommu_global_init(struct etnaviv_gpu *gpu)
memset32(global->bad_page_cpu, 0xdead55aa, SZ_4K / sizeof(u32));

if (version == ETNAVIV_IOMMU_V2) {
global->v2.broken_pta = gpu->identity.model == chipModel_GC620;
global->v2.pta_cpu = dma_alloc_wc(dev, ETNAVIV_PTA_SIZE,
&global->v2.pta_dma, GFP_KERNEL);
if (!global->v2.pta_cpu)
Expand Down
24 changes: 9 additions & 15 deletions drivers/gpu/drm/etnaviv/etnaviv_mmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,15 @@ struct etnaviv_iommu_global {

u32 memory_base;

/*
* This union holds members needed by either MMUv1 or MMUv2, which
* can not exist at the same time.
*/
union {
struct {
struct etnaviv_iommu_context *shared_context;
} v1;
struct {
/* P(age) T(able) A(rray) */
u64 *pta_cpu;
dma_addr_t pta_dma;
DECLARE_BITMAP(pta_alloc, ETNAVIV_PTA_ENTRIES);
} v2;
};
struct etnaviv_iommu_context *shared_context;
struct {
/* P(age) T(able) A(rray) */
u64 *pta_cpu;
dma_addr_t pta_dma;
DECLARE_BITMAP(pta_alloc, ETNAVIV_PTA_ENTRIES);
/* Whether runtime switching page table ID will fail */
bool broken_pta;
} v2;
};

struct etnaviv_iommu_context {
Expand Down