From patchwork Sun Sep 27 19:36:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Cercueil X-Patchwork-Id: 11803061 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2664B618 for ; Mon, 28 Sep 2020 07:08:19 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EE36620789 for ; Mon, 28 Sep 2020 07:08:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=crapouillou.net header.i=@crapouillou.net header.b="Ga6MOrPT" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EE36620789 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=crapouillou.net Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2CD5A6E432; Mon, 28 Sep 2020 07:07:51 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from crapouillou.net (crapouillou.net [89.234.176.41]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7ECA96E204 for ; Sun, 27 Sep 2020 19:37:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=crapouillou.net; s=mail; t=1601235413; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lh7NfaMRR2/5OvVIOgj2QdyiBr5bakMb9ZkqYQ/T7EU=; b=Ga6MOrPTtutYmOjlYB8bZJT9He75EYbWR7gtLO1HBv9LG5miP/MVGCkjvkVeelnf1VzQmI EKWvbKBITDuVr0eXRrH5gx93TVDstWqqLkBomC41+jqucG0Aus5obGq0EEjWf6yqNoGzgu TumeCz59g1MgLoTxpuoF37ifFCzhaog= From: Paul Cercueil To: David Airlie , Daniel Vetter Subject: [PATCH v3 1/1] drm/ingenic: Add support for paletted 8bpp Date: Sun, 27 Sep 2020 21:36:45 +0200 Message-Id: <20200927193645.262612-2-paul@crapouillou.net> In-Reply-To: <20200927193645.262612-1-paul@crapouillou.net> References: <20200927193645.262612-1-paul@crapouillou.net> MIME-Version: 1.0 X-Mailman-Approved-At: Mon, 28 Sep 2020 07:06:24 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paul Cercueil , od@zcrc.me, Sam Ravnborg , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" On JZ4725B and newer, the F0 plane supports paletted 8bpp with a 256-entry palette. Add support for it. v3: Only accept a full 256-entry palette. Signed-off-by: Paul Cercueil --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 66 +++++++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 589fc0c60716..0225dc1f5eb8 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,8 @@ struct ingenic_dma_hwdesc { struct ingenic_dma_hwdescs { struct ingenic_dma_hwdesc hwdesc_f0; struct ingenic_dma_hwdesc hwdesc_f1; + struct ingenic_dma_hwdesc hwdesc_pal; + u16 palette[256] __aligned(16); }; struct jz_soc_info { @@ -249,6 +252,12 @@ static int ingenic_drm_crtc_atomic_check(struct drm_crtc *crtc, struct ingenic_drm *priv = drm_crtc_get_priv(crtc); struct drm_plane_state *f1_state, *f0_state, *ipu_state = NULL; + if (state->gamma_lut && + drm_color_lut_size(state->gamma_lut) != ARRAY_SIZE(priv->dma_hwdescs->palette)) { + dev_dbg(priv->dev, "Invalid palette size\n"); + return -EINVAL; + } + if (drm_atomic_crtc_needs_modeset(state) && priv->soc_info->has_osd) { f1_state = drm_atomic_get_plane_state(state->state, &priv->f1); if (IS_ERR(f1_state)) @@ -470,6 +479,9 @@ void ingenic_drm_plane_config(struct device *dev, JZ_LCD_OSDCTRL_BPP_MASK, ctrl); } else { switch (fourcc) { + case DRM_FORMAT_C8: + ctrl |= JZ_LCD_CTRL_BPP_8; + break; case DRM_FORMAT_XRGB1555: ctrl |= JZ_LCD_CTRL_RGB555; fallthrough; @@ -541,16 +553,34 @@ void ingenic_drm_sync_data(struct device *dev, } } +static void ingenic_drm_update_palette(struct ingenic_drm *priv, + const struct drm_color_lut *lut) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(priv->dma_hwdescs->palette); i++) { + u16 color = drm_color_lut_extract(lut[i].red, 5) << 11 + | drm_color_lut_extract(lut[i].green, 6) << 5 + | drm_color_lut_extract(lut[i].blue, 5); + + priv->dma_hwdescs->palette[i] = color; + } +} + static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *oldstate) { struct ingenic_drm *priv = drm_device_get_priv(plane->dev); struct drm_plane_state *state = plane->state; + struct drm_crtc_state *crtc_state; struct ingenic_dma_hwdesc *hwdesc; - unsigned int width, height, cpp; + unsigned int width, height, cpp, offset; dma_addr_t addr; + u32 fourcc; if (state && state->fb) { + crtc_state = state->crtc->state; + ingenic_drm_sync_data(priv->dev, oldstate, state); addr = drm_fb_cma_get_gem_addr(state->fb, state, 0); @@ -566,9 +596,23 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, hwdesc->addr = addr; hwdesc->cmd = JZ_LCD_CMD_EOF_IRQ | (width * height * cpp / 4); - if (drm_atomic_crtc_needs_modeset(state->crtc->state)) - ingenic_drm_plane_config(priv->dev, plane, - state->fb->format->format); + if (drm_atomic_crtc_needs_modeset(crtc_state)) { + fourcc = state->fb->format->format; + + ingenic_drm_plane_config(priv->dev, plane, fourcc); + + if (fourcc == DRM_FORMAT_C8) + offset = offsetof(struct ingenic_dma_hwdescs, hwdesc_pal); + else + offset = offsetof(struct ingenic_dma_hwdescs, hwdesc_f0); + + priv->dma_hwdescs->hwdesc_f0.next = priv->dma_hwdescs_phys + offset; + + crtc_state->color_mgmt_changed = fourcc == DRM_FORMAT_C8; + } + + if (crtc_state->color_mgmt_changed) + ingenic_drm_update_palette(priv, crtc_state->gamma_lut->data); } } @@ -964,6 +1008,15 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) priv->dma_hwdescs->hwdesc_f1.next = dma_hwdesc_phys_f1; priv->dma_hwdescs->hwdesc_f1.id = 0xf1; + /* Configure DMA hwdesc for palette */ + priv->dma_hwdescs->hwdesc_pal.next = priv->dma_hwdescs_phys + + offsetof(struct ingenic_dma_hwdescs, hwdesc_f0); + priv->dma_hwdescs->hwdesc_pal.id = 0xc0; + priv->dma_hwdescs->hwdesc_pal.addr = priv->dma_hwdescs_phys + + offsetof(struct ingenic_dma_hwdescs, palette); + priv->dma_hwdescs->hwdesc_pal.cmd = JZ_LCD_CMD_ENABLE_PAL + | (sizeof(priv->dma_hwdescs->palette) / 4); + if (soc_info->has_osd) priv->ipu_plane = drm_plane_from_index(drm, 0); @@ -990,6 +1043,9 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) return ret; } + drm_crtc_enable_color_mgmt(&priv->crtc, 0, false, + ARRAY_SIZE(priv->dma_hwdescs->palette)); + if (soc_info->has_osd) { drm_plane_helper_add(&priv->f0, &ingenic_drm_plane_helper_funcs); @@ -1225,6 +1281,7 @@ static const u32 jz4725b_formats_f1[] = { }; static const u32 jz4725b_formats_f0[] = { + DRM_FORMAT_C8, DRM_FORMAT_XRGB1555, DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888, @@ -1239,6 +1296,7 @@ static const u32 jz4770_formats_f1[] = { }; static const u32 jz4770_formats_f0[] = { + DRM_FORMAT_C8, DRM_FORMAT_XRGB1555, DRM_FORMAT_RGB565, DRM_FORMAT_RGB888,