1a1d2a633SQiang Yu /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2a1d2a633SQiang Yu /* Copyright 2018-2019 Qiang Yu <yuq825@gmail.com> */ 3a1d2a633SQiang Yu 4a1d2a633SQiang Yu #ifndef __LIMA_DEVICE_H__ 5a1d2a633SQiang Yu #define __LIMA_DEVICE_H__ 6a1d2a633SQiang Yu 7a1d2a633SQiang Yu #include <drm/drm_device.h> 8a1d2a633SQiang Yu #include <linux/delay.h> 9b78edd46SQiang Yu #include <linux/list.h> 10b78edd46SQiang Yu #include <linux/mutex.h> 11a1d2a633SQiang Yu 12a1d2a633SQiang Yu #include "lima_sched.h" 13b78edd46SQiang Yu #include "lima_dump.h" 1419969707SMartin Blumenstingl #include "lima_devfreq.h" 15a1d2a633SQiang Yu 16a1d2a633SQiang Yu enum lima_gpu_id { 17a1d2a633SQiang Yu lima_gpu_mali400 = 0, 18a1d2a633SQiang Yu lima_gpu_mali450, 19a1d2a633SQiang Yu lima_gpu_num, 20a1d2a633SQiang Yu }; 21a1d2a633SQiang Yu 22a1d2a633SQiang Yu enum lima_ip_id { 23a1d2a633SQiang Yu lima_ip_pmu, 24a1d2a633SQiang Yu lima_ip_gpmmu, 25a1d2a633SQiang Yu lima_ip_ppmmu0, 26a1d2a633SQiang Yu lima_ip_ppmmu1, 27a1d2a633SQiang Yu lima_ip_ppmmu2, 28a1d2a633SQiang Yu lima_ip_ppmmu3, 29a1d2a633SQiang Yu lima_ip_ppmmu4, 30a1d2a633SQiang Yu lima_ip_ppmmu5, 31a1d2a633SQiang Yu lima_ip_ppmmu6, 32a1d2a633SQiang Yu lima_ip_ppmmu7, 33a1d2a633SQiang Yu lima_ip_gp, 34a1d2a633SQiang Yu lima_ip_pp0, 35a1d2a633SQiang Yu lima_ip_pp1, 36a1d2a633SQiang Yu lima_ip_pp2, 37a1d2a633SQiang Yu lima_ip_pp3, 38a1d2a633SQiang Yu lima_ip_pp4, 39a1d2a633SQiang Yu lima_ip_pp5, 40a1d2a633SQiang Yu lima_ip_pp6, 41a1d2a633SQiang Yu lima_ip_pp7, 42a1d2a633SQiang Yu lima_ip_l2_cache0, 43a1d2a633SQiang Yu lima_ip_l2_cache1, 44a1d2a633SQiang Yu lima_ip_l2_cache2, 45a1d2a633SQiang Yu lima_ip_dlbu, 46a1d2a633SQiang Yu lima_ip_bcast, 47a1d2a633SQiang Yu lima_ip_pp_bcast, 48a1d2a633SQiang Yu lima_ip_ppmmu_bcast, 49a1d2a633SQiang Yu lima_ip_num, 50a1d2a633SQiang Yu }; 51a1d2a633SQiang Yu 52a1d2a633SQiang Yu struct lima_device; 53a1d2a633SQiang Yu 54a1d2a633SQiang Yu struct lima_ip { 55a1d2a633SQiang Yu struct lima_device *dev; 56a1d2a633SQiang Yu enum lima_ip_id id; 57a1d2a633SQiang Yu bool present; 58a1d2a633SQiang Yu 59a1d2a633SQiang Yu void __iomem *iomem; 60a1d2a633SQiang Yu int irq; 61a1d2a633SQiang Yu 62a1d2a633SQiang Yu union { 63a1d2a633SQiang Yu /* gp/pp */ 64a1d2a633SQiang Yu bool async_reset; 65a1d2a633SQiang Yu /* l2 cache */ 66a1d2a633SQiang Yu spinlock_t lock; 67*9f5072a1SQiang Yu /* pmu */ 68*9f5072a1SQiang Yu u32 mask; 69a1d2a633SQiang Yu } data; 70a1d2a633SQiang Yu }; 71a1d2a633SQiang Yu 72a1d2a633SQiang Yu enum lima_pipe_id { 73a1d2a633SQiang Yu lima_pipe_gp, 74a1d2a633SQiang Yu lima_pipe_pp, 75a1d2a633SQiang Yu lima_pipe_num, 76a1d2a633SQiang Yu }; 77a1d2a633SQiang Yu 78a1d2a633SQiang Yu struct lima_device { 79a1d2a633SQiang Yu struct device *dev; 80a1d2a633SQiang Yu struct drm_device *ddev; 81a1d2a633SQiang Yu 82a1d2a633SQiang Yu enum lima_gpu_id id; 83a1d2a633SQiang Yu u32 gp_version; 84a1d2a633SQiang Yu u32 pp_version; 85a1d2a633SQiang Yu int num_pp; 86a1d2a633SQiang Yu 87a1d2a633SQiang Yu void __iomem *iomem; 88a1d2a633SQiang Yu struct clk *clk_bus; 89a1d2a633SQiang Yu struct clk *clk_gpu; 90a1d2a633SQiang Yu struct reset_control *reset; 91a1d2a633SQiang Yu struct regulator *regulator; 92a1d2a633SQiang Yu 93a1d2a633SQiang Yu struct lima_ip ip[lima_ip_num]; 94a1d2a633SQiang Yu struct lima_sched_pipe pipe[lima_pipe_num]; 95a1d2a633SQiang Yu 96a1d2a633SQiang Yu struct lima_vm *empty_vm; 97a1d2a633SQiang Yu uint64_t va_start; 98a1d2a633SQiang Yu uint64_t va_end; 99a1d2a633SQiang Yu 100a1d2a633SQiang Yu u32 *dlbu_cpu; 101a1d2a633SQiang Yu dma_addr_t dlbu_dma; 102b78edd46SQiang Yu 10319969707SMartin Blumenstingl struct lima_devfreq devfreq; 10419969707SMartin Blumenstingl 105b78edd46SQiang Yu /* debug info */ 106b78edd46SQiang Yu struct lima_dump_head dump; 107b78edd46SQiang Yu struct list_head error_task_list; 108b78edd46SQiang Yu struct mutex error_task_list_lock; 109a1d2a633SQiang Yu }; 110a1d2a633SQiang Yu 111a1d2a633SQiang Yu static inline struct lima_device * 112a1d2a633SQiang Yu to_lima_dev(struct drm_device *dev) 113a1d2a633SQiang Yu { 114a1d2a633SQiang Yu return dev->dev_private; 115a1d2a633SQiang Yu } 116a1d2a633SQiang Yu 117a1d2a633SQiang Yu int lima_device_init(struct lima_device *ldev); 118a1d2a633SQiang Yu void lima_device_fini(struct lima_device *ldev); 119a1d2a633SQiang Yu 120a1d2a633SQiang Yu const char *lima_ip_name(struct lima_ip *ip); 121a1d2a633SQiang Yu 122a1d2a633SQiang Yu typedef int (*lima_poll_func_t)(struct lima_ip *); 123a1d2a633SQiang Yu 124a1d2a633SQiang Yu static inline int lima_poll_timeout(struct lima_ip *ip, lima_poll_func_t func, 125a1d2a633SQiang Yu int sleep_us, int timeout_us) 126a1d2a633SQiang Yu { 127a1d2a633SQiang Yu ktime_t timeout = ktime_add_us(ktime_get(), timeout_us); 128a1d2a633SQiang Yu 129a1d2a633SQiang Yu might_sleep_if(sleep_us); 130a1d2a633SQiang Yu while (1) { 131a1d2a633SQiang Yu if (func(ip)) 132a1d2a633SQiang Yu return 0; 133a1d2a633SQiang Yu 134a1d2a633SQiang Yu if (timeout_us && ktime_compare(ktime_get(), timeout) > 0) 135a1d2a633SQiang Yu return -ETIMEDOUT; 136a1d2a633SQiang Yu 137a1d2a633SQiang Yu if (sleep_us) 138a1d2a633SQiang Yu usleep_range((sleep_us >> 2) + 1, sleep_us); 139a1d2a633SQiang Yu } 140a1d2a633SQiang Yu return 0; 141a1d2a633SQiang Yu } 142a1d2a633SQiang Yu 143a1d2a633SQiang Yu #endif 144