* [U-Boot] [PATCH v2 1/2] sunxi: video: Add lvds support
2015-01-08 19:49 [U-Boot] [PATCH v2 0/2] sunxi: video: Add lvds support Hans de Goede
@ 2015-01-08 19:49 ` Hans de Goede
2015-01-10 0:12 ` Anatolij Gustschin
2015-01-08 19:49 ` [U-Boot] [PATCH v2 2/2] sunxi: video: Add support for Hitachi tx18d42vm LCD panels Hans de Goede
2015-01-10 10:40 ` [U-Boot] [PATCH v2 0/2] sunxi: video: Add lvds support Ian Campbell
2 siblings, 1 reply; 7+ messages in thread
From: Hans de Goede @ 2015-01-08 19:49 UTC (permalink / raw)
To: u-boot
Add support for lvds lcd panels
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
arch/arm/include/asm/arch-sunxi/clock_sun4i.h | 2 ++
arch/arm/include/asm/arch-sunxi/display.h | 12 +++++++++
arch/arm/include/asm/arch-sunxi/gpio.h | 1 +
board/sunxi/Kconfig | 27 +++++++++++++++++++
drivers/video/sunxi_display.c | 37 +++++++++++++++++++++++++--
5 files changed, 77 insertions(+), 2 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
index 64b5c38..70b789e 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
@@ -284,6 +284,8 @@ struct sunxi_ccm_reg {
/* Enable / disable both ch1 sclk1 and sclk2 at the same time */
#define CCM_LCD_CH1_CTRL_GATE (0x1 << 31 | 0x1 << 15)
+#define CCM_LVDS_CTRL_RST (1 << 0)
+
#define CCM_HDMI_CTRL_M(n) ((((n) - 1) & 0xf) << 0)
#define CCM_HDMI_CTRL_PLL_MASK (3 << 24)
#define CCM_HDMI_CTRL_PLL3 (0 << 24)
diff --git a/arch/arm/include/asm/arch-sunxi/display.h b/arch/arm/include/asm/arch-sunxi/display.h
index 19582c1..6f586f1 100644
--- a/arch/arm/include/asm/arch-sunxi/display.h
+++ b/arch/arm/include/asm/arch-sunxi/display.h
@@ -91,6 +91,9 @@ struct sunxi_lcdc_reg {
u8 res3[0x44]; /* 0xac */
u32 tcon1_io_polarity; /* 0xf0 */
u32 tcon1_io_tristate; /* 0xf4 */
+ u8 res4[0x128]; /* 0xf8 */
+ u32 lvds_ana0; /* 0x220 */
+ u32 lvds_ana1; /* 0x224 */
};
struct sunxi_hdmi_reg {
@@ -244,12 +247,21 @@ struct sunxi_tve_reg {
#define SUNXI_LCDC_TCON0_TIMING_H_TOTAL(n) (((n) - 1) << 16)
#define SUNXI_LCDC_TCON0_TIMING_V_BP(n) (((n) - 1) << 0)
#define SUNXI_LCDC_TCON0_TIMING_V_TOTAL(n) (((n) * 2) << 16)
+#define SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(n) ((n) << 26)
+#define SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE (1 << 31)
+#define SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE0 (0 << 28)
+#define SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE60 (1 << 28)
+#define SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE120 (2 << 28)
#define SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(n) (((n) & 0x1f) << 4)
#define SUNXI_LCDC_TCON1_CTRL_ENABLE (1 << 31)
#define SUNXI_LCDC_TCON1_TIMING_H_BP(n) (((n) - 1) << 0)
#define SUNXI_LCDC_TCON1_TIMING_H_TOTAL(n) (((n) - 1) << 16)
#define SUNXI_LCDC_TCON1_TIMING_V_BP(n) (((n) - 1) << 0)
#define SUNXI_LCDC_TCON1_TIMING_V_TOTAL(n) (((n) * 2) << 16)
+#define SUNXI_LCDC_LVDS_ANA0 0x3f310000
+#define SUNXI_LCDC_LVDS_ANA0_UPDATE (1 << 22)
+#define SUNXI_LCDC_LVDS_ANA1_INIT1 (0x1f << 26 | 0x1f << 10)
+#define SUNXI_LCDC_LVDS_ANA1_INIT2 (0x1f << 16 | 0x1f << 00)
/*
* HDMI register constants.
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index 9438f5a..71cc879 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -151,6 +151,7 @@ enum sunxi_gpio_number {
#define SUNXI_GPC6_SDC2 3
#define SUNXI_GPD0_LCD0 2
+#define SUNXI_GPD0_LVDS0 3
#define SUNXI_GPF0_SDC0 2
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index 8782394..e5aa05b 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -345,6 +345,33 @@ config VIDEO_LCD_BL_PWM
Set the backlight pwm pin for the LCD panel. This takes a string in the
format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
+
+# Note only one of these may be selected@a time! But hidden choices are
+# not supported by Kconfig
+config VIDEO_LCD_IF_PARALLEL
+ bool
+
+config VIDEO_LCD_IF_LVDS
+ bool
+
+
+choice
+ prompt "LCD panel support"
+ depends on VIDEO
+ ---help---
+ Select which type of LCD panel to support.
+
+config VIDEO_LCD_PANEL_PARALLEL
+ bool "Generic parallel interface LCD panel"
+ select VIDEO_LCD_IF_PARALLEL
+
+config VIDEO_LCD_PANEL_LVDS
+ bool "Generic lvds interface LCD panel"
+ select VIDEO_LCD_IF_LVDS
+
+endchoice
+
+
config USB_KEYBOARD
boolean "Enable USB keyboard support"
default y
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index 8241492..47d820d 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -339,8 +339,13 @@ static void sunxi_lcdc_pll_set(int tcon, int dotclock,
int best_double = 0;
if (tcon == 0) {
+#ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
min_m = 6;
max_m = 127;
+#endif
+#ifdef CONFIG_VIDEO_LCD_IF_LVDS
+ min_m = max_m = 7;
+#endif
} else {
min_m = 1;
max_m = 15;
@@ -420,6 +425,9 @@ static void sunxi_lcdc_init(void)
/* Clock on */
setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_LCD0);
+#ifdef CONFIG_VIDEO_LCD_IF_LVDS
+ setbits_le32(&ccm->lvds_clk_cfg, CCM_LVDS_CTRL_RST);
+#endif
/* Init lcdc */
writel(0, &lcdc->ctrl); /* Disable tcon */
@@ -439,6 +447,16 @@ static void sunxi_lcdc_enable(void)
(struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
setbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_TCON_ENABLE);
+#ifdef CONFIG_VIDEO_LCD_IF_LVDS
+ setbits_le32(&lcdc->tcon0_lvds_intf, SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE);
+ setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0);
+ setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_UPDATE);
+ udelay(2); /* delay at least 1200 ns */
+ setbits_le32(&lcdc->lvds_ana1, SUNXI_LCDC_LVDS_ANA1_INIT1);
+ udelay(1); /* delay at least 120 ns */
+ setbits_le32(&lcdc->lvds_ana1, SUNXI_LCDC_LVDS_ANA1_INIT2);
+ setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_UPDATE);
+#endif
}
static void sunxi_lcdc_panel_enable(void)
@@ -507,7 +525,12 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode)
int bp, clk_delay, clk_div, clk_double, pin, total, val;
for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++)
+#ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
sunxi_gpio_set_cfgpin(pin, SUNXI_GPD0_LCD0);
+#endif
+#ifdef CONFIG_VIDEO_LCD_IF_LVDS
+ sunxi_gpio_set_cfgpin(pin, SUNXI_GPD0_LVDS0);
+#endif
sunxi_lcdc_pll_set(0, mode->pixclock_khz, &clk_div, &clk_double);
@@ -535,12 +558,17 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode)
writel(SUNXI_LCDC_TCON0_TIMING_V_TOTAL(total) |
SUNXI_LCDC_TCON0_TIMING_V_BP(bp), &lcdc->tcon0_timing_v);
+#ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len),
&lcdc->tcon0_timing_sync);
- /* We only support hv-sync parallel lcd-s for now */
writel(0, &lcdc->tcon0_hv_intf);
writel(0, &lcdc->tcon0_cpu_intf);
+#endif
+#ifdef CONFIG_VIDEO_LCD_IF_LVDS
+ val = (sunxi_display.depth == 18) ? 1 : 0;
+ writel(SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(val), &lcdc->tcon0_lvds_intf);
+#endif
if (sunxi_display.depth == 18 || sunxi_display.depth == 16) {
writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[0]);
@@ -559,7 +587,12 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode)
&lcdc->tcon0_frm_ctrl);
}
- val = 0;
+#ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
+ val = SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE0;
+#endif
+#ifdef CONFIG_VIDEO_LCD_IF_LVDS
+ val = SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE60;
+#endif
if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
val |= SUNXI_LCDC_TCON_HSYNC_MASK;
if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
--
2.1.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [U-Boot] [PATCH v2 2/2] sunxi: video: Add support for Hitachi tx18d42vm LCD panels
2015-01-08 19:49 [U-Boot] [PATCH v2 0/2] sunxi: video: Add lvds support Hans de Goede
2015-01-08 19:49 ` [U-Boot] [PATCH v2 1/2] " Hans de Goede
@ 2015-01-08 19:49 ` Hans de Goede
2015-01-10 0:14 ` Anatolij Gustschin
2015-01-10 10:40 ` [U-Boot] [PATCH v2 0/2] sunxi: video: Add lvds support Ian Campbell
2 siblings, 1 reply; 7+ messages in thread
From: Hans de Goede @ 2015-01-08 19:49 UTC (permalink / raw)
To: u-boot
Hitachi tx18d42vm LCD panels have an onboard controller which needs some
initialization via spi for the panel to become functional as a regular LVDS
panel.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
board/sunxi/Kconfig | 4 +++
drivers/video/Makefile | 2 +-
drivers/video/sunxi_display.c | 5 +++
drivers/video/sunxi_lcd_panel.c | 68 +++++++++++++++++++++++++++++++++++++++++
drivers/video/sunxi_lcd_panel.h | 9 ++++++
5 files changed, 87 insertions(+), 1 deletion(-)
create mode 100644 drivers/video/sunxi_lcd_panel.c
create mode 100644 drivers/video/sunxi_lcd_panel.h
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index e5aa05b..adee5ed 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -369,6 +369,10 @@ config VIDEO_LCD_PANEL_LVDS
bool "Generic lvds interface LCD panel"
select VIDEO_LCD_IF_LVDS
+config VIDEO_LCD_PANEL_HITACHI_TX18D42VM
+ bool "Hitachi tx18d42vm LCD panel"
+ select VIDEO_LCD_IF_LVDS
+
endchoice
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 42b1eaa..d4fe1aa 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -39,7 +39,7 @@ obj-$(CONFIG_VIDEO_SANDBOX_SDL) += sandbox_sdl.o
obj-$(CONFIG_VIDEO_SED13806) += sed13806.o
obj-$(CONFIG_VIDEO_SM501) += sm501.o
obj-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o
-obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o videomodes.o
+obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o sunxi_lcd_panel.o videomodes.o
obj-$(CONFIG_VIDEO_TEGRA) += tegra.o
obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
obj-$(CONFIG_VIDEO_X86) += x86_fb.o
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index 47d820d..c3fc732 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -19,6 +19,7 @@
#include <fdtdec.h>
#include <fdt_support.h>
#include <video_fb.h>
+#include "sunxi_lcd_panel.h"
#include "videomodes.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -487,6 +488,10 @@ static void sunxi_lcdc_panel_enable(void)
gpio_request(pin, "lcd_power");
gpio_direction_output(pin, 1);
}
+
+#ifdef CONFIG_VIDEO_LCD_PANEL_HITACHI_TX18D42VM
+ sunxi_lcd_panel_hitachi_tx18d42vm_init();
+#endif
}
static void sunxi_lcdc_backlight_enable(void)
diff --git a/drivers/video/sunxi_lcd_panel.c b/drivers/video/sunxi_lcd_panel.c
new file mode 100644
index 0000000..9ebaff2
--- /dev/null
+++ b/drivers/video/sunxi_lcd_panel.c
@@ -0,0 +1,68 @@
+/*
+ * LCD panel driver for Allwinner SoCs.
+ *
+ * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_VIDEO_LCD_PANEL_HITACHI_TX18D42VM
+
+#define SPI_CS SUNXI_GPA(0)
+#define SPI_CLK SUNXI_GPA(1)
+#define SPI_MOSI SUNXI_GPA(2)
+
+/*
+ * Very simple write only SPI support, this does not use the generic SPI infra
+ * because that assumes R/W SPI, requiring a MISO pin. Also the necessary glue
+ * code alone would be larger then this minimal version.
+ */
+
+static void sunxi_lcd_panel_spi_write(unsigned int data, int bits)
+{
+ int i, offset;
+
+ gpio_direction_output(SPI_CS, 0);
+ for (i = 0; i < bits; i++) {
+ gpio_direction_output(SPI_CLK, 0);
+ offset = (bits - 1) - i;
+ gpio_direction_output(SPI_MOSI, (data >> offset) & 1);
+ udelay(2);
+ gpio_direction_output(SPI_CLK, 1);
+ udelay(2);
+ }
+ gpio_direction_output(SPI_CS, 1);
+ udelay(2);
+}
+
+void sunxi_lcd_panel_hitachi_tx18d42vm_init(void)
+{
+ const u16 init_data[] = {
+ 0x0029, /* reset */
+ 0x0025, /* standby */
+ 0x0840, /* enable normally black */
+ 0x0430, /* enable FRC/dither */
+ 0x385f, /* enter test mode(1) */
+ 0x3ca4, /* enter test mode(2) */
+ 0x3409, /* enable SDRRS, enlarge OE width */
+ 0x4041, /* adopt 2 line / 1 dot */
+ };
+ int i;
+
+ mdelay(50); /* Wait for lcd controller power on */
+
+ for (i = 0; i < ARRAY_SIZE(init_data); i++)
+ sunxi_lcd_panel_spi_write(init_data[i], 16);
+
+ mdelay(50); /* All the tx18d42vm drivers have a delay here ? */
+
+ sunxi_lcd_panel_spi_write(0x00ad, 16); /* display on */
+}
+
+#endif
diff --git a/drivers/video/sunxi_lcd_panel.h b/drivers/video/sunxi_lcd_panel.h
new file mode 100644
index 0000000..1fb9f1e
--- /dev/null
+++ b/drivers/video/sunxi_lcd_panel.h
@@ -0,0 +1,9 @@
+/*
+ * LCD panel driver for Allwinner SoCs.
+ *
+ * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+void sunxi_lcd_panel_hitachi_tx18d42vm_init(void);
--
2.1.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [U-Boot] [PATCH v2 0/2] sunxi: video: Add lvds support
2015-01-08 19:49 [U-Boot] [PATCH v2 0/2] sunxi: video: Add lvds support Hans de Goede
2015-01-08 19:49 ` [U-Boot] [PATCH v2 1/2] " Hans de Goede
2015-01-08 19:49 ` [U-Boot] [PATCH v2 2/2] sunxi: video: Add support for Hitachi tx18d42vm LCD panels Hans de Goede
@ 2015-01-10 10:40 ` Ian Campbell
2015-01-10 13:55 ` Hans de Goede
2 siblings, 1 reply; 7+ messages in thread
From: Ian Campbell @ 2015-01-10 10:40 UTC (permalink / raw)
To: u-boot
On Thu, 2015-01-08 at 20:49 +0100, Hans de Goede wrote:
> Hi Ian, Anatolij,
>
> Here is v2 of the lvds support for sunxi-video. I've reworked how to Kconfig
> bits are handled as requested by Ian.
>
> Anatolij, the second patch in this sets adds support for initializing the
> lcd controller found on hitachi tx18d42vm lcd panels, this lvds lcd controller
> needs some poking via a separate spi bus before the panel will do anything.
>
> This code is not really sunxi specific, but since sunxi is the only (known)
> user of such a lcd controller I've chosen to do this in a sunxi specific file
> for now, with the idea that making the code generic is more easy when we
> actually have a second user, and thus a better idea of what is needed for a
> generic implementation. Can we get your ack for this solution? Or let me know
> if you want me todo something generic right away and then I'll rework the
> patch.
Anatolij has acked it, so I don't object.
Acked-by: Ian Campbell <ijc@hellion.org.uk>
Do you think it might be worth doing:
#if definged(CONFIG_VIDEO_LCD_IF_PARALLEL)
...
#elif defined(CONFIG_VIDEO_LCD_IF_LVDS)
...
#else
#error unknown LCD_IF
#endif
instead of the independnent #ifdef's, so anyone adding a third option
gets a warning to think about at each site? (Just a suggestion, not to
block the patches if you disagree).
Ian.
^ permalink raw reply [flat|nested] 7+ messages in thread