/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that 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.
 */

#include <linux/init.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/jiffies.h>
#include <linux/smp.h>
#include <linux/io.h>
#include <linux/interrupt.h>

#include <asm/cacheflush.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/smp_scu.h>
#include <asm/unified.h>
#include <mach/msm_iomap.h>
#include <mach/smp.h>
#include "pm.h"

#define MSM_CORE1_RESET		0xA8600590
#define MSM_CORE1_STATUS_MSK	0x02800000

/*
 * control for which core is the next to come out of the secondary
 * boot "holding pen"
 */
int pen_release = -1;

static bool cold_boot_done;

static uint32_t *msm8625_boot_vector;

/*
 * Write pen_release in a way that is guaranteed to be visible to all
 * observers, irrespective of whether they're taking part in coherency
 * or not.  This is necessary for the hotplug code to work reliably.
 */
static void __cpuinit write_pen_release(int val)
{
	pen_release = val;
	smp_wmb();
	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
}

static void __iomem *scu_base_addr(void)
{
	return MSM_SCU_BASE;
}

static DEFINE_SPINLOCK(boot_lock);

/*
 * MP_CORE_IPC will be used to generate interrupt and can be used by either
 * of core.
 * To bring core1 out of GDFS we need to raise the SPI using the MP_CORE_IPC.
 */
static void raise_clear_spi(unsigned int cpu, bool set)
{
	int value;

	value = __raw_readl(MSM_CSR_BASE + 0x54);
	if (set)
		__raw_writel(value | BIT(cpu), MSM_CSR_BASE + 0x54);
	else
		__raw_writel(value & ~BIT(cpu), MSM_CSR_BASE + 0x54);
	mb();
}

static void clear_pending_spi(unsigned int irq)
{
	/* Clear the IRQ from the ENABLE_SET */
	local_irq_disable();
	gic_clear_spi_pending(irq);
	local_irq_enable();
}

void __cpuinit platform_secondary_init(unsigned int cpu)
{
	pr_debug("CPU%u: Booted secondary processor\n", cpu);

	WARN_ON(msm_platform_secondary_init(cpu));

	/*
	 * if any interrupts are already enabled for the primary
	 * core (e.g. timer irq), then they will not have been enabled
	 * for us: do so
	 */
	gic_secondary_init(0);

	/*
	 * let the primary processor know we're out of the
	 * pen, then head off into the C entry point
	 */
	write_pen_release(-1);

	/* clear the IPC1(SPI-8) pending SPI */
	if (power_collapsed) {
		raise_clear_spi(1, false);
		clear_pending_spi(MSM8625_INT_ACSR_MP_CORE_IPC1);
		power_collapsed = 0;
	}

	/*
	 * Synchronise with the boot thread.
	 */
	spin_lock(&boot_lock);
	spin_unlock(&boot_lock);
}

static int  __cpuinit msm8625_release_secondary(void)
{
	void __iomem *base_ptr;
	int value = 0;
	unsigned long timeout;

	/*
	 * loop to ensure that the GHS_STATUS_CORE1 bit in the
	 * MPA5_STATUS_REG(0x3c) is set. The timeout for the while
	 * loop can be set as 20us as of now
	 */
	timeout = jiffies + usecs_to_jiffies(20);
	while (time_before(jiffies, timeout)) {
		value = __raw_readl(MSM_CFG_CTL_BASE + 0x3c);
		if ((value & MSM_CORE1_STATUS_MSK) ==
				MSM_CORE1_STATUS_MSK)
			break;
			udelay(1);
	}

	if (!value) {
		pr_err("Core 1 cannot be brought out of Reset!!!\n");
		return -ENODEV;
	}

	base_ptr = ioremap_nocache(MSM_CORE1_RESET, SZ_4);
	if (!base_ptr)
		return -ENODEV;
	/* Reset core 1 out of reset */
	__raw_writel(0x0, base_ptr);
	mb();

	iounmap(base_ptr);

	return 0;
}

int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
	unsigned long timeout;

	if (cold_boot_done == false) {
		if (msm8625_release_secondary()) {
			pr_err("Failed to release secondary core\n");
			return -ENODEV;
		}
		cold_boot_done = true;
	}

	/*
	 * Set synchronisation state between this boot processor
	 * and the secondary one
	 */
	spin_lock(&boot_lock);

	/*
	 * This is really belt and braces; we hold unintended secondary
	 * CPUs in the holding pen until we're ready for them.  However,
	 * since we haven't sent them a soft interrupt, they shouldn't
	 * be there.
	 */
	write_pen_release(cpu);

	/*
	 * Send the secondary CPU a soft interrupt, thereby causing
	 * the boot monitor to read the system wide flags register,
	 * and branch to the address found there.
	 *
	 * power_collapsed is the flag which will be updated for Powercollapse.
	 * Once we are out of PC, as Core1 will be in the state of GDFS which
	 * needs to be brought out by raising an SPI.
	 */

	if (power_collapsed) {
		core1_gic_configure_and_raise();
		raise_clear_spi(1, true);
	} else {
		gic_raise_softirq(cpumask_of(cpu), 1);
	}

	timeout = jiffies + (1 * HZ);
	while (time_before(jiffies, timeout)) {
		smp_rmb();
		if (pen_release == -1)
			break;

		udelay(10);
	}

	/*
	 * now the secondary core is starting up let it run its
	 * calibrations, then wait for it to finish
	 */
	spin_unlock(&boot_lock);

	return 0;
}

/*
 * Initialise the CPU possible map early - this describes the CPUs
 * which may be present or become present in the system.
 */
void __init smp_init_cpus(void)
{
	void __iomem *scu_base = scu_base_addr();

	unsigned int i, ncores;

	ncores = scu_base ? scu_get_core_count(scu_base) : 1;

	for (i = 0; i < ncores; i++)
		set_cpu_possible(i, true);

	set_smp_cross_call(gic_raise_softirq);
}

static void __init msm8625_boot_vector_init(uint32_t *boot_vector,
		unsigned long entry)
{
	if (!boot_vector)
		return;
	msm8625_boot_vector = boot_vector;

	msm8625_boot_vector[0] = 0xE51FF004; /* ldr pc, 4 */
	msm8625_boot_vector[1] = entry;
}

void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
	int i, value;
	void __iomem *second_ptr;

	/*
	 * Initialise the present map, which describes the set of CPUs
	 * actually populated at the present time.
	 */
	for (i = 0; i < max_cpus; i++)
		set_cpu_present(i, true);

	scu_enable(scu_base_addr());

	/*
	 * Write the address of secondary startup into the
	 * boot remapper register. The secondary CPU branches to this address.
	 */
	__raw_writel(MSM8625_SECONDARY_PHYS, (MSM_CFG_CTL_BASE + 0x34));
	mb();

	second_ptr = ioremap_nocache(MSM8625_SECONDARY_PHYS, SZ_8);
	if (!second_ptr) {
		pr_err("failed to ioremap for secondary core\n");
		return;
	}

	msm8625_boot_vector_init(second_ptr,
			virt_to_phys(msm_secondary_startup));
	iounmap(second_ptr);

	/* Enable boot remapper address: bit 26 for core1 */
	value = __raw_readl(MSM_CFG_CTL_BASE + 0x30);
	__raw_writel(value | (0x4 << 24), MSM_CFG_CTL_BASE + 0x30) ;
	mb();
}
