X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fagp%2Fgeneric.c;h=f656624374615236d8af8a238482f47f892a82e1;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=ba6c102d26acbfd615690b4a61709a0a969208dc;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index ba6c102d2..f65662437 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -1,6 +1,6 @@ /* * 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. @@ -18,12 +18,12 @@ * 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 @@ -37,7 +37,7 @@ #include #include "agp.h" -__u32 *agp_gatt_table; +__u32 *agp_gatt_table; int agp_memory_reserved; /* @@ -46,7 +46,7 @@ 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. */ @@ -142,12 +142,12 @@ EXPORT_SYMBOL(agp_free_memory); * 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) { @@ -311,7 +311,7 @@ EXPORT_SYMBOL(agp_copy_info); /** * 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 * @@ -347,9 +347,9 @@ EXPORT_SYMBOL(agp_bind_memory); /** * 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 */ @@ -404,12 +404,18 @@ static void agp_v2_parse_one(u32 *mode, u32 *cmd, u32 *tmp) *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) | @@ -452,17 +458,43 @@ static void agp_v3_parse_one(u32 *mode, u32 *cmd, u32 *tmp) *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. @@ -479,8 +511,10 @@ u32 agp_collect_device_status(u32 mode, u32 cmd) 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); @@ -489,7 +523,7 @@ u32 agp_collect_device_status(u32 mode, u32 cmd) 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; @@ -663,7 +697,7 @@ int agp_generic_create_gatt_table(void) agp_bridge->current_size; break; } - temp = agp_bridge->current_size; + temp = agp_bridge->current_size; } else { agp_bridge->aperture_size_idx = i; } @@ -684,7 +718,7 @@ int agp_generic_create_gatt_table(void) 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), @@ -870,9 +904,9 @@ void agp_generic_free_by_type(struct agp_memory *curr) 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. */ @@ -883,7 +917,7 @@ void *agp_generic_alloc_page(void) page = alloc_page(GFP_KERNEL); if (page == NULL) - return 0; + return NULL; map_page_into_agp(page); @@ -914,9 +948,9 @@ EXPORT_SYMBOL(agp_generic_destroy_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)