/*
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 *
 * SPDX-License-Identifier:  GPL-2.0+
 */
#include <common.h>
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
#include <asm/imx-common/rdc-sema.h>
#include <asm/arch/imx-rdc.h>
#include <linux/errno.h>

/*
 * Check if the RDC Semaphore is required for this peripheral.
 */
static inline int imx_rdc_check_sema_required(int per_id)
{
	struct rdc_regs *imx_rdc = (struct rdc_regs *)RDC_BASE_ADDR;
	u32 reg;

	reg = readl(&imx_rdc->pdap[per_id]);
	/*
	 * No semaphore:
	 * Intial value or this peripheral is assigned to only one domain
	 */
	if (!(reg & RDC_PDAP_SREQ_MASK))
		return -ENOENT;

	return 0;
}

/*
 * Check the peripheral read / write access permission on Domain [dom_id].
 */
int imx_rdc_check_permission(int per_id, int dom_id)
{
	struct rdc_regs *imx_rdc = (struct rdc_regs *)RDC_BASE_ADDR;
	u32 reg;

	reg = readl(&imx_rdc->pdap[per_id]);
	if (!(reg & RDC_PDAP_DRW_MASK(dom_id)))
		return -EACCES;  /*No access*/

	return 0;
}

/*
 * Lock up the RDC semaphore for this peripheral if semaphore is required.
 */
int imx_rdc_sema_lock(int per_id)
{
	struct rdc_sema_regs *imx_rdc_sema;
	int ret;
	u8 reg;

	ret = imx_rdc_check_sema_required(per_id);
	if (ret)
		return ret;

	if (per_id < SEMA_GATES_NUM)
		imx_rdc_sema  = (struct rdc_sema_regs *)SEMAPHORE1_BASE_ADDR;
	else
		imx_rdc_sema  = (struct rdc_sema_regs *)SEMAPHORE2_BASE_ADDR;

	do {
		writeb(RDC_SEMA_PROC_ID,
		       &imx_rdc_sema->gate[per_id % SEMA_GATES_NUM]);
		reg = readb(&imx_rdc_sema->gate[per_id % SEMA_GATES_NUM]);
		if ((reg & RDC_SEMA_GATE_GTFSM_MASK) == RDC_SEMA_PROC_ID)
			break;  /* Get the Semaphore*/
	} while (1);

	return 0;
}

/*
 * Unlock the RDC semaphore for this peripheral if main CPU is the
 * semaphore owner.
 */
int imx_rdc_sema_unlock(int per_id)
{
	struct rdc_sema_regs *imx_rdc_sema;
	int ret;
	u8 reg;

	ret = imx_rdc_check_sema_required(per_id);
	if (ret)
		return ret;

	if (per_id < SEMA_GATES_NUM)
		imx_rdc_sema  = (struct rdc_sema_regs *)SEMAPHORE1_BASE_ADDR;
	else
		imx_rdc_sema  = (struct rdc_sema_regs *)SEMAPHORE2_BASE_ADDR;

	reg = readb(&imx_rdc_sema->gate[per_id % SEMA_GATES_NUM]);
	if ((reg & RDC_SEMA_GATE_GTFSM_MASK) != RDC_SEMA_PROC_ID)
		return -EACCES;	/*Not the semaphore owner */

	writeb(0x0, &imx_rdc_sema->gate[per_id % SEMA_GATES_NUM]);

	return 0;
}

/*
 * Setup RDC setting for one peripheral
 */
int imx_rdc_setup_peri(rdc_peri_cfg_t p)
{
	struct rdc_regs *imx_rdc = (struct rdc_regs *)RDC_BASE_ADDR;
	u32 reg = 0;
	u32 share_count = 0;
	u32 peri_id = p & RDC_PERI_MASK;
	u32 domain = (p & RDC_DOMAIN_MASK) >> RDC_DOMAIN_SHIFT_BASE;

	/* No domain assigned */
	if (domain == 0)
		return -EINVAL;

	reg |= domain;

	share_count = (domain & 0x3)
		+ ((domain >> 2) & 0x3)
		+ ((domain >> 4) & 0x3)
		+ ((domain >> 6) & 0x3);

	if (share_count > 0x3)
		reg |= RDC_PDAP_SREQ_MASK;

	writel(reg, &imx_rdc->pdap[peri_id]);

	return 0;
}

/*
 * Setup RDC settings for multiple peripherals
 */
int imx_rdc_setup_peripherals(rdc_peri_cfg_t const *peripherals_list,
				     unsigned count)
{
	rdc_peri_cfg_t const *p = peripherals_list;
	int i, ret;

	for (i = 0; i < count; i++) {
		ret = imx_rdc_setup_peri(*p);
		if (ret)
			return ret;
		p++;
	}

	return 0;
}

/*
 * Setup RDC setting for one master
 */
int imx_rdc_setup_ma(rdc_ma_cfg_t p)
{
	struct rdc_regs *imx_rdc = (struct rdc_regs *)RDC_BASE_ADDR;
	u32 master_id = (p & RDC_MASTER_MASK) >> RDC_MASTER_SHIFT;
	u32 domain = (p & RDC_DOMAIN_MASK) >> RDC_DOMAIN_SHIFT_BASE;

	writel((domain & RDC_MDA_DID_MASK), &imx_rdc->mda[master_id]);

	return 0;
}

/*
 * Setup RDC settings for multiple masters
 */
int imx_rdc_setup_masters(rdc_ma_cfg_t const *masters_list, unsigned count)
{
	rdc_ma_cfg_t const *p = masters_list;
	int i, ret;

	for (i = 0; i < count; i++) {
		ret = imx_rdc_setup_ma(*p);
		if (ret)
			return ret;
		p++;
	}

	return 0;
}
