aboutsummaryrefslogblamecommitdiffstats
path: root/arch/arm/mach-imx/mcc_imx6sx.c
blob: 4e22ffc6f6f4f66a4965ba6db7ee22183f04dfd2 (plain) (tree)



















































































































































                                                                                
/*
 * Copyright (C) 2014 Freescale Semiconductor, Inc.
 * Freescale IMX Linux-specific MCC implementation.
 * iMX6sx-specific MCC library functions.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/regmap.h>
#include <linux/mcc_imx6sx.h>
#include <linux/mcc_linux.h>

/*!
 * \brief This function returns the core number
 *
 * \return int
 */
unsigned int _psp_core_num(void)
{
    return 0;
}

/*
 * This field contains CPU-to-CPU interrupt vector numbers
 * for all device cores.
 */
static const unsigned int mcc_cpu_to_cpu_vectors[] = {INT_CPU_TO_CPU_MU_A2M,
	INT_CPU_TO_CPU_MU_M2A};

/*!
 * \brief This function gets the CPU-to-CPU vector num for the particular core.
 *
 * Platform-specific inter-CPU vector numbers for each core are defined in the
 * mcc_cpu_to_cpu_vectors[] field.
 *
 * \param[in] core Core number.
 *
 * \return vector number for the particular core
 * \return MCC_VECTOR_NUMBER_INVALID (vector number for the particular core
 * number not found)
 */
unsigned int mcc_get_cpu_to_cpu_vector(unsigned int core)
{
	u32 val;

	val = sizeof(mcc_cpu_to_cpu_vectors)/sizeof(mcc_cpu_to_cpu_vectors[0]);
	if (core <  val)
		return  mcc_cpu_to_cpu_vectors[core];

	return MCC_VECTOR_NUMBER_INVALID;
}

/*!
 * \brief This function clears the CPU-to-CPU int flag for the particular core.
 *
 * Implementation is platform-specific.
 *
 * \param[in] core Core number.
 */
void mcc_clear_cpu_to_cpu_interrupt(unsigned int core)
{
	u32 val;

	regmap_read(imx_mu_reg, MU_ASR, &val);
	/* write 1 to BIT31 to clear the bit31(GIP3) of MU_ASR */
	val = val | (1 << 31);
	regmap_write(imx_mu_reg, MU_ASR, val);
}

/*!
 * \brief This function triggers the CPU-to-CPU interrupt.
 *
 * Platform-specific software triggering the inter-CPU interrupts.
 */
void mcc_triger_cpu_to_cpu_interrupt(void)
{
	int i = 0;
	u32 val;

	regmap_read(imx_mu_reg, MU_ACR, &val);

	if ((val & BIT(19)) != 0) {
		do {
			regmap_read(imx_mu_reg, MU_ACR, &val);
			msleep(1);
		} while (((val & BIT(19)) > 0) && (i++ < 100));
	}

	if ((val & BIT(19)) == 0)
		/* Enable the bit19(GIR3) of MU_ACR */
		regmap_update_bits(imx_mu_reg, MU_ACR, BIT(19), BIT(19));
	else
		pr_info("mcc int still be triggered after %d ms polling!\n", i);
}

/*!
 * \brief This function disable the CPU-to-CPU interrupt.
 *
 * Platform-specific software disable the inter-CPU interrupts.
 */
int imx_mcc_bsp_int_disable(unsigned int vector_number)
{
	u32 val;

	if (vector_number == INT_CPU_TO_CPU_MU_A2M) {
		/* Disable the bit31(GIE3) of MU_ACR */
		regmap_update_bits(imx_mu_reg, MU_ACR, BIT(31), 0);
		/* flush */
		regmap_read(imx_mu_reg, MU_ACR, &val);
	} else
		pr_err("ERR:wrong vector number in mcc.\n");

	return 0;
}

/*!
 * \brief This function enable the CPU-to-CPU interrupt.
 *
 * Platform-specific software enable the inter-CPU interrupts.
 */
int imx_mcc_bsp_int_enable(unsigned int vector_number)
{
	u32 val;

	if (vector_number == INT_CPU_TO_CPU_MU_A2M) {
		/* Enable the bit31(GIE3) of MU_ACR */
		regmap_update_bits(imx_mu_reg, MU_ACR, BIT(31), BIT(31));
		/* flush */
		regmap_read(imx_mu_reg, MU_ACR, &val);
		return 0;
	} else {
		pr_err("ERR:wrong vector number in mcc.\n");
		return -EINVAL;
	}
}