Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.2.
  1/*
  2 * This file is subject to the terms and conditions of the GNU General Public
  3 * License.  See the file "COPYING" in the main directory of this archive
  4 * for more details.
  5 *
  6 * Copyright (C) 2013 Cavium, Inc.
  7 */
  8
  9#include <linux/kernel.h>
 10#include <linux/init.h>
 11#include <linux/interrupt.h>
 12#include <linux/pci.h>
 13
 14#include <uapi/asm/bitfield.h>
 15#include <asm/byteorder.h>
 16#include <asm/io.h>
 17
 18#define PCI_CONFIG_ADDRESS	0xcf8
 19#define PCI_CONFIG_DATA		0xcfc
 20
 21union pci_config_address {
 22	struct {
 23		__BITFIELD_FIELD(unsigned enable_bit	  : 1,	/* 31       */
 24		__BITFIELD_FIELD(unsigned reserved	  : 7,	/* 30 .. 24 */
 25		__BITFIELD_FIELD(unsigned bus_number	  : 8,	/* 23 .. 16 */
 26		__BITFIELD_FIELD(unsigned devfn_number	  : 8,	/* 15 .. 8  */
 27		__BITFIELD_FIELD(unsigned register_number : 8,	/* 7  .. 0  */
 28		)))));
 29	};
 30	u32 w;
 31};
 32
 33int pcibios_plat_dev_init(struct pci_dev *dev)
 34{
 35	return 0;
 36}
 37
 38int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 39{
 40	return ((pin + slot) % 4)+ MIPS_IRQ_PCIA;
 41}
 42
 43static void pci_virtio_guest_write_config_addr(struct pci_bus *bus,
 44					unsigned int devfn, int reg)
 45{
 46	union pci_config_address pca = { .w = 0 };
 47
 48	pca.register_number = reg;
 49	pca.devfn_number = devfn;
 50	pca.bus_number = bus->number;
 51	pca.enable_bit = 1;
 52
 53	outl(pca.w, PCI_CONFIG_ADDRESS);
 54}
 55
 56static int pci_virtio_guest_write_config(struct pci_bus *bus,
 57		unsigned int devfn, int reg, int size, u32 val)
 58{
 59	pci_virtio_guest_write_config_addr(bus, devfn, reg);
 60
 61	switch (size) {
 62	case 1:
 63		outb(val, PCI_CONFIG_DATA + (reg & 3));
 64		break;
 65	case 2:
 66		outw(val, PCI_CONFIG_DATA + (reg & 2));
 67		break;
 68	case 4:
 69		outl(val, PCI_CONFIG_DATA);
 70		break;
 71	}
 72
 73	return PCIBIOS_SUCCESSFUL;
 74}
 75
 76static int pci_virtio_guest_read_config(struct pci_bus *bus, unsigned int devfn,
 77					int reg, int size, u32 *val)
 78{
 79	pci_virtio_guest_write_config_addr(bus, devfn, reg);
 80
 81	switch (size) {
 82	case 1:
 83		*val = inb(PCI_CONFIG_DATA + (reg & 3));
 84		break;
 85	case 2:
 86		*val = inw(PCI_CONFIG_DATA + (reg & 2));
 87		break;
 88	case 4:
 89		*val = inl(PCI_CONFIG_DATA);
 90		break;
 91	}
 92	return PCIBIOS_SUCCESSFUL;
 93}
 94
 95static struct pci_ops pci_virtio_guest_ops = {
 96	.read  = pci_virtio_guest_read_config,
 97	.write = pci_virtio_guest_write_config,
 98};
 99
100static struct resource pci_virtio_guest_mem_resource = {
101	.name = "Virtio MEM",
102	.flags = IORESOURCE_MEM,
103	.start	= 0x10000000,
104	.end	= 0x1dffffff
105};
106
107static struct resource pci_virtio_guest_io_resource = {
108	.name = "Virtio IO",
109	.flags = IORESOURCE_IO,
110	.start	= 0,
111	.end	= 0xffff
112};
113
114static struct pci_controller pci_virtio_guest_controller = {
115	.pci_ops = &pci_virtio_guest_ops,
116	.mem_resource = &pci_virtio_guest_mem_resource,
117	.io_resource = &pci_virtio_guest_io_resource,
118};
119
120static int __init pci_virtio_guest_setup(void)
121{
122	pr_err("pci_virtio_guest_setup\n");
123
124	/* Virtio comes pre-assigned */
125	pci_set_flags(PCI_PROBE_ONLY);
126
127	pci_virtio_guest_controller.io_map_base = mips_io_port_base;
128	register_pci_controller(&pci_virtio_guest_controller);
129	return 0;
130}
131arch_initcall(pci_virtio_guest_setup);