// SPDX-License-Identifier: GPL-2.0-only
/*
 * Common CPM code
 *
 * Author: Scott Wood <scottwood@freescale.com>
 *
 * Copyright 2007-2008,2010 Freescale Semiconductor, Inc.
 *
 * Some parts derived from commproc.c/cpm2_common.c, which is:
 * Copyright (c) 1997 Dan error_act (dmalek@jlc.net)
 * Copyright (c) 1999-2001 Dan Malek <dan@embeddedalley.com>
 * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com)
 * 2006 (c) MontaVista Software, Inc.
 * Vitaly Bordug <vbordug@ru.mvista.com>
 */

#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/export.h>
#include <linux/of.h>
#include <linux/slab.h>

#include <asm/udbg.h>
#include <asm/io.h>
#include <asm/cpm.h>
#include <asm/fixmap.h>
#include <soc/fsl/qe/qe.h>

#include <mm/mmu_decl.h>

static int __init cpm_init(void)
{
	struct device_node *np;

	np = of_find_compatible_node(NULL, NULL, "fsl,cpm1");
	if (!np)
		np = of_find_compatible_node(NULL, NULL, "fsl,cpm2");
	if (!np)
		return -ENODEV;
	cpm_muram_init();
	of_node_put(np);
	return 0;
}
subsys_initcall(cpm_init);

#ifdef CONFIG_PPC_EARLY_DEBUG_CPM
static u32 __iomem *cpm_udbg_txdesc;
static u8 __iomem *cpm_udbg_txbuf;

static void udbg_putc_cpm(char c)
{
	if (c == '\n')
		udbg_putc_cpm('\r');

	while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000)
		;

	out_8(cpm_udbg_txbuf, c);
	out_be32(&cpm_udbg_txdesc[0], 0xa0000001);
}

void __init udbg_init_cpm(void)
{
#ifdef CONFIG_PPC_8xx
	mmu_mapin_immr();

	cpm_udbg_txdesc = (u32 __iomem __force *)
			  (CONFIG_PPC_EARLY_DEBUG_CPM_ADDR - PHYS_IMMR_BASE +
			   VIRT_IMMR_BASE);
	cpm_udbg_txbuf = (u8 __iomem __force *)
			 (in_be32(&cpm_udbg_txdesc[1]) - PHYS_IMMR_BASE +
			  VIRT_IMMR_BASE);
#else
	cpm_udbg_txdesc = (u32 __iomem __force *)
			  CONFIG_PPC_EARLY_DEBUG_CPM_ADDR;
	cpm_udbg_txbuf = (u8 __iomem __force *)in_be32(&cpm_udbg_txdesc[1]);
#endif

	if (cpm_udbg_txdesc) {
#ifdef CONFIG_CPM2
		setbat(1, 0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG);
#endif
		udbg_putc = udbg_putc_cpm;
	}
}
#endif

#if defined(CONFIG_CPM2) || defined(CONFIG_8xx_GPIO)

#include <linux/gpio/driver.h>

struct cpm2_ioports {
	u32 dir, par, sor, odr, dat;
	u32 res[3];
};

struct cpm2_gpio32_chip {
	struct gpio_chip gc;
	void __iomem *regs;
	spinlock_t lock;

	/* shadowed data register to clear/set bits safely */
	u32 cpdata;
};

static void cpm2_gpio32_save_regs(struct cpm2_gpio32_chip *cpm2_gc)
{
	struct cpm2_ioports __iomem *iop = cpm2_gc->regs;

	cpm2_gc->cpdata = in_be32(&iop->dat);
}

static int cpm2_gpio32_get(struct gpio_chip *gc, unsigned int gpio)
{
	struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
	struct cpm2_ioports __iomem *iop = cpm2_gc->regs;
	u32 pin_mask;

	pin_mask = 1 << (31 - gpio);

	return !!(in_be32(&iop->dat) & pin_mask);
}

static void __cpm2_gpio32_set(struct cpm2_gpio32_chip *cpm2_gc, u32 pin_mask, int value)
{
	struct cpm2_ioports __iomem *iop = cpm2_gc->regs;

	if (value)
		cpm2_gc->cpdata |= pin_mask;
	else
		cpm2_gc->cpdata &= ~pin_mask;

	out_be32(&iop->dat, cpm2_gc->cpdata);
}

static int cpm2_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value)
{
	struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
	unsigned long flags;
	u32 pin_mask = 1 << (31 - gpio);

	spin_lock_irqsave(&cpm2_gc->lock, flags);

	__cpm2_gpio32_set(cpm2_gc, pin_mask, value);

	spin_unlock_irqrestore(&cpm2_gc->lock, flags);

	return 0;
}

static int cpm2_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
{
	struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
	struct cpm2_ioports __iomem *iop = cpm2_gc->regs;
	unsigned long flags;
	u32 pin_mask = 1 << (31 - gpio);

	spin_lock_irqsave(&cpm2_gc->lock, flags);

	setbits32(&iop->dir, pin_mask);
	__cpm2_gpio32_set(cpm2_gc, pin_mask, val);

	spin_unlock_irqrestore(&cpm2_gc->lock, flags);

	return 0;
}

static int cpm2_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
{
	struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
	struct cpm2_ioports __iomem *iop = cpm2_gc->regs;
	unsigned long flags;
	u32 pin_mask = 1 << (31 - gpio);

	spin_lock_irqsave(&cpm2_gc->lock, flags);

	clrbits32(&iop->dir, pin_mask);

	spin_unlock_irqrestore(&cpm2_gc->lock, flags);

	return 0;
}

static int cpm2_gpio32_get_direction(struct gpio_chip *gc, unsigned int gpio)
{
	struct cpm2_gpio32_chip *cpm2_gc = gpiochip_get_data(gc);
	struct cpm2_ioports __iomem *iop = cpm2_gc->regs;
	u32 pin_mask = 1 << (31 - gpio);

	if (in_be32(&iop->dir) & pin_mask)
		return GPIO_LINE_DIRECTION_OUT;

	return GPIO_LINE_DIRECTION_IN;
}

int cpm2_gpiochip_add32(struct device *dev)
{
	struct device_node *np = dev->of_node;
	struct cpm2_gpio32_chip *cpm2_gc;
	struct gpio_chip *gc;

	cpm2_gc = devm_kzalloc(dev, sizeof(*cpm2_gc), GFP_KERNEL);
	if (!cpm2_gc)
		return -ENOMEM;

	spin_lock_init(&cpm2_gc->lock);

	gc = &cpm2_gc->gc;

	gc->base = -1;
	gc->ngpio = 32;
	gc->direction_input = cpm2_gpio32_dir_in;
	gc->direction_output = cpm2_gpio32_dir_out;
	gc->get_direction = cpm2_gpio32_get_direction;
	gc->get = cpm2_gpio32_get;
	gc->set = cpm2_gpio32_set;
	gc->parent = dev;
	gc->owner = THIS_MODULE;

	gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np);
	if (!gc->label)
		return -ENOMEM;

	cpm2_gc->regs = devm_of_iomap(dev, np, 0, NULL);
	if (IS_ERR(cpm2_gc->regs))
		return PTR_ERR(cpm2_gc->regs);

	cpm2_gpio32_save_regs(cpm2_gc);

	return devm_gpiochip_add_data(dev, gc, cpm2_gc);
}
#endif /* CONFIG_CPM2 || CONFIG_8xx_GPIO */
