Unverified Commit d718e53a authored by Andrey Lebedev's avatar Andrey Lebedev Committed by Maxime Ripard
Browse files

drm/sun4i: tcon: Support LVDS output on Allwinner A20



A20 SoC (found in Cubieboard 2 among others) requires different LVDS set
up procedure than A33. Timing controller (tcon) driver only implements
sun6i-style procedure, that doesn't work on A20 (sun7i).

Signed-off-by: default avatarAndrey Lebedev <andrey@lebedev.lt>
Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20200219180858.4806-6-andrey.lebedev@gmail.com
parent cd0ecabd
Loading
Loading
Loading
Loading
+35 −1
Original line number Diff line number Diff line
@@ -114,6 +114,30 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
	}
}

static void sun4i_tcon_setup_lvds_phy(struct sun4i_tcon *tcon,
				      const struct drm_encoder *encoder)
{
	regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
		     SUN4I_TCON0_LVDS_ANA0_CK_EN |
		     SUN4I_TCON0_LVDS_ANA0_REG_V |
		     SUN4I_TCON0_LVDS_ANA0_REG_C |
		     SUN4I_TCON0_LVDS_ANA0_EN_MB |
		     SUN4I_TCON0_LVDS_ANA0_PD |
		     SUN4I_TCON0_LVDS_ANA0_DCHS);

	udelay(2); /* delay at least 1200 ns */
	regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA1_REG,
			   SUN4I_TCON0_LVDS_ANA1_INIT,
			   SUN4I_TCON0_LVDS_ANA1_INIT);
	udelay(1); /* delay at least 120 ns */
	regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA1_REG,
			   SUN4I_TCON0_LVDS_ANA1_UPDATE,
			   SUN4I_TCON0_LVDS_ANA1_UPDATE);
	regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
			   SUN4I_TCON0_LVDS_ANA0_EN_MB,
			   SUN4I_TCON0_LVDS_ANA0_EN_MB);
}

static void sun6i_tcon_setup_lvds_phy(struct sun4i_tcon *tcon,
				      const struct drm_encoder *encoder)
{
@@ -1454,6 +1478,16 @@ static const struct sun4i_tcon_quirks sun6i_a31s_quirks = {
	.dclk_min_div		= 1,
};

static const struct sun4i_tcon_quirks sun7i_a20_tcon0_quirks = {
	.supports_lvds		= true,
	.has_channel_0		= true,
	.has_channel_1		= true,
	.dclk_min_div		= 4,
	/* Same display pipeline structure as A10 */
	.set_mux		= sun4i_a10_tcon_set_mux,
	.setup_lvds_phy		= sun4i_tcon_setup_lvds_phy,
};

static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
	.has_channel_0		= true,
	.has_channel_1		= true,
@@ -1508,7 +1542,7 @@ const struct of_device_id sun4i_tcon_of_table[] = {
	{ .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks },
	{ .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks },
	{ .compatible = "allwinner,sun7i-a20-tcon", .data = &sun7i_a20_quirks },
	{ .compatible = "allwinner,sun7i-a20-tcon0", .data = &sun7i_a20_quirks },
	{ .compatible = "allwinner,sun7i-a20-tcon0", .data = &sun7i_a20_tcon0_quirks },
	{ .compatible = "allwinner,sun7i-a20-tcon1", .data = &sun7i_a20_quirks },
	{ .compatible = "allwinner,sun8i-a23-tcon", .data = &sun8i_a33_quirks },
	{ .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks },
+11 −0
Original line number Diff line number Diff line
@@ -193,6 +193,13 @@
#define SUN4I_TCON_MUX_CTRL_REG			0x200

#define SUN4I_TCON0_LVDS_ANA0_REG		0x220
#define SUN4I_TCON0_LVDS_ANA0_DCHS			BIT(16)
#define SUN4I_TCON0_LVDS_ANA0_PD			(BIT(20) | BIT(21))
#define SUN4I_TCON0_LVDS_ANA0_EN_MB			BIT(22)
#define SUN4I_TCON0_LVDS_ANA0_REG_C			(BIT(24) | BIT(25))
#define SUN4I_TCON0_LVDS_ANA0_REG_V			(BIT(26) | BIT(27))
#define SUN4I_TCON0_LVDS_ANA0_CK_EN			(BIT(29) | BIT(28))

#define SUN6I_TCON0_LVDS_ANA0_EN_MB			BIT(31)
#define SUN6I_TCON0_LVDS_ANA0_EN_LDO			BIT(30)
#define SUN6I_TCON0_LVDS_ANA0_EN_DRVC			BIT(24)
@@ -201,6 +208,10 @@
#define SUN6I_TCON0_LVDS_ANA0_V(x)			(((x) & 3) << 8)
#define SUN6I_TCON0_LVDS_ANA0_PD(x)			(((x) & 3) << 4)

#define SUN4I_TCON0_LVDS_ANA1_REG		0x224
#define SUN4I_TCON0_LVDS_ANA1_INIT			(0x1f << 26 | 0x1f << 10)
#define SUN4I_TCON0_LVDS_ANA1_UPDATE			(0x1f << 16 | 0x1f << 00)

#define SUN4I_TCON1_FILL_CTL_REG		0x300
#define SUN4I_TCON1_FILL_BEG0_REG		0x304
#define SUN4I_TCON1_FILL_END0_REG		0x308