From patchwork Thu Sep 22 14:25:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 12985287 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 438BDC54EE9 for ; Thu, 22 Sep 2022 14:29:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5E24D10EBC2; Thu, 22 Sep 2022 14:29:41 +0000 (UTC) Received: from wnew4-smtp.messagingengine.com (wnew4-smtp.messagingengine.com [64.147.123.18]) by gabe.freedesktop.org (Postfix) with ESMTPS id 73F0E10EBC4; Thu, 22 Sep 2022 14:29:36 +0000 (UTC) Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailnew.west.internal (Postfix) with ESMTP id 322DB2B05B40; Thu, 22 Sep 2022 10:29:33 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute2.internal (MEProxy); Thu, 22 Sep 2022 10:29:35 -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=1663856972; x= 1663864172; bh=YFRn0O6fdeTj6hsCk5Z7dc6Lkrxw4LhpsyxdMerwZXg=; b=L WQNfRdCEBX9MKVUErJgto0hC+hCYuq2o37GIUzysepfZ5wTuGI6uDaPsEo4hA/u5 EDmSsHIcB0+03x6+InXdYKMnuzr5mWrkj6PgkyWRf2lieKlpAx/tzoelwQy5kILy U7m+jCC9gFVaQ4cqrE7BDOFC9zgRrwimSvrGe0Aj6LCFkallEuWa1ckjzFk1Taca HXVoeBxauPMj+SEA2SrhO1MobST2mO2/VoiWxnql0xkSda56mi7UCIiFyMyw08I+ wBLL91ZEM9zLF9EVSs/zU6GZK12s4zGTkBrnmhe65TX0jvYzJFq4ZLQ2CZHtkHsm yMHwD7QCt0RBHCj8KjYTw== 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=fm2; t=1663856972; x= 1663864172; bh=YFRn0O6fdeTj6hsCk5Z7dc6Lkrxw4LhpsyxdMerwZXg=; b=e QdzQhjo7hp3ANFOsXE+dly/+ZxxC108Dv0cwA0qfWj4SGSsh16Xd1oXHzTnYmj03 MCIKNdJJhlU9NdVnALHxUXrunQp9g8XjbWB3Q7ZVn1U5E+fPavzlUqQEGHLOcI27 eE+QJSK67qH/mJ1ZP6/TPFkNN5rkFgRyK/Bv4RDBNRRduptJ3gJ3TFporXVcwu4V PNSSU3Hbl0bp8b4s95Bp/WnJOet4CMwWIdqG1gwMoQo0cn0eBOHSIRpmD+sa+zmS 9fyXAvr/HvWEdQ/oHSQGgf7Y/igT17P2688fQT2fnRB8r0bVJDWIVRTe6TU0IaPh c4huaoOJZwoUsGDncnAeA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedrfeefgedgudekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephfffufggtgfgkfhfjgfvvefosehtkeertdertdejnecuhfhrohhmpeforgig ihhmvgcutfhiphgrrhguuceomhgrgihimhgvsegtvghrnhhordhtvggthheqnecuggftrf grthhtvghrnhepudduudfhveejteefgedvffdvvedvjedugedukeejhedtlefhffevtefh jeeltdevnecuvehluhhsthgvrhfuihiivgepudenucfrrghrrghmpehmrghilhhfrhhomh epmhgrgihimhgvsegtvghrnhhordhtvggthh X-ME-Proxy: Feedback-ID: i8771445c:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 22 Sep 2022 10:29:31 -0400 (EDT) From: Maxime Ripard Date: Thu, 22 Sep 2022 16:25:50 +0200 MIME-Version: 1.0 Message-Id: <20220728-rpi-analog-tv-properties-v2-33-f733a0ed9f90@cerno.tech> References: <20220728-rpi-analog-tv-properties-v2-0-f733a0ed9f90@cerno.tech> In-Reply-To: <20220728-rpi-analog-tv-properties-v2-0-f733a0ed9f90@cerno.tech> To: Jernej Skrabec , Rodrigo Vivi , Ben Skeggs , David Airlie , Maxime Ripard , Joonas Lahtinen , Emma Anholt , Karol Herbst , Samuel Holland , Jani Nikula , Thomas Zimmermann , Daniel Vetter , Lyude Paul , Maarten Lankhorst , Tvrtko Ursulin , Chen-Yu Tsai X-Mailer: b4 0.10.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=8558; i=maxime@cerno.tech; h=from:subject:message-id; bh=Mfq/57nRwG95ttN/MIZw6AtSRZdBflD/eUn6vPpPiGE=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDMk6BUGb2s5c2luxfYHtdjlJkRvbRVltGkQqF8pteO+p862F bdW1jlIWBjEuBlkxRZYYYfMlcadmve5k45sHM4eVCWQIAxenAExk9TdGhtV3rE64axpPMWXyPtdQ43 v7bbFte8q/ToMdr5cUcJ3vLGD4X73HcsWvBe79v8x1m/78q83uitQ7NTP8z3sD/gnr9ogJcQEA X-Developer-Key: i=maxime@cerno.tech; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D Subject: [Intel-gfx] [PATCH v2 33/33] drm/sun4i: tv: Convert to the new TV mode property X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?unknown-8bit?q?Dom_Cobley_=3Cdom=40raspberrypi=2Ecom=3E=2C_Dave_Steven?= =?unknown-8bit?q?son_=3Cdave=2Estevenson=40raspberrypi=2Ecom=3E=2C_nouveau?= =?unknown-8bit?q?=40lists=2Efreedesktop=2Eorg=2C_intel-gfx=40lists=2Efreede?= =?unknown-8bit?q?sktop=2Eorg=2C_linux-kernel=40vger=2Ekernel=2Eorg=2C_dri-d?= =?unknown-8bit?q?evel=40lists=2Efreedesktop=2Eorg=2C_linux-sunxi=40lists=2E?= =?unknown-8bit?q?linux=2Edev=2C_Noralf_Tr=C3=B8nnes_=3Cnoralf=40tronnes=2Eo?= =?unknown-8bit?q?rg=3E=2C_Geert_Uytterhoeven_=3Cgeert=40linux-m68k=2Eorg=3E?= =?unknown-8bit?q?=2C_Maxime_Ripard_=3Cmaxime=40cerno=2Etech=3E=2C_Mateusz_K?= =?unknown-8bit?q?wiatkowski_=3Ckfyatek+publicgit=40gmail=2Ecom=3E=2C_Phil_E?= =?unknown-8bit?q?lwell_=3Cphil=40raspberrypi=2Ecom=3E=2C_linux-arm-kernel?= =?unknown-8bit?q?=40lists=2Einfradead=2Eorg?= Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Now that the core can deal fine with analog TV modes, let's convert the sun4i TV driver to leverage those new features. Signed-off-by: Maxime Ripard diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c index 74ff5ad6a8b9..833742cee745 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tv.c +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c @@ -140,23 +140,14 @@ struct resync_parameters { struct tv_mode { char *name; + unsigned int tv_mode; + u32 mode; u32 chroma_freq; u16 back_porch; u16 front_porch; - u16 line_number; u16 vblank_level; - u32 hdisplay; - u16 hfront_porch; - u16 hsync_len; - u16 hback_porch; - - u32 vdisplay; - u16 vfront_porch; - u16 vsync_len; - u16 vback_porch; - bool yc_en; bool dac3_en; bool dac_bit25_en; @@ -212,7 +203,7 @@ static const struct resync_parameters pal_resync_parameters = { static const struct tv_mode tv_modes[] = { { - .name = "NTSC", + .tv_mode = DRM_MODE_TV_MODE_NTSC, .mode = SUN4I_TVE_CFG0_RES_480i, .chroma_freq = 0x21f07c1f, .yc_en = true, @@ -221,17 +212,6 @@ static const struct tv_mode tv_modes[] = { .back_porch = 118, .front_porch = 32, - .line_number = 525, - - .hdisplay = 720, - .hfront_porch = 18, - .hsync_len = 2, - .hback_porch = 118, - - .vdisplay = 480, - .vfront_porch = 26, - .vsync_len = 2, - .vback_porch = 17, .vblank_level = 240, @@ -241,23 +221,12 @@ static const struct tv_mode tv_modes[] = { .resync_params = &ntsc_resync_parameters, }, { - .name = "PAL", + .tv_mode = DRM_MODE_TV_MODE_PAL, .mode = SUN4I_TVE_CFG0_RES_576i, .chroma_freq = 0x2a098acb, .back_porch = 138, .front_porch = 24, - .line_number = 625, - - .hdisplay = 720, - .hfront_porch = 3, - .hsync_len = 2, - .hback_porch = 139, - - .vdisplay = 576, - .vfront_porch = 28, - .vsync_len = 2, - .vback_porch = 19, .vblank_level = 252, @@ -275,63 +244,21 @@ drm_encoder_to_sun4i_tv(struct drm_encoder *encoder) encoder); } -/* - * FIXME: If only the drm_display_mode private field was usable, this - * could go away... - * - * So far, it doesn't seem to be preserved when the mode is passed by - * to mode_set for some reason. - */ -static const struct tv_mode *sun4i_tv_find_tv_by_mode(const struct drm_display_mode *mode) +static const struct tv_mode * +sun4i_tv_find_tv_by_mode(unsigned int mode) { int i; - /* First try to identify the mode by name */ for (i = 0; i < ARRAY_SIZE(tv_modes); i++) { const struct tv_mode *tv_mode = &tv_modes[i]; - DRM_DEBUG_DRIVER("Comparing mode %s vs %s", - mode->name, tv_mode->name); - - if (!strcmp(mode->name, tv_mode->name)) - return tv_mode; - } - - /* Then by number of lines */ - for (i = 0; i < ARRAY_SIZE(tv_modes); i++) { - const struct tv_mode *tv_mode = &tv_modes[i]; - - DRM_DEBUG_DRIVER("Comparing mode %s vs %s (X: %d vs %d)", - mode->name, tv_mode->name, - mode->vdisplay, tv_mode->vdisplay); - - if (mode->vdisplay == tv_mode->vdisplay) + if (tv_mode->tv_mode == mode) return tv_mode; } return NULL; } -static void sun4i_tv_mode_to_drm_mode(const struct tv_mode *tv_mode, - struct drm_display_mode *mode) -{ - DRM_DEBUG_DRIVER("Creating mode %s\n", mode->name); - - mode->type = DRM_MODE_TYPE_DRIVER; - mode->clock = 13500; - mode->flags = DRM_MODE_FLAG_INTERLACE; - - mode->hdisplay = tv_mode->hdisplay; - mode->hsync_start = mode->hdisplay + tv_mode->hfront_porch; - mode->hsync_end = mode->hsync_start + tv_mode->hsync_len; - mode->htotal = mode->hsync_end + tv_mode->hback_porch; - - mode->vdisplay = tv_mode->vdisplay; - mode->vsync_start = mode->vdisplay + tv_mode->vfront_porch; - mode->vsync_end = mode->vsync_start + tv_mode->vsync_len; - mode->vtotal = mode->vsync_end + tv_mode->vback_porch; -} - static void sun4i_tv_disable(struct drm_encoder *encoder, struct drm_atomic_state *state) { @@ -355,7 +282,11 @@ static void sun4i_tv_enable(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, encoder->crtc); struct drm_display_mode *mode = &crtc_state->mode; - const struct tv_mode *tv_mode = sun4i_tv_find_tv_by_mode(mode); + struct drm_connector *connector = &tv->connector; + struct drm_connector_state *conn_state = + drm_atomic_get_new_connector_state(state, connector); + const struct tv_mode *tv_mode = + sun4i_tv_find_tv_by_mode(conn_state->tv.mode); DRM_DEBUG_DRIVER("Enabling the TV Output\n"); @@ -403,7 +334,7 @@ static void sun4i_tv_enable(struct drm_encoder *encoder, /* Set the lines setup */ regmap_write(tv->regs, SUN4I_TVE_LINE_REG, SUN4I_TVE_LINE_FIRST(22) | - SUN4I_TVE_LINE_NUMBER(tv_mode->line_number)); + SUN4I_TVE_LINE_NUMBER(mode->vtotal)); regmap_write(tv->regs, SUN4I_TVE_LEVEL_REG, SUN4I_TVE_LEVEL_BLANK(tv_mode->video_levels->blank) | @@ -466,35 +397,46 @@ static const struct drm_encoder_helper_funcs sun4i_tv_helper_funcs = { static int sun4i_tv_comp_get_modes(struct drm_connector *connector) { - int i; + struct drm_display_mode *mode; + int count = 0; - for (i = 0; i < ARRAY_SIZE(tv_modes); i++) { - struct drm_display_mode *mode; - const struct tv_mode *tv_mode = &tv_modes[i]; - - mode = drm_mode_create(connector->dev); - if (!mode) { - DRM_ERROR("Failed to create a new display mode\n"); - return 0; - } + mode = drm_mode_analog_ntsc_480i(connector->dev); + if (!mode) { + DRM_ERROR("Failed to create a new display mode\n"); + return -ENOMEM; + } - strcpy(mode->name, tv_mode->name); + mode->type |= DRM_MODE_TYPE_PREFERRED; + drm_mode_probed_add(connector, mode); + count += 1; - sun4i_tv_mode_to_drm_mode(tv_mode, mode); - drm_mode_probed_add(connector, mode); + mode = drm_mode_analog_pal_576i(connector->dev); + if (!mode) { + DRM_ERROR("Failed to create a new display mode\n"); + return -ENOMEM; } - return i; + drm_mode_probed_add(connector, mode); + count += 1; + + return count; } static const struct drm_connector_helper_funcs sun4i_tv_comp_connector_helper_funcs = { + .atomic_check = drm_atomic_helper_connector_tv_check, .get_modes = sun4i_tv_comp_get_modes, }; +static void sun4i_tv_connector_reset(struct drm_connector *connector) +{ + drm_atomic_helper_connector_reset(connector); + drm_atomic_helper_connector_tv_reset(connector); +} + static const struct drm_connector_funcs sun4i_tv_comp_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .destroy = drm_connector_cleanup, - .reset = drm_atomic_helper_connector_reset, + .reset = sun4i_tv_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; @@ -586,8 +528,20 @@ static int sun4i_tv_bind(struct device *dev, struct device *master, drm_connector_attach_encoder(&tv->connector, &tv->encoder); + ret = drm_mode_create_tv_properties(drm, + BIT(DRM_MODE_TV_MODE_NTSC) | + BIT(DRM_MODE_TV_MODE_PAL)); + if (ret) + goto err_cleanup_connector; + + drm_object_attach_property(&tv->connector.base, + drm->mode_config.tv_mode_property, + DRM_MODE_TV_MODE_NTSC); + return 0; +err_cleanup_connector: + drm_connector_cleanup(&tv->connector); err_cleanup_encoder: drm_encoder_cleanup(&tv->encoder); err_disable_clk: diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c index 0862462aa9e3..b9f7bd7b8b7a 100644 --- a/drivers/gpu/drm/vc4/vc4_vec.c +++ b/drivers/gpu/drm/vc4/vc4_vec.c @@ -322,7 +322,7 @@ vc4_vec_tv_mode_lookup(unsigned int mode) return NULL; } -static const struct drm_prop_enum_list tv_mode_names[] = { +static const struct drm_prop_enum_list legacy_tv_mode_names[] = { { VC4_VEC_TV_MODE_NTSC, "NTSC", }, { VC4_VEC_TV_MODE_NTSC_443, "NTSC-443", }, { VC4_VEC_TV_MODE_NTSC_J, "NTSC-J", }, @@ -501,7 +501,8 @@ static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec) DRM_MODE_TV_MODE_NTSC); prop = drm_property_create_enum(dev, 0, "mode", - tv_mode_names, ARRAY_SIZE(tv_mode_names)); + legacy_tv_mode_names, + ARRAY_SIZE(legacy_tv_mode_names)); if (!prop) return -ENOMEM; vec->legacy_tv_mode_property = prop;