{"id":2222508,"url":"http://patchwork.ozlabs.org/api/1.2/patches/2222508/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/patch/20260412075822.29858-1-ssrane_b23@ee.vjti.ac.in/","project":{"id":18,"url":"http://patchwork.ozlabs.org/api/1.2/projects/18/?format=json","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":"<20260412075822.29858-1-ssrane_b23@ee.vjti.ac.in>","list_archive_url":null,"date":"2026-04-12T07:58:22","name":"video: bridge: add ITE IT66121 DPI-to-HDMI bridge driver","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"94edc96eddbfecbc52dda4777a6131ab10f3ae63","submitter":{"id":92105,"url":"http://patchwork.ozlabs.org/api/1.2/people/92105/?format=json","name":"Shaurya Rane","email":"ssrane_b23@ee.vjti.ac.in"},"delegate":{"id":1700,"url":"http://patchwork.ozlabs.org/api/1.2/users/1700/?format=json","username":"ag","first_name":"Anatolij","last_name":"Gustschin","email":"agust@denx.de"},"mbox":"http://patchwork.ozlabs.org/project/uboot/patch/20260412075822.29858-1-ssrane_b23@ee.vjti.ac.in/mbox/","series":[{"id":499604,"url":"http://patchwork.ozlabs.org/api/1.2/series/499604/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/list/?series=499604","date":"2026-04-12T07:58:22","name":"video: bridge: add ITE IT66121 DPI-to-HDMI bridge driver","version":1,"mbox":"http://patchwork.ozlabs.org/series/499604/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2222508/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2222508/checks/","tags":{},"related":[],"headers":{"Return-Path":"<u-boot-bounces@lists.denx.de>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=vjti.ac.in header.i=@vjti.ac.in header.a=rsa-sha256\n header.s=google header.b=SaoCGtjY;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=85.214.62.61; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)","phobos.denx.de;\n dmarc=none (p=none dis=none) header.from=ee.vjti.ac.in","phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de","phobos.denx.de;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=vjti.ac.in header.i=@vjti.ac.in header.b=\"SaoCGtjY\";\n\tdkim-atps=neutral","phobos.denx.de;\n dmarc=none (p=none dis=none) header.from=ee.vjti.ac.in","phobos.denx.de;\n spf=none smtp.mailfrom=ssrane_b23@ee.vjti.ac.in"],"Received":["from phobos.denx.de (phobos.denx.de [85.214.62.61])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4ftrKS0TSbz1y2d\n\tfor <incoming@patchwork.ozlabs.org>; Sun, 12 Apr 2026 23:02:04 +1000 (AEST)","from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id 53196841CD;\n\tSun, 12 Apr 2026 15:00:32 +0200 (CEST)","by phobos.denx.de (Postfix, from userid 109)\n id 85F4B83B99; Sun, 12 Apr 2026 09:58:37 +0200 (CEST)","from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com\n [IPv6:2607:f8b0:4864:20::102e])\n (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id ACF618341A\n for <u-boot@lists.denx.de>; Sun, 12 Apr 2026 09:58:34 +0200 (CEST)","by mail-pj1-x102e.google.com with SMTP id\n 98e67ed59e1d1-3591cc98871so1669115a91.3\n for <u-boot@lists.denx.de>; Sun, 12 Apr 2026 00:58:34 -0700 (PDT)","from ranegod-HP-ENVY-x360-Convertible-13-bd0xxx.www.tendawifi.com\n ([14.139.108.62]) by smtp.gmail.com with ESMTPSA id\n 98e67ed59e1d1-35e41bc6541sm2986438a91.0.2026.04.12.00.58.29\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Sun, 12 Apr 2026 00:58:30 -0700 (PDT)"],"X-Spam-Checker-Version":"SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de","X-Spam-Level":"","X-Spam-Status":"No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_NONE\n autolearn=ham autolearn_force=no version=3.4.2","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=vjti.ac.in; s=google; t=1775980713; x=1776585513; darn=lists.denx.de;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:from:to:cc:subject:date:message-id:reply-to;\n bh=0zmzh+p+i1uf3NCJK8YNpCw+27Psm4ZyhOVuEEH7kbM=;\n b=SaoCGtjY2/5xUv8/XUM7FTVcIyIrzW9pHpV0S/kINBYdvB32YZij6lMVTH4WkUg0Wt\n 7KAoTwPp5GKpg6c9lfiOCsVKJ1jR1p7GsygLgLeGn9YHkjbX8kvEzrEonaja8ZYFElnr\n 7Cbv3/83sJn8N9RIOiZzrFmHcHxqSOwEnXED4=","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1775980713; x=1776585513;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=0zmzh+p+i1uf3NCJK8YNpCw+27Psm4ZyhOVuEEH7kbM=;\n b=prQoO5pylPPGDvXy5VMR3+1GP4vMWqPIoAMOuFgJvTCPH0S4leJYDoEbiIaT5is8VI\n Y5uhW+Qmih8YiMVGRYgfUK1b1fL32qL/FVzCbAhm4c0xBd4PsWaYotKpWuAmRzWEz6vT\n KfPoyUnnz4Xp3NMZY58yl3bzPtrDYzt8my/J51SE7Q5+59tnOpwvo2QvDkAtknUm2WeU\n gdBtjHn60jqYwk6fJDghkim1IMS38RKp1D7bKtZy6eJA2qfKmF9zoDnDuaA4UkNsabmV\n uDiYOCdOh7X+3cboITGrIespieRaCuJZxfYyfvVbQTQ6yG5AhuwGXi+qW04TmhMOKu1g\n yjbA==","X-Gm-Message-State":"AOJu0YwPeNz68YP5oBwatTH+/gCl7XMX8NVPyOsCXgnkL2gN+LB1L2OB\n 3yVVe7rXTQX53908ugUs+J0a2TIdSgRka+XPQrQEiluPlL5dVXcWHrahaEd2CoI0icsxzSm9ox5\n kSgCK//c=","X-Gm-Gg":"AeBDieu+YjBfl8tef/9FAOtEl9naP3/JkqdNPwAbM6HuNTKk9SEwbh8JO8CElOH9VW/\n QwIIHKx2zQ80tbzmqHrUQci/9ozczwHVjp3sbRAdC00tlsYYBOTsl2eOJsrlKCbwarc4qmESIA7\n SpHBoLqFBDzf9JMNh4JfTMnyWgq+Sbz3j2jxMbAWQUIfBj2Bc/XVvpARrtWjwg276XhxiepBkMM\n hbS0jOR25Ki5ASd+zckU12+T8jbZa+37r2zQwAx5FJQB0XVIHGIZU8Qjm7MqblARsYE7GIIvjJe\n fF3SNW4wQ+Zx3EdA0tHQ7bTE0g/pwmaiN3HI2V4xIA7y7NwabYy7VsSLtzbAnF59wXoRUrp6UWQ\n D6QviU0/X4J6x+ThZPYTiDJD3Q672OHebBygyOOzDA/mgD2ISTb8T6NO1K9OdEpuF0e+76Ro9qn\n t93UFrNhyJdibxyEe7rsoE6jboiiXAk8TWilz9+DERos2I37a1oGlnf3mGABUz6KUttzFeCyo/E\n oV7f20CqNT6Syk8r//7nx5QvmD2RSRx","X-Received":"by 2002:a17:90a:bc1:b0:35e:58d4:3906 with SMTP id\n 98e67ed59e1d1-35e58d439e2mr1556287a91.23.1775980712425;\n Sun, 12 Apr 2026 00:58:32 -0700 (PDT)","From":"Shaurya Rane <ssrane_b23@ee.vjti.ac.in>","To":"u-boot@lists.denx.de","Cc":"agust@denx.de, trini@konsulko.com, Shaurya Rane <ssrane_b23@ee.vjti.ac.in>","Subject":"[PATCH] video: bridge: add ITE IT66121 DPI-to-HDMI bridge driver","Date":"Sun, 12 Apr 2026 13:28:22 +0530","Message-Id":"<20260412075822.29858-1-ssrane_b23@ee.vjti.ac.in>","X-Mailer":"git-send-email 2.34.1","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","X-Mailman-Approved-At":"Sun, 12 Apr 2026 15:00:19 +0200","X-BeenThere":"u-boot@lists.denx.de","X-Mailman-Version":"2.1.39","Precedence":"list","List-Id":"U-Boot discussion <u-boot.lists.denx.de>","List-Unsubscribe":"<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>","List-Archive":"<https://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 <mailto:u-boot-request@lists.denx.de?subject=subscribe>","Errors-To":"u-boot-bounces@lists.denx.de","Sender":"\"U-Boot\" <u-boot-bounces@lists.denx.de>","X-Virus-Scanned":"clamav-milter 0.103.8 at phobos.denx.de","X-Virus-Status":"Clean"},"content":"Add support for the ITE IT66121 DPI-to-HDMI bridge chip. The IT66121\nconverts parallel RGB/DPI video input to HDMI output. It is found on\nboards like the BeaglePlay where the TI AM625 SoC's DPI output is\nrouted to an HDMI connector through this chip.\n\nThe driver is based on the IT66121 Programmer Guide and the Linux\nkernel driver drivers/gpu/drm/bridge/ite-it66121.c.\n\nTested on BeaglePlay hardware with HDMI output via TI TIDSS.\n\nSigned-off-by: Shaurya Rane <ssrane_b23@ee.vjti.ac.in>\n---\n drivers/video/bridge/Kconfig   |  10 +\n drivers/video/bridge/Makefile  |   1 +\n drivers/video/bridge/it66121.c | 535 +++++++++++++++++++++++++++++++++\n 3 files changed, 546 insertions(+)\n create mode 100644 drivers/video/bridge/it66121.c","diff":"diff --git a/drivers/video/bridge/Kconfig b/drivers/video/bridge/Kconfig\nindex 5322a002928..175e836e2f3 100644\n--- a/drivers/video/bridge/Kconfig\n+++ b/drivers/video/bridge/Kconfig\n@@ -44,6 +44,16 @@ config VIDEO_BRIDGE_ANALOGIX_ANX6345\n \t The Analogix ANX6345 is RGB-to-DP converter. It enables an eDP LCD\n \t panel to be connected to an parallel LCD interface.\n \n+config VIDEO_BRIDGE_ITE_IT66121\n+\tbool \"Support ITE IT66121 DPI->HDMI bridge\"\n+\tdepends on VIDEO_BRIDGE\n+\tselect DM_I2C\n+\thelp\n+\t The ITE IT66121 is a DPI-to-HDMI bridge chip. It converts a parallel\n+\t RGB/DPI video input to an HDMI output. This is used on boards like\n+\t the BeaglePlay where the SoC's DPI output is connected to an HDMI\n+\t connector via this bridge chip.\n+\n config VIDEO_BRIDGE_SOLOMON_SSD2825\n \tbool \"Solomon SSD2825 bridge driver\"\n \tdepends on VIDEO_BRIDGE && PANEL && DM_GPIO\ndiff --git a/drivers/video/bridge/Makefile b/drivers/video/bridge/Makefile\nindex 520f36a7a6f..bd048b7333e 100644\n--- a/drivers/video/bridge/Makefile\n+++ b/drivers/video/bridge/Makefile\n@@ -8,6 +8,7 @@ obj-$(CONFIG_VIDEO_BRIDGE_PARADE_DP501) += dp501.o\n obj-$(CONFIG_VIDEO_BRIDGE_PARADE_PS862X) += ps862x.o\n obj-$(CONFIG_VIDEO_BRIDGE_NXP_PTN3460) += ptn3460.o\n obj-$(CONFIG_VIDEO_BRIDGE_ANALOGIX_ANX6345) += anx6345.o\n+obj-$(CONFIG_VIDEO_BRIDGE_ITE_IT66121) += it66121.o\n obj-$(CONFIG_VIDEO_BRIDGE_SOLOMON_SSD2825) += ssd2825.o\n obj-$(CONFIG_VIDEO_BRIDGE_TOSHIBA_TC358768) += tc358768.o\n obj-$(CONFIG_VIDEO_BRIDGE_LVDS_CODEC) += lvds-codec.o\ndiff --git a/drivers/video/bridge/it66121.c b/drivers/video/bridge/it66121.c\nnew file mode 100644\nindex 00000000000..11c46768341\n--- /dev/null\n+++ b/drivers/video/bridge/it66121.c\n@@ -0,0 +1,535 @@\n+// SPDX-License-Identifier: GPL-2.0+\n+/*\n+ * Copyright (C) 2025 Shaurya Rane <ssrane_b23@ee.vjti.ac.in>\n+ */\n+\n+#include <dm.h>\n+#include <i2c.h>\n+#include <edid.h>\n+#include <log.h>\n+#include <video_bridge.h>\n+#include <linux/delay.h>\n+\n+#define IT66121_VENDOR_ID0\t\t0x00\n+#define IT66121_VENDOR_ID1\t\t0x01\n+#define IT66121_DEVICE_ID0\t\t0x02\n+#define IT66121_DEVICE_ID1\t\t0x03\n+\n+#define IT66121_VENDOR_ID0_VAL\t\t0x54\n+#define IT66121_VENDOR_ID1_VAL\t\t0x49\n+#define IT66121_DEVICE_ID0_VAL\t\t0x12\n+#define IT66121_DEVICE_ID1_MASK\t\t0x0F\n+#define IT66121_DEVICE_ID1_VAL\t\t0x06\n+\n+#define IT66121_SW_RST\t\t\t0x04\n+#define IT66121_SW_RST_REF\t\tBIT(5)\n+#define IT66121_SW_RST_AREF\t\tBIT(4)\n+#define IT66121_SW_RST_VID\t\tBIT(3)\n+#define IT66121_SW_RST_AUD\t\tBIT(2)\n+#define IT66121_SW_RST_HDCP\t\tBIT(0)\n+\n+#define IT66121_CLK_BANK_REG\t\t0x0F\n+#define IT66121_CLK_BANK_PWROFF_RCLK\tBIT(6)\n+#define IT66121_CLK_BANK_PWROFF_TXCLK\tBIT(4)\n+#define IT66121_CLK_BANK_SEL\t\t0x03\n+\n+#define IT66121_SYS_STATUS\t\t0x0E\n+#define IT66121_SYS_STATUS_HPD\t\tBIT(6)\n+\n+#define IT66121_INT_MASK1\t\t0x09\n+#define IT66121_INT_MASK2\t\t0x0A\n+#define IT66121_INT_MASK3\t\t0x0B\n+\n+#define IT66121_PCLK_CNT_REG\t\t0x05\n+\n+#define IT66121_DDC_MASTER_SEL\t\t0x10\n+#define IT66121_DDC_HEADER\t\t0x11\n+#define IT66121_DDC_REQOFF\t\t0x12\n+#define IT66121_DDC_REQCOUNT\t\t0x13\n+#define IT66121_DDC_EDIDSEG\t\t0x14\n+#define IT66121_DDC_CMD\t\t\t0x15\n+#define IT66121_DDC_STATUS\t\t0x16\n+#define IT66121_DDC_READFIFO\t\t0x17\n+\n+#define IT66121_DDC_STATUS_DONE\t\tBIT(7)\n+#define IT66121_DDC_STATUS_ERROR_MASK\t(BIT(5) | BIT(4) | BIT(3))\n+\n+#define IT66121_DDC_CMD_EDID_RD\t\t0x03\n+#define IT66121_DDC_CMD_FIFO_CLR\t0x09\n+#define IT66121_DDC_CMD_ABORT\t\t0x0F\n+\n+#define IT66121_INPUT_MODE\t\t0x70\n+#define IT66121_INPUT_MODE_RGB\t\t0x00\n+\n+#define IT66121_INPUT_CSC\t\t0x72\n+#define IT66121_INPUT_CSC_NO_CONV\t0x00\n+\n+#define IT66121_AFE_DRV_REG\t\t0x61\n+#define IT66121_AFE_DRV_RST\t\tBIT(4)\n+#define IT66121_AFE_XP_REG\t\t0x62\n+#define IT66121_AFE_IP_REG\t\t0x64\n+#define IT66121_AFE_XP_EC1\t\t0x68\n+\n+#define IT66121_HDMI_MODE\t\t0xC0\n+#define IT66121_HDMI_MODE_HDMI\t\tBIT(0)\n+\n+#define IT66121_AV_MUTE\t\t0xC1\n+#define IT66121_AV_MUTE_ON\t\tBIT(0)\n+\n+#define IT66121_PKT_GEN_CTRL\t\t0xC6\n+#define IT66121_PKT_GEN_CTRL_RPT\tBIT(1)\n+#define IT66121_PKT_GEN_CTRL_EN\t\tBIT(0)\n+\n+#define IT66121_DDC_FIFO_SIZE\t\t32\n+#define IT66121_EDID_SLAVE_ADDR\t\t0xA0\n+#define IT66121_EDID_BUF_SIZE\t\tEDID_EXT_SIZE\n+\n+struct it66121_priv {\n+\tu8 edid[IT66121_EDID_BUF_SIZE];\n+\tint edid_len;\n+};\n+\n+static int it66121_reg_read(struct udevice *dev, u8 reg, u8 *val)\n+{\n+\treturn dm_i2c_read(dev, reg, val, 1);\n+}\n+\n+static int it66121_reg_write(struct udevice *dev, u8 reg, u8 val)\n+{\n+\treturn dm_i2c_write(dev, reg, &val, 1);\n+}\n+\n+static int it66121_reg_set(struct udevice *dev, u8 reg, u8 mask, u8 val)\n+{\n+\tu8 orig;\n+\tint ret;\n+\n+\tret = it66121_reg_read(dev, reg, &orig);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\torig = (orig & ~mask) | (val & mask);\n+\n+\treturn it66121_reg_write(dev, reg, orig);\n+}\n+\n+static int it66121_identify(struct udevice *dev)\n+{\n+\tu8 v0, v1, d0, d1;\n+\tint ret;\n+\n+\tret = it66121_reg_read(dev, IT66121_VENDOR_ID0, &v0);\n+\tif (ret)\n+\t\treturn ret;\n+\tret = it66121_reg_read(dev, IT66121_VENDOR_ID1, &v1);\n+\tif (ret)\n+\t\treturn ret;\n+\tret = it66121_reg_read(dev, IT66121_DEVICE_ID0, &d0);\n+\tif (ret)\n+\t\treturn ret;\n+\tret = it66121_reg_read(dev, IT66121_DEVICE_ID1, &d1);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (v0 != IT66121_VENDOR_ID0_VAL || v1 != IT66121_VENDOR_ID1_VAL ||\n+\t    d0 != IT66121_DEVICE_ID0_VAL ||\n+\t    (d1 & IT66121_DEVICE_ID1_MASK) != IT66121_DEVICE_ID1_VAL) {\n+\t\tdebug(\"IT66121: chip not found (vendor=%02x%02x dev=%02x%02x)\\n\",\n+\t\t      v1, v0, d1, d0);\n+\t\treturn -ENODEV;\n+\t}\n+\n+\tdebug(\"IT66121: found chip (vendor=%02x%02x dev=%02x%02x)\\n\",\n+\t      v1, v0, d1, d0);\n+\treturn 0;\n+}\n+\n+static int it66121_hw_init(struct udevice *dev)\n+{\n+\tint ret;\n+\n+\tret = it66121_reg_set(dev, IT66121_CLK_BANK_REG,\n+\t\t\t      IT66121_CLK_BANK_PWROFF_RCLK, 0);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_set(dev, IT66121_CLK_BANK_REG,\n+\t\t\t      IT66121_CLK_BANK_SEL, 0);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_set(dev, IT66121_PCLK_CNT_REG, BIT(0), 0);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_set(dev, IT66121_AFE_DRV_REG, BIT(5), 0);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_set(dev, IT66121_AFE_XP_REG, BIT(6) | BIT(2), 0);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_set(dev, IT66121_AFE_IP_REG, BIT(6), 0);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_set(dev, IT66121_AFE_DRV_REG, BIT(4), 0);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_set(dev, IT66121_AFE_XP_REG, BIT(3), BIT(3));\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_set(dev, IT66121_AFE_IP_REG, BIT(2), BIT(2));\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* Keep AREF/VID/AUD/HDCP in reset, leave REF clock running. */\n+\tret = it66121_reg_write(dev, IT66121_SW_RST,\n+\t\t\t\tIT66121_SW_RST_AREF | IT66121_SW_RST_VID |\n+\t\t\t\tIT66121_SW_RST_AUD | IT66121_SW_RST_HDCP);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tmdelay(5);\n+\n+\tret = it66121_reg_write(dev, IT66121_HDMI_MODE, 0x00);\n+\tif (ret)\n+\t\treturn ret;\n+\tret = it66121_reg_write(dev, IT66121_AV_MUTE, 0x00);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_write(dev, IT66121_INT_MASK1, 0xFF);\n+\tif (ret)\n+\t\treturn ret;\n+\tret = it66121_reg_write(dev, IT66121_INT_MASK2, 0xFF);\n+\tif (ret)\n+\t\treturn ret;\n+\tret = it66121_reg_write(dev, IT66121_INT_MASK3, 0xFF);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+\n+static int it66121_ddc_wait(struct udevice *dev)\n+{\n+\tu8 status;\n+\tint i, ret;\n+\n+\tfor (i = 0; i < 200; i++) {\n+\t\tret = it66121_reg_read(dev, IT66121_DDC_STATUS, &status);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tif (status & IT66121_DDC_STATUS_DONE)\n+\t\t\treturn 0;\n+\n+\t\tif (status & IT66121_DDC_STATUS_ERROR_MASK) {\n+\t\t\tdebug(\"IT66121: DDC error status=0x%02x\\n\", status);\n+\t\t\treturn -EIO;\n+\t\t}\n+\n+\t\tmdelay(2);\n+\t}\n+\n+\tdebug(\"IT66121: DDC timeout\\n\");\n+\treturn -ETIMEDOUT;\n+}\n+\n+static int it66121_ddc_fifo_clear(struct udevice *dev)\n+{\n+\tint ret;\n+\n+\tret = it66121_reg_write(dev, IT66121_DDC_CMD,\n+\t\t\t\tIT66121_DDC_CMD_FIFO_CLR);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn it66121_ddc_wait(dev);\n+}\n+\n+static int it66121_read_edid_block(struct udevice *dev, u8 *buf,\n+\t\t\t\t   int offset, int segment, int len)\n+{\n+\tint ret, i, bytes_read = 0;\n+\n+\twhile (bytes_read < len) {\n+\t\tint chunk = len - bytes_read;\n+\n+\t\tif (chunk > IT66121_DDC_FIFO_SIZE)\n+\t\t\tchunk = IT66121_DDC_FIFO_SIZE;\n+\n+\t\tret = it66121_reg_write(dev, IT66121_DDC_MASTER_SEL, 0x01);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tret = it66121_ddc_fifo_clear(dev);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tret = it66121_reg_write(dev, IT66121_DDC_HEADER,\n+\t\t\t\t\tIT66121_EDID_SLAVE_ADDR);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tret = it66121_reg_write(dev, IT66121_DDC_REQOFF,\n+\t\t\t\t\t(offset + bytes_read) & 0xFF);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tret = it66121_reg_write(dev, IT66121_DDC_REQCOUNT, chunk);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tret = it66121_reg_write(dev, IT66121_DDC_EDIDSEG, segment);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tret = it66121_reg_write(dev, IT66121_DDC_CMD,\n+\t\t\t\t\tIT66121_DDC_CMD_EDID_RD);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tret = it66121_ddc_wait(dev);\n+\t\tif (ret) {\n+\t\t\tdebug(\"IT66121: EDID read failed at offset %d\\n\",\n+\t\t\t      offset + bytes_read);\n+\t\t\tit66121_reg_write(dev, IT66121_DDC_CMD,\n+\t\t\t\t\t  IT66121_DDC_CMD_ABORT);\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tfor (i = 0; i < chunk; i++) {\n+\t\t\tret = it66121_reg_read(dev, IT66121_DDC_READFIFO,\n+\t\t\t\t\t       &buf[bytes_read + i]);\n+\t\t\tif (ret)\n+\t\t\t\treturn ret;\n+\t\t}\n+\n+\t\tbytes_read += chunk;\n+\t}\n+\n+\treturn bytes_read;\n+}\n+\n+static int it66121_setup_afe(struct udevice *dev, unsigned long pclk_khz)\n+{\n+\tint ret;\n+\n+\tret = it66121_reg_write(dev, IT66121_AFE_DRV_REG, IT66121_AFE_DRV_RST);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (pclk_khz > 80000) {\n+\t\tret = it66121_reg_set(dev, IT66121_AFE_XP_REG, 0x90, 0x80);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t\tret = it66121_reg_set(dev, IT66121_AFE_IP_REG, 0x89, 0x80);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t\tret = it66121_reg_set(dev, IT66121_AFE_XP_EC1, 0x10, 0x00);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t} else {\n+\t\tret = it66121_reg_set(dev, IT66121_AFE_XP_REG, 0x90, 0x10);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t\tret = it66121_reg_set(dev, IT66121_AFE_IP_REG, 0x89, 0x09);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t\tret = it66121_reg_set(dev, IT66121_AFE_XP_EC1, 0x10, 0x10);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\tret = it66121_reg_set(dev, IT66121_SW_RST,\n+\t\t\t      IT66121_SW_RST_REF | IT66121_SW_RST_VID, 0);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_write(dev, IT66121_AFE_DRV_REG, 0x00);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+\n+/* Basic HDMI RGB output; AVI InfoFrame programming is not implemented. */\n+static int it66121_setup_video(struct udevice *dev, unsigned long pclk_khz)\n+{\n+\tint ret;\n+\n+\tret = it66121_reg_set(dev, IT66121_AV_MUTE,\n+\t\t\t      IT66121_AV_MUTE_ON, IT66121_AV_MUTE_ON);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_write(dev, IT66121_HDMI_MODE,\n+\t\t\t\tIT66121_HDMI_MODE_HDMI);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_set(dev, IT66121_CLK_BANK_REG,\n+\t\t\t      IT66121_CLK_BANK_PWROFF_TXCLK,\n+\t\t\t      IT66121_CLK_BANK_PWROFF_TXCLK);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_write(dev, IT66121_INPUT_MODE,\n+\t\t\t\tIT66121_INPUT_MODE_RGB);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_write(dev, IT66121_INPUT_CSC,\n+\t\t\t\tIT66121_INPUT_CSC_NO_CONV);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_setup_afe(dev, pclk_khz);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_set(dev, IT66121_CLK_BANK_REG,\n+\t\t\t      IT66121_CLK_BANK_PWROFF_TXCLK, 0);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_write(dev, IT66121_PKT_GEN_CTRL,\n+\t\t\t\tIT66121_PKT_GEN_CTRL_RPT |\n+\t\t\t\tIT66121_PKT_GEN_CTRL_EN);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_reg_set(dev, IT66121_AV_MUTE, IT66121_AV_MUTE_ON, 0);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+\n+static int it66121_attach(struct udevice *dev)\n+{\n+\tstruct it66121_priv *priv = dev_get_priv(dev);\n+\tunsigned long pclk_khz;\n+\tu8 status;\n+\tint ret;\n+\n+\tret = video_bridge_set_active(dev, true);\n+\tif (ret) {\n+\t\tdebug(\"IT66121: set_active failed: %d\\n\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tmdelay(50);\n+\n+\tret = it66121_identify(dev);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = it66121_hw_init(dev);\n+\tif (ret) {\n+\t\tdebug(\"IT66121: hw_init failed: %d\\n\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tret = it66121_reg_read(dev, IT66121_SYS_STATUS, &status);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (!(status & IT66121_SYS_STATUS_HPD)) {\n+\t\tdebug(\"IT66121: no HPD, skipping EDID read\\n\");\n+\t\treturn 0;\n+\t}\n+\n+\tret = it66121_read_edid_block(dev, priv->edid, 0, 0, 128);\n+\tif (ret < 0) {\n+\t\tdebug(\"IT66121: EDID block 0 read failed: %d\\n\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\tpriv->edid_len = 128;\n+\n+\tif (priv->edid[0x7E] > 0) {\n+\t\tret = it66121_read_edid_block(dev, priv->edid + 128,\n+\t\t\t\t\t      128, 0, 128);\n+\t\tif (ret < 0)\n+\t\t\tdebug(\"IT66121: EDID block 1 read failed: %d\\n\", ret);\n+\t\telse\n+\t\t\tpriv->edid_len = 256;\n+\t}\n+\n+\t/* Preferred DTD pixel clock: bytes 54-55, units of 10 kHz. */\n+\tpclk_khz = ((unsigned long)priv->edid[55] << 8 |\n+\t\t     priv->edid[54]) * 10;\n+\tif (pclk_khz > 0) {\n+\t\tdebug(\"IT66121: configuring video for %lu kHz pclk\\n\",\n+\t\t      pclk_khz);\n+\t\tret = it66121_setup_video(dev, pclk_khz);\n+\t\tif (ret)\n+\t\t\tdebug(\"IT66121: setup_video failed: %d\\n\", ret);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int it66121_check_attached(struct udevice *dev)\n+{\n+\tu8 status;\n+\tint ret;\n+\n+\tret = it66121_reg_read(dev, IT66121_SYS_STATUS, &status);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (status & IT66121_SYS_STATUS_HPD)\n+\t\treturn 0;\n+\n+\treturn -ENOTCONN;\n+}\n+\n+static int it66121_read_edid(struct udevice *dev, u8 *buf, int buf_size)\n+{\n+\tstruct it66121_priv *priv = dev_get_priv(dev);\n+\tint size;\n+\n+\tif (!priv->edid_len)\n+\t\treturn -ENODATA;\n+\n+\tsize = min_t(int, buf_size, priv->edid_len);\n+\tmemcpy(buf, priv->edid, size);\n+\n+\treturn size;\n+}\n+\n+static int it66121_probe(struct udevice *dev)\n+{\n+\tif (device_get_uclass_id(dev->parent) != UCLASS_I2C)\n+\t\treturn -EPROTONOSUPPORT;\n+\n+\tdebug(\"IT66121: probed on I2C bus\\n\");\n+\treturn 0;\n+}\n+\n+static const struct video_bridge_ops it66121_ops = {\n+\t.attach\t\t= it66121_attach,\n+\t.check_attached\t= it66121_check_attached,\n+\t.read_edid\t= it66121_read_edid,\n+};\n+\n+static const struct udevice_id it66121_ids[] = {\n+\t{ .compatible = \"ite,it66121\" },\n+\t{ }\n+};\n+\n+U_BOOT_DRIVER(ite_it66121) = {\n+\t.name\t\t= \"ite_it66121\",\n+\t.id\t\t= UCLASS_VIDEO_BRIDGE,\n+\t.of_match\t= it66121_ids,\n+\t.probe\t\t= it66121_probe,\n+\t.ops\t\t= &it66121_ops,\n+\t.priv_auto\t= sizeof(struct it66121_priv),\n+};\n","prefixes":[]}