From patchwork Thu Aug 3 11:02:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AngeloGioacchino Del Regno X-Patchwork-Id: 13339768 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id B33C5C04E69 for ; Thu, 3 Aug 2023 11:03:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0B15110E5E4; Thu, 3 Aug 2023 11:02:37 +0000 (UTC) Received: from madras.collabora.co.uk (madras.collabora.co.uk [46.235.227.172]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8D21D10E5EB for ; Thu, 3 Aug 2023 11:02:32 +0000 (UTC) Received: from IcarusMOD.eternityproject.eu (2-237-20-237.ip236.fastwebnet.it [2.237.20.237]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: kholk11) by madras.collabora.co.uk (Postfix) with ESMTPSA id 7403F66071A6; Thu, 3 Aug 2023 12:02:30 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1691060551; bh=n8HvV63ZZGMSvMV6QA95OQQ7cx7V5oON5E66oBaNqmA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=N/wuBhL5RfBQ83ntwFbrMNoTHw14m7RF521k2cMK6UBlNQlRFhAjh/A1Zl3qy9H/5 Ykoc+wvz4qIvq5VBdb86kKZRnHiXsd73plSfFT7SCrk8YX0YuVdebYzFyjxwjWkODl 0Pm5GwAhGU0zr4xkf7z514R18Qa8XVXwzZLzgFSheh9Rf0LnCOGbpmEp3UW4Ht624d P+2nyu5mWhsRvf1ZsDxbDKJzoGP1kjTbYPO1AAIODQQ+yShrDxijXbdbTqwPWqBlmm DKjO+skdHD8B/1TaSCBY+4RaYZDkQOdEyhet772zU9TRSr6DBm/Vr40Awkcunr6aD6 yqqStageyAx4A== From: AngeloGioacchino Del Regno To: chunkuang.hu@kernel.org Subject: [PATCH v9 11/16] drm/mediatek: gamma: Add support for 12-bit LUT and MT8195 Date: Thu, 3 Aug 2023 13:02:09 +0200 Message-ID: <20230803110214.163645-12-angelogioacchino.delregno@collabora.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230803110214.163645-1-angelogioacchino.delregno@collabora.com> References: <20230803110214.163645-1-angelogioacchino.delregno@collabora.com> MIME-Version: 1.0 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: Alexandre Mergnat , "Jason-JH . Lin" , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-mediatek@lists.infradead.org, ehristev@collabora.com, wenst@chromium.org, matthias.bgg@gmail.com, kernel@collabora.com, linux-arm-kernel@lists.infradead.org, angelogioacchino.delregno@collabora.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add support for 12-bit gamma lookup tables and introduce the first user for it: MT8195. While at it, also reorder the variables in mtk_gamma_set_common() and rename `lut_base` to `lut0_base` to improve readability. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Jason-JH.Lin Reviewed-by: Alexandre Mergnat --- drivers/gpu/drm/mediatek/mtk_disp_gamma.c | 74 +++++++++++++++++++---- 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c index 3f1c6815ea5a..7d2f8042ace0 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c @@ -26,12 +26,20 @@ #define DISP_GAMMA_SIZE_VSIZE GENMASK(12, 0) #define DISP_GAMMA_BANK 0x0100 #define DISP_GAMMA_BANK_BANK GENMASK(1, 0) +#define DISP_GAMMA_BANK_DATA_MODE BIT(2) #define DISP_GAMMA_LUT 0x0700 +#define DISP_GAMMA_LUT1 0x0b00 +/* For 10 bit LUT layout, R/G/B are in the same register */ #define DISP_GAMMA_LUT_10BIT_R GENMASK(29, 20) #define DISP_GAMMA_LUT_10BIT_G GENMASK(19, 10) #define DISP_GAMMA_LUT_10BIT_B GENMASK(9, 0) +/* For 12 bit LUT layout, R/G are in LUT, B is in LUT1 */ +#define DISP_GAMMA_LUT_12BIT_R GENMASK(11, 0) +#define DISP_GAMMA_LUT_12BIT_G GENMASK(23, 12) +#define DISP_GAMMA_LUT_12BIT_B GENMASK(11, 0) + #define LUT_10BIT_MASK 0x03ff #define LUT_BITS_DEFAULT 10 #define LUT_SIZE_DEFAULT 512 @@ -77,14 +85,30 @@ unsigned int mtk_gamma_get_lut_size(struct device *dev) return LUT_SIZE_DEFAULT; } +/* + * SoCs supporting 12-bits LUTs are using a new register layout that does + * always support (by HW) both 12-bits and 10-bits LUT but, on those, we + * ignore the support for 10-bits in this driver and always use 12-bits. + * + * Summarizing: + * - SoC HW support 9/10-bits LUT only + * - Old register layout + * - 10-bits LUT supported + * - 9-bits LUT not supported + * - SoC HW support both 10/12bits LUT + * - New register layout + * - 12-bits LUT supported + * - 10-its LUT not supported + */ void mtk_gamma_set(struct device *dev, struct drm_crtc_state *state) { struct mtk_disp_gamma *gamma = dev_get_drvdata(dev); - unsigned int i; - struct drm_color_lut *lut; - void __iomem *lut_base; - u32 cfg_val, lbank_val, word; + void __iomem *lut0_base = gamma->regs + DISP_GAMMA_LUT; + void __iomem *lut1_base = gamma->regs + DISP_GAMMA_LUT1; + u32 cfg_val, data_mode, lbank_val, word[2]; int cur_bank, num_lut_banks; + struct drm_color_lut *lut; + unsigned int i; /* If there's no gamma lut there's nothing to do here. */ if (!state->gamma_lut) @@ -92,14 +116,17 @@ void mtk_gamma_set(struct device *dev, struct drm_crtc_state *state) num_lut_banks = gamma->data->lut_size / gamma->data->lut_bank_size; cfg_val = readl(gamma->regs + DISP_GAMMA_CFG); - lut_base = gamma->regs + DISP_GAMMA_LUT; lut = (struct drm_color_lut *)state->gamma_lut->data; + /* Switch to 12 bits data mode if supported */ + data_mode = FIELD_PREP(DISP_GAMMA_BANK_DATA_MODE, !!(gamma->data->lut_bits == 12)); + for (cur_bank = 0; cur_bank < num_lut_banks; cur_bank++) { /* Switch gamma bank and set data mode before writing LUT */ if (num_lut_banks > 1) { lbank_val = FIELD_PREP(DISP_GAMMA_BANK_BANK, cur_bank); + lbank_val |= data_mode; writel(lbank_val, gamma->regs + DISP_GAMMA_BANK); } @@ -112,9 +139,15 @@ void mtk_gamma_set(struct device *dev, struct drm_crtc_state *state) hwlut.blue = drm_color_lut_extract(lut[n].blue, gamma->data->lut_bits); if (!gamma->data->lut_diff || (i % 2 == 0)) { - word = FIELD_PREP(DISP_GAMMA_LUT_10BIT_R, hwlut.red); - word |= FIELD_PREP(DISP_GAMMA_LUT_10BIT_G, hwlut.green); - word |= FIELD_PREP(DISP_GAMMA_LUT_10BIT_B, hwlut.blue); + if (gamma->data->lut_bits == 12) { + word[0] = FIELD_PREP(DISP_GAMMA_LUT_12BIT_R, hwlut.red); + word[0] |= FIELD_PREP(DISP_GAMMA_LUT_12BIT_G, hwlut.green); + word[1] = FIELD_PREP(DISP_GAMMA_LUT_12BIT_B, hwlut.blue); + } else { + word[0] = FIELD_PREP(DISP_GAMMA_LUT_10BIT_R, hwlut.red); + word[0] |= FIELD_PREP(DISP_GAMMA_LUT_10BIT_G, hwlut.green); + word[0] |= FIELD_PREP(DISP_GAMMA_LUT_10BIT_B, hwlut.blue); + } } else { diff.red = lut[n].red - lut[n - 1].red; diff.red = drm_color_lut_extract(diff.red, gamma->data->lut_bits); @@ -125,11 +158,19 @@ void mtk_gamma_set(struct device *dev, struct drm_crtc_state *state) diff.blue = lut[n].blue - lut[n - 1].blue; diff.blue = drm_color_lut_extract(diff.blue, gamma->data->lut_bits); - word = FIELD_PREP(DISP_GAMMA_LUT_10BIT_R, diff.red); - word |= FIELD_PREP(DISP_GAMMA_LUT_10BIT_G, diff.green); - word |= FIELD_PREP(DISP_GAMMA_LUT_10BIT_B, diff.blue); + if (gamma->data->lut_bits == 12) { + word[0] = FIELD_PREP(DISP_GAMMA_LUT_12BIT_R, diff.red); + word[0] |= FIELD_PREP(DISP_GAMMA_LUT_12BIT_G, diff.green); + word[1] = FIELD_PREP(DISP_GAMMA_LUT_12BIT_B, diff.blue); + } else { + word[0] = FIELD_PREP(DISP_GAMMA_LUT_10BIT_R, diff.red); + word[0] |= FIELD_PREP(DISP_GAMMA_LUT_10BIT_G, diff.green); + word[0] |= FIELD_PREP(DISP_GAMMA_LUT_10BIT_B, diff.blue); + } } - writel(word, (lut_base + i * 4)); + writel(word[0], (lut0_base + i * 4)); + if (gamma->data->lut_bits == 12) + writel(word[1], (lut1_base + i * 4)); } } @@ -246,11 +287,20 @@ static const struct mtk_disp_gamma_data mt8183_gamma_driver_data = { .lut_size = 512, }; +static const struct mtk_disp_gamma_data mt8195_gamma_driver_data = { + .lut_bank_size = 256, + .lut_bits = 12, + .lut_diff = true, + .lut_size = 1024, +}; + static const struct of_device_id mtk_disp_gamma_driver_dt_match[] = { { .compatible = "mediatek,mt8173-disp-gamma", .data = &mt8173_gamma_driver_data}, { .compatible = "mediatek,mt8183-disp-gamma", .data = &mt8183_gamma_driver_data}, + { .compatible = "mediatek,mt8195-disp-gamma", + .data = &mt8195_gamma_driver_data}, {}, }; MODULE_DEVICE_TABLE(of, mtk_disp_gamma_driver_dt_match);