diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/Kconfig patch_script_temp/drivers/gpu/drm/Kconfig --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/Kconfig 2009-08-27 11:30:10.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/Kconfig 2009-10-06 10:30:05.000000000 -0700 @@ -154,3 +154,10 @@ Choose this option if you have a Poulsbo or Moorestown platform. If M is selected the module will be called psb. + +config IEGD + tristate "Intel IEGD" + depends on DRM + help + Choose this option for the Intel Embedded Graphics Driver (IEGD) + diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/Makefile patch_script_temp/drivers/gpu/drm/Makefile --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/Makefile 2009-08-27 11:30:10.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/Makefile 2009-10-06 10:30:05.000000000 -0700 @@ -32,3 +32,4 @@ obj-$(CONFIG_DRM_SIS) += sis/ obj-$(CONFIG_DRM_SAVAGE)+= savage/ obj-$(CONFIG_DRM_VIA) +=via/ +obj-$(CONFIG_IEGD) += iegd/ diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/Makefile patch_script_temp/drivers/gpu/drm/iegd/Makefile --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/Makefile 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/Makefile 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,9 @@ + + +ccflags-y := -Idrivers/gpu/drm/iegd/include +ccflags-y += -Idrivers/char/agp -Iinclude/drm + +iegd_mod-objs := agp/pci.o agp/global.o agp/drv_alm.o agp/drv_nap.o agp/drv_plb.o agp/drv_cmn.o agp/drv_gn4.o drm/iegd_drv.o drm/iegd_interface.o drm/iegd_interface_265.o drm/iegd_interface_2611.o drm/iegd_interface_2615.o drm/iegd_interface_2624.o drm/psb_irq.o + +obj-$(CONFIG_IEGD) += iegd_mod.o + diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/agp_test.c patch_script_temp/drivers/gpu/drm/iegd/agp/agp_test.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/agp_test.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/agp/agp_test.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,314 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: agp_test.c + * $Revision: 1.5 $ + *---------------------------------------------------------------------------- + * Unit level test for IEGD AGP + * Copyright © 2009 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#include +#include +#include +#include +#include +#include +#include + +/*#define PAGE_SIZE 1024*/ + +#define VERBOSE "-v" + +int verbose = 0; +int file_desc, temp, length; +unsigned char *mmap_gart; + +int init_agp(void) +{ + agp_info info; + agp_setup setup; + + if (verbose) + { + printf("Testing ioctl AGPIOC_ACQUIRE.\n"); + } + if(ioctl(file_desc, AGPIOC_ACQUIRE) != 0) + { + printf("Error on AGPIOC_ACQUIRE.\n"); + printf("Reinstall IKM.\n"); + exit(-1); + } + if (verbose) + { + printf("Testing ioctl call for info init\n"); + } + if(ioctl(file_desc, AGPIOC_INFO, &info) != 0) + { + printf("Error on AGPIOC_INFO\n"); + printf("Reinstall IKM.\n"); + exit(-1); + } + if (verbose) + { + printf("Testing init info\n version:%i.%i,\n id:0x%lx,\n mode:0x%lx,\n" + " base:0x%lx,\n size:%i,\n total mem:%i,\n system mem:%i,\n" + " used mem:%i\n", info.version.major, info.version.minor, + info.bridge_id, info.agp_mode, info.aper_base, info.aper_size, + info.pg_total, info.pg_system, info.pg_used); + + printf("Testing mmap the device\n"); + } + length = info.aper_size*0x100000; + mmap_gart = mmap(NULL, info.aper_size*0x100000, + PROT_READ | PROT_WRITE, MAP_SHARED, file_desc, 0); + if(mmap_gart == (unsigned char *) 0xFFFFFFFF) + { + printf("Error on mmap\n"); + printf("Reinstall IKM.\n"); + close(file_desc); + exit(-1); + } + + setup.agp_mode = info.agp_mode; + if (verbose) + { + printf("Testing ioctl AGPIOC_SETUP\n"); + } + if(ioctl(file_desc, AGPIOC_SETUP, &setup) != 0) + { + printf("Error on AGPIOC_SETUP\n"); + printf("Reinstall IKM.\n"); + exit(-1); + } +} + +void gart_unbind(int key) +{ + agp_unbind unbind; + unbind.key = key; + unbind.priority = 0; + if (verbose) + { + printf("Testing ioctl AGPIOC_UNBIND\n"); + } + if(ioctl(file_desc, AGPIOC_UNBIND, &unbind) != 0) + { + printf("Error on AGPIOC_UNBIND\n"); + printf("Reinstall IKM.\n"); + exit(-1); + } +} + +void gart_bind(int key) +{ + agp_bind bind; + bind.key = key; + agp_info info; + + int page_size = 4000; + int aper_size, gtt_entries, bind_error; + + if(ioctl(file_desc, AGPIOC_INFO, &info) != 0) + { + printf("Error on AGPIOC_INFO\n"); + printf("Reinstall IKM.\n"); + exit(-1); + } + aper_size = info.aper_size; + gtt_entries = aper_size*1000000/page_size; + if (verbose) + { + printf("max memory: %i\n", gtt_entries); + } + + do + { + bind_error = 0; + bind.pg_start = page_size; + printf("Testing ioctl AGPIOC_BIND\n"); + if(ioctl(file_desc, AGPIOC_BIND, &bind) != 0) + { + if (page_size < gtt_entries) + { + page_size = page_size+4000; + printf("Trying new address for bind %i.\n", page_size); + bind_error = 1; + } + else + { + printf("Error on AGPIOC_BIND\n"); + printf("Reinstall IKM."); + exit(-1); + } + } + } while (bind_error); + printf("Sucessful bind.\n"); +} + +int gart_alloc(int count) +{ + agp_allocate allocate; + + allocate.type = 0; + allocate.pg_count = count; + if (verbose) + { + printf("Testing ioctl AGPIOC_ALLOCATE\n"); + } + if(ioctl(file_desc, AGPIOC_ALLOCATE, &allocate) != 0) + { + printf("Error on AGPIOC_ALLOCATE\n"); + printf("Reinstall IKM."); + exit(-1); + } + + gart_bind(allocate.key); + + return(allocate.key); +} + +void gart_free(int key) +{ + + gart_unbind(key); + if (verbose) + { + printf("Testing ioctl AGPIOC_DEALLOCATE\n"); + } + if(ioctl(file_desc, AGPIOC_DEALLOCATE, key) != 0) + { + printf("Error on AGPIOC_DEALLOCATE\n"); + printf("Reinstall IKM.\n"); + exit(-1); + } +} + +int main(int argc, char *argv[]) +{ + /* Check for verbose mode */ + int i, key, key1; + agp_info info; + + for (i = 1; i < argc; i++) + { + if(strcmp(argv[1], VERBOSE) == 0) + { + verbose = 1; + printf("Verbose mode.\n"); + } + } + + /* Open the agpgart */ + file_desc=open("/dev/agpgart",O_RDWR); + + if(file_desc<0){ + printf("Cannot open device file:%d\n",file_desc); + printf("Check for root level permissions."); + exit(-1); + } + + if (verbose) + { + printf("Open device file:%d\n",file_desc); + /* This the ioctl that allocates physical memory */ + printf("Testing ioctl for memory allocation\n"); + } + + init_agp(); + + key = gart_alloc(64); + key1 = gart_alloc(0); + if (verbose) + { + printf("Testing ioctl call for info\n"); + } + if(ioctl(file_desc, AGPIOC_INFO, &info) != 0) + { + close(file_desc); + printf("Error on AGPIOC_INFO\n"); + printf("Reinstall IKM.\n"); + exit(-1); + } + + if (verbose) + { + printf("Testing init info\n version:%i.%i,\n id:0x%lx,\n mode:0x%lx,\n" + " base:0x%lx,\n size:%i,\n total mem:%i,\n system mem:%i,\n" + " used mem:%i\n", info.version.major, info.version.minor, + info.bridge_id, info.agp_mode, info.aper_base, info.aper_size, + info.pg_total, info.pg_system, info.pg_used); + } + + gart_free(key); + gart_free(key1); + + if (munmap(mmap_gart, length) < 0) + { + close(file_desc); + printf("Error on munmap\n"); + printf("Reinstall IKM.\n"); + exit(-1); + } + + if (verbose) + { + printf("Testing ioctl AGPIOC_RELEASE\n"); + } + if(ioctl(file_desc, AGPIOC_RELEASE) != 0) + { + close(file_desc); + printf("Error on AGPIOC_RELEASE\n"); + printf("Reinstall IKM."); + exit(-1); + } + + printf("AGPGART successfully loaded\n"); + + close(file_desc); + + return 0; + + +} diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/drv_alm.c patch_script_temp/drivers/gpu/drm/iegd/agp/drv_alm.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/drv_alm.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/agp/drv_alm.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,447 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: drv_alm.c + * $Revision: 1.7 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "global.h" +#include "intelpci.h" + +static int iegd_alm_configure(void); +static int iegd_alm_fetch_size(void); +static void iegd_alm_cleanup(void); +static void iegd_alm_tlbflush(struct agp_memory *mem); + +static int iegd_alm_insert_entries( + struct agp_memory *mem, + off_t pg_start, + int type); + +static int iegd_alm_remove_entries( + struct agp_memory *mem, + off_t pg_start, + int type); + +struct aper_size_info_fixed intel_i830_sizes[] = +{ + {128, 32768, 5}, + /* The 64M mode still requires a 128k gatt */ + {64, 16384, 5}, + {256, 65536, 6}, + {512, 131072, 7}, +}; + +struct aper_size_info_fixed intel_i810_sizes[] = +{ + {64, 16384, 4}, + {32, 8192, 4}, +}; + +bridge_driver_t drv_alm = { + .owner = THIS_MODULE, + .size_type = FIXED_APER_SIZE, + .aperture_sizes = 0, + .num_aperture_sizes = 0, + .needs_scratch_page = TRUE, + .configure = iegd_alm_configure, + .fetch_size = iegd_alm_fetch_size, + .cleanup = iegd_alm_cleanup, + .tlb_flush = iegd_alm_tlbflush, + .mask_memory = iegd_cmn_mask_memory, + .masks = iegd_cmn_masks, + .agp_enable = iegd_cmn_agp_enable, + .cache_flush = global_cache_flush, + .create_gatt_table = NULL, + .free_gatt_table = NULL, + .insert_memory = iegd_alm_insert_entries, + .remove_memory = iegd_alm_remove_entries, + .alloc_by_type = iegd_cmn_alloc_by_type, + .free_by_type = iegd_cmn_free_by_type, + .agp_alloc_page = agp_generic_alloc_page, + .agp_destroy_page = agp_generic_destroy_page, +}; + +static int iegd_alm_configure(void) +{ + struct aper_size_info_fixed *current_size; + u32 temp; + u16 gmch_ctrl; + int i; + int entries_start = 0; + + AGN_DEBUG("Enter"); + + current_size = A_SIZE_FIX(agp_bridge->current_size); + + if(private_data.pdev->device == PCI_DEVICE_ID_810 || + private_data.pdev->device == PCI_DEVICE_ID_810DC || + private_data.pdev->device == PCI_DEVICE_ID_810E || + private_data.pdev->device == PCI_DEVICE_ID_815) { + + pci_read_config_dword(private_data.pdev, I810_MMADDR, &temp); + temp &= 0xfff80000; + + private_data.registers = ioremap(temp, 128*4096); + if(!private_data.registers) { + AGN_ERROR("Unable to remap memory"); + return -ENOMEM; + } + + if((readl(private_data.registers+I810_DRAM_CTL) + & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) { + AGN_LOG("Detected 4MB dedicated video RAM."); + private_data.num_dcache_entries = 1024; + } + } else if(private_data.pdev->device == PCI_DEVICE_ID_830M || + private_data.pdev->device == PCI_DEVICE_ID_845G || + private_data.pdev->device == PCI_DEVICE_ID_855 || + private_data.pdev->device == PCI_DEVICE_ID_865G) { + + entries_start = private_data.gtt_entries; + pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); + gmch_ctrl |= I830_GMCH_ENABLED; + pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl); + } + + /* Get based address of the graphic aperture */ + pci_read_config_dword(private_data.pdev, I810_GMADDR, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + /* Write the based address of the gtt table to the + * page table control register */ + writel(agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED, + private_data.registers+I810_PGETBL_CTL); + readl(private_data.registers+I810_PGETBL_CTL); + + if (agp_bridge->driver->needs_scratch_page) { + for (i = entries_start; i < current_size->num_entries; i++) { + writel(agp_bridge->scratch_page, + private_data.registers+I810_PTE_BASE+(i*4)); + /* PCI Posting. */ + readl(private_data.registers+I810_PTE_BASE+(i*4)); + } + } + + global_cache_flush(); + + AGN_DEBUG("Exit"); + return 0; +} + + +static int iegd_alm_fetch_size(void) +{ + u32 smram_miscc; + u16 gmch_ctrl; + struct aper_size_info_fixed *values; + + AGN_DEBUG("Enter"); + + values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); + + if(private_data.pdev->device == PCI_DEVICE_ID_810 || + private_data.pdev->device == PCI_DEVICE_ID_810DC || + private_data.pdev->device == PCI_DEVICE_ID_810E || + private_data.pdev->device == PCI_DEVICE_ID_815) { + + pci_read_config_dword(agp_bridge->dev, I810_SMRAM_MISCC, + &smram_miscc); + + if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) { + printk(KERN_WARNING PFX "i810 is disabled\n"); + return 0; + } + if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == + I810_GFX_MEM_WIN_32M) { + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values + 1); + agp_bridge->aperture_size_idx = 1; + return values[1].size; + } else { + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values); + agp_bridge->aperture_size_idx = 0; + return values[0].size; + } + } else if(private_data.pdev->device == PCI_DEVICE_ID_830M || + private_data.pdev->device == PCI_DEVICE_ID_845G || + private_data.pdev->device == PCI_DEVICE_ID_855 || + private_data.pdev->device == PCI_DEVICE_ID_865G) { + + if (agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82830_HB && + agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82845G_HB) { + /* 855GM/852GM/865G has 128MB aperture size */ + agp_bridge->previous_size = + agp_bridge->current_size = (void *) values; + agp_bridge->aperture_size_idx = 0; + return values[0].size; + } + + pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); + + if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { + agp_bridge->previous_size = + agp_bridge->current_size = (void *) values; + agp_bridge->aperture_size_idx = 0; + return values[0].size; + } else { + agp_bridge->previous_size = + agp_bridge->current_size = (void *) (values + 1); + agp_bridge->aperture_size_idx = 1; + return values[1].size; + } + } + + AGN_DEBUG("Exit"); + + return 0; +} + +static void iegd_alm_cleanup(void) +{ + + AGN_DEBUG("Enter"); + + if(private_data.pdev->device == PCI_DEVICE_ID_810 || + private_data.pdev->device == PCI_DEVICE_ID_810DC || + private_data.pdev->device == PCI_DEVICE_ID_810E || + private_data.pdev->device == PCI_DEVICE_ID_815) { + + writel(0, private_data.registers+I810_PGETBL_CTL); + readl(private_data.registers); /* PCI Posting. */ + } + + /* Unmap the mapping of the mmio */ + iounmap((void *) private_data.registers); + + AGN_DEBUG("Exit"); +} + +static void iegd_alm_tlbflush(struct agp_memory *mem) +{ + AGN_DEBUG("Enter"); + return; + AGN_DEBUG("Exit"); +} + +int AGP_CREATE_GATT(iegd_alm_create_gatt_table) +{ + int num_entries = 0; + int i830_gtt_page_order = 0; + u32 gtt_bus_addr = 0; + u32 mmio_bus_addr = 0; + char *gtt_table = NULL; + char *gtt_table_end = NULL; + char *current_entry = NULL; + int gtt_enabled = FALSE; + struct page *gtt_table_page = NULL; + struct aper_size_info_fixed *aper_size = NULL; + + AGN_DEBUG("Enter"); + + agp_bridge->gatt_table_real = NULL; + agp_bridge->gatt_table = NULL; + aper_size = (struct aper_size_info_fixed *)agp_bridge->current_size; + + /* Find and save the address of the MMIO registers */ + pci_read_config_dword(private_data.pdev, I810_MMADDR, + &mmio_bus_addr); + mmio_bus_addr &= 0xFFF80000; + + private_data.registers = (volatile u8 *) + ioremap(mmio_bus_addr, 128 * 4096); + + if (!private_data.registers) { + AGN_ERROR("ioremap failed to map"); + return (-ENOMEM); + } + + /* Get value on the control register */ + gtt_bus_addr = readl(private_data.registers+I810_PGETBL_CTL) & + 0xFFFFF000; + gtt_enabled = readl(private_data.registers+I810_PGETBL_CTL) & + I810_PGETBL_ENABLED; + global_cache_flush(); + + /* we have to call this as early as possible after the MMIO base address + * is known */ + iegd_cmn_init_gtt_entries(); + + /* If GTT does not exist, which can happen if a PCI graphics card is the + * boot-up display device, then we will have to allocate the GTT table + * ourselves + */ + if (!gtt_enabled) { + + AGN_DEBUG("Gtt is disabled"); + + i830_gtt_page_order = aper_size->page_order; + num_entries = aper_size->num_entries; + gtt_table = (char *) __get_free_pages( + GFP_KERNEL, i830_gtt_page_order); + gtt_table_end = gtt_table + + ((PAGE_SIZE * (1<flags); + } + agp_bridge->gatt_bus_addr = virt_to_phys(gtt_table); + } else { + agp_bridge->gatt_bus_addr = gtt_bus_addr; + } + + AGN_DEBUG("Exit"); + return(0); +} + + +static int iegd_alm_insert_entries( + struct agp_memory *mem, + off_t pg_start, + int type) +{ + int i, j, num_entries; + void *temp; + + AGN_DEBUG("Enter"); + + temp = agp_bridge->current_size; + num_entries = A_SIZE_FIX(temp)->num_entries; + + if ((pg_start + mem->page_count) > num_entries) { + AGN_ERROR("Trying to write beyond aperture limit"); + AGN_DEBUG("pg_start=0x%.8lx, mem->page_count=%d," + "num_entries=%d", pg_start, mem->page_count, + num_entries); + return -EINVAL; + } + + if(private_data.pdev->device == PCI_DEVICE_ID_830M || + private_data.pdev->device == PCI_DEVICE_ID_845G || + private_data.pdev->device == PCI_DEVICE_ID_855 || + private_data.pdev->device == PCI_DEVICE_ID_865G) { + + if (pg_start < private_data.gtt_entries) { + AGN_ERROR("Trying to insert into local/stolen memory"); + AGN_DEBUG("pg_start == 0x%.8lx,private_data.gtt_entries ==" + "0x%.8x", pg_start,private_data.gtt_entries); + return -EINVAL; + } + } else if(private_data.pdev->device == PCI_DEVICE_ID_810 || + private_data.pdev->device == PCI_DEVICE_ID_810DC || + private_data.pdev->device == PCI_DEVICE_ID_810E || + private_data.pdev->device == PCI_DEVICE_ID_815) { + + for (j = pg_start; j < (pg_start + mem->page_count); j++) { + if (!PGE_EMPTY(agp_bridge, readl(agp_bridge->gatt_table+j))) { + AGN_ERROR("Device busy"); + return -EBUSY; + } + } + if (type != 0 || mem->type != 0) { + if ((type == AGP_DCACHE_MEMORY) && + (mem->type == AGP_DCACHE_MEMORY)) { + /* special insert */ + global_cache_flush(); + for (i = pg_start; i < (pg_start + mem->page_count); + i++) { + writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID, + private_data.registers+I810_PTE_BASE+(i*4)); + /* PCI Posting. */ + readl(private_data.registers + + I810_PTE_BASE+(i*4)); + } + global_cache_flush(); + agp_bridge->driver->tlb_flush(mem); + AGN_DEBUG("AGP_DCACHE_MEMORY.. Exit"); + return 0; + } + } + } + + if ((type != 0 && type != AGP_PHYS_MEMORY) || + (mem->type != 0 && mem->type != AGP_PHYS_MEMORY)) { + AGN_ERROR("Unsupported memory type"); + AGN_DEBUG("mem->type=%x", mem->type); + return -EINVAL; + } + + global_cache_flush(); + for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { + writel(AGP_MASK_GTT(), private_data.registers+I810_PTE_BASE+(j*4)); + /* PCI Posting. */ + readl(private_data.registers+I810_PTE_BASE+(j*4)); + } + + global_cache_flush(); + agp_bridge->driver->tlb_flush(mem); + + AGN_DEBUG("Exit"); + + return 0; +} + +static int iegd_alm_remove_entries( + struct agp_memory *mem, + off_t pg_start, + int type) +{ + int i; + + AGN_DEBUG("Enter"); + + global_cache_flush(); + + if(private_data.pdev->device == PCI_DEVICE_ID_830M || + private_data.pdev->device == PCI_DEVICE_ID_845G || + private_data.pdev->device == PCI_DEVICE_ID_855 || + private_data.pdev->device == PCI_DEVICE_ID_865G) { + + if (pg_start < private_data.gtt_entries) { + AGN_ERROR("Trying to disable local/stolen memory"); + AGN_DEBUG("pg_start=0x%.8lx, private_data.gtt_entries=%d", + pg_start, private_data.gtt_entries); + return -EINVAL; + } + } + + for (i = pg_start; i < (mem->page_count + pg_start); i++) { + writel(agp_bridge->scratch_page, + private_data.registers+I810_PTE_BASE+(i*4)); + /* PCI Posting. */ + readl(private_data.registers+I810_PTE_BASE+(i*4)); + } + + global_cache_flush(); + agp_bridge->driver->tlb_flush(mem); + + AGN_DEBUG("Exit"); + + return 0; +} + diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/drv_cmn.c patch_script_temp/drivers/gpu/drm/iegd/agp/drv_cmn.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/drv_cmn.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/agp/drv_cmn.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,682 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: drv_cmn.c + * $Revision: 1.28 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include "global.h" +#include "intelpci.h" +#include "interface_abs.h" +#include "igd_abs.h" + +static struct agp_memory *alloc_agpphysmem_i8xx( + size_t pg_count, int type); +static AGP_MEM_TYPE i8xx_alloc_pages(size_t pg_count, + unsigned int order); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) +static void i8xx_destroy_pages_by_addr(void *addr, + size_t pg_count, unsigned int order); +#define PAGES_OR_MEMORY(a) gart_to_virt(a->memory[0]) +#define DESTROY_PAGES i8xx_destroy_pages_by_addr +#else +static void i8xx_destroy_pages(struct page **pages, + size_t pg_count, unsigned int order); +#define PAGES_OR_MEMORY(a) a->pages +#define DESTROY_PAGES i8xx_destroy_pages +#endif + +dispatch_table_t driver_dispatch_list[] = { + { PCI_DEVICE_ID_810, &drv_alm }, + { PCI_DEVICE_ID_810DC, &drv_alm }, + { PCI_DEVICE_ID_810E, &drv_alm }, + { PCI_DEVICE_ID_815, &drv_alm }, + { PCI_DEVICE_ID_830M, &drv_alm }, + { PCI_DEVICE_ID_845G, &drv_alm }, + { PCI_DEVICE_ID_855, &drv_alm }, + { PCI_DEVICE_ID_865G, &drv_alm }, + { PCI_DEVICE_ID_915GD, &drv_nap }, + { PCI_DEVICE_ID_915AL, &drv_nap }, + { PCI_DEVICE_ID_945G, &drv_nap }, + { PCI_DEVICE_ID_945GM, &drv_nap }, + { PCI_DEVICE_ID_945GME,&drv_nap }, + { PCI_DEVICE_ID_Q35, &drv_nap }, + { PCI_DEVICE_ID_Q35A2, &drv_nap }, + { PCI_DEVICE_ID_965G, &drv_gn4 }, + { PCI_DEVICE_ID_946GZ, &drv_gn4 }, + { PCI_DEVICE_ID_G965, &drv_gn4 }, + { PCI_DEVICE_ID_Q965, &drv_gn4 }, + { PCI_DEVICE_ID_GM965, &drv_gn4 }, + { PCI_DEVICE_ID_GME965,&drv_gn4 }, + { PCI_DEVICE_ID_GM45, &drv_gm45}, +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,5) + { PCI_DEVICE_ID_PLB, &drv_plb }, +#endif + { PCI_DEVICE_ID_ELK, &drv_gm45}, + { PCI_DEVICE_ID_Q45, &drv_gm45}, + { PCI_DEVICE_ID_G45, &drv_gm45}, + { PCI_DEVICE_ID_G41, &drv_gm45}, + { 0, NULL }, +}; + +/* Structure contained bit mask for the page table entries */ +struct gatt_mask iegd_cmn_masks[] = +{ + {.mask = I810_PTE_VALID, .type = 0}, + {.mask = (I810_PTE_VALID | I810_PTE_LOCAL), + .type = AGP_DCACHE_MEMORY}, + {.mask = I810_PTE_VALID, .type = 0} +}; + + +int iegd_cmn_configure(void) +{ + struct aper_size_info_fixed *current_size; + u32 temp; + u16 gmch_ctrl; + int i; + + AGN_DEBUG("Enter"); + + current_size = A_SIZE_FIX(agp_bridge->current_size); + + pci_read_config_dword(private_data.pdev, I915_GMADDR, &temp); + + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + if(!((private_data.pdev->device == PCI_DEVICE_ID_Q35) || + (private_data.pdev->device == PCI_DEVICE_ID_Q35A2))) { + pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); + gmch_ctrl |= I830_GMCH_ENABLED; + pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl); + + global_cache_flush(); + agp_bridge->driver->tlb_flush(0); + + writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, + private_data.registers+I810_PGETBL_CTL); + /* PCI Posting. */ + readl(private_data.registers+I810_PGETBL_CTL); + } + + AGN_DEBUG ("gtt_entries: %X", private_data.gtt_entries); + if (agp_bridge->driver->needs_scratch_page) { + for (i = private_data.gtt_entries; + i < current_size->num_entries; i++) { + writel(agp_bridge->scratch_page, private_data.gtt+i); + readl(private_data.gtt+i); /* PCI Posting. */ + } + } + global_cache_flush(); + + AGN_DEBUG("Exit"); + + return 0; +} + +void iegd_cmn_init_gtt_entries(void) +{ + u16 gmch_ctrl; + u32 iegd_scratch, iegd_scratch2; + int gtt_entries; + u8 rdct; + int local = 0; + static const int ddt[4] = { 0, 16, 32, 64 }; + int size; + int gtt_enabled = FALSE; + + AGN_DEBUG("Enter"); + + /* This code original read the GMCH_CTRL register of the host + * bridge. This register is also mirrored on the VGA device at + * the same address. In the PLB family, the host bridge no + * longer contains the register. As a result, all platforms + * will now use the mirrored register. This breaks + * compatability with chipsets prior to 915G + */ + pci_read_config_word(private_data.pdev, I830_GMCH_CTRL, &gmch_ctrl); + + gtt_enabled = readl(private_data.registers + I810_PGETBL_CTL) & + I810_PGETBL_ENABLED; + + /* A note on stolen memory: + * Intel chipsets set aside a small area at the top of system memory + * for VGA framebuffers etc. When the Intel device is the VGA + * device, this memory is used to contain the GTT itself, and a scratch + * memory page. Therefore the actual available memory already populated + * in the GTT is the stolen memory minus the 4k scratch page minus the + * 128 page table. + * + * Additionally, the embedded firmware may further alter this amount. + * It can either allocate additional memory to be placed in the GTT + * or use some stolen memory for data. If the IEGD vBIOS has altered + * the amount we can detect it by reading a well-defined scratch + * register. + * + * When the Intel Graphics Device is not the VGA device, i.e. + * the system boots with a PCI card, then this driver discards + * the stolen memory. + * + * We obtain the size of the GTT, which is also stored (for some + * reason) at the top of stolen memory. Then we add 4KB to that + * for the video BIOS popup, which is also stored in there. */ + + size = agp_bridge->driver->fetch_size() + 4; + AGN_DEBUG("Size from fetch size + 4 = %x", size); + + if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB || + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) { + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I830_GMCH_GMS_STOLEN_512: + gtt_entries = KB(512) - KB(size); + break; + case I830_GMCH_GMS_STOLEN_1024: + gtt_entries = MB(1) - KB(size); + break; + case I830_GMCH_GMS_STOLEN_8192: + gtt_entries = MB(8) - KB(size); + break; + case I830_GMCH_GMS_LOCAL: + rdct = readb(private_data.registers+I830_RDRAM_CHANNEL_TYPE); + gtt_entries = (I830_RDRAM_ND(rdct) + 1) * + MB(ddt[I830_RDRAM_DDT(rdct)]); + local = 1; + break; + default: + gtt_entries = 0; + break; + } + } else { + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I855_GMCH_GMS_STOLEN_1M: + gtt_entries = MB(1) - KB(size); + break; + case I855_GMCH_GMS_STOLEN_4M: + gtt_entries = MB(4) - KB(size); + break; + case I855_GMCH_GMS_STOLEN_8M: + gtt_entries = MB(8) - KB(size); + break; + case I855_GMCH_GMS_STOLEN_16M: + gtt_entries = MB(16) - KB(size); + break; + case I855_GMCH_GMS_STOLEN_32M: + gtt_entries = MB(32) - KB(size); + break; + case I915_GMCH_GMS_STOLEN_48M: + /* Check it's really I915G */ + if (agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_915GD || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_915AL || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_945G || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_945GM || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_945GME || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_965G || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_G965 || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_Q965 || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_GM965 || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_GME965 || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_946GZ ) + gtt_entries = MB(48) - KB(size); + else + gtt_entries = 0; + break; + case I915_GMCH_GMS_STOLEN_64M: + /* Check it's really I915G */ + if (agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_915GD || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_915AL || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_945G || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_945GM || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_945GME || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_965G || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_G965 || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_Q965 || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_GM965 || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_GME965 || + agp_bridge->dev->device == PCI_DEVICE_ID_BRIDGE_946GZ ) + gtt_entries = MB(64) - KB(size); + else + gtt_entries = 0; + default: + gtt_entries = 0; + break; + } + } + + /* if GTT is not enabled, then initialize gtt entries to 0 */ + + if (!gtt_entries) { + AGN_DEBUG("GTT is disabled"); + AGN_LOG("IGD not primary, throwing away stolen memory."); + + /* Update the scratch registers to say that we have no stolen memory */ + writel((0xE1DF << 16), private_data.registers + 0x71410); + + iegd_scratch = readl(private_data.registers + 0x71410); + iegd_scratch |= 0x4; + + writel(iegd_scratch, private_data.registers + 0x71410); + + /* say that we have 0 stolen memory regardless of what was + * really in there */ + writel(0, private_data.registers + 0x71418); + + gtt_entries = 0; + } + + iegd_scratch = readl(private_data.registers + 0x71410); + + if(((iegd_scratch>>16) == 0xE1DF) && (iegd_scratch & 0x4)) { + AGN_LOG("IEGD Firmware Detected"); + /* IEGD firmware found, and Mem Reservation Flag present */ + iegd_scratch2 = readl(private_data.registers + 0x71418); + gtt_entries = (iegd_scratch2 & 0xFFFF) * 4096; + } + + if (gtt_entries > 0) + AGN_LOG("Detected %dK %s memory.", + gtt_entries / KB(1), local ? "local" : "stolen"); + else + AGN_LOG("No pre-allocated video memory detected.\n"); + + gtt_entries /= KB(4); + private_data.gtt_entries = gtt_entries; + + AGN_DEBUG("Exit"); +} + +int AGP_FREE_GATT(iegd_cmn_free_gatt_table) +{ + AGN_DEBUG("Enter"); + return 0; + AGN_DEBUG("Exit"); +} + +void AGP_ENABLE(iegd_cmn_agp_enable) +{ + AGN_DEBUG("Enter"); + return; + AGN_DEBUG("Exit"); +} + +struct agp_memory *iegd_cmn_alloc_by_type( + size_t pg_count, int type) +{ + struct agp_memory *new; + + AGN_DEBUG("Enter"); + + /* AGP_DCACHE_MEMORY use by certain chipset only, especially + * chipset from almador family. */ + if(private_data.pdev->device == PCI_DEVICE_ID_810 || + private_data.pdev->device == PCI_DEVICE_ID_810DC || + private_data.pdev->device == PCI_DEVICE_ID_810E || + private_data.pdev->device == PCI_DEVICE_ID_815) { + if (type == AGP_DCACHE_MEMORY) { + if (pg_count != private_data.num_dcache_entries) { + AGN_ERROR("Page count error"); + AGN_DEBUG("pg_count=%d, num_dcache_entries=%d", + pg_count, private_data.num_dcache_entries); + return NULL; + } + + new = agp_create_memory(1); + if (new == NULL) { + AGN_ERROR("Allocating memory failed"); + return NULL; + } + + new->type = AGP_DCACHE_MEMORY; + new->page_count = pg_count; + new->num_scratch_pages = 0; + vfree(new->AGP_MEMORY_MEMBER); //free pages or memory + AGN_DEBUG("AGP_DCACHE_MEMORY.. Exit"); + return new; + } + } + + if (type == AGP_PHYS_MEMORY) { + AGN_DEBUG("AGP_PHYS_MEMORY.. Exit"); + return alloc_agpphysmem_i8xx(pg_count, type); + } + + AGN_DEBUG("NULL.. Exit"); + return NULL; +} + +void iegd_cmn_free_by_type(struct agp_memory *curr) +{ + unsigned int order; + + AGN_DEBUG("Enter"); + + switch (curr->page_count) { + case 1: + order = 0; /* pg_count = 1 => 2 ^ 0 */ + break; + case 4: + order = 2; /* pg_count = 4 => 2 ^ 2 */ + break; + case 8: + order = 3; /* pg_count = 8 => 2 ^ 3 */ + break; + default: + /* This case should never happen */ + return; + } + + agp_free_key(curr->key); + if(curr->type == AGP_PHYS_MEMORY) { + DESTROY_PAGES(PAGES_OR_MEMORY(curr), curr->page_count, + order); + IGD_FREE_MEM(curr); + } + kfree(curr); + + AGN_DEBUG("Exit"); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) +static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) +{ + struct agp_memory *new; + void *addr; + unsigned int order, i; + + AGN_DEBUG("Enter"); + + /* To support RGBA hardware cursor which may require contiguous physical + * * memory to be allocated with either 1, 4 or 8 pages. 8 pages is + * * the worst case for 830 which requires 4 pages and 4 page alignment. + * */ + switch (pg_count) { + case 1: + order = 0; /* pg_count = 1 => 2 ^ 0 */ + break; + case 4: + order = 2; /* pg_count = 4 => 2 ^ 2 */ + break; + case 8: + order = 3; /* pg_count = 8 => 2 ^ 3 */ + break; + default: + return NULL; + } + + addr = i8xx_alloc_pages(pg_count, order); + if (addr == NULL) { + AGN_ERROR("Allocating pages failed"); + return NULL; + } + + new = agp_create_memory(pg_count); + if (new == NULL) { + AGN_ERROR("Allocating memory failed"); + return NULL; + } + + new->memory[0] = virt_to_gart(addr); + for (i = 1; i < pg_count; i++) { + new->memory[i] = new->memory[i-1] + PAGE_SIZE; + } + new->page_count = pg_count; + new->num_scratch_pages = pg_count; + new->type = AGP_PHYS_MEMORY; + new->physical = new->memory[0]; + + AGN_DEBUG("Exit"); + return new; +} +#else // kernel 31 or newer +static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) +{ + struct agp_memory *new; + struct page *page; + unsigned int order, i; + + AGN_DEBUG("Enter"); + + /* To support RGBA hardware cursor which may require contiguous physical + * memory to be allocated with either 1, 4 or 8 pages. 8 pages is + * the worst case for 830 which requires 4 pages and 4 page alignment. + */ + switch (pg_count) { + case 1: + order = 0; /* pg_count = 1 => 2 ^ 0 */ + break; + case 4: + order = 2; /* pg_count = 4 => 2 ^ 2 */ + break; + case 8: + order = 3; /* pg_count = 8 => 2 ^ 3 */ + break; + default: + return NULL; + } + + page = i8xx_alloc_pages(pg_count, order); + if (page == NULL) { + AGN_ERROR("Allocating pages failed"); + return NULL; + } + + new = agp_create_memory(pg_count); + if (new == NULL) { + AGN_ERROR("Allocating memory failed"); + return NULL; + } + + new->pages[0] = page; + if (pg_count > 1) { // if page count is 4 or 8 + for (i=0; i< pg_count-1; i++) { + new->pages[i+1] = new->pages[i] + 1; + } + } + new->page_count = pg_count; + new->num_scratch_pages = pg_count; + new->type = AGP_PHYS_MEMORY; + new->physical = page_to_phys(new->pages[0]); + return new; + + AGN_DEBUG("Exit"); +} +#endif + +static AGP_MEM_TYPE i8xx_alloc_pages(size_t pg_count, unsigned int order) +{ + struct page * page; + + AGN_DEBUG("Enter"); + + page = alloc_pages(GFP_KERNEL, order); + if (page == NULL) { + AGN_ERROR("Allocating kernel page failed"); + return NULL; + } + + if (SET_PAGES_UC(page, pg_count) < 0) { + SET_PAGES_WB(page, pg_count); + GLOBAL_FLUSH_TLB(); + __free_pages(page, pg_count); + AGN_ERROR("Change page attribute failed"); + return NULL; + } + GLOBAL_FLUSH_TLB(); + get_page(page); + + /* + * Starting kernel 2.6.23 locking will causing lot of trouble. This is + * because of the changes in page fault handler in the kernel. + */ + AGP_LOCK_PAGE(page); + atomic_inc(&agp_bridge->current_memory_agp); + return PAGE_ADDRESS(page); //returns page or addr depending on kernel + + AGN_DEBUG("Exit"); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) +static void i8xx_destroy_pages_by_addr(void *addr, + size_t pg_count, unsigned int order) +{ + struct page *page; + + AGN_DEBUG("Enter"); + + if (addr == NULL) + return; + + page = virt_to_page(addr); + SET_PAGES_WB(page, pg_count); + GLOBAL_FLUSH_TLB(); + put_page(page); + /* + * Starting kernel 2.6.23 locking will causing lot of trouble. This is + * because of the changes in page fault handler in the kernel. + */ + AGP_UNLOCK_PAGE(page); + + free_pages((unsigned long)addr, order); + atomic_dec(&agp_bridge->current_memory_agp); + + AGN_DEBUG("Exit"); +} + +#else //kernel is 31 or newer +static void i8xx_destroy_pages(struct page **pages, + size_t pg_count, unsigned int order) +{ + struct page *page; + int i; + + AGN_DEBUG("Enter"); + + if (pages == NULL) + return; + + GLOBAL_FLUSH_TLB(); + //The following code is based on agp_generic_destroy_pages in generic.c + for (i = 0; i < pg_count; i++) { + page = pages[i]; + + put_page(page); + __free_page(page); + atomic_dec(&agp_bridge->current_memory_agp); + pages[i] = NULL; + } + + AGN_DEBUG("Exit"); +} +#endif + +unsigned long AGP_MASK_MEMORY(iegd_cmn_mask_memory) +{ + struct agp_bridge_data *brdg = AGP_BRIDGE_VAR; + + // only converts if kernel is 2.6.31 or newer + unsigned long address = CONVERT_PAGE_TO_GART(addr); + + /* Type checking must be done elsewhere */ + return address | AGP_MASK_ADDR(brdg); +} + +int iegd_cmn_insert_entries(struct agp_memory *mem, + off_t pg_start, int type) +{ + int i,j,num_entries; + void *temp; + + AGN_DEBUG("Enter"); + + temp = agp_bridge->current_size; + num_entries = A_SIZE_FIX(temp)->num_entries; + + if (pg_start < private_data.gtt_entries) { + AGN_ERROR("Trying to insert into local/stolen memory"); + AGN_DEBUG("pg_start == 0x%.8lx,private_data.gtt_entries ==" + "%d", pg_start,private_data.gtt_entries); + return -EINVAL; + } + + /* If we try to write beyond gtt table, return error */ + if ((pg_start + mem->page_count) > num_entries) { + AGN_ERROR("Trying to write beyond aperture limit"); + AGN_DEBUG("pg_start=0x%.8lx, mem->page_count=%d," + "num_entries=%d", pg_start, mem->page_count, + num_entries); + return -EINVAL; + } + + /* The i830 can't check the GTT for entries since its read only, + * depend on the caller to make the correct offset decisions. + */ + + if ((type != 0 && type != AGP_PHYS_MEMORY) || + (mem->type != 0 && mem->type != AGP_PHYS_MEMORY)) { + AGN_ERROR("Unsupported memory type"); + AGN_DEBUG("mem->type=%x, type=%x", mem->type, type); + return -EINVAL; + } + + global_cache_flush(); + agp_bridge->driver->tlb_flush(mem); + + for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { + writel(AGP_MASK_GTT(), private_data.gtt+j); + readl(private_data.gtt+j); /* PCI Posting. */ + } + + global_cache_flush(); + agp_bridge->driver->tlb_flush(mem); + + AGN_DEBUG("Exit"); + + return 0; +} + +int iegd_cmn_remove_entries(struct agp_memory *mem, + off_t pg_start, int type) +{ + int i; + + AGN_DEBUG("Enter"); + + global_cache_flush(); + agp_bridge->driver->tlb_flush(mem); + + if (pg_start < private_data.gtt_entries) { + AGN_ERROR("Trying to disable local/stolen memory"); + AGN_DEBUG("pg_start=0x%.8lx, private_data.gtt_entries=%d", + pg_start, private_data.gtt_entries); + return -EINVAL; + } + + for (i = pg_start; i < (mem->page_count + pg_start); i++) { + writel(agp_bridge->scratch_page, private_data.gtt+i); + readl(private_data.gtt+i); + } + + global_cache_flush(); + agp_bridge->driver->tlb_flush(mem); + + AGN_DEBUG("Exit"); + + return 0; +} diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/drv_gn4.c patch_script_temp/drivers/gpu/drm/iegd/agp/drv_gn4.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/drv_gn4.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/agp/drv_gn4.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,455 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_interface.c + * $Revision: 1.17 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2007, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "global.h" +#include "intelpci.h" + +static int iegd_gn4_fetch_size(void); +static void iegd_gn4_cleanup(void); +static void iegd_gn4_tlbflush(struct agp_memory *mem); +static int AGP_CREATE_GATT(iegd_gn4_create_gatt_table); + +/* GM45 functions */ +static int iegd_igm45_fetch_size(void); +static int iegd_igm45_configure(void); +static int AGP_CREATE_GATT(iegd_igm45_create_gatt_table); + +struct aper_size_info_fixed iegd_i965_sizes[] = +{ + /* VBIOS always allocates enough space for 512MB aperture */ + /* Size KB, # of entries, ? */ + {128, 131072, 7}, + {64, 131072, 7}, + {256, 131072, 7}, + {512, 131072, 7}, +}; + +struct aper_size_info_fixed iegd_igm45_sizes[] = +{ + /* GM45 has 2MB GTT (EDS page 217) size */ + /* Size_KB #_of_entries ? */ + {256, 524288, 7}, + {512, 524288, 7}, +}; + + +bridge_driver_t drv_gn4 = { + .owner = THIS_MODULE, + .size_type = FIXED_APER_SIZE, + .aperture_sizes = 0, + .num_aperture_sizes = 0, + .needs_scratch_page = TRUE, + .configure = iegd_cmn_configure, + .fetch_size = iegd_gn4_fetch_size, + .cleanup = iegd_gn4_cleanup, + .tlb_flush = iegd_gn4_tlbflush, + .mask_memory = iegd_cmn_mask_memory, + .masks = iegd_cmn_masks, + .agp_enable = iegd_cmn_agp_enable, + .cache_flush = global_cache_flush, + .create_gatt_table = iegd_gn4_create_gatt_table, + .free_gatt_table = iegd_cmn_free_gatt_table, + .insert_memory = iegd_cmn_insert_entries, + .remove_memory = iegd_cmn_remove_entries, + .alloc_by_type = iegd_cmn_alloc_by_type, + .free_by_type = iegd_cmn_free_by_type, + .agp_alloc_page = agp_generic_alloc_page, + .agp_destroy_page = agp_generic_destroy_page, +}; + +/* GM45 */ +bridge_driver_t drv_gm45 = { + .owner = THIS_MODULE, + .size_type = FIXED_APER_SIZE, + .aperture_sizes = (void *)iegd_igm45_sizes, + .num_aperture_sizes = 3, + .needs_scratch_page = TRUE, + .configure = iegd_igm45_configure, + .fetch_size = iegd_igm45_fetch_size, + .cleanup = iegd_gn4_cleanup, + .tlb_flush = iegd_gn4_tlbflush, + .mask_memory = iegd_cmn_mask_memory, + .masks = iegd_cmn_masks, + .agp_enable = iegd_cmn_agp_enable, + .cache_flush = global_cache_flush, + .create_gatt_table = iegd_igm45_create_gatt_table, + .free_gatt_table = iegd_cmn_free_gatt_table, + .insert_memory = iegd_cmn_insert_entries, + .remove_memory = iegd_cmn_remove_entries, + .alloc_by_type = iegd_cmn_alloc_by_type, + .free_by_type = iegd_cmn_free_by_type, + .agp_alloc_page = agp_generic_alloc_page, + .agp_destroy_page = agp_generic_destroy_page, +}; + + +static int iegd_gn4_fetch_size(void) +{ + struct aper_size_info_fixed *values; + u32 offset = 0; + u8 temp; + +#define IG965_GMCH_MSAC 0x62 +#define IGM965_GMCH_MSAC 0x66 + + AGN_DEBUG("Enter"); + + values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); + + if(private_data.pdev->device == PCI_DEVICE_ID_GM965) { + pci_read_config_byte(private_data.pdev, IGM965_GMCH_MSAC, &temp); + } else { + pci_read_config_byte(private_data.pdev, IG965_GMCH_MSAC, &temp); + } + + switch (temp & 6) { + case 0: + offset = 0; /* 128MB aperture */ + break; + case 2: + offset = 2; /* 256MB aperture */ + break; + case 6: + offset = 3; /* 512MB aperture */ + break; + } + + /* Set the actual size here */ + agp_bridge->previous_size = agp_bridge->current_size = + (void *)(values + offset); + + AGN_DEBUG("Exit"); + + /* Always return 512KB GTT when calculating available stolen memory */ + return values[3].size; +} + +static void iegd_gn4_cleanup(void) +{ + AGN_DEBUG("Enter"); + iounmap((void *)private_data.registers); + AGN_DEBUG("Exit"); +} + +static void iegd_gn4_tlbflush(struct agp_memory *mem) +{ + AGN_DEBUG("Enter"); + /* Gen4 must flush the GTT or simple 2D rendering will lock the engine. */ + writel(0, private_data.registers+0x2170); + writel(0, private_data.registers+0x2174); + AGN_DEBUG("Exit"); + return; +} + +static int AGP_CREATE_GATT(iegd_gn4_create_gatt_table) +{ + const u32 i965_gtt_table_order = 7; + + int i; + u16 j = 0; + int num_entries; + u32 gtt_bus_addr; + u32 mmio_bus_addr; + u32 gtt_enabled = FALSE; + u32 gtt_table_size = (1 << i965_gtt_table_order) * PAGE_SIZE - 1; + u32 gtt_pgctl_reg; + char *gtt_table, *gtt_table_end, *current_entry; + struct page *gtt_table_page; + + AGN_DEBUG("Enter"); + + agp_bridge->gatt_table_real = NULL; + + /* Find and save the address of the MMIO register */ + pci_read_config_dword(private_data.pdev, I915_MMADDR, &mmio_bus_addr); + + mmio_bus_addr &= 0xFFF80000; + private_data.registers =(volatile u8 *) + ioremap(mmio_bus_addr,1024 * 4096); + if (!private_data.registers) { + AGN_ERROR("ioremap failed to map"); + return (-ENOMEM); + } + /* GTT is mapped 512KB after the registers */ + private_data.gtt = (u32 __iomem *)((u32)private_data.registers + + 512*1024); + + /* Extract the content of the control register */ + gtt_pgctl_reg = readl(private_data.registers+I810_PGETBL_CTL); + gtt_bus_addr = gtt_pgctl_reg & 0xFFFFF000; + gtt_enabled = gtt_pgctl_reg & I810_PGETBL_ENABLED; + + global_cache_flush(); + agp_bridge->driver->tlb_flush(0); + + /* we have to call this as early as possible after the MMIO base address is known */ + iegd_cmn_init_gtt_entries(); + + if( !gtt_enabled ) { + num_entries = iegd_i965_sizes[0].num_entries; + gtt_table = (char *) __get_free_pages(GFP_KERNEL, + i965_gtt_table_order); + gtt_table_end = gtt_table + gtt_table_size; + + /* Make sure allocation was successful */ + if( NULL == gtt_table ) { + AGN_ERROR("Fail to allocate kernel pages"); + return (-ENOMEM); + } + + for( current_entry = gtt_table; current_entry < gtt_table_end; + current_entry += PAGE_SIZE ) { + gtt_table_page = virt_to_page( current_entry ); + set_bit( PG_reserved, >t_table_page->flags ); + } + + agp_bridge->gatt_bus_addr = virt_to_phys( gtt_table ); + + for( i = 0; i < num_entries; i++ ) { + *(gtt_table + j) = (unsigned long) agp_bridge->scratch_page; + j += 4; + } + } + else { + agp_bridge->gatt_bus_addr = gtt_bus_addr; + } + + agp_bridge->gatt_table = NULL; + + AGN_DEBUG("Exit"); + + return(0); +} + +static int AGP_CREATE_GATT(iegd_igm45_create_gatt_table) +{ + u32 mmio_bus_addr; + + u32 gtt_mem_size; + u32 base_stolen_mem; + u16 gmch_ctrl; + + u32 iegd_scratch, iegd_scratch2; + int gtt_entries; + int size = 4; /* Scratch page 4KB */ + + AGN_DEBUG("Enter"); + + agp_bridge->gatt_table_real = NULL; + + /* Find and save the address of the MMIO register */ + pci_read_config_dword(private_data.pdev, I915_MMADDR, &mmio_bus_addr); + + /* Bits 35-22 */ + mmio_bus_addr &= 0xFFC00000; + + /* Map 4MB: 512KB MMIO, 2MB GTT */ + private_data.registers =(volatile u8 *) ioremap(mmio_bus_addr, MB(4)); + + if (!private_data.registers) { + AGN_ERROR("ioremap failed to map"); + return (-ENOMEM); + } + + /* GTT is mapped 2MB after the registers */ + private_data.gtt = (u32 __iomem *)((u32)private_data.registers + MB(2)); + + global_cache_flush(); + agp_bridge->driver->tlb_flush(0); + + pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL, &gmch_ctrl); + +#define IGM45_GMCH_GMS_STOLEN_128M (0x8 << 4) +#define IGM45_GMCH_GMS_STOLEN_256M (0x9 << 4) +#define IGM45_BASE_STOLEN 0x5C + pci_read_config_dword(private_data.pdev,IGM45_BASE_STOLEN,&base_stolen_mem); + base_stolen_mem &= 0xFFF00000; + + /* Bits [7:4] will tell the amount of stolen memory */ + /* Stolen memory = Amount specfied - 1 scratch page */ + switch (gmch_ctrl & 0xf0) { + case I855_GMCH_GMS_STOLEN_1M: + gtt_entries = MB(1) - KB(size); + break; + case I855_GMCH_GMS_STOLEN_4M: + gtt_entries = MB(4) - KB(size); + break; + case I855_GMCH_GMS_STOLEN_8M: + gtt_entries = MB(8) - KB(size); + break; + case I855_GMCH_GMS_STOLEN_16M: + gtt_entries = MB(16) - KB(size); + break; + case I855_GMCH_GMS_STOLEN_32M: + gtt_entries = MB(32) - KB(size); + break; + case I915_GMCH_GMS_STOLEN_48M: + gtt_entries = MB(48) - KB(size); + break; + case I915_GMCH_GMS_STOLEN_64M: + gtt_entries = MB(64) - KB(size); + break; + case IGM45_GMCH_GMS_STOLEN_128M: + gtt_entries = MB(128) - KB(size); + break; + case IGM45_GMCH_GMS_STOLEN_256M: + gtt_entries = MB(256) - KB(size); + break; + default: + gtt_entries = 0; + break; + } + + iegd_scratch = readl(private_data.registers + 0x71410); + + /* check for the pci card as primary */ + if (iegd_scratch == 0) { + /* No stolen memory has been used */ + /* + * In Gen4, GTT is 2MB below stolen memory, which is a fix location + * The GTT is empty. + * Populate the GTT with PTE point to the stolen memory. + * This will not waste the stolen memory which BIOS already allocated. + */ + int num_entries; + int i; + u16 j = 0; + + AGN_DEBUG("PCI as primary.\n"); + + num_entries = gtt_entries / KB (4); + + for (i = 0; i < num_entries; i++) { + writel(((base_stolen_mem + i * KB(4)) | 1), private_data.gtt+j); + j+=1; + } + + gtt_entries = num_entries * KB(4); + + AGN_DEBUG("PCI as primary scratch_page = %08lx gtt_entries = %d", + agp_bridge->scratch_page, gtt_entries); + } else if (((iegd_scratch>>16) == 0xE1DF) && (iegd_scratch & 0x4)) { + AGN_LOG("IEGD Firmware Detected"); + /* IEGD firmware found, and Mem Reservation Flag present */ + iegd_scratch2 = readl(private_data.registers + 0x71418); + /* Stolen memory = # of pages * 4KB */ + gtt_entries = (iegd_scratch2 & 0xFFFF) * 4096; + } + + if (gtt_entries > 0) { + AGN_LOG("Detected %d KB = %d MB stolen memory.", gtt_entries / KB(1), + gtt_entries/MB(1)); + } else { + AGN_LOG("No pre-allocated video memory detected."); + } + + /* Divide by 4KB to get the # of GTT entries */ + private_data.gtt_entries = gtt_entries/KB(4); + + + /* On GM45, GTTADR size is 2MB. EDS page 217 */ + gtt_mem_size = MB(2); + + AGN_DEBUG("gtt_mem_size = %uMB", gtt_mem_size/MB(1)); + + /* Minus base stolen memory to get the base of gtt. This address + * can also get from register 0xA8 of config space device 0 */ + agp_bridge->gatt_bus_addr = base_stolen_mem - gtt_mem_size; + agp_bridge->gatt_table = NULL; + AGN_DEBUG("Exit"); + + return(0); +} + +/* GM45: configure */ +static int iegd_igm45_configure(void) +{ + struct aper_size_info_fixed *current_size; + u32 temp; + int i; + + AGN_DEBUG("Enter"); + + current_size = A_SIZE_FIX(agp_bridge->current_size); + + pci_read_config_dword(private_data.pdev, I915_GMADDR, &temp); + AGN_DEBUG("1. Reg[0x%x] = 0x%x\n", I915_GMADDR, temp); + + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + AGN_DEBUG("2. Reg[0x%x] = 0x%x\n", I915_GMADDR, temp); + + if (agp_bridge->driver->needs_scratch_page) { + for (i = private_data.gtt_entries; + i < current_size->num_entries; i++) { + writel(agp_bridge->scratch_page, private_data.gtt+i); + readl(private_data.gtt+i); /* PCI Posting. */ + } + } + global_cache_flush(); + + AGN_DEBUG("Exit"); + + return 0; +} + +/* GM45: fetch_size() */ +static int iegd_igm45_fetch_size(void) +{ + struct aper_size_info_fixed *values; + u32 offset = 0; + u8 temp; + +#define IGM45_GMCH_MSAC 0x66 +#define Q45_GMCH_MSAC 0x62 + + AGN_DEBUG("Enter"); + + values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); + + if(private_data.pdev->device == PCI_DEVICE_ID_ELK || + private_data.pdev->device == PCI_DEVICE_ID_Q45 || + private_data.pdev->device == PCI_DEVICE_ID_G45 || + private_data.pdev->device == PCI_DEVICE_ID_G41) { + pci_read_config_byte(private_data.pdev, Q45_GMCH_MSAC, &temp); + } else { + pci_read_config_byte(private_data.pdev, IGM45_GMCH_MSAC, &temp); + } + + /* GM45 has only 2 aperture sizes (EDS 227) : 256MB/512MB */ + switch (temp & 6) { + case 2: + offset = 0; /* 256MB aperture */ + break; + case 6: + offset = 1; /* 512MB aperture */ + break; + } + + /* Set the actual size here */ + agp_bridge->previous_size = agp_bridge->current_size = + (void *)(values + offset); + + AGN_DEBUG("Exit"); + /* For GM45 always return 2MB as GTT size */ + return values[0].size; +} diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/drv_nap.c patch_script_temp/drivers/gpu/drm/iegd/agp/drv_nap.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/drv_nap.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/agp/drv_nap.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,470 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: drv_nap.c + * $Revision: 1.14 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "global.h" +#include "intelpci.h" + +static int iegd_nap_fetch_size(void); +static void iegd_nap_tlbflush(struct agp_memory *mem); + +static void iegd_iq35_init_gtt_entries(void); +static void iegd_nap_iq35_gatt(void); +static int iegd_nap_9series(u32 order); +static int AGP_CREATE_GATT(iegd_nap_create_gatt_table); +static void iegd_nap_cleanup(void); + + +struct aper_size_info_fixed iegd_i915_sizes[] = +{ + {128, 32768, 5}, + /* The 64M mode still requires a 128k gatt */ + {64, 16384, 5}, + {256, 65536, 6}, + {512, 131072, 7}, +}; + +struct aper_size_info_fixed iegd_iq35_sizes[] = +{ + {128, 32768, 5}, + {256, 65536, 6}, + {512, 131072, 7}, +}; + +bridge_driver_t drv_nap = { + .owner = THIS_MODULE, + .size_type = FIXED_APER_SIZE, + .aperture_sizes = 0, + .num_aperture_sizes = 0, + .needs_scratch_page = TRUE, + .configure = iegd_cmn_configure, + .fetch_size = iegd_nap_fetch_size, + .cleanup = iegd_nap_cleanup, + .tlb_flush = iegd_nap_tlbflush, + .mask_memory = iegd_cmn_mask_memory, + .masks = iegd_cmn_masks, + .agp_enable = iegd_cmn_agp_enable, + .cache_flush = global_cache_flush, + .create_gatt_table = iegd_nap_create_gatt_table, + .free_gatt_table = iegd_cmn_free_gatt_table, + .insert_memory = iegd_cmn_insert_entries, + .remove_memory = iegd_cmn_remove_entries, + .alloc_by_type = iegd_cmn_alloc_by_type, + .free_by_type = iegd_cmn_free_by_type, + .agp_alloc_page = agp_generic_alloc_page, + .agp_destroy_page = agp_generic_destroy_page, +}; + +static int iegd_nap_fetch_size() +{ + struct aper_size_info_fixed *values; + u32 offset = 0; + u32 temp2; + u8 temp; + +#define IQ35_GMCH_MSAC 0x62 +#define I915_256MB_ADDRESS_MASK (1<<27) + + AGN_DEBUG("Enter"); + + values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); + + switch(private_data.pdev->device) { + case PCI_DEVICE_ID_Q35: + case PCI_DEVICE_ID_Q35A2: + pci_read_config_byte(private_data.pdev, + IQ35_GMCH_MSAC, &temp); + switch(temp & 0x3) { + case 1: + offset = 2; /* 512MB aperture size */ + break; + case 2: + offset = 1; /* 256MB aperture size */ + break; + case 3: + offset = 0; /* 128MB aperture size */ + break; + } + break; + case PCI_DEVICE_ID_915GD: + case PCI_DEVICE_ID_915AL: + case PCI_DEVICE_ID_945G: + case PCI_DEVICE_ID_945GM: + case PCI_DEVICE_ID_945GME: + pci_read_config_dword(private_data.pdev, + I915_GMADDR, &temp2); + if (temp2 & I915_256MB_ADDRESS_MASK) { + offset = 0; /* 128MB aperture */ + } else { + offset = 2; /* 256MB aperture */ + } + break; + } + + agp_bridge->previous_size = agp_bridge->current_size = + (void *)(values + offset); + + AGN_DEBUG("Exit"); + + return values[offset].size; +} + +static void iegd_nap_tlbflush(struct agp_memory *mem) +{ + AGN_DEBUG("Enter"); + return; + AGN_DEBUG("Exit"); +} + +static void iegd_iq35_init_gtt_entries(void) +{ + u16 gmch_ctrl; + u32 iegd_scratch, iegd_scratch2; + int gtt_entries; + int local = 0; + int size = 4; + +#define I35_GMCH_GMS_STOLEN_128M (0x8 << 4) +#define I35_GMCH_GMS_STOLEN_256M (0x9 << 4) +#define I35_GMCH_GMS_MASK 0xf0 + + AGN_DEBUG("Enter"); + + pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); + + switch (gmch_ctrl & I35_GMCH_GMS_MASK) { + case I855_GMCH_GMS_STOLEN_1M: + gtt_entries = MB(1) - KB(size); + break; + case I855_GMCH_GMS_STOLEN_4M: + gtt_entries = MB(4) - KB(size); + break; + case I855_GMCH_GMS_STOLEN_8M: + gtt_entries = MB(8) - KB(size); + break; + case I855_GMCH_GMS_STOLEN_16M: + gtt_entries = MB(16) - KB(size); + break; + case I855_GMCH_GMS_STOLEN_32M: + gtt_entries = MB(32) - KB(size); + break; + case I915_GMCH_GMS_STOLEN_48M: + gtt_entries = MB(48) - KB(size); + break; + case I915_GMCH_GMS_STOLEN_64M: + gtt_entries = MB(64) - KB(size); + break; + case I35_GMCH_GMS_STOLEN_128M: + gtt_entries = MB(128) - KB(size); + break; + case I35_GMCH_GMS_STOLEN_256M: + gtt_entries = MB(256) - KB(size); + break; + default: + gtt_entries = 0; + break; + } + + iegd_scratch = readl(private_data.registers + 0x71410); + + /* FIXME: check for the pci card as primary */ + if(iegd_scratch == 0) { + gtt_entries = 0; + } else if (((iegd_scratch>>16) == 0xE1DF) && (iegd_scratch & 0x4)) { + AGN_LOG("IEGD Firmware Detected"); + /* IEGD firmware found, and Mem Reservation Flag present */ + iegd_scratch2 = readl(private_data.registers + 0x71418); + gtt_entries = (iegd_scratch2 & 0xFFFF) * 4096; + } + + if (gtt_entries > 0) { + AGN_LOG("Detected %dK %s memory.", + gtt_entries / KB(1), local ? "local" : "stolen"); + } else { + AGN_LOG("No pre-allocated video memory detected."); + } + + gtt_entries /= KB(4); + + private_data.gtt_entries = gtt_entries; + + AGN_DEBUG("Exit"); +} + +static void iegd_nap_iq35_gatt() +{ + u32 gtt_mem_size; + u32 base_stolen_mem; + u16 gmch_ctrl; + + AGN_DEBUG("Enter"); + + iegd_iq35_init_gtt_entries(); + + pci_read_config_dword(private_data.pdev, + IQ35_BASE_STOLEN, &base_stolen_mem); + base_stolen_mem &= 0xFFF00000; + + pci_read_config_word(private_data.pdev, + I830_GMCH_CTRL, &gmch_ctrl); + + switch(gmch_ctrl & IQ35_GTT_MEM_SIZE) { + case IQ35_GGMS_1MB: + gtt_mem_size = MB(1); /* Normal mode */ + break; + case IQ35_GGMS_2MB: + gtt_mem_size = MB(2); /* VT mode */ + break; + default: + gtt_mem_size = 0; + } + + AGN_DEBUG("gtt_mem_size = %uMB", gtt_mem_size); + + /* Minus based stolen memory to get the base of gtt. This address + * can also get from register 0xA8 of config space device 0 */ + agp_bridge->gatt_bus_addr = base_stolen_mem - gtt_mem_size; + + AGN_DEBUG("Exit"); +} + +static int iegd_nap_9series(u32 order) +{ + u32 gtt_pgctl_reg; + u32 gtt_bus_addr; + u32 gtt_enabled = FALSE; + u32 iegd_scratch; + + gtt_pgctl_reg = readl(private_data.registers + + I810_PGETBL_CTL); + global_cache_flush(); + gtt_bus_addr = gtt_pgctl_reg & 0xFFFFF000; + gtt_enabled = gtt_pgctl_reg & I810_PGETBL_ENABLED; + + + /* we have to call this as early as possible after the MMIO base + * address is known */ + iegd_cmn_init_gtt_entries(); + + /* + * If GTT not enabled created our own gtt table from kernel memory + * and initialize it to scratch page. This in case the VBIOS is + * not our VBIOS + */ + iegd_scratch = readl(private_data.registers + 0x71410); + + if (iegd_scratch == 0) { + /* PCI as primary device. IEGD VBIOS is not loaded. + * Need to setup the GTT in stolen memory + * GTT will located at the bottom of stolen memory. + * The rest of the memory will use as video memory and map the PTE except + * the last page, which use as sratch page. + */ + u32 gtt_end; + u32 gtt_addr_reg; + u32 base_stolen_mem; + u16 gmch_ctrl; + int aperture_size = 0; + int total_stolen_pages = 0; + int total_gtt_entries = 0; + int num_entries; + int i; + u16 j = 0; + u32 temp2; + u8 temp; + + /* read the stolen memory address. + * use 512 bytes as GTT table, and use the rest table for memory. */ + pci_read_config_dword(private_data.pdev, + IQ35_BASE_STOLEN, &base_stolen_mem); + base_stolen_mem &= 0xFFF00000; + + /* have to determine the stolen memory size. + * We can't use the private_data.gtt_entries value because the value assume VBIOS is present. */ + pci_read_config_word(private_data.pdev, I830_GMCH_CTRL, &gmch_ctrl); + gmch_ctrl = (gmch_ctrl >> 4) & 0xf; + /* Translate the stolen memory size to num of pages available. */ + if (gmch_ctrl == 1) { + total_stolen_pages = 1024 / 4 ; + } else if (gmch_ctrl > 1) { + total_stolen_pages = (2 << (gmch_ctrl - 1)) * (1024 / 4); + } + + /* We need to allocate the last page as scratch page. */ + total_stolen_pages = total_stolen_pages - 1; + + /* Need to program the PGETBL_CTL to enable page table. */ + writel(base_stolen_mem | 1, private_data.registers + I810_PGETBL_CTL); + +#define I810_GTT_ADDR 0x1c + /* Find and save the address of the MMIO register */ + pci_read_config_dword(private_data.pdev, I810_GTT_ADDR, >t_addr_reg); + private_data.gtt = (volatile u32 *) ioremap(gtt_addr_reg, KB(512)); + + if (!private_data.gtt) { + AGN_ERROR("ioremap failed to map"); + return (-ENOMEM); + } + + + switch(private_data.pdev->device) { + case PCI_DEVICE_ID_Q35: + case PCI_DEVICE_ID_Q35A2: + pci_read_config_byte(private_data.pdev, + IQ35_GMCH_MSAC, &temp); + switch(temp & 0x3) { + case 1: + aperture_size = 512; /* 512MB aperture size */ + break; + case 2: + aperture_size = 256; /* 256MB aperture size */ + break; + case 3: + aperture_size = 128; /* 128MB aperture size */ + break; + } + break; + case PCI_DEVICE_ID_915GD: + case PCI_DEVICE_ID_915AL: + case PCI_DEVICE_ID_945G: + case PCI_DEVICE_ID_945GM: + case PCI_DEVICE_ID_945GME: + pci_read_config_dword(private_data.pdev, + I915_GMADDR, &temp2); + if (temp2 & I915_256MB_ADDRESS_MASK) { + aperture_size = 128; /* 128MB aperture */ + } else { + aperture_size = 256; /* 256MB aperture */ + } + break; + default: AGN_ERROR("Illegal Device ID"); + break; + } + /* Number of GTT entries available based on the aperture size. */ + total_gtt_entries = aperture_size * 1024 / 4; + /* gtt_end is the last entry of the GTT, and start of video memory. */ + gtt_end = base_stolen_mem + KB(aperture_size); + + /* This num_entries mean total of PTE can be populate based on the + * remaining stolen memory size.*/ + num_entries = ((total_stolen_pages * 4) - aperture_size) / 4; + + /* Have to program the PTE through the GTT ADDRESS.*/ + for (i=0; i < num_entries; i++) { + writel(((gtt_end + i * KB(4)) | 1), (private_data.gtt + j)); + j+=1; + } + + /* I believe this will be the reserved memory refer by GMM. + * So, have to update the actual PTE has been used.*/ + private_data.gtt_entries = num_entries - 1; + + /* This num_entries is the remaining GTT table not fill up. Have to + * populate with scratch page. */ + num_entries = total_gtt_entries - num_entries; + + for (i=0; i < num_entries; i++) + { + writel(agp_bridge->scratch_page, private_data.gtt + j); + j+=1; + } + + agp_bridge->gatt_bus_addr = base_stolen_mem; + } else { + agp_bridge->gatt_bus_addr = gtt_bus_addr; + } + + agp_bridge->gatt_table = NULL; + + AGN_DEBUG("Exit"); + + return 0; +} + + +static int AGP_CREATE_GATT(iegd_nap_create_gatt_table) +{ + const u32 i915_gtt_table_order = 6; + u32 mmio_bus_addr, temp2; + int ret; + + AGN_DEBUG("Enter"); + + agp_bridge->gatt_table_real = NULL; + + /* Find and save the address of the MMIO register */ + pci_read_config_dword(private_data.pdev, I915_MMADDR, + &mmio_bus_addr); + mmio_bus_addr &= 0xFFF80000; + + private_data.registers = (volatile u8 *) ioremap(mmio_bus_addr, + 128 * 4096); + if (!private_data.registers) { + AGN_ERROR("ioremap failed to map mmio"); + return (-ENOMEM); + } + + pci_read_config_dword(private_data.pdev, I915_PTEADDR,&temp2); + + /* FIXME: double check the size of area to map to pci space */ + private_data.gtt = (volatile u32 *)ioremap(temp2, 512 * 1024); + if (!private_data.gtt) { + AGN_ERROR("ioremap failed to map gtt"); + return (-ENOMEM); + } + + switch(private_data.pdev->device) { + case PCI_DEVICE_ID_Q35: + case PCI_DEVICE_ID_Q35A2: + /* Bearlake B is difference from other chipset, especially + * when reading gtt based address. Probably future chipset + * will have same architecture as Bearlake-B and this + * code can move to common file*/ + iegd_nap_iq35_gatt(); + break; + case PCI_DEVICE_ID_915GD: + case PCI_DEVICE_ID_915AL: + case PCI_DEVICE_ID_945G: + case PCI_DEVICE_ID_945GM: + case PCI_DEVICE_ID_945GME: + if((ret = iegd_nap_9series(i915_gtt_table_order))) { + return (ret); + } + break; + } + + agp_bridge->gatt_table = NULL; + + AGN_DEBUG("Exit"); + + return (0); +} + +static void iegd_nap_cleanup(void) +{ + + AGN_DEBUG("Enter"); + iounmap((void *)private_data.gtt); + iounmap((void *)private_data.registers); + AGN_DEBUG("Exit"); +} + diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/drv_plb.c patch_script_temp/drivers/gpu/drm/iegd/agp/drv_plb.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/drv_plb.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/agp/drv_plb.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,945 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_interface.c + * $Revision: 1.36 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2007, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "global.h" +#include "intelpci.h" +#include +#include + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,5) + +static int iegd_plb_fetch_size(void); +static void iegd_plb_tlbflush(struct agp_memory *mem); +static int iegd_plb_init_gtt(u32 order); +static int AGP_CREATE_GATT(iegd_plb_create_gatt_table); +static void iegd_plb_cleanup(void); +static struct page *iegd_plb_vm_nopage(struct vm_area_struct *, + unsigned long, int *); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) +static int iegd_plb_vm_fault(struct vm_area_struct *vma, + struct vm_fault *vmf); +#endif +static void iegd_plb_vm_close(struct vm_area_struct *); +int iegd_plb_insert_entries(struct agp_memory *, off_t, int); +int iegd_plb_remove_entries(struct agp_memory *, off_t, int); +void iegd_plb_free_by_type(struct agp_memory *); +int iegd_plb_configure(void); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) +#define PLB_DESTROY_PAGES(a,b,c) plb_destroy_pages(a->pages[0],b,c) +#else +#define PLB_DESTROY_PAGES(a,b,c) plb_destroy_pages_by_addr(gart_to_virt(a->memory[0]),b,c) +#endif + + +/* Each structure in this array contains three elements: + * Size of GTT in KB + * Number of 32-bit entries that make up the GTT + * Page "order" -- 2^order == number of contiguous CPU pages + * required to store the GTT + */ +struct aper_size_info_fixed iegd_plb_sizes[] = +{ + {256, 65536, 6}, +}; + +bridge_driver_t drv_plb = { + .owner = THIS_MODULE, + .size_type = FIXED_APER_SIZE, + .aperture_sizes = iegd_plb_sizes, + .num_aperture_sizes = 1, + .needs_scratch_page = TRUE, + .configure = iegd_plb_configure, + .fetch_size = iegd_plb_fetch_size, + .cleanup = iegd_plb_cleanup, + .tlb_flush = iegd_plb_tlbflush, + .mask_memory = iegd_cmn_mask_memory, + .masks = iegd_cmn_masks, + .agp_enable = iegd_cmn_agp_enable, + .cache_flush = global_cache_flush, + .create_gatt_table = iegd_plb_create_gatt_table, + .free_gatt_table = iegd_cmn_free_gatt_table, + .insert_memory = iegd_plb_insert_entries, + .remove_memory = iegd_plb_remove_entries, + .alloc_by_type = iegd_cmn_alloc_by_type, + .free_by_type = iegd_plb_free_by_type, + .agp_alloc_page = agp_generic_alloc_page, + .agp_destroy_page = agp_generic_destroy_page, +}; + +struct vm_operations_struct iegd_plb_vm_ops = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) + .fault = iegd_plb_vm_fault, +#else + .nopage = iegd_plb_vm_nopage, +#endif + .close = iegd_plb_vm_close +}; + +static DECLARE_MUTEX(client_sem); + +struct client_list_struct { + struct list_head list; + struct vm_area_struct *vma; + pid_t pid; +}; + +static LIST_HEAD(client_list); + + +static int iegd_plb_fetch_size() +{ + struct aper_size_info_fixed *values; + + values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); + + + agp_bridge->previous_size = agp_bridge->current_size = + (void *)(values); + + return values[0].size; +} + +static void iegd_plb_tlbflush(struct agp_memory *mem) +{ + u32 sgx_mmu; + + /* Flush TLB */ + sgx_mmu = readl(private_data.registers + 0x40C00); + sgx_mmu &= 0xFFFFFFE0; + sgx_mmu |= 0x0C; + writel(sgx_mmu, private_data.registers + 0x40C00); + + wmb(); + sgx_mmu = readl(private_data.registers + 0x40C00); + sgx_mmu &= 0xFFFFFFE0; + writel(sgx_mmu, private_data.registers + 0x40C00); + + return; +} + +#define IUS15_GMCH_MSAC 0x62 + +static int iegd_plb_init_gtt(u32 order) +{ + u32 gtt_pgctl_reg; + u32 gtt_bus_addr; + u32 gtt_enabled = FALSE; + int num_entries; + u32 *gtt_table, *dstvirt; + u32 *sgx_dir, sgx_mmu; + u32 iegd_scratch, aperphys; + u8 temp; + struct page *gtt_table_page; + int i,j; + u32 new_order; + + /* Has the system BIOS only allocateda GTT for 128MB? If + * so we need to replace it with one sized for 256MB + */ + pci_read_config_byte(private_data.pdev, IUS15_GMCH_MSAC, &temp); + if ((temp & 0x03) == 0x03) { + AGN_DEBUG("Graphics aperture is configured for 128MB"); + AGN_DEBUG("Enabling 256MB split aperture"); + private_data.split_gtt = 1; + } else { + private_data.split_gtt = 0; + } + + gtt_pgctl_reg = readl(private_data.registers + + I810_PGETBL_CTL); + global_cache_flush(); + gtt_bus_addr = gtt_pgctl_reg & 0xFFFFF000; + gtt_enabled = gtt_pgctl_reg & I810_PGETBL_ENABLED; + + /* we have to call this as early as possible after the MMIO base + * address is known */ + iegd_cmn_init_gtt_entries(); + + /* Update the scratch registers to say that we have no stolen memory */ + iegd_scratch = readl(private_data.registers + 0x71410); + if ((iegd_scratch & 0xE1DF0000) == 0xE1DF0000) { + /* if our vBios modify only the stolen memory bit */ + iegd_scratch |= 0x00000004; + writel(iegd_scratch, private_data.registers + 0x71410); + } else { + /* Not our vBIOS but set the stolen memory anyway */ + writel(0xE1DF0004, private_data.registers + 0x71410); + } + + /* Reportthat we have 0 stolen memory regardless of what was + * really in there. We _want_ to insert fresh pages on top of + * stolen memory. */ + writel(0, private_data.registers + 0x71418); + + num_entries = (1 << order) * KB(1); + + private_data.upper_gtt=NULL; + + /* + * If GTT not enabled created our own gtt table from kernel memory + * and initialize it to scratch page. This in case the VBIOS is + * not our VBIOS + */ + if (!gtt_enabled) { + gtt_table = (u32 *)__get_free_pages(GFP_KERNEL, order); + + /* Make sure allocation was successful */ + if (NULL == gtt_table) { + AGN_ERROR("Failed to allocate kernel pages"); + return (-ENOMEM); + } + + for (i=0; i < (1 << order); i++) { + dstvirt = gtt_table + (PAGE_SIZE * i); + gtt_table_page = virt_to_page(dstvirt); + AGN_DEBUG("Setting reserved bit on %p", gtt_table_page); + set_bit(PG_reserved, >t_table_page->flags); + } + + private_data.upper_gtt = gtt_table + 0x8000; + agp_bridge->gatt_bus_addr = virt_to_phys(gtt_table); + + for (i = 0; i < num_entries; i++) { + gtt_table[i] = (unsigned long) agp_bridge->scratch_page; + } + + /* Enable the newly created GTT */ + AGN_DEBUG("Enabling new GTT"); + writel(agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED, + private_data.registers+I810_PGETBL_CTL); + readl(private_data.registers+I810_PGETBL_CTL); + + } else if (private_data.split_gtt) { + /* We're keeping the system BIOS created normal gtt but + * augmenting it with more entries + */ + gtt_table = (u32 *)__get_free_pages(GFP_KERNEL, order - 1); + + //AGN_DEBUG("Allocated secondary GTT at %p:%p (virt:phys)", gtt_table, + // virt_to_phys(gtt_table)); + + /* Make sure allocation was successful */ + if (NULL == gtt_table) { + AGN_ERROR("Failed to allocate kernel pages"); + return (-ENOMEM); + } + + private_data.upper_gtt = gtt_table; + + for (i = 0; i < num_entries/2; i++) { + gtt_table[i] = (unsigned long) agp_bridge->scratch_page; + } + + agp_bridge->gatt_bus_addr = gtt_bus_addr; + + } else { + + agp_bridge->gatt_bus_addr = gtt_bus_addr; + + } + + /* + * Now that the GTT exists and has been configured, enable + * the SGX MMU to point to the GTT as its page tables + */ + + /* The directory level is a single page of memory */ + sgx_dir = (u32 *)__get_free_pages(GFP_KERNEL, 0); + if (NULL == sgx_dir ) { + AGN_ERROR("Failed to allocate kernel page"); + return (-ENOMEM); + } + + /* Mark the directory so that it is not swappable */ + gtt_table_page = virt_to_page( sgx_dir ); + set_bit(PG_reserved, >t_table_page->flags); + + memset (sgx_dir, 0, PAGE_SIZE); + + /* Initialize the directory so that each used page table + * is addressed + */ + + /* Make sure entire SGX directory is populated */ + for (i = 0; i < 0x400; i++) { + sgx_dir[i] = agp_bridge->gatt_bus_addr | 0x01; + } + + pci_read_config_dword(private_data.pdev, I915_GMADDR, &aperphys); + aperphys &= PCI_BASE_ADDRESS_MEM_MASK; + aperphys = aperphys >> 22; + + if (private_data.split_gtt) { + /* Only use half of the entries */ + new_order = order-1; + } else { + /* Full GTT, use all entries */ + new_order = order; + } + + for (i = 0; i < (1 << new_order); i++) { + /* Set the address for 2D/3D*/ + sgx_dir[i] = agp_bridge->gatt_bus_addr + (PAGE_SIZE * i); + /* Set the address for hostport */ + sgx_dir[i+aperphys] = agp_bridge->gatt_bus_addr + (PAGE_SIZE * i); + + /* Mark them as valid */ + sgx_dir[i] |= 0x01; + sgx_dir[i+aperphys] |= 0x01; + + //AGN_DEBUG("Directory %d is %08lx", i, sgx_dir[i]); + } + + /* If we're in split gtt mode, set the directory entries of the second + * gtt + */ + + if (private_data.split_gtt) { + j=0; + for (i = (1 << (order - 1)); i < (1 << order); i++) { + /* Set the address for 2D/3D*/ + sgx_dir[i] = virt_to_phys(private_data.upper_gtt) + (PAGE_SIZE * j); + /* Set the address for hostport */ + sgx_dir[i+aperphys] = virt_to_phys(private_data.upper_gtt) + (PAGE_SIZE * j); + + j++; + + /* Mark them as valid */ + sgx_dir[i] |= 0x01; + sgx_dir[i+aperphys] |= 0x01; + //AGN_DEBUG("Directory %d is %08lx", i, sgx_dir[i]); + } + } + + /* + * Program the directory's address into the MMU control + * register + */ + + /* Flush the cache */ + flush_cache_all(); + global_cache_flush(); + + /* Invalidate directory cache */ + sgx_mmu = readl(private_data.registers + 0x40C00); + sgx_mmu |= 0x1E; + writel(sgx_mmu, private_data.registers + 0x40C00); + wmb(); + readl(private_data.registers + 0x40C00); + + writel(virt_to_phys(sgx_dir), private_data.registers + 0x40C84); + wmb(); + readl(private_data.registers + 0x40C84); + + /* Turn on host access to aperture via the MMU */ + sgx_mmu = readl(private_data.registers + 0x40C00); + sgx_mmu &= 0xFFFE0000; + writel(sgx_mmu, private_data.registers + 0x40C00); + wmb(); + readl(private_data.registers + 0x40C00); + + return 0; +} + + +static int AGP_CREATE_GATT(iegd_plb_create_gatt_table) +{ + u32 order; + u32 mmio_bus_addr, temp2; + int ret; + u32 gtt_size; + unsigned char msac; + u32 msac_gtt_size; + + agp_bridge->gatt_table_real = NULL; + + order=A_SIZE_FIX(agp_bridge->current_size)->page_order; + + /* Find and save the address of the MMIO register */ + pci_read_config_dword(private_data.pdev, I915_MMADDR, + &mmio_bus_addr); + mmio_bus_addr &= 0xFFF80000; + + private_data.registers = (volatile u8 *) ioremap(mmio_bus_addr, + KB(512)); + + if (!private_data.registers) { + AGN_ERROR("ioremap failed to map mmio"); + return (-ENOMEM); + } + + pci_read_config_dword(private_data.pdev, I915_PTEADDR, &temp2); + + /* Get the GTT size via MSAC */ + pci_read_config_byte(private_data.pdev, IUS15_GMCH_MSAC, &msac); + + switch (msac & 0x03) { + case 0x02: /* 256K GTT size */ + msac_gtt_size = KB(256); + break; + case 0x03: /* 128K GTT size */ + default: + msac_gtt_size = KB(128); + break; + } + + gtt_size = A_SIZE_FIX(agp_bridge->current_size)->num_entries * sizeof(u32); + + if (gtt_size!=msac_gtt_size) { + AGN_DEBUG("MSAC GTT size 0x%08x, bridge GTT size 0x%08x; using MSAC", + msac_gtt_size, gtt_size); + gtt_size = msac_gtt_size; + } + + private_data.gtt = (volatile u32 *)ioremap(temp2, gtt_size); + + if (!private_data.gtt) { + AGN_ERROR("ioremap failed to map gtt"); + return (-ENOMEM); + } + + if((ret = iegd_plb_init_gtt(order))) { + return (ret); + } + + agp_bridge->gatt_table = NULL; + + return (0); +} + +static void iegd_plb_cleanup(void) +{ + + iounmap((void *)private_data.gtt); + iounmap((void *)private_data.registers); +} + + +static void iegd_plb_vm_close(struct vm_area_struct *vma) +{ + struct list_head *tmp; + struct client_list_struct *entry; + + down(&client_sem); + list_for_each(tmp, &client_list) { + entry = list_entry(tmp, struct client_list_struct, list); + if (entry->vma == vma) { + list_del(&entry->list); + kfree(entry); + AGN_DEBUG("Removed VMA %p from client list", vma); + break; + } + } + up(&client_sem); +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) +static int iegd_plb_vm_fault(struct vm_area_struct *vma, + struct vm_fault *vmf) +{ + int type=0; /* New fault handler doesn't use type */ + unsigned long address = (unsigned long) vmf->virtual_address; + + vmf->page = iegd_plb_vm_nopage(vma, address, &type); + + return 0; +} +#endif + +static struct page *iegd_plb_vm_nopage(struct vm_area_struct *vma, + unsigned long address, + int *type) +{ + unsigned long offset=0; + unsigned long physaddr=0; + struct page *page; + struct list_head *tmp; + struct client_list_struct *entry; + int flag=0; + + /* On the Intel SCH US15, we don't have a traditional aperture. As + * a result, we're substituting the base of stolen memory + * as the aperture address. + * + * Mmaps relative to the base of stolen memory will be + * treated as mmaps covering parts of our virtual aperture. + * + * Given that a single surface may be mapped, and not the + * whole virtual aperture, we must translate the values + * received so that they are relative to our 0-based virtual + * aperture. + */ + offset = (vma->vm_pgoff << PAGE_SHIFT) - agp_bridge->gart_bus_addr; + + /* All pages returned must be noncached or write-combined*/ + if (agp_use_pat()) { + pgprot_val(vma->vm_page_prot) &= ~(_PAGE_PCD | _PAGE_PWT); + pgprot_val(vma->vm_page_prot) |= _PAGE_PAT; + } else { + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + } + + /* Access to the virtual frame buffer does not appear to + * call open properly before faulting. As a result, we + * need to do this housekeeping at each fault. + */ + down(&client_sem); + list_for_each(tmp, &client_list) { + entry = list_entry(tmp, struct client_list_struct, list); + if (entry->vma == vma) { + flag=1; + } + } + + if (!flag) { + entry = kmalloc(sizeof(struct client_list_struct), GFP_KERNEL); + if (entry) { + entry->vma = vma; + list_add(&(entry->list), &client_list); + AGN_DEBUG("Added VMA %p to client list", vma); + + AGN_DEBUG("Scratch: %p", virt_to_page(agp_bridge->scratch_page)); + + } else { + AGN_ERROR("Failed to add VMA to client list"); + } + } + up(&client_sem); + + offset += address - vma->vm_start; + + if (private_data.split_gtt && ((offset >> PAGE_SHIFT)) >= 0x8000) { + physaddr = readl(private_data.upper_gtt + (offset >> PAGE_SHIFT) + - 0x8000); + } else { + physaddr = readl(private_data.gtt + (offset >> PAGE_SHIFT)); + } + + + physaddr &= PAGE_MASK; + + if (!pfn_valid(physaddr >> PAGE_SHIFT)) { + AGN_ERROR("Referencing non-existant struct page.\n"); + } + + if (physaddr >= agp_bridge->gart_bus_addr) { + AGN_DEBUG("Faulted before insert, returning scratch page"); + page = virt_to_page(__va(agp_bridge->scratch_page)); + } else { + page = virt_to_page(__va(physaddr)); + } + + get_page(page); + + if (type) { + *type = VM_FAULT_MINOR; + } + + return (page); +} + + +int iegd_plb_insert_entries(struct agp_memory *mem, + off_t pg_start, int type) +{ + int i,j,num_entries, zap; + void *temp; + struct list_head *tmp; + struct client_list_struct *entry; + unsigned long addr_start=0; + unsigned long addr_end=0; + unsigned long addr_offset=0; + unsigned long vaddr; + char *srcvirt; + unsigned long srcphys; + unsigned long dstphys; + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + + temp = agp_bridge->current_size; + num_entries = A_SIZE_FIX(temp)->num_entries; + + /* If we try to write beyond gtt table, return error */ + if ((pg_start + mem->page_count) > num_entries) { + AGN_ERROR("Trying to write beyond aperture limit"); + AGN_DEBUG("pg_start=0x%.8lx, mem->page_count=%d," + "num_entries=%d", pg_start, mem->page_count, + num_entries); + return -EINVAL; + } + + /* The i830 can't check the GTT for entries since its read only, + * depend on the caller to make the correct offset decisions. + */ + + if ((type != 0 && type != AGP_PHYS_MEMORY) || + (mem->type != 0 && mem->type != AGP_PHYS_MEMORY)) { + AGN_ERROR("Unsupported memory type"); + AGN_DEBUG("mem->type=%x, type=%x", mem->type, type); + return -EINVAL; + } + + global_cache_flush(); + agp_bridge->driver->tlb_flush(mem); + + for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { + + /* If we're inserting into stolen memory, we need to read + * the contents of the original page that occupied this space + */ + if (j < private_data.gtt_entries) { + srcphys=readl(private_data.gtt+j); + srcphys &= PAGE_MASK; + + if (srcphys >= agp_bridge->gart_bus_addr) { + srcvirt=ioremap(srcphys, PAGE_SIZE); + + if (!srcvirt) { + AGN_ERROR("Could not map stolen memory source %d:%08lX", j, srcphys); + return -ENOMEM; + } + + dstphys=AGP_MASK_GTT(); + dstphys &= PAGE_MASK; + + copy_page(__va(dstphys), srcvirt); + + iounmap(srcvirt); + } else { + AGN_ERROR ("Tried to copy a page not in stolen memory %d:%08lX", j, srcphys); + } + } + + if (private_data.split_gtt && (j >= 0x8000)) { + writel(AGP_MASK_GTT(), private_data.upper_gtt + j - 0x8000); + } else { + writel(AGP_MASK_GTT(), private_data.gtt+j); + readl(private_data.gtt+j); /* PCI Posting. */ + } + + down(&client_sem); + list_for_each(tmp, &client_list) { + entry = list_entry(tmp, struct client_list_struct, list); + + /* We need to handle invalidating VMA's that are only mapping + * a portion of the virtual aperture. Calculate what if + * any invalidated pages need to be zapped + */ + addr_start = (entry->vma->vm_pgoff << PAGE_SHIFT) + - agp_bridge->gart_bus_addr; + addr_end = addr_start + (entry->vma->vm_end - entry->vma->vm_start); + addr_offset = j << PAGE_SHIFT; + + vaddr = entry->vma->vm_start + (addr_offset - addr_start); + + zap=0; + pgd=NULL; + pud=NULL; + pmd=NULL; + pte=NULL; + + pgd = pgd_offset(entry->vma->vm_mm, vaddr); + if (!pgd_none(*pgd)) { + pud = pud_offset(pgd, vaddr); + if (!pud_none(*pud)) { + pmd = pmd_offset(pud, vaddr); + if (!pmd_none(*pmd)) { + pte = pte_offset_map(pmd, vaddr); + if (!pte_none(*pte)) { + zap=1; + } + } + } + } + + /* Only zap a page if it falls within the mapped region + * and it has previously faulted + */ + if (zap && (addr_offset >= addr_start) && + (addr_offset < addr_end)) { + + if (!page_mapcount(pte_page(*pte))) { + AGN_ERROR("ERROR No mapcount"); + AGN_DEBUG("ZI %p %08lX %d %d %p", pte_page(*pte), + pte_page(*pte)->flags, page_count(pte_page(*pte)), + page_mapcount(pte_page(*pte)), pte_page(*pte)->mapping); + } else { + atomic_add_negative(-1, &pte_page(*pte)->_mapcount); + put_page(pte_page(*pte)); + dec_mm_counter(entry->vma->vm_mm, file_rss); + } + + pte_clear(entry->vma->vm_mm, vaddr, pte); + } + + if(pte) { + pte_unmap(pte); + } + } + up(&client_sem); + } + + global_cache_flush(); + agp_bridge->driver->tlb_flush(mem); + + AGN_DEBUG("Exit"); + return 0; +} + + +int iegd_plb_remove_entries(struct agp_memory *mem, + off_t pg_start, int type) +{ + int i, zap; + struct list_head *tmp; + struct client_list_struct *entry; + unsigned long physaddr; + unsigned long addr_start=0; + unsigned long addr_end=0; + unsigned long addr_offset=0; + unsigned long vaddr; + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + + global_cache_flush(); + agp_bridge->driver->tlb_flush(mem); + + for (i = pg_start; i < (mem->page_count + pg_start); i++) { + if (i < private_data.gtt_entries) { + physaddr = agp_bridge->gart_bus_addr + (i * PAGE_SIZE); + physaddr |= 0x01; + writel(physaddr, private_data.gtt+i); + readl(private_data.gtt+i); /* PCI Posting. */ + } else { + if (private_data.split_gtt && (i >= 0x8000)) { + writel(agp_bridge->scratch_page, private_data.upper_gtt + i - 0x8000); + } else { + writel(agp_bridge->scratch_page, private_data.gtt+i); + readl(private_data.gtt+i); /* PCI Posting. */ + } + } + + down(&client_sem); + list_for_each(tmp, &client_list) { + entry = list_entry(tmp, struct client_list_struct, list); + + /* We need to handle invalidating VMA's that are only mapping + * a portion of the virtual aperture. Calculate what if + * any invalidated pages need to be zapped + */ + addr_start = (entry->vma->vm_pgoff << PAGE_SHIFT) + - agp_bridge->gart_bus_addr; + addr_end = addr_start + (entry->vma->vm_end - entry->vma->vm_start); + addr_offset = i << PAGE_SHIFT; + + vaddr = entry->vma->vm_start + (addr_offset - addr_start); + + zap=0; + pgd=NULL; + pud=NULL; + pmd=NULL; + pte=NULL; + + /* Look up page table entries for all VMAs that currently + * have the virtual aperture mapped -- to see if the page + * has ever faulted + */ + pgd = pgd_offset(entry->vma->vm_mm, vaddr); + if (!pgd_none(*pgd)) { + pud = pud_offset(pgd, vaddr); + if (!pud_none(*pud)) { + pmd = pmd_offset(pud, vaddr); + if (!pmd_none(*pmd)) { + pte = pte_offset_map(pmd, vaddr); + if (!pte_none(*pte)) { + zap=1; + } + } + } + } + + /* Only zap a page if it falls within the mapped region + * and it has previously faulted + */ + if (zap && (addr_offset >= addr_start) && + (addr_offset < addr_end)) { + + + if (!page_mapcount(pte_page(*pte))) { + AGN_ERROR("ERROR No mapcount"); + AGN_DEBUG("ZR %p %08lX %d %d %p", pte_page(*pte), + pte_page(*pte)->flags, page_count(pte_page(*pte)), + page_mapcount(pte_page(*pte)), pte_page(*pte)->mapping); + } else { + atomic_add_negative(-1, &pte_page(*pte)->_mapcount); + put_page(pte_page(*pte)); + dec_mm_counter(entry->vma->vm_mm, file_rss); + } + + pte_clear(entry->vma->vm_mm, vaddr, pte); + } + + if(pte) { + pte_unmap(pte); + } + } + up(&client_sem); + } + + global_cache_flush(); + agp_bridge->driver->tlb_flush(mem); + + return 0; +} + + +int iegd_plb_configure(void) +{ + struct aper_size_info_fixed *current_size; + u32 temp; + u16 gmch_ctrl; + int i; + + current_size = A_SIZE_FIX(agp_bridge->current_size); + + /* SCH US15 uses the Base of Stolen Memory as it's artificial + * aperture address + */ + pci_read_config_dword(private_data.pdev, 0x5C, &temp); + agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); + gmch_ctrl |= I830_GMCH_ENABLED; + pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl); + + global_cache_flush(); + agp_bridge->driver->tlb_flush(0); + + writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, + private_data.registers+I810_PGETBL_CTL); + /* PCI Posting. */ + readl(private_data.registers+I810_PGETBL_CTL); + + if (agp_bridge->driver->needs_scratch_page) { + + for (i = private_data.gtt_entries; i < current_size->num_entries; i++) { + if ((private_data.split_gtt) && (i >= 0x8000)) { + writel(agp_bridge->scratch_page, private_data.upper_gtt+i-0x8000); + readl(private_data.upper_gtt+i-0x8000); + } else { + writel(agp_bridge->scratch_page, private_data.gtt+i); + readl(private_data.gtt+i); /* PCI Posting. */ + } + } + } + + global_cache_flush(); + + return 0; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) +static void plb_destroy_pages_by_addr(void *addr, size_t pg_count, unsigned int order) +{ + struct page *page; + + AGN_DEBUG("Enter"); + + if (addr == NULL) { + return; + } + + page = virt_to_page(addr); + SET_PAGES_WB(page, pg_count); + GLOBAL_FLUSH_TLB(); + put_page(page); + AGP_UNLOCK_PAGE(page); + + if(page_count(page) > 1) { + free_pages((unsigned long)addr, order); + } + + atomic_dec(&agp_bridge->current_memory_agp); + + AGN_DEBUG("Exit"); +} +#else +static void plb_destroy_pages(struct page *page, size_t pg_count, unsigned int order) +{ + //AGN_LOG("IN plb_destroy_pages"); + AGN_DEBUG("Enter"); + + if (page == NULL) { + return; + } + + SET_PAGES_WB(page, pg_count); + GLOBAL_FLUSH_TLB(); + put_page(page); + AGP_UNLOCK_PAGE(page); + + if(page_count(page) > 1) { + __free_pages(page, order); + } + + atomic_dec(&agp_bridge->current_memory_agp); + + AGN_DEBUG("Exit"); +} +#endif + +void iegd_plb_free_by_type(struct agp_memory *curr) +{ + unsigned int order; + + switch (curr->page_count) { + case 1: + order = 0; /* pg_count = 1 => 2 ^ 0 */ + break; + case 4: + order = 2; /* pg_count = 4 => 2 ^ 2 */ + break; + case 8: + order = 3; /* pg_count = 8 => 2 ^ 3 */ + break; + default: + /* This case should never happen */ + return; + } + + agp_free_key(curr->key); + if(curr->type == AGP_PHYS_MEMORY) { + PLB_DESTROY_PAGES(curr, curr->page_count, order); + IGD_FREE_MEM(curr); + } + + kfree(curr); + +} + +#endif diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/global.c patch_script_temp/drivers/gpu/drm/iegd/agp/global.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/global.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/agp/global.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,142 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: global.c + * $Revision: 1.17 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "global.h" +#include "intelpci.h" + +/* will point to the current table entries for + * current chipset */ +gart_dispatch_t *gart_id; + +/* Private data that contained chipset information */ +dev_private_data_t private_data; + +int iegd_find_device(u16 device) +{ + struct pci_dev *device_pdev; + + device_pdev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL); + /* Check for function 0. */ + if(device_pdev && PCI_FUNC(device_pdev->devfn) != 0) { + device_pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + device, device_pdev); + } + + if(!device_pdev) { + return 0; + } + + AGN_DEBUG("Device found = 0x%x\n", device); + private_data.pdev = device_pdev; + return 1; + +} + +/** + * This function is to hook the function pointer that + * belong to specific chipset, other than that this + * is the place for customization of the structure + * in case chipset in the same family have different + * architecture. Make sure to add new device id here + * if new device been introduce. + * + * parameter: + * driver_hook - Pointer to hold the structure + * did - device id + * list - lookup table for the chipset family + * + * return value: + * 0 - success + * 1 - No function hook + */ +int bridge_driver_init(bridge_driver_t **driver_hook, + unsigned short did, dispatch_table_t *list ) +{ + + (*driver_hook) = (bridge_driver_t *)dispatch_acquire( + gart_id->device_id, list); + + /* For specific chipset implementation assign the pointer + * here. */ + switch(did) { + case PCI_DEVICE_ID_GM45: + case PCI_DEVICE_ID_ELK: + case PCI_DEVICE_ID_Q45: + case PCI_DEVICE_ID_G45: + case PCI_DEVICE_ID_G41: + (*driver_hook)->aperture_sizes = iegd_igm45_sizes; + (*driver_hook)->num_aperture_sizes = 2; + break; + case PCI_DEVICE_ID_Q35: + case PCI_DEVICE_ID_Q35A2: + (*driver_hook)->aperture_sizes = iegd_iq35_sizes; + (*driver_hook)->num_aperture_sizes = 3; + break; + case PCI_DEVICE_ID_915GD: + case PCI_DEVICE_ID_915AL: + case PCI_DEVICE_ID_945G: + case PCI_DEVICE_ID_945GM: + case PCI_DEVICE_ID_945GME: + (*driver_hook)->aperture_sizes = iegd_i915_sizes; + (*driver_hook)->num_aperture_sizes = 4; + break; + case PCI_DEVICE_ID_965G: + case PCI_DEVICE_ID_946GZ: + case PCI_DEVICE_ID_G965: + case PCI_DEVICE_ID_Q965: + case PCI_DEVICE_ID_GM965: + case PCI_DEVICE_ID_GME965: + (*driver_hook)->aperture_sizes = iegd_i965_sizes; + (*driver_hook)->num_aperture_sizes = 4; + break; + case PCI_DEVICE_ID_810: + case PCI_DEVICE_ID_810DC: + case PCI_DEVICE_ID_810E: + case PCI_DEVICE_ID_815: + (*driver_hook)->aperture_sizes = intel_i810_sizes; + (*driver_hook)->num_aperture_sizes = 2; + (*driver_hook)->create_gatt_table = agp_generic_create_gatt_table; + (*driver_hook)->free_gatt_table = agp_generic_free_gatt_table; + break; + case PCI_DEVICE_ID_830M: + case PCI_DEVICE_ID_845G: + case PCI_DEVICE_ID_855: + case PCI_DEVICE_ID_865G: + (*driver_hook)->aperture_sizes = intel_i830_sizes; + (*driver_hook)->num_aperture_sizes = 4; + (*driver_hook)->create_gatt_table = iegd_alm_create_gatt_table; + (*driver_hook)->free_gatt_table = iegd_cmn_free_gatt_table; + break; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,5) + case PCI_DEVICE_ID_PLB: + (*driver_hook)->aperture_sizes = iegd_plb_sizes; + (*driver_hook)->num_aperture_sizes = 1; + break; +#endif + default: + return -1; + } + + return 0; + +} diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/pci.c patch_script_temp/drivers/gpu/drm/iegd/agp/pci.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/agp/pci.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/agp/pci.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,501 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: pci.c + * $Revision: 1.31 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include +#include +#include "agp.h" +#include "global.h" +#include "igd_gart.h" +#include "intelpci.h" +#include "igd_abs.h" + +static gart_dispatch_t gart_pci_device_table[] = { + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_810, PCI_DEVICE_ID_810, + "810", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_810DC, PCI_DEVICE_ID_810DC, + "810DC", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_810E, PCI_DEVICE_ID_810E, + "810E", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_815, PCI_DEVICE_ID_815, + "815", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_830M, PCI_DEVICE_ID_830M, + "830M", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_835, PCI_DEVICE_ID_835, + "835", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_845G, PCI_DEVICE_ID_845G, + "845G", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_855, PCI_DEVICE_ID_855, + "855", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_865G, PCI_DEVICE_ID_865G, + "865G", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_915GD, PCI_DEVICE_ID_915GD, + "915GD", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_910GL, PCI_DEVICE_ID_910GL, + "910GL", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_915AL, PCI_DEVICE_ID_915AL, + "915AL", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_945G, PCI_DEVICE_ID_945G, + "945G", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_945GM, PCI_DEVICE_ID_945GM, + "945GM", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_945GME, PCI_DEVICE_ID_945GME, + "945GME/GSE", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_Q35, PCI_DEVICE_ID_Q35, + "Q33/Q35", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_Q35A2, PCI_DEVICE_ID_Q35A2, + "Q33/Q35", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_965G, PCI_DEVICE_ID_965G, + "965G", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_946GZ, PCI_DEVICE_ID_946GZ, + "946GZ", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_G965, PCI_DEVICE_ID_G965, + "G965", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_Q965, PCI_DEVICE_ID_Q965, + "Q965", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_GM965, PCI_DEVICE_ID_GM965, + "GM965", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_GME965, PCI_DEVICE_ID_GME965, + "GLE960/GME965", 0, 0, 0, + }, +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,5) + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_PLB, PCI_DEVICE_ID_PLB, + "US15", 0, 0, 0, + }, +#endif + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_GM45, PCI_DEVICE_ID_GM45, + "GM45/GS45/GL40", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_ELK, PCI_DEVICE_ID_ELK, + "Q45", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_Q45, PCI_DEVICE_ID_Q45, + "Q45", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_G45, PCI_DEVICE_ID_G45, + "G45", 0, 0, 0, + }, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRIDGE_G41, PCI_DEVICE_ID_G41, + "G41", 0, 0, 0, + }, +}; + +/* PCI device id that supported by IEGD */ +struct pci_device_id iegd_pci_table[] = { + ID(PCI_DEVICE_ID_BRIDGE_810), + ID(PCI_DEVICE_ID_BRIDGE_810DC), + ID(PCI_DEVICE_ID_BRIDGE_810E), + ID(PCI_DEVICE_ID_BRIDGE_815), + ID(PCI_DEVICE_ID_BRIDGE_830M), + ID(PCI_DEVICE_ID_BRIDGE_845G), + ID(PCI_DEVICE_ID_BRIDGE_855), + ID(PCI_DEVICE_ID_BRIDGE_865G), + ID(PCI_DEVICE_ID_BRIDGE_915GD), + ID(PCI_DEVICE_ID_BRIDGE_915AL), + ID(PCI_DEVICE_ID_BRIDGE_945G), + ID(PCI_DEVICE_ID_BRIDGE_945GM), + ID(PCI_DEVICE_ID_BRIDGE_945GME), + ID(PCI_DEVICE_ID_BRIDGE_965G), + ID(PCI_DEVICE_ID_BRIDGE_946GZ), + ID(PCI_DEVICE_ID_BRIDGE_G965), + ID(PCI_DEVICE_ID_BRIDGE_Q965), + ID(PCI_DEVICE_ID_BRIDGE_GM965), + ID(PCI_DEVICE_ID_BRIDGE_GME965), + ID(PCI_DEVICE_ID_BRIDGE_Q35), + ID(PCI_DEVICE_ID_BRIDGE_Q35A2), +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,5) + ID(PCI_DEVICE_ID_BRIDGE_PLB), +#endif + ID(PCI_DEVICE_ID_BRIDGE_GM45), + ID(PCI_DEVICE_ID_BRIDGE_ELK), + ID(PCI_DEVICE_ID_BRIDGE_Q45), + ID(PCI_DEVICE_ID_BRIDGE_G45), + ID(PCI_DEVICE_ID_BRIDGE_G41), + { } +}; + +MODULE_DEVICE_TABLE(pci, iegd_pci_table); + +#include + +static int agp_has_pat = 0; + +int agp_use_pat(void) +{ + return agp_has_pat; +} +EXPORT_SYMBOL(agp_use_pat); + +static void agp_pat_ipi_handler(void *notused) +{ + u32 v1, v2; + + rdmsr(MSR_IA32_CR_PAT, v1, v2); + v2 &= 0xFFFFFFF8; + v2 |= 0x00000001; + wbinvd(); + wrmsr(MSR_IA32_CR_PAT, v1, v2); + __flush_tlb_all(); +} + +/* + * Set i386 PAT entry PAT4 to Write-combining memory type on all processors. + */ + +void agp_init_pat(void) +{ + + if (!boot_cpu_has(X86_FEATURE_PAT)) { + AGN_ERROR("PAT Feature not available\n"); + return; + } + AGN_DEBUG("Enabled PAT"); + if (ON_EACH_CPU(agp_pat_ipi_handler, NULL, 1, 1) != 0) { + AGN_ERROR("Timed out setting up CPU PAT.\n"); + return; + } + agp_has_pat = 1; +} +EXPORT_SYMBOL(agp_init_pat); + + +/* This function get called by PCI core when one of the chipset + * above detected */ +static int __devinit iegd_intel_probe( + struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + bridge_data_t *bridge_device; + u8 cap_ptr = 0; + struct resource *r; + int ret; + + AGN_DEBUG("Enter"); + AGN_LOG("Initialize IEGD agpgart and drm"); + + /* Make sure this probing is called because of prefered + * chipsets. This is because to make sure we initialize + * chipset that belong to deregister gart module */ + if(!gart_id->bridge_pdev || + (gart_id->bridge_pdev->device != pdev->device)) { + return -ENODEV; + } + + cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); + + /* Allocate memory for the bridge. This data structure then will be + * used by the agp backend and frontend */ + gart_id->bridge_info = agp_alloc_bridge(); + if(gart_id->bridge_info == NULL) { + return -ENOMEM; + } + + /* Check for the device and initialize private data */ + if(!iegd_find_device(gart_id->device_id)) { + agp_put_bridge(gart_id->bridge_info); + AGN_ERROR("Unsupported device: %x", gart_id->device_id); + return -ENODEV; + } + + bridge_device = gart_id->bridge_info; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,5) + if (gart_id->device_id == PCI_DEVICE_ID_PLB) { + agp_init_pat(); + bridge_device->vm_ops = &iegd_plb_vm_ops; + } +#endif + + AGN_DEBUG("driver %p, id %X, list %p", bridge_device->driver, + gart_id->device_id, driver_dispatch_list); + /* Dispatch the core function based on the chipset id */ + ret = bridge_driver_init((bridge_driver_t **) &bridge_device->driver, + gart_id->device_id, driver_dispatch_list); + + if(ret) { + agp_put_bridge(gart_id->bridge_info); + AGN_ERROR("Device found but no function hook"); + return -ENODEV; + } + + bridge_device->dev = pdev; + bridge_device->capndx = cap_ptr; + bridge_device->dev_private_data = &private_data; + + AGN_LOG("Intel %s chipset detected", gart_id->name); + + r = &pdev->resource[0]; + if (!r->start && r->end) { + if (pci_assign_resource(pdev, 0)) { + AGN_ERROR("could not assign resource 0"); + agp_put_bridge(gart_id->bridge_info); + return -ENODEV; + } + } + + if(pci_enable_device(pdev)) { + AGN_ERROR("Unable to enable PCI device"); + agp_put_bridge(gart_id->bridge_info); + return -ENODEV; + } + + if(cap_ptr) { + pci_read_config_dword(pdev, + bridge_device->capndx+PCI_AGP_STATUS, + &bridge_device->mode); + } + + pci_set_drvdata(pdev, bridge_device); + AGN_DEBUG("Exit"); + return agp_add_bridge(bridge_device); +} + +static void iegd_intel_remove(struct pci_dev *pdev) +{ + AGN_LOG("Exit from module"); +} + +int iegd_intel_suspend(struct pci_dev *dev, pm_message_t state) +{ + int pm_cap; + struct pci_dev *iegd_dev; + unsigned short pci_pm_csr; + + AGN_DEBUG("Enter"); + + if (!(IGD_IS_SUSPEND(state))) { + AGN_DEBUG("Unsupported PM event %d", state.event); + return -EINVAL; + } + + iegd_dev = private_data.pdev; + + /* Save our resources */ + IGD_PCI_SAVE_STATE(iegd_dev, private_data.pm_save); + + /* Find the PM CSR */ + pm_cap = pci_find_capability(iegd_dev, PCI_CAP_ID_PM); + + if (!pm_cap) { + AGN_DEBUG("No PCI PM capability record.. Exit"); + return 0; + } + + /* Power down the device */ + pci_read_config_word(iegd_dev, pm_cap + PCI_PM_CTRL, &pci_pm_csr); + pci_pm_csr |= PCI_PM_CTRL_STATE_MASK; + pci_write_config_word(iegd_dev, pm_cap + PCI_PM_CTRL, pci_pm_csr); + + AGN_DEBUG("Suspended.. Exit"); + return 0; +} + +int iegd_intel_resume(struct pci_dev *dev) +{ + int pm_cap; + struct pci_dev *iegd_dev; + unsigned short pci_pm_csr; + + AGN_DEBUG("Enter"); + + iegd_dev = private_data.pdev; + + /* Get back our resources */ + IGD_PCI_RESTORE_STATE(iegd_dev, private_data.pm_save); + + /* Find the PM CSR */ + pm_cap = pci_find_capability(iegd_dev, PCI_CAP_ID_PM); + + if (!pm_cap) { + AGN_DEBUG("No PCI PM capability record.. Exit"); + return 0; + } + + /* Power on device */ + pci_read_config_word(iegd_dev, pm_cap + PCI_PM_CTRL, &pci_pm_csr); + pci_pm_csr &= ~PCI_PM_CTRL_STATE_MASK; + pci_write_config_word(iegd_dev, pm_cap + PCI_PM_CTRL, pci_pm_csr); + + AGN_DEBUG("Resumed.. Exit"); + return 0; +} + +static struct pci_driver iegd_pci_driver = { + .name = "iegd-intel", + .id_table = iegd_pci_table, + .probe = iegd_intel_probe, + .remove = __devexit_p(iegd_intel_remove), + .suspend = iegd_intel_suspend, + .resume = iegd_intel_resume, +}; + +struct pci_dev *iegd_probe_device() +{ + int i; + struct pci_dev *dev; + + AGN_DEBUG("Enter"); + + /* Probed for the supported devices */ + for(i=0 ; ibridge_pdev = temp_pdev; + curr_driver = pci_dev_driver(gart_id->bridge_pdev); + + if(curr_driver) { + /* FIXME: Don't know whether we have to make separate copy of this + * structure */ + gart_id->old_gart = curr_driver; + + /* deregister pci driver from pci core. This is needed since we + * don't want 2 agpgart reside in the kernel that respond to the + * same device id */ + AGN_LOG("Unregister agpgart name %s", curr_driver->name); + pci_unregister_driver(curr_driver); + } + + AGN_LOG("Registering iegd gart module"); + /* Register our own to pci core */ + AGN_DEBUG("Exit"); + return pci_register_driver(&iegd_pci_driver); + +} + +static void iegd_restore_device(void) +{ + int ret; + + AGN_DEBUG("Enter"); + + /* Decrement the reference for this pci device */ + pci_dev_put(gart_id->bridge_pdev); + + if(gart_id->old_gart) { + /* Register the original driver */ + ret = pci_register_driver(gart_id->old_gart); + } + + AGN_DEBUG("Exit"); + +} + +static int iegd_gart_init(void) +{ + int ret; + + AGN_DEBUG("Enter"); + + /* Find bridge based on chipset supported by IEGD */ + ret = iegd_agp_init(); + if(AGP_RET(ret)) { + AGN_LOG("Registering iegd drm module"); + /* Initialize DRM module by calling DRM init function */ + return DRM_INIT_MODULE(); + } else { + /* Log the driver failed to register */ + AGN_LOG("Driver registration failed"); + } + + AGN_DEBUG("Exit"); + + /* Return agp error if agp init failed */ + return ret; +} + +static void iegd_gart_exit(void) +{ + /* Unregister DRM module */ + AGN_DEBUG("Unregister iegd DRM module"); + DRM_EXIT_MODULE(); + + /* Remove our device from the kernel */ + AGN_DEBUG("Unregister IKM module"); + pci_unregister_driver(&iegd_pci_driver); + + /* Restore back the old agp gart */ + AGN_DEBUG("Register original module"); + iegd_restore_device(); +} + +MODULE_LICENSE("GPL and additional rights"); + +module_init(iegd_gart_init); +module_exit(iegd_gart_exit); diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/drm_test.c patch_script_temp/drivers/gpu/drm/iegd/drm/drm_test.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/drm_test.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/drm_test.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,288 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: drm_test.c + * $Revision: 1.3 $ + *---------------------------------------------------------------------------- + * Unit level test for IEGD DRM + * Copyright © 2009 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "iegd.h" +#include "iegd_drm_client.h" + +#define DRM_IOCTL_BASE 'd' +#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) +#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) +#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) +#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) + +#define DRM_IOCTL_INTEL_GETPAGES DRM_IOWR(DRM_BASE_COMMAND + \ + DRM_INTEL_GETPAGES, drm_intel_getpages_t) +#define DRM_IOCTL_INTEL_FREEPAGES DRM_IOWR(DRM_BASE_COMMAND + \ + DRM_INTEL_FREEPAGES, drm_intel_freepages_t) +#define DRM_IOCTL_INTEL_INFO_INIT DRM_IOW( DRM_BASE_COMMAND + \ + DRM_INTEL_INFO_INIT, intel_drm_info_t) +#define DRM_IOCTL_INTEL_INFO_GET DRM_IOR( DRM_BASE_COMMAND + \ + DRM_INTEL_INFO_GET, intel_drm_info_t) + +#define PAGE_SIZE 4096 + +#define VERBOSE "-v" + +int main(int argc, char *argv[]) +{ + int file_desc, ret_value, i; + unsigned long *virt_ptr; + int failed=0; + + /* Check for verbose mode */ + int index; + int verbose = 0; + + for (index = 1; index < argc; index++) + { + if(strcmp(argv[index], VERBOSE) == 0) + { + verbose = 1; + printf("Verbose mode.\n"); + } + } + + if (verbose) + { + printf("Starting client\n"); + } + /* Open the drm */ + file_desc=open("/dev/dri/card0",O_RDWR); + + if(file_desc<0){ + /* In case of a different /dev tree struct. + * try /dev/card0 + */ + file_desc=open("/dev/card0",O_RDWR); + } + + if(file_desc<0){ + printf("Can't open device file:%s\n",DRIVER_DESC); + printf("Check for root level permissions."); + printf("Reinstall IKM.\n"); + exit(-1); + } + + if (verbose) + { + printf("Open device file:%d\n",file_desc); + /* This the ioctl that allocates physical memory */ + printf("Testing ioctl for memory allocation\n"); + } + + drm_intel_getpages_t getpages; + /* set the number of bytes we want the drm to allocate */ + getpages.size=(PAGE_SIZE- 1000); + + ret_value=ioctl(file_desc,DRM_IOCTL_INTEL_GETPAGES,&getpages); + if (verbose) + { + printf("IOCTL call memory allocation test:"); + } + if(ret_value<0){ + printf("DRM module failed memory allocation test.\n"); + printf("Reinstall IKM.\n"); + exit(-1); + } + if (verbose) + { + printf(" Success\n"); + printf("size: %d,phy_address: %#x,virt_address: %#x,offset: %#x\n", + getpages.size, getpages.phy_address, getpages.virt_address, + getpages.offset); + + /* test for memory access */ + + printf("Testing ioctl for memory access\n"); + } + + virt_ptr=(unsigned long *)getpages.virt_address; + + /* input 0..10 into subsequent memory */ + + for(i=0;i<=11;i++){ + *virt_ptr=i; + virt_ptr++; + } + + /*read from subsequent memory */ + virt_ptr=(unsigned long *)getpages.virt_address; + for(i=0;i<=11;i++){ + if (verbose) + { + printf("virt_ptr @ %#x,value: %d\n",virt_ptr,*virt_ptr); + } + if(*virt_ptr!=i){ + printf("Failed memory read.\n"); + } + virt_ptr++; + } + if (verbose) + { + printf("IOCTL call memory access test:"); + } + if(failed){ + printf("DRM module failed memory access test.\n"); + printf("Reinstall IKM.\n"); + exit(-1); + } + if (verbose) + { + printf(" Success\n"); + } + /* freeing memory */ + + drm_intel_freepages_t freepages; + freepages.size=getpages.size; + freepages.phy_address=getpages.phy_address; + freepages.virt_address=getpages.virt_address; + if (verbose) + { + printf("Freeing phy_address:%#x,size:%#x\n", + freepages.phy_address,freepages.size); + + printf("Testing ioctl call for info init\n"); + } + /* init the drm info structure in the drm and test its value */ + intel_drm_info_t info; + intel_drm_info_t test_info; + info.device_id=0x456; + info.revision=333; + info.video_memory_offset=0x10245; + info.video_memory_size=987; + info.hw_status_offset=0x444; + if (verbose) + { + + printf("Testing init info device_id: %#x,revision: %d,offset: %#x," + " size: %d, hw_status_offset: %lx\n", info.device_id, info.revision, + info.video_memory_offset, info.video_memory_size, + info.hw_status_offset); + } + + ioctl(file_desc,DRM_IOCTL_INTEL_INFO_INIT,&info); + + if (verbose) + { + printf("Alternative data to init\n"); + } + /* init the drm info structure in the drm and test its value */ + info.device_id=0x123; + info.revision=456; + info.video_memory_offset=0x789; + info.video_memory_size=111; + info.hw_status_offset=0x555; + + if (verbose) + { + printf("Testing init 2nd info device_id: %#x,revision: %d,offset: %#x," + " size: %d, hw_status_offset: %lx\n", info.device_id, info.revision, + info.video_memory_offset, info.video_memory_size, + info.hw_status_offset); + + printf("Get init info\n"); + } + ioctl(file_desc,DRM_IOCTL_INTEL_INFO_GET,&test_info); + + if (verbose) + { + printf("IOCTL call for info init:"); + printf("Got init info device_id: %#x,revision: %d," + "offset: %#x,size:%d, hw_status_offset: %lx\n", test_info.device_id, + test_info.revision, test_info.video_memory_offset, + test_info.video_memory_size, test_info.hw_status_offset); + } + + /* compare with original data to see if its still the same */ + info.device_id=0x456; + info.revision=333; + info.video_memory_offset=0x10245; + info.video_memory_size=987; + info.hw_status_offset=0x444; + failed=0; + + if(info.device_id!=test_info.device_id){ + failed=1; + } + if(info.revision!=test_info.revision){ + failed=1; + } + if(info.video_memory_offset!=test_info.video_memory_offset){ + failed=1; + } + if(info.video_memory_size!=test_info.video_memory_size){ + failed=1; + } + if(info.hw_status_offset!=test_info.hw_status_offset){ + failed=1; + } + + if(failed){ + printf("DRM module failed IOCTL info did not match.\n"); + printf("Reinstall IKM."); + exit(-1); + } + + printf("DRM successfully loaded\n"); + + close(file_desc); + + return 0; + +} diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/drmult.c patch_script_temp/drivers/gpu/drm/iegd/drm/drmult.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/drmult.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/drmult.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,270 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: drmult.c + * $Revision: 1.7 $ + *---------------------------------------------------------------------------- + * Unit level test for IEGD DRM + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/*client to test the ioctl + * make sure you change the permission bits in intel.h to 0,0 + * before you start using this + */ + +#include "iegd.h" + +#include +#include +#include +#include +#include + +#if 0 +#define DRM_IOCTL_BASE 'd' +#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) +#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) +#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) +#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) +#endif + +#include "iegd_drm_client.h" + +#if 0 +#define DRM_IOCTL_INTEL_GETPAGES DRM_IOWR(DRM_BASE_COMMAND + \ + DRM_INTEL_GETPAGES, drm_intel_getpages_t) +#define DRM_IOCTL_INTEL_FREEPAGES DRM_IOWR(DRM_BASE_COMMAND + \ + DRM_INTEL_FREEPAGES, drm_intel_freepages_t) +#define DRM_IOCTL_INTEL_INFO_INIT DRM_IOW( DRM_BASE_COMMAND + \ + DRM_INTEL_INFO_INIT, intel_drm_info_t) +#define DRM_IOCTL_INTEL_INFO_GET DRM_IOR( DRM_BASE_COMMAND + \ + DRM_INTEL_INFO_GET, intel_drm_info_t) +#endif + + +#define PAGE_SIZE 4096 +int main() +{ +int file_desc, ret_value; +printf("Starting client\n"); +/* Open the drm */ +file_desc=open("/dev/dri/card0",O_RDWR); + +if(file_desc<0){ +/* Suse has a different /dev tree struct. + * try /dev/card0 + */ + +file_desc=open("/dev/card0",O_RDWR); + +} + +if(file_desc<0){ + printf("Can't open device file:%s\n",DRIVER_DESC); + exit(-1); +} + +printf("Open device file:%d\n",file_desc); + + +/* Test interrupt IOCTL */ +interrupt_info_t irq_info; + +irq_info.req_status = 0; +irq_info.req_type = READ_INT; /* CLEAR_INT, WAIT_INT */ +irq_info.in[0] = 0xffffffff; +irq_info.in[1] = 0xffffffff; +irq_info.in[2] = 0xffffffff; +irq_info.in[3] = 0xffffffff; +irq_info.in[4] = 0xa5a5a5a5; +irq_info.in[5] = 0xdeadbeef; + +ret_value = ioctl(file_desc, DRM_IOCTL_INTEL_INTERRUPT, &irq_info); +printf("ULT IOCTL call read interrupt tests: %d\n\n", irq_info.req_status); + +irq_info.req_status = 0; +irq_info.req_type = WAIT_INT; +irq_info.in[0] = 0xffffffff; +irq_info.in[1] = 0xffffffff; +irq_info.in[2] = 0xffffffff; +irq_info.in[3] = 0xffffffff; + +ret_value = ioctl(file_desc, DRM_IOCTL_INTEL_INTERRUPT, &irq_info); +printf("ULT IOCTL call wait interrupt tests: %d\n\n", irq_info.req_status); + + + +/* This the ioctl that allocates physical memory */ +printf("ULT: Testing ioctl for memory allocation\n"); + +drm_intel_getpages_t getpages; +/* set the number of bytes we want the drm to allocate */ +getpages.size=(PAGE_SIZE- 1000); + +ret_value=ioctl(file_desc,DRM_IOCTL_INTEL_GETPAGES,&getpages); +printf("ULT IOCTL call memory allocation test:"); +if(ret_value<0){ + printf(" Failed\n"); + exit(-1); +} +printf(" Success\n"); +printf("size%d,phy_address:%#x,virt_address:%#x,offset:%#x\n",getpages.size,getpages.phy_address,getpages.virt_address,getpages.offset); + +/* test for memory access */ + +printf("ULT: Testing ioctl for memory access\n"); +int i; +unsigned long *virt_ptr; + +virt_ptr=(unsigned long *)getpages.virt_address; + +/* input 0..10 into subsequent memory */ + +for(i=0;i<=11;i++){ +*virt_ptr=i; +virt_ptr++; + +} + +/*read from subsequent memory */ +int failed=0; +virt_ptr=(unsigned long *)getpages.virt_address; +for(i=0;i<=11;i++){ + printf("virt_ptr@%#x,value:%d\n",virt_ptr,*virt_ptr); + if(*virt_ptr!=i){ + printf("Test failed!\n"); + } +virt_ptr++; +} +printf("ULT IOCTL call memory access test:"); +if(failed){ + printf(" Failed\n"); + exit(-1); +} + + printf(" Success\n"); +/* freeing memory */ + +drm_intel_freepages_t freepages; +freepages.size=getpages.size; +freepages.phy_address=getpages.phy_address; +freepages.virt_address=getpages.virt_address; +printf("Freeing phy_address:%#x,size:%#x\n",freepages.phy_address,freepages.size); + +/* init the drm info structure in the drm and test its value */ + +printf("ULT: Testing ioctl call for info init\n"); + intel_drm_info_t info; + intel_drm_info_t test_info; + info.device_id=0x456; + info.revision=333; + info.video_memory_offset=0x10245; + info.video_memory_size=987; + info.hw_status_offset=0x444; + + printf("Testing init info device_id:%#x,revision:%d,offset:%#x,size:%d,hw_status_offset:%lx\n", + info.device_id,info.revision,info.video_memory_offset,info.video_memory_size,info.hw_status_offset); + + ioctl(file_desc,DRM_IOCTL_INTEL_INFO_INIT,&info); + +/* init the drm info structure in the drm and test its value */ +printf("Alternative data to init\n"); + info.device_id=0x123; + info.revision=456; + info.video_memory_offset=0x789; + info.video_memory_size=111; + info.hw_status_offset=0x555; + + printf("Testing init 2nd info device_id:%#x,revision:%d,offset:%#x,size:%d,hw_status_offset:%lx\n", + info.device_id,info.revision,info.video_memory_offset,info.video_memory_size,info.hw_status_offset); + + ioctl(file_desc,DRM_IOCTL_INTEL_INFO_INIT,&info); + + +printf("Get init info\n"); + ioctl(file_desc,DRM_IOCTL_INTEL_INFO_GET,&test_info); + + printf("Got init info device_id:%#x,revision:%d,offset:%#x,size:%d,hw_status_offset:%lx\n", + test_info.device_id,test_info.revision,test_info.video_memory_offset,test_info.video_memory_size,test_info.hw_status_offset); +/* compare with original data to see if its still the same */ +info.device_id=0x456; +info.revision=333; +info.video_memory_offset=0x10245; +info.video_memory_size=987; +info.hw_status_offset=0x444; +failed=0; + +if(info.device_id!=test_info.device_id){ + failed=1; +} +if(info.revision!=test_info.revision){ + failed=1; +} +if(info.video_memory_offset!=test_info.video_memory_offset){ + failed=1; +} +if(info.video_memory_size!=test_info.video_memory_size){ + failed=1; +} +if(info.hw_status_offset!=test_info.hw_status_offset){ + failed=1; +} + +printf("ULT IOCTL call for info init:"); +if(failed){ + printf(" Failed\n"); + exit(-1); +} + + printf(" Success\n"); + +close(file_desc); +/* +sleep(100000000000); +*/ +return 0; + +} diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd.h patch_script_temp/drivers/gpu/drm/iegd/drm/iegd.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/iegd.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,117 @@ + +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd.h + * $Revision: 1.7 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#include +#ifndef __IEGD_H__ +#define __IEGD_H__ + +/* General customization: + */ +#define __HAVE_AGP 1 +#define __MUST_HAVE_AGP 0 +#define __HAVE_MTRR 0 +#define __HAVE_CTX_BITMAP 1 + +#define DRIVER_AUTHOR " " + +#define DRIVER_NAME "iegd" +#define DRIVER_DESC "Intel DRM" +#define DRIVER_DATE "20081022" + +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 0 +#define DRIVER_PATCHLEVEL 1 + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,5) +#define KERNEL265 1 +#endif + +#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))) +#define KERNEL2611 1 +#endif + +#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))) +#define KERNEL2615 1 +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +#define KERNEL2624 1 +#endif + +#ifndef KERNEL265 +#define KERNEL265 0 +#endif + +#ifndef KERNEL2611 +#define KERNEL2611 0 +#endif + +#ifndef KERNEL2615 +#define KERNEL2615 0 +#endif + +#ifndef KERNEL2624 +#define KERNEL2624 0 +#endif + +/* For some arcane reasons certain stuff needs to be defined in this file. + * This is being defined in intel_interface_265.h.If not the drm won't + * compile properly. + */ +#include "iegd_interface_265.h" +#include "iegd_interface_2611.h" +#include "iegd_interface_2615.h" +#include "iegd_interface_2624.h" + +#endif diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_drm.h patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_drm.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_drm.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_drm.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,116 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_drm.h + * $Revision: 1.7 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _IEGD_DRM_H__ +#define _IEGD_DRM_H__ + +#include "iegd_drm_client.h" + +/* INTEL specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ + +#define DRM_IOCTL_INTEL_GETPAGES DRM_IOWR(DRM_BASE_COMMAND + \ + DRM_INTEL_GETPAGES, drm_intel_getpages_t) +#define DRM_IOCTL_INTEL_FREEPAGES DRM_IOWR(DRM_BASE_COMMAND + \ + DRM_INTEL_FREEPAGES, drm_intel_freepages_t) +#define DRM_IOCTL_INTEL_INFO_INIT DRM_IOW( DRM_BASE_COMMAND + \ + DRM_INTEL_INFO_INIT, intel_drm_info_t) +#define DRM_IOCTL_INTEL_INFO_GET DRM_IOR( DRM_BASE_COMMAND + \ + DRM_INTEL_INFO_GET, intel_drm_info_t) +#define DRM_IOCTL_INTEL_INTERRUPT DRM_IOWR( DRM_BASE_COMMAND + \ + DRM_INTEL_INTERRUPT, interrupt_info_t) + +/* New ioctl to set kernel params: + */ +typedef struct drm_intel_listpages { + int pid; + int size; + unsigned long phy_address; + unsigned long virt_address; + unsigned long offset; +} drm_intel_listpages_t; + +typedef struct drm_intel_list{ + struct list_head head; + drm_intel_listpages_t *page; +}drm_intel_list_t; +/* + * This is the basic information structure that is obtained from the + * IEGD XFree driver. + */ +typedef struct intel_device_private{ + drm_intel_list_t *pagelist; + intel_drm_info_t *info_ptr; + spinlock_t irqmask_lock; + uint8_t *sgx_reg; + uint8_t *vdc_reg; + uint8_t *msvdx_reg; + uint32_t sgx_irq_mask; + uint32_t sgx_irq_mask2; + uint32_t vdc_irq_mask; + uint32_t msvdx_irq_mask; + /* interrupt status bits returned once woken up */ + uint32_t interrupt_status; + int irq_enabled; + /* condition to wake up on */ + unsigned int event_present; + wait_queue_head_t event_queue; + /* interrupts that have already occured */ + unsigned int out_vdc; + unsigned int out_sgx; + unsigned int out_sgx2; + unsigned int out_mtx; +} intel_device_private_t; + +#endif /* _INTEL_DRM_H_ */ + diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_drm_client.h patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_drm_client.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_drm_client.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_drm_client.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,139 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_drm_client.h + * $Revision: 1.7 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __IEGD_DRM_CLIENT_H__ +#define __IEGD_DRM_CLIENT_H__ + +/* Requests made from client to drm */ +#define CLEAR_INT 1 +#define WAIT_INT 2 +#define READ_INT 3 +#define UNMASK_INT 4 +#define MASK_INT 5 + +/* Responses returned to the client from drm */ +#define INT_INVALID -1 +#define INT_NOOP 0 +#define INT_CLEARED 1 +#define INT_HANDLED 2 +#define INT_READ 3 +#define INT_STORED 4 +#define INT_TIMEOUT 5 + +typedef struct drm_intel_getpages { + int size; + unsigned long phy_address; + unsigned long virt_address; + unsigned long offset; +} drm_intel_getpages_t; + +typedef struct drm_intel_freepages { + int size; + unsigned long phy_address; + unsigned long virt_address; + unsigned long offset; +} drm_intel_freepages_t; + +/* + * This is the basic information structure that is is obtained from the + * IEGD drm driver. + */ +typedef struct _intel_drm_info { + unsigned long device_id; + unsigned long revision; + unsigned long video_memory_offset; + unsigned long video_memory_size; + unsigned long hw_status_offset; +} intel_drm_info_t; + +typedef struct { + /* request status returned to client */ + unsigned int req_status; + /* what type of request is being made to drm (clear/wait/read) */ + unsigned int req_type; + /* which interrupts to clear or look for */ + unsigned long in[8]; /* Array of device dependant mask/request bits */ + /* interrupts that have already occured, returned to the client */ + unsigned long out[8]; /* Array of device dependant status bits */ +} interrupt_info_t; + +#define DRM_IOCTL_BASE 'd' +#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) +#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) +#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) +#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) + +/* IOCTL numbers to be used along side drmCommand* in Xserver + * example taken from intel_dri.c: + * drmCommandWrite(iptr->drm_sub_fd + * , DRM_INTEL_INFO_INIT + * , &info,sizeof(intel_drm_info_t) + */ + +#define DRM_BASE_COMMAND 0x40 +#define DRM_INTEL_GETPAGES 0x01 +#define DRM_INTEL_FREEPAGES 0x02 +#define DRM_INTEL_INFO_INIT 0x03 +#define DRM_INTEL_INFO_GET 0x04 +#define DRM_INTEL_INTERRUPT 0x05 + +#define DRM_IOCTL_INTEL_GETPAGES DRM_IOWR(DRM_BASE_COMMAND + \ + DRM_INTEL_GETPAGES, drm_intel_getpages_t) +#define DRM_IOCTL_INTEL_FREEPAGES DRM_IOWR(DRM_BASE_COMMAND + \ + DRM_INTEL_FREEPAGES, drm_intel_freepages_t) +#define DRM_IOCTL_INTEL_INFO_INIT DRM_IOW( DRM_BASE_COMMAND + \ + DRM_INTEL_INFO_INIT, intel_drm_info_t) +#define DRM_IOCTL_INTEL_INFO_GET DRM_IOR( DRM_BASE_COMMAND + \ + DRM_INTEL_INFO_GET, intel_drm_info_t) +#define DRM_IOCTL_INTEL_INTERRUPT DRM_IOWR( DRM_BASE_COMMAND + \ + DRM_INTEL_INTERRUPT, interrupt_info_t) +#endif diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_drv.c patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_drv.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_drv.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_drv.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,59 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_drv.c + * $Revision: 1.5 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include "iegd.h" +#include +#include +#include "iegd_drm.h" +#include "iegd_drv.h" + diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_drv.h patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_drv.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_drv.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_drv.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,216 @@ + +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_drv.h + * $Revision: 1.15 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _IEGD_DRV_H_ +#define _IEGD_DRV_H_ + +#define KB(x) ((x) * 1024) +#define MB(x) (KB (KB (x))) +#define GB(x) (MB (KB (x))) +#include "iegd_drm.h" +#include "igd_gart.h" + +/* Define the PCI IDs below */ +#define INTEL_PCI_IDS \ + {0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x27a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x27ae, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2972, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2a02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2a12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x29c2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x29b2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2e02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2e32, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0, 0, 0} + +/* Latest kernel remove this macro from drmP.h */ +#ifndef VM_OFFSET +#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) +#endif + +#ifndef DRMFILE +#define DRMFILE struct file * +#endif + +/* + * We check kernel version here because in kernel 2.6.23 onward some of the + * structure definition for the drm have been change. They have remove all the + * typedef for the drm data structure to follow kernel coding guidelines. This + * causing backward compatibility problem with IKM. Since only the typedef and + * the way they handling link list are changing, to create separate file just + * for handling this changes are redundant since implementation wise are + * still the same. + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) +typedef struct drm_device drm_device_t; +typedef struct drm_file drm_file_t; +typedef struct drm_map drm_map_t; +typedef struct drm_map_list drm_map_list_t; +typedef struct drm_vma_entry drm_vma_entry_t; +typedef struct drm_ioctl_desc drm_ioctl_desc_t; + +#define INSERT_VMA() \ + mutex_lock(&dev->struct_mutex); \ + vma_entry->vma = vma; \ + vma_entry->pid = current->pid; \ + list_add(&vma_entry->head, &dev->vmalist); \ + mutex_unlock(&dev->struct_mutex); + +#define LIST_FOR_EACH(l, d) list_for_each((l), &(d)->maplist) + +#else + +#define INSERT_VMA() \ + mutex_lock(&dev->struct_mutex); \ + vma_entry->vma = vma; \ + vma_entry->next = dev->vmalist; \ + vma_entry->pid = current->pid; \ + dev->vmalist = vma_entry; \ + mutex_unlock(&dev->struct_mutex); + +#define LIST_FOR_EACH(l, d) list_for_each((l), &(d)->maplist->head) + +#endif /* #if LINUX_VERSION_CODE */ + +/* Define the prototype and interfaces for functions for the different + * kernel version below. + */ + +/* function definition in intel_interface.c */ +extern int intel_mmap_buffers(struct file *filp,struct vm_area_struct *vma); + +/* function definition to get pages this is in intel_interface*/ +extern int intel_getpages( drm_device_t *dev,struct file *filp, unsigned long arg ); + +extern int intel_freepages(drm_device_t *dev , unsigned long arg ); + +extern int intel_drm_info_init( drm_device_t *dev, unsigned long arg ); + +extern int intel_drm_info_get( drm_device_t *dev, unsigned long arg ); + +extern int intel_postinit(intel_device_private_t **priv); + +extern int intel_prerelease(drm_device_t *dev); + +/* Functions in intel_interface_265.c used in 2.6.5 kernel and below */ + +extern int intel_postinit_265(drm_device_t *dev); + +extern int intel_prerelease_265(drm_device_t *dev); + +extern int intel_getpages_265( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +extern int intel_freepages_265( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +extern int intel_drm_info_init_265( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +extern int intel_drm_info_get_265( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +/* Functions in intel_interface_2611.c used in 2.6.11 kernel and above */ + +extern int intel_postinit_2611(struct drm_device *dev,unsigned long flags); + +extern void intel_prerelease_2611(drm_device_t *dev,DRMFILE filp); + +extern int intel_getpages_2611( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +extern int intel_freepages_2611( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +extern int intel_drm_info_init_2611( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +extern int intel_drm_info_get_2611( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +extern unsigned long intel_alloc_pages(int order, int area); + +extern void intel_free_pages(unsigned long address, int order, int area); + +extern int drm_plb_mmap(struct file *, struct vm_area_struct *); + +extern struct vm_operations_struct iegd_plb_vm_ops_drm; +extern gart_dispatch_t *gart_id; +extern dev_private_data_t private_data; + +extern irqreturn_t psb_irq_handler(DRM_IRQ_ARGS); +extern void psb_irq_preinstall(struct drm_device *dev); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) +extern void psb_irq_postinstall(struct drm_device *dev); +#else +extern int psb_irq_postinstall(struct drm_device *dev); +#endif +extern void psb_irq_uninstall(struct drm_device *dev); +extern int psb_init(intel_device_private_t *priv); +int intel_drm_plb_interrupts( drm_device_t *dev, void *data ); +#endif + diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface.c patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,888 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_interface.c + * $Revision: 1.23 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "iegd.h" +#include "igd_abs.h" +#include "drmP.h" +#include "drm.h" + +#include "iegd_drm.h" +#include "iegd_drv.h" +#include "psb_intregs.h" + +#ifndef MSR_IA32_CR_PAT +#define MSR_IA32_CR_PAT 0x0277 +#endif +#ifndef _PAGE_PAT +#define _PAGE_PAT 0x080 +#endif + +extern void agp_init_pat(void); +extern int agp_use_pat (void); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) +int drm_irq_install(drm_device_t *dev); +#endif + +/* get intel_buffer_fops from the interface_###.c files */ +extern struct file_operations intel_buffer_fops; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,5) +extern struct vm_operations_struct iegd_plb_vm_ops; +#endif + + +/* Global variable to keep track the amount of memory we are using */ +static int memory; + +/* Our own mmap function to memory map physical to user space memory + */ +int intel_mmap_buffers(struct file *filp, struct vm_area_struct *vma) +{ + DRM_DEBUG("\n"); + + lock_kernel(); + vma->vm_flags |= (VM_IO | VM_RESERVED); + vma->vm_file = filp; + unlock_kernel(); + + DRM_DEBUG("VM_OFFSET(vma):%#x\n",(unsigned int)VM_OFFSET(vma)); + if (REMAP_PAGE( vma, + vma->vm_start, + VM_OFFSET(vma), + (vma->vm_end - vma->vm_start), + pgprot_noncached(vma->vm_page_prot))){ + return -EAGAIN; + } + + return 0; +} + +/* IOCTL to Allocate size pages and mmap it to the client calling it with + * corresponding virtual address + */ +int intel_getpages( drm_device_t *dev, struct file *filp, unsigned long arg ){ + + drm_intel_getpages_t getpages; + /* allocate some bytes */ + unsigned long bytes; + int order; + int size; + + unsigned long address; + unsigned long phy_address; + unsigned long offset; + + struct page *pg; + + unsigned long virtual; + struct file_operations *old_fops; + + intel_device_private_t *dev_ptr=dev->dev_private; + drm_intel_listpages_t *page; + drm_intel_list_t *list; + + DRM_DEBUG("\n"); + /* copy user arguments */ + if(copy_from_user(&getpages, (void __user *) arg, sizeof(getpages))){ + return -EFAULT; + } + + bytes=getpages.size; + /* Check to see if this allocation would exceed 16MEG in total memory + * This is to prevent denial of service attack. 16Meg should be enough. + */ + if((memory+bytes)>MB(16) ){ + /* We exceeded 16MEG. Bail out */ + DRM_ERROR("Total memory allocated exceeded 16Meg!\n"); + return -EFAULT; + } + + /*number of pages that are needed*/ + size=bytes>>PAGE_SHIFT; + if(bytes & ~(PAGE_SIZE*size)){ + ++size; + } + order=ORDER(size); + DRM_DEBUG("Allocating bytes:%#lx,size:%d,order:%d\n", + (unsigned long)bytes,size,order); + /* allocate the pages */ + /* returns kernel logical address. + * Is this the same as the kernel virtual address?? + */ + address=ALLOC_PAGES(order,0); + if(!address){ + DRM_ERROR("Can't get pages\n"); + return -EFAULT; + } + phy_address=__pa(address); + + /* Find virtual address of the phys address */ + pg=virt_to_page((void *)address); + offset=pg->index; + /* Find the number of bytes that is actually allocated */ + size=PAGE_SIZE<mm->mmap_sem); + + old_fops= (struct file_operations *)filp->f_op; + filp->f_op=&intel_buffer_fops; + + virtual=do_mmap(filp,0,size,PROT_READ|PROT_WRITE,MAP_SHARED,phy_address); + + filp->f_op=old_fops; + up_write(¤t->mm->mmap_sem); + DRM_DEBUG("Mmaped virtual:%#lx,address:%#lx\n",virtual, + (unsigned long)__va(phy_address)); + if(virtual > -1024UL){ + DRM_ERROR("mmap failed:%d\n",(int)virtual); + return -EFAULT; + } + getpages.phy_address=phy_address; + getpages.virt_address=virtual; + getpages.size=size; + getpages.offset=offset; + + DRM_DEBUG("Mmap success requested size:%d (%d)\n", + getpages.size,(int)bytes); + + /* alloc the page to be put into the linked list */ + page=ALLOC(sizeof(*page),DRM_MEM_DRIVER); + if(!page){ + DRM_DEBUG("Can't alloc list for page\n"); + return -ENOMEM; + } + + /*page->pid=current->pid;*/ + page->pid=current->group_leader->pid; + page->size=size; + page->phy_address=phy_address; + page->virt_address=virtual; + page->offset=offset; + + DRM_DEBUG("parent pid:%d,pid:%d,group_leader->pid:%d\n" + ,current->parent->pid,current->pid,current->group_leader->pid); + /* Alloc the list to be added then add it to the linked list */ + list=ALLOC(sizeof(*list),DRM_MEM_DRIVER); + if(!list){ + DRM_DEBUG("Can't alloc list for page\n"); + FREE(page,sizeof(*page),0); + return -ENOMEM; + } + memset(list,0,sizeof(*list)); + list->page=page; + LOCK_DRM(dev); + list_add(&list->head,&dev_ptr->pagelist->head); + UNLOCK_DRM(dev); + if(copy_to_user((void __user *) arg,&getpages,sizeof(getpages))){ + return -EFAULT; + } + /* update the total amount of memory we use */ + memory+=size; + DRM_DEBUG("memory has:%d bytes\n",memory); + +return 0; +} + +/* IOCTL to free pages that are allocated by getpages + */ +int intel_freepages( drm_device_t *dev, unsigned long arg ){ + + drm_intel_freepages_t freepages; + /* allocate some bytes */ + unsigned long bytes; + int order; + int size; + + intel_device_private_t *dev_ptr=dev->dev_private; + drm_intel_listpages_t *page; + drm_intel_list_t *r_list=NULL; + struct list_head *pagelist; + + DRM_DEBUG("Freeing pages\n"); + /* copy user arguments */ + if(copy_from_user(&freepages, (void __user *) arg, sizeof(freepages))){ + return -EFAULT; + } + + bytes=freepages.size; + /*number of pages that are needed*/ + size=bytes>>PAGE_SHIFT; + if(bytes & ~(PAGE_SIZE*size)){ + ++size; + } + order=ORDER(size); + DRM_DEBUG("bytes:%d,size:%d,order:%d,phy_address:%#lx\n",(int)bytes,(int)size,(int)order,freepages.phy_address); + + /* free the pages */ + DRM_DEBUG("freeing address:%#lx,size:%#lx\n",(unsigned long)__va(freepages.phy_address),(unsigned long)bytes); + + DRM_DEBUG("parent pid:%d,pid:%d,group_leader->pid:%d\n" + ,current->parent->pid,current->pid,current->group_leader->pid); + /* See if the requested address is in our page list */ + LOCK_DRM(dev); + pagelist=&dev_ptr->pagelist->head; + list_for_each(pagelist,&dev_ptr->pagelist->head){ + r_list=list_entry(pagelist,drm_intel_list_t,head); + if((r_list->page->pid==current->group_leader->pid) + && (r_list->page->phy_address==freepages.phy_address)){ + + DRM_DEBUG("found pid:%d\n",current->group_leader->pid); + DRM_DEBUG("size:%d\n",r_list->page->size); + DRM_DEBUG("phy_address:%#lx\n",r_list->page->phy_address); + DRM_DEBUG("virt_add:%#lx\n",r_list->page->virt_address); + DRM_DEBUG("offset:%#lx\n",r_list->page->offset); + + break; + } + + } + if(pagelist==(&dev_ptr->pagelist->head)){ + DRM_DEBUG("Can't find pages alloc for pid:%d\n",current->pid); + UNLOCK_DRM(dev); + return -EINVAL; + } + + /* munmap the region 1st */ + down_write(¤t->mm->mmap_sem); + DRM_DEBUG("Unmapping virt_address:%#lx\n",freepages.virt_address); + do_munmap(current->mm,freepages.virt_address,bytes); + up_write(¤t->mm->mmap_sem); + + /* Free the pages! */ + FREE_PAGES((unsigned long)__va(freepages.phy_address),order,0); + + /* Free the page list */ + page=r_list->page; + list_del(pagelist); + size=r_list->page->size; + FREE(pagelist,sizeof(*pagelist),0); + FREE(page,sizeof(*page),0); + UNLOCK_DRM(dev); + + /* update the total memory that we use */ + memory-=size; + DRM_DEBUG("memory has:%d bytes\n",memory); + return 0; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) +/* This code is copied verbatim from the DRM module code in + * IKM/val/drm/drmv11p0/drm_irq.c. It's here because we + * need to activate interrupt handling, but for some reason the DRM module + * only exports the routine to disable interrupt handling drm_irq_uninstall(), + * and not the one to install. + * + * This could be problematic when new DRM versions appear. + * + * Fortunately, should a new DRM version appear, it should export + * drm_irq_install(), and then this source won't be needed at all; the + * code should compile cleanly with an external reference if this + * static version is removed completely. + */ +int drm_irq_install(drm_device_t * dev) +{ + int ret; + unsigned long sh_flags = 0; + int dev_irq = 0; + + if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) + return -EINVAL; + + dev_irq = DRM_DEV_TO_IRQ(dev); + if (dev_irq == 0) + return -EINVAL; + + mutex_lock(&dev->struct_mutex); + + /* Driver must have been initialized */ + if (!dev->dev_private) { + mutex_unlock(&dev->struct_mutex); + return -EINVAL; + } + + if (dev->irq_enabled) { + mutex_unlock(&dev->struct_mutex); + return -EBUSY; + } + dev->irq_enabled = 1; + mutex_unlock(&dev->struct_mutex); + + DRM_DEBUG("%s: irq=%d\n", __FUNCTION__, dev_irq); + + /* + if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) { + init_waitqueue_head(&dev->vbl_queue); + + spin_lock_init(&dev->vbl_lock); + + INIT_LIST_HEAD(&dev->vbl_sigs.head); + INIT_LIST_HEAD(&dev->vbl_sigs2.head); + + dev->vbl_pending = 0; + } + */ + + /* Before installing handler */ + dev->driver->irq_preinstall(dev); + + /* Install handler */ + if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) + sh_flags = IRQF_SHARED; + + ret = request_irq(dev_irq, dev->driver->irq_handler, + sh_flags, dev->devname, dev); + if (ret < 0) { + mutex_lock(&dev->struct_mutex); + dev->irq_enabled = 0; + mutex_unlock(&dev->struct_mutex); + return ret; + } + + /* After installing handler */ + dev->driver->irq_postinstall(dev); + + return 0; +} +#endif + +/* IOCTL to init the info that is needed by the client + */ +int intel_drm_info_init( drm_device_t *dev, unsigned long arg ){ + + intel_drm_info_t info; + intel_drm_info_t *info_ptr; + intel_device_private_t *dev_ptr; + + DRM_DEBUG("info init succesful dev_private:%#lx\n",(unsigned long)dev->dev_private); + dev_ptr=dev->dev_private; + /* See if dev_private is already allocated */ + if(!dev->dev_private){ + DRM_ERROR("dev_private not allocated!\n"); + return 0; + } + info_ptr=dev_ptr->info_ptr; + /* See if info is already allocated */ + if(info_ptr->device_id){ + DRM_ERROR("Info already allocated!\n"); + return 0; + } + + /* copy user arguments */ + if(copy_from_user(&info, (void __user *) arg, sizeof(info))){ + return -EFAULT; + } + + info_ptr->device_id=info.device_id; + info_ptr->revision=info.revision; + info_ptr->video_memory_offset=info.video_memory_offset; + info_ptr->video_memory_size=info.video_memory_size; + info_ptr->hw_status_offset=info.hw_status_offset; + DRM_DEBUG("device_id:%#lx,revision:%#lx,offset:%#lx,size:%#lx,hw_status_offset:%lx\n", + info_ptr->device_id,info_ptr->revision, + info_ptr->video_memory_offset,info_ptr->video_memory_size, + info_ptr->hw_status_offset); +return 0; +} +/* IOCTL to get the info that is needed by the client + */ +int intel_drm_info_get( drm_device_t *dev, unsigned long arg ){ + + intel_drm_info_t info; + intel_device_private_t *dev_ptr=dev->dev_private; + intel_drm_info_t *info_ptr=dev_ptr->info_ptr; + + DRM_DEBUG("Info get device_id:%#lx,revision:%#lx,offset:%#lx,size:%#lx, hw_status_offset:%lx\n", + info_ptr->device_id,info_ptr->revision, + info_ptr->video_memory_offset,info_ptr->video_memory_size, + info_ptr->hw_status_offset); + + info.device_id=info_ptr->device_id; + info.revision=info_ptr->revision; + info.video_memory_offset=info_ptr->video_memory_offset; + info.video_memory_size=info_ptr->video_memory_size; + info.hw_status_offset=info_ptr->hw_status_offset; + + if(copy_to_user((void __user *) arg,&info,sizeof(info))){ + return -EFAULT; + } + +return 0; +} + +/* initialise structure for link list and driver info in dev_private */ +int intel_postinit(intel_device_private_t **priv){ + + intel_drm_info_t *info_ptr; + intel_device_private_t *dev_ptr; + DRM_DEBUG("\n"); + /* allocate info to be stored */ + dev_ptr=ALLOC(sizeof(intel_device_private_t),DRM_MEM_DRIVER); + + if(!dev_ptr){ + return -ENOMEM; + } + + DRM_DEBUG("dev_ptr allocation succesful\n"); + + memset(dev_ptr,0,sizeof(intel_device_private_t)); + *priv=dev_ptr; + + info_ptr=ALLOC(sizeof(intel_drm_info_t),DRM_MEM_DRIVER); + + if(!info_ptr){ + return -ENOMEM; + } + + DRM_DEBUG("Info_ptr allocation succesful\n"); + memset(info_ptr,0,sizeof(intel_drm_info_t)); + dev_ptr->info_ptr=info_ptr; + + dev_ptr->pagelist=ALLOC(sizeof(*dev_ptr->pagelist),DRM_MEM_DRIVER); + + if(!dev_ptr->pagelist){ + return -ENOMEM; + } + + DRM_DEBUG("pagelist allocation succesful\n"); + memset(dev_ptr->pagelist,0,sizeof(*dev_ptr->pagelist)); + INIT_LIST_HEAD(&dev_ptr->pagelist->head); + /* Initialise global variable to zero when we start up */ + memory=0; + DRM_DEBUG("Initialised memory:%d\n",memory); + +return 0; + +} +/* check and free pages of client that is closing the fd */ +int intel_prerelease(drm_device_t *dev){ + unsigned long bytes; + int order; + int size; + + intel_device_private_t *dev_ptr=dev->dev_private; + drm_intel_listpages_t *page; + drm_intel_list_t *r_list=NULL; + struct list_head *pagelist, *pagelist_next; + + DRM_DEBUG("Client closing freeing pages alloc to it\n"); + + + /* Search for the page list has been added and free it */ + + LOCK_DRM(dev); + + /* The changes to this function are copied form 8.1 */ + /* I've no idea why, but sometimes during bootup the dev_private + * field can show up as NULL. Guarding against this for now... + */ + if (dev_ptr != NULL) { + + pagelist=&dev_ptr->pagelist->head; + list_for_each_safe(pagelist,pagelist_next,&dev_ptr->pagelist->head){ + r_list=list_entry(pagelist,drm_intel_list_t,head); + if(r_list->page->pid==current->group_leader->pid){ +#if 0 + printk("found pid:%d\n",current->pid); + printk("size:%d\n",r_list->page->size); + printk("phy_address:%#lx\n",r_list->page->phy_address); + printk("virt_add:%#lx\n",r_list->page->virt_address); + printk("offset:%#lx\n",r_list->page->offset); +#endif + bytes=r_list->page->size; + + /*number of pages that are needed*/ + + size=bytes>>PAGE_SHIFT; + if(bytes & ~(PAGE_SIZE*size)){ + ++size; + } + order=ORDER(size); + /* free the pages */ + +#if 0 + printk("freeing address:%#lx,size:%#lx\n" + ,(unsigned long)__va(r_list->page->phy_address) + ,(unsigned long)bytes); +#endif + + FREE_PAGES((unsigned long)__va(r_list->page->phy_address) + ,order,0); + + /* remove from list and free the resource */ + + page=r_list->page; + list_del(pagelist); + FREE(pagelist,sizeof(*pagelist),0); + FREE(page,sizeof(*page),0); + /* update the total memory that we use */ + memory-=bytes; + DRM_DEBUG("memory:%d bytes\n",memory); + } + } + } + + UNLOCK_DRM(dev); + + return 0; + +} + +int drm_plb_mmap(struct file *filp, struct vm_area_struct *vma) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,5) + drm_file_t *priv = filp->private_data; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) + drm_device_t *dev = priv->minor->dev; +#else + drm_device_t *dev = priv->head->dev; +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) + drm_local_map_t *map = NULL; +#else + drm_map_t *map = NULL; +#endif + drm_map_list_t *r_list; + unsigned long offset = 0; + struct list_head *list; + drm_vma_entry_t *vma_entry; + + DRM_DEBUG("drm_plb_mmap: start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", + vma->vm_start, vma->vm_end, VM_OFFSET(vma)); + + if (!priv->authenticated) { + DRM_DEBUG("Did not authenticate"); + return -EACCES; + } else { + DRM_DEBUG("Authenticate successful"); + } + + /* A sequential search of a linked list is + * fine here because: 1) there will only be + * about 5-10 entries in the list and, 2) a + * DRI client only has to do this mapping + * once, so it doesn't have to be optimized + * for performance, even if the list was a + * bit longer. */ + + /* FIXME: Temporary fix. */ + LIST_FOR_EACH(list, dev) { + + r_list = list_entry(list, drm_map_list_t, head); + map = r_list->map; + if (!map) + continue; + if (r_list->user_token == VM_OFFSET(vma)) + break; + } + + if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) + return -EPERM; + + /* Check for valid size. */ + if (map->size != vma->vm_end - vma->vm_start) { + return -EINVAL; + } + + if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) { + vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE); + pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW; + } + + switch (map->type) { + + case _DRM_AGP: + case _DRM_FRAME_BUFFER: + if (agp_use_pat()) { + pgprot_val(vma->vm_page_prot) &= ~(_PAGE_PWT | _PAGE_PCD); + pgprot_val(vma->vm_page_prot) |= _PAGE_PAT; + vma->vm_flags |= VM_IO; /* not in core dump */ + + offset = VM_OFFSET(vma) - agp_bridge->gart_bus_addr; + vma->vm_ops = &iegd_plb_vm_ops; + break; + } + + /* Fallthrough */ + case _DRM_REGISTERS: + if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) { + pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; + pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT; + } + vma->vm_flags |= VM_IO; /* not in core dump */ + offset = VM_OFFSET(vma) - agp_bridge->gart_bus_addr; + + vma->vm_ops = &iegd_plb_vm_ops; + break; + case _DRM_SHM: + case _DRM_CONSISTENT: + case _DRM_SCATTER_GATHER: + DRM_DEBUG("Fall through to original mmap\n"); + return drm_mmap(filp, vma); + break; + default: + return -EINVAL; /* This should never happen. */ + } + + + vma->vm_flags |= VM_RESERVED; /* Don't swap */ + + vma->vm_file = filp; /* Needed for drm_vm_open() */ + + vma_entry = ALLOC(sizeof(*vma_entry), DRM_MEM_VMAS); + if (vma_entry) { + /* + * FIXME: Temporary fix. Will figure out later + */ + INSERT_VMA(); + } + +#endif + return 0; +} + +int psb_init(intel_device_private_t *priv) +{ + DRM_INIT_WAITQUEUE(&priv->event_queue); + spin_lock_init(&priv->irqmask_lock); + priv->event_present = 0; + priv->out_vdc = 0; + priv->out_sgx = 0; + priv->out_sgx2 = 0; + priv->out_mtx = 0; + + return 0; +} + +int intel_drm_plb_interrupts( drm_device_t *dev, void *data ) +{ + intel_device_private_t *priv; + interrupt_info_t plb_info; + unsigned long irqflags; + int ret = 0; + int rv; + priv=(intel_device_private_t *)dev->dev_private; + + if(copy_from_user(&plb_info, (void __user *) data, sizeof(plb_info))) { + return -EFAULT; + } + + /* USW15 definition of in and out + * + * in/out[0] VDC + * in/out[1] sgx + * in/out[2] sgx2 + * in/out[3] msvdx + */ + + plb_info.out[0]=0; + plb_info.out[1]=0; + plb_info.out[2]=0; + plb_info.out[3]=0; + + switch (plb_info.req_type) { + case CLEAR_INT: + + plb_info.in[0] &= priv->vdc_irq_mask; + plb_info.in[1] &= priv->sgx_irq_mask; + plb_info.in[2] &= priv->sgx_irq_mask2; + plb_info.in[3] &= priv->msvdx_irq_mask; + + if (plb_info.in[0] || plb_info.in[1] || + plb_info.in[2] || plb_info.in[3]) { + + spin_lock_irqsave(&priv->irqmask_lock, irqflags); + priv->out_vdc &= ~plb_info.in[0]; + plb_info.out[0] = priv->out_vdc; + + priv->out_sgx &= ~plb_info.in[1]; + plb_info.out[1] = priv->out_sgx; + + priv->out_sgx2 &= ~plb_info.in[2]; + plb_info.out[2] = priv->out_sgx2; + + priv->out_mtx &= ~plb_info.in[3]; + plb_info.out[3] = priv->out_mtx; + spin_unlock_irqrestore(&priv->irqmask_lock, irqflags); + + plb_info.req_status = INT_CLEARED; + + } else { + plb_info.req_status = INT_NOOP; + } + + break; + + case READ_INT: + + + plb_info.out[0] = priv->out_vdc; + plb_info.out[1] = priv->out_sgx; + plb_info.out[2] = priv->out_sgx2; + plb_info.out[3] = priv->out_mtx; + plb_info.req_status = INT_READ; + + break; + + case WAIT_INT: + + plb_info.in[0] &= priv->vdc_irq_mask; + plb_info.in[1] &= priv->sgx_irq_mask; + plb_info.in[2] &= priv->sgx_irq_mask2; + plb_info.in[3] &= priv->msvdx_irq_mask; + + if (plb_info.in[0] || plb_info.in[1] || + plb_info.in[2] || plb_info.in[3]) { + + spin_lock_irqsave(&priv->irqmask_lock, irqflags); + + /* none of the interrupts have ocurred */ + if ((priv->out_vdc & plb_info.in[0]) || + (priv->out_sgx & plb_info.in[1]) || + (priv->out_sgx2 & plb_info.in[2]) || + (priv->out_mtx & plb_info.in[3])) { + + /* At least one of the interrupts has already occurred */ + plb_info.req_status = INT_STORED; + + } else { + + /* Wait for an interrupt to occur */ + priv->event_present = 0; + spin_unlock_irqrestore(&priv->irqmask_lock, irqflags); + + DRM_WAIT_ON(ret, priv->event_queue, 20 * DRM_HZ, + priv->event_present); + + if (ret) { + plb_info.req_status = INT_TIMEOUT; + break; + } + + spin_lock_irqsave(&priv->irqmask_lock, irqflags); + + plb_info.req_status = INT_HANDLED; + + } + + plb_info.out[0] = priv->out_vdc; + plb_info.out[1] = priv->out_sgx; + plb_info.out[2] = priv->out_sgx2; + plb_info.out[3] = priv->out_mtx; + + /* Clear the outstanding interrupts that have just been + * retrieved + */ + priv->out_vdc &= ~(plb_info.out[0] & plb_info.in[0]); + priv->out_sgx &= ~(plb_info.out[1] & plb_info.in[1]) ; + priv->out_sgx2 &= ~(plb_info.out[2] & plb_info.in[2]); + priv->out_mtx &= ~(plb_info.out[3] & plb_info.in[3]); + spin_unlock_irqrestore(&priv->irqmask_lock, irqflags); + + } else { + + /* Unsupported interrupt */ + plb_info.req_status = INT_NOOP; + + } + + break; + + case UNMASK_INT: + + if (!dev->irq_enabled) { + rv = drm_irq_install(dev); + if (rv != 0) { + DRM_ERROR("%s: could not install IRQs: rv = %d\n", __FUNCTION__, rv); + return rv; + } + } + + spin_lock_irqsave(&priv->irqmask_lock, irqflags); + PSB_WVDC32(0x00000000, IMR); + spin_unlock_irqrestore(&priv->irqmask_lock, irqflags); + + break; + + case MASK_INT: + + if (dev->irq_enabled) { + rv = drm_irq_uninstall(dev); + if (rv != 0) { + DRM_ERROR("%s: could not uninstall IRQs: rv = %d\n", __FUNCTION__, rv); + return rv; + } + } + + spin_lock_irqsave(&priv->irqmask_lock, irqflags); + PSB_WVDC32(0xFFFFFFFF, IMR); + spin_unlock_irqrestore(&priv->irqmask_lock, irqflags); + + break; + + default: + + plb_info.req_status = INT_INVALID; + + } + + + if (copy_to_user((void __user *) data, &plb_info, sizeof(plb_info))) { + return -EFAULT; + } + + return 0; +} diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_2611.c patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_2611.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_2611.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_2611.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,250 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_interface_2611.c + * $Revision: 1.6 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "iegd.h" +#include "drmP.h" +#include "drm.h" + +#include "iegd_drm.h" +#include "iegd_drv.h" + +#if KERNEL2611 +int intel_postinit_2611(struct drm_device *dev,unsigned long flags){ + + intel_device_private_t *priv; + priv=(intel_device_private_t *)dev->dev_private; + + intel_postinit(&priv); + dev->dev_private=priv; + + return 0; + +} + +void intel_prerelease_2611(drm_device_t *dev,DRMFILE filp){ + + intel_prerelease(dev); + +} + +int intel_getpages_2611( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ){ + + drm_file_t *priv=filp->private_data; + drm_device_t *dev=priv->head->dev; + return intel_getpages(dev,filp,arg); + +} + +int intel_freepages_2611( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ){ + + drm_file_t *priv=filp->private_data; + drm_device_t *dev=priv->head->dev; + return intel_freepages(dev,arg); +} + +int intel_drm_info_init_2611( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ){ + + drm_file_t *priv=filp->private_data; + drm_device_t *dev=priv->head->dev; + return intel_drm_info_init(dev,arg); + +} + +int intel_drm_info_get_2611( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ){ + + drm_file_t *priv=filp->private_data; + drm_device_t *dev=priv->head->dev; + return intel_drm_info_get(dev,arg); + +} + +/* Following 2 functions were taken from drm_memory.c + * For some reason they are not being exported to use + * by the other drm. + */ + +/** + * Allocate pages. + * + * \param order size order. + * \param area memory area. (Not used.) + * \return page address on success, or zero on failure. + * + * Allocate and reserve free pages. + */ +unsigned long intel_alloc_pages(int order, int area) +{ + unsigned long address; + unsigned long bytes = PAGE_SIZE << order; + unsigned long addr; + unsigned int sz; + + address = __get_free_pages(GFP_KERNEL, order); + if (!address) + return 0; + + /* Zero */ + memset((void *)address, 0, bytes); + + /* Reserve */ + for (addr = address, sz = bytes; + sz > 0; + addr += PAGE_SIZE, sz -= PAGE_SIZE) { + SetPageReserved(virt_to_page(addr)); + } + + return address; +} + +/** + * Free pages. + * + * \param address address of the pages to free. + * \param order size order. + * \param area memory area. (Not used.) + * + * Unreserve and free pages allocated by alloc_pages(). + */ +void intel_free_pages(unsigned long address, int order, int area) +{ + unsigned long bytes = PAGE_SIZE << order; + unsigned long addr; + unsigned int sz; + + if (!address) + return; + + /* Unreserve */ + for (addr = address, sz = bytes; + sz > 0; + addr += PAGE_SIZE, sz -= PAGE_SIZE) { + ClearPageReserved(virt_to_page(addr)); + } + + free_pages(address, order); +} + +drm_ioctl_desc_t intel_ioctls[]={ + [DRM_IOCTL_NR(DRM_INTEL_GETPAGES)] = { intel_getpages_2611, 0,0 }, + [DRM_IOCTL_NR(DRM_INTEL_FREEPAGES)] = { intel_freepages_2611, 0,0 }, + [DRM_IOCTL_NR(DRM_INTEL_INFO_INIT)] = { intel_drm_info_init_2611, 0,0 }, + [DRM_IOCTL_NR(DRM_INTEL_INFO_GET)] = { intel_drm_info_get_2611, 0,0 } +}; + +int intel_max_ioctl = DRM_ARRAY_SIZE(intel_ioctls); + + +static int version( drm_version_t *version ) +{ + int len; + + version->version_major = DRIVER_MAJOR; + version->version_minor = DRIVER_MINOR; + version->version_patchlevel = DRIVER_PATCHLEVEL; + DRM_COPY( version->name, DRIVER_NAME ); + DRM_COPY( version->date, DRIVER_DATE ); + DRM_COPY( version->desc, DRIVER_DESC ); + return 0; +} + +static struct pci_device_id pciidlist[] = { + INTEL_PCI_IDS +}; + +static struct drm_driver driver = { + .driver_features = DRIVER_USE_AGP|DRIVER_REQUIRE_AGP|DRIVER_USE_MTRR, + .prerelease = intel_prerelease_2611, + .postinit =intel_postinit_2611, + .reclaim_buffers=drm_core_reclaim_buffers, + .get_map_ofs=drm_core_get_map_ofs, + .get_reg_ofs=drm_core_get_reg_ofs, + .version = version, + .ioctls = intel_ioctls, + .fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + }, + .pci_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, + } +}; + +int __init intel_init(void) +{ + driver.num_ioctls = intel_max_ioctl; + return drm_init(&driver); +} + +void __exit intel_exit(void) +{ + drm_exit(&driver); +} + +struct file_operations intel_buffer_fops = { + .open = drm_open, + .flush = drm_flush, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = intel_mmap_buffers, + .fasync = drm_fasync, +}; +#endif diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_2611.h patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_2611.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_2611.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_2611.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,71 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_interface_2611.h + * $Revision: 1.6 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* Macros are defined here such that only kernel specific functions can be + * used. + */ +#if KERNEL2611 +#define REMAP_PAGE(a,b,c,d,e) io_remap_pfn_range(a,b, \ + c >>PAGE_SHIFT, \ + d,e) + +#define ORDER(a) drm_order(a) +#define ALLOC_PAGES(a,b) intel_alloc_pages(a,b) +#define ALLOC(a,b) drm_alloc(a,b) +#define FREE(a,b,c) drm_free(a,b,c) +#define FREE_PAGES(a,b,c) intel_free_pages(a,b,c) + +#define LOCK_DRM(d) down(&d->struct_sem) +#define UNLOCK_DRM(d) up(&d->struct_sem) +#endif + +/* endif for KERNEL2611 */ diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_2615.c patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_2615.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_2615.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_2615.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,394 @@ + +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_interface_2615.c + * $Revision: 1.11 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "iegd.h" +#include "drmP.h" +#include "drm.h" + +#include "iegd_drm.h" + +#include "iegd_drv.h" +#include "psb_intregs.h" +#include "intelpci.h" +#include + +int drm_irq_install(drm_device_t *dev); + +#if KERNEL2615 +int intel_firstopen_2615(struct drm_device *dev) +{ + + intel_device_private_t *priv; + priv=(intel_device_private_t *)dev->dev_private; + + intel_postinit(&priv); + dev->dev_private=priv; + + return 0; + +} + + +int intel_psb_firstopen_2615(struct drm_device *dev) +{ + + unsigned long resource_start; + intel_device_private_t *priv; + priv=(intel_device_private_t *)dev->dev_private; + + intel_postinit(&priv); + psb_init(priv); + dev->dev_private=priv; + + + /* + * Map MMIO addresses so that the DRM can control interrupt support + */ + + resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE); + + priv->vdc_reg = ioremap(resource_start + PSB_VDC_OFFSET, PSB_VDC_SIZE); + + if (!priv->vdc_reg) { + /* Normally we'd want to unload the driver on failure. But due + * to circular dependancies, we can only return failure. + */ + /* psb_driver_unload(dev); */ + return 1; + } + + priv->sgx_reg = ioremap(resource_start + PSB_SGX_OFFSET, PSB_SGX_SIZE); + if (!priv->sgx_reg) { + /* Normally we'd want to unload the driver on failure. But due + * to circular dependancies, we can only return failure. + */ + /* psb_driver_unload(dev); */ + return 1; + } + + priv->msvdx_reg = ioremap(resource_start + PSB_MSVDX_OFFSET, PSB_MSVDX_SIZE); + if (!priv->msvdx_reg) { + /* Normally we'd want to unload the driver on failure. But due + * to circular dependancies, we can only return failure. + */ + /* psb_driver_unload(dev); */ + return 1; + } + + return 0; + +} + +void intel_preclose_2615(drm_device_t *dev,DRMFILE filp) +{ + intel_prerelease(dev); +} + + +int intel_getpages_2615( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv=filp->private_data; + drm_device_t *dev=priv->head->dev; + return intel_getpages(dev,filp,arg); +} + + +int intel_freepages_2615( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + + drm_file_t *priv=filp->private_data; + drm_device_t *dev=priv->head->dev; + return intel_freepages(dev,arg); +} + + +int intel_drm_info_init_2615( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + + drm_file_t *priv=filp->private_data; + drm_device_t *dev=priv->head->dev; + return intel_drm_info_init(dev,arg); + +} + + +int intel_drm_info_get_2615( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + + drm_file_t *priv=filp->private_data; + drm_device_t *dev=priv->head->dev; + return intel_drm_info_get(dev,arg); + +} + + +/* Following 2 functions were taken from drm_memory.c + * For some reason they are not being exported to use + * by the other drm. + */ + +/** + * Allocate pages. + * + * \param order size order. + * \param area memory area. (Not used.) + * \return page address on success, or zero on failure. + * + * Allocate and reserve free pages. + */ +unsigned long intel_alloc_pages(int order, int area) +{ + unsigned long address; + unsigned long bytes = PAGE_SIZE << order; + unsigned long addr; + unsigned int sz; + + address = __get_free_pages(GFP_KERNEL, order); + if (!address) + return 0; + + /* Zero */ + memset((void *)address, 0, bytes); + + /* Reserve */ + for (addr = address, sz = bytes; + sz > 0; + addr += PAGE_SIZE, sz -= PAGE_SIZE) { + SetPageReserved(virt_to_page(addr)); + } + + return address; +} + + +/** + * Free pages. + * + * \param address address of the pages to free. + * \param order size order. + * \param area memory area. (Not used.) + * + * Unreserve and free pages allocated by alloc_pages(). + */ +void intel_free_pages(unsigned long address, int order, int area) +{ + unsigned long bytes = PAGE_SIZE << order; + unsigned long addr; + unsigned int sz; + + if (!address) { + return; + } + + /* Unreserve */ + for (addr = address, sz = bytes; + sz > 0; + addr += PAGE_SIZE, sz -= PAGE_SIZE) { + ClearPageReserved(virt_to_page(addr)); + } + + free_pages(address, order); +} + +static int psb_driver_load(struct drm_device *dev, unsigned long chipset) +{ + intel_device_private_t *priv; + + priv=(intel_device_private_t *)dev->dev_private; + + return 0; +} + +int intel_drm_plb_interrupts_2615 ( struct inode *inode, + struct file *filp, + unsigned int cmd, void *arg ) +{ + drm_file_t *priv=filp->private_data; + drm_device_t *dev=priv->head->dev; + + return intel_drm_plb_interrupts( dev, arg ); +} + +drm_ioctl_desc_t intel_ioctls[] = { + [DRM_IOCTL_NR(DRM_INTEL_GETPAGES)] = { intel_getpages_2615, 0}, + [DRM_IOCTL_NR(DRM_INTEL_FREEPAGES)] = { intel_freepages_2615, 0}, + [DRM_IOCTL_NR(DRM_INTEL_INFO_INIT)] = { intel_drm_info_init_2615, 0}, + [DRM_IOCTL_NR(DRM_INTEL_INFO_GET)] = { intel_drm_info_get_2615, 0}, + [DRM_IOCTL_NR(DRM_INTEL_INTERRUPT)] = {intel_drm_plb_interrupts_2615,0} +}; + +int intel_max_ioctl = DRM_ARRAY_SIZE(intel_ioctls); + + + +static struct pci_device_id pciidlist[] = { + INTEL_PCI_IDS +}; + +int device_is_agp_2615(drm_device_t * dev) +{ + return 1; +} + + +static struct drm_driver driver = { + .firstopen = intel_firstopen_2615, + .preclose = intel_preclose_2615, + .reclaim_buffers=drm_core_reclaim_buffers, + .get_map_ofs=drm_core_get_map_ofs, + .get_reg_ofs=drm_core_get_reg_ofs, + + .device_is_agp = device_is_agp_2615, + + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, + .patchlevel = DRIVER_PATCHLEVEL, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + + .driver_features = DRIVER_USE_AGP|DRIVER_REQUIRE_AGP|DRIVER_USE_MTRR, + .ioctls = intel_ioctls, + .fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + }, + .pci_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, + } +}; + +static struct drm_driver driver_plb = { + .load = psb_driver_load, + .firstopen = intel_psb_firstopen_2615, + .preclose = intel_preclose_2615, + .reclaim_buffers=drm_core_reclaim_buffers, + .get_map_ofs=drm_core_get_map_ofs, + .get_reg_ofs=drm_core_get_reg_ofs, + + .device_is_agp = device_is_agp_2615, + + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, + .patchlevel = DRIVER_PATCHLEVEL, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + + .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | + DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, + .ioctls = intel_ioctls, + .irq_preinstall = psb_irq_preinstall, + .irq_postinstall = psb_irq_postinstall, + .irq_uninstall = psb_irq_uninstall, + .irq_handler = psb_irq_handler, + + .fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_plb_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + }, + .pci_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, + } +}; + + +int intel_init(void) +{ + driver.num_ioctls = intel_max_ioctl; + driver_plb.num_ioctls = intel_max_ioctl; + + /* We are peeking into the global AGP structures that + * we have access to in order to determine what chipset we're + * on. This isn't necessarily a good thing to do. + */ + + if (gart_id->device_id == PCI_DEVICE_ID_PLB) { + printk(KERN_ERR "Initializing DRM for Intel US15 SCH\n"); + return drm_init(&driver_plb); + } else { + return drm_init(&driver); + } + +} + +void intel_exit(void) +{ + drm_exit(&driver); +} + +struct file_operations intel_buffer_fops = { + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = intel_mmap_buffers, + .poll = drm_poll, + .fasync = drm_fasync, +}; +#endif diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_2615.h patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_2615.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_2615.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_2615.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,72 @@ + +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_interface_2615.h + * $Revision: 1.6 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* Macros are defined here such that only kernel specific functions can be + * used. + */ +#if KERNEL2615 +#define REMAP_PAGE(a,b,c,d,e) io_remap_pfn_range(a,b, \ + c >>PAGE_SHIFT, \ + d,e) + +#define ORDER(a) drm_order(a) +#define ALLOC_PAGES(a,b) intel_alloc_pages(a,b) +#define ALLOC(a,b) drm_alloc(a,b) +#define FREE(a,b,c) drm_free(a,b,c) +#define FREE_PAGES(a,b,c) intel_free_pages(a,b,c) + +#define LOCK_DRM(d) mutex_lock(&d->struct_mutex) +#define UNLOCK_DRM(d) mutex_unlock(&d->struct_mutex) +#endif + +/* endif for KERNEL2615 */ diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_2624.c patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_2624.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_2624.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_2624.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,820 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_interface_2611.c + * $Revision: 1.8 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "iegd.h" +#include "drmP.h" +#include "drm.h" + +#include "iegd_drm.h" +#include "iegd_drv.h" +#include "psb_intregs.h" +#include "intelpci.h" + +int drm_irq_install(drm_device_t *dev); + +#if KERNEL2624 + +/* get intel_buffer_fops from the interface_###.c files */ +extern struct file_operations intel_buffer_fops; + +/* Global variable to keep track the amount of memory we are using */ +static int memory = 0; + +int intel_firstopen_2624(struct drm_device *dev) +{ + intel_device_private_t *priv; + priv=(intel_device_private_t *)dev->dev_private; + + intel_postinit(&priv); + dev->dev_private=priv; + + return 0; + +} + +int intel_plb_firstopen_2624(struct drm_device *dev) +{ + + unsigned long resource_start; + intel_device_private_t *priv; + priv=(intel_device_private_t *)dev->dev_private; + + intel_postinit(&priv); + psb_init(priv); + dev->dev_private=priv; + + /* + * Map MMIO addresses so that the DRM can control interrupt support + */ + + resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE); + priv->vdc_reg = ioremap(resource_start + PSB_VDC_OFFSET, PSB_VDC_SIZE); + if (!priv->vdc_reg) { + /* + * Normally we'd want to unload the driver on failure. But due + * to circular dependancies, we can only return failure. + */ + /* psb_driver_unload(dev); */ + return 1; + } + + priv->sgx_reg = ioremap(resource_start + PSB_SGX_OFFSET, PSB_SGX_SIZE); + if (!priv->sgx_reg) { + /* + * Normally we'd want to unload the driver on failure. But due + * to circular dependancies, we can only return failure. + */ + /* psb_driver_unload(dev); */ + return 1; + } + + priv->msvdx_reg = ioremap(resource_start + PSB_MSVDX_OFFSET, PSB_MSVDX_SIZE); + if (!priv->msvdx_reg) { + /* + * Normally we'd want to unload the driver on failure. But due + * to circular dependancies, we can only return failure. + */ + /* psb_driver_unload(dev); */ + return 1; + } + + return 0; + +} + +void intel_preclose_2624(drm_device_t *dev, struct drm_file *filp) +{ + intel_prerelease(dev); +} + +/* + * Implement the 2.6.24 kernel interface for the device specific IOCTL + * that gets pages of memory from the DRM and returns them to the caller. + */ +int intel_getpages_2624(struct drm_device *dev, + void *data, + struct drm_file *filepriv) +{ + drm_intel_getpages_t *getpages; + unsigned long bytes; + int order; + int size; + + unsigned long address; + unsigned long phy_address; + unsigned long offset; + + struct page *pg; + + unsigned long virtual; + struct file_operations *old_fops; + + intel_device_private_t *dev_ptr = dev->dev_private; + drm_intel_listpages_t *page; + drm_intel_list_t *list; + + DRM_DEBUG("\n"); + DRM_INFO("in intel_getpages_2624, calling intel_getpages\n"); + getpages = (drm_intel_getpages_t *)data; + + bytes = getpages->size; + + /* + * Check to see if this allocation would exceed 16MEG in total memory + * This is to prevent denial of service attack. 16Meg should be enough. + */ + if((memory + bytes) > MB(16) ){ + /* We exceeded 16MEG. Bail out */ + DRM_ERROR("Total memory allocated exceeded 16Meg!\n"); + DRM_INFO("Total memory allocated exceeded 16Meg!\n"); + return -EFAULT; + } + + /* number of pages that are needed */ + size = bytes>>PAGE_SHIFT; + if(bytes & ~(PAGE_SIZE*size)){ + ++size; + } + order = ORDER(size); + DRM_DEBUG("Allocating bytes:%#lx,size:%d,order:%d\n", + (unsigned long)bytes,size,order); + + /* + * Allocate the pages. + * returns kernel logical address. + * Is this the same as the kernel virtual address?? + */ + address = ALLOC_PAGES(order,0); + if(!address){ + DRM_ERROR("Can't get pages\n"); + DRM_INFO("Can't get pages\n"); + return -EFAULT; + } + phy_address = __pa(address); + + /* Find virtual address of the phys address */ + pg = virt_to_page((void *)address); + offset = pg->index; + + /* Find the number of bytes that is actually allocated */ + size = PAGE_SIZE<mm->mmap_sem); + + old_fops = (struct file_operations *) (filepriv->filp->f_op); + filepriv->filp->f_op = &intel_buffer_fops; + + virtual = do_mmap(filepriv->filp, 0, size, + PROT_READ|PROT_WRITE,MAP_SHARED, phy_address); + filepriv->filp->f_op = old_fops; + + up_write(¤t->mm->mmap_sem); + DRM_DEBUG("Mmaped virtual:%#lx,address:%#lx\n",virtual, + (unsigned long)__va(phy_address)); + + if(virtual > -1024UL){ + DRM_ERROR("mmap failed:%d\n",(int)virtual); + DRM_INFO("mmap failed:%d\n",(int)virtual); + return -EFAULT; + } + + getpages->phy_address = phy_address; + getpages->virt_address = virtual; + getpages->size = size; + getpages->offset = offset; + + DRM_DEBUG("Mmap success requested size:%d (%d)\n", + getpages->size,(int)bytes); + + /* alloc the page to be put into the linked list */ + page = ALLOC(sizeof(*page),DRM_MEM_DRIVER); + if(!page){ + DRM_DEBUG("Can't alloc list for page\n"); + DRM_INFO("Can't alloc list for page\n"); + return -ENOMEM; + } + + /*page->pid=current->pid;*/ + page->pid = current->group_leader->pid; + page->size = size; + page->phy_address = phy_address; + page->virt_address = virtual; + page->offset = offset; + + DRM_DEBUG("parent pid:%d,pid:%d,group_leader->pid:%d\n" + ,current->parent->pid,current->pid,current->group_leader->pid); + + /* Alloc the list to be added then add it to the linked list */ + list = ALLOC(sizeof(*list),DRM_MEM_DRIVER); + if(!list){ + DRM_DEBUG("Can't alloc list for page\n"); + DRM_INFO("Can't alloc list for page\n"); + FREE(page,sizeof(*page),0); + return -ENOMEM; + } + memset(list,0,sizeof(*list)); + list->page = page; + LOCK_DRM(dev); + list_add(&list->head,&dev_ptr->pagelist->head); + UNLOCK_DRM(dev); + + /* update the total amount of memory we use */ + memory += size; + DRM_DEBUG("memory has:%d bytes\n",memory); + + DRM_INFO("intel_getpages Exit\n"); + return 0; +} + + +/* + * Implement the 2.6.24 kernel interface for the device specific IOCTL + * that frees pages of memory that were previouslly allocated from the DRM. + */ +int intel_freepages_2624(struct drm_device *dev, + void *data, + struct drm_file *filepriv) +{ + drm_intel_freepages_t *freepages; + unsigned long bytes; + int order; + int size; + + intel_device_private_t *dev_ptr=dev->dev_private; + drm_intel_listpages_t *page; + drm_intel_list_t *r_list=NULL; + struct list_head *pagelist; + + DRM_DEBUG("Freeing pages\n"); + freepages = (drm_intel_freepages_t *)data; + + /* number of pages that are needed */ + bytes = freepages->size; + size = bytes>>PAGE_SHIFT; + if(bytes & ~(PAGE_SIZE*size)){ + ++size; + } + order = ORDER(size); + DRM_DEBUG("bytes:%d,size:%d,order:%d,phy_address:%#lx\n", (int)bytes, + (int)size,(int)order,freepages->phy_address); + + /* free the pages */ + DRM_DEBUG("freeing address:%#lx,size:%#lx\n", + (unsigned long)__va(freepages->phy_address),(unsigned long)bytes); + + DRM_DEBUG("parent pid:%d,pid:%d,group_leader->pid:%d\n" + ,current->parent->pid,current->pid,current->group_leader->pid); + + /* See if the requested address is in our page list */ + LOCK_DRM(dev); + pagelist = &dev_ptr->pagelist->head; + list_for_each(pagelist, &dev_ptr->pagelist->head){ + r_list=list_entry(pagelist, drm_intel_list_t, head); + if((r_list->page->pid==current->group_leader->pid) + && (r_list->page->phy_address==freepages->phy_address)){ + + DRM_DEBUG("found pid:%d\n",current->group_leader->pid); + DRM_DEBUG("size:%d\n",r_list->page->size); + DRM_DEBUG("phy_address:%#lx\n",r_list->page->phy_address); + DRM_DEBUG("virt_add:%#lx\n",r_list->page->virt_address); + DRM_DEBUG("offset:%#lx\n",r_list->page->offset); + + break; + } + + } + + if(pagelist == (&dev_ptr->pagelist->head)){ + DRM_DEBUG("Can't find pages alloc for pid:%d\n",current->pid); + UNLOCK_DRM(dev); + return -EINVAL; + } + + /* munmap the region 1st */ + down_write(¤t->mm->mmap_sem); + DRM_DEBUG("Unmapping virt_address:%#lx\n",freepages->virt_address); + do_munmap(current->mm,freepages->virt_address,bytes); + up_write(¤t->mm->mmap_sem); + + /* Free the pages! */ + FREE_PAGES((unsigned long)__va(freepages->phy_address), order, 0); + + /* Free the page list */ + page = r_list->page; + list_del(pagelist); + size = r_list->page->size; + FREE(pagelist,sizeof(*pagelist),0); + FREE(page,sizeof(*page),0); + UNLOCK_DRM(dev); + + /* update the total memory that we use */ + memory -= size; + DRM_DEBUG("memory has:%d bytes\n", memory); + return 0; +} + + +/* + * Implement the 2.6.24 kernel interface for the device specific IOCTL + * that stores client specific information. + */ +int intel_drm_info_init_2624(struct drm_device *dev, + void *data, + struct drm_file *filepriv) +{ + intel_drm_info_t *info; + intel_drm_info_t *info_ptr; + intel_device_private_t *dev_ptr; + + if (dev == NULL) { + DRM_INFO("ERROR ERROR, drm device is NULL\n"); + return -EFAULT; + } + DRM_DEBUG("info init succesful dev_private:%#lx\n", + (unsigned long)dev->dev_private); + dev_ptr = dev->dev_private; + + /* See if dev_private is already allocated */ + if(!dev->dev_private){ + DRM_ERROR("dev_private not allocated!\n"); + return 0; + } + info_ptr = dev_ptr->info_ptr; + + /* See if info is already allocated */ + if(info_ptr->device_id){ + DRM_DEBUG("Info already allocated: device id = 0x%lx\n", + info_ptr->device_id); + DRM_ERROR("Info already allocated!\n"); + return 0; + } + + info = (intel_drm_info_t *)data; + + info_ptr->device_id = info->device_id; + info_ptr->revision = info->revision; + info_ptr->video_memory_offset = info->video_memory_offset; + info_ptr->video_memory_size = info->video_memory_size; + info_ptr->hw_status_offset = info->hw_status_offset; + DRM_DEBUG("Saving dev_id:%#lx rev:%#lx offset:%#lx size:%#lx, " + "hwst_offset:%lx\n", + info_ptr->device_id, info_ptr->revision, + info_ptr->video_memory_offset, info_ptr->video_memory_size, + info_ptr->hw_status_offset); + + return 0; +} + + +/* + * Implement the 2.6.24 kernel interface for the device specific IOCTL + * that retrieves client specific information. + */ +int intel_drm_info_get_2624(struct drm_device *dev, + void *data, + struct drm_file *filepriv) +{ + intel_drm_info_t *info; + intel_device_private_t *dev_ptr = dev->dev_private; + intel_drm_info_t *info_ptr = dev_ptr->info_ptr; + + DRM_DEBUG("Info get dev_id:%#lx rev:%#lx offset:%#lx size:%#lx " + "hwst_offset:%lx\n", + info_ptr->device_id,info_ptr->revision, + info_ptr->video_memory_offset,info_ptr->video_memory_size, + info_ptr->hw_status_offset); + + info = (intel_drm_info_t *)data; + + info->device_id = info_ptr->device_id; + info->revision = info_ptr->revision; + info->video_memory_offset = info_ptr->video_memory_offset; + info->video_memory_size = info_ptr->video_memory_size; + info->hw_status_offset = info_ptr->hw_status_offset; + + return 0; +} + +/* + * The following 2 functions were taken from drm_memory.c + * For some reason they are not being exported to use by the other drm. + */ + +/** + * Allocate pages. + * + * \param order size order. + * \param area memory area. (Not used.) + * \return page address on success, or zero on failure. + * + * Allocate and reserve free pages. + */ +unsigned long intel_alloc_pages(int order, int area) +{ + unsigned long address; + unsigned long bytes = PAGE_SIZE << order; + unsigned long addr; + unsigned int sz; + + address = __get_free_pages(GFP_KERNEL, order); + if (!address) + return 0; + + /* Zero */ + memset((void *)address, 0, bytes); + + /* Reserve */ + for (addr = address, sz = bytes; + sz > 0; + addr += PAGE_SIZE, sz -= PAGE_SIZE) { + SetPageReserved(virt_to_page(addr)); + } + + return address; +} + +/** + * Free pages. + * + * \param address address of the pages to free. + * \param order size order. + * \param area memory area. (Not used.) + * + * Unreserve and free pages allocated by alloc_pages(). + */ +void intel_free_pages(unsigned long address, int order, int area) +{ + unsigned long bytes = PAGE_SIZE << order; + unsigned long addr; + unsigned int sz; + + if (!address) { + return; + } + + /* Unreserve */ + for (addr = address, sz = bytes; sz > 0; + addr += PAGE_SIZE, sz -= PAGE_SIZE) { + ClearPageReserved(virt_to_page(addr)); + } + + free_pages(address, order); +} + +static int psb_driver_load(struct drm_device *dev, unsigned long chipset) +{ + intel_device_private_t *priv; + + priv=(intel_device_private_t *)dev->dev_private; + + return 0; +} + +int intel_drm_plb_interrupts_2624 (struct drm_device *dev, + void *data, + struct drm_file *filepriv) +{ + intel_device_private_t *priv = dev->dev_private; + interrupt_info_t *plb_info; + unsigned long irqflags; + int ret = 0; + int rv; + + plb_info = (interrupt_info_t *)data; + + /* USW15 definition of in and out + * + * in/out[0] VDC + * in/out[1] sgx + * in/out[2] sgx2 + * in/out[3] msvdx + */ + + plb_info->out[0]=0; + plb_info->out[1]=0; + plb_info->out[2]=0; + plb_info->out[3]=0; + + switch (plb_info->req_type) { + case CLEAR_INT: + plb_info->in[0] &= priv->vdc_irq_mask; + plb_info->in[1] &= priv->sgx_irq_mask; + plb_info->in[2] &= priv->sgx_irq_mask2; + plb_info->in[3] &= priv->msvdx_irq_mask; + + if (plb_info->in[0] || plb_info->in[1] || + plb_info->in[2] || plb_info->in[3]) { + + spin_lock_irqsave(&priv->irqmask_lock, irqflags); + priv->out_vdc &= ~plb_info->in[0]; + plb_info->out[0] = priv->out_vdc; + + priv->out_sgx &= ~plb_info->in[1]; + plb_info->out[1] = priv->out_sgx; + + priv->out_sgx2 &= ~plb_info->in[2]; + plb_info->out[2] = priv->out_sgx2; + + priv->out_mtx &= ~plb_info->in[3]; + plb_info->out[3] = priv->out_mtx; + spin_unlock_irqrestore(&priv->irqmask_lock, irqflags); + + plb_info->req_status = INT_CLEARED; + + } else { + plb_info->req_status = INT_NOOP; + } + + break; + + case READ_INT: + plb_info->out[0] = priv->out_vdc; + plb_info->out[1] = priv->out_sgx; + plb_info->out[2] = priv->out_sgx2; + plb_info->out[3] = priv->out_mtx; + plb_info->req_status = INT_READ; + + break; + + case WAIT_INT: + plb_info->in[0] &= priv->vdc_irq_mask; + plb_info->in[1] &= priv->sgx_irq_mask; + plb_info->in[2] &= priv->sgx_irq_mask2; + plb_info->in[3] &= priv->msvdx_irq_mask; + + if (plb_info->in[0] || plb_info->in[1] || + plb_info->in[2] || plb_info->in[3]) { + + spin_lock_irqsave(&priv->irqmask_lock, irqflags); + + /* none of the interrupts have ocurred */ + if ((priv->out_vdc & plb_info->in[0]) || + (priv->out_sgx & plb_info->in[1]) || + (priv->out_sgx2 & plb_info->in[2]) || + (priv->out_mtx & plb_info->in[3])) { + + /* At least one of the interrupts has already occurred */ + plb_info->req_status = INT_STORED; + + } else { + + /* Wait for an interrupt to occur */ + priv->event_present = 0; + spin_unlock_irqrestore(&priv->irqmask_lock, irqflags); + + DRM_WAIT_ON(ret, priv->event_queue, 20 * DRM_HZ, + priv->event_present); + + if (ret) { + plb_info->req_status = INT_TIMEOUT; + break; + } + + spin_lock_irqsave(&priv->irqmask_lock, irqflags); + + plb_info->req_status = INT_HANDLED; + + } + plb_info->out[0] = priv->out_vdc; + plb_info->out[1] = priv->out_sgx; + plb_info->out[2] = priv->out_sgx2; + plb_info->out[3] = priv->out_mtx; + + /* Clear the outstanding interrupts that have just been + * retrieved + */ + priv->out_vdc &= ~(plb_info->out[0] & plb_info->in[0]); + priv->out_sgx &= ~(plb_info->out[1] & plb_info->in[1]) ; + priv->out_sgx2 &= ~(plb_info->out[2] & plb_info->in[2]); + priv->out_mtx &= ~(plb_info->out[3] & plb_info->in[3]); + spin_unlock_irqrestore(&priv->irqmask_lock, irqflags); + + } else { + + /* Unsupported interrupt */ + plb_info->req_status = INT_NOOP; + + } + + break; + + case UNMASK_INT: + + if (!dev->irq_enabled) { + rv = drm_irq_install(dev); + if (rv != 0) { + DRM_ERROR("%s: could not install IRQs: rv = %d\n", __FUNCTION__, rv); + return rv; + } + } + + spin_lock_irqsave(&priv->irqmask_lock, irqflags); + PSB_WVDC32(0x00000000, IMR); + spin_unlock_irqrestore(&priv->irqmask_lock, irqflags); + + break; + + case MASK_INT: + + if (dev->irq_enabled) { + rv = drm_irq_uninstall(dev); + if (rv != 0) { + DRM_ERROR("%s: could not uninstall IRQs: rv = %d\n", __FUNCTION__, rv); + return rv; + } + } + + spin_lock_irqsave(&priv->irqmask_lock, irqflags); + PSB_WVDC32(0xFFFFFFFF, IMR); + spin_unlock_irqrestore(&priv->irqmask_lock, irqflags); + + break; + + default: + + plb_info->req_status = INT_INVALID; + } + + return 0; +} + + +drm_ioctl_desc_t intel_ioctls[] = { + DRM_IOCTL_DEF(DRM_INTEL_GETPAGES, intel_getpages_2624, 0), + DRM_IOCTL_DEF(DRM_INTEL_FREEPAGES, intel_freepages_2624, 0), + DRM_IOCTL_DEF(DRM_INTEL_INFO_INIT, intel_drm_info_init_2624, 0), + DRM_IOCTL_DEF(DRM_INTEL_INFO_GET, intel_drm_info_get_2624, 0), + DRM_IOCTL_DEF(DRM_INTEL_INTERRUPT, intel_drm_plb_interrupts_2624, 0) +}; + +int intel_max_ioctl = DRM_ARRAY_SIZE(intel_ioctls); + + + +static struct pci_device_id pciidlist[] = { + INTEL_PCI_IDS +}; + +int device_is_agp_2624(drm_device_t * dev) +{ + return 1; +} + +static struct drm_driver driver = { + .firstopen = intel_firstopen_2624, + .preclose = intel_preclose_2624, + .reclaim_buffers=drm_core_reclaim_buffers, + .get_map_ofs=drm_core_get_map_ofs, + .get_reg_ofs=drm_core_get_reg_ofs, + + .device_is_agp = device_is_agp_2624, + + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, + .patchlevel = DRIVER_PATCHLEVEL, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + + .driver_features = DRIVER_USE_AGP|DRIVER_REQUIRE_AGP|DRIVER_USE_MTRR, + .ioctls = intel_ioctls, + .fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + }, + .pci_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, + } +}; + +static struct drm_driver driver_plb = { + .load = psb_driver_load, + .firstopen = intel_plb_firstopen_2624, + .preclose = intel_preclose_2624, + .reclaim_buffers=drm_core_reclaim_buffers, + .get_map_ofs=drm_core_get_map_ofs, + .get_reg_ofs=drm_core_get_reg_ofs, + + .device_is_agp = device_is_agp_2624, + + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, + .patchlevel = DRIVER_PATCHLEVEL, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + + .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | + DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_USE_MTRR, + .ioctls = intel_ioctls, + .irq_preinstall = psb_irq_preinstall, + .irq_postinstall = psb_irq_postinstall, + .irq_uninstall = psb_irq_uninstall, + .irq_handler = psb_irq_handler, + + .fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_plb_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + }, + .pci_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, + } +}; + +int intel_init(void) +{ + driver.num_ioctls = intel_max_ioctl; + driver_plb.num_ioctls = intel_max_ioctl; + + /* We are peeking into the global AGP structures that + * we have access to in order to determine what chipset we're + * on. This isn't necessarily a good thing to do. + */ + + if (gart_id->device_id == PCI_DEVICE_ID_PLB) { + printk(KERN_ERR "Initializing DRM for Intel US15 SCH\n"); + return drm_init(&driver_plb); + } else { + return drm_init(&driver); + } + +} + +void intel_exit(void) +{ + drm_exit(&driver); +} + +struct file_operations intel_buffer_fops = { + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = intel_mmap_buffers, + .poll = drm_poll, + .fasync = drm_fasync, +}; +#endif diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_2624.h patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_2624.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_2624.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_2624.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,78 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_interface_2611.h + * $Revision: 1.5 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* Macros are defined here such that only kernel specific functions can be + * used. + */ +#if KERNEL2624 +#define REMAP_PAGE(a,b,c,d,e) io_remap_pfn_range(a,b, \ + c >>PAGE_SHIFT, \ + d,e) + +#define ORDER(a) drm_order(a) +#define ALLOC_PAGES(a,b) intel_alloc_pages(a,b) + +//kernel version 31 removed some wrapper functions +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) +#define ALLOC(a, b) kmalloc(a, GFP_KERNEL) +#define FREE(a,b,c) kfree(a) +#else +#define ALLOC(a,b) drm_alloc(a,b) +#define FREE(a,b,c) drm_free(a,b,c) +#endif + +#define FREE_PAGES(a,b,c) intel_free_pages(a,b,c) +#define LOCK_DRM(d) mutex_lock(&d->struct_mutex) +#define UNLOCK_DRM(d) mutex_unlock(&d->struct_mutex) +#endif + +/* endif for KERNEL2624 */ diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_265.c patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_265.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_265.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_265.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,147 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_interface_265.c + * $Revision: 1.6 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "iegd.h" +#include "drmP.h" +#include "drm.h" + +#include "iegd_drm.h" +#include "iegd_drv.h" + +#if KERNEL265 +#include "drm_agpsupport.h" +#include "drm_auth.h" +#include "drm_bufs.h" +#include "drm_context.h" +#include "drm_dma.h" +#include "drm_drawable.h" +#include "drm_drv.h" + +#include "drm_fops.h" +#include "drm_init.h" +#include "drm_ioctl.h" +#include "drm_lock.h" +#include "drm_memory.h" +#include "drm_proc.h" +#include "drm_vm.h" +#include "drm_stub.h" + +int intel_postinit_265(drm_device_t *dev){ + + intel_device_private_t *priv; + priv=(intel_device_private_t *)dev->dev_private; + + intel_postinit(&priv); + dev->dev_private=priv; + + return 0; + +} + +int intel_prerelease_265(drm_device_t *dev){ + + intel_prerelease(dev); + + return 0; + +} + +int intel_getpages_265( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ){ + + drm_file_t *priv=filp->private_data; + drm_device_t *dev=priv->dev; + return intel_getpages(dev,filp,arg); + + +} + +int intel_freepages_265( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ){ + + drm_file_t *priv=filp->private_data; + drm_device_t *dev=priv->dev; + return intel_freepages(dev,arg); + +} + +int intel_drm_info_init_265( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ){ + + drm_file_t *priv=filp->private_data; + drm_device_t *dev=priv->dev; + return intel_drm_info_init(dev,arg); + +} + +int intel_drm_info_get_265( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ){ + + drm_file_t *priv=filp->private_data; + drm_device_t *dev=priv->dev; + return intel_drm_info_get(dev,arg); + +} + +struct file_operations intel_buffer_fops = { + .open = DRM(open), + .flush = DRM(flush), + .release = DRM(release), + .ioctl = DRM(ioctl), + .mmap = intel_mmap_buffers, + .fasync = DRM(fasync), +}; + +#endif +/*end of 2.6.5 definition */ + + diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_265.h patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_265.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/iegd_interface_265.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/iegd_interface_265.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,129 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_interface_265.h + * $Revision: 1.6 $ + *---------------------------------------------------------------------------- + * Gart and DRM driver for Intel Embedded Graphics Driver + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* For some arcane reasons this must be defined for 2.6.5 kernel in + * intel.h if not the drm won't compile properly. + */ +#if KERNEL265 + + +/* KERNEL265 defines these functions in the drm directory + * that got expanded when you #define DRM(x) intel_##x. This is very ugly and + * confusing. Luckily 2.6.11 don't have this. Can't do much here but follow + * the rules for it. + */ +#define DRM(x) intel_##x + +/* Changing the permission bits to 0,0 for testing. auth,root permission */ +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_INTEL_GETPAGES)] = { intel_getpages_265, 0, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_INTEL_FREEPAGES)] = { intel_freepages_265, 0, 0 },\ + [DRM_IOCTL_NR(DRM_IOCTL_INTEL_INFO_INIT)] = { intel_drm_info_init_265, 0, 0 },\ + [DRM_IOCTL_NR(DRM_IOCTL_INTEL_INFO_GET)] = { intel_drm_info_get_265, 0, 0 } + +/* Driver customization: + */ +#define __HAVE_RELEASE 1 +#define DRIVER_PRERELEASE() do { \ + intel_prerelease_265(dev); \ +} while (0) + +#define DRIVER_RELEASE() do { \ +} while (0) + +#define DRIVER_PRETAKEDOWN() do { \ +} while (0) + +#define DRIVER_POSTSETUP() do { \ +} while (0) + +#define DRIVER_POSTCLEANUP() do { \ +} while (0) + +#define DRIVER_POSTINIT() do { \ + intel_postinit_265(dev); \ +} while (0) + +/* + * Explaination: For unknown reasons the DRM infrastructure has a lot + * of really horrid programming techniques to generate custom init + * code using header files (containing c code) and macros. Apparently + * this is to save a few nano seconds during init. + * + * This logic here is that if you define this magic macro you will use + * this code to count the number of devices you are supporting. We + * need to support 2 devices and we don't know the device IDs at startup + * and there is usually not 2 PCI devices anyway. So we just return 2 + * and worry about it later. + * + * Note: DRM has issues with DIH so for now we'll live with one drm + *#define DRIVER_COUNT_CARDS() 2 + */ + +/* KERNEL265 defines these functions in the drm directory + * that got expanded when you #define DRM(x) intel_##x. This is very ugly and + * confusing. Luckily 2.6.11 don't have this + */ +#define REMAP_PAGE(a,b,c,d,e) remap_page_range( \ + DRM_RPR_ARG(a) b , \ + c,d,e) +#define ORDER(a) DRM(order)(a) +#define ALLOC_PAGES(a,b) DRM(alloc_pages)(a,b) +#define ALLOC(a,b) DRM(alloc)(a,b) +#define FREE(a,b,c) DRM(free)(a,b,c) +#define FREE_PAGES(a,b,c) DRM(free_pages)(a,b,c) + +#define LOCK_DRM(d) down(&d->struct_sem) +#define UNLOCK_DRM(d) up(&d->struct_sem) + +#endif +/* endif for KERNEL265 */ diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/myclient.c patch_script_temp/drivers/gpu/drm/iegd/drm/myclient.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/myclient.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/myclient.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,210 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: myclient.c + * $Revision: 1.5 $ + *---------------------------------------------------------------------------- + * DRM test program + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +/* Copyright 2003 - 2005 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/*client to test the ioctl + * make sure you change the permission bits in intel.h to 0,0 + * before you start using this + */ + +#include "iegd.h" + +#include +#include +#include +#include +#include + +#define DRM_IOCTL_BASE 'd' +#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) +#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) +#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) +#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) + +#include "intel_drm_client.h" + +#define DRM_IOCTL_INTEL_GETPAGES DRM_IOWR(DRM_BASE_COMMAND + \ + DRM_INTEL_GETPAGES, drm_intel_getpages_t) +#define DRM_IOCTL_INTEL_FREEPAGES DRM_IOWR(DRM_BASE_COMMAND + \ + DRM_INTEL_FREEPAGES, drm_intel_freepages_t) +#define DRM_IOCTL_INTEL_INFO_INIT DRM_IOW( DRM_BASE_COMMAND + \ + DRM_INTEL_INFO_INIT, intel_drm_info_t) +#define DRM_IOCTL_INTEL_INFO_GET DRM_IOR( DRM_BASE_COMMAND + \ + DRM_INTEL_INFO_GET, intel_drm_info_t) + + +#define PAGE_SIZE 4096 +int main() +{ +int file_desc, ret_value; +printf("ytay starting client\n"); +/* Open the drm */ +file_desc=open("/dev/dri/card0",O_RDWR); + +if(file_desc<0){ +/* probably Suse distro since the dev tree is different. + * try /dev/card0 + */ +file_desc=open("/dev/card0",O_RDWR); + +} + +if(file_desc<0){ + +printf("ytay can't open device file:%s\n",DRIVER_DESC); + exit(-1); +} + +printf("ytay open device file:%d\n",file_desc); +drm_intel_getpages_t getpages; +/* set the number of bytes we want the drm to allocate */ +getpages.size=(PAGE_SIZE- 1000); + +ret_value=ioctl(file_desc,DRM_IOCTL_INTEL_GETPAGES,&getpages); +if(ret_value<0){ +printf("ytay ioctl failed!\n"); + exit(-1); +} +printf("ytay ioctl success\n"); +printf("ytay size%d,phy_address:%#x,virt_address:%#x,offset:%#x\n",getpages.size,getpages.phy_address,getpages.virt_address,getpages.offset); + +/* test for memory access */ + +int i; +unsigned long *virt_ptr; + +virt_ptr=(unsigned long *)getpages.virt_address; + +/* input 0..10 into subsequent memory */ + +for(i=0;i<=11;i++){ +*virt_ptr=i; +virt_ptr++; + +} + +/*read from subsequent memory */ + +virt_ptr=(unsigned long *)getpages.virt_address; +for(i=0;i<=15;i++){ +printf("virt_ptr@%#x,value:%d\n",virt_ptr,*virt_ptr); +virt_ptr++; +} +/* set the number of bytes we want the drm to allocate */ +getpages.size=(PAGE_SIZE- 1000); + +ret_value=ioctl(file_desc,DRM_IOCTL_INTEL_GETPAGES,&getpages); +if(ret_value<0){ +printf("ytay ioctl failed!\n"); + exit(-1); +} +printf("ytay ioctl success\n"); +printf("ytay size%d,phy_address:%#x,virt_address:%#x,offset:%#x\n",getpages.size,getpages.phy_address,getpages.virt_address,getpages.offset); + + +/* freeing memory */ + +drm_intel_freepages_t freepages; +freepages.size=getpages.size; +freepages.phy_address=getpages.phy_address; +freepages.virt_address=getpages.virt_address; +printf("ytay freeing phy_address:%#x,size:%#x\n",freepages.phy_address,freepages.size); +/* +ioctl(file_desc,DRM_IOCTL_INTEL_FREEPAGES,&freepages); +*/ +/* init the drm info structure in the drm and test its value */ + + intel_drm_info_t info; + intel_drm_info_t test_info; + info.device_id=0x456; + info.revision=333; + info.video_memory_offset=0x10245; + info.video_memory_size=987; + info.hw_status_offset=0x444; + + printf("Testing init info device_id:%#x,revision:%d,offset:%#x,size:%d,hw_status_offset:%lx\n", + info.device_id,info.revision,info.video_memory_offset,info.video_memory_size,info.hw_status_offset); + + ioctl(file_desc,DRM_IOCTL_INTEL_INFO_INIT,&info); + +/* init the drm info structure in the drm and test its value */ + + info.device_id=0x123; + info.revision=456; + info.video_memory_offset=0x789; + info.video_memory_size=111; + info.hw_status_offset=0x555; + + printf("Testing init 2nd info device_id:%#x,revision:%d,offset:%#x,size:%d,hw_status_offset:%lx\n", + info.device_id,info.revision,info.video_memory_offset,info.video_memory_size,info.hw_status_offset); + + ioctl(file_desc,DRM_IOCTL_INTEL_INFO_INIT,&info); + + printf("Testing init 2nd info device_id:%#x,revision:%d,offset:%#x,size:%d,hw_status_offset:%lx\n", + info.device_id,info.revision,info.video_memory_offset,info.video_memory_size,info.hw_status_offset); + + ioctl(file_desc,DRM_IOCTL_INTEL_INFO_INIT,&info); + + + + ioctl(file_desc,DRM_IOCTL_INTEL_INFO_GET,&test_info); + + printf("Got init info device_id:%#x,revision:%d,offset:%#x,size:%d,hw_status_offset:%lx\n", + test_info.device_id,test_info.revision,test_info.video_memory_offset,test_info.video_memory_size,test_info.hw_status_offset); + + +close(file_desc); +/* +sleep(100000000000); +*/ +return 0; + +} diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/psb_intregs.h patch_script_temp/drivers/gpu/drm/iegd/drm/psb_intregs.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/psb_intregs.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/psb_intregs.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,114 @@ +/* -*- pse-c -*- + *----------------------------------------------------------------------------- + * Filename: psb_intregs.h + *----------------------------------------------------------------------------- + * INTEL CONFIDENTIAL + * Copyright (2002-2008) Intel Corporation All Rights Reserved. + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. Title to the Material remains with Intel Corporation or its + * suppliers and licensors. The Material contains trade secrets and proprietary + * and confidential information of Intel or its suppliers and licensors. The + * Material is protected by worldwide copyright and trade secret laws and + * treaty provisions. No part of the Material may be used, copied, reproduced, + * modified, published, uploaded, posted, transmitted, distributed, or + * disclosed in any way without Intel's prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or + * delivery of the Materials, either expressly, by implication, inducement, + * estoppel or otherwise. Any license under such intellectual property rights + * must be express and approved by Intel in writing. + * + * + *----------------------------------------------------------------------------- + * Description: + * This file contains the interrupt related register definition and + * macros for the PLB platform. + *----------------------------------------------------------------------------- + */ + +#ifndef _REGS_H_ +#define _REGS_H_ + +/*----------------------------------------------------------------------------- + * SGX, VDC, and MSVDX interrupt registers + ----------------------------------------------------------------------------*/ +//#define SGX_BASE 0x40000 + +#define PSB_MMIO_RESOURCE 0 + +#define PSB_VDC_OFFSET 0x00000000 +#define PSB_VDC_SIZE 0x000080000 +#define PSB_SGX_OFFSET 0x00040000 +#define PSB_SGX_SIZE 0x8000 +#define PSB_MSVDX_OFFSET 0x00050000 +#define PSB_MSVDX_SIZE 0x1000 + +/* bits in PSB_CR_EVENT_STATUS */ +#define PSB_DPM_3D_MEM_FREE (1<<0) +#define PSB_OUT_OF_MEM_MT (1<<1) +#define PSB_OUT_OF_MEM_GBL (1<<2) +#define PSB_REACHED_MEM_THRESH (1<<3) +#define PSB_TA_TERMINATE (1<<12) +#define PSB_TA_FINISHED (1<<13) +#define PSB_PIXELBE_END_RENDER (1<<18) +#define PSB_DPM_TA_MEM_FREE (1<<24) +#define PSB_DPM_OUT_OF_MEM_ZLS (1<<25) +#define PSB_TWOD_COMPLETE (1<<27) +#define PSB_TA_DPM_FAULT (1<<28) + +#define PSB_BIF_REQ_FAULT (1<<4) +#define PSB_TRIG_DL (1<<5) +#define PSB_TRIG_3D (1<<6) +#define PSB_TRIG_TA (1<<7) + +#define PSB_CR_EVENT_HOST_ENABLE2 0x0110 +#define PSB_CR_EVENT_HOST_CLEAR2 0x0114 +#define PSB_CR_EVENT_STATUS2 0x0118 + +#define PSB_CR_EVENT_HOST_ENABLE 0x0130 +#define PSB_CR_EVENT_HOST_CLEAR 0x0134 +#define PSB_CR_EVENT_STATUS 0x012C + +#define PSB_MTX_EVENT_HOST_ENABLE 0x0610 +#define PSB_MTX_EVENT_CLEAR 0x060C +#define PSB_MTX_EVENT_STATUS 0x0608 + +/*----------------------------------------------------------------------------- + * Memory mapped I/O Registers Definitions + *---------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------- + * Instruction and Interrupt Control Registers (01000h - 02FFFh) + *---------------------------------------------------------------------------*/ +#define HWSTAM 0x02098 /* Hardware Status Mask */ +#define IER 0x020A0 /* Interrupt Enable */ +#define IIR 0x020A4 /* Interrupt Identity */ +#define IMR 0x020A8 /* Interrupt Mask */ +#define ISR 0x020AC /* Interrupt Status */ + +#define PIPEA_STAT 0x70024 /* Pipe A Display Status */ +#define PIPEB_STAT 0x71024 /* Pipe B Display Status */ + +#define VBLANK_CLEAR (1<<1) +#define VSYNC_PIPEB_FLAG (1<<5) +#define VSYNC_PIPEA_FLAG (1<<7) +#define VBLANK_INTERRUPT_ENABLE (1<<17) +#define IRQ_SGX_FLAG (1<<18) +#define IRQ_MSVDX_FLAG (1<<19) + +#define PSB_WVDC32(_val, _offs) \ + iowrite32(_val, priv->vdc_reg + (_offs)) +#define PSB_RVDC32(_offs) \ + ioread32(priv->vdc_reg + (_offs)) +#define PSB_WSGX32(_val, _offs) \ + iowrite32(_val, priv->sgx_reg + (_offs)) +#define PSB_RSGX32(_offs) \ + ioread32(priv->sgx_reg + (_offs)) +#define PSB_WMSVDX32(_val, _offs) \ + iowrite32(_val, priv->msvdx_reg + (_offs)) +#define PSB_RMSVDX32(_offs) \ + ioread32(priv->msvdx_reg + (_offs)) + +#endif /* _REGS_H_ */ diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/psb_irq.c patch_script_temp/drivers/gpu/drm/iegd/drm/psb_irq.c --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/drm/psb_irq.c 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/drm/psb_irq.c 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,185 @@ +/* -*- pse-c -*- + *----------------------------------------------------------------------------- + * Filename: psb_intregs.h + *----------------------------------------------------------------------------- + * INTEL CONFIDENTIAL + * Copyright (2002-2008) Intel Corporation All Rights Reserved. + * The source code contained or described herein and all documents related to + * the source code ("Material") are owned by Intel Corporation or its suppliers + * or licensors. Title to the Material remains with Intel Corporation or its + * suppliers and licensors. The Material contains trade secrets and proprietary + * and confidential information of Intel or its suppliers and licensors. The + * Material is protected by worldwide copyright and trade secret laws and + * treaty provisions. No part of the Material may be used, copied, reproduced, + * modified, published, uploaded, posted, transmitted, distributed, or + * disclosed in any way without Intel's prior express written permission. + * + * No license under any patent, copyright, trade secret or other intellectual + * property right is granted to or conferred upon you by disclosure or + * delivery of the Materials, either expressly, by implication, inducement, + * estoppel or otherwise. Any license under such intellectual property rights + * must be express and approved by Intel in writing. + * + * + *----------------------------------------------------------------------------- + * Description: + * This file contains nterrupt related routines for the PLB platform. + *----------------------------------------------------------------------------- + */ + +#include +#include "drmP.h" +#include "psb_intregs.h" +#include "iegd_drm.h" + + +irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) +{ + int handled = 0; + struct drm_device *dev = (struct drm_device *)arg; + intel_device_private_t *priv=dev->dev_private; + uint32_t vdc_stat, sgx_stat, sgx_stat2, mtx_stat; + + spin_lock(&priv->irqmask_lock); + vdc_stat = PSB_RVDC32(IIR); + sgx_stat = PSB_RSGX32(PSB_CR_EVENT_STATUS); + sgx_stat2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2); + mtx_stat = PSB_RMSVDX32(PSB_MTX_EVENT_STATUS); + vdc_stat &= priv->vdc_irq_mask; + sgx_stat &= priv->sgx_irq_mask; + sgx_stat2 &= priv->sgx_irq_mask2; + mtx_stat &= priv->msvdx_irq_mask; + + if (vdc_stat) { + PSB_WVDC32(vdc_stat, IIR); + (void)PSB_RVDC32(IIR); + + priv->out_vdc |= vdc_stat; + handled = 1; + + if (sgx_stat || sgx_stat2 || mtx_stat) { + PSB_WSGX32(sgx_stat, PSB_CR_EVENT_HOST_CLEAR); + (void)PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR); + PSB_WSGX32(sgx_stat2, PSB_CR_EVENT_HOST_CLEAR2); + (void)PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR2); + PSB_WMSVDX32(mtx_stat, PSB_MTX_EVENT_CLEAR); + (void)PSB_RMSVDX32(PSB_MTX_EVENT_CLEAR); + + priv->out_sgx |= sgx_stat; + priv->out_sgx2 |= sgx_stat2; + priv->out_mtx |= mtx_stat; + + priv->event_present = 1; + spin_unlock(&priv->irqmask_lock); + DRM_WAKEUP(&priv->event_queue); + + } else { + + spin_unlock(&priv->irqmask_lock); + + } + + } else { + + spin_unlock(&priv->irqmask_lock); + + } + + if (!handled) { + return IRQ_NONE; + } + + return IRQ_HANDLED; +} + +void psb_irq_preinstall(struct drm_device *dev) +{ + intel_device_private_t *priv = + (intel_device_private_t *)dev->dev_private; + + spin_lock(&priv->irqmask_lock); + PSB_WVDC32(0xFFFFFFFF, HWSTAM); + PSB_WVDC32(0xFFFFFFFF, IMR); + PSB_WVDC32(0x00000000, IER); + + PSB_WSGX32(0x00000000, PSB_CR_EVENT_HOST_ENABLE); + (void)PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE); + PSB_WSGX32(0x00000000, PSB_CR_EVENT_HOST_ENABLE2); + (void)PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE2); + PSB_WMSVDX32(0x00000000, PSB_MTX_EVENT_HOST_ENABLE); + (void)PSB_RMSVDX32(PSB_MTX_EVENT_HOST_ENABLE); + + priv->sgx_irq_mask = PSB_TWOD_COMPLETE | + PSB_TA_FINISHED | PSB_TA_TERMINATE | + PSB_PIXELBE_END_RENDER | PSB_DPM_3D_MEM_FREE | + PSB_OUT_OF_MEM_MT | PSB_OUT_OF_MEM_GBL | + PSB_REACHED_MEM_THRESH | PSB_DPM_TA_MEM_FREE | + PSB_DPM_OUT_OF_MEM_ZLS | PSB_TA_DPM_FAULT; + + priv->sgx_irq_mask2 = PSB_BIF_REQ_FAULT | PSB_TRIG_TA | PSB_TRIG_3D | + PSB_TRIG_DL; + + priv->vdc_irq_mask = IRQ_SGX_FLAG | IRQ_MSVDX_FLAG; + + priv->msvdx_irq_mask = (1<<14); /* Enable only MTX interrupt */ + + spin_unlock(&priv->irqmask_lock); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) +void psb_irq_postinstall(struct drm_device *dev) +#else +int psb_irq_postinstall(struct drm_device *dev) +#endif +{ + intel_device_private_t *priv = + (intel_device_private_t *)dev->dev_private; + unsigned long irqflags; + + spin_lock_irqsave(&priv->irqmask_lock, irqflags); + PSB_WVDC32(priv->vdc_irq_mask, IER); + PSB_WSGX32(priv->sgx_irq_mask, PSB_CR_EVENT_HOST_ENABLE); + (void)PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE); + PSB_WSGX32(priv->sgx_irq_mask2, PSB_CR_EVENT_HOST_ENABLE2); + (void)PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE2); + PSB_WMSVDX32(priv->msvdx_irq_mask, PSB_MTX_EVENT_HOST_ENABLE); + (void)PSB_RMSVDX32(PSB_MTX_EVENT_HOST_ENABLE); + + priv->irq_enabled = 1; + spin_unlock_irqrestore(&priv->irqmask_lock, irqflags); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) + return 0; +#endif + +} + +void psb_irq_uninstall(struct drm_device *dev) +{ + intel_device_private_t *priv = + (intel_device_private_t *)dev->dev_private; + unsigned long irqflags; + + spin_lock_irqsave(&priv->irqmask_lock, irqflags); + + priv->sgx_irq_mask = 0x00000000; + priv->sgx_irq_mask2 = 0x00000000; + priv->vdc_irq_mask = 0x00000000; + priv->msvdx_irq_mask = 0x00000000; + + /* By default, we're enabling interrupts buy leaving them masked */ + PSB_WVDC32(0xFFFFFFFF, HWSTAM); + PSB_WVDC32(0xFFFFFFFF, IMR); + PSB_WVDC32(priv->vdc_irq_mask, IER); + PSB_WSGX32(priv->sgx_irq_mask, PSB_CR_EVENT_HOST_ENABLE); + PSB_WSGX32(priv->sgx_irq_mask2, PSB_CR_EVENT_HOST_ENABLE2); + PSB_WMSVDX32(priv->msvdx_irq_mask, PSB_MTX_EVENT_HOST_ENABLE); + wmb(); + PSB_WVDC32(PSB_RVDC32(IIR), IIR); + PSB_WSGX32(PSB_RSGX32(PSB_CR_EVENT_STATUS), PSB_CR_EVENT_HOST_CLEAR); + PSB_WSGX32(PSB_RSGX32(PSB_CR_EVENT_STATUS2), PSB_CR_EVENT_HOST_CLEAR2); + PSB_WMSVDX32(PSB_RMSVDX32(PSB_MTX_EVENT_STATUS), PSB_MTX_EVENT_CLEAR); + + priv->irq_enabled = 0; + spin_unlock_irqrestore(&priv->irqmask_lock, irqflags); +} diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/include/global.h patch_script_temp/drivers/gpu/drm/iegd/include/global.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/include/global.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/include/global.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,160 @@ +/* -*- pse-c -*- + * Filename: iegd_interface.c + * $Revision: 1.19 $ + *---------------------------------------------------------------------------- + * <> + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * + *---------------------------------------------------------------------------- + * Functions: + * + * + *---------------------------------------------------------------------------- + */ + +#ifndef _GART_GLOBAL_DEF +#define _GART_GLOBAL_DEF +#include "igd_gart.h" +#include "igd_abs.h" +#include "interface_abs.h" + + +#define APER_ENTRY(a,b) sizeof((a))/(b) +#define AGP_DCACHE_MEMORY 1 +#define AGP_PHYS_MEMORY 2 + +#define IEGD "IEGD" + +/** + * This is global data that is shared across file. New global + * data should goes here. + */ +extern gart_dispatch_t *gart_id; +extern dev_private_data_t private_data; +extern struct pci_device_id iegd_pci_table[]; +extern dispatch_table_t driver_dispatch_list[]; +extern struct gatt_mask iegd_cmn_masks[]; +extern struct aper_size_info_fixed iegd_i915_sizes[]; +extern struct aper_size_info_fixed iegd_iq35_sizes[]; +extern struct aper_size_info_fixed iegd_i965_sizes[]; +extern struct aper_size_info_fixed intel_i830_sizes[]; +extern struct aper_size_info_fixed intel_i810_sizes[]; +extern struct aper_size_info_fixed iegd_igm45_sizes[]; + +/* All dispatch table for the chipset family goes here */ +extern bridge_driver_t drv_alm; +extern bridge_driver_t drv_nap; +extern bridge_driver_t drv_gn4; +extern bridge_driver_t drv_gm45; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,5) +/* Poulsbo */ +extern struct aper_size_info_fixed iegd_plb_sizes[]; +extern bridge_driver_t drv_plb; + +/* Poulsbo specific structure so that the DRM can utilize the + * AGP's virtual aperture management code + */ +extern struct vm_operations_struct iegd_plb_vm_ops; +#endif + + +/* + * Macro to fill device information for PCI devices registration. + * Copy from public agpgart in kernel source + */ +#define ID(x) { \ + .class = (PCI_CLASS_BRIDGE_HOST << 8), \ + .class_mask = ~0, \ + .vendor = PCI_VENDOR_ID_INTEL, \ + .device = x, \ + .subvendor = PCI_ANY_ID, \ + .subdevice = PCI_ANY_ID, \ +} + +#ifdef CONFIG_AGP_DEBUG +#define AGN_DEBUG(x,y...) printk(KERN_INFO "[" IEGD \ + ":DEBUG]:%s " x "\n", __FUNCTION__, ##y) +#else +#define AGN_DEBUG(x,y...) do {} while(0) +#endif + +#define AGN_ERROR(x,y...) printk(KERN_ALERT "[" IEGD \ + ":ERROR]:%s: " x "\n", __FUNCTION__, ##y) +#define AGN_LOG(x,y...) printk(KERN_INFO "[" IEGD "]: " x "\n", ##y) + +/** + * Global extern function prototype, basically common function + * should goes here. Most of this function extern is from + * drv_cmn.c + */ +extern int iegd_find_device(u16 device); +extern struct pci_dev *iegd_probe_device(void); +extern void iegd_cmn_init_gtt_entries(void); +extern int AGP_FREE_GATT(iegd_cmn_free_gatt_table); +extern void iegd_cmn_free_by_type(struct agp_memory *curr); +extern struct agp_memory *iegd_cmn_alloc_by_type( + size_t pg_count, int type); +extern int iegd_cmn_insert_entries(struct agp_memory *mem, + off_t pg_start, int type); +extern int iegd_cmn_remove_entries(struct agp_memory *mem, off_t pg_start, + int type); +extern int bridge_driver_init(bridge_driver_t **driver_hook, + unsigned short did, dispatch_table_t *list ); + +#ifndef MSR_IA32_CR_PAT +#define MSR_IA32_CR_PAT 0x0277 +#endif +#ifndef _PAGE_PAT +#define _PAGE_PAT 0x080 +#endif +extern void agp_init_pat(void); +extern int agp_use_pat (void); + +/** + * masking valid bit for page table entries before + * put it insert it to gtt table + */ +unsigned long AGP_MASK_MEMORY(iegd_cmn_mask_memory); +int AGP_CREATE_GATT(iegd_alm_create_gatt_table); +extern int iegd_cmn_configure(void); +extern void AGP_ENABLE(iegd_cmn_agp_enable); + +/* Global DRM function prototype */ +extern int intel_init(void); +extern void intel_exit(void); +extern int drm_init(void); +extern void drm_cleanup(void); + +/* Generic function to dispatch the information according to + * chipset id */ +static __inline void *dispatch_acquire( + + unsigned short did, + dispatch_table_t *table_list) { + + dispatch_table_t *curr = table_list; + while(curr && (curr->did != 0)) { + if(curr->did == did) { + return curr->table; + } + curr++; + } + + return NULL; +} +#endif diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/include/igd_abs.h patch_script_temp/drivers/gpu/drm/iegd/include/igd_abs.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/include/igd_abs.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/include/igd_abs.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,136 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_interface.c + * $Revision: 1.15 $ + *---------------------------------------------------------------------------- + * <> + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * + *---------------------------------------------------------------------------- + * Functions: + * + * + *---------------------------------------------------------------------------- + */ + +#ifndef _KERNEL_ABS_LAYER +#define _KERNEL_ABS_LAYER + +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) +#define IGD_FREE_MEM(a) agp_free_page_array(a) +#else +#define IGD_FREE_MEM(a) vfree((a)->memory) +#endif + +#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,5) +#define DRM_INIT_MODULE() drm_init() +#define DRM_EXIT_MODULE() drm_cleanup() +#define AGP_RET(a) ((a)>=0) ? 1 : 0 +#else +#define DRM_INIT_MODULE() intel_init() +#define DRM_EXIT_MODULE() intel_exit() +#define AGP_RET(a) ((a)==0) ? 1 : 0 +#endif + +#if LINUX_VERSION_CODE= KERNEL_VERSION(2,6,23) +#define AGP_LOCK_PAGE(a) +#define AGP_UNLOCK_PAGE(a) +#else +#define AGP_LOCK_PAGE(a) SetPageLocked((a)) +#define AGP_UNLOCK_PAGE(a) unlock_page((a)) +#endif + +#define MASK_PTE(a,b) (a)->driver->masks[(b)].mask +#define AGP_MASK_ADDR(x) MASK_PTE((x),type) + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#define SET_PAGES_UC(a,b) set_pages_uc(a,b) +#define SET_PAGES_WB(a,b) set_pages_wb(a,b) +#define GLOBAL_FLUSH_TLB() +#ifndef SetPageLocked +#define SetPageLocked(page) set_bit(PG_locked, &page->flags); +#endif +#else +#define SET_PAGES_UC(a,b) change_page_attr(a,b,PAGE_KERNEL_NOCACHE) +#define SET_PAGES_WB(a,b) change_page_attr(a,b,PAGE_KERNEL) +#define GLOBAL_FLUSH_TLB() global_flush_tlb() +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) +#define ON_EACH_CPU(a,b,c,d) on_each_cpu(a,b,d) +/* Note: drm_dev_to_irq appears 2.6.28, but some distros + * have pulled it into earlier versions of their kernel. + * That's why it's defined here. + */ +#define DRM_DEV_TO_IRQ(a) drm_dev_to_irq(a) +#else +#define ON_EACH_CPU(a,b,c,d) on_each_cpu(a,b,c,d) +#define DRM_DEV_TO_IRQ(a) (a->irq) +#endif + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) +#define AGP_MEM_TYPE struct page* +#define CONVERT_PAGE_TO_GART(a) phys_to_gart(page_to_phys(a)); +#define AGP_MEMORY_MEMBER pages +#define PAGE_ADDRESS(a) a +#else +#define AGP_MEM_TYPE void* +#define CONVERT_PAGE_TO_GART(a) a +#define AGP_MEMORY_MEMBER memory +#define PAGE_ADDRESS(a) page_address(a) +#endif + + +/* + * Kernel interface abstraction. This macro will + * point to the proper definition for that particular + * kernel + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) +#define AGP_MASK_MEMORY(f) _MASK_MEMORY_PAGE(f) +#else +#define AGP_MASK_MEMORY(f) _MASK_MEMORY(f) +#endif +#define AGP_CREATE_GATT(f) _CREATE_GATT_TABLE(f) +#define AGP_FREE_GATT(f) _FREE_GATT_TABLE(f) +#define AGP_ALLOC_PAGE(f) _ALLOC_PAGE_AGP(f) +#define AGP_ENABLE(f) _ENABLE_AGP(f) +#define AGP_TYPE_TO_MASK_TYPE(f) _TYPE_TO_MASK_TYPE(f) + +#define AGP_MASK_GTT() _mask_gtt() +#endif diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/include/igd_gart.h patch_script_temp/drivers/gpu/drm/iegd/include/igd_gart.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/include/igd_gart.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/include/igd_gart.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,81 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: igd_gart.h + * $Revision: 1.10 $ + *---------------------------------------------------------------------------- + * <> + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * + *---------------------------------------------------------------------------- + * Functions: + * + * + *---------------------------------------------------------------------------- + */ + +#ifndef _INIT_GART_DISPATCH +#define _INIT_GART_DISPATCH + +#include +#include +#include "agp.h" + +typedef struct agp_bridge_driver bridge_driver_t; +typedef struct agp_bridge_data bridge_data_t; + +/* Dispatch table that contained information about + * specific chipset */ +typedef struct _gart_dispatch { + unsigned short vendor_id; + unsigned short bridge_id; /* Bridge device id */ + unsigned short device_id; /* chipset id */ + char *name; /* Name for the chipset */ + unsigned short dev_flag; + struct pci_driver *old_gart; /* old gart info */ + struct pci_dev *bridge_pdev; /* Bridge device info */ + bridge_data_t *bridge_info; /* bridge information for gart */ +}gart_dispatch_t; + +/* Structure that keep the private data for chipset */ +typedef struct _dev_private_data { + struct pci_dev *pdev; + volatile u8 __iomem *registers; + volatile u32 __iomem *gtt; + union { + int num_dcache_entries; + int gtt_entries; + }; + u32 pm_save[16]; /* PCI config saved here on suspend/resume. */ + /* Required for older kernel versions. */ + int split_gtt; + volatile u32 __iomem *upper_gtt; +}dev_private_data_t; + +/* Dispatch table for function hook */ +typedef struct _dispatch_table { + unsigned short did; + void *table; +}dispatch_table_t; + +/* Table contained function pointer for specific chipset */ +typedef struct _driver_func_table { + bridge_driver_t driver_func; /* Contained actual function */ + void (*config_private)(void); /* config private */ +}driver_func_table_t; + + +#endif diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/include/intelpci.h patch_script_temp/drivers/gpu/drm/iegd/include/intelpci.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/include/intelpci.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/include/intelpci.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,178 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: intelpci.h + * $Revision: 1.16 $ + *---------------------------------------------------------------------------- + * <> + * Copyright © 2008, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * + *---------------------------------------------------------------------------- + * Functions: + * + * + *---------------------------------------------------------------------------- + */ + +#define PCI_VENDOR_ID_INTEL 0x8086 + + +/* Start: Whitney core specific */ +#define PCI_DEVICE_ID_BRIDGE_810 0x7120 +#define PCI_DEVICE_ID_810 0x7121 + +#define PCI_DEVICE_ID_BRIDGE_810DC 0x7122 +#define PCI_DEVICE_ID_810DC 0x7123 + +#define PCI_DEVICE_ID_BRIDGE_810E 0x7124 +#define PCI_DEVICE_ID_810E 0x7125 + +#define PCI_DEVICE_ID_BRIDGE_815 0x1130 +#define PCI_DEVICE_ID_815 0x1132 + + +/* Start: Almador core specific */ +#define PCI_DEVICE_ID_BRIDGE_830M 0x3575 +#define PCI_DEVICE_ID_830M 0x3577 +#define PCI_DEVICE_ID_AGP_830M 0x3576 + +#define PCI_DEVICE_ID_BRIDGE_835 0x3579 +#define PCI_DEVICE_ID_835 0x357b +#define PCI_DEVICE_ID_AGP_835 0x357a + +#define PCI_DEVICE_ID_BRIDGE_845G 0x2560 +#define PCI_DEVICE_ID_845G 0x2562 +#define PCI_DEVICE_ID_AGP_845G 0x0000 + +#define PCI_DEVICE_ID_BRIDGE_855 0x3580 /* Montara-G */ +#define PCI_DEVICE_ID_MEM_855 0x3584 +#define PCI_DEVICE_ID_855 0x3582 +#define PCI_DEVICE_ID_AGP_855 0x0000 + +#define PCI_DEVICE_ID_BRIDGE_865G 0x2570 +#define PCI_DEVICE_ID_865G 0x2572 +#define PCI_DEVICE_ID_AGP_865G 0x0000 + + +/* Start: Napa core specific */ +/* Grantsdale - 915G/915GV */ +#define PCI_DEVICE_ID_BRIDGE_915GD 0x2580 +#define PCI_DEVICE_ID_PEG_915GD 0x2581 +#define PCI_DEVICE_ID_915GD 0x2582 +/* Grantsdale - 910GL*/ +#define PCI_DEVICE_ID_BRIDGE_910GL 0x258C +#define PCI_DEVICE_ID_PEG_910GL PCI_DEVICE_ID_PEG_915GD +#define PCI_DEVICE_ID_910GL PCI_DEVICE_ID_915GD +/* Alviso - 915GM/GMS/910GML*/ +#define PCI_DEVICE_ID_BRIDGE_915AL 0x2590 +#define PCI_DEVICE_ID_PEG_915AL 0x2591 +#define PCI_DEVICE_ID_915AL 0x2592 + +/* Lakeport - 945G */ +#define PCI_DEVICE_ID_BRIDGE_945G 0x2770 +#define PCI_DEVICE_ID_PEG_945G 0x2771 +#define PCI_DEVICE_ID_945G 0x2772 + +/* Calistoga - 945GM */ +#define PCI_DEVICE_ID_BRIDGE_945GM 0x27A0 +#define PCI_DEVICE_ID_PEG_945GM 0x27A1 +#define PCI_DEVICE_ID_945GM 0x27A2 + +/* Calistoga Westbriar - 945GME/GSE */ +#define PCI_DEVICE_ID_BRIDGE_945GME 0x27AC +#define PCI_DEVICE_ID_PEG_945GME 0x27AD +#define PCI_DEVICE_ID_945GME 0x27AE + +/* Bearlake B - Q35 */ +#define PCI_DEVICE_ID_BRIDGE_Q35 0x29C0 +#define PCI_DEVICE_ID_PEG_Q35 0x29C1 +#define PCI_DEVICE_ID_Q35 0x29C2 + +/* Bearlake B - Q35 */ +#define PCI_DEVICE_ID_BRIDGE_Q35A2 0x29B0 +#define PCI_DEVICE_ID_PEG_Q35A2 0x29B1 +#define PCI_DEVICE_ID_Q35A2 0x29B2 + +/* Start: Gen4 core specific*/ +/* Broadwater - Unlocked - 965G */ +#define PCI_DEVICE_ID_BRIDGE_965G 0x2980 +#define PCI_DEVICE_ID_PEG_965G 0x2981 +#define PCI_DEVICE_ID_965G 0x2982 + +/* Broadwater - Value - 945GZ */ +#define PCI_DEVICE_ID_BRIDGE_946GZ 0x2970 +#define PCI_DEVICE_ID_PEG_946GZ 0x2971 +#define PCI_DEVICE_ID_946GZ 0x2972 + +/* Broadwater - Consumer - G965 */ +#define PCI_DEVICE_ID_BRIDGE_G965 0x29A0 +#define PCI_DEVICE_ID_PEG_G965 0x29A1 +#define PCI_DEVICE_ID_G965 0x29A2 + +/* Broadwater - Corporate - Q965/Q963 */ +#define PCI_DEVICE_ID_BRIDGE_Q965 0x2990 +#define PCI_DEVICE_ID_PEG_Q965 0x2991 +#define PCI_DEVICE_ID_Q965 0x2992 + +/* Crestline - Generic GM965 */ +#define PCI_DEVICE_ID_BRIDGE_GM965 0x2A00 +#define PCI_DEVICE_ID_PEG_GM965 0x2A01 +#define PCI_DEVICE_ID_GM965 0x2A02 + +/* Crestline Westbriar GME965 */ +#define PCI_DEVICE_ID_BRIDGE_GME965 0x2A10 +#define PCI_DEVICE_ID_PEG_GME965 0x2A11 +#define PCI_DEVICE_ID_GME965 0x2A12 + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,5) +/* Poulsbo */ +#define PCI_DEVICE_ID_BRIDGE_PLB 0x8100 +#define PCI_DEVICE_ID_PEG_PLB 0x8101 +#define PCI_DEVICE_ID_PLB 0x8108 +#endif + +/* Cantiga GM45 */ +#define PCI_DEVICE_ID_BRIDGE_GM45 0x2A40 +#define PCI_DEVICE_ID_PEG_GM45 0x2A41 +#define PCI_DEVICE_ID_GM45 0x2A42 + +#define PCI_DEVICE_ID_BRIDGE_ELK 0x2E00 +#define PCI_DEVICE_ID_PEG_ELK 0x2E01 +#define PCI_DEVICE_ID_ELK 0x2E02 + +#define PCI_DEVICE_ID_BRIDGE_Q45 0x2E10 +#define PCI_DEVICE_ID_PEG_Q45 0x2E11 +#define PCI_DEVICE_ID_Q45 0x2E12 + +#define PCI_DEVICE_ID_BRIDGE_G45 0x2E20 +#define PCI_DEVICE_ID_PEG_G45 0x2E21 +#define PCI_DEVICE_ID_G45 0x2E22 + +#define PCI_DEVICE_ID_BRIDGE_G41 0x2E30 +#define PCI_DEVICE_ID_PEG_G41 0x2E31 +#define PCI_DEVICE_ID_G41 0x2E32 + +#define I915_GMADDR 0x18 +#define I915_MMADDR 0x10 +#define I915_PTEADDR 0x1C +#define I915_GMCH_GMS_STOLEN_48M (0x6 << 4) +#define I915_GMCH_GMS_STOLEN_64M (0x7 << 4) + +/* intel Q35 register */ +#define IQ35_BASE_STOLEN 0x5c +#define IQ35_GTT_MEM_SIZE 0x300 +#define IQ35_GGMS_1MB 0x100 +#define IQ35_GGMS_2MB 0x200 diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/include/interface_abs.h patch_script_temp/drivers/gpu/drm/iegd/include/interface_abs.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/drivers/gpu/drm/iegd/include/interface_abs.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/drivers/gpu/drm/iegd/include/interface_abs.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1,48 @@ +/* -*- pse-c -*- + *---------------------------------------------------------------------------- + * Filename: iegd_interface.c + * $Revision: 1.4 $ + *---------------------------------------------------------------------------- + * <> + * Copyright © 2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + *---------------------------------------------------------------------------- + * Functions: + * + * + *---------------------------------------------------------------------------- + */ + +#ifndef _AGP_INTERFACE_ABS_LAYER +#define _AGP_INTERFACE_ABS_LAYER + +#define AGP_BRIDGE_VAR bridge + +#define _MASK_MEMORY_PAGE(f) f( struct agp_bridge_data *bridge, \ + struct page* addr, int type) + +#define _MASK_MEMORY(f) f( struct agp_bridge_data *bridge, \ + unsigned long addr, int type) + +#define _CREATE_GATT_TABLE(f) f(struct agp_bridge_data *bridge) +#define _FREE_GATT_TABLE(f) f(struct agp_bridge_data *bridge) +#define _ALLOC_PAGE_AGP(f) f(struct agp_bridge_data *bridge) +#define _ENABLE_AGP(f) f(struct agp_bridge_data *bridge, u32 mode) +#define _TYPE_TO_MASK_TYPE(f) f(struct agp_bridge_data *bridge, int x) + +#define _mask_gtt() agp_bridge->driver->mask_memory( \ + agp_bridge, mem->pages[i], mem->type) +#endif diff -uNr vanilla.2.6.31.rc6-67.1.moblin2-ivi/include/linux/config.h patch_script_temp/include/linux/config.h --- vanilla.2.6.31.rc6-67.1.moblin2-ivi/include/linux/config.h 1969-12-31 17:00:00.000000000 -0700 +++ patch_script_temp/include/linux/config.h 2009-10-06 10:30:05.000000000 -0700 @@ -0,0 +1 @@ +