summaryrefslogtreecommitdiffstats
path: root/drivers/soc/hisilicon/kunpeng_hccs.h
blob: 6012d27760281669030cb85739db2d0e5f9a79f8 (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
/* 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 |
 */

/*
 * 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 lane_mode;
	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 hccs_dev {
	struct device *dev;
	struct acpi_device *acpi_dev;
	u64 caps;
	u8 chip_num;
	struct hccs_chip_info *chips;
	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_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 lane_mode;
	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_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__ */