From patchwork Tue Nov 8 04:26:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AceLan Kao X-Patchwork-Id: 1701115 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=I7q7d/3u; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4N5w6w0Lh8z23mG for ; Tue, 8 Nov 2022 15:27:20 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1osGCe-0003tN-K3; Tue, 08 Nov 2022 04:27:12 +0000 Received: from mail-pf1-f169.google.com ([209.85.210.169]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1osGCZ-0003MO-KS for kernel-team@lists.ubuntu.com; Tue, 08 Nov 2022 04:27:07 +0000 Received: by mail-pf1-f169.google.com with SMTP id d10so12737952pfh.6 for ; Mon, 07 Nov 2022 20:26:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=gWNsML8D5qnS5nEb5BOBxc/R8+xB3tTztOspffYSFhQ=; b=I7q7d/3uJyQqQhNFWNEwnno6cgiiMJu4Mu0I2Si72xDSawhUqwraswFPk8rR1BjpOm hSfqH13LI7zWdNj3KbMsWwhBrAKTGhDqJ6siPZD+OUFxoXv/2aMUh7he8lcYx/46BCyu 6197O0Z+U8OEtbgUBn55IUopKH1f/fp8ZFOFX4If+qXMOtzTEIZkuLYSVucQjwRI/YeW ++hW+vM7+bF2wMHz1S/G9LnrHFNnHgeTk8wtSWPY22J+3f7+oO80dE1WI6dijh7EcA6X o/8+cbq0+kA2r/e0nZGjSwjeZNinW3+RJQqgo6xZYwug0eKn50xW71RMw7LZpcFRufdt cLJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:sender:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=gWNsML8D5qnS5nEb5BOBxc/R8+xB3tTztOspffYSFhQ=; b=a5Fw5o+Q/wY2IIOOhFLttJVPe+52r+9F6kctM/wQrj+LxHbHxh6/Z4qrBLOyBRICt3 ghX2wEizyURVU6AiTt1KBh3kR8WIyWzYVtWxA/3moglgn7VYccDTv4nSzKIHi8YsSf8a q8/cNi2aMQ1jFxwrnJKSu5LMNGBxc5I2bhu3ix0OpHs3q4GwvPm5zQgPy5+a/tm8NP2S Lkko3+E3OKoE90K8dBzrHOpU+MumtmKRVprk8umwvJbJthyPyLD7KeUO6/hjlazWeuZt M2TLMvvEOZ6dSW2dM9L5WtwQ5StsH7zoqWcJEesEkx2rwc9v9A7Z+4If/Hp8jJrHIihn D83w== X-Gm-Message-State: ACrzQf1kBgDtk+EeG/Xn13Zo6CVaxmH6sjDvUulTA6Q7ArLRi/lQhpb8 m1IIDUZEN676DsyhbCcsD/o5lXHacDE= X-Google-Smtp-Source: AMsMyM4USQVCcxw9aZHsEE5blPn2AQfpWtZ5sJYoaqSu/Xd+5VHKvMrrZLyGDI387d11qhAbdHP7Ag== X-Received: by 2002:a65:4d47:0:b0:46f:8e45:6fd4 with SMTP id j7-20020a654d47000000b0046f8e456fd4mr43334496pgt.481.1667881616583; Mon, 07 Nov 2022 20:26:56 -0800 (PST) Received: from localhost (220-135-95-34.hinet-ip.hinet.net. [220.135.95.34]) by smtp.gmail.com with ESMTPSA id t15-20020a17090a4e4f00b00202618f0df4sm7032912pjl.0.2022.11.07.20.26.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Nov 2022 20:26:56 -0800 (PST) From: AceLan Kao To: kernel-team@lists.ubuntu.com Subject: [PATCH 3/3][SRU][K] drm/mgag200: Enable atomic gamma lut update Date: Tue, 8 Nov 2022 12:26:34 +0800 Message-Id: <20221108042634.24176-10-acelan.kao@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221108042634.24176-1-acelan.kao@canonical.com> References: <20221108042634.24176-1-acelan.kao@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.210.169; envelope-from=acelan@gmail.com; helo=mail-pf1-f169.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Jocelyn Falempe BugLink: https://launchpad.net/bugs/1995573 Add support for atomic update of gamma lut. With this patch the "Night light" feature of gnome3 is working properly on mgag200. v2: - Add a default linear gamma function - renamed functions with mgag200 prefix - use format's 4cc code instead of bit depth - use better interpolation for 16bits gamma - remove legacy function mga_crtc_load_lut() - can't remove the call to drm_mode_crtc_set_gamma_size() because it doesn't work with userspace. - other small refactors v3: - change mgag200_crtc_set_gamma*() argument to struct drm_format_info *format - fix printk format to %p4cc for 4cc and %zu for size_t - rebased to drm-misc-next. Signed-off-by: Jocelyn Falempe Tested-by: Thomas Zimmermann Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20220513084900.1832381-1-jfalempe@redhat.com (cherry picked from commit c577b2f43e80d707870a74de0fd726c51b206956) Signed-off-by: Chia-Lin Kao (AceLan) --- drivers/gpu/drm/mgag200/mgag200_mode.c | 127 ++++++++++++++++--------- 1 file changed, 83 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 59f850f296ee..5f7d013685b5 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -32,57 +32,78 @@ * This file contains setup code for the CRTC. */ -static void mga_crtc_load_lut(struct drm_crtc *crtc) +static void mgag200_crtc_set_gamma_linear(struct mga_device *mdev, + const struct drm_format_info *format) { - struct drm_device *dev = crtc->dev; - struct mga_device *mdev = to_mga_device(dev); - struct drm_framebuffer *fb; - u16 *r_ptr, *g_ptr, *b_ptr; int i; - if (!crtc->enabled) - return; - - if (!mdev->display_pipe.plane.state) - return; + WREG8(DAC_INDEX + MGA1064_INDEX, 0); - fb = mdev->display_pipe.plane.state->fb; + switch (format->format) { + case DRM_FORMAT_RGB565: + /* Use better interpolation, to take 32 values from 0 to 255 */ + for (i = 0; i < MGAG200_LUT_SIZE / 8; i++) { + WREG8(DAC_INDEX + MGA1064_COL_PAL, i * 8 + i / 4); + WREG8(DAC_INDEX + MGA1064_COL_PAL, i * 4 + i / 16); + WREG8(DAC_INDEX + MGA1064_COL_PAL, i * 8 + i / 4); + } + /* Green has one more bit, so add padding with 0 for red and blue. */ + for (i = MGAG200_LUT_SIZE / 8; i < MGAG200_LUT_SIZE / 4; i++) { + WREG8(DAC_INDEX + MGA1064_COL_PAL, 0); + WREG8(DAC_INDEX + MGA1064_COL_PAL, i * 4 + i / 16); + WREG8(DAC_INDEX + MGA1064_COL_PAL, 0); + } + break; + case DRM_FORMAT_RGB888: + case DRM_FORMAT_XRGB8888: + for (i = 0; i < MGAG200_LUT_SIZE; i++) { + WREG8(DAC_INDEX + MGA1064_COL_PAL, i); + WREG8(DAC_INDEX + MGA1064_COL_PAL, i); + WREG8(DAC_INDEX + MGA1064_COL_PAL, i); + } + break; + default: + drm_warn_once(&mdev->base, "Unsupported format %p4cc for gamma correction\n", + &format->format); + break; + } +} - r_ptr = crtc->gamma_store; - g_ptr = r_ptr + crtc->gamma_size; - b_ptr = g_ptr + crtc->gamma_size; +static void mgag200_crtc_set_gamma(struct mga_device *mdev, + const struct drm_format_info *format, + struct drm_color_lut *lut) +{ + int i; WREG8(DAC_INDEX + MGA1064_INDEX, 0); - if (fb && fb->format->cpp[0] * 8 == 16) { - int inc = (fb->format->depth == 15) ? 8 : 4; - u8 r, b; - for (i = 0; i < MGAG200_LUT_SIZE; i += inc) { - if (fb->format->depth == 16) { - if (i > (MGAG200_LUT_SIZE >> 1)) { - r = b = 0; - } else { - r = *r_ptr++ >> 8; - b = *b_ptr++ >> 8; - r_ptr++; - b_ptr++; - } - } else { - r = *r_ptr++ >> 8; - b = *b_ptr++ >> 8; - } - /* VGA registers */ - WREG8(DAC_INDEX + MGA1064_COL_PAL, r); - WREG8(DAC_INDEX + MGA1064_COL_PAL, *g_ptr++ >> 8); - WREG8(DAC_INDEX + MGA1064_COL_PAL, b); + switch (format->format) { + case DRM_FORMAT_RGB565: + /* Use better interpolation, to take 32 values from lut[0] to lut[255] */ + for (i = 0; i < MGAG200_LUT_SIZE / 8; i++) { + WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i * 8 + i / 4].red >> 8); + WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i * 4 + i / 16].green >> 8); + WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i * 8 + i / 4].blue >> 8); } - return; - } - for (i = 0; i < MGAG200_LUT_SIZE; i++) { - /* VGA registers */ - WREG8(DAC_INDEX + MGA1064_COL_PAL, *r_ptr++ >> 8); - WREG8(DAC_INDEX + MGA1064_COL_PAL, *g_ptr++ >> 8); - WREG8(DAC_INDEX + MGA1064_COL_PAL, *b_ptr++ >> 8); + /* Green has one more bit, so add padding with 0 for red and blue. */ + for (i = MGAG200_LUT_SIZE / 8; i < MGAG200_LUT_SIZE / 4; i++) { + WREG8(DAC_INDEX + MGA1064_COL_PAL, 0); + WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i * 4 + i / 16].green >> 8); + WREG8(DAC_INDEX + MGA1064_COL_PAL, 0); + } + break; + case DRM_FORMAT_RGB888: + case DRM_FORMAT_XRGB8888: + for (i = 0; i < MGAG200_LUT_SIZE; i++) { + WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i].red >> 8); + WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i].green >> 8); + WREG8(DAC_INDEX + MGA1064_COL_PAL, lut[i].blue >> 8); + } + break; + default: + drm_warn_once(&mdev->base, "Unsupported format %p4cc for gamma correction\n", + &format->format); + break; } } @@ -914,7 +935,11 @@ mgag200_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, if (mdev->type == G200_WB || mdev->type == G200_EW3) mgag200_g200wb_release_bmc(mdev); - mga_crtc_load_lut(crtc); + if (crtc_state->gamma_lut) + mgag200_crtc_set_gamma(mdev, fb->format, crtc_state->gamma_lut->data); + else + mgag200_crtc_set_gamma_linear(mdev, fb->format); + mgag200_enable_display(mdev); mgag200_handle_damage(mdev, fb, &fullscreen, &shadow_plane_state->data[0]); @@ -965,6 +990,14 @@ mgag200_simple_display_pipe_check(struct drm_simple_display_pipe *pipe, return ret; } + if (crtc_state->color_mgmt_changed && crtc_state->gamma_lut) { + if (crtc_state->gamma_lut->length != + MGAG200_LUT_SIZE * sizeof(struct drm_color_lut)) { + drm_err(dev, "Wrong size for gamma_lut %zu\n", + crtc_state->gamma_lut->length); + return -EINVAL; + } + } return 0; } @@ -973,6 +1006,7 @@ mgag200_simple_display_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_state) { struct drm_plane *plane = &pipe->plane; + struct drm_crtc *crtc = &pipe->crtc; struct drm_device *dev = plane->dev; struct mga_device *mdev = to_mga_device(dev); struct drm_plane_state *state = plane->state; @@ -986,6 +1020,9 @@ mgag200_simple_display_pipe_update(struct drm_simple_display_pipe *pipe, mutex_lock(&mdev->rmmio_lock); + if (crtc->state->color_mgmt_changed && crtc->state->gamma_lut) + mgag200_crtc_set_gamma(mdev, fb->format, crtc->state->gamma_lut->data); + drm_atomic_helper_damage_iter_init(&iter, old_state, state); drm_atomic_for_each_plane_damage(&iter, &damage) { mgag200_handle_damage(mdev, fb, &damage, &shadow_plane_state->data[0]); @@ -1139,9 +1176,11 @@ int mgag200_modeset_init(struct mga_device *mdev) drm_plane_enable_fb_damage_clips(&pipe->plane); - /* FIXME: legacy gamma tables; convert to CRTC state */ + /* FIXME: legacy gamma tables, but atomic gamma doesn't work without */ drm_mode_crtc_set_gamma_size(&pipe->crtc, MGAG200_LUT_SIZE); + drm_crtc_enable_color_mgmt(&pipe->crtc, 0, false, MGAG200_LUT_SIZE); + drm_mode_config_reset(dev); return 0;