summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/lima/lima_device.h
blob: 41b9d7b4bcc7a0128adda97379b6048735310096 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/* Copyright 2018-2019 Qiang Yu <yuq825@gmail.com> */

#ifndef __LIMA_DEVICE_H__
#define __LIMA_DEVICE_H__

#include <drm/drm_device.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/mutex.h>

#include "lima_sched.h"
#include "lima_dump.h"
#include "lima_devfreq.h"

enum lima_gpu_id {
	lima_gpu_mali400 = 0,
	lima_gpu_mali450,
	lima_gpu_num,
};

enum lima_ip_id {
	lima_ip_pmu,
	lima_ip_gpmmu,
	lima_ip_ppmmu0,
	lima_ip_ppmmu1,
	lima_ip_ppmmu2,
	lima_ip_ppmmu3,
	lima_ip_ppmmu4,
	lima_ip_ppmmu5,
	lima_ip_ppmmu6,
	lima_ip_ppmmu7,
	lima_ip_gp,
	lima_ip_pp0,
	lima_ip_pp1,
	lima_ip_pp2,
	lima_ip_pp3,
	lima_ip_pp4,
	lima_ip_pp5,
	lima_ip_pp6,
	lima_ip_pp7,
	lima_ip_l2_cache0,
	lima_ip_l2_cache1,
	lima_ip_l2_cache2,
	lima_ip_dlbu,
	lima_ip_bcast,
	lima_ip_pp_bcast,
	lima_ip_ppmmu_bcast,
	lima_ip_num,
};

struct lima_device;

struct lima_ip {
	struct lima_device *dev;
	enum lima_ip_id id;
	bool present;

	void __iomem *iomem;
	int irq;

	union {
		/* gp/pp */
		bool async_reset;
		/* l2 cache */
		spinlock_t lock;
		/* pmu/bcast */
		u32 mask;
	} data;
};

enum lima_pipe_id {
	lima_pipe_gp,
	lima_pipe_pp,
	lima_pipe_num,
};

struct lima_device {
	struct device *dev;
	struct drm_device *ddev;

	enum lima_gpu_id id;
	u32 gp_version;
	u32 pp_version;
	int num_pp;

	void __iomem *iomem;
	struct clk *clk_bus;
	struct clk *clk_gpu;
	struct reset_control *reset;
	struct regulator *regulator;

	struct lima_ip ip[lima_ip_num];
	struct lima_sched_pipe pipe[lima_pipe_num];

	struct lima_vm *empty_vm;
	uint64_t va_start;
	uint64_t va_end;

	u32 *dlbu_cpu;
	dma_addr_t dlbu_dma;

	struct lima_devfreq devfreq;

	/* debug info */
	struct lima_dump_head dump;
	struct list_head error_task_list;
	struct mutex error_task_list_lock;
};

static inline struct lima_device *
to_lima_dev(struct drm_device *dev)
{
	return dev->dev_private;
}

int lima_device_init(struct lima_device *ldev);
void lima_device_fini(struct lima_device *ldev);

const char *lima_ip_name(struct lima_ip *ip);

typedef int (*lima_poll_func_t)(struct lima_ip *);

static inline int lima_poll_timeout(struct lima_ip *ip, lima_poll_func_t func,
				    int sleep_us, int timeout_us)
{
	ktime_t timeout = ktime_add_us(ktime_get(), timeout_us);

	might_sleep_if(sleep_us);
	while (1) {
		if (func(ip))
			return 0;

		if (timeout_us && ktime_compare(ktime_get(), timeout) > 0)
			return -ETIMEDOUT;

		if (sleep_us)
			usleep_range((sleep_us >> 2) + 1, sleep_us);
	}
	return 0;
}

int lima_device_suspend(struct device *dev);
int lima_device_resume(struct device *dev);

#endif