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 */
44struct 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 */
63struct 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 */
77int 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 */
85void 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 */
95struct 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 */
103void 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 */
112void 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 */
120void 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 */
128void 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)
141void 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