Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da184dee authored by Chen-Yu Tsai's avatar Chen-Yu Tsai Committed by Maxime Ripard
Browse files

drm/sun4i: hdmi: Add support for A31's HDMI controller



The HDMI controller found in the A31 SoCs is slightly different
from the one already supported, which is found in the A10s:

  - Need different initial values for the PLL related registers

  - Different behavior of the DDC and TMDS clocks

  - Different register layout for the DDC portion

  - Separate DDC parent clock

This patch adds support for it.

Signed-off-by: default avatarChen-Yu Tsai <wens@csie.org>
Acked-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171010032008.682-10-wens@csie.org
parent c4a9aec3
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -59,10 +59,13 @@
#define SUN4I_HDMI_PAD_CTRL0_TXEN		BIT(23)

#define SUN4I_HDMI_PAD_CTRL1_REG	0x204
#define SUN4I_HDMI_PAD_CTRL1_UNKNOWN		BIT(24)	/* set on A31 */
#define SUN4I_HDMI_PAD_CTRL1_AMP_OPT		BIT(23)
#define SUN4I_HDMI_PAD_CTRL1_AMPCK_OPT		BIT(22)
#define SUN4I_HDMI_PAD_CTRL1_EMP_OPT		BIT(20)
#define SUN4I_HDMI_PAD_CTRL1_EMPCK_OPT		BIT(19)
#define SUN4I_HDMI_PAD_CTRL1_PWSCK		BIT(18)
#define SUN4I_HDMI_PAD_CTRL1_PWSDT		BIT(17)
#define SUN4I_HDMI_PAD_CTRL1_REG_DEN		BIT(15)
#define SUN4I_HDMI_PAD_CTRL1_REG_DENCK		BIT(14)
#define SUN4I_HDMI_PAD_CTRL1_REG_EMP(n)		(((n) & 7) << 10)
+58 −0
Original line number Diff line number Diff line
@@ -324,6 +324,63 @@ static const struct sun4i_hdmi_variant sun5i_variant = {
	.ddc_fifo_has_dir	= true,
};

static const struct sun4i_hdmi_variant sun6i_variant = {
	.has_ddc_parent_clk	= true,
	.has_reset_control	= true,
	.pad_ctrl0_init_val	= 0xff |
				  SUN4I_HDMI_PAD_CTRL0_TXEN |
				  SUN4I_HDMI_PAD_CTRL0_CKEN |
				  SUN4I_HDMI_PAD_CTRL0_PWENG |
				  SUN4I_HDMI_PAD_CTRL0_PWEND |
				  SUN4I_HDMI_PAD_CTRL0_PWENC |
				  SUN4I_HDMI_PAD_CTRL0_LDODEN |
				  SUN4I_HDMI_PAD_CTRL0_LDOCEN,
	.pad_ctrl1_init_val	= SUN4I_HDMI_PAD_CTRL1_REG_AMP(6) |
				  SUN4I_HDMI_PAD_CTRL1_REG_EMP(4) |
				  SUN4I_HDMI_PAD_CTRL1_REG_DENCK |
				  SUN4I_HDMI_PAD_CTRL1_REG_DEN |
				  SUN4I_HDMI_PAD_CTRL1_EMPCK_OPT |
				  SUN4I_HDMI_PAD_CTRL1_EMP_OPT |
				  SUN4I_HDMI_PAD_CTRL1_PWSDT |
				  SUN4I_HDMI_PAD_CTRL1_PWSCK |
				  SUN4I_HDMI_PAD_CTRL1_AMPCK_OPT |
				  SUN4I_HDMI_PAD_CTRL1_AMP_OPT |
				  SUN4I_HDMI_PAD_CTRL1_UNKNOWN,
	.pll_ctrl_init_val	= SUN4I_HDMI_PLL_CTRL_VCO_S(8) |
				  SUN4I_HDMI_PLL_CTRL_CS(3) |
				  SUN4I_HDMI_PLL_CTRL_CP_S(10) |
				  SUN4I_HDMI_PLL_CTRL_S(4) |
				  SUN4I_HDMI_PLL_CTRL_VCO_GAIN(4) |
				  SUN4I_HDMI_PLL_CTRL_SDIV2 |
				  SUN4I_HDMI_PLL_CTRL_LDO2_EN |
				  SUN4I_HDMI_PLL_CTRL_LDO1_EN |
				  SUN4I_HDMI_PLL_CTRL_HV_IS_33 |
				  SUN4I_HDMI_PLL_CTRL_PLL_EN,

	.ddc_clk_reg		= REG_FIELD(SUN6I_HDMI_DDC_CLK_REG, 0, 6),
	.ddc_clk_pre_divider	= 1,
	.ddc_clk_m_offset	= 2,

	.tmds_clk_div_offset	= 1,

	.field_ddc_en		= REG_FIELD(SUN6I_HDMI_DDC_CTRL_REG, 0, 0),
	.field_ddc_start	= REG_FIELD(SUN6I_HDMI_DDC_CTRL_REG, 27, 27),
	.field_ddc_reset	= REG_FIELD(SUN6I_HDMI_DDC_CTRL_REG, 31, 31),
	.field_ddc_addr_reg	= REG_FIELD(SUN6I_HDMI_DDC_ADDR_REG, 1, 31),
	.field_ddc_slave_addr	= REG_FIELD(SUN6I_HDMI_DDC_ADDR_REG, 1, 7),
	.field_ddc_int_status	= REG_FIELD(SUN6I_HDMI_DDC_INT_STATUS_REG, 0, 8),
	.field_ddc_fifo_clear	= REG_FIELD(SUN6I_HDMI_DDC_FIFO_CTRL_REG, 18, 18),
	.field_ddc_fifo_rx_thres = REG_FIELD(SUN6I_HDMI_DDC_FIFO_CTRL_REG, 4, 7),
	.field_ddc_fifo_tx_thres = REG_FIELD(SUN6I_HDMI_DDC_FIFO_CTRL_REG, 0, 3),
	.field_ddc_byte_count	= REG_FIELD(SUN6I_HDMI_DDC_CMD_REG, 16, 25),
	.field_ddc_cmd		= REG_FIELD(SUN6I_HDMI_DDC_CMD_REG, 0, 2),
	.field_ddc_sda_en	= REG_FIELD(SUN6I_HDMI_DDC_CTRL_REG, 6, 6),
	.field_ddc_sck_en	= REG_FIELD(SUN6I_HDMI_DDC_CTRL_REG, 4, 4),

	.ddc_fifo_reg		= SUN6I_HDMI_DDC_FIFO_DATA_REG,
	.ddc_fifo_thres_incl	= true,
};

static const struct regmap_config sun4i_hdmi_regmap_config = {
	.reg_bits	= 32,
	.val_bits	= 32,
@@ -551,6 +608,7 @@ static int sun4i_hdmi_remove(struct platform_device *pdev)

static const struct of_device_id sun4i_hdmi_of_table[] = {
	{ .compatible = "allwinner,sun5i-a10s-hdmi", .data = &sun5i_variant, },
	{ .compatible = "allwinner,sun6i-a31-hdmi", .data = &sun6i_variant, },
	{ }
};
MODULE_DEVICE_TABLE(of, sun4i_hdmi_of_table);