// SPDX-License-Identifier: GPL-2.0
/*
 * devoard misc stuff.
 */

#include <linux/init.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/physmap.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/pm.h>

#include <asm/bootinfo.h>
#include <asm/idle.h>
#include <asm/reboot.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h>

#include <prom.h>

void __init prom_init(void)
{
	unsigned char *memsize_str;
	unsigned long memsize;

	prom_argc = (int)fw_arg0;
	prom_argv = (char **)fw_arg1;
	prom_envp = (char **)fw_arg2;

	prom_init_cmdline();
	memsize_str = prom_getenv("memsize");
	if (!memsize_str || kstrtoul(memsize_str, 0, &memsize))
		memsize = 64 << 20; /* all devboards have at least 64MB RAM */

	add_memory_region(0, memsize, BOOT_MEM_RAM);
}

void prom_putchar(unsigned char c)
{
	if (alchemy_get_cputype() == ALCHEMY_CPU_AU1300)
		alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c);
	else
		alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
}


static struct platform_device db1x00_rtc_dev = {
	.name	= "rtc-au1xxx",
	.id	= -1,
};


static void db1x_power_off(void)
{
	bcsr_write(BCSR_RESETS, 0);
	bcsr_write(BCSR_SYSTEM, BCSR_SYSTEM_PWROFF | BCSR_SYSTEM_RESET);
	while (1)		/* sit and spin */
		cpu_wait();
}

static void db1x_reset(char *c)
{
	bcsr_write(BCSR_RESETS, 0);
	bcsr_write(BCSR_SYSTEM, 0);
}

static int __init db1x_late_setup(void)
{
	if (!pm_power_off)
		pm_power_off = db1x_power_off;
	if (!_machine_halt)
		_machine_halt = db1x_power_off;
	if (!_machine_restart)
		_machine_restart = db1x_reset;

	platform_device_register(&db1x00_rtc_dev);

	return 0;
}
device_initcall(db1x_late_setup);

/* register a pcmcia socket */
int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start,
				       phys_addr_t pcmcia_attr_end,
				       phys_addr_t pcmcia_mem_start,
				       phys_addr_t pcmcia_mem_end,
				       phys_addr_t pcmcia_io_start,
				       phys_addr_t pcmcia_io_end,
				       int card_irq,
				       int cd_irq,
				       int stschg_irq,
				       int eject_irq,
				       int id)
{
	int cnt, i, ret;
	struct resource *sr;
	struct platform_device *pd;

	cnt = 5;
	if (eject_irq)
		cnt++;
	if (stschg_irq)
		cnt++;

	sr = kzalloc(sizeof(struct resource) * cnt, GFP_KERNEL);
	if (!sr)
		return -ENOMEM;

	pd = platform_device_alloc("db1xxx_pcmcia", id);
	if (!pd) {
		ret = -ENOMEM;
		goto out;
	}

	sr[0].name	= "pcmcia-attr";
	sr[0].flags	= IORESOURCE_MEM;
	sr[0].start	= pcmcia_attr_start;
	sr[0].end	= pcmcia_attr_end;

	sr[1].name	= "pcmcia-mem";
	sr[1].flags	= IORESOURCE_MEM;
	sr[1].start	= pcmcia_mem_start;
	sr[1].end	= pcmcia_mem_end;

	sr[2].name	= "pcmcia-io";
	sr[2].flags	= IORESOURCE_MEM;
	sr[2].start	= pcmcia_io_start;
	sr[2].end	= pcmcia_io_end;

	sr[3].name	= "insert";
	sr[3].flags	= IORESOURCE_IRQ;
	sr[3].start = sr[3].end = cd_irq;

	sr[4].name	= "card";
	sr[4].flags	= IORESOURCE_IRQ;
	sr[4].start = sr[4].end = card_irq;

	i = 5;
	if (stschg_irq) {
		sr[i].name	= "stschg";
		sr[i].flags	= IORESOURCE_IRQ;
		sr[i].start = sr[i].end = stschg_irq;
		i++;
	}
	if (eject_irq) {
		sr[i].name	= "eject";
		sr[i].flags	= IORESOURCE_IRQ;
		sr[i].start = sr[i].end = eject_irq;
	}

	pd->resource = sr;
	pd->num_resources = cnt;

	ret = platform_device_add(pd);
	if (!ret)
		return 0;

	platform_device_put(pd);
out:
	kfree(sr);
	return ret;
}

#define YAMON_SIZE	0x00100000
#define YAMON_ENV_SIZE	0x00040000

int __init db1x_register_norflash(unsigned long size, int width,
				  int swapped)
{
	struct physmap_flash_data *pfd;
	struct platform_device *pd;
	struct mtd_partition *parts;
	struct resource *res;
	int ret, i;

	if (size < (8 * 1024 * 1024))
		return -EINVAL;

	ret = -ENOMEM;
	parts = kzalloc(sizeof(struct mtd_partition) * 5, GFP_KERNEL);
	if (!parts)
		goto out;

	res = kzalloc(sizeof(struct resource), GFP_KERNEL);
	if (!res)
		goto out1;

	pfd = kzalloc(sizeof(struct physmap_flash_data), GFP_KERNEL);
	if (!pfd)
		goto out2;

	pd = platform_device_alloc("physmap-flash", 0);
	if (!pd)
		goto out3;

	/* NOR flash ends at 0x20000000, regardless of size */
	res->start = 0x20000000 - size;
	res->end = 0x20000000 - 1;
	res->flags = IORESOURCE_MEM;

	/* partition setup.  Most Develboards have a switch which allows
	 * to swap the physical locations of the 2 NOR flash banks.
	 */
	i = 0;
	if (!swapped) {
		/* first NOR chip */
		parts[i].offset = 0;
		parts[i].name = "User FS";
		parts[i].size = size / 2;
		i++;
	}

	parts[i].offset = MTDPART_OFS_APPEND;
	parts[i].name = "User FS 2";
	parts[i].size = (size / 2) - (0x20000000 - 0x1fc00000);
	i++;

	parts[i].offset = MTDPART_OFS_APPEND;
	parts[i].name = "YAMON";
	parts[i].size = YAMON_SIZE;
	parts[i].mask_flags = MTD_WRITEABLE;
	i++;

	parts[i].offset = MTDPART_OFS_APPEND;
	parts[i].name = "raw kernel";
	parts[i].size = 0x00400000 - YAMON_SIZE - YAMON_ENV_SIZE;
	i++;

	parts[i].offset = MTDPART_OFS_APPEND;
	parts[i].name = "YAMON Env";
	parts[i].size = YAMON_ENV_SIZE;
	parts[i].mask_flags = MTD_WRITEABLE;
	i++;

	if (swapped) {
		parts[i].offset = MTDPART_OFS_APPEND;
		parts[i].name = "User FS";
		parts[i].size = size / 2;
		i++;
	}

	pfd->width = width;
	pfd->parts = parts;
	pfd->nr_parts = 5;

	pd->dev.platform_data = pfd;
	pd->resource = res;
	pd->num_resources = 1;

	ret = platform_device_add(pd);
	if (!ret)
		return ret;

	platform_device_put(pd);
out3:
	kfree(pfd);
out2:
	kfree(res);
out1:
	kfree(parts);
out:
	return ret;
}
