Merge git://git.denx.de/u-boot-video
diff --git a/arch/arm/include/asm/arch-am33xx/clock.h b/arch/arm/include/asm/arch-am33xx/clock.h
index 5399bb8..9dbcd3a 100644
--- a/arch/arm/include/asm/arch-am33xx/clock.h
+++ b/arch/arm/include/asm/arch-am33xx/clock.h
@@ -104,6 +104,7 @@
 extern const struct dpll_regs dpll_core_regs;
 extern const struct dpll_regs dpll_per_regs;
 extern const struct dpll_regs dpll_ddr_regs;
+extern const struct dpll_regs dpll_disp_regs;
 extern const struct dpll_params dpll_mpu_opp[NUM_CRYSTAL_FREQ][NUM_OPPS];
 extern const struct dpll_params dpll_core_1000MHz[NUM_CRYSTAL_FREQ];
 extern const struct dpll_params dpll_per_192MHz[NUM_CRYSTAL_FREQ];
diff --git a/arch/arm/mach-omap2/am33xx/clock_am33xx.c b/arch/arm/mach-omap2/am33xx/clock_am33xx.c
index 1780bbd..9ab4d25 100644
--- a/arch/arm/mach-omap2/am33xx/clock_am33xx.c
+++ b/arch/arm/mach-omap2/am33xx/clock_am33xx.c
@@ -52,6 +52,13 @@
 	.cm_div_m2_dpll		= CM_WKUP + 0xA0,
 };
 
+const struct dpll_regs dpll_disp_regs = {
+	.cm_clkmode_dpll	= CM_WKUP + 0x98,
+	.cm_idlest_dpll		= CM_WKUP + 0x48,
+	.cm_clksel_dpll		= CM_WKUP + 0x54,
+	.cm_div_m2_dpll		= CM_WKUP + 0xA4,
+};
+
 struct dpll_params dpll_mpu_opp100 = {
 		CONFIG_SYS_MPUCLK, OSC-1, 1, -1, -1, -1, -1};
 const struct dpll_params dpll_core_opp100 = {
diff --git a/board/BuR/brppt1/board.c b/board/BuR/brppt1/board.c
index 6083479..9f7b2d9 100644
--- a/board/BuR/brppt1/board.c
+++ b/board/BuR/brppt1/board.c
@@ -120,9 +120,6 @@
 	};
 	do_enable_clocks(clk_domains, clk_modules_tsspecific, 1);
 
-	/* setup LCD-Pixel Clock */
-	writel(0x2, &cmdpll->clklcdcpixelclk);	/* clock comes from perPLL M2 */
-
 	/* setup I2C */
 	enable_i2c_pin_mux();
 	i2c_set_bus_num(0);
diff --git a/board/BuR/brxre1/board.c b/board/BuR/brxre1/board.c
index ca08f3c..7e83437 100644
--- a/board/BuR/brxre1/board.c
+++ b/board/BuR/brxre1/board.c
@@ -114,8 +114,6 @@
 		0
 	};
 	do_enable_clocks(clk_domains, clk_modules_xre1specific, 1);
-	/* setup LCD-Pixel Clock */
-	writel(0x2, CM_DPLL + 0x34);
 	/* power-OFF LCD-Display */
 	gpio_direction_output(LCD_PWR, 0);
 
diff --git a/board/BuR/common/common.c b/board/BuR/common/common.c
index c1cd010..d82b8cd 100644
--- a/board/BuR/common/common.c
+++ b/board/BuR/common/common.c
@@ -139,13 +139,7 @@
 	pnltmp.vsw = FDTPROP(PATHTIM, "vsync-len");
 	pnltmp.pup_delay = FDTPROP(PATHTIM, "pupdelay");
 	pnltmp.pon_delay = FDTPROP(PATHTIM, "pondelay");
-
-	/* calc. proper clk-divisor */
-	dtbprop = FDTPROP(PATHTIM, "clock-frequency");
-	if (dtbprop != ~0UL)
-		pnltmp.pxl_clk_div = 192000000 / dtbprop;
-	else
-		pnltmp.pxl_clk_div = ~0UL;
+	pnltmp.pxl_clk = FDTPROP(PATHTIM, "clock-frequency");
 
 	/* check polarity of control-signals */
 	dtbprop = FDTPROP(PATHTIM, "hsync-active");
@@ -195,7 +189,7 @@
 	pnltmp.vfp = env_get_ulong("ds1_vfp", 10, ~0UL);
 	pnltmp.vbp = env_get_ulong("ds1_vbp", 10, ~0UL);
 	pnltmp.vsw = env_get_ulong("ds1_vsw", 10, ~0UL);
-	pnltmp.pxl_clk_div = env_get_ulong("ds1_pxlclkdiv", 10, ~0UL);
+	pnltmp.pxl_clk = env_get_ulong("ds1_pxlclk", 10, ~0UL);
 	pnltmp.pol = env_get_ulong("ds1_pol", 16, ~0UL);
 	pnltmp.pup_delay = env_get_ulong("ds1_pupdelay", 10, ~0UL);
 	pnltmp.pon_delay = env_get_ulong("ds1_tondelay", 10, ~0UL);
@@ -211,7 +205,7 @@
 	   ~0UL == (pnltmp.vfp) ||
 	   ~0UL == (pnltmp.vbp) ||
 	   ~0UL == (pnltmp.vsw) ||
-	   ~0UL == (pnltmp.pxl_clk_div) ||
+	   ~0UL == (pnltmp.pxl_clk) ||
 	   ~0UL == (pnltmp.pol) ||
 	   ~0UL == (pnltmp.pup_delay) ||
 	   ~0UL == (pnltmp.pon_delay)
@@ -234,7 +228,7 @@
 			pnltmp.hactive, pnltmp.vactive, pnltmp.bpp,
 			pnltmp.hfp, pnltmp.hbp, pnltmp.hsw,
 			pnltmp.vfp, pnltmp.vbp, pnltmp.vsw,
-			pnltmp.pxl_clk_div, pnltmp.pol, pnltmp.pon_delay);
+			pnltmp.pxl_clk, pnltmp.pol, pnltmp.pon_delay);
 
 		return -1;
 	}
diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c
index a8b3e74..a7892f7 100644
--- a/drivers/video/am335x-fb.c
+++ b/drivers/video/am335x-fb.c
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2013 Hannes Schmelzer <oe5hpm@oevsv.at>
- * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
+ * Copyright (C) 2013-2018 Hannes Schmelzer <oe5hpm@oevsv.at>
+ * B&R Industrial Automation GmbH - http://www.br-automation.com
  *
  * minimal framebuffer driver for TI's AM335x SoC to be compatible with
  * Wolfgang Denk's LCD-Framework (CONFIG_LCD, common/lcd.c)
@@ -12,7 +12,11 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 #include <common.h>
+#include <asm/io.h>
 #include <asm/arch/hardware.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
 #include <lcd.h>
 #include "am335x-fb.h"
 
@@ -20,6 +24,7 @@
 #error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!"
 #endif
 
+#define LCDC_FMAX				200000000
 
 /* LCD Control Register */
 #define LCD_CLK_DIVISOR(x)			((x) << 8)
@@ -96,6 +101,7 @@
 };
 
 static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE;
+
 DECLARE_GLOBAL_DATA_PTR;
 
 int lcd_get_size(int *line_length)
@@ -108,11 +114,16 @@
 {
 	u32 raster_ctrl = 0;
 
-	if (0 == gd->fb_base) {
+	struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL;
+	struct dpll_params dpll_disp = { 1, 0, 1, -1, -1, -1, -1 };
+	unsigned int m, n, d, best_d = 2;
+	int err = 0, err_r = 0;
+
+	if (gd->fb_base == 0) {
 		printf("ERROR: no valid fb_base stored in GLOBAL_DATA_PTR!\n");
 		return -1;
 	}
-	if (0 == panel) {
+	if (panel == NULL) {
 		printf("ERROR: missing ptr to am335x_lcdpanel!\n");
 		return -1;
 	}
@@ -132,14 +143,51 @@
 		return -1;
 	}
 
+	/* check given clock-frequency */
+	if (panel->pxl_clk > (LCDC_FMAX / 2)) {
+		pr_err("am335x-fb: requested pxl-clk: %d not supported!\n",
+		       panel->pxl_clk);
+		return -1;
+	}
+
 	debug("setting up LCD-Controller for %dx%dx%d (hfp=%d,hbp=%d,hsw=%d / ",
 	      panel->hactive, panel->vactive, panel->bpp,
 	      panel->hfp, panel->hbp, panel->hsw);
-	debug("vfp=%d,vbp=%d,vsw=%d / clk-div=%d)\n",
-	      panel->vfp, panel->vfp, panel->vsw, panel->pxl_clk_div);
+	debug("vfp=%d,vbp=%d,vsw=%d / clk=%d)\n",
+	      panel->vfp, panel->vfp, panel->vsw, panel->pxl_clk);
 	debug("using frambuffer at 0x%08x with size %d.\n",
 	      (unsigned int)gd->fb_base, FBSIZE(panel));
 
+	/* setup display pll for requested clock frequency */
+	err = panel->pxl_clk;
+	err_r = err;
+
+	for (d = 2; d < 255; d++) {
+		for (m = 2; m < 2047; m++) {
+			if ((V_OSCK * m) < (panel->pxl_clk * d))
+				continue;
+			n = (V_OSCK * m) / (panel->pxl_clk * d);
+			if (n > 127)
+				break;
+			if (((V_OSCK * m) / n) > LCDC_FMAX)
+				break;
+
+			err = abs((V_OSCK * m) / n / d - panel->pxl_clk);
+			if (err < err_r) {
+				err_r = err;
+				dpll_disp.m = m;
+				dpll_disp.n = n;
+				best_d = d;
+			}
+		}
+	}
+	debug("%s: PLL: best error %d Hz (M %d, N %d, DISP %d)\n",
+	      __func__, err_r, dpll_disp.m, dpll_disp.n, best_d);
+	do_setup_dpll(&dpll_disp_regs, &dpll_disp);
+
+	/* clock source for LCDC from dispPLL M2 */
+	writel(0x0, &cmdpll->clklcdcpixelclk);
+
 	/* palette default entry */
 	memset((void *)gd->fb_base, 0, 0x20);
 	*(unsigned int *)gd->fb_base = 0x4000;
@@ -147,14 +195,14 @@
 	gd->fb_base += 0x20;
 
 	/* turn ON display through powercontrol function if accessible */
-	if (0 != panel->panel_power_ctrl)
+	if (panel->panel_power_ctrl != NULL)
 		panel->panel_power_ctrl(1);
 
 	debug("am335x-fb: wait for stable power ...\n");
 	mdelay(panel->pup_delay);
 	lcdhw->clkc_enable = LCD_CORECLKEN | LCD_LIDDCLKEN | LCD_DMACLKEN;
 	lcdhw->raster_ctrl = 0;
-	lcdhw->ctrl = LCD_CLK_DIVISOR(panel->pxl_clk_div) | LCD_RASTER_MODE;
+	lcdhw->ctrl = LCD_CLK_DIVISOR(best_d) | LCD_RASTER_MODE;
 	lcdhw->lcddma_fb0_base = gd->fb_base;
 	lcdhw->lcddma_fb0_ceiling = gd->fb_base + FBSIZE(panel);
 	lcdhw->lcddma_fb1_base = gd->fb_base;
diff --git a/drivers/video/am335x-fb.h b/drivers/video/am335x-fb.h
index 3f4b567..f99b341 100644
--- a/drivers/video/am335x-fb.h
+++ b/drivers/video/am335x-fb.h
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2013 Hannes Schmelzer <oe5hpm@oevsv.at> -
- * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
+ * Copyright (C) 2013-2018 Hannes Schmelzer <oe5hpm@oevsv.at> -
+ * B&R Industrial Automation GmbH - http://www.br-automation.com
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -53,7 +53,7 @@
 	unsigned int	vfp;		/* Vertical front porch */
 	unsigned int	vbp;		/* Vertical back porch */
 	unsigned int	vsw;		/* Vertical Sync Pulse Width */
-	unsigned int	pxl_clk_div;	/* Pixel clock divider*/
+	unsigned int	pxl_clk;	/* Pixel clock */
 	unsigned int	pol;		/* polarity of sync, clock signals */
 	unsigned int	pup_delay;	/*
 					 * time in ms after power on to