From patchwork Fri Sep 13 09:55:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 3480 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-ed1-f70.google.com (mail-ed1-f70.google.com [209.85.208.70]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id 3C68841280 for ; Fri, 13 Sep 2024 11:57:16 +0200 (CEST) Received: by mail-ed1-f70.google.com with SMTP id 4fb4d7f45d1cf-5c244732fe0sf1212348a12.3 for ; Fri, 13 Sep 2024 02:57:16 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1726221436; cv=pass; d=google.com; s=arc-20240605; b=f7rtkBgflPFQn84MZoJTSKXeDWJPPWy8VhgdQfjz7VbS1f84d0nWjaQicr5Aehu967 bibTul2vkMozh9IW2zQakJ+Gk47spU/612HAkkFd5JJbM7dSJZ9Jx68PvwCzOqrNRoeV oJT9kqRfe+NwZvw0cXOTf74off7GW55EFn0Y4gv2WBA1x8zYitXKdlJim/5/0I9piif6 rhi57XcC2MGjL3mwW7/3Rpq36SlOYvrV6y/Wxi0Yn58VUQ5QmQnpHj1pa5Sy+mUtnf+A oi1FV+05OtnGCGhRv485JU4mZbQYAoHeOhvlgddCxtO1UkmeDJ7i5PxiT1+4dj7qnMZ/ aOZA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=/sbimWxLABSY3mwKyxNpL+1AgdJUKKUCh7RCoDFV4Ew=; fh=Z0NLAIA9DKFRRX+fIAWzfNuLKihNH833m9EanZxuZxc=; b=ZfSp8hE9u4aenPzh9aaCHZPXqZ3B8G41xt8xpRN5Jh6oKNfnIQNyVFxntW1Lw1WQcG Y2yxzsXIWAf9RvOIgHSpZpJWEduNlMASJuV9PRSdzddouwlxJAsQseRAq56TqYYjAZIB chaBJ1lOgLfZlv3jguIKv1IRuaGMgFSDl+cqZxWMB8OSnD0ku6e4b19zK9Aio+7eU6IF hBsh0dL1/nHIGdTkMl4LGxoMPwO530yxPuSMZTa36Soi8I1L1+jbg8j+ICHOOiQMdVJ/ JGk3fFhvm81/LJZRjUhT/qq6/zh2ArqklwjTAj8QH0bEVduba2BmUDblvN/qVoJhihmP MmbQ==; darn=patchwork.amarulasolutions.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b="aq09rl/T"; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com; dara=pass header.i=@amarulasolutions.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; t=1726221436; x=1726826236; darn=patchwork.amarulasolutions.com; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:x-original-authentication-results :x-original-sender:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=/sbimWxLABSY3mwKyxNpL+1AgdJUKKUCh7RCoDFV4Ew=; b=Ziy77b5rApxkWz6gTynlYaGlcTPG4w6bnnKOcnc7mPmyypd94CHxItn0YCw9Cln/yE XT9iEO8OYOrhEFmYYfToa7aMKF9TLxnWYhN2i14mx9pEcIhkDzlvB3PRLovoJgprcI22 bPR5XLs6Z9sFWTGwrNKh6yDaD1XJDTuYINphA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726221436; x=1726826236; h=list-unsubscribe:list-archive:list-help:list-post :x-spam-checked-in-group:list-id:mailing-list:precedence :x-original-authentication-results:x-original-sender:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :x-beenthere:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=/sbimWxLABSY3mwKyxNpL+1AgdJUKKUCh7RCoDFV4Ew=; b=tQsZ+3bXYImCWwmsHVFRiYsNwc689k83y9z7F/t3jUVTvsp5QobDTk35fPcBuI6uAd idUZb/dXWPHZOVmoktBoUXNA1WQ+ceU/StASgkNio5VMMMcdGfNUlJYDYUIwpEoHg9YT 36SJw+w9LxrZh3wgxsMKCU3FUzK6lA/5LcMfBBPaXy5F0T8DxiO+bB3nLij+Rd4Z7NUL Rmqr7lZ55gP4OtkLRIOS6vS3+kq452Gdh6+gn+h8Y6eFLTdg8sbMrqSAlBijI7vhyJUf T9gy1CHl7coF1yGBKcaoUU/dcanAchzvmZcHPta8KPqQSHEjwEZbEc3laAueA7tdWpE7 aIhQ== X-Forwarded-Encrypted: i=2; AJvYcCWptgFKPIy7oAshJBNWZDPSghZAy0AqYe6sCo8Cx4CRGvf4eCpFT4K0TQb67chy0QXWDFEmqMcBaFsNKTOi@patchwork.amarulasolutions.com X-Gm-Message-State: AOJu0YxfXfjBSSQGtLkgaTvPC6y8supF75qIuPHr302kRrS4/m0n4/so k7tgDoSjX/7WSrvdzGlhMmr4TgGuaOmiCJPTzLC2clyTtwLPR+vC48bMyktPwaytgA== X-Google-Smtp-Source: AGHT+IHomNs7UERFBxJSv9pZ96+MxpMdn6otziIUW4uwnCY9WoC8RVFmfMXpZet6wG9yTfJxcCyS3g== X-Received: by 2002:a05:6402:40c4:b0:5c4:23ba:95c4 with SMTP id 4fb4d7f45d1cf-5c423ba9733mr290621a12.9.1726221435807; Fri, 13 Sep 2024 02:57:15 -0700 (PDT) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a05:6402:2685:b0:5be:dded:4357 with SMTP id 4fb4d7f45d1cf-5c41408e81dls608990a12.2.-pod-prod-09-eu; Fri, 13 Sep 2024 02:57:14 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCW97WAqkrqAXYgi3fyjUAsgnX70EhyCiUJKR9jW3TNPGRVfKRWw7gU17aqzsgrPl/rWuEnkg7ySOkMf+fTY@amarulasolutions.com X-Received: by 2002:a17:907:e26a:b0:a7a:8da1:eb00 with SMTP id a640c23a62f3a-a902941faefmr512725366b.7.1726221434367; Fri, 13 Sep 2024 02:57:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726221434; cv=none; d=google.com; s=arc-20160816; b=ec+QIf0FaUPs2l/GD09lJ+N3iaP/K0t2wGCh4maKZBe0HRjWHcpS9BnT1dZm41Q4rg 2rCydu60hWJA8hLJmwQWJ9msMb4313jqD3Y+hLUmjigTVZQsFOr88PM2kFKnU3TcpEuE RF6jUV9CSYR8/nEAImWM7cvy+kPkqzJBognaW6bjtFvNOiTdPjT04aeL+xKev57u+luN KKa3SxkYLP8ESbbTLACHwTidby7Ab+jUeWNwu/TyfaoTBCUL/WkMc7vjYRurfbfAPbL+ VlVTT5tPEfVx02q6k2Z4PHOy8w/jjpgTAIjWS3HMf7C0UXUwkLBSbYTpFyqcN3BYh26U BqPQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=4mvzLq45UAwkCCqqyJ82Yf/IOCaPYS9JtH6sYR6xojk=; fh=CDDqr4lWtnqRpVrMct3+CKfiCLipSN4UcbAcnlo34vI=; b=Lw0tPtHwvoXYgH9caIC9tV6SjgB85EYzlYHaX6pg133daIEJpjBqfv1aHOfncY8b03 eg/VE844rPfIc1DDe/eGMm4QE2wxW/6JCQsH9XoOsXhxsya5w+dCJmLutRwhOAHEYwJJ 0AFmjy6tQxiazJOm2HTZvPz/G/+EQqO47hN5OGdvyxn7vhs8GQ0B31WSxp//+I/n5zHj iy667ItpSpWtXt2m5Bw7YYPyITTcZsfMsqz1lXq04aFpHWLJ5DyY9tWi3y1hyRyEwb7j DrM1sTktdwwpRvx3YcJrEIbewVM8Ic6RM7c+iCYcDXgkQXuXCcirVtjRG0opUImvIgUo wVag==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b="aq09rl/T"; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com; dara=pass header.i=@amarulasolutions.com Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) by mx.google.com with SMTPS id a640c23a62f3a-a8d258167b2sor420068266b.4.2024.09.13.02.57.14 for (Google Transport Security); Fri, 13 Sep 2024 02:57:14 -0700 (PDT) Received-SPF: pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; X-Forwarded-Encrypted: i=1; AJvYcCUNz/0eDrsbZJjAmSeggyBflyn87jE07VS9OpIJJPa4VNTfTnBheKZQwJWQ4sEJFp8KbxLWn3DV/Pz+HWG7@amarulasolutions.com X-Received: by 2002:a17:906:c104:b0:a7a:c083:857b with SMTP id a640c23a62f3a-a902961a6c6mr580328166b.42.1726221433667; Fri, 13 Sep 2024 02:57:13 -0700 (PDT) Received: from dario-ThinkPad-T14s-Gen-2i.homenet.telecomitalia.it (host-87-4-102-18.retail.telecomitalia.it. [87.4.102.18]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a8d25cee72bsm863224766b.173.2024.09.13.02.57.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 Sep 2024 02:57:13 -0700 (PDT) From: Dario Binacchi To: u-boot@lists.denx.de Cc: Fabio Estevam , linux-amarula@amarulasolutions.com, michael@amarulasolutions.com, Miquel Raynal , Ye Li , Dario Binacchi , Anatolij Gustschin , Peter Robinson , =?utf-8?q?S=C3=A9bastien_Szymanski?= , Tom Rini Subject: [PATCH 12/26] video: Update mxsfb video drivers for iMX8MM/iMX8MN display Date: Fri, 13 Sep 2024 11:55:54 +0200 Message-ID: <20240913095622.72377-13-dario.binacchi@amarulasolutions.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240913095622.72377-1-dario.binacchi@amarulasolutions.com> References: <20240913095622.72377-1-dario.binacchi@amarulasolutions.com> MIME-Version: 1.0 X-Original-Sender: dario.binacchi@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b="aq09rl/T"; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com; dara=pass header.i=@amarulasolutions.com Content-Type: text/plain; charset="UTF-8" Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Michael Trimarchi Update mxsfb for LCD video driver Signed-off-by: Ye Li Signed-off-by: Michael Trimarchi Signed-off-by: Dario Binacchi --- drivers/video/mxsfb.c | 139 ++++++++++++++++++++++++++++-------------- 1 file changed, 93 insertions(+), 46 deletions(-) diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 792d6314d15e..45431f0a1047 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -21,8 +21,13 @@ #include #include #include +#include +#include +#include +#include #include "videomodes.h" +#include #define PS2KHZ(ps) (1000000000UL / (ps)) #define HZ2PS(hz) (1000000000UL / ((hz) / 1000)) @@ -30,6 +35,11 @@ #define BITS_PP 18 #define BYTES_PP 4 +struct mxsfb_priv { + fdt_addr_t reg_base; + struct udevice *disp_dev; +}; + struct mxs_dma_desc desc; /** @@ -56,9 +66,10 @@ __weak void mxsfb_system_setup(void) */ static void mxs_lcd_init(struct udevice *dev, u32 fb_addr, - struct display_timing *timings, int bpp) + struct display_timing *timings, int bpp, bool bridge) { - struct mxs_lcdif_regs *regs = (struct mxs_lcdif_regs *)MXS_LCDIF_BASE; + struct mxsfb_priv *priv = dev_get_priv(dev); + struct mxs_lcdif_regs *regs = (struct mxs_lcdif_regs *)priv->reg_base; const enum display_flags flags = timings->flags; uint32_t word_len = 0, bus_width = 0; uint8_t valid_data = 0; @@ -109,7 +120,7 @@ static void mxs_lcd_init(struct udevice *dev, u32 fb_addr, } #else /* Kick in the LCDIF clock */ - mxs_set_lcdclk(MXS_LCDIF_BASE, timings->pixelclock.typ / 1000); + mxs_set_lcdclk(priv->reg_base, timings->pixelclock.typ / 1000); #endif /* Restart the LCDIF block */ @@ -142,26 +153,30 @@ static void mxs_lcd_init(struct udevice *dev, u32 fb_addr, LCDIF_CTRL_BYPASS_COUNT | LCDIF_CTRL_LCDIF_MASTER, ®s->hw_lcdif_ctrl); - writel(valid_data << LCDIF_CTRL1_BYTE_PACKING_FORMAT_OFFSET, + writel((valid_data << LCDIF_CTRL1_BYTE_PACKING_FORMAT_OFFSET) | + LCDIF_CTRL1_RECOVER_ON_UNDERFLOW, ®s->hw_lcdif_ctrl1); + if (bridge) + writel(LCDIF_CTRL2_OUTSTANDING_REQS_REQ_16, ®s->hw_lcdif_ctrl2); + mxsfb_system_setup(); writel((timings->vactive.typ << LCDIF_TRANSFER_COUNT_V_COUNT_OFFSET) | timings->hactive.typ, ®s->hw_lcdif_transfer_count); - vdctrl0 = LCDIF_VDCTRL0_ENABLE_PRESENT | LCDIF_VDCTRL0_ENABLE_POL | + vdctrl0 = LCDIF_VDCTRL0_ENABLE_PRESENT | LCDIF_VDCTRL0_VSYNC_PERIOD_UNIT | LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT | timings->vsync_len.typ; - if(flags & DISPLAY_FLAGS_HSYNC_HIGH) + if (flags & DISPLAY_FLAGS_HSYNC_HIGH) vdctrl0 |= LCDIF_VDCTRL0_HSYNC_POL; - if(flags & DISPLAY_FLAGS_VSYNC_HIGH) + if (flags & DISPLAY_FLAGS_VSYNC_HIGH) vdctrl0 |= LCDIF_VDCTRL0_VSYNC_POL; - if(flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) + if (flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) vdctrl0 |= LCDIF_VDCTRL0_DOTCLK_POL; - if(flags & DISPLAY_FLAGS_DE_HIGH) + if (flags & DISPLAY_FLAGS_DE_HIGH) vdctrl0 |= LCDIF_VDCTRL0_ENABLE_POL; writel(vdctrl0, ®s->hw_lcdif_vdctrl0); @@ -198,10 +213,10 @@ static void mxs_lcd_init(struct udevice *dev, u32 fb_addr, } static int mxs_probe_common(struct udevice *dev, struct display_timing *timings, - int bpp, u32 fb) + int bpp, u32 fb, bool bridge) { /* Start framebuffer */ - mxs_lcd_init(dev, fb, timings, bpp); + mxs_lcd_init(dev, fb, timings, bpp, bridge); #ifdef CONFIG_VIDEO_MXS_MODE_SYSTEM /* @@ -212,7 +227,8 @@ static int mxs_probe_common(struct udevice *dev, struct display_timing *timings, * sets the RUN bit, then waits until it gets cleared and repeats this * infinitelly. This way, we get smooth continuous updates of the LCD. */ - struct mxs_lcdif_regs *regs = (struct mxs_lcdif_regs *)MXS_LCDIF_BASE; + struct mxsfb_priv *priv = dev_get_priv(dev); + struct mxs_lcdif_regs *regs = (struct mxs_lcdif_regs *)priv->reg_base; memset(&desc, 0, sizeof(struct mxs_dma_desc)); desc.address = (dma_addr_t)&desc; @@ -229,9 +245,9 @@ static int mxs_probe_common(struct udevice *dev, struct display_timing *timings, return 0; } -static int mxs_remove_common(u32 fb) +static int mxs_remove_common(phys_addr_t reg_base, u32 fb) { - struct mxs_lcdif_regs *regs = (struct mxs_lcdif_regs *)MXS_LCDIF_BASE; + struct mxs_lcdif_regs *regs = (struct mxs_lcdif_regs *)(reg_base); int timeout = 1000000; if (!fb) @@ -258,6 +274,7 @@ static int mxs_of_get_timings(struct udevice *dev, int ret = 0; u32 display_phandle; ofnode display_node; + struct mxsfb_priv *priv = dev_get_priv(dev); ret = ofnode_read_u32(dev_ofnode(dev), "display", &display_phandle); if (ret) { @@ -278,10 +295,19 @@ static int mxs_of_get_timings(struct udevice *dev, return -EINVAL; } - ret = ofnode_decode_display_timing(display_node, 0, timings); - if (ret) { - dev_err(dev, "failed to get any display timings\n"); - return -EINVAL; + priv->disp_dev = video_link_get_next_device(dev); + if (priv->disp_dev) { + ret = video_link_get_display_timings(timings); + if (ret) { + dev_err(dev, "failed to get any video link display timings\n"); + return -EINVAL; + } + } else { + ret = ofnode_decode_display_timing(display_node, 0, timings); + if (ret) { + dev_err(dev, "failed to get any display timings\n"); + return -EINVAL; + } } return ret; @@ -291,20 +317,58 @@ static int mxs_video_probe(struct udevice *dev) { struct video_uc_plat *plat = dev_get_uclass_plat(dev); struct video_priv *uc_priv = dev_get_uclass_priv(dev); + struct mxsfb_priv *priv = dev_get_priv(dev); struct display_timing timings; u32 bpp = 0; u32 fb_start, fb_end; int ret; + bool enable_bridge = false; debug("%s() plat: base 0x%lx, size 0x%x\n", __func__, plat->base, plat->size); + priv->reg_base = dev_read_addr(dev); + if (priv->reg_base == FDT_ADDR_T_NONE) { + dev_err(dev, "lcdif base address is not found\n"); + return -EINVAL; + } + ret = mxs_of_get_timings(dev, &timings, &bpp); if (ret) return ret; - ret = mxs_probe_common(dev, &timings, bpp, plat->base); + if (priv->disp_dev) { + if (IS_ENABLED(CONFIG_VIDEO_BRIDGE)) { + if (device_get_uclass_id(priv->disp_dev) == UCLASS_VIDEO_BRIDGE) { + ret = video_bridge_attach(priv->disp_dev); + if (ret) { + dev_err(dev, "fail to attach bridge\n"); + return ret; + } + + ret = video_bridge_set_backlight(priv->disp_dev, 80); + if (ret) { + dev_err(dev, "fail to set backlight\n"); + return ret; + } + + enable_bridge = true; + video_bridge_check_timing(priv->disp_dev, &timings); + } + } + + if (device_get_uclass_id(priv->disp_dev) == UCLASS_PANEL) { + ret = panel_enable_backlight(priv->disp_dev); + if (ret) { + dev_err(dev, "panel %s enable backlight error %d\n", + priv->disp_dev->name, ret); + return ret; + } + } + } + + ret = mxs_probe_common(dev, &timings, bpp, plat->base, enable_bridge); if (ret) return ret; @@ -343,33 +407,9 @@ static int mxs_video_probe(struct udevice *dev) static int mxs_video_bind(struct udevice *dev) { struct video_uc_plat *plat = dev_get_uclass_plat(dev); - struct display_timing timings; - u32 bpp = 0; - u32 bytes_pp = 0; - int ret; - ret = mxs_of_get_timings(dev, &timings, &bpp); - if (ret) - return ret; - - switch (bpp) { - case 32: - case 24: - case 18: - bytes_pp = 4; - break; - case 16: - bytes_pp = 2; - break; - case 8: - bytes_pp = 1; - break; - default: - dev_err(dev, "invalid bpp specified (bpp = %i)\n", bpp); - return -EINVAL; - } - - plat->size = timings.hactive.typ * timings.vactive.typ * bytes_pp; + /* Max size supported by LCDIF, because in bind, we can't probe panel */ + plat->size = 1920 * 1080 * 4 * 2; return 0; } @@ -377,8 +417,12 @@ static int mxs_video_bind(struct udevice *dev) static int mxs_video_remove(struct udevice *dev) { struct video_uc_plat *plat = dev_get_uclass_plat(dev); + struct mxsfb_priv *priv = dev_get_priv(dev); + + if (priv->disp_dev) + device_remove(priv->disp_dev, DM_REMOVE_NORMAL); - mxs_remove_common(plat->base); + mxs_remove_common(priv->reg_base, plat->base); return 0; } @@ -389,6 +433,8 @@ static const struct udevice_id mxs_video_ids[] = { { .compatible = "fsl,imx6sx-lcdif" }, { .compatible = "fsl,imx7ulp-lcdif" }, { .compatible = "fsl,imxrt-lcdif" }, + { .compatible = "fsl,imx8mm-lcdif" }, + { .compatible = "fsl,imx8mn-lcdif" }, { /* sentinel */ } }; @@ -400,4 +446,5 @@ U_BOOT_DRIVER(mxs_video) = { .probe = mxs_video_probe, .remove = mxs_video_remove, .flags = DM_FLAG_PRE_RELOC | DM_FLAG_OS_PREPARE, + .priv_auto = sizeof(struct mxsfb_priv), };