From patchwork Tue Jul 28 02:10:26 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhao, Yakui" X-Patchwork-Id: 37658 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n6S29up7003892 for ; Tue, 28 Jul 2009 02:09:56 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 17FDB9F006; Mon, 27 Jul 2009 19:09:55 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [143.182.124.37]) by gabe.freedesktop.org (Postfix) with ESMTP id B18AD9E773 for ; Mon, 27 Jul 2009 19:09:53 -0700 (PDT) Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga102.ch.intel.com with ESMTP; 27 Jul 2009 19:09:53 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.43,280,1246863600"; d="scan'208";a="169537363" Received: from yakui_zhao.sh.intel.com (HELO localhost.localdomain) ([10.239.13.194]) by azsmga001.ch.intel.com with ESMTP; 27 Jul 2009 19:09:52 -0700 From: yakui.zhao@intel.com To: eric@anholt.net Date: Tue, 28 Jul 2009 10:10:26 +0800 Message-Id: <1248747028-4231-2-git-send-email-yakui.zhao@intel.com> X-Mailer: git-send-email 1.5.4.5 In-Reply-To: <1248747028-4231-1-git-send-email-yakui.zhao@intel.com> References: <1248747028-4231-1-git-send-email-yakui.zhao@intel.com> Cc: intel-gfx@lists.freedesktop.org Subject: [Intel-gfx] [Patch 1/3] DRM/I915: parse child device from VBT X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org From: Zhao Yakui Parse the child device from VBT. Signed-Off-by: Zhao Yakui --- drivers/gpu/drm/i915/i915_dma.c | 11 ++++++ drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/intel_bios.c | 65 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) Index: linux-2.6/drivers/gpu/drm/i915/i915_drv.h =================================================================== --- linux-2.6.orig/drivers/gpu/drm/i915/i915_drv.h 2009-07-20 15:00:01.000000000 +0800 +++ linux-2.6/drivers/gpu/drm/i915/i915_drv.h 2009-07-20 17:24:22.000000000 +0800 @@ -437,6 +437,8 @@ struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; } mm; struct sdvo_device_mapping sdvo_mappings[2]; + int child_dev_num; + struct child_device_config *child_dev; } drm_i915_private_t; /** driver private structure attached to each drm_gem_object */ Index: linux-2.6/drivers/gpu/drm/i915/intel_bios.c =================================================================== --- linux-2.6.orig/drivers/gpu/drm/i915/intel_bios.c 2009-07-13 08:49:30.000000000 +0800 +++ linux-2.6/drivers/gpu/drm/i915/intel_bios.c 2009-07-20 16:52:51.000000000 +0800 @@ -295,6 +295,70 @@ } return; } +static void +parse_device_mapping_from_vbt(struct drm_i915_private *dev_priv, + struct bdb_header *bdb) +{ + struct bdb_general_definitions *p_defs; + struct child_device_config *p_child, *child_dev_ptr; + int i, child_device_num, count; + u16 block_size, *block_ptr; + + p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); + if (!p_defs) { + DRM_DEBUG("No general definition block is found\n"); + return; + } + /* judge whether the size of child device meets the requirements. + * If the child device size obtained from general definition block + * is different with sizeof(struct child_device_config), skip the + * parsing of sdvo device info + */ + if (p_defs->child_dev_size != sizeof(*p_child)) { + /* different child dev size . Ignore it */ + DRM_DEBUG("different child size is found. Invalid.\n"); + return; + } + /* get the block size of general definitions */ + block_ptr = (u16 *)((char *)p_defs - 2); + block_size = *block_ptr; + /* get the number of child device */ + child_device_num = (block_size - sizeof(*p_defs)) / + sizeof(*p_child); + count = 0; + /* get the number of child device that is present */ + for (i = 0; i < child_device_num; i++) { + p_child = &(p_defs->devices[i]); + if (!p_child->device_type) { + /* skip the device block if device type is invalid */ + continue; + } + count++; + } + if (!count) { + DRM_DEBUG("no child dev is parsed from VBT \n"); + return; + } + dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL); + if (!dev_priv->child_dev) { + DRM_DEBUG("Can't allocate memory space for child device\n"); + } + dev_priv->child_dev_num = count; + count = 0; + for (i = 0; i < child_device_num; i++) { + p_child = &(p_defs->devices[i]); + if (!p_child->device_type) { + /* skip the device block if device type is invalid */ + continue; + } + child_dev_ptr = dev_priv->child_dev + count; + printk(KERN_DEBUG "initial %p, result %p, size %d\n", + dev_priv->child_dev, child_dev_ptr, sizeof(*p_child) * count); + count++; + memcpy((void *)child_dev_ptr, (void *)p_child, sizeof(*p_child)); + } + return; +} /** * intel_init_bios - initialize VBIOS settings & find VBT * @dev: DRM device @@ -345,6 +409,7 @@ parse_lfp_panel_data(dev_priv, bdb); parse_sdvo_panel_data(dev_priv, bdb); parse_sdvo_device_mapping(dev_priv, bdb); + parse_device_mapping_from_vbt(dev_priv, bdb); pci_unmap_rom(pdev, bios); return 0; Index: linux-2.6/drivers/gpu/drm/i915/i915_dma.c =================================================================== --- linux-2.6.orig/drivers/gpu/drm/i915/i915_dma.c 2009-07-20 15:26:30.000000000 +0800 +++ linux-2.6/drivers/gpu/drm/i915/i915_dma.c 2009-07-20 15:29:54.000000000 +0800 @@ -1242,6 +1242,8 @@ } if (drm_core_check_feature(dev, DRIVER_MODESET)) { + dev_priv->child_dev = NULL; + dev_priv->child_dev_num = 0; ret = i915_load_modeset_init(dev, prealloc_size, agp_size); if (ret < 0) { DRM_ERROR("failed to init modeset\n"); @@ -1299,6 +1301,15 @@ mutex_unlock(&dev->struct_mutex); drm_mm_takedown(&dev_priv->vram); i915_gem_lastclose(dev); + /* + * free the memory space allocated for the child device + * config parsed from VBT + */ + if (dev_priv->child_dev_num && dev_priv->child_dev) { + kfree(dev_priv->child_dev); + dev_priv->child_dev = NULL; + dev_priv->child_dev_num = 0; + } } kfree(dev->dev_private);