From patchwork Mon Aug 29 13:11:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 12957944 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 D517DECAAD5 for ; Mon, 29 Aug 2022 13:45:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=W005D2OvGfOJIqiMKbqquKoPiZ+zK9g05wCT7otvi+I=; b=0oJtab0R4hr6bS yc4p8ojqOOirmpAi+DNLjrYuM05xDhdUfvJsNXQTeRY73t5HZnt+jmKZpy7J+VHZvrxGE16PgVyRL DEnnoB7rJhqmJ02hUDE1EO6G/K0rDc7VBDIsIGQX0W3fd7oBBR8m9n6a/mAFi6VBfTkr31fDsaDWQ meFIjB0Bhj/+mkGvNhdw87re8m7f5aL/+BUdEUxboPPPOG1LLIBvweVHWjqqa71unH2y1h2Zot29q JfoPTcp7rZ8rcKXxfjk9Iece0WAZskB+FOOt5V+rg3XLHcS+nRG0irwmwI1Ov6uDbe4x/04vJmSbw whpsQPxYkC1BuIVHkXEg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oSf3S-00Ao4c-Ge; Mon, 29 Aug 2022 13:43:55 +0000 Received: from wnew2-smtp.messagingengine.com ([64.147.123.27]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oSec6-00AbQY-9r for linux-arm-kernel@lists.infradead.org; Mon, 29 Aug 2022 13:15:42 +0000 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailnew.west.internal (Postfix) with ESMTP id 12B562B0607E; Mon, 29 Aug 2022 09:15:34 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Mon, 29 Aug 2022 09:15:37 -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=fm3; t=1661778934; x= 1661786134; bh=d74tP5iKS7wtiPkK9wp1T9Mx2zT0b5CzIXUZcq4F8kI=; b=h hmqCHmZ05R8wz+RuLpvYze/OuKbUQBZI6ODYaQ2icBRLaWjy9ut20laMImXzxxZ4 gR8SbG8q9Wnl34FzAYNXpuEZq8XTJBFFDwdTfd+PJRzyfSjtIZZoYyTRBbsgST0u WGSM1qYclKIyaI0JV5GhFcgEnxJ/wWcQQhstysIk5bTZeCndv3a11DpSU6zg3mfF vLYMXK7f/o34Qf8ZnlfBHkZPKqxplN1J1X6KJDlpEZberhgnRFjqrZ2nfp+vvIjG x2xauzJqL4TZSk+zIPKzkUCvqDY+0cf7FmQHqkbTM4B0lFmtUEHRipFEYABLEk/N tSpBeOCVzRNhCt8xV7jfg== 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=fm1; t=1661778934; x= 1661786134; bh=d74tP5iKS7wtiPkK9wp1T9Mx2zT0b5CzIXUZcq4F8kI=; b=m iM7JFVLOyjTjTvHinPsieIVJaGVBDCJy42PVT9KM+0KUBAkqAazD5tBHJOYXx6jq QhPYYSrffDJ1FhpJvJs5u4AOlB03mPNM4YKnGREKhG1qFmSalR78a8aM0YtDcs/c Bg/oqPDjwfS9UBGT8lUQBtTaktQS4yEtfmXLwUlLwo2sGm6kECR3Gny9Pev5vokX bo/cM1C6qg1rOciX6Ef9whhvkRpJoaIYZkj2uELz9lpXV7KvBr6Igea8MOz46lOB BRj7aaDc11RmsqSytkSauWpLQRbkS6KEUBlol/yJuaqYS9mL9ZQP2Z+oqQraCIGa 1gL9ol+cLeNKaH/iPQfYw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedrvdekuddgieefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkofgjfhggtgfogfesthhqredtredtjeenucfhrhhomhepofgr gihimhgvucftihhprghrugcuoehmrgigihhmvgestggvrhhnohdrthgvtghhqeenucggtf frrghtthgvrhhnpeefiedvfefggffgffehveejieffuddtgffhjefggeetieduvdeileet lefgveegtdenucevlhhushhtvghrufhiiigvpeehnecurfgrrhgrmhepmhgrihhlfhhroh hmpehmrgigihhmvgestggvrhhnohdrthgvtghh X-ME-Proxy: Feedback-ID: i8771445c:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 29 Aug 2022 09:15:32 -0400 (EDT) From: Maxime Ripard To: Maxime Ripard , Ben Skeggs , David Airlie , Chen-Yu Tsai , Thomas Zimmermann , Jani Nikula , Lyude Paul , Philipp Zabel , Maarten Lankhorst , Rodrigo Vivi , Tvrtko Ursulin , Jernej Skrabec , Samuel Holland , Karol Herbst , =?utf-8?q?Noralf_Tr=C3=B8nnes?= , Emma Anholt , Daniel Vetter , Joonas Lahtinen Cc: Maxime Ripard , Hans de Goede , linux-arm-kernel@lists.infradead.org, Phil Elwell , intel-gfx@lists.freedesktop.org, Dave Stevenson , dri-devel@lists.freedesktop.org, Dom Cobley , linux-kernel@vger.kernel.org, nouveau@lists.freedesktop.org, linux-sunxi@lists.linux.dev, Mateusz Kwiatkowski , Geert Uytterhoeven Subject: [PATCH v2 32/41] drm/vc4: vec: Convert to the new TV mode property Date: Mon, 29 Aug 2022 15:11:46 +0200 Message-Id: <20220728-rpi-analog-tv-properties-v2-32-459522d653a7@cerno.tech> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220728-rpi-analog-tv-properties-v2-0-459522d653a7@cerno.tech> References: <20220728-rpi-analog-tv-properties-v2-0-459522d653a7@cerno.tech> MIME-Version: 1.0 X-Mailer: b4 0.10.0-dev-65ba7 X-Developer-Signature: v=1; a=openpgp-sha256; l=9147; i=maxime@cerno.tech; h=from:subject:message-id; bh=lcNmN9CzcnK3ui/H7KmOX4lEfytOWT0LrcJRB2J9u68=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDMk8uxTCUu9d4nvW1XSQx+qrpzdD6v0fTlN3fph7xXrHTucb X2bldZSyMIhxMciKKbLECJsviTs163UnG988mDmsTCBDGLg4BWAie2Yw/E9k+ZLc/SlU+PSVj51eXu ZNlkrHOQwVA9+d4XiZcGHJgVhGhr//uV81tiXNFDscaOMbuHL1hMg+a/5n178/X+9rK1YwhxUA X-Developer-Key: i=maxime@cerno.tech; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220829_061538_479963_9FA8451A X-CRM114-Status: GOOD ( 15.37 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.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 ba6f81908923..58286acf4b9e 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 *legacy_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_MODE_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_MODE_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_MODE_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_MODE_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,19 +292,98 @@ static 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; + int count = 0; - mode = drm_mode_duplicate(connector->dev, - vc4_vec_tv_modes[state->tv.mode].mode); + mode = drm_mode_analog_ntsc_480i(connector->dev); if (!mode) { DRM_ERROR("Failed to create a new display mode\n"); return -ENOMEM; } drm_mode_probed_add(connector, mode); + count += 1; - return 1; + mode = drm_mode_analog_pal_576i(connector->dev); + if (!mode) { + DRM_ERROR("Failed to create a new display mode\n"); + return -ENOMEM; + } + + drm_mode_probed_add(connector, mode); + count += 1; + + return count; +} + +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->legacy_tv_mode_property) + return -EINVAL; + + switch (val) { + case VC4_VEC_TV_MODE_NTSC: + state->tv.mode = DRM_MODE_TV_MODE_NTSC_M; + break; + + case VC4_VEC_TV_MODE_NTSC_J: + state->tv.mode = DRM_MODE_TV_MODE_NTSC_J; + break; + + case VC4_VEC_TV_MODE_PAL: + state->tv.mode = DRM_MODE_TV_MODE_PAL_B; + break; + + case VC4_VEC_TV_MODE_PAL_M: + state->tv.mode = DRM_MODE_TV_MODE_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->legacy_tv_mode_property) + return -EINVAL; + + switch (state->tv.mode) { + case DRM_MODE_TV_MODE_NTSC_J: + *val = VC4_VEC_TV_MODE_NTSC_J; + break; + + case DRM_MODE_TV_MODE_NTSC_M: + *val = VC4_VEC_TV_MODE_NTSC; + break; + + case DRM_MODE_TV_MODE_PAL_B: + *val = VC4_VEC_TV_MODE_PAL; + break; + + case DRM_MODE_TV_MODE_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 = { @@ -283,15 +392,19 @@ static const struct drm_connector_funcs vc4_vec_connector_funcs = { .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 +417,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.legacy_tv_mode_property, - VC4_VEC_TV_MODE_NTSC); + dev->mode_config.tv_mode_property, + DRM_MODE_TV_MODE_NTSC_M); + + prop = drm_property_create_enum(dev, 0, "mode", + tv_mode_names, ARRAY_SIZE(tv_mode_names)); + if (!prop) + return -ENOMEM; + vec->legacy_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 +473,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.mode); + 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 +559,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 +600,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); @@ -506,9 +607,11 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data) struct vc4_vec *vec; int ret; - ret = drm_mode_create_tv_properties_legacy(drm, - ARRAY_SIZE(tv_mode_names), - tv_mode_names); + ret = drm_mode_create_tv_properties(drm, + BIT(DRM_MODE_TV_MODE_NTSC_J) | + BIT(DRM_MODE_TV_MODE_NTSC_M) | + BIT(DRM_MODE_TV_MODE_PAL_B) | + BIT(DRM_MODE_TV_MODE_PAL_M)); if (ret) return ret;