Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/797141/?format=api
{ "id": 797141, "url": "http://patchwork.ozlabs.org/api/1.2/patches/797141/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/1501756568-28641-4-git-send-email-philippe.cornu@st.com/", "project": { "id": 18, "url": "http://patchwork.ozlabs.org/api/1.2/projects/18/?format=api", "name": "U-Boot", "link_name": "uboot", "list_id": "u-boot.lists.denx.de", "list_email": "u-boot@lists.denx.de", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<1501756568-28641-4-git-send-email-philippe.cornu@st.com>", "list_archive_url": null, "date": "2017-08-03T10:36:08", "name": "[U-Boot,v1,3/3] video: add STM32 LTDC display controller", "commit_ref": "72719d2f8ae5022fb45d3020d85a644da8884f2a", "pull_url": null, "state": "accepted", "archived": false, "hash": "898499da658fa2045438c4146c5cb7c0d0652589", "submitter": { "id": 71606, "url": "http://patchwork.ozlabs.org/api/1.2/people/71606/?format=api", "name": "Philippe CORNU", "email": "philippe.cornu@st.com" }, "delegate": { "id": 1700, "url": "http://patchwork.ozlabs.org/api/1.2/users/1700/?format=api", "username": "ag", "first_name": "Anatolij", "last_name": "Gustschin", "email": "agust@denx.de" }, "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/1501756568-28641-4-git-send-email-philippe.cornu@st.com/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/797141/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/797141/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<u-boot-bounces@lists.denx.de>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=lists.denx.de\n\t(client-ip=81.169.180.215; helo=lists.denx.de;\n\tenvelope-from=u-boot-bounces@lists.denx.de;\n\treceiver=<UNKNOWN>)", "Received": [ "from lists.denx.de (dione.denx.de [81.169.180.215])\n\tby ozlabs.org (Postfix) with ESMTP id 3xNRXz0qxnz9s7C\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 3 Aug 2017 20:45:38 +1000 (AEST)", "by lists.denx.de (Postfix, from userid 105)\n\tid C01FBC21D7D; Thu, 3 Aug 2017 10:44:21 +0000 (UTC)", "from lists.denx.de (localhost [IPv6:::1])\n\tby lists.denx.de (Postfix) with ESMTP id 7B773C21DBC;\n\tThu, 3 Aug 2017 10:43:29 +0000 (UTC)", "by lists.denx.de (Postfix, from userid 105)\n\tid 51405C21C2B; Thu, 3 Aug 2017 10:36:36 +0000 (UTC)", "from mx07-00178001.pphosted.com (mx08-00178001.pphosted.com\n\t[91.207.212.93])\n\tby lists.denx.de (Postfix) with ESMTPS id C9A89C21C2B\n\tfor <u-boot@lists.denx.de>; Thu, 3 Aug 2017 10:36:35 +0000 (UTC)", "from pps.filterd (m0046660.ppops.net [127.0.0.1])\n\tby mx08-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id\n\tv73AYs4b014951; Thu, 3 Aug 2017 12:36:33 +0200", "from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35])\n\tby mx08-.pphosted.com with ESMTP id 2c2upm448k-1\n\t(version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT);\n\tThu, 03 Aug 2017 12:36:33 +0200", "from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9])\n\tby beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 091BD31;\n\tThu, 3 Aug 2017 10:36:33 +0000 (GMT)", "from Webmail-eu.st.com (Safex1hubcas24.st.com [10.75.90.94])\n\tby zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 6A67114E5;\n\tThu, 3 Aug 2017 10:36:32 +0000 (GMT)", "from SAFEX1HUBCAS21.st.com (10.75.90.45) by Safex1hubcas24.st.com\n\t(10.75.90.94) with Microsoft SMTP Server (TLS) id 14.3.339.0;\n\tThu, 3 Aug 2017 12:36:32 +0200", "from localhost (10.201.23.32) by Webmail-ga.st.com (10.75.90.48)\n\twith Microsoft SMTP Server (TLS) id 14.3.339.0;\n\tThu, 3 Aug 2017 12:36:31 +0200" ], "X-Spam-Checker-Version": "SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de", "X-Spam-Level": "", "X-Spam-Status": "No, score=-0.7 required=5.0 tests=RCVD_IN_DNSWL_LOW\n\tautolearn=unavailable autolearn_force=no version=3.4.0", "From": "Philippe CORNU <philippe.cornu@st.com>", "To": "Anatolij Gustschin <agust@denx.de>, <u-boot@lists.denx.de>, \"Christophe\n\tKerello\" <christophe.kerello@st.com>, Patrick Delaunay\n\t<patrick.delaunay@st.com>, Vikas Manocha <vikas.manocha@st.com>, \"Patrice\n\tChotard\" <patrice.chotard@st.com>", "Date": "Thu, 3 Aug 2017 12:36:08 +0200", "Message-ID": "<1501756568-28641-4-git-send-email-philippe.cornu@st.com>", "X-Mailer": "git-send-email 1.9.1", "In-Reply-To": "<1501756568-28641-1-git-send-email-philippe.cornu@st.com>", "References": "<1501756568-28641-1-git-send-email-philippe.cornu@st.com>", "MIME-Version": "1.0", "X-Originating-IP": "[10.201.23.32]", "X-Proofpoint-Virus-Version": "vendor=fsecure engine=2.50.10432:, ,\n\tdefinitions=2017-08-03_06:, , signatures=0", "X-Mailman-Approved-At": "Thu, 03 Aug 2017 10:43:25 +0000", "Cc": "Yannick Fertre <yannick.fertre@st.com>,\n\tBenjamin Gaignard <benjamin.gaignard@linaro.org>", "Subject": "[U-Boot] [PATCH v1 3/3] video: add STM32 LTDC display controller", "X-BeenThere": "u-boot@lists.denx.de", "X-Mailman-Version": "2.1.18", "Precedence": "list", "List-Id": "U-Boot discussion <u-boot.lists.denx.de>", "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n\t<mailto:u-boot-request@lists.denx.de?subject=unsubscribe>", "List-Archive": "<http://lists.denx.de/pipermail/u-boot/>", "List-Post": "<mailto:u-boot@lists.denx.de>", "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>", "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n\t<mailto:u-boot-request@lists.denx.de?subject=subscribe>", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "base64", "Errors-To": "u-boot-bounces@lists.denx.de", "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>" }, "content": "The STM32 LTDC display controller provides a parallel digital RGB and\nsignals for horizontal, vertical synchronization, Pixel Clock and Data\nEnable as output to interface directly to a variety of LCD and TFT panels.\n\nThe LTDC main features are:\n- 24-bit RGB Parallel Pixel Output, Programmable timings & polarity for\n HSync, VSync and Data Enable.\n- 2 layers with Blending, Color Keying, Window position & size,\n Dithering, Background color, Color Look-Up Table (CLUT).\n- Supported layer color formats: ARGB8888, RGB888, RGB565, ARGB1555,\n ARGB4444, L8 CLUT, AL44 & AL88\n\nThis LTDC driver:\n- supports: RGB parallel output with timings & polarity, 1 layer\n in RGB565.\n- supports but with hard-coded configurations: blending, window\n position & size (crop), background color.\n- does not support yet: rgb888, argb8888, 8-bit clut, dithering.\n\nThis LTDC driver is compatible with all stm32 platforms with the\nLTDC IP and has been tested on stm32 f746-disco board.\n\nSigned-off-by: Philippe CORNU <philippe.cornu@st.com>\n---\n drivers/video/Kconfig | 2 +\n drivers/video/Makefile | 1 +\n drivers/video/stm32/Kconfig | 44 +++++\n drivers/video/stm32/Makefile | 10 +\n drivers/video/stm32/stm32_ltdc.c | 406 +++++++++++++++++++++++++++++++++++++++\n 5 files changed, 463 insertions(+)\n create mode 100644 drivers/video/stm32/Kconfig\n create mode 100644 drivers/video/stm32/Makefile\n create mode 100644 drivers/video/stm32/stm32_ltdc.c", "diff": "diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig\nindex 32dc8ea..ecaf613 100644\n--- a/drivers/video/Kconfig\n+++ b/drivers/video/Kconfig\n@@ -457,6 +457,8 @@ config VIDEO_SANDBOX_SDL\n \t console device and can display stdout output. Within U-Boot is is\n \t a normal bitmap display and can display images as well as text.\n \n+source \"drivers/video/stm32/Kconfig\"\n+\n config VIDEO_TEGRA20\n \tbool \"Enable LCD support on Tegra20\"\n \tdepends on OF_CONTROL\ndiff --git a/drivers/video/Makefile b/drivers/video/Makefile\nindex d6df709..a1a5309 100644\n--- a/drivers/video/Makefile\n+++ b/drivers/video/Makefile\n@@ -60,6 +60,7 @@ obj-$(CONFIG_VIDEO_DW_HDMI) += dw_hdmi.o\n obj-${CONFIG_VIDEO_TEGRA124} += tegra124/\n obj-${CONFIG_EXYNOS_FB} += exynos/\n obj-${CONFIG_VIDEO_ROCKCHIP} += rockchip/\n+obj-${CONFIG_VIDEO_STM32} += stm32/\n \n obj-y += bridge/\n obj-y += sunxi/\ndiff --git a/drivers/video/stm32/Kconfig b/drivers/video/stm32/Kconfig\nnew file mode 100644\nindex 0000000..113a2bb\n--- /dev/null\n+++ b/drivers/video/stm32/Kconfig\n@@ -0,0 +1,44 @@\n+#\n+# Copyright (C) STMicroelectronics SA 2017\n+#\n+# Authors: Philippe Cornu <philippe.cornu@st.com>\n+# Yannick Fertre <yannick.fertre@st.com>\n+#\n+# SPDX-License-Identifier:\tGPL-2.0+\n+#\n+\n+menuconfig VIDEO_STM32\n+\tbool \"Enable STM32 video support\"\n+\tdepends on DM_VIDEO\n+\thelp\n+\t STM32 supports many video output options including RGB and\n+\t DSI. This option enables these supports which can be used on\n+\t devices which have RGB TFT or DSI display connected.\n+\n+config VIDEO_STM32_MAX_XRES\n+\tint \"Maximum horizontal resolution (for memory allocation purposes)\"\n+\tdepends on VIDEO_STM32\n+\tdefault 640\n+\thelp\n+\t The maximum horizontal resolution to support for the framebuffer.\n+\t This configuration is used for reserving/allocating memory for the\n+\t framebuffer during device-model binding/probing.\n+\n+config VIDEO_STM32_MAX_YRES\n+\tint \"Maximum vertical resolution (for memory allocation purposes)\"\n+\tdepends on VIDEO_STM32\n+\tdefault 480\n+\thelp\n+\t The maximum vertical resolution to support for the framebuffer.\n+\t This configuration is used for reserving/allocating memory for the\n+\t framebuffer during device-model binding/probing.\n+\n+config VIDEO_STM32_MAX_BPP\n+\tint \"Maximum bits per pixel (for memory allocation purposes)\"\n+\tdepends on VIDEO_STM32\n+\tdefault 16\n+\thelp\n+\t The maximum bits per pixel to support for the framebuffer.\n+\t This configuration is used for reserving/allocating memory for the\n+\t framebuffer during device-model binding/probing.\n+\ndiff --git a/drivers/video/stm32/Makefile b/drivers/video/stm32/Makefile\nnew file mode 100644\nindex 0000000..372a2e1\n--- /dev/null\n+++ b/drivers/video/stm32/Makefile\n@@ -0,0 +1,10 @@\n+#\n+# Copyright (C) STMicroelectronics SA 2017\n+#\n+# Authors: Philippe Cornu <philippe.cornu@st.com>\n+# Yannick Fertre <yannick.fertre@st.com>\n+#\n+# SPDX-License-Identifier:\tGPL-2.0+\n+#\n+\n+obj-${CONFIG_VIDEO_STM32} = stm32_ltdc.o\ndiff --git a/drivers/video/stm32/stm32_ltdc.c b/drivers/video/stm32/stm32_ltdc.c\nnew file mode 100644\nindex 0000000..b417ac2\n--- /dev/null\n+++ b/drivers/video/stm32/stm32_ltdc.c\n@@ -0,0 +1,406 @@\n+/*\n+ * Copyright (C) STMicroelectronics SA 2017\n+ *\n+ * Authors: Philippe Cornu <philippe.cornu@st.com>\n+ * Yannick Fertre <yannick.fertre@st.com>\n+ *\n+ * SPDX-License-Identifier: GPL-2.0+\n+ */\n+\n+#include <common.h>\n+#include <clk.h>\n+#include <dm.h>\n+#include <panel.h>\n+#include <video.h>\n+#include <asm/io.h>\n+#include <asm/arch/gpio.h>\n+#include <dm/device-internal.h>\n+\n+DECLARE_GLOBAL_DATA_PTR;\n+\n+struct stm32_ltdc_priv {\n+\tvoid __iomem *regs;\n+\tstruct display_timing timing;\n+\tenum video_log2_bpp l2bpp;\n+\tu32 bg_col_argb;\n+\tu32 crop_x, crop_y, crop_w, crop_h;\n+\tu32 alpha;\n+};\n+\n+/* LTDC main registers */\n+#define LTDC_IDR\t0x00\t/* IDentification */\n+#define LTDC_LCR\t0x04\t/* Layer Count */\n+#define LTDC_SSCR\t0x08\t/* Synchronization Size Configuration */\n+#define LTDC_BPCR\t0x0C\t/* Back Porch Configuration */\n+#define LTDC_AWCR\t0x10\t/* Active Width Configuration */\n+#define LTDC_TWCR\t0x14\t/* Total Width Configuration */\n+#define LTDC_GCR\t0x18\t/* Global Control */\n+#define LTDC_GC1R\t0x1C\t/* Global Configuration 1 */\n+#define LTDC_GC2R\t0x20\t/* Global Configuration 2 */\n+#define LTDC_SRCR\t0x24\t/* Shadow Reload Configuration */\n+#define LTDC_GACR\t0x28\t/* GAmma Correction */\n+#define LTDC_BCCR\t0x2C\t/* Background Color Configuration */\n+#define LTDC_IER\t0x34\t/* Interrupt Enable */\n+#define LTDC_ISR\t0x38\t/* Interrupt Status */\n+#define LTDC_ICR\t0x3C\t/* Interrupt Clear */\n+#define LTDC_LIPCR\t0x40\t/* Line Interrupt Position Conf. */\n+#define LTDC_CPSR\t0x44\t/* Current Position Status */\n+#define LTDC_CDSR\t0x48\t/* Current Display Status */\n+\n+/* LTDC layer 1 registers */\n+#define LTDC_L1LC1R\t0x80\t/* L1 Layer Configuration 1 */\n+#define LTDC_L1LC2R\t0x84\t/* L1 Layer Configuration 2 */\n+#define LTDC_L1CR\t0x84\t/* L1 Control */\n+#define LTDC_L1WHPCR\t0x88\t/* L1 Window Hor Position Config */\n+#define LTDC_L1WVPCR\t0x8C\t/* L1 Window Vert Position Config */\n+#define LTDC_L1CKCR\t0x90\t/* L1 Color Keying Configuration */\n+#define LTDC_L1PFCR\t0x94\t/* L1 Pixel Format Configuration */\n+#define LTDC_L1CACR\t0x98\t/* L1 Constant Alpha Config */\n+#define LTDC_L1DCCR\t0x9C\t/* L1 Default Color Configuration */\n+#define LTDC_L1BFCR\t0xA0\t/* L1 Blend Factors Configuration */\n+#define LTDC_L1FBBCR\t0xA4\t/* L1 FrameBuffer Bus Control */\n+#define LTDC_L1AFBCR\t0xA8\t/* L1 AuxFB Control */\n+#define LTDC_L1CFBAR\t0xAC\t/* L1 Color FrameBuffer Address */\n+#define LTDC_L1CFBLR\t0xB0\t/* L1 Color FrameBuffer Length */\n+#define LTDC_L1CFBLNR\t0xB4\t/* L1 Color FrameBuffer Line Nb */\n+#define LTDC_L1AFBAR\t0xB8\t/* L1 AuxFB Address */\n+#define LTDC_L1AFBLR\t0xBC\t/* L1 AuxFB Length */\n+#define LTDC_L1AFBLNR\t0xC0\t/* L1 AuxFB Line Number */\n+#define LTDC_L1CLUTWR\t0xC4\t/* L1 CLUT Write */\n+\n+/* Bit definitions */\n+#define SSCR_VSH\tGENMASK(10, 0)\t/* Vertical Synchronization Height */\n+#define SSCR_HSW\tGENMASK(27, 16)\t/* Horizontal Synchronization Width */\n+\n+#define BPCR_AVBP\tGENMASK(10, 0)\t/* Accumulated Vertical Back Porch */\n+#define BPCR_AHBP\tGENMASK(27, 16)\t/* Accumulated Horizontal Back Porch */\n+\n+#define AWCR_AAH\tGENMASK(10, 0)\t/* Accumulated Active Height */\n+#define AWCR_AAW\tGENMASK(27, 16)\t/* Accumulated Active Width */\n+\n+#define TWCR_TOTALH\tGENMASK(10, 0)\t/* TOTAL Height */\n+#define TWCR_TOTALW\tGENMASK(27, 16)\t/* TOTAL Width */\n+\n+#define GCR_LTDCEN\tBIT(0)\t\t/* LTDC ENable */\n+#define GCR_DEN\t\tBIT(16)\t\t/* Dither ENable */\n+#define GCR_PCPOL\tBIT(28)\t\t/* Pixel Clock POLarity-Inverted */\n+#define GCR_DEPOL\tBIT(29)\t\t/* Data Enable POLarity-High */\n+#define GCR_VSPOL\tBIT(30)\t\t/* Vertical Synchro POLarity-High */\n+#define GCR_HSPOL\tBIT(31)\t\t/* Horizontal Synchro POLarity-High */\n+\n+#define GC1R_WBCH\tGENMASK(3, 0)\t/* Width of Blue CHannel output */\n+#define GC1R_WGCH\tGENMASK(7, 4)\t/* Width of Green Channel output */\n+#define GC1R_WRCH\tGENMASK(11, 8)\t/* Width of Red Channel output */\n+#define GC1R_PBEN\tBIT(12)\t\t/* Precise Blending ENable */\n+#define GC1R_DT\t\tGENMASK(15, 14)\t/* Dithering Technique */\n+#define GC1R_GCT\tGENMASK(19, 17)\t/* Gamma Correction Technique */\n+#define GC1R_SHREN\tBIT(21)\t\t/* SHadow Registers ENabled */\n+#define GC1R_BCP\tBIT(22)\t\t/* Background Colour Programmable */\n+#define GC1R_BBEN\tBIT(23)\t\t/* Background Blending ENabled */\n+#define GC1R_LNIP\tBIT(24)\t\t/* Line Number IRQ Position */\n+#define GC1R_TP\t\tBIT(25)\t\t/* Timing Programmable */\n+#define GC1R_IPP\tBIT(26)\t\t/* IRQ Polarity Programmable */\n+#define GC1R_SPP\tBIT(27)\t\t/* Sync Polarity Programmable */\n+#define GC1R_DWP\tBIT(28)\t\t/* Dither Width Programmable */\n+#define GC1R_STREN\tBIT(29)\t\t/* STatus Registers ENabled */\n+#define GC1R_BMEN\tBIT(31)\t\t/* Blind Mode ENabled */\n+\n+#define GC2R_EDCA\tBIT(0)\t\t/* External Display Control Ability */\n+#define GC2R_STSAEN\tBIT(1)\t\t/* Slave Timing Sync Ability ENabled */\n+#define GC2R_DVAEN\tBIT(2)\t\t/* Dual-View Ability ENabled */\n+#define GC2R_DPAEN\tBIT(3)\t\t/* Dual-Port Ability ENabled */\n+#define GC2R_BW\t\tGENMASK(6, 4)\t/* Bus Width (log2 of nb of bytes) */\n+#define GC2R_EDCEN\tBIT(7)\t\t/* External Display Control ENabled */\n+\n+#define SRCR_IMR\tBIT(0)\t\t/* IMmediate Reload */\n+#define SRCR_VBR\tBIT(1)\t\t/* Vertical Blanking Reload */\n+\n+#define LXCR_LEN\tBIT(0)\t\t/* Layer ENable */\n+#define LXCR_COLKEN\tBIT(1)\t\t/* Color Keying Enable */\n+#define LXCR_CLUTEN\tBIT(4)\t\t/* Color Look-Up Table ENable */\n+\n+#define LXWHPCR_WHSTPOS\tGENMASK(11, 0)\t/* Window Horizontal StarT POSition */\n+#define LXWHPCR_WHSPPOS\tGENMASK(27, 16)\t/* Window Horizontal StoP POSition */\n+\n+#define LXWVPCR_WVSTPOS\tGENMASK(10, 0)\t/* Window Vertical StarT POSition */\n+#define LXWVPCR_WVSPPOS\tGENMASK(26, 16)\t/* Window Vertical StoP POSition */\n+\n+#define LXPFCR_PF\tGENMASK(2, 0)\t/* Pixel Format */\n+\n+#define LXCACR_CONSTA\tGENMASK(7, 0)\t/* CONSTant Alpha */\n+\n+#define LXBFCR_BF2\tGENMASK(2, 0)\t/* Blending Factor 2 */\n+#define LXBFCR_BF1\tGENMASK(10, 8)\t/* Blending Factor 1 */\n+\n+#define LXCFBLR_CFBLL\tGENMASK(12, 0)\t/* Color Frame Buffer Line Length */\n+#define LXCFBLR_CFBP\tGENMASK(28, 16)\t/* Color Frame Buffer Pitch in bytes */\n+\n+#define LXCFBLNR_CFBLN\tGENMASK(10, 0)\t/* Color Frame Buffer Line Number */\n+\n+#define BF1_PAXCA\t0x600\t\t/* Pixel Alpha x Constant Alpha */\n+#define BF2_1PAXCA\t0x007\t\t/* 1 - (Pixel Alpha x Constant Alpha) */\n+\n+enum stm32_ltdc_pix_fmt {\n+\tPF_ARGB8888 = 0,\n+\tPF_RGB888,\n+\tPF_RGB565,\n+\tPF_ARGB1555,\n+\tPF_ARGB4444,\n+\tPF_L8,\n+\tPF_AL44,\n+\tPF_AL88\n+};\n+\n+/* TODO add more color format support */\n+static u32 stm32_ltdc_get_pixel_format(enum video_log2_bpp l2bpp)\n+{\n+\tenum stm32_ltdc_pix_fmt pf;\n+\n+\tswitch (l2bpp) {\n+\tcase VIDEO_BPP16:\n+\t\tpf = PF_RGB565;\n+\t\tbreak;\n+\n+\tcase VIDEO_BPP1:\n+\tcase VIDEO_BPP2:\n+\tcase VIDEO_BPP4:\n+\tcase VIDEO_BPP8:\n+\tcase VIDEO_BPP32:\n+\tdefault:\n+\t\tdebug(\"%s: warning %dbpp not supported yet, %dbpp instead\\n\",\n+\t\t __func__, VNBITS(l2bpp), VNBITS(VIDEO_BPP16));\n+\t\tpf = PF_RGB565;\n+\t\tbreak;\n+\t}\n+\n+\tdebug(\"%s: %d bpp -> ltdc pf %d\\n\", __func__, VNBITS(l2bpp), pf);\n+\n+\treturn (u32)pf;\n+}\n+\n+static void stm32_ltdc_enable(struct stm32_ltdc_priv *priv)\n+{\n+\t/* Reload configuration immediately & enable LTDC */\n+\tsetbits_le32(priv->regs + LTDC_SRCR, SRCR_IMR);\n+\tsetbits_le32(priv->regs + LTDC_GCR, GCR_LTDCEN);\n+}\n+\n+static void stm32_ltdc_set_mode(struct stm32_ltdc_priv *priv)\n+{\n+\tvoid __iomem *regs = priv->regs;\n+\tstruct display_timing *timing = &priv->timing;\n+\tu32 hsync, vsync, acc_hbp, acc_vbp, acc_act_w, acc_act_h;\n+\tu32 total_w, total_h;\n+\tu32 val;\n+\n+\t/* Convert video timings to ltdc timings */\n+\thsync = timing->hsync_len.typ - 1;\n+\tvsync = timing->vsync_len.typ - 1;\n+\tacc_hbp = hsync + timing->hback_porch.typ;\n+\tacc_vbp = vsync + timing->vback_porch.typ;\n+\tacc_act_w = acc_hbp + timing->hactive.typ;\n+\tacc_act_h = acc_vbp + timing->vactive.typ;\n+\ttotal_w = acc_act_w + timing->hfront_porch.typ;\n+\ttotal_h = acc_act_h + timing->vfront_porch.typ;\n+\n+\t/* Synchronization sizes */\n+\tval = (hsync << 16) | vsync;\n+\tclrsetbits_le32(regs + LTDC_SSCR, SSCR_VSH | SSCR_HSW, val);\n+\n+\t/* Accumulated back porch */\n+\tval = (acc_hbp << 16) | acc_vbp;\n+\tclrsetbits_le32(regs + LTDC_BPCR, BPCR_AVBP | BPCR_AHBP, val);\n+\n+\t/* Accumulated active width */\n+\tval = (acc_act_w << 16) | acc_act_h;\n+\tclrsetbits_le32(regs + LTDC_AWCR, AWCR_AAW | AWCR_AAH, val);\n+\n+\t/* Total width & height */\n+\tval = (total_w << 16) | total_h;\n+\tclrsetbits_le32(regs + LTDC_TWCR, TWCR_TOTALH | TWCR_TOTALW, val);\n+\n+\t/* Signal polarities */\n+\tval = 0;\n+\tdebug(\"%s: timing->flags 0x%08x\\n\", __func__, timing->flags);\n+\tif (timing->flags & DISPLAY_FLAGS_HSYNC_HIGH)\n+\t\tval |= GCR_HSPOL;\n+\tif (timing->flags & DISPLAY_FLAGS_VSYNC_HIGH)\n+\t\tval |= GCR_VSPOL;\n+\tif (timing->flags & DISPLAY_FLAGS_DE_HIGH)\n+\t\tval |= GCR_DEPOL;\n+\tif (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)\n+\t\tval |= GCR_PCPOL;\n+\tclrsetbits_le32(regs + LTDC_GCR,\n+\t\t\tGCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val);\n+\n+\t/* Overall background color */\n+\twritel(priv->bg_col_argb, priv->regs + LTDC_BCCR);\n+}\n+\n+static void stm32_ltdc_set_layer1(struct stm32_ltdc_priv *priv, ulong fb_addr)\n+{\n+\tvoid __iomem *regs = priv->regs;\n+\tu32 x0, x1, y0, y1;\n+\tu32 pitch_in_bytes;\n+\tu32 line_length;\n+\tu32 bus_width;\n+\tu32 val, tmp, bpp;\n+\n+\tx0 = priv->crop_x;\n+\tx1 = priv->crop_x + priv->crop_w - 1;\n+\ty0 = priv->crop_y;\n+\ty1 = priv->crop_y + priv->crop_h - 1;\n+\n+\t/* Horizontal start and stop position */\n+\ttmp = (readl(regs + LTDC_BPCR) & BPCR_AHBP) >> 16;\n+\tval = ((x1 + 1 + tmp) << 16) + (x0 + 1 + tmp);\n+\tclrsetbits_le32(regs + LTDC_L1WHPCR, LXWHPCR_WHSTPOS | LXWHPCR_WHSPPOS,\n+\t\t\tval);\n+\n+\t/* Vertical start & stop position */\n+\ttmp = readl(regs + LTDC_BPCR) & BPCR_AVBP;\n+\tval = ((y1 + 1 + tmp) << 16) + (y0 + 1 + tmp);\n+\tclrsetbits_le32(regs + LTDC_L1WVPCR, LXWVPCR_WVSTPOS | LXWVPCR_WVSPPOS,\n+\t\t\tval);\n+\n+\t/* Layer background color */\n+\twritel(priv->bg_col_argb, regs + LTDC_L1DCCR);\n+\n+\t/* Color frame buffer pitch in bytes & line length */\n+\tbpp = VNBITS(priv->l2bpp);\n+\tpitch_in_bytes = priv->crop_w * (bpp >> 3);\n+\tbus_width = 8 << ((readl(regs + LTDC_GC2R) & GC2R_BW) >> 4);\n+\tline_length = ((bpp >> 3) * priv->crop_w) + (bus_width >> 3) - 1;\n+\tval = (pitch_in_bytes << 16) | line_length;\n+\tclrsetbits_le32(regs + LTDC_L1CFBLR, LXCFBLR_CFBLL | LXCFBLR_CFBP, val);\n+\n+\t/* Pixel format */\n+\tval = stm32_ltdc_get_pixel_format(priv->l2bpp);\n+\tclrsetbits_le32(regs + LTDC_L1PFCR, LXPFCR_PF, val);\n+\n+\t/* Constant alpha value */\n+\tclrsetbits_le32(regs + LTDC_L1CACR, LXCACR_CONSTA, priv->alpha);\n+\n+\t/* Blending factors */\n+\tclrsetbits_le32(regs + LTDC_L1BFCR, LXBFCR_BF2 | LXBFCR_BF1,\n+\t\t\tBF1_PAXCA | BF2_1PAXCA);\n+\n+\t/* Frame buffer line number */\n+\tclrsetbits_le32(regs + LTDC_L1CFBLNR, LXCFBLNR_CFBLN, priv->crop_h);\n+\n+\t/* Frame buffer address */\n+\twritel(fb_addr, regs + LTDC_L1CFBAR);\n+\n+\t/* Enable layer 1 */\n+\tsetbits_le32(priv->regs + LTDC_L1CR, LXCR_LEN);\n+}\n+\n+static int stm32_ltdc_probe(struct udevice *dev)\n+{\n+\tstruct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);\n+\tstruct video_priv *uc_priv = dev_get_uclass_priv(dev);\n+\tstruct stm32_ltdc_priv *priv = dev_get_priv(dev);\n+\tstruct udevice *panel;\n+\tstruct clk pclk, pxclk;\n+\tint ret;\n+\n+\tpriv->regs = (void *)dev_read_addr(dev);\n+\tif ((fdt_addr_t)priv->regs == FDT_ADDR_T_NONE) {\n+\t\tdebug(\"%s: ltdc dt register address error\\n\", __func__);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tret = uclass_first_device(UCLASS_PANEL, &panel);\n+\tif (ret) {\n+\t\tdebug(\"%s: panel device error %d\\n\", __func__, ret);\n+\t\treturn ret;\n+\t}\n+\n+\tret = panel_enable_backlight(panel);\n+\tif (ret) {\n+\t\tdebug(\"%s: panel %s enable backlight error %d\\n\",\n+\t\t __func__, panel->name, ret);\n+\t\treturn ret;\n+\t}\n+\n+\tret = fdtdec_decode_display_timing(gd->fdt_blob, dev_of_offset(dev),\n+\t\t\t\t\t 0, &priv->timing);\n+\tif (ret) {\n+\t\tdebug(\"%s: decode display timing error %d\\n\", __func__, ret);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tret = clk_get_by_name(dev, \"pclk\", &pclk);\n+\tif (ret) {\n+\t\tdebug(\"%s: peripheral clock get error %d\\n\", __func__, ret);\n+\t\treturn ret;\n+\t}\n+\n+\tret = clk_enable(&pclk);\n+\tif (ret) {\n+\t\tdebug(\"%s: peripheral clock enable error %d\\n\", __func__, ret);\n+\t\treturn ret;\n+\t}\n+\n+\t/* Verify pixel clock value if any & inform user accordingly */\n+\tret = clk_get_by_name(dev, \"pxclk\", &pxclk);\n+\tif (!ret) {\n+\t\tif (clk_get_rate(&pxclk) != priv->timing.pixelclock.typ)\n+\t\t\tprintf(\"Warning: please adjust ltdc pixel clock\\n\");\n+\t}\n+\n+\t/* TODO Below parameters are hard-coded for the moment... */\n+\tpriv->l2bpp = VIDEO_BPP16;\n+\tpriv->bg_col_argb = 0xFFFFFFFF; /* white no transparency */\n+\tpriv->crop_x = 0;\n+\tpriv->crop_y = 0;\n+\tpriv->crop_w = priv->timing.hactive.typ;\n+\tpriv->crop_h = priv->timing.vactive.typ;\n+\tpriv->alpha = 0xFF;\n+\n+\tdebug(\"%s: %dx%d %dbpp frame buffer at 0x%lx\\n\", __func__,\n+\t priv->timing.hactive.typ, priv->timing.vactive.typ,\n+\t VNBITS(priv->l2bpp), uc_plat->base);\n+\tdebug(\"%s: crop %d,%d %dx%d bg 0x%08x alpha %d\\n\", __func__,\n+\t priv->crop_x, priv->crop_y, priv->crop_w, priv->crop_h,\n+\t priv->bg_col_argb, priv->alpha);\n+\n+\t/* Configure & start LTDC */\n+\tstm32_ltdc_set_mode(priv);\n+\tstm32_ltdc_set_layer1(priv, uc_plat->base);\n+\tstm32_ltdc_enable(priv);\n+\n+\tuc_priv->xsize = priv->timing.hactive.typ;\n+\tuc_priv->ysize = priv->timing.vactive.typ;\n+\tuc_priv->bpix = priv->l2bpp;\n+\n+\tvideo_set_flush_dcache(dev, true);\n+\n+\treturn 0;\n+}\n+\n+static int stm32_ltdc_bind(struct udevice *dev)\n+{\n+\tstruct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);\n+\n+\tuc_plat->size = CONFIG_VIDEO_STM32_MAX_XRES *\n+\t\t\tCONFIG_VIDEO_STM32_MAX_YRES *\n+\t\t\t(CONFIG_VIDEO_STM32_MAX_BPP >> 3);\n+\tdebug(\"%s: frame buffer max size %d bytes\\n\", __func__, uc_plat->size);\n+\n+\treturn 0;\n+}\n+\n+static const struct udevice_id stm32_ltdc_ids[] = {\n+\t{ .compatible = \"st,stm32-ltdc\" },\n+\t{ }\n+};\n+\n+U_BOOT_DRIVER(stm32_ltdc) = {\n+\t.name\t= \"stm32_ltdc\",\n+\t.id\t= UCLASS_VIDEO,\n+\t.of_match = stm32_ltdc_ids,\n+\t.probe\t= stm32_ltdc_probe,\n+\t.bind\t= stm32_ltdc_bind,\n+\t.priv_auto_alloc_size\t= sizeof(struct stm32_ltdc_priv),\n+};\n", "prefixes": [ "U-Boot", "v1", "3/3" ] }