From 11f9765a8e6723bcb7243f6dbc48e6deaf17b097 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 3 Apr 2022 15:15:41 -0500
Subject: [PATCH 008/117] drm/sun4i: sun8i-hdmi-phy: Add support for D1 PHY

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h  | 169 +++++++++++++++++++++++++
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c |  32 +++++
 2 files changed, 201 insertions(+)

--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -145,6 +145,175 @@
 
 #define SUN8I_HDMI_PHY_CEC_REG		0x003c
 
+#define SUN20I_HDMI_PHY_CTL0_REG	0x0040
+#define SUN20I_HDMI_PHY_CTL0_PLL_LOCK_MODE_MAN	BIT(31)
+#define SUN20I_HDMI_PHY_CTL0_PLL_LOCK_MODE	BIT(30)
+#define SUN20I_HDMI_PHY_CTL0_FIFO_WORKC_EN	BIT(29)
+#define SUN20I_HDMI_PHY_CTL0_FIFO_AUTOSYNC_DIS	BIT(28)
+#define SUN20I_HDMI_PHY_CTL0_ENTX		GENMASK(27, 24)
+#define SUN20I_HDMI_PHY_CTL0_ENBI		GENMASK(23, 20)
+#define SUN20I_HDMI_PHY_CTL0_ENLDO		BIT(18)
+#define SUN20I_HDMI_PHY_CTL0_ENLDO_FS		BIT(17)
+#define SUN20I_HDMI_PHY_CTL0_ENCK		BIT(16)
+#define SUN20I_HDMI_PHY_CTL0_REG_PLR		GENMASK(15, 12)
+#define SUN20I_HDMI_PHY_CTL0_REG_DEN		GENMASK(11, 8)
+#define SUN20I_HDMI_PHY_CTL0_REG_CSMPS		GENMASK(7, 6)
+#define SUN20I_HDMI_PHY_CTL0_REG_CK_TEST_SEL	BIT(5)
+#define SUN20I_HDMI_PHY_CTL0_REG_CK_SEL		BIT(4)
+#define SUN20I_HDMI_PHY_CTL0_HPD_EN		BIT(2)
+#define SUN20I_HDMI_PHY_CTL0_SCL_EN		BIT(1)
+#define SUN20I_HDMI_PHY_CTL0_SDA_EN		BIT(0)
+
+#define SUN20I_HDMI_PHY_CTL1_REG	0x0044
+#define SUN20I_HDMI_PHY_CTL1_RXSENSE_MODE_MAN	BIT(31)
+#define SUN20I_HDMI_PHY_CTL1_RXSENSE_MODE	BIT(30)
+#define SUN20I_HDMI_PHY_CTL1_RES_S		GENMASK(29, 28)
+#define SUN20I_HDMI_PHY_CTL1_RES_SCKTMDS	BIT(27)
+#define SUN20I_HDMI_PHY_CTL1_REG_SWI		BIT(26)
+#define SUN20I_HDMI_PHY_CTL1_REG_SVR		GENMASK(25, 24)
+#define SUN20I_HDMI_PHY_CTL1_REG_BST2		GENMASK(21, 20)
+#define SUN20I_HDMI_PHY_CTL1_REG_BST1		GENMASK(19, 18)
+#define SUN20I_HDMI_PHY_CTL1_REG_BST0		GENMASK(17, 16)
+#define SUN20I_HDMI_PHY_CTL1_REG_SP2_3		GENMASK(15, 12)
+#define SUN20I_HDMI_PHY_CTL1_REG_SP2_2		GENMASK(11, 8)
+#define SUN20I_HDMI_PHY_CTL1_REG_SP2_1		GENMASK(7, 4)
+#define SUN20I_HDMI_PHY_CTL1_REG_SP2_0		GENMASK(3, 0)
+
+#define SUN20I_HDMI_PHY_CTL2_REG	0x0048
+#define SUN20I_HDMI_PHY_CTL2_HPDO_MODE_MAN	BIT(31)
+#define SUN20I_HDMI_PHY_CTL2_HPDO_MODE		BIT(30)
+#define SUN20I_HDMI_PHY_CTL2_REG_RESDI		GENMASK(29, 24)
+#define SUN20I_HDMI_PHY_CTL2_REG_SP1_3		GENMASK(23, 19)
+#define SUN20I_HDMI_PHY_CTL2_REG_SP1_2		GENMASK(18, 14)
+#define SUN20I_HDMI_PHY_CTL2_REG_SP1_1		GENMASK(13, 9)
+#define SUN20I_HDMI_PHY_CTL2_REG_SP1_0		GENMASK(8, 4)
+#define SUN20I_HDMI_PHY_CTL2_REG_P2OPT		GENMASK(3, 0)
+
+#define SUN20I_HDMI_PHY_CTL3_REG	0x004c
+#define SUN20I_HDMI_PHY_CTL3_REG_P2_3		GENMASK(31, 28)
+#define SUN20I_HDMI_PHY_CTL3_REG_P2_2		GENMASK(27, 24)
+#define SUN20I_HDMI_PHY_CTL3_REG_P2_1		GENMASK(23, 20)
+#define SUN20I_HDMI_PHY_CTL3_REG_P2_0		GENMASK(19, 16)
+#define SUN20I_HDMI_PHY_CTL3_REG_MC3		GENMASK(15, 12)
+#define SUN20I_HDMI_PHY_CTL3_REG_MC2		GENMASK(11, 8)
+#define SUN20I_HDMI_PHY_CTL3_REG_MC1		GENMASK(7, 4)
+#define SUN20I_HDMI_PHY_CTL3_REG_MC0		GENMASK(3, 0)
+
+#define SUN20I_HDMI_PHY_CTL4_REG	0x0050
+#define SUN20I_HDMI_PHY_CTL4_REG_SLV		GENMASK(31, 29)
+#define SUN20I_HDMI_PHY_CTL4_REG_P1_3		GENMASK(28, 24)
+#define SUN20I_HDMI_PHY_CTL4_REG_P1_2		GENMASK(20, 16)
+#define SUN20I_HDMI_PHY_CTL4_REG_P1_1		GENMASK(12, 8)
+#define SUN20I_HDMI_PHY_CTL4_REG_P1_0		GENMASK(4, 0)
+
+#define SUN20I_HDMI_PHY_CTL5_REG	0x0054
+#define SUN20I_HDMI_PHY_CTL5_REG_P1OPT		GENMASK(19, 16)
+#define SUN20I_HDMI_PHY_CTL5_REG_CKPDLYOPT	BIT(12)
+#define SUN20I_HDMI_PHY_CTL5_REG_CALSW		BIT(11)
+#define SUN20I_HDMI_PHY_CTL5_ENRESCK		BIT(10)
+#define SUN20I_HDMI_PHY_CTL5_ENRES		BIT(9)
+#define SUN20I_HDMI_PHY_CTL5_ENRCAL		BIT(8)
+#define SUN20I_HDMI_PHY_CTL5_ENP2S		GENMASK(7, 4)
+#define SUN20I_HDMI_PHY_CTL5_ENIB		BIT(1)
+#define SUN20I_HDMI_PHY_CTL5_ENCALOG		BIT(0)
+
+#define SUN20I_HDMI_PLL_CTL0_REG	0x0058
+#define SUN20I_HDMI_PLL_CTL0_CKO_SEL		GENMASK(31, 30)
+#define SUN20I_HDMI_PLL_CTL0_BYPASS_PPLL	BIT(29)
+#define SUN20I_HDMI_PLL_CTL0_ENVBS		BIT(28)
+#define SUN20I_HDMI_PLL_CTL0_SLV		GENMASK(26, 24)
+#define SUN20I_HDMI_PLL_CTL0_BCR		BIT(23)
+#define SUN20I_HDMI_PLL_CTL0_BYPASS_CLRDPTH	BIT(22)
+#define SUN20I_HDMI_PLL_CTL0_CLR_DPTH		GENMASK(21, 20)
+#define SUN20I_HDMI_PLL_CTL0_CUTFB		BIT(18)
+#define SUN20I_HDMI_PLL_CTL0_DIV2_CKBIT		BIT(17)
+#define SUN20I_HDMI_PLL_CTL0_DIV2_CKTMDS	BIT(16)
+#define SUN20I_HDMI_PLL_CTL0_DIV_PRE		GENMASK(15, 12)
+#define SUN20I_HDMI_PLL_CTL0_DIVX1		BIT(10)
+#define SUN20I_HDMI_PLL_CTL0_SDRVEN		BIT(9)
+#define SUN20I_HDMI_PLL_CTL0_VCORANGE		BIT(8)
+#define SUN20I_HDMI_PLL_CTL0_N_CNTRL		GENMASK(7, 6)
+#define SUN20I_HDMI_PLL_CTL0_GMP_CNTRL		GENMASK(5, 4)
+#define SUN20I_HDMI_PLL_CTL0_PROP_CNTRL		GENMASK(2, 0)
+
+#define SUN20I_HDMI_PLL_CTL1_REG	0x005c
+#define SUN20I_HDMI_PLL_CTL1_CTRL_MODLE_CLKSRC	BIT(31)
+#define SUN20I_HDMI_PLL_CTL1_PCNT_N		GENMASK(27, 20)
+#define SUN20I_HDMI_PLL_CTL1_PCNT_EN		BIT(19)
+#define SUN20I_HDMI_PLL_CTL1_SDM_EN		BIT(18)
+#define SUN20I_HDMI_PLL_CTL1_PIXEL_REP		GENMASK(17, 16)
+#define SUN20I_HDMI_PLL_CTL1_PWRON		BIT(12)
+#define SUN20I_HDMI_PLL_CTL1_RESET		BIT(11)
+#define SUN20I_HDMI_PLL_CTL1_SCKREF		BIT(10)
+#define SUN20I_HDMI_PLL_CTL1_SCKFB		BIT(9)
+#define SUN20I_HDMI_PLL_CTL1_DRV_ANA		BIT(8)
+#define SUN20I_HDMI_PLL_CTL1_FAST_TECH		BIT(7)
+#define SUN20I_HDMI_PLL_CTL1_GEAR_SHIFT		BIT(6)
+#define SUN20I_HDMI_PLL_CTL1_REF_CNTRL		GENMASK(5, 4)
+#define SUN20I_HDMI_PLL_CTL1_INT_CNTRL		GENMASK(2, 0)
+
+#define SUN20I_HDMI_AFIFO_CFG_REG	0x0060
+#define SUN20I_HDMI_AFIFO_CFG_AFIFO_ERROR	BIT(0)
+#define SUN20I_HDMI_AFIFO_CFG_AFIFO_ERROR_DET	BIT(1)
+
+#define SUN20I_HDMI_MODULATOR_CFG0_REG	0x0064
+#define SUN20I_HDMI_MODULATOR_CFG1_REG	0x0068
+
+#define SUN20I_HDMI_INDEB_CTRL_REG	0x006c
+#define SUN20I_HDMI_INDEB_CTRL_HPDI_DEBUGMODE	BIT(29)
+#define SUN20I_HDMI_INDEB_CTRL_HPDI_DEBUG	BIT(28)
+#define SUN20I_HDMI_INDEB_CTRL_SDAI_DEBUGMODE	BIT(25)
+#define SUN20I_HDMI_INDEB_CTRL_SDAI_DEBUG	BIT(24)
+#define SUN20I_HDMI_INDEB_CTRL_SCLI_DEBUGMODE	BIT(21)
+#define SUN20I_HDMI_INDEB_CTRL_SCLI_DEBUG	BIT(20)
+#define SUN20I_HDMI_INDEB_CTRL_CECI_DEBUGMODE	BIT(17)
+#define SUN20I_HDMI_INDEB_CTRL_CECI_DEBUG	BIT(16)
+#define SUN20I_HDMI_INDEB_CTRL_TXDATA_DEBUGMODE	GENMASK(1, 0)
+
+#define SUN20I_HDMI_INDBG_TXD0_REG	0x0070
+#define SUN20I_HDMI_INDBG_TXD1_REG	0x0074
+#define SUN20I_HDMI_INDBG_TXD2_REG	0x0078
+#define SUN20I_HDMI_INDBG_TXD3_REG	0x007c
+
+#define SUN20I_HDMI_PLL_STS_REG		0x0080
+#define SUN20I_HDMI_PLL_STS_PHY_CDETPCK_STATUS	BIT(31)
+#define SUN20I_HDMI_PLL_STS_PHY_CDETP_STATUS	GENMASK(30, 28)
+#define SUN20I_HDMI_PLL_STS_PHY_CDETNCK_STATUS	BIT(27)
+#define SUN20I_HDMI_PLL_STS_PHY_CDETN_STATUS	GENMASK(26, 24)
+#define SUN20I_HDMI_PLL_STS_PHY_HPDO_STATUS	BIT(23)
+#define SUN20I_HDMI_PLL_STS_PHY_SCLO_STATUS	BIT(22)
+#define SUN20I_HDMI_PLL_STS_PHY_SDAO_STATUS	BIT(21)
+#define SUN20I_HDMI_PLL_STS_PHY_CECO_STATUS	BIT(20)
+#define SUN20I_HDMI_PLL_STS_PHY_COUT2D_STATUS	BIT(17)
+#define SUN20I_HDMI_PLL_STS_PHY_RCALEND2D_STS	BIT(16)
+#define SUN20I_HDMI_PLL_STS_PHY_RESDO2D_STATUS	GENMASK(13, 8)
+#define SUN20I_HDMI_PLL_STS_PLL_LOCK_STATUS	BIT(4)
+#define SUN20I_HDMI_PLL_STS_RXSENSE_DLY_STATUS	BIT(1)
+#define SUN20I_HDMI_PLL_STS_TX_READY_DLY_STATUS	BIT(0)
+
+#define SUN20I_HDMI_PRBS_CTL_REG	0x0084
+#define SUN20I_HDMI_PRBS_SEED_GEN_REG	0x0088
+#define SUN20I_HDMI_PRBS_SEED_CHK_REG	0x008c
+#define SUN20I_HDMI_PRBS_SEED_NUM_REG	0x0090
+#define SUN20I_HDMI_PRBS_CYCLE_NUM_REG	0x0094
+
+#define SUN20I_HDMI_PLL_ODLY_REG	0x0098
+#define SUN20I_HDMI_PLL_ODLY_RXSENSE_DLY_RESET	BIT(31)
+#define SUN20I_HDMI_PLL_ODLY_RXSENSE_DLY_COUNT	GENMASK(30, 16)
+#define SUN20I_HDMI_PLL_ODLY_TX_READY_DLY_RESET	BIT(15)
+#define SUN20I_HDMI_PLL_ODLY_TX_READY_DLY_COUNT	GENMASK(14, 0)
+
+#define SUN20I_HDMI_PHY_CTL6_REG	0x009c
+#define SUN20I_HDMI_PHY_CTL6_SWITCH_CLKCH_DATA	BIT(31)
+#define SUN20I_HDMI_PHY_CTL6_EN_CKDAT		BIT(30)
+#define SUN20I_HDMI_PHY_CTL6_CLK_GREATE2_340M	GENMASK(29, 20)
+#define SUN20I_HDMI_PHY_CTL6_CLK_GREATE1_340M	GENMASK(19, 10)
+#define SUN20I_HDMI_PHY_CTL6_CLK_GREATE0_340M	GENMASK(9, 0)
+
+#define SUN20I_HDMI_PHY_CTL7_REG	0x00a0
+#define SUN20I_HDMI_PHY_CTL7_CLK_LOW_340M	GENMASK(21, 12)
+#define SUN20I_HDMI_PHY_CTL7_CLK_GREATE3_340M	GENMASK(9, 0)
+
 struct sun8i_hdmi_phy;
 
 struct sun8i_hdmi_phy_variant {
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -398,6 +398,28 @@ static const struct dw_hdmi_phy_ops sun8
 	.setup_hpd	= dw_hdmi_phy_setup_hpd,
 };
 
+static int sun20i_d1_hdmi_phy_config(struct dw_hdmi *hdmi, void *data,
+				     const struct drm_display_info *display,
+				     const struct drm_display_mode *mode)
+{
+	struct sun8i_hdmi_phy *phy = data;
+
+	return 0;
+}
+
+static void sun20i_d1_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data)
+{
+	struct sun8i_hdmi_phy *phy = data;
+}
+
+static const struct dw_hdmi_phy_ops sun20i_d1_hdmi_phy_ops = {
+	.init		= sun20i_d1_hdmi_phy_config,
+	.disable	= sun20i_d1_hdmi_phy_disable,
+	.read_hpd	= dw_hdmi_phy_read_hpd,
+	.update_hpd	= dw_hdmi_phy_update_hpd,
+	.setup_hpd	= dw_hdmi_phy_setup_hpd,
+};
+
 static void sun8i_hdmi_phy_unlock(struct sun8i_hdmi_phy *phy)
 {
 	/* enable read access to HDMI controller */
@@ -576,6 +598,7 @@ void sun8i_hdmi_phy_set_ops(struct sun8i
 	const struct sun8i_hdmi_phy_variant *variant = phy->variant;
 
 	if (variant->phy_ops) {
+		plat_data->phy_force_vendor = true;
 		plat_data->phy_ops = variant->phy_ops;
 		plat_data->phy_name = "sun8i_dw_hdmi_phy";
 		plat_data->phy_data = phy;
@@ -612,6 +635,11 @@ static const struct sun8i_hdmi_phy_varia
 	.phy_init = &sun8i_hdmi_phy_init_h3,
 };
 
+static const struct sun8i_hdmi_phy_variant sun20i_d1_hdmi_phy = {
+	.phy_ops = &sun20i_d1_hdmi_phy_ops,
+	.phy_init = &sun50i_hdmi_phy_init_h6,
+};
+
 static const struct sun8i_hdmi_phy_variant sun50i_a64_hdmi_phy = {
 	.has_phy_clk = true,
 	.phy_ops = &sun8i_h3_hdmi_phy_ops,
@@ -639,6 +667,10 @@ static const struct of_device_id sun8i_h
 		.data = &sun8i_r40_hdmi_phy,
 	},
 	{
+		.compatible = "allwinner,sun20i-d1-hdmi-phy",
+		.data = &sun20i_d1_hdmi_phy,
+	},
+	{
 		.compatible = "allwinner,sun50i-a64-hdmi-phy",
 		.data = &sun50i_a64_hdmi_phy,
 	},
