// SPDX-License-Identifier: GPL-2.0-only
/*
 * HP Quicksilver AGP GART routines
 *
 * Copyright (c) 2006, Kyle McMartin <kyle@parisc-linux.org>
 *
 * Based on drivers/char/agpgart/hp-agp.c which is
 * (c) Copyright 2002, 2003 Hewlett-Packard Development Company, L.P.
 *	Bjorn Helgaas <bjorn.helgaas@hp.com>
 */

#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/klist.h>
#include <linux/agp_backend.h>
#include <linux/log2.h>
#include <linux/slab.h>

#include <asm/parisc-device.h>
#include <asm/ropes.h>

#include "agp.h"

#define DRVNAME	"quicksilver"
#define DRVPFX	DRVNAME ": "

#define AGP8X_MODE_BIT		3
#define AGP8X_MODE		(1 << AGP8X_MODE_BIT)

static unsigned long
parisc_agp_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr,
		       int type);

static struct _parisc_agp_info {
	void __iomem *ioc_regs;
	void __iomem *lba_regs;

	int lba_cap_offset;

	__le64 *gatt;
	u64 gatt_entries;

	u64 gart_base;
	u64 gart_size;

	int io_page_size;
	int io_pages_per_kpage;
} parisc_agp_info;

static struct gatt_mask parisc_agp_masks[] =
{
        {
		.mask = SBA_PDIR_VALID_BIT,
		.type = 0
	}
};

static struct aper_size_info_fixed parisc_agp_sizes[] =
{
        {0, 0, 0},              /* filled in by parisc_agp_fetch_size() */
};

static int
parisc_agp_fetch_size(void)
{
	int size;

	size = parisc_agp_info.gart_size / MB(1);
	parisc_agp_sizes[0].size = size;
	agp_bridge->current_size = (void *) &parisc_agp_sizes[0];

	return size;
}

static int
parisc_agp_configure(void)
{
	struct _parisc_agp_info *info = &parisc_agp_info;

	agp_bridge->gart_bus_addr = info->gart_base;
	agp_bridge->capndx = info->lba_cap_offset;
	agp_bridge->mode = readl(info->lba_regs+info->lba_cap_offset+PCI_AGP_STATUS);

	return 0;
}

static void
parisc_agp_tlbflush(struct agp_memory *mem)
{
	struct _parisc_agp_info *info = &parisc_agp_info;

	/* force fdc ops to be visible to IOMMU */
	asm_io_sync();

	writeq(info->gart_base | ilog2(info->gart_size), info->ioc_regs+IOC_PCOM);
	readq(info->ioc_regs+IOC_PCOM);	/* flush */
}

static int
parisc_agp_create_gatt_table(struct agp_bridge_data *bridge)
{
	struct _parisc_agp_info *info = &parisc_agp_info;
	int i;

	for (i = 0; i < info->gatt_entries; i++) {
		info->gatt[i] = cpu_to_le64(agp_bridge->scratch_page);
	}

	return 0;
}

static int
parisc_agp_free_gatt_table(struct agp_bridge_data *bridge)
{
	struct _parisc_agp_info *info = &parisc_agp_info;

	info->gatt[0] = SBA_AGPGART_COOKIE;

	return 0;
}

static int
parisc_agp_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
{
	struct _parisc_agp_info *info = &parisc_agp_info;
	int i, k;
	off_t j, io_pg_start;
	int io_pg_count;

	if (type != mem->type ||
		agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) {
		return -EINVAL;
	}

	io_pg_start = info->io_pages_per_kpage * pg_start;
	io_pg_count = info->io_pages_per_kpage * mem->page_count;
	if ((io_pg_start + io_pg_count) > info->gatt_entries) {
		return -EINVAL;
	}

	j = io_pg_start;
	while (j < (io_pg_start + io_pg_count)) {
		if (info->gatt[j])
			return -EBUSY;
		j++;
	}

	if (!mem->is_flushed) {
		global_cache_flush();
		mem->is_flushed = true;
	}

	for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
		unsigned long paddr;

		paddr = page_to_phys(mem->pages[i]);
		for (k = 0;
		     k < info->io_pages_per_kpage;
		     k++, j++, paddr += info->io_page_size) {
			info->gatt[j] = cpu_to_le64(
				parisc_agp_mask_memory(agp_bridge,
					paddr, type));
			asm_io_fdc(&info->gatt[j]);
		}
	}

	agp_bridge->driver->tlb_flush(mem);

	return 0;
}

static int
parisc_agp_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
{
	struct _parisc_agp_info *info = &parisc_agp_info;
	int i, io_pg_start, io_pg_count;

	if (type != mem->type ||
		agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) {
		return -EINVAL;
	}

	io_pg_start = info->io_pages_per_kpage * pg_start;
	io_pg_count = info->io_pages_per_kpage * mem->page_count;
	for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) {
		info->gatt[i] = cpu_to_le64(agp_bridge->scratch_page);
	}

	agp_bridge->driver->tlb_flush(mem);
	return 0;
}

static unsigned long
parisc_agp_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr,
		       int type)
{
	unsigned ci;			/* coherent index */
	dma_addr_t pa;

	pa = addr & IOVP_MASK;
	asm("lci 0(%1), %0" : "=r" (ci) : "r" (phys_to_virt(pa)));

	pa |= (ci >> PAGE_SHIFT) & 0xff;/* move CI (8 bits) into lowest byte */
	pa |= SBA_PDIR_VALID_BIT;	/* set "valid" bit */

	/* return native (big-endian) PDIR entry */
	return pa;
}

static void
parisc_agp_enable(struct agp_bridge_data *bridge, u32 mode)
{
	struct _parisc_agp_info *info = &parisc_agp_info;
	u32 command;

	command = readl(info->lba_regs + info->lba_cap_offset + PCI_AGP_STATUS);

	command = agp_collect_device_status(bridge, mode, command);
	command |= 0x00000100;

	writel(command, info->lba_regs + info->lba_cap_offset + PCI_AGP_COMMAND);

	agp_device_command(command, (mode & AGP8X_MODE) != 0);
}

static const struct agp_bridge_driver parisc_agp_driver = {
	.owner			= THIS_MODULE,
	.size_type		= FIXED_APER_SIZE,
	.configure		= parisc_agp_configure,
	.fetch_size		= parisc_agp_fetch_size,
	.tlb_flush		= parisc_agp_tlbflush,
	.mask_memory		= parisc_agp_mask_memory,
	.masks			= parisc_agp_masks,
	.agp_enable		= parisc_agp_enable,
	.cache_flush		= global_cache_flush,
	.create_gatt_table	= parisc_agp_create_gatt_table,
	.free_gatt_table	= parisc_agp_free_gatt_table,
	.insert_memory		= parisc_agp_insert_memory,
	.remove_memory		= parisc_agp_remove_memory,
	.alloc_by_type		= agp_generic_alloc_by_type,
	.free_by_type		= agp_generic_free_by_type,
	.agp_alloc_page		= agp_generic_alloc_page,
	.agp_alloc_pages	= agp_generic_alloc_pages,
	.agp_destroy_page	= agp_generic_destroy_page,
	.agp_destroy_pages	= agp_generic_destroy_pages,
	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
	.cant_use_aperture	= true,
};

static int __init
agp_ioc_init(void __iomem *ioc_regs)
{
	struct _parisc_agp_info *info = &parisc_agp_info;
        u64 iova_base, io_tlb_ps;
	__le64 *io_pdir;
        int io_tlb_shift;

        printk(KERN_INFO DRVPFX "IO PDIR shared with sba_iommu\n");

        info->ioc_regs = ioc_regs;

        io_tlb_ps = readq(info->ioc_regs+IOC_TCNFG);
        switch (io_tlb_ps) {
        case 0: io_tlb_shift = 12; break;
        case 1: io_tlb_shift = 13; break;
        case 2: io_tlb_shift = 14; break;
        case 3: io_tlb_shift = 16; break;
        default:
                printk(KERN_ERR DRVPFX "Invalid IOTLB page size "
                       "configuration 0x%llx\n", io_tlb_ps);
                info->gatt = NULL;
                info->gatt_entries = 0;
                return -ENODEV;
        }
        info->io_page_size = 1 << io_tlb_shift;
        info->io_pages_per_kpage = PAGE_SIZE / info->io_page_size;

        iova_base = readq(info->ioc_regs+IOC_IBASE) & ~0x1;
        info->gart_base = iova_base + PLUTO_IOVA_SIZE - PLUTO_GART_SIZE;

        info->gart_size = PLUTO_GART_SIZE;
        info->gatt_entries = info->gart_size / info->io_page_size;

        io_pdir = phys_to_virt(readq(info->ioc_regs+IOC_PDIR_BASE));
        info->gatt = &io_pdir[(PLUTO_IOVA_SIZE/2) >> PAGE_SHIFT];

        if (info->gatt[0] != SBA_AGPGART_COOKIE) {
                info->gatt = NULL;
                info->gatt_entries = 0;
                printk(KERN_ERR DRVPFX "No reserved IO PDIR entry found; "
                       "GART disabled\n");
                return -ENODEV;
        }

        return 0;
}

static int __init
lba_find_capability(int cap)
{
	struct _parisc_agp_info *info = &parisc_agp_info;
        u16 status;
        u8 pos, id;
        int ttl = 48;

        status = readw(info->lba_regs + PCI_STATUS);
        if (!(status & PCI_STATUS_CAP_LIST))
                return 0;
        pos = readb(info->lba_regs + PCI_CAPABILITY_LIST);
        while (ttl-- && pos >= 0x40) {
                pos &= ~3;
                id = readb(info->lba_regs + pos + PCI_CAP_LIST_ID);
                if (id == 0xff)
                        break;
                if (id == cap)
                        return pos;
                pos = readb(info->lba_regs + pos + PCI_CAP_LIST_NEXT);
        }
        return 0;
}

static int __init
agp_lba_init(void __iomem *lba_hpa)
{
	struct _parisc_agp_info *info = &parisc_agp_info;
        int cap;

	info->lba_regs = lba_hpa;
        info->lba_cap_offset = lba_find_capability(PCI_CAP_ID_AGP);

        cap = readl(lba_hpa + info->lba_cap_offset) & 0xff;
        if (cap != PCI_CAP_ID_AGP) {
                printk(KERN_ERR DRVPFX "Invalid capability ID 0x%02x at 0x%x\n",
                       cap, info->lba_cap_offset);
                return -ENODEV;
        }

        return 0;
}

static int __init
parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa)
{
	struct pci_dev *fake_bridge_dev = NULL;
	struct agp_bridge_data *bridge;
	int error = 0;

	fake_bridge_dev = pci_alloc_dev(NULL);
	if (!fake_bridge_dev) {
		error = -ENOMEM;
		goto fail;
	}

	error = agp_ioc_init(ioc_hpa);
	if (error)
		goto fail;

	error = agp_lba_init(lba_hpa);
	if (error)
		goto fail;

	bridge = agp_alloc_bridge();
	if (!bridge) {
		error = -ENOMEM;
		goto fail;
	}
	bridge->driver = &parisc_agp_driver;

	fake_bridge_dev->vendor = PCI_VENDOR_ID_HP;
	fake_bridge_dev->device = PCI_DEVICE_ID_HP_PCIX_LBA;
	bridge->dev = fake_bridge_dev;

	error = agp_add_bridge(bridge);
	if (error)
		goto fail;
	return 0;

fail:
	kfree(fake_bridge_dev);
	return error;
}

static int __init
find_quicksilver(struct device *dev, void *data)
{
	struct parisc_device **lba = data;
	struct parisc_device *padev = to_parisc_device(dev);

	if (IS_QUICKSILVER(padev))
		*lba = padev;

	return 0;
}

static int __init
parisc_agp_init(void)
{
	int err = -1;
	struct parisc_device *sba = NULL, *lba = NULL;
	struct lba_device *lbadev = NULL;

	if (!sba_list)
		goto out;

	/* Find our parent Pluto */
	sba = sba_list->dev;
	if (!IS_PLUTO(sba)) {
		printk(KERN_INFO DRVPFX "No Pluto found, so no AGPGART for you.\n");
		goto out;
	}

	/* Now search our Pluto for our precious AGP device... */
	device_for_each_child(&sba->dev, &lba, find_quicksilver);

	if (!lba) {
		printk(KERN_INFO DRVPFX "No AGP devices found.\n");
		goto out;
	}

	lbadev = parisc_get_drvdata(lba);

	/* w00t, let's go find our cookies... */
	parisc_agp_setup(sba_list->ioc[0].ioc_hpa, lbadev->hba.base_addr);

	return 0;

out:
	return err;
}

module_init(parisc_agp_init);

MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>");
MODULE_LICENSE("GPL");
