From nobody Sun Feb 8 20:17:37 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 76DFA2C21D8 for ; Sun, 28 Dec 2025 11:41:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766922096; cv=none; b=DbbMVj8u+L4X/iJZ2Wear4qKMNAhwVuRYtQB/S/UKTaKDa6UPwpEhBfjetWFGAxioTTYwt+A2WIXGpxtMYmW4gFCjx+PdIS0Nemz8vAdabEP68KOV7niyF8ip90EHOj5ohoZqhksvtkucL1p+EDBIhvt0vxsbRj0w3fEGxrZ6jY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766922096; c=relaxed/simple; bh=XVPQ7rPYmAEJm3mRiqhhzmp1bAkwnsvuW/w6LudOoJk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tBfQCoSklpZEnTpjWcCAXHD9brq/oWHyXYK/TIY84dWdwwPARRAB824RqNi2P/nc0rY5u6uaV5xtWqKnGny71QPuxarV/lCq/Qo1DH5w29EfdHra43F+Vd72DWNNqzjPFqHBOeGPZxyuoAAXZ0ZaTytoEDKf/C5W5LsjZeilBK8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=D3MW3z40; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=dF0q2Ul5; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="D3MW3z40"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="dF0q2Ul5" Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5BS7fjIs2127444 for ; Sun, 28 Dec 2025 11:41:29 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= FNT26ndq1t4/QCNe8yPe6Cu+o316T1+uFmgBr5OVFOM=; b=D3MW3z40+TqJTav1 19BrlbI3hdzcXV4QtIE8X7n2pp5v8RisK2k14OlGoKiDMd13JV+jdXyMVZAuGLvi kXu6CqlAsMWKBW7AVbZGTHKeBeib0DNBGucKITj+3av6Hat3WhamwJh6lU0Xl3Km bpV6BGIlX75PfliOOu83gLNe4QabThLU4AP/OfGAwyaiVVbIxoKKvBw1xjUWzKDC EdLwpuqCUN4XUOaW7HTiUJemS4fTDz7rq94+zkJW5sGkHcVIIJlj17yeeIASOaQv q7e8xHtnJdyVgyXFB8BngyDRsAkdGjkXGcMNN6QFx3YB0gAKyQRMSbFyGA6NgiYI G6W4qg== Received: from mail-pl1-f200.google.com (mail-pl1-f200.google.com [209.85.214.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4ba6dr27ph-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Sun, 28 Dec 2025 11:41:28 +0000 (GMT) Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-29f1b1f0c1dso23116035ad.3 for ; Sun, 28 Dec 2025 03:41:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1766922088; x=1767526888; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=FNT26ndq1t4/QCNe8yPe6Cu+o316T1+uFmgBr5OVFOM=; b=dF0q2Ul5/Va14DdSv8S87eiLcTaT9Cf6iWXml7GTB6eo4LZ8rAg7H0ikRqLbK6h5kD NVoCXXPPNj1KqOge/kYz42NBcHMFcgLfQvnLYxVemuIEX6xqZBrqwqQ8yE8MM+pqOEIf hgj8X5mbbeTY7qWULcsTOI2xd1XTgh4R17hfKC70Md5Jk5/J10eHm5LVUPNp3ST6kX7V wr54FPka0+9MmeYyp/WawCOYBSQyQXPDK9XgonAaWWuLZ6M3qVF6Fk+tuA87XR7NIVsz TWE+o2IUI1oLeyzZ5wN+iT0DBb57V85TdtfidYpsc/IxfFiTkR98xOGSrvFsyq9QC7gu F0ig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766922088; x=1767526888; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=FNT26ndq1t4/QCNe8yPe6Cu+o316T1+uFmgBr5OVFOM=; b=I+AX5zdRfKuOHSHebkh92dmhbCHYKZYGKiPc4SAhVgdDrpFqXrzGboXSPIyXInoVR2 q3rPmwNx8+WT0lFTMnD9nuaS9Jsb8CHJ9daPxuYbIjL6xnIrX9MYBo3Bf7pWjJo3Jh43 /5x9aEf4RWGxrsO5BsuUJvCCTRQWvF5syt0nU3ItLHMXn18qTZR/KW8X7UZJhu02KCWQ pfJkqxMVtGPMf1jRr+Q1AySeI2eqUrYepOJjThucoPfFaKf3OqPB6HomHDWfwO+SL+J+ Z+Vtp0ntnd8MwCyif2oXg0xFIaP4mOEJ+XFWdWJkuwH4NEvEOwuU6rDFi///PdJpF+47 ZZJA== X-Forwarded-Encrypted: i=1; AJvYcCX7AB0g9WpRh32hzqOd7g925hHPqLdiYVJ/kCJXP8ILOPKwa4aaIyRI/7fhWdni6FOfpALiSDzW4vXKYJ8=@vger.kernel.org X-Gm-Message-State: AOJu0YxpWpcVD2TTOqlTGVAZnz+Tizd2r/2BjZ7yyhPk6hc6UBrkvr4H O7s1f6CwrHj1L0Pve36s5fGopsYiWWlfZMzmBtTbM8TzFnNICTn0bfhmMEH9Jax5qTIxHhfvc5G 60sUK8UUVXUQHbfEILmdmKC3zTFxqWzxOoixaddlbdCZmfFR6Cj++Y0yO6ha0FNpSQl4= X-Gm-Gg: AY/fxX60Bc6Hz9uoUEqhrk6c+INi/mfOIog7ngDRBeBMgzF1Wn2voiaBX6QrZgf68EQ rPZsB3AqFTab4+hsENGfzSXZcLGO2Q+M/1gjAuuths/shxwsvO5B9vhJtKcALh47gjBaB8wyHRI vpi3kji7aXOqKHV2zgGMn0xNm3E7mzJc6N7BPJ6HPu2wBOtffFpVXNnRIU+jMFBvzGy6pv1QC6Q NZWw0gkW9G3O2fXmQIu3gxZbMdvOv4ezC5UogINc/43eNZhXfvz2a2FPAAPUHt9OciHm/4MNywe BGxBa5t9OYUoteeD5j0aDwyFbJxFxEZl2LfOlGuoqefgPEhS5GwRMCVtdyXn+jpJC15EUYcJBMT 9uoQ2AXnZeVfqheMQFbHV5Af9nSNptmci77HTSOJ5SJ+ve9CBfihuZXU9d3vEmDwxiVpGqFxAz+ Wr3pQJ5xmGqcug3z3Tqb7VwvyVo+PLtg== X-Received: by 2002:a05:6a00:2d1d:b0:7ab:9850:25fb with SMTP id d2e1a72fcca58-7ff648e4c38mr19484086b3a.2.1766922088243; Sun, 28 Dec 2025 03:41:28 -0800 (PST) X-Google-Smtp-Source: AGHT+IG5lXiGHvxQ4uJ4M5pEORms1C0F45w/GKGFFYagT0cJBDkpxnUqrLm7f71ENER/q9umScaIqw== X-Received: by 2002:a05:6a00:2d1d:b0:7ab:9850:25fb with SMTP id d2e1a72fcca58-7ff648e4c38mr19484071b3a.2.1766922087808; Sun, 28 Dec 2025 03:41:27 -0800 (PST) Received: from hu-vishsain-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7ff7e197f9asm26214067b3a.43.2025.12.28.03.41.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Dec 2025 03:41:27 -0800 (PST) From: Vishnu Saini Date: Sun, 28 Dec 2025 17:10:39 +0530 Subject: [PATCH v3 1/2] dt-bindings: bridge: lt8713sx: Add bindings Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251228-lt8713sx-bridge-driver-v3-1-9169fbef0e5b@oss.qualcomm.com> References: <20251228-lt8713sx-bridge-driver-v3-0-9169fbef0e5b@oss.qualcomm.com> In-Reply-To: <20251228-lt8713sx-bridge-driver-v3-0-9169fbef0e5b@oss.qualcomm.com> To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Tony Cc: dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Vishnu Saini , prahlad.valluru@oss.qualcomm.com, Prahlad Valluru X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1766922077; l=3328; i=vishnu.saini@oss.qualcomm.com; s=20251113; h=from:subject:message-id; bh=XVPQ7rPYmAEJm3mRiqhhzmp1bAkwnsvuW/w6LudOoJk=; b=LraHjzxylvSG8j/1IBKt7BGO3vHl6tIWqljjLLjyhBaPzV5EKiOklZZon714wAlfVmsYNorcz ShxYcXM+IsnAhriKmMZWOx+qvNnXwWnk/ITJVs655y22Jr9FurnNuEu X-Developer-Key: i=vishnu.saini@oss.qualcomm.com; a=ed25519; pk=8hlXlF8j/3GeOaDK3w2LYhkv9FanCQru0c7kRH/It7k= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjI4MDEwOCBTYWx0ZWRfX6MU3WojVEp6b HagoQXU39ZKNW0ipMEsDgJoybwbLAgkiAnSzdnyW7EPPdOsjcrHGXsw3eSGCT5YZeWw8ooCpGRk uIpRaEocOYrfOZUSwkFgmEtVGfnqImdXErUkIXUOvNo+N0rAYceI1LP2pN3GHlu3jXrWpQ4vC6G G0mZpHIV3ZvgFbV2fh/biPcbH0zCXYm6K9bnJ1B3E7Vqsqgd+sgSeYKky8NiWqjGcnngFub3JBl zBJZggkhCaYig929H1H2xVdzZJwRcX5DG5DB3rKf6G4MAHPKmgJ+fPwachib0HAYmMDvApCzuN2 H5MduEGkJM9ascRUzazJvFWxBRKruHN0XKZPq1uQKnrlqCkSM86NTr4bK6CviuqQf8o2I35/AMz XajP7Mh00AvkbeyIfuxOoMbDy3WNQ/88ql5RPY9VBG8qKvjZdYrzu0b+LRDjerXCVdLRGJRLVpe EOv5F5GPvPHzgXS23Xg== X-Authority-Analysis: v=2.4 cv=VdP6/Vp9 c=1 sm=1 tr=0 ts=69511768 cx=c_pps a=IZJwPbhc+fLeJZngyXXI0A==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=wP3pNCr1ah4A:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=gEfo2CItAAAA:8 a=EUspDBNiAAAA:8 a=Kz8-B0t5AAAA:8 a=u03R5FaqcccxyDpVlScA:9 a=QEXdDO2ut3YA:10 a=uG9DUKGECoFWVXl0Dc02:22 a=sptkURWiP4Gy88Gu7hUp:22 a=RuZk68QooNbwfxovefhk:22 X-Proofpoint-GUID: qqvnJaIVvghv1BwutaeVN-N0VrCz5eM5 X-Proofpoint-ORIG-GUID: qqvnJaIVvghv1BwutaeVN-N0VrCz5eM5 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-12-28_04,2025-12-26_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 spamscore=0 phishscore=0 lowpriorityscore=0 bulkscore=0 adultscore=0 clxscore=1015 malwarescore=0 suspectscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2512120000 definitions=main-2512280108 Add bindings for lt8713sx. Co-developed-by: Prahlad Valluru Signed-off-by: Prahlad Valluru Signed-off-by: Vishnu Saini Reviewed-by: Krzysztof Kozlowski --- .../bindings/display/bridge/lontium,lt8713sx.yaml | 101 +++++++++++++++++= ++++ 1 file changed, 101 insertions(+) diff --git a/Documentation/devicetree/bindings/display/bridge/lontium,lt871= 3sx.yaml b/Documentation/devicetree/bindings/display/bridge/lontium,lt8713s= x.yaml new file mode 100644 index 000000000000..0a6dc56e337c --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/lontium,lt8713sx.yaml @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/lontium,lt8713sx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Lontium LT8713SX Type-C/DP1.4 to Type-C/DP1.4/HDMI2.0/DP++ bridge-h= ub + +maintainers: + - Tony + +description: + The Lontium LT8713SX is a Type-C/DP1.4 to Type-C/DP1.4/HDMI2.0 converter + that integrates one DP input and up to three configurable output interfa= ces + (DP1.4 / HDMI2.0 / DP++), with SST/MST functionality and audio support. + +properties: + compatible: + enum: + - lontium,lt8713sx + + reg: + maxItems: 1 + + vcc-supply: + description: Regulator for 3.3V vcc. + + vdd-supply: + description: Regulator for 1.1V vdd. + + reset-gpios: + description: GPIO connected to active low RESET pin. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: + DP port for DP input from soc to bridge chip + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: + DP port for DP output from bridge + + port@2: + $ref: /schemas/graph.yaml#/properties/port + description: + Additional DP port for DP output from bridge + + required: + - port@0 + +required: + - compatible + - reg + - ports + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + bridge@4f { + compatible =3D "lontium,lt8713sx"; + reg =3D <0x4f>; + reset-gpios =3D <&tlmm 6 GPIO_ACTIVE_LOW>; + + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + port@0 { + reg =3D <0>; + lt8713sx_dp_in: endpoint { + remote-endpoint =3D <&mdss_dp0_out>; + }; + }; + + port@1 { + reg =3D <1>; + lt8713sx_dp0_out: endpoint { + remote-endpoint =3D <&dp0_connector_in>; + }; + }; + + port@2 { + reg =3D <2>; + lt8713sx_dp1_out: endpoint { + remote-endpoint =3D <&dp1_connector_in>; + }; + }; + }; + }; + }; --=20 2.34.1 From nobody Sun Feb 8 20:17:37 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A5E182C21F5 for ; Sun, 28 Dec 2025 11:41:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766922097; cv=none; b=Kg8Nx1oAtb84IT22c6R2APjR59sbrmfmPinRO7gQsMxlveLEzuIfkiG50/hVZcicV5PWY7eLHK45nXvcQgKcJipDKumEDIV0+XhJYyt19N6PRAuUS0l0nJYkJFfrYFc2vlbzj7ODInmTO6aJXdfyftkMWy4BaNUaSZyYw2EvgXA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766922097; c=relaxed/simple; bh=YGUOA/mG99rfEU/eoERsbhNRUe7s7u1n+QTtZ/X6mlM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=G6i25lGRZzDHBZ+bf+rPI2P5MX4sBOOLmXWiPgb/Jptqc0jEwf8woEiuhlKriaHoLKXeOkYgha8wkqVg9kk8VTHfqqbe9sH/Rx9dRyqkliwz5T7r51Xkq2mgvyruxN6/zYeKqE1qwDqRGX5olkGsw1MTJaW8MfFGgat+Z7IAdcI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=htWF5g+q; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=f2+ZBF6r; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="htWF5g+q"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="f2+ZBF6r" Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5BS4pQjx1940873 for ; Sun, 28 Dec 2025 11:41:35 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= z0rsyMfnSMVjG7eYM5sSuBfEla5IEk3vdg7bZNHRL4Y=; b=htWF5g+q2lsfVpbs m9xJtGN0TgPhBY5TuVkg3/nNTSJy0vGvudfBqvHpfrK+CIflD3xZWFhFkaUKxT1O Sj6m110/6Xzur4hjivpxchFls1M32ILwQk5uakzzeYOMw5qWeMZYMCK5izWJnmZb HeT9M7HTI0xwKiQTLwiDqxGv9v0FtI9GLoDEsZNc1Y4YClf4LkB6kCyHO1GvEq6v NObjFhP6yCe7zSEkhyqmvwiS/b5Ptn80blbZBUfr/Fhaf6wLVDl4W72fLwSZNxfE nz79p1qf1LDUm5JGZTPFwkwF3KfIR6xFfrQ7md9OzvsOGH+jge4Y1xsiA0h/DZDw Ebl/Bw== Received: from mail-pg1-f200.google.com (mail-pg1-f200.google.com [209.85.215.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4ba87bt37h-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Sun, 28 Dec 2025 11:41:34 +0000 (GMT) Received: by mail-pg1-f200.google.com with SMTP id 41be03b00d2f7-bdd6dfa6f85so586757a12.1 for ; Sun, 28 Dec 2025 03:41:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1766922094; x=1767526894; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=z0rsyMfnSMVjG7eYM5sSuBfEla5IEk3vdg7bZNHRL4Y=; b=f2+ZBF6rQAB9OFWl4cTyTAPijK60to/AOQXzNZIHILBcu8ImseS0Jp02EdAVbQ5wBp mIU9k8ffXiqNQ7bNCmrCRSCzKYKLdb+4vAc8IXEXJpDjHIL4pZlY+5yKWO1kLSx6jTE/ ZrQzMEkzaI3oQdrMNtU/OljjXCkdAi2TY69/BzNchqmdFOeXIPxbRtnh8YrxTwxDW4KS nIvkUY/R2p8aR6DLBnEz0rJWY9+YsPxSTv6lo6HZ4Ezjrws9ivtzJ3m9H4Yt9ajVZjHw vT841REUY5HcwYtd2Sopq4LLuHVS8A+9VIqlQtTSkJkcxC+5/LXwKh3Vo6Z/A3FiWOtk 0FgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766922094; x=1767526894; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=z0rsyMfnSMVjG7eYM5sSuBfEla5IEk3vdg7bZNHRL4Y=; b=T6283Ff/iF6WJ+IBtKSX13q57UrRzZpz/jOyq77CY6zu8cFdu6JACS1+x4sooJyjYn gCHcbs3HSRy/gzFxWO4dlR1MYYSa5DcB9Hc/rCVyJu8uEcofQujh7hxnAxgqfxaow9yE TB/2fAyt+MU90PFbCC4avP6gYlgTZF0ob52b7kuS42obRZtntvaU63vla+fMN2pLanSf LcHIrxzay01Si5lobaFEpcRGa0d53eDWc0SXNSLDCQb85CN7VHRYnKHYclRUYw+rLAgq +1GJe4fbgEwx62FCXe2+PPvp17CmRwBFIetaiyKwcXcRd7nel5C+n/mo10FVEaSZ4QRq 8xAA== X-Forwarded-Encrypted: i=1; AJvYcCWXA4EhoY2O/5GyL3j5R8yzuDcPLewETJXCwFDTQVqlpHZpLcLWL1LqANYudVqHkzkCcq3rJOQgH3tQxgY=@vger.kernel.org X-Gm-Message-State: AOJu0YwpLNwe/sjoKLXtZdDdRFf/+DLQlc0KAp2p5RYIEnDrmC+FQzM3 SFXjJ5E/dasaCsFzXe/hm7sl0b//WGlPpGyNgei2R0jfd9JkKRpdcTwHeQqNQirHqNEHjWmb2Dt OqFcnZ8IX8ui4ruqWgDJqP0GxFa/POJn6o+ro2UwKVgZoG9b2vURIBnKW2qWqt4PPa6Y= X-Gm-Gg: AY/fxX6oGKxjc+DyG7XweviB/6yufeoLIbZV4kQ6mvM5MkoKfRvssKDMw3c9Va1QTw2 CbKx6dY6sz7LJzz55aWOmM5yVmV/wXZL7H/LvxuogWoPIsYjfXVwJn7B2GfYB4DqamkX9+hUPkc jGIpXUpOauy+jN+Idw2T5kqYBQ6rii3FxelnpOyabDVK+dFp0Fw3Zh2geV65YjT69gpNDlpNOpZ CBqh4+O3RWGBxu6QYUXk33XD+hz0IQpFq9lc3VnauSKc431N8SY3KxCvosKkHFaw8ZaWnyM17Ui CrgQPwYG8JOhGO30I8kH7B0m1ujTSdBg/pkmSFlcao0QFF2Pt2MWdUj3O6rdVriS9MzUiFUPV5K c0MM9LN1PtGjcPxmDIGtcdk4GjAeUxy9bPH+PQEGivU99yRTIuR8VWVLqZ2JobUHz5MiXBqum6D 3lS3Oedyzo7PMPUu7W7Mmmp4MLWS/kcg== X-Received: by 2002:a05:6a00:17a1:b0:7b2:b20:e8d9 with SMTP id d2e1a72fcca58-7ff682460c9mr16272782b3a.6.1766922093826; Sun, 28 Dec 2025 03:41:33 -0800 (PST) X-Google-Smtp-Source: AGHT+IFbzuZjej7dofVQz+LVzaPa4pI3i4/MrbeAYBDogcsludpnEXNFnzNmKk+D5ibY8b1M1Ob4Lg== X-Received: by 2002:a05:6a00:17a1:b0:7b2:b20:e8d9 with SMTP id d2e1a72fcca58-7ff682460c9mr16272764b3a.6.1766922093223; Sun, 28 Dec 2025 03:41:33 -0800 (PST) Received: from hu-vishsain-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7ff7e197f9asm26214067b3a.43.2025.12.28.03.41.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Dec 2025 03:41:32 -0800 (PST) From: Vishnu Saini Date: Sun, 28 Dec 2025 17:10:40 +0530 Subject: [PATCH v3 2/2] drm/bridge: add support for lontium lt8713sx bridge driver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251228-lt8713sx-bridge-driver-v3-2-9169fbef0e5b@oss.qualcomm.com> References: <20251228-lt8713sx-bridge-driver-v3-0-9169fbef0e5b@oss.qualcomm.com> In-Reply-To: <20251228-lt8713sx-bridge-driver-v3-0-9169fbef0e5b@oss.qualcomm.com> To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Tony Cc: dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Vishnu Saini , prahlad.valluru@oss.qualcomm.com, Prahlad Valluru X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1766922077; l=21368; i=vishnu.saini@oss.qualcomm.com; s=20251113; h=from:subject:message-id; bh=YGUOA/mG99rfEU/eoERsbhNRUe7s7u1n+QTtZ/X6mlM=; b=slwxm0toGxl3ud50AGJhdfYa3RzVhhhy24wRu4D2OsP7EIqtUL/DPe9EBhDh2Er2bN0FkVP2L llbjeURvLyjA+iCCggY6JYKI7qq2rlfSU6YNfa8VPQ04vqKX7fuPpNS X-Developer-Key: i=vishnu.saini@oss.qualcomm.com; a=ed25519; pk=8hlXlF8j/3GeOaDK3w2LYhkv9FanCQru0c7kRH/It7k= X-Proofpoint-ORIG-GUID: 0IJGukPNMjqZgQMEitYoa55rFA1qJUzE X-Proofpoint-GUID: 0IJGukPNMjqZgQMEitYoa55rFA1qJUzE X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjI4MDEwOCBTYWx0ZWRfXy8caJiBZPOQ+ DowPzetgWPr8AlOIYWWr234Up2YLS38Xux1Mpt+Gj/FMJ5lGqvrcKVNPsFPUXS+9dCZ6q3b1msT sXRWFk79rNQPi+4npYXkww8w/bs9nCB/xeC4uwpO4w6t4opNMFPGRwMFRHFdHk5LsA5OsvHS7Jo uLmWeXaup1yh989Q8kej4OVocT/7HCT3Q36cL2B15Bwyp8VkFPk1wGKM/HzY/LPOncYKqPaMFgK X7nHtwxTMUbMyaRc/DiInvqxAZ3uDNM6ppSUsPxFPvdnlFPjrBSEIXRsHSYdBzxVnKvcIHaWnip FpVKEF2YaqWF6uUxxS3ulrX7fXLPlrytPln6jWrwmLIsQKpmHZy8KT6J451tVEHIBRUwhhXvZt+ JuKXuLDtT1Qcuykd9oBrzBFGbxyMOfBR5DOQrsAJQx++flp6dVyjiwiOrYS8SFCLUsLPFPr8RI3 Pgh5yr3S3XT38BRTUuA== X-Authority-Analysis: v=2.4 cv=do7Wylg4 c=1 sm=1 tr=0 ts=6951176e cx=c_pps a=oF/VQ+ItUULfLr/lQ2/icg==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=wP3pNCr1ah4A:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=EUspDBNiAAAA:8 a=Kz8-B0t5AAAA:8 a=Los8Fsgh6qdBVcIiYUAA:9 a=QEXdDO2ut3YA:10 a=3WC7DwWrALyhR5TkjVHa:22 a=RuZk68QooNbwfxovefhk:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-12-28_04,2025-12-26_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 malwarescore=0 bulkscore=0 clxscore=1015 lowpriorityscore=0 adultscore=0 spamscore=0 suspectscore=0 phishscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2512120000 definitions=main-2512280108 The lt8713sx is a Type-C/DP1.4 to Type-C/DP1.4/HDMI2.0 converter, with three configurable DP1.4/HDMI2.0/DP++ output interfaces and audio output interface. Driver is required for firmware upgrade in the bridge chip. Co-developed-by: Prahlad Valluru Signed-off-by: Prahlad Valluru Signed-off-by: Vishnu Saini --- drivers/gpu/drm/bridge/Kconfig | 10 + drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/lontium-lt8713sx.c | 682 ++++++++++++++++++++++++++= ++++ 3 files changed, 693 insertions(+) diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index a250afd8d662..7fef383ed7cb 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -184,6 +184,16 @@ config DRM_LONTIUM_LT9611UXC HDMI signals Please say Y if you have such hardware. =20 +config DRM_LONTIUM_LT8713SX + tristate "Lontium LT8713SX DP MST bridge" + depends on OF + select REGMAP_I2C + help + Driver for Lontium LT8713SX DP MST bridge + chip firmware upgrade, which converts Type-C/DP1.4 + to 3 configurable Type-C/DP1.4/HDMI2.0 outputs + Please say Y if you have such hardware. + config DRM_ITE_IT66121 tristate "ITE IT66121 HDMI bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makef= ile index c7dc03182e59..07eeb13fa497 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_DRM_LONTIUM_LT8912B) +=3D lontium-lt8912b.o obj-$(CONFIG_DRM_LONTIUM_LT9211) +=3D lontium-lt9211.o obj-$(CONFIG_DRM_LONTIUM_LT9611) +=3D lontium-lt9611.o obj-$(CONFIG_DRM_LONTIUM_LT9611UXC) +=3D lontium-lt9611uxc.o +obj-$(CONFIG_DRM_LONTIUM_LT8713SX) +=3D lontium-lt8713sx.o obj-$(CONFIG_DRM_LVDS_CODEC) +=3D lvds-codec.o obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) +=3D megachips-stdpxxxx-= ge-b850v3-fw.o obj-$(CONFIG_DRM_MICROCHIP_LVDS_SERIALIZER) +=3D microchip-lvds.o diff --git a/drivers/gpu/drm/bridge/lontium-lt8713sx.c b/drivers/gpu/drm/br= idge/lontium-lt8713sx.c new file mode 100644 index 000000000000..6ea54ff3733d --- /dev/null +++ b/drivers/gpu/drm/bridge/lontium-lt8713sx.c @@ -0,0 +1,682 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define FW_FILE "lt8713sx_fw.bin" + +#define REG_PAGE_CONTROL 0xff + +#define MAX_OUTPUT_PORTS 3 +#define LT8713SX_PAGE_SIZE 256 + +DECLARE_CRC8_TABLE(lt8713sx_crc_table); + +struct lt8713sx { + struct device *dev; + struct drm_bridge bridge; + struct drm_bridge *next_bridge[MAX_OUTPUT_PORTS]; + int num_outputs; + + struct regmap *regmap; + /* Protects all accesses to registers by stopping the on-chip MCU */ + struct mutex ocm_lock; + + struct gpio_desc *reset_gpio; + struct gpio_desc *enable_gpio; + + struct i2c_client *client; + const struct firmware *fw; + + u8 *fw_buffer; + + u32 main_crc_value; + u32 bank_crc_value[17]; + + int bank_num; +}; + +static void lt8713sx_reset(struct lt8713sx *lt8713sx); + +static const struct regmap_range lt8713sx_ranges[] =3D { + { + .range_min =3D 0x0000, + .range_max =3D 0xffff + }, +}; + +static const struct regmap_access_table lt8713sx_table =3D { + .yes_ranges =3D lt8713sx_ranges, + .n_yes_ranges =3D ARRAY_SIZE(lt8713sx_ranges), +}; + +static const struct regmap_range_cfg lt8713sx_range_cfg =3D { + .name =3D "lt8713sx", + .range_min =3D 0x0000, + .range_max =3D 0xffff, + .selector_reg =3D REG_PAGE_CONTROL, + .selector_mask =3D 0xff, + .selector_shift =3D 0, + .window_start =3D 0, + .window_len =3D 0x100, +}; + +static const struct regmap_config lt8713sx_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + .volatile_table =3D <8713sx_table, + .ranges =3D <8713sx_range_cfg, + .num_ranges =3D 1, + .cache_type =3D REGCACHE_NONE, + .max_register =3D 0xffff, +}; + +static void lt8713sx_i2c_enable(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe0ee, 0x01); +} + +static void lt8713sx_i2c_disable(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe0ee, 0x00); +} + +static u32 calculate_crc(const u8 *upgrade_data, u64 len, u64 crc_size) +{ + u8 crc =3D 0x00; + u8 pad =3D 0xff; + + crc =3D crc8(lt8713sx_crc_table, upgrade_data, len, crc); + + /* pad remaining bytes */ + crc_size -=3D len; + while (crc_size--) + crc =3D crc8(lt8713sx_crc_table, &pad, 1, crc); + + return crc; +} + +static int lt8713sx_prepare_firmware_data(struct lt8713sx *lt8713sx) +{ + int ret =3D 0; + u64 sz_12k =3D 12 * SZ_1K; + + ret =3D request_firmware(<8713sx->fw, FW_FILE, lt8713sx->dev); + if (ret < 0) { + dev_err(lt8713sx->dev, "request firmware failed\n"); + return ret; + } + + dev_dbg(lt8713sx->dev, "Firmware size: %zu bytes\n", lt8713sx->fw->size); + + if (lt8713sx->fw->size > SZ_256K - 1) { + dev_err(lt8713sx->dev, "Firmware size exceeds 256KB limit\n"); + release_firmware(lt8713sx->fw); + return -EINVAL; + } + + lt8713sx->fw_buffer =3D kvmalloc(SZ_256K, GFP_KERNEL); + if (!lt8713sx->fw_buffer) { + release_firmware(lt8713sx->fw); + return -ENOMEM; + } + + memset(lt8713sx->fw_buffer, 0xff, SZ_256K); + + if (lt8713sx->fw->size < SZ_64K) { + memcpy(lt8713sx->fw_buffer, lt8713sx->fw->data, lt8713sx->fw->size); + lt8713sx->fw_buffer[SZ_64K - 1] =3D + calculate_crc(lt8713sx->fw->data, lt8713sx->fw->size, SZ_64K - 1); + lt8713sx->main_crc_value =3D lt8713sx->fw_buffer[SZ_64K - 1]; + dev_dbg(lt8713sx->dev, + "Main Firmware Data Crc=3D0x%02X\n", lt8713sx->main_crc_value); + + } else { + /* main firmware */ + memcpy(lt8713sx->fw_buffer, lt8713sx->fw->data, SZ_64K - 1); + lt8713sx->fw_buffer[SZ_64K - 1] =3D + calculate_crc(lt8713sx->fw_buffer, SZ_64K - 1, SZ_64K - 1); + lt8713sx->main_crc_value =3D lt8713sx->fw_buffer[SZ_64K - 1]; + dev_dbg(lt8713sx->dev, + "Main Firmware Data Crc=3D0x%02X\n", lt8713sx->main_crc_value); + + /* bank firmware */ + memcpy(lt8713sx->fw_buffer + SZ_64K, + lt8713sx->fw->data + SZ_64K, + lt8713sx->fw->size - SZ_64K); + + lt8713sx->bank_num =3D (lt8713sx->fw->size - SZ_64K + sz_12k - 1) / sz_1= 2k; + dev_dbg(lt8713sx->dev, "Bank Number Total is %d.\n", lt8713sx->bank_num); + + for (int i =3D 0; i < lt8713sx->bank_num; i++) { + lt8713sx->bank_crc_value[i] =3D + calculate_crc(lt8713sx->fw_buffer + SZ_64K + i * sz_12k, + sz_12k, sz_12k); + dev_dbg(lt8713sx->dev, "Bank number:%d; Firmware Data Crc:0x%02X\n", + i, lt8713sx->bank_crc_value[i]); + } + } + return 0; +} + +static void lt8713sx_config_parameters(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe0ee, 0x01); + regmap_write(lt8713sx->regmap, 0xe05e, 0xc1); + regmap_write(lt8713sx->regmap, 0xe058, 0x00); + regmap_write(lt8713sx->regmap, 0xe059, 0x50); + regmap_write(lt8713sx->regmap, 0xe05a, 0x10); + regmap_write(lt8713sx->regmap, 0xe05a, 0x00); + regmap_write(lt8713sx->regmap, 0xe058, 0x21); +} + +static void lt8713sx_wren(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe103, 0xbf); + regmap_write(lt8713sx->regmap, 0xe103, 0xff); + regmap_write(lt8713sx->regmap, 0xe05a, 0x04); + regmap_write(lt8713sx->regmap, 0xe05a, 0x00); +} + +static void lt8713sx_wrdi(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe05a, 0x08); + regmap_write(lt8713sx->regmap, 0xe05a, 0x00); +} + +static void lt8713sx_fifo_reset(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe103, 0xbf); + regmap_write(lt8713sx->regmap, 0xe103, 0xff); +} + +static void lt8713sx_disable_sram_write(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe055, 0x00); +} + +static void lt8713sx_sram_to_flash(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe05a, 0x30); + regmap_write(lt8713sx->regmap, 0xe05a, 0x00); +} + +static void lt8713sx_i2c_to_sram(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe055, 0x80); + regmap_write(lt8713sx->regmap, 0xe05e, 0xc0); + regmap_write(lt8713sx->regmap, 0xe058, 0x21); +} + +static u8 lt8713sx_read_flash_status(struct lt8713sx *lt8713sx) +{ + u32 flash_status =3D 0; + + regmap_write(lt8713sx->regmap, 0xe103, 0x3f); + regmap_write(lt8713sx->regmap, 0xe103, 0xff); + + regmap_write(lt8713sx->regmap, 0xe05e, 0x40); + regmap_write(lt8713sx->regmap, 0xe056, 0x05); /* opcode=3Dread status re= gister */ + regmap_write(lt8713sx->regmap, 0xe055, 0x25); + regmap_write(lt8713sx->regmap, 0xe055, 0x01); + regmap_write(lt8713sx->regmap, 0xe058, 0x21); + + regmap_read(lt8713sx->regmap, 0xe05f, &flash_status); + dev_dbg(lt8713sx->dev, "flash_status:%x\n", flash_status); + + return flash_status; +} + +static void lt8713sx_block_erase(struct lt8713sx *lt8713sx) +{ + u32 i =3D 0; + u8 flash_status =3D 0; + u8 blocknum =3D 0x00; + u32 flashaddr =3D 0x00; + + for (blocknum =3D 0; blocknum < 8; blocknum++) { + flashaddr =3D blocknum * SZ_32K; + regmap_write(lt8713sx->regmap, 0xe0ee, 0x01); + regmap_write(lt8713sx->regmap, 0xe05a, 0x04); + regmap_write(lt8713sx->regmap, 0xe05a, 0x00); + regmap_write(lt8713sx->regmap, 0xe05b, flashaddr >> 16); + regmap_write(lt8713sx->regmap, 0xe05c, flashaddr >> 8); + regmap_write(lt8713sx->regmap, 0xe05d, flashaddr); + regmap_write(lt8713sx->regmap, 0xe05a, 0x01); + regmap_write(lt8713sx->regmap, 0xe05a, 0x00); + msleep(100); + i =3D 0; + while (1) { + flash_status =3D lt8713sx_read_flash_status(lt8713sx); + if ((flash_status & 0x01) =3D=3D 0) + break; + + if (i > 50) + break; + + i++; + msleep(50); + } + } + dev_dbg(lt8713sx->dev, "erase flash done.\n"); +} + +static void lt8713sx_load_main_fw_to_sram(struct lt8713sx *lt8713sx) +{ + regmap_write(lt8713sx->regmap, 0xe0ee, 0x01); + regmap_write(lt8713sx->regmap, 0xe068, 0x00); + regmap_write(lt8713sx->regmap, 0xe069, 0x00); + regmap_write(lt8713sx->regmap, 0xe06a, 0x00); + regmap_write(lt8713sx->regmap, 0xe065, 0x00); + regmap_write(lt8713sx->regmap, 0xe066, 0xff); + regmap_write(lt8713sx->regmap, 0xe067, 0xff); + regmap_write(lt8713sx->regmap, 0xe06b, 0x00); + regmap_write(lt8713sx->regmap, 0xe06c, 0x00); + regmap_write(lt8713sx->regmap, 0xe060, 0x01); + msleep(200); + regmap_write(lt8713sx->regmap, 0xe060, 0x00); +} + +static void lt8713sx_load_bank_fw_to_sram(struct lt8713sx *lt8713sx, u64 a= ddr) +{ + regmap_write(lt8713sx->regmap, 0xe0ee, 0x01); + regmap_write(lt8713sx->regmap, 0xe068, ((addr & 0xff0000) >> 16)); + regmap_write(lt8713sx->regmap, 0xe069, ((addr & 0x00ff00) >> 8)); + regmap_write(lt8713sx->regmap, 0xe06a, (addr & 0x0000ff)); + regmap_write(lt8713sx->regmap, 0xe065, 0x00); + regmap_write(lt8713sx->regmap, 0xe066, 0x30); + regmap_write(lt8713sx->regmap, 0xe067, 0x00); + regmap_write(lt8713sx->regmap, 0xe06b, 0x00); + regmap_write(lt8713sx->regmap, 0xe06c, 0x00); + regmap_write(lt8713sx->regmap, 0xe060, 0x01); + msleep(50); + regmap_write(lt8713sx->regmap, 0xe060, 0x00); +} + +static int lt8713sx_write_data(struct lt8713sx *lt8713sx, const u8 *data, = u64 filesize) +{ + int page =3D 0, num =3D 0, i =3D 0, val; + + page =3D (filesize % LT8713SX_PAGE_SIZE) ? + ((filesize / LT8713SX_PAGE_SIZE) + 1) : (filesize / LT8713SX_PAGE_SIZE); + + dev_dbg(lt8713sx->dev, + "Writing to Sram=3D%u pages, total size =3D %llu bytes\n", page, filesiz= e); + + for (num =3D 0; num < page; num++) { + dev_dbg(lt8713sx->dev, "page[%d]\n", num); + lt8713sx_i2c_to_sram(lt8713sx); + + for (i =3D 0; i < LT8713SX_PAGE_SIZE; i++) { + if ((num * LT8713SX_PAGE_SIZE + i) < filesize) + val =3D *(data + (num * LT8713SX_PAGE_SIZE + i)); + else + val =3D 0xff; + regmap_write(lt8713sx->regmap, 0xe059, val); + } + + lt8713sx_wren(lt8713sx); + lt8713sx_sram_to_flash(lt8713sx); + } + + lt8713sx_wrdi(lt8713sx); + lt8713sx_disable_sram_write(lt8713sx); + + return 0; +} + +static void lt8713sx_main_upgrade_result(struct lt8713sx *lt8713sx) +{ + u32 main_crc_result; + + regmap_read(lt8713sx->regmap, 0xe023, &main_crc_result); + + dev_dbg(lt8713sx->dev, "Main CRC HW: 0x%02X\n", main_crc_result); + dev_dbg(lt8713sx->dev, "Main CRC FW: 0x%02X\n", lt8713sx->main_crc_value); + + if (main_crc_result =3D=3D lt8713sx->main_crc_value) + dev_dbg(lt8713sx->dev, "Main Firmware Upgrade Success.\n"); + else + dev_err(lt8713sx->dev, "Main Firmware Upgrade Failed.\n"); +} + +static void lt8713sx_bank_upgrade_result(struct lt8713sx *lt8713sx, u8 ban= knum) +{ + u32 bank_crc_result; + + regmap_read(lt8713sx->regmap, 0xe023, &bank_crc_result); + + dev_dbg(lt8713sx->dev, "Bank %d CRC Result: 0x%02X\n", banknum, bank_crc_= result); + + if (bank_crc_result =3D=3D lt8713sx->bank_crc_value[banknum]) + dev_dbg(lt8713sx->dev, "Bank %d Firmware Upgrade Success.\n", banknum); + else + dev_err(lt8713sx->dev, "Bank %d Firmware Upgrade Failed.\n", banknum); +} + +static void lt8713sx_bank_result_check(struct lt8713sx *lt8713sx) +{ + int i; + u64 addr =3D 0x010000; + + for (i =3D 0; i < lt8713sx->bank_num; i++) { + lt8713sx_load_bank_fw_to_sram(lt8713sx, addr); + lt8713sx_bank_upgrade_result(lt8713sx, i); + addr +=3D 0x3000; + } +} + +static int lt8713sx_firmware_upgrade(struct lt8713sx *lt8713sx) +{ + int ret; + + lt8713sx_config_parameters(lt8713sx); + + lt8713sx_block_erase(lt8713sx); + + if (lt8713sx->fw->size < SZ_64K) { + ret =3D lt8713sx_write_data(lt8713sx, lt8713sx->fw_buffer, SZ_64K); + if (ret < 0) { + dev_err(lt8713sx->dev, "Failed to write firmware data: %d\n", ret); + return ret; + } + } else { + ret =3D lt8713sx_write_data(lt8713sx, lt8713sx->fw_buffer, lt8713sx->fw-= >size); + if (ret < 0) { + dev_err(lt8713sx->dev, "Failed to write firmware data: %d\n", ret); + return ret; + } + } + dev_dbg(lt8713sx->dev, "Write Data done.\n"); + + return 0; +} + +static int lt8713sx_firmware_update(struct lt8713sx *lt8713sx) +{ + int ret =3D 0; + + mutex_lock(<8713sx->ocm_lock); + lt8713sx_i2c_enable(lt8713sx); + + ret =3D lt8713sx_prepare_firmware_data(lt8713sx); + if (ret < 0) { + dev_err(lt8713sx->dev, "Failed to prepare firmware data: %d\n", ret); + goto error; + } + + ret =3D lt8713sx_firmware_upgrade(lt8713sx); + if (ret < 0) { + dev_err(lt8713sx->dev, "Upgrade failure.\n"); + goto error; + } else { + /* Validate CRC */ + lt8713sx_load_main_fw_to_sram(lt8713sx); + lt8713sx_main_upgrade_result(lt8713sx); + lt8713sx_wrdi(lt8713sx); + lt8713sx_fifo_reset(lt8713sx); + lt8713sx_bank_result_check(lt8713sx); + lt8713sx_wrdi(lt8713sx); + } + +error: + lt8713sx_i2c_disable(lt8713sx); + if (!ret) + lt8713sx_reset(lt8713sx); + + kvfree(lt8713sx->fw_buffer); + lt8713sx->fw_buffer =3D NULL; + + if (lt8713sx->fw) { + release_firmware(lt8713sx->fw); + lt8713sx->fw =3D NULL; + } + mutex_unlock(<8713sx->ocm_lock); + + return ret; +} + +static void lt8713sx_reset(struct lt8713sx *lt8713sx) +{ + dev_dbg(lt8713sx->dev, "reset bridge.\n"); + gpiod_set_value_cansleep(lt8713sx->reset_gpio, 1); + msleep(20); + + gpiod_set_value_cansleep(lt8713sx->reset_gpio, 0); + msleep(20); + + dev_dbg(lt8713sx->dev, "reset done.\n"); +} + +static int lt8713sx_regulator_enable(struct lt8713sx *lt8713sx) +{ + int ret; + + ret =3D devm_regulator_get_enable(lt8713sx->dev, "vdd"); + if (ret < 0) + return dev_err_probe(lt8713sx->dev, ret, "failed to enable vdd regulator= \n"); + + usleep_range(1000, 10000); + + ret =3D devm_regulator_get_enable(lt8713sx->dev, "vcc"); + if (ret < 0) + return dev_err_probe(lt8713sx->dev, ret, "failed to enable vcc regulator= \n"); + return 0; +} + +static int lt8713sx_bridge_attach(struct drm_bridge *bridge, + struct drm_encoder *encoder, + enum drm_bridge_attach_flags flags) +{ + struct lt8713sx *lt8713sx =3D container_of(bridge, struct lt8713sx, bridg= e); + int i, ret; + + for (i =3D 0; i < lt8713sx->num_outputs; i++) { + if (!lt8713sx->next_bridge[i]) + continue; + + ret =3D drm_bridge_attach(encoder, + lt8713sx->next_bridge[i], + bridge, flags); + if (ret) + return ret; + } + + return 0; +} + +static int lt8713sx_get_ports(struct lt8713sx *lt8713sx) +{ + struct device *dev =3D lt8713sx->dev; + struct device_node *port, *ports, *ep, *remote; + int i =3D 0; + u32 reg; + + ports =3D of_get_child_by_name(dev->of_node, "ports"); + if (!ports) + return -ENODEV; + + for_each_child_of_node(ports, port) { + if (of_property_read_u32(port, "reg", ®)) + continue; + + if (reg =3D=3D 0) + continue; + + if (i >=3D ARRAY_SIZE(lt8713sx->next_bridge)) { + of_node_put(port); + break; + } + + ep =3D of_graph_get_next_endpoint(port, NULL); + if (!ep) + continue; + + remote =3D of_graph_get_remote_port_parent(ep); + of_node_put(ep); + + if (!remote) + continue; + + lt8713sx->next_bridge[i] =3D of_drm_find_bridge(remote); + of_node_put(remote); + if (lt8713sx->next_bridge[i]) + i++; + } + lt8713sx->num_outputs =3D i; + dev_dbg(dev, "Enabled %d output ports", i); + + of_node_put(ports); + return 0; +}; + +static int lt8713sx_gpio_init(struct lt8713sx *lt8713sx) +{ + struct device *dev =3D lt8713sx->dev; + + lt8713sx->reset_gpio =3D devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(lt8713sx->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(lt8713sx->reset_gpio), + "failed to acquire reset gpio\n"); + + /* power enable gpio */ + lt8713sx->enable_gpio =3D devm_gpiod_get_optional(dev, "enable", GPIOD_OU= T_HIGH); + if (IS_ERR(lt8713sx->enable_gpio)) + return dev_err_probe(dev, PTR_ERR(lt8713sx->enable_gpio), + "failed to acquire enable gpio\n"); + return 0; +} + +static ssize_t lt8713sx_firmware_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct lt8713sx *lt8713sx =3D dev_get_drvdata(dev); + int ret; + + ret =3D lt8713sx_firmware_update(lt8713sx); + if (ret < 0) + return ret; + return len; +} + +static DEVICE_ATTR_WO(lt8713sx_firmware); + +static struct attribute *lt8713sx_attrs[] =3D { + &dev_attr_lt8713sx_firmware.attr, + NULL, +}; + +static const struct attribute_group lt8713sx_attr_group =3D { + .attrs =3D lt8713sx_attrs, +}; + +static const struct attribute_group *lt8713sx_attr_groups[] =3D { + <8713sx_attr_group, + NULL, +}; + +static const struct drm_bridge_funcs lt8713sx_bridge_funcs =3D { + .attach =3D lt8713sx_bridge_attach, +}; + +static int lt8713sx_probe(struct i2c_client *client) +{ + struct lt8713sx *lt8713sx; + struct device *dev =3D &client->dev; + int ret; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return dev_err_probe(dev, -ENODEV, "device doesn't support I2C\n"); + + lt8713sx =3D devm_drm_bridge_alloc(dev, struct lt8713sx, bridge, <8713s= x_bridge_funcs); + if (IS_ERR(lt8713sx)) + return PTR_ERR(lt8713sx); + + lt8713sx->dev =3D dev; + lt8713sx->client =3D client; + i2c_set_clientdata(client, lt8713sx); + + ret =3D devm_mutex_init(lt8713sx->dev, <8713sx->ocm_lock); + if (ret) + return ret; + + lt8713sx->regmap =3D devm_regmap_init_i2c(client, <8713sx_regmap_config= ); + if (IS_ERR(lt8713sx->regmap)) + return dev_err_probe(dev, PTR_ERR(lt8713sx->regmap), "regmap i2c init fa= iled\n"); + + ret =3D lt8713sx_get_ports(lt8713sx); + if (ret < 0) + return ret; + + ret =3D lt8713sx_gpio_init(lt8713sx); + if (ret < 0) + return ret; + + ret =3D lt8713sx_regulator_enable(lt8713sx); + if (ret) + return ret; + + lt8713sx_reset(lt8713sx); + + lt8713sx->bridge.funcs =3D <8713sx_bridge_funcs; + lt8713sx->bridge.of_node =3D dev->of_node; + lt8713sx->bridge.type =3D DRM_MODE_CONNECTOR_DisplayPort; + drm_bridge_add(<8713sx->bridge); + + crc8_populate_msb(lt8713sx_crc_table, 0x31); + + return 0; +} + +static void lt8713sx_remove(struct i2c_client *client) +{ + struct lt8713sx *lt8713sx =3D i2c_get_clientdata(client); + + drm_bridge_remove(<8713sx->bridge); +} + +static struct i2c_device_id lt8713sx_id[] =3D { + { "lontium,lt8713sx", 0 }, + { /* sentinel */ } +}; + +static const struct of_device_id lt8713sx_match_table[] =3D { + { .compatible =3D "lontium,lt8713sx" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, lt8713sx_match_table); + +static struct i2c_driver lt8713sx_driver =3D { + .driver =3D { + .name =3D "lt8713sx", + .of_match_table =3D lt8713sx_match_table, + .dev_groups =3D lt8713sx_attr_groups, + }, + .probe =3D lt8713sx_probe, + .remove =3D lt8713sx_remove, + .id_table =3D lt8713sx_id, +}; + +module_i2c_driver(lt8713sx_driver); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("lt8713sx drm bridge driver"); +MODULE_AUTHOR("Tony "); +MODULE_FIRMWARE(FW_FILE); --=20 2.34.1