xref: /dflybsd-src/sys/dev/drm/i915/intel_uncore.h (revision 3f2dd94a569761201b5b0a18b2f697f97fe1b9dc)
1*3f2dd94aSFrançois Tigeot /*
2*3f2dd94aSFrançois Tigeot  * Copyright © 2017 Intel Corporation
3*3f2dd94aSFrançois Tigeot  *
4*3f2dd94aSFrançois Tigeot  * Permission is hereby granted, free of charge, to any person obtaining a
5*3f2dd94aSFrançois Tigeot  * copy of this software and associated documentation files (the "Software"),
6*3f2dd94aSFrançois Tigeot  * to deal in the Software without restriction, including without limitation
7*3f2dd94aSFrançois Tigeot  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*3f2dd94aSFrançois Tigeot  * and/or sell copies of the Software, and to permit persons to whom the
9*3f2dd94aSFrançois Tigeot  * Software is furnished to do so, subject to the following conditions:
10*3f2dd94aSFrançois Tigeot  *
11*3f2dd94aSFrançois Tigeot  * The above copyright notice and this permission notice (including the next
12*3f2dd94aSFrançois Tigeot  * paragraph) shall be included in all copies or substantial portions of the
13*3f2dd94aSFrançois Tigeot  * Software.
14*3f2dd94aSFrançois Tigeot  *
15*3f2dd94aSFrançois Tigeot  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*3f2dd94aSFrançois Tigeot  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*3f2dd94aSFrançois Tigeot  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*3f2dd94aSFrançois Tigeot  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*3f2dd94aSFrançois Tigeot  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*3f2dd94aSFrançois Tigeot  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*3f2dd94aSFrançois Tigeot  * IN THE SOFTWARE.
22*3f2dd94aSFrançois Tigeot  *
23*3f2dd94aSFrançois Tigeot  */
24*3f2dd94aSFrançois Tigeot 
25*3f2dd94aSFrançois Tigeot #ifndef __INTEL_UNCORE_H__
26*3f2dd94aSFrançois Tigeot #define __INTEL_UNCORE_H__
27*3f2dd94aSFrançois Tigeot 
28*3f2dd94aSFrançois Tigeot #include <linux/spinlock.h>
29*3f2dd94aSFrançois Tigeot #include <linux/notifier.h>
30*3f2dd94aSFrançois Tigeot #include <linux/hrtimer.h>
31*3f2dd94aSFrançois Tigeot 
32*3f2dd94aSFrançois Tigeot #include "i915_reg.h"
33*3f2dd94aSFrançois Tigeot 
34*3f2dd94aSFrançois Tigeot struct drm_i915_private;
35*3f2dd94aSFrançois Tigeot 
36*3f2dd94aSFrançois Tigeot enum forcewake_domain_id {
37*3f2dd94aSFrançois Tigeot 	FW_DOMAIN_ID_RENDER = 0,
38*3f2dd94aSFrançois Tigeot 	FW_DOMAIN_ID_BLITTER,
39*3f2dd94aSFrançois Tigeot 	FW_DOMAIN_ID_MEDIA,
40*3f2dd94aSFrançois Tigeot 
41*3f2dd94aSFrançois Tigeot 	FW_DOMAIN_ID_COUNT
42*3f2dd94aSFrançois Tigeot };
43*3f2dd94aSFrançois Tigeot 
44*3f2dd94aSFrançois Tigeot enum forcewake_domains {
45*3f2dd94aSFrançois Tigeot 	FORCEWAKE_RENDER = BIT(FW_DOMAIN_ID_RENDER),
46*3f2dd94aSFrançois Tigeot 	FORCEWAKE_BLITTER = BIT(FW_DOMAIN_ID_BLITTER),
47*3f2dd94aSFrançois Tigeot 	FORCEWAKE_MEDIA	= BIT(FW_DOMAIN_ID_MEDIA),
48*3f2dd94aSFrançois Tigeot 	FORCEWAKE_ALL = (FORCEWAKE_RENDER |
49*3f2dd94aSFrançois Tigeot 			 FORCEWAKE_BLITTER |
50*3f2dd94aSFrançois Tigeot 			 FORCEWAKE_MEDIA)
51*3f2dd94aSFrançois Tigeot };
52*3f2dd94aSFrançois Tigeot 
53*3f2dd94aSFrançois Tigeot struct intel_uncore_funcs {
54*3f2dd94aSFrançois Tigeot 	void (*force_wake_get)(struct drm_i915_private *dev_priv,
55*3f2dd94aSFrançois Tigeot 			       enum forcewake_domains domains);
56*3f2dd94aSFrançois Tigeot 	void (*force_wake_put)(struct drm_i915_private *dev_priv,
57*3f2dd94aSFrançois Tigeot 			       enum forcewake_domains domains);
58*3f2dd94aSFrançois Tigeot 
59*3f2dd94aSFrançois Tigeot 	uint8_t  (*mmio_readb)(struct drm_i915_private *dev_priv,
60*3f2dd94aSFrançois Tigeot 			       i915_reg_t r, bool trace);
61*3f2dd94aSFrançois Tigeot 	uint16_t (*mmio_readw)(struct drm_i915_private *dev_priv,
62*3f2dd94aSFrançois Tigeot 			       i915_reg_t r, bool trace);
63*3f2dd94aSFrançois Tigeot 	uint32_t (*mmio_readl)(struct drm_i915_private *dev_priv,
64*3f2dd94aSFrançois Tigeot 			       i915_reg_t r, bool trace);
65*3f2dd94aSFrançois Tigeot 	u64      (*mmio_readq)(struct drm_i915_private *dev_priv,
66*3f2dd94aSFrançois Tigeot 			       i915_reg_t r, bool trace);
67*3f2dd94aSFrançois Tigeot 
68*3f2dd94aSFrançois Tigeot 	void (*mmio_writeb)(struct drm_i915_private *dev_priv,
69*3f2dd94aSFrançois Tigeot 			    i915_reg_t r, uint8_t val, bool trace);
70*3f2dd94aSFrançois Tigeot 	void (*mmio_writew)(struct drm_i915_private *dev_priv,
71*3f2dd94aSFrançois Tigeot 			    i915_reg_t r, uint16_t val, bool trace);
72*3f2dd94aSFrançois Tigeot 	void (*mmio_writel)(struct drm_i915_private *dev_priv,
73*3f2dd94aSFrançois Tigeot 			    i915_reg_t r, uint32_t val, bool trace);
74*3f2dd94aSFrançois Tigeot };
75*3f2dd94aSFrançois Tigeot 
76*3f2dd94aSFrançois Tigeot struct intel_forcewake_range {
77*3f2dd94aSFrançois Tigeot 	u32 start;
78*3f2dd94aSFrançois Tigeot 	u32 end;
79*3f2dd94aSFrançois Tigeot 
80*3f2dd94aSFrançois Tigeot 	enum forcewake_domains domains;
81*3f2dd94aSFrançois Tigeot };
82*3f2dd94aSFrançois Tigeot 
83*3f2dd94aSFrançois Tigeot struct intel_uncore {
84*3f2dd94aSFrançois Tigeot 	spinlock_t lock; /** lock is also taken in irq contexts. */
85*3f2dd94aSFrançois Tigeot 
86*3f2dd94aSFrançois Tigeot 	const struct intel_forcewake_range *fw_domains_table;
87*3f2dd94aSFrançois Tigeot 	unsigned int fw_domains_table_entries;
88*3f2dd94aSFrançois Tigeot 
89*3f2dd94aSFrançois Tigeot 	struct notifier_block pmic_bus_access_nb;
90*3f2dd94aSFrançois Tigeot 	struct intel_uncore_funcs funcs;
91*3f2dd94aSFrançois Tigeot 
92*3f2dd94aSFrançois Tigeot 	unsigned int fifo_count;
93*3f2dd94aSFrançois Tigeot 
94*3f2dd94aSFrançois Tigeot 	enum forcewake_domains fw_domains;
95*3f2dd94aSFrançois Tigeot 	enum forcewake_domains fw_domains_active;
96*3f2dd94aSFrançois Tigeot 
97*3f2dd94aSFrançois Tigeot 	u32 fw_set;
98*3f2dd94aSFrançois Tigeot 	u32 fw_clear;
99*3f2dd94aSFrançois Tigeot 	u32 fw_reset;
100*3f2dd94aSFrançois Tigeot 
101*3f2dd94aSFrançois Tigeot 	struct intel_uncore_forcewake_domain {
102*3f2dd94aSFrançois Tigeot 		enum forcewake_domain_id id;
103*3f2dd94aSFrançois Tigeot 		enum forcewake_domains mask;
104*3f2dd94aSFrançois Tigeot 		unsigned int wake_count;
105*3f2dd94aSFrançois Tigeot 		bool active;
106*3f2dd94aSFrançois Tigeot 		struct hrtimer timer;
107*3f2dd94aSFrançois Tigeot 		i915_reg_t reg_set;
108*3f2dd94aSFrançois Tigeot 		i915_reg_t reg_ack;
109*3f2dd94aSFrançois Tigeot 	} fw_domain[FW_DOMAIN_ID_COUNT];
110*3f2dd94aSFrançois Tigeot 
111*3f2dd94aSFrançois Tigeot 	struct {
112*3f2dd94aSFrançois Tigeot 		unsigned int count;
113*3f2dd94aSFrançois Tigeot 
114*3f2dd94aSFrançois Tigeot 		int saved_mmio_check;
115*3f2dd94aSFrançois Tigeot 		int saved_mmio_debug;
116*3f2dd94aSFrançois Tigeot 	} user_forcewake;
117*3f2dd94aSFrançois Tigeot 
118*3f2dd94aSFrançois Tigeot 	int unclaimed_mmio_check;
119*3f2dd94aSFrançois Tigeot };
120*3f2dd94aSFrançois Tigeot 
121*3f2dd94aSFrançois Tigeot /* Iterate over initialised fw domains */
122*3f2dd94aSFrançois Tigeot #define for_each_fw_domain_masked(domain__, mask__, dev_priv__, tmp__) \
123*3f2dd94aSFrançois Tigeot 	for (tmp__ = (mask__); \
124*3f2dd94aSFrançois Tigeot 	     tmp__ ? (domain__ = &(dev_priv__)->uncore.fw_domain[__mask_next_bit(tmp__)]), 1 : 0;)
125*3f2dd94aSFrançois Tigeot 
126*3f2dd94aSFrançois Tigeot #define for_each_fw_domain(domain__, dev_priv__, tmp__) \
127*3f2dd94aSFrançois Tigeot 	for_each_fw_domain_masked(domain__, (dev_priv__)->uncore.fw_domains, dev_priv__, tmp__)
128*3f2dd94aSFrançois Tigeot 
129*3f2dd94aSFrançois Tigeot 
130*3f2dd94aSFrançois Tigeot void intel_uncore_sanitize(struct drm_i915_private *dev_priv);
131*3f2dd94aSFrançois Tigeot void intel_uncore_init(struct drm_i915_private *dev_priv);
132*3f2dd94aSFrançois Tigeot bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv);
133*3f2dd94aSFrançois Tigeot bool intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv);
134*3f2dd94aSFrançois Tigeot void intel_uncore_fini(struct drm_i915_private *dev_priv);
135*3f2dd94aSFrançois Tigeot void intel_uncore_suspend(struct drm_i915_private *dev_priv);
136*3f2dd94aSFrançois Tigeot void intel_uncore_resume_early(struct drm_i915_private *dev_priv);
137*3f2dd94aSFrançois Tigeot void intel_uncore_runtime_resume(struct drm_i915_private *dev_priv);
138*3f2dd94aSFrançois Tigeot 
139*3f2dd94aSFrançois Tigeot u64 intel_uncore_edram_size(struct drm_i915_private *dev_priv);
140*3f2dd94aSFrançois Tigeot void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
141*3f2dd94aSFrançois Tigeot void assert_forcewakes_active(struct drm_i915_private *dev_priv,
142*3f2dd94aSFrançois Tigeot 			      enum forcewake_domains fw_domains);
143*3f2dd94aSFrançois Tigeot const char *intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id);
144*3f2dd94aSFrançois Tigeot 
145*3f2dd94aSFrançois Tigeot enum forcewake_domains
146*3f2dd94aSFrançois Tigeot intel_uncore_forcewake_for_reg(struct drm_i915_private *dev_priv,
147*3f2dd94aSFrançois Tigeot 			       i915_reg_t reg, unsigned int op);
148*3f2dd94aSFrançois Tigeot #define FW_REG_READ  (1)
149*3f2dd94aSFrançois Tigeot #define FW_REG_WRITE (2)
150*3f2dd94aSFrançois Tigeot 
151*3f2dd94aSFrançois Tigeot void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
152*3f2dd94aSFrançois Tigeot 				enum forcewake_domains domains);
153*3f2dd94aSFrançois Tigeot void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
154*3f2dd94aSFrançois Tigeot 				enum forcewake_domains domains);
155*3f2dd94aSFrançois Tigeot /* Like above but the caller must manage the uncore.lock itself.
156*3f2dd94aSFrançois Tigeot  * Must be used with I915_READ_FW and friends.
157*3f2dd94aSFrançois Tigeot  */
158*3f2dd94aSFrançois Tigeot void intel_uncore_forcewake_get__locked(struct drm_i915_private *dev_priv,
159*3f2dd94aSFrançois Tigeot 					enum forcewake_domains domains);
160*3f2dd94aSFrançois Tigeot void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv,
161*3f2dd94aSFrançois Tigeot 					enum forcewake_domains domains);
162*3f2dd94aSFrançois Tigeot 
163*3f2dd94aSFrançois Tigeot void intel_uncore_forcewake_user_get(struct drm_i915_private *dev_priv);
164*3f2dd94aSFrançois Tigeot void intel_uncore_forcewake_user_put(struct drm_i915_private *dev_priv);
165*3f2dd94aSFrançois Tigeot 
166*3f2dd94aSFrançois Tigeot int intel_wait_for_register(struct drm_i915_private *dev_priv,
167*3f2dd94aSFrançois Tigeot 			    i915_reg_t reg,
168*3f2dd94aSFrançois Tigeot 			    u32 mask,
169*3f2dd94aSFrançois Tigeot 			    u32 value,
170*3f2dd94aSFrançois Tigeot 			    unsigned int timeout_ms);
171*3f2dd94aSFrançois Tigeot int __intel_wait_for_register_fw(struct drm_i915_private *dev_priv,
172*3f2dd94aSFrançois Tigeot 				 i915_reg_t reg,
173*3f2dd94aSFrançois Tigeot 				 u32 mask,
174*3f2dd94aSFrançois Tigeot 				 u32 value,
175*3f2dd94aSFrançois Tigeot 				 unsigned int fast_timeout_us,
176*3f2dd94aSFrançois Tigeot 				 unsigned int slow_timeout_ms,
177*3f2dd94aSFrançois Tigeot 				 u32 *out_value);
178*3f2dd94aSFrançois Tigeot static inline
intel_wait_for_register_fw(struct drm_i915_private * dev_priv,i915_reg_t reg,u32 mask,u32 value,unsigned int timeout_ms)179*3f2dd94aSFrançois Tigeot int intel_wait_for_register_fw(struct drm_i915_private *dev_priv,
180*3f2dd94aSFrançois Tigeot 			       i915_reg_t reg,
181*3f2dd94aSFrançois Tigeot 			       u32 mask,
182*3f2dd94aSFrançois Tigeot 			       u32 value,
183*3f2dd94aSFrançois Tigeot 			       unsigned int timeout_ms)
184*3f2dd94aSFrançois Tigeot {
185*3f2dd94aSFrançois Tigeot 	return __intel_wait_for_register_fw(dev_priv, reg, mask, value,
186*3f2dd94aSFrançois Tigeot 					    2, timeout_ms, NULL);
187*3f2dd94aSFrançois Tigeot }
188*3f2dd94aSFrançois Tigeot 
189*3f2dd94aSFrançois Tigeot #endif /* !__INTEL_UNCORE_H__ */
190