drm/lima: add mali 4xx GPU hardware regs
Subsystems (3)
A message that is not in the archive (sent off-list or not yet received): [email protected]
Qiang Yu
maintainerRFC 7/24 drm/lima: add mali 4xx GPU hardware regs
From: Lima Project Developers <[email protected]>
--- drivers/gpu/drm/lima/lima_regs.h | 304 +++++++++++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 drivers/gpu/drm/lima/lima_regs.h
drivers/gpu/drm/lima/lima_regs.h new file +304 -0
@@ -0,0 +1,304 @@ +/* +* Copyright (C) 2010-2017 ARM Limited. All rights reserved. +* Copyright (C) 2017-2018 Lima Project +* +* This program is free software and is provided to you under +* the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation, and any use by +* you of this program is subject to the terms of such GNU +* licence. +* +* A copy of the licence is included with the program, and +* can also be obtained from Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __LIMA_REGS_H__ +#define __LIMA_REGS_H__ + +/* PMU regs */ +#define LIMA_PMU_POWER_UP 0x00 +#define LIMA_PMU_POWER_DOWN 0x04 +#define LIMA_PMU_POWER_GP0_MASK (1 << 0) +#define LIMA_PMU_POWER_L2_MASK (1 << 1) +#define LIMA_PMU_POWER_PP_MASK (i) (1 << (2 + i)) + +/* +* On Mali450 each block automatically starts up its corresponding L2 +* and the PPs are not fully independent controllable. +* Instead PP0, PP1-3 and PP4-7 can be turned on or off. +*/ +#define LIMA450_PMU_POWER_PP0_MASK BIT(1) +#define LIMA450_PMU_POWER_PP13_MASK BIT(2) +#define LIMA450_PMU_POWER_PP47_MASK BIT(3) + +#define LIMA_PMU_STATUS 0x08 +#define LIMA_PMU_INT_MASK 0x0C +#define LIMA_PMU_INT_RAWSTAT 0x10 +#define LIMA_PMU_INT_CLEAR 0x18 +#define LIMA_PMU_INT_CMD_MASK (1 << 0) +#define LIMA_PMU_SW_DELAY 0x1C + +/* L2 cache regs */ +#define LIMA_L2_CACHE_SIZE 0x0004 +#define LIMA_L2_CACHE_STATUS 0x0008 +#define LIMA_L2_CACHE_STATUS_COMMAND_BUSY (1 << 0) +#define LIMA_L2_CACHE_STATUS_DATA_BUSY (1 << 1) +#define LIMA_L2_CACHE_COMMAND 0x0010 +#define LIMA_L2_CACHE_COMMAND_CLEAR_ALL (1 << 0) +#define LIMA_L2_CACHE_CLEAR_PAGE 0x0014 +#define LIMA_L2_CACHE_MAX_READS 0x0018 +#define LIMA_L2_CACHE_ENABLE 0x001C +#define LIMA_L2_CACHE_ENABLE_ACCESS (1 << 0) +#define LIMA_L2_CACHE_ENABLE_READ_ALLOCATE (1 << 1) +#define LIMA_L2_CACHE_PERFCNT_SRC0 0x0020 +#define LIMA_L2_CACHE_PERFCNT_VAL0 0x0024 +#define LIMA_L2_CACHE_PERFCNT_SRC1 0x0028 +#define LIMA_L2_CACHE_ERFCNT_VAL1 0x002C + +/* GP regs */ +#define LIMA_GP_VSCL_START_ADDR 0x00 +#define LIMA_GP_VSCL_END_ADDR 0x04 +#define LIMA_GP_PLBUCL_START_ADDR 0x08 +#define LIMA_GP_PLBUCL_END_ADDR 0x0c +#define LIMA_GP_PLBU_ALLOC_START_ADDR 0x10 +#define LIMA_GP_PLBU_ALLOC_END_ADDR 0x14 +#define LIMA_GP_CMD 0x20 +#define LIMA_GP_CMD_START_VS (1 << 0) +#define LIMA_GP_CMD_START_PLBU (1 << 1) +#define LIMA_GP_CMD_UPDATE_PLBU_ALLOC (1 << 4) +#define LIMA_GP_CMD_RESET (1 << 5) +#define LIMA_GP_CMD_FORCE_HANG (1 << 6) +#define LIMA_GP_CMD_STOP_BUS (1 << 9) +#define LIMA_GP_CMD_SOFT_RESET (1 << 10) +#define LIMA_GP_INT_RAWSTAT 0x24 +#define LIMA_GP_INT_CLEAR 0x28 +#define LIMA_GP_INT_MASK 0x2C +#define LIMA_GP_INT_STAT 0x30 +#define LIMA_GP_IRQ_VS_END_CMD_LST (1 << 0) +#define LIMA_GP_IRQ_PLBU_END_CMD_LST (1 << 1) +#define LIMA_GP_IRQ_PLBU_OUT_OF_MEM (1 << 2) +#define LIMA_GP_IRQ_VS_SEM_IRQ (1 << 3) +#define LIMA_GP_IRQ_PLBU_SEM_IRQ (1 << 4) +#define LIMA_GP_IRQ_HANG (1 << 5) +#define LIMA_GP_IRQ_FORCE_HANG (1 << 6) +#define LIMA_GP_IRQ_PERF_CNT_0_LIMIT (1 << 7) +#define LIMA_GP_IRQ_PERF_CNT_1_LIMIT (1 << 8) +#define LIMA_GP_IRQ_WRITE_BOUND_ERR (1 << 9) +#define LIMA_GP_IRQ_SYNC_ERROR (1 << 10) +#define LIMA_GP_IRQ_AXI_BUS_ERROR (1 << 11) +#define LIMA_GP_IRQ_AXI_BUS_STOPPED (1 << 12) +#define LIMA_GP_IRQ_VS_INVALID_CMD (1 << 13) +#define LIMA_GP_IRQ_PLB_INVALID_CMD (1 << 14) +#define LIMA_GP_IRQ_RESET_COMPLETED (1 << 19) +#define LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW (1 << 20) +#define LIMA_GP_IRQ_SEMAPHORE_OVERFLOW (1 << 21) +#define LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS (1 << 22) +#define LIMA_GP_WRITE_BOUND_LOW 0x34 +#define LIMA_GP_PERF_CNT_0_ENABLE 0x3C +#define LIMA_GP_PERF_CNT_1_ENABLE 0x40 +#define LIMA_GP_PERF_CNT_0_SRC 0x44 +#define LIMA_GP_PERF_CNT_1_SRC 0x48 +#define LIMA_GP_PERF_CNT_0_VALUE 0x4C +#define LIMA_GP_PERF_CNT_1_VALUE 0x50 +#define LIMA_GP_PERF_CNT_0_LIMIT 0x54 +#define LIMA_GP_STATUS 0x68 +#define LIMA_GP_STATUS_VS_ACTIVE (1 << 1) +#define LIMA_GP_STATUS_BUS_STOPPED (1 << 2) +#define LIMA_GP_STATUS_PLBU_ACTIVE (1 << 3) +#define LIMA_GP_STATUS_BUS_ERROR (1 << 6) +#define LIMA_GP_STATUS_WRITE_BOUND_ERR (1 << 8) +#define LIMA_GP_VERSION 0x6C +#define LIMA_GP_VSCL_START_ADDR_READ 0x80 +#define LIMA_GP_PLBCL_START_ADDR_READ 0x84 +#define LIMA_GP_CONTR_AXI_BUS_ERROR_STAT 0x94 + +#define LIMA_GP_IRQ_MASK_ALL \ + ( \ + LIMA_GP_IRQ_VS_END_CMD_LST | \ + LIMA_GP_IRQ_PLBU_END_CMD_LST | \ + LIMA_GP_IRQ_PLBU_OUT_OF_MEM | \ + LIMA_GP_IRQ_VS_SEM_IRQ | \ + LIMA_GP_IRQ_PLBU_SEM_IRQ | \ + LIMA_GP_IRQ_HANG | \ + LIMA_GP_IRQ_FORCE_HANG | \ + LIMA_GP_IRQ_PERF_CNT_0_LIMIT | \ + LIMA_GP_IRQ_PERF_CNT_1_LIMIT | \ + LIMA_GP_IRQ_WRITE_BOUND_ERR | \ + LIMA_GP_IRQ_SYNC_ERROR | \ + LIMA_GP_IRQ_AXI_BUS_ERROR | \ + LIMA_GP_IRQ_AXI_BUS_STOPPED | \ + LIMA_GP_IRQ_VS_INVALID_CMD | \ + LIMA_GP_IRQ_PLB_INVALID_CMD | \ + LIMA_GP_IRQ_RESET_COMPLETED | \ + LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW | \ + LIMA_GP_IRQ_SEMAPHORE_OVERFLOW | \ + LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS) + +#define LIMA_GP_IRQ_MASK_ERROR \ + ( \ + LIMA_GP_IRQ_PLBU_OUT_OF_MEM | \ + LIMA_GP_IRQ_FORCE_HANG | \ + LIMA_GP_IRQ_WRITE_BOUND_ERR | \ + LIMA_GP_IRQ_SYNC_ERROR | \ + LIMA_GP_IRQ_AXI_BUS_ERROR | \ + LIMA_GP_IRQ_VS_INVALID_CMD | \ + LIMA_GP_IRQ_PLB_INVALID_CMD | \ + LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW | \ + LIMA_GP_IRQ_SEMAPHORE_OVERFLOW | \ + LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS) + +#define LIMA_GP_IRQ_MASK_USED \ + ( \ + LIMA_GP_IRQ_VS_END_CMD_LST | \ + LIMA_GP_IRQ_PLBU_END_CMD_LST | \ + LIMA_GP_IRQ_MASK_ERROR) + +/* PP regs */ +#define LIMA_PP_FRAME 0x0000 +#define LIMA_PP_RSW 0x0004 +#define LIMA_PP_STACK 0x0030 +#define LIMA_PP_STACK_SIZE 0x0034 +#define LIMA_PP_ORIGIN_OFFSET_X 0x0040 +#define LIMA_PP_WB (i) (0x0100 * (i + 1)) +#define LIMA_PP_WB_SOURCE_SELECT 0x0000 +#define LIMA_PP_WB_SOURCE_ADDR 0x0004 + +#define LIMA_PP_VERSION 0x1000 +#define LIMA_PP_CURRENT_REND_LIST_ADDR 0x1004 +#define LIMA_PP_STATUS 0x1008 +#define LIMA_PP_STATUS_RENDERING_ACTIVE (1 << 0) +#define LIMA_PP_STATUS_BUS_STOPPED (1 << 4) +#define LIMA_PP_CTRL 0x100c +#define LIMA_PP_CTRL_STOP_BUS (1 << 0) +#define LIMA_PP_CTRL_FLUSH_CACHES (1 << 3) +#define LIMA_PP_CTRL_FORCE_RESET (1 << 5) +#define LIMA_PP_CTRL_START_RENDERING (1 << 6) +#define LIMA_PP_CTRL_SOFT_RESET (1 << 7) +#define LIMA_PP_INT_RAWSTAT 0x1020 +#define LIMA_PP_INT_CLEAR 0x1024 +#define LIMA_PP_INT_MASK 0x1028 +#define LIMA_PP_INT_STATUS 0x102c +#define LIMA_PP_IRQ_END_OF_FRAME (1 << 0) +#define LIMA_PP_IRQ_END_OF_TILE (1 << 1) +#define LIMA_PP_IRQ_HANG (1 << 2) +#define LIMA_PP_IRQ_FORCE_HANG (1 << 3) +#define LIMA_PP_IRQ_BUS_ERROR (1 << 4) +#define LIMA_PP_IRQ_BUS_STOP (1 << 5) +#define LIMA_PP_IRQ_CNT_0_LIMIT (1 << 6) +#define LIMA_PP_IRQ_CNT_1_LIMIT (1 << 7) +#define LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR (1 << 8) +#define LIMA_PP_IRQ_INVALID_PLIST_COMMAND (1 << 9) +#define LIMA_PP_IRQ_CALL_STACK_UNDERFLOW (1 << 10) +#define LIMA_PP_IRQ_CALL_STACK_OVERFLOW (1 << 11) +#define LIMA_PP_IRQ_RESET_COMPLETED (1 << 12) +#define LIMA_PP_WRITE_BOUNDARY_LOW 0x1044 +#define LIMA_PP_BUS_ERROR_STATUS 0x1050 +#define LIMA_PP_PERF_CNT_0_ENABLE 0x1080 +#define LIMA_PP_PERF_CNT_0_SRC 0x1084 +#define LIMA_PP_PERF_CNT_0_LIMIT 0x1088 +#define LIMA_PP_PERF_CNT_0_VALUE 0x108c +#define LIMA_PP_PERF_CNT_1_ENABLE 0x10a0 +#define LIMA_PP_PERF_CNT_1_SRC 0x10a4 +#define LIMA_PP_PERF_CNT_1_LIMIT 0x10a8 +#define LIMA_PP_PERF_CNT_1_VALUE 0x10ac +#define LIMA_PP_PERFMON_CONTR 0x10b0 +#define LIMA_PP_PERFMON_BASE 0x10b4 + +#define LIMA_PP_IRQ_MASK_ALL \ + ( \ + LIMA_PP_IRQ_END_OF_FRAME | \ + LIMA_PP_IRQ_END_OF_TILE | \ + LIMA_PP_IRQ_HANG | \ + LIMA_PP_IRQ_FORCE_HANG | \ + LIMA_PP_IRQ_BUS_ERROR | \ + LIMA_PP_IRQ_BUS_STOP | \ + LIMA_PP_IRQ_CNT_0_LIMIT | \ + LIMA_PP_IRQ_CNT_1_LIMIT | \ + LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR | \ + LIMA_PP_IRQ_INVALID_PLIST_COMMAND | \ + LIMA_PP_IRQ_CALL_STACK_UNDERFLOW | \ + LIMA_PP_IRQ_CALL_STACK_OVERFLOW | \ + LIMA_PP_IRQ_RESET_COMPLETED) + +#define LIMA_PP_IRQ_MASK_ERROR \ + ( \ + LIMA_PP_IRQ_FORCE_HANG | \ + LIMA_PP_IRQ_BUS_ERROR | \ + LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR | \ + LIMA_PP_IRQ_INVALID_PLIST_COMMAND | \ + LIMA_PP_IRQ_CALL_STACK_UNDERFLOW | \ + LIMA_PP_IRQ_CALL_STACK_OVERFLOW) + +#define LIMA_PP_IRQ_MASK_USED \ + ( \ + LIMA_PP_IRQ_END_OF_FRAME | \ + LIMA_PP_IRQ_MASK_ERROR) + +/* MMU regs */ +#define LIMA_MMU_DTE_ADDR 0x0000 +#define LIMA_MMU_STATUS 0x0004 +#define LIMA_MMU_STATUS_PAGING_ENABLED (1 << 0) +#define LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE (1 << 1) +#define LIMA_MMU_STATUS_STALL_ACTIVE (1 << 2) +#define LIMA_MMU_STATUS_IDLE (1 << 3) +#define LIMA_MMU_STATUS_REPLAY_BUFFER_EMPTY (1 << 4) +#define LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE (1 << 5) +#define LIMA_MMU_STATUS_BUS_ID (x) ((x >> 6) & 0x1F) +#define LIMA_MMU_COMMAND 0x0008 +#define LIMA_MMU_COMMAND_ENABLE_PAGING 0x00 +#define LIMA_MMU_COMMAND_DISABLE_PAGING 0x01 +#define LIMA_MMU_COMMAND_ENABLE_STALL 0x02 +#define LIMA_MMU_COMMAND_DISABLE_STALL 0x03 +#define LIMA_MMU_COMMAND_ZAP_CACHE 0x04 +#define LIMA_MMU_COMMAND_PAGE_FAULT_DONE 0x05 +#define LIMA_MMU_COMMAND_HARD_RESET 0x06 +#define LIMA_MMU_PAGE_FAULT_ADDR 0x000C +#define LIMA_MMU_ZAP_ONE_LINE 0x0010 +#define LIMA_MMU_INT_RAWSTAT 0x0014 +#define LIMA_MMU_INT_CLEAR 0x0018 +#define LIMA_MMU_INT_MASK 0x001C +#define LIMA_MMU_INT_PAGE_FAULT 0x01 +#define LIMA_MMU_INT_READ_BUS_ERROR 0x02 +#define LIMA_MMU_INT_STATUS 0x0020 + +#define LIMA_VM_FLAG_PRESENT (1 << 0) +#define LIMA_VM_FLAG_READ_PERMISSION (1 << 1) +#define LIMA_VM_FLAG_WRITE_PERMISSION (1 << 2) +#define LIMA_VM_FLAG_OVERRIDE_CACHE (1 << 3) +#define LIMA_VM_FLAG_WRITE_CACHEABLE (1 << 4) +#define LIMA_VM_FLAG_WRITE_ALLOCATE (1 << 5) +#define LIMA_VM_FLAG_WRITE_BUFFERABLE (1 << 6) +#define LIMA_VM_FLAG_READ_CACHEABLE (1 << 7) +#define LIMA_VM_FLAG_READ_ALLOCATE (1 << 8) +#define LIMA_VM_FLAG_MASK 0x1FF + +#define LIMA_VM_FLAGS_CACHE ( \ + LIMA_VM_FLAG_PRESENT | \ + LIMA_VM_FLAG_READ_PERMISSION | \ + LIMA_VM_FLAG_WRITE_PERMISSION | \ + LIMA_VM_FLAG_OVERRIDE_CACHE | \ + LIMA_VM_FLAG_WRITE_CACHEABLE | \ + LIMA_VM_FLAG_WRITE_BUFFERABLE | \ + LIMA_VM_FLAG_READ_CACHEABLE | \ + LIMA_VM_FLAG_READ_ALLOCATE ) + +#define LIMA_VM_FLAGS_UNCACHE ( \ + LIMA_VM_FLAG_PRESENT | \ + LIMA_VM_FLAG_READ_PERMISSION | \ + LIMA_VM_FLAG_WRITE_PERMISSION ) + +/* DLBU regs */ +#define LIMA_DLBU_MASTER_TLLIST_PHYS_ADDR 0x0000 +#define LIMA_DLBU_MASTER_TLLIST_VADDR 0x0004 +#define LIMA_DLBU_TLLIST_VBASEADDR 0x0008 +#define LIMA_DLBU_FB_DIM 0x000C +#define LIMA_DLBU_TLLIST_CONF 0x0010 +#define LIMA_DLBU_START_TILE_POS 0x0014 +#define LIMA_DLBU_PP_ENABLE_MASK 0x0018 + +/* BCAST regs */ +#define LIMA_BCAST_BROADCAST_MASK 0x0 +#define LIMA_BCAST_INTERRUPT_MASK 0x4 + +#endif
Signature · 6 lines
2.17.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Sorry, I'm preparing RFC for lima driver, this mail is send by accident. Will resend a formal one latter.
Regards,
Qiang
Quoted 321 lines · Qiang Yu
From: Lima Project Developers <[email protected]>
Signed-off-by Qiang Yu <[email protected]>Signed-off-by Heiko Stuebner <[email protected]>--- drivers/gpu/drm/lima/lima_regs.h | 304 +++++++++++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 drivers/gpu/drm/lima/lima_regs.hdrivers/gpu/drm/lima/lima_ renamed from drivers/gpu/drm/lima/lima_regs.h +0
-0
regs.h
new file mode 100644
index 000000000000..ea4a37d69b98drivers/gpu/drm/lima/lima_regs.h new file +304
-1@@ -0,0 +1,304 @@ +/* +* Copyright (C) 2010-2017 ARM Limited. All rights reserved. +* Copyright (C) 2017-2018 Lima Project +* +* This program is free software and is provided to you under +* the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation, and any use by +* you of this program is subject to the terms of such GNU +* licence. +* +* A copy of the licence is included with the program, and +* can also be obtained from Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __LIMA_REGS_H__ +#define __LIMA_REGS_H__ + +/* PMU regs */ +#define LIMA_PMU_POWER_UP 0x00 +#define LIMA_PMU_POWER_DOWN 0x04 +#define LIMA_PMU_POWER_GP0_MASK (1 << 0) +#define LIMA_PMU_POWER_L2_MASK (1 << 1) +#define LIMA_PMU_POWER_PP_MASK (i) (1 << (2 + i)) + +/* +* On Mali450 each block automatically starts up its corresponding L2 +* and the PPs are not fully independent controllable. +* Instead PP0, PP1-3 and PP4-7 can be turned on or off. +*/ +#define LIMA450_PMU_POWER_PP0_MASK BIT(1) +#define LIMA450_PMU_POWER_PP13_MASK BIT(2) +#define LIMA450_PMU_POWER_PP47_MASK BIT(3) + +#define LIMA_PMU_STATUS 0x08 +#define LIMA_PMU_INT_MASK 0x0C +#define LIMA_PMU_INT_RAWSTAT 0x10 +#define LIMA_PMU_INT_CLEAR 0x18 +#define LIMA_PMU_INT_CMD_MASK (1 << 0) +#define LIMA_PMU_SW_DELAY 0x1C + +/* L2 cache regs */ +#define LIMA_L2_CACHE_SIZE 0x0004 +#define LIMA_L2_CACHE_STATUS 0x0008 +#define LIMA_L2_CACHE_STATUS_COMMAND_BUSY (1 << 0) +#define LIMA_L2_CACHE_STATUS_DATA_BUSY (1 << 1) +#define LIMA_L2_CACHE_COMMAND 0x0010 +#define LIMA_L2_CACHE_COMMAND_CLEAR_ALL (1 << 0) +#define LIMA_L2_CACHE_CLEAR_PAGE 0x0014 +#define LIMA_L2_CACHE_MAX_READS 0x0018 +#define LIMA_L2_CACHE_ENABLE 0x001C +#define LIMA_L2_CACHE_ENABLE_ACCESS (1 << 0) +#define LIMA_L2_CACHE_ENABLE_READ_ALLOCATE (1 << 1) +#define LIMA_L2_CACHE_PERFCNT_SRC0 0x0020 +#define LIMA_L2_CACHE_PERFCNT_VAL0 0x0024 +#define LIMA_L2_CACHE_PERFCNT_SRC1 0x0028 +#define LIMA_L2_CACHE_ERFCNT_VAL1 0x002C + +/* GP regs */ +#define LIMA_GP_VSCL_START_ADDR 0x00 +#define LIMA_GP_VSCL_END_ADDR 0x04 +#define LIMA_GP_PLBUCL_START_ADDR 0x08 +#define LIMA_GP_PLBUCL_END_ADDR 0x0c +#define LIMA_GP_PLBU_ALLOC_START_ADDR 0x10 +#define LIMA_GP_PLBU_ALLOC_END_ADDR 0x14 +#define LIMA_GP_CMD 0x20 +#define LIMA_GP_CMD_START_VS (1 << 0) +#define LIMA_GP_CMD_START_PLBU (1 << 1) +#define LIMA_GP_CMD_UPDATE_PLBU_ALLOC (1 << 4) +#define LIMA_GP_CMD_RESET (1 << 5) +#define LIMA_GP_CMD_FORCE_HANG (1 << 6) +#define LIMA_GP_CMD_STOP_BUS (1 << 9) +#define LIMA_GP_CMD_SOFT_RESET (1 << 10) +#define LIMA_GP_INT_RAWSTAT 0x24 +#define LIMA_GP_INT_CLEAR 0x28 +#define LIMA_GP_INT_MASK 0x2C +#define LIMA_GP_INT_STAT 0x30 +#define LIMA_GP_IRQ_VS_END_CMD_LST (1 << 0) +#define LIMA_GP_IRQ_PLBU_END_CMD_LST (1 << 1) +#define LIMA_GP_IRQ_PLBU_OUT_OF_MEM (1 << 2) +#define LIMA_GP_IRQ_VS_SEM_IRQ (1 << 3) +#define LIMA_GP_IRQ_PLBU_SEM_IRQ (1 << 4) +#define LIMA_GP_IRQ_HANG (1 << 5) +#define LIMA_GP_IRQ_FORCE_HANG (1 << 6) +#define LIMA_GP_IRQ_PERF_CNT_0_LIMIT (1 << 7) +#define LIMA_GP_IRQ_PERF_CNT_1_LIMIT (1 << 8) +#define LIMA_GP_IRQ_WRITE_BOUND_ERR (1 << 9) +#define LIMA_GP_IRQ_SYNC_ERROR (1 << 10) +#define LIMA_GP_IRQ_AXI_BUS_ERROR (1 << 11) +#define LIMA_GP_IRQ_AXI_BUS_STOPPED (1 << 12) +#define LIMA_GP_IRQ_VS_INVALID_CMD (1 << 13) +#define LIMA_GP_IRQ_PLB_INVALID_CMD (1 << 14) +#define LIMA_GP_IRQ_RESET_COMPLETED (1 << 19) +#define LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW (1 << 20) +#define LIMA_GP_IRQ_SEMAPHORE_OVERFLOW (1 << 21) +#define LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS (1 << 22) +#define LIMA_GP_WRITE_BOUND_LOW 0x34 +#define LIMA_GP_PERF_CNT_0_ENABLE 0x3C +#define LIMA_GP_PERF_CNT_1_ENABLE 0x40 +#define LIMA_GP_PERF_CNT_0_SRC 0x44 +#define LIMA_GP_PERF_CNT_1_SRC 0x48 +#define LIMA_GP_PERF_CNT_0_VALUE 0x4C +#define LIMA_GP_PERF_CNT_1_VALUE 0x50 +#define LIMA_GP_PERF_CNT_0_LIMIT 0x54 +#define LIMA_GP_STATUS 0x68 +#define LIMA_GP_STATUS_VS_ACTIVE (1 << 1) +#define LIMA_GP_STATUS_BUS_STOPPED (1 << 2) +#define LIMA_GP_STATUS_PLBU_ACTIVE (1 << 3) +#define LIMA_GP_STATUS_BUS_ERROR (1 << 6) +#define LIMA_GP_STATUS_WRITE_BOUND_ERR (1 << 8) +#define LIMA_GP_VERSION 0x6C +#define LIMA_GP_VSCL_START_ADDR_READ 0x80 +#define LIMA_GP_PLBCL_START_ADDR_READ 0x84 +#define LIMA_GP_CONTR_AXI_BUS_ERROR_STAT 0x94 + +#define LIMA_GP_IRQ_MASK_ALL \ + ( \ + LIMA_GP_IRQ_VS_END_CMD_LST | \ + LIMA_GP_IRQ_PLBU_END_CMD_LST | \ + LIMA_GP_IRQ_PLBU_OUT_OF_MEM | \ + LIMA_GP_IRQ_VS_SEM_IRQ | \ + LIMA_GP_IRQ_PLBU_SEM_IRQ | \ + LIMA_GP_IRQ_HANG | \ + LIMA_GP_IRQ_FORCE_HANG | \ + LIMA_GP_IRQ_PERF_CNT_0_LIMIT | \ + LIMA_GP_IRQ_PERF_CNT_1_LIMIT | \ + LIMA_GP_IRQ_WRITE_BOUND_ERR | \ + LIMA_GP_IRQ_SYNC_ERROR | \ + LIMA_GP_IRQ_AXI_BUS_ERROR | \ + LIMA_GP_IRQ_AXI_BUS_STOPPED | \ + LIMA_GP_IRQ_VS_INVALID_CMD | \ + LIMA_GP_IRQ_PLB_INVALID_CMD | \ + LIMA_GP_IRQ_RESET_COMPLETED | \ + LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW | \ + LIMA_GP_IRQ_SEMAPHORE_OVERFLOW | \ + LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS) + +#define LIMA_GP_IRQ_MASK_ERROR \ + ( \ + LIMA_GP_IRQ_PLBU_OUT_OF_MEM | \ + LIMA_GP_IRQ_FORCE_HANG | \ + LIMA_GP_IRQ_WRITE_BOUND_ERR | \ + LIMA_GP_IRQ_SYNC_ERROR | \ + LIMA_GP_IRQ_AXI_BUS_ERROR | \ + LIMA_GP_IRQ_VS_INVALID_CMD | \ + LIMA_GP_IRQ_PLB_INVALID_CMD | \ + LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW | \ + LIMA_GP_IRQ_SEMAPHORE_OVERFLOW | \ + LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS) + +#define LIMA_GP_IRQ_MASK_USED \ + ( \ + LIMA_GP_IRQ_VS_END_CMD_LST | \ + LIMA_GP_IRQ_PLBU_END_CMD_LST | \ + LIMA_GP_IRQ_MASK_ERROR) + +/* PP regs */ +#define LIMA_PP_FRAME 0x0000 +#define LIMA_PP_RSW 0x0004 +#define LIMA_PP_STACK 0x0030 +#define LIMA_PP_STACK_SIZE 0x0034 +#define LIMA_PP_ORIGIN_OFFSET_X 0x0040 +#define LIMA_PP_WB (i) (0x0100 * (i + 1)) +#define LIMA_PP_WB_SOURCE_SELECT 0x0000 +#define LIMA_PP_WB_SOURCE_ADDR 0x0004 + +#define LIMA_PP_VERSION 0x1000 +#define LIMA_PP_CURRENT_REND_LIST_ADDR 0x1004 +#define LIMA_PP_STATUS 0x1008 +#define LIMA_PP_STATUS_RENDERING_ACTIVE (1 << 0) +#define LIMA_PP_STATUS_BUS_STOPPED (1 << 4) +#define LIMA_PP_CTRL 0x100c +#define LIMA_PP_CTRL_STOP_BUS (1 << 0) +#define LIMA_PP_CTRL_FLUSH_CACHES (1 << 3) +#define LIMA_PP_CTRL_FORCE_RESET (1 << 5) +#define LIMA_PP_CTRL_START_RENDERING (1 << 6) +#define LIMA_PP_CTRL_SOFT_RESET (1 << 7) +#define LIMA_PP_INT_RAWSTAT 0x1020 +#define LIMA_PP_INT_CLEAR 0x1024 +#define LIMA_PP_INT_MASK 0x1028 +#define LIMA_PP_INT_STATUS 0x102c +#define LIMA_PP_IRQ_END_OF_FRAME (1 << 0) +#define LIMA_PP_IRQ_END_OF_TILE (1 << 1) +#define LIMA_PP_IRQ_HANG (1 << 2) +#define LIMA_PP_IRQ_FORCE_HANG (1 << 3) +#define LIMA_PP_IRQ_BUS_ERROR (1 << 4) +#define LIMA_PP_IRQ_BUS_STOP (1 << 5) +#define LIMA_PP_IRQ_CNT_0_LIMIT (1 << 6) +#define LIMA_PP_IRQ_CNT_1_LIMIT (1 << 7) +#define LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR (1 << 8) +#define LIMA_PP_IRQ_INVALID_PLIST_COMMAND (1 << 9) +#define LIMA_PP_IRQ_CALL_STACK_UNDERFLOW (1 << 10) +#define LIMA_PP_IRQ_CALL_STACK_OVERFLOW (1 << 11) +#define LIMA_PP_IRQ_RESET_COMPLETED (1 << 12) +#define LIMA_PP_WRITE_BOUNDARY_LOW 0x1044 +#define LIMA_PP_BUS_ERROR_STATUS 0x1050 +#define LIMA_PP_PERF_CNT_0_ENABLE 0x1080 +#define LIMA_PP_PERF_CNT_0_SRC 0x1084 +#define LIMA_PP_PERF_CNT_0_LIMIT 0x1088 +#define LIMA_PP_PERF_CNT_0_VALUE 0x108c +#define LIMA_PP_PERF_CNT_1_ENABLE 0x10a0 +#define LIMA_PP_PERF_CNT_1_SRC 0x10a4 +#define LIMA_PP_PERF_CNT_1_LIMIT 0x10a8 +#define LIMA_PP_PERF_CNT_1_VALUE 0x10ac +#define LIMA_PP_PERFMON_CONTR 0x10b0 +#define LIMA_PP_PERFMON_BASE 0x10b4 + +#define LIMA_PP_IRQ_MASK_ALL \ + ( \ + LIMA_PP_IRQ_END_OF_FRAME | \ + LIMA_PP_IRQ_END_OF_TILE | \ + LIMA_PP_IRQ_HANG | \ + LIMA_PP_IRQ_FORCE_HANG | \ + LIMA_PP_IRQ_BUS_ERROR | \ + LIMA_PP_IRQ_BUS_STOP | \ + LIMA_PP_IRQ_CNT_0_LIMIT | \ + LIMA_PP_IRQ_CNT_1_LIMIT | \ + LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR | \ + LIMA_PP_IRQ_INVALID_PLIST_COMMAND | \ + LIMA_PP_IRQ_CALL_STACK_UNDERFLOW | \ + LIMA_PP_IRQ_CALL_STACK_OVERFLOW | \ + LIMA_PP_IRQ_RESET_COMPLETED) + +#define LIMA_PP_IRQ_MASK_ERROR \ + ( \ + LIMA_PP_IRQ_FORCE_HANG | \ + LIMA_PP_IRQ_BUS_ERROR | \ + LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR | \ + LIMA_PP_IRQ_INVALID_PLIST_COMMAND | \ + LIMA_PP_IRQ_CALL_STACK_UNDERFLOW | \ + LIMA_PP_IRQ_CALL_STACK_OVERFLOW) + +#define LIMA_PP_IRQ_MASK_USED \ + ( \ + LIMA_PP_IRQ_END_OF_FRAME | \ + LIMA_PP_IRQ_MASK_ERROR) + +/* MMU regs */ +#define LIMA_MMU_DTE_ADDR 0x0000 +#define LIMA_MMU_STATUS 0x0004 +#define LIMA_MMU_STATUS_PAGING_ENABLED (1 << 0) +#define LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE (1 << 1) +#define LIMA_MMU_STATUS_STALL_ACTIVE (1 << 2) +#define LIMA_MMU_STATUS_IDLE (1 << 3) +#define LIMA_MMU_STATUS_REPLAY_BUFFER_EMPTY (1 << 4) +#define LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE (1 << 5) +#define LIMA_MMU_STATUS_BUS_ID (x) ((x >> 6) & 0x1F) +#define LIMA_MMU_COMMAND 0x0008 +#define LIMA_MMU_COMMAND_ENABLE_PAGING 0x00 +#define LIMA_MMU_COMMAND_DISABLE_PAGING 0x01 +#define LIMA_MMU_COMMAND_ENABLE_STALL 0x02 +#define LIMA_MMU_COMMAND_DISABLE_STALL 0x03 +#define LIMA_MMU_COMMAND_ZAP_CACHE 0x04 +#define LIMA_MMU_COMMAND_PAGE_FAULT_DONE 0x05 +#define LIMA_MMU_COMMAND_HARD_RESET 0x06 +#define LIMA_MMU_PAGE_FAULT_ADDR 0x000C +#define LIMA_MMU_ZAP_ONE_LINE 0x0010 +#define LIMA_MMU_INT_RAWSTAT 0x0014 +#define LIMA_MMU_INT_CLEAR 0x0018 +#define LIMA_MMU_INT_MASK 0x001C +#define LIMA_MMU_INT_PAGE_FAULT 0x01 +#define LIMA_MMU_INT_READ_BUS_ERROR 0x02 +#define LIMA_MMU_INT_STATUS 0x0020 + +#define LIMA_VM_FLAG_PRESENT (1 << 0) +#define LIMA_VM_FLAG_READ_PERMISSION (1 << 1) +#define LIMA_VM_FLAG_WRITE_PERMISSION (1 << 2) +#define LIMA_VM_FLAG_OVERRIDE_CACHE (1 << 3) +#define LIMA_VM_FLAG_WRITE_CACHEABLE (1 << 4) +#define LIMA_VM_FLAG_WRITE_ALLOCATE (1 << 5) +#define LIMA_VM_FLAG_WRITE_BUFFERABLE (1 << 6) +#define LIMA_VM_FLAG_READ_CACHEABLE (1 << 7) +#define LIMA_VM_FLAG_READ_ALLOCATE (1 << 8) +#define LIMA_VM_FLAG_MASK 0x1FF + +#define LIMA_VM_FLAGS_CACHE ( \ + LIMA_VM_FLAG_PRESENT | \ + LIMA_VM_FLAG_READ_PERMISSION | \ + LIMA_VM_FLAG_WRITE_PERMISSION | \ + LIMA_VM_FLAG_OVERRIDE_CACHE | \ + LIMA_VM_FLAG_WRITE_CACHEABLE | \ + LIMA_VM_FLAG_WRITE_BUFFERABLE | \ + LIMA_VM_FLAG_READ_CACHEABLE | \ + LIMA_VM_FLAG_READ_ALLOCATE ) + +#define LIMA_VM_FLAGS_UNCACHE ( \ + LIMA_VM_FLAG_PRESENT | \ + LIMA_VM_FLAG_READ_PERMISSION | \ + LIMA_VM_FLAG_WRITE_PERMISSION ) + +/* DLBU regs */ +#define LIMA_DLBU_MASTER_TLLIST_PHYS_ADDR 0x0000 +#define LIMA_DLBU_MASTER_TLLIST_VADDR 0x0004 +#define LIMA_DLBU_TLLIST_VBASEADDR 0x0008 +#define LIMA_DLBU_FB_DIM 0x000C +#define LIMA_DLBU_TLLIST_CONF 0x0010 +#define LIMA_DLBU_START_TILE_POS 0x0014 +#define LIMA_DLBU_PP_ENABLE_MASK 0x0018 + +/* BCAST regs */ +#define LIMA_BCAST_BROADCAST_MASK 0x0 +#define LIMA_BCAST_INTERRUPT_MASK 0x4 + +#endif --
Quoted 3 lines
2.17.0
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Qiang Yu
maintainerRFC 8/24 drm/lima: add lima core driver
In reply to a message not in the archiveFrom: Lima Project Developers <[email protected]>
--- drivers/gpu/drm/lima/lima_drv.c | 466 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/lima/lima_drv.h | 77 ++++++ 2 files changed, 543 insertions(+) create mode 100644 drivers/gpu/drm/lima/lima_drv.c create mode 100644 drivers/gpu/drm/lima/lima_drv.h
drivers/gpu/drm/lima/lima_drv.c new file +466 -0
@@ -0,0 +1,466 @@ +/* +* Copyright (C) 2017-2018 Lima Project +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/log2.h> +#include <drm/drm_prime.h> +#include <drm/lima_drm.h> + +#include "lima_drv.h" +#include "lima_gem.h" +#include "lima_gem_prime.h" +#include "lima_vm.h" + +int lima_sched_timeout_ms =0 ; +int lima_sched_max_tasks =32 ; +int lima_max_mem =-1 ; + +MODULE_PARM_DESC (sched_timeout_ms,"task run timeout in ms (0 = no timeout (default))" ); +module_param_named (sched_timeout_ms, lima_sched_timeout_ms, int,0444 ); + +MODULE_PARM_DESC (sched_max_tasks,"max queued task num in a context (default 32)" ); +module_param_named (sched_max_tasks, lima_sched_max_tasks, int,0444 ); + +MODULE_PARM_DESC (max_mem,"Max memory size in MB can be used (<0 = auto)" ); +module_param_named (max_mem, lima_max_mem, int,0444 ); + +static int lima_ioctl_info (struct drm_device *dev,void *data,struct drm_file *file) +{ +struct drm_lima_info *info = data; +struct lima_device *ldev =to_lima_dev (dev); + +switch (ldev->id) { +case lima_gpu_mali400: + info->gpu_id =LIMA_INFO_GPU_MALI400 ; +break ; +case lima_gpu_mali450: + info->gpu_id =LIMA_INFO_GPU_MALI450 ; +break ; +default : +return -ENODEV ; + } + info->num_pp = ldev->pipe[lima_pipe_pp].num_processor; + info->va_start = ldev->va_start; + info->va_end = ldev->va_end; +return 0 ; +} + +static int lima_ioctl_gem_create (struct drm_device *dev,void *data,struct drm_file *file) +{ +struct drm_lima_gem_create *args = data; + +if (args->flags) +return -EINVAL ; + +if (args->size ==0 ) +return -EINVAL ; + +return lima_gem_create_handle (dev, file, args->size, args->flags, &args->handle); +} + +static int lima_ioctl_gem_info (struct drm_device *dev,void *data,struct drm_file *file) +{ +struct drm_lima_gem_info *args = data; + +return lima_gem_mmap_offset (file, args->handle, &args->offset); +} + +static int lima_ioctl_gem_va (struct drm_device *dev,void *data,struct drm_file *file) +{ +struct drm_lima_gem_va *args = data; + +switch (args->op) { +case LIMA_VA_OP_MAP : +return lima_gem_va_map (file, args->handle, args->flags, args->va); +case LIMA_VA_OP_UNMAP : +return lima_gem_va_unmap (file, args->handle, args->va); +default : +return -EINVAL ; + } +} + +static int lima_ioctl_gem_submit (struct drm_device *dev,void *data,struct drm_file *file) +{ +struct drm_lima_gem_submit_in *args = data; +struct lima_device *ldev =to_lima_dev (dev); +struct lima_drm_priv *priv = file->driver_priv; +struct drm_lima_gem_submit_bo *bos; +struct ttm_validate_buffer *vbs; +union drm_lima_gem_submit_dep *deps =NULL ; +struct lima_sched_pipe *pipe; +struct lima_sched_task *task; +struct lima_ctx *ctx; +struct lima_submit submit = {0 }; +int err =0 , size; + +if (args->pipe >= lima_pipe_num || args->nr_bos ==0 ) +return -EINVAL ; + +if (args->flags & ~(LIMA_SUBMIT_FLAG_EXPLICIT_FENCE | +LIMA_SUBMIT_FLAG_SYNC_FD_OUT )) +return -EINVAL ; + + pipe = ldev->pipe + args->pipe; +if (args->frame_size != pipe->frame_size) +return -EINVAL ; + + size = args->nr_bos * (sizeof (*submit.bos) +sizeof (*submit.vbs)) + + args->nr_deps *sizeof (*submit.deps); + bos =kzalloc (size,GFP_KERNEL ); +if (!bos) +return -ENOMEM ; + + size = args->nr_bos *sizeof (*submit.bos); +if (copy_from_user (bos,u64_to_user_ptr (args->bos), size)) { + err = -EFAULT ; + goto out0; + } + + vbs = (void *)bos + size; + +if (args->nr_deps) { + deps = (void *)vbs + args->nr_bos *sizeof (*submit.vbs); + size = args->nr_deps *sizeof (*submit.deps); +if (copy_from_user (deps,u64_to_user_ptr (args->deps), size)) { + err = -EFAULT ; + goto out0; + } + } + + task =kmem_cache_zalloc (pipe->task_slab,GFP_KERNEL ); +if (!task) { + err = -ENOMEM ; + goto out0; + } + + task->frame = task +1 ; +if (copy_from_user (task->frame,u64_to_user_ptr (args->frame), args->frame_size)) { + err = -EFAULT ; + goto out1; + } + + err = pipe->task_validate (pipe, task); +if (err) + goto out1; + + ctx =lima_ctx_get (&priv->ctx_mgr, args->ctx); +if (!ctx) { + err = -ENOENT ; + goto out1; + } + + submit.pipe = args->pipe; + submit.bos = bos; + submit.vbs = vbs; + submit.nr_bos = args->nr_bos; + submit.task = task; + submit.ctx = ctx; + submit.deps = deps; + submit.nr_deps = args->nr_deps; + submit.flags = args->flags; + + err =lima_gem_submit (file, &submit); +if (!err) { +struct drm_lima_gem_submit_out *out = data; + out->fence = submit.fence; + out->done = submit.done; + out->sync_fd = submit.sync_fd; + } + +lima_ctx_put (ctx); +out1: +if (err) +kmem_cache_free (pipe->task_slab, task); +out0: +kfree (bos); +return err; +} + +static int lima_wait_fence (struct dma_fence *fence,u64 timeout_ns) +{ +signed long ret; + +if (!timeout_ns) + ret =dma_fence_is_signaled (fence) ?0 : -EBUSY ; +else { +unsigned long timeout =lima_timeout_to_jiffies (timeout_ns); + +/* must use long for result check because in 64bit arch int +* will overflow if timeout is too large and get <0 result +*/ + ret =dma_fence_wait_timeout (fence, true, timeout); +if (ret ==0 ) + ret = timeout ? -ETIMEDOUT : -EBUSY ; +else if (ret >0 ) + ret =0 ; + } + +return ret; +} + +static int lima_ioctl_wait_fence (struct drm_device *dev,void *data,struct drm_file *file) +{ +struct drm_lima_wait_fence *args = data; +struct lima_drm_priv *priv = file->driver_priv; +struct dma_fence *fence; +int err =0 ; + + fence =lima_ctx_get_native_fence (&priv->ctx_mgr, args->ctx, + args->pipe, args->seq); +if (IS_ERR (fence)) +return PTR_ERR (fence); + +if (fence) { + err =lima_wait_fence (fence, args->timeout_ns); +dma_fence_put (fence); + } + +return err; +} + +static int lima_ioctl_gem_wait (struct drm_device *dev,void *data,struct drm_file *file) +{ +struct drm_lima_gem_wait *args = data; + +if (!(args->op & (LIMA_GEM_WAIT_READ |LIMA_GEM_WAIT_WRITE ))) +return -EINVAL ; + +return lima_gem_wait (file, args->handle, args->op, args->timeout_ns); +} + +static int lima_ioctl_ctx (struct drm_device *dev,void *data,struct drm_file *file) +{ +struct drm_lima_ctx *args = data; +struct lima_drm_priv *priv = file->driver_priv; +struct lima_device *ldev =to_lima_dev (dev); + +if (args->op ==LIMA_CTX_OP_CREATE ) +return lima_ctx_create (ldev, &priv->ctx_mgr, &args->id); +else if (args->op ==LIMA_CTX_OP_FREE ) +return lima_ctx_free (&priv->ctx_mgr, args->id); + +return -EINVAL ; +} + +static int lima_drm_driver_open (struct drm_device *dev,struct drm_file *file) +{ +int err; +struct lima_drm_priv *priv; +struct lima_device *ldev =to_lima_dev (dev); + + priv =kzalloc (sizeof (*priv),GFP_KERNEL ); +if (!priv) +return -ENOMEM ; + + priv->vm =lima_vm_create (ldev); +if (!priv->vm) { + err = -ENOMEM ; + goto err_out0; + } + +lima_ctx_mgr_init (&priv->ctx_mgr); + + file->driver_priv = priv; +return 0 ; + +err_out0: +kfree (priv); +return err; +} + +static void lima_drm_driver_preclose (struct drm_device *dev,struct drm_file *file) +{ +struct lima_drm_priv *priv = file->driver_priv; + +lima_ctx_mgr_fini (&priv->ctx_mgr); +} + +static void lima_drm_driver_postclose (struct drm_device *dev,struct drm_file *file) +{ +struct lima_drm_priv *priv = file->driver_priv; + +lima_vm_put (priv->vm); +kfree (priv); +} + +static const struct drm_ioctl_desc lima_drm_driver_ioctls[] = { +DRM_IOCTL_DEF_DRV (LIMA_INFO , lima_ioctl_info,DRM_AUTH |DRM_RENDER_ALLOW ), +DRM_IOCTL_DEF_DRV (LIMA_GEM_CREATE , lima_ioctl_gem_create,DRM_AUTH |DRM_RENDER_ALLOW ), +DRM_IOCTL_DEF_DRV (LIMA_GEM_INFO , lima_ioctl_gem_info,DRM_AUTH |DRM_RENDER_ALLOW ), +DRM_IOCTL_DEF_DRV (LIMA_GEM_VA , lima_ioctl_gem_va,DRM_AUTH |DRM_RENDER_ALLOW ), +DRM_IOCTL_DEF_DRV (LIMA_GEM_SUBMIT , lima_ioctl_gem_submit,DRM_AUTH |DRM_RENDER_ALLOW ), +DRM_IOCTL_DEF_DRV (LIMA_WAIT_FENCE , lima_ioctl_wait_fence,DRM_AUTH |DRM_RENDER_ALLOW ), +DRM_IOCTL_DEF_DRV (LIMA_GEM_WAIT , lima_ioctl_gem_wait,DRM_AUTH |DRM_RENDER_ALLOW ), +DRM_IOCTL_DEF_DRV (LIMA_CTX , lima_ioctl_ctx,DRM_AUTH |DRM_RENDER_ALLOW ), +}; + +static const struct file_operations lima_drm_driver_fops = { + .owner =THIS_MODULE , + .open = drm_open, + .release = drm_release, + .unlocked_ioctl = drm_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, +#endif + .mmap = lima_gem_mmap, +}; + +static struct drm_driver lima_drm_driver = { + .driver_features =DRIVER_RENDER |DRIVER_GEM |DRIVER_PRIME , + .open = lima_drm_driver_open, + .preclose = lima_drm_driver_preclose, + .postclose = lima_drm_driver_postclose, + .ioctls = lima_drm_driver_ioctls, + .num_ioctls =ARRAY_SIZE (lima_drm_driver_ioctls), + .fops = &lima_drm_driver_fops, + .gem_free_object_unlocked = lima_gem_free_object, + .gem_open_object = lima_gem_object_open, + .gem_close_object = lima_gem_object_close, + .name ="lima" , + .desc ="lima DRM" , + .date ="20170325" , + .major =1 , + .minor =0 , + .patchlevel =0 , + + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .gem_prime_import = drm_gem_prime_import, + .gem_prime_import_sg_table = lima_gem_prime_import_sg_table, + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, + .gem_prime_export = drm_gem_prime_export, + .gem_prime_res_obj = lima_gem_prime_res_obj, + .gem_prime_get_sg_table = lima_gem_prime_get_sg_table, +}; + +static int lima_pdev_probe (struct platform_device *pdev) +{ +struct lima_device *ldev; +struct drm_device *ddev; +int err; + + ldev =devm_kzalloc (&pdev->dev,sizeof (*ldev),GFP_KERNEL ); +if (!ldev) +return -ENOMEM ; + + ldev->pdev = pdev; + ldev->dev = &pdev->dev; + ldev->id = (enum lima_gpu_id )of_device_get_match_data (&pdev->dev); + +platform_set_drvdata (pdev, ldev); + +/* Allocate and initialize the DRM device. */ + ddev =drm_dev_alloc (&lima_drm_driver, &pdev->dev); +if (IS_ERR (ddev)) +return PTR_ERR (ddev); + + ddev->dev_private = ldev; + ldev->ddev = ddev; + + err =lima_device_init (ldev); +if (err) { +dev_err (&pdev->dev,"Fatal error during GPU init\n" ); + goto err_out0; + } + +/* +* Register the DRM device with the core and the connectors with +* sysfs. +*/ + err =drm_dev_register (ddev,0 ); +if (err <0 ) + goto err_out1; + +return 0 ; + +err_out1: +lima_device_fini (ldev); +err_out0: +drm_dev_unref (ddev); +return err; +} + +static int lima_pdev_remove (struct platform_device *pdev) +{ +struct lima_device *ldev =platform_get_drvdata (pdev); +struct drm_device *ddev = ldev->ddev; + +drm_dev_unregister (ddev); +lima_device_fini (ldev); +drm_dev_unref (ddev); +return 0 ; +} + +static const struct of_device_id dt_match[] = { + { .compatible ="arm,mali-400" , .data = (void *)lima_gpu_mali400 }, + { .compatible ="arm,mali-450" , .data = (void *)lima_gpu_mali450 }, + {} +}; +MODULE_DEVICE_TABLE (of, dt_match); + +static struct platform_driver lima_platform_driver = { + .probe = lima_pdev_probe, + .remove = lima_pdev_remove, + .driver = { + .name ="lima" , + .of_match_table = dt_match, + }, +}; + +static void lima_check_module_param (void ) +{ +if (lima_sched_max_tasks <4 ) + lima_sched_max_tasks =4 ; +else + lima_sched_max_tasks =roundup_pow_of_two (lima_sched_max_tasks); + +if (lima_max_mem <32 ) + lima_max_mem =-1 ; +} + +static int __init lima_init (void ) +{ +int ret; + +lima_check_module_param (); + ret =lima_sched_slab_init (); +if (ret) +return ret; + + ret =platform_driver_register (&lima_platform_driver); +if (ret) +lima_sched_slab_fini (); + +return ret; +} +module_init (lima_init); + +static void __exit lima_exit(void) +{ +platform_driver_unregister (&lima_platform_driver); +lima_sched_slab_fini (); +} +module_exit (lima_exit); + +MODULE_AUTHOR ("Lima Project Developers" ); +MODULE_DESCRIPTION ("Lima DRM Driver" ); +MODULE_LICENSE ("GPL v2" );
drivers/gpu/drm/lima/lima_drv.h new file +77 -0
77 lines not on this page · raw message
Signature · 6 lines
2.17.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Qiang Yu
maintainerRFC 9/24 drm/lima: add GPU device functions
In reply to a message not in the archiveFrom: Lima Project Developers <[email protected]>
--- drivers/gpu/drm/lima/lima_device.c | 407 +++++++++++++++++++++++++++++ drivers/gpu/drm/lima/lima_device.h | 136 ++++++++++ 2 files changed, 543 insertions(+) create mode 100644 drivers/gpu/drm/lima/lima_device.c create mode 100644 drivers/gpu/drm/lima/lima_device.h
drivers/gpu/drm/lima/lima_device.c new file +407 -0
@@ -0,0 +1,407 @@ +/* +* Copyright (C) 2017-2018 Lima Project +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ +#include <linux/regulator/consumer.h> +#include <linux/reset.h> +#include <linux/clk.h> +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> + +#include "lima_device.h" +#include "lima_gp.h" +#include "lima_pp.h" +#include "lima_mmu.h" +#include "lima_pmu.h" +#include "lima_l2_cache.h" +#include "lima_dlbu.h" +#include "lima_bcast.h" +#include "lima_vm.h" + +struct lima_ip_desc { +char *name; +char *irq_name; +bool must_have[lima_gpu_num]; +int offset[lima_gpu_num]; + +int (*init)(struct lima_ip *); +void (*fini)(struct lima_ip *); +}; + +#define LIMA_IP_DESC (ipname, mst0, mst1, off0, off1, func, irq) \ + [lima_ip_##ipname] = { \ + .name = #ipname, \ + .irq_name = irq, \ + .must_have = { \ + [lima_gpu_mali400] = mst0, \ + [lima_gpu_mali450] = mst1, \ + }, \ + .offset = { \ + [lima_gpu_mali400] = off0, \ + [lima_gpu_mali450] = off1, \ + }, \ + .init = lima_##func##_init, \ + .fini = lima_##func##_fini, \ + } + +static struct lima_ip_desc lima_ip_desc[lima_ip_num] = { +LIMA_IP_DESC (pmu, false, false,0x02000 ,0x02000 , pmu,"pmu" ), +LIMA_IP_DESC (l2_cache0, true, true,0x01000 ,0x10000 , l2_cache,NULL ), +LIMA_IP_DESC (l2_cache1, false, true,-1 ,0x01000 , l2_cache,NULL ), +LIMA_IP_DESC (l2_cache2, false, false,-1 ,0x11000 , l2_cache,NULL ), +LIMA_IP_DESC (gp, true, true,0x00000 ,0x00000 , gp,"gp" ), +LIMA_IP_DESC (pp0, true, true,0x08000 ,0x08000 , pp,"pp0" ), +LIMA_IP_DESC (pp1, false, false,0x0A000 ,0x0A000 , pp,"pp1" ), +LIMA_IP_DESC (pp2, false, false,0x0C000 ,0x0C000 , pp,"pp2" ), +LIMA_IP_DESC (pp3, false, false,0x0E000 ,0x0E000 , pp,"pp3" ), +LIMA_IP_DESC (pp4, false, false,-1 ,0x28000 , pp,"pp4" ), +LIMA_IP_DESC (pp5, false, false,-1 ,0x2A000 , pp,"pp5" ), +LIMA_IP_DESC (pp6, false, false,-1 ,0x2C000 , pp,"pp6" ), +LIMA_IP_DESC (pp7, false, false,-1 ,0x2E000 , pp,"pp7" ), +LIMA_IP_DESC (gpmmu, true, true,0x03000 ,0x03000 , mmu,"gpmmu" ), +LIMA_IP_DESC (ppmmu0, true, true,0x04000 ,0x04000 , mmu,"ppmmu0" ), +LIMA_IP_DESC (ppmmu1, false, false,0x05000 ,0x05000 , mmu,"ppmmu1" ), +LIMA_IP_DESC (ppmmu2, false, false,0x06000 ,0x06000 , mmu,"ppmmu2" ), +LIMA_IP_DESC (ppmmu3, false, false,0x07000 ,0x07000 , mmu,"ppmmu3" ), +LIMA_IP_DESC (ppmmu4, false, false,-1 ,0x1C000 , mmu,"ppmmu4" ), +LIMA_IP_DESC (ppmmu5, false, false,-1 ,0x1D000 , mmu,"ppmmu5" ), +LIMA_IP_DESC (ppmmu6, false, false,-1 ,0x1E000 , mmu,"ppmmu6" ), +LIMA_IP_DESC (ppmmu7, false, false,-1 ,0x1F000 , mmu,"ppmmu7" ), +LIMA_IP_DESC (dlbu, false, true,-1 ,0x14000 , dlbu,NULL ), +LIMA_IP_DESC (bcast, false, true,-1 ,0x13000 , bcast,NULL ), +LIMA_IP_DESC (pp_bcast, false, true,-1 ,0x16000 , pp_bcast,"pp" ), +LIMA_IP_DESC (ppmmu_bcast, false, true,-1 ,0x15000 , mmu,NULL ), +}; + +const char *lima_ip_name (struct lima_ip *ip) +{ +return lima_ip_desc[ip->id].name; +} + +static int lima_clk_init (struct lima_device *dev) +{ +int err; +unsigned long bus_rate, gpu_rate; + + dev->clk_bus =devm_clk_get (dev->dev,"bus" ); +if (IS_ERR (dev->clk_bus)) { +dev_err (dev->dev,"get bus clk failed %ld\n" ,PTR_ERR (dev->clk_bus)); +return PTR_ERR (dev->clk_bus); + } + + dev->clk_gpu =devm_clk_get (dev->dev,"core" ); +if (IS_ERR (dev->clk_gpu)) { +dev_err (dev->dev,"get core clk failed %ld\n" ,PTR_ERR (dev->clk_gpu)); +return PTR_ERR (dev->clk_gpu); + } + + bus_rate =clk_get_rate (dev->clk_bus); +dev_info (dev->dev,"bus rate = %lu\n" , bus_rate); + + gpu_rate =clk_get_rate (dev->clk_gpu); +dev_info (dev->dev,"mod rate = %lu" , gpu_rate); + +if ((err =clk_prepare_enable (dev->clk_bus))) +return err; +if ((err =clk_prepare_enable (dev->clk_gpu))) + goto error_out0; + + dev->reset =devm_reset_control_get_optional (dev->dev,NULL ); +if (IS_ERR (dev->reset)) { + err =PTR_ERR (dev->reset); + goto error_out1; + }else if (dev->reset !=NULL ) { +if ((err =reset_control_deassert (dev->reset))) + goto error_out1; + } + +return 0 ; + +error_out1: +clk_disable_unprepare (dev->clk_gpu); +error_out0: +clk_disable_unprepare (dev->clk_bus); +return err; +} + +static void lima_clk_fini (struct lima_device *dev) +{ +if (dev->reset !=NULL ) +reset_control_assert (dev->reset); +clk_disable_unprepare (dev->clk_gpu); +clk_disable_unprepare (dev->clk_bus); +} + +static int lima_regulator_init (struct lima_device *dev) +{ +int ret; + dev->regulator =devm_regulator_get_optional (dev->dev,"mali" ); +if (IS_ERR (dev->regulator)) { + ret =PTR_ERR (dev->regulator); + dev->regulator =NULL ; +if (ret == -ENODEV ) +return 0 ; +dev_err (dev->dev,"failed to get regulator: %ld\n" ,PTR_ERR (dev->regulator)); +return ret; + } + + ret =regulator_enable (dev->regulator); +if (ret <0 ) { +dev_err (dev->dev,"failed to enable regulator: %d\n" , ret); +return ret; + } + +return 0 ; +} + +static void lima_regulator_fini (struct lima_device *dev) +{ +if (dev->regulator) +regulator_disable (dev->regulator); +} + +static int lima_init_ip (struct lima_device *dev,int index) +{ +struct lima_ip_desc *desc = lima_ip_desc + index; +struct lima_ip *ip = dev->ip + index; +int offset = desc->offset[dev->id]; +bool must = desc->must_have[dev->id]; +int err; + +if (offset <0 ) +return 0 ; + + ip->dev = dev; + ip->id = index; + ip->iomem = dev->iomem + offset; +if (desc->irq_name) { + err =platform_get_irq_byname (dev->pdev, desc->irq_name); +if (err <0 ) + goto out; + ip->irq = err; + } + + err = desc->init (ip); +if (!err) { + ip->present = true; +return 0 ; + } + +out: +return must ? err :0 ; +} + +static void lima_fini_ip (struct lima_device *ldev,int index) +{ +struct lima_ip_desc *desc = lima_ip_desc + index; +struct lima_ip *ip = ldev->ip + index; + +if (ip->present) + desc->fini (ip); +} + +static int lima_init_gp_pipe (struct lima_device *dev) +{ +struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp; +int err; + +if ((err =lima_sched_pipe_init (pipe,"gp" ))) +return err; + + pipe->l2_cache[pipe->num_l2_cache++] = dev->ip + lima_ip_l2_cache0; + pipe->mmu[pipe->num_mmu++] = dev->ip + lima_ip_gpmmu; + pipe->processor[pipe->num_processor++] = dev->ip + lima_ip_gp; + +if ((err =lima_gp_pipe_init (dev))) { +lima_sched_pipe_fini (pipe); +return err; + } + +return 0 ; +} + +static void lima_fini_gp_pipe (struct lima_device *dev) +{ +struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp; + +lima_gp_pipe_fini (dev); +lima_sched_pipe_fini (pipe); +} + +static int lima_init_pp_pipe (struct lima_device *dev) +{ +struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; +int err, i; + +if ((err =lima_sched_pipe_init (pipe,"pp" ))) +return err; + +for (i =0 ; i <LIMA_SCHED_PIPE_MAX_PROCESSOR ; i++) { +struct lima_ip *pp = dev->ip + lima_ip_pp0 + i; +struct lima_ip *ppmmu = dev->ip + lima_ip_ppmmu0 + i; +struct lima_ip *l2_cache; + +if (dev->id == lima_gpu_mali400) + l2_cache = dev->ip + lima_ip_l2_cache0; +else + l2_cache = dev->ip + lima_ip_l2_cache1 + (i >>2 ); + +if (pp->present && ppmmu->present && l2_cache->present) { + pipe->mmu[pipe->num_mmu++] = ppmmu; + pipe->processor[pipe->num_processor++] = pp; +if (!pipe->l2_cache[i >>2 ]) + pipe->l2_cache[pipe->num_l2_cache++] = l2_cache; + } + } + +if (dev->ip[lima_ip_bcast].present) { + pipe->bcast_processor = dev->ip + lima_ip_pp_bcast; + pipe->bcast_mmu = dev->ip + lima_ip_ppmmu_bcast; + } + +if ((err =lima_pp_pipe_init (dev))) { +lima_sched_pipe_fini (pipe); +return err; + } + +return 0 ; +} + +static void lima_fini_pp_pipe (struct lima_device *dev) +{ +struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; + +lima_pp_pipe_fini (dev); +lima_sched_pipe_fini (pipe); +} + +int lima_device_init (struct lima_device *ldev) +{ +int err, i; +struct resource *res; + +dma_set_coherent_mask (ldev->dev,DMA_BIT_MASK (32 )); + + err =lima_clk_init (ldev); +if (err) { +dev_err (ldev->dev,"clk init fail %d\n" , err); +return err; + } + +if ((err =lima_regulator_init (ldev))) { +dev_err (ldev->dev,"regulator init fail %d\n" , err); + goto err_out0; + } + + err =lima_ttm_init (ldev); +if (err) + goto err_out1; + + ldev->empty_vm =lima_vm_create (ldev); +if (!ldev->empty_vm) { + err = -ENOMEM ; + goto err_out2; + } + + ldev->va_start =0 ; +if (ldev->id == lima_gpu_mali450) { + ldev->va_end =LIMA_VA_RESERVE_START ; + ldev->dlbu_cpu =dma_alloc_wc ( + ldev->dev,LIMA_PAGE_SIZE , + &ldev->dlbu_dma,GFP_KERNEL ); +if (!ldev->dlbu_cpu) { + err = -ENOMEM ; + goto err_out3; + } + } +else + ldev->va_end =LIMA_VA_RESERVE_END ; + + res =platform_get_resource (ldev->pdev,IORESOURCE_MEM ,0 ); + ldev->iomem =devm_ioremap_resource (ldev->dev, res); +if (IS_ERR (ldev->iomem)) { +dev_err (ldev->dev,"fail to ioremap iomem\n" ); + err =PTR_ERR (ldev->iomem); + goto err_out4; + } + +for (i =0 ; i < lima_ip_num; i++) { + err =lima_init_ip (ldev, i); +if (err) + goto err_out5; + } + + err =lima_init_gp_pipe (ldev); +if (err) + goto err_out5; + + err =lima_init_pp_pipe (ldev); +if (err) + goto err_out6; + +if (ldev->id == lima_gpu_mali450) { +lima_dlbu_enable (ldev); +lima_bcast_enable (ldev); + } + +return 0 ; + +err_out6: +lima_fini_gp_pipe (ldev); +err_out5: +while (--i >=0 ) +lima_fini_ip (ldev, i); +err_out4: +if (ldev->dlbu_cpu) +dma_free_wc (ldev->dev,LIMA_PAGE_SIZE , + ldev->dlbu_cpu, ldev->dlbu_dma); +err_out3: +lima_vm_put (ldev->empty_vm); +err_out2: +lima_ttm_fini (ldev); +err_out1: +lima_regulator_fini (ldev); +err_out0: +lima_clk_fini (ldev); +return err; +} + +void lima_device_fini (struct lima_device *ldev) +{ +int i; + +lima_fini_pp_pipe (ldev); +lima_fini_gp_pipe (ldev); + +for (i = lima_ip_num -1 ; i >=0 ; i--) +lima_fini_ip (ldev, i); + +if (ldev->dlbu_cpu) +dma_free_wc (ldev->dev,LIMA_PAGE_SIZE , + ldev->dlbu_cpu, ldev->dlbu_dma); + +lima_vm_put (ldev->empty_vm); + +lima_ttm_fini (ldev); + +lima_regulator_fini (ldev); + +lima_clk_fini (ldev); +}
drivers/gpu/drm/lima/lima_device.h new file +136 -0
136 lines not on this page · raw message
Signature · 6 lines
2.17.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Qiang Yu
maintainerRFC 10/24 drm/lima: add PMU related functions
In reply to a message not in the archiveFrom: Lima Project Developers <[email protected]>
--- drivers/gpu/drm/lima/lima_pmu.c | 85 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/lima/lima_pmu.h | 30 ++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 drivers/gpu/drm/lima/lima_pmu.c create mode 100644 drivers/gpu/drm/lima/lima_pmu.h
drivers/gpu/drm/lima/lima_pmu.c new file +85 -0
@@ -0,0 +1,85 @@ +/* +* Copyright (C) 2017-2018 Lima Project +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <linux/of.h> +#include <linux/io.h> +#include <linux/device.h> + +#include "lima_device.h" +#include "lima_pmu.h" +#include "lima_regs.h" + +#define pmu_write (reg, data) writel(data, ip->iomem + LIMA_PMU_##reg) +#define pmu_read (reg) readl(ip->iomem + LIMA_PMU_##reg) + +static int lima_pmu_wait_cmd (struct lima_ip *ip) +{ +struct lima_device *dev = ip->dev; +u32 stat, timeout; + +for (timeout =1000000 ; timeout >0 ; timeout--) { + stat =pmu_read (INT_RAWSTAT ); +if (stat &LIMA_PMU_INT_CMD_MASK ) +break ; + } + +if (!timeout) { +dev_err (dev->dev,"timeout wait pmd cmd\n" ); +return -ETIMEDOUT ; + } + +pmu_write (INT_CLEAR ,LIMA_PMU_INT_CMD_MASK ); +return 0 ; +} + +int lima_pmu_init (struct lima_ip *ip) +{ +int err; +u32 stat; +struct lima_device *dev = ip->dev; +struct device_node *np = dev->dev->of_node; + +/* If this value is too low, when in high GPU clk freq, +* GPU will be in unstable state. */ +if (of_property_read_u32 (np,"switch-delay" , &ip->data.switch_delay)) + ip->data.switch_delay =0xff ; + +pmu_write (INT_MASK ,0 ); +pmu_write (SW_DELAY , ip->data.switch_delay); + +/* status reg 1=off 0=on */ + stat =pmu_read (STATUS ); + +/* power up all ip */ +if (stat) { +pmu_write (POWER_UP , stat); + err =lima_pmu_wait_cmd (ip); +if (err) +return err; + } +return 0 ; +} + +void lima_pmu_fini (struct lima_ip *ip) +{ + +}
drivers/gpu/drm/lima/lima_pmu.h new file +30 -0
@@ -0,0 +1,30 @@ +/* +* Copyright (C) 2017-2018 Lima Project +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef __LIMA_PMU_H__ +#define __LIMA_PMU_H__ + +struct lima_ip ; + +int lima_pmu_init (struct lima_ip *ip); +void lima_pmu_fini (struct lima_ip *ip); + +#endif
Signature · 6 lines
2.17.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Qiang Yu
maintainerRFC 13/24 drm/lima: add PP related functions
In reply to a message not in the archiveFrom: Lima Project Developers <[email protected]>
PP is a processor used for OpenGL fragment shader
processing.
--- drivers/gpu/drm/lima/lima_pp.c | 418 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/lima/lima_pp.h | 37 +++ 2 files changed, 455 insertions(+) create mode 100644 drivers/gpu/drm/lima/lima_pp.c create mode 100644 drivers/gpu/drm/lima/lima_pp.h
drivers/gpu/drm/lima/lima_pp.c new file +418 -0
@@ -0,0 +1,418 @@ +/* +* Copyright (C) 2017-2018 Lima Project +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/device.h> +#include <linux/slab.h> + +#include <drm/lima_drm.h> + +#include "lima_device.h" +#include "lima_pp.h" +#include "lima_dlbu.h" +#include "lima_bcast.h" +#include "lima_vm.h" +#include "lima_regs.h" + +#define pp_write (reg, data) writel(data, ip->iomem + LIMA_PP_##reg) +#define pp_read (reg) readl(ip->iomem + LIMA_PP_##reg) + +static void lima_pp_handle_irq (struct lima_ip *ip,u32 state) +{ +struct lima_device *dev = ip->dev; +struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; + +if (state &LIMA_PP_IRQ_MASK_ERROR ) { +u32 status =pp_read (STATUS ); + +dev_err (dev->dev,"pp error irq state=%x status=%x\n" , + state, status); + + pipe->error = true; + +/* mask all interrupts before hard reset */ +pp_write (INT_MASK ,0 ); + } + +pp_write (INT_CLEAR , state); +} + +static irqreturn_t lima_pp_irq_handler (int irq,void *data) +{ +struct lima_ip *ip = data; +struct lima_device *dev = ip->dev; +struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; +u32 state =pp_read (INT_STATUS ); + +/* for shared irq case */ +if (!state) +return IRQ_NONE ; + +lima_pp_handle_irq (ip, state); + +if (atomic_dec_and_test (&pipe->task)) +lima_sched_pipe_task_done (pipe); + +return IRQ_HANDLED ; +} + +static irqreturn_t lima_pp_bcast_irq_handler (int irq,void *data) +{ +int i; +irqreturn_t ret =IRQ_NONE ; +struct lima_ip *pp_bcast = data; +struct lima_device *dev = pp_bcast->dev; +struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; + +for (i =0 ; i < pipe->num_processor; i++) { +struct lima_ip *ip = pipe->processor[i]; +u32 status, state; + +if (pipe->done & (1 << i)) +continue ; + +/* status read first in case int state change in the middle +* which may miss the interrupt handling */ + status =pp_read (STATUS ); + state =pp_read (INT_STATUS ); + +if (state) { +lima_pp_handle_irq (ip, state); + ret =IRQ_HANDLED ; + } +else { +if (status &LIMA_PP_STATUS_RENDERING_ACTIVE ) +continue ; + } + + pipe->done |= (1 << i); +if (atomic_dec_and_test (&pipe->task)) +lima_sched_pipe_task_done (pipe); + } + +return ret; +} + +static void lima_pp_soft_reset_async (struct lima_ip *ip) +{ +if (ip->data.async_reset) +return ; + +pp_write (INT_MASK ,0 ); +pp_write (INT_RAWSTAT ,LIMA_PP_IRQ_MASK_ALL ); +pp_write (CTRL ,LIMA_PP_CTRL_SOFT_RESET ); + ip->data.async_reset = true; +} + +static int lima_pp_soft_reset_async_wait_one (struct lima_ip *ip) +{ +struct lima_device *dev = ip->dev; +int timeout; + +for (timeout =1000 ; timeout >0 ; timeout--) { +if (!(pp_read (STATUS ) &LIMA_PP_STATUS_RENDERING_ACTIVE ) && +pp_read (INT_RAWSTAT ) ==LIMA_PP_IRQ_RESET_COMPLETED ) +break ; + } +if (!timeout) { +dev_err (dev->dev,"pp %s reset time out\n" ,lima_ip_name (ip)); +return -ETIMEDOUT ; + } + +pp_write (INT_CLEAR ,LIMA_PP_IRQ_MASK_ALL ); +pp_write (INT_MASK ,LIMA_PP_IRQ_MASK_USED ); +return 0 ; +} + +static int lima_pp_soft_reset_async_wait (struct lima_ip *ip) +{ +int i, err =0 ; + +if (!ip->data.async_reset) +return 0 ; + +if (ip->id == lima_ip_pp_bcast) { +struct lima_device *dev = ip->dev; +struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; +for (i =0 ; i < pipe->num_processor; i++) + err |=lima_pp_soft_reset_async_wait_one (pipe->processor[i]); + } +else + err =lima_pp_soft_reset_async_wait_one (ip); + + ip->data.async_reset = false; +return err; +} + +static void lima_pp_start_task (struct lima_ip *ip,u32 *frame,u32 *wb, +bool skip_stack_addr) +{ +int i, j, n =0 ; + +for (i =0 ; i <LIMA_PP_FRAME_REG_NUM ; i++) { +if (skip_stack_addr && i *4 ==LIMA_PP_STACK ) +continue ; + +writel (frame[i], ip->iomem +LIMA_PP_FRAME + i *4 ); + } + +for (i =0 ; i <3 ; i++) { +for (j =0 ; j <LIMA_PP_WB_REG_NUM ; j++) +writel (wb[n++], ip->iomem +LIMA_PP_WB (i) + j *4 ); + } + +pp_write (CTRL ,LIMA_PP_CTRL_START_RENDERING ); +} + +static int lima_pp_hard_reset (struct lima_ip *ip) +{ +struct lima_device *dev = ip->dev; +int timeout; + +pp_write (PERF_CNT_0_LIMIT ,0xC0FFE000 ); +pp_write (INT_MASK ,0 ); +pp_write (CTRL ,LIMA_PP_CTRL_FORCE_RESET ); +for (timeout =1000 ; timeout >0 ; timeout--) { +pp_write (PERF_CNT_0_LIMIT ,0xC01A0000 ); +if (pp_read (PERF_CNT_0_LIMIT ) ==0xC01A0000 ) +break ; + } +if (!timeout) { +dev_err (dev->dev,"pp hard reset timeout\n" ); +return -ETIMEDOUT ; + } + +pp_write (PERF_CNT_0_LIMIT ,0 ); +pp_write (INT_CLEAR ,LIMA_PP_IRQ_MASK_ALL ); +pp_write (INT_MASK ,LIMA_PP_IRQ_MASK_USED ); +return 0 ; +} + +static void lima_pp_print_version (struct lima_ip *ip) +{ +u32 version, major, minor; +char *name; + + version =pp_read (VERSION ); + major = (version >>8 ) &0xFF ; + minor = version &0xFF ; +switch (version >>16 ) { +case 0xC807 : + name ="mali200" ; +break ; +case 0xCE07 : + name ="mali300" ; +break ; +case 0xCD07 : + name ="mali400" ; +break ; +case 0xCF07 : + name ="mali450" ; +break ; +default : + name ="unknow" ; +break ; + } +dev_info (ip->dev->dev,"%s - %s version major %d minor %d\n" , +lima_ip_name (ip), name, major, minor); +} + +int lima_pp_init (struct lima_ip *ip) +{ +struct lima_device *dev = ip->dev; +int err; + +lima_pp_print_version (ip); + + ip->data.async_reset = false; +lima_pp_soft_reset_async (ip); + err =lima_pp_soft_reset_async_wait (ip); +if (err) +return err; + + err =devm_request_irq (dev->dev, ip->irq, lima_pp_irq_handler, +IRQF_SHARED ,lima_ip_name (ip), ip); +if (err) { +dev_err (dev->dev,"pp %s fail to request irq\n" , +lima_ip_name (ip)); +return err; + } + +return 0 ; +} + +void lima_pp_fini (struct lima_ip *ip) +{ + +} + +int lima_pp_bcast_init (struct lima_ip *ip) +{ +struct lima_device *dev = ip->dev; +int err; + + err =devm_request_irq (dev->dev, ip->irq, lima_pp_bcast_irq_handler, +IRQF_SHARED ,lima_ip_name (ip), ip); +if (err) { +dev_err (dev->dev,"pp %s fail to request irq\n" , +lima_ip_name (ip)); +return err; + } + +return 0 ; +} + +void lima_pp_bcast_fini (struct lima_ip *ip) +{ + +} + +static int lima_pp_task_validate (struct lima_sched_pipe *pipe, +struct lima_sched_task *task) +{ +if (!pipe->bcast_processor) { +struct drm_lima_m400_pp_frame *f = task->frame; + +if (f->num_pp > pipe->num_processor) +return -EINVAL ; + } + +return 0 ; +} + +static void lima_pp_task_run (struct lima_sched_pipe *pipe, +struct lima_sched_task *task) +{ +if (pipe->bcast_processor) { +struct drm_lima_m450_pp_frame *frame = task->frame; +struct lima_device *dev = pipe->bcast_processor->dev; +int i; + + pipe->done =0 ; +atomic_set (&pipe->task, pipe->num_processor); + + frame->frame[LIMA_PP_FRAME >>2 ] =LIMA_VA_RESERVE_DLBU ; +lima_dlbu_set_reg (dev->ip + lima_ip_dlbu, frame->dlbu_regs); + +lima_pp_soft_reset_async_wait (pipe->bcast_processor); + +for (i =0 ; i < pipe->num_processor; i++) { +struct lima_ip *ip = pipe->processor[i]; +pp_write (STACK , frame->fragment_stack_address[i]); + } + +lima_pp_start_task (pipe->bcast_processor, frame->frame, + frame->wb, true); + } +else { +struct drm_lima_m400_pp_frame *frame = task->frame; +int i; + +atomic_set (&pipe->task, frame->num_pp); + +for (i =0 ; i < frame->num_pp; i++) { + frame->frame[LIMA_PP_FRAME >>2 ] = + frame->plbu_array_address[i]; + frame->frame[LIMA_PP_STACK >>2 ] = + frame->fragment_stack_address[i]; + +lima_pp_soft_reset_async_wait (pipe->processor[i]); + +lima_pp_start_task (pipe->processor[i], frame->frame, + frame->wb, false); + } + } +} + +static void lima_pp_task_fini (struct lima_sched_pipe *pipe) +{ +if (pipe->bcast_processor) +lima_pp_soft_reset_async (pipe->bcast_processor); +else { +int i; +for (i =0 ; i < pipe->num_processor; i++) +lima_pp_soft_reset_async (pipe->processor[i]); + } +} + +static void lima_pp_task_error (struct lima_sched_pipe *pipe) +{ +int i; + +if (pipe->bcast_processor) +lima_bcast_disable (pipe->bcast_processor->dev); + +for (i =0 ; i < pipe->num_processor; i++) +lima_pp_hard_reset (pipe->processor[i]); + +if (pipe->bcast_processor) +lima_bcast_enable (pipe->bcast_processor->dev); +} + +static void lima_pp_task_mmu_error (struct lima_sched_pipe *pipe) +{ +if (atomic_dec_and_test (&pipe->task)) +lima_sched_pipe_task_done (pipe); +} + +static struct kmem_cache *lima_pp_task_slab =NULL ; +static int lima_pp_task_slab_refcnt =0 ; + +int lima_pp_pipe_init (struct lima_device *dev) +{ +int frame_size; +struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; + +if (dev->id == lima_gpu_mali400) + frame_size =sizeof (struct drm_lima_m400_pp_frame ); +else + frame_size =sizeof (struct drm_lima_m450_pp_frame ); + +if (!lima_pp_task_slab) { + lima_pp_task_slab =kmem_cache_create ( +"lima_pp_task" ,sizeof (struct lima_sched_task ) + frame_size, +0 ,SLAB_HWCACHE_ALIGN ,NULL ); +if (!lima_pp_task_slab) +return -ENOMEM ; + } + lima_pp_task_slab_refcnt++; + + pipe->frame_size = frame_size; + pipe->task_slab = lima_pp_task_slab; + + pipe->task_validate = lima_pp_task_validate; + pipe->task_run = lima_pp_task_run; + pipe->task_fini = lima_pp_task_fini; + pipe->task_error = lima_pp_task_error; + pipe->task_mmu_error = lima_pp_task_mmu_error; + +return 0 ; +} + +void lima_pp_pipe_fini (struct lima_device *dev) +{ +if (!--lima_pp_task_slab_refcnt) { +kmem_cache_destroy (lima_pp_task_slab); + lima_pp_task_slab =NULL ; + } +}
drivers/gpu/drm/lima/lima_pp.h new file +37 -0
@@ -0,0 +1,37 @@ +/* +* Copyright (C) 2017-2018 Lima Project +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef __LIMA_PP_H__ +#define __LIMA_PP_H__ + +struct lima_ip ; +struct lima_device ; + +int lima_pp_init (struct lima_ip *ip); +void lima_pp_fini (struct lima_ip *ip); + +int lima_pp_bcast_init (struct lima_ip *ip); +void lima_pp_bcast_fini (struct lima_ip *ip); + +int lima_pp_pipe_init (struct lima_device *dev); +void lima_pp_pipe_fini (struct lima_device *dev); + +#endif
Signature · 6 lines
2.17.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Qiang Yu
maintainerRFC 14/24 drm/lima: add MMU related functions
In reply to a message not in the archiveFrom: Lima Project Developers <[email protected]>
--- drivers/gpu/drm/lima/lima_mmu.c | 154 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/lima/lima_mmu.h | 34 +++++++ 2 files changed, 188 insertions(+) create mode 100644 drivers/gpu/drm/lima/lima_mmu.c create mode 100644 drivers/gpu/drm/lima/lima_mmu.h
drivers/gpu/drm/lima/lima_mmu.c new file +154 -0
@@ -0,0 +1,154 @@ +/* +* Copyright (C) 2017-2018 Lima Project +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/device.h> + +#include "lima_device.h" +#include "lima_mmu.h" +#include "lima_vm.h" +#include "lima_object.h" +#include "lima_regs.h" + +#define mmu_write (reg, data) writel(data, ip->iomem + LIMA_MMU_##reg) +#define mmu_read (reg) readl(ip->iomem + LIMA_MMU_##reg) + +#define lima_mmu_send_command (command, condition) \ +({ \ + int __timeout, __ret = 0; \ + \ + mmu_write(COMMAND, command); \ + for (__timeout = 1000; __timeout > 0; __timeout--) { \ + if (condition) \ + break; \ + } \ + if (!__timeout) { \ + dev_err(dev->dev, "mmu command %x timeout\n", command); \ + __ret = -ETIMEDOUT; \ + } \ + __ret; \ +}) + +static irqreturn_t lima_mmu_irq_handler (int irq,void *data) +{ +struct lima_ip *ip = data; +struct lima_device *dev = ip->dev; +u32 status =mmu_read (INT_STATUS ); +struct lima_sched_pipe *pipe; + +/* for shared irq case */ +if (!status) +return IRQ_NONE ; + +if (status &LIMA_MMU_INT_PAGE_FAULT ) { +u32 fault =mmu_read (PAGE_FAULT_ADDR ); +dev_err (dev->dev,"mmu page fault at 0x%x from bus id %d of type %s on %s\n" , + fault,LIMA_MMU_STATUS_BUS_ID (status), + status &LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE ?"write" :"read" , +lima_ip_name (ip)); + } + +if (status &LIMA_MMU_INT_READ_BUS_ERROR ) { +dev_err (dev->dev,"mmu %s irq bus error\n" ,lima_ip_name (ip)); + } + +/* mask all interrupts before resume */ +mmu_write (INT_MASK ,0 ); +mmu_write (INT_CLEAR , status); + + pipe = dev->pipe + (ip->id == lima_ip_gpmmu ? lima_pipe_gp : lima_pipe_pp); +lima_sched_pipe_mmu_error (pipe); + +return IRQ_HANDLED ; +} + +int lima_mmu_init (struct lima_ip *ip) +{ +struct lima_device *dev = ip->dev; +int err; + +if (ip->id == lima_ip_ppmmu_bcast) +return 0 ; + +mmu_write (DTE_ADDR ,0xCAFEBABE ); +if (mmu_read (DTE_ADDR ) !=0xCAFEB000 ) { +dev_err (dev->dev,"mmu %s dte write test fail\n" ,lima_ip_name (ip)); +return -EIO ; + } + + err =lima_mmu_send_command (LIMA_MMU_COMMAND_HARD_RESET ,mmu_read (DTE_ADDR ) ==0 ); +if (err) +return err; + + err =devm_request_irq (dev->dev, ip->irq, lima_mmu_irq_handler, +IRQF_SHARED ,lima_ip_name (ip), ip); +if (err) { +dev_err (dev->dev,"mmu %s fail to request irq\n" ,lima_ip_name (ip)); +return err; + } + +mmu_write (INT_MASK ,LIMA_MMU_INT_PAGE_FAULT |LIMA_MMU_INT_READ_BUS_ERROR ); +mmu_write (DTE_ADDR , *lima_bo_get_pages (dev->empty_vm->pd)); +return lima_mmu_send_command (LIMA_MMU_COMMAND_ENABLE_PAGING , +mmu_read (STATUS ) &LIMA_MMU_STATUS_PAGING_ENABLED ); +} + +void lima_mmu_fini (struct lima_ip *ip) +{ + +} + +void lima_mmu_switch_vm (struct lima_ip *ip,struct lima_vm *vm) +{ +struct lima_device *dev = ip->dev; + +lima_mmu_send_command (LIMA_MMU_COMMAND_ENABLE_STALL , +mmu_read (STATUS ) &LIMA_MMU_STATUS_STALL_ACTIVE ); + +if (vm) +mmu_write (DTE_ADDR , *lima_bo_get_pages (vm->pd)); + +/* flush the TLB */ +mmu_write (COMMAND ,LIMA_MMU_COMMAND_ZAP_CACHE ); + +lima_mmu_send_command (LIMA_MMU_COMMAND_DISABLE_STALL , + !(mmu_read (STATUS ) &LIMA_MMU_STATUS_STALL_ACTIVE )); +} + +void lima_mmu_page_fault_resume (struct lima_ip *ip) +{ +struct lima_device *dev = ip->dev; +u32 status =mmu_read (STATUS ); + +if (status &LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE ) { +dev_info (dev->dev,"mmu resume\n" ); + +mmu_write (INT_MASK ,0 ); +mmu_write (DTE_ADDR ,0xCAFEBABE ); +lima_mmu_send_command (LIMA_MMU_COMMAND_HARD_RESET ,mmu_read (DTE_ADDR ) ==0 ); +mmu_write (INT_MASK ,LIMA_MMU_INT_PAGE_FAULT |LIMA_MMU_INT_READ_BUS_ERROR ); +mmu_write (DTE_ADDR , *lima_bo_get_pages (dev->empty_vm->pd)); +lima_mmu_send_command (LIMA_MMU_COMMAND_ENABLE_PAGING , +mmu_read (STATUS ) &LIMA_MMU_STATUS_PAGING_ENABLED ); + } +}
drivers/gpu/drm/lima/lima_mmu.h new file +34 -0
@@ -0,0 +1,34 @@ +/* +* Copyright (C) 2017-2018 Lima Project +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ +#ifndef __LIMA_MMU_H__ +#define __LIMA_MMU_H__ + +struct lima_ip ; +struct lima_vm ; + +int lima_mmu_init (struct lima_ip *ip); +void lima_mmu_fini (struct lima_ip *ip); + +void lima_mmu_switch_vm (struct lima_ip *ip,struct lima_vm *vm); +void lima_mmu_page_fault_resume (struct lima_ip *ip); + +#endif
Signature · 6 lines
2.17.0 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel