Skip to content

Commit

Permalink
drm/etnaviv: handle security states
Browse files Browse the repository at this point in the history
GPUs with support for the security features need some additional
setup to get the frontend started.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
  • Loading branch information
Lucas Stach committed Mar 9, 2018
1 parent 007ad58 commit c997c3d
Showing 1 changed file with 43 additions and 5 deletions.
48 changes: 43 additions & 5 deletions drivers/gpu/drm/etnaviv/etnaviv_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,9 +481,14 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu)
control |= VIVS_HI_CLOCK_CONTROL_ISOLATE_GPU;
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control);

/* set soft reset. */
control |= VIVS_HI_CLOCK_CONTROL_SOFT_RESET;
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control);
if (gpu->sec_mode == ETNA_SEC_KERNEL) {
gpu_write(gpu, VIVS_MMUv2_AHB_CONTROL,
VIVS_MMUv2_AHB_CONTROL_RESET);
} else {
/* set soft reset. */
control |= VIVS_HI_CLOCK_CONTROL_SOFT_RESET;
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control);
}

/* wait for reset. */
usleep_range(10, 20);
Expand Down Expand Up @@ -594,6 +599,12 @@ void etnaviv_gpu_start_fe(struct etnaviv_gpu *gpu, u32 address, u16 prefetch)
gpu_write(gpu, VIVS_FE_COMMAND_CONTROL,
VIVS_FE_COMMAND_CONTROL_ENABLE |
VIVS_FE_COMMAND_CONTROL_PREFETCH(prefetch));

if (gpu->sec_mode == ETNA_SEC_KERNEL) {
gpu_write(gpu, VIVS_MMUv2_SEC_COMMAND_CONTROL,
VIVS_MMUv2_SEC_COMMAND_CONTROL_ENABLE |
VIVS_MMUv2_SEC_COMMAND_CONTROL_PREFETCH(prefetch));
}
}

static void etnaviv_gpu_setup_pulse_eater(struct etnaviv_gpu *gpu)
Expand Down Expand Up @@ -667,6 +678,12 @@ 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) {
u32 val = gpu_read(gpu, VIVS_MMUv2_AHB_CONTROL);
val |= VIVS_MMUv2_AHB_CONTROL_NONSEC_ACCESS;
gpu_write(gpu, VIVS_MMUv2_AHB_CONTROL, val);
}

/* setup the pulse eater */
etnaviv_gpu_setup_pulse_eater(gpu);

Expand Down Expand Up @@ -729,6 +746,14 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
}

/*
* On cores with security features supported, we claim control over the
* security states.
*/
if ((gpu->identity.minor_features7 & chipMinorFeatures7_BIT_SECURITY) &&
(gpu->identity.minor_features10 & chipMinorFeatures10_SECURITY_AHB))
gpu->sec_mode = ETNA_SEC_KERNEL;

ret = etnaviv_hw_reset(gpu);
if (ret) {
dev_err(gpu->dev, "GPU reset failed\n");
Expand Down Expand Up @@ -1342,17 +1367,30 @@ static void sync_point_worker(struct work_struct *work)

static void dump_mmu_fault(struct etnaviv_gpu *gpu)
{
u32 status = gpu_read(gpu, VIVS_MMUv2_STATUS);
u32 status_reg, status;
int i;

if (gpu->sec_mode == ETNA_SEC_NONE)
status_reg = VIVS_MMUv2_STATUS;
else
status_reg = VIVS_MMUv2_SEC_STATUS;

status = gpu_read(gpu, status_reg);
dev_err_ratelimited(gpu->dev, "MMU fault status 0x%08x\n", status);

for (i = 0; i < 4; i++) {
u32 address_reg;

if (!(status & (VIVS_MMUv2_STATUS_EXCEPTION0__MASK << (i * 4))))
continue;

if (gpu->sec_mode == ETNA_SEC_NONE)
address_reg = VIVS_MMUv2_EXCEPTION_ADDR(i);
else
address_reg = VIVS_MMUv2_SEC_EXCEPTION_ADDR;

dev_err_ratelimited(gpu->dev, "MMU %d fault addr 0x%08x\n", i,
gpu_read(gpu, VIVS_MMUv2_EXCEPTION_ADDR(i)));
gpu_read(gpu, address_reg));
}
}

Expand Down

0 comments on commit c997c3d

Please sign in to comment.