-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
Showing
72 changed files
with
11,240 additions
and
406 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# | ||
# 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
/* | ||
* 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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* 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); |
Oops, something went wrong.