1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright 2018 Marty E. Plummer <hanetzer@startmail.com> */
3 /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
5 #ifndef __PANFROST_DEVICE_H__
6 #define __PANFROST_DEVICE_H__
8 #include <linux/atomic.h>
9 #include <linux/io-pgtable.h>
11 #include <linux/regulator/consumer.h>
12 #include <linux/spinlock.h>
13 #include <drm/drm_device.h>
14 #include <drm/drm_mm.h>
15 #include <drm/gpu_scheduler.h>
17 #include "panfrost_devfreq.h"
19 struct panfrost_device
;
21 struct panfrost_job_slot
;
23 struct panfrost_perfcnt
;
25 #define NUM_JOB_SLOTS 3
26 #define MAX_PM_DOMAINS 5
28 enum panfrost_drv_comp_bits
{
29 PANFROST_COMP_BIT_GPU
,
30 PANFROST_COMP_BIT_JOB
,
31 PANFROST_COMP_BIT_MMU
,
36 * enum panfrost_gpu_pm - Supported kernel power management features
37 * @GPU_PM_CLK_DIS: Allow disabling clocks during system suspend
38 * @GPU_PM_VREG_OFF: Allow turning off regulators during system suspend
40 enum panfrost_gpu_pm
{
45 struct panfrost_features
{
63 u32 thread_max_workgroup_sz
;
64 u32 thread_max_barrier_sz
;
65 u32 coherency_features
;
67 u32 texture_features
[4];
73 unsigned long hw_features
[64 / BITS_PER_LONG
];
74 unsigned long hw_issues
[64 / BITS_PER_LONG
];
78 * Features that cannot be automatically detected and need matching using the
79 * compatible string, typically SoC-specific.
81 struct panfrost_compatible
{
82 /* Supplies count and names. */
84 const char * const *supply_names
;
86 * Number of power domains required, note that values 0 and 1 are
87 * handled identically, as only values > 1 need special handling.
90 /* Only required if num_pm_domains > 1. */
91 const char * const *pm_domain_names
;
93 /* Vendor implementation quirks callback */
94 void (*vendor_quirk
)(struct panfrost_device
*pfdev
);
96 /* Allowed PM features */
100 struct panfrost_device
{
102 struct drm_device
*ddev
;
103 struct platform_device
*pdev
;
109 struct clk
*bus_clock
;
110 struct regulator_bulk_data
*regulators
;
111 struct reset_control
*rstc
;
112 /* pm_domains for devices with more than one. */
113 struct device
*pm_domain_devs
[MAX_PM_DOMAINS
];
114 struct device_link
*pm_domain_links
[MAX_PM_DOMAINS
];
117 struct panfrost_features features
;
118 const struct panfrost_compatible
*comp
;
119 DECLARE_BITMAP(is_suspended
, PANFROST_COMP_BIT_MAX
);
122 unsigned long as_in_use_mask
;
123 unsigned long as_alloc_mask
;
124 unsigned long as_faulty_mask
;
125 struct list_head as_lru_list
;
127 struct panfrost_job_slot
*js
;
129 struct panfrost_job
*jobs
[NUM_JOB_SLOTS
][2];
130 struct list_head scheduled_jobs
;
132 struct panfrost_perfcnt
*perfcnt
;
135 struct mutex sched_lock
;
138 struct workqueue_struct
*wq
;
139 struct work_struct work
;
143 struct mutex shrinker_lock
;
144 struct list_head shrinker_list
;
145 struct shrinker
*shrinker
;
147 struct panfrost_devfreq pfdevfreq
;
155 struct panfrost_mmu
{
156 struct panfrost_device
*pfdev
;
157 struct kref refcount
;
158 struct io_pgtable_cfg pgtbl_cfg
;
159 struct io_pgtable_ops
*pgtbl_ops
;
164 struct list_head list
;
167 struct panfrost_engine_usage
{
168 unsigned long long elapsed_ns
[NUM_JOB_SLOTS
];
169 unsigned long long cycles
[NUM_JOB_SLOTS
];
172 struct panfrost_file_priv
{
173 struct panfrost_device
*pfdev
;
175 struct drm_sched_entity sched_entity
[NUM_JOB_SLOTS
];
177 struct panfrost_mmu
*mmu
;
179 struct panfrost_engine_usage engine_usage
;
182 static inline struct panfrost_device
*to_panfrost_device(struct drm_device
*ddev
)
184 return ddev
->dev_private
;
187 static inline int panfrost_model_cmp(struct panfrost_device
*pfdev
, s32 id
)
189 s32 match_id
= pfdev
->features
.id
;
191 if (match_id
& 0xf000)
193 return match_id
- id
;
196 static inline bool panfrost_model_is_bifrost(struct panfrost_device
*pfdev
)
198 return panfrost_model_cmp(pfdev
, 0x1000) >= 0;
201 static inline bool panfrost_model_eq(struct panfrost_device
*pfdev
, s32 id
)
203 return !panfrost_model_cmp(pfdev
, id
);
206 int panfrost_unstable_ioctl_check(void);
208 int panfrost_device_init(struct panfrost_device
*pfdev
);
209 void panfrost_device_fini(struct panfrost_device
*pfdev
);
210 void panfrost_device_reset(struct panfrost_device
*pfdev
);
212 extern const struct dev_pm_ops panfrost_pm_ops
;
214 enum drm_panfrost_exception_type
{
215 DRM_PANFROST_EXCEPTION_OK
= 0x00,
216 DRM_PANFROST_EXCEPTION_DONE
= 0x01,
217 DRM_PANFROST_EXCEPTION_INTERRUPTED
= 0x02,
218 DRM_PANFROST_EXCEPTION_STOPPED
= 0x03,
219 DRM_PANFROST_EXCEPTION_TERMINATED
= 0x04,
220 DRM_PANFROST_EXCEPTION_KABOOM
= 0x05,
221 DRM_PANFROST_EXCEPTION_EUREKA
= 0x06,
222 DRM_PANFROST_EXCEPTION_ACTIVE
= 0x08,
223 DRM_PANFROST_EXCEPTION_MAX_NON_FAULT
= 0x3f,
224 DRM_PANFROST_EXCEPTION_JOB_CONFIG_FAULT
= 0x40,
225 DRM_PANFROST_EXCEPTION_JOB_POWER_FAULT
= 0x41,
226 DRM_PANFROST_EXCEPTION_JOB_READ_FAULT
= 0x42,
227 DRM_PANFROST_EXCEPTION_JOB_WRITE_FAULT
= 0x43,
228 DRM_PANFROST_EXCEPTION_JOB_AFFINITY_FAULT
= 0x44,
229 DRM_PANFROST_EXCEPTION_JOB_BUS_FAULT
= 0x48,
230 DRM_PANFROST_EXCEPTION_INSTR_INVALID_PC
= 0x50,
231 DRM_PANFROST_EXCEPTION_INSTR_INVALID_ENC
= 0x51,
232 DRM_PANFROST_EXCEPTION_INSTR_TYPE_MISMATCH
= 0x52,
233 DRM_PANFROST_EXCEPTION_INSTR_OPERAND_FAULT
= 0x53,
234 DRM_PANFROST_EXCEPTION_INSTR_TLS_FAULT
= 0x54,
235 DRM_PANFROST_EXCEPTION_INSTR_BARRIER_FAULT
= 0x55,
236 DRM_PANFROST_EXCEPTION_INSTR_ALIGN_FAULT
= 0x56,
237 DRM_PANFROST_EXCEPTION_DATA_INVALID_FAULT
= 0x58,
238 DRM_PANFROST_EXCEPTION_TILE_RANGE_FAULT
= 0x59,
239 DRM_PANFROST_EXCEPTION_ADDR_RANGE_FAULT
= 0x5a,
240 DRM_PANFROST_EXCEPTION_IMPRECISE_FAULT
= 0x5b,
241 DRM_PANFROST_EXCEPTION_OOM
= 0x60,
242 DRM_PANFROST_EXCEPTION_OOM_AFBC
= 0x61,
243 DRM_PANFROST_EXCEPTION_UNKNOWN
= 0x7f,
244 DRM_PANFROST_EXCEPTION_DELAYED_BUS_FAULT
= 0x80,
245 DRM_PANFROST_EXCEPTION_GPU_SHAREABILITY_FAULT
= 0x88,
246 DRM_PANFROST_EXCEPTION_SYS_SHAREABILITY_FAULT
= 0x89,
247 DRM_PANFROST_EXCEPTION_GPU_CACHEABILITY_FAULT
= 0x8a,
248 DRM_PANFROST_EXCEPTION_TRANSLATION_FAULT_0
= 0xc0,
249 DRM_PANFROST_EXCEPTION_TRANSLATION_FAULT_1
= 0xc1,
250 DRM_PANFROST_EXCEPTION_TRANSLATION_FAULT_2
= 0xc2,
251 DRM_PANFROST_EXCEPTION_TRANSLATION_FAULT_3
= 0xc3,
252 DRM_PANFROST_EXCEPTION_TRANSLATION_FAULT_4
= 0xc4,
253 DRM_PANFROST_EXCEPTION_TRANSLATION_FAULT_IDENTITY
= 0xc7,
254 DRM_PANFROST_EXCEPTION_PERM_FAULT_0
= 0xc8,
255 DRM_PANFROST_EXCEPTION_PERM_FAULT_1
= 0xc9,
256 DRM_PANFROST_EXCEPTION_PERM_FAULT_2
= 0xca,
257 DRM_PANFROST_EXCEPTION_PERM_FAULT_3
= 0xcb,
258 DRM_PANFROST_EXCEPTION_TRANSTAB_BUS_FAULT_0
= 0xd0,
259 DRM_PANFROST_EXCEPTION_TRANSTAB_BUS_FAULT_1
= 0xd1,
260 DRM_PANFROST_EXCEPTION_TRANSTAB_BUS_FAULT_2
= 0xd2,
261 DRM_PANFROST_EXCEPTION_TRANSTAB_BUS_FAULT_3
= 0xd3,
262 DRM_PANFROST_EXCEPTION_ACCESS_FLAG_0
= 0xd8,
263 DRM_PANFROST_EXCEPTION_ACCESS_FLAG_1
= 0xd9,
264 DRM_PANFROST_EXCEPTION_ACCESS_FLAG_2
= 0xda,
265 DRM_PANFROST_EXCEPTION_ACCESS_FLAG_3
= 0xdb,
266 DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_IN0
= 0xe0,
267 DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_IN1
= 0xe1,
268 DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_IN2
= 0xe2,
269 DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_IN3
= 0xe3,
270 DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_OUT0
= 0xe4,
271 DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_OUT1
= 0xe5,
272 DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_OUT2
= 0xe6,
273 DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_OUT3
= 0xe7,
274 DRM_PANFROST_EXCEPTION_MEM_ATTR_FAULT_0
= 0xe8,
275 DRM_PANFROST_EXCEPTION_MEM_ATTR_FAULT_1
= 0xe9,
276 DRM_PANFROST_EXCEPTION_MEM_ATTR_FAULT_2
= 0xea,
277 DRM_PANFROST_EXCEPTION_MEM_ATTR_FAULT_3
= 0xeb,
278 DRM_PANFROST_EXCEPTION_MEM_ATTR_NONCACHE_0
= 0xec,
279 DRM_PANFROST_EXCEPTION_MEM_ATTR_NONCACHE_1
= 0xed,
280 DRM_PANFROST_EXCEPTION_MEM_ATTR_NONCACHE_2
= 0xee,
281 DRM_PANFROST_EXCEPTION_MEM_ATTR_NONCACHE_3
= 0xef,
285 panfrost_exception_is_fault(u32 exception_code
)
287 return exception_code
> DRM_PANFROST_EXCEPTION_MAX_NON_FAULT
;
290 const char *panfrost_exception_name(u32 exception_code
);
291 bool panfrost_exception_needs_reset(const struct panfrost_device
*pfdev
,
295 panfrost_device_schedule_reset(struct panfrost_device
*pfdev
)
297 atomic_set(&pfdev
->reset
.pending
, 1);
298 queue_work(pfdev
->reset
.wq
, &pfdev
->reset
.work
);