Commit f0a08fcb authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile

Pull arch/tile updates from Chris Metcalf:
 "These changes provide support for PCIe root complex and USB host mode
  for tilegx's on-chip I/Os.

  In addition, this pull provides the required underpinning for the
  on-chip networking support that was pulled into 3.5.  The changes have
  all been through LKML (with several rounds for PCIe RC) and on
  linux-next."

* git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile:
  tile: updates to pci root complex from community feedback
  bounce: allow use of bounce pool via config option
  usb: add host support for the tilegx architecture
  arch/tile: provide kernel support for the tilegx USB shim
  tile pci: enable IOMMU to support DMA for legacy devices
  arch/tile: enable ZONE_DMA for tilegx
  tilegx pci: support I/O to arbitrarily-cached pages
  tile: remove unused header
  arch/tile: tilegx PCI root complex support
  arch/tile: provide kernel support for the tilegx TRIO shim
  arch/tile: break out the "csum a long" function to <asm/checksum.h>
  arch/tile: provide kernel support for the tilegx mPIPE shim
  arch/tile: common DMA code for the GXIO IORPC subsystem
  arch/tile: support MMIO-based readb/writeb etc.
  arch/tile: introduce GXIO IORPC framework for tilegx
parents 474183b1 f6d2ce00
......@@ -3,6 +3,8 @@
config TILE
def_bool y
select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
select HAVE_KVM if !TILEGX
select GENERIC_FIND_FIRST_BIT
select USE_GENERIC_SMP_HELPERS
......@@ -79,6 +81,9 @@ config ARCH_DMA_ADDR_T_64BIT
config NEED_DMA_MAP_STATE
def_bool y
config ARCH_HAS_DMA_SET_COHERENT_MASK
bool
config LOCKDEP_SUPPORT
def_bool y
......@@ -212,6 +217,22 @@ config HIGHMEM
If unsure, say "true".
config ZONE_DMA
def_bool y
config IOMMU_HELPER
bool
config NEED_SG_DMA_LENGTH
bool
config SWIOTLB
bool
default TILEGX
select IOMMU_HELPER
select NEED_SG_DMA_LENGTH
select ARCH_HAS_DMA_SET_COHERENT_MASK
# We do not currently support disabling NUMA.
config NUMA
bool # "NUMA Memory Allocation and Scheduler Support"
......@@ -345,6 +366,8 @@ config KERNEL_PL
kernel will be built to run at. Generally you should use
the default value here.
source "arch/tile/gxio/Kconfig"
endmenu # Tilera-specific configuration
menu "Bus options"
......@@ -354,6 +377,9 @@ config PCI
default y
select PCI_DOMAINS
select GENERIC_PCI_IOMAP
select TILE_GXIO_TRIO if TILEGX
select ARCH_SUPPORTS_MSI if TILEGX
select PCI_MSI if TILEGX
---help---
Enable PCI root complex support, so PCIe endpoint devices can
be attached to the Tile chip. Many, but not all, PCI devices
......@@ -370,6 +396,22 @@ config NO_IOPORT
source "drivers/pci/Kconfig"
config TILE_USB
tristate "Tilera USB host adapter support"
default y
depends on USB
depends on TILEGX
select TILE_GXIO_USB_HOST
---help---
Provides USB host adapter support for the built-in EHCI and OHCI
interfaces on TILE-Gx chips.
# USB OHCI needs the bounce pool since tilegx will often have more
# than 4GB of memory, but we don't currently use the IOTLB to present
# a 32-bit address to OHCI. So we need to use a bounce pool instead.
config NEED_BOUNCE_POOL
def_bool USB_OHCI_HCD
config HOTPLUG
bool "Support for hot-pluggable devices"
---help---
......
......@@ -59,6 +59,8 @@ libs-y += $(LIBGCC_PATH)
# See arch/tile/Kbuild for content of core part of the kernel
core-y += arch/tile/
core-$(CONFIG_TILE_GXIO) += arch/tile/gxio/
ifdef TILERA_ROOT
INSTALL_PATH ?= $(TILERA_ROOT)/tile/boot
endif
......
# Support direct access to TILE-Gx hardware from user space, via the
# gxio library, or from kernel space, via kernel IORPC support.
config TILE_GXIO
bool
depends on TILEGX
# Support direct access to the common I/O DMA facility within the
# TILE-Gx mPIPE and Trio hardware from kernel space.
config TILE_GXIO_DMA
bool
select TILE_GXIO
# Support direct access to the TILE-Gx mPIPE hardware from kernel space.
config TILE_GXIO_MPIPE
bool
select TILE_GXIO
select TILE_GXIO_DMA
# Support direct access to the TILE-Gx TRIO hardware from kernel space.
config TILE_GXIO_TRIO
bool
select TILE_GXIO
select TILE_GXIO_DMA
# Support direct access to the TILE-Gx USB hardware from kernel space.
config TILE_GXIO_USB_HOST
bool
select TILE_GXIO
#
# Makefile for the Tile-Gx device access support.
#
obj-$(CONFIG_TILE_GXIO) += iorpc_globals.o kiorpc.o
obj-$(CONFIG_TILE_GXIO_DMA) += dma_queue.o
obj-$(CONFIG_TILE_GXIO_MPIPE) += mpipe.o iorpc_mpipe.o iorpc_mpipe_info.o
obj-$(CONFIG_TILE_GXIO_TRIO) += trio.o iorpc_trio.o
obj-$(CONFIG_TILE_GXIO_USB_HOST) += usb_host.o iorpc_usb_host.o
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#include <linux/io.h>
#include <linux/atomic.h>
#include <linux/module.h>
#include <gxio/dma_queue.h>
/* Wait for a memory read to complete. */
#define wait_for_value(val) \
__asm__ __volatile__("move %0, %0" :: "r"(val))
/* The index is in the low 16. */
#define DMA_QUEUE_INDEX_MASK ((1 << 16) - 1)
/*
* The hardware descriptor-ring type.
* This matches the types used by mpipe (MPIPE_EDMA_POST_REGION_VAL_t)
* and trio (TRIO_PUSH_DMA_REGION_VAL_t or TRIO_PULL_DMA_REGION_VAL_t).
* See those types for more documentation on the individual fields.
*/
typedef union {
struct {
#ifndef __BIG_ENDIAN__
uint64_t ring_idx:16;
uint64_t count:16;
uint64_t gen:1;
uint64_t __reserved:31;
#else
uint64_t __reserved:31;
uint64_t gen:1;
uint64_t count:16;
uint64_t ring_idx:16;
#endif
};
uint64_t word;
} __gxio_ring_t;
void __gxio_dma_queue_init(__gxio_dma_queue_t *dma_queue,
void *post_region_addr, unsigned int num_entries)
{
/*
* Limit 65536 entry rings to 65535 credits because we only have a
* 16 bit completion counter.
*/
int64_t credits = (num_entries < 65536) ? num_entries : 65535;
memset(dma_queue, 0, sizeof(*dma_queue));
dma_queue->post_region_addr = post_region_addr;
dma_queue->hw_complete_count = 0;
dma_queue->credits_and_next_index = credits << DMA_QUEUE_CREDIT_SHIFT;
}
EXPORT_SYMBOL_GPL(__gxio_dma_queue_init);
void __gxio_dma_queue_update_credits(__gxio_dma_queue_t *dma_queue)
{
__gxio_ring_t val;
uint64_t count;
uint64_t delta;
uint64_t new_count;
/*
* Read the 64-bit completion count without touching the cache, so
* we later avoid having to evict any sharers of this cache line
* when we update it below.
*/
uint64_t orig_hw_complete_count =
cmpxchg(&dma_queue->hw_complete_count,
-1, -1);
/* Make sure the load completes before we access the hardware. */
wait_for_value(orig_hw_complete_count);
/* Read the 16-bit count of how many packets it has completed. */
val.word = __gxio_mmio_read(dma_queue->post_region_addr);
count = val.count;
/*
* Calculate the number of completions since we last updated the
* 64-bit counter. It's safe to ignore the high bits because the
* maximum credit value is 65535.
*/
delta = (count - orig_hw_complete_count) & 0xffff;
if (delta == 0)
return;
/*
* Try to write back the count, advanced by delta. If we race with
* another thread, this might fail, in which case we return
* immediately on the assumption that some credits are (or at least
* were) available.
*/
new_count = orig_hw_complete_count + delta;
if (cmpxchg(&dma_queue->hw_complete_count,
orig_hw_complete_count,
new_count) != orig_hw_complete_count)
return;
/*
* We succeeded in advancing the completion count; add back the
* corresponding number of egress credits.
*/
__insn_fetchadd(&dma_queue->credits_and_next_index,
(delta << DMA_QUEUE_CREDIT_SHIFT));
}
EXPORT_SYMBOL_GPL(__gxio_dma_queue_update_credits);
/*
* A separate 'blocked' method for put() so that backtraces and
* profiles will clearly indicate that we're wasting time spinning on
* egress availability rather than actually posting commands.
*/
int64_t __gxio_dma_queue_wait_for_credits(__gxio_dma_queue_t *dma_queue,
int64_t modifier)
{
int backoff = 16;
int64_t old;
do {
int i;
/* Back off to avoid spamming memory networks. */
for (i = backoff; i > 0; i--)
__insn_mfspr(SPR_PASS);
/* Check credits again. */
__gxio_dma_queue_update_credits(dma_queue);
old = __insn_fetchaddgez(&dma_queue->credits_and_next_index,
modifier);
/* Calculate bounded exponential backoff for next iteration. */
if (backoff < 256)
backoff *= 2;
} while (old + modifier < 0);
return old;
}
EXPORT_SYMBOL_GPL(__gxio_dma_queue_wait_for_credits);
int64_t __gxio_dma_queue_reserve_aux(__gxio_dma_queue_t *dma_queue,
unsigned int num, int wait)
{
return __gxio_dma_queue_reserve(dma_queue, num, wait != 0, true);
}
EXPORT_SYMBOL_GPL(__gxio_dma_queue_reserve_aux);
int __gxio_dma_queue_is_complete(__gxio_dma_queue_t *dma_queue,
int64_t completion_slot, int update)
{
if (update) {
if (ACCESS_ONCE(dma_queue->hw_complete_count) >
completion_slot)
return 1;
__gxio_dma_queue_update_credits(dma_queue);
}
return ACCESS_ONCE(dma_queue->hw_complete_count) > completion_slot;
}
EXPORT_SYMBOL_GPL(__gxio_dma_queue_is_complete);
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#include "gxio/iorpc_globals.h"
struct arm_pollfd_param {
union iorpc_pollfd pollfd;
};
int __iorpc_arm_pollfd(int fd, int pollfd_cookie)
{
struct arm_pollfd_param temp;
struct arm_pollfd_param *params = &temp;
params->pollfd.kernel.cookie = pollfd_cookie;
return hv_dev_pwrite(fd, 0, (HV_VirtAddr) params, sizeof(*params),
IORPC_OP_ARM_POLLFD);
}
EXPORT_SYMBOL(__iorpc_arm_pollfd);
struct close_pollfd_param {
union iorpc_pollfd pollfd;
};
int __iorpc_close_pollfd(int fd, int pollfd_cookie)
{
struct close_pollfd_param temp;
struct close_pollfd_param *params = &temp;
params->pollfd.kernel.cookie = pollfd_cookie;
return hv_dev_pwrite(fd, 0, (HV_VirtAddr) params, sizeof(*params),
IORPC_OP_CLOSE_POLLFD);
}
EXPORT_SYMBOL(__iorpc_close_pollfd);
struct get_mmio_base_param {
HV_PTE base;
};
int __iorpc_get_mmio_base(int fd, HV_PTE *base)
{
int __result;
struct get_mmio_base_param temp;
struct get_mmio_base_param *params = &temp;
__result =
hv_dev_pread(fd, 0, (HV_VirtAddr) params, sizeof(*params),
IORPC_OP_GET_MMIO_BASE);
*base = params->base;
return __result;
}
EXPORT_SYMBOL(__iorpc_get_mmio_base);
struct check_mmio_offset_param {
unsigned long offset;
unsigned long size;
};
int __iorpc_check_mmio_offset(int fd, unsigned long offset, unsigned long size)
{
struct check_mmio_offset_param temp;
struct check_mmio_offset_param *params = &temp;
params->offset = offset;
params->size = size;
return hv_dev_pwrite(fd, 0, (HV_VirtAddr) params, sizeof(*params),
IORPC_OP_CHECK_MMIO_OFFSET);
}
EXPORT_SYMBOL(__iorpc_check_mmio_offset);
This diff is collapsed.
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#include "gxio/iorpc_mpipe_info.h"
struct enumerate_aux_param {
_gxio_mpipe_link_name_t name;
_gxio_mpipe_link_mac_t mac;
};
int gxio_mpipe_info_enumerate_aux(gxio_mpipe_info_context_t * context,
unsigned int idx,
_gxio_mpipe_link_name_t * name,
_gxio_mpipe_link_mac_t * mac)
{
int __result;
struct enumerate_aux_param temp;
struct enumerate_aux_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
(((uint64_t) idx << 32) |
GXIO_MPIPE_INFO_OP_ENUMERATE_AUX));
*name = params->name;
*mac = params->mac;
return __result;
}
EXPORT_SYMBOL(gxio_mpipe_info_enumerate_aux);
struct get_mmio_base_param {
HV_PTE base;
};
int gxio_mpipe_info_get_mmio_base(gxio_mpipe_info_context_t * context,
HV_PTE *base)
{
int __result;
struct get_mmio_base_param temp;
struct get_mmio_base_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
GXIO_MPIPE_INFO_OP_GET_MMIO_BASE);
*base = params->base;
return __result;
}
EXPORT_SYMBOL(gxio_mpipe_info_get_mmio_base);
struct check_mmio_offset_param {
unsigned long offset;
unsigned long size;
};
int gxio_mpipe_info_check_mmio_offset(gxio_mpipe_info_context_t * context,
unsigned long offset, unsigned long size)
{
struct check_mmio_offset_param temp;
struct check_mmio_offset_param *params = &temp;
params->offset = offset;
params->size = size;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_INFO_OP_CHECK_MMIO_OFFSET);
}
EXPORT_SYMBOL(gxio_mpipe_info_check_mmio_offset);
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#include "gxio/iorpc_trio.h"
struct alloc_asids_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_trio_alloc_asids(gxio_trio_context_t * context, unsigned int count,
unsigned int first, unsigned int flags)
{
struct alloc_asids_param temp;
struct alloc_asids_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_ALLOC_ASIDS);
}
EXPORT_SYMBOL(gxio_trio_alloc_asids);
struct alloc_memory_maps_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_trio_alloc_memory_maps(gxio_trio_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags)
{
struct alloc_memory_maps_param temp;
struct alloc_memory_maps_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_ALLOC_MEMORY_MAPS);
}
EXPORT_SYMBOL(gxio_trio_alloc_memory_maps);
struct alloc_pio_regions_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_trio_alloc_pio_regions(gxio_trio_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags)
{
struct alloc_pio_regions_param temp;
struct alloc_pio_regions_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_ALLOC_PIO_REGIONS);
}
EXPORT_SYMBOL(gxio_trio_alloc_pio_regions);
struct init_pio_region_aux_param {
unsigned int pio_region;
unsigned int mac;
uint32_t bus_address_hi;
unsigned int flags;
};
int gxio_trio_init_pio_region_aux(gxio_trio_context_t * context,
unsigned int pio_region, unsigned int mac,
uint32_t bus_address_hi, unsigned int flags)
{
struct init_pio_region_aux_param temp;
struct init_pio_region_aux_param *params = &temp;
params->pio_region = pio_region;
params->mac = mac;
params->bus_address_hi = bus_address_hi;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_INIT_PIO_REGION_AUX);
}
EXPORT_SYMBOL(gxio_trio_init_pio_region_aux);
struct init_memory_map_mmu_aux_param {
unsigned int map;
unsigned long va;
uint64_t size;
unsigned int asid;
unsigned int mac;
uint64_t bus_address;
unsigned int node;
unsigned int order_mode;
};
int gxio_trio_init_memory_map_mmu_aux(gxio_trio_context_t * context,
unsigned int map, unsigned long va,
uint64_t size, unsigned int asid,
unsigned int mac, uint64_t bus_address,
unsigned int node,
unsigned int order_mode)
{
struct init_memory_map_mmu_aux_param temp;
struct init_memory_map_mmu_aux_param *params = &temp;
params->map = map;
params->va = va;
params->size = size;
params->asid = asid;
params->mac = mac;
params->bus_address = bus_address;
params->node = node;
params->order_mode = order_mode;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_TRIO_OP_INIT_MEMORY_MAP_MMU_AUX);
}
EXPORT_SYMBOL(gxio_trio_init_memory_map_mmu_aux);
struct get_port_property_param {
struct pcie_trio_ports_property trio_ports;
};
int gxio_trio_get_port_property(gxio_trio_context_t * context,
struct pcie_trio_ports_property *trio_ports)
{
int __result;
struct get_port_property_param temp;
struct get_port_property_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
GXIO_TRIO_OP_GET_PORT_PROPERTY);
*trio_ports = params->trio_ports;
return __result;
}
EXPORT_SYMBOL(gxio_trio_get_port_property);
struct config_legacy_intr_param {
union iorpc_interrupt interrupt;
unsigned int mac;
unsigned int intx;
};
int gxio_trio_config_legacy_intr(gxio_trio_context_t * context, int inter_x,
int inter_y, int inter_ipi, int inter_event,
unsigned int mac, unsigned int intx)
{
struct config_legacy_intr_param temp;
struct config_legacy_intr_param *params = &temp;
params->interrupt.kernel.x = inter_x;
params->interrupt.kernel.y = inter_y;
params->interrupt.kernel.ipi = inter_ipi;
params->interrupt.kernel.event = inter_event;
params->mac = mac;
params->intx = intx;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_CONFIG_LEGACY_INTR);
}
EXPORT_SYMBOL(gxio_trio_config_legacy_intr);
struct config_msi_intr_param {
union iorpc_interrupt interrupt;
unsigned int mac;
unsigned int mem_map;
uint64_t mem_map_base;
uint64_t mem_map_limit;
unsigned int asid;
};
int gxio_trio_config_msi_intr(gxio_trio_context_t * context, int inter_x,
int inter_y, int inter_ipi, int inter_event,
unsigned int mac, unsigned int mem_map,
uint64_t mem_map_base, uint64_t mem_map_limit,
unsigned int asid)
{
struct config_msi_intr_param temp;
struct config_msi_intr_param *params = &temp;
params->interrupt.kernel.x = inter_x;
params->interrupt.kernel.y = inter_y;
params->interrupt.kernel.ipi = inter_ipi;
params->interrupt.kernel.event = inter_event;
params->mac = mac;
params->mem_map = mem_map;
params->mem_map_base = mem_map_base;
params->mem_map_limit = mem_map_limit;
params->asid = asid;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_CONFIG_MSI_INTR);
}
EXPORT_SYMBOL(gxio_trio_config_msi_intr);
struct set_mps_mrs_param {
uint16_t mps;
uint16_t mrs;
unsigned int mac;
};
int gxio_trio_set_mps_mrs(gxio_trio_context_t * context, uint16_t mps,
uint16_t mrs, unsigned int mac)
{
struct set_mps_mrs_param temp;
struct set_mps_mrs_param *params = &temp;
params->mps = mps;
params->mrs = mrs;
params->mac = mac;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_SET_MPS_MRS);
}
EXPORT_SYMBOL(gxio_trio_set_mps_mrs);
struct force_rc_link_up_param {
unsigned int mac;
};
int gxio_trio_force_rc_link_up(gxio_trio_context_t * context, unsigned int mac)
{
struct force_rc_link_up_param temp;
struct force_rc_link_up_param *params = &temp;
params->mac = mac;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_FORCE_RC_LINK_UP);
}
EXPORT_SYMBOL(gxio_trio_force_rc_link_up);
struct force_ep_link_up_param {
unsigned int mac;
};
int gxio_trio_force_ep_link_up(gxio_trio_context_t * context, unsigned int mac)
{
struct force_ep_link_up_param temp;
struct force_ep_link_up_param *params = &temp;
params->mac = mac;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_FORCE_EP_LINK_UP);
}
EXPORT_SYMBOL(gxio_trio_force_ep_link_up);
struct get_mmio_base_param {
HV_PTE base;
};
int gxio_trio_get_mmio_base(gxio_trio_context_t * context, HV_PTE *base)
{
int __result;
struct get_mmio_base_param temp;
struct get_mmio_base_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
GXIO_TRIO_OP_GET_MMIO_BASE);
*base = params->base;
return __result;
}
EXPORT_SYMBOL(gxio_trio_get_mmio_base);
struct check_mmio_offset_param {
unsigned long offset;
unsigned long size;
};
int gxio_trio_check_mmio_offset(gxio_trio_context_t * context,
unsigned long offset, unsigned long size)
{
struct check_mmio_offset_param temp;
struct check_mmio_offset_param *params = &temp;
params->offset = offset;
params->size = size;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_CHECK_MMIO_OFFSET);
}
EXPORT_SYMBOL(gxio_trio_check_mmio_offset);
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#include "gxio/iorpc_usb_host.h"
struct cfg_interrupt_param {
union iorpc_interrupt interrupt;
};
int gxio_usb_host_cfg_interrupt(gxio_usb_host_context_t * context, int inter_x,
int inter_y, int inter_ipi, int inter_event)
{
struct cfg_interrupt_param temp;
struct cfg_interrupt_param *params = &temp;
params->interrupt.kernel.x = inter_x;
params->interrupt.kernel.y = inter_y;
params->interrupt.kernel.ipi = inter_ipi;
params->interrupt.kernel.event = inter_event;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_USB_HOST_OP_CFG_INTERRUPT);
}
EXPORT_SYMBOL(gxio_usb_host_cfg_interrupt);
struct register_client_memory_param {
HV_PTE pte;
unsigned int flags;
};
int gxio_usb_host_register_client_memory(gxio_usb_host_context_t * context,
HV_PTE pte, unsigned int flags)
{
struct register_client_memory_param temp;
struct register_client_memory_param *params = &temp;
params->pte = pte;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_USB_HOST_OP_REGISTER_CLIENT_MEMORY);
}
EXPORT_SYMBOL(gxio_usb_host_register_client_memory);
struct get_mmio_base_param {
HV_PTE base;
};
int gxio_usb_host_get_mmio_base(gxio_usb_host_context_t * context, HV_PTE *base)
{
int __result;
struct get_mmio_base_param temp;
struct get_mmio_base_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
GXIO_USB_HOST_OP_GET_MMIO_BASE);
*base = params->base;
return __result;
}
EXPORT_SYMBOL(gxio_usb_host_get_mmio_base);
struct check_mmio_offset_param {
unsigned long offset;
unsigned long size;
};
int gxio_usb_host_check_mmio_offset(gxio_usb_host_context_t * context,
unsigned long offset, unsigned long size)
{
struct check_mmio_offset_param temp;
struct check_mmio_offset_param *params = &temp;
params->offset = offset;
params->size = size;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_USB_HOST_OP_CHECK_MMIO_OFFSET);
}
EXPORT_SYMBOL(gxio_usb_host_check_mmio_offset);
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*
* TILE-Gx IORPC support for kernel I/O drivers.
*/
#include <linux/mmzone.h>
#include <linux/module.h>
#include <linux/io.h>
#include <gxio/iorpc_globals.h>
#include <gxio/kiorpc.h>
#ifdef DEBUG_IORPC
#define TRACE(FMT, ...) pr_info(SIMPLE_MSG_LINE FMT, ## __VA_ARGS__)
#else
#define TRACE(...)
#endif
/* Create kernel-VA-space MMIO mapping for an on-chip IO device. */
void __iomem *iorpc_ioremap(int hv_fd, resource_size_t offset,
unsigned long size)
{
pgprot_t mmio_base, prot = { 0 };
unsigned long pfn;
int err;
/* Look up the shim's lotar and base PA. */
err = __iorpc_get_mmio_base(hv_fd, &mmio_base);
if (err) {
TRACE("get_mmio_base() failure: %d\n", err);
return NULL;
}
/* Make sure the HV driver approves of our offset and size. */
err = __iorpc_check_mmio_offset(hv_fd, offset, size);
if (err) {
TRACE("check_mmio_offset() failure: %d\n", err);
return NULL;
}
/*
* mmio_base contains a base pfn and homing coordinates. Turn
* it into an MMIO pgprot and offset pfn.
*/
prot = hv_pte_set_lotar(prot, hv_pte_get_lotar(mmio_base));
pfn = pte_pfn(mmio_base) + PFN_DOWN(offset);
return ioremap_prot(PFN_PHYS(pfn), size, prot);
}
EXPORT_SYMBOL(iorpc_ioremap);
This diff is collapsed.
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/*
* Implementation of trio gxio calls.
*/
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/module.h>
#include <gxio/trio.h>
#include <gxio/iorpc_globals.h>
#include <gxio/iorpc_trio.h>
#include <gxio/kiorpc.h>
int gxio_trio_init(gxio_trio_context_t *context, unsigned int trio_index)
{
char file[32];
int fd;
snprintf(file, sizeof(file), "trio/%d/iorpc", trio_index);
fd = hv_dev_open((HV_VirtAddr) file, 0);
if (fd < 0) {
context->fd = -1;
if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX)
return fd;
else
return -ENODEV;
}
context->fd = fd;
return 0;
}
EXPORT_SYMBOL_GPL(gxio_trio_init);
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/*
*
* Implementation of USB gxio calls.
*/
#include <linux/io.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <gxio/iorpc_globals.h>
#include <gxio/iorpc_usb_host.h>
#include <gxio/kiorpc.h>
#include <gxio/usb_host.h>
int gxio_usb_host_init(gxio_usb_host_context_t * context, int usb_index,
int is_ehci)
{
char file[32];
int fd;
if (is_ehci)
snprintf(file, sizeof(file), "usb_host/%d/iorpc/ehci",
usb_index);
else
snprintf(file, sizeof(file), "usb_host/%d/iorpc/ohci",
usb_index);
fd = hv_dev_open((HV_VirtAddr) file, 0);
if (fd < 0) {
if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX)
return fd;
else
return -ENODEV;
}
context->fd = fd;
// Map in the MMIO space.
context->mmio_base =
(void __force *)iorpc_ioremap(fd, 0, HV_USB_HOST_MMIO_SIZE);
if (context->mmio_base == NULL) {
hv_dev_close(context->fd);
return -ENODEV;
}
return 0;
}
EXPORT_SYMBOL_GPL(gxio_usb_host_init);
int gxio_usb_host_destroy(gxio_usb_host_context_t * context)
{
iounmap((void __force __iomem *)(context->mmio_base));
hv_dev_close(context->fd);
context->mmio_base = NULL;
context->fd = -1;
return 0;
}
EXPORT_SYMBOL_GPL(gxio_usb_host_destroy);
void *gxio_usb_host_get_reg_start(gxio_usb_host_context_t * context)
{
return context->mmio_base;
}
EXPORT_SYMBOL_GPL(gxio_usb_host_get_reg_start);
size_t gxio_usb_host_get_reg_len(gxio_usb_host_context_t * context)
{
return HV_USB_HOST_MMIO_SIZE;
}
EXPORT_SYMBOL_GPL(gxio_usb_host_get_reg_len);
This diff is collapsed.
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#ifndef __ARCH_MPIPE_CONSTANTS_H__
#define __ARCH_MPIPE_CONSTANTS_H__
#define MPIPE_NUM_CLASSIFIERS 10
#define MPIPE_CLS_MHZ 1200
#define MPIPE_NUM_EDMA_RINGS 32
#define MPIPE_NUM_SGMII_MACS 16
#define MPIPE_NUM_XAUI_MACS 4
#define MPIPE_NUM_LOOPBACK_CHANNELS 4
#define MPIPE_NUM_NON_LB_CHANNELS 28
#define MPIPE_NUM_IPKT_BLOCKS 1536
#define MPIPE_NUM_BUCKETS 4160
#define MPIPE_NUM_NOTIF_RINGS 256
#define MPIPE_NUM_NOTIF_GROUPS 32
#define MPIPE_NUM_TLBS_PER_ASID 16
#define MPIPE_TLB_IDX_WIDTH 4
#define MPIPE_MMIO_NUM_SVC_DOM 32
#endif /* __ARCH_MPIPE_CONSTANTS_H__ */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_MPIPE_DEF_H__
#define __ARCH_MPIPE_DEF_H__
#define MPIPE_MMIO_ADDR__REGION_SHIFT 26
#define MPIPE_MMIO_ADDR__REGION_VAL_CFG 0x0
#define MPIPE_MMIO_ADDR__REGION_VAL_IDMA 0x4
#define MPIPE_MMIO_ADDR__REGION_VAL_EDMA 0x5
#define MPIPE_MMIO_ADDR__REGION_VAL_BSM 0x6
#define MPIPE_BSM_REGION_VAL__VA_SHIFT 7
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_128 0x0
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_256 0x1
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_512 0x2
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_1024 0x3
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_1664 0x4
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_4096 0x5
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_10368 0x6
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_16384 0x7
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_DFA 0x0
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_FIXED 0x1
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_ALWAYS_PICK 0x2
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_STICKY 0x3
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_STICKY_RAND 0x7
#define MPIPE_LBL_NR_STATE__FIRST_WORD 0x2138
#endif /* !defined(__ARCH_MPIPE_DEF_H__) */
This diff is collapsed.
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_MPIPE_SHM_DEF_H__
#define __ARCH_MPIPE_SHM_DEF_H__
#define MPIPE_EDMA_DESC_WORD1__C_VAL_UNCHAINED 0x0
#define MPIPE_EDMA_DESC_WORD1__C_VAL_CHAINED 0x1
#define MPIPE_EDMA_DESC_WORD1__C_VAL_NOT_RDY 0x2
#define MPIPE_EDMA_DESC_WORD1__C_VAL_INVALID 0x3
#endif /* !defined(__ARCH_MPIPE_SHM_DEF_H__) */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_H__
#define __ARCH_TRIO_H__
#include <arch/abi.h>
#include <arch/trio_def.h>
#ifndef __ASSEMBLER__
/*
* Tile PIO Region Configuration - CFG Address Format.
* This register describes the address format for PIO accesses when the
* associated region is setup with TYPE=CFG.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* Register Address (full byte address). */
uint_reg_t reg_addr : 12;
/* Function Number */
uint_reg_t fn : 3;
/* Device Number */
uint_reg_t dev : 5;
/* BUS Number */
uint_reg_t bus : 8;
/* Config Type: 0 for access to directly-attached device. 1 otherwise. */
uint_reg_t type : 1;
/* Reserved. */
uint_reg_t __reserved_0 : 1;
/*
* MAC select. This must match the configuration in
* TILE_PIO_REGION_SETUP.MAC.
*/
uint_reg_t mac : 2;
/* Reserved. */
uint_reg_t __reserved_1 : 32;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_1 : 32;
uint_reg_t mac : 2;
uint_reg_t __reserved_0 : 1;
uint_reg_t type : 1;
uint_reg_t bus : 8;
uint_reg_t dev : 5;
uint_reg_t fn : 3;
uint_reg_t reg_addr : 12;
#endif
};
uint_reg_t word;
} TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR_t;
#endif /* !defined(__ASSEMBLER__) */
#endif /* !defined(__ARCH_TRIO_H__) */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#ifndef __ARCH_TRIO_CONSTANTS_H__
#define __ARCH_TRIO_CONSTANTS_H__
#define TRIO_NUM_ASIDS 16
#define TRIO_NUM_TLBS_PER_ASID 16
#define TRIO_NUM_TPIO_REGIONS 8
#define TRIO_LOG2_NUM_TPIO_REGIONS 3
#define TRIO_NUM_MAP_MEM_REGIONS 16
#define TRIO_LOG2_NUM_MAP_MEM_REGIONS 4
#define TRIO_NUM_MAP_SQ_REGIONS 8
#define TRIO_LOG2_NUM_MAP_SQ_REGIONS 3
#define TRIO_LOG2_NUM_SQ_FIFO_ENTRIES 6
#define TRIO_NUM_PUSH_DMA_RINGS 32
#define TRIO_NUM_PULL_DMA_RINGS 32
#endif /* __ARCH_TRIO_CONSTANTS_H__ */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_DEF_H__
#define __ARCH_TRIO_DEF_H__
#define TRIO_CFG_REGION_ADDR__REG_SHIFT 0
#define TRIO_CFG_REGION_ADDR__INTFC_SHIFT 16
#define TRIO_CFG_REGION_ADDR__INTFC_VAL_TRIO 0x0
#define TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_INTERFACE 0x1
#define TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_STANDARD 0x2
#define TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_PROTECTED 0x3
#define TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT 18
#define TRIO_CFG_REGION_ADDR__PROT_SHIFT 20
#define TRIO_PIO_REGIONS_ADDR__REGION_SHIFT 32
#define TRIO_MAP_MEM_REG_INT0 0x1000000000
#define TRIO_MAP_MEM_REG_INT1 0x1000000008
#define TRIO_MAP_MEM_REG_INT2 0x1000000010
#define TRIO_MAP_MEM_REG_INT3 0x1000000018
#define TRIO_MAP_MEM_REG_INT4 0x1000000020
#define TRIO_MAP_MEM_REG_INT5 0x1000000028
#define TRIO_MAP_MEM_REG_INT6 0x1000000030
#define TRIO_MAP_MEM_REG_INT7 0x1000000038
#define TRIO_MAP_MEM_LIM__ADDR_SHIFT 12
#define TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_UNORDERED 0x0
#define TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_STRICT 0x1
#define TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_REL_ORD 0x2
#define TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT 30
#endif /* !defined(__ARCH_TRIO_DEF_H__) */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_PCIE_INTFC_H__
#define __ARCH_TRIO_PCIE_INTFC_H__
#include <arch/abi.h>
#include <arch/trio_pcie_intfc_def.h>
#ifndef __ASSEMBLER__
/*
* Port Configuration.
* Configuration of the PCIe Port
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* Provides the state of the strapping pins for this port. */
uint_reg_t strap_state : 3;
/* Reserved. */
uint_reg_t __reserved_0 : 1;
/*
* When 1, the device type will be overridden using OVD_DEV_TYPE_VAL.
* When 0, the device type is determined based on the STRAP_STATE.
*/
uint_reg_t ovd_dev_type : 1;
/* Provides the device type when OVD_DEV_TYPE is 1. */
uint_reg_t ovd_dev_type_val : 4;
/* Determines how link is trained. */
uint_reg_t train_mode : 2;
/* Reserved. */
uint_reg_t __reserved_1 : 1;
/*
* For PCIe, used to flip physical RX lanes that were not properly wired.
* This is not the same as lane reversal which is handled automatically
* during link training. When 0, RX Lane0 must be wired to the link
* partner (either to its Lane0 or it's LaneN). When RX_LANE_FLIP is 1,
* the highest numbered lane for this port becomes Lane0 and Lane0 does
* NOT have to be wired to the link partner.
*/
uint_reg_t rx_lane_flip : 1;
/*
* For PCIe, used to flip physical TX lanes that were not properly wired.
* This is not the same as lane reversal which is handled automatically
* during link training. When 0, TX Lane0 must be wired to the link
* partner (either to its Lane0 or it's LaneN). When TX_LANE_FLIP is 1,
* the highest numbered lane for this port becomes Lane0 and Lane0 does
* NOT have to be wired to the link partner.
*/
uint_reg_t tx_lane_flip : 1;
/*
* For StreamIO port, configures the width of the port when TRAIN_MODE is
* not STRAP.
*/
uint_reg_t stream_width : 2;
/*
* For StreamIO port, configures the rate of the port when TRAIN_MODE is
* not STRAP.
*/
uint_reg_t stream_rate : 2;
/* Reserved. */
uint_reg_t __reserved_2 : 46;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_2 : 46;
uint_reg_t stream_rate : 2;
uint_reg_t stream_width : 2;
uint_reg_t tx_lane_flip : 1;
uint_reg_t rx_lane_flip : 1;
uint_reg_t __reserved_1 : 1;
uint_reg_t train_mode : 2;
uint_reg_t ovd_dev_type_val : 4;
uint_reg_t ovd_dev_type : 1;
uint_reg_t __reserved_0 : 1;
uint_reg_t strap_state : 3;
#endif
};
uint_reg_t word;
} TRIO_PCIE_INTFC_PORT_CONFIG_t;
/*
* Port Status.
* Status of the PCIe Port. This register applies to the StreamIO port when
* StreamIO is enabled.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/*
* Indicates the DL state of the port. When 1, the port is up and ready
* to receive traffic.
*/
uint_reg_t dl_up : 1;
/*
* Indicates the number of times the link has gone down. Clears on read.
*/
uint_reg_t dl_down_cnt : 7;
/* Indicates the SERDES PLL has spun up and is providing a valid clock. */
uint_reg_t clock_ready : 1;
/* Reserved. */
uint_reg_t __reserved_0 : 7;
/* Device revision ID. */
uint_reg_t device_rev : 8;
/* Link state (PCIe). */
uint_reg_t ltssm_state : 6;
/* Link power management state (PCIe). */
uint_reg_t pm_state : 3;
/* Reserved. */
uint_reg_t __reserved_1 : 31;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_1 : 31;
uint_reg_t pm_state : 3;
uint_reg_t ltssm_state : 6;
uint_reg_t device_rev : 8;
uint_reg_t __reserved_0 : 7;
uint_reg_t clock_ready : 1;
uint_reg_t dl_down_cnt : 7;
uint_reg_t dl_up : 1;
#endif
};
uint_reg_t word;
} TRIO_PCIE_INTFC_PORT_STATUS_t;
/*
* Transmit FIFO Control.
* Contains TX FIFO thresholds. These registers are for diagnostics purposes
* only. Changing these values causes undefined behavior.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/*
* Almost-Empty level for TX0 data. Typically set to at least
* roundup(38.0*M/N) where N=tclk frequency and M=MAC symbol rate in MHz
* for a x4 port (250MHz).
*/
uint_reg_t tx0_data_ae_lvl : 7;
/* Reserved. */
uint_reg_t __reserved_0 : 1;
/* Almost-Empty level for TX1 data. */
uint_reg_t tx1_data_ae_lvl : 7;
/* Reserved. */
uint_reg_t __reserved_1 : 1;
/* Almost-Full level for TX0 data. */
uint_reg_t tx0_data_af_lvl : 7;
/* Reserved. */
uint_reg_t __reserved_2 : 1;
/* Almost-Full level for TX1 data. */
uint_reg_t tx1_data_af_lvl : 7;
/* Reserved. */
uint_reg_t __reserved_3 : 1;
/* Almost-Full level for TX0 info. */
uint_reg_t tx0_info_af_lvl : 5;
/* Reserved. */
uint_reg_t __reserved_4 : 3;
/* Almost-Full level for TX1 info. */
uint_reg_t tx1_info_af_lvl : 5;
/* Reserved. */
uint_reg_t __reserved_5 : 3;
/*
* This register provides performance adjustment for high bandwidth
* flows. The MAC will assert almost-full to TRIO if non-posted credits
* fall below this level. Note that setting this larger than the initial
* PORT_CREDIT.NPH value will cause READS to never be sent. If the
* initial credit value from the link partner is smaller than this value
* when the link comes up, the value will be reset to the initial credit
* value to prevent lockup.
*/
uint_reg_t min_np_credits : 8;
/*
* This register provides performance adjustment for high bandwidth
* flows. The MAC will assert almost-full to TRIO if posted credits fall
* below this level. Note that setting this larger than the initial
* PORT_CREDIT.PH value will cause WRITES to never be sent. If the
* initial credit value from the link partner is smaller than this value
* when the link comes up, the value will be reset to the initial credit
* value to prevent lockup.
*/
uint_reg_t min_p_credits : 8;
#else /* __BIG_ENDIAN__ */
uint_reg_t min_p_credits : 8;
uint_reg_t min_np_credits : 8;
uint_reg_t __reserved_5 : 3;
uint_reg_t tx1_info_af_lvl : 5;
uint_reg_t __reserved_4 : 3;
uint_reg_t tx0_info_af_lvl : 5;
uint_reg_t __reserved_3 : 1;
uint_reg_t tx1_data_af_lvl : 7;
uint_reg_t __reserved_2 : 1;
uint_reg_t tx0_data_af_lvl : 7;
uint_reg_t __reserved_1 : 1;
uint_reg_t tx1_data_ae_lvl : 7;
uint_reg_t __reserved_0 : 1;
uint_reg_t tx0_data_ae_lvl : 7;
#endif
};
uint_reg_t word;
} TRIO_PCIE_INTFC_TX_FIFO_CTL_t;
#endif /* !defined(__ASSEMBLER__) */
#endif /* !defined(__ARCH_TRIO_PCIE_INTFC_H__) */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_PCIE_INTFC_DEF_H__
#define __ARCH_TRIO_PCIE_INTFC_DEF_H__
#define TRIO_PCIE_INTFC_MAC_INT_STS 0x0000
#define TRIO_PCIE_INTFC_MAC_INT_STS__INT_LEVEL_MASK 0xf000
#define TRIO_PCIE_INTFC_PORT_CONFIG 0x0018
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_DISABLED 0x0
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_ENDPOINT 0x1
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_RC 0x2
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_ENDPOINT_G1 0x3
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_RC_G1 0x4
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_XLINK 0x5
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_STREAM_X1 0x6
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_STREAM_X4 0x7
#define TRIO_PCIE_INTFC_PORT_STATUS 0x0020
#define TRIO_PCIE_INTFC_TX_FIFO_CTL 0x0050
#endif /* !defined(__ARCH_TRIO_PCIE_INTFC_DEF_H__) */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_PCIE_RC_H__
#define __ARCH_TRIO_PCIE_RC_H__
#include <arch/abi.h>
#include <arch/trio_pcie_rc_def.h>
#ifndef __ASSEMBLER__
/* Device Capabilities Register. */
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/*
* Max_Payload_Size Supported, writablethrough the MAC_STANDARD interface
*/
uint_reg_t mps_sup : 3;
/*
* This field is writable through the MAC_STANDARD interface. However,
* Phantom Function is not supported. Therefore, the application must
* not write any value other than 0x0 to this field.
*/
uint_reg_t phantom_function_supported : 2;
/* This bit is writable through the MAC_STANDARD interface. */
uint_reg_t ext_tag_field_supported : 1;
/* Reserved. */
uint_reg_t __reserved_0 : 3;
/* Endpoint L1 Acceptable Latency Must be 0x0 for non-Endpoint devices. */
uint_reg_t l1_lat : 3;
/*
* Undefined since PCI Express 1.1 (Was Attention Button Present for PCI
* Express 1.0a)
*/
uint_reg_t r1 : 1;
/*
* Undefined since PCI Express 1.1 (Was Attention Indicator Present for
* PCI Express 1.0a)
*/
uint_reg_t r2 : 1;
/*
* Undefined since PCI Express 1.1 (Was Power Indicator Present for PCI
* Express 1.0a)
*/
uint_reg_t r3 : 1;
/*
* Role-Based Error Reporting, writable through the MAC_STANDARD
* interface. Required to be set for device compliant to 1.1 spec and
* later.
*/
uint_reg_t rer : 1;
/* Reserved. */
uint_reg_t __reserved_1 : 2;
/* Captured Slot Power Limit Value Upstream port only. */
uint_reg_t slot_pwr_lim : 8;
/* Captured Slot Power Limit Scale Upstream port only. */
uint_reg_t slot_pwr_scale : 2;
/* Reserved. */
uint_reg_t __reserved_2 : 4;
/* Endpoint L0s Acceptable LatencyMust be 0x0 for non-Endpoint devices. */
uint_reg_t l0s_lat : 1;
/* Reserved. */
uint_reg_t __reserved_3 : 31;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_3 : 31;
uint_reg_t l0s_lat : 1;
uint_reg_t __reserved_2 : 4;
uint_reg_t slot_pwr_scale : 2;
uint_reg_t slot_pwr_lim : 8;
uint_reg_t __reserved_1 : 2;
uint_reg_t rer : 1;
uint_reg_t r3 : 1;
uint_reg_t r2 : 1;
uint_reg_t r1 : 1;
uint_reg_t l1_lat : 3;
uint_reg_t __reserved_0 : 3;
uint_reg_t ext_tag_field_supported : 1;
uint_reg_t phantom_function_supported : 2;
uint_reg_t mps_sup : 3;
#endif
};
uint_reg_t word;
} TRIO_PCIE_RC_DEVICE_CAP_t;
/* Device Control Register. */
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* Correctable Error Reporting Enable */
uint_reg_t cor_err_ena : 1;
/* Non-Fatal Error Reporting Enable */
uint_reg_t nf_err_ena : 1;
/* Fatal Error Reporting Enable */
uint_reg_t fatal_err_ena : 1;
/* Unsupported Request Reporting Enable */
uint_reg_t ur_ena : 1;
/* Relaxed orderring enable */
uint_reg_t ro_ena : 1;
/* Max Payload Size */
uint_reg_t max_payload_size : 3;
/* Extended Tag Field Enable */
uint_reg_t ext_tag : 1;
/* Phantom Function Enable */
uint_reg_t ph_fn_ena : 1;
/* AUX Power PM Enable */
uint_reg_t aux_pm_ena : 1;
/* Enable NoSnoop */
uint_reg_t no_snoop : 1;
/* Max read request size */
uint_reg_t max_read_req_sz : 3;
/* Reserved. */
uint_reg_t __reserved : 49;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved : 49;
uint_reg_t max_read_req_sz : 3;
uint_reg_t no_snoop : 1;
uint_reg_t aux_pm_ena : 1;
uint_reg_t ph_fn_ena : 1;
uint_reg_t ext_tag : 1;
uint_reg_t max_payload_size : 3;
uint_reg_t ro_ena : 1;
uint_reg_t ur_ena : 1;
uint_reg_t fatal_err_ena : 1;
uint_reg_t nf_err_ena : 1;
uint_reg_t cor_err_ena : 1;
#endif
};
uint_reg_t word;
} TRIO_PCIE_RC_DEVICE_CONTROL_t;
#endif /* !defined(__ASSEMBLER__) */
#endif /* !defined(__ARCH_TRIO_PCIE_RC_H__) */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_PCIE_RC_DEF_H__
#define __ARCH_TRIO_PCIE_RC_DEF_H__
#define TRIO_PCIE_RC_DEVICE_CAP 0x0074
#define TRIO_PCIE_RC_DEVICE_CONTROL 0x0078
#define TRIO_PCIE_RC_DEVICE_ID_VEN_ID 0x0000
#define TRIO_PCIE_RC_DEVICE_ID_VEN_ID__DEV_ID_SHIFT 16
#define TRIO_PCIE_RC_REVISION_ID 0x0008
#endif /* !defined(__ARCH_TRIO_PCIE_RC_DEF_H__) */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_SHM_H__
#define __ARCH_TRIO_SHM_H__
#include <arch/abi.h>
#include <arch/trio_shm_def.h>
#ifndef __ASSEMBLER__
/**
* TRIO DMA Descriptor.
* The TRIO DMA descriptor is written by software and consumed by hardware.
* It is used to specify the location of transaction data in the IO and Tile
* domains.
*/
__extension__
typedef union
{
struct
{
/* Word 0 */
#ifndef __BIG_ENDIAN__
/** Tile side virtual address. */
int_reg_t va : 42;
/**
* Encoded size of buffer used on push DMA when C=1:
* 0 = 128 bytes
* 1 = 256 bytes
* 2 = 512 bytes
* 3 = 1024 bytes
* 4 = 1664 bytes
* 5 = 4096 bytes
* 6 = 10368 bytes
* 7 = 16384 bytes
*/
uint_reg_t bsz : 3;
/**
* Chaining designation. Always zero for pull DMA
* 0 : Unchained buffer pointer
* 1 : Chained buffer pointer. Next buffer descriptor (e.g. VA) stored
* in 1st 8-bytes in buffer. For chained buffers, first 8-bytes of each
* buffer contain the next buffer descriptor formatted exactly like a PDE
* buffer descriptor. This allows a chained PDE buffer to be sent using
* push DMA.
*/
uint_reg_t c : 1;
/**
* Notification interrupt will be delivered when the transaction has
* completed (all data has been read from or written to the Tile-side
* buffer).
*/
uint_reg_t notif : 1;
/**
* When 0, the XSIZE field specifies the total byte count for the
* transaction. When 1, the XSIZE field is encoded as 2^(N+14) for N in
* {0..6}:
* 0 = 16KB
* 1 = 32KB
* 2 = 64KB
* 3 = 128KB
* 4 = 256KB
* 5 = 512KB
* 6 = 1MB
* All other encodings of the XSIZE field are reserved when SMOD=1
*/
uint_reg_t smod : 1;
/**
* Total number of bytes to move for this transaction. When SMOD=1,
* this field is encoded - see SMOD description.
*/
uint_reg_t xsize : 14;
/** Reserved. */
uint_reg_t __reserved_0 : 1;
/**
* Generation number. Used to indicate a valid descriptor in ring. When
* a new descriptor is written into the ring, software must toggle this
* bit. The net effect is that the GEN bit being written into new
* descriptors toggles each time the ring tail pointer wraps.
*/
uint_reg_t gen : 1;
#else /* __BIG_ENDIAN__ */
uint_reg_t gen : 1;
uint_reg_t __reserved_0 : 1;
uint_reg_t xsize : 14;
uint_reg_t smod : 1;
uint_reg_t notif : 1;
uint_reg_t c : 1;
uint_reg_t bsz : 3;
int_reg_t va : 42;
#endif
/* Word 1 */
#ifndef __BIG_ENDIAN__
/** IO-side address */
uint_reg_t io_address : 64;
#else /* __BIG_ENDIAN__ */
uint_reg_t io_address : 64;
#endif
};
/** Word access */
uint_reg_t words[2];
} TRIO_DMA_DESC_t;
#endif /* !defined(__ASSEMBLER__) */
#endif /* !defined(__ARCH_TRIO_SHM_H__) */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_SHM_DEF_H__
#define __ARCH_TRIO_SHM_DEF_H__
#endif /* !defined(__ARCH_TRIO_SHM_DEF_H__) */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_USB_HOST_H__
#define __ARCH_USB_HOST_H__
#include <arch/abi.h>
#include <arch/usb_host_def.h>
#ifndef __ASSEMBLER__
#endif /* !defined(__ASSEMBLER__) */
#endif /* !defined(__ARCH_USB_HOST_H__) */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_USB_HOST_DEF_H__
#define __ARCH_USB_HOST_DEF_H__
#endif /* !defined(__ARCH_USB_HOST_DEF_H__) */
......@@ -9,7 +9,6 @@ header-y += hardwall.h
generic-y += bug.h
generic-y += bugs.h
generic-y += cputime.h
generic-y += device.h
generic-y += div64.h
generic-y += emergency-restart.h
generic-y += errno.h
......
......@@ -27,11 +27,17 @@
#define L2_CACHE_ALIGN(x) (((x)+(L2_CACHE_BYTES-1)) & -L2_CACHE_BYTES)
/*
* TILE-Gx is fully coherent so we don't need to define ARCH_DMA_MINALIGN.
* TILEPro I/O is not always coherent (networking typically uses coherent
* I/O, but PCI traffic does not) and setting ARCH_DMA_MINALIGN to the
* L2 cacheline size helps ensure that kernel heap allocations are aligned.
* TILE-Gx I/O is always coherent when used on hash-for-home pages.
*
* However, it's possible at runtime to request not to use hash-for-home
* for the kernel heap, in which case the kernel will use flush-and-inval
* to manage coherence. As a result, we use L2_CACHE_BYTES for the
* DMA minimum alignment to avoid false sharing in the kernel heap.
*/
#ifndef __tilegx__
#define ARCH_DMA_MINALIGN L2_CACHE_BYTES
#endif
/* use the cache line size for the L2, which is where it counts */
#define SMP_CACHE_BYTES_SHIFT L2_CACHE_SHIFT
......
......@@ -21,4 +21,22 @@
__wsum do_csum(const unsigned char *buff, int len);
#define do_csum do_csum
/*
* Return the sum of all the 16-bit subwords in a long.
* This sums two subwords on a 32-bit machine, and four on 64 bits.
* The implementation does two vector adds to capture any overflow.
*/
static inline unsigned int csum_long(unsigned long x)
{
unsigned long ret;
#ifdef __tilegx__
ret = __insn_v2sadu(x, 0);
ret = __insn_v2sadu(ret, 0);
#else
ret = __insn_sadh_u(x, 0);
ret = __insn_sadh_u(ret, 0);
#endif
return ret;
}
#endif /* _ASM_TILE_CHECKSUM_H */
......@@ -10,24 +10,24 @@
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*
* The hypervisor's memory controller profiling infrastructure allows
* the programmer to find out what fraction of the available memory
* bandwidth is being consumed at each memory controller. The
* profiler provides start, stop, and clear operations to allows
* profiling over a specific time window, as well as an interface for
* reading the most recent profile values.
*
* This header declares IOCTL codes necessary to control memprof.
* Arch specific extensions to struct device
*/
#ifndef _ASM_TILE_MEMPROF_H
#define _ASM_TILE_MEMPROF_H
#include <linux/ioctl.h>
#ifndef _ASM_TILE_DEVICE_H
#define _ASM_TILE_DEVICE_H
struct dev_archdata {
/* DMA operations on that device */
struct dma_map_ops *dma_ops;
/* Offset of the DMA address from the PA. */
dma_addr_t dma_offset;
/* Highest DMA address that can be generated by this device. */
dma_addr_t max_direct_dma_addr;
};
#define MEMPROF_IOCTL_TYPE 0xB4
#define MEMPROF_IOCTL_START _IO(MEMPROF_IOCTL_TYPE, 0)
#define MEMPROF_IOCTL_STOP _IO(MEMPROF_IOCTL_TYPE, 1)
#define MEMPROF_IOCTL_CLEAR _IO(MEMPROF_IOCTL_TYPE, 2)
struct pdev_archdata {
};
#endif /* _ASM_TILE_MEMPROF_H */
#endif /* _ASM_TILE_DEVICE_H */
......@@ -20,69 +20,80 @@
#include <linux/cache.h>
#include <linux/io.h>
/*
* Note that on x86 and powerpc, there is a "struct dma_mapping_ops"
* that is used for all the DMA operations. For now, we don't have an
* equivalent on tile, because we only have a single way of doing DMA.
* (Tilera bug 7994 to use dma_mapping_ops.)
*/
extern struct dma_map_ops *tile_dma_map_ops;
extern struct dma_map_ops *gx_pci_dma_map_ops;
extern struct dma_map_ops *gx_legacy_pci_dma_map_ops;
static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
if (dev && dev->archdata.dma_ops)
return dev->archdata.dma_ops;
else
return tile_dma_map_ops;
}
static inline dma_addr_t get_dma_offset(struct device *dev)
{
return dev->archdata.dma_offset;
}
static inline void set_dma_offset(struct device *dev, dma_addr_t off)
{
dev->archdata.dma_offset = off;
}
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction);
extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
size_t size, enum dma_data_direction);
extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction);
extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
int nhwentries, enum dma_data_direction);
extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
enum dma_data_direction);
extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
size_t size, enum dma_data_direction);
extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
int nelems, enum dma_data_direction);
extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
int nelems, enum dma_data_direction);
void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag);
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
extern void dma_sync_single_for_cpu(struct device *, dma_addr_t, size_t,
enum dma_data_direction);
extern void dma_sync_single_for_device(struct device *, dma_addr_t,
size_t, enum dma_data_direction);
extern void dma_sync_single_range_for_cpu(struct device *, dma_addr_t,
unsigned long offset, size_t,
enum dma_data_direction);
extern void dma_sync_single_range_for_device(struct device *, dma_addr_t,
unsigned long offset, size_t,
enum dma_data_direction);
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t,
enum dma_data_direction);
static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
{
return paddr + get_dma_offset(dev);
}
static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
{
return daddr - get_dma_offset(dev);
}
static inline void dma_mark_clean(void *addr, size_t size) {}
#include <asm-generic/dma-mapping-common.h>
static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
{
dev->archdata.dma_ops = ops;
}
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
if (!dev->dma_mask)
return 0;
return addr + size - 1 <= *dev->dma_mask;
}
static inline int
dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
return 0;
return get_dma_ops(dev)->mapping_error(dev, dma_addr);
}
static inline int
dma_supported(struct device *dev, u64 mask)
{
return 1;
return get_dma_ops(dev)->dma_supported(dev, mask);
}
static inline int
dma_set_mask(struct device *dev, u64 mask)
{
struct dma_map_ops *dma_ops = get_dma_ops(dev);
/* Handle legacy PCI devices with limited memory addressability. */
if ((dma_ops == gx_pci_dma_map_ops) && (mask <= DMA_BIT_MASK(32))) {
set_dma_ops(dev, gx_legacy_pci_dma_map_ops);
set_dma_offset(dev, 0);
if (mask > dev->archdata.max_direct_dma_addr)
mask = dev->archdata.max_direct_dma_addr;
}
if (!dev->dma_mask || !dma_supported(dev, mask))
return -EIO;
......@@ -91,4 +102,43 @@ dma_set_mask(struct device *dev, u64 mask)
return 0;
}
static inline void *dma_alloc_attrs(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag,
struct dma_attrs *attrs)
{
struct dma_map_ops *dma_ops = get_dma_ops(dev);
void *cpu_addr;
cpu_addr = dma_ops->alloc(dev, size, dma_handle, flag, attrs);
debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
return cpu_addr;
}
static inline void dma_free_attrs(struct device *dev, size_t size,
void *cpu_addr, dma_addr_t dma_handle,
struct dma_attrs *attrs)
{
struct dma_map_ops *dma_ops = get_dma_ops(dev);
debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
dma_ops->free(dev, size, cpu_addr, dma_handle, attrs);
}
#define dma_alloc_coherent(d, s, h, f) dma_alloc_attrs(d, s, h, f, NULL)
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_attrs(d, s, h, f, NULL)
#define dma_free_coherent(d, s, v, h) dma_free_attrs(d, s, v, h, NULL)
#define dma_free_noncoherent(d, s, v, h) dma_free_attrs(d, s, v, h, NULL)
/*
* dma_alloc_noncoherent() is #defined to return coherent memory,
* so there's no need to do any flushing here.
*/
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
{
}
#endif /* _ASM_TILE_DMA_MAPPING_H */
......@@ -45,14 +45,22 @@
*
* TLB entries of such buffers will not be flushed across
* task switches.
*
* We don't bother with a FIX_HOLE since above the fixmaps
* is unmapped memory in any case.
*/
enum fixed_addresses {
#ifdef __tilegx__
/*
* TILEPro has unmapped memory above so the hole isn't needed,
* and in any case the hole pushes us over a single 16MB pmd.
*/
FIX_HOLE,
#endif
#ifdef CONFIG_HIGHMEM
FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
#endif
#ifdef __tilegx__ /* see homecache.c */
FIX_HOMECACHE_BEGIN,
FIX_HOMECACHE_END = FIX_HOMECACHE_BEGIN+(NR_CPUS)-1,
#endif
__end_of_permanent_fixed_addresses,
......
......@@ -79,10 +79,17 @@ extern void homecache_change_page_home(struct page *, int order, int home);
/*
* Flush a page out of whatever cache(s) it is in.
* This is more than just finv, since it properly handles waiting
* for the data to reach memory on tilepro, but it can be quite
* heavyweight, particularly on hash-for-home memory.
* for the data to reach memory, but it can be quite
* heavyweight, particularly on incoherent or immutable memory.
*/
extern void homecache_flush_cache(struct page *, int order);
extern void homecache_finv_page(struct page *);
/*
* Flush a page out of the specified home cache.
* Note that the specified home need not be the actual home of the page,
* as for example might be the case when coordinating with I/O devices.
*/
extern void homecache_finv_map_page(struct page *, int home);
/*
* Allocate a page with the given GFP flags, home, and optionally
......@@ -104,10 +111,10 @@ extern struct page *homecache_alloc_pages_node(int nid, gfp_t gfp_mask,
* routines use homecache_change_page_home() to reset the home
* back to the default before returning the page to the allocator.
*/
void __homecache_free_pages(struct page *, unsigned int order);
void homecache_free_pages(unsigned long addr, unsigned int order);
#define homecache_free_page(page) \
homecache_free_pages((page), 0)
#define __homecache_free_page(page) __homecache_free_pages((page), 0)
#define homecache_free_page(page) homecache_free_pages((page), 0)
/*
......
......@@ -62,6 +62,92 @@ extern void iounmap(volatile void __iomem *addr);
#define mm_ptov(addr) ((void *)phys_to_virt(addr))
#define mm_vtop(addr) ((unsigned long)virt_to_phys(addr))
#if CHIP_HAS_MMIO()
/*
* We use inline assembly to guarantee that the compiler does not
* split an access into multiple byte-sized accesses as it might
* sometimes do if a register data structure is marked "packed".
* Obviously on tile we can't tolerate such an access being
* actually unaligned, but we want to avoid the case where the
* compiler conservatively would generate multiple accesses even
* for an aligned read or write.
*/
static inline u8 __raw_readb(const volatile void __iomem *addr)
{
return *(const volatile u8 __force *)addr;
}
static inline u16 __raw_readw(const volatile void __iomem *addr)
{
u16 ret;
asm volatile("ld2u %0, %1" : "=r" (ret) : "r" (addr));
barrier();
return le16_to_cpu(ret);
}
static inline u32 __raw_readl(const volatile void __iomem *addr)
{
u32 ret;
/* Sign-extend to conform to u32 ABI sign-extension convention. */
asm volatile("ld4s %0, %1" : "=r" (ret) : "r" (addr));
barrier();
return le32_to_cpu(ret);
}
static inline u64 __raw_readq(const volatile void __iomem *addr)
{
u64 ret;
asm volatile("ld %0, %1" : "=r" (ret) : "r" (addr));
barrier();
return le64_to_cpu(ret);
}
static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
{
*(volatile u8 __force *)addr = val;
}
static inline void __raw_writew(u16 val, volatile void __iomem *addr)
{
asm volatile("st2 %0, %1" :: "r" (addr), "r" (cpu_to_le16(val)));
}
static inline void __raw_writel(u32 val, volatile void __iomem *addr)
{
asm volatile("st4 %0, %1" :: "r" (addr), "r" (cpu_to_le32(val)));
}
static inline void __raw_writeq(u64 val, volatile void __iomem *addr)
{
asm volatile("st %0, %1" :: "r" (addr), "r" (cpu_to_le64(val)));
}
/*
* The on-chip I/O hardware on tilegx is configured with VA=PA for the
* kernel's PA range. The low-level APIs and field names use "va" and
* "void *" nomenclature, to be consistent with the general notion
* that the addresses in question are virtualizable, but in the kernel
* context we are actually manipulating PA values. (In other contexts,
* e.g. access from user space, we do in fact use real virtual addresses
* in the va fields.) To allow readers of the code to understand what's
* happening, we direct their attention to this comment by using the
* following two functions that just duplicate __va() and __pa().
*/
typedef unsigned long tile_io_addr_t;
static inline tile_io_addr_t va_to_tile_io_addr(void *va)
{
BUILD_BUG_ON(sizeof(phys_addr_t) != sizeof(tile_io_addr_t));
return __pa(va);
}
static inline void *tile_io_addr_to_va(tile_io_addr_t tile_io_addr)
{
return __va(tile_io_addr);
}
#else /* CHIP_HAS_MMIO() */
#ifdef CONFIG_PCI
extern u8 _tile_readb(unsigned long addr);
......@@ -73,10 +159,19 @@ extern void _tile_writew(u16 val, unsigned long addr);
extern void _tile_writel(u32 val, unsigned long addr);
extern void _tile_writeq(u64 val, unsigned long addr);
#else
#define __raw_readb(addr) _tile_readb((unsigned long)addr)
#define __raw_readw(addr) _tile_readw((unsigned long)addr)
#define __raw_readl(addr) _tile_readl((unsigned long)addr)
#define __raw_readq(addr) _tile_readq((unsigned long)addr)
#define __raw_writeb(val, addr) _tile_writeb(val, (unsigned long)addr)
#define __raw_writew(val, addr) _tile_writew(val, (unsigned long)addr)
#define __raw_writel(val, addr) _tile_writel(val, (unsigned long)addr)
#define __raw_writeq(val, addr) _tile_writeq(val, (unsigned long)addr)
#else /* CONFIG_PCI */
/*
* The Tile architecture does not support IOMEM unless PCI is enabled.
* The tilepro architecture does not support IOMEM unless PCI is enabled.
* Unfortunately we can't yet simply not declare these methods,
* since some generic code that compiles into the kernel, but
* we never run, uses them unconditionally.
......@@ -88,65 +183,58 @@ static inline int iomem_panic(void)
return 0;
}
static inline u8 _tile_readb(unsigned long addr)
static inline u8 readb(unsigned long addr)
{
return iomem_panic();
}
static inline u16 _tile_readw(unsigned long addr)
static inline u16 _readw(unsigned long addr)
{
return iomem_panic();
}
static inline u32 _tile_readl(unsigned long addr)
static inline u32 readl(unsigned long addr)
{
return iomem_panic();
}
static inline u64 _tile_readq(unsigned long addr)
static inline u64 readq(unsigned long addr)
{
return iomem_panic();
}
static inline void _tile_writeb(u8 val, unsigned long addr)
static inline void writeb(u8 val, unsigned long addr)
{
iomem_panic();
}
static inline void _tile_writew(u16 val, unsigned long addr)
static inline void writew(u16 val, unsigned long addr)
{
iomem_panic();
}
static inline void _tile_writel(u32 val, unsigned long addr)
static inline void writel(u32 val, unsigned long addr)
{
iomem_panic();
}
static inline void _tile_writeq(u64 val, unsigned long addr)
static inline void writeq(u64 val, unsigned long addr)
{
iomem_panic();
}
#endif
#endif /* CONFIG_PCI */
#endif /* CHIP_HAS_MMIO() */
#define readb(addr) _tile_readb((unsigned long)addr)
#define readw(addr) _tile_readw((unsigned long)addr)
#define readl(addr) _tile_readl((unsigned long)addr)
#define readq(addr) _tile_readq((unsigned long)addr)
#define writeb(val, addr) _tile_writeb(val, (unsigned long)addr)
#define writew(val, addr) _tile_writew(val, (unsigned long)addr)
#define writel(val, addr) _tile_writel(val, (unsigned long)addr)
#define writeq(val, addr) _tile_writeq(val, (unsigned long)addr)
#define __raw_readb readb
#define __raw_readw readw
#define __raw_readl readl
#define __raw_readq readq
#define __raw_writeb writeb
#define __raw_writew writew
#define __raw_writel writel
#define __raw_writeq writeq
#define readb __raw_readb
#define readw __raw_readw
#define readl __raw_readl
#define readq __raw_readq
#define writeb __raw_writeb
#define writew __raw_writew
#define writel __raw_writel
#define writeq __raw_writeq
#define readb_relaxed readb
#define readw_relaxed readw
......
......@@ -174,7 +174,9 @@ static inline __attribute_const__ int get_order(unsigned long size)
#define MEM_LOW_END (HALF_VA_SPACE - 1) /* low half */
#define MEM_HIGH_START (-HALF_VA_SPACE) /* high half */
#define PAGE_OFFSET MEM_HIGH_START
#define _VMALLOC_START _AC(0xfffffff500000000, UL) /* 4 GB */
#define FIXADDR_BASE _AC(0xfffffff400000000, UL) /* 4 GB */
#define FIXADDR_TOP _AC(0xfffffff500000000, UL) /* 4 GB */
#define _VMALLOC_START FIXADDR_TOP
#define HUGE_VMAP_BASE _AC(0xfffffff600000000, UL) /* 4 GB */
#define MEM_SV_START _AC(0xfffffff700000000, UL) /* 256 MB */
#define MEM_SV_INTRPT MEM_SV_START
......@@ -185,9 +187,6 @@ static inline __attribute_const__ int get_order(unsigned long size)
/* Highest DTLB address we will use */
#define KERNEL_HIGH_VADDR MEM_SV_START
/* Since we don't currently provide any fixmaps, we use an impossible VA. */
#define FIXADDR_TOP MEM_HV_START
#else /* !__tilegx__ */
/*
......
......@@ -15,9 +15,13 @@
#ifndef _ASM_TILE_PCI_H
#define _ASM_TILE_PCI_H
#include <linux/dma-mapping.h>
#include <linux/pci.h>
#include <linux/numa.h>
#include <asm-generic/pci_iomap.h>
#ifndef __tilegx__
/*
* Structure of a PCI controller (host bridge)
*/
......@@ -40,6 +44,16 @@ struct pci_controller {
struct resource mem_resources[3];
};
/*
* This flag tells if the platform is TILEmpower that needs
* special configuration for the PLX switch chip.
*/
extern int tile_plx_gen1;
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
#define TILE_NUM_PCIE 2
/*
* The hypervisor maps the entirety of CPA-space as bus addresses, so
* bus addresses are physical addresses. The networking and block
......@@ -47,15 +61,135 @@ struct pci_controller {
*/
#define PCI_DMA_BUS_IS_PHYS 1
/* generic pci stuff */
#include <asm-generic/pci.h>
#else
#include <asm/page.h>
#include <gxio/trio.h>
/**
* We reserve the hugepage-size address range at the top of the 64-bit address
* space to serve as the PCI window, emulating the BAR0 space of an endpoint
* device. This window is used by the chip-to-chip applications running on
* the RC node. The reason for carving out this window is that Mem-Maps that
* back up this window will not overlap with those that map the real physical
* memory.
*/
#define PCIE_HOST_BAR0_SIZE HPAGE_SIZE
#define PCIE_HOST_BAR0_START HPAGE_MASK
/**
* The first PAGE_SIZE of the above "BAR" window is mapped to the
* gxpci_host_regs structure.
*/
#define PCIE_HOST_REGS_SIZE PAGE_SIZE
/*
* This is the PCI address where the Mem-Map interrupt regions start.
* We use the 2nd to the last huge page of the 64-bit address space.
* The last huge page is used for the rootcomplex "bar", for C2C purpose.
*/
#define MEM_MAP_INTR_REGIONS_BASE (HPAGE_MASK - HPAGE_SIZE)
/*
* Each Mem-Map interrupt region occupies 4KB.
*/
#define MEM_MAP_INTR_REGION_SIZE (1 << TRIO_MAP_MEM_LIM__ADDR_SHIFT)
/*
* Allocate the PCI BAR window right below 4GB.
*/
#define TILE_PCI_BAR_WINDOW_TOP (1ULL << 32)
/*
* Allocate 1GB for the PCI BAR window.
*/
#define TILE_PCI_BAR_WINDOW_SIZE (1 << 30)
/*
* This is the highest bus address targeting the host memory that
* can be generated by legacy PCI devices with 32-bit or less
* DMA capability, dictated by the BAR window size and location.
*/
#define TILE_PCI_MAX_DIRECT_DMA_ADDRESS \
(TILE_PCI_BAR_WINDOW_TOP - TILE_PCI_BAR_WINDOW_SIZE - 1)
/*
* We shift the PCI bus range for all the physical memory up by the whole PA
* range. The corresponding CPA of an incoming PCI request will be the PCI
* address minus TILE_PCI_MEM_MAP_BASE_OFFSET. This also implies
* that the 64-bit capable devices will be given DMA addresses as
* the CPA plus TILE_PCI_MEM_MAP_BASE_OFFSET. To support 32-bit
* devices, we create a separate map region that handles the low
* 4GB.
*/
#define TILE_PCI_MEM_MAP_BASE_OFFSET (1ULL << CHIP_PA_WIDTH())
/*
* Start of the PCI memory resource, which starts at the end of the
* maximum system physical RAM address.
*/
#define TILE_PCI_MEM_START (1ULL << CHIP_PA_WIDTH())
/*
* Structure of a PCI controller (host bridge) on Gx.
*/
struct pci_controller {
/* Pointer back to the TRIO that this PCIe port is connected to. */
gxio_trio_context_t *trio;
int mac; /* PCIe mac index on the TRIO shim */
int trio_index; /* Index of TRIO shim that contains the MAC. */
int pio_mem_index; /* PIO region index for memory access */
/*
* Mem-Map regions for all the memory controllers so that Linux can
* map all of its physical memory space to the PCI bus.
*/
int mem_maps[MAX_NUMNODES];
int index; /* PCI domain number */
struct pci_bus *root_bus;
/* PCI memory space resource for this controller. */
struct resource mem_space;
char mem_space_name[32];
uint64_t mem_offset; /* cpu->bus memory mapping offset. */
int first_busno;
struct pci_ops *ops;
/* Table that maps the INTx numbers to Linux irq numbers. */
int irq_intx_table[4];
/* Address ranges that are routed to this controller/bridge. */
struct resource mem_resources[3];
};
extern struct pci_controller pci_controllers[TILEGX_NUM_TRIO * TILEGX_TRIO_PCIES];
extern gxio_trio_context_t trio_contexts[TILEGX_NUM_TRIO];
extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
/*
* The PCI address space does not equal the physical memory address
* space (we have an IOMMU). The IDE and SCSI device layers use this
* boolean for bounce buffer decisions.
*/
#define PCI_DMA_BUS_IS_PHYS 0
#endif /* __tilegx__ */
int __init tile_pci_init(void);
int __init pcibios_init(void);
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
void __devinit pcibios_fixup_bus(struct pci_bus *bus);
#define TILE_NUM_PCIE 2
#define pci_domain_nr(bus) (((struct pci_controller *)(bus)->sysdata)->index)
/*
......@@ -79,19 +213,10 @@ static inline int pcibios_assign_all_busses(void)
#define PCIBIOS_MIN_MEM 0
#define PCIBIOS_MIN_IO 0
/*
* This flag tells if the platform is TILEmpower that needs
* special configuration for the PLX switch chip.
*/
extern int tile_plx_gen1;
/* Use any cpu for PCI. */
#define cpumask_of_pcibus(bus) cpu_online_mask
/* implement the pci_ DMA API in terms of the generic device dma_ one */
#include <asm-generic/pci-dma-compat.h>
/* generic pci stuff */
#include <asm-generic/pci.h>
#endif /* _ASM_TILE_PCI_H */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#ifndef _GXIO_COMMON_H_
#define _GXIO_COMMON_H_
/*
* Routines shared between the various GXIO device components.
*/
#include <hv/iorpc.h>
#include <linux/types.h>
#include <linux/compiler.h>
#include <linux/io.h>
/* Define the standard gxio MMIO functions using kernel functions. */
#define __gxio_mmio_read8(addr) readb(addr)
#define __gxio_mmio_read16(addr) readw(addr)
#define __gxio_mmio_read32(addr) readl(addr)
#define __gxio_mmio_read64(addr) readq(addr)
#define __gxio_mmio_write8(addr, val) writeb((val), (addr))
#define __gxio_mmio_write16(addr, val) writew((val), (addr))
#define __gxio_mmio_write32(addr, val) writel((val), (addr))
#define __gxio_mmio_write64(addr, val) writeq((val), (addr))
#define __gxio_mmio_read(addr) __gxio_mmio_read64(addr)
#define __gxio_mmio_write(addr, val) __gxio_mmio_write64((addr), (val))
#endif /* !_GXIO_COMMON_H_ */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#ifndef _GXIO_DMA_QUEUE_H_
#define _GXIO_DMA_QUEUE_H_
/*
* DMA queue management APIs shared between TRIO and mPIPE.
*/
#include "common.h"
/* The credit counter lives in the high 32 bits. */
#define DMA_QUEUE_CREDIT_SHIFT 32
/*
* State object that tracks a DMA queue's head and tail indices, as
* well as the number of commands posted and completed. The
* structure is accessed via a thread-safe, lock-free algorithm.
*/
typedef struct {
/*
* Address of a MPIPE_EDMA_POST_REGION_VAL_t,
* TRIO_PUSH_DMA_REGION_VAL_t, or TRIO_PULL_DMA_REGION_VAL_t
* register. These register have identical encodings and provide
* information about how many commands have been processed.
*/
void *post_region_addr;
/*
* A lazily-updated count of how many edescs the hardware has
* completed.
*/
uint64_t hw_complete_count __attribute__ ((aligned(64)));
/*
* High 32 bits are a count of available egress command credits,
* low 24 bits are the next egress "slot".
*/
int64_t credits_and_next_index;
} __gxio_dma_queue_t;
/* Initialize a dma queue. */
extern void __gxio_dma_queue_init(__gxio_dma_queue_t *dma_queue,
void *post_region_addr,
unsigned int num_entries);
/*
* Update the "credits_and_next_index" and "hw_complete_count" fields
* based on pending hardware completions. Note that some other thread
* may have already done this and, importantly, may still be in the
* process of updating "credits_and_next_index".
*/
extern void __gxio_dma_queue_update_credits(__gxio_dma_queue_t *dma_queue);
/* Wait for credits to become available. */
extern int64_t __gxio_dma_queue_wait_for_credits(__gxio_dma_queue_t *dma_queue,
int64_t modifier);
/* Reserve slots in the queue, optionally waiting for slots to become
* available, and optionally returning a "completion_slot" suitable for
* direct comparison to "hw_complete_count".
*/
static inline int64_t __gxio_dma_queue_reserve(__gxio_dma_queue_t *dma_queue,
unsigned int num, bool wait,
bool completion)
{
uint64_t slot;
/*
* Try to reserve 'num' egress command slots. We do this by
* constructing a constant that subtracts N credits and adds N to
* the index, and using fetchaddgez to only apply it if the credits
* count doesn't go negative.
*/
int64_t modifier = (((int64_t)(-num)) << DMA_QUEUE_CREDIT_SHIFT) | num;
int64_t old =
__insn_fetchaddgez(&dma_queue->credits_and_next_index,
modifier);
if (unlikely(old + modifier < 0)) {
/*
* We're out of credits. Try once to get more by checking for
* completed egress commands. If that fails, wait or fail.
*/
__gxio_dma_queue_update_credits(dma_queue);
old = __insn_fetchaddgez(&dma_queue->credits_and_next_index,
modifier);
if (old + modifier < 0) {
if (wait)
old = __gxio_dma_queue_wait_for_credits
(dma_queue, modifier);
else
return GXIO_ERR_DMA_CREDITS;
}
}
/* The bottom 24 bits of old encode the "slot". */
slot = (old & 0xffffff);
if (completion) {
/*
* A "completion_slot" is a "slot" which can be compared to
* "hw_complete_count" at any time in the future. To convert
* "slot" into a "completion_slot", we access "hw_complete_count"
* once (knowing that we have reserved a slot, and thus, it will
* be "basically" accurate), and combine its high 40 bits with
* the 24 bit "slot", and handle "wrapping" by adding "1 << 24"
* if the result is LESS than "hw_complete_count".
*/
uint64_t complete;
complete = ACCESS_ONCE(dma_queue->hw_complete_count);
slot |= (complete & 0xffffffffff000000);
if (slot < complete)
slot += 0x1000000;
}
/*
* If any of our slots mod 256 were equivalent to 0, go ahead and
* collect some egress credits, and update "hw_complete_count", and
* make sure the index doesn't overflow into the credits.
*/
if (unlikely(((old + num) & 0xff) < num)) {
__gxio_dma_queue_update_credits(dma_queue);
/* Make sure the index doesn't overflow into the credits. */
#ifdef __BIG_ENDIAN__
*(((uint8_t *)&dma_queue->credits_and_next_index) + 4) = 0;
#else
*(((uint8_t *)&dma_queue->credits_and_next_index) + 3) = 0;
#endif
}
return slot;
}
/* Non-inlinable "__gxio_dma_queue_reserve(..., true)". */
extern int64_t __gxio_dma_queue_reserve_aux(__gxio_dma_queue_t *dma_queue,
unsigned int num, int wait);
/* Check whether a particular "completion slot" has completed.
*
* Note that this function requires a "completion slot", and thus
* cannot be used with the result of any "reserve_fast" function.
*/
extern int __gxio_dma_queue_is_complete(__gxio_dma_queue_t *dma_queue,
int64_t completion_slot, int update);
#endif /* !_GXIO_DMA_QUEUE_H_ */
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#ifndef __IORPC_LINUX_RPC_H__
#define __IORPC_LINUX_RPC_H__
#include <hv/iorpc.h>
#include <linux/string.h>
#include <linux/module.h>
#include <asm/pgtable.h>
#define IORPC_OP_ARM_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9000)
#define IORPC_OP_CLOSE_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9001)
#define IORPC_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
#define IORPC_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
int __iorpc_arm_pollfd(int fd, int pollfd_cookie);
int __iorpc_close_pollfd(int fd, int pollfd_cookie);
int __iorpc_get_mmio_base(int fd, HV_PTE *base);
int __iorpc_check_mmio_offset(int fd, unsigned long offset, unsigned long size);
#endif /* !__IORPC_LINUX_RPC_H__ */
This diff is collapsed.
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#ifndef __GXIO_MPIPE_INFO_LINUX_RPC_H__
#define __GXIO_MPIPE_INFO_LINUX_RPC_H__
#include <hv/iorpc.h>
#include <hv/drv_mpipe_intf.h>
#include <asm/page.h>
#include <gxio/kiorpc.h>
#include <gxio/mpipe.h>
#include <linux/string.h>
#include <linux/module.h>
#include <asm/pgtable.h>
#define GXIO_MPIPE_INFO_OP_ENUMERATE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1251)
#define GXIO_MPIPE_INFO_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
#define GXIO_MPIPE_INFO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
int gxio_mpipe_info_enumerate_aux(gxio_mpipe_info_context_t * context,
unsigned int idx,
_gxio_mpipe_link_name_t * name,
_gxio_mpipe_link_mac_t * mac);
int gxio_mpipe_info_get_mmio_base(gxio_mpipe_info_context_t * context,
HV_PTE *base);
int gxio_mpipe_info_check_mmio_offset(gxio_mpipe_info_context_t * context,
unsigned long offset, unsigned long size);
#endif /* !__GXIO_MPIPE_INFO_LINUX_RPC_H__ */
This diff is collapsed.
/*
* Copyright 2012 Tilera Corporation. All Rights Reserved.
*
* 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, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#ifndef __GXIO_USB_HOST_LINUX_RPC_H__
#define __GXIO_USB_HOST_LINUX_RPC_H__
#include <hv/iorpc.h>
#include <hv/drv_usb_host_intf.h>
#include <asm/page.h>
#include <gxio/kiorpc.h>
#include <gxio/usb_host.h>
#include <linux/string.h>
#include <linux/module.h>
#include <asm/pgtable.h>
#define GXIO_USB_HOST_OP_CFG_INTERRUPT IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1800)
#define GXIO_USB_HOST_OP_REGISTER_CLIENT_MEMORY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1801)
#define GXIO_USB_HOST_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
#define GXIO_USB_HOST_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
int gxio_usb_host_cfg_interrupt(gxio_usb_host_context_t * context, int inter_x,
int inter_y, int inter_ipi, int inter_event);
int gxio_usb_host_register_client_memory(gxio_usb_host_context_t * context,
HV_PTE pte, unsigned int flags);
int gxio_usb_host_get_mmio_base(gxio_usb_host_context_t * context,
HV_PTE *base);
int gxio_usb_host_check_mmio_offset(gxio_usb_host_context_t * context,
unsigned long offset, unsigned long size);
#endif /* !__GXIO_USB_HOST_LINUX_RPC_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -14,4 +14,9 @@ obj-$(CONFIG_SMP) += smpboot.o smp.o tlb.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel_$(BITS).o
ifdef CONFIG_TILEGX
obj-$(CONFIG_PCI) += pci_gx.o
else
obj-$(CONFIG_PCI) += pci.o
endif
obj-$(CONFIG_TILE_USB) += usb.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -575,13 +575,6 @@ void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
}
EXPORT_SYMBOL(ioremap_prot);
/* Map a PCI MMIO bus address into VA space. */
void __iomem *ioremap(resource_size_t phys_addr, unsigned long size)
{
panic("ioremap for PCI MMIO is not supported");
}
EXPORT_SYMBOL(ioremap);
/* Unmap an MMIO VA mapping. */
void iounmap(volatile void __iomem *addr_in)
{
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment