diff options
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-iegd.patch')
-rw-r--r-- | meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-iegd.patch | 9290 |
1 files changed, 9290 insertions, 0 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-iegd.patch b/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-iegd.patch new file mode 100644 index 000000000..fa6a3ea9f --- /dev/null +++ b/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-iegd.patch @@ -0,0 +1,9290 @@ +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 <fcntl.h> ++#include <unistd.h> ++#include <sys/ioctl.h> ++#include <stdlib.h> ++#include <stdio.h> ++#include <linux/agpgart.h> ++#include <sys/mman.h> ++ ++/*#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<<i830_gtt_page_order)) - 1); ++ ++ /* Make sure allocation was successful */ ++ if (NULL == gtt_table) { ++ AGN_ERROR("Fail to allocate kernel memory"); ++ 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); ++ } 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 <linux/pagemap.h> ++#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 <linux/pagemap.h> ++#include <linux/list.h> ++ ++#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 <linux/init.h> ++#include <linux/module.h> ++#include <linux/pci.h> ++#include <linux/agp_backend.h> ++#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 <asm/tlbflush.h> ++ ++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 ; i<sizeof(gart_pci_device_table)/sizeof(gart_dispatch_t); ++ i++) { ++ dev = pci_get_device(PCI_VENDOR_ID_INTEL, ++ (unsigned int)gart_pci_device_table[i].bridge_id, NULL); ++ if(dev){ ++ gart_id = &gart_pci_device_table[i]; ++ AGN_DEBUG("Device found.. Exit"); ++ return dev; ++ } ++ } ++ AGN_DEBUG("Device not found.. Exit"); ++ return NULL; ++} ++ ++/** ++ * This is the first routine been called by the init function. ++ * This function will probe for devices that supported by IEGD. ++ * Once it found the device, it will check whether driver for ++ * this device exist. If it exist, get the pci_driver structure ++ * for the existing driver and call the pci unregister fucntion ++ * to deregister existing driver and register iegd agpgart ++ */ ++static int iegd_agp_init(void) ++{ ++ struct pci_driver *curr_driver; ++ struct pci_dev *temp_pdev; ++ ++ AGN_DEBUG("Enter"); ++ ++ /* Probe for the intel embedded graphic device chipset */ ++ temp_pdev = iegd_probe_device(); ++ ++ if(!temp_pdev) { ++ AGN_ERROR("Probe device failed"); ++ return -ENODEV; ++ } ++ ++ gart_id->bridge_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 <fcntl.h> ++#include <unistd.h> ++#include <sys/ioctl.h> ++#include <stdlib.h> ++#include <stdio.h> ++#include <string.h> ++ ++#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 <fcntl.h> ++#include <unistd.h> ++#include <sys/ioctl.h> ++#include <stdlib.h> ++#include <stdio.h> ++ ++#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 <linux/version.h> ++#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 <linux/config.h> ++#include "iegd.h" ++#include <drmP.h> ++#include <drm.h> ++#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<<order; ++ DRM_DEBUG("Allocated address:%#lx,page offset:%#lx,phy_address:%#lx\n", ++ address,offset,phy_address); ++ ++ /*do_mmap on the logical address and return virtual address */ ++ down_write(¤t->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 <linux/i2c.h> ++ ++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<<order; ++ DRM_DEBUG("Allocated address:%#lx,page offset:%#lx,phy_address:%#lx\n", ++ address,offset,phy_address); ++ ++ /*do_mmap on the logical address and return virtual address */ ++ down_write(¤t->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 <fcntl.h> ++#include <unistd.h> ++#include <sys/ioctl.h> ++#include <stdlib.h> ++#include <stdio.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) ++ ++#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 <linux/version.h> ++#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 <linux/version.h> ++ ++#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,10) ++#define IGD_PCI_SAVE_STATE(a,b) pci_save_state(a,b) ++#define IGD_PCI_RESTORE_STATE(a,b) pci_restore_state(a,b) ++#define pm_message_t u32 ++#define IGD_IS_SUSPEND(state) ((state)==3) ++#else ++#define IGD_PCI_SAVE_STATE(a,b) pci_save_state(a) ++#define IGD_PCI_RESTORE_STATE(a,b) pci_restore_state(a) ++#define IGD_IS_SUSPEND(state) \ ++ (((state.event)==PM_EVENT_SUSPEND) | ((state.event)==PM_EVENT_FREEZE)) ++#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 <linux/pci.h> ++#include <linux/agp_backend.h> ++#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 @@ ++ |