1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. |
4 | */ |
5 | |
6 | #ifndef MSM_DISP_SNAPSHOT_H_ |
7 | #define MSM_DISP_SNAPSHOT_H_ |
8 | |
9 | #include <drm/drm_atomic_helper.h> |
10 | #include <drm/drm_device.h> |
11 | #include "../../../drm_crtc_internal.h" |
12 | #include <drm/drm_print.h> |
13 | #include <drm/drm_atomic.h> |
14 | #include <linux/debugfs.h> |
15 | #include <linux/list.h> |
16 | #include <linux/delay.h> |
17 | #include <linux/spinlock.h> |
18 | #include <linux/ktime.h> |
19 | #include <linux/uaccess.h> |
20 | #include <linux/dma-buf.h> |
21 | #include <linux/slab.h> |
22 | #include <linux/list_sort.h> |
23 | #include <linux/pm.h> |
24 | #include <linux/pm_runtime.h> |
25 | #include <linux/kthread.h> |
26 | #include <linux/devcoredump.h> |
27 | #include "msm_kms.h" |
28 | |
29 | #define MSM_DISP_SNAPSHOT_MAX_BLKS 10 |
30 | |
31 | /* debug option to print the registers in logs */ |
32 | #define MSM_DISP_SNAPSHOT_DUMP_IN_CONSOLE 0 |
33 | |
34 | /* print debug ranges in groups of 4 u32s */ |
35 | #define REG_DUMP_ALIGN 16 |
36 | |
37 | /** |
38 | * struct msm_disp_state - structure to store current dpu state |
39 | * @dev: device pointer |
40 | * @drm_dev: drm device pointer |
41 | * @atomic_state: atomic state duplicated at the time of the error |
42 | * @time: timestamp at which the coredump was captured |
43 | */ |
44 | struct msm_disp_state { |
45 | struct device *dev; |
46 | struct drm_device *drm_dev; |
47 | |
48 | struct list_head blocks; |
49 | |
50 | struct drm_atomic_state *atomic_state; |
51 | |
52 | struct timespec64 time; |
53 | }; |
54 | |
55 | /** |
56 | * struct msm_disp_state_block - structure to store each hardware block state |
57 | * @name: name of the block |
58 | * @drm_dev: handle to the linked list head |
59 | * @size: size of the register space of this hardware block |
60 | * @state: array holding the register dump of this hardware block |
61 | * @base_addr: starting address of this hardware block's register space |
62 | */ |
63 | struct msm_disp_state_block { |
64 | char name[SZ_128]; |
65 | struct list_head node; |
66 | unsigned int size; |
67 | u32 *state; |
68 | void __iomem *base_addr; |
69 | }; |
70 | |
71 | /** |
72 | * msm_disp_snapshot_init - initialize display snapshot |
73 | * @drm_dev: drm device handle |
74 | * |
75 | * Returns: 0 or -ERROR |
76 | */ |
77 | int msm_disp_snapshot_init(struct drm_device *drm_dev); |
78 | |
79 | /** |
80 | * msm_disp_snapshot_destroy - destroy the display snapshot |
81 | * @drm_dev: drm device handle |
82 | * |
83 | * Returns: none |
84 | */ |
85 | void msm_disp_snapshot_destroy(struct drm_device *drm_dev); |
86 | |
87 | /** |
88 | * msm_disp_snapshot_state_sync - synchronously snapshot display state |
89 | * @kms: the kms object |
90 | * |
91 | * Returns state or error |
92 | * |
93 | * Must be called with &kms->dump_mutex held |
94 | */ |
95 | struct msm_disp_state *msm_disp_snapshot_state_sync(struct msm_kms *kms); |
96 | |
97 | /** |
98 | * msm_disp_snapshot_state - trigger to dump the display snapshot |
99 | * @drm_dev: handle to drm device |
100 | |
101 | * Returns: none |
102 | */ |
103 | void msm_disp_snapshot_state(struct drm_device *drm_dev); |
104 | |
105 | /** |
106 | * msm_disp_state_print - print out the current dpu state |
107 | * @disp_state: handle to drm device |
108 | * @p: handle to drm printer |
109 | * |
110 | * Returns: none |
111 | */ |
112 | void msm_disp_state_print(struct msm_disp_state *disp_state, struct drm_printer *p); |
113 | |
114 | /** |
115 | * msm_disp_snapshot_capture_state - utility to capture atomic state and hw registers |
116 | * @disp_state: handle to msm_disp_state struct |
117 | |
118 | * Returns: none |
119 | */ |
120 | void msm_disp_snapshot_capture_state(struct msm_disp_state *disp_state); |
121 | |
122 | /** |
123 | * msm_disp_state_free - free the memory after the coredump has been read |
124 | * @data: handle to struct msm_disp_state |
125 | |
126 | * Returns: none |
127 | */ |
128 | void msm_disp_state_free(void *data); |
129 | |
130 | /** |
131 | * msm_disp_snapshot_add_block - add a hardware block with its register dump |
132 | * @disp_state: handle to struct msm_disp_state |
133 | * @name: name of the hardware block |
134 | * @len: size of the register space of the hardware block |
135 | * @base_addr: starting address of the register space of the hardware block |
136 | * @fmt: format in which the block names need to be printed |
137 | * |
138 | * Returns: none |
139 | */ |
140 | __printf(4, 5) |
141 | void msm_disp_snapshot_add_block(struct msm_disp_state *disp_state, u32 len, |
142 | void __iomem *base_addr, const char *fmt, ...); |
143 | |
144 | #endif /* MSM_DISP_SNAPSHOT_H_ */ |
145 | |