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