Received: by 2002:ac0:e350:0:0:0:0:0 with SMTP id g16csp397129imn; Fri, 29 Jul 2022 10:10:00 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tfMfiYXKMIBX3XRKkG6eopTLEPrjs+lA/0Cry9bwLNh7GEeP3WiRESgkfKh3N2NNi4j0DK X-Received: by 2002:a05:6402:28ca:b0:43b:5235:f325 with SMTP id ef10-20020a05640228ca00b0043b5235f325mr4408515edb.320.1659114599826; Fri, 29 Jul 2022 10:09:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659114599; cv=none; d=google.com; s=arc-20160816; b=QbvLt/yXJqXCxoywaWb7247+ldcOQ9NW3GcjzWc6kXd2KW5DqanSWddFcXvdM25blU i0SLNcFPh2TsPydRsJ4j7QjMe+gENGteqYujI7XsXHkm/bLSSeRycs3ISTDdRo8wzFs1 MEemVxPssnlQDlE8rqtnvzE3p5yGcP/vq0Yt82JbI05FXqgxf97JTCydLXqZ3L2GJQGG YHoJqLcXk0QyDkQM6Fr6F+snysku+jf7fsIGYoEzvGKLwKvgmSviMf6JMhSHp3YaUzdE 0lbsUOxscTfk1RaIIU4CDtjy6YAkDJZBPhqZY4gCzRvKFWGMGRryINXUMjmmKyvuhc86 9hAQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :feedback-id:dkim-signature:dkim-signature; bh=dD15BsyaW+QYuCRJy0566Klym6N86DYmjmb7CUM9paU=; b=LSBdmpbR8i9VdwRUtkSzaxTBTTMtPLu9uqCFzdhC7jGiSmgNQSbaauJ7C238TluPaX sl0BhySwQD0/zmneE9hAxti/Yp7ZQUaDErDyYVJgJSaW0neohJGoTIxOhysO7LlciYIP mz2kzetlbx22aBBAXmA3OWWXYTRxx1zux8XOKfYSj08LgnLvfjSMTrz3kogYaHIeaE/r iEXiqGwUkl+AjymMLmJTIP2By++FEfJRjCYy0zurteG7yMl9EpyROw2KQaKem26BzmTt d8SiVBoKv4aTrFMpSL0a1NlVtZ5PGOyYy+Je3sklpGNgXQjAPTxb4QzgzJYap8iTJSAx J5Iw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cerno.tech header.s=fm2 header.b=KnhzlrBx; dkim=pass header.i=@messagingengine.com header.s=fm3 header.b=HkbBuOhv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cerno.tech Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id gh4-20020a170906e08400b0072a84044156si3206412ejb.849.2022.07.29.10.09.33; Fri, 29 Jul 2022 10:09:59 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@cerno.tech header.s=fm2 header.b=KnhzlrBx; dkim=pass header.i=@messagingengine.com header.s=fm3 header.b=HkbBuOhv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cerno.tech Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237507AbiG2QhJ (ORCPT + 99 others); Fri, 29 Jul 2022 12:37:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237346AbiG2Qgw (ORCPT ); Fri, 29 Jul 2022 12:36:52 -0400 Received: from new4-smtp.messagingengine.com (new4-smtp.messagingengine.com [66.111.4.230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4CB6482387 for ; Fri, 29 Jul 2022 09:36:51 -0700 (PDT) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailnew.nyi.internal (Postfix) with ESMTP id 9FF5C580983; Fri, 29 Jul 2022 12:36:50 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Fri, 29 Jul 2022 12:36:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cerno.tech; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm2; t=1659112610; x= 1659119810; bh=dD15BsyaW+QYuCRJy0566Klym6N86DYmjmb7CUM9paU=; b=K nhzlrBxfUUd1K/1TuWkR96avuQ1TLBjYHqrTJVh9vruWcIdT8DFIXwHA3O+Otkgt pf9FCPitdrSn37+AFLC41/f8Is+aBkYG49dJSq+5SkBAFkpzydY0LsgFahyX9aUc g7Avyv/lD3TkQlP0Pr6UIa3ltFonSjjyktdwUwT7i9DFnR/jbZQ+JzUhW3BbL9YA 0KSba565BU+hgL4TNxPnAvTRxxm6wIDpKWKek0eTE76DIEsHQr2QPb81YMVlFcSP ictHWUsMXA4fwaxlayPUM3GDaVuMy9arQsvS2AtniAa+tObdmjZVPuB9t196c1wc DXu8fZmfQcBNp3vintMLg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t=1659112610; x= 1659119810; bh=dD15BsyaW+QYuCRJy0566Klym6N86DYmjmb7CUM9paU=; b=H kbBuOhvcwuN5+39NeHRO+OUxvf0oqmIxyg9HgXF6caUY/HbrVYX5dYsFhNurhTtc 3cNAkDU9Yilq8E6WEQpD2vB/T+cMH5SGbFExDP/hX+uNZ0p3fBqS1erAkaqbZCcM SJNgd/X1C+7pwvWByiVc/4+md24eheKr/mhAG1NqD0VA5Fw9AyhNxKvXZLB+upDr Y57tm8LHX26ZdRB2YqlSdKoUcCluUqSfVkA7sm9wp4OMY29amrcuFBB7Lr5t+nvS zbLnhnbA3OQJH+8iuU4goFfmg56J/OkjE32GB2KadOMa2lvEbUCyYHESsc5qHTDd pRLudDzNPL8nlKfjCgFJg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedrvddujedguddtfecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpefhvfevufffkffojghfgggtoffgsehtkeertdertdejnecuhfhrohhmpefo rgigihhmvgcutfhiphgrrhguuceomhgrgihimhgvsegtvghrnhhordhtvggthheqnecugg ftrfgrthhtvghrnhepgfffgfetffduudelhfevieffffduleevgfegkeeutefgffejheel leekjeefhfejnecuvehluhhsthgvrhfuihiivgepieenucfrrghrrghmpehmrghilhhfrh homhepmhgrgihimhgvsegtvghrnhhordhtvggthh X-ME-Proxy: Feedback-ID: i8771445c:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Fri, 29 Jul 2022 12:36:49 -0400 (EDT) From: Maxime Ripard To: Jernej Skrabec , Martin Blumenstingl , Chen-Yu Tsai , Philipp Zabel , Jerome Brunet , Samuel Holland , Thomas Zimmermann , Daniel Vetter , Emma Anholt , David Airlie , Maarten Lankhorst , =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= , Kevin Hilman , Neil Armstrong , Maxime Ripard Cc: Maxime Ripard , linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, Phil Elwell , Mateusz Kwiatkowski , linux-arm-kernel@lists.infradead.org, Geert Uytterhoeven , Dave Stevenson , linux-amlogic@lists.infradead.org, dri-devel@lists.freedesktop.org, Dom Cobley Subject: [PATCH v1 23/35] drm/vc4: vec: Convert to the new TV mode property Date: Fri, 29 Jul 2022 18:35:06 +0200 Message-Id: <20220728-rpi-analog-tv-properties-v1-23-3d53ae722097@cerno.tech> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220728-rpi-analog-tv-properties-v1-0-3d53ae722097@cerno.tech> References: <20220728-rpi-analog-tv-properties-v1-0-3d53ae722097@cerno.tech> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" X-Mailer: b4 0.10.0-dev-49460 X-Developer-Signature: v=1; a=openpgp-sha256; l=9047; i=maxime@cerno.tech; h=from:subject:message-id; bh=5OWHqL1TWqDdRNr5zwS2Im5z29Ujg+Vg5EAQgi/glLg=; b=owGbwMvMwCHc4XzqmfnC7acZT6slMSQ94VFqFPgmoObB4/Co1Hz9h6DHW6bZba2fV7deuOiFS/mU S6z8HaUsDMIcDLJiiizXBd/a8YVFuUXwfNgMM4eVCWQIAxenAExEypyRYV3Qw5fy2iyf62WdzRb5Kl 4Ke2ze5TLvcpj1n8C7ZxP8ljIyHPVUTrNc4pfV6/xxe4qAQlfZ6qpkQ/0Xx/QTlA9V3G4VAQA= X-Developer-Key: i=maxime@cerno.tech; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Now that the core can deal fine with analog TV modes, let's convert the vc4 VEC driver to leverage those new features. We've added some backward compatibility to support the old TV mode property and translate it into the new TV norm property. Signed-off-by: Maxime Ripard diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c index 6f4536bf537f..e40b55de1b3c 100644 --- a/drivers/gpu/drm/vc4/vc4_vec.c +++ b/drivers/gpu/drm/vc4/vc4_vec.c @@ -172,6 +172,8 @@ struct vc4_vec { struct clk *clock; + struct drm_property *tv_mode_property; + struct debugfs_regset32 regset; }; @@ -184,6 +186,12 @@ encoder_to_vc4_vec(struct drm_encoder *encoder) return container_of(encoder, struct vc4_vec, encoder.base); } +static inline struct vc4_vec * +connector_to_vc4_vec(struct drm_connector *connector) +{ + return container_of(connector, struct vc4_vec, connector); +} + enum vc4_vec_tv_mode_id { VC4_VEC_TV_MODE_NTSC, VC4_VEC_TV_MODE_NTSC_J, @@ -192,7 +200,7 @@ enum vc4_vec_tv_mode_id { }; struct vc4_vec_tv_mode { - const struct drm_display_mode *mode; + unsigned int mode; u32 config0; u32 config1; u32 custom_freq; @@ -226,28 +234,50 @@ static const struct debugfs_reg32 vec_regs[] = { }; static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = { - [VC4_VEC_TV_MODE_NTSC] = { - .mode = &drm_mode_480i, + { + .mode = DRM_MODE_TV_NORM_NTSC_M, .config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN, .config1 = VEC_CONFIG1_C_CVBS_CVBS, }, - [VC4_VEC_TV_MODE_NTSC_J] = { - .mode = &drm_mode_480i, + { + .mode = DRM_MODE_TV_NORM_NTSC_J, .config0 = VEC_CONFIG0_NTSC_STD, .config1 = VEC_CONFIG1_C_CVBS_CVBS, }, - [VC4_VEC_TV_MODE_PAL] = { - .mode = &drm_mode_576i, + { + .mode = DRM_MODE_TV_NORM_PAL_B, .config0 = VEC_CONFIG0_PAL_BDGHI_STD, .config1 = VEC_CONFIG1_C_CVBS_CVBS, }, - [VC4_VEC_TV_MODE_PAL_M] = { - .mode = &drm_mode_480i, + { + .mode = DRM_MODE_TV_NORM_PAL_M, .config0 = VEC_CONFIG0_PAL_M_STD, .config1 = VEC_CONFIG1_C_CVBS_CVBS, }, }; +static inline const struct vc4_vec_tv_mode * +vc4_vec_tv_mode_lookup(unsigned int mode) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(vc4_vec_tv_modes); i++) { + const struct vc4_vec_tv_mode *tv_mode = &vc4_vec_tv_modes[i]; + + if (tv_mode->mode == mode) + return tv_mode; + } + + return NULL; +} + +static const struct drm_prop_enum_list tv_mode_names[] = { + { VC4_VEC_TV_MODE_NTSC, "NTSC", }, + { VC4_VEC_TV_MODE_NTSC_J, "NTSC-J", }, + { VC4_VEC_TV_MODE_PAL, "PAL", }, + { VC4_VEC_TV_MODE_PAL_M, "PAL-M", }, +}; + static enum drm_connector_status vc4_vec_connector_detect(struct drm_connector *connector, bool force) { @@ -262,11 +292,17 @@ void vc4_vec_connector_reset(struct drm_connector *connector) static int vc4_vec_connector_get_modes(struct drm_connector *connector) { - struct drm_connector_state *state = connector->state; struct drm_display_mode *mode; - mode = drm_mode_duplicate(connector->dev, - vc4_vec_tv_modes[state->tv.mode].mode); + mode = drm_mode_duplicate(connector->dev, &drm_mode_480i); + if (!mode) { + DRM_ERROR("Failed to create a new display mode\n"); + return -ENOMEM; + } + + drm_mode_probed_add(connector, mode); + + mode = drm_mode_duplicate(connector->dev, &drm_mode_576i); if (!mode) { DRM_ERROR("Failed to create a new display mode\n"); return -ENOMEM; @@ -277,21 +313,95 @@ static int vc4_vec_connector_get_modes(struct drm_connector *connector) return 1; } +static int +vc4_vec_connector_set_property(struct drm_connector *connector, + struct drm_connector_state *state, + struct drm_property *property, + uint64_t val) +{ + struct vc4_vec *vec = connector_to_vc4_vec(connector); + + if (property != vec->tv_mode_property) + return -EINVAL; + + switch (val) { + case VC4_VEC_TV_MODE_NTSC: + state->tv.norm = DRM_MODE_TV_NORM_NTSC_M; + break; + + case VC4_VEC_TV_MODE_NTSC_J: + state->tv.norm = DRM_MODE_TV_NORM_NTSC_J; + break; + + case VC4_VEC_TV_MODE_PAL: + state->tv.norm = DRM_MODE_TV_NORM_PAL_B; + break; + + case VC4_VEC_TV_MODE_PAL_M: + state->tv.norm = DRM_MODE_TV_NORM_PAL_M; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int +vc4_vec_connector_get_property(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val) +{ + struct vc4_vec *vec = connector_to_vc4_vec(connector); + + if (property != vec->tv_mode_property) + return -EINVAL; + + switch (state->tv.norm) { + case DRM_MODE_TV_NORM_NTSC_J: + *val = VC4_VEC_TV_MODE_NTSC_J; + break; + + case DRM_MODE_TV_NORM_NTSC_M: + *val = VC4_VEC_TV_MODE_NTSC; + break; + + case DRM_MODE_TV_NORM_PAL_B: + *val = VC4_VEC_TV_MODE_PAL; + break; + + case DRM_MODE_TV_NORM_PAL_M: + *val = VC4_VEC_TV_MODE_PAL_M; + break; + + default: + return -EINVAL; + } + + return 0; +} + static const struct drm_connector_funcs vc4_vec_connector_funcs = { .detect = vc4_vec_connector_detect, .fill_modes = drm_helper_probe_single_connector_modes, .reset = vc4_vec_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, + .atomic_get_property = vc4_vec_connector_get_property, + .atomic_set_property = vc4_vec_connector_set_property, }; static const struct drm_connector_helper_funcs vc4_vec_connector_helper_funcs = { + .atomic_check = drm_atomic_helper_connector_tv_check, .get_modes = vc4_vec_connector_get_modes, }; static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec) { struct drm_connector *connector = &vec->connector; + struct drm_property *prop; int ret; connector->interlace_allowed = true; @@ -304,8 +414,16 @@ static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec) drm_connector_helper_add(connector, &vc4_vec_connector_helper_funcs); drm_object_attach_property(&connector->base, - dev->mode_config.tv_mode_property, - VC4_VEC_TV_MODE_NTSC); + dev->mode_config.tv_norm_property, + DRM_MODE_TV_NORM_NTSC_M); + + prop = drm_property_create_enum(dev, 0, "mode", + tv_mode_names, ARRAY_SIZE(tv_mode_names)); + if (!prop) + return -ENOMEM; + vec->tv_mode_property = prop; + + drm_object_attach_property(&connector->base, prop, VC4_VEC_TV_MODE_NTSC); drm_connector_attach_encoder(connector, &vec->encoder.base); @@ -352,13 +470,16 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder, struct drm_connector *connector = &vec->connector; struct drm_connector_state *conn_state = drm_atomic_get_new_connector_state(state, connector); - const struct vc4_vec_tv_mode *tv_mode = - &vc4_vec_tv_modes[conn_state->tv.mode]; + const struct vc4_vec_tv_mode *tv_mode; int idx, ret; if (!drm_dev_enter(drm, &idx)) return; + tv_mode = vc4_vec_tv_mode_lookup(conn_state->tv.norm); + if (!tv_mode) + goto err_dev_exit; + ret = pm_runtime_get_sync(&vec->pdev->dev); if (ret < 0) { DRM_ERROR("Failed to retain power domain: %d\n", ret); @@ -435,23 +556,7 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder, drm_dev_exit(idx); } -static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) -{ - const struct vc4_vec_tv_mode *vec_mode; - - vec_mode = &vc4_vec_tv_modes[conn_state->tv.mode]; - - if (conn_state->crtc && - !drm_mode_equal(vec_mode->mode, &crtc_state->adjusted_mode)) - return -EINVAL; - - return 0; -} - static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = { - .atomic_check = vc4_vec_encoder_atomic_check, .atomic_disable = vc4_vec_encoder_disable, .atomic_enable = vc4_vec_encoder_enable, }; @@ -492,13 +597,6 @@ static const struct of_device_id vc4_vec_dt_match[] = { { /* sentinel */ }, }; -static const char * const tv_mode_names[] = { - [VC4_VEC_TV_MODE_NTSC] = "NTSC", - [VC4_VEC_TV_MODE_NTSC_J] = "NTSC-J", - [VC4_VEC_TV_MODE_PAL] = "PAL", - [VC4_VEC_TV_MODE_PAL_M] = "PAL-M", -}; - static int vc4_vec_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); @@ -507,9 +605,11 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data) int ret; ret = drm_mode_create_tv_properties(drm, - 0, - ARRAY_SIZE(tv_mode_names), - tv_mode_names); + DRM_MODE_TV_NORM_NTSC_J | + DRM_MODE_TV_NORM_NTSC_M | + DRM_MODE_TV_NORM_PAL_B | + DRM_MODE_TV_NORM_PAL_M, + 0, NULL); if (ret) return ret; -- b4 0.10.0-dev-49460