All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dario Binacchi <dariobin@libero.it>
To: u-boot@lists.denx.de
Subject: [PATCH 08/11] video: omap: create two routines to set the pixel clock rate
Date: Sun,  9 Feb 2020 19:47:41 +0100	[thread overview]
Message-ID: <20200209184745.20473-9-dariobin@libero.it> (raw)
In-Reply-To: <20200209184745.20473-1-dariobin@libero.it>

Created in preparation to support driver-model, they can also be called
from legacy code. In this way, code duplication is avoided.

Signed-off-by: Dario Binacchi <dariobin@libero.it>
---

 drivers/video/am335x-fb.c | 130 ++++++++++++++++++++++++++++----------
 1 file changed, 97 insertions(+), 33 deletions(-)

diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c
index bb89cb515d..e53c1d276e 100644
--- a/drivers/video/am335x-fb.c
+++ b/drivers/video/am335x-fb.c
@@ -16,6 +16,7 @@
 #include <asm/arch/omap.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
+#include <linux/err.h>
 #include <lcd.h>
 #include "am335x-fb.h"
 
@@ -26,6 +27,7 @@
 #define LCDC_FMAX				200000000
 
 /* LCD Control Register */
+#define LCDC_CTRL_CLK_DIVISOR_MASK		(0x0000FF00)
 #define LCDC_CTRL_RASTER_MODE			BIT(0)
 #define LCDC_CTRL_CLK_DIVISOR(x)		(((x) & 0xFF) << 8)
 /* LCD Clock Enable Register */
@@ -98,10 +100,95 @@ struct am335x_lcdhw {
 	unsigned int		clkc_reset;		/* 0x70 */
 };
 
+struct dpll_data {
+	unsigned long rounded_rate;
+	u16 rounded_m;
+	u8 rounded_n;
+	u8 rounded_div;
+};
+
 static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE;
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/**
+ * am335x_dpll_round_rate() - Round a target rate for an OMAP DPLL
+ *
+ * @dpll_data: struct dpll_data pointer for the DPLL
+ * @rate:      New DPLL clock rate
+ * @return rounded rate and the computed m, n and div values in the dpll_data
+ *         structure, or -ve error code.
+ */
+static ulong am335x_dpll_round_rate(struct dpll_data *dd, ulong rate)
+{
+	unsigned int m, n, d;
+	unsigned long rounded_rate;
+	int err, err_r;
+
+	dd->rounded_rate = -EFAULT;
+	err = rate;
+	err_r = err;
+
+	for (d = 2; err && d < 255; d++) {
+		for (m = 2; m < 2047; m++) {
+			if ((V_OSCK * m) < (rate * d))
+				continue;
+
+			n = (V_OSCK * m) / (rate * d);
+			if (n > 127)
+				break;
+
+			if (((V_OSCK * m) / n) > LCDC_FMAX)
+				break;
+
+			rounded_rate = (V_OSCK * m) / n / d;
+			err = abs(rounded_rate - rate);
+			if (err < err_r) {
+				err_r = err;
+				dd->rounded_rate = rounded_rate;
+				dd->rounded_m = m;
+				dd->rounded_n = n;
+				dd->rounded_div = d;
+				if (err == 0)
+					break;
+			}
+		}
+	}
+
+	debug("DPLL display: best error %d Hz (M %d, N %d, DIV %d)\n",
+	      err_r, dd->rounded_m, dd->rounded_n, dd->rounded_div);
+
+	return dd->rounded_rate;
+}
+
+/**
+ * am335x_fb_set_pixel_clk_rate() - Set pixel clock rate.
+ *
+ * @am335x_lcdhw: Base address of the LCD controller registers.
+ * @rate:         New clock rate in Hz.
+ * @return new rate, or -ve error code.
+ */
+static ulong am335x_fb_set_pixel_clk_rate(struct am335x_lcdhw *regs, ulong rate)
+{
+	struct dpll_params dpll_disp = { 1, 0, 1, -1, -1, -1, -1 };
+	struct dpll_data dd;
+	ulong round_rate;
+	u32 reg;
+
+	round_rate = am335x_dpll_round_rate(&dd, rate);
+	if (IS_ERR_VALUE(round_rate))
+		return round_rate;
+
+	dpll_disp.m = dd.rounded_m;
+	dpll_disp.n = dd.rounded_n;
+	do_setup_dpll(&dpll_disp_regs, &dpll_disp);
+
+	reg = readl(&regs->ctrl) & ~LCDC_CTRL_CLK_DIVISOR_MASK;
+	reg |= LCDC_CTRL_CLK_DIVISOR(dd.rounded_div);
+	writel(reg, &regs->ctrl);
+	return round_rate;
+}
+
 int lcd_get_size(int *line_length)
 {
 	*line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
@@ -111,11 +198,9 @@ int lcd_get_size(int *line_length)
 int am335xfb_init(struct am335x_lcdpanel *panel)
 {
 	u32 raster_ctrl = 0;
-
 	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;
+	ulong rate;
+	u32 reg;
 
 	if (gd->fb_base == 0) {
 		printf("ERROR: no valid fb_base stored in GLOBAL_DATA_PTR!\n");
@@ -156,34 +241,9 @@ int am335xfb_init(struct am335x_lcdpanel *panel)
 	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; err_r && 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;
-				if (err_r == 0)
-					break;
-			}
-		}
-	}
-	debug("%s: PLL: best error %d Hz (M %d, N %d, DIV %d)\n",
-	      __func__, err_r, dpll_disp.m, dpll_disp.n, best_d);
-	do_setup_dpll(&dpll_disp_regs, &dpll_disp);
+	rate = am335x_fb_set_pixel_clk_rate(lcdhw, panel->pxl_clk);
+	if (IS_ERR_VALUE(rate))
+		return rate;
 
 	/* clock source for LCDC from dispPLL M2 */
 	writel(0x0, &cmdpll->clklcdcpixelclk);
@@ -203,7 +263,11 @@ int am335xfb_init(struct am335x_lcdpanel *panel)
 	lcdhw->clkc_enable = LCDC_CLKC_ENABLE_CORECLKEN |
 		LCDC_CLKC_ENABLE_LIDDCLKEN | LCDC_CLKC_ENABLE_DMACLKEN;
 	lcdhw->raster_ctrl = 0;
-	lcdhw->ctrl = LCDC_CTRL_CLK_DIVISOR(best_d) | LCDC_CTRL_RASTER_MODE;
+
+	reg = lcdhw->ctrl & LCDC_CTRL_CLK_DIVISOR_MASK;
+	reg |= LCDC_CTRL_RASTER_MODE;
+	lcdhw->ctrl = reg;
+
 	lcdhw->lcddma_fb0_base = gd->fb_base;
 	lcdhw->lcddma_fb0_ceiling = gd->fb_base + FBSIZE(panel);
 	lcdhw->lcddma_fb1_base = gd->fb_base;
-- 
2.24.0

  parent reply	other threads:[~2020-02-09 18:47 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-09 18:47 [PATCH 00/11] Add DM/DTS support for omap video driver Dario Binacchi
2020-02-09 18:47 ` [PATCH 01/11] video: omap: use BIT() macro Dario Binacchi
2020-02-10  4:08   ` Lokesh Vutla
2020-02-09 18:47 ` [PATCH 02/11] video: omap: add missing bitfield masks Dario Binacchi
2020-02-10  4:06   ` Lokesh Vutla
2020-02-09 18:47 ` [PATCH 03/11] video: omap: fix coding style on use of spaces Dario Binacchi
2020-02-09 18:47 ` [PATCH 04/11] video: omap: fix bitfields order Dario Binacchi
2020-02-09 18:47 ` [PATCH 05/11] video: omap: rename LCD controller registers Dario Binacchi
2020-02-09 18:47 ` [PATCH 06/11] video: omap: fix debug message Dario Binacchi
2020-02-10  4:09   ` Lokesh Vutla
2020-02-09 18:47 ` [PATCH 07/11] video: omap: add loop exit conditions to the dpll setup Dario Binacchi
2020-02-10  4:10   ` Lokesh Vutla
2020-02-09 18:47 ` Dario Binacchi [this message]
2020-02-09 18:47 ` [PATCH 09/11] video: omap: add support for DM/DTS Dario Binacchi
2020-02-10  4:20   ` Lokesh Vutla
2020-02-09 18:47 ` [PATCH 10/11] arm: fdt: omap: update dts panel node Dario Binacchi
2020-02-10  4:22   ` Lokesh Vutla
2020-02-10 15:15     ` Tom Rini
2020-02-10 16:04       ` Tom Rini
     [not found]     ` <948333446.1041134.1581365999202@mail1.libero.it>
     [not found]       ` <6d060e0d-dcba-e94c-7078-1e461a9c5b8b@ti.com>
2020-02-11 20:06         ` dariobin at libero.it
2020-02-09 18:47 ` [PATCH 11/11] fdt: video: omap: add framebuffer and panel bindings Dario Binacchi
2020-02-10 23:13   ` Simon Glass
2020-02-10 11:25 ` [PATCH 00/11] Add DM/DTS support for omap video driver Adam Ford

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=20200209184745.20473-9-dariobin@libero.it \
    --to=dariobin@libero.it \
    --cc=u-boot@lists.denx.de \
    /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.