9c90bdde77
Provide a driver for the altix TIOCA AGP chipset. An agpgart backend will be provided as a separate patch. Signed-off-by: Mark Maule <maule@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
207 lines
6.0 KiB
C
207 lines
6.0 KiB
C
/*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file "COPYING" in the main directory of this archive
|
|
* for more details.
|
|
*
|
|
* Copyright (c) 2003-2005 Silicon Graphics, Inc. All rights reserved.
|
|
*/
|
|
|
|
#ifndef _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H
|
|
#define _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H
|
|
|
|
#include <asm/sn/tioca.h>
|
|
|
|
/*
|
|
* WAR enables
|
|
* Defines for individual WARs. Each is a bitmask of applicable
|
|
* part revision numbers. (1 << 1) == rev A, (1 << 2) == rev B,
|
|
* (3 << 1) == (rev A or rev B), etc
|
|
*/
|
|
|
|
#define TIOCA_WAR_ENABLED(pv, tioca_common) \
|
|
((1 << tioca_common->ca_rev) & pv)
|
|
|
|
/* TIO:ICE:FRZ:Freezer loses a PIO data ucred on PIO RD RSP with CW error */
|
|
#define PV907908 (1 << 1)
|
|
/* ATI config space problems after BIOS execution starts */
|
|
#define PV908234 (1 << 1)
|
|
/* CA:AGPDMA write request data mismatch with ABC1CL merge */
|
|
#define PV895469 (1 << 1)
|
|
/* TIO:CA TLB invalidate of written GART entries possibly not occuring in CA*/
|
|
#define PV910244 (1 << 1)
|
|
|
|
struct tioca_dmamap{
|
|
struct list_head cad_list; /* headed by ca_list */
|
|
|
|
dma_addr_t cad_dma_addr; /* Linux dma handle */
|
|
uint cad_gart_entry; /* start entry in ca_gart_pagemap */
|
|
uint cad_gart_size; /* #entries for this map */
|
|
};
|
|
|
|
/*
|
|
* Kernel only fields. Prom may look at this stuff for debugging only.
|
|
* Access this structure through the ca_kernel_private ptr.
|
|
*/
|
|
|
|
struct tioca_common ;
|
|
|
|
struct tioca_kernel {
|
|
struct tioca_common *ca_common; /* tioca this belongs to */
|
|
struct list_head ca_list; /* list of all ca's */
|
|
struct list_head ca_dmamaps;
|
|
spinlock_t ca_lock; /* Kernel lock */
|
|
cnodeid_t ca_closest_node;
|
|
struct list_head *ca_devices; /* bus->devices */
|
|
|
|
/*
|
|
* General GART stuff
|
|
*/
|
|
uint64_t ca_ap_size; /* size of aperature in bytes */
|
|
uint32_t ca_gart_entries; /* # uint64_t entries in gart */
|
|
uint32_t ca_ap_pagesize; /* aperature page size in bytes */
|
|
uint64_t ca_ap_bus_base; /* bus address of CA aperature */
|
|
uint64_t ca_gart_size; /* gart size in bytes */
|
|
uint64_t *ca_gart; /* gart table vaddr */
|
|
uint64_t ca_gart_coretalk_addr; /* gart coretalk addr */
|
|
uint8_t ca_gart_iscoherent; /* used in tioca_tlbflush */
|
|
|
|
/* PCI GART convenience values */
|
|
uint64_t ca_pciap_base; /* pci aperature bus base address */
|
|
uint64_t ca_pciap_size; /* pci aperature size (bytes) */
|
|
uint64_t ca_pcigart_base; /* gfx GART bus base address */
|
|
uint64_t *ca_pcigart; /* gfx GART vm address */
|
|
uint32_t ca_pcigart_entries;
|
|
uint32_t ca_pcigart_start; /* PCI start index in ca_gart */
|
|
void *ca_pcigart_pagemap;
|
|
|
|
/* AGP GART convenience values */
|
|
uint64_t ca_gfxap_base; /* gfx aperature bus base address */
|
|
uint64_t ca_gfxap_size; /* gfx aperature size (bytes) */
|
|
uint64_t ca_gfxgart_base; /* gfx GART bus base address */
|
|
uint64_t *ca_gfxgart; /* gfx GART vm address */
|
|
uint32_t ca_gfxgart_entries;
|
|
uint32_t ca_gfxgart_start; /* agpgart start index in ca_gart */
|
|
};
|
|
|
|
/*
|
|
* Common tioca info shared between kernel and prom
|
|
*
|
|
* DO NOT CHANGE THIS STRUCT WITHOUT MAKING CORRESPONDING CHANGES
|
|
* TO THE PROM VERSION.
|
|
*/
|
|
|
|
struct tioca_common {
|
|
struct pcibus_bussoft ca_common; /* common pciio header */
|
|
|
|
uint32_t ca_rev;
|
|
uint32_t ca_closest_nasid;
|
|
|
|
uint64_t ca_prom_private;
|
|
uint64_t ca_kernel_private;
|
|
};
|
|
|
|
/**
|
|
* tioca_paddr_to_gart - Convert an SGI coretalk address to a CA GART entry
|
|
* @paddr: page address to convert
|
|
*
|
|
* Convert a system [coretalk] address to a GART entry. GART entries are
|
|
* formed using the following:
|
|
*
|
|
* data = ( (1<<63) | ( (REMAP_NODE_ID << 40) | (MD_CHIPLET_ID << 38) |
|
|
* (REMAP_SYS_ADDR) ) >> 12 )
|
|
*
|
|
* DATA written to 1 GART TABLE Entry in system memory is remapped system
|
|
* addr for 1 page
|
|
*
|
|
* The data is for coretalk address format right shifted 12 bits with a
|
|
* valid bit.
|
|
*
|
|
* GART_TABLE_ENTRY [ 25:0 ] -- REMAP_SYS_ADDRESS[37:12].
|
|
* GART_TABLE_ENTRY [ 27:26 ] -- SHUB MD chiplet id.
|
|
* GART_TABLE_ENTRY [ 41:28 ] -- REMAP_NODE_ID.
|
|
* GART_TABLE_ENTRY [ 63 ] -- Valid Bit
|
|
*/
|
|
static inline u64
|
|
tioca_paddr_to_gart(unsigned long paddr)
|
|
{
|
|
/*
|
|
* We are assuming right now that paddr already has the correct
|
|
* format since the address from xtalk_dmaXXX should already have
|
|
* NODE_ID, CHIPLET_ID, and SYS_ADDR in the correct locations.
|
|
*/
|
|
|
|
return ((paddr) >> 12) | (1UL << 63);
|
|
}
|
|
|
|
/**
|
|
* tioca_physpage_to_gart - Map a host physical page for SGI CA based DMA
|
|
* @page_addr: system page address to map
|
|
*/
|
|
|
|
static inline unsigned long
|
|
tioca_physpage_to_gart(uint64_t page_addr)
|
|
{
|
|
uint64_t coretalk_addr;
|
|
|
|
coretalk_addr = PHYS_TO_TIODMA(page_addr);
|
|
if (!coretalk_addr) {
|
|
return 0;
|
|
}
|
|
|
|
return tioca_paddr_to_gart(coretalk_addr);
|
|
}
|
|
|
|
/**
|
|
* tioca_tlbflush - invalidate cached SGI CA GART TLB entries
|
|
* @tioca_kernel: CA context
|
|
*
|
|
* Invalidate tlb entries for a given CA GART. Main complexity is to account
|
|
* for revA bug.
|
|
*/
|
|
static inline void
|
|
tioca_tlbflush(struct tioca_kernel *tioca_kernel)
|
|
{
|
|
volatile uint64_t tmp;
|
|
volatile struct tioca *ca_base;
|
|
struct tioca_common *tioca_common;
|
|
|
|
tioca_common = tioca_kernel->ca_common;
|
|
ca_base = (struct tioca *)tioca_common->ca_common.bs_base;
|
|
|
|
/*
|
|
* Explicit flushes not needed if GART is in cached mode
|
|
*/
|
|
if (tioca_kernel->ca_gart_iscoherent) {
|
|
if (TIOCA_WAR_ENABLED(PV910244, tioca_common)) {
|
|
/*
|
|
* PV910244: RevA CA needs explicit flushes.
|
|
* Need to put GART into uncached mode before
|
|
* flushing otherwise the explicit flush is ignored.
|
|
*
|
|
* Alternate WAR would be to leave GART cached and
|
|
* touch every CL aligned GART entry.
|
|
*/
|
|
|
|
ca_base->ca_control2 &= ~(CA_GART_MEM_PARAM);
|
|
ca_base->ca_control2 |= CA_GART_FLUSH_TLB;
|
|
ca_base->ca_control2 |=
|
|
(0x2ull << CA_GART_MEM_PARAM_SHFT);
|
|
tmp = ca_base->ca_control2;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Gart in uncached mode ... need an explicit flush.
|
|
*/
|
|
|
|
ca_base->ca_control2 |= CA_GART_FLUSH_TLB;
|
|
tmp = ca_base->ca_control2;
|
|
}
|
|
|
|
extern uint32_t tioca_gart_found;
|
|
extern int tioca_init_provider(void);
|
|
extern void tioca_fastwrite_enable(struct tioca_kernel *tioca_kern);
|
|
#endif /* _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H */
|