From: Naeem M. Afzal Date: Wed, 11 Jan 2012 19:53:50 +0000 (-0800) Subject: MUST_REVERT: drm: psb: Added gralloc buffer support for video X-Git-Tag: 2.1b_release~365 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c9d75bc4b28b261f4663c5733a387959ca204684;p=kernel%2Fkernel-mfld-blackbay.git MUST_REVERT: drm: psb: Added gralloc buffer support for video Gralloc buffers are created and bound to TTM buffers independent of the BCD module. This patch has received many change requests from Pauli and Jani. Jani Nacked it. However, Sean believes the requests are not critical. Pierre said that we have to take this patch because it is urgent, and improve it later. This is why it is marked as MUST_REVERT. Sean is supposed to send the new version which should be taken instead of this one, and this commit message should be removed. Signed-off-by: Naeem M Afzal Signed-off-by: Sean V Kelley --- diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 7739625..90038a0 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -631,9 +631,18 @@ int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem) 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)) diff --git a/drivers/staging/mrst/Makefile b/drivers/staging/mrst/Makefile index 693cf60..5b52d39 100644 --- a/drivers/staging/mrst/Makefile +++ b/drivers/staging/mrst/Makefile @@ -209,9 +209,13 @@ medfield_gfx-y += \ $(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 diff --git a/drivers/staging/mrst/drv/psb_drv.c b/drivers/staging/mrst/drv/psb_drv.c index bbd0268..d76dc18 100644 --- a/drivers/staging/mrst/drv/psb_drv.c +++ b/drivers/staging/mrst/drv/psb_drv.c @@ -272,6 +272,9 @@ MODULE_DEVICE_TABLE(pci, pciidlist); /*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) @@ -317,6 +320,10 @@ MODULE_DEVICE_TABLE(pci, pciidlist); #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); @@ -449,7 +456,9 @@ static struct drm_ioctl_desc psb_ioctls[] = { 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) @@ -1350,6 +1359,17 @@ int psb_extension_ioctl(struct drm_device *dev, void *data, 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; } diff --git a/drivers/staging/mrst/drv/psb_drv.h b/drivers/staging/mrst/drv/psb_drv.h index 0388f85..6d7ae63 100644 --- a/drivers/staging/mrst/drv/psb_drv.h +++ b/drivers/staging/mrst/drv/psb_drv.h @@ -1150,6 +1150,10 @@ int psb_set_brightness(struct backlight_device *bd); 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 */ diff --git a/drivers/staging/mrst/imgv/psb_mmu.c b/drivers/staging/mrst/imgv/psb_mmu.c index 82b7c62..e052700 100644 --- a/drivers/staging/mrst/imgv/psb_mmu.c +++ b/drivers/staging/mrst/imgv/psb_mmu.c @@ -15,83 +15,7 @@ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * **************************************************************************/ -#include -#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) { diff --git a/drivers/staging/mrst/imgv/psb_mmu.h b/drivers/staging/mrst/imgv/psb_mmu.h new file mode 100644 index 0000000..524a85b --- /dev/null +++ b/drivers/staging/mrst/imgv/psb_mmu.h @@ -0,0 +1,98 @@ +/************************************************************************** + * 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 +#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 diff --git a/drivers/staging/mrst/imgv/psb_video_bind.c b/drivers/staging/mrst/imgv/psb_video_bind.c new file mode 100644 index 0000000..abe1f18 --- /dev/null +++ b/drivers/staging/mrst/imgv/psb_video_bind.c @@ -0,0 +1,275 @@ +/**************************************************************************** + * + * 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 +#include +#include +#include +#include +#include +#include + +#if defined(LMA) +#include +#else +#include +#endif + +#include +#include +#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); diff --git a/drivers/staging/mrst/imgv/psb_video_bind.h b/drivers/staging/mrst/imgv/psb_video_bind.h new file mode 100644 index 0000000..6e3cb62 --- /dev/null +++ b/drivers/staging/mrst/imgv/psb_video_bind.h @@ -0,0 +1,50 @@ +/***************************************************************************** + * + * 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 + +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 diff --git a/include/drm/ttm/ttm_placement.h b/include/drm/ttm/ttm_placement.h index 06f7443..15a3ecb 100644 --- a/include/drm/ttm/ttm_placement.h +++ b/include/drm/ttm/ttm_placement.h @@ -93,4 +93,10 @@ #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