summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2014-09-15intel: make drm_intel_gem_bo_get_reloc_count() thread safeLionel Landwerlin
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
2014-09-15intel: make bo_unreference() thread safeLionel Landwerlin
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
2014-09-15intel: make bufmgr_gem shareable from different APILionel Landwerlin
When using Mesa and LibVA in the same process, one would like to be able bind buffers from the output of the decoder to a GL texture through an EGLImage. LibVA can reuse buffers allocated by Gbm through a file descriptor. It will then wrap it into a drm_intel_bo with drm_intel_bo_gem_create_from_prime(). The problem at the moment is that both library get a different drm_intel_bufmgr object when they call drm_intel_bufmgr_gem_init() even though they're using the same drm file descriptor. As a result, instead of manipulating the same buffer object for a given file descriptor, they get 2 different drm_intel_bo objects and 2 different refcounts, leading one of the library to get errors from the kernel on invalid BO when one of the 2 library is done with a shared buffer. This patch modifies drm_intel_bufmgr_gem_init() so, given a file descriptor, it will look for an already existing drm_intel_bufmgr using the same file descriptor and return that object. Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
2014-09-15atomic: add atomic_add_unless()Lionel Landwerlin
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
2014-09-01freedreno: fd_bo_from_handle() remove duplicate declarationEmil Velikov
Already declared in our public header freedreno_drmif.h Cc: Rob Clark <robclark@freedesktop.org> Cc: freedreno@lists.freedesktop.org Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> Acked-by: Rob Clark <robclark@freedesktop.org>
2014-09-01android: add CleanSpec.mkEmil Velikov
The file contains rules that are executed on incremental builds. This way one can avoid doing a full clean and ensure that the new object (library) is correctly build. Let's also cleanup the headers. Inspired by the work of Chih-Wei Huang, from the Android-x86 project. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
2014-09-01freedreno: add Android build supportEmil Velikov
v2 Rename the headers variable(s) to *_H_FILES. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
2014-09-01nouveau: add Android build supportEmil Velikov
v2 Rename the headers variable(s) to *_H_FILES. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
2014-09-01radeon: add Android build supportEmil Velikov
v2 Rename the headers variable(s) to *_H_FILES. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
2014-09-01libdrm,intel: rework android header handlingEmil Velikov
Contains the following patches squashed in: commit 99247a5bd724ddcf0f06a5518baad207c53f1e2b Author: Haitao Huang <haitao.huang@intel.com> Date: Fri, 27 Apr 2012 13:20:53 -0500 Android.mk: use LOCAL_COPY_HEADERS to export headers. Export necessary header files used by other components for Android, such as libva intel-driver, gralloc, hwcomposer, etc. Change-Id: I2feabf6941379ef4d756e942f30eba059de641f1 Signed-off-by: Haitao Huang <haitao.huang@intel.com> [chad: Fixed inconsistent indentation.] Signed-off-by: Chad Versace <chad.versace@linux.intel.com> commit 7d0b528cb69995d7ea4e29b2daa1e3b28a362f42 Author: Emil Velikov <emil.l.velikov@gmail.com> Date: Sun, 27 Jul 2014 18:22:41 +0100 android: reuse headers lists, separate libdrm from intel headers Rather than having a duplicate copy of the headers list(s), reuse the existing one(s). Distinguish that the intel headers should be copied when libdrm_intel is used. v2 Rename the headers variable(s) to *_H_FILES. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com> commit 361de3ba4cadd5357596d1537bb3f216d281532b Author: Piotr Luc <piotr.luc@intel.com> Date: Fri, 14 Jun 2013 13:00:39 +0200 Export include dir from libdrm BZ: 116218 Google introduced new method of specifying include path(s) between modules. This allows a module to include header from a library without directly specifyining by includer the path where headers are located. The method requires from library that holds headers to export include path(s) in LOCAL_EXPORT_C_INCLUDE_DIRS variable. These exported include path(s) are automatically added to include path(s) of modules that have name of the library in the LOCAL_SHARED_LIBRARIES or LOCAL_STATIC_LIBRARIES list. This change sets LOCAL_EXPORT_C_INCLUDE_DIRS to folders that contain headers file that used by other modules in order to export these paths. Change-Id: Id1ac885b31ef2efe194e0289fbcaecd9eb533df0 Signed-off-by: Piotr Luc <piotr.luc@intel.com> Reviewed-on: http://android.intel.com:8080/113562 Reviewed-by: cactus <cactus@intel.com> Reviewed-by: Luc, Piotr <Piotr.Luc@intel.com> Reviewed-by: Purushothaman, Vijay A <vijay.a.purushothaman@intel.com> Reviewed-by: Stimson, Dale B <dale.b.stimson@intel.com> Tested-by: Stimson, Dale B <dale.b.stimson@intel.com> Reviewed-by: buildbot <buildbot@intel.com> Tested-by: buildbot <buildbot@intel.com> commit 2bf22fcbd4cbb9e7c7764d5eff0bb4e75ab1a005 Author: Emil Velikov <emil.l.velikov@gmail.com> Date: 27 Jul 2014 18:27:21 +0100 android: Separate libdrm and intel LOCAL_EXPORT_C_INCLUDE_DIRS Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
2014-09-01libdrm,intel: Add Android buildEmil Velikov
Contains the following patches squashed in: commit f340a8b9f2b84d5762553bef046914e0bde20795 Author: Chad Versace <chad.versace@linux.intel.com> Date: Wed, 21 Dec 2011 11:43:57 -0800 libdrm,intel: Add Android makefiles (v2) This enables libdrm.so and libdrm_intel.so to build on Android IceCreamSandwich. v2: Link libdrm_intel to libpciaccess. Change-Id: Ie5ed4bc0e6b4f9f819e3ec44488e385c35e97128 Signed-off-by: Chad Versace <chad.versace@linux.intel.com> commit 8fb3f42389dea34218ed1fe59550ec2abb4d6953 Author: Andrew Boie <andrew.p.boie@intel.com> Date: Wed, 26 Sep 2012 13:32:05 -0700 libdrm, libdrm_intel: Skip driver name checks These libraries have 'optional' tags, which means they won't get built unless something else depends on them or they are added to PRODUCT_PACKAGES. There's no need for additional filtering. Change-Id: I5d90969f38671f8144c0dc27d47144b3f09a15ce Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2014-09-01libdrm, freedreno, intel, nouveau, radeon: add Makefile.sourcesEmil Velikov
Will be used to consolidate the required sources lists as well as the install-able headers. This is turn will help us to avoid the duplication with the upcoming Android build support. v2: Rename the headers variable to *_H_FILES. v3: Rebase on top of symbol visibility patches. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
2014-09-01libkms: remove explicit define _FILE_OFFSET_BITS 64Emil Velikov
configure.ac has AC_SYS_LARGEFILE which provides the define and/or approapriate magic when required. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
2014-09-01all: include config.h only when available and use its definesEmil Velikov
... rather than explicitly redefining HAVE_STDINT_H and _GNU_SOURCE. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
2014-08-25radeon: Fix surf->bankh init by default value when surf->tile_split == 0Maks Naumov
Signed-off-by: Maks Naumov <maksqwe1@ukr.net> Signed-off-by: Marek Olšák <marek.olsak@amd.com>
2014-08-21radeon: add new SI pci idsAlex Deucher
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2014-08-21radeon: add new CIK pci idsAlex Deucher
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2014-08-14exynos: Use symbol visibility.Maarten Lankhorst
No changes to exported symbols. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
2014-08-14freedreno: Use symbol visibility.Maarten Lankhorst
Hiding fd_device_del_locked, and fd_cleanup_bo_cache. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
2014-08-14omap: Use symbol visibility.Maarten Lankhorst
No changes to exported symbols. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
2014-08-14drm: Implement drmCheckModesettingSupported() for DragonFlyFrançois Tigeot
For the sake of simplicity, KMS support can always be considered present on DragonFly. If some particular version doesn't support KMS yet, appropriate checks are already done in Dports's x11-drivers/ Makefiles and KMS-enabled driver packages don't get built. Signed-off-by: François Tigeot <ftigeot@wolfpond.org> Signed-off-by: Maarten Lankhorst <dev@mblankhorst.nl>
2014-08-04intel: Use symbol visibility.Maarten Lankhorst
No exports changed for this driver. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2014-08-04radeon: Use symbol visibility.Maarten Lankhorst
All the bof_* symbols are now no longer exported. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
2014-08-04nouveau: Only export public functions.Maarten Lankhorst
This hides all the abi16_* functions and the nouveau_debug variable, they should have been private to begin with. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com> Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
2014-07-30configure: Support symbol visibility when availableThierry Reding
Checks whether or not the compiler supports the -fvisibility option. If so it sets the VISIBILITY_CFLAGS variable which can be added to the per directory AM_CFLAGS where appropriate. By default all symbols will be hidden via the VISIBILITY_CFLAGS. The drm_public macro can be used to mark symbols that should be exported. Reviewed-by: Maarten Lankhorst <maarten.lankhorst@canonical.com> Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
2014-07-29configure.ac: bump version to 2.4.56 for releaseMarek Olšák
2014-07-29radeon: fix typo in sample split / fixes MSAA on HawaiiMarek Olšák
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
2014-07-28libdrm: Fix drm.h include in qxl drm header fileAndreas Boll
Use "drm.h" instead of "drm/drm.h" as used in the other header files. Fixes xserver-xorg-video-qxl build with KMS support on Debian, where this file is installed in /usr/include/libdrm. Fixes Debian bug #746807 Reported-by: Bastian Blank <waldi@debian.org> Signed-off-by: Andreas Boll <andreas.boll.dev@gmail.com> Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
2014-07-25bump to version 2.4.55 for releaseMaarten Lankhorst
2014-07-25exynos: do not build fimg2d_test when building without libkms support.Maarten Lankhorst
This prevents a build failure. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
2014-07-16radeon: Add missing header includes.Thomas Klausner
unistd.h for close() and xf86drm.h for drmOpen(). Signed-off-by: Thomas Klausner <wiz@NetBSD.org>
2014-07-16radeon: Remove superfluous parentheses.Thomas Klausner
Signed-off-by: Thomas Klausner <wiz@NetBSD.org>
2014-06-20exynos: fix scaling factor computation in g2d_copy_with_scaleTobias Jakobi
When division of source and destination width yields the scaling factor for the x-coordinate, then it should be source/destination _height_ for y. Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de> Signed-off-by: Inki Dae <inki.dae@samsung.com>
2014-06-20exynos: fix G2D_DOUBLE_TO_FIXED for non-integer inputTobias Jakobi
The hardware accepts scaling factors formatted in a fixed-point format. The current macro casts to integer first, then multiplies by the fp conversion factor. This does not make any sense. In particular, truly 'fractional' inputs, like 1.5, won't work that way. Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de> Signed-off-by: Inki Dae <inki.dae@samsung.com>
2014-06-20exynos: fix coordinate computation in g2d_copyTobias Jakobi
The right-bottom register isn't set correctly. Looks like a copy-and-paste error. Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de> Signed-off-by: Inki Dae <inki.dae@samsung.com>
2014-06-19intel: Add new userptr ioctlTvrtko Ursulin
Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
2014-06-19intel: Sync typo fix from the kernel sources.Damien Lespiau
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
2014-06-19intel: Sync the command parser version parameter from kernelDamien Lespiau
Cc: Bradley Volkin <bradley.d.volkin@intel.com> Reviewed-by: Brad Volkin <bradley.d.volkin@intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
2014-06-18freedreno: add chip-id propertyRob Clark
Userspace needs to know the patch-revision in addition to just the gpu-id (ie. 320, 305, etc). Signed-off-by: Rob Clark <robclark@freedesktop.org>
2014-06-18freedreno: sync kernel headerRob Clark
Signed-off-by: Rob Clark <robclark@freedesktop.org>
2014-05-19drm: Add universal plane capability bit and plane type enumsMatt Roper
Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Rob Clark <robclark@freedesktop.org>
2014-05-13drmOpenByName: remove redundant drmAvailable checkDaniel Kurtz
drmOpenByName() is a static function that is only called by drmOpen(). drmOpen() already checks drmAvailable(), so the check in drmOpenByName() is redundant. Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> Signed-off-by: Thierry Reding <treding@nvidia.com>
2014-05-12exynos: removed unused fd fieldDaniel Kurtz
The documentation says fd holds the fd from prime import/export. However, it isn't actually used, nor is it necessary, so let's just remove it. Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> Acked-by: Inki Dae <inki.dae@samsung.com>
2014-05-12exynos: prime: use drmPrime*() helpersDaniel Kurtz
Reuse the common drmPrime() helper functions rather than reinventing them. Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> Acked-by: Inki Dae <inki.dae@samsung.com>
2014-05-12exynos_fimg2d_test: fix drmModeRmFBDaniel Kurtz
The first parameter should be the drm fd, second param is the fb id. Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> Acked-by: Inki Dae <inki.dae@samsung.com>
2014-05-12exynos: remove unusable "run" targetDaniel Kurtz
This looks like it was copied from kmstest, but isn't needed, and doesn't actually work since exynos_fimg2d_test requires parameters. Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> Acked-by: Inki Dae <inki.dae@samsung.com>
2014-05-12exynos_fimg2d: fix cast from pointer to integer of different sizeDaniel Kurtz
Fixes two gcc [-Wpointer-to-int-cast] warnings. Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> Acked-by: Inki Dae <inki.dae@samsung.com>
2014-05-12exynos: fix two warningsDaniel Kurtz
warning: assignment makes pointer from integer without a cast [enabled by default] warning: initialization makes integer from pointer without a cast [enabled by default] Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> Acked-by: Inki Dae <inki.dae@samsung.com>
2014-05-12eyxnos: install exynos tests if HAVE_INSTALL_TESTSDaniel Kurtz
This exynos test was added just before HAVE_INSTALL_TESTS, and so didn't get this annotation. Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> Acked-by: Inki Dae <inki.dae@samsung.com>
2014-05-02bump version to 2.4.54 for releaseAlex Deucher
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
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 COPYRIGHT OWNER(S) 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. * * Authors: * Gareth Hughes <gareth@valinux.com> * Leif Delgass <ldelgass@retinalburn.net> * Jos�Fonseca <j_r_fonseca@yahoo.co.uk> */ #include "drmP.h" #include "drm.h" #include "mach64_drm.h" #include "mach64_drv.h" /* Interface history: * * 1.0 - Initial mach64 DRM * */ drm_ioctl_desc_t mach64_ioctls[] = { [DRM_IOCTL_NR(DRM_MACH64_INIT)] = {mach64_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, [DRM_IOCTL_NR(DRM_MACH64_CLEAR)] = {mach64_dma_clear, DRM_AUTH}, [DRM_IOCTL_NR(DRM_MACH64_SWAP)] = {mach64_dma_swap, DRM_AUTH}, [DRM_IOCTL_NR(DRM_MACH64_IDLE)] = {mach64_dma_idle, DRM_AUTH}, [DRM_IOCTL_NR(DRM_MACH64_RESET)] = {mach64_engine_reset, DRM_AUTH}, [DRM_IOCTL_NR(DRM_MACH64_VERTEX)] = {mach64_dma_vertex, DRM_AUTH}, [DRM_IOCTL_NR(DRM_MACH64_BLIT)] = {mach64_dma_blit, DRM_AUTH}, [DRM_IOCTL_NR(DRM_MACH64_FLUSH)] = {mach64_dma_flush, DRM_AUTH}, [DRM_IOCTL_NR(DRM_MACH64_GETPARAM)] = {mach64_get_param, DRM_AUTH}, }; int mach64_max_ioctl = DRM_ARRAY_SIZE(mach64_ioctls); /* ================================================================ * DMA hardware state programming functions */ static void mach64_print_dirty(const char *msg, unsigned int flags) { DRM_DEBUG("%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s\n", msg, flags, (flags & MACH64_UPLOAD_DST_OFF_PITCH) ? "dst_off_pitch, " : "", (flags & MACH64_UPLOAD_Z_ALPHA_CNTL) ? "z_alpha_cntl, " : "", (flags & MACH64_UPLOAD_SCALE_3D_CNTL) ? "scale_3d_cntl, " : "", (flags & MACH64_UPLOAD_DP_FOG_CLR) ? "dp_fog_clr, " : "", (flags & MACH64_UPLOAD_DP_WRITE_MASK) ? "dp_write_mask, " : "", (flags & MACH64_UPLOAD_DP_PIX_WIDTH) ? "dp_pix_width, " : "", (flags & MACH64_UPLOAD_SETUP_CNTL) ? "setup_cntl, " : "", (flags & MACH64_UPLOAD_MISC) ? "misc, " : "", (flags & MACH64_UPLOAD_TEXTURE) ? "texture, " : "", (flags & MACH64_UPLOAD_TEX0IMAGE) ? "tex0 image, " : "", (flags & MACH64_UPLOAD_TEX1IMAGE) ? "tex1 image, " : "", (flags & MACH64_UPLOAD_CLIPRECTS) ? "cliprects, " : ""); } /* Mach64 doesn't have hardware cliprects, just one hardware scissor, * so the GL scissor is intersected with each cliprect here */ /* This function returns 0 on success, 1 for no intersection, and * negative for an error */ static int mach64_emit_cliprect(DRMFILE filp, drm_mach64_private_t * dev_priv, drm_clip_rect_t * box) { u32 sc_left_right, sc_top_bottom; drm_clip_rect_t scissor; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mach64_context_regs_t *regs = &sarea_priv->context_state; DMALOCALS; DRM_DEBUG("%s: box=%p\n", __FUNCTION__, box); /* Get GL scissor */ /* FIXME: store scissor in SAREA as a cliprect instead of in * hardware format, or do intersection client-side */ scissor.x1 = regs->sc_left_right & 0xffff; scissor.x2 = (regs->sc_left_right & 0xffff0000) >> 16; scissor.y1 = regs->sc_top_bottom & 0xffff; scissor.y2 = (regs->sc_top_bottom & 0xffff0000) >> 16; /* Intersect GL scissor with cliprect */ if (box->x1 > scissor.x1) scissor.x1 = box->x1; if (box->y1 > scissor.y1) scissor.y1 = box->y1; if (box->x2 < scissor.x2) scissor.x2 = box->x2; if (box->y2 < scissor.y2) scissor.y2 = box->y2; /* positive return means skip */ if (scissor.x1 >= scissor.x2) return 1; if (scissor.y1 >= scissor.y2) return 1; DMAGETPTR(filp, dev_priv, 2); /* returns on failure to get buffer */ sc_left_right = ((scissor.x1 << 0) | (scissor.x2 << 16)); sc_top_bottom = ((scissor.y1 << 0) | (scissor.y2 << 16)); DMAOUTREG(MACH64_SC_LEFT_RIGHT, sc_left_right); DMAOUTREG(MACH64_SC_TOP_BOTTOM, sc_top_bottom); DMAADVANCE(dev_priv, 1); return 0; } static __inline__ int mach64_emit_state(DRMFILE filp, drm_mach64_private_t * dev_priv) { drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mach64_context_regs_t *regs = &sarea_priv->context_state; unsigned int dirty = sarea_priv->dirty; u32 offset = ((regs->tex_size_pitch & 0xf0) >> 2); DMALOCALS; if (MACH64_VERBOSE) { mach64_print_dirty(__FUNCTION__, dirty); } else { DRM_DEBUG("%s: dirty=0x%08x\n", __FUNCTION__, dirty); } DMAGETPTR(filp, dev_priv, 17); /* returns on failure to get buffer */ if (dirty & MACH64_UPLOAD_MISC) { DMAOUTREG(MACH64_DP_MIX, regs->dp_mix); DMAOUTREG(MACH64_DP_SRC, regs->dp_src); DMAOUTREG(MACH64_CLR_CMP_CNTL, regs->clr_cmp_cntl); DMAOUTREG(MACH64_GUI_TRAJ_CNTL, regs->gui_traj_cntl); sarea_priv->dirty &= ~MACH64_UPLOAD_MISC; } if (dirty & MACH64_UPLOAD_DST_OFF_PITCH) { DMAOUTREG(MACH64_DST_OFF_PITCH, regs->dst_off_pitch); sarea_priv->dirty &= ~MACH64_UPLOAD_DST_OFF_PITCH; } if (dirty & MACH64_UPLOAD_Z_OFF_PITCH) { DMAOUTREG(MACH64_Z_OFF_PITCH, regs->z_off_pitch); sarea_priv->dirty &= ~MACH64_UPLOAD_Z_OFF_PITCH; } if (dirty & MACH64_UPLOAD_Z_ALPHA_CNTL) { DMAOUTREG(MACH64_Z_CNTL, regs->z_cntl); DMAOUTREG(MACH64_ALPHA_TST_CNTL, regs->alpha_tst_cntl); sarea_priv->dirty &= ~MACH64_UPLOAD_Z_ALPHA_CNTL; } if (dirty & MACH64_UPLOAD_SCALE_3D_CNTL) { DMAOUTREG(MACH64_SCALE_3D_CNTL, regs->scale_3d_cntl); sarea_priv->dirty &= ~MACH64_UPLOAD_SCALE_3D_CNTL; } if (dirty & MACH64_UPLOAD_DP_FOG_CLR) { DMAOUTREG(MACH64_DP_FOG_CLR, regs->dp_fog_clr); sarea_priv->dirty &= ~MACH64_UPLOAD_DP_FOG_CLR; } if (dirty & MACH64_UPLOAD_DP_WRITE_MASK) { DMAOUTREG(MACH64_DP_WRITE_MASK, regs->dp_write_mask); sarea_priv->dirty &= ~MACH64_UPLOAD_DP_WRITE_MASK; } if (dirty & MACH64_UPLOAD_DP_PIX_WIDTH) { DMAOUTREG(MACH64_DP_PIX_WIDTH, regs->dp_pix_width); sarea_priv->dirty &= ~MACH64_UPLOAD_DP_PIX_WIDTH; } if (dirty & MACH64_UPLOAD_SETUP_CNTL) { DMAOUTREG(MACH64_SETUP_CNTL, regs->setup_cntl); sarea_priv->dirty &= ~MACH64_UPLOAD_SETUP_CNTL; } if (dirty & MACH64_UPLOAD_TEXTURE) { DMAOUTREG(MACH64_TEX_SIZE_PITCH, regs->tex_size_pitch); DMAOUTREG(MACH64_TEX_CNTL, regs->tex_cntl); DMAOUTREG(MACH64_SECONDARY_TEX_OFF, regs->secondary_tex_off); DMAOUTREG(MACH64_TEX_0_OFF + offset, regs->tex_offset); sarea_priv->dirty &= ~MACH64_UPLOAD_TEXTURE; } DMAADVANCE(dev_priv, 1); sarea_priv->dirty &= MACH64_UPLOAD_CLIPRECTS; return 0; } /* ================================================================ * DMA command dispatch functions */ static int mach64_dma_dispatch_clear(DRMFILE filp, drm_device_t * dev, unsigned int flags, int cx, int cy, int cw, int ch, unsigned int clear_color, unsigned int clear_depth) { drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mach64_context_regs_t *ctx = &sarea_priv->context_state; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; u32 fb_bpp, depth_bpp; int i; DMALOCALS; DRM_DEBUG("%s\n", __FUNCTION__); switch (dev_priv->fb_bpp) { case 16: fb_bpp = MACH64_DATATYPE_RGB565; break; case 32: fb_bpp = MACH64_DATATYPE_ARGB8888; break; default: return DRM_ERR(EINVAL); } switch (dev_priv->depth_bpp) { case 16: depth_bpp = MACH64_DATATYPE_RGB565; break; case 24: case 32: depth_bpp = MACH64_DATATYPE_ARGB8888; break; default: return DRM_ERR(EINVAL); } if (!nbox) return 0; DMAGETPTR(filp, dev_priv, nbox * 31); /* returns on failure to get buffer */ for (i = 0; i < nbox; i++) { int x = pbox[i].x1; int y = pbox[i].y1; int w = pbox[i].x2 - x; int h = pbox[i].y2 - y; DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n", pbox[i].x1, pbox[i].y1, pbox[i].x2, pbox[i].y2, flags); if (flags & (MACH64_FRONT | MACH64_BACK)) { /* Setup for color buffer clears */ DMAOUTREG(MACH64_Z_CNTL, 0); DMAOUTREG(MACH64_SCALE_3D_CNTL, 0); DMAOUTREG(MACH64_SC_LEFT_RIGHT, ctx->sc_left_right); DMAOUTREG(MACH64_SC_TOP_BOTTOM, ctx->sc_top_bottom); DMAOUTREG(MACH64_CLR_CMP_CNTL, 0); DMAOUTREG(MACH64_GUI_TRAJ_CNTL, (MACH64_DST_X_LEFT_TO_RIGHT | MACH64_DST_Y_TOP_TO_BOTTOM)); DMAOUTREG(MACH64_DP_PIX_WIDTH, ((fb_bpp << 0) | (fb_bpp << 4) | (fb_bpp << 8) | (fb_bpp << 16) | (fb_bpp << 28))); DMAOUTREG(MACH64_DP_FRGD_CLR, clear_color); DMAOUTREG(MACH64_DP_WRITE_MASK, ctx->dp_write_mask); DMAOUTREG(MACH64_DP_MIX, (MACH64_BKGD_MIX_D | MACH64_FRGD_MIX_S)); DMAOUTREG(MACH64_DP_SRC, (MACH64_BKGD_SRC_FRGD_CLR | MACH64_FRGD_SRC_FRGD_CLR | MACH64_MONO_SRC_ONE)); } if (flags & MACH64_FRONT) { DMAOUTREG(MACH64_DST_OFF_PITCH, dev_priv->front_offset_pitch); DMAOUTREG(MACH64_DST_X_Y, (y << 16) | x); DMAOUTREG(MACH64_DST_WIDTH_HEIGHT, (h << 16) | w); } if (flags & MACH64_BACK) { DMAOUTREG(MACH64_DST_OFF_PITCH, dev_priv->back_offset_pitch); DMAOUTREG(MACH64_DST_X_Y, (y << 16) | x); DMAOUTREG(MACH64_DST_WIDTH_HEIGHT, (h << 16) | w); } if (flags & MACH64_DEPTH) { /* Setup for depth buffer clear */ DMAOUTREG(MACH64_Z_CNTL, 0); DMAOUTREG(MACH64_SCALE_3D_CNTL, 0); DMAOUTREG(MACH64_SC_LEFT_RIGHT, ctx->sc_left_right); DMAOUTREG(MACH64_SC_TOP_BOTTOM, ctx->sc_top_bottom); DMAOUTREG(MACH64_CLR_CMP_CNTL, 0); DMAOUTREG(MACH64_GUI_TRAJ_CNTL, (MACH64_DST_X_LEFT_TO_RIGHT | MACH64_DST_Y_TOP_TO_BOTTOM)); DMAOUTREG(MACH64_DP_PIX_WIDTH, ((depth_bpp << 0) | (depth_bpp << 4) | (depth_bpp << 8) | (depth_bpp << 16) | (depth_bpp << 28))); DMAOUTREG(MACH64_DP_FRGD_CLR, clear_depth); DMAOUTREG(MACH64_DP_WRITE_MASK, 0xffffffff); DMAOUTREG(MACH64_DP_MIX, (MACH64_BKGD_MIX_D | MACH64_FRGD_MIX_S)); DMAOUTREG(MACH64_DP_SRC, (MACH64_BKGD_SRC_FRGD_CLR | MACH64_FRGD_SRC_FRGD_CLR | MACH64_MONO_SRC_ONE)); DMAOUTREG(MACH64_DST_OFF_PITCH, dev_priv->depth_offset_pitch); DMAOUTREG(MACH64_DST_X_Y, (y << 16) | x); DMAOUTREG(MACH64_DST_WIDTH_HEIGHT, (h << 16) | w); } } DMAADVANCE(dev_priv, 1); return 0; } static int mach64_dma_dispatch_swap(DRMFILE filp, drm_device_t * dev) { drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; drm_clip_rect_t *pbox = sarea_priv->boxes; u32 fb_bpp; int i; DMALOCALS; DRM_DEBUG("%s\n", __FUNCTION__); switch (dev_priv->fb_bpp) { case 16: fb_bpp = MACH64_DATATYPE_RGB565; break; case 32: default: fb_bpp = MACH64_DATATYPE_ARGB8888; break; } if (!nbox) return 0; DMAGETPTR(filp, dev_priv, 13 + nbox * 4); /* returns on failure to get buffer */ DMAOUTREG(MACH64_Z_CNTL, 0); DMAOUTREG(MACH64_SCALE_3D_CNTL, 0); DMAOUTREG(MACH64_SC_LEFT_RIGHT, 0 | (8191 << 16)); /* no scissor */ DMAOUTREG(MACH64_SC_TOP_BOTTOM, 0 | (16383 << 16)); DMAOUTREG(MACH64_CLR_CMP_CNTL, 0); DMAOUTREG(MACH64_GUI_TRAJ_CNTL, (MACH64_DST_X_LEFT_TO_RIGHT | MACH64_DST_Y_TOP_TO_BOTTOM)); DMAOUTREG(MACH64_DP_PIX_WIDTH, ((fb_bpp << 0) | (fb_bpp << 4) | (fb_bpp << 8) | (fb_bpp << 16) | (fb_bpp << 28))); DMAOUTREG(MACH64_DP_WRITE_MASK, 0xffffffff); DMAOUTREG(MACH64_DP_MIX, (MACH64_BKGD_MIX_D | MACH64_FRGD_MIX_S)); DMAOUTREG(MACH64_DP_SRC, (MACH64_BKGD_SRC_BKGD_CLR | MACH64_FRGD_SRC_BLIT | MACH64_MONO_SRC_ONE)); DMAOUTREG(MACH64_SRC_OFF_PITCH, dev_priv->back_offset_pitch); DMAOUTREG(MACH64_DST_OFF_PITCH, dev_priv->front_offset_pitch); for (i = 0; i < nbox; i++) { int x = pbox[i].x1; int y = pbox[i].y1; int w = pbox[i].x2 - x; int h = pbox[i].y2 - y; DRM_DEBUG("dispatch swap %d,%d-%d,%d\n", pbox[i].x1, pbox[i].y1, pbox[i].x2, pbox[i].y2); DMAOUTREG(MACH64_SRC_WIDTH1, w); DMAOUTREG(MACH64_SRC_Y_X, (x << 16) | y); DMAOUTREG(MACH64_DST_Y_X, (x << 16) | y); DMAOUTREG(MACH64_DST_WIDTH_HEIGHT, (h << 16) | w); } DMAADVANCE(dev_priv, 1); if (dev_priv->driver_mode == MACH64_MODE_DMA_ASYNC) { for (i = 0; i < MACH64_MAX_QUEUED_FRAMES - 1; i++) { dev_priv->frame_ofs[i] = dev_priv->frame_ofs[i + 1]; } dev_priv->frame_ofs[i] = GETRINGOFFSET(); dev_priv->sarea_priv->frames_queued++; } return 0; } static int mach64_do_get_frames_queued(drm_mach64_private_t * dev_priv) { drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; int i, start; u32 head, tail, ofs; DRM_DEBUG("%s\n", __FUNCTION__); if (sarea_priv->frames_queued == 0) return 0; tail = ring->tail; mach64_ring_tick(dev_priv, ring); head = ring->head; start = (MACH64_MAX_QUEUED_FRAMES - DRM_MIN(MACH64_MAX_QUEUED_FRAMES, sarea_priv->frames_queued)); if (head == tail) { sarea_priv->frames_queued = 0; for (i = start; i < MACH64_MAX_QUEUED_FRAMES; i++) { dev_priv->frame_ofs[i] = ~0; } return 0; } for (i = start; i < MACH64_MAX_QUEUED_FRAMES; i++) { ofs = dev_priv->frame_ofs[i]; DRM_DEBUG("frame_ofs[%d] ofs: %d\n", i, ofs); if (ofs == ~0 || (head < tail && (ofs < head || ofs >= tail)) || (head > tail && (ofs < head && ofs >= tail))) { sarea_priv->frames_queued = (MACH64_MAX_QUEUED_FRAMES - 1) - i; dev_priv->frame_ofs[i] = ~0; } } return sarea_priv->frames_queued; } /* Copy and verify a client submited buffer. * FIXME: Make an assembly optimized version */ static __inline__ int copy_from_user_vertex(u32 *to, const u32 __user *ufrom, unsigned long bytes) { unsigned long n = bytes; /* dwords remaining in buffer */ u32 *from, *orig_from; from = drm_alloc(bytes, DRM_MEM_DRIVER); if (from == NULL) return DRM_ERR(ENOMEM); if (DRM_COPY_FROM_USER(from, ufrom, bytes)) { drm_free(from, bytes, DRM_MEM_DRIVER); return DRM_ERR(EFAULT); } orig_from = from; /* we'll be modifying the "from" ptr, so save it */ n >>= 2; while (n > 1) { u32 data, reg, count; data = *from++; n--; reg = le32_to_cpu(data); count = (reg >> 16) + 1; if (count <= n) { n -= count; reg &= 0xffff; /* This is an exact match of Mach64's Setup Engine registers, * excluding SETUP_CNTL (1_C1). */ if ((reg >= 0x0190 && reg < 0x01c1) || (reg >= 0x01ca && reg <= 0x01cf)) { *to++ = data; memcpy(to, from, count << 2); from += count; to += count; } else { DRM_ERROR("%s: Got bad command: 0x%04x\n", __FUNCTION__, reg); drm_free(orig_from, bytes, DRM_MEM_DRIVER); return DRM_ERR(EACCES); } } else { DRM_ERROR ("%s: Got bad command count(=%u) dwords remaining=%lu\n", __FUNCTION__, count, n); drm_free(orig_from, bytes, DRM_MEM_DRIVER); return DRM_ERR(EINVAL); } } drm_free(orig_from, bytes, DRM_MEM_DRIVER); if (n == 0) return 0; else { DRM_ERROR("%s: Bad buf->used(=%lu)\n", __FUNCTION__, bytes); return DRM_ERR(EINVAL); } } static int mach64_dma_dispatch_vertex(DRMFILE filp, drm_device_t * dev, drm_mach64_vertex_t * vertex) { drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_buf_t *copy_buf; void *buf = vertex->buf; unsigned long used = vertex->used; int ret = 0; int i = 0; int done = 0; int verify_ret = 0; DMALOCALS; DRM_DEBUG("%s: buf=%p used=%lu nbox=%d\n", __FUNCTION__, buf, used, sarea_priv->nbox); if (!used) goto _vertex_done; copy_buf = mach64_freelist_get(dev_priv); if (copy_buf == NULL) { DRM_ERROR("%s: couldn't get buffer\n", __FUNCTION__); return DRM_ERR(EAGAIN); } verify_ret = copy_from_user_vertex(GETBUFPTR(copy_buf), buf, used); if (verify_ret != 0) { mach64_freelist_put(dev_priv, copy_buf); goto _vertex_done; } copy_buf->used = used; DMASETPTR(copy_buf); if (sarea_priv->dirty & ~MACH64_UPLOAD_CLIPRECTS) { ret = mach64_emit_state(filp, dev_priv); if (ret < 0) return ret; } do { /* Emit the next cliprect */ if (i < sarea_priv->nbox) { ret = mach64_emit_cliprect(filp, dev_priv, &sarea_priv->boxes[i]); if (ret < 0) { /* failed to get buffer */ return ret; } else if (ret != 0) { /* null intersection with scissor */ continue; } } if ((i >= sarea_priv->nbox - 1)) done = 1; /* Add the buffer to the DMA queue */ DMAADVANCE(dev_priv, done); } while (++i < sarea_priv->nbox); if (!done) { if (copy_buf->pending) { DMADISCARDBUF(); } else { /* This buffer wasn't used (no cliprects), so place it * back on the free list */ mach64_freelist_put(dev_priv, copy_buf); } } _vertex_done: sarea_priv->dirty &= ~MACH64_UPLOAD_CLIPRECTS; sarea_priv->nbox = 0; return verify_ret; } static __inline__ int copy_from_user_blit(u32 *to, const u32 __user *ufrom, unsigned long bytes) { to = (u32 *)((char *)to + MACH64_HOSTDATA_BLIT_OFFSET); if (DRM_COPY_FROM_USER(to, ufrom, bytes)) { return DRM_ERR(EFAULT); } return 0; } static int mach64_dma_dispatch_blit(DRMFILE filp, drm_device_t * dev, drm_mach64_blit_t * blit) { drm_mach64_private_t *dev_priv = dev->dev_private; int dword_shift, dwords; unsigned long used; drm_buf_t *copy_buf; int verify_ret = 0; DMALOCALS; /* The compiler won't optimize away a division by a variable, * even if the only legal values are powers of two. Thus, we'll * use a shift instead. */ switch (blit->format) { case MACH64_DATATYPE_ARGB8888: dword_shift = 0; break; case MACH64_DATATYPE_ARGB1555: case MACH64_DATATYPE_RGB565: case MACH64_DATATYPE_VYUY422: case MACH64_DATATYPE_YVYU422: case MACH64_DATATYPE_ARGB4444: dword_shift = 1; break; case MACH64_DATATYPE_CI8: case MACH64_DATATYPE_RGB8: dword_shift = 2; break; default: DRM_ERROR("invalid blit format %d\n", blit->format); return DRM_ERR(EINVAL); } /* Set buf->used to the bytes of blit data based on the blit dimensions * and verify the size. When the setup is emitted to the buffer with * the DMA* macros below, buf->used is incremented to include the bytes * used for setup as well as the blit data. */ dwords = (blit->width * blit->height) >> dword_shift; used = dwords << 2; if (used <= 0 || used > MACH64_BUFFER_SIZE - MACH64_HOSTDATA_BLIT_OFFSET) { DRM_ERROR("Invalid blit size: %lu bytes\n", used); return DRM_ERR(EINVAL); } copy_buf = mach64_freelist_get(dev_priv); if (copy_buf == NULL) { DRM_ERROR("%s: couldn't get buffer\n", __FUNCTION__); return DRM_ERR(EAGAIN); } verify_ret = copy_from_user_blit(GETBUFPTR(copy_buf), blit->buf, used); if (verify_ret != 0) { mach64_freelist_put(dev_priv, copy_buf); goto _blit_done; } copy_buf->used = used; /* FIXME: Use a last buffer flag and reduce the state emitted for subsequent, * continuation buffers? */ /* Blit via BM_HOSTDATA (gui-master) - like HOST_DATA[0-15], but doesn't require * a register command every 16 dwords. State setup is added at the start of the * buffer -- the client leaves space for this based on MACH64_HOSTDATA_BLIT_OFFSET */ DMASETPTR(copy_buf); DMAOUTREG(MACH64_Z_CNTL, 0); DMAOUTREG(MACH64_SCALE_3D_CNTL, 0); DMAOUTREG(MACH64_SC_LEFT_RIGHT, 0 | (8191 << 16)); /* no scissor */ DMAOUTREG(MACH64_SC_TOP_BOTTOM, 0 | (16383 << 16)); DMAOUTREG(MACH64_CLR_CMP_CNTL, 0); /* disable */ DMAOUTREG(MACH64_GUI_TRAJ_CNTL, MACH64_DST_X_LEFT_TO_RIGHT | MACH64_DST_Y_TOP_TO_BOTTOM); DMAOUTREG(MACH64_DP_PIX_WIDTH, (blit->format << 0) /* dst pix width */ |(blit->format << 4) /* composite pix width */ |(blit->format << 8) /* src pix width */ |(blit->format << 16) /* host data pix width */ |(blit->format << 28) /* scaler/3D pix width */ ); DMAOUTREG(MACH64_DP_WRITE_MASK, 0xffffffff); /* enable all planes */ DMAOUTREG(MACH64_DP_MIX, MACH64_BKGD_MIX_D | MACH64_FRGD_MIX_S); DMAOUTREG(MACH64_DP_SRC, MACH64_BKGD_SRC_BKGD_CLR | MACH64_FRGD_SRC_HOST | MACH64_MONO_SRC_ONE); DMAOUTREG(MACH64_DST_OFF_PITCH,