summaryrefslogtreecommitdiff
path: root/drivers/video/rockchip/mpp/mpp_rkvdec2.h
blob: bf237ca7fd9b608a97113f9f0970ca5c691c8f0d (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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
 * Copyright (c) 2021 Rockchip Electronics Co., Ltd
 *
 * author:
 *	Herman Chen <herman.chen@rock-chips.com>
 *
 */
#ifndef __ROCKCHIP_MPP_RKVDEC2_H__
#define __ROCKCHIP_MPP_RKVDEC2_H__

#include <linux/dma-iommu.h>
#include <linux/iopoll.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/regmap.h>
#include <linux/kernel.h>
#include <linux/thermal.h>
#include <linux/notifier.h>
#include <linux/proc_fs.h>
#include <linux/nospec.h>
#include <linux/rockchip/rockchip_sip.h>
#include <linux/regulator/consumer.h>

#include <soc/rockchip/pm_domains.h>
#include <soc/rockchip/rockchip_sip.h>

#include "mpp_debug.h"
#include "mpp_common.h"
#include "mpp_iommu.h"

#define RKVDEC_DRIVER_NAME		"mpp_rkvdec2"

#define	RKVDEC_SESSION_MAX_BUFFERS	40
/* The maximum registers number of all the version */
#define RKVDEC_REG_NUM			278
#define RKVDEC_REG_HW_ID_INDEX		0
#define RKVDEC_REG_START_INDEX		0
#define RKVDEC_REG_END_INDEX		277

#define REVDEC_GET_PROD_NUM(x)		(((x) >> 16) & 0xffff)
#define RKVDEC_REG_FORMAT_INDEX		9
#define RKVDEC_GET_FORMAT(x)		((x) & 0x3ff)

#define RKVDEC_REG_START_EN_BASE       0x28

#define RKVDEC_REG_START_EN_INDEX      10

#define RKVDEC_START_EN			BIT(0)

#define RKVDEC_REG_YSTRIDE_INDEX	20
#define RKVDEC_REG_CORE_CTRL_INDEX	28
#define RKVDEC_REG_FILM_IDX_MASK	(0x3ff0000)

#define RKVDEC_REG_RLC_BASE		0x200
#define RKVDEC_REG_RLC_BASE_INDEX	(128)

#define RKVDEC_REG_INT_EN		0x380
#define RKVDEC_REG_INT_EN_INDEX		(224)
#define RKVDEC_SOFT_RESET_READY		BIT(9)
#define RKVDEC_CABAC_END_STA		BIT(8)
#define RKVDEC_COLMV_REF_ERR_STA	BIT(7)
#define RKVDEC_BUF_EMPTY_STA		BIT(6)
#define RKVDEC_TIMEOUT_STA		BIT(5)
#define RKVDEC_ERROR_STA		BIT(4)
#define RKVDEC_BUS_STA			BIT(3)
#define RKVDEC_READY_STA		BIT(2)
#define RKVDEC_IRQ_RAW			BIT(1)
#define RKVDEC_IRQ			BIT(0)
#define RKVDEC_INT_ERROR_MASK		(RKVDEC_COLMV_REF_ERR_STA |\
					RKVDEC_BUF_EMPTY_STA |\
					RKVDEC_TIMEOUT_STA |\
					RKVDEC_ERROR_STA)
#define RKVDEC_PERF_WORKING_CNT		0x41c

/* perf sel reference register */
#define RKVDEC_PERF_SEL_OFFSET		0x20000
#define RKVDEC_PERF_SEL_NUM		64
#define RKVDEC_PERF_SEL_BASE		0x424
#define RKVDEC_SEL_VAL0_BASE		0x428
#define RKVDEC_SEL_VAL1_BASE		0x42c
#define RKVDEC_SEL_VAL2_BASE		0x430
#define RKVDEC_SET_PERF_SEL(a, b, c)	((a) | ((b) << 8) | ((c) << 16))

/* cache reference register */
#define RKVDEC_REG_CACHE0_SIZE_BASE	0x51c
#define RKVDEC_REG_CACHE1_SIZE_BASE	0x55c
#define RKVDEC_REG_CACHE2_SIZE_BASE	0x59c
#define RKVDEC_REG_CLR_CACHE0_BASE	0x510
#define RKVDEC_REG_CLR_CACHE1_BASE	0x550
#define RKVDEC_REG_CLR_CACHE2_BASE	0x590

#define RKVDEC_CACHE_PERMIT_CACHEABLE_ACCESS	BIT(0)
#define RKVDEC_CACHE_PERMIT_READ_ALLOCATE	BIT(1)
#define RKVDEC_CACHE_LINE_SIZE_64_BYTES		BIT(4)

#define to_rkvdec2_task(task)		\
		container_of(task, struct rkvdec2_task, mpp_task)
#define to_rkvdec2_dev(dev)		\
		container_of(dev, struct rkvdec2_dev, mpp)

enum RKVDEC_FMT {
	RKVDEC_FMT_H265D	= 0,
	RKVDEC_FMT_H264D	= 1,
	RKVDEC_FMT_VP9D		= 2,
	RKVDEC_FMT_AVS2		= 3,
};

#define RKVDEC_MAX_RCB_NUM		(16)

struct rcb_info_elem {
	u32 index;
	u32 size;
};

struct rkvdec2_rcb_info {
	u32 cnt;
	struct rcb_info_elem elem[RKVDEC_MAX_RCB_NUM];
};

struct rkvdec2_task {
	struct mpp_task mpp_task;

	enum MPP_CLOCK_MODE clk_mode;
	u32 reg[RKVDEC_REG_NUM];
	struct reg_offset_info off_inf;

	/* perf sel data back */
	u32 reg_sel[RKVDEC_PERF_SEL_NUM];

	u32 strm_addr;
	u32 irq_status;
	/* req for current task */
	u32 w_req_cnt;
	struct mpp_request w_reqs[MPP_MAX_MSG_NUM];
	u32 r_req_cnt;
	struct mpp_request r_reqs[MPP_MAX_MSG_NUM];
	/* image info */
	u32 width;
	u32 height;
	u32 pixels;

	/* task index for link table rnunning list */
	int slot_idx;
	u32 need_hack;

	/* event for task wait timeout or session timeout */
	wait_queue_head_t wait;
	/* link table DMA buffer */
	struct mpp_dma_buffer *table;
};

struct rkvdec2_session_priv {
	/* codec info from user */
	struct {
		/* show mode */
		u32 flag;
		/* item data */
		u64 val;
	} codec_info[DEC_INFO_BUTT];
	/* rcb_info for sram */
	struct rkvdec2_rcb_info rcb_inf;
};

struct rkvdec2_dev {
	struct mpp_dev mpp;
	/* sip smc reset lock */
	struct mutex sip_reset_lock;

	struct mpp_clk_info aclk_info;
	struct mpp_clk_info hclk_info;
	struct mpp_clk_info core_clk_info;
	struct mpp_clk_info cabac_clk_info;
	struct mpp_clk_info hevc_cabac_clk_info;
	u32 default_max_load;
#ifdef CONFIG_ROCKCHIP_MPP_PROC_FS
	struct proc_dir_entry *procfs;
#endif
	struct reset_control *rst_a;
	struct reset_control *rst_h;
	struct reset_control *rst_niu_a;
	struct reset_control *rst_niu_h;
	struct reset_control *rst_core;
	struct reset_control *rst_cabac;
	struct reset_control *rst_hevc_cabac;

#ifdef CONFIG_PM_DEVFREQ
	struct regulator *vdd;
	struct devfreq *devfreq;
	unsigned long volt;
	unsigned long core_rate_hz;
	unsigned long core_last_rate_hz;
	struct ipa_power_model_data *model_data;
	struct thermal_cooling_device *devfreq_cooling;
	struct monitor_dev_info *mdev_info;
#endif

	/* internal rcb-memory */
	u32 sram_size;
	u32 rcb_size;
	dma_addr_t rcb_iova;
	struct page *rcb_page;
	u32 rcb_min_width;

	/* for link mode */
	struct rkvdec_link_dev *link_dec;
	struct mpp_dma_buffer *fix;

	/* for ccu link mode */
	struct rkvdec2_ccu *ccu;
	u32 core_mask;
	u32 task_index;
};

int mpp_set_rcbbuf(struct mpp_dev *mpp, struct mpp_session *session,
		   struct mpp_task *task);
int rkvdec2_task_init(struct mpp_dev *mpp, struct mpp_session *session,
		      struct rkvdec2_task *task, struct mpp_task_msgs *msgs);
void *rkvdec2_alloc_task(struct mpp_session *session,
			 struct mpp_task_msgs *msgs);
int rkvdec2_free_task(struct mpp_session *session, struct mpp_task *mpp_task);

int rkvdec2_free_session(struct mpp_session *session);

int rkvdec2_result(struct mpp_dev *mpp, struct mpp_task *mpp_task,
		   struct mpp_task_msgs *msgs);
int rkvdec2_reset(struct mpp_dev *mpp);

void mpp_devfreq_set_core_rate(struct mpp_dev *mpp, enum MPP_CLOCK_MODE mode);

#endif