From: Andrey Lebedev <andrey.lebedev@gmail.com>
To: mripard@kernel.org, wens@csie.org, airlied@linux.ie,
daniel@ffwll.ch, dri-devel@lists.freedesktop.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 1/1] Support LVDS output on Allwinner A20
Date: Mon, 10 Feb 2020 21:56:33 +0200 [thread overview]
Message-ID: <20200210195633.GA21832@kedthinkpad> (raw)
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).
The support for such procedure is ported from u-boot and follows u-boot
naming convention: SUN6I* for sun6i-style procedure, and SUN4I for other
(which happens to be compatible with A20).
---
drivers/gpu/drm/sun4i/sun4i_tcon.c | 91 ++++++++++++++++++++----------
drivers/gpu/drm/sun4i/sun4i_tcon.h | 12 ++++
2 files changed, 73 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index c81cdce6ed55..78896e907ca9 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -114,46 +114,74 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
}
}
+static void sun4i_tcon_lvds_sun6i_enable(struct sun4i_tcon *tcon,
+ const struct drm_encoder *encoder) {
+ u8 val;
+ regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+ SUN6I_TCON0_LVDS_ANA0_C(2) |
+ SUN6I_TCON0_LVDS_ANA0_V(3) |
+ SUN6I_TCON0_LVDS_ANA0_PD(2) |
+ SUN6I_TCON0_LVDS_ANA0_EN_LDO);
+ udelay(2);
+
+ regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+ SUN6I_TCON0_LVDS_ANA0_EN_MB,
+ SUN6I_TCON0_LVDS_ANA0_EN_MB);
+ udelay(2);
+
+ regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+ SUN6I_TCON0_LVDS_ANA0_EN_DRVC,
+ SUN6I_TCON0_LVDS_ANA0_EN_DRVC);
+
+ if (sun4i_tcon_get_pixel_depth(encoder) == 18)
+ val = 7;
+ else
+ val = 0xf;
+
+ regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+ SUN6I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
+ SUN6I_TCON0_LVDS_ANA0_EN_DRVD(val));
+
+}
+
+static void sun4i_tcon_lvds_sun4i_enable(struct sun4i_tcon *tcon) {
+ 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 1200 ns */
+ regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA1_REG,
+ SUN4I_TCON0_LVDS_ANA1_UPDATE,
+ SUN4I_TCON0_LVDS_ANA1_UPDATE);
+}
+
+
static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
const struct drm_encoder *encoder,
bool enabled)
{
if (enabled) {
- u8 val;
-
+ // Enable LVDS interface
regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
SUN4I_TCON0_LVDS_IF_EN,
SUN4I_TCON0_LVDS_IF_EN);
- /*
- * As their name suggest, these values only apply to the A31
- * and later SoCs. We'll have to rework this when merging
- * support for the older SoCs.
- */
- regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
- SUN6I_TCON0_LVDS_ANA0_C(2) |
- SUN6I_TCON0_LVDS_ANA0_V(3) |
- SUN6I_TCON0_LVDS_ANA0_PD(2) |
- SUN6I_TCON0_LVDS_ANA0_EN_LDO);
- udelay(2);
-
- regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
- SUN6I_TCON0_LVDS_ANA0_EN_MB,
- SUN6I_TCON0_LVDS_ANA0_EN_MB);
- udelay(2);
-
- regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
- SUN6I_TCON0_LVDS_ANA0_EN_DRVC,
- SUN6I_TCON0_LVDS_ANA0_EN_DRVC);
-
- if (sun4i_tcon_get_pixel_depth(encoder) == 18)
- val = 7;
- else
- val = 0xf;
+ // Perform SoC-specific setup procedure
+ if (tcon->quirks->sun6i_lvds_init) {
+ sun4i_tcon_lvds_sun6i_enable(tcon, encoder);
+ }
+ else {
+ sun4i_tcon_lvds_sun4i_enable(tcon);
+ }
- regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
- SUN6I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
- SUN6I_TCON0_LVDS_ANA0_EN_DRVD(val));
} else {
regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
SUN4I_TCON0_LVDS_IF_EN, 0);
@@ -1454,6 +1482,7 @@ static const struct sun4i_tcon_quirks sun6i_a31s_quirks = {
};
static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
+ .supports_lvds = true,
.has_channel_0 = true,
.has_channel_1 = true,
.dclk_min_div = 4,
@@ -1464,11 +1493,13 @@ static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
.has_channel_0 = true,
.has_lvds_alt = true,
+ .sun6i_lvds_init = true,
.dclk_min_div = 1,
};
static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
.supports_lvds = true,
+ .sun6i_lvds_init = true,
.has_channel_0 = true,
.dclk_min_div = 1,
};
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index a62ec826ae71..973901c1bee5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -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
@@ -224,6 +235,7 @@ struct sun4i_tcon_quirks {
bool needs_de_be_mux; /* sun6i needs mux to select backend */
bool needs_edp_reset; /* a80 edp reset needed for tcon0 access */
bool supports_lvds; /* Does the TCON support an LVDS output? */
+ bool sun6i_lvds_init; /* Requires sun6i lvds initialization? */
u8 dclk_min_div; /* minimum divider for TCON0 DCLK */
/* callback to handle tcon muxing options */
--
2.20.1
WARNING: multiple messages have this Message-ID (diff)
From: Andrey Lebedev <andrey.lebedev@gmail.com>
To: mripard@kernel.org, wens@csie.org, airlied@linux.ie,
daniel@ffwll.ch, dri-devel@lists.freedesktop.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 1/1] Support LVDS output on Allwinner A20
Date: Mon, 10 Feb 2020 21:56:33 +0200 [thread overview]
Message-ID: <20200210195633.GA21832@kedthinkpad> (raw)
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).
The support for such procedure is ported from u-boot and follows u-boot
naming convention: SUN6I* for sun6i-style procedure, and SUN4I for other
(which happens to be compatible with A20).
---
drivers/gpu/drm/sun4i/sun4i_tcon.c | 91 ++++++++++++++++++++----------
drivers/gpu/drm/sun4i/sun4i_tcon.h | 12 ++++
2 files changed, 73 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index c81cdce6ed55..78896e907ca9 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -114,46 +114,74 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
}
}
+static void sun4i_tcon_lvds_sun6i_enable(struct sun4i_tcon *tcon,
+ const struct drm_encoder *encoder) {
+ u8 val;
+ regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+ SUN6I_TCON0_LVDS_ANA0_C(2) |
+ SUN6I_TCON0_LVDS_ANA0_V(3) |
+ SUN6I_TCON0_LVDS_ANA0_PD(2) |
+ SUN6I_TCON0_LVDS_ANA0_EN_LDO);
+ udelay(2);
+
+ regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+ SUN6I_TCON0_LVDS_ANA0_EN_MB,
+ SUN6I_TCON0_LVDS_ANA0_EN_MB);
+ udelay(2);
+
+ regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+ SUN6I_TCON0_LVDS_ANA0_EN_DRVC,
+ SUN6I_TCON0_LVDS_ANA0_EN_DRVC);
+
+ if (sun4i_tcon_get_pixel_depth(encoder) == 18)
+ val = 7;
+ else
+ val = 0xf;
+
+ regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+ SUN6I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
+ SUN6I_TCON0_LVDS_ANA0_EN_DRVD(val));
+
+}
+
+static void sun4i_tcon_lvds_sun4i_enable(struct sun4i_tcon *tcon) {
+ 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 1200 ns */
+ regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA1_REG,
+ SUN4I_TCON0_LVDS_ANA1_UPDATE,
+ SUN4I_TCON0_LVDS_ANA1_UPDATE);
+}
+
+
static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
const struct drm_encoder *encoder,
bool enabled)
{
if (enabled) {
- u8 val;
-
+ // Enable LVDS interface
regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
SUN4I_TCON0_LVDS_IF_EN,
SUN4I_TCON0_LVDS_IF_EN);
- /*
- * As their name suggest, these values only apply to the A31
- * and later SoCs. We'll have to rework this when merging
- * support for the older SoCs.
- */
- regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
- SUN6I_TCON0_LVDS_ANA0_C(2) |
- SUN6I_TCON0_LVDS_ANA0_V(3) |
- SUN6I_TCON0_LVDS_ANA0_PD(2) |
- SUN6I_TCON0_LVDS_ANA0_EN_LDO);
- udelay(2);
-
- regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
- SUN6I_TCON0_LVDS_ANA0_EN_MB,
- SUN6I_TCON0_LVDS_ANA0_EN_MB);
- udelay(2);
-
- regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
- SUN6I_TCON0_LVDS_ANA0_EN_DRVC,
- SUN6I_TCON0_LVDS_ANA0_EN_DRVC);
-
- if (sun4i_tcon_get_pixel_depth(encoder) == 18)
- val = 7;
- else
- val = 0xf;
+ // Perform SoC-specific setup procedure
+ if (tcon->quirks->sun6i_lvds_init) {
+ sun4i_tcon_lvds_sun6i_enable(tcon, encoder);
+ }
+ else {
+ sun4i_tcon_lvds_sun4i_enable(tcon);
+ }
- regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
- SUN6I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
- SUN6I_TCON0_LVDS_ANA0_EN_DRVD(val));
} else {
regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
SUN4I_TCON0_LVDS_IF_EN, 0);
@@ -1454,6 +1482,7 @@ static const struct sun4i_tcon_quirks sun6i_a31s_quirks = {
};
static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
+ .supports_lvds = true,
.has_channel_0 = true,
.has_channel_1 = true,
.dclk_min_div = 4,
@@ -1464,11 +1493,13 @@ static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
.has_channel_0 = true,
.has_lvds_alt = true,
+ .sun6i_lvds_init = true,
.dclk_min_div = 1,
};
static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
.supports_lvds = true,
+ .sun6i_lvds_init = true,
.has_channel_0 = true,
.dclk_min_div = 1,
};
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index a62ec826ae71..973901c1bee5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -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
@@ -224,6 +235,7 @@ struct sun4i_tcon_quirks {
bool needs_de_be_mux; /* sun6i needs mux to select backend */
bool needs_edp_reset; /* a80 edp reset needed for tcon0 access */
bool supports_lvds; /* Does the TCON support an LVDS output? */
+ bool sun6i_lvds_init; /* Requires sun6i lvds initialization? */
u8 dclk_min_div; /* minimum divider for TCON0 DCLK */
/* callback to handle tcon muxing options */
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: Andrey Lebedev <andrey.lebedev@gmail.com>
To: mripard@kernel.org, wens@csie.org, airlied@linux.ie,
daniel@ffwll.ch, dri-devel@lists.freedesktop.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 1/1] Support LVDS output on Allwinner A20
Date: Mon, 10 Feb 2020 21:56:33 +0200 [thread overview]
Message-ID: <20200210195633.GA21832@kedthinkpad> (raw)
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).
The support for such procedure is ported from u-boot and follows u-boot
naming convention: SUN6I* for sun6i-style procedure, and SUN4I for other
(which happens to be compatible with A20).
---
drivers/gpu/drm/sun4i/sun4i_tcon.c | 91 ++++++++++++++++++++----------
drivers/gpu/drm/sun4i/sun4i_tcon.h | 12 ++++
2 files changed, 73 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index c81cdce6ed55..78896e907ca9 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -114,46 +114,74 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
}
}
+static void sun4i_tcon_lvds_sun6i_enable(struct sun4i_tcon *tcon,
+ const struct drm_encoder *encoder) {
+ u8 val;
+ regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+ SUN6I_TCON0_LVDS_ANA0_C(2) |
+ SUN6I_TCON0_LVDS_ANA0_V(3) |
+ SUN6I_TCON0_LVDS_ANA0_PD(2) |
+ SUN6I_TCON0_LVDS_ANA0_EN_LDO);
+ udelay(2);
+
+ regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+ SUN6I_TCON0_LVDS_ANA0_EN_MB,
+ SUN6I_TCON0_LVDS_ANA0_EN_MB);
+ udelay(2);
+
+ regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+ SUN6I_TCON0_LVDS_ANA0_EN_DRVC,
+ SUN6I_TCON0_LVDS_ANA0_EN_DRVC);
+
+ if (sun4i_tcon_get_pixel_depth(encoder) == 18)
+ val = 7;
+ else
+ val = 0xf;
+
+ regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
+ SUN6I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
+ SUN6I_TCON0_LVDS_ANA0_EN_DRVD(val));
+
+}
+
+static void sun4i_tcon_lvds_sun4i_enable(struct sun4i_tcon *tcon) {
+ 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 1200 ns */
+ regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA1_REG,
+ SUN4I_TCON0_LVDS_ANA1_UPDATE,
+ SUN4I_TCON0_LVDS_ANA1_UPDATE);
+}
+
+
static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
const struct drm_encoder *encoder,
bool enabled)
{
if (enabled) {
- u8 val;
-
+ // Enable LVDS interface
regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
SUN4I_TCON0_LVDS_IF_EN,
SUN4I_TCON0_LVDS_IF_EN);
- /*
- * As their name suggest, these values only apply to the A31
- * and later SoCs. We'll have to rework this when merging
- * support for the older SoCs.
- */
- regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
- SUN6I_TCON0_LVDS_ANA0_C(2) |
- SUN6I_TCON0_LVDS_ANA0_V(3) |
- SUN6I_TCON0_LVDS_ANA0_PD(2) |
- SUN6I_TCON0_LVDS_ANA0_EN_LDO);
- udelay(2);
-
- regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
- SUN6I_TCON0_LVDS_ANA0_EN_MB,
- SUN6I_TCON0_LVDS_ANA0_EN_MB);
- udelay(2);
-
- regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
- SUN6I_TCON0_LVDS_ANA0_EN_DRVC,
- SUN6I_TCON0_LVDS_ANA0_EN_DRVC);
-
- if (sun4i_tcon_get_pixel_depth(encoder) == 18)
- val = 7;
- else
- val = 0xf;
+ // Perform SoC-specific setup procedure
+ if (tcon->quirks->sun6i_lvds_init) {
+ sun4i_tcon_lvds_sun6i_enable(tcon, encoder);
+ }
+ else {
+ sun4i_tcon_lvds_sun4i_enable(tcon);
+ }
- regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
- SUN6I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
- SUN6I_TCON0_LVDS_ANA0_EN_DRVD(val));
} else {
regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
SUN4I_TCON0_LVDS_IF_EN, 0);
@@ -1454,6 +1482,7 @@ static const struct sun4i_tcon_quirks sun6i_a31s_quirks = {
};
static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
+ .supports_lvds = true,
.has_channel_0 = true,
.has_channel_1 = true,
.dclk_min_div = 4,
@@ -1464,11 +1493,13 @@ static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
.has_channel_0 = true,
.has_lvds_alt = true,
+ .sun6i_lvds_init = true,
.dclk_min_div = 1,
};
static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
.supports_lvds = true,
+ .sun6i_lvds_init = true,
.has_channel_0 = true,
.dclk_min_div = 1,
};
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index a62ec826ae71..973901c1bee5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -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
@@ -224,6 +235,7 @@ struct sun4i_tcon_quirks {
bool needs_de_be_mux; /* sun6i needs mux to select backend */
bool needs_edp_reset; /* a80 edp reset needed for tcon0 access */
bool supports_lvds; /* Does the TCON support an LVDS output? */
+ bool sun6i_lvds_init; /* Requires sun6i lvds initialization? */
u8 dclk_min_div; /* minimum divider for TCON0 DCLK */
/* callback to handle tcon muxing options */
--
2.20.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
next reply other threads:[~2020-02-10 19:56 UTC|newest]
Thread overview: 114+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-10 19:56 Andrey Lebedev [this message]
2020-02-10 19:56 ` [PATCH 1/1] Support LVDS output on Allwinner A20 Andrey Lebedev
2020-02-10 19:56 ` Andrey Lebedev
2020-02-11 7:20 ` Maxime Ripard
2020-02-11 7:20 ` Maxime Ripard
2020-02-11 7:20 ` Maxime Ripard
2020-02-11 20:48 ` Andrey Lebedev
2020-02-11 20:48 ` Andrey Lebedev
2020-02-11 20:48 ` Andrey Lebedev
2020-02-12 12:53 ` Maxime Ripard
2020-02-12 12:53 ` Maxime Ripard
2020-02-12 12:53 ` Maxime Ripard
2020-02-12 22:46 ` Andrey Lebedev
2020-02-12 22:46 ` Andrey Lebedev
2020-02-12 22:46 ` Andrey Lebedev
2020-02-13 9:24 ` Maxime Ripard
2020-02-13 9:24 ` Maxime Ripard
2020-02-13 9:24 ` Maxime Ripard
2020-02-13 18:11 ` Andrey Lebedev
2020-02-13 18:11 ` Andrey Lebedev
2020-02-13 18:11 ` Andrey Lebedev
2020-02-14 7:58 ` Maxime Ripard
2020-02-14 7:58 ` Maxime Ripard
2020-02-14 7:58 ` Maxime Ripard
2020-02-12 22:23 ` [PATCH v2 1/2] ARM: sun7i: " andrey.lebedev
2020-02-12 22:23 ` andrey.lebedev
2020-02-12 22:23 ` andrey.lebedev
2020-02-13 9:32 ` Maxime Ripard
2020-02-13 9:32 ` Maxime Ripard
2020-02-13 9:32 ` Maxime Ripard
2020-02-12 22:23 ` [PATCH v2 2/2] ARM: sun7i: dts: Add LVDS panel support on A20 andrey.lebedev
2020-02-12 22:23 ` andrey.lebedev
2020-02-12 22:23 ` andrey.lebedev
2020-02-13 9:43 ` Maxime Ripard
2020-02-13 9:43 ` Maxime Ripard
2020-02-13 9:43 ` Maxime Ripard
2020-02-13 20:08 ` Andrey Lebedev
2020-02-13 20:08 ` Andrey Lebedev
2020-02-13 20:08 ` Andrey Lebedev
2020-02-14 7:52 ` Maxime Ripard
2020-02-14 7:52 ` Maxime Ripard
2020-02-14 7:52 ` Maxime Ripard
2020-02-14 8:43 ` Andrey Lebedev
2020-02-14 8:43 ` Andrey Lebedev
2020-02-14 8:43 ` Andrey Lebedev
2020-02-14 8:53 ` Maxime Ripard
2020-02-14 8:53 ` Maxime Ripard
2020-02-14 8:53 ` Maxime Ripard
2020-02-14 21:32 ` Andrey Lebedev
2020-02-14 21:32 ` Andrey Lebedev
2020-02-14 21:32 ` Andrey Lebedev
2020-02-17 17:51 ` Maxime Ripard
2020-02-17 17:51 ` Maxime Ripard
2020-02-17 17:51 ` Maxime Ripard
2020-02-18 17:50 ` Andrey Lebedev
2020-02-18 17:50 ` Andrey Lebedev
2020-02-18 17:50 ` Andrey Lebedev
2020-02-19 12:06 ` Maxime Ripard
2020-02-19 12:06 ` Maxime Ripard
2020-02-19 12:06 ` Maxime Ripard
2020-02-13 20:18 ` [PATCH v3 1/3] drm/sun4i: tcon: Introduce LVDS setup routine setting Andrey Lebedev
2020-02-13 20:18 ` Andrey Lebedev
2020-02-13 20:18 ` Andrey Lebedev
2020-02-13 20:18 ` [PATCH v3 2/3] drm/sun4i: tcon: Support LVDS output on Allwinner A20 Andrey Lebedev
2020-02-13 20:18 ` Andrey Lebedev
2020-02-13 20:18 ` Andrey Lebedev
2020-02-13 20:18 ` [PATCH v3 3/3] ARM: dts: sun7i: Add LVDS panel support on A20 Andrey Lebedev
2020-02-13 20:18 ` Andrey Lebedev
2020-02-13 20:18 ` Andrey Lebedev
2020-02-14 8:55 ` Maxime Ripard
2020-02-14 8:55 ` Maxime Ripard
2020-02-14 8:55 ` Maxime Ripard
2020-02-19 18:08 ` PATCH v4 Andrey Lebedev
2020-02-19 18:08 ` Andrey Lebedev
2020-02-19 18:08 ` Andrey Lebedev
2020-02-19 18:08 ` [PATCH 1/5] drm/sun4i: tcon: Introduce LVDS setup routine setting Andrey Lebedev
2020-02-19 18:08 ` Andrey Lebedev
2020-02-19 18:08 ` Andrey Lebedev
2020-02-20 17:21 ` Maxime Ripard
2020-02-20 17:21 ` Maxime Ripard
2020-02-20 17:21 ` Maxime Ripard
2020-02-20 18:19 ` Andrey Lebedev
2020-02-20 18:19 ` Andrey Lebedev
2020-02-20 18:19 ` Andrey Lebedev
2020-02-19 18:08 ` [PATCH 2/5] drm/sun4i: tcon: Separate quirks for tcon0 and tcon1 on A20 Andrey Lebedev
2020-02-19 18:08 ` Andrey Lebedev
2020-02-19 18:08 ` Andrey Lebedev
2020-02-20 17:22 ` Maxime Ripard
2020-02-20 17:22 ` Maxime Ripard
2020-02-20 17:22 ` Maxime Ripard
2020-02-19 18:08 ` [PATCH 3/5] ARM: dts: sun7i: Add LVDS panel support " Andrey Lebedev
2020-02-19 18:08 ` Andrey Lebedev
2020-02-19 18:08 ` Andrey Lebedev
2020-02-20 17:23 ` Maxime Ripard
2020-02-20 17:23 ` Maxime Ripard
2020-02-20 17:23 ` Maxime Ripard
2020-02-19 18:08 ` [PATCH 4/5] dt-bindings: display: sun4i: New compatibles for A20 tcons Andrey Lebedev
2020-02-19 18:08 ` Andrey Lebedev
2020-02-19 18:08 ` Andrey Lebedev
2020-02-20 17:24 ` Maxime Ripard
2020-02-20 17:24 ` Maxime Ripard
2020-02-20 17:24 ` Maxime Ripard
2020-02-19 18:08 ` [PATCH 5/5] drm/sun4i: tcon: Support LVDS output on Allwinner A20 Andrey Lebedev
2020-02-19 18:08 ` Andrey Lebedev
2020-02-19 18:08 ` Andrey Lebedev
2020-02-20 17:25 ` Maxime Ripard
2020-02-20 17:25 ` Maxime Ripard
2020-02-20 17:25 ` Maxime Ripard
2020-04-01 10:59 ` Andrey Lebedev
2020-04-01 10:59 ` Andrey Lebedev
2020-04-01 10:59 ` Andrey Lebedev
2020-04-01 12:14 ` Maxime Ripard
2020-04-01 12:14 ` Maxime Ripard
2020-04-01 12:14 ` Maxime Ripard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200210195633.GA21832@kedthinkpad \
--to=andrey.lebedev@gmail.com \
--cc=airlied@linux.ie \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mripard@kernel.org \
--cc=wens@csie.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.