/*
 *  Copyright (c) 2013 Qualcomm Atheros, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/cpumask.h>
#include <linux/delay.h>
#include <linux/irq.h>

#include <asm/delay.h>
#include <asm/irq.h>

#include <atheros.h>
/*
 * Support for Atheros pci interrupt and core pci initialization
 */
/*
 * PCI interrupts.
 * roughly the interrupts flow is:
 *
 * - save flags
 * - CLI (disable all)
 * - IC->ack (mask out the source)
 * - EI (enable all, except the source that was masked of course)
 * - action (ISR)
 * - IC->enable (unmask the source)
 *
 * The reason we have a separate PCI IC is beacause of the following:
 * If we dont, then Throughout the "action" of a PCI slot, the
 * entire PCI "IP" on the cpu will remain disabled. Which means that we cant
 * prioritize between PCI interrupts. Normally this should be ok, if all PCI
 * interrupts are considered equal. However, creating a PCI IC gives
 * the flexibility to prioritize.
 */

static void
ath_pci_irq_enable(unsigned int irq)
{
	ATH_DECL_PCI_IM_ARR(r);

	ath_reg_rmw_set(r[irq - ATH_PCI_IRQ_BASE], PCIE_INT_MASK_INTAL_MASK);
}

static void
ath_pci_irq_disable(unsigned int irq)
{
	ATH_DECL_PCI_IM_ARR(r1);
	ATH_DECL_PCI_IS_ARR(r2);

	ath_reg_rmw_clear(r1[irq - ATH_PCI_IRQ_BASE], PCIE_INT_MASK_INTAL_MASK);
	ath_reg_rmw_clear(r2[irq - ATH_PCI_IRQ_BASE], PCIE_INT_STATUS_INTAL_MASK);

#ifdef CONFIG_MACH_QCA956x
    ath_reg_rmw_clear(r1[irq - ATH_PCI_IRQ_BASE], PCIE_INT_MASK_INTA_MASK);
	ath_reg_rmw_clear(r2[irq - ATH_PCI_IRQ_BASE], PCIE_INT_STATUS_INTA_MASK);
#endif
}

static unsigned int
ath_pci_irq_startup(unsigned int irq)
{
	ath_pci_irq_enable(irq);
	return 0;
}

static void
ath_pci_irq_shutdown(unsigned int irq)
{
	ath_pci_irq_disable(irq);
}

static void
ath_pci_irq_ack(unsigned int irq)
{
	ath_pci_irq_disable(irq);
}

static void
ath_pci_irq_end(unsigned int irq)
{
	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
		ath_pci_irq_enable(irq);
}

static int
ath_pci_irq_set_affinity(unsigned int irq, const struct cpumask *mask)
{
	/*
	 * Only 1 CPU; ignore affinity request
	 */
	return 0;
}

struct irq_chip /* hw_interrupt_type */ ath_pci_irq_controller = {
	.name		= "ATH PCI",
	.startup	= ath_pci_irq_startup,
	.shutdown	= ath_pci_irq_shutdown,
	.enable		= ath_pci_irq_enable,
	.disable	= ath_pci_irq_disable,
	.ack		= ath_pci_irq_ack,
	.end		= ath_pci_irq_end,
	.eoi		= ath_pci_irq_end,
	.set_affinity	= ath_pci_irq_set_affinity,
};

void
ath_pci_irq_init(int irq_base)
{
	int i;

	for (i = irq_base; i < irq_base + ATH_PCI_IRQ_COUNT; i++) {
		irq_desc[i].status = IRQ_DISABLED;
		irq_desc[i].action = NULL;
		irq_desc[i].depth = 1;
		//irq_desc[i].chip = &ath_pci_irq_controller;
		set_irq_chip_and_handler(i, &ath_pci_irq_controller,
					 handle_percpu_irq);
	}
}

#ifndef CONFIG_ATH_EMULATION
/*
 * init the pci controller
 */

#define ATH_PCI_RES(x, n, s, e, f)			\
	{ .name = n, .start = s, .end = e, .flags = f }

#define ATH_PCI_RES_IO(x, s, e)				\
	ATH_PCI_RES(x, "PCI I/O - " # x, s, e, IORESOURCE_IO)

#define ATH_PCI_RES_MEM(x)				\
	ATH_PCI_RES(x, "PCI MEM - " # x,		\
	ATH_PCI_MEM_BASE(x),				\
	ATH_PCI_MEM_BASE(x) + ATH_PCI_WINDOW - 1,	\
	IORESOURCE_MEM)

/*
 * We don't use I/O transaction ability.
 */
static struct resource ath_io_resource[] = {
	ATH_DECL_PCI_IO_RES
};

static struct resource ath_mem_resource[] = {
	ATH_DECL_PCI_MEM_RES
};


extern struct pci_ops ath_pci_ops;

#define ATH_PCI_CTRL_DESCRIPTOR(x)			\
	{						\
		.pci_ops	= &ath_pci_ops,		\
		.mem_resource	= &ath_mem_resource[x],	\
		.io_resource	= &ath_io_resource[x],	\
	}

static struct pci_controller ath_pci_controller[] = {
	ATH_DECL_PCI_CTRLR
};

#define ATH_NUM_PCI_CONTROLLER	\
	(sizeof(ath_pci_controller) / sizeof(ath_pci_controller[0]))

int ath_pci_link[ATH_NUM_PCI_CONTROLLER];

/*
 * We want a 1:1 mapping between PCI and DDR for inbound and outbound.
 * The PCI<---AHB decoding works as follows:
 *
 * 8 registers in the DDR unit provide software configurable 32 bit offsets
 * for each of the eight 16MB PCI windows in the 128MB. The offsets will be
 * added to any address in the 16MB segment before being sent to the PCI unit.
 *
 * Essentially  for any AHB address generated by the CPU,
 * 1. the MSB  four bits are stripped off, [31:28],
 * 2. Bit 27 is used to decide between the lower 128Mb (PCI) or the rest of
 *    the AHB space
 * 3. Bits 26:24 are used to access one of the 8 window registers and are
 *    masked off.
 * 4. If it is a PCI address, then the WINDOW offset in the WINDOW register
 *    corresponding to the next 3 bits (bit 26:24) is ADDED to the address,
 *    to generate the address to PCI unit.
 *
 *     eg. CPU address = 0x100000ff
 *         window 0 offset = 0x10000000
 *         This points to lowermost 16MB window in PCI space.
 *         So the resulting address would be 0x000000ff+0x10000000
 *         = 0x100000ff
 *
 *         eg2. CPU address = 0x120000ff
 *         WINDOW 2 offset = 0x12000000
 *         resulting address would be 0x000000ff+0x12000000
 *                         = 0x120000ff
 *
 * There is no translation for inbound access (PCI device as a master)
 */

static int __init ath_pcibios_init(void)
{
	uint32_t i;
	ATH_DECL_PCI_RST_ARR(pcie_reset);

#if ATH_LOW_POWER_ENABLE
	ATH_DECL_PCI_ASPM_SUPP_ARR(aspm_sup);
	ATH_DECL_PCI_ASPM_EN_ARR(aspm_en);
#endif

#ifdef CONFIG_MACH_AR934x
	if (is_ar9341()) {
		return 0;
	}
#endif

	for (i = 0; i < ATH_NUM_PCI_CONTROLLER; i++) {
		printk("%s: bus %d\n", __func__, i);
		/*
		 * Check if the WLAN PCI-E H/W is present, If the
		 * WLAN H/W is not present, skip the PCI
		 * initialization code and just return.
		 */
		if (!(ath_reg_rd(pcie_reset[i]) & PCIE_RESET_LINK_UP_MASK)) {
			printk("***** Warning PCIe %d H/W not found !!!\n", i);
		} else {
			ath_pci_link[i] = 1;

#ifndef CONFIG_PCI_INIT_IN_MONITOR

#define ATH_PCI_CMD_INIT	(PCI_COMMAND_MEMORY |		\
				 PCI_COMMAND_MASTER |		\
				 PCI_COMMAND_INVALIDATE |	\
				 PCI_COMMAND_PARITY |		\
				 PCI_COMMAND_SERR |		\
				 PCI_COMMAND_FAST_BACK)

			printk("%s(%d): PCI %d CMD write: 0x%x\n",
				__func__, __LINE__, i, ATH_PCI_CMD_INIT);

			ath_local_write_config(i, PCI_COMMAND, 4, ATH_PCI_CMD_INIT);
#endif

#if ATH_LOW_POWER_ENABLE
			// Enable L0 & L1 ASPM Support
			ath_reg_rmw_set(aspm_sup[i], ATH_PCIE_RC_SUPP_VAL);
			// Enable L0 & L1
			ath_reg_rmw_set(aspm_en[i], ATH_PCIE_RC_EN_VAL);
#endif
		}
		register_pci_controller(&ath_pci_controller[i]);
	}
	return 0;
}

arch_initcall(ath_pcibios_init);
#endif
