From patchwork Mon Oct 31 14:19:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 9405529 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2964F60234 for ; Mon, 31 Oct 2016 14:23:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0581728D83 for ; Mon, 31 Oct 2016 14:23:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EE42C29149; Mon, 31 Oct 2016 14:23:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 95EA928D83 for ; Mon, 31 Oct 2016 14:23:05 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1c1DSS-0001W8-I8; Mon, 31 Oct 2016 14:21:04 +0000 Received: from mail-wm0-x236.google.com ([2a00:1450:400c:c09::236]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1c1DRp-0008Fl-NI for linux-arm-kernel@lists.infradead.org; Mon, 31 Oct 2016 14:20:27 +0000 Received: by mail-wm0-x236.google.com with SMTP id n67so231684603wme.1 for ; Mon, 31 Oct 2016 07:20:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nUdrJb/SO4lX9I8/SGEgEHDvh4bdYGG2CjZSNo9ggsQ=; b=ng4nhqtv3FEGU/JSHDSQwwqsA/Yssl5/mwx6Pq/sdVvNNjBF7O0bFu0JANmsoJaikd yjkHKzIEjVoVGtZ89tDWOogL+gwINlEbIOGgLPTJIYHOXEjepSAUIZTCQ/Z0NtlN4Obq 8hUbR2gzyl9es8nC9YMDEjItB0BNjxBh/6HKxD0iS/rCiaWP5pzvMhmIFEWqGl1DjVIO bxvQIMjbDhb4xGcZF+3s8CO5mdI0ZICxi4lC4BE+G4xa7NOq84RAPWSKf3BHWk/mCyLr nZwfru+DSN3SIYwc7baE3hOGlKH7UyiqwSi1RUhZzeXAv1REvpAYxcI1AT69XAbWPtLK hA3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nUdrJb/SO4lX9I8/SGEgEHDvh4bdYGG2CjZSNo9ggsQ=; b=MK4MVnimoqO1lH4QKCRygmCVnbFcXKTvE4nYllfcQsmaEcOBCfc/EqlBxiqPRcQlZe 0qKWKCrq6RkaLET1tOvus3vomsdCB+COJtON5jQ2xqxbpvgNbyDFCZvsDtATAaOnVrKS yNX67OGQglnVMHg4Ah7bmMpNG7JN11zLQj9cJQPA5/QBn8iM7Lvb2T8vMa/9+tnQGpwK mQgSWGy6T7rY0STBxl39WOTnc1B1KlgDMRd+v7D4kNUiKc1q8XLeB/zIpF0kM3FKj+G3 B3EAQjxrt8kLcV6hie7v+IZBaizswxJ1cVdY+Tph6w/AaniV0z3ukmvZc4LjN9l+JzIw Q9yA== X-Gm-Message-State: ABUngvcDQzAqrlwrJL0bm/b7q3dpcPru9Fyv8GACaPz4AdZQYP5k+IL1zratH6lm33E6dvE5 X-Received: by 10.28.216.17 with SMTP id p17mr10719274wmg.11.1477923603364; Mon, 31 Oct 2016 07:20:03 -0700 (PDT) Received: from localhost.localdomain ([90.63.244.31]) by smtp.gmail.com with ESMTPSA id f4sm24929965wmd.15.2016.10.31.07.20.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 31 Oct 2016 07:20:01 -0700 (PDT) From: Bartosz Golaszewski To: Jyri Sarha , Tomi Valkeinen , David Airlie , Kevin Hilman , Michael Turquette , Sekhar Nori Subject: [PATCH v5 1/2] drm: tilcdc: implement palette loading for rev1 Date: Mon, 31 Oct 2016 15:19:26 +0100 Message-Id: <1477923567-1610-2-git-send-email-bgolaszewski@baylibre.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1477923567-1610-1-git-send-email-bgolaszewski@baylibre.com> References: <1477923567-1610-1-git-send-email-bgolaszewski@baylibre.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161031_072026_042355_193AF46E X-CRM114-Status: GOOD ( 19.11 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Bartosz Golaszewski , LKML , linux-drm , arm-soc MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Revision 1 of the IP doesn't work if we don't load the palette (even if it's not used, which is the case for the RGB565 format). Add a function called from tilcdc_crtc_enable() which performs all required actions if we're dealing with a rev1 chip. Signed-off-by: Bartosz Golaszewski --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 88 +++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index db2f538..937697d 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -21,11 +21,15 @@ #include #include #include +#include +#include #include "tilcdc_drv.h" #include "tilcdc_regs.h" -#define TILCDC_VBLANK_SAFETY_THRESHOLD_US 1000 +#define TILCDC_VBLANK_SAFETY_THRESHOLD_US 1000 +#define TILCDC_REV1_PALETTE_SIZE 32 +#define TILCDC_REV1_PALETTE_FIRST_ENTRY 0x4000 struct tilcdc_crtc { struct drm_crtc base; @@ -53,6 +57,10 @@ struct tilcdc_crtc { int sync_lost_count; bool frame_intact; + + dma_addr_t palette_dma_handle; + void *palette_base; + struct completion palette_loaded; }; #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base) @@ -98,6 +106,55 @@ static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb) tilcdc_crtc->curr_fb = fb; } +/* + * The driver currently only supports the RGB565 format for revision 1. For + * 16 bits-per-pixel the palette block is bypassed, but the first 32 bytes of + * the framebuffer are still considered palette. The first 16-bit entry must + * be 0x4000 while all other entries must be zeroed. + */ +static void tilcdc_crtc_load_palette(struct drm_crtc *crtc) +{ + u32 dma_fb_base, dma_fb_ceiling, raster_ctl; + struct tilcdc_crtc *tilcdc_crtc; + struct drm_device *dev; + u16 *first_entry; + + dev = crtc->dev; + tilcdc_crtc = to_tilcdc_crtc(crtc); + first_entry = tilcdc_crtc->palette_base; + + *first_entry = TILCDC_REV1_PALETTE_FIRST_ENTRY; + + dma_fb_base = tilcdc_read(dev, LCDC_DMA_FB_BASE_ADDR_0_REG); + dma_fb_ceiling = tilcdc_read(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG); + raster_ctl = tilcdc_read(dev, LCDC_RASTER_CTRL_REG); + + /* Tell the LCDC where the palette is located. */ + tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, + tilcdc_crtc->palette_dma_handle); + tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, + (u32)tilcdc_crtc->palette_dma_handle + + TILCDC_REV1_PALETTE_SIZE - 1); + + /* Load it. */ + tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, + LCDC_PALETTE_LOAD_MODE(DATA_ONLY)); + tilcdc_set(dev, LCDC_RASTER_CTRL_REG, + LCDC_PALETTE_LOAD_MODE(PALETTE_ONLY)); + + /* Enable the LCDC and wait for palette to be loaded. */ + tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA); + tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); + + wait_for_completion(&tilcdc_crtc->palette_loaded); + + /* Restore the registers. */ + tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); + tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, dma_fb_base); + tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, dma_fb_ceiling); + tilcdc_write(dev, LCDC_RASTER_CTRL_REG, raster_ctl); +} + static void tilcdc_crtc_enable_irqs(struct drm_device *dev) { struct tilcdc_drm_private *priv = dev->dev_private; @@ -152,6 +209,7 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); + struct tilcdc_drm_private *priv = dev->dev_private; WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); @@ -162,6 +220,9 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc) reset(crtc); + if (priv->rev == 1 && !completion_done(&tilcdc_crtc->palette_loaded)) + tilcdc_crtc_load_palette(crtc); + tilcdc_crtc_enable_irqs(dev); tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_DUAL_FRAME_BUFFER_ENABLE); @@ -200,6 +261,13 @@ void tilcdc_crtc_disable(struct drm_crtc *crtc) __func__); } + /* + * LCDC will not retain the palette when reset. Make sure it gets + * reloaded on tilcdc_crtc_enable(). + */ + if (priv->rev == 1) + reinit_completion(&tilcdc_crtc->palette_loaded); + drm_crtc_vblank_off(crtc); tilcdc_crtc_disable_irqs(dev); @@ -802,6 +870,14 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO underfow", __func__, stat); + if (priv->rev == 1) { + if (stat & LCDC_PL_LOAD_DONE) { + complete(&tilcdc_crtc->palette_loaded); + tilcdc_clear(dev, + LCDC_RASTER_CTRL_REG, LCDC_V1_PL_INT_ENA); + } + } + /* For revision 2 only */ if (priv->rev == 2) { if (stat & LCDC_FRAME_DONE) { @@ -843,6 +919,16 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) return NULL; } + if (priv->rev == 1) { + init_completion(&tilcdc_crtc->palette_loaded); + tilcdc_crtc->palette_base = dmam_alloc_coherent(dev->dev, + TILCDC_REV1_PALETTE_SIZE, + &tilcdc_crtc->palette_dma_handle, + GFP_KERNEL | __GFP_ZERO); + if (!tilcdc_crtc->palette_base) + return ERR_PTR(-ENOMEM); + } + crtc = &tilcdc_crtc->base; ret = tilcdc_plane_init(dev, &tilcdc_crtc->primary);