/*
* AGPGART driver.
- * Copyright (C) 2002-2003 Dave Jones.
+ * Copyright (C) 2002-2004 Dave Jones.
* Copyright (C) 1999 Jeff Hartmann.
* Copyright (C) 1999 Precision Insight, Inc.
* Copyright (C) 1999 Xi Graphics, Inc.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
- * TODO:
+ * TODO:
* - Allocate more than order 0 pages to avoid too much linear map splitting.
*/
#include <linux/config.h>
#include <linux/vmalloc.h>
#include "agp.h"
-__u32 *agp_gatt_table;
+__u32 *agp_gatt_table;
int agp_memory_reserved;
/*
*/
EXPORT_SYMBOL_GPL(agp_memory_reserved);
-/*
+/*
* Generic routines for handling agp_memory structures -
* They use the basic page allocation routines to do the brunt of the work.
*/
* agp_allocate_memory - allocate a group of pages of a certain type.
*
* @page_count: size_t argument of the number of pages
- * @type: u32 argument of the type of memory to be allocated.
+ * @type: u32 argument of the type of memory to be allocated.
*
* Every agp bridge device will allow you to allocate AGP_NORMAL_MEMORY which
* maps to physical ram. Any other type is device dependent.
*
- * It returns NULL whenever memory is unavailable.
+ * It returns NULL whenever memory is unavailable.
*/
struct agp_memory *agp_allocate_memory(size_t page_count, u32 type)
{
/**
* agp_bind_memory - Bind an agp_memory structure into the GATT.
- *
+ *
* @curr: agp_memory pointer
* @pg_start: an offset into the graphics aperture translation table
*
/**
* agp_unbind_memory - Removes an agp_memory structure from the GATT
- *
+ *
* @curr: agp_memory pointer to be removed from the GATT.
- *
+ *
* It returns -EINVAL if this piece of agp_memory is not currently bound to
* the graphics aperture translation table or if the agp_memory pointer == NULL
*/
*cmd &= ~(AGPSTAT2_1X | AGPSTAT2_4X); /* 2X */
if (*cmd & AGPSTAT2_1X)
- *cmd &= ~(AGPSTAT2_2X | AGPSTAT2_4X); /* 1Xf */
+ *cmd &= ~(AGPSTAT2_2X | AGPSTAT2_4X); /* 1X */
}
-
+/*
+ * mode = requested mode.
+ * cmd = PCI_AGP_STATUS from agp bridge.
+ * tmp = PCI_AGP_STATUS from graphic card.
+ */
static void agp_v3_parse_one(u32 *mode, u32 *cmd, u32 *tmp)
{
+ u32 origcmd=*cmd, origtmp=*tmp;
+
/* ARQSZ - Set the value to the maximum one.
* Don't allow the mode register to override values. */
*cmd = ((*cmd & ~AGPSTAT_ARQSZ) |
*mode |= AGPSTAT3_4X;
}
- if (!((*cmd & AGPSTAT3_8X) && (*tmp & AGPSTAT3_8X) && (*mode & AGPSTAT3_8X)))
- *cmd &= ~AGPSTAT3_8X;
+ if (*mode & AGPSTAT3_8X) {
+ if (!(*cmd & AGPSTAT3_8X)) {
+ *cmd &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
+ *cmd |= AGPSTAT3_4X;
+ printk ("%s requested AGPx8 but bridge not capable.\n", current->comm);
+ return;
+ }
+ if (!(*tmp & AGPSTAT3_8X)) {
+ *cmd &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
+ *cmd |= AGPSTAT3_4X;
+ printk ("%s requested AGPx8 but graphic card not capable.\n", current->comm);
+ return;
+ }
+ /* All set, bridge & device can do AGP x8*/
+ *cmd &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD);
+ return;
- if (!((*cmd & AGPSTAT3_4X) && (*tmp & AGPSTAT3_4X) && (*mode & AGPSTAT3_4X)))
- *cmd &= ~AGPSTAT3_4X;
+ } else {
- /* Clear out unwanted bits. */
- if (*cmd & AGPSTAT3_8X)
- *cmd &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD);
- if (*cmd & AGPSTAT3_4X)
+ /*
+ * If we didn't specify AGPx8, we can only do x4.
+ * If the hardware can't do x4, we're up shit creek, and never
+ * should have got this far.
+ */
*cmd &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
+ if ((*cmd & AGPSTAT3_4X) && (*tmp & AGPSTAT3_4X))
+ *cmd |= AGPSTAT3_4X;
+ else {
+ printk (KERN_INFO PFX "Badness. Don't know which AGP mode to set. "
+ "[cmd:%x tmp:%x fell back to:- cmd:%x tmp:%x]\n",
+ origcmd, origtmp, *cmd, *tmp);
+ if (!(*cmd & AGPSTAT3_4X))
+ printk (KERN_INFO PFX "Bridge couldn't do AGP x4.\n");
+ if (!(*tmp & AGPSTAT3_4X))
+ printk (KERN_INFO PFX "Graphic card couldn't do AGP x4.\n");
+ }
+ }
}
//FIXME: This doesn't smell right.
if (!cap_ptr)
continue;
+ //FIXME: We should probably skip anything here that
+ // isn't an AGP graphic card.
/*
- * Ok, here we have a AGP device. Disable impossible
+ * Ok, here we have a AGP device. Disable impossible
* settings, and adjust the readqueue to the minimum.
*/
pci_read_config_dword(device, cap_ptr+PCI_AGP_STATUS, &tmp);
cmd = ((cmd & ~AGPSTAT_RQ_DEPTH) |
min_t(u32, (mode & AGPSTAT_RQ_DEPTH),
min_t(u32, (cmd & AGPSTAT_RQ_DEPTH), (tmp & AGPSTAT_RQ_DEPTH))));
-
+
/* disable FW if it's not supported */
if (!((cmd & AGPSTAT_FW) && (tmp & AGPSTAT_FW) && (mode & AGPSTAT_FW)))
cmd &= ~AGPSTAT_FW;
agp_bridge->current_size;
break;
}
- temp = agp_bridge->current_size;
+ temp = agp_bridge->current_size;
} else {
agp_bridge->aperture_size_idx = i;
}
SetPageReserved(page);
agp_bridge->gatt_table_real = (u32 *) table;
- agp_gatt_table = (void *)table;
+ agp_gatt_table = (void *)table;
agp_bridge->driver->cache_flush();
agp_bridge->gatt_table = ioremap_nocache(virt_to_phys(table),
EXPORT_SYMBOL(agp_generic_free_by_type);
-/*
+/*
* Basic Page Allocation Routines -
- * These routines handle page allocation and by default they reserve the allocated
+ * These routines handle page allocation and by default they reserve the allocated
* memory. They also handle incrementing the current_memory_agp value, Which is checked
* against a maximum value.
*/
page = alloc_page(GFP_KERNEL);
if (page == NULL)
- return 0;
+ return NULL;
map_page_into_agp(page);
/* End Basic Page Allocation Routines */
-/**
+/**
* agp_enable - initialise the agp point-to-point connection.
- *
+ *
* @mode: agp mode register value to configure with.
*/
void agp_enable(u32 mode)