/*
 * SUNXI MBUS support
 *
 * Copyright (C) 2015 AllWinnertech Ltd.
 *
 * 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.
 */

#ifndef __LINUX_SUNXI_MBUS_H
#define __LINUX_SUNXI_MBUS_H

#include <linux/types.h>

/* Port ids */
enum mbus_port {
#if (defined CONFIG_ARCH_SUN8IW10)
	MBUS_PORT_CPU           = 0,
	MBUS_PORT_MAHB          = 1,
	MBUS_PORT_DMA           = 2,
	MBUS_PORT_CSI           = 3,
	MBUS_PORT_NAND          = 4,
	enum mbus_portINK0         = 5,
	enum mbus_portINK1         = 6,
	MBUS_PORT_SD2           = 7,
	MBUS_PORT_DE            = 8,
	MBUS_PORTS_MAX          = 9,
#elif (defined CONFIG_ARCH_SUN50IW3)
	MBUS_PORT_CPU           = 0,
	MBUS_PORT_GPU           = 1,
	MBUS_PORT_MAHB          = 2,
	MBUS_PORT_DMA           = 3,
	MBUS_PORT_VE            = 4,
	MBUS_PORT_CE            = 5,
	MBUS_PORT_NDFC0         = 8,
	MBUS_PORT_CSI0          = 11,
	MBUS_PORT_G2D0          = 13,
	MBUS_PORT_DI0           = 14,
	MBUS_PORT_DE300         = 16,
	MBUS_PORT_DE300_ROT     = 17,
	MBUS_PORT_EVE           = 24,
	MBUS_PORT_IOMMU         = 25,
	MBUS_PORT_CVE           = 26,
	MBUS_PORT_ISE           = 27,
	MBUS_PORT_DE200         = 35,
	MBUS_PORT_DE200_ROT     = 36,
	MBUS_PORT_AXI           = 38,
	MBUS_PORT_VP9           = 39,
	MBUS_PORTS_MAX          = 40,
#elif (defined CONFIG_ARCH_SUN8IW11)
	MBUS_PORT_CPU           = 0,
	MBUS_PORT_GPU           = 1,
	/*MAHB for: SATA, ATH, USB0, SD0-3, USB1-2,GMAC*/
	MBUS_PORT_MAHB          = 2,
	MBUS_PORT_DMA           = 3,
	MBUS_PORT_VE            = 4,
	MBUS_PORT_CSI           = 5,
	MBUS_PORT_NAND          = 6,
	MBUS_PORT_SS            = 7,
	MBUS_PORT_TS            = 8,
	MBUS_PORT_DI            = 9,
	MBUS_PORT_CSI1          = 10,
	MBUS_PORT_MIXER         = 11,
	MBUS_PORT_TVIN          = 12,
	MBUS_PORT_DE200         = 13,
	MBUS_PORT_ROT           = 14,
	MBUS_PORTS_MAX          = 15,
	MBUS_PORT_SATA          = 16,
	MBUS_PORT_ATH           = 17,
	MBUS_PORT_USB0          = 18,
	MBUS_PORT_SD0           = 19,
	MBUS_PORT_SD1           = 20,
	MBUS_PORT_SD2           = 21,
	MBUS_PORT_USB1          = 22,
	MBUS_PORT_USB2          = 23,
	MBUS_PORT_SD3           = 24,
	MBUS_PORT_GMAC          = 25,
	MBUS_PORTSAE_MAX        = 26,
#elif (defined CONFIG_ARCH_SUN8IW12)
	MBUS_PORT_CPU           = 0,
	/*reserved: 1*/
	MBUS_PORT_MAHB          = 2,
	MBUS_PORT_DMA           = 3,
	MBUS_PORT_VE            = 4,
	MBUS_PORT_CE            = 5,
	MBUS_PORT_NDFC0         = 8,
	MBUS_PORT_CSI0          = 11,
	MBUS_PORT_ISP0          = 12,
	MBUS_PORT_G2D0          = 13,
	MBUS_PORT_DI0           = 14,
	MBUS_PORT_CSI1          = 22,
	MBUS_PORT_EVE           = 24,
	MBUS_PORT_CVE           = 26,
	MBUS_PORT_ISE           = 27,
	MBUS_PORT_DE200         = 35,
	MBUS_PORT_DE_ROT        = 36,
	MBUS_PORT_AXI           = 38,
	MBUS_PORTS_MAX          = 39,
	MBUS_PORT_U_SH1         = 64,
	MBUS_PORT_USB0          = 65,
	MBUS_PORT_USB1          = 66,
	MBUS_PORT_SD0           = 69,
	MBUS_PORT_SD1           = 70,
	MBUS_PORT_SD2           = 71,
	MBUS_PORT_GMAC          = 75,
#elif (defined CONFIG_ARCH_SUN8IW15)
	MBUS_PORT_CPU           = 0,
	MBUS_PORT_GPU           = 1,
	MBUS_PORT_MAHB          = 2,
	MBUS_PORT_DMA           = 3,
	MBUS_PORT_VE            = 4,
	MBUS_PORT_CE            = 5,
	MBUS_PORT_NDFC0         = 8,
	MBUS_PORT_CSI0          = 11,
	MBUS_PORT_DE300         = 16,
	MBUS_PORT_EINK0         = 18,
	MBUS_PORT_EINK1         = 19,
	MBUS_PORT_EINK2         = 20,
	MBUS_PORT_G2D1          = 21,
	MBUS_PORT_IOMMU         = 25,
	MBUS_PORT_EMCE          = 28,
	MBUS_PORTS_MAX          = 29,
#elif defined CONFIG_ARCH_SUN8IW6P1
	MBUS_PORT_CPU           = 0,
	/*reserved: 1*/
	MBUS_PORT_GPU           = 1,
	/* reversed bit2 */
	MBUS_PORT_DMA           = 3,
	MBUS_PORT_VE            = 4,
	MBUS_PORT_CSI           = 5,
	MBUS_PORT_NAND          = 6,
	MBUS_PORT_IEP           = 7,
	MBUS_PORT_BE            = 8,
	MBUS_PORT_FE            = 9,
	MBUS_PORT_SS            = 10,
	MBUS_PORT_IEP1          = 11,
	MBUS_PORT_BE1           = 12,
	MBUS_PORT_FE1           = 13,
	MBUS_PORTS_MAX          = 14,
	/* reversed bit14/15 */
	MBUS_PORT_CPUS          = 16,
	MBUS_PORT_TEST          = 17,
	MBUS_PORT_USB0          = 18,
	MBUS_PORT_SD0           = 19,
	MBUS_PORT_SD1           = 20,
	MBUS_PORT_SD2           = 21,
	MBUS_PORT_USB1          = 22,
	MBUS_PORT_USB2          = 23,
	MBUS_PORT_GMAC          = 24,
	MBUS_PORTSAE_MAX        = 25,
#else
	MBUS_PORT_CPU           = 0,
	MBUS_PORT_GPU           = 1,
	/* reversed bit2           */
	MBUS_PORT_DMA           = 3,
	MBUS_PORT_VE            = 4,
	MBUS_PORT_CSI           = 5,
	MBUS_PORT_NAND          = 6,
	MBUS_PORT_SS            = 7,
	MBUS_PORT_TS            = 8,
	MBUS_PORT_DI            = 9,
	MBUS_PORT_DE            = 10,
	MBUS_PORT_DE_CFD        = 11,
	MBUS_PORTS_MAX          = 13,
	/* reversed bit12/15       */
	MBUS_PORT_CPUS          = 16,
	MBUS_PORT_ATH           = 17,
	MBUS_PORT_USB0          = 18,
	MBUS_PORT_SD0           = 19,
	MBUS_PORT_SD1           = 20,
	MBUS_PORT_SD2           = 21,
	MBUS_PORT_USB1          = 22,
	MBUS_PORT_USB2          = 23,
	MBUS_PORT_GMAC          = 24,
	MBUS_PORTSAE_MAX        = 25,
#endif
};

struct device_node;

#ifdef CONFIG_SUNXI_MBUS
extern int mbus_port_setbwlen(enum mbus_port port, bool en);
extern int mbus_port_setpri(enum mbus_port port, bool pri);
extern int mbus_port_setqos(enum mbus_port port, unsigned int qos);
extern int mbus_port_setwt(enum mbus_port port, unsigned int wt);
extern int mbus_port_setacs(enum mbus_port port, unsigned int acs);
extern int mbus_port_setbwl0(enum mbus_port port, unsigned int bwl0);
extern int mbus_port_setbwl1(enum mbus_port port, unsigned int bwl1);
extern int mbus_port_setbwl2(enum mbus_port port, unsigned int bwl2);
extern int mbus_port_setbwl(enum mbus_port port, unsigned int bwl0,
			    unsigned int bwl1, unsigned int bwl2);
extern int mbus_set_bwlwen(bool enable);
extern int mbus_set_bwlwsiz(unsigned int size);
extern int mbus_port_control_by_index(enum mbus_port port, bool enable);
extern bool mbus_probed(void);
extern int mbus_port_setbwcu(unsigned int unit);
#else
static inline int mbus_port_setbwlen(enum mbus_port port, bool en)
{
	return -ENODEV;
}
static inline int mbus_port_setpri(enum mbus_port port, bool pri)
{
	return -ENODEV;
}
static inline int mbus_port_setqos(enum mbus_port port, unsigned int qos)
{
	return -ENODEV;
}
static inline int mbus_port_setwt(enum mbus_port port, unsigned int wt)
{
	return -ENODEV;
}
static inline int mbus_port_setacs(enum mbus_port port, unsigned int acs)
{
	return -ENODEV;
}
static inline int mbus_port_setbwl0(enum mbus_port port, unsigned int bwl0)
{
	return -ENODEV;
}
static inline int mbus_port_setbwl1(enum mbus_port port, unsigned int bwl1)
{
	return -ENODEV;
}
static inline int mbus_port_setbwl2(enum mbus_port port, unsigned int bwl2)
{
	return -ENODEV;
}
static inline int mbus_port_setbwl(enum mbus_port port, unsigned int bwl0,
				   unsigned int bwl1, unsigned int bwl2)
{
	return -ENODEV;
}
static inline int mbus_set_bwlwen(bool enable)
{
	return -ENODEV;
}
static inline int mbus_set_bwlwsiz(unsigned int size)
{
	return -ENODEV;
}
static inline int mbus_port_control_by_index(enum mbus_port port, bool enable)
{
	return -ENODEV;
}
static inline bool mbus_probed(void)
{
	return false;
}
static inline int mbus_port_setbwcu(unsigned int unit)
{
	return -ENODEV;
}
#endif

#define mbus_disable_port_by_index(dev) \
	mbus_port_control_by_index(dev, false)
#define mbus_enable_port_by_index(dev) \
	mbus_port_control_by_index(dev, true)

#endif