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#include <linux/delay.h> 15 16static u16 mc_cmd_hdr_read_cmdid(struct mc_command *cmd) 17{ 18 struct mc_cmd_header *hdr = (struct mc_cmd_header *)&cmd->header; 19 u16 cmd_id = le16_to_cpu(hdr->cmd_id); 20 21 return cmd_id; 22} 23 24/** 25 * mc_send_command - Send MC command and wait for response 26 * 27 * @mc_io: Pointer to MC I/O object to be used 28 * @cmd: MC command buffer. On input, it contains the command to send to the MC. 29 * On output, it contains the response from the MC if any. 30 * 31 * Depending on the sharing option specified when creating the MC portal 32 * wrapper, this function will use a spinlock or mutex to ensure exclusive 33 * access to the MC portal from the point when the command is sent until a 34 * response is received from the MC. 35 */ 36int mc_send_command(struct fsl_mc_io *mc_io, 37 struct mc_command *cmd) 38{ 39 enum mc_cmd_status status; 40 int timeout = 12000; 41 42 mc_write_command(mc_io->mmio_regs, cmd); 43 44 for ( ; ; ) { 45 status = mc_read_response(mc_io->mmio_regs, cmd); 46 if (status != MC_CMD_STATUS_READY) 47 break; 48 49 if (--timeout == 0) { 50 printf("Error: Timeout waiting for MC response\n"); 51 return -ETIMEDOUT; 52 } 53 54 udelay(500); 55 } 56 57 if (status != MC_CMD_STATUS_OK) { 58 printf("Error: MC command failed (portal: %p, obj handle: %#x, command: %#x, status: %#x)\n", 59 mc_io->mmio_regs, 60 (unsigned int)mc_cmd_hdr_read_token(cmd), 61 (unsigned int)mc_cmd_hdr_read_cmdid(cmd), 62 (unsigned int)status); 63 64 return -EIO; 65 } 66 67 return 0; 68} 69