be = ttm->be;
- ret = ttm_tt_populate(ttm);
- if (ret)
- return ret;
+ /* Bypass ttm_tt_populate when TTM_PL_FLAG_VED is enabled */
+ if (!(bo_mem->placement & TTM_PL_FLAG_VED)) {
+ ret = ttm_tt_populate(ttm);
+ if (ret)
+ return ret;
+ } else {
+ /* TTM_PL_FLAG_VED indicates gralloc buffer allocation. As such,
+ * TTM allocation and BE bind should be bypassed.
+ * ttm->state remains unpopulated.
+ */
+ return 0;
+ }
ret = be->func->bind(be, bo_mem);
if (unlikely(ret != 0))
$(IMGVDIR)/topaz_power.o
medfield_gfx-y += \
+ $(IMGVDIR)/psb_video_bind.o
+
+medfield_gfx-y += \
$(BUFFER_CLASS_DIR)/bufferclass_video.o \
$(BUFFER_CLASS_DIR)/bufferclass_video_linux.o
+
medfield_gfx-$(CONFIG_MDFLD_DSI_DPU) += $(DRMDRVDIR)/mdfld_dsi_dbi_dpu.o
medfield_gfx-$(CONFIG_MDFD_GL3) += $(DRMDRVDIR)/mdfld_gl3.o
/*BC_VIDEO ioctl*/
#define DRM_BUFFER_CLASS_VIDEO (DRM_LNC_VIDEO_GETPARAM + 1) /*0x32*/
+/*BC_ST_GFX_VIDEO ioctl*/
+#define DRM_ST_GFX_BUFFER_CLASS_VIDEO (DRM_BUFFER_CLASS_VIDEO + 1) /*0x33*/
+
#define DRM_IOCTL_PSB_TTM_PL_CREATE \
DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_CREATE,\
union ttm_pl_create_arg)
#define DRM_IOCTL_PSB_TTM_PL_WRAP_PVR_BUF \
DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_WRAP_PVR_BUF, \
union ttm_pl_create_arg)
+/*bc_st_gfx_video ioctl*/
+#define DRM_IOCTL_ST_GFX_BUFFER_CLASS_VIDEO \
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_ST_GFX_BUFFER_CLASS_VIDEO, \
+ BC_Video_ioctl_package)
static int psb_vt_leave_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
PSB_IOCTL_DEF(DRM_IOCRL_PSB_DPU_DSR_ON, psb_dpu_dsr_on_ioctl,
DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCRL_PSB_DPU_DSR_OFF, psb_dpu_dsr_off_ioctl,
- DRM_AUTH)
+ DRM_AUTH),
+ PSB_IOCTL_DEF(DRM_IOCTL_ST_GFX_BUFFER_CLASS_VIDEO,
+ psb_st_gfx_video_bridge, DRM_AUTH)
};
static void psb_lastclose(struct drm_device *dev)
return 0;
}
+ /* return the video bind offset */
+ if (strcmp(arg->extension, "psb_video_bind") == 0) {
+ rep->exists = 1;
+ rep->driver_ioctl_offset = DRM_ST_GFX_BUFFER_CLASS_VIDEO;
+ rep->sarea_offset = 0;
+ rep->major = 1;
+ rep->minor = 0;
+ rep->pl = 0;
+ return 0;
+ }
+
rep->exists = 0;
return 0;
}
int psb_get_brightness(struct backlight_device *bd);
struct backlight_device * psb_get_backlight_device(void);
+/* psb_video_bind.c */
+int psb_st_gfx_video_bridge(struct drm_device *dev,
+ IMG_VOID *arg, struct drm_file *file_priv);
+
/*
*Debug print bits setting
*/
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
**************************************************************************/
-#include <drm/drmP.h>
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_msvdx.h"
-
-/*
- * Code for the SGX MMU:
- */
-
-/*
- * clflush on one processor only:
- * clflush should apparently flush the cache line on all processors in an
- * SMP system.
- */
-
-/*
- * kmap atomic:
- * The usage of the slots must be completely encapsulated within a spinlock, and
- * no other functions that may be using the locks for other purposed may be
- * called from within the locked region.
- * Since the slots are per processor, this will guarantee that we are the only
- * user.
- */
-
-/*
- * TODO: Inserting ptes from an interrupt handler:
- * This may be desirable for some SGX functionality where the GPU can fault in
- * needed pages. For that, we need to make an atomic insert_pages function, that
- * may fail.
- * If it fails, the caller need to insert the page using a workqueue function,
- * but on average it should be fast.
- */
-
-struct psb_mmu_driver {
- /* protects driver- and pd structures. Always take in read mode
- * before taking the page table spinlock.
- */
- struct rw_semaphore sem;
-
- /* protects page tables, directory tables and pt tables.
- * and pt structures.
- */
- spinlock_t lock;
-
- atomic_t needs_tlbflush;
-
- uint8_t __iomem *register_map;
- struct psb_mmu_pd *default_pd;
- /*uint32_t bif_ctrl;*/
- int has_clflush;
- int clflush_add;
- unsigned long clflush_mask;
-
- struct drm_psb_private *dev_priv;
-};
-
-struct psb_mmu_pd;
-
-struct psb_mmu_pt {
- struct psb_mmu_pd *pd;
- uint32_t index;
- uint32_t count;
- struct page *p;
- uint32_t *v;
-};
-
-struct psb_mmu_pd {
- struct psb_mmu_driver *driver;
- int hw_context;
- struct psb_mmu_pt **tables;
- struct page *p;
- struct page *dummy_pt;
- struct page *dummy_page;
- uint32_t pd_mask;
- uint32_t invalid_pde;
- uint32_t invalid_pte;
-};
+#include "psb_mmu.h"
static inline uint32_t psb_mmu_pt_index(uint32_t offset)
{
--- /dev/null
+/**************************************************************************
+ * Copyright (c) 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.
+ *
+ **************************************************************************/
+#ifndef __PSB_MMU_H__
+#define __PSB_MMU_H__
+
+#include <drm/drmP.h>
+#include "psb_drv.h"
+#include "psb_reg.h"
+
+/*
+ * Code for the SGX MMU:
+ */
+
+/*
+ * clflush on one processor only:
+ * clflush should apparently flush the cache line on all processors in an
+ * SMP system.
+ */
+
+/*
+ * kmap atomic:
+ * The usage of the slots must be completely encapsulated within a spinlock, and
+ * no other functions that may be using the locks for other purposed may be
+ * called from within the locked region.
+ * Since the slots are per processor, this will guarantee that we are the only
+ * user.
+ */
+
+/*
+ * TODO: Inserting ptes from an interrupt handler:
+ * This may be desirable for some SGX functionality where the GPU can fault in
+ * needed pages. For that, we need to make an atomic insert_pages function, that
+ * may fail.
+ * If it fails, the caller need to insert the page using a workqueue function,
+ * but on average it should be fast.
+ */
+
+struct psb_mmu_driver {
+ /* protects driver- and pd structures. Always take in read mode
+ * before taking the page table spinlock.
+ */
+ struct rw_semaphore sem;
+
+ /* protects page tables, directory tables and pt tables.
+ * and pt structures.
+ */
+ spinlock_t lock;
+
+ atomic_t needs_tlbflush;
+
+ uint8_t __iomem *register_map;
+ struct psb_mmu_pd *default_pd;
+ /*uint32_t bif_ctrl;*/
+ int has_clflush;
+ int clflush_add;
+ unsigned long clflush_mask;
+
+ struct drm_psb_private *dev_priv;
+};
+
+struct psb_mmu_pd;
+
+struct psb_mmu_pt {
+ struct psb_mmu_pd *pd;
+ uint32_t index;
+ uint32_t count;
+ struct page *p;
+ uint32_t *v;
+};
+
+struct psb_mmu_pd {
+ struct psb_mmu_driver *driver;
+ int hw_context;
+ struct psb_mmu_pt **tables;
+ struct page *p;
+ struct page *dummy_pt;
+ struct page *dummy_page;
+ uint32_t pd_mask;
+ uint32_t invalid_pde;
+ uint32_t invalid_pte;
+};
+
+#endif
--- /dev/null
+/****************************************************************************
+ *
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ ******************************************************************************/
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+
+#if defined(LMA)
+#include <linux/pci.h>
+#else
+#include <linux/dma-mapping.h>
+#endif
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include "psb_drv.h"
+#include "ttm/ttm_bo_api.h"
+#include "ttm/ttm_placement.h"
+#include "ttm/ttm_object.h"
+
+#include "psb_video_bind.h"
+#include "pvrmodule.h"
+#include "sys_pvr_drm_export.h"
+#include "psb_pvr_glue.h"
+
+#include "perproc.h"
+
+/*#define PSB_VIDEO_BIND_DEBUG 1 */
+
+static int
+set_unset_ttm_st_gfx_buffer(
+ struct drm_file *file_priv,
+ struct page **pPageList,
+ int handle,
+ int release)
+{
+ struct ttm_object_file *tfile = psb_fpriv(file_priv)->tfile;
+ struct ttm_buffer_object *bo = NULL;
+ struct ttm_tt *ttm = NULL;
+ int i;
+
+ if (!handle) {
+ printk(KERN_ERR " : handle is NULL.\n");
+ return -EINVAL;
+ }
+
+ bo = ttm_buffer_object_lookup(tfile, handle);
+ if (unlikely(bo == NULL)) {
+ printk(KERN_ERR
+ " : Could not find buffer object for setstatus.\n");
+ return -EINVAL;
+ }
+ ttm = bo->ttm;
+
+ for (i = 0; i < ttm->num_pages; i++) {
+ if (release)
+ ttm->pages[i] = NULL;
+ else
+ ttm->pages[i] = pPageList[i];
+ }
+
+ if (bo)
+ ttm_bo_unref(&bo);
+ return 0;
+}
+
+
+static int
+psb_st_drm_tbe_bind(
+ struct psb_mmu_pd *pd,
+ unsigned long address,
+ struct drm_file *file_priv,
+ int hTTMHandle,
+ IMG_HANDLE hKernelMemInfo)
+{
+ int ret = 0;
+ uint32_t num_pages;
+ struct page **pPageList;
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+ IMG_HANDLE hOSMemHandle;
+ IMG_UINT32 uiAllocSize = 0;
+ int eError = 0;
+
+ eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+ (IMG_PVOID *)&psKernelMemInfo,
+ hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError == PVRSRV_OK) {
+ hOSMemHandle = psKernelMemInfo->sMemBlk.hOSMemHandle;
+ uiAllocSize = psKernelMemInfo->ui32AllocSize;
+ } else {
+ printk(KERN_ERR "LookUpKernelHandle (0x%x)- FAILED\n",
+ (unsigned int)hKernelMemInfo);
+ return -EINVAL;
+ }
+
+ ret = psb_get_pages_by_mem_handle(hOSMemHandle, &pPageList);
+ if (ret) {
+ printk(KERN_ERR "%s: get pages error\n", __func__);
+ return ret;
+ }
+
+ num_pages = (uiAllocSize + PAGE_SIZE - 1) / PAGE_SIZE;
+
+#if defined(PSB_VIDEO_BIND_DEBUG)
+{
+ int i;
+
+ printk(KERN_ALERT "%s: hOSMemHandle:0x%x pageList:0x%x num_pages:%d",
+ __func__, hOSMemHandle, pPageList, num_pages);
+ for (i = 0; i < 12; i++) {
+ printk(KERN_ALERT "[%d] addr: 0x%x vir:0x%x pfn:0x%x kmap:0x%x",
+ i, pPageList[i], page_address(pPageList[i]),
+ page_to_pfn(pPageList[i]), kmap(pPageList[i]));
+ kunmap(pPageList);
+ }
+}
+#endif
+
+ PSB_DEBUG_GENERAL("%s:insert in MMU address: 0x08%lx num_pages:0x%x\n",
+ __func__, address, num_pages);
+ ret = psb_mmu_insert_pages(pd, pPageList, address, num_pages, 0, 0, 0);
+ if (ret)
+ printk(KERN_ERR "%s:Insert Pages failed for gralloc buffer\n",
+ __func__);
+ ret = set_unset_ttm_st_gfx_buffer(file_priv, pPageList, hTTMHandle, 0);
+ if (ret)
+ printk(KERN_ERR "ERORR: set_ttm_st_gfx_buffer failed.\n");
+ return ret;
+}
+
+static int
+psb_st_drm_tbe_unbind(
+ struct psb_mmu_pd *pd,
+ unsigned long address,
+ struct drm_file *file_priv,
+ int hTTMHandle,
+ IMG_HANDLE hKernelMemInfo)
+{
+ int ret = 0;
+ uint32_t num_pages;
+ struct page **pPageList;
+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
+ IMG_HANDLE hOSMemHandle;
+ IMG_UINT32 uiAllocSize = 0;
+ int eError = 0;
+
+ eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+ (IMG_PVOID *)&psKernelMemInfo,
+ hKernelMemInfo,
+ PVRSRV_HANDLE_TYPE_MEM_INFO);
+ if (eError == PVRSRV_OK) {
+ hOSMemHandle = psKernelMemInfo->sMemBlk.hOSMemHandle;
+ uiAllocSize = psKernelMemInfo->ui32AllocSize;
+ } else {
+ printk(KERN_ERR "LookUpKernelHandle (0x%x)- FAILED\n",
+ (unsigned int)hKernelMemInfo);
+ return -EINVAL;
+ }
+
+ ret = psb_get_pages_by_mem_handle(hOSMemHandle, &pPageList);
+ if (ret) {
+ printk(KERN_ERR "%s: get pages error\n", __func__);
+ return ret;
+ }
+
+ num_pages = (uiAllocSize + PAGE_SIZE - 1) / PAGE_SIZE;
+
+ if (set_unset_ttm_st_gfx_buffer(file_priv, NULL, hTTMHandle, 1)) {
+ printk(KERN_ERR "%s:Failed to release TTM buffer\n", __func__);
+ return -EFAULT;
+ }
+
+ PSB_DEBUG_GENERAL("%s: remove in MMU address: 0x08%lx num_pages:0x%x\n",
+ __func__, address, num_pages);
+
+ psb_mmu_remove_pages(pd, address, uiAllocSize, 0, 0);
+
+ return ret;
+}
+
+
+int
+psb_st_gfx_video_bridge(struct drm_device *dev, IMG_VOID * arg,
+ struct drm_file *file_priv)
+{
+ int err = 0;
+ struct PSB_Video_ioctl_package *psBridge =
+ (struct PSB_Video_ioctl_package *) arg;
+ int command = psBridge->ioctl_cmd;
+ PVRSRV_BRIDGE_RETURN sRet;
+ struct psb_mmu_pd *pd;
+ struct BC_Video_bind_input_t bridge;
+
+ struct drm_psb_private *dev_priv =
+ (struct drm_psb_private *) dev->dev_private;
+
+ pd = psb_mmu_get_default_pd(dev_priv->mmu);
+
+ switch (command) {
+ case PSB_Video_ioctl_bind_st_gfx_buffer:
+ PSB_DEBUG_GENERAL("[%s]:BC_BIND_GFX - Triggered", __func__);
+ if (copy_from_user
+ (&bridge, (void __user *) (psBridge->inputparam),
+ sizeof(bridge))) {
+ printk(KERN_ERR ":Failed to copy inputparam.\n");
+ err = -EFAULT;
+ goto _exitError;
+ }
+ if (psb_st_drm_tbe_bind(pd,
+ (unsigned long)bridge.pVAddr,
+ file_priv,
+ bridge.hTTMBuffer,
+ bridge.view_ids[0])) {
+ printk(KERN_ERR " ERROR : psb_st_drm_tbe_bind failed\n");
+ err = -EFAULT;
+ goto _exitError;
+ }
+ return 0;
+ case PSB_Video_ioctl_unbind_st_gfx_buffer:
+ PSB_DEBUG_GENERAL("[%s]:BC_UNBIND_GFX - Triggered", __func__);
+ if (copy_from_user
+ (&bridge, (void __user *) (psBridge->inputparam),
+ sizeof(bridge))) {
+ printk(KERN_ERR "Failed to copy inputparam.\n");
+ err = -EFAULT;
+ goto _exitError;
+ }
+ if (psb_st_drm_tbe_unbind(pd, (unsigned long)bridge.pVAddr,
+ file_priv,
+ bridge.hTTMBuffer,
+ bridge.view_ids[0])) {
+ printk(KERN_ERR "ERROR : psb_st_drm_tbe_unbind failed\n");
+ err = -EFAULT;
+ goto _exitError;
+ }
+
+ return 0;
+ default:
+ err = -EFAULT;
+ goto _exitError;
+ break;
+ }
+
+_exitError:
+ sRet.eError = err;
+ return err;
+}
+EXPORT_SYMBOL_GPL(psb_st_gfx_video_bridge);
--- /dev/null
+/*****************************************************************************
+ *
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ ******************************************************************************/
+
+#ifndef __PSB_VIDEO_BIND_H__
+#define __PSB_VIDEO_BIND_H__
+
+#include <linux/ioctl.h>
+
+struct PSB_Video_ioctl_package {
+ int ioctl_cmd;
+ int device_id;
+ int inputparam;
+ int outputparam;
+};
+
+#define PVR_MAX_VIEW_NUM 2
+struct BC_Video_bind_input_t {
+ IMG_UINT32 hTTMBuffer;
+ void *pVAddr;
+ IMG_UINT32 view_n;
+ IMG_HANDLE view_ids[PVR_MAX_VIEW_NUM];
+};
+
+
+#define PSB_Video_ioctl_bind_st_gfx_buffer 0
+#define PSB_Video_ioctl_unbind_st_gfx_buffer 1
+
+#endif
#define TTM_ACCESS_READ (1 << 0)
#define TTM_ACCESS_WRITE (1 << 1)
+/*
+ * TTM_PL_FLAG_VED indicates gralloc buffer allocation is active and
+ * that TTM allocation must be inhibited.
+ */
+#define TTM_PL_FLAG_VED (1 << 22)
+
#endif