xref: /openbmc/u-boot/drivers/net/fsl-mc/mc_sys.c (revision ae485b54)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Freescale Layerscape MC I/O wrapper
4  *
5  * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
6  * Author: German Rivera <German.Rivera@freescale.com>
7  */
8 
9 #include <fsl-mc/fsl_mc_sys.h>
10 #include <fsl-mc/fsl_mc_cmd.h>
11 #include <common.h>
12 #include <errno.h>
13 #include <asm/io.h>
14 
15 #define MC_CMD_HDR_READ_CMDID(_hdr) \
16 	((uint16_t)mc_dec((_hdr), MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S))
17 
18 /**
19  * mc_send_command - Send MC command and wait for response
20  *
21  * @mc_io: Pointer to MC I/O object to be used
22  * @cmd: MC command buffer. On input, it contains the command to send to the MC.
23  * On output, it contains the response from the MC if any.
24  *
25  * Depending on the sharing option specified when creating the MC portal
26  * wrapper, this function will use a spinlock or mutex to ensure exclusive
27  * access to the MC portal from the point when the command is sent until a
28  * response is received from the MC.
29  */
30 int mc_send_command(struct fsl_mc_io *mc_io,
31 		    struct mc_command *cmd)
32 {
33 	enum mc_cmd_status status;
34 	int timeout = 12000;
35 
36 	mc_write_command(mc_io->mmio_regs, cmd);
37 
38 	for ( ; ; ) {
39 		status = mc_read_response(mc_io->mmio_regs, cmd);
40 		if (status != MC_CMD_STATUS_READY)
41 			break;
42 
43 		if (--timeout == 0) {
44 			printf("Error: Timeout waiting for MC response\n");
45 			return -ETIMEDOUT;
46 		}
47 
48 		udelay(500);
49 	}
50 
51 	if (status != MC_CMD_STATUS_OK) {
52 		printf("Error: MC command failed (portal: %p, obj handle: %#x, command: %#x, status: %#x)\n",
53 		       mc_io->mmio_regs,
54 			(unsigned int)MC_CMD_HDR_READ_TOKEN(cmd->header),
55 		       (unsigned int)MC_CMD_HDR_READ_CMDID(cmd->header),
56 		       (unsigned int)status);
57 
58 		return -EIO;
59 	}
60 
61 	return 0;
62 }
63