xref: /linux/drivers/gpu/drm/xe/xe_force_wake.c (revision b4db9f840283caca0d904436f187ef56a9126eaa)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2022 Intel Corporation
4  */
5 
6 #include "xe_force_wake.h"
7 
8 #include <drm/drm_util.h>
9 
10 #include "regs/xe_gt_regs.h"
11 #include "regs/xe_reg_defs.h"
12 #include "xe_gt.h"
13 #include "xe_mmio.h"
14 
15 #define XE_FORCE_WAKE_ACK_TIMEOUT_MS	50
16 
17 static struct xe_gt *
18 fw_to_gt(struct xe_force_wake *fw)
19 {
20 	return fw->gt;
21 }
22 
23 static struct xe_device *
24 fw_to_xe(struct xe_force_wake *fw)
25 {
26 	return gt_to_xe(fw_to_gt(fw));
27 }
28 
29 static void domain_init(struct xe_force_wake_domain *domain,
30 			enum xe_force_wake_domain_id id,
31 			struct xe_reg reg, struct xe_reg ack, u32 val, u32 mask)
32 {
33 	domain->id = id;
34 	domain->reg_ctl = reg;
35 	domain->reg_ack = ack;
36 	domain->val = val;
37 	domain->mask = mask;
38 }
39 
40 void xe_force_wake_init_gt(struct xe_gt *gt, struct xe_force_wake *fw)
41 {
42 	struct xe_device *xe = gt_to_xe(gt);
43 
44 	fw->gt = gt;
45 	spin_lock_init(&fw->lock);
46 
47 	/* Assuming gen11+ so assert this assumption is correct */
48 	xe_gt_assert(gt, GRAPHICS_VER(gt_to_xe(gt)) >= 11);
49 
50 	if (xe->info.graphics_verx100 >= 1270) {
51 		domain_init(&fw->domains[XE_FW_DOMAIN_ID_GT],
52 			    XE_FW_DOMAIN_ID_GT,
53 			    FORCEWAKE_GT,
54 			    FORCEWAKE_ACK_GT_MTL,
55 			    BIT(0), BIT(16));
56 	} else {
57 		domain_init(&fw->domains[XE_FW_DOMAIN_ID_GT],
58 			    XE_FW_DOMAIN_ID_GT,
59 			    FORCEWAKE_GT,
60 			    FORCEWAKE_ACK_GT,
61 			    BIT(0), BIT(16));
62 	}
63 }
64 
65 void xe_force_wake_init_engines(struct xe_gt *gt, struct xe_force_wake *fw)
66 {
67 	int i, j;
68 
69 	/* Assuming gen11+ so assert this assumption is correct */
70 	xe_gt_assert(gt, GRAPHICS_VER(gt_to_xe(gt)) >= 11);
71 
72 	if (!xe_gt_is_media_type(gt))
73 		domain_init(&fw->domains[XE_FW_DOMAIN_ID_RENDER],
74 			    XE_FW_DOMAIN_ID_RENDER,
75 			    FORCEWAKE_RENDER,
76 			    FORCEWAKE_ACK_RENDER,
77 			    BIT(0), BIT(16));
78 
79 	for (i = XE_HW_ENGINE_VCS0, j = 0; i <= XE_HW_ENGINE_VCS7; ++i, ++j) {
80 		if (!(gt->info.engine_mask & BIT(i)))
81 			continue;
82 
83 		domain_init(&fw->domains[XE_FW_DOMAIN_ID_MEDIA_VDBOX0 + j],
84 			    XE_FW_DOMAIN_ID_MEDIA_VDBOX0 + j,
85 			    FORCEWAKE_MEDIA_VDBOX(j),
86 			    FORCEWAKE_ACK_MEDIA_VDBOX(j),
87 			    BIT(0), BIT(16));
88 	}
89 
90 	for (i = XE_HW_ENGINE_VECS0, j = 0; i <= XE_HW_ENGINE_VECS3; ++i, ++j) {
91 		if (!(gt->info.engine_mask & BIT(i)))
92 			continue;
93 
94 		domain_init(&fw->domains[XE_FW_DOMAIN_ID_MEDIA_VEBOX0 + j],
95 			    XE_FW_DOMAIN_ID_MEDIA_VEBOX0 + j,
96 			    FORCEWAKE_MEDIA_VEBOX(j),
97 			    FORCEWAKE_ACK_MEDIA_VEBOX(j),
98 			    BIT(0), BIT(16));
99 	}
100 
101 	if (gt->info.engine_mask & BIT(XE_HW_ENGINE_GSCCS0))
102 		domain_init(&fw->domains[XE_FW_DOMAIN_ID_GSC],
103 			    XE_FW_DOMAIN_ID_GSC,
104 			    FORCEWAKE_GSC,
105 			    FORCEWAKE_ACK_GSC,
106 			    BIT(0), BIT(16));
107 }
108 
109 static void domain_wake(struct xe_gt *gt, struct xe_force_wake_domain *domain)
110 {
111 	xe_mmio_write32(gt, domain->reg_ctl, domain->mask | domain->val);
112 }
113 
114 static int domain_wake_wait(struct xe_gt *gt,
115 			    struct xe_force_wake_domain *domain)
116 {
117 	return xe_mmio_wait32(gt, domain->reg_ack, domain->val, domain->val,
118 			      XE_FORCE_WAKE_ACK_TIMEOUT_MS * USEC_PER_MSEC,
119 			      NULL, true);
120 }
121 
122 static void domain_sleep(struct xe_gt *gt, struct xe_force_wake_domain *domain)
123 {
124 	xe_mmio_write32(gt, domain->reg_ctl, domain->mask);
125 }
126 
127 static int domain_sleep_wait(struct xe_gt *gt,
128 			     struct xe_force_wake_domain *domain)
129 {
130 	return xe_mmio_wait32(gt, domain->reg_ack, domain->val, 0,
131 			      XE_FORCE_WAKE_ACK_TIMEOUT_MS * USEC_PER_MSEC,
132 			      NULL, true);
133 }
134 
135 #define for_each_fw_domain_masked(domain__, mask__, fw__, tmp__) \
136 	for (tmp__ = (mask__); tmp__; tmp__ &= ~BIT(ffs(tmp__) - 1)) \
137 		for_each_if((domain__ = ((fw__)->domains + \
138 					 (ffs(tmp__) - 1))) && \
139 					 domain__->reg_ctl.addr)
140 
141 int xe_force_wake_get(struct xe_force_wake *fw,
142 		      enum xe_force_wake_domains domains)
143 {
144 	struct xe_device *xe = fw_to_xe(fw);
145 	struct xe_gt *gt = fw_to_gt(fw);
146 	struct xe_force_wake_domain *domain;
147 	enum xe_force_wake_domains tmp, woken = 0;
148 	unsigned long flags;
149 	int ret, ret2 = 0;
150 
151 	spin_lock_irqsave(&fw->lock, flags);
152 	for_each_fw_domain_masked(domain, domains, fw, tmp) {
153 		if (!domain->ref++) {
154 			woken |= BIT(domain->id);
155 			domain_wake(gt, domain);
156 		}
157 	}
158 	for_each_fw_domain_masked(domain, woken, fw, tmp) {
159 		ret = domain_wake_wait(gt, domain);
160 		ret2 |= ret;
161 		if (ret)
162 			drm_notice(&xe->drm, "Force wake domain (%d) failed to ack wake, ret=%d\n",
163 				   domain->id, ret);
164 	}
165 	fw->awake_domains |= woken;
166 	spin_unlock_irqrestore(&fw->lock, flags);
167 
168 	return ret2;
169 }
170 
171 int xe_force_wake_put(struct xe_force_wake *fw,
172 		      enum xe_force_wake_domains domains)
173 {
174 	struct xe_device *xe = fw_to_xe(fw);
175 	struct xe_gt *gt = fw_to_gt(fw);
176 	struct xe_force_wake_domain *domain;
177 	enum xe_force_wake_domains tmp, sleep = 0;
178 	unsigned long flags;
179 	int ret, ret2 = 0;
180 
181 	spin_lock_irqsave(&fw->lock, flags);
182 	for_each_fw_domain_masked(domain, domains, fw, tmp) {
183 		if (!--domain->ref) {
184 			sleep |= BIT(domain->id);
185 			domain_sleep(gt, domain);
186 		}
187 	}
188 	for_each_fw_domain_masked(domain, sleep, fw, tmp) {
189 		ret = domain_sleep_wait(gt, domain);
190 		ret2 |= ret;
191 		if (ret)
192 			drm_notice(&xe->drm, "Force wake domain (%d) failed to ack sleep, ret=%d\n",
193 				   domain->id, ret);
194 	}
195 	fw->awake_domains &= ~sleep;
196 	spin_unlock_irqrestore(&fw->lock, flags);
197 
198 	return ret2;
199 }
200