18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* Copyright 2018 Marty E. Plummer <hanetzer@startmail.com> */ 38c2ecf20Sopenharmony_ci/* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */ 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#ifndef __PANFROST_DEVICE_H__ 68c2ecf20Sopenharmony_ci#define __PANFROST_DEVICE_H__ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/atomic.h> 98c2ecf20Sopenharmony_ci#include <linux/io-pgtable.h> 108c2ecf20Sopenharmony_ci#include <linux/regulator/consumer.h> 118c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 128c2ecf20Sopenharmony_ci#include <drm/drm_device.h> 138c2ecf20Sopenharmony_ci#include <drm/drm_mm.h> 148c2ecf20Sopenharmony_ci#include <drm/gpu_scheduler.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include "panfrost_devfreq.h" 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_cistruct panfrost_device; 198c2ecf20Sopenharmony_cistruct panfrost_mmu; 208c2ecf20Sopenharmony_cistruct panfrost_job_slot; 218c2ecf20Sopenharmony_cistruct panfrost_job; 228c2ecf20Sopenharmony_cistruct panfrost_perfcnt; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define NUM_JOB_SLOTS 3 258c2ecf20Sopenharmony_ci#define MAX_PM_DOMAINS 3 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistruct panfrost_features { 288c2ecf20Sopenharmony_ci u16 id; 298c2ecf20Sopenharmony_ci u16 revision; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci u64 shader_present; 328c2ecf20Sopenharmony_ci u64 tiler_present; 338c2ecf20Sopenharmony_ci u64 l2_present; 348c2ecf20Sopenharmony_ci u64 stack_present; 358c2ecf20Sopenharmony_ci u32 as_present; 368c2ecf20Sopenharmony_ci u32 js_present; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci u32 l2_features; 398c2ecf20Sopenharmony_ci u32 core_features; 408c2ecf20Sopenharmony_ci u32 tiler_features; 418c2ecf20Sopenharmony_ci u32 mem_features; 428c2ecf20Sopenharmony_ci u32 mmu_features; 438c2ecf20Sopenharmony_ci u32 thread_features; 448c2ecf20Sopenharmony_ci u32 max_threads; 458c2ecf20Sopenharmony_ci u32 thread_max_workgroup_sz; 468c2ecf20Sopenharmony_ci u32 thread_max_barrier_sz; 478c2ecf20Sopenharmony_ci u32 coherency_features; 488c2ecf20Sopenharmony_ci u32 texture_features[4]; 498c2ecf20Sopenharmony_ci u32 js_features[16]; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci u32 nr_core_groups; 528c2ecf20Sopenharmony_ci u32 thread_tls_alloc; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci unsigned long hw_features[64 / BITS_PER_LONG]; 558c2ecf20Sopenharmony_ci unsigned long hw_issues[64 / BITS_PER_LONG]; 568c2ecf20Sopenharmony_ci}; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci/* 598c2ecf20Sopenharmony_ci * Features that cannot be automatically detected and need matching using the 608c2ecf20Sopenharmony_ci * compatible string, typically SoC-specific. 618c2ecf20Sopenharmony_ci */ 628c2ecf20Sopenharmony_cistruct panfrost_compatible { 638c2ecf20Sopenharmony_ci /* Supplies count and names. */ 648c2ecf20Sopenharmony_ci int num_supplies; 658c2ecf20Sopenharmony_ci const char * const *supply_names; 668c2ecf20Sopenharmony_ci /* 678c2ecf20Sopenharmony_ci * Number of power domains required, note that values 0 and 1 are 688c2ecf20Sopenharmony_ci * handled identically, as only values > 1 need special handling. 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_ci int num_pm_domains; 718c2ecf20Sopenharmony_ci /* Only required if num_pm_domains > 1. */ 728c2ecf20Sopenharmony_ci const char * const *pm_domain_names; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci /* Vendor implementation quirks callback */ 758c2ecf20Sopenharmony_ci void (*vendor_quirk)(struct panfrost_device *pfdev); 768c2ecf20Sopenharmony_ci}; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_cistruct panfrost_device { 798c2ecf20Sopenharmony_ci struct device *dev; 808c2ecf20Sopenharmony_ci struct drm_device *ddev; 818c2ecf20Sopenharmony_ci struct platform_device *pdev; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci void __iomem *iomem; 848c2ecf20Sopenharmony_ci struct clk *clock; 858c2ecf20Sopenharmony_ci struct clk *bus_clock; 868c2ecf20Sopenharmony_ci struct regulator_bulk_data *regulators; 878c2ecf20Sopenharmony_ci struct reset_control *rstc; 888c2ecf20Sopenharmony_ci /* pm_domains for devices with more than one. */ 898c2ecf20Sopenharmony_ci struct device *pm_domain_devs[MAX_PM_DOMAINS]; 908c2ecf20Sopenharmony_ci struct device_link *pm_domain_links[MAX_PM_DOMAINS]; 918c2ecf20Sopenharmony_ci bool coherent; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci struct panfrost_features features; 948c2ecf20Sopenharmony_ci const struct panfrost_compatible *comp; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci spinlock_t as_lock; 978c2ecf20Sopenharmony_ci unsigned long as_in_use_mask; 988c2ecf20Sopenharmony_ci unsigned long as_alloc_mask; 998c2ecf20Sopenharmony_ci struct list_head as_lru_list; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci struct panfrost_job_slot *js; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci struct panfrost_job *jobs[NUM_JOB_SLOTS]; 1048c2ecf20Sopenharmony_ci struct list_head scheduled_jobs; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci struct panfrost_perfcnt *perfcnt; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci struct mutex sched_lock; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci struct { 1118c2ecf20Sopenharmony_ci struct work_struct work; 1128c2ecf20Sopenharmony_ci atomic_t pending; 1138c2ecf20Sopenharmony_ci } reset; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci struct mutex shrinker_lock; 1168c2ecf20Sopenharmony_ci struct list_head shrinker_list; 1178c2ecf20Sopenharmony_ci struct shrinker shrinker; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci struct panfrost_devfreq pfdevfreq; 1208c2ecf20Sopenharmony_ci}; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cistruct panfrost_mmu { 1238c2ecf20Sopenharmony_ci struct panfrost_device *pfdev; 1248c2ecf20Sopenharmony_ci struct kref refcount; 1258c2ecf20Sopenharmony_ci struct io_pgtable_cfg pgtbl_cfg; 1268c2ecf20Sopenharmony_ci struct io_pgtable_ops *pgtbl_ops; 1278c2ecf20Sopenharmony_ci struct drm_mm mm; 1288c2ecf20Sopenharmony_ci spinlock_t mm_lock; 1298c2ecf20Sopenharmony_ci int as; 1308c2ecf20Sopenharmony_ci atomic_t as_count; 1318c2ecf20Sopenharmony_ci struct list_head list; 1328c2ecf20Sopenharmony_ci}; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistruct panfrost_file_priv { 1358c2ecf20Sopenharmony_ci struct panfrost_device *pfdev; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci struct drm_sched_entity sched_entity[NUM_JOB_SLOTS]; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci struct panfrost_mmu *mmu; 1408c2ecf20Sopenharmony_ci}; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic inline struct panfrost_device *to_panfrost_device(struct drm_device *ddev) 1438c2ecf20Sopenharmony_ci{ 1448c2ecf20Sopenharmony_ci return ddev->dev_private; 1458c2ecf20Sopenharmony_ci} 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_cistatic inline int panfrost_model_cmp(struct panfrost_device *pfdev, s32 id) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci s32 match_id = pfdev->features.id; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci if (match_id & 0xf000) 1528c2ecf20Sopenharmony_ci match_id &= 0xf00f; 1538c2ecf20Sopenharmony_ci return match_id - id; 1548c2ecf20Sopenharmony_ci} 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cistatic inline bool panfrost_model_is_bifrost(struct panfrost_device *pfdev) 1578c2ecf20Sopenharmony_ci{ 1588c2ecf20Sopenharmony_ci return panfrost_model_cmp(pfdev, 0x1000) >= 0; 1598c2ecf20Sopenharmony_ci} 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_cistatic inline bool panfrost_model_eq(struct panfrost_device *pfdev, s32 id) 1628c2ecf20Sopenharmony_ci{ 1638c2ecf20Sopenharmony_ci return !panfrost_model_cmp(pfdev, id); 1648c2ecf20Sopenharmony_ci} 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ciint panfrost_unstable_ioctl_check(void); 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ciint panfrost_device_init(struct panfrost_device *pfdev); 1698c2ecf20Sopenharmony_civoid panfrost_device_fini(struct panfrost_device *pfdev); 1708c2ecf20Sopenharmony_civoid panfrost_device_reset(struct panfrost_device *pfdev); 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ciint panfrost_device_resume(struct device *dev); 1738c2ecf20Sopenharmony_ciint panfrost_device_suspend(struct device *dev); 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ciconst char *panfrost_exception_name(struct panfrost_device *pfdev, u32 exception_code); 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci#endif 178