summaryrefslogtreecommitdiff
path: root/drivers/soc/hisilicon/kunpeng_hccs.h
blob: dc267136919b7bf3ecc0deb8cf7291267dd91789 (plain) (blame)
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
234
235
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2023 Hisilicon Limited. */

#ifndef __KUNPENG_HCCS_H__
#define __KUNPENG_HCCS_H__

/*
 * |---------------  Chip0  ---------------|----------------  ChipN  -------------|
 * |--------Die0-------|--------DieN-------|--------Die0-------|-------DieN-------|
 * | P0 | P1 | P2 | P3 | P0 | P1 | P2 | P3 | P0 | P1 | P2 | P3 |P0 | P1 | P2 | P3 |
 */

enum hccs_port_type {
	HCCS_V1 = 1,
	HCCS_V2,
};

#define HCCS_IP_PREFIX	"HCCS-v"
#define HCCS_IP_MAX		255
#define HCCS_NAME_MAX_LEN	9
struct hccs_type_name_map {
	u8 type;
	char name[HCCS_NAME_MAX_LEN + 1];
};

/*
 * This value cannot be 255, otherwise the loop of the multi-BD communication
 * case cannot end.
 */
#define HCCS_DIE_MAX_PORT_ID	254

struct hccs_port_info {
	u8 port_id;
	u8 port_type;
	u8 max_lane_num;
	bool enable; /* if the port is enabled */
	struct kobject kobj;
	bool dir_created;
	struct hccs_die_info *die; /* point to the die the port is located */
};

struct hccs_die_info {
	u8 die_id;
	u8 port_num;
	u8 min_port_id;
	u8 max_port_id;
	struct hccs_port_info *ports;
	struct kobject kobj;
	bool dir_created;
	struct hccs_chip_info *chip; /* point to the chip the die is located */
};

struct hccs_chip_info {
	u8 chip_id;
	u8 die_num;
	struct hccs_die_info *dies;
	struct kobject kobj;
	struct hccs_dev *hdev;
};

struct hccs_mbox_client_info {
	struct mbox_client client;
	struct mbox_chan *mbox_chan;
	struct pcc_mbox_chan *pcc_chan;
	u64 deadline_us;
	void __iomem *pcc_comm_addr;
	struct completion done;
};

struct hccs_desc;

struct hccs_verspecific_data {
	void (*rx_callback)(struct mbox_client *cl, void *mssg);
	int (*wait_cmd_complete)(struct hccs_dev *hdev);
	void (*fill_pcc_shared_mem)(struct hccs_dev *hdev,
				    u8 cmd, struct hccs_desc *desc,
				    void __iomem *comm_space,
				    u16 space_size);
	u16 shared_mem_size;
	bool has_txdone_irq;
};

#define HCCS_CAPS_HCCS_V2_PM	BIT_ULL(0)

struct hccs_dev {
	struct device *dev;
	struct acpi_device *acpi_dev;
	const struct hccs_verspecific_data *verspec_data;
	/* device capabilities from firmware, like HCCS_CAPS_xxx. */
	u64 caps;
	u8 chip_num;
	struct hccs_chip_info *chips;
	u16 used_type_num;
	struct hccs_type_name_map *type_name_maps;
	u8 chan_id;
	struct mutex lock;
	struct hccs_mbox_client_info cl_info;
};

#define HCCS_SERDES_MODULE_CODE 0x32
enum hccs_subcmd_type {
	HCCS_GET_CHIP_NUM = 0x1,
	HCCS_GET_DIE_NUM,
	HCCS_GET_DIE_INFO,
	HCCS_GET_DIE_PORT_INFO,
	HCCS_GET_DEV_CAP,
	HCCS_GET_PORT_LINK_STATUS,
	HCCS_GET_PORT_CRC_ERR_CNT,
	HCCS_GET_DIE_PORTS_LANE_STA,
	HCCS_GET_DIE_PORTS_LINK_STA,
	HCCS_GET_DIE_PORTS_CRC_ERR_CNT,
	HCCS_GET_PORT_IDLE_STATUS,
	HCCS_PM_DEC_LANE,
	HCCS_PM_INC_LANE,
	HCCS_SUB_CMD_MAX = 255,
};

struct hccs_die_num_req_param {
	u8 chip_id;
};

struct hccs_die_info_req_param {
	u8 chip_id;
	u8 die_idx;
};

struct hccs_die_info_rsp_data {
	u8 die_id;
	u8 port_num;
	u8 min_port_id;
	u8 max_port_id;
};

struct hccs_port_attr {
	u8 port_id;
	u8 port_type;
	u8 max_lane_num;
	u8 enable : 1; /* if the port is enabled */
	u16 rsv[2];
};

/*
 * The common command request for getting the information of all HCCS port on
 * specified DIE.
 */
struct hccs_die_comm_req_param {
	u8 chip_id;
	u8 die_id; /* id in hardware */
};

/* The common command request for getting the information of a specific port */
struct hccs_port_comm_req_param {
	u8 chip_id;
	u8 die_id;
	u8 port_id;
};

#define HCCS_PREPARE_INC_LANE	1
#define HCCS_GET_ADAPT_RES	2
#define HCCS_START_RETRAINING	3
struct hccs_inc_lane_req_param {
	u8 port_type;
	u8 opt_type;
};

#define HCCS_PORT_RESET         1
#define HCCS_PORT_SETUP         2
#define HCCS_PORT_CONFIG        3
#define HCCS_PORT_READY         4
struct hccs_link_status {
	u8 lane_mask; /* indicate which lanes are used. */
	u8 link_fsm : 3; /* link fsm, 1: reset 2: setup 3: config 4: link-up */
	u8 lane_num : 5; /* current lane number */
};

struct hccs_req_head {
	u8 module_code; /* set to 0x32 for serdes */
	u8 start_id;
	u8 rsv[2];
};

struct hccs_rsp_head {
	u8 data_len;
	u8 next_id;
	u8 rsv[2];
};

struct hccs_fw_inner_head {
	u8 retStatus; /* 0: success, other: failure */
	u8 rsv[7];
};

#define HCCS_PCC_SHARE_MEM_BYTES	64
#define HCCS_FW_INNER_HEAD_BYTES	8
#define HCCS_RSP_HEAD_BYTES		4

#define HCCS_MAX_RSP_DATA_BYTES		(HCCS_PCC_SHARE_MEM_BYTES - \
					 HCCS_FW_INNER_HEAD_BYTES - \
					 HCCS_RSP_HEAD_BYTES)
#define HCCS_MAX_RSP_DATA_SIZE_MAX	(HCCS_MAX_RSP_DATA_BYTES / 4)

/*
 * Note: Actual available size of data field also depands on the PCC header
 * bytes of the specific type. Driver needs to copy the response data in the
 * communication space based on the real length.
 */
struct hccs_rsp_desc {
	struct hccs_fw_inner_head fw_inner_head; /* 8 Bytes */
	struct hccs_rsp_head rsp_head; /* 4 Bytes */
	u32 data[HCCS_MAX_RSP_DATA_SIZE_MAX];
};

#define HCCS_REQ_HEAD_BYTES		4
#define HCCS_MAX_REQ_DATA_BYTES		(HCCS_PCC_SHARE_MEM_BYTES - \
					 HCCS_REQ_HEAD_BYTES)
#define HCCS_MAX_REQ_DATA_SIZE_MAX	(HCCS_MAX_REQ_DATA_BYTES / 4)

/*
 * Note: Actual available size of data field also depands on the PCC header
 * bytes of the specific type. Driver needs to copy the request data to the
 * communication space based on the real length.
 */
struct hccs_req_desc {
	struct hccs_req_head req_head; /* 4 Bytes */
	u32 data[HCCS_MAX_REQ_DATA_SIZE_MAX];
};

struct hccs_desc {
	union {
		struct hccs_req_desc req;
		struct hccs_rsp_desc rsp;
	};
};

#endif /* __KUNPENG_HCCS_H__ */