From patchwork Tue Jul 16 19:33:53 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrik Jakobsson X-Patchwork-Id: 2828291 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2E361C0AB2 for ; Tue, 16 Jul 2013 19:55:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 09BA520233 for ; Tue, 16 Jul 2013 19:55:32 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id D918420150 for ; Tue, 16 Jul 2013 19:55:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A34C2E6D78 for ; Tue, 16 Jul 2013 12:55:30 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lb0-f172.google.com (mail-lb0-f172.google.com [209.85.217.172]) by gabe.freedesktop.org (Postfix) with ESMTP id 6DBD1E661D for ; Tue, 16 Jul 2013 12:34:28 -0700 (PDT) Received: by mail-lb0-f172.google.com with SMTP id v20so932913lbc.31 for ; Tue, 16 Jul 2013 12:34:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:subject:date:message-id:x-mailer; bh=+w9uoT5ypEPMmiLWvmExmGRduXRVCuANFy2tSNO6EiQ=; b=O7xTQOhE2Oq79EJpEMJXMu5Ev0O6qr7Y/UisQxhuLTGpi/ZjgYRAEBu9fYE5xObFLT vgveDG8WBKCS7+Qqr1mLO7JK8IQ9sKWnh3rcKYpq35zVpRJJwTd4Kz7x/2G2aoeJ/Kpi C9BAsAVUdKG4sNmcWA1lIOSh7Ubv5UhyA8FfAHlgwfCAe07zLB5u6BCWGljYKLFDAd0h tfmiNyhPq5DpHQ9laRu2mGnBz4wFkMh1ljnBl04gNNTt5KcJlQZSPiWszUoFvzl+aG/4 CN0ZyfPEvyFZucuNQuMOdc9ME1Rdej54hmG/CTDPzGjYE4JiXRgn5mwugwG3WgCROJi3 W+rw== X-Received: by 10.112.58.135 with SMTP id r7mr1750272lbq.89.1374003267444; Tue, 16 Jul 2013 12:34:27 -0700 (PDT) Received: from patrik-cedarview.lan (h138n8-oer-a32.ias.bredband.telia.com. [2.248.103.138]) by mx.google.com with ESMTPSA id 8sm1581822lbq.4.2013.07.16.12.34.26 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 16 Jul 2013 12:34:27 -0700 (PDT) From: Patrik Jakobsson To: dri-devel@lists.freedesktop.org Subject: [PATCH 20/30] drm/gma500: Add generic cursor functions Date: Tue, 16 Jul 2013 21:33:53 +0200 Message-Id: <1374003243-15888-21-git-send-email-patrik.r.jakobsson@gmail.com> X-Mailer: git-send-email 1.8.1.2 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org X-Spam-Status: No, score=-4.5 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Patrik Jakobsson --- drivers/gpu/drm/gma500/gma_display.c | 151 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/gma500/gma_display.h | 5 ++ 2 files changed, 156 insertions(+) diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c index 7a0888a..40894c2 100644 --- a/drivers/gpu/drm/gma500/gma_display.c +++ b/drivers/gpu/drm/gma500/gma_display.c @@ -327,6 +327,157 @@ void gma_crtc_dpms(struct drm_crtc *crtc, int mode) REG_WRITE(DSPARB, 0x3F3E); } +int gma_crtc_cursor_set(struct drm_crtc *crtc, + struct drm_file *file_priv, + uint32_t handle, + uint32_t width, uint32_t height) +{ + struct drm_device *dev = crtc->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; + uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; + uint32_t temp; + size_t addr = 0; + struct gtt_range *gt; + struct gtt_range *cursor_gt = psb_intel_crtc->cursor_gt; + struct drm_gem_object *obj; + void *tmp_dst, *tmp_src; + int ret = 0, i, cursor_pages; + + /* If we didn't get a handle then turn the cursor off */ + if (!handle) { + temp = CURSOR_MODE_DISABLE; + + if (gma_power_begin(dev, false)) { + REG_WRITE(control, temp); + REG_WRITE(base, 0); + gma_power_end(dev); + } + + /* Unpin the old GEM object */ + if (psb_intel_crtc->cursor_obj) { + gt = container_of(psb_intel_crtc->cursor_obj, + struct gtt_range, gem); + psb_gtt_unpin(gt); + drm_gem_object_unreference(psb_intel_crtc->cursor_obj); + psb_intel_crtc->cursor_obj = NULL; + } + + return 0; + } + + /* Currently we only support 64x64 cursors */ + if (width != 64 || height != 64) { + dev_dbg(dev->dev, "We currently only support 64x64 cursors\n"); + return -EINVAL; + } + + obj = drm_gem_object_lookup(dev, file_priv, handle); + if (!obj) + return -ENOENT; + + if (obj->size < width * height * 4) { + dev_dbg(dev->dev, "Buffer is too small\n"); + ret = -ENOMEM; + goto unref_cursor; + } + + gt = container_of(obj, struct gtt_range, gem); + + /* Pin the memory into the GTT */ + ret = psb_gtt_pin(gt); + if (ret) { + dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle); + goto unref_cursor; + } + + if (dev_priv->ops->cursor_needs_phys) { + if (cursor_gt == NULL) { + dev_err(dev->dev, "No hardware cursor mem available"); + ret = -ENOMEM; + goto unref_cursor; + } + + /* Prevent overflow */ + if (gt->npage > 4) + cursor_pages = 4; + else + cursor_pages = gt->npage; + + /* Copy the cursor to cursor mem */ + tmp_dst = dev_priv->vram_addr + cursor_gt->offset; + for (i = 0; i < cursor_pages; i++) { + tmp_src = kmap(gt->pages[i]); + memcpy(tmp_dst, tmp_src, PAGE_SIZE); + kunmap(gt->pages[i]); + tmp_dst += PAGE_SIZE; + } + + addr = psb_intel_crtc->cursor_addr; + } else { + addr = gt->offset; + psb_intel_crtc->cursor_addr = addr; + } + + temp = 0; + /* set the pipe for the cursor */ + temp |= (pipe << 28); + temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + + if (gma_power_begin(dev, false)) { + REG_WRITE(control, temp); + REG_WRITE(base, addr); + gma_power_end(dev); + } + + /* unpin the old bo */ + if (psb_intel_crtc->cursor_obj) { + gt = container_of(psb_intel_crtc->cursor_obj, + struct gtt_range, gem); + psb_gtt_unpin(gt); + drm_gem_object_unreference(psb_intel_crtc->cursor_obj); + } + + psb_intel_crtc->cursor_obj = obj; + return ret; + +unref_cursor: + drm_gem_object_unreference(obj); + return ret; +} + +int gma_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) +{ + struct drm_device *dev = crtc->dev; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + uint32_t temp = 0; + uint32_t addr; + + if (x < 0) { + temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT); + x = -x; + } + if (y < 0) { + temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT); + y = -y; + } + + temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT); + temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); + + addr = psb_intel_crtc->cursor_addr; + + if (gma_power_begin(dev, false)) { + REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp); + REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, addr); + gma_power_end(dev); + } + return 0; +} + bool gma_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) diff --git a/drivers/gpu/drm/gma500/gma_display.h b/drivers/gpu/drm/gma500/gma_display.h index 665164d..0d3b607 100644 --- a/drivers/gpu/drm/gma500/gma_display.h +++ b/drivers/gpu/drm/gma500/gma_display.h @@ -64,6 +64,11 @@ extern bool gma_pipe_has_type(struct drm_crtc *crtc, int type); extern void gma_wait_for_vblank(struct drm_device *dev); extern int gma_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb); +extern int gma_crtc_cursor_set(struct drm_crtc *crtc, + struct drm_file *file_priv, + uint32_t handle, + uint32_t width, uint32_t height); +extern int gma_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); extern void gma_crtc_load_lut(struct drm_crtc *crtc); extern void gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, u32 start, u32 size);