From nobody Tue May 13 05:04:52 2025
Received: from m16.mail.163.com (m16.mail.163.com [117.135.210.5])
	by smtp.subspace.kernel.org (Postfix) with ESMTP id 99D7F236A98;
	Wed,  2 Apr 2025 12:32:43 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=117.135.210.5
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1743597166; cv=none;
 b=WmG69pbe1NubM59Da6/W0grHep4A2URgIt+Vfe30wodZVL85lw9T2teHx214S63IUaIWoglDc4Qa9U++7Kp9pmeolp/A8pEz4wDbY3ZoUYs+D9P75SG6G6/UIk3cQN0qo1RHOWu3pHQK9Ndxu74YewqUTiw8n8aq8KK3UHkrDOI=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1743597166; c=relaxed/simple;
	bh=lHPcC6roTWI6j5MuLnP9MGdLrR/C3X98BMj/TCy80J0=;
	h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:
	 MIME-Version;
 b=tcF+eedt5MxNMZa9UKgsekYghg03K8btayGr0IMypJ1j8t17ZC/eNHfcZarrteXJPzOfwwdRt62mbln4PhsTkvKVDsGXCM8+teU9XpzxCPFU8G9D47tr7pyOLqUrTfn2O7CSQF/IFdJykGEYprD5k70Y10Q6RzWZ0VX6dq/OXMA=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=163.com;
 spf=pass smtp.mailfrom=163.com;
 dkim=pass (1024-bit key) header.d=163.com header.i=@163.com
 header.b=BcEW+rvw; arc=none smtp.client-ip=117.135.210.5
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=163.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=163.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (1024-bit key) header.d=163.com header.i=@163.com
 header.b="BcEW+rvw"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com;
	s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=SNu0F
	4yGXjEea7fLM5tg1tfl9TwC9mxjxgn2oB/nJL4=; b=BcEW+rvwQsMha7wu8x4wx
	zuHulSHPsqMBiF00ST0U4AZam9wNdb3QtjgiauVhfLPSYZeJEg8UuLoNMIE23VaV
	tP7lxr48GfjB/G66vGuRwUHO3BQCZ1mXi67Ex1fnKr1W070ttmoQoEviR5CuTRWo
	KaTi2V2O2SL9l75o5J9CM0=
Received: from ProDesk.. (unknown [])
	by gzsmtp4 (Coremail) with SMTP id PygvCgDnd405Lu1nJwOJBA--.36321S3;
	Wed, 02 Apr 2025 20:31:58 +0800 (CST)
From: Andy Yan <andyshrk@163.com>
To: heiko@sntech.de
Cc: conor+dt@kernel.org,
	krzk+dt@kernel.org,
	robh@kernel.org,
	hjc@rock-chips.com,
	mripard@kernel.org,
	neil.armstrong@linaro.org,
	dmitry.baryshkov@oss.qualcomm.com,
	devicetree@vger.kernel.org,
	dri-devel@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	linux-rockchip@lists.infradead.org,
	Andy Yan <andy.yan@rock-chips.com>
Subject: [PATCH v3 1/7] dt-bindings: display: rockchip,inno-hdmi: Fix Document
 of RK3036 compatible
Date: Wed,  2 Apr 2025 20:31:35 +0800
Message-ID: <20250402123150.238234-2-andyshrk@163.com>
X-Mailer: git-send-email 2.43.0
In-Reply-To: <20250402123150.238234-1-andyshrk@163.com>
References: <20250402123150.238234-1-andyshrk@163.com>
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
X-CM-TRANSID: PygvCgDnd405Lu1nJwOJBA--.36321S3
X-Coremail-Antispam: 1Uf129KBjvJXoW7tw45GrW5ur4xJFyrWF45Wrg_yoW8Ar4Dpa
	93C3WkXr1xur1UX34Dtr18CrWkta4kAa1YkFy2q3W8Gr1j9a1DKa1agr4DZay3ArsrAa9F
	vFsFgry8A34SvrJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2
	9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07j8pnPUUUUU=
X-CM-SenderInfo: 5dqg52xkunqiywtou0bp/xtbBkA0jXmftKOaFiAAAsp
Content-Type: text/plain; charset="utf-8"

From: Andy Yan <andy.yan@rock-chips.com>

The RK3036 HDMI DDC bus requires it's PHY's reference clock to be enabled
first before normal DDC communication can be carried out.

Therefore, both RK3036 and RK3128 HDMI require two identical clocks.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>

---

(no changes since v1)

 .../bindings/display/rockchip/rockchip,inno-hdmi.yaml | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,in=
no-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,=
inno-hdmi.yaml
index 5b87b0f1963e1..9d1e7f894ea54 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi=
.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi=
.yaml
@@ -23,13 +23,11 @@ properties:
     maxItems: 1
=20
   clocks:
-    minItems: 1
     items:
       - description: The HDMI controller main clock
       - description: The HDMI PHY reference clock
=20
   clock-names:
-    minItems: 1
     items:
       - const: pclk
       - const: ref
@@ -87,11 +85,6 @@ allOf:
             const: rockchip,rk3128-inno-hdmi
=20
     then:
-      properties:
-        clocks:
-          minItems: 2
-        clock-names:
-          minItems: 2
       required:
         - power-domains
=20
@@ -106,8 +99,8 @@ examples:
       compatible =3D "rockchip,rk3036-inno-hdmi";
       reg =3D <0x20034000 0x4000>;
       interrupts =3D <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
-      clocks =3D <&cru  PCLK_HDMI>;
-      clock-names =3D "pclk";
+      clocks =3D <&cru PCLK_HDMI>, <&cru SCLK_LCDC>;
+      clock-names =3D "pclk", "ref";
       pinctrl-names =3D "default";
       pinctrl-0 =3D <&hdmi_ctl>;
       #sound-dai-cells =3D <0>;
--=20
2.43.0
From nobody Tue May 13 05:04:52 2025
Received: from m16.mail.163.com (m16.mail.163.com [117.135.210.4])
	by smtp.subspace.kernel.org (Postfix) with ESMTP id 95CE12376E1;
	Wed,  2 Apr 2025 12:32:43 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=117.135.210.4
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1743597167; cv=none;
 b=fMI8CK0CABm9H9+Ptv/1debyoL7RUozUDeRIYhO/u79pOOm7aAgnhopLUn3cU+dpjWGlHbVo44k6zInxvSRTkqDwJHjLz7B0yh8W2NOFp042HmqgVuohog7LmKCV3qlERCpV6EilCuo457F21h6XNgUBPm/J1NPEp3yGznbA8E0=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1743597167; c=relaxed/simple;
	bh=lKYht5ql/5FIPEeJczRwWYQx5Oi2NvAPbM4ZIVsT/Pk=;
	h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:
	 MIME-Version;
 b=SzxaHzHCZoi7EF4tsQQ75XWPVTYvtxOQ0gJcBQnqUAgdv2u9OdPpYITC0kXZao1+IA7qC7My8/YSWww8EOP9AoylalukQlN+Znik+QILj6ssKyxJEQMQP0M9tnyIXSU4tk8JKKDcLKKAjY6yPmOBEdgWCnf2QMJUML8ULSSqk4Y=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=163.com;
 spf=pass smtp.mailfrom=163.com;
 dkim=pass (1024-bit key) header.d=163.com header.i=@163.com
 header.b=jz30fZ3v; arc=none smtp.client-ip=117.135.210.4
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=163.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=163.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (1024-bit key) header.d=163.com header.i=@163.com
 header.b="jz30fZ3v"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com;
	s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=jvJrC
	JlXKu0zyBhFzDwypCRXXkJB5PHy1URiAxDBM28=; b=jz30fZ3v9aBAfxkd5mqMl
	jkHWm5hKKsL+mYZErNFNeJjOJ6oSukaEG2MpzVhhWIKpfAKDC/Cudfjd1bAKvxZn
	PdfRkYOd93NPhfUyzRIWUKyJYHb+IemVxCndB7vnGWlTII2TNkZX0HsStTg/3MA9
	TB+PKwuMm3mk2Uc1xOPz+w=
Received: from ProDesk.. (unknown [])
	by gzsmtp4 (Coremail) with SMTP id PygvCgDnd405Lu1nJwOJBA--.36321S4;
	Wed, 02 Apr 2025 20:31:59 +0800 (CST)
From: Andy Yan <andyshrk@163.com>
To: heiko@sntech.de
Cc: conor+dt@kernel.org,
	krzk+dt@kernel.org,
	robh@kernel.org,
	hjc@rock-chips.com,
	mripard@kernel.org,
	neil.armstrong@linaro.org,
	dmitry.baryshkov@oss.qualcomm.com,
	devicetree@vger.kernel.org,
	dri-devel@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	linux-rockchip@lists.infradead.org,
	Andy Yan <andy.yan@rock-chips.com>
Subject: [PATCH v3 2/7] dt-bindings: display: rockchip,inno-hdmi: Document GRF
 for RK3036 HDMI
Date: Wed,  2 Apr 2025 20:31:36 +0800
Message-ID: <20250402123150.238234-3-andyshrk@163.com>
X-Mailer: git-send-email 2.43.0
In-Reply-To: <20250402123150.238234-1-andyshrk@163.com>
References: <20250402123150.238234-1-andyshrk@163.com>
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
X-CM-TRANSID: PygvCgDnd405Lu1nJwOJBA--.36321S4
X-Coremail-Antispam: 1Uf129KBjvJXoW7ZryxWw47XF1UAFyxtFyrZwb_yoW8Gw15pa
	sxC3srWFyxGFy7X34ktr1kCrWYgF97Aa15GFW2qr17tr12gan5Ka1agwn8ZF4UAFs7ZFyS
	9ay7GFy5Aw1Ivr7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2
	9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jrjjgUUUUU=
X-CM-SenderInfo: 5dqg52xkunqiywtou0bp/xtbBkA0jXmftKOaFiAABso
Content-Type: text/plain; charset="utf-8"

From: Andy Yan <andy.yan@rock-chips.com>

HDMI on RK3036 use GRF control the HSYNC/VSYNC polarity, but this part
is missing when it first landing upstream.

Document that it is mandatory for RK3036 HDMI.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---

(no changes since v2)

Changes in v2:
- First included in v2

 .../bindings/display/rockchip/rockchip,inno-hdmi.yaml    | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,in=
no-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,=
inno-hdmi.yaml
index 9d1e7f894ea54..290376bec079a 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi=
.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,inno-hdmi=
.yaml
@@ -56,6 +56,12 @@ properties:
       - port@0
       - port@1
=20
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to GRF used for control the polarity of hsync/vsync of rk3036
+      HDMI.
+
 required:
   - compatible
   - reg
@@ -75,6 +81,8 @@ allOf:
             const: rockchip,rk3036-inno-hdmi
=20
     then:
+      required:
+        - rockchip,grf
       properties:
         power-domains: false
=20
@@ -103,6 +111,7 @@ examples:
       clock-names =3D "pclk", "ref";
       pinctrl-names =3D "default";
       pinctrl-0 =3D <&hdmi_ctl>;
+      rockchip,grf =3D <&grf>;
       #sound-dai-cells =3D <0>;
=20
       ports {
--=20
2.43.0
From nobody Tue May 13 05:04:52 2025
Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.5])
	by smtp.subspace.kernel.org (Postfix) with ESMTP id 2C169239570;
	Wed,  2 Apr 2025 12:32:43 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=220.197.31.5
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1743597166; cv=none;
 b=Iy+S4v3Rqn4M9rMewLUTjRaSZlK8bCN3nuPlVCWYf1X3ct6O7MMPsp+CvGl6lHidX6Lh9S3q8tPEqynnlcML2ByaJHyuq+nE0oDaakfx0/mAY/cLtKqBr+CgHvIiSOPS/cialyefgmaQ7+0nTyhEu61ZscNcj0GOFQiE1yw/mIQ=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1743597166; c=relaxed/simple;
	bh=tOZz0L3GVjXW2ZtzMwyl/yYNyYzyFJ+GZZpA5ROpJRY=;
	h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:
	 MIME-Version;
 b=elF9FxipESejZbz3hQ4g7YEZ+cyTdLNcMOPGjRWqoTiin0HBtDMferZqwZyt+oXmLjenFAN0QPW/DGAsqC6md8ashBMkIKDxD8cw6jPuT3tfA5ex0TMxPF+NfzqX1ac2F/6bcxsJmsRmRkqK7Dz4AacDS8ET2aq3M/k8xtw1fO4=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=163.com;
 spf=pass smtp.mailfrom=163.com;
 dkim=pass (1024-bit key) header.d=163.com header.i=@163.com
 header.b=MGTwIXCl; arc=none smtp.client-ip=220.197.31.5
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=163.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=163.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (1024-bit key) header.d=163.com header.i=@163.com
 header.b="MGTwIXCl"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com;
	s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=SAmBQ
	fQ4gtVQYYiOf9e8DZppYPFI9MirWXA6gFfsoeE=; b=MGTwIXCl6X63pnKuYAA0r
	pXDerXH7TBHXky8AaQZOE3YVkWYj7hrNbRQl9F7ffYA9A2/7BYHcTXEJO5429OB0
	Qh4s+pyuAJfJwbsjBzFf3HG8m3GbJnnTghIrD6UkgaYt4MMUppHNtk5lmuoWmCc8
	PBzyuDtQF8fIlHIv6oVfgM=
Received: from ProDesk.. (unknown [])
	by gzsmtp4 (Coremail) with SMTP id PygvCgDnd405Lu1nJwOJBA--.36321S5;
	Wed, 02 Apr 2025 20:32:00 +0800 (CST)
From: Andy Yan <andyshrk@163.com>
To: heiko@sntech.de
Cc: conor+dt@kernel.org,
	krzk+dt@kernel.org,
	robh@kernel.org,
	hjc@rock-chips.com,
	mripard@kernel.org,
	neil.armstrong@linaro.org,
	dmitry.baryshkov@oss.qualcomm.com,
	devicetree@vger.kernel.org,
	dri-devel@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	linux-rockchip@lists.infradead.org,
	Andy Yan <andy.yan@rock-chips.com>
Subject: [PATCH v3 3/7] drm/rockchip: inno-hdmi: Simplify error handler with
 dev_err_probe
Date: Wed,  2 Apr 2025 20:31:37 +0800
Message-ID: <20250402123150.238234-4-andyshrk@163.com>
X-Mailer: git-send-email 2.43.0
In-Reply-To: <20250402123150.238234-1-andyshrk@163.com>
References: <20250402123150.238234-1-andyshrk@163.com>
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
X-CM-TRANSID: PygvCgDnd405Lu1nJwOJBA--.36321S5
X-Coremail-Antispam: 1Uf129KBjvJXoW7uryfXr4fuF1fJr4Utr1xuFg_yoW8Aw1Dpr
	ZxJFyjvFy8JF18W347ua15Ar1Sya1Uta18CrZrGwn5Zw17Zrs8try3ZFWFqrWFyF95Zw4a
	y393Xa4UZ3W7WaUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2
	9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jJkuxUUUUU=
X-CM-SenderInfo: 5dqg52xkunqiywtou0bp/xtbB0gMjXmftK+o5ZwAAs5
Content-Type: text/plain; charset="utf-8"

From: Andy Yan <andy.yan@rock-chips.com>

Use dev_err_probe simplify the error handle.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

(no changes since v2)

Changes in v2:
- First included in this series

 drivers/gpu/drm/rockchip/inno_hdmi.c | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchi=
p/inno_hdmi.c
index 483ecfeaebb08..e891d42dd08a4 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -885,29 +885,22 @@ static int inno_hdmi_bind(struct device *dev, struct =
device *master,
 		return PTR_ERR(hdmi->regs);
=20
 	hdmi->pclk =3D devm_clk_get(hdmi->dev, "pclk");
-	if (IS_ERR(hdmi->pclk)) {
-		DRM_DEV_ERROR(hdmi->dev, "Unable to get HDMI pclk clk\n");
-		return PTR_ERR(hdmi->pclk);
-	}
+	if (IS_ERR(hdmi->pclk))
+		return dev_err_probe(dev, PTR_ERR(hdmi->pclk), "Unable to get HDMI pclk\=
n");
=20
 	ret =3D clk_prepare_enable(hdmi->pclk);
-	if (ret) {
-		DRM_DEV_ERROR(hdmi->dev,
-			      "Cannot enable HDMI pclk clock: %d\n", ret);
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(dev, ret, "Cannot enable HDMI pclk: %d\n", ret);
=20
 	hdmi->refclk =3D devm_clk_get_optional(hdmi->dev, "ref");
 	if (IS_ERR(hdmi->refclk)) {
-		DRM_DEV_ERROR(hdmi->dev, "Unable to get HDMI reference clock\n");
-		ret =3D PTR_ERR(hdmi->refclk);
+		ret =3D dev_err_probe(dev, PTR_ERR(hdmi->refclk), "Unable to get HDMI re=
fclk\n");
 		goto err_disable_pclk;
 	}
=20
 	ret =3D clk_prepare_enable(hdmi->refclk);
 	if (ret) {
-		DRM_DEV_ERROR(hdmi->dev,
-			      "Cannot enable HDMI reference clock: %d\n", ret);
+		ret =3D dev_err_probe(dev, ret, "Cannot enable HDMI refclk: %d\n", ret);
 		goto err_disable_pclk;
 	}
=20
--=20
2.43.0
From nobody Tue May 13 05:04:52 2025
Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.3])
	by smtp.subspace.kernel.org (Postfix) with ESMTP id 66672238D2D;
	Wed,  2 Apr 2025 12:32:40 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=220.197.31.3
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1743597166; cv=none;
 b=Ju3dAtDIbYaLD0LtYfzyyH04M8v80jZUOCGQ68vTQBx4maplJfXgMhcYQ17Fzrge8xSaeytbNa9awb+iMiq86pCLz0JhGnE+DADEQEfSuVHt/+sWXWGQfmT+swjjqFYt1VAM+xsYi5eBsi8wC4zbvkE0yWlUpPfcY71Qx7/B/gg=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1743597166; c=relaxed/simple;
	bh=RY1wOESZWxNAL6kdiDv+BIzI3pjPPM9sK0ZV9d7NMYk=;
	h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:
	 MIME-Version;
 b=uscBzd/av9a9WMo+tWjjx8UBDVICTLRIvy/PQcX9zFhW8JeZlmhCD+P/3VsNrDwkNsoK6WMGvHnT3VJIs7/lpzlS7H+vdLfDhbSlldqxbMfTSLnBtsAQd00jw07zsjSvVLvxBW49u54NKE0yivGX/ZOeAu4eTWVfsUqI09szt60=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=163.com;
 spf=pass smtp.mailfrom=163.com;
 dkim=pass (1024-bit key) header.d=163.com header.i=@163.com
 header.b=M7F54b6X; arc=none smtp.client-ip=220.197.31.3
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=163.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=163.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (1024-bit key) header.d=163.com header.i=@163.com
 header.b="M7F54b6X"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com;
	s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=CBuVD
	5mLxW1qWVh3yysFaNPsNmOWSZ6Qe90zC/Vn6b4=; b=M7F54b6XJU+kRYft5LtkL
	Z6VagWP+2LCz3EVq3DxVZzZKAdHopIr1/Y079LCLE2IzRkka9P7h7LxY0BAjQrtB
	HOISEyKLKPyUe2qVBgZs7NKURvHtA5f+BWNtW1qLkWaZpBUqvk/LChH7EVjrDkE8
	FN9cRUgvV71k5ayvX5R75E=
Received: from ProDesk.. (unknown [])
	by gzsmtp4 (Coremail) with SMTP id PygvCgDnd405Lu1nJwOJBA--.36321S6;
	Wed, 02 Apr 2025 20:32:01 +0800 (CST)
From: Andy Yan <andyshrk@163.com>
To: heiko@sntech.de
Cc: conor+dt@kernel.org,
	krzk+dt@kernel.org,
	robh@kernel.org,
	hjc@rock-chips.com,
	mripard@kernel.org,
	neil.armstrong@linaro.org,
	dmitry.baryshkov@oss.qualcomm.com,
	devicetree@vger.kernel.org,
	dri-devel@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	linux-rockchip@lists.infradead.org,
	Andy Yan <andy.yan@rock-chips.com>
Subject: [PATCH v3 4/7] drm/rockchip: inno-hdmi: Fix video timing HSYNC/VSYNC
 polarity setting for rk3036
Date: Wed,  2 Apr 2025 20:31:38 +0800
Message-ID: <20250402123150.238234-5-andyshrk@163.com>
X-Mailer: git-send-email 2.43.0
In-Reply-To: <20250402123150.238234-1-andyshrk@163.com>
References: <20250402123150.238234-1-andyshrk@163.com>
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
X-CM-TRANSID: PygvCgDnd405Lu1nJwOJBA--.36321S6
X-Coremail-Antispam: 1Uf129KBjvJXoWxZr17Gry3Ar18CFW5Xw4xZwb_yoWrJF4xpa
	yUCFyUJF43Xa13Jw4xAa97Cr1aga97ta12yry7W3Wa9w12gr9YyF1kZF43uF1rAF93Was7
	trWkGa4UG3W7Zw7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2
	9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07js2-5UUUUU=
X-CM-SenderInfo: 5dqg52xkunqiywtou0bp/1tbiqB0jXmftKV94EgAAse
Content-Type: text/plain; charset="utf-8"

From: Andy Yan <andy.yan@rock-chips.com>

The HSYNC/VSYNC polarity of rk3036 HDMI are controlled by GRF.
Without the polarity configuration in GRF, it can be observed
from the HDMI protocol analyzer that the H/V front/back timing
output by RK3036 HDMI are currently not in line with the specifications.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

(no changes since v2)

Changes in v2:
- First included in this series

 drivers/gpu/drm/rockchip/inno_hdmi.c | 36 +++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchi=
p/inno_hdmi.c
index e891d42dd08a4..db4b4038e51d5 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -10,10 +10,12 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/hdmi.h>
+#include <linux/mfd/syscon.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
=20
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
@@ -29,8 +31,19 @@
=20
 #include "inno_hdmi.h"
=20
+#define HIWORD_UPDATE(val, mask)	((val) | (mask) << 16)
+
 #define INNO_HDMI_MIN_TMDS_CLOCK  25000000U
=20
+#define RK3036_GRF_SOC_CON2	0x148
+#define RK3036_HDMI_PHSYNC	BIT(4)
+#define RK3036_HDMI_PVSYNC	BIT(5)
+
+enum inno_hdmi_dev_type {
+	RK3036_HDMI,
+	RK3128_HDMI,
+};
+
 struct inno_hdmi_phy_config {
 	unsigned long pixelclock;
 	u8 pre_emphasis;
@@ -38,6 +51,7 @@ struct inno_hdmi_phy_config {
 };
=20
 struct inno_hdmi_variant {
+	enum inno_hdmi_dev_type dev_type;
 	struct inno_hdmi_phy_config *phy_configs;
 	struct inno_hdmi_phy_config *default_phy_config;
 };
@@ -58,6 +72,7 @@ struct inno_hdmi {
 	struct clk *pclk;
 	struct clk *refclk;
 	void __iomem *regs;
+	struct regmap *grf;
=20
 	struct drm_connector	connector;
 	struct rockchip_encoder	encoder;
@@ -374,7 +389,15 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi=
 *hdmi)
 static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
 					 struct drm_display_mode *mode)
 {
-	int value;
+	int value, psync;
+
+	if (hdmi->variant->dev_type =3D=3D RK3036_HDMI) {
+		psync =3D mode->flags & DRM_MODE_FLAG_PHSYNC ? RK3036_HDMI_PHSYNC : 0;
+		value =3D HIWORD_UPDATE(psync, RK3036_HDMI_PHSYNC);
+		psync =3D mode->flags & DRM_MODE_FLAG_PVSYNC ? RK3036_HDMI_PVSYNC : 0;
+		value |=3D HIWORD_UPDATE(psync, RK3036_HDMI_PVSYNC);
+		regmap_write(hdmi->grf, RK3036_GRF_SOC_CON2, value);
+	}
=20
 	/* Set detail external video timing polarity and interlace mode */
 	value =3D v_EXTERANL_VIDEO(1);
@@ -904,6 +927,15 @@ static int inno_hdmi_bind(struct device *dev, struct d=
evice *master,
 		goto err_disable_pclk;
 	}
=20
+	if (hdmi->variant->dev_type =3D=3D RK3036_HDMI) {
+		hdmi->grf =3D syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,gr=
f");
+		if (IS_ERR(hdmi->grf)) {
+			ret =3D dev_err_probe(dev, PTR_ERR(hdmi->grf),
+					    "Unable to get rockchip,grf\n");
+			goto err_disable_clk;
+		}
+	}
+
 	irq =3D platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		ret =3D irq;
@@ -988,11 +1020,13 @@ static void inno_hdmi_remove(struct platform_device =
*pdev)
 }
=20
 static const struct inno_hdmi_variant rk3036_inno_hdmi_variant =3D {
+	.dev_type =3D RK3036_HDMI,
 	.phy_configs =3D rk3036_hdmi_phy_configs,
 	.default_phy_config =3D &rk3036_hdmi_phy_configs[1],
 };
=20
 static const struct inno_hdmi_variant rk3128_inno_hdmi_variant =3D {
+	.dev_type =3D RK3128_HDMI,
 	.phy_configs =3D rk3128_hdmi_phy_configs,
 	.default_phy_config =3D &rk3128_hdmi_phy_configs[1],
 };
--=20
2.43.0
From nobody Tue May 13 05:04:52 2025
Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.4])
	by smtp.subspace.kernel.org (Postfix) with ESMTP id 651D1238D22;
	Wed,  2 Apr 2025 12:32:41 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=220.197.31.4
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1743597165; cv=none;
 b=cXb2gI3Y5Crvw1oURaQNhg86AhYgufN31Bze5XkCHNbn1/Xun+55d13QOiaUsK0t3j88JSRAtExbrHzSzA47wcdtjRg7b6qSi0we0+Ghrv1ZA6/t6CZmUSxL+lMEwWmDA+eN23AoyB7XWNczz4SJYtUyC6dAbzC7ahXoTCtC3po=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1743597165; c=relaxed/simple;
	bh=J/FkQ+SkHYYoPQcELkb+tIcpNOe26kLfqD3rb2wWEoo=;
	h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:
	 MIME-Version;
 b=D7hYScEvjTLsA+H5oSJF7L/lkm1cBmksjpWqDWvEu5d25T/u1DINJ3Jp/GBZ4fHKgPRgBNIRvASlw53V6VTS2CY/ZGnHV5KeY1RobTWAvE0Dp1e/mZKSu6C0VGCbzIlhJBbJa5PyJbHwAbHdoQ94pxyV7aONnWe1Ky45zrbH8RY=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=163.com;
 spf=pass smtp.mailfrom=163.com;
 dkim=pass (1024-bit key) header.d=163.com header.i=@163.com
 header.b=FHHYmnk8; arc=none smtp.client-ip=220.197.31.4
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=163.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=163.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (1024-bit key) header.d=163.com header.i=@163.com
 header.b="FHHYmnk8"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com;
	s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=XjB5C
	GDy56iSBUj/onMIQC1Fw0WRXap96Du59NyDvPE=; b=FHHYmnk8bBtXKyHUfklTf
	ByPqOdQhLfYcPUAXIit/E/u8aIJEEQlnqPHFDfG7pI07pE75Z3GpSPrfJogpk3y/
	6azwa6yItgQ2lAbwwmY41qCq5E2Oefcc/gYAtbmfIBa/i9Z01MbF/ebiIVkSDhqS
	J2cZvffcu4tlw/MsM/9Iuw=
Received: from ProDesk.. (unknown [])
	by gzsmtp4 (Coremail) with SMTP id PygvCgDnd405Lu1nJwOJBA--.36321S7;
	Wed, 02 Apr 2025 20:32:02 +0800 (CST)
From: Andy Yan <andyshrk@163.com>
To: heiko@sntech.de
Cc: conor+dt@kernel.org,
	krzk+dt@kernel.org,
	robh@kernel.org,
	hjc@rock-chips.com,
	mripard@kernel.org,
	neil.armstrong@linaro.org,
	dmitry.baryshkov@oss.qualcomm.com,
	devicetree@vger.kernel.org,
	dri-devel@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	linux-rockchip@lists.infradead.org,
	Andy Yan <andy.yan@rock-chips.com>
Subject: [PATCH v3 5/7] ARM: dts: rockchip: Add ref clk for hdmi
Date: Wed,  2 Apr 2025 20:31:39 +0800
Message-ID: <20250402123150.238234-6-andyshrk@163.com>
X-Mailer: git-send-email 2.43.0
In-Reply-To: <20250402123150.238234-1-andyshrk@163.com>
References: <20250402123150.238234-1-andyshrk@163.com>
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
X-CM-TRANSID: PygvCgDnd405Lu1nJwOJBA--.36321S7
X-Coremail-Antispam: 1Uf129KBjvdXoWrKF1xJw4kAFWfZry3tw4xWFg_yoWDWFX_t3
	WIgw15GF4fGrZIq34Dtr4UW39F9w4fC397XrnYqr4UJF9aqr4UXF4kGayIyry5Jay2g3sx
	CFZ5Xw4aya1agjkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8Yxn0WfASr-VFAUDa7-sFnT
	9fnUUvcSsGvfC2KfnxnUUI43ZEXa7IU03CztUUUUU==
X-CM-SenderInfo: 5dqg52xkunqiywtou0bp/xtbB0gUjXmftK+o5lQAAsN
Content-Type: text/plain; charset="utf-8"

From: Andy Yan <andy.yan@rock-chips.com>

The RK3036 HDMI DDC bus requires it's PHY's reference clock to be
enabled first before normal DDC communication can be carried out.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
---

(no changes since v1)

 arch/arm/boot/dts/rockchip/rk3036.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/rockchip/rk3036.dtsi b/arch/arm/boot/dts/roc=
kchip/rk3036.dtsi
index 6039a0908af1c..22685cd23a708 100644
--- a/arch/arm/boot/dts/rockchip/rk3036.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3036.dtsi
@@ -403,8 +403,8 @@ hdmi: hdmi@20034000 {
 		compatible =3D "rockchip,rk3036-inno-hdmi";
 		reg =3D <0x20034000 0x4000>;
 		interrupts =3D <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
-		clocks =3D <&cru  PCLK_HDMI>;
-		clock-names =3D "pclk";
+		clocks =3D <&cru PCLK_HDMI>, <&cru SCLK_LCDC>;
+		clock-names =3D "pclk", "ref";
 		pinctrl-names =3D "default";
 		pinctrl-0 =3D <&hdmi_ctl>;
 		#sound-dai-cells =3D <0>;
--=20
2.43.0
From nobody Tue May 13 05:04:52 2025
Received: from m16.mail.163.com (m16.mail.163.com [117.135.210.4])
	by smtp.subspace.kernel.org (Postfix) with ESMTP id 51AC61E7C02;
	Wed,  2 Apr 2025 12:32:39 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=117.135.210.4
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1743597163; cv=none;
 b=H6WoqilB5ieapz6gtRLc/Yc7lbEdcjU8GFRtV6QrZ81W/sYjPWz7h9y1wFPMciublm/5FQtrLr0QBN89OObMgSO66RgspM8ydsM9iwePshYuiPwNYl24prlwWWQnayyalV/W0IWgG6DDZHzc2Od84J2BNV7Mz0Vpftw8zATkV7M=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1743597163; c=relaxed/simple;
	bh=UTATp5Vy18bL4XWdu6qCARwaTStSHDvxTPvSI0YaSRQ=;
	h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:
	 MIME-Version;
 b=HF+PGMtMnHoVZ8fHDFW7eXoaZyaJFea62qr9cpeb9Cg87A+B8nJJSLT7tMEh2duBeVREskQyx9pvpMm2GzZdPaiYuSwK1l6fNC7V7yWziTVGyZ9e/SHCCsXdYpdmU50CwAiCEFA3HtESQZfV621AHBsGVuRGpG6AzJUZdfwiJVc=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=163.com;
 spf=pass smtp.mailfrom=163.com;
 dkim=pass (1024-bit key) header.d=163.com header.i=@163.com
 header.b=k5MNf0c0; arc=none smtp.client-ip=117.135.210.4
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=163.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=163.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (1024-bit key) header.d=163.com header.i=@163.com
 header.b="k5MNf0c0"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com;
	s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=g3jx9
	mZP84zW4GKnneObG67nUX/ojN2RZWPwZ8uHvVk=; b=k5MNf0c0yOQ3sb37A0N3O
	v5SekZwbRQDWEyzuVS8p8n/70pO3xrDjvdOBJOIKUjwqu4DCQ5KJDsTFDi5JBDgz
	wOck6gWjtbCpBzXqGkjTW+25I5SRYSXy9LXF4UgBf3GCVY3EA9PKZTcrftg9JxW6
	08pn4WtwXXq+o0QUga2UqU=
Received: from ProDesk.. (unknown [])
	by gzsmtp4 (Coremail) with SMTP id PygvCgDnd405Lu1nJwOJBA--.36321S8;
	Wed, 02 Apr 2025 20:32:03 +0800 (CST)
From: Andy Yan <andyshrk@163.com>
To: heiko@sntech.de
Cc: conor+dt@kernel.org,
	krzk+dt@kernel.org,
	robh@kernel.org,
	hjc@rock-chips.com,
	mripard@kernel.org,
	neil.armstrong@linaro.org,
	dmitry.baryshkov@oss.qualcomm.com,
	devicetree@vger.kernel.org,
	dri-devel@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	linux-rockchip@lists.infradead.org,
	Andy Yan <andy.yan@rock-chips.com>
Subject: [PATCH v3 6/7] Revert "ARM: dts: rockchip: drop grf reference from
 rk3036 hdmi"
Date: Wed,  2 Apr 2025 20:31:40 +0800
Message-ID: <20250402123150.238234-7-andyshrk@163.com>
X-Mailer: git-send-email 2.43.0
In-Reply-To: <20250402123150.238234-1-andyshrk@163.com>
References: <20250402123150.238234-1-andyshrk@163.com>
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
X-CM-TRANSID: PygvCgDnd405Lu1nJwOJBA--.36321S8
X-Coremail-Antispam: 1Uf129KBjvdXoW7Gry5Kr43uFW8Ary3Kw15Arb_yoWkWFX_tF
	yIg3W5Ka1FkrWYqry8tw4UGwsFywn5GFWrJw1rJr4UGwnYqF4DuFs5GayxAr15Gay2grZ3
	WFZ5Xa1Yyw13WjkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8Yxn0WfASr-VFAUDa7-sFnT
	9fnUUvcSsGvfC2KfnxnUUI43ZEXa7IU0aYLDUUUUU==
X-CM-SenderInfo: 5dqg52xkunqiywtou0bp/xtbB0gUjXmftK+o5lQABsM
Content-Type: text/plain; charset="utf-8"

From: Andy Yan <andy.yan@rock-chips.com>

This reverts commit 1580ccb6ed9dc76b8ff3e2d8912e8215c8b0fa6d.

The HSYNC/VSYNC polarity of rk3036 HDMI are controlled by GRF.
Without the polarity configuration in GRF, it can be observed from
the HDMI protocol analyzer that the H/V front/back timing output
by RK3036 HDMI are currently not in line with the specifications.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

(no changes since v2)

Changes in v2:
- First included in this series

 arch/arm/boot/dts/rockchip/rk3036.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/rockchip/rk3036.dtsi b/arch/arm/boot/dts/roc=
kchip/rk3036.dtsi
index 22685cd23a708..95ae815ba56d3 100644
--- a/arch/arm/boot/dts/rockchip/rk3036.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3036.dtsi
@@ -405,6 +405,7 @@ hdmi: hdmi@20034000 {
 		interrupts =3D <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
 		clocks =3D <&cru PCLK_HDMI>, <&cru SCLK_LCDC>;
 		clock-names =3D "pclk", "ref";
+		rockchip,grf =3D <&grf>;
 		pinctrl-names =3D "default";
 		pinctrl-0 =3D <&hdmi_ctl>;
 		#sound-dai-cells =3D <0>;
--=20
2.43.0
From nobody Tue May 13 05:04:52 2025
Received: from m16.mail.163.com (m16.mail.163.com [117.135.210.3])
	by smtp.subspace.kernel.org (Postfix) with ESMTP id A317223957C;
	Wed,  2 Apr 2025 12:32:52 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=117.135.210.3
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1743597177; cv=none;
 b=VnyB9XnYNhE49pgSWbd5ubxDVxtpunOj+MuAGKroy5LyqC74RU6l4Xseu7BGHINcYl7UxYrUFf2WhYZzFrKx1smJAV2BLWo7KS+7fqLM5fPgZ1rFepcRIHE2Pj682zDwDp/KP80bZUMC1DP/pj19cqI/qgXdOhBdHCwT9piJN9Y=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1743597177; c=relaxed/simple;
	bh=yrUbeNEcjyelpvaxTJZWuxrwA8qhq4dr5mEPQ+7/oZE=;
	h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:
	 MIME-Version;
 b=XMkw0PLHny3Oxi6AE+yuxtn9sciTNioMWhwN/t5sP3fyhZZRklNWxtfrx2OK6YO624cBpKKqLu53Pt4GvdlHut3SWM0SVjzlW7ta4/jQMWR9s+/prqqltyv24hulIlrm6nlbqJAXTDr+yeO/FTpl1y0kArMAcm7i0DA8zpYw9OA=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=163.com;
 spf=pass smtp.mailfrom=163.com;
 dkim=pass (1024-bit key) header.d=163.com header.i=@163.com
 header.b=KB9MJjvX; arc=none smtp.client-ip=117.135.210.3
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=none dis=none) header.from=163.com
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=163.com
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (1024-bit key) header.d=163.com header.i=@163.com
 header.b="KB9MJjvX"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com;
	s=s110527; h=From:Subject:Date:Message-ID:MIME-Version; bh=73lFm
	s+gOb4OUsHmwZs/2rCT35x2LYfoJha12tZAvOE=; b=KB9MJjvX13cj2hyxiij0i
	qOl7KS3z/ngpALJQEA3lJabgbz5u+W6IOyv/LIKaqJ729rRjqrwMfLFDsHDlTOLE
	TZ0Qsl49haPVpgXBswQ5pGXs0vfbtCtL9Te+HxHqOukrl6naC/LtVwrJ+3ZVS22i
	OloF2u6lTCH+D2QsrYPGrU=
Received: from ProDesk.. (unknown [])
	by gzsmtp4 (Coremail) with SMTP id PygvCgDnd405Lu1nJwOJBA--.36321S9;
	Wed, 02 Apr 2025 20:32:04 +0800 (CST)
From: Andy Yan <andyshrk@163.com>
To: heiko@sntech.de
Cc: conor+dt@kernel.org,
	krzk+dt@kernel.org,
	robh@kernel.org,
	hjc@rock-chips.com,
	mripard@kernel.org,
	neil.armstrong@linaro.org,
	dmitry.baryshkov@oss.qualcomm.com,
	devicetree@vger.kernel.org,
	dri-devel@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	linux-rockchip@lists.infradead.org,
	Andy Yan <andy.yan@rock-chips.com>
Subject: [PATCH v3 7/7] drm/rockchip: inno-hdmi: Convert to drm bridge
Date: Wed,  2 Apr 2025 20:31:41 +0800
Message-ID: <20250402123150.238234-8-andyshrk@163.com>
X-Mailer: git-send-email 2.43.0
In-Reply-To: <20250402123150.238234-1-andyshrk@163.com>
References: <20250402123150.238234-1-andyshrk@163.com>
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
X-CM-TRANSID: PygvCgDnd405Lu1nJwOJBA--.36321S9
X-Coremail-Antispam: 1Uf129KBjvAXoWDXr4UJr17ArykJFWrAFy3twb_yoW7tFyfXo
	Z7JFnxXw18Zr1xZr4DG3WI9rsrZ3Wxtrn3Xw1rAFWkZasrJw4qga47KryFvF9FqFyrKr98
	Cw1kKFn3Gr93AF4Dn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3
	AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjxUIk9NUUUUU
X-CM-SenderInfo: 5dqg52xkunqiywtou0bp/xtbB0gUjXmftK+o5lQACsP
Content-Type: text/plain; charset="utf-8"

From: Andy Yan <andy.yan@rock-chips.com>

Convert it to drm bridge driver, it will be convenient for us to
migrate the connector part to the display driver later.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>

---

Changes in v3:
- First included in v3
- Link to V2: https://lore.kernel.org/dri-devel/20250325132944.171111-1-and=
yshrk@163.com/

 drivers/gpu/drm/bridge/Kconfig                |   7 +
 drivers/gpu/drm/bridge/Makefile               |   1 +
 .../inno_hdmi.c =3D> bridge/inno-hdmi.c}        | 924 ++++++++++--------
 drivers/gpu/drm/rockchip/Kconfig              |   1 +
 drivers/gpu/drm/rockchip/Makefile             |   2 +-
 drivers/gpu/drm/rockchip/inno_hdmi-rockchip.c | 187 ++++
 drivers/gpu/drm/rockchip/inno_hdmi.h          | 349 -------
 include/drm/bridge/inno_hdmi.h                |  33 +
 8 files changed, 741 insertions(+), 763 deletions(-)
 rename drivers/gpu/drm/{rockchip/inno_hdmi.c =3D> bridge/inno-hdmi.c} (52%)
 create mode 100644 drivers/gpu/drm/rockchip/inno_hdmi-rockchip.c
 delete mode 100644 drivers/gpu/drm/rockchip/inno_hdmi.h
 create mode 100644 include/drm/bridge/inno_hdmi.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index d20f1646dac27..39ba511181d9b 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -98,6 +98,13 @@ config DRM_I2C_NXP_TDA998X
        help
          Support for NXP Semiconductors TDA998X HDMI encoders.
=20
+config DRM_INNO_HDMI
+	tristate
+	select DRM_BRIDGE_CONNECTOR
+	select DRM_DISPLAY_HDMI_HELPER
+	select DRM_DISPLAY_HELPER
+	select DRM_KMS_HELPER
+
 config DRM_ITE_IT6263
 	tristate "ITE IT6263 LVDS/HDMI bridge"
 	depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makef=
ile
index 245e8a27e3fc5..efe049afa4d27 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_DRM_FSL_LDB) +=3D fsl-ldb.o
 tda998x-y :=3D tda998x_drv.o
 obj-$(CONFIG_DRM_I2C_NXP_TDA998X) +=3D tda998x.o
=20
+obj-$(CONFIG_DRM_INNO_HDMI) +=3D inno-hdmi.o
 obj-$(CONFIG_DRM_ITE_IT6263) +=3D ite-it6263.o
 obj-$(CONFIG_DRM_ITE_IT6505) +=3D ite-it6505.o
 obj-$(CONFIG_DRM_LONTIUM_LT8912B) +=3D lontium-lt8912b.o
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/bridge/=
inno-hdmi.c
similarity index 52%
rename from drivers/gpu/drm/rockchip/inno_hdmi.c
rename to drivers/gpu/drm/bridge/inno-hdmi.c
index db4b4038e51d5..2e8c19a438fed 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/bridge/inno-hdmi.c
@@ -3,12 +3,14 @@
  * Copyright (C) Rockchip Electronics Co., Ltd.
  *    Zheng Yang <zhengyang@rock-chips.com>
  *    Yakir Yang <ykk@rock-chips.com>
+ *    Andy Yan <andyshrk@163.com>
  */
=20
 #include <linux/irq.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/err.h>
+#include <linux/i2c.h>
 #include <linux/hdmi.h>
 #include <linux/mfd/syscon.h>
 #include <linux/mod_devicetable.h>
@@ -17,45 +19,370 @@
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
=20
+#include <drm/bridge/inno_hdmi.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_of.h>
+#include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_simple_kms_helper.h>
=20
 #include <drm/display/drm_hdmi_helper.h>
 #include <drm/display/drm_hdmi_state_helper.h>
=20
-#include "rockchip_drm_drv.h"
+#define INNO_HDMI_MIN_TMDS_CLOCK  25000000U
=20
-#include "inno_hdmi.h"
+#define DDC_SEGMENT_ADDR		0x30
+
+#define HDMI_SCL_RATE			(100 * 1000)
+#define DDC_BUS_FREQ_L			0x4b
+#define DDC_BUS_FREQ_H			0x4c
+
+#define HDMI_SYS_CTRL			0x00
+#define m_RST_ANALOG			BIT(6)
+#define v_RST_ANALOG			(0 << 6)
+#define v_NOT_RST_ANALOG		BIT(6)
+#define m_RST_DIGITAL			BIT(5)
+#define v_RST_DIGITAL			(0 << 5)
+#define v_NOT_RST_DIGITAL		BIT(5)
+#define m_REG_CLK_INV			BIT(4)
+#define v_REG_CLK_NOT_INV		(0 << 4)
+#define v_REG_CLK_INV			BIT(4)
+#define m_VCLK_INV			BIT(3)
+#define v_VCLK_NOT_INV			(0 << 3)
+#define v_VCLK_INV			BIT(3)
+#define m_REG_CLK_SOURCE		BIT(2)
+#define v_REG_CLK_SOURCE_TMDS		(0 << 2)
+#define v_REG_CLK_SOURCE_SYS		BIT(2)
+#define m_POWER				BIT(1)
+#define v_PWR_ON			(0 << 1)
+#define v_PWR_OFF			BIT(1)
+#define m_INT_POL			(1 << 0)
+#define v_INT_POL_HIGH			1
+#define v_INT_POL_LOW			0
+
+#define HDMI_VIDEO_CONTRL1		0x01
+#define m_VIDEO_INPUT_FORMAT		(7 << 1)
+#define m_DE_SOURCE			(1 << 0)
+#define v_VIDEO_INPUT_FORMAT(n)		((n) << 1)
+#define v_DE_EXTERNAL			1
+#define v_DE_INTERNAL			0
+enum {
+	VIDEO_INPUT_SDR_RGB444 =3D 0,
+	VIDEO_INPUT_DDR_RGB444 =3D 5,
+	VIDEO_INPUT_DDR_YCBCR422 =3D 6
+};
=20
-#define HIWORD_UPDATE(val, mask)	((val) | (mask) << 16)
+#define HDMI_VIDEO_CONTRL2		0x02
+#define m_VIDEO_OUTPUT_COLOR		(3 << 6)
+#define m_VIDEO_INPUT_BITS		(3 << 4)
+#define m_VIDEO_INPUT_CSP		(1 << 0)
+#define v_VIDEO_OUTPUT_COLOR(n)		(((n) & 0x3) << 6)
+#define v_VIDEO_INPUT_BITS(n)		((n) << 4)
+#define v_VIDEO_INPUT_CSP(n)		((n) << 0)
+enum {
+	VIDEO_INPUT_12BITS =3D 0,
+	VIDEO_INPUT_10BITS =3D 1,
+	VIDEO_INPUT_REVERT =3D 2,
+	VIDEO_INPUT_8BITS =3D 3,
+};
=20
-#define INNO_HDMI_MIN_TMDS_CLOCK  25000000U
+#define HDMI_VIDEO_CONTRL		0x03
+#define m_VIDEO_AUTO_CSC		BIT(7)
+#define v_VIDEO_AUTO_CSC(n)		((n) << 7)
+#define m_VIDEO_C0_C2_SWAP		(1 << 0)
+#define v_VIDEO_C0_C2_SWAP(n)		((n) << 0)
+enum {
+	C0_C2_CHANGE_ENABLE =3D 0,
+	C0_C2_CHANGE_DISABLE =3D 1,
+	AUTO_CSC_DISABLE =3D 0,
+	AUTO_CSC_ENABLE =3D 1,
+};
+
+#define HDMI_VIDEO_CONTRL3		0x04
+#define m_COLOR_DEPTH_NOT_INDICATED	BIT(4)
+#define m_SOF				BIT(3)
+#define m_COLOR_RANGE			BIT(2)
+#define m_CSC				(1 << 0)
+#define v_COLOR_DEPTH_NOT_INDICATED(n)	((n) << 4)
+#define v_SOF_ENABLE			(0 << 3)
+#define v_SOF_DISABLE			BIT(3)
+#define v_COLOR_RANGE_FULL		BIT(2)
+#define v_COLOR_RANGE_LIMITED		(0 << 2)
+#define v_CSC_ENABLE			1
+#define v_CSC_DISABLE			0
+
+#define HDMI_AV_MUTE			0x05
+#define m_AVMUTE_CLEAR			BIT(7)
+#define m_AVMUTE_ENABLE			BIT(6)
+#define m_AUDIO_MUTE			BIT(1)
+#define m_VIDEO_BLACK			(1 << 0)
+#define v_AVMUTE_CLEAR(n)		((n) << 7)
+#define v_AVMUTE_ENABLE(n)		((n) << 6)
+#define v_AUDIO_MUTE(n)			((n) << 1)
+#define v_VIDEO_MUTE(n)			((n) << 0)
+
+#define HDMI_VIDEO_TIMING_CTL		0x08
+#define v_HSYNC_POLARITY(n)		((n) << 3)
+#define v_VSYNC_POLARITY(n)		((n) << 2)
+#define v_INETLACE(n)			((n) << 1)
+#define v_EXTERANL_VIDEO(n)		((n) << 0)
+
+#define HDMI_VIDEO_EXT_HTOTAL_L		0x09
+#define HDMI_VIDEO_EXT_HTOTAL_H		0x0a
+#define HDMI_VIDEO_EXT_HBLANK_L		0x0b
+#define HDMI_VIDEO_EXT_HBLANK_H		0x0c
+#define HDMI_VIDEO_EXT_HDELAY_L		0x0d
+#define HDMI_VIDEO_EXT_HDELAY_H		0x0e
+#define HDMI_VIDEO_EXT_HDURATION_L	0x0f
+#define HDMI_VIDEO_EXT_HDURATION_H	0x10
+#define HDMI_VIDEO_EXT_VTOTAL_L		0x11
+#define HDMI_VIDEO_EXT_VTOTAL_H		0x12
+#define HDMI_VIDEO_EXT_VBLANK		0x13
+#define HDMI_VIDEO_EXT_VDELAY		0x14
+#define HDMI_VIDEO_EXT_VDURATION	0x15
+
+#define HDMI_VIDEO_CSC_COEF		0x18
+
+#define HDMI_AUDIO_CTRL1		0x35
+enum {
+	CTS_SOURCE_INTERNAL =3D 0,
+	CTS_SOURCE_EXTERNAL =3D 1,
+};
+
+#define v_CTS_SOURCE(n)			((n) << 7)
+
+enum {
+	DOWNSAMPLE_DISABLE =3D 0,
+	DOWNSAMPLE_1_2 =3D 1,
+	DOWNSAMPLE_1_4 =3D 2,
+};
+
+#define v_DOWN_SAMPLE(n)		((n) << 5)
+
+enum {
+	AUDIO_SOURCE_IIS =3D 0,
+	AUDIO_SOURCE_SPDIF =3D 1,
+};
+
+#define v_AUDIO_SOURCE(n)		((n) << 3)
+
+#define v_MCLK_ENABLE(n)		((n) << 2)
+
+enum {
+	MCLK_128FS =3D 0,
+	MCLK_256FS =3D 1,
+	MCLK_384FS =3D 2,
+	MCLK_512FS =3D 3,
+};
+
+#define v_MCLK_RATIO(n)			(n)
+
+#define AUDIO_SAMPLE_RATE		0x37
+
+enum {
+	AUDIO_32K =3D 0x3,
+	AUDIO_441K =3D 0x0,
+	AUDIO_48K =3D 0x2,
+	AUDIO_882K =3D 0x8,
+	AUDIO_96K =3D 0xa,
+	AUDIO_1764K =3D 0xc,
+	AUDIO_192K =3D 0xe,
+};
=20
-#define RK3036_GRF_SOC_CON2	0x148
-#define RK3036_HDMI_PHSYNC	BIT(4)
-#define RK3036_HDMI_PVSYNC	BIT(5)
+#define AUDIO_I2S_MODE			0x38
=20
-enum inno_hdmi_dev_type {
-	RK3036_HDMI,
-	RK3128_HDMI,
+enum {
+	I2S_CHANNEL_1_2 =3D 1,
+	I2S_CHANNEL_3_4 =3D 3,
+	I2S_CHANNEL_5_6 =3D 7,
+	I2S_CHANNEL_7_8 =3D 0xf
 };
=20
-struct inno_hdmi_phy_config {
-	unsigned long pixelclock;
-	u8 pre_emphasis;
-	u8 voltage_level_control;
+#define v_I2S_CHANNEL(n)		((n) << 2)
+
+enum {
+	I2S_STANDARD =3D 0,
+	I2S_LEFT_JUSTIFIED =3D 1,
+	I2S_RIGHT_JUSTIFIED =3D 2,
+};
+
+#define v_I2S_MODE(n)			(n)
+
+#define AUDIO_I2S_MAP			0x39
+#define AUDIO_I2S_SWAPS_SPDIF		0x3a
+#define v_SPIDF_FREQ(n)			(n)
+
+#define N_32K				0x1000
+#define N_441K				0x1880
+#define N_882K				0x3100
+#define N_1764K				0x6200
+#define N_48K				0x1800
+#define N_96K				0x3000
+#define N_192K				0x6000
+
+#define HDMI_AUDIO_CHANNEL_STATUS	0x3e
+#define m_AUDIO_STATUS_NLPCM		BIT(7)
+#define m_AUDIO_STATUS_USE		BIT(6)
+#define m_AUDIO_STATUS_COPYRIGHT	BIT(5)
+#define m_AUDIO_STATUS_ADDITION		(3 << 2)
+#define m_AUDIO_STATUS_CLK_ACCURACY	(2 << 0)
+#define v_AUDIO_STATUS_NLPCM(n)		(((n) & 1) << 7)
+#define AUDIO_N_H			0x3f
+#define AUDIO_N_M			0x40
+#define AUDIO_N_L			0x41
+
+#define HDMI_AUDIO_CTS_H		0x45
+#define HDMI_AUDIO_CTS_M		0x46
+#define HDMI_AUDIO_CTS_L		0x47
+
+#define HDMI_DDC_CLK_L			0x4b
+#define HDMI_DDC_CLK_H			0x4c
+
+#define HDMI_EDID_SEGMENT_POINTER	0x4d
+#define HDMI_EDID_WORD_ADDR		0x4e
+#define HDMI_EDID_FIFO_OFFSET		0x4f
+#define HDMI_EDID_FIFO_ADDR		0x50
+
+#define HDMI_PACKET_SEND_MANUAL		0x9c
+#define HDMI_PACKET_SEND_AUTO		0x9d
+#define m_PACKET_GCP_EN			BIT(7)
+#define m_PACKET_MSI_EN			BIT(6)
+#define m_PACKET_SDI_EN			BIT(5)
+#define m_PACKET_VSI_EN			BIT(4)
+#define v_PACKET_GCP_EN(n)		(((n) & 1) << 7)
+#define v_PACKET_MSI_EN(n)		(((n) & 1) << 6)
+#define v_PACKET_SDI_EN(n)		(((n) & 1) << 5)
+#define v_PACKET_VSI_EN(n)		(((n) & 1) << 4)
+
+#define HDMI_CONTROL_PACKET_BUF_INDEX	0x9f
+
+enum {
+	INFOFRAME_VSI =3D 0x05,
+	INFOFRAME_AVI =3D 0x06,
+	INFOFRAME_AAI =3D 0x08,
 };
=20
-struct inno_hdmi_variant {
-	enum inno_hdmi_dev_type dev_type;
-	struct inno_hdmi_phy_config *phy_configs;
-	struct inno_hdmi_phy_config *default_phy_config;
+#define HDMI_CONTROL_PACKET_ADDR	0xa0
+#define HDMI_MAXIMUM_INFO_FRAME_SIZE	0x11
+
+enum {
+	AVI_COLOR_MODE_RGB =3D 0,
+	AVI_COLOR_MODE_YCBCR422 =3D 1,
+	AVI_COLOR_MODE_YCBCR444 =3D 2,
+	AVI_COLORIMETRY_NO_DATA =3D 0,
+
+	AVI_COLORIMETRY_SMPTE_170M =3D 1,
+	AVI_COLORIMETRY_ITU709 =3D 2,
+	AVI_COLORIMETRY_EXTENDED =3D 3,
+
+	AVI_CODED_FRAME_ASPECT_NO_DATA =3D 0,
+	AVI_CODED_FRAME_ASPECT_4_3 =3D 1,
+	AVI_CODED_FRAME_ASPECT_16_9 =3D 2,
+
+	ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME =3D 0x08,
+	ACTIVE_ASPECT_RATE_4_3 =3D 0x09,
+	ACTIVE_ASPECT_RATE_16_9 =3D 0x0A,
+	ACTIVE_ASPECT_RATE_14_9 =3D 0x0B,
 };
=20
+#define HDMI_HDCP_CTRL			0x52
+#define m_HDMI_DVI			BIT(1)
+#define v_HDMI_DVI(n)			((n) << 1)
+
+#define HDMI_INTERRUPT_MASK1		0xc0
+#define HDMI_INTERRUPT_STATUS1		0xc1
+#define	m_INT_ACTIVE_VSYNC		BIT(5)
+#define m_INT_EDID_READY		BIT(2)
+
+#define HDMI_INTERRUPT_MASK2		0xc2
+#define HDMI_INTERRUPT_STATUS2		0xc3
+#define m_INT_HDCP_ERR			BIT(7)
+#define m_INT_BKSV_FLAG			BIT(6)
+#define m_INT_HDCP_OK			BIT(4)
+
+#define HDMI_STATUS			0xc8
+#define m_HOTPLUG			BIT(7)
+#define m_MASK_INT_HOTPLUG		BIT(5)
+#define m_INT_HOTPLUG			BIT(1)
+#define v_MASK_INT_HOTPLUG(n)		(((n) & 0x1) << 5)
+
+#define HDMI_COLORBAR                   0xc9
+
+#define HDMI_PHY_SYNC			0xce
+#define HDMI_PHY_SYS_CTL		0xe0
+#define m_TMDS_CLK_SOURCE		BIT(5)
+#define v_TMDS_FROM_PLL			(0 << 5)
+#define v_TMDS_FROM_GEN			BIT(5)
+#define m_PHASE_CLK			BIT(4)
+#define v_DEFAULT_PHASE			(0 << 4)
+#define v_SYNC_PHASE			BIT(4)
+#define m_TMDS_CURRENT_PWR		BIT(3)
+#define v_TURN_ON_CURRENT		(0 << 3)
+#define v_CAT_OFF_CURRENT		BIT(3)
+#define m_BANDGAP_PWR			BIT(2)
+#define v_BANDGAP_PWR_UP		(0 << 2)
+#define v_BANDGAP_PWR_DOWN		BIT(2)
+#define m_PLL_PWR			BIT(1)
+#define v_PLL_PWR_UP			(0 << 1)
+#define v_PLL_PWR_DOWN			BIT(1)
+#define m_TMDS_CHG_PWR			(1 << 0)
+#define v_TMDS_CHG_PWR_UP		(0 << 0)
+#define v_TMDS_CHG_PWR_DOWN		(1 << 0)
+
+#define HDMI_PHY_CHG_PWR		0xe1
+#define v_CLK_CHG_PWR(n)		(((n) & 1) << 3)
+#define v_DATA_CHG_PWR(n)		(((n) & 7) << 0)
+
+#define HDMI_PHY_DRIVER			0xe2
+#define v_CLK_MAIN_DRIVER(n)		((n) << 4)
+#define v_DATA_MAIN_DRIVER(n)		((n) << 0)
+
+#define HDMI_PHY_PRE_EMPHASIS		0xe3
+#define v_PRE_EMPHASIS(n)		(((n) & 7) << 4)
+#define v_CLK_PRE_DRIVER(n)		(((n) & 3) << 2)
+#define v_DATA_PRE_DRIVER(n)		(((n) & 3) << 0)
+
+#define HDMI_PHY_FEEDBACK_DIV_RATIO_LOW		0xe7
+#define v_FEEDBACK_DIV_LOW(n)			((n) & 0xff)
+#define HDMI_PHY_FEEDBACK_DIV_RATIO_HIGH	0xe8
+#define v_FEEDBACK_DIV_HIGH(n)			((n) & 1)
+
+#define HDMI_PHY_PRE_DIV_RATIO		0xed
+#define v_PRE_DIV_RATIO(n)		((n) & 0x1f)
+
+#define HDMI_CEC_CTRL			0xd0
+#define m_ADJUST_FOR_HISENSE		BIT(6)
+#define m_REJECT_RX_BROADCAST		BIT(5)
+#define m_BUSFREETIME_ENABLE		BIT(2)
+#define m_REJECT_RX			BIT(1)
+#define m_START_TX			(1 << 0)
+
+#define HDMI_CEC_DATA			0xd1
+#define HDMI_CEC_TX_OFFSET		0xd2
+#define HDMI_CEC_RX_OFFSET		0xd3
+#define HDMI_CEC_CLK_H			0xd4
+#define HDMI_CEC_CLK_L			0xd5
+#define HDMI_CEC_TX_LENGTH		0xd6
+#define HDMI_CEC_RX_LENGTH		0xd7
+#define HDMI_CEC_TX_INT_MASK		0xd8
+#define m_TX_DONE			BIT(3)
+#define m_TX_NOACK			BIT(2)
+#define m_TX_BROADCAST_REJ		BIT(1)
+#define m_TX_BUSNOTFREE			(1 << 0)
+
+#define HDMI_CEC_RX_INT_MASK		0xd9
+#define m_RX_LA_ERR			BIT(4)
+#define m_RX_GLITCH			BIT(3)
+#define m_RX_DONE			(1 << 0)
+
+#define HDMI_CEC_TX_INT			0xda
+#define HDMI_CEC_RX_INT			0xdb
+#define HDMI_CEC_BUSFREETIME_L		0xdc
+#define HDMI_CEC_BUSFREETIME_H		0xdd
+#define HDMI_CEC_LOGICADDR		0xde
+
 struct inno_hdmi_i2c {
 	struct i2c_adapter adap;
=20
@@ -68,41 +395,18 @@ struct inno_hdmi_i2c {
=20
 struct inno_hdmi {
 	struct device *dev;
-
+	struct drm_bridge bridge;
 	struct clk *pclk;
 	struct clk *refclk;
 	void __iomem *regs;
 	struct regmap *grf;
=20
-	struct drm_connector	connector;
-	struct rockchip_encoder	encoder;
-
 	struct inno_hdmi_i2c *i2c;
 	struct i2c_adapter *ddc;
-
-	const struct inno_hdmi_variant *variant;
+	const struct inno_hdmi_plat_data *plat_data;
+	unsigned int colorimetry;
 };
=20
-struct inno_hdmi_connector_state {
-	struct drm_connector_state	base;
-	unsigned int			colorimetry;
-};
-
-static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
-{
-	struct rockchip_encoder *rkencoder =3D to_rockchip_encoder(encoder);
-
-	return container_of(rkencoder, struct inno_hdmi, encoder);
-}
-
-static struct inno_hdmi *connector_to_inno_hdmi(struct drm_connector *conn=
ector)
-{
-	return container_of(connector, struct inno_hdmi, connector);
-}
-
-#define to_inno_hdmi_conn_state(conn_state) \
-	container_of_const(conn_state, struct inno_hdmi_connector_state, base)
-
 enum {
 	CSC_RGB_0_255_TO_ITU601_16_235_8BIT,
 	CSC_RGB_0_255_TO_ITU709_16_235_8BIT,
@@ -145,23 +449,15 @@ static const char coeff_csc[][24] =3D {
 	},
 };
=20
-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 struct inno_hdmi *bridge_to_inno_hdmi(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct inno_hdmi, bridge);
+}
=20
 static int inno_hdmi_find_phy_config(struct inno_hdmi *hdmi,
 				     unsigned long pixelclk)
 {
-	const struct inno_hdmi_phy_config *phy_configs =3D
-						hdmi->variant->phy_configs;
+	const struct inno_hdmi_phy_config *phy_configs =3D hdmi->plat_data->phy_c=
onfigs;
 	int i;
=20
 	for (i =3D 0; phy_configs[i].pixelclock !=3D ~0UL; i++) {
@@ -233,12 +529,12 @@ static void inno_hdmi_power_up(struct inno_hdmi *hdmi,
 	int ret =3D inno_hdmi_find_phy_config(hdmi, mpixelclock);
=20
 	if (ret < 0) {
-		phy_config =3D hdmi->variant->default_phy_config;
+		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->variant->phy_configs[ret];
+		phy_config =3D &hdmi->plat_data->phy_configs[ret];
 	}
=20
 	inno_hdmi_sys_power(hdmi, false);
@@ -255,32 +551,46 @@ static void inno_hdmi_power_up(struct inno_hdmi *hdmi,
 	inno_hdmi_sys_power(hdmi, true);
 };
=20
-static void inno_hdmi_reset(struct inno_hdmi *hdmi)
+static void inno_hdmi_init_hw(struct inno_hdmi *hdmi)
 {
 	u32 val;
 	u32 msk;
=20
 	hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL);
-	udelay(100);
+	usleep_range(100, 150);
=20
 	hdmi_modb(hdmi, HDMI_SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG);
-	udelay(100);
+	usleep_range(100, 150);
=20
 	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_HIGH;
 	hdmi_modb(hdmi, HDMI_SYS_CTRL, msk, val);
=20
 	inno_hdmi_standby(hdmi);
+
+	/*
+	 * When the controller isn't configured to an accurate
+	 * video timing and there is no reference clock available,
+	 * then the TMDS clock source would be switched to PCLK_HDMI,
+	 * so we need to init the TMDS rate to PCLK rate, and
+	 * reconfigure the DDC clock.
+	 */
+	if (hdmi->refclk)
+		inno_hdmi_i2c_init(hdmi, clk_get_rate(hdmi->refclk));
+	else
+		inno_hdmi_i2c_init(hdmi, clk_get_rate(hdmi->pclk));
+
+	/* Unmute hotplug interrupt */
+	hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1));
 }
=20
-static int inno_hdmi_disable_frame(struct drm_connector *connector,
-				   enum hdmi_infoframe_type type)
+static int inno_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge,
+					    enum hdmi_infoframe_type type)
 {
-	struct inno_hdmi *hdmi =3D connector_to_inno_hdmi(connector);
+	struct inno_hdmi *hdmi =3D bridge_to_inno_hdmi(bridge);
=20
 	if (type !=3D HDMI_INFOFRAME_TYPE_AVI) {
-		drm_err(connector->dev,
-			"Unsupported infoframe type: %u\n", type);
+		drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type);
 		return 0;
 	}
=20
@@ -289,20 +599,19 @@ static int inno_hdmi_disable_frame(struct drm_connect=
or *connector,
 	return 0;
 }
=20
-static int inno_hdmi_upload_frame(struct drm_connector *connector,
-				  enum hdmi_infoframe_type type,
-				  const u8 *buffer, size_t len)
+static int inno_hdmi_bridge_write_infoframe(struct drm_bridge *bridge,
+					    enum hdmi_infoframe_type type,
+					    const u8 *buffer, size_t len)
 {
-	struct inno_hdmi *hdmi =3D connector_to_inno_hdmi(connector);
+	struct inno_hdmi *hdmi =3D bridge_to_inno_hdmi(bridge);
 	ssize_t i;
=20
 	if (type !=3D HDMI_INFOFRAME_TYPE_AVI) {
-		drm_err(connector->dev,
-			"Unsupported infoframe type: %u\n", type);
+		drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type);
 		return 0;
 	}
=20
-	inno_hdmi_disable_frame(connector, type);
+	inno_hdmi_bridge_clear_infoframe(bridge, type);
=20
 	for (i =3D 0; i < len; i++)
 		hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i, buffer[i]);
@@ -310,17 +619,9 @@ static int inno_hdmi_upload_frame(struct drm_connector=
 *connector,
 	return 0;
 }
=20
-static const struct drm_connector_hdmi_funcs inno_hdmi_hdmi_connector_func=
s =3D {
-	.clear_infoframe	=3D inno_hdmi_disable_frame,
-	.write_infoframe	=3D inno_hdmi_upload_frame,
-};
-
-static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
+static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi, struct drm_c=
onnector *connector)
 {
-	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;
@@ -356,7 +657,7 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi =
*hdmi)
 			return 0;
 		}
 	} else {
-		if (inno_conn_state->colorimetry =3D=3D HDMI_COLORIMETRY_ITU_601) {
+		if (hdmi->colorimetry =3D=3D HDMI_COLORIMETRY_ITU_601) {
 			if (conn_state->hdmi.output_format =3D=3D HDMI_COLORSPACE_YUV444) {
 				csc_mode =3D CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
 				auto_csc =3D AUTO_CSC_DISABLE;
@@ -374,8 +675,7 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi =
*hdmi)
 	}
=20
 	for (i =3D 0; i < 24; i++)
-		hdmi_writeb(hdmi, HDMI_VIDEO_CSC_COEF + i,
-			    coeff_csc[csc_mode][i]);
+		hdmi_writeb(hdmi, HDMI_VIDEO_CSC_COEF + i, coeff_csc[csc_mode][i]);
=20
 	value =3D v_SOF_DISABLE | csc_enable | v_COLOR_DEPTH_NOT_INDICATED(1);
 	hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL3, value);
@@ -389,15 +689,11 @@ static int inno_hdmi_config_video_csc(struct inno_hdm=
i *hdmi)
 static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
 					 struct drm_display_mode *mode)
 {
-	int value, psync;
-
-	if (hdmi->variant->dev_type =3D=3D RK3036_HDMI) {
-		psync =3D mode->flags & DRM_MODE_FLAG_PHSYNC ? RK3036_HDMI_PHSYNC : 0;
-		value =3D HIWORD_UPDATE(psync, RK3036_HDMI_PHSYNC);
-		psync =3D mode->flags & DRM_MODE_FLAG_PVSYNC ? RK3036_HDMI_PVSYNC : 0;
-		value |=3D HIWORD_UPDATE(psync, RK3036_HDMI_PVSYNC);
-		regmap_write(hdmi->grf, RK3036_GRF_SOC_CON2, value);
-	}
+	const struct inno_hdmi_plat_ops *plat_ops =3D hdmi->plat_data->ops;
+	u32 value;
+
+	if (plat_ops && plat_ops->enable)
+		plat_ops->enable(hdmi->dev, mode);
=20
 	/* Set detail external video timing polarity and interlace mode */
 	value =3D v_EXTERANL_VIDEO(1);
@@ -446,14 +742,16 @@ static int inno_hdmi_config_video_timing(struct inno_=
hdmi *hdmi,
 	return 0;
 }
=20
-static int inno_hdmi_setup(struct inno_hdmi *hdmi,
-			   struct drm_atomic_state *state)
+static int inno_hdmi_setup(struct inno_hdmi *hdmi, struct drm_atomic_state=
 *state)
 {
-	struct drm_connector *connector =3D &hdmi->connector;
-	struct drm_display_info *display =3D &connector->display_info;
+	struct drm_bridge *bridge =3D &hdmi->bridge;
+	struct drm_connector *connector;
+	struct drm_display_info *info;
 	struct drm_connector_state *new_conn_state;
 	struct drm_crtc_state *new_crtc_state;
=20
+	connector =3D drm_atomic_get_new_connector_for_encoder(state, bridge->enc=
oder);
+
 	new_conn_state =3D drm_atomic_get_new_connector_state(state, connector);
 	if (WARN_ON(!new_conn_state))
 		return -EINVAL;
@@ -462,17 +760,18 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
 	if (WARN_ON(!new_crtc_state))
 		return -EINVAL;
=20
+	info =3D &connector->display_info;
+
 	/* 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));
=20
 	/* Set HDMI Mode */
-	hdmi_writeb(hdmi, HDMI_HDCP_CTRL,
-		    v_HDMI_DVI(display->is_hdmi));
+	hdmi_writeb(hdmi, HDMI_HDCP_CTRL, v_HDMI_DVI(info->is_hdmi));
=20
 	inno_hdmi_config_video_timing(hdmi, &new_crtc_state->adjusted_mode);
=20
-	inno_hdmi_config_video_csc(hdmi);
+	inno_hdmi_config_video_csc(hdmi, connector);
=20
 	drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
=20
@@ -493,9 +792,11 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
 	return 0;
 }
=20
-static enum drm_mode_status inno_hdmi_display_mode_valid(struct inno_hdmi =
*hdmi,
-							 const struct drm_display_mode *mode)
+static enum drm_mode_status inno_hdmi_bridge_mode_valid(struct drm_bridge =
*bridge,
+							const struct drm_display_info *info,
+							const struct drm_display_mode *mode)
 {
+	struct inno_hdmi *hdmi =3D bridge_to_inno_hdmi(bridge);
 	unsigned long mpixelclk, max_tolerance;
 	long rounded_refclk;
=20
@@ -525,189 +826,78 @@ static enum drm_mode_status inno_hdmi_display_mode_v=
alid(struct inno_hdmi *hdmi,
 	return MODE_OK;
 }
=20
-static void inno_hdmi_encoder_enable(struct drm_encoder *encoder,
-				     struct drm_atomic_state *state)
-{
-	struct inno_hdmi *hdmi =3D encoder_to_inno_hdmi(encoder);
-
-	inno_hdmi_setup(hdmi, state);
-}
-
-static void inno_hdmi_encoder_disable(struct drm_encoder *encoder,
-				      struct drm_atomic_state *state)
-{
-	struct inno_hdmi *hdmi =3D encoder_to_inno_hdmi(encoder);
-
-	inno_hdmi_standby(hdmi);
-}
-
-static int
-inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
-			       struct drm_crtc_state *crtc_state,
-			       struct drm_connector_state *conn_state)
-{
-	struct rockchip_crtc_state *s =3D to_rockchip_crtc_state(crtc_state);
-	struct drm_display_mode *mode =3D &crtc_state->adjusted_mode;
-	u8 vic =3D drm_match_cea_mode(mode);
-	struct inno_hdmi_connector_state *inno_conn_state =3D
-					to_inno_hdmi_conn_state(conn_state);
-
-	s->output_mode =3D ROCKCHIP_OUT_MODE_P888;
-	s->output_type =3D DRM_MODE_CONNECTOR_HDMIA;
-
-	if (vic =3D=3D 6 || vic =3D=3D 7 ||
-	    vic =3D=3D 21 || vic =3D=3D 22 ||
-	    vic =3D=3D 2 || vic =3D=3D 3 ||
-	    vic =3D=3D 17 || vic =3D=3D 18)
-		inno_conn_state->colorimetry =3D HDMI_COLORIMETRY_ITU_601;
-	else
-		inno_conn_state->colorimetry =3D HDMI_COLORIMETRY_ITU_709;
-
-	return 0;
-}
-
-static const struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_func=
s =3D {
-	.atomic_check	=3D inno_hdmi_encoder_atomic_check,
-	.atomic_enable	=3D inno_hdmi_encoder_enable,
-	.atomic_disable	=3D inno_hdmi_encoder_disable,
-};
-
-static enum drm_connector_status
-inno_hdmi_connector_detect(struct drm_connector *connector, bool force)
+static enum drm_connector_status inno_hdmi_bridge_detect(struct drm_bridge=
 *bridge)
 {
-	struct inno_hdmi *hdmi =3D connector_to_inno_hdmi(connector);
+	struct inno_hdmi *hdmi =3D bridge_to_inno_hdmi(bridge);
=20
 	return (hdmi_readb(hdmi, HDMI_STATUS) & m_HOTPLUG) ?
 		connector_status_connected : connector_status_disconnected;
 }
=20
-static int inno_hdmi_connector_get_modes(struct drm_connector *connector)
+static const struct drm_edid *
+inno_hdmi_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector=
 *connector)
 {
-	struct inno_hdmi *hdmi =3D connector_to_inno_hdmi(connector);
+	struct inno_hdmi *hdmi =3D bridge_to_inno_hdmi(bridge);
 	const struct drm_edid *drm_edid;
-	int ret =3D 0;
-
-	if (!hdmi->ddc)
-		return 0;
=20
-	drm_edid =3D drm_edid_read_ddc(connector, hdmi->ddc);
-	drm_edid_connector_update(connector, drm_edid);
-	ret =3D drm_edid_connector_add_modes(connector);
-	drm_edid_free(drm_edid);
+	drm_edid =3D drm_edid_read_ddc(connector, bridge->ddc);
+	if (!drm_edid)
+		dev_dbg(hdmi->dev, "failed to get edid\n");
=20
-	return ret;
+	return drm_edid;
 }
=20
-static enum drm_mode_status
-inno_hdmi_connector_mode_valid(struct drm_connector *connector,
-			       const struct drm_display_mode *mode)
+static void inno_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
+					   struct drm_atomic_state *state)
 {
-	struct inno_hdmi *hdmi =3D connector_to_inno_hdmi(connector);
+	struct inno_hdmi *hdmi =3D bridge_to_inno_hdmi(bridge);
=20
-	return  inno_hdmi_display_mode_valid(hdmi, mode);
+	inno_hdmi_setup(hdmi, state);
 }
=20
-static void
-inno_hdmi_connector_destroy_state(struct drm_connector *connector,
-				  struct drm_connector_state *state)
+static void inno_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
+					    struct drm_atomic_state *state)
 {
-	struct inno_hdmi_connector_state *inno_conn_state =3D
-						to_inno_hdmi_conn_state(state);
+	struct inno_hdmi *hdmi =3D bridge_to_inno_hdmi(bridge);
=20
-	__drm_atomic_helper_connector_destroy_state(&inno_conn_state->base);
-	kfree(inno_conn_state);
+	inno_hdmi_standby(hdmi);
 }
=20
-static void inno_hdmi_connector_reset(struct drm_connector *connector)
-{
-	struct inno_hdmi_connector_state *inno_conn_state;
-
-	if (connector->state) {
-		inno_hdmi_connector_destroy_state(connector, connector->state);
-		connector->state =3D NULL;
-	}
-
-	inno_conn_state =3D kzalloc(sizeof(*inno_conn_state), GFP_KERNEL);
-	if (!inno_conn_state)
-		return;
-
-	__drm_atomic_helper_connector_reset(connector, &inno_conn_state->base);
-	__drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
-
-	inno_conn_state->colorimetry =3D HDMI_COLORIMETRY_ITU_709;
-}
+static int inno_hdmi_bridge_atomic_check(struct drm_bridge *bridge,
+					 struct drm_bridge_state *bridge_state,
+					 struct drm_crtc_state *crtc_state,
+					 struct drm_connector_state *conn_state)
=20
-static struct drm_connector_state *
-inno_hdmi_connector_duplicate_state(struct drm_connector *connector)
 {
-	struct inno_hdmi_connector_state *inno_conn_state;
-
-	if (WARN_ON(!connector->state))
-		return NULL;
-
-	inno_conn_state =3D kmemdup(to_inno_hdmi_conn_state(connector->state),
-				  sizeof(*inno_conn_state), GFP_KERNEL);
-
-	if (!inno_conn_state)
-		return NULL;
+	struct inno_hdmi *hdmi =3D bridge_to_inno_hdmi(bridge);
+	struct drm_display_mode *mode =3D &crtc_state->adjusted_mode;
+	u8 vic =3D drm_match_cea_mode(mode);
=20
-	__drm_atomic_helper_connector_duplicate_state(connector,
-						      &inno_conn_state->base);
+	if (vic =3D=3D 6 || vic =3D=3D 7 ||
+	    vic =3D=3D 21 || vic =3D=3D 22 ||
+	    vic =3D=3D 2 || vic =3D=3D 3 ||
+	    vic =3D=3D 17 || vic =3D=3D 18)
+		hdmi->colorimetry =3D HDMI_COLORIMETRY_ITU_601;
+	else
+		hdmi->colorimetry =3D HDMI_COLORIMETRY_ITU_709;
=20
-	return &inno_conn_state->base;
+	return 0;
 }
=20
-static const struct drm_connector_funcs inno_hdmi_connector_funcs =3D {
-	.fill_modes =3D drm_helper_probe_single_connector_modes,
-	.detect =3D inno_hdmi_connector_detect,
-	.reset =3D inno_hdmi_connector_reset,
-	.atomic_duplicate_state =3D inno_hdmi_connector_duplicate_state,
-	.atomic_destroy_state =3D inno_hdmi_connector_destroy_state,
-};
-
-static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs =
=3D {
-	.atomic_check =3D drm_atomic_helper_connector_hdmi_check,
-	.get_modes =3D inno_hdmi_connector_get_modes,
-	.mode_valid =3D inno_hdmi_connector_mode_valid,
+static const struct drm_bridge_funcs inno_hdmi_bridge_funcs =3D {
+	.atomic_duplicate_state =3D drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state =3D drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset =3D drm_atomic_helper_bridge_reset,
+	.atomic_enable =3D inno_hdmi_bridge_atomic_enable,
+	.atomic_disable =3D inno_hdmi_bridge_atomic_disable,
+	.atomic_check =3D inno_hdmi_bridge_atomic_check,
+	.detect =3D inno_hdmi_bridge_detect,
+	.edid_read =3D inno_hdmi_bridge_edid_read,
+	.hdmi_clear_infoframe =3D inno_hdmi_bridge_clear_infoframe,
+	.hdmi_write_infoframe =3D inno_hdmi_bridge_write_infoframe,
+	.mode_valid =3D inno_hdmi_bridge_mode_valid,
 };
=20
-static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hd=
mi)
-{
-	struct drm_encoder *encoder =3D &hdmi->encoder.encoder;
-	struct device *dev =3D hdmi->dev;
-
-	encoder->possible_crtcs =3D drm_of_find_possible_crtcs(drm, dev->of_node);
-
-	/*
-	 * If we failed to find the CRTC(s) which this encoder is
-	 * supposed to be connected to, it's because the CRTC has
-	 * not been registered yet.  Defer probing, and hope that
-	 * the required CRTC is added later.
-	 */
-	if (encoder->possible_crtcs =3D=3D 0)
-		return -EPROBE_DEFER;
-
-	drm_encoder_helper_add(encoder, &inno_hdmi_encoder_helper_funcs);
-	drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
-
-	hdmi->connector.polled =3D DRM_CONNECTOR_POLL_HPD;
-
-	drm_connector_helper_add(&hdmi->connector,
-				 &inno_hdmi_connector_helper_funcs);
-	drmm_connector_hdmi_init(drm, &hdmi->connector,
-				 "Rockchip", "Inno HDMI",
-				 &inno_hdmi_connector_funcs,
-				 &inno_hdmi_hdmi_connector_funcs,
-				 DRM_MODE_CONNECTOR_HDMIA,
-				 hdmi->ddc,
-				 BIT(HDMI_COLORSPACE_RGB),
-				 8);
-
-	drm_connector_attach_encoder(&hdmi->connector, encoder);
-
-	return 0;
-}
-
 static irqreturn_t inno_hdmi_i2c_irq(struct inno_hdmi *hdmi)
 {
 	struct inno_hdmi_i2c *i2c =3D hdmi->i2c;
@@ -725,6 +915,15 @@ static irqreturn_t inno_hdmi_i2c_irq(struct inno_hdmi =
*hdmi)
 	return IRQ_HANDLED;
 }
=20
+static irqreturn_t inno_hdmi_irq(int irq, void *dev_id)
+{
+	struct inno_hdmi *hdmi =3D dev_id;
+
+	drm_helper_hpd_irq_event(hdmi->bridge.dev);
+
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t inno_hdmi_hardirq(int irq, void *dev_id)
 {
 	struct inno_hdmi *hdmi =3D dev_id;
@@ -743,15 +942,6 @@ static irqreturn_t inno_hdmi_hardirq(int irq, void *de=
v_id)
 	return ret;
 }
=20
-static irqreturn_t inno_hdmi_irq(int irq, void *dev_id)
-{
-	struct inno_hdmi *hdmi =3D dev_id;
-
-	drm_helper_hpd_irq_event(hdmi->connector.dev);
-
-	return IRQ_HANDLED;
-}
-
 static int inno_hdmi_i2c_read(struct inno_hdmi *hdmi, struct i2c_msg *msgs)
 {
 	int length =3D msgs->len;
@@ -775,8 +965,7 @@ static int inno_hdmi_i2c_write(struct inno_hdmi *hdmi, =
struct i2c_msg *msgs)
 	 * we assume that each word write to this i2c adapter
 	 * should be the offset of EDID word address.
 	 */
-	if ((msgs->len !=3D 1) ||
-	    ((msgs->addr !=3D DDC_ADDR) && (msgs->addr !=3D DDC_SEGMENT_ADDR)))
+	if (msgs->len !=3D 1 || (msgs->addr !=3D DDC_ADDR && msgs->addr !=3D DDC_=
SEGMENT_ADDR))
 		return -EINVAL;
=20
 	reinit_completion(&hdmi->i2c->cmp);
@@ -867,7 +1056,7 @@ static struct i2c_adapter *inno_hdmi_i2c_adapter(struc=
t inno_hdmi *hdmi)
 	strscpy(adap->name, "Inno HDMI", sizeof(adap->name));
 	i2c_set_adapdata(adap, hdmi);
=20
-	ret =3D i2c_add_adapter(adap);
+	ret =3D devm_i2c_add_adapter(hdmi->dev, adap);
 	if (ret) {
 		dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
 		devm_kfree(hdmi->dev, i2c);
@@ -876,177 +1065,86 @@ static struct i2c_adapter *inno_hdmi_i2c_adapter(st=
ruct inno_hdmi *hdmi)
=20
 	hdmi->i2c =3D i2c;
=20
-	DRM_DEV_INFO(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
+	dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
=20
 	return adap;
 }
=20
-static int inno_hdmi_bind(struct device *dev, struct device *master,
-				 void *data)
+struct inno_hdmi *inno_hdmi_bind(struct device *dev,
+				 struct drm_encoder *encoder,
+				 const struct inno_hdmi_plat_data *plat_data)
 {
 	struct platform_device *pdev =3D to_platform_device(dev);
-	struct drm_device *drm =3D data;
 	struct inno_hdmi *hdmi;
-	const struct inno_hdmi_variant *variant;
 	int irq;
 	int ret;
=20
+	if (!plat_data->phy_configs || !plat_data->default_phy_config) {
+		dev_err(dev, "Missing platform PHY ops\n");
+		return ERR_PTR(-ENODEV);
+	}
+
 	hdmi =3D devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
 	if (!hdmi)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
=20
 	hdmi->dev =3D dev;
-
-	variant =3D of_device_get_match_data(hdmi->dev);
-	if (!variant)
-		return -EINVAL;
-
-	hdmi->variant =3D variant;
+	hdmi->plat_data =3D plat_data;
=20
 	hdmi->regs =3D devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(hdmi->regs))
-		return PTR_ERR(hdmi->regs);
-
-	hdmi->pclk =3D devm_clk_get(hdmi->dev, "pclk");
-	if (IS_ERR(hdmi->pclk))
-		return dev_err_probe(dev, PTR_ERR(hdmi->pclk), "Unable to get HDMI pclk\=
n");
+		return ERR_CAST(hdmi->regs);
=20
-	ret =3D clk_prepare_enable(hdmi->pclk);
-	if (ret)
-		return dev_err_probe(dev, ret, "Cannot enable HDMI pclk: %d\n", ret);
-
-	hdmi->refclk =3D devm_clk_get_optional(hdmi->dev, "ref");
-	if (IS_ERR(hdmi->refclk)) {
-		ret =3D dev_err_probe(dev, PTR_ERR(hdmi->refclk), "Unable to get HDMI re=
fclk\n");
-		goto err_disable_pclk;
+	hdmi->pclk =3D devm_clk_get_enabled(hdmi->dev, "pclk");
+	if (IS_ERR(hdmi->pclk)) {
+		dev_err(dev, "Unable to get HDMI pclk\n");
+		return ERR_CAST(hdmi->pclk);
 	}
=20
-	ret =3D clk_prepare_enable(hdmi->refclk);
-	if (ret) {
-		ret =3D dev_err_probe(dev, ret, "Cannot enable HDMI refclk: %d\n", ret);
-		goto err_disable_pclk;
+	hdmi->refclk =3D devm_clk_get_enabled(hdmi->dev, "ref");
+	if (IS_ERR(hdmi->refclk)) {
+		dev_err(dev, "Unable to get HDMI refclk\n");
+		return ERR_CAST(hdmi->refclk);
 	}
=20
-	if (hdmi->variant->dev_type =3D=3D RK3036_HDMI) {
-		hdmi->grf =3D syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,gr=
f");
-		if (IS_ERR(hdmi->grf)) {
-			ret =3D dev_err_probe(dev, PTR_ERR(hdmi->grf),
-					    "Unable to get rockchip,grf\n");
-			goto err_disable_clk;
-		}
-	}
+	inno_hdmi_init_hw(hdmi);
=20
 	irq =3D platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		ret =3D irq;
-		goto err_disable_clk;
-	}
-
-	inno_hdmi_reset(hdmi);
-
-	hdmi->ddc =3D inno_hdmi_i2c_adapter(hdmi);
-	if (IS_ERR(hdmi->ddc)) {
-		ret =3D PTR_ERR(hdmi->ddc);
-		hdmi->ddc =3D NULL;
-		goto err_disable_clk;
-	}
-
-	/*
-	 * When the controller isn't configured to an accurate
-	 * video timing and there is no reference clock available,
-	 * then the TMDS clock source would be switched to PCLK_HDMI,
-	 * so we need to init the TMDS rate to PCLK rate, and
-	 * reconfigure the DDC clock.
-	 */
-	if (hdmi->refclk)
-		inno_hdmi_i2c_init(hdmi, clk_get_rate(hdmi->refclk));
-	else
-		inno_hdmi_i2c_init(hdmi, clk_get_rate(hdmi->pclk));
-
-	ret =3D inno_hdmi_register(drm, hdmi);
-	if (ret)
-		goto err_put_adapter;
-
-	dev_set_drvdata(dev, hdmi);
-
-	/* Unmute hotplug interrupt */
-	hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1));
+	if (irq < 0)
+		return ERR_PTR(ret);
=20
 	ret =3D devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq,
 					inno_hdmi_irq, IRQF_SHARED,
 					dev_name(dev), hdmi);
-	if (ret < 0)
-		goto err_cleanup_hdmi;
-
-	return 0;
-err_cleanup_hdmi:
-	hdmi->connector.funcs->destroy(&hdmi->connector);
-	hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder);
-err_put_adapter:
-	i2c_put_adapter(hdmi->ddc);
-err_disable_clk:
-	clk_disable_unprepare(hdmi->refclk);
-err_disable_pclk:
-	clk_disable_unprepare(hdmi->pclk);
-	return ret;
-}
-
-static void inno_hdmi_unbind(struct device *dev, struct device *master,
-			     void *data)
-{
-	struct inno_hdmi *hdmi =3D dev_get_drvdata(dev);
-
-	hdmi->connector.funcs->destroy(&hdmi->connector);
-	hdmi->encoder.encoder.funcs->destroy(&hdmi->encoder.encoder);
-
-	i2c_put_adapter(hdmi->ddc);
-	clk_disable_unprepare(hdmi->refclk);
-	clk_disable_unprepare(hdmi->pclk);
-}
+	if (ret)
+		return ERR_PTR(ret);
=20
-static const struct component_ops inno_hdmi_ops =3D {
-	.bind	=3D inno_hdmi_bind,
-	.unbind	=3D inno_hdmi_unbind,
-};
+	hdmi->bridge.driver_private =3D hdmi;
+	hdmi->bridge.funcs =3D &inno_hdmi_bridge_funcs;
+	hdmi->bridge.ops =3D DRM_BRIDGE_OP_DETECT |
+			   DRM_BRIDGE_OP_EDID |
+			   DRM_BRIDGE_OP_HDMI |
+			   DRM_BRIDGE_OP_HPD;
+	hdmi->bridge.of_node =3D pdev->dev.of_node;
+	hdmi->bridge.type =3D DRM_MODE_CONNECTOR_HDMIA;
+	hdmi->bridge.vendor =3D "Inno";
+	hdmi->bridge.product =3D "Inno HDMI";
+
+	hdmi->bridge.ddc =3D inno_hdmi_i2c_adapter(hdmi);
+	if (IS_ERR(hdmi->bridge.ddc))
+		return ERR_CAST(hdmi->bridge.ddc);
+
+	ret =3D devm_drm_bridge_add(dev, &hdmi->bridge);
+	if (ret)
+		return ERR_PTR(ret);
=20
-static int inno_hdmi_probe(struct platform_device *pdev)
-{
-	return component_add(&pdev->dev, &inno_hdmi_ops);
-}
+	ret =3D drm_bridge_attach(encoder, &hdmi->bridge, NULL, DRM_BRIDGE_ATTACH=
_NO_CONNECTOR);
+	if (ret)
+		return ERR_PTR(ret);
=20
-static void inno_hdmi_remove(struct platform_device *pdev)
-{
-	component_del(&pdev->dev, &inno_hdmi_ops);
+	return hdmi;
 }
-
-static const struct inno_hdmi_variant rk3036_inno_hdmi_variant =3D {
-	.dev_type =3D RK3036_HDMI,
-	.phy_configs =3D rk3036_hdmi_phy_configs,
-	.default_phy_config =3D &rk3036_hdmi_phy_configs[1],
-};
-
-static const struct inno_hdmi_variant rk3128_inno_hdmi_variant =3D {
-	.dev_type =3D RK3128_HDMI,
-	.phy_configs =3D rk3128_hdmi_phy_configs,
-	.default_phy_config =3D &rk3128_hdmi_phy_configs[1],
-};
-
-static const struct of_device_id inno_hdmi_dt_ids[] =3D {
-	{ .compatible =3D "rockchip,rk3036-inno-hdmi",
-	  .data =3D &rk3036_inno_hdmi_variant,
-	},
-	{ .compatible =3D "rockchip,rk3128-inno-hdmi",
-	  .data =3D &rk3128_inno_hdmi_variant,
-	},
-	{},
-};
-MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids);
-
-struct platform_driver inno_hdmi_driver =3D {
-	.probe  =3D inno_hdmi_probe,
-	.remove =3D inno_hdmi_remove,
-	.driver =3D {
-		.name =3D "innohdmi-rockchip",
-		.of_match_table =3D inno_hdmi_dt_ids,
-	},
-};
+EXPORT_SYMBOL_GPL(inno_hdmi_bind);
+MODULE_AUTHOR("Andy Yan <andyshrk@163.com>");
+MODULE_DESCRIPTION("INNOSILICON HDMI transmitter library");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kc=
onfig
index 26c4410b2407c..06cd969ce4f85 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -10,6 +10,7 @@ config DRM_ROCKCHIP
 	select DRM_ANALOGIX_DP if ROCKCHIP_ANALOGIX_DP
 	select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
 	select DRM_DW_HDMI_QP if ROCKCHIP_DW_HDMI_QP
+	select DRM_INNO_HDMI if ROCKCHIP_INNO_HDMI
 	select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
 	select DRM_DW_MIPI_DSI2 if ROCKCHIP_DW_MIPI_DSI2
 	select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/M=
akefile
index 2b867cebbc121..11176db14af6e 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -14,7 +14,7 @@ rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) +=3D dw_hdmi-rockc=
hip.o
 rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI_QP) +=3D dw_hdmi_qp-rockchip.o
 rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) +=3D dw-mipi-dsi-rockchip.o
 rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI2) +=3D dw-mipi-dsi2-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/dr=
m/rockchip/inno_hdmi-rockchip.c
new file mode 100644
index 0000000000000..d1f37bd92b89c
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/inno_hdmi-rockchip.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) Rockchip Electronics Co., Ltd.
+ *    Zheng Yang <zhengyang@rock-chips.com>
+ *    Andy Yan <andy.yan@rock-chips.com>
+ */
+#include <linux/err.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <drm/bridge/inno_hdmi.h>
+#include <drm/drm_bridge_connector.h>
+#include <drm/drm_of.h>
+
+#include "rockchip_drm_drv.h"
+
+#define HIWORD_UPDATE(val, mask)	((val) | (mask) << 16)
+
+#define RK3036_GRF_SOC_CON2	0x148
+#define RK3036_HDMI_PHSYNC	BIT(4)
+#define RK3036_HDMI_PVSYNC	BIT(5)
+
+enum inno_hdmi_dev_type {
+	RK3036_HDMI,
+	RK3128_HDMI,
+};
+
+struct inno_hdmi_connector_state {
+	struct drm_connector_state	base;
+	unsigned int			colorimetry;
+};
+
+struct rockchip_inno_hdmi {
+	struct inno_hdmi *base;
+	struct device *dev;
+	struct regmap *grf;
+	struct rockchip_encoder encoder;
+};
+
+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 void inno_hdmi_rk3036_enable(struct device *dev, struct drm_display=
_mode *mode)
+{
+	struct rockchip_inno_hdmi *hdmi =3D dev_get_drvdata(dev);
+	int value, psync;
+
+	psync =3D mode->flags & DRM_MODE_FLAG_PHSYNC ? RK3036_HDMI_PHSYNC : 0;
+	value =3D HIWORD_UPDATE(psync, RK3036_HDMI_PHSYNC);
+	psync =3D mode->flags & DRM_MODE_FLAG_PVSYNC ? RK3036_HDMI_PVSYNC : 0;
+	value |=3D HIWORD_UPDATE(psync, RK3036_HDMI_PVSYNC);
+	regmap_write(hdmi->grf, RK3036_GRF_SOC_CON2, value);
+}
+
+static int inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
+					  struct drm_crtc_state *crtc_state,
+					  struct drm_connector_state *conn_state)
+{
+	struct rockchip_crtc_state *s =3D to_rockchip_crtc_state(crtc_state);
+
+	s->output_mode =3D ROCKCHIP_OUT_MODE_P888;
+	s->output_type =3D DRM_MODE_CONNECTOR_HDMIA;
+
+	return 0;
+}
+
+static const struct drm_encoder_helper_funcs inno_hdmi_rockchip_encoder_he=
lper_funcs =3D {
+	.atomic_check	=3D inno_hdmi_encoder_atomic_check,
+};
+
+static int inno_hdmi_rockchip_bind(struct device *dev, struct device *mast=
er, void *data)
+{
+	struct drm_device *drm =3D data;
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+	struct rockchip_inno_hdmi *hdmi;
+	const struct inno_hdmi_plat_data *plat_data;
+	int ret;
+
+	hdmi =3D devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
+	if (!hdmi)
+		return -ENOMEM;
+
+	hdmi->dev =3D dev;
+
+	plat_data =3D of_device_get_match_data(hdmi->dev);
+	if (!plat_data)
+		return -EINVAL;
+
+	if (of_device_is_compatible(dev->of_node, "rockchip,rk3036-inno-hdmi")) {
+		hdmi->grf =3D syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,gr=
f");
+		if (IS_ERR(hdmi->grf))
+			return dev_err_probe(dev, PTR_ERR(hdmi->grf), "Unable to get rockchip,g=
rf\n");
+	}
+
+	encoder =3D &hdmi->encoder.encoder;
+	encoder->possible_crtcs =3D drm_of_find_possible_crtcs(drm, dev->of_node);
+
+	/*
+	 * If we failed to find the CRTC(s) which this encoder is
+	 * supposed to be connected to, it's because the CRTC has
+	 * not been registered yet.  Defer probing, and hope that
+	 * the required CRTC is added later.
+	 */
+	if (encoder->possible_crtcs =3D=3D 0)
+		return -EPROBE_DEFER;
+
+	ret =3D drmm_encoder_init(drm, encoder, NULL, DRM_MODE_ENCODER_TMDS, NULL=
);
+	if (ret)
+		return ret;
+
+	drm_encoder_helper_add(encoder, &inno_hdmi_rockchip_encoder_helper_funcs);
+
+	dev_set_drvdata(dev, hdmi);
+
+	hdmi->base =3D inno_hdmi_bind(dev, encoder, plat_data);
+
+	connector =3D drm_bridge_connector_init(drm, encoder);
+	if (IS_ERR(connector)) {
+		ret =3D PTR_ERR(connector);
+		dev_err(hdmi->dev, "failed to init bridge connector: %d\n", ret);
+		return ret;
+	}
+
+	return drm_connector_attach_encoder(connector, encoder);
+}
+
+static const struct component_ops inno_hdmi_rockchip_ops =3D {
+	.bind	=3D inno_hdmi_rockchip_bind,
+};
+
+static int inno_hdmi_rockchip_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &inno_hdmi_rockchip_ops);
+}
+
+static void inno_hdmi_rockchip_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &inno_hdmi_rockchip_ops);
+}
+
+static const struct inno_hdmi_plat_ops rk3036_inno_hdmi_plat_ops =3D {
+	.enable =3D inno_hdmi_rk3036_enable,
+};
+
+static const struct inno_hdmi_plat_data rk3036_inno_hdmi_plat_data =3D {
+	.ops =3D &rk3036_inno_hdmi_plat_ops,
+	.phy_configs =3D rk3036_hdmi_phy_configs,
+	.default_phy_config =3D &rk3036_hdmi_phy_configs[1],
+};
+
+static const struct inno_hdmi_plat_data rk3128_inno_hdmi_plat_data =3D {
+	.phy_configs =3D rk3128_hdmi_phy_configs,
+	.default_phy_config =3D &rk3128_hdmi_phy_configs[1],
+};
+
+static const struct of_device_id inno_hdmi_rockchip_dt_ids[] =3D {
+	{ .compatible =3D "rockchip,rk3036-inno-hdmi",
+	  .data =3D &rk3036_inno_hdmi_plat_data,
+	},
+	{ .compatible =3D "rockchip,rk3128-inno-hdmi",
+	  .data =3D &rk3128_inno_hdmi_plat_data,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, inno_hdmi_rockchip_dt_ids);
+
+struct platform_driver inno_hdmi_driver =3D {
+	.probe  =3D inno_hdmi_rockchip_probe,
+	.remove =3D inno_hdmi_rockchip_remove,
+	.driver =3D {
+		.name =3D "innohdmi-rockchip",
+		.of_match_table =3D inno_hdmi_rockchip_dt_ids,
+	},
+};
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.h b/drivers/gpu/drm/rockchi=
p/inno_hdmi.h
deleted file mode 100644
index 8b7ef3fac4853..0000000000000
--- a/drivers/gpu/drm/rockchip/inno_hdmi.h
+++ /dev/null
@@ -1,349 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) Rockchip Electronics Co., Ltd.
- *    Zheng Yang <zhengyang@rock-chips.com>
- *    Yakir Yang <ykk@rock-chips.com>
- */
-
-#ifndef __INNO_HDMI_H__
-#define __INNO_HDMI_H__
-
-#define DDC_SEGMENT_ADDR		0x30
-
-#define HDMI_SCL_RATE			(100*1000)
-#define DDC_BUS_FREQ_L			0x4b
-#define DDC_BUS_FREQ_H			0x4c
-
-#define HDMI_SYS_CTRL			0x00
-#define m_RST_ANALOG			(1 << 6)
-#define v_RST_ANALOG			(0 << 6)
-#define v_NOT_RST_ANALOG		(1 << 6)
-#define m_RST_DIGITAL			(1 << 5)
-#define v_RST_DIGITAL			(0 << 5)
-#define v_NOT_RST_DIGITAL		(1 << 5)
-#define m_REG_CLK_INV			(1 << 4)
-#define v_REG_CLK_NOT_INV		(0 << 4)
-#define v_REG_CLK_INV			(1 << 4)
-#define m_VCLK_INV			(1 << 3)
-#define v_VCLK_NOT_INV			(0 << 3)
-#define v_VCLK_INV			(1 << 3)
-#define m_REG_CLK_SOURCE		(1 << 2)
-#define v_REG_CLK_SOURCE_TMDS		(0 << 2)
-#define v_REG_CLK_SOURCE_SYS		(1 << 2)
-#define m_POWER				(1 << 1)
-#define v_PWR_ON			(0 << 1)
-#define v_PWR_OFF			(1 << 1)
-#define m_INT_POL			(1 << 0)
-#define v_INT_POL_HIGH			1
-#define v_INT_POL_LOW			0
-
-#define HDMI_VIDEO_CONTRL1		0x01
-#define m_VIDEO_INPUT_FORMAT		(7 << 1)
-#define m_DE_SOURCE			(1 << 0)
-#define v_VIDEO_INPUT_FORMAT(n)		(n << 1)
-#define v_DE_EXTERNAL			1
-#define v_DE_INTERNAL			0
-enum {
-	VIDEO_INPUT_SDR_RGB444 =3D 0,
-	VIDEO_INPUT_DDR_RGB444 =3D 5,
-	VIDEO_INPUT_DDR_YCBCR422 =3D 6
-};
-
-#define HDMI_VIDEO_CONTRL2		0x02
-#define m_VIDEO_OUTPUT_COLOR		(3 << 6)
-#define m_VIDEO_INPUT_BITS		(3 << 4)
-#define m_VIDEO_INPUT_CSP		(1 << 0)
-#define v_VIDEO_OUTPUT_COLOR(n)		(((n) & 0x3) << 6)
-#define v_VIDEO_INPUT_BITS(n)		(n << 4)
-#define v_VIDEO_INPUT_CSP(n)		(n << 0)
-enum {
-	VIDEO_INPUT_12BITS =3D 0,
-	VIDEO_INPUT_10BITS =3D 1,
-	VIDEO_INPUT_REVERT =3D 2,
-	VIDEO_INPUT_8BITS =3D 3,
-};
-
-#define HDMI_VIDEO_CONTRL		0x03
-#define m_VIDEO_AUTO_CSC		(1 << 7)
-#define v_VIDEO_AUTO_CSC(n)		(n << 7)
-#define m_VIDEO_C0_C2_SWAP		(1 << 0)
-#define v_VIDEO_C0_C2_SWAP(n)		(n << 0)
-enum {
-	C0_C2_CHANGE_ENABLE =3D 0,
-	C0_C2_CHANGE_DISABLE =3D 1,
-	AUTO_CSC_DISABLE =3D 0,
-	AUTO_CSC_ENABLE =3D 1,
-};
-
-#define HDMI_VIDEO_CONTRL3		0x04
-#define m_COLOR_DEPTH_NOT_INDICATED	(1 << 4)
-#define m_SOF				(1 << 3)
-#define m_COLOR_RANGE			(1 << 2)
-#define m_CSC				(1 << 0)
-#define v_COLOR_DEPTH_NOT_INDICATED(n)	((n) << 4)
-#define v_SOF_ENABLE			(0 << 3)
-#define v_SOF_DISABLE			(1 << 3)
-#define v_COLOR_RANGE_FULL		(1 << 2)
-#define v_COLOR_RANGE_LIMITED		(0 << 2)
-#define v_CSC_ENABLE			1
-#define v_CSC_DISABLE			0
-
-#define HDMI_AV_MUTE			0x05
-#define m_AVMUTE_CLEAR			(1 << 7)
-#define m_AVMUTE_ENABLE			(1 << 6)
-#define m_AUDIO_MUTE			(1 << 1)
-#define m_VIDEO_BLACK			(1 << 0)
-#define v_AVMUTE_CLEAR(n)		(n << 7)
-#define v_AVMUTE_ENABLE(n)		(n << 6)
-#define v_AUDIO_MUTE(n)			(n << 1)
-#define v_VIDEO_MUTE(n)			(n << 0)
-
-#define HDMI_VIDEO_TIMING_CTL		0x08
-#define v_HSYNC_POLARITY(n)		(n << 3)
-#define v_VSYNC_POLARITY(n)		(n << 2)
-#define v_INETLACE(n)			(n << 1)
-#define v_EXTERANL_VIDEO(n)		(n << 0)
-
-#define HDMI_VIDEO_EXT_HTOTAL_L		0x09
-#define HDMI_VIDEO_EXT_HTOTAL_H		0x0a
-#define HDMI_VIDEO_EXT_HBLANK_L		0x0b
-#define HDMI_VIDEO_EXT_HBLANK_H		0x0c
-#define HDMI_VIDEO_EXT_HDELAY_L		0x0d
-#define HDMI_VIDEO_EXT_HDELAY_H		0x0e
-#define HDMI_VIDEO_EXT_HDURATION_L	0x0f
-#define HDMI_VIDEO_EXT_HDURATION_H	0x10
-#define HDMI_VIDEO_EXT_VTOTAL_L		0x11
-#define HDMI_VIDEO_EXT_VTOTAL_H		0x12
-#define HDMI_VIDEO_EXT_VBLANK		0x13
-#define HDMI_VIDEO_EXT_VDELAY		0x14
-#define HDMI_VIDEO_EXT_VDURATION	0x15
-
-#define HDMI_VIDEO_CSC_COEF		0x18
-
-#define HDMI_AUDIO_CTRL1		0x35
-enum {
-	CTS_SOURCE_INTERNAL =3D 0,
-	CTS_SOURCE_EXTERNAL =3D 1,
-};
-#define v_CTS_SOURCE(n)			(n << 7)
-
-enum {
-	DOWNSAMPLE_DISABLE =3D 0,
-	DOWNSAMPLE_1_2 =3D 1,
-	DOWNSAMPLE_1_4 =3D 2,
-};
-#define v_DOWN_SAMPLE(n)		(n << 5)
-
-enum {
-	AUDIO_SOURCE_IIS =3D 0,
-	AUDIO_SOURCE_SPDIF =3D 1,
-};
-#define v_AUDIO_SOURCE(n)		(n << 3)
-
-#define v_MCLK_ENABLE(n)		(n << 2)
-enum {
-	MCLK_128FS =3D 0,
-	MCLK_256FS =3D 1,
-	MCLK_384FS =3D 2,
-	MCLK_512FS =3D 3,
-};
-#define v_MCLK_RATIO(n)			(n)
-
-#define AUDIO_SAMPLE_RATE		0x37
-enum {
-	AUDIO_32K =3D 0x3,
-	AUDIO_441K =3D 0x0,
-	AUDIO_48K =3D 0x2,
-	AUDIO_882K =3D 0x8,
-	AUDIO_96K =3D 0xa,
-	AUDIO_1764K =3D 0xc,
-	AUDIO_192K =3D 0xe,
-};
-
-#define AUDIO_I2S_MODE			0x38
-enum {
-	I2S_CHANNEL_1_2 =3D 1,
-	I2S_CHANNEL_3_4 =3D 3,
-	I2S_CHANNEL_5_6 =3D 7,
-	I2S_CHANNEL_7_8 =3D 0xf
-};
-#define v_I2S_CHANNEL(n)		((n) << 2)
-enum {
-	I2S_STANDARD =3D 0,
-	I2S_LEFT_JUSTIFIED =3D 1,
-	I2S_RIGHT_JUSTIFIED =3D 2,
-};
-#define v_I2S_MODE(n)			(n)
-
-#define AUDIO_I2S_MAP			0x39
-#define AUDIO_I2S_SWAPS_SPDIF		0x3a
-#define v_SPIDF_FREQ(n)			(n)
-
-#define N_32K				0x1000
-#define N_441K				0x1880
-#define N_882K				0x3100
-#define N_1764K				0x6200
-#define N_48K				0x1800
-#define N_96K				0x3000
-#define N_192K				0x6000
-
-#define HDMI_AUDIO_CHANNEL_STATUS	0x3e
-#define m_AUDIO_STATUS_NLPCM		(1 << 7)
-#define m_AUDIO_STATUS_USE		(1 << 6)
-#define m_AUDIO_STATUS_COPYRIGHT	(1 << 5)
-#define m_AUDIO_STATUS_ADDITION		(3 << 2)
-#define m_AUDIO_STATUS_CLK_ACCURACY	(2 << 0)
-#define v_AUDIO_STATUS_NLPCM(n)		((n & 1) << 7)
-#define AUDIO_N_H			0x3f
-#define AUDIO_N_M			0x40
-#define AUDIO_N_L			0x41
-
-#define HDMI_AUDIO_CTS_H		0x45
-#define HDMI_AUDIO_CTS_M		0x46
-#define HDMI_AUDIO_CTS_L		0x47
-
-#define HDMI_DDC_CLK_L			0x4b
-#define HDMI_DDC_CLK_H			0x4c
-
-#define HDMI_EDID_SEGMENT_POINTER	0x4d
-#define HDMI_EDID_WORD_ADDR		0x4e
-#define HDMI_EDID_FIFO_OFFSET		0x4f
-#define HDMI_EDID_FIFO_ADDR		0x50
-
-#define HDMI_PACKET_SEND_MANUAL		0x9c
-#define HDMI_PACKET_SEND_AUTO		0x9d
-#define m_PACKET_GCP_EN			(1 << 7)
-#define m_PACKET_MSI_EN			(1 << 6)
-#define m_PACKET_SDI_EN			(1 << 5)
-#define m_PACKET_VSI_EN			(1 << 4)
-#define v_PACKET_GCP_EN(n)		((n & 1) << 7)
-#define v_PACKET_MSI_EN(n)		((n & 1) << 6)
-#define v_PACKET_SDI_EN(n)		((n & 1) << 5)
-#define v_PACKET_VSI_EN(n)		((n & 1) << 4)
-
-#define HDMI_CONTROL_PACKET_BUF_INDEX	0x9f
-enum {
-	INFOFRAME_VSI =3D 0x05,
-	INFOFRAME_AVI =3D 0x06,
-	INFOFRAME_AAI =3D 0x08,
-};
-
-#define HDMI_CONTROL_PACKET_ADDR	0xa0
-#define HDMI_MAXIMUM_INFO_FRAME_SIZE	0x11
-enum {
-	AVI_COLOR_MODE_RGB =3D 0,
-	AVI_COLOR_MODE_YCBCR422 =3D 1,
-	AVI_COLOR_MODE_YCBCR444 =3D 2,
-	AVI_COLORIMETRY_NO_DATA =3D 0,
-
-	AVI_COLORIMETRY_SMPTE_170M =3D 1,
-	AVI_COLORIMETRY_ITU709 =3D 2,
-	AVI_COLORIMETRY_EXTENDED =3D 3,
-
-	AVI_CODED_FRAME_ASPECT_NO_DATA =3D 0,
-	AVI_CODED_FRAME_ASPECT_4_3 =3D 1,
-	AVI_CODED_FRAME_ASPECT_16_9 =3D 2,
-
-	ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME =3D 0x08,
-	ACTIVE_ASPECT_RATE_4_3 =3D 0x09,
-	ACTIVE_ASPECT_RATE_16_9 =3D 0x0A,
-	ACTIVE_ASPECT_RATE_14_9 =3D 0x0B,
-};
-
-#define HDMI_HDCP_CTRL			0x52
-#define m_HDMI_DVI			(1 << 1)
-#define v_HDMI_DVI(n)			(n << 1)
-
-#define HDMI_INTERRUPT_MASK1		0xc0
-#define HDMI_INTERRUPT_STATUS1		0xc1
-#define	m_INT_ACTIVE_VSYNC		(1 << 5)
-#define m_INT_EDID_READY		(1 << 2)
-
-#define HDMI_INTERRUPT_MASK2		0xc2
-#define HDMI_INTERRUPT_STATUS2		0xc3
-#define m_INT_HDCP_ERR			(1 << 7)
-#define m_INT_BKSV_FLAG			(1 << 6)
-#define m_INT_HDCP_OK			(1 << 4)
-
-#define HDMI_STATUS			0xc8
-#define m_HOTPLUG			(1 << 7)
-#define m_MASK_INT_HOTPLUG		(1 << 5)
-#define m_INT_HOTPLUG			(1 << 1)
-#define v_MASK_INT_HOTPLUG(n)		((n & 0x1) << 5)
-
-#define HDMI_COLORBAR                   0xc9
-
-#define HDMI_PHY_SYNC			0xce
-#define HDMI_PHY_SYS_CTL		0xe0
-#define m_TMDS_CLK_SOURCE		(1 << 5)
-#define v_TMDS_FROM_PLL			(0 << 5)
-#define v_TMDS_FROM_GEN			(1 << 5)
-#define m_PHASE_CLK			(1 << 4)
-#define v_DEFAULT_PHASE			(0 << 4)
-#define v_SYNC_PHASE			(1 << 4)
-#define m_TMDS_CURRENT_PWR		(1 << 3)
-#define v_TURN_ON_CURRENT		(0 << 3)
-#define v_CAT_OFF_CURRENT		(1 << 3)
-#define m_BANDGAP_PWR			(1 << 2)
-#define v_BANDGAP_PWR_UP		(0 << 2)
-#define v_BANDGAP_PWR_DOWN		(1 << 2)
-#define m_PLL_PWR			(1 << 1)
-#define v_PLL_PWR_UP			(0 << 1)
-#define v_PLL_PWR_DOWN			(1 << 1)
-#define m_TMDS_CHG_PWR			(1 << 0)
-#define v_TMDS_CHG_PWR_UP		(0 << 0)
-#define v_TMDS_CHG_PWR_DOWN		(1 << 0)
-
-#define HDMI_PHY_CHG_PWR		0xe1
-#define v_CLK_CHG_PWR(n)		((n & 1) << 3)
-#define v_DATA_CHG_PWR(n)		((n & 7) << 0)
-
-#define HDMI_PHY_DRIVER			0xe2
-#define v_CLK_MAIN_DRIVER(n)		(n << 4)
-#define v_DATA_MAIN_DRIVER(n)		(n << 0)
-
-#define HDMI_PHY_PRE_EMPHASIS		0xe3
-#define v_PRE_EMPHASIS(n)		((n & 7) << 4)
-#define v_CLK_PRE_DRIVER(n)		((n & 3) << 2)
-#define v_DATA_PRE_DRIVER(n)		((n & 3) << 0)
-
-#define HDMI_PHY_FEEDBACK_DIV_RATIO_LOW		0xe7
-#define v_FEEDBACK_DIV_LOW(n)			(n & 0xff)
-#define HDMI_PHY_FEEDBACK_DIV_RATIO_HIGH	0xe8
-#define v_FEEDBACK_DIV_HIGH(n)			(n & 1)
-
-#define HDMI_PHY_PRE_DIV_RATIO		0xed
-#define v_PRE_DIV_RATIO(n)		(n & 0x1f)
-
-#define HDMI_CEC_CTRL			0xd0
-#define m_ADJUST_FOR_HISENSE		(1 << 6)
-#define m_REJECT_RX_BROADCAST		(1 << 5)
-#define m_BUSFREETIME_ENABLE		(1 << 2)
-#define m_REJECT_RX			(1 << 1)
-#define m_START_TX			(1 << 0)
-
-#define HDMI_CEC_DATA			0xd1
-#define HDMI_CEC_TX_OFFSET		0xd2
-#define HDMI_CEC_RX_OFFSET		0xd3
-#define HDMI_CEC_CLK_H			0xd4
-#define HDMI_CEC_CLK_L			0xd5
-#define HDMI_CEC_TX_LENGTH		0xd6
-#define HDMI_CEC_RX_LENGTH		0xd7
-#define HDMI_CEC_TX_INT_MASK		0xd8
-#define m_TX_DONE			(1 << 3)
-#define m_TX_NOACK			(1 << 2)
-#define m_TX_BROADCAST_REJ		(1 << 1)
-#define m_TX_BUSNOTFREE			(1 << 0)
-
-#define HDMI_CEC_RX_INT_MASK		0xd9
-#define m_RX_LA_ERR			(1 << 4)
-#define m_RX_GLITCH			(1 << 3)
-#define m_RX_DONE			(1 << 0)
-
-#define HDMI_CEC_TX_INT			0xda
-#define HDMI_CEC_RX_INT			0xdb
-#define HDMI_CEC_BUSFREETIME_L		0xdc
-#define HDMI_CEC_BUSFREETIME_H		0xdd
-#define HDMI_CEC_LOGICADDR		0xde
-
-#endif /* __INNO_HDMI_H__ */
diff --git a/include/drm/bridge/inno_hdmi.h b/include/drm/bridge/inno_hdmi.h
new file mode 100644
index 0000000000000..20eec29bd2a27
--- /dev/null
+++ b/include/drm/bridge/inno_hdmi.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __INNO_HDMI_QP__
+#define __INNO_HDMI_QP__
+
+struct device;
+struct drm_encoder;
+struct drm_display_mode;
+struct inno_hdmi;
+
+struct inno_hdmi_plat_ops {
+	void (*enable)(struct device *pdev, struct drm_display_mode *mode);
+};
+
+struct inno_hdmi_phy_config {
+	unsigned long pixelclock;
+	u8 pre_emphasis;
+	u8 voltage_level_control;
+};
+
+struct inno_hdmi_plat_data {
+	const struct inno_hdmi_plat_ops *ops;
+	struct inno_hdmi_phy_config *phy_configs;
+	struct inno_hdmi_phy_config *default_phy_config;
+};
+
+struct inno_hdmi *inno_hdmi_bind(struct device *pdev,
+				 struct drm_encoder *encoder,
+				 const struct inno_hdmi_plat_data *plat_data);
+#endif /* __INNO_HDMI__ */
--=20
2.43.0