summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/sde/sde_rm.h
blob: d0a31f97d45b1f96622ac4921c2dd1869ef9223f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
/*
 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#ifndef __SDE_RM_H__
#define __SDE_RM_H__

#include <linux/list.h>

#include "msm_kms.h"
#include "sde_hw_top.h"

/**
 * enum sde_rm_topology_name - HW resource use case in use by connector
 * @SDE_RM_TOPOLOGY_UNKNOWN: No topology in use currently
 * @SDE_RM_TOPOLOGY_SINGLEPIPE: 1 LM, 1 PP, 1 INTF/WB
 * @SDE_RM_TOPOLOGY_DUALPIPE: 2 LM, 2 PP, 2 INTF/WB
 * @SDE_RM_TOPOLOGY_PPSPLIT: 1 LM, 2 PPs, 2 INTF/WB
 * @SDE_RM_TOPOLOGY_DUALPIPEMERGE: 2 LM, 2 PP, 3DMux, 1 INTF/WB
 */
enum sde_rm_topology_name {
	SDE_RM_TOPOLOGY_UNKNOWN = 0,
	SDE_RM_TOPOLOGY_SINGLEPIPE,
	SDE_RM_TOPOLOGY_DUALPIPE,
	SDE_RM_TOPOLOGY_PPSPLIT,
	SDE_RM_TOPOLOGY_DUALPIPEMERGE,
};

/**
 * enum sde_rm_topology_control - HW resource use case in use by connector
 * @SDE_RM_TOPCTL_RESERVE_LOCK: If set, in AtomicTest phase, after a successful
 *                              test, reserve the resources for this display.
 *                              Normal behavior would not impact the reservation
 *                              list during the AtomicTest phase.
 * @SDE_RM_TOPCTL_RESERVE_CLEAR: If set, in AtomicTest phase, before testing,
 *                               release any reservation held by this display.
 *                               Normal behavior would not impact the
 *                               reservation list during the AtomicTest phase.
 * @SDE_RM_TOPCTL_DSPP: Require layer mixers with DSPP capabilities
 * @SDE_RM_TOPCTL_FORCE_TILING: Require kernel to split across multiple layer
 *                              mixers, despite width fitting within capability
 *                              of a single layer mixer.
 * @SDE_RM_TOPCTL_PPSPLIT: Require kernel to use pingpong split pipe
 *                         configuration instead of dual pipe.
 * @SDE_RM_TOPCTL_FORCE_MIXER: Require kernel to force single mixer usage
 */
enum sde_rm_topology_control {
	SDE_RM_TOPCTL_RESERVE_LOCK,
	SDE_RM_TOPCTL_RESERVE_CLEAR,
	SDE_RM_TOPCTL_DSPP,
	SDE_RM_TOPCTL_FORCE_TILING,
	SDE_RM_TOPCTL_PPSPLIT,
	SDE_RM_TOPCTL_FORCE_MIXER,
};

/**
 * struct sde_rm - SDE dynamic hardware resource manager
 * @dev: device handle for event logging purposes
 * @rsvps: list of hardware reservations by each crtc->encoder->connector
 * @hw_blks: array of lists of hardware resources present in the system, one
 *	list per type of hardware block
 * @hw_mdp: hardware object for mdp_top
 * @lm_max_width: cached layer mixer maximum width
 * @rsvp_next_seq: sequence number for next reservation for debugging purposes
 * @rm_lock: resource manager mutex
 */
struct sde_rm {
	struct drm_device *dev;
	struct list_head rsvps;
	struct list_head hw_blks[SDE_HW_BLK_MAX];
	struct sde_hw_mdp *hw_mdp;
	uint32_t lm_max_width;
	uint32_t rsvp_next_seq;
	struct mutex rm_lock;
};

/**
 *  struct sde_rm_hw_blk - resource manager internal structure
 *	forward declaration for single iterator definition without void pointer
 */
struct sde_rm_hw_blk;

/**
 * struct sde_rm_hw_iter - iterator for use with sde_rm
 * @hw: sde_hw object requested, or NULL on failure
 * @blk: sde_rm internal block representation. Clients ignore. Used as iterator.
 * @enc_id: DRM ID of Encoder client wishes to search for, or 0 for Any Encoder
 * @type: Hardware Block Type client wishes to search for.
 */
struct sde_rm_hw_iter {
	void *hw;
	struct sde_rm_hw_blk *blk;
	uint32_t enc_id;
	enum sde_hw_blk_type type;
};

/**
 * sde_rm_init - Read hardware catalog and create reservation tracking objects
 *	for all HW blocks.
 * @rm: SDE Resource Manager handle
 * @cat: Pointer to hardware catalog
 * @mmio: mapped register io address of MDP
 * @dev: device handle for event logging purposes
 * @Return: 0 on Success otherwise -ERROR
 */
int sde_rm_init(struct sde_rm *rm,
		struct sde_mdss_cfg *cat,
		void *mmio,
		struct drm_device *dev);

/**
 * sde_rm_destroy - Free all memory allocated by sde_rm_init
 * @rm: SDE Resource Manager handle
 * @Return: 0 on Success otherwise -ERROR
 */
int sde_rm_destroy(struct sde_rm *rm);

/**
 * sde_rm_reserve - Given a CRTC->Encoder->Connector display chain, analyze
 *	the use connections and user requirements, specified through related
 *	topology control properties, and reserve hardware blocks to that
 *	display chain.
 *	HW blocks can then be accessed through sde_rm_get_* functions.
 *	HW Reservations should be released via sde_rm_release_hw.
 * @rm: SDE Resource Manager handle
 * @drm_enc: DRM Encoder handle
 * @crtc_state: Proposed Atomic DRM CRTC State handle
 * @conn_state: Proposed Atomic DRM Connector State handle
 * @test_only: Atomic-Test phase, discard results (unless property overrides)
 * @Return: 0 on Success otherwise -ERROR
 */
int sde_rm_reserve(struct sde_rm *rm,
		struct drm_encoder *drm_enc,
		struct drm_crtc_state *crtc_state,
		struct drm_connector_state *conn_state,
		bool test_only);

/**
 * sde_rm_reserve - Given the encoder for the display chain, release any
 *	HW blocks previously reserved for that use case.
 * @rm: SDE Resource Manager handle
 * @enc: DRM Encoder handle
 * @Return: 0 on Success otherwise -ERROR
 */
void sde_rm_release(struct sde_rm *rm, struct drm_encoder *enc);

/**
 * sde_rm_get_mdp - Retrieve HW block for MDP TOP.
 *	This is never reserved, and is usable by any display.
 * @rm: SDE Resource Manager handle
 * @Return: Pointer to hw block or NULL
 */
struct sde_hw_mdp *sde_rm_get_mdp(struct sde_rm *rm);

/**
 * sde_rm_init_hw_iter - setup given iterator for new iteration over hw list
 *	using sde_rm_get_hw
 * @iter: iter object to initialize
 * @enc_id: DRM ID of Encoder client wishes to search for, or 0 for Any Encoder
 * @type: Hardware Block Type client wishes to search for.
 */
void sde_rm_init_hw_iter(
		struct sde_rm_hw_iter *iter,
		uint32_t enc_id,
		enum sde_hw_blk_type type);
/**
 * sde_rm_get_hw - retrieve reserved hw object given encoder and hw type
 *	Meant to do a single pass through the hardware list to iteratively
 *	retrieve hardware blocks of a given type for a given encoder.
 *	Initialize an iterator object.
 *	Set hw block type of interest. Set encoder id of interest, 0 for any.
 *	Function returns first hw of type for that encoder.
 *	Subsequent calls will return the next reserved hw of that type in-order.
 *	Iterator HW pointer will be null on failure to find hw.
 * @rm: SDE Resource Manager handle
 * @iter: iterator object
 * @Return: true on match found, false on no match found
 */
bool sde_rm_get_hw(struct sde_rm *rm, struct sde_rm_hw_iter *iter);

/**
 * sde_rm_get_hw_by_id - retrieve hw object given hw type and hw id
 *	Meant to do a single pass through the hardware list to iteratively
 *	retrieve hardware blocks of a given type and id.
 *	Function returns the hw resource pointer.
 * @rm: SDE Resource Manager handle
 * @type: hw type
 * @id: hw id
 * @Return: hw resource pointer on match found, NULL on no match found
 */
void *sde_rm_get_hw_by_id(struct sde_rm *rm, enum sde_hw_blk_type type, int id);

/**
 * sde_rm_check_property_topctl - validate property bitmask before it is set
 * @val: user's proposed topology control bitmask
 * @Return: 0 on success or error
 */
int sde_rm_check_property_topctl(uint64_t val);

/**
 * sde_rm_check_property_topctl - validate property bitmask before it is set
 * @val: user's proposed topology control bitmask
 * @Return: 0 on success or error
 */
int sde_rm_check_property_topctl(uint64_t val);

/**
 * sde_rm_read_resource_for_splash - read splash resource used in bootloader
 * @rm: SDE Resource Manager handle
 * @sinfo: handle for splash info
 * @cat: Pointer to hardware catalog
 */
int sde_rm_read_resource_for_splash(struct sde_rm *rm,
				void *sinfo,
				struct sde_mdss_cfg *cat);

/**
 * sde_rm_ext_blk_create_reserve - Create external HW blocks
 *	in resource manager and reserve for specific encoder.
 * @rm: SDE Resource Manager handle
 * @type: external HW block type
 * @id: external HW block id
 * @hw: external HW block
 * @enc: DRM Encoder handle
 * @Return: 0 on Success otherwise -ERROR
 */
int sde_rm_ext_blk_create_reserve(struct sde_rm *rm,
		enum sde_hw_blk_type type,
		uint32_t id,
		void *hw,
		struct drm_encoder *enc);

/**
 * sde_rm_ext_blk_destroy - Given the encoder for the display chain, release
 *	external HW blocks created for that.
 * @rm: SDE Resource Manager handle
 * @enc: DRM Encoder handle
 * @Return: 0 on Success otherwise -ERROR
 */
int sde_rm_ext_blk_destroy(struct sde_rm *rm,
				struct drm_encoder *enc);

#endif /* __SDE_RM_H__ */