Received: by 2002:ab2:7855:0:b0:1f9:5764:f03e with SMTP id m21csp172961lqp; Wed, 22 May 2024 00:25:06 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCWSmOI+tBuzzRVJ8250fcaTdBc27QfV/krSgF9UFrM0hkqP5RNJ2gE1OpENZNGPH1wVbfjfzP5jEW9ntyF3QhNPeQeKSgf+AZn0KjQSCA== X-Google-Smtp-Source: AGHT+IHnh+SZpfOFl+Itlqc+ZPaKGha0TfykA006nqjRWLgIS+WoIjZT/3MTA7Dt3DY6Cahd+0Uz X-Received: by 2002:a05:622a:18a8:b0:43a:f4e1:e8e8 with SMTP id d75a77b69052e-43f9e0571c2mr14475681cf.7.1716362705956; Wed, 22 May 2024 00:25:05 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1716362705; cv=pass; d=google.com; s=arc-20160816; b=qLWazXGue3ZDgzuKEZqQAIt3gKAJwD7sdLzr2RmbsZjcfP5+rXiLWZjBs33E4oVz9x B+PyYSQCKlvg88duN9antQGS2SeZh5pjUUxjFXxWKAo7rSPoPdnpXTPMH3rhBcZfvEzz CKagSvJpbA77Q75IzPAjUrq/WhH3hzGJcQSkB8TZjjK/KL0rZIZgAOx1trpgKWkIZ1MM M/L7hIbr2xNQdAjTuGWOYGN5e15dJeRwBfUESC4PXOIa/xELA/uT45z1cV8IHPVqYYUP fQ1Wu5H5pTJdAOi7EsJ/tqpJOrCnNXmPw7KC4JdkRnEz1MN+CFghbNKh7evqzcaB3rX9 8Kkw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=in-reply-to:content-disposition:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:message-id:subject:cc :to:from:date:dkim-signature; bh=O16hslwbm4lSR8pmt+KM2PjASGqiAmJ8QKWGcOS3jLQ=; fh=CEg7PTaULm+sdKo4bRw3E+ZnZu4bjHYmoUmLuTCVVpk=; b=svODYW48+MrK+zsIHyb9pCVdxBCdeVw5fAPJRmyQCVJJlq8wwtL5sLsYbkN3lFJhNa 2v1FVTUAacg5lKjL81Kee8F0IZ9bnP4WwGsxplUuih81CTSdH8Tb+RdE+lxtAzbDKPuL KHUI38kjXxMdnnY268x4TUKt5f90Ggmcj06RZbMx4qTwMfN7q1yTKa8YFZFzO0RZoF4u 9i1NLOhZrlPh9eoEbqMFhcJvUqjjmUBdcaUu2ciJA5DT5KYSHrHcup7wRH7nJy+Bck0w a4Thl8zrmAH8pryTzUTcCsaEpw0jSQTwtdT9rVVxybJUmm7fKcBgkMXUeJEkn99yNg48 hZKw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=pNjMpomt; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-185852-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-185852-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id d75a77b69052e-43df566fb78si50510521cf.271.2024.05.22.00.25.05 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 May 2024 00:25:05 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-185852-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=pNjMpomt; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-185852-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-185852-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 9EBD01C213C0 for ; Wed, 22 May 2024 07:25:05 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 40D877C6D4; Wed, 22 May 2024 07:24:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pNjMpomt" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ECD0179B84; Wed, 22 May 2024 07:24:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716362696; cv=none; b=joiSEaeRJTXEqVrSHb3x+mICPAuIORoe67iTF9wl9Jto1qAh5xot1c7FUT8fPU4EQchSZJs+mgHPzkZyEvLHCb9V7ieOYkqdKLWnVXpnCqfTHgJuJ+ZrVIkLj+nAjRU+kRGWf462a+WKsGIyqLyu15pgHWMD+WowFIA4tG8vwRc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716362696; c=relaxed/simple; bh=RpsenxW2up+GVmBDLm6Dft7F/NhXAT1mwDTvcipp7Z4=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=cPXwL03WBp+zAty242WP6gsrDnoucd+ZXIoocRwjfGiq8V0DCStVKnfJuZwNQ4U342M8jIQSbjVfhfpSgGvsiCha57Z6CsVhvkWkA9io4NzaUII7/qHZuYOcGXX3hMJPAWw68KqHh2sB99Hz5Ud8KYeCuTylZFLXZMGMvOsfF10= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pNjMpomt; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id EF7ABC2BD11; Wed, 22 May 2024 07:24:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716362695; bh=RpsenxW2up+GVmBDLm6Dft7F/NhXAT1mwDTvcipp7Z4=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=pNjMpomtvjQBv5Hjcg8V1knk5U1Ck3kyAAQp4cjLRRTanqbSYUMaj02eE4mjlpq3F HAznm5C5tJDnvm5TS+VET8UqIDlRhdIqIBWHdTrmINV0s4BY/Pfv/TrTNrBh9hKHTQ 5g9iAsOpw2ZNmIYrrq2KdlesxXzBsl8XW1yheNRucWLzxUkRTmCAXkkGsw9k0O0zPv Jle/fGczN58C6Yk61zkp9nuyyYkgpNFxjdBbBwFtsB7ojnkUft1m+zFSOLKUIKm564 5//jvMdcCydazkmRoxECUhk6h3VUi/dyJKfi8CjbO+hAhT0k+IDeH4jEDc6RDhf2fj 3HvC0AOE7IPow== Date: Wed, 22 May 2024 09:24:52 +0200 From: Maxime Ripard To: keith Cc: andrzej.hajda@intel.com, neil.armstrong@linaro.org, rfoss@kernel.org, Laurent.pinchart@ideasonboard.com, jonas@kwiboo.se, jernej.skrabec@gmail.com, maarten.lankhorst@linux.intel.com, tzimmermann@suse.de, airlied@gmail.com, daniel@ffwll.ch, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, hjc@rock-chips.com, heiko@sntech.de, andy.yan@rock-chips.com, xingyu.wu@starfivetech.com, p.zabel@pengutronix.de, jack.zhu@starfivetech.com, shengyang.chen@starfivetech.com, dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: Re: [PATCH v4 03/10] drm/rockchip:hdmi: migrate to use inno-hdmi bridge driver Message-ID: <20240522-opalescent-orchid-worm-2996ad@houat> References: <20240521105817.3301-1-keith.zhao@starfivetech.com> <20240521105817.3301-4-keith.zhao@starfivetech.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha384; protocol="application/pgp-signature"; boundary="sz2tqw6l7ovh4mjb" Content-Disposition: inline In-Reply-To: <20240521105817.3301-4-keith.zhao@starfivetech.com> --sz2tqw6l7ovh4mjb Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi, On Tue, May 21, 2024 at 06:58:10PM GMT, keith wrote: > Add the ROCKCHIP inno hdmi driver that uses the Inno DesignWare > HDMI TX bridge and remove the old separate one. >=20 > Signed-off-by: keith > --- > drivers/gpu/drm/rockchip/Kconfig | 1 + > drivers/gpu/drm/rockchip/Makefile | 2 +- > drivers/gpu/drm/rockchip/inno_hdmi-rockchip.c | 517 ++++++++ > .../{inno_hdmi.h =3D> inno_hdmi-rockchip.h} | 45 - > drivers/gpu/drm/rockchip/inno_hdmi.c | 1073 ----------------- > 5 files changed, 519 insertions(+), 1119 deletions(-) > create mode 100644 drivers/gpu/drm/rockchip/inno_hdmi-rockchip.c > rename drivers/gpu/drm/rockchip/{inno_hdmi.h =3D> inno_hdmi-rockchip.h} = (85%) > delete mode 100644 drivers/gpu/drm/rockchip/inno_hdmi.c >=20 > diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/= Kconfig > index 1bf3e2829cd0..cc6cfd5a30d6 100644 > --- a/drivers/gpu/drm/rockchip/Kconfig > +++ b/drivers/gpu/drm/rockchip/Kconfig > @@ -74,6 +74,7 @@ config ROCKCHIP_DW_MIPI_DSI > =20 > config ROCKCHIP_INNO_HDMI > bool "Rockchip specific extensions for Innosilicon HDMI" > + select DRM_INNO_HDMI > help > This selects support for Rockchip SoC specific extensions > for the Innosilicon HDMI driver. If you want to enable > diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip= /Makefile > index 3ff7b21c0414..4b2d0cba8db3 100644 > --- a/drivers/gpu/drm/rockchip/Makefile > +++ b/drivers/gpu/drm/rockchip/Makefile > @@ -12,7 +12,7 @@ rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) +=3D analogi= x_dp-rockchip.o > rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) +=3D cdn-dp-core.o cdn-dp-reg.o > rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) +=3D dw_hdmi-rockchip.o > rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) +=3D dw-mipi-dsi-rockchip.o > -rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) +=3D inno_hdmi.o > +rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) +=3D inno_hdmi-rockchip.o > rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) +=3D rockchip_lvds.o > rockchipdrm-$(CONFIG_ROCKCHIP_RGB) +=3D rockchip_rgb.o > rockchipdrm-$(CONFIG_ROCKCHIP_RK3066_HDMI) +=3D rk3066_hdmi.o > diff --git a/drivers/gpu/drm/rockchip/inno_hdmi-rockchip.c b/drivers/gpu/= drm/rockchip/inno_hdmi-rockchip.c > new file mode 100644 > index 000000000000..69d0e913e13b > --- /dev/null > +++ b/drivers/gpu/drm/rockchip/inno_hdmi-rockchip.c > @@ -0,0 +1,517 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd > + * Zheng Yang > + * Yakir Yang > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "rockchip_drm_drv.h" > + > +#include "inno_hdmi-rockchip.h" > + > +#define INNO_HDMI_MIN_TMDS_CLOCK 25000000U > + > +struct rk_inno_hdmi { > + struct rockchip_encoder encoder; > + struct inno_hdmi inno_hdmi; > + struct clk *pclk; > + struct clk *refclk; > +}; > + > +static struct inno_hdmi *rk_encoder_to_inno_hdmi(struct drm_encoder *enc= oder) > +{ > + struct rockchip_encoder *rkencoder =3D to_rockchip_encoder(encoder); > + struct rk_inno_hdmi *rk_hdmi =3D container_of(rkencoder, struct rk_inno= _hdmi, encoder); > + > + return &rk_hdmi->inno_hdmi; > +} > + > +enum { > + CSC_RGB_0_255_TO_ITU601_16_235_8BIT, > + CSC_RGB_0_255_TO_ITU709_16_235_8BIT, > + CSC_RGB_0_255_TO_RGB_16_235_8BIT, > +}; > + > +static const char coeff_csc[][24] =3D { > + /* > + * RGB2YUV:601 SD mode: > + * Cb =3D -0.291G - 0.148R + 0.439B + 128 > + * Y =3D 0.504G + 0.257R + 0.098B + 16 > + * Cr =3D -0.368G + 0.439R - 0.071B + 128 > + */ > + { > + 0x11, 0x5f, 0x01, 0x82, 0x10, 0x23, 0x00, 0x80, > + 0x02, 0x1c, 0x00, 0xa1, 0x00, 0x36, 0x00, 0x1e, > + 0x11, 0x29, 0x10, 0x59, 0x01, 0x82, 0x00, 0x80 > + }, > + /* > + * RGB2YUV:709 HD mode: > + * Cb =3D - 0.338G - 0.101R + 0.439B + 128 > + * Y =3D 0.614G + 0.183R + 0.062B + 16 > + * Cr =3D - 0.399G + 0.439R - 0.040B + 128 > + */ > + { > + 0x11, 0x98, 0x01, 0xc1, 0x10, 0x28, 0x00, 0x80, > + 0x02, 0x74, 0x00, 0xbb, 0x00, 0x3f, 0x00, 0x10, > + 0x11, 0x5a, 0x10, 0x67, 0x01, 0xc1, 0x00, 0x80 > + }, > + /* > + * RGB[0:255]2RGB[16:235]: > + * R' =3D R x (235-16)/255 + 16; > + * G' =3D G x (235-16)/255 + 16; > + * B' =3D B x (235-16)/255 + 16; > + */ > + { > + 0x00, 0x00, 0x03, 0x6F, 0x00, 0x00, 0x00, 0x10, > + 0x03, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, > + 0x00, 0x00, 0x00, 0x00, 0x03, 0x6F, 0x00, 0x10 > + }, > +}; > + > +static struct inno_hdmi_phy_config rk3036_hdmi_phy_configs[] =3D { > + { 74250000, 0x3f, 0xbb }, > + { 165000000, 0x6f, 0xbb }, > + { ~0UL, 0x00, 0x00 } > +}; > + > +static struct inno_hdmi_phy_config rk3128_hdmi_phy_configs[] =3D { > + { 74250000, 0x3f, 0xaa }, > + { 165000000, 0x5f, 0xaa }, > + { ~0UL, 0x00, 0x00 } > +}; > + > +static int inno_hdmi_find_phy_config(struct inno_hdmi *hdmi, > + unsigned long pixelclk) > +{ > + const struct inno_hdmi_phy_config *phy_configs =3D hdmi->plat_data->phy= _configs; > + int i; > + > + for (i =3D 0; phy_configs[i].pixelclock !=3D ~0UL; i++) { > + if (pixelclk <=3D phy_configs[i].pixelclock) > + return i; > + } > + > + DRM_DEV_DEBUG(hdmi->dev, "No phy configuration for pixelclock %lu\n", > + pixelclk); > + > + return -EINVAL; > +} > + > +static void inno_hdmi_standby(struct inno_hdmi *hdmi) > +{ > + inno_hdmi_sys_power(hdmi, false); > + > + hdmi_writeb(hdmi, HDMI_PHY_DRIVER, 0x00); > + hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, 0x00); > + hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x00); > + hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15); > +}; > + > +static void inno_hdmi_power_up(struct inno_hdmi *hdmi, > + unsigned long mpixelclock) > +{ > + struct inno_hdmi_phy_config *phy_config; > + int ret =3D inno_hdmi_find_phy_config(hdmi, mpixelclock); > + > + if (ret < 0) { > + phy_config =3D hdmi->plat_data->default_phy_config; > + DRM_DEV_ERROR(hdmi->dev, > + "Using default phy configuration for TMDS rate %lu", > + mpixelclock); > + } else { > + phy_config =3D &hdmi->plat_data->phy_configs[ret]; > + } > + > + inno_hdmi_sys_power(hdmi, false); > + > + hdmi_writeb(hdmi, HDMI_PHY_PRE_EMPHASIS, phy_config->pre_emphasis); > + hdmi_writeb(hdmi, HDMI_PHY_DRIVER, phy_config->voltage_level_control); > + hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x15); > + hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x14); > + hdmi_writeb(hdmi, HDMI_PHY_SYS_CTL, 0x10); > + hdmi_writeb(hdmi, HDMI_PHY_CHG_PWR, 0x0f); > + hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x00); > + hdmi_writeb(hdmi, HDMI_PHY_SYNC, 0x01); > + > + inno_hdmi_sys_power(hdmi, true); > +}; > + > +static void inno_hdmi_reset(struct inno_hdmi *hdmi) > +{ > + u32 val; > + u32 msk; > + > + hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL); > + udelay(100); > + > + hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG); > + udelay(100); > + > + msk =3D m_REG_CLK_INV | m_REG_CLK_SOURCE | m_POWER | m_INT_POL; > + val =3D v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | v_INT_POL_HIG= H; > + hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val); > + > + inno_hdmi_standby(hdmi); > +} > + > +static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi) > +{ > + struct drm_connector *connector =3D &hdmi->connector; > + struct drm_connector_state *conn_state =3D connector->state; > + struct inno_hdmi_connector_state *inno_conn_state =3D > + to_inno_hdmi_conn_state(conn_state); > + int c0_c2_change =3D 0; > + int csc_enable =3D 0; > + int csc_mode =3D 0; > + int auto_csc =3D 0; > + int value; > + int i; > + > + /* Input video mode is SDR RGB24bit, data enable signal from external */ > + hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL1, v_DE_EXTERNAL | > + v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444)); > + > + /* Input color hardcode to RGB, and output color hardcode to RGB888 */ > + value =3D v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) | > + v_VIDEO_OUTPUT_COLOR(0) | > + v_VIDEO_INPUT_CSP(0); > + hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value); > + > + if (inno_conn_state->enc_out_format =3D=3D HDMI_COLORSPACE_RGB) { > + if (inno_conn_state->rgb_limited_range) { > + csc_mode =3D CSC_RGB_0_255_TO_RGB_16_235_8BIT; > + auto_csc =3D AUTO_CSC_DISABLE; > + c0_c2_change =3D C0_C2_CHANGE_DISABLE; > + csc_enable =3D v_CSC_ENABLE; > + > + } else { > + value =3D v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1); > + hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value); > + > + hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, > + m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP, > + v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) | > + v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE)); > + return 0; > + } > + } else { > + if (inno_conn_state->colorimetry =3D=3D HDMI_COLORIMETRY_ITU_601) { > + if (inno_conn_state->enc_out_format =3D=3D HDMI_COLORSPACE_YUV444) { > + csc_mode =3D CSC_RGB_0_255_TO_ITU601_16_235_8BIT; > + auto_csc =3D AUTO_CSC_DISABLE; > + c0_c2_change =3D C0_C2_CHANGE_DISABLE; > + csc_enable =3D v_CSC_ENABLE; > + } > + } else { > + if (inno_conn_state->enc_out_format =3D=3D HDMI_COLORSPACE_YUV444) { > + csc_mode =3D CSC_RGB_0_255_TO_ITU709_16_235_8BIT; > + auto_csc =3D AUTO_CSC_DISABLE; > + c0_c2_change =3D C0_C2_CHANGE_DISABLE; > + csc_enable =3D v_CSC_ENABLE; > + } > + } > + } > + > + for (i =3D 0; i < 24; i++) > + hdmi_writeb(hdmi, HDMI_VIDEO_CSC_COEF + i, > + coeff_csc[csc_mode][i]); > + > + value =3D v_SOF_DISABLE | csc_enable | v_COLOR_DEPTH_NOT_INDICATED(1); > + hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value); > + hdmi_modb(hdmi, HDMI_VIDEO_CONTRL, m_VIDEO_AUTO_CSC | > + m_VIDEO_C0_C2_SWAP, v_VIDEO_AUTO_CSC(auto_csc) | > + v_VIDEO_C0_C2_SWAP(c0_c2_change)); > + > + return 0; > +} > + > +static int inno_hdmi_setup(struct inno_hdmi *hdmi, > + struct drm_display_mode *mode) > +{ > + struct drm_display_info *display =3D &hdmi->connector.display_info; > + unsigned long mpixelclock =3D mode->clock * 1000; > + > + /* Mute video and audio output */ > + hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, > + v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); > + > + /* Set HDMI Mode */ > + hdmi_writeb(hdmi, HDMI_HDCP_CTRL, > + v_HDMI_DVI(display->is_hdmi)); > + > + inno_hdmi_config_video_timing(hdmi, mode); > + > + inno_hdmi_config_video_csc(hdmi); > + > + if (display->is_hdmi) > + inno_hdmi_config_video_avi(hdmi, mode); > + > + /* > + * When IP controller have configured to an accurate video > + * timing, then the TMDS clock source would be switched to > + * DCLK_LCDC, so we need to init the TMDS rate to mode pixel > + * clock rate, and reconfigure the DDC clock. > + */ > + inno_hdmi_i2c_init(hdmi, mpixelclock); > + > + /* Unmute video and audio output */ > + hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, > + v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0)); > + > + inno_hdmi_power_up(hdmi, mpixelclock); > + > + return 0; > +} > It's kind of a general comment, but I don't think that's the right abstraction. You should create a inno_hdmi bridge that allows to supplement some of the atomic hooks, but not reimplement them entirely each time. You can have a look at how dw-hdmi does it for example. Also, why do you still need the encoder and connectors? Maxime --sz2tqw6l7ovh4mjb Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iJUEABMJAB0WIQTkHFbLp4ejekA/qfgnX84Zoj2+dgUCZk2duwAKCRAnX84Zoj2+ dkF2AX9jQnZV3sONCKFSJhi4lZ/Ymcq3X6xWZyt2lmjwp1iEsJhOqYHPKEqQQ6AM GoKkbb0BgI+VNaNW48TQaT/S1RTayRRJCu/a3d4teB5nzeFKgubg71rRHSYXQRsI YSGF1RP4Vw== =jc7l -----END PGP SIGNATURE----- --sz2tqw6l7ovh4mjb--