/* Copyright 2017-2018 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * P9 OPAL - SBE communication driver
 *
 * P9 chip has Self Boot Engine (SBE). OPAL uses SBE for various purpose like
 * timer, scom, MPIPL, etc,. Every chip has SBE. OPAL can communicate to SBE
 * on all chips. Based on message type it selects appropriate SBE (ex: schedule
 * timer on any chip).
 *
 * OPAL communicates to SBE via a set of data and control registers provided by
 * the PSU block in P9 chip.
 *  - Four 8 byte registers for Host to send command packets to SBE.
 *  - Four 8 byte registers for SBE to send response packets to Host.
 *  - Two doorbell registers (1 on each side) to alert either party
 *    when data is placed in above mentioned data registers. Once Host/SBE reads
 *    incoming data, it should clear doorbell register. Interrupt is disabled
 *    as soon as doorbell register is cleared.
 *
 * OPAL - SBE message format:
 *  - OPAL communicates to SBE via set of well defined commands.
 *  - Reg0 contains message header (command class, subclass, flags etc).
 *  - Reg1-3 contains actual data. If data is big then it uses indirect method
 *    (data is passed via memory and memory address/size is passed in Reg1-3).
 *  - Every message has defined timeout. SBE must respond within specified
 *    time. Otherwise OPAL discards message and sends error message to caller.
 *
 * Constraints:
 *  - Only one command is accepted in the command buffer until the response for
 *    the command is enqueued in the response buffer by SBE.
 */

#define pr_fmt(fmt) "SBE: " fmt

#include <chip.h>
#include <errorlog.h>
#include <lock.h>
#include <opal.h>
#include <sbe-p9.h>
#include <skiboot.h>
#include <timebase.h>
#include <timer.h>
#include <trace.h>
#include <xscom.h>

enum p9_sbe_mbox_state {
	sbe_mbox_idle = 0,	/* Ready to send message */
	sbe_mbox_send,		/* Message sent, waiting for ack/response */
	sbe_mbox_rr,		/* SBE in R/R */
};

struct p9_sbe {
	/* Chip ID to send message */
	u32			chip_id;

	/* List to hold SBE queue messages */
	struct list_head	msg_list;

	struct lock		lock;

	enum p9_sbe_mbox_state	state;

	/* SBE MBOX message sequence number */
	u16			cur_seq;
};

/* Default SBE chip ID */
static int sbe_default_chip_id = -1;

/* Is SBE timer running? */
static bool sbe_has_timer = false;
static bool sbe_timer_in_progress = false;
static bool has_new_target = false;

/* Inflight and next timer in TB */
static uint64_t sbe_last_gen_stamp;
static uint64_t sbe_timer_target;

/* Timer lock */
struct lock sbe_timer_lock;

/*
 * Minimum timeout value for P9 is 500 microseconds. After that
 * SBE timer can handle granularity of 1 microsecond.
 */
#define SBE_TIMER_DEFAULT_US	500
static uint64_t sbe_timer_def_tb;

/*
 * Rate limit continuous timer update.
 * We can update inflight timer if new timer request is lesser than inflight
 * one. Limit such updates so that SBE gets time to handle FIFO side requests.
 */
#define SBE_TIMER_UPDATE_MAX	2
static uint32_t timer_update_cnt = 0;

/* Timer control message */
static struct p9_sbe_msg *timer_ctrl_msg;

#define SBE_STATUS_PRI_SHIFT	0x30
#define SBE_STATUS_SEC_SHIFT	0x20

/* Forward declaration */
static void p9_sbe_timeout_poll_one(struct p9_sbe *sbe);
static void p9_sbe_timer_schedule(void);

/* bit 0-15 : Primary status code */
static inline u16 p9_sbe_get_primary_rc(struct p9_sbe_msg *resp)
{
	return (resp->reg[0] >> SBE_STATUS_PRI_SHIFT);
}

static inline void p9_sbe_set_primary_rc(struct p9_sbe_msg *resp, u64 rc)
{
	resp->reg[0] |= (rc << SBE_STATUS_PRI_SHIFT);
}

static u64 p9_sbe_rreg(u32 chip_id, u64 reg)
{
	u64 data = 0;
	int rc;

	rc = xscom_read(chip_id, reg, &data);
	if (rc != OPAL_SUCCESS) {
		prlog(PR_DEBUG, "XSCOM error %d reading reg 0x%llx\n", rc, reg);
		return 0xffffffff;
	}

	return be64_to_cpu(data);
}

static void p9_sbe_reg_dump(u32 chip_id)
{
#define SBE_DUMP_REG_ONE(chip_id, x) \
	prlog(PR_DEBUG, "  %20s: %016llx\n", #x, p9_sbe_rreg(chip_id, x))

	prlog(PR_DEBUG, "MBOX register dump for chip : %x\n", chip_id);
	SBE_DUMP_REG_ONE(chip_id, PSU_SBE_DOORBELL_REG_RW);
	SBE_DUMP_REG_ONE(chip_id, PSU_HOST_SBE_MBOX_REG0);
	SBE_DUMP_REG_ONE(chip_id, PSU_HOST_SBE_MBOX_REG1);
	SBE_DUMP_REG_ONE(chip_id, PSU_HOST_SBE_MBOX_REG2);
	SBE_DUMP_REG_ONE(chip_id, PSU_HOST_SBE_MBOX_REG3);
	SBE_DUMP_REG_ONE(chip_id, PSU_HOST_DOORBELL_REG_RW);
	SBE_DUMP_REG_ONE(chip_id, PSU_HOST_SBE_MBOX_REG4);
	SBE_DUMP_REG_ONE(chip_id, PSU_HOST_SBE_MBOX_REG5);
	SBE_DUMP_REG_ONE(chip_id, PSU_HOST_SBE_MBOX_REG6);
	SBE_DUMP_REG_ONE(chip_id, PSU_HOST_SBE_MBOX_REG7);
}

void p9_sbe_freemsg(struct p9_sbe_msg *msg)
{
	if (msg && msg->resp)
		free(msg->resp);
	free(msg);
}

static void p9_sbe_fillmsg(struct p9_sbe_msg *msg, u16 cmd,
			   u16 ctrl_flag, u64 reg1, u64 reg2, u64 reg3)
{
	bool response = !!(ctrl_flag & SBE_CMD_CTRL_RESP_REQ);
	u16 flag;

	/*
	 * Always set ack required flag. SBE will interrupt OPAL once it read
	 * message from mailbox register. If OPAL is expecting response, then
	 * it will update message timeout, otherwise it will send next message.
	 */
	flag = ctrl_flag | SBE_CMD_CTRL_ACK_REQ;

	/* Seqence ID is filled by p9_sbe_queue_msg() */
	msg->reg[0] = ((u64)flag << 32) | cmd;
	msg->reg[1] = reg1;
	msg->reg[2] = reg2;
	msg->reg[3] = reg3;
	msg->state = sbe_msg_unused;
	msg->response = response;
}

static struct p9_sbe_msg *p9_sbe_allocmsg(bool alloc_resp)
{
	struct p9_sbe_msg *msg;

	msg = zalloc(sizeof(struct p9_sbe_msg));
	if (!msg) {
		prlog(PR_ERR, "Failed to allocate SBE message\n");
		return NULL;
	}
	if (alloc_resp) {
		msg->resp = zalloc(sizeof(struct p9_sbe_msg));
		if (!msg->resp) {
			prlog(PR_ERR, "Failed to allocate SBE resp message\n");
			free(msg);
			return NULL;
		}
	}

	return msg;
}

/*
 * Handles "command with direct data" format only.
 *
 * Note: All mbox messages of our interest uses direct data format. If we need
 *       indirect data format then we may have to enhance this function.
 */
struct p9_sbe_msg *p9_sbe_mkmsg(u16 cmd, u16 ctrl_flag,
				u64 reg1, u64 reg2, u64 reg3)
{
	struct p9_sbe_msg *msg;

	msg = p9_sbe_allocmsg(!!(ctrl_flag & SBE_CMD_CTRL_RESP_REQ));
	if (!msg)
		return NULL;

	p9_sbe_fillmsg(msg, cmd, ctrl_flag, reg1, reg2, reg3);
	return msg;
}

static inline bool p9_sbe_mbox_busy(struct p9_sbe *sbe)
{
	return (sbe->state != sbe_mbox_idle);
}

static inline bool p9_sbe_msg_busy(struct p9_sbe_msg *msg)
{
	switch (msg->state) {
	case sbe_msg_queued:
	/* fall through */
	case sbe_msg_sent:
	case sbe_msg_wresp:
		return true;
	default:	/* + sbe_msg_unused, sbe_msg_done,
			     sbe_msg_timeout, sbe_msg_error */
		break;
	}
	return false;
}

static inline struct p9_sbe *p9_sbe_get_sbe(u32 chip_id)
{
	struct proc_chip *chip;

	/* Default to SBE on master chip */
	if (chip_id == -1) {
		if (sbe_default_chip_id == -1)
			return NULL;

		chip = get_chip(sbe_default_chip_id);
	} else {
		chip = get_chip(chip_id);
	}
	if (chip == NULL || chip->sbe == NULL)
		return NULL;

	return chip->sbe;
}

static int p9_sbe_msg_send(struct p9_sbe *sbe, struct p9_sbe_msg *msg)
{
	int rc, i;
	u64 addr, *data;

	addr = PSU_HOST_SBE_MBOX_REG0;
	data = &msg->reg[0];

	for (i = 0; i < NR_HOST_SBE_MBOX_REG; i++) {
		rc = xscom_write(sbe->chip_id, addr, *data);
		if (rc)
			return rc;

		addr++;
		data++;
	}

	rc = xscom_write(sbe->chip_id, PSU_SBE_DOORBELL_REG_OR,
			 HOST_SBE_MSG_WAITING);
	if (rc != OPAL_SUCCESS)
		return rc;

	prlog(PR_TRACE, "Message queued [chip id = 0x%x]:\n\t Reg0 : %016llx"
	      "\n\t Reg1 : %016llx\n\t Reg2 : %016llx\n\t Reg3 : %016llx\n",
	      sbe->chip_id, msg->reg[0], msg->reg[1], msg->reg[2], msg->reg[3]);

	msg->timeout = mftb() + msecs_to_tb(SBE_CMD_TIMEOUT_MAX);
	sbe->state = sbe_mbox_send;
	msg->state = sbe_msg_sent;
	return rc;
}

static int p9_sbe_msg_receive(u32 chip_id, struct p9_sbe_msg *resp)
{
	int i;
	int rc = OPAL_SUCCESS;
	u64 addr, *data;

	addr = PSU_HOST_SBE_MBOX_REG4;
	data = &resp->reg[0];

	for (i = 0; i < NR_HOST_SBE_MBOX_REG; i++) {
		rc = xscom_read(chip_id, addr, data);
		if (rc)
			return rc;

		addr++;
		data++;
	}
	return rc;
}

/* WARNING: This will drop sbe->lock */
static void p9_sbe_msg_complete(struct p9_sbe *sbe, struct p9_sbe_msg *msg,
				enum p9_sbe_msg_state msg_state)
{
	void (*comp)(struct p9_sbe_msg *msg);

	prlog(PR_TRACE, "Completing msg [chip id = %x], reg0 : 0x%llx\n",
	      sbe->chip_id, msg->reg[0]);

	comp = msg->complete;
	list_del(&msg->link);
	sync();
	msg->state = msg_state;

	if (comp) {
		unlock(&sbe->lock);
		comp(msg);
		lock(&sbe->lock);
	}
}

/* WARNING: This will drop sbe->lock */
static void p9_sbe_send_complete(struct p9_sbe *sbe)
{
	struct p9_sbe_msg *msg;

	if (list_empty(&sbe->msg_list))
		return;

	msg = list_top(&sbe->msg_list, struct p9_sbe_msg, link);
	/* Need response */
	if (msg->response) {
		msg->state = sbe_msg_wresp;
	} else {
		sbe->state = sbe_mbox_idle;
		p9_sbe_msg_complete(sbe, msg, sbe_msg_done);
	}
}

/* WARNING: This will drop sbe->lock */
static void p9_sbe_process_queue(struct p9_sbe *sbe)
{
	int rc, retry_cnt = 0;
	struct p9_sbe_msg *msg = NULL;

	if (p9_sbe_mbox_busy(sbe))
		return;

	while (!list_empty(&sbe->msg_list)) {
		msg = list_top(&sbe->msg_list, struct p9_sbe_msg, link);
		/* Send message */
		rc = p9_sbe_msg_send(sbe, msg);
		if (rc == OPAL_SUCCESS)
			return;

		prlog(PR_ERR, "Failed to send message to SBE [chip id = %x]\n",
		      sbe->chip_id);
		if (msg->resp) {
			p9_sbe_set_primary_rc(msg->resp,
					      SBE_STATUS_PRI_GENERIC_ERR);
		}
		p9_sbe_msg_complete(sbe, msg, sbe_msg_error);

		/*
		 * Repeatedly failed to send message to SBE. Lets stop
		 * sending message.
		 */
		if (retry_cnt++ >= 3) {
			prlog(PR_ERR, "Temporarily stopped sending "
			      "message to SBE\n");
			return;
		}
	}
}

/*
 * WARNING:
 *         Only one command is accepted in the command buffer until response
 *         to the command is enqueued in the response buffer by SBE.
 *
 *         Head of msg_list contains in-flight message. Hence we should always
 *         add new message to tail of the list.
 */
int p9_sbe_queue_msg(u32 chip_id, struct p9_sbe_msg *msg,
		     void (*comp)(struct p9_sbe_msg *msg))
{
	struct p9_sbe *sbe;

	if (!msg)
		return OPAL_PARAMETER;

	sbe = p9_sbe_get_sbe(chip_id);
	if (!sbe)
		return OPAL_HARDWARE;

	lock(&sbe->lock);
	/* Set completion and update sequence number */
	msg->complete = comp;
	msg->state = sbe_msg_queued;
	msg->reg[0] = msg->reg[0] | ((u64)sbe->cur_seq << 16);
	sbe->cur_seq++;

	/* Reset sequence number */
	if (sbe->cur_seq == 0xffff)
		sbe->cur_seq = 1;

	/* Add message to queue */
	list_add_tail(&sbe->msg_list, &msg->link);
	p9_sbe_process_queue(sbe);
	unlock(&sbe->lock);

	return OPAL_SUCCESS;
}

int p9_sbe_sync_msg(u32 chip_id, struct p9_sbe_msg *msg, bool autofree)
{
	int rc;
	struct p9_sbe *sbe;

	rc = p9_sbe_queue_msg(chip_id, msg, NULL);
	if (rc)
		goto free_msg;

	sbe = p9_sbe_get_sbe(chip_id);
	if (!sbe) {
		rc = OPAL_HARDWARE;
		goto free_msg;
	}

	while (p9_sbe_msg_busy(msg)) {
		cpu_relax();
		p9_sbe_timeout_poll_one(sbe);
	}

	if (msg->state == sbe_msg_done)
		rc = SBE_STATUS_PRI_SUCCESS;
	else
		rc = SBE_STATUS_PRI_GENERIC_ERR;

	if (msg->response && msg->resp)
		rc = p9_sbe_get_primary_rc(msg->resp);

free_msg:
	if (autofree)
		p9_sbe_freemsg(msg);

	return rc;
}

/* Remove SBE message from queue. It will not remove inflight message */
int p9_sbe_cancelmsg(u32 chip_id, struct p9_sbe_msg *msg)
{
	struct p9_sbe *sbe;

	sbe = p9_sbe_get_sbe(chip_id);
	if (!sbe)
		return OPAL_PARAMETER;

	lock(&sbe->lock);
	if (msg->state != sbe_msg_queued) {
		unlock(&sbe->lock);
		return OPAL_BUSY;
	}

	list_del(&msg->link);
	msg->state = sbe_msg_done;
	unlock(&sbe->lock);
	return OPAL_SUCCESS;
}

static void p9_sbe_handle_response(u32 chip_id, struct p9_sbe_msg *msg)
{
	u16 send_seq, resp_seq;
	int rc;

	if (msg == NULL || msg->resp == NULL)
		return;

	memset(msg->resp, 0, sizeof(struct p9_sbe_msg));

	rc = p9_sbe_msg_receive(chip_id, msg->resp);
	if (rc != OPAL_SUCCESS) {
		prlog(PR_ERR, "Failed to read response message "
		      "[chip id = %x]\n", chip_id);
		p9_sbe_set_primary_rc(msg->resp, SBE_STATUS_PRI_GENERIC_ERR);
		return;
	}

	/* Validate sequence number */
	send_seq = (msg->reg[0] >> 16) & 0xffff;
	resp_seq = (msg->resp->reg[0] >> 16) & 0xffff;
	if (send_seq != resp_seq) {
		/*
		 * XXX Handle SBE R/R.
		 *     Lets send sequence error to caller until SBE reset works.
		 */
		prlog(PR_ERR, "Invalid sequence id [chip id = %x]\n", chip_id);
		p9_sbe_set_primary_rc(msg->resp, SBE_STATUS_PRI_SEQ_ERR);
		return;
	}
}

static int p9_sbe_clear_interrupt(struct p9_sbe *sbe, u64 bits)
{
	int rc;
	u64 val;

	/* Clear doorbell register */
	val = SBE_HOST_RESPONSE_MASK & ~bits;
	rc = xscom_write(sbe->chip_id, PSU_HOST_DOORBELL_REG_AND, val);
	if (rc) {
		prlog(PR_ERR, "Failed to clear SBE to Host doorbell "
		      "interrupt [chip id = %x]\n", sbe->chip_id);
	}
	return rc;
}

/* WARNING: This will drop sbe->lock */
static void p9_sbe_timer_response(struct p9_sbe *sbe)
{
	if (sbe->chip_id != sbe_default_chip_id)
		return;

	sbe_timer_in_progress = false;
	/* Drop lock and call timers */
	unlock(&sbe->lock);

	lock(&sbe_timer_lock);
	/*
	 * Once we get timer expiry interrupt (even if its suprious interrupt)
	 * we can schedule next timer request.
	 */
	timer_update_cnt = 0;
	unlock(&sbe_timer_lock);

	check_timers(true);
	lock(&sbe->lock);
}

/* WARNING: This will drop sbe->lock */
static void __p9_sbe_interrupt(struct p9_sbe *sbe)
{
	bool has_response;
	int rc;
	u64 data = 0, val;
	struct p9_sbe_msg *msg = NULL;

again:
	/* Read doorbell register */
	rc = xscom_read(sbe->chip_id, PSU_HOST_DOORBELL_REG_RW, &data);
	if (rc) {
		prlog(PR_ERR, "Failed to read SBE to Host doorbell register "
		      "[chip id = %x]\n", sbe->chip_id);
		p9_sbe_reg_dump(sbe->chip_id);
		return;
	}

	/* Completed processing all the bits */
	if (!data)
		return;

	/* SBE came back from reset */
	if (data & SBE_HOST_RESET) {
		/* Clear all bits and restart sending message */
		rc = p9_sbe_clear_interrupt(sbe, data);
		if (rc)
			return;

		prlog(PR_NOTICE,
		      "Back from reset [chip id = %x]\n", sbe->chip_id);
		/* Reset SBE MBOX state */
		sbe->state = sbe_mbox_idle;

		/* Reset message state */
		if (!list_empty(&sbe->msg_list)) {
			msg = list_top(&sbe->msg_list, struct p9_sbe_msg, link);
			msg->state = sbe_msg_queued;
		}
		return;
	}

	/* Process ACK message before response */
	if (data & SBE_HOST_MSG_READ) {
		rc = p9_sbe_clear_interrupt(sbe, SBE_HOST_MSG_READ);
		if (rc)
			return;
		p9_sbe_send_complete(sbe);
		goto again;
	}

	/* Read SBE response before clearing doorbell register */
	if (data & SBE_HOST_RESPONSE_WAITING) {
		if (!list_empty(&sbe->msg_list)) {
			msg = list_top(&sbe->msg_list, struct p9_sbe_msg, link);
			p9_sbe_handle_response(sbe->chip_id, msg);
			has_response = true;
		} else {
			has_response = false;
			prlog(PR_DEBUG,
			      "Got response with no pending message\n");
		}

		rc = p9_sbe_clear_interrupt(sbe, SBE_HOST_RESPONSE_WAITING);
		if (rc)
			return;

		/* Reset SBE MBOX state */
		sbe->state = sbe_mbox_idle;
		if (has_response)
			p9_sbe_msg_complete(sbe, msg, sbe_msg_done);

		goto again;
	}

	/* SBE passthrough command, call prd handler */
	if (data & SBE_HOST_PASSTHROUGH) {
		rc = p9_sbe_clear_interrupt(sbe, SBE_HOST_PASSTHROUGH);
		if (rc)
			return;
		prd_sbe_passthrough(sbe->chip_id);
		goto again;
	}

	/* Timer expired */
	if (data & SBE_HOST_TIMER_EXPIRY) {
		rc = p9_sbe_clear_interrupt(sbe, SBE_HOST_TIMER_EXPIRY);
		if (rc)
			return;
		p9_sbe_timer_response(sbe);
		goto again;
	}

	/* Unhandled bits */
	val = data & ~(SBE_HOST_RESPONSE_MASK);
	if (val) {
		prlog(PR_ERR, "Unhandled interrupt bit [chip id = %x] : "
		      " %016llx\n", sbe->chip_id, val);
		rc = p9_sbe_clear_interrupt(sbe, data);
		if (rc)
			return;
		goto again;
	}
}

void p9_sbe_interrupt(uint32_t chip_id)
{
	struct proc_chip *chip;
	struct p9_sbe *sbe;

	chip = get_chip(chip_id);
	if (chip == NULL || chip->sbe == NULL)
		return;

	sbe = chip->sbe;
	lock(&sbe->lock);
	__p9_sbe_interrupt(sbe);
	p9_sbe_process_queue(sbe);
	unlock(&sbe->lock);
}

/*
 * Check if the timer is working. If at least 10ms elapsed since
 * last scheduled timer expiry.
 */
static void p9_sbe_timer_poll(struct p9_sbe *sbe)
{
	if (sbe->chip_id != sbe_default_chip_id)
		return;

	if (!sbe_has_timer || !sbe_timer_in_progress)
		return;

	if (tb_compare(mftb(), sbe_last_gen_stamp + msecs_to_tb(10))
	    != TB_AAFTERB)
		return;

	prlog(PR_ERR, "Timer stuck, falling back to OPAL pollers.\n");
	prlog(PR_ERR, "You will likely have slower I2C and may have "
	      "experienced increased jitter.\n");
	p9_sbe_reg_dump(sbe->chip_id);
	sbe_has_timer = false;
	sbe_timer_in_progress = false;
}

static void p9_sbe_timeout_poll_one(struct p9_sbe *sbe)
{
	struct p9_sbe_msg *msg;

	if (sbe->chip_id == sbe_default_chip_id) {
		if (list_empty_nocheck(&sbe->msg_list) &&
		    !sbe_timer_in_progress)
			return;
	} else {
		if (list_empty_nocheck(&sbe->msg_list))
			return;
	}

	lock(&sbe->lock);

	/*
	 * In some cases there will be a delay in calling OPAL interrupt
	 * handler routine (opal_handle_interrupt). In such cases its
	 * possible that SBE has responded, but OPAL didn't act on that.
	 * Hence check for SBE response.
	 */
	__p9_sbe_interrupt(sbe);
	p9_sbe_timer_poll(sbe);

	if (list_empty(&sbe->msg_list))
		goto out;

	/*
	 * For some reason OPAL didn't sent message to SBE.
	 * Lets try to send message again.
	 */
	if (!p9_sbe_mbox_busy(sbe)) {
		p9_sbe_process_queue(sbe);
		goto out;
	}

	msg = list_top(&sbe->msg_list, struct p9_sbe_msg, link);
	if (tb_compare(mftb(), msg->timeout) != TB_AAFTERB)
		goto out;

	/* Message timeout */
	prlog(PR_ERR, "Message timeout [chip id = %x], cmd = %llx, "
	      "subcmd = %llx\n", sbe->chip_id,
	      (msg->reg[0] >> 8) & 0xff, msg->reg[0] & 0xff);
	p9_sbe_reg_dump(sbe->chip_id);
	if (msg->resp) {
		p9_sbe_set_primary_rc(msg->resp,
				      SBE_STATUS_PRI_GENERIC_ERR);
	}

	/* XXX Handle SBE R/R. Reset SBE state until SBE R/R works. */
	sbe->state = sbe_mbox_idle;
	p9_sbe_msg_complete(sbe, msg, sbe_msg_timeout);
	p9_sbe_process_queue(sbe);

out:
	unlock(&sbe->lock);
}

static void p9_sbe_timeout_poll(void *user_data __unused)
{
	struct p9_sbe *sbe;
	struct proc_chip *chip;

	for_each_chip(chip) {
		if (chip->sbe == NULL)
			continue;
		sbe = chip->sbe;
		p9_sbe_timeout_poll_one(sbe);
	}
}

static void p9_sbe_timer_resp(struct p9_sbe_msg *msg)
{
	if (msg->state != sbe_msg_done) {
		prlog(PR_DEBUG, "Failed to schedule timer [chip id %x]\n",
		      sbe_default_chip_id);
	} else {
		/* Update last scheduled timer value */
		sbe_last_gen_stamp = mftb() +
			usecs_to_tb(timer_ctrl_msg->reg[1]);
		sbe_timer_in_progress = true;
	}

	if (!has_new_target)
		return;

	lock(&sbe_timer_lock);
	if (has_new_target) {
		if (!p9_sbe_msg_busy(timer_ctrl_msg)) {
			has_new_target = false;
			p9_sbe_timer_schedule();
		}
	}
	unlock(&sbe_timer_lock);
}

static void p9_sbe_timer_schedule(void)
{
	int rc;
	u32 tick_us = SBE_TIMER_DEFAULT_US;
	u64 tb_cnt, now = mftb();

	if (sbe_timer_in_progress) {
		if (sbe_timer_target >= sbe_last_gen_stamp)
			return;

		if (now >= sbe_last_gen_stamp)
			return;

		/* Remaining time of inflight timer <= sbe_timer_def_tb */
		if ((sbe_last_gen_stamp - now) <= sbe_timer_def_tb)
			return;
	}

	/* Stop sending timer update chipop until inflight timer expires */
	if (timer_update_cnt > SBE_TIMER_UPDATE_MAX)
		return;
	timer_update_cnt++;

	if (now < sbe_timer_target) {
		/* Calculate how many microseconds from now, rounded up */
		if ((sbe_timer_target - now) > sbe_timer_def_tb) {
			tb_cnt = sbe_timer_target - now + usecs_to_tb(1) - 1;
			tick_us = tb_to_usecs(tb_cnt);
		}
	}

	/* Clear sequence number. p9_sbe_queue_msg will add new sequene ID */
	timer_ctrl_msg->reg[0] &= ~(PPC_BITMASK(32, 47));
	/* Update timeout value */
	timer_ctrl_msg->reg[1] = tick_us;
	rc = p9_sbe_queue_msg(sbe_default_chip_id, timer_ctrl_msg,
			      p9_sbe_timer_resp);
	if (rc != OPAL_SUCCESS) {
		prlog(PR_ERR, "Failed to start timer [chip id = %x]\n",
		      sbe_default_chip_id);
		return;
	}
}

/*
 * This is called with the timer lock held, so there is no
 * issue with re-entrancy or concurrence
 */
void p9_sbe_update_timer_expiry(uint64_t new_target)
{
	if (!sbe_has_timer || new_target == sbe_timer_target)
		return;

	lock(&sbe_timer_lock);
	/* Timer message is in flight. Record new timer and schedule later */
	if (p9_sbe_msg_busy(timer_ctrl_msg) || has_new_target) {
		if (new_target < sbe_timer_target) {
			sbe_timer_target = new_target;
			has_new_target = true;
		}
	} else {
		sbe_timer_target = new_target;
		p9_sbe_timer_schedule();
	}
	unlock(&sbe_timer_lock);
}

/* Initialize SBE timer */
static void p9_sbe_timer_init(void)
{
	timer_ctrl_msg = p9_sbe_mkmsg(SBE_CMD_CONTROL_TIMER,
				      CONTROL_TIMER_START, 0, 0, 0);
	assert(timer_ctrl_msg);
	init_lock(&sbe_timer_lock);
	sbe_has_timer = true;
	sbe_timer_target = mftb();
	sbe_last_gen_stamp = ~0ull;
	sbe_timer_def_tb = usecs_to_tb(SBE_TIMER_DEFAULT_US);
	prlog(PR_INFO, "Timer facility on chip %x\n", sbe_default_chip_id);
}

bool p9_sbe_timer_ok(void)
{
	return sbe_has_timer;
}

void p9_sbe_init(void)
{
	struct dt_node *xn;
	struct proc_chip *chip;
	struct p9_sbe *sbe;

	if (proc_gen < proc_gen_p9)
		return;

	dt_for_each_compatible(dt_root, xn, "ibm,xscom") {
		sbe = zalloc(sizeof(struct p9_sbe));
		assert(sbe);
		sbe->chip_id = dt_get_chip_id(xn);
		sbe->cur_seq = 1;
		sbe->state = sbe_mbox_idle;
		list_head_init(&sbe->msg_list);
		init_lock(&sbe->lock);

		chip = get_chip(sbe->chip_id);
		assert(chip);
		chip->sbe = sbe;

		if (dt_has_node_property(xn, "primary", NULL)) {
			sbe_default_chip_id = sbe->chip_id;
			prlog(PR_DEBUG, "Master chip id : %x\n", sbe->chip_id);
		}
	}

	if (sbe_default_chip_id == -1) {
		prlog(PR_ERR, "Master chip ID not found.\n");
		return;
	}

	/* Initiate SBE timer */
	p9_sbe_timer_init();

	/* Initiate SBE timeout poller */
	opal_add_poller(p9_sbe_timeout_poll, NULL);
}
