From patchwork Fri Mar 16 21:50:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Schake X-Patchwork-Id: 10290353 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 B3118602C2 for ; Fri, 16 Mar 2018 21:51:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A35942903C for ; Fri, 16 Mar 2018 21:51:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 986E1290C9; Fri, 16 Mar 2018 21:51:33 +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_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 36F4A2903C for ; Fri, 16 Mar 2018 21:51:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0380F6EC12; Fri, 16 Mar 2018 21:51:30 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x243.google.com (mail-wm0-x243.google.com [IPv6:2a00:1450:400c:c09::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id EC0666EC0F for ; Fri, 16 Mar 2018 21:51:25 +0000 (UTC) Received: by mail-wm0-x243.google.com with SMTP id t6so5565212wmt.5 for ; Fri, 16 Mar 2018 14:51:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=KADDQ2CQE5BOBZhnXPkLLAA1h94wFlKWv6HpgcxWbfY=; b=Vsfmqbbg/ebI/tzXHkJtvumT8CdW7Qs7hYerLF1UosQcNBG1Cdep+B7QmCR/sfQCv1 lLgzofHKaZqO3RsSaWg+t6XaWSQntVK1FS5uZUsqclxV9y5ZGBuMgvcob8mPfmTJl7EJ ynBtd0rezxypYHErxkJmHAF/WuJPZi35yozXrgRXgnkJFemDMG4qfzFmN0cVXYVLlcyL O+N3p9nf3yj6f3liqf8nIfTBvra5tZ2JA0eJxMmoIMMsNrLFep8mk1etMAMIfeQbtQrj 10ezGTsMm1QoAHVJp8qsTsgweDfI9BZYeND3cWjDl3Dy/B0EBZQZXytqDj52SI5RLwbh N8WA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=KADDQ2CQE5BOBZhnXPkLLAA1h94wFlKWv6HpgcxWbfY=; b=dW7GUZfQ0TMdqTIHulU3zZ5o1ZzPNtpGHL7ZoZao3mLDYyNHOw9nBxN+00i94skiye eX/WkUA8uGuV2o/P0J3ZgJYU8qOze095YhuTGmCSzdP+R0WUmFZgwc7aoeak/KQFq5l5 VIaeHrwtBpygJjPbS0exr4AwgUR9VKq9bQQjzcBYDJAC/IVWPqhsrScSct6B2LUu86YS UXen6hUZ0HJnZzcTg1AX8IQ0wyQoPaS7N9cMnpuAgqzmwQuWKkwiYHrXaY7b6tBaNK2e 5Or+UykwV2qxXd+WQIIl3Fb7fdpm7Y2ftmwDysoy5QzxlzbBrD04CvDHMl4/OdEpVbtj +7tg== X-Gm-Message-State: AElRT7EuZMnrsY1sjRL+MKK9i7K5Q/k5VR2a84V1TvisZ9Jl1JIkb0CK VlxbbS2Wskt+yZHabW14AAvlYnmo X-Google-Smtp-Source: AG47ELtHlsDacHmrUkm82iCWU/kz6xcACdja5BziezfnImKCh9C2+RRG+a35C84Ky+yA4EvP1uncYg== X-Received: by 10.80.221.7 with SMTP id t7mr4095723edk.192.1521237084286; Fri, 16 Mar 2018 14:51:24 -0700 (PDT) Received: from localhost.localdomain (x5ce4c84b.dyn.telefonica.de. [92.228.200.75]) by smtp.gmail.com with ESMTPSA id m23sm5000606edc.69.2018.03.16.14.51.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 16 Mar 2018 14:51:23 -0700 (PDT) From: Stefan Schake To: eric@anholt.net Subject: [PATCH 2/3] drm/vc4: Add color transformation matrix (CTM) support Date: Fri, 16 Mar 2018 22:50:58 +0100 Message-Id: <1521237059-37117-3-git-send-email-stschake@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1521237059-37117-1-git-send-email-stschake@gmail.com> References: <1521237059-37117-1-git-send-email-stschake@gmail.com> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: airlied@linux.ie, linux-rpi-kernel@lists.infradead.org, dri-devel@lists.freedesktop.org, Stefan Schake MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP The hardware supports a CTM with S0.9 values. We therefore only allow a value of 1.0 or fractional only and reject all others with integer parts. This restriction is mostly inconsequential in practice since commonly used transformation matrices have all scalars <= 1.0. Signed-off-by: Stefan Schake --- drivers/gpu/drm/vc4/vc4_crtc.c | 99 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 8d71098..5c83fd2 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -315,6 +315,81 @@ vc4_crtc_update_gamma_lut(struct drm_crtc *crtc) vc4_crtc_lut_load(crtc); } +/* Converts a DRM S31.32 value to the HW S0.9 format. */ +static u16 vc4_crtc_s31_32_to_s0_9(u64 in) +{ + u16 r; + + /* Sign bit. */ + r = in & BIT_ULL(63) ? BIT(9) : 0; + /* We have zero integer bits so we can only saturate here. */ + if ((in & GENMASK_ULL(62, 32)) > 0) + r |= GENMASK(8, 0); + /* Otherwise take the 9 most important fractional bits. */ + else + r |= (in >> 22) & GENMASK(8, 0); + return r; +} + +static void +vc4_crtc_update_ctm(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct vc4_dev *vc4 = to_vc4_dev(dev); + struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + struct drm_color_ctm *ctm = crtc->state->ctm->data; + + HVS_WRITE(SCALER_OLEDCOEF2, + VC4_SET_FIELD(vc4_crtc_s31_32_to_s0_9(ctm->matrix[0]), + SCALER_OLEDCOEF2_R_TO_R) | + VC4_SET_FIELD(vc4_crtc_s31_32_to_s0_9(ctm->matrix[3]), + SCALER_OLEDCOEF2_R_TO_G) | + VC4_SET_FIELD(vc4_crtc_s31_32_to_s0_9(ctm->matrix[6]), + SCALER_OLEDCOEF2_R_TO_B)); + HVS_WRITE(SCALER_OLEDCOEF1, + VC4_SET_FIELD(vc4_crtc_s31_32_to_s0_9(ctm->matrix[1]), + SCALER_OLEDCOEF1_G_TO_R) | + VC4_SET_FIELD(vc4_crtc_s31_32_to_s0_9(ctm->matrix[4]), + SCALER_OLEDCOEF1_G_TO_G) | + VC4_SET_FIELD(vc4_crtc_s31_32_to_s0_9(ctm->matrix[7]), + SCALER_OLEDCOEF1_G_TO_B)); + HVS_WRITE(SCALER_OLEDCOEF0, + VC4_SET_FIELD(vc4_crtc_s31_32_to_s0_9(ctm->matrix[2]), + SCALER_OLEDCOEF0_B_TO_R) | + VC4_SET_FIELD(vc4_crtc_s31_32_to_s0_9(ctm->matrix[5]), + SCALER_OLEDCOEF0_B_TO_G) | + VC4_SET_FIELD(vc4_crtc_s31_32_to_s0_9(ctm->matrix[8]), + SCALER_OLEDCOEF0_B_TO_B)); + + /* Channel is 0-based but for DISPFIFO, 0 means disabled. */ + HVS_WRITE(SCALER_OLEDOFFS, VC4_SET_FIELD(vc4_crtc->channel + 1, + SCALER_OLEDOFFS_DISPFIFO)); +} + +/* Check if the CTM contains valid input. + * + * DRM exposes CTM with S31.32 scalars, but the HW only supports S0.9. + * We don't allow integer values >1, and 1 only without fractional part + * to handle the common 1.0 value. + */ +static int vc4_crtc_atomic_check_ctm(struct drm_crtc_state *state) +{ + struct drm_color_ctm *ctm = state->ctm->data; + u32 i; + + for (i = 0; i < ARRAY_SIZE(ctm->matrix); i++) { + u64 val = ctm->matrix[i]; + + val &= ~BIT_ULL(63); + if ((val >> 32) > 1) + return -EINVAL; + if ((val >> 32) == 1 && (val & GENMASK_ULL(31, 0)) != 0) + return -EINVAL; + } + + return 0; +} + static u32 vc4_get_fifo_full_level(u32 format) { static const u32 fifo_len_bytes = 64; @@ -621,6 +696,15 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc, if (hweight32(state->connector_mask) > 1) return -EINVAL; + if (state->ctm) { + /* The CTM hardware has no integer bits, so we check + * and reject scalars >1.0 that we have no chance of + * approximating. + */ + if (vc4_crtc_atomic_check_ctm(state)) + return -EINVAL; + } + drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, state) dlist_count += vc4_plane_dlist_size(plane_state); @@ -697,8 +781,17 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc, if (crtc->state->active && old_state->active) vc4_crtc_update_dlist(crtc); - if (crtc->state->color_mgmt_changed && crtc->state->gamma_lut) - vc4_crtc_update_gamma_lut(crtc); + if (crtc->state->color_mgmt_changed) { + if (crtc->state->gamma_lut) + vc4_crtc_update_gamma_lut(crtc); + + if (crtc->state->ctm) + vc4_crtc_update_ctm(crtc); + /* We are transitioning to CTM disabled. */ + else if (old_state->ctm) + HVS_WRITE(SCALER_OLEDOFFS, + VC4_SET_FIELD(0, SCALER_OLEDOFFS_DISPFIFO)); + } if (debug_dump_regs) { DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc)); @@ -1036,7 +1129,7 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data) primary_plane->crtc = crtc; vc4_crtc->channel = vc4_crtc->data->hvs_channel; drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r)); - drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size); + drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size); /* Set up some arbitrary number of planes. We're not limited * by a set number of physical registers, just the space in