From patchwork Sun Nov 22 16:16:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 1404518 X-Patchwork-Delegate: lokeshvutla@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=libero.it Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=libero.it header.i=@libero.it header.a=rsa-sha256 header.s=s2014 header.b=Gm2cnUlT; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CfFp16Bb9z9sSf for ; Mon, 23 Nov 2020 03:18:33 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1D9C5825AE; Sun, 22 Nov 2020 17:17:43 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=libero.it Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=libero.it header.i=@libero.it header.b="Gm2cnUlT"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 48B9282605; Sun, 22 Nov 2020 17:17:31 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FORGED_SPF_HELO,FREEMAIL_FROM, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from libero.it (smtp-31.italiaonline.it [213.209.10.31]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 7F184825CA for ; Sun, 22 Nov 2020 17:17:24 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=libero.it Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=dariobin@libero.it Received: from passgat-Modern-14-A10M.homenet.telecomitalia.it ([87.2.94.187]) by smtp-31.iol.local with ESMTPA id gs31kH3pbQgqqgs37knAyi; Sun, 22 Nov 2020 17:17:13 +0100 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2014; t=1606061833; bh=kCLrOstbkOycLT1Y97kbcjoA7LGtj8mu0q5UncclQnw=; h=From; b=Gm2cnUlT06o7+RaxAD3vL67rS2dh22nFxugVfif2K0UFzIIPJPBrybbJpg+7GXUOK 26dDuypd6ejIReOsEHgu6wlliPctJ2ffQ7RUr7WoPmXHQDBCaXWFY1mUdsPQLxg9wl qIYPMypsleOzawFHKMwKjC9zdtVBE8Bx46ekuBXYX5Fv57H1K3UvU8GYED365tKvLg kxUqFB1MrZ0XXHtZSA9VALgpROSDxdFiRyqfjnTWdeTct4n3dsbwCu+Y45Q3DCsZri ivPA0LkRW2gGbf0tg5Db/qV3XzsukGRwxjO/vj0MdCEIziL4wZeOpAW8WAvH+uMrmK TwwVlzN/N5uxA== X-CNFS-Analysis: v=2.4 cv=K4fnowaI c=1 sm=1 tr=0 ts=5fba8f09 a=/8YHF75YQ9f7f3UrJFxoKA==:117 a=/8YHF75YQ9f7f3UrJFxoKA==:17 a=U7GvtkirgPeyM4qxJq4A:9 a=vbrGtdLndY3beCn0:21 a=de3mZ0dmDnV1G4_4:21 From: Dario Binacchi To: u-boot@lists.denx.de Cc: Dario Binacchi , Anatolij Gustschin Subject: [PATCH v6 25/28] video: omap: set LCD clock rate through DM API Date: Sun, 22 Nov 2020 17:16:33 +0100 Message-Id: <20201122161636.14587-26-dariobin@libero.it> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201122161636.14587-19-dariobin@libero.it> References: <20201122161636.14587-19-dariobin@libero.it> X-CMAE-Envelope: MS4xfJSKCZV82RdvkHQwSK/eduqUcQ8lixHxJBnBce2L5cyrDGBhoQookN468Uy18rJeWXJLBZufLIXt+jweSEFvi+67BVyjpj0zPcovfmbb1OXSzgATlFvU tAumA0edJ3wP2itiJ8909qkxt5MOyYsgLCz3xF1QneTEIVC/mhFPUNFjhCg7sJ/T7JX8jP1bowc7gkqKy4TOPALMHZIdcccoCpfSqDLDYA8JgFRZU2SxPR+q jHLwPlPTwdPsCqaLyrBN38FY/SZaU2EajHpcGwTaaR0= X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean The patch configures the display DPLL using the functions provided by the driver model API for the clock. The device tree contains everything needed to get the DPLL clock. The round rate function developed for calculating the DPLL multiplier and divisor and the platform routines for accessing the DPLL registers are removed from the LCD driver code because they are implemented inside the DPLL clock driver. Signed-off-by: Dario Binacchi --- (no changes since v3) Changes in v3: - Add clk.h header. - Fix an error code returned by the probe function. drivers/video/am335x-fb.c | 129 ++++++++++++++++++++++++++++++-------- 1 file changed, 103 insertions(+), 26 deletions(-) diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c index dc959baa27..a0a635cc29 100644 --- a/drivers/video/am335x-fb.c +++ b/drivers/video/am335x-fb.c @@ -12,6 +12,7 @@ * - starts output DMA from gd->fb_base buffer */ #include +#include #include #include #include @@ -112,6 +113,27 @@ struct am335x_lcdhw { unsigned int clkc_reset; /* 0x70 */ }; +DECLARE_GLOBAL_DATA_PTR; + +#if !CONFIG_IS_ENABLED(DM_VIDEO) + +#if !defined(LCD_CNTL_BASE) +#error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!" +#endif + +/* Macro definitions */ +#define FBSIZE(x) (((x)->hactive * (x)->vactive * (x)->bpp) >> 3) + +#define LCDC_RASTER_TIMING_2_INVMASK(x) ((x) & GENMASK(25, 20)) + +static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE; + +int lcd_get_size(int *line_length) +{ + *line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8; + return *line_length * panel_info.vl_row + 0x20; +} + struct dpll_data { unsigned long rounded_rate; u16 rounded_m; @@ -119,8 +141,6 @@ struct dpll_data { u8 rounded_div; }; -DECLARE_GLOBAL_DATA_PTR; - /** * am335x_dpll_round_rate() - Round a target rate for an OMAP DPLL * @@ -199,25 +219,6 @@ static ulong am335x_fb_set_pixel_clk_rate(struct am335x_lcdhw *regs, ulong rate) return round_rate; } -#if !CONFIG_IS_ENABLED(DM_VIDEO) - -#if !defined(LCD_CNTL_BASE) -#error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!" -#endif - -/* Macro definitions */ -#define FBSIZE(x) (((x)->hactive * (x)->vactive * (x)->bpp) >> 3) - -#define LCDC_RASTER_TIMING_2_INVMASK(x) ((x) & GENMASK(25, 20)) - -static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE; - -int lcd_get_size(int *line_length) -{ - *line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8; - return *line_length * panel_info.vl_row + 0x20; -} - int am335xfb_init(struct am335x_lcdpanel *panel) { u32 raster_ctrl = 0; @@ -335,14 +336,58 @@ enum { struct am335x_fb_priv { struct am335x_lcdhw *regs; + struct clk gclk; + struct clk dpll_m2_clk; }; +static ulong tilcdc_set_pixel_clk_rate(struct udevice *dev, ulong rate) +{ + struct am335x_fb_priv *priv = dev_get_priv(dev); + struct am335x_lcdhw *regs = priv->regs; + ulong mult_rate, mult_round_rate, best_err, err; + u32 v; + int div, i; + + best_err = rate; + div = 0; + for (i = 2; i <= 255; i++) { + mult_rate = rate * i; + mult_round_rate = clk_round_rate(&priv->gclk, mult_rate); + if (IS_ERR_VALUE(mult_round_rate)) + return mult_round_rate; + + err = mult_rate - mult_round_rate; + if (err < best_err) { + best_err = err; + div = i; + if (err == 0) + break; + } + } + + if (div == 0) { + dev_err(dev, "failed to find a divisor\n"); + return -EFAULT; + } + + mult_rate = clk_set_rate(&priv->gclk, rate * div); + v = readl(®s->ctrl) & ~LCDC_CTRL_CLK_DIVISOR_MASK; + v |= LCDC_CTRL_CLK_DIVISOR(div); + writel(v, ®s->ctrl); + rate = mult_rate / div; + dev_dbg(dev, "rate=%ld, div=%d, err=%ld\n", rate, div, err); + return rate; +} + static int am335x_fb_remove(struct udevice *dev) { struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev); + struct am335x_fb_priv *priv = dev_get_priv(dev); uc_plat->base -= 0x20; uc_plat->size += 0x20; + clk_release_all(&priv->gclk, 1); + clk_release_all(&priv->dpll_m2_clk, 1); return 0; } @@ -352,10 +397,10 @@ static int am335x_fb_probe(struct udevice *dev) struct video_priv *uc_priv = dev_get_uclass_priv(dev); struct am335x_fb_priv *priv = dev_get_priv(dev); struct am335x_lcdhw *regs = priv->regs; - struct udevice *panel; + struct udevice *panel, *clk_dev; struct tilcdc_panel_info info; struct display_timing timing; - struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL; + ulong rate; u32 reg; int err; @@ -416,10 +461,42 @@ static int am335x_fb_probe(struct udevice *dev) return -EINVAL; } - am335x_fb_set_pixel_clk_rate(regs, timing.pixelclock.typ); + err = uclass_get_device_by_name(UCLASS_CLK, "lcd_gclk@534", &clk_dev); + if (err) { + dev_err(dev, "failed to get lcd_gclk device\n"); + return err; + } - /* clock source for LCDC from dispPLL M2 */ - writel(0, &cmdpll->clklcdcpixelclk); + err = clk_request(clk_dev, &priv->gclk); + if (err) { + dev_err(dev, "failed to get %s clock\n", clk_dev->name); + return err; + } + + rate = tilcdc_set_pixel_clk_rate(dev, timing.pixelclock.typ); + if (IS_ERR_VALUE(rate)) { + dev_err(dev, "failed to set pixel clock rate\n"); + return rate; + } + + err = uclass_get_device_by_name(UCLASS_CLK, "dpll_disp_m2_ck@4a4", &clk_dev); + if (err) { + dev_err(dev, "failed to get dpll_disp_m2 clock device\n"); + return err; + } + + err = clk_request(clk_dev, &priv->dpll_m2_clk); + if (err) { + dev_err(dev, "failed to get %s clock\n", clk_dev->name); + return err; + } + + err = clk_set_parent(&priv->gclk, &priv->dpll_m2_clk); + if (err) { + dev_err(dev, "failed to set %s clock as %s's parent\n", + priv->dpll_m2_clk.dev->name, priv->gclk.dev->name); + return err; + } /* palette default entry */ memset((void *)uc_plat->base, 0, 0x20);