xref: /rk3399_rockchip-uboot/include/fsl-mc/fsl_mc_cmd.h (revision 7b3bd9a7988a8b4c8ba22a52b4927e8e59819b12)
1*7b3bd9a7SJ. German Rivera /* Copyright 2014 Freescale Semiconductor Inc.
2*7b3bd9a7SJ. German Rivera  *
3*7b3bd9a7SJ. German Rivera  * SPDX-License-Identifier:	GPL-2.0+
4*7b3bd9a7SJ. German Rivera  */
5*7b3bd9a7SJ. German Rivera #ifndef __FSL_MC_CMD_H
6*7b3bd9a7SJ. German Rivera #define __FSL_MC_CMD_H
7*7b3bd9a7SJ. German Rivera 
8*7b3bd9a7SJ. German Rivera #define MC_CMD_NUM_OF_PARAMS	7
9*7b3bd9a7SJ. German Rivera 
10*7b3bd9a7SJ. German Rivera #define MAKE_UMASK64(_width) \
11*7b3bd9a7SJ. German Rivera 	((uint64_t)((_width) < 64 ? ((uint64_t)1 << (_width)) - 1 : -1))
12*7b3bd9a7SJ. German Rivera 
13*7b3bd9a7SJ. German Rivera static inline uint64_t u64_enc(int lsoffset, int width, uint64_t val)
14*7b3bd9a7SJ. German Rivera {
15*7b3bd9a7SJ. German Rivera 	return (uint64_t)(((uint64_t)val & MAKE_UMASK64(width)) << lsoffset);
16*7b3bd9a7SJ. German Rivera }
17*7b3bd9a7SJ. German Rivera static inline uint64_t u64_dec(uint64_t val, int lsoffset, int width)
18*7b3bd9a7SJ. German Rivera {
19*7b3bd9a7SJ. German Rivera 	return (uint64_t)((val >> lsoffset) & MAKE_UMASK64(width));
20*7b3bd9a7SJ. German Rivera }
21*7b3bd9a7SJ. German Rivera 
22*7b3bd9a7SJ. German Rivera struct mc_command {
23*7b3bd9a7SJ. German Rivera 	uint64_t header;
24*7b3bd9a7SJ. German Rivera 	uint64_t params[MC_CMD_NUM_OF_PARAMS];
25*7b3bd9a7SJ. German Rivera };
26*7b3bd9a7SJ. German Rivera 
27*7b3bd9a7SJ. German Rivera enum mc_cmd_status {
28*7b3bd9a7SJ. German Rivera 	MC_CMD_STATUS_OK = 0x0, /*!< Completed successfully */
29*7b3bd9a7SJ. German Rivera 	MC_CMD_STATUS_READY = 0x1, /*!< Ready to be processed */
30*7b3bd9a7SJ. German Rivera 	MC_CMD_STATUS_AUTH_ERR = 0x3, /*!< Authentication error */
31*7b3bd9a7SJ. German Rivera 	MC_CMD_STATUS_NO_PRIVILEGE = 0x4, /*!< No privilege */
32*7b3bd9a7SJ. German Rivera 	MC_CMD_STATUS_DMA_ERR = 0x5, /*!< DMA or I/O error */
33*7b3bd9a7SJ. German Rivera 	MC_CMD_STATUS_CONFIG_ERR = 0x6, /*!< Configuration error */
34*7b3bd9a7SJ. German Rivera 	MC_CMD_STATUS_TIMEOUT = 0x7, /*!< Operation timed out */
35*7b3bd9a7SJ. German Rivera 	MC_CMD_STATUS_NO_RESOURCE = 0x8, /*!< No resources */
36*7b3bd9a7SJ. German Rivera 	MC_CMD_STATUS_NO_MEMORY = 0x9, /*!< No memory available */
37*7b3bd9a7SJ. German Rivera 	MC_CMD_STATUS_BUSY = 0xA, /*!< Device is busy */
38*7b3bd9a7SJ. German Rivera 	MC_CMD_STATUS_UNSUPPORTED_OP = 0xB, /*!< Unsupported operation */
39*7b3bd9a7SJ. German Rivera 	MC_CMD_STATUS_INVALID_STATE = 0xC /*!< Invalid state */
40*7b3bd9a7SJ. German Rivera };
41*7b3bd9a7SJ. German Rivera 
42*7b3bd9a7SJ. German Rivera #define MC_CMD_HDR_CMDID_O	52	/* Command ID field offset */
43*7b3bd9a7SJ. German Rivera #define MC_CMD_HDR_CMDID_S	12	/* Command ID field size */
44*7b3bd9a7SJ. German Rivera #define MC_CMD_HDR_AUTHID_O	38	/* Authentication ID field offset */
45*7b3bd9a7SJ. German Rivera #define MC_CMD_HDR_AUTHID_S	10	/* Authentication ID field size */
46*7b3bd9a7SJ. German Rivera #define MC_CMD_HDR_STATUS_O	16	/* Status field offset */
47*7b3bd9a7SJ. German Rivera #define MC_CMD_HDR_STATUS_S	8	/* Status field size*/
48*7b3bd9a7SJ. German Rivera #define MC_CMD_HDR_PRI_O	15	/* Priority field offset */
49*7b3bd9a7SJ. German Rivera #define MC_CMD_HDR_PRI_S	1	/* Priority field size */
50*7b3bd9a7SJ. German Rivera 
51*7b3bd9a7SJ. German Rivera #define MC_CMD_HDR_READ_STATUS(_hdr) \
52*7b3bd9a7SJ. German Rivera 	((enum mc_cmd_status)u64_dec((_hdr), \
53*7b3bd9a7SJ. German Rivera 		MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S))
54*7b3bd9a7SJ. German Rivera 
55*7b3bd9a7SJ. German Rivera #define MC_CMD_HDR_READ_AUTHID(_hdr) \
56*7b3bd9a7SJ. German Rivera 	((uint16_t)u64_dec((_hdr), MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S))
57*7b3bd9a7SJ. German Rivera 
58*7b3bd9a7SJ. German Rivera #define MC_CMD_PRI_LOW		0 /*!< Low Priority command indication */
59*7b3bd9a7SJ. German Rivera #define MC_CMD_PRI_HIGH		1 /*!< High Priority command indication */
60*7b3bd9a7SJ. German Rivera 
61*7b3bd9a7SJ. German Rivera #define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \
62*7b3bd9a7SJ. German Rivera 	((_cmd).params[_param] |= u64_enc((_offset), (_width), _arg))
63*7b3bd9a7SJ. German Rivera 
64*7b3bd9a7SJ. German Rivera #define MC_RSP_OP(_cmd, _param, _offset, _width, _type, _arg) \
65*7b3bd9a7SJ. German Rivera 	(_arg = (_type)u64_dec(_cmd.params[_param], (_offset), (_width)))
66*7b3bd9a7SJ. German Rivera 
67*7b3bd9a7SJ. German Rivera static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id,
68*7b3bd9a7SJ. German Rivera 					    uint8_t priority,
69*7b3bd9a7SJ. German Rivera 					    uint16_t auth_id)
70*7b3bd9a7SJ. German Rivera {
71*7b3bd9a7SJ. German Rivera 	uint64_t hdr;
72*7b3bd9a7SJ. German Rivera 
73*7b3bd9a7SJ. German Rivera 	hdr = u64_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id);
74*7b3bd9a7SJ. German Rivera 	hdr |= u64_enc(MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S, auth_id);
75*7b3bd9a7SJ. German Rivera 	hdr |= u64_enc(MC_CMD_HDR_PRI_O, MC_CMD_HDR_PRI_S, priority);
76*7b3bd9a7SJ. German Rivera 	hdr |= u64_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S,
77*7b3bd9a7SJ. German Rivera 		       MC_CMD_STATUS_READY);
78*7b3bd9a7SJ. German Rivera 
79*7b3bd9a7SJ. German Rivera 	return hdr;
80*7b3bd9a7SJ. German Rivera }
81*7b3bd9a7SJ. German Rivera 
82*7b3bd9a7SJ. German Rivera /**
83*7b3bd9a7SJ. German Rivera  * mc_write_command - writes a command to a Management Complex (MC) portal
84*7b3bd9a7SJ. German Rivera  *
85*7b3bd9a7SJ. German Rivera  * @portal: pointer to an MC portal
86*7b3bd9a7SJ. German Rivera  * @cmd: pointer to a filled command
87*7b3bd9a7SJ. German Rivera  */
88*7b3bd9a7SJ. German Rivera static inline void mc_write_command(struct mc_command __iomem *portal,
89*7b3bd9a7SJ. German Rivera 				    struct mc_command *cmd)
90*7b3bd9a7SJ. German Rivera {
91*7b3bd9a7SJ. German Rivera 	int i;
92*7b3bd9a7SJ. German Rivera 
93*7b3bd9a7SJ. German Rivera 	/* copy command parameters into the portal */
94*7b3bd9a7SJ. German Rivera 	for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
95*7b3bd9a7SJ. German Rivera 		writeq(cmd->params[i], &portal->params[i]);
96*7b3bd9a7SJ. German Rivera 
97*7b3bd9a7SJ. German Rivera 	/* submit the command by writing the header */
98*7b3bd9a7SJ. German Rivera 	writeq(cmd->header, &portal->header);
99*7b3bd9a7SJ. German Rivera }
100*7b3bd9a7SJ. German Rivera 
101*7b3bd9a7SJ. German Rivera /**
102*7b3bd9a7SJ. German Rivera  * mc_read_response - reads the response for the last MC command from a
103*7b3bd9a7SJ. German Rivera  * Management Complex (MC) portal
104*7b3bd9a7SJ. German Rivera  *
105*7b3bd9a7SJ. German Rivera  * @portal: pointer to an MC portal
106*7b3bd9a7SJ. German Rivera  * @resp: pointer to command response buffer
107*7b3bd9a7SJ. German Rivera  *
108*7b3bd9a7SJ. German Rivera  * Returns MC_CMD_STATUS_OK on Success; Error code otherwise.
109*7b3bd9a7SJ. German Rivera  */
110*7b3bd9a7SJ. German Rivera static inline enum mc_cmd_status mc_read_response(
111*7b3bd9a7SJ. German Rivera 					struct mc_command __iomem *portal,
112*7b3bd9a7SJ. German Rivera 					struct mc_command *resp)
113*7b3bd9a7SJ. German Rivera {
114*7b3bd9a7SJ. German Rivera 	int i;
115*7b3bd9a7SJ. German Rivera 	enum mc_cmd_status status;
116*7b3bd9a7SJ. German Rivera 
117*7b3bd9a7SJ. German Rivera 	/* Copy command response header from MC portal: */
118*7b3bd9a7SJ. German Rivera 	resp->header = readq(&portal->header);
119*7b3bd9a7SJ. German Rivera 	status = MC_CMD_HDR_READ_STATUS(resp->header);
120*7b3bd9a7SJ. German Rivera 	if (status != MC_CMD_STATUS_OK)
121*7b3bd9a7SJ. German Rivera 		return status;
122*7b3bd9a7SJ. German Rivera 
123*7b3bd9a7SJ. German Rivera 	/* Copy command response data from MC portal: */
124*7b3bd9a7SJ. German Rivera 	for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
125*7b3bd9a7SJ. German Rivera 		resp->params[i] = readq(&portal->params[i]);
126*7b3bd9a7SJ. German Rivera 
127*7b3bd9a7SJ. German Rivera 	return status;
128*7b3bd9a7SJ. German Rivera }
129*7b3bd9a7SJ. German Rivera 
130*7b3bd9a7SJ. German Rivera int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd);
131*7b3bd9a7SJ. German Rivera 
132*7b3bd9a7SJ. German Rivera #endif /* __FSL_MC_CMD_H */
133