Re: [U-Boot] [PATCH v4 5/5] sunxi: video: add LCD support to DE2 driver

2017-10-27 Thread Anatolij Gustschin
On Thu, 26 Oct 2017 21:51:52 -0700
Vasily Khoruzhick anars...@gmail.com wrote:

> Extend DE2 driver with LCD support. Tested on Pinebook which is based
> on A64 and has ANX6345 eDP bridge with eDP panel connected to it.
> 
> Signed-off-by: Vasily Khoruzhick 
> ---
> v4: - adapted to v4 changes in patch 4/5
> v3: - rebased and fixed checkpatch errors/warnings
> 
> v2: - drop redundant clock_set_pll10() call
> - fallback to timings from DT if reading EDID from bridge failed
> - read panel_bpp from DT
>  arch/arm/mach-sunxi/Kconfig |   2 +-
>  drivers/video/sunxi/Makefile|   2 +-
>  drivers/video/sunxi/sunxi_de2.c |  17 +
>  drivers/video/sunxi/sunxi_lcd.c | 152 
> 
>  4 files changed, 171 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/video/sunxi/sunxi_lcd.c

Applied to u-boot-video/master, thanks!

--
Anatolij
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v4 5/5] sunxi: video: add LCD support to DE2 driver

2017-10-26 Thread Vasily Khoruzhick
Extend DE2 driver with LCD support. Tested on Pinebook which is based
on A64 and has ANX6345 eDP bridge with eDP panel connected to it.

Signed-off-by: Vasily Khoruzhick 
---
v4: - adapted to v4 changes in patch 4/5
v3: - rebased and fixed checkpatch errors/warnings

v2: - drop redundant clock_set_pll10() call
- fallback to timings from DT if reading EDID from bridge failed
- read panel_bpp from DT
 arch/arm/mach-sunxi/Kconfig |   2 +-
 drivers/video/sunxi/Makefile|   2 +-
 drivers/video/sunxi/sunxi_de2.c |  17 +
 drivers/video/sunxi/sunxi_lcd.c | 152 
 4 files changed, 171 insertions(+), 2 deletions(-)
 create mode 100644 drivers/video/sunxi/sunxi_lcd.c

diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 2309f5..06d697e3a7 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -680,7 +680,7 @@ config VIDEO_LCD_MODE
 
 config VIDEO_LCD_DCLK_PHASE
int "LCD panel display clock phase"
-   depends on VIDEO
+   depends on VIDEO || DM_VIDEO
default 1
---help---
Select LCD panel display clock phase shift, range 0-3.
diff --git a/drivers/video/sunxi/Makefile b/drivers/video/sunxi/Makefile
index 0d64c2021f..8c91766c24 100644
--- a/drivers/video/sunxi/Makefile
+++ b/drivers/video/sunxi/Makefile
@@ -6,4 +6,4 @@
 #
 
 obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o lcdc.o tve_common.o 
../videomodes.o
-obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o lcdc.o ../dw_hdmi.o
+obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o lcdc.o ../dw_hdmi.o 
sunxi_lcd.o
diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c
index ee67764ac5..49c36b8d73 100644
--- a/drivers/video/sunxi/sunxi_de2.c
+++ b/drivers/video/sunxi/sunxi_de2.c
@@ -232,6 +232,23 @@ static int sunxi_de2_probe(struct udevice *dev)
if (!(gd->flags & GD_FLG_RELOC))
return 0;
 
+   ret = uclass_find_device_by_name(UCLASS_DISPLAY,
+"sunxi_lcd", );
+   if (!ret) {
+   int mux;
+
+   mux = 0;
+
+   ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux,
+false);
+   if (!ret) {
+   video_set_flush_dcache(dev, 1);
+   return 0;
+   }
+   }
+
+   debug("%s: lcd display not found (ret=%d)\n", __func__, ret);
+
ret = uclass_find_device_by_name(UCLASS_DISPLAY,
 "sunxi_dw_hdmi", );
if (!ret) {
diff --git a/drivers/video/sunxi/sunxi_lcd.c b/drivers/video/sunxi/sunxi_lcd.c
new file mode 100644
index 00..2f51aebe27
--- /dev/null
+++ b/drivers/video/sunxi/sunxi_lcd.c
@@ -0,0 +1,152 @@
+/*
+ * Allwinner LCD driver
+ *
+ * (C) Copyright 2017 Vasily Khoruzhick 
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct sunxi_lcd_priv {
+   struct display_timing timing;
+   int panel_bpp;
+};
+
+static void sunxi_lcdc_config_pinmux(void)
+{
+#ifdef CONFIG_MACH_SUN50I
+   int pin;
+
+   for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(21); pin++) {
+   sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LCD0);
+   sunxi_gpio_set_drv(pin, 3);
+   }
+#endif
+}
+
+static int sunxi_lcd_enable(struct udevice *dev, int bpp,
+   const struct display_timing *edid)
+{
+   struct sunxi_ccm_reg * const ccm =
+  (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+   struct sunxi_lcdc_reg * const lcdc =
+  (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
+   struct sunxi_lcd_priv *priv = dev_get_priv(dev);
+   struct udevice *backlight;
+   int clk_div, clk_double, ret;
+
+   /* Reset off */
+   setbits_le32(>ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_LCD0);
+   /* Clock on */
+   setbits_le32(>ahb_gate1, 1 << AHB_GATE_OFFSET_LCD0);
+
+   lcdc_init(lcdc);
+   sunxi_lcdc_config_pinmux();
+   lcdc_pll_set(ccm, 0, edid->pixelclock.typ / 1000,
+_div, _double, false);
+   lcdc_tcon0_mode_set(lcdc, edid, clk_div, false,
+   priv->panel_bpp, CONFIG_VIDEO_LCD_DCLK_PHASE);
+   lcdc_enable(lcdc, priv->panel_bpp);
+
+   ret = uclass_get_device(UCLASS_PANEL_BACKLIGHT, 0, );
+   if (!ret)
+   backlight_enable(backlight);
+
+   return 0;
+}
+
+static int sunxi_lcd_read_timing(struct udevice *dev,
+struct display_timing *timing)
+{
+   struct sunxi_lcd_priv *priv = dev_get_priv(dev);
+
+   memcpy(timing, >timing, sizeof(struct display_timing));
+
+   return 0;
+}
+
+static int sunxi_lcd_probe(struct udevice *dev)
+{
+   struct udevice *cdev;
+   struct sunxi_lcd_priv