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