ivpu_mmu.c (c9da9a1f17bf4fa96b115950fd389c917b583c1c) | ivpu_mmu.c (b039f1c4d3727c3e44a7e89ff79e7e8533e1beec) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2020-2023 Intel Corporation 4 */ 5 6#include <linux/circ_buf.h> 7#include <linux/highmem.h> 8 --- 58 unchanged lines hidden (view full) --- 67 68#define IVPU_MMU_STRTAB_ENT_SIZE 64 69#define IVPU_MMU_STRTAB_ENT_COUNT 4 70#define IVPU_MMU_STRTAB_CFG_LOG2SIZE 2 71#define IVPU_MMU_STRTAB_CFG IVPU_MMU_STRTAB_CFG_LOG2SIZE 72 73#define IVPU_MMU_Q_COUNT_LOG2 4 /* 16 entries */ 74#define IVPU_MMU_Q_COUNT ((u32)1 << IVPU_MMU_Q_COUNT_LOG2) | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2020-2023 Intel Corporation 4 */ 5 6#include <linux/circ_buf.h> 7#include <linux/highmem.h> 8 --- 58 unchanged lines hidden (view full) --- 67 68#define IVPU_MMU_STRTAB_ENT_SIZE 64 69#define IVPU_MMU_STRTAB_ENT_COUNT 4 70#define IVPU_MMU_STRTAB_CFG_LOG2SIZE 2 71#define IVPU_MMU_STRTAB_CFG IVPU_MMU_STRTAB_CFG_LOG2SIZE 72 73#define IVPU_MMU_Q_COUNT_LOG2 4 /* 16 entries */ 74#define IVPU_MMU_Q_COUNT ((u32)1 << IVPU_MMU_Q_COUNT_LOG2) |
75#define IVPU_MMU_Q_WRAP_BIT (IVPU_MMU_Q_COUNT << 1) 76#define IVPU_MMU_Q_WRAP_MASK (IVPU_MMU_Q_WRAP_BIT - 1) 77#define IVPU_MMU_Q_IDX_MASK (IVPU_MMU_Q_COUNT - 1) | 75#define IVPU_MMU_Q_WRAP_MASK GENMASK(IVPU_MMU_Q_COUNT_LOG2, 0) 76#define IVPU_MMU_Q_IDX_MASK (IVPU_MMU_Q_COUNT - 1) |
78#define IVPU_MMU_Q_IDX(val) ((val) & IVPU_MMU_Q_IDX_MASK) | 77#define IVPU_MMU_Q_IDX(val) ((val) & IVPU_MMU_Q_IDX_MASK) |
78#define IVPU_MMU_Q_WRP(val) ((val) & IVPU_MMU_Q_COUNT) |
|
79 80#define IVPU_MMU_CMDQ_CMD_SIZE 16 81#define IVPU_MMU_CMDQ_SIZE (IVPU_MMU_Q_COUNT * IVPU_MMU_CMDQ_CMD_SIZE) 82 83#define IVPU_MMU_EVTQ_CMD_SIZE 32 84#define IVPU_MMU_EVTQ_SIZE (IVPU_MMU_Q_COUNT * IVPU_MMU_EVTQ_CMD_SIZE) 85 86#define IVPU_MMU_CMD_OPCODE GENMASK(7, 0) --- 383 unchanged lines hidden (view full) --- 470 if (ret) 471 return ret; 472 473 cmdq->cons = cmdq->prod; 474 475 return 0; 476} 477 | 79 80#define IVPU_MMU_CMDQ_CMD_SIZE 16 81#define IVPU_MMU_CMDQ_SIZE (IVPU_MMU_Q_COUNT * IVPU_MMU_CMDQ_CMD_SIZE) 82 83#define IVPU_MMU_EVTQ_CMD_SIZE 32 84#define IVPU_MMU_EVTQ_SIZE (IVPU_MMU_Q_COUNT * IVPU_MMU_EVTQ_CMD_SIZE) 85 86#define IVPU_MMU_CMD_OPCODE GENMASK(7, 0) --- 383 unchanged lines hidden (view full) --- 470 if (ret) 471 return ret; 472 473 cmdq->cons = cmdq->prod; 474 475 return 0; 476} 477 |
478static bool ivpu_mmu_queue_is_full(struct ivpu_mmu_queue *q) 479{ 480 return ((IVPU_MMU_Q_IDX(q->prod) == IVPU_MMU_Q_IDX(q->cons)) && 481 (IVPU_MMU_Q_WRP(q->prod) != IVPU_MMU_Q_WRP(q->cons))); 482} 483 484static bool ivpu_mmu_queue_is_empty(struct ivpu_mmu_queue *q) 485{ 486 return ((IVPU_MMU_Q_IDX(q->prod) == IVPU_MMU_Q_IDX(q->cons)) && 487 (IVPU_MMU_Q_WRP(q->prod) == IVPU_MMU_Q_WRP(q->cons))); 488} 489 |
|
478static int ivpu_mmu_cmdq_cmd_write(struct ivpu_device *vdev, const char *name, u64 data0, u64 data1) 479{ | 490static int ivpu_mmu_cmdq_cmd_write(struct ivpu_device *vdev, const char *name, u64 data0, u64 data1) 491{ |
480 struct ivpu_mmu_queue *q = &vdev->mmu->cmdq; 481 u64 *queue_buffer = q->base; 482 int idx = IVPU_MMU_Q_IDX(q->prod) * (IVPU_MMU_CMDQ_CMD_SIZE / sizeof(*queue_buffer)); | 492 struct ivpu_mmu_queue *cmdq = &vdev->mmu->cmdq; 493 u64 *queue_buffer = cmdq->base; 494 int idx = IVPU_MMU_Q_IDX(cmdq->prod) * (IVPU_MMU_CMDQ_CMD_SIZE / sizeof(*queue_buffer)); |
483 | 495 |
484 if (!CIRC_SPACE(IVPU_MMU_Q_IDX(q->prod), IVPU_MMU_Q_IDX(q->cons), IVPU_MMU_Q_COUNT)) { | 496 if (ivpu_mmu_queue_is_full(cmdq)) { |
485 ivpu_err(vdev, "Failed to write MMU CMD %s\n", name); 486 return -EBUSY; 487 } 488 489 queue_buffer[idx] = data0; 490 queue_buffer[idx + 1] = data1; | 497 ivpu_err(vdev, "Failed to write MMU CMD %s\n", name); 498 return -EBUSY; 499 } 500 501 queue_buffer[idx] = data0; 502 queue_buffer[idx + 1] = data1; |
491 q->prod = (q->prod + 1) & IVPU_MMU_Q_WRAP_MASK; | 503 cmdq->prod = (cmdq->prod + 1) & IVPU_MMU_Q_WRAP_MASK; |
492 493 ivpu_dbg(vdev, MMU, "CMD write: %s data: 0x%llx 0x%llx\n", name, data0, data1); 494 495 return 0; 496} 497 498static int ivpu_mmu_cmdq_sync(struct ivpu_device *vdev) 499{ --- 368 unchanged lines hidden (view full) --- 868 869static u32 *ivpu_mmu_get_event(struct ivpu_device *vdev) 870{ 871 struct ivpu_mmu_queue *evtq = &vdev->mmu->evtq; 872 u32 idx = IVPU_MMU_Q_IDX(evtq->cons); 873 u32 *evt = evtq->base + (idx * IVPU_MMU_EVTQ_CMD_SIZE); 874 875 evtq->prod = REGV_RD32(IVPU_MMU_REG_EVTQ_PROD_SEC); | 504 505 ivpu_dbg(vdev, MMU, "CMD write: %s data: 0x%llx 0x%llx\n", name, data0, data1); 506 507 return 0; 508} 509 510static int ivpu_mmu_cmdq_sync(struct ivpu_device *vdev) 511{ --- 368 unchanged lines hidden (view full) --- 880 881static u32 *ivpu_mmu_get_event(struct ivpu_device *vdev) 882{ 883 struct ivpu_mmu_queue *evtq = &vdev->mmu->evtq; 884 u32 idx = IVPU_MMU_Q_IDX(evtq->cons); 885 u32 *evt = evtq->base + (idx * IVPU_MMU_EVTQ_CMD_SIZE); 886 887 evtq->prod = REGV_RD32(IVPU_MMU_REG_EVTQ_PROD_SEC); |
876 if (!CIRC_CNT(IVPU_MMU_Q_IDX(evtq->prod), IVPU_MMU_Q_IDX(evtq->cons), IVPU_MMU_Q_COUNT)) | 888 if (ivpu_mmu_queue_is_empty(evtq)) |
877 return NULL; 878 879 evtq->cons = (evtq->cons + 1) & IVPU_MMU_Q_WRAP_MASK; | 889 return NULL; 890 891 evtq->cons = (evtq->cons + 1) & IVPU_MMU_Q_WRAP_MASK; |
880 REGV_WR32(IVPU_MMU_REG_EVTQ_CONS_SEC, evtq->cons); 881 | |
882 return evt; 883} 884 885void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev) 886{ 887 u32 *event; 888 u32 ssid; 889 --- 4 unchanged lines hidden (view full) --- 894 895 ssid = FIELD_GET(IVPU_MMU_EVT_SSID_MASK, event[0]); 896 if (ssid == IVPU_GLOBAL_CONTEXT_MMU_SSID) { 897 ivpu_pm_trigger_recovery(vdev, "MMU event"); 898 return; 899 } 900 901 ivpu_mmu_user_context_mark_invalid(vdev, ssid); | 892 return evt; 893} 894 895void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev) 896{ 897 u32 *event; 898 u32 ssid; 899 --- 4 unchanged lines hidden (view full) --- 904 905 ssid = FIELD_GET(IVPU_MMU_EVT_SSID_MASK, event[0]); 906 if (ssid == IVPU_GLOBAL_CONTEXT_MMU_SSID) { 907 ivpu_pm_trigger_recovery(vdev, "MMU event"); 908 return; 909 } 910 911 ivpu_mmu_user_context_mark_invalid(vdev, ssid); |
912 REGV_WR32(IVPU_MMU_REG_EVTQ_CONS_SEC, vdev->mmu->evtq.cons); |
|
902 } 903} 904 905void ivpu_mmu_evtq_dump(struct ivpu_device *vdev) 906{ 907 u32 *event; 908 909 while ((event = ivpu_mmu_get_event(vdev)) != NULL) --- 49 unchanged lines hidden --- | 913 } 914} 915 916void ivpu_mmu_evtq_dump(struct ivpu_device *vdev) 917{ 918 u32 *event; 919 920 while ((event = ivpu_mmu_get_event(vdev)) != NULL) --- 49 unchanged lines hidden --- |