summaryrefslogtreecommitdiffstats
path: root/drivers/accel/ivpu/ivpu_hw.h
blob: b2909168a0a6902b4fb061910796ac19d5caf6e1 (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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (C) 2020-2023 Intel Corporation
 */

#ifndef __IVPU_HW_H__
#define __IVPU_HW_H__

#include "ivpu_drv.h"

struct ivpu_hw_ops {
	int (*info_init)(struct ivpu_device *vdev);
	int (*power_up)(struct ivpu_device *vdev);
	int (*boot_fw)(struct ivpu_device *vdev);
	int (*power_down)(struct ivpu_device *vdev);
	int (*reset)(struct ivpu_device *vdev);
	bool (*is_idle)(struct ivpu_device *vdev);
	int (*wait_for_idle)(struct ivpu_device *vdev);
	void (*wdt_disable)(struct ivpu_device *vdev);
	void (*diagnose_failure)(struct ivpu_device *vdev);
	u32 (*profiling_freq_get)(struct ivpu_device *vdev);
	void (*profiling_freq_drive)(struct ivpu_device *vdev, bool enable);
	u32 (*reg_pll_freq_get)(struct ivpu_device *vdev);
	u32 (*reg_telemetry_offset_get)(struct ivpu_device *vdev);
	u32 (*reg_telemetry_size_get)(struct ivpu_device *vdev);
	u32 (*reg_telemetry_enable_get)(struct ivpu_device *vdev);
	void (*reg_db_set)(struct ivpu_device *vdev, u32 db_id);
	u32 (*reg_ipc_rx_addr_get)(struct ivpu_device *vdev);
	u32 (*reg_ipc_rx_count_get)(struct ivpu_device *vdev);
	void (*reg_ipc_tx_set)(struct ivpu_device *vdev, u32 vpu_addr);
	void (*irq_clear)(struct ivpu_device *vdev);
	void (*irq_enable)(struct ivpu_device *vdev);
	void (*irq_disable)(struct ivpu_device *vdev);
	irqreturn_t (*irq_handler)(int irq, void *ptr);
};

struct ivpu_addr_range {
	resource_size_t start;
	resource_size_t end;
};

struct ivpu_hw_info {
	const struct ivpu_hw_ops *ops;
	struct {
		struct ivpu_addr_range global;
		struct ivpu_addr_range user;
		struct ivpu_addr_range shave;
		struct ivpu_addr_range dma;
	} ranges;
	struct {
		u8 min_ratio;
		u8 max_ratio;
		/*
		 * Pll ratio for the efficiency frequency. The VPU has optimum
		 * performance to power ratio at this frequency.
		 */
		u8 pn_ratio;
		u32 profiling_freq;
	} pll;
	u32 tile_fuse;
	u32 sku;
	u16 config;
	int dma_bits;
	ktime_t d0i3_entry_host_ts;
	u64 d0i3_entry_vpu_ts;
};

extern const struct ivpu_hw_ops ivpu_hw_37xx_ops;
extern const struct ivpu_hw_ops ivpu_hw_40xx_ops;

static inline int ivpu_hw_info_init(struct ivpu_device *vdev)
{
	return vdev->hw->ops->info_init(vdev);
};

static inline int ivpu_hw_power_up(struct ivpu_device *vdev)
{
	ivpu_dbg(vdev, PM, "HW power up\n");

	return vdev->hw->ops->power_up(vdev);
};

static inline int ivpu_hw_boot_fw(struct ivpu_device *vdev)
{
	return vdev->hw->ops->boot_fw(vdev);
};

static inline bool ivpu_hw_is_idle(struct ivpu_device *vdev)
{
	return vdev->hw->ops->is_idle(vdev);
};

static inline int ivpu_hw_wait_for_idle(struct ivpu_device *vdev)
{
	return vdev->hw->ops->wait_for_idle(vdev);
};

static inline int ivpu_hw_power_down(struct ivpu_device *vdev)
{
	ivpu_dbg(vdev, PM, "HW power down\n");

	return vdev->hw->ops->power_down(vdev);
};

static inline int ivpu_hw_reset(struct ivpu_device *vdev)
{
	ivpu_dbg(vdev, PM, "HW reset\n");

	return vdev->hw->ops->reset(vdev);
};

static inline void ivpu_hw_wdt_disable(struct ivpu_device *vdev)
{
	vdev->hw->ops->wdt_disable(vdev);
};

static inline u32 ivpu_hw_profiling_freq_get(struct ivpu_device *vdev)
{
	return vdev->hw->ops->profiling_freq_get(vdev);
};

static inline void ivpu_hw_profiling_freq_drive(struct ivpu_device *vdev, bool enable)
{
	return vdev->hw->ops->profiling_freq_drive(vdev, enable);
};

/* Register indirect accesses */
static inline u32 ivpu_hw_reg_pll_freq_get(struct ivpu_device *vdev)
{
	return vdev->hw->ops->reg_pll_freq_get(vdev);
};

static inline u32 ivpu_hw_reg_telemetry_offset_get(struct ivpu_device *vdev)
{
	return vdev->hw->ops->reg_telemetry_offset_get(vdev);
};

static inline u32 ivpu_hw_reg_telemetry_size_get(struct ivpu_device *vdev)
{
	return vdev->hw->ops->reg_telemetry_size_get(vdev);
};

static inline u32 ivpu_hw_reg_telemetry_enable_get(struct ivpu_device *vdev)
{
	return vdev->hw->ops->reg_telemetry_enable_get(vdev);
};

static inline void ivpu_hw_reg_db_set(struct ivpu_device *vdev, u32 db_id)
{
	vdev->hw->ops->reg_db_set(vdev, db_id);
};

static inline u32 ivpu_hw_reg_ipc_rx_addr_get(struct ivpu_device *vdev)
{
	return vdev->hw->ops->reg_ipc_rx_addr_get(vdev);
};

static inline u32 ivpu_hw_reg_ipc_rx_count_get(struct ivpu_device *vdev)
{
	return vdev->hw->ops->reg_ipc_rx_count_get(vdev);
};

static inline void ivpu_hw_reg_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr)
{
	vdev->hw->ops->reg_ipc_tx_set(vdev, vpu_addr);
};

static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev)
{
	vdev->hw->ops->irq_clear(vdev);
};

static inline void ivpu_hw_irq_enable(struct ivpu_device *vdev)
{
	vdev->hw->ops->irq_enable(vdev);
};

static inline void ivpu_hw_irq_disable(struct ivpu_device *vdev)
{
	vdev->hw->ops->irq_disable(vdev);
};

static inline void ivpu_hw_init_range(struct ivpu_addr_range *range, u64 start, u64 size)
{
	range->start = start;
	range->end = start + size;
}

static inline u64 ivpu_hw_range_size(const struct ivpu_addr_range *range)
{
	return range->end - range->start;
}

static inline void ivpu_hw_diagnose_failure(struct ivpu_device *vdev)
{
	vdev->hw->ops->diagnose_failure(vdev);
}

#endif /* __IVPU_HW_H__ */