2018-09-10 14:27:58 -05:00
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright 2018 Marty E. Plummer <hanetzer@startmail.com> */
/* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
# ifndef __PANFROST_DEVICE_H__
# define __PANFROST_DEVICE_H__
2019-08-13 09:01:15 -06:00
# include <linux/atomic.h>
# include <linux/io-pgtable.h>
2022-11-29 19:19:32 +00:00
# include <linux/pm.h>
2020-02-07 13:26:24 +08:00
# include <linux/regulator/consumer.h>
2018-09-10 14:27:58 -05:00
# include <linux/spinlock.h>
# include <drm/drm_device.h>
# include <drm/drm_mm.h>
# include <drm/gpu_scheduler.h>
2020-07-10 11:53:59 +02:00
# include "panfrost_devfreq.h"
2018-09-10 14:27:58 -05:00
struct panfrost_device ;
struct panfrost_mmu ;
struct panfrost_job_slot ;
struct panfrost_job ;
2019-06-18 10:16:48 +02:00
struct panfrost_perfcnt ;
2018-09-10 14:27:58 -05:00
# define NUM_JOB_SLOTS 3
2020-02-07 13:26:25 +08:00
# define MAX_PM_DOMAINS 3
2018-09-10 14:27:58 -05:00
struct panfrost_features {
u16 id ;
u16 revision ;
u64 shader_present ;
u64 tiler_present ;
u64 l2_present ;
u64 stack_present ;
u32 as_present ;
u32 js_present ;
u32 l2_features ;
u32 core_features ;
u32 tiler_features ;
u32 mem_features ;
u32 mmu_features ;
u32 thread_features ;
u32 max_threads ;
u32 thread_max_workgroup_sz ;
u32 thread_max_barrier_sz ;
u32 coherency_features ;
2021-06-04 09:00:11 -04:00
u32 afbc_features ;
2018-09-10 14:27:58 -05:00
u32 texture_features [ 4 ] ;
u32 js_features [ 16 ] ;
u32 nr_core_groups ;
2019-07-24 11:56:26 +01:00
u32 thread_tls_alloc ;
2018-09-10 14:27:58 -05:00
unsigned long hw_features [ 64 / BITS_PER_LONG ] ;
unsigned long hw_issues [ 64 / BITS_PER_LONG ] ;
} ;
2020-02-07 13:26:24 +08:00
/*
* Features that cannot be automatically detected and need matching using the
* compatible string , typically SoC - specific .
*/
struct panfrost_compatible {
/* Supplies count and names. */
int num_supplies ;
const char * const * supply_names ;
2020-02-07 13:26:25 +08:00
/*
* Number of power domains required , note that values 0 and 1 are
* handled identically , as only values > 1 need special handling .
*/
int num_pm_domains ;
/* Only required if num_pm_domains > 1. */
const char * const * pm_domain_names ;
2020-09-16 17:01:45 +02:00
/* Vendor implementation quirks callback */
void ( * vendor_quirk ) ( struct panfrost_device * pfdev ) ;
2020-02-07 13:26:24 +08:00
} ;
2018-09-10 14:27:58 -05:00
struct panfrost_device {
struct device * dev ;
struct drm_device * ddev ;
struct platform_device * pdev ;
void __iomem * iomem ;
struct clk * clock ;
2019-05-21 18:10:57 +02:00
struct clk * bus_clock ;
2020-07-10 11:54:04 +02:00
struct regulator_bulk_data * regulators ;
2018-09-10 14:27:58 -05:00
struct reset_control * rstc ;
2020-02-07 13:26:25 +08:00
/* pm_domains for devices with more than one. */
struct device * pm_domain_devs [ MAX_PM_DOMAINS ] ;
struct device_link * pm_domain_links [ MAX_PM_DOMAINS ] ;
2020-09-22 15:16:49 +01:00
bool coherent ;
2018-09-10 14:27:58 -05:00
struct panfrost_features features ;
2020-02-07 13:26:24 +08:00
const struct panfrost_compatible * comp ;
2018-09-10 14:27:58 -05:00
2019-08-13 09:01:15 -06:00
spinlock_t as_lock ;
unsigned long as_in_use_mask ;
unsigned long as_alloc_mask ;
2021-06-30 08:27:46 +02:00
unsigned long as_faulty_mask ;
2019-08-13 09:01:15 -06:00
struct list_head as_lru_list ;
2018-09-10 14:27:58 -05:00
struct panfrost_job_slot * js ;
2021-06-30 08:27:50 +02:00
struct panfrost_job * jobs [ NUM_JOB_SLOTS ] [ 2 ] ;
2018-09-10 14:27:58 -05:00
struct list_head scheduled_jobs ;
2019-06-18 10:16:48 +02:00
struct panfrost_perfcnt * perfcnt ;
2018-09-10 14:27:58 -05:00
struct mutex sched_lock ;
2020-11-05 16:17:04 +01:00
struct {
2021-06-30 08:27:44 +02:00
struct workqueue_struct * wq ;
2020-11-05 16:17:04 +01:00
struct work_struct work ;
atomic_t pending ;
} reset ;
2018-09-10 14:27:58 -05:00
2019-08-05 08:33:58 -06:00
struct mutex shrinker_lock ;
struct list_head shrinker_list ;
struct shrinker shrinker ;
2020-07-10 11:53:59 +02:00
struct panfrost_devfreq pfdevfreq ;
2018-09-10 14:27:58 -05:00
} ;
2019-08-13 09:01:15 -06:00
struct panfrost_mmu {
2021-06-21 15:38:56 +02:00
struct panfrost_device * pfdev ;
struct kref refcount ;
2019-08-13 09:01:15 -06:00
struct io_pgtable_cfg pgtbl_cfg ;
struct io_pgtable_ops * pgtbl_ops ;
2021-06-21 15:38:56 +02:00
struct drm_mm mm ;
spinlock_t mm_lock ;
2019-08-13 09:01:15 -06:00
int as ;
atomic_t as_count ;
struct list_head list ;
} ;
2018-09-10 14:27:58 -05:00
struct panfrost_file_priv {
struct panfrost_device * pfdev ;
struct drm_sched_entity sched_entity [ NUM_JOB_SLOTS ] ;
2019-08-13 09:01:15 -06:00
2021-06-21 15:38:56 +02:00
struct panfrost_mmu * mmu ;
2018-09-10 14:27:58 -05:00
} ;
static inline struct panfrost_device * to_panfrost_device ( struct drm_device * ddev )
{
return ddev - > dev_private ;
}
static inline int panfrost_model_cmp ( struct panfrost_device * pfdev , s32 id )
{
s32 match_id = pfdev - > features . id ;
if ( match_id & 0xf000 )
match_id & = 0xf00f ;
return match_id - id ;
}
2019-06-18 10:16:47 +02:00
static inline bool panfrost_model_is_bifrost ( struct panfrost_device * pfdev )
{
return panfrost_model_cmp ( pfdev , 0x1000 ) > = 0 ;
}
2018-09-10 14:27:58 -05:00
static inline bool panfrost_model_eq ( struct panfrost_device * pfdev , s32 id )
{
return ! panfrost_model_cmp ( pfdev , id ) ;
}
2019-06-18 10:16:46 +02:00
int panfrost_unstable_ioctl_check ( void ) ;
2018-09-10 14:27:58 -05:00
int panfrost_device_init ( struct panfrost_device * pfdev ) ;
void panfrost_device_fini ( struct panfrost_device * pfdev ) ;
2019-08-08 14:30:39 -06:00
void panfrost_device_reset ( struct panfrost_device * pfdev ) ;
2018-09-10 14:27:58 -05:00
2022-11-29 19:19:32 +00:00
extern const struct dev_pm_ops panfrost_pm_ops ;
2018-09-10 14:27:58 -05:00
2021-06-30 08:27:41 +02:00
enum drm_panfrost_exception_type {
DRM_PANFROST_EXCEPTION_OK = 0x00 ,
DRM_PANFROST_EXCEPTION_DONE = 0x01 ,
DRM_PANFROST_EXCEPTION_INTERRUPTED = 0x02 ,
DRM_PANFROST_EXCEPTION_STOPPED = 0x03 ,
DRM_PANFROST_EXCEPTION_TERMINATED = 0x04 ,
DRM_PANFROST_EXCEPTION_KABOOM = 0x05 ,
DRM_PANFROST_EXCEPTION_EUREKA = 0x06 ,
DRM_PANFROST_EXCEPTION_ACTIVE = 0x08 ,
2021-06-30 08:27:49 +02:00
DRM_PANFROST_EXCEPTION_MAX_NON_FAULT = 0x3f ,
2021-06-30 08:27:41 +02:00
DRM_PANFROST_EXCEPTION_JOB_CONFIG_FAULT = 0x40 ,
DRM_PANFROST_EXCEPTION_JOB_POWER_FAULT = 0x41 ,
DRM_PANFROST_EXCEPTION_JOB_READ_FAULT = 0x42 ,
DRM_PANFROST_EXCEPTION_JOB_WRITE_FAULT = 0x43 ,
DRM_PANFROST_EXCEPTION_JOB_AFFINITY_FAULT = 0x44 ,
DRM_PANFROST_EXCEPTION_JOB_BUS_FAULT = 0x48 ,
DRM_PANFROST_EXCEPTION_INSTR_INVALID_PC = 0x50 ,
DRM_PANFROST_EXCEPTION_INSTR_INVALID_ENC = 0x51 ,
DRM_PANFROST_EXCEPTION_INSTR_TYPE_MISMATCH = 0x52 ,
DRM_PANFROST_EXCEPTION_INSTR_OPERAND_FAULT = 0x53 ,
DRM_PANFROST_EXCEPTION_INSTR_TLS_FAULT = 0x54 ,
DRM_PANFROST_EXCEPTION_INSTR_BARRIER_FAULT = 0x55 ,
DRM_PANFROST_EXCEPTION_INSTR_ALIGN_FAULT = 0x56 ,
DRM_PANFROST_EXCEPTION_DATA_INVALID_FAULT = 0x58 ,
DRM_PANFROST_EXCEPTION_TILE_RANGE_FAULT = 0x59 ,
DRM_PANFROST_EXCEPTION_ADDR_RANGE_FAULT = 0x5a ,
DRM_PANFROST_EXCEPTION_IMPRECISE_FAULT = 0x5b ,
DRM_PANFROST_EXCEPTION_OOM = 0x60 ,
DRM_PANFROST_EXCEPTION_OOM_AFBC = 0x61 ,
DRM_PANFROST_EXCEPTION_UNKNOWN = 0x7f ,
DRM_PANFROST_EXCEPTION_DELAYED_BUS_FAULT = 0x80 ,
DRM_PANFROST_EXCEPTION_GPU_SHAREABILITY_FAULT = 0x88 ,
DRM_PANFROST_EXCEPTION_SYS_SHAREABILITY_FAULT = 0x89 ,
DRM_PANFROST_EXCEPTION_GPU_CACHEABILITY_FAULT = 0x8a ,
DRM_PANFROST_EXCEPTION_TRANSLATION_FAULT_0 = 0xc0 ,
DRM_PANFROST_EXCEPTION_TRANSLATION_FAULT_1 = 0xc1 ,
DRM_PANFROST_EXCEPTION_TRANSLATION_FAULT_2 = 0xc2 ,
DRM_PANFROST_EXCEPTION_TRANSLATION_FAULT_3 = 0xc3 ,
DRM_PANFROST_EXCEPTION_TRANSLATION_FAULT_4 = 0xc4 ,
DRM_PANFROST_EXCEPTION_TRANSLATION_FAULT_IDENTITY = 0xc7 ,
DRM_PANFROST_EXCEPTION_PERM_FAULT_0 = 0xc8 ,
DRM_PANFROST_EXCEPTION_PERM_FAULT_1 = 0xc9 ,
DRM_PANFROST_EXCEPTION_PERM_FAULT_2 = 0xca ,
DRM_PANFROST_EXCEPTION_PERM_FAULT_3 = 0xcb ,
DRM_PANFROST_EXCEPTION_TRANSTAB_BUS_FAULT_0 = 0xd0 ,
DRM_PANFROST_EXCEPTION_TRANSTAB_BUS_FAULT_1 = 0xd1 ,
DRM_PANFROST_EXCEPTION_TRANSTAB_BUS_FAULT_2 = 0xd2 ,
DRM_PANFROST_EXCEPTION_TRANSTAB_BUS_FAULT_3 = 0xd3 ,
DRM_PANFROST_EXCEPTION_ACCESS_FLAG_0 = 0xd8 ,
DRM_PANFROST_EXCEPTION_ACCESS_FLAG_1 = 0xd9 ,
DRM_PANFROST_EXCEPTION_ACCESS_FLAG_2 = 0xda ,
DRM_PANFROST_EXCEPTION_ACCESS_FLAG_3 = 0xdb ,
DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_IN0 = 0xe0 ,
DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_IN1 = 0xe1 ,
DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_IN2 = 0xe2 ,
DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_IN3 = 0xe3 ,
DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_OUT0 = 0xe4 ,
DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_OUT1 = 0xe5 ,
DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_OUT2 = 0xe6 ,
DRM_PANFROST_EXCEPTION_ADDR_SIZE_FAULT_OUT3 = 0xe7 ,
DRM_PANFROST_EXCEPTION_MEM_ATTR_FAULT_0 = 0xe8 ,
DRM_PANFROST_EXCEPTION_MEM_ATTR_FAULT_1 = 0xe9 ,
DRM_PANFROST_EXCEPTION_MEM_ATTR_FAULT_2 = 0xea ,
DRM_PANFROST_EXCEPTION_MEM_ATTR_FAULT_3 = 0xeb ,
DRM_PANFROST_EXCEPTION_MEM_ATTR_NONCACHE_0 = 0xec ,
DRM_PANFROST_EXCEPTION_MEM_ATTR_NONCACHE_1 = 0xed ,
DRM_PANFROST_EXCEPTION_MEM_ATTR_NONCACHE_2 = 0xee ,
DRM_PANFROST_EXCEPTION_MEM_ATTR_NONCACHE_3 = 0xef ,
} ;
2021-06-30 08:27:49 +02:00
static inline bool
panfrost_exception_is_fault ( u32 exception_code )
{
return exception_code > DRM_PANFROST_EXCEPTION_MAX_NON_FAULT ;
}
2021-06-30 08:27:40 +02:00
const char * panfrost_exception_name ( u32 exception_code ) ;
2021-06-30 08:27:48 +02:00
bool panfrost_exception_needs_reset ( const struct panfrost_device * pfdev ,
u32 exception_code ) ;
2018-09-10 14:27:58 -05:00
2021-06-30 08:27:42 +02:00
static inline void
panfrost_device_schedule_reset ( struct panfrost_device * pfdev )
{
2021-06-30 08:27:44 +02:00
atomic_set ( & pfdev - > reset . pending , 1 ) ;
queue_work ( pfdev - > reset . wq , & pfdev - > reset . work ) ;
2021-06-30 08:27:42 +02:00
}
2018-09-10 14:27:58 -05:00
# endif