From nobody Sun Feb 8 21:49:05 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 3315431ED97 for ; Thu, 18 Dec 2025 06:24:34 +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=1766039076; cv=none; b=B8upGMz9v9QeqJy7NdE/T5ThsufqcA03edfe8kvR8SInGj/HbsVuYJwrNt2Aw+btMpGfTmkA9HkOQWiBG0MTrhgRhhgxsRtnETBjC9Tr/iQPou4mbJuiPPXTFbyea9V0Q5X0JZSdlHSTrbcwMW6SOQgULyQmiDQhg2JifvQHz+w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766039076; c=relaxed/simple; bh=YS2v6vLCtx5V598IdOCf2ikhkqgSJA7lx9ZSuwPALV0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OYCP6VqkNXQ7SpozYtwfNwaGFYYA9PqSPXu21FVJdSoMdOOvp1qPP6FVs62hSLC9/hH25NOSNTjP6+m/FA8k5xOY2hesLgRBgst2DQh4ZgXsXs7YdZZxMozfx0zWkI1pjP5UIxdYW8K2BVi44ypP52nyQMK75eNFKF0pA40bwrI= 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=K0ie+oIn; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=Dl4wM6OL; 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="K0ie+oIn"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Dl4wM6OL" Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5BI1Zkua2016433 for ; Thu, 18 Dec 2025 06:24:34 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= 6uvKGEnhe6pjfLoE2vbLJnqxhEW8HHQ6u7PTnpBiilk=; b=K0ie+oInyr/8ullV pr9z0IVsiGSzm5JpEayA6eJnTmbsWQaQtAx1mpd0zP5nOgV75lR74rOj5P4TWe3v AyIvRrtktL+2fwOv/NjENHhHU7ugKYFGkKrvjMRe7WVbqECiJnJZi2QjMZSV+0hX feRf9PfOKyybZcP1OjaFU7AuqSQs+9q8Jj4nnGos6SjTYBbzjYh8K3lM3CWuOBVd qYq95kvGC8vTHSekcQ+p1M7/SvvBanPYCSvEaw/k0iayZrx6vhf4s55ijPZVpyX7 uRVg9xaXgazWGtYnRqSiFFGh2gx3nuKajKd6+OsDMSYa3rGnks3dWXaZyX/zGHiE iLJlPA== Received: from mail-pf1-f200.google.com (mail-pf1-f200.google.com [209.85.210.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4b3t8e3c32-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 18 Dec 2025 06:24:34 +0000 (GMT) Received: by mail-pf1-f200.google.com with SMTP id d2e1a72fcca58-7b9ef46df43so444902b3a.1 for ; Wed, 17 Dec 2025 22:24:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1766039074; x=1766643874; 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=6uvKGEnhe6pjfLoE2vbLJnqxhEW8HHQ6u7PTnpBiilk=; b=Dl4wM6OLcRUwr6lkmYFiDDBvUfUbfrzMyFpmsJtg5VJs6LMd0t5wBddy269WqO/DBG P5srx51rzQSBLGg2and44tL+fxWTUAPk6Jch/loV9DQpNPdD77RT02s4GX/4fk4esbM1 fpgFIkK6zRK0TgUzSTK7O4pyA0PAcKNyB6qpS/7YXYTeXtyfyHnkqyhklX1yDiqMeYZD luWjzf6yZA0pIGHlB75EMkIGJCQVJ1Hkx1N983SB9+vYHbnxEmyyiyAlpoIF5FvLUny3 /3c4IQ4RsnMHwOHN2nUkM3fDVjEruweAH39G8UFR+AJvMsnOkzUTaxVS6qeF4ujDCHgS yyCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766039074; x=1766643874; 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=6uvKGEnhe6pjfLoE2vbLJnqxhEW8HHQ6u7PTnpBiilk=; b=egQQvRvMjHbU6ICN6t8tKlBTRocdqy7ZO/CyPuiPcUlTwb+GHExinFEkjMcj8QCAnj hK2CrkmuD76vMaxdBVVgoJrMe6KwwDTdY3vyTL+crvrGLuLFyiGdHRK4ao/nAH8fvoWj /MWPbTW7nAv1hsJPd8OpDCEw8bcm1BsiBQuNovXLl+FDnoDqR0URVzHfneluCXqSa/Pw rO4xXN5clg6s22r8Q7MrTSHmtAlrEB+CbMrRKPW64Y8zRxBNXSrck4HHXX1ITT1WU08G TPpaaqMydfyWcAJVC77iiwsPxKn3sx/Yk7aKxk2eenXOrJWMQg69MOVwjbNYIXTDdwXw Sbfw== X-Forwarded-Encrypted: i=1; AJvYcCXb5E+eF5KvkAXmdtAPpq7tvsdDeNCV6Af1Aef0J5nVz9tkWmdw6qc4nVBYZqn9msbRL1AHYDU5/JmiQyY=@vger.kernel.org X-Gm-Message-State: AOJu0Yxgcdoz8cufOZZibCTcpaf7QfJ9ANUJsXQUxnC6c1MGoG04Fr0+ JHSyF+ty3auXUh9iH9QkXDDsfKl/fkEv7edT09KJlWH1qe0q1ej/jAVmO1eTMUfgxilwt3f1j1k 6TVMDty6g1RE1/mTR6pdUHLskC/aFM7/9auaQQEZcrqXHA2ixpa7V/6PcEayRlTmWzeg= X-Gm-Gg: AY/fxX5b18SIBKi/U2puzax6boGzSfVWjpa8SklzxPWK8BM2nRSUzVbWT4lSus9bIbS +fWCbei4BaOpPpLnxkh3HLosT3XH3JeMmun33BD3F7PK4NdIAKPYOX68QFpALAXoHg5q5lF2fe+ IsYmTf1k02k5IYT4B9ySnualszmVa2anTJUutVc7MmGKkINo9XsbSBpAEbhhocH/zLDicRMhoqW QPDcPIilKBERCIVKiTMIS75gM2dnh3ksmjr2cNXQs/vxEgpn9Np/KXq3y9hlR3FvvXNiC52PhoK OMzFqDCaJUkV6u0odfy44rMMk38LwdBJFWTFIlofYoT1ciONzRoBJ4OxE/nWWK2vp7pk+sVbWwN 6AzdDgi0JpFwTqRVyQEwwwTSrr7GghNbnn4UEf2EWk9lDmeQhBw== X-Received: by 2002:a05:6a20:4306:b0:366:1e4c:e6dc with SMTP id adf61e73a8af0-369ad9d825amr18490216637.3.1766039073594; Wed, 17 Dec 2025 22:24:33 -0800 (PST) X-Google-Smtp-Source: AGHT+IHiyTPRMnsbhCkfiENIikkJGznn0RbyEhUjF2FXxdiraJgjxsN9O0XTm9l0bMUuqzjp/DDR5g== X-Received: by 2002:a05:6a20:4306:b0:366:1e4c:e6dc with SMTP id adf61e73a8af0-369ad9d825amr18490176637.3.1766039072988; Wed, 17 Dec 2025 22:24:32 -0800 (PST) Received: from hu-botlagun-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7fe0eb24d7dsm1433161b3a.0.2025.12.17.22.24.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 22:24:32 -0800 (PST) From: Venkata Gopi Nagaraju Botlagunta Date: Thu, 18 Dec 2025 11:54:07 +0530 Subject: [PATCH v3 1/2] dt-bindings: bridge: lt9211c: 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: <20251218-add-lt9211c-bridge-v3-1-1ee0670a0db2@oss.qualcomm.com> References: <20251218-add-lt9211c-bridge-v3-0-1ee0670a0db2@oss.qualcomm.com> In-Reply-To: <20251218-add-lt9211c-bridge-v3-0-1ee0670a0db2@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 , Marek Vasut Cc: dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Gopi Botlagunta , Nilesh Laad , venkata.valluru@oss.qualcomm.com, jessica.zhang@oss.qualcomm.com, Yi Zhang X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1766039060; l=3457; i=venkata.botlagunta@oss.qualcomm.com; s=20251110; h=from:subject:message-id; bh=7q9+o7KY/Qy4pzF2+VsQ5yxUwbBaD/W5k7jescl7Efs=; b=v8rkInL5CgcZZZvMO0StOu/K6sIaUsbER9QWkNYqLQ0+dJ6l61G3mD6ItJ96I9u/YmvmThdEG vnXVnw5+YvnB5psVbkKSRloXwjCkbGm2IG9WTfkkyT2qwi3OyPFbDe1 X-Developer-Key: i=venkata.botlagunta@oss.qualcomm.com; a=ed25519; pk=/SnYBwlkTzDCLnHFgEY0qFwPgKIV+aQWRbc3naiLzrk= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjE4MDA1MCBTYWx0ZWRfXziwUBMrcQThQ wkAPm/QMP/jKYxo+0+CcgpWgwc6tN5sCNYbFlfRxT3LH+cTae9bYmW46BGPPVYzyM62/7TYqtjK c4k5bg/1+A/qdYz4Ylk2z8n+v9zX7rnKIt/wun8IPZ3oi/f8cL3cIt+Czg0jZPtkezSVIdj7P22 6CIS8C4594EX769fxwHYlep+RRZy1MUoQmAa+8/rumUuEugnKWF8NDbAwDzHhvcGFhiUxZf8dIw EdhcqBvkLJWVnFHOf5Eks0Of2Y49GAFCU1Z0LlQ1jVzU6tQjcNSNj+cqkh9x9Ta42FPFqbYr2wZ k/dlUQMU7zlwSk5ppcsyhoyK1VgEYDVFzVkGDUTejUptm2Emjkb3USFRj2Rusee/rLZAGEnZgC6 SQlmMgoagfcjdt/z1bte1SjEJNNY1w== X-Proofpoint-GUID: gWV50dleqVqN_vZVdlhMo57IP_IPviDG X-Proofpoint-ORIG-GUID: gWV50dleqVqN_vZVdlhMo57IP_IPviDG X-Authority-Analysis: v=2.4 cv=EsHfbCcA c=1 sm=1 tr=0 ts=69439e22 cx=c_pps a=mDZGXZTwRPZaeRUbqKGCBw==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=wP3pNCr1ah4A:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=gEfo2CItAAAA:8 a=EUspDBNiAAAA:8 a=Xc6W96i5Xe6cDM1WBtQA:9 a=QEXdDO2ut3YA:10 a=zc0IvFSfCIW2DFIPzwfm:22 a=sptkURWiP4Gy88Gu7hUp: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-18_01,2025-12-17_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 bulkscore=0 priorityscore=1501 suspectscore=0 impostorscore=0 clxscore=1015 lowpriorityscore=0 phishscore=0 spamscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2512180050 From: Yi Zhang Add bindings for lt9211c. Signed-off-by: Yi Zhang Signed-off-by: Nilesh Laad Signed-off-by: Gopi Botlagunta --- .../bindings/display/bridge/lontium,lt9211c.yaml | 113 +++++++++++++++++= ++++ 1 file changed, 113 insertions(+) diff --git a/Documentation/devicetree/bindings/display/bridge/lontium,lt921= 1c.yaml b/Documentation/devicetree/bindings/display/bridge/lontium,lt9211c.= yaml new file mode 100644 index 000000000000..619f718618d6 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/lontium,lt9211c.yaml @@ -0,0 +1,113 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/lontium,lt9211c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Lontium LT9211C DSI/LVDS/DPI to DSI/LVDS/DPI bridge. + +maintainers: + - Marek Vasut + +description: | + The LT9211C are bridge devices which convert Single/Dual-Link DSI/LVDS + or Single DPI to Single/Dual-Link DSI/LVDS or Single DPI. + +properties: + compatible: + enum: + - lontium,lt9211c + + reg: + maxItems: 1 + + reset-gpios: + maxItems: 1 + description: GPIO connected to active high RESET pin. + + vccio-supply: + description: Regulator for 1.8V IO power. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: + Primary MIPI DSI port-1 for MIPI input or + LVDS port-1 for LVDS input or DPI input. + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: + Additional MIPI port-2 for MIPI input or LVDS port-2 + for LVDS input. Used in combination with primary + port-1 to drive higher resolution displays + + port@2: + $ref: /schemas/graph.yaml#/properties/port + description: + Primary MIPI DSI port-1 for MIPI output or + LVDS port-1 for LVDS output or DPI output. + + port@3: + $ref: /schemas/graph.yaml#/properties/port + description: + Additional MIPI port-2 for MIPI output or LVDS port-2 + for LVDS output. Used in combination with primary + port-1 to drive higher resolution displays. + + required: + - port@0 + - port@2 + +required: + - compatible + - reg + - vccio-supply + - ports + +additionalProperties: false + +examples: + - | + #include + #include + + i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + + lvds-bridge@3b { + compatible =3D "lontium,lt9211c"; + reg =3D <0x3b>; + + reset-gpios =3D <&tlmm 128 GPIO_ACTIVE_HIGH>; + + vccio-supply =3D <<9211c_1v8>; + + ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + port@0 { + reg =3D <0>; + + endpoint { + remote-endpoint =3D <&dsi0_out>; + }; + }; + + port@2 { + reg =3D <2>; + + endpoint { + remote-endpoint =3D <&panel_in_lvds>; + }; + }; + }; + }; + }; + +... --=20 2.34.1 From nobody Sun Feb 8 21:49:05 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 2576B320CCD for ; Thu, 18 Dec 2025 06:24:41 +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=1766039084; cv=none; b=YcHU3uCJ/6bwaQRUECSuTjSbARG5PeKyqffKaqE3fgglo3db+AgXUGveVWVqWLuSgQu0RwvfUwwwt9XreJu/rCiUVL1gyOxK+F8BPBpnmNCUlWLjDMbx/j9x4h+s/3t9CDJeMrXGFS7UnTiecWvMUGCuWZ+QQMMsVt6DFr6z78k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766039084; c=relaxed/simple; bh=421fNgLNR/rNAKKedij3CAFW0qOSGWTUZ5+OGQP0Lsg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qbcpMu6bKM4nBRfUa0ldFTvJ9PNXm7+u3aLsCK2IwNCDnDzCl8KbBDYsywhCFMYT3X6CZ+nZhGbCkmb5YvRHg69ehwdGRP6z6yfvPHCorWMRpW9sTZlohWV1SVnVmBYvL+7nVc+G+pl9gEMwuh4FWcj2vTbELcRqv+ZBk6dnu5w= 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=oZcWCyM0; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=U3YxqSGr; 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="oZcWCyM0"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="U3YxqSGr" 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 5BI1YfDP167607 for ; Thu, 18 Dec 2025 06:24:41 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= P/Uonx2pxi5wJyCworWRtzZG7D+KfVCQrD8PS8WCsDk=; b=oZcWCyM048CQ/z9A 3vt4VClizucwWRiySZD/r3z6R/RNQeOO0SJq8BNP3DbRuVQxHfaWA7+UoCAworu5 RFwK7686GZcgiYpbEkMUPHYaATI+tbj11LRaCTbw25HAvgjgC70gFaetsasPQMZ5 KCeZXtZuBhAB/cBbS56/dWDg61cnYY2Pyseq4Rr+Rwdsemx7eLcDPIQjYfDlYneL yV6c3ZgCjQXESRCg34ZR4EuoP10Z3MgK3ycvGm4kAUqZnLZ4ptxTgx0FDTY9RrDW ZzXDhPD6gMFs4khLiueAvgEjMuiEavuhlThODMxXMAeb/Pgx5VCU8nrpv4wK3fJ+ Jz0wqw== Received: from mail-pf1-f200.google.com (mail-pf1-f200.google.com [209.85.210.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4b45w511v9-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 18 Dec 2025 06:24:40 +0000 (GMT) Received: by mail-pf1-f200.google.com with SMTP id d2e1a72fcca58-7c240728e2aso672769b3a.3 for ; Wed, 17 Dec 2025 22:24:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1766039080; x=1766643880; 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=P/Uonx2pxi5wJyCworWRtzZG7D+KfVCQrD8PS8WCsDk=; b=U3YxqSGrm0kuT+rbgrn0Lm7XQ0l0146zurEUxuqqx7xLe5/txlDZ/5MQM+ZRnUZpMj jaBWJUuwlVSqVnQC/GQWSD0ctURIQS4fHRlxBi5Beq/USSDFoOW+8vVQpq0/wVG6xWUu A8xP7VoaElQBenisdiNjx5HkYbbe05dum+bBCx4TVPcVtOPj8lzF1srmsPrrD2tKjYKm OfRW+FPCjlkwE6sk8Gdy/v7bS8+kPRVo4dg/rlomW5ORI2Mw8dcaIxWv7ijYgVP7bk++ 8EtggpQwtFwMPSKLQUvmjI0lCd+1iXRnSV6ylX1AhBMCqF0EVtm/ULSdHIep1WUPRA1k +n+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766039080; x=1766643880; 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=P/Uonx2pxi5wJyCworWRtzZG7D+KfVCQrD8PS8WCsDk=; b=QGdZuyEdlSmEUGS23LeQrfJUqKn65x210/44RzotbIPgAPgCyIuTj7hlzw2I85GJDu hkcwdKkmkAHgK2VLjQk7o2zdzV9Up3z+a9S/9yRdhK7fQa15RVMs7Ib6lji3hdCLWCNG n7LothyawC/K7KO0Ihi3D3hMUPs1o/MKTci8NrJHd5rlMrhFU4qBCTUZ5CLp3eZJPg7M 0USOYbFEI+DCAdwE0GCRzqs84bH2rjfLRni3WVbRHC1BZfYoj9o+IrNKXyiKh21HlL68 CX5Ze+e5ctVymWcem9FcRf0zsy4KvCrwBSjVVpuZJF9WKrbyI6SV3cy7TsdMnVBcvFcR OFpw== X-Forwarded-Encrypted: i=1; AJvYcCWeJS4BVPzF+BX1ehSceyc/Cqd9zIdGPasVKu1NGc0tmh8kvujHV9iy41mbW1K87KVWH8HWoaPVIRjbroA=@vger.kernel.org X-Gm-Message-State: AOJu0Yxgh5SW4i/+vjr0dzZqrZTHZVN7/aw5NUmjXfhex0YHD7aD7ZR2 VpawTQqntKvDDMeKCUURb9r9V6s0ejmpdqLk4rbcQHOsxakaN4DMAg7CoanB4Z6Z/yEJGwkkwAM AndeZwqA29An1ErH/+FqD0WM6ktUJkD0XDcIBUojbrK26bCPEGDh+RlvBcyH2tU6MZjM= X-Gm-Gg: AY/fxX5sllLXOPcUmwTBs7o0aqZ38ky5GEqSjPxRTePNZVOo63612l7lXqUAUcN1seQ AHvCT4KamJ5gx0CjVbOMWdc6XciuqHUaquUNS/XYjxlyp+y5ErZkzXwpTzJxeXGJBvoht/N2Jhd IF1lJQoO++rBLJ9y3W2E5LZqL3Cigcun2LKusGi6uKq96SuRQJG6559eIHfkRolGhgmqSTJdGmv t9wG8HYvEu2wualVdEAEzJkQrWP1gVjS0AEgdmbeHYy4/54anq6ohdHVFkhU1bTdKBtfH+q+uTU 9oGwG6/eS8fSvT4GFlqasjiSqfnBXQuVYDFHV58HyqiCpWxUl5rqTQ5LsXwMZemR4irJHCNZ4ua Fi2tzk6RGQEzSoT/EAVrnoBQYmVbNQi+ogpeBPjTbJ7CbOpUL+Q== X-Received: by 2002:a05:6a00:4191:b0:7a2:7458:7fc8 with SMTP id d2e1a72fcca58-7f6674468bbmr20232269b3a.13.1766039080069; Wed, 17 Dec 2025 22:24:40 -0800 (PST) X-Google-Smtp-Source: AGHT+IFn8MKeP5Uegbkxo8MVJCnzjcaGk1boHA2EMMGlEzekEy/W5F94HanPjTjt72YdMzvNOpZCzQ== X-Received: by 2002:a05:6a00:4191:b0:7a2:7458:7fc8 with SMTP id d2e1a72fcca58-7f6674468bbmr20232243b3a.13.1766039079418; Wed, 17 Dec 2025 22:24:39 -0800 (PST) Received: from hu-botlagun-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7fe0eb24d7dsm1433161b3a.0.2025.12.17.22.24.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Dec 2025 22:24:39 -0800 (PST) From: Venkata Gopi Nagaraju Botlagunta Date: Thu, 18 Dec 2025 11:54:08 +0530 Subject: [PATCH v3 2/2] drm/bridge: add support for lontium lt9211c bridge 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: <20251218-add-lt9211c-bridge-v3-2-1ee0670a0db2@oss.qualcomm.com> References: <20251218-add-lt9211c-bridge-v3-0-1ee0670a0db2@oss.qualcomm.com> In-Reply-To: <20251218-add-lt9211c-bridge-v3-0-1ee0670a0db2@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 , Marek Vasut Cc: dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Gopi Botlagunta , Nilesh Laad , venkata.valluru@oss.qualcomm.com, jessica.zhang@oss.qualcomm.com, Yi Zhang X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1766039060; l=28270; i=venkata.botlagunta@oss.qualcomm.com; s=20251110; h=from:subject:message-id; bh=V2PQZz2IED13zxKTCdXA25xqbnt3RL/i+9UttWurYjQ=; b=Bs9xlhOHvt5aYb9jZWoqPsjWN7AcQ/Pz4udPt6/pZoFFyNGQXoeXq39ftSKlAbJEjIj+QVHU+ Vl60iGUeJKMBunyqkZ+wQGs7FwpudArv+mjaiBewS9X7XM1ymIRDt0r X-Developer-Key: i=venkata.botlagunta@oss.qualcomm.com; a=ed25519; pk=/SnYBwlkTzDCLnHFgEY0qFwPgKIV+aQWRbc3naiLzrk= X-Proofpoint-ORIG-GUID: NpARqTE4Ql7T7ckwKXFfP_u4D8EZmBe3 X-Authority-Analysis: v=2.4 cv=eKceTXp1 c=1 sm=1 tr=0 ts=69439e29 cx=c_pps a=mDZGXZTwRPZaeRUbqKGCBw==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=wP3pNCr1ah4A:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=EUspDBNiAAAA:8 a=997wjNfAVR2wvfQCef8A:9 a=QEXdDO2ut3YA:10 a=zc0IvFSfCIW2DFIPzwfm:22 X-Proofpoint-GUID: NpARqTE4Ql7T7ckwKXFfP_u4D8EZmBe3 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjE4MDA1MCBTYWx0ZWRfX299wZXlCDOoG 42Zvl/GjEHIKgZWc6PJvTAKwzTD5uWznRPH0qKdJi5YcUxjPNMBpIffrTT92aF66o6sglrxfsEl VhKol+T2fQFmLd6hw/zT6s14yQfzGK6ZPBw2BRu+qAmYiZpYsZKSn1xS9Yzbbu/ZmuPfvym42Ns QD8FpC+KGZqtuz7wm5JkRvcAaHD13EFM6BWxIdMVEUwExtEFEXZdN3Gk2fVqKo5boWUIhh6LtXh UrFUwltTS47dWw58aNyJQAdWBafWJ1vUTsC5X/+9NmK3ZhzfKf8Id7el0VvcwyqdXRL4ektWY9x r639wk+1IK58+RS41yful+1LK4w6kUFz9hc8vIYgJrbXmgNlW4VK8RpG8hrNH3GdxDrjlUXu8gn +Vl3POKQKm3TaZNNihbZyoNK9UcEuw== 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-18_01,2025-12-17_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 bulkscore=0 adultscore=0 clxscore=1015 malwarescore=0 spamscore=0 suspectscore=0 lowpriorityscore=0 impostorscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2512180050 From: Yi Zhang LT9211c is a Single/Dual-Link DSI/LVDS or Single DPI input to Single-link/Dual-Link DSI/LVDS or Single DPI output bridge chip. Extend the existing lontium-lt9211 driver to support DSI-to-LVDS bridge configuration. Signed-off-by: Yi Zhang Signed-off-by: Nilesh Laad Signed-off-by: Gopi Botlagunta --- drivers/gpu/drm/bridge/lontium-lt9211.c | 829 ++++++++++++++++++++++++++++= +--- 1 file changed, 768 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9211.c b/drivers/gpu/drm/brid= ge/lontium-lt9211.c index 399fa7eebd49..c8318bf81392 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9211.c +++ b/drivers/gpu/drm/bridge/lontium-lt9211.c @@ -19,6 +19,7 @@ #include #include #include +#include =20 #include #include @@ -36,20 +37,37 @@ #define REG_CHIPID2 0x8102 #define REG_CHIPID2_VALUE 0xe3 =20 +/* LT9211C chip ID values */ +#define REG_CHIPID0_LT9211C_VALUE 0x21 +#define REG_CHIPID1_LT9211C_VALUE 0x03 +#define REG_CHIPID2_LT9211C_VALUE 0xe1 + #define REG_DSI_LANE 0xd000 /* DSI lane count - 0 means 4 lanes ; 1, 2, 3 means 1, 2, 3 lanes. */ #define REG_DSI_LANE_COUNT(n) ((n) & 3) =20 +enum lt9211_chip_type { + LT9211, + LT9211C, +}; + struct lt9211 { struct drm_bridge bridge; struct device *dev; struct regmap *regmap; - struct mipi_dsi_device *dsi; + struct mipi_dsi_device *dsi; struct drm_bridge *panel_bridge; struct gpio_desc *reset_gpio; struct regulator *vccio; - bool lvds_dual_link; - bool lvds_dual_link_even_odd_swap; + bool lvds_dual_link; + bool lvds_dual_link_even_odd_swap; + enum lt9211_chip_type chip_type; + struct workqueue_struct *wq; + struct delayed_work lt9211_dw; + struct drm_display_mode mode; + bool bpp24; + bool jeida; + bool de; }; =20 static const struct regmap_range lt9211_rw_ranges[] =3D { @@ -70,6 +88,14 @@ static const struct regmap_access_table lt9211_rw_table = =3D { .n_yes_ranges =3D ARRAY_SIZE(lt9211_rw_ranges), }; =20 +static const struct mipi_dsi_device_info lt9211_info =3D { + "lt9211", 0, NULL +}; + +static const struct mipi_dsi_device_info lt9211c_info =3D { + "lt9211c", 0, NULL +}; + static const struct regmap_range_cfg lt9211_range =3D { .name =3D "lt9211", .range_min =3D 0x0000, @@ -93,6 +119,49 @@ static const struct regmap_config lt9211_regmap_config = =3D { .max_register =3D 0xda00, }; =20 +static const struct regmap_range lt9211c_rw_ranges[] =3D { + regmap_reg_range(0xff, 0xff), + regmap_reg_range(0x8100, 0x8182), + regmap_reg_range(0x8200, 0x82aa), + regmap_reg_range(0x8500, 0x85ff), + regmap_reg_range(0x8600, 0x86a0), + regmap_reg_range(0x8700, 0x8746), + regmap_reg_range(0xd000, 0xd0a7), + regmap_reg_range(0xd400, 0xd42c), + regmap_reg_range(0xd800, 0xd838), + regmap_reg_range(0xd9c0, 0xd9d5), +}; + +static const struct regmap_access_table lt9211c_rw_table =3D { + .yes_ranges =3D lt9211c_rw_ranges, + .n_yes_ranges =3D ARRAY_SIZE(lt9211c_rw_ranges), +}; + +static const struct regmap_range_cfg lt9211c_range =3D { + .name =3D "lt9211c", + .range_min =3D 0x0000, + .range_max =3D 0xda00, + .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 lt9211c_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + .rd_table =3D <9211c_rw_table, + .wr_table =3D <9211c_rw_table, + .volatile_table =3D <9211c_rw_table, + .ranges =3D <9211c_range, + .num_ranges =3D 1, + .cache_type =3D REGCACHE_RBTREE, + .max_register =3D 0xda00, +}; + +static void lt9211_delayed_work_func(struct work_struct *work); + static struct lt9211 *bridge_to_lt9211(struct drm_bridge *bridge) { return container_of(bridge, struct lt9211, bridge); @@ -120,15 +189,24 @@ static int lt9211_read_chipid(struct lt9211 *ctx) return ret; } =20 - /* Test for known Chip ID. */ - if (chipid[0] !=3D REG_CHIPID0_VALUE || chipid[1] !=3D REG_CHIPID1_VALUE = || - chipid[2] !=3D REG_CHIPID2_VALUE) { - dev_err(ctx->dev, "Unknown Chip ID: 0x%02x 0x%02x 0x%02x\n", - chipid[0], chipid[1], chipid[2]); - return -EINVAL; + /* Test for LT9211 Chip ID. */ + if (chipid[0] =3D=3D REG_CHIPID0_VALUE && chipid[1] =3D=3D REG_CHIPID1_VA= LUE && + chipid[2] =3D=3D REG_CHIPID2_VALUE) { + dev_dbg(ctx->dev, "Detected LT9211 chip\n"); + return 0; } =20 - return 0; + /* Test for LT9211C Chip ID. */ + if (chipid[0] =3D=3D REG_CHIPID0_LT9211C_VALUE && + chipid[1] =3D=3D REG_CHIPID1_LT9211C_VALUE && + chipid[2] =3D=3D REG_CHIPID2_LT9211C_VALUE) { + dev_dbg(ctx->dev, "Detected LT9211C chip\n"); + return 0; + } + + dev_err(ctx->dev, "Unknown Chip ID: 0x%02x 0x%02x 0x%02x\n", chipid[0], + chipid[1], chipid[2]); + return -EINVAL; } =20 static int lt9211_system_init(struct lt9211 *ctx) @@ -366,8 +444,8 @@ static int lt9211_configure_plls(struct lt9211 *ctx, return ret; } =20 -static int lt9211_configure_tx(struct lt9211 *ctx, bool jeida, - bool bpp24, bool de) +static int lt9211_configure_tx(struct lt9211 *ctx, bool jeida, bool bpp24, + bool de) { const struct reg_sequence system_lt9211_tx_phy_seq[] =3D { /* DPI output disable */ @@ -394,8 +472,8 @@ static int lt9211_configure_tx(struct lt9211 *ctx, bool= jeida, }; =20 const struct reg_sequence system_lt9211_tx_dig_seq[] =3D { - { 0x8559, 0x40 | (jeida ? BIT(7) : 0) | - (de ? BIT(5) : 0) | (bpp24 ? BIT(4) : 0) }, + { 0x8559, 0x40 | (jeida ? BIT(7) : 0) | (de ? BIT(5) : 0) | + (bpp24 ? BIT(4) : 0) }, { 0x855a, 0xaa }, { 0x855b, 0xaa }, { 0x855c, ctx->lvds_dual_link ? BIT(0) : 0 }, @@ -464,8 +542,6 @@ static void lt9211_atomic_enable(struct drm_bridge *bri= dge, const struct drm_display_mode *mode; struct drm_connector *connector; struct drm_crtc *crtc; - bool lvds_format_24bpp; - bool lvds_format_jeida; u32 bus_flags; int ret; =20 @@ -483,18 +559,19 @@ static void lt9211_atomic_enable(struct drm_bridge *b= ridge, bridge_state =3D drm_atomic_get_new_bridge_state(state, bridge); bus_flags =3D bridge_state->output_bus_cfg.flags; =20 + ctx->de =3D !!(bus_flags & DRM_BUS_FLAG_DE_HIGH); switch (bridge_state->output_bus_cfg.format) { case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: - lvds_format_24bpp =3D false; - lvds_format_jeida =3D true; + ctx->bpp24 =3D false; + ctx->jeida =3D true; break; case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: - lvds_format_24bpp =3D true; - lvds_format_jeida =3D true; + ctx->bpp24 =3D true; + ctx->jeida =3D true; break; case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: - lvds_format_24bpp =3D true; - lvds_format_jeida =3D false; + ctx->bpp24 =3D true; + ctx->jeida =3D false; break; default: /* @@ -502,8 +579,8 @@ static void lt9211_atomic_enable(struct drm_bridge *bri= dge, * LVDS bus pixel format, use SPWG24 default * format until those are fixed. */ - lvds_format_24bpp =3D true; - lvds_format_jeida =3D false; + ctx->bpp24 =3D true; + ctx->jeida =3D false; dev_warn(ctx->dev, "Unsupported LVDS bus format 0x%04x, please check output bridge driver= . Falling back to SPWG24.\n", bridge_state->output_bus_cfg.format); @@ -519,35 +596,42 @@ static void lt9211_atomic_enable(struct drm_bridge *b= ridge, crtc =3D drm_atomic_get_new_connector_state(state, connector)->crtc; crtc_state =3D drm_atomic_get_new_crtc_state(state, crtc); mode =3D &crtc_state->adjusted_mode; - ret =3D lt9211_read_chipid(ctx); if (ret) return; =20 - ret =3D lt9211_system_init(ctx); - if (ret) - return; - - ret =3D lt9211_configure_rx(ctx); - if (ret) - return; - - ret =3D lt9211_autodetect_rx(ctx, mode); - if (ret) - return; - - ret =3D lt9211_configure_timing(ctx, mode); - if (ret) - return; - - ret =3D lt9211_configure_plls(ctx, mode); - if (ret) - return; - - ret =3D lt9211_configure_tx(ctx, lvds_format_jeida, lvds_format_24bpp, - bus_flags & DRM_BUS_FLAG_DE_HIGH); - if (ret) - return; + if (ctx->chip_type =3D=3D LT9211C && ctx->wq) { + drm_mode_copy(&ctx->mode, mode); + /* LT9211C must enable after mipi clock enable */ + queue_delayed_work(ctx->wq, &ctx->lt9211_dw, + msecs_to_jiffies(100)); + } else if (ctx->chip_type =3D=3D LT9211) { + ret =3D lt9211_system_init(ctx); + if (ret) + return; + + ret =3D lt9211_configure_rx(ctx); + if (ret) + return; + + ret =3D lt9211_autodetect_rx(ctx, mode); + if (ret) + return; + + ret =3D lt9211_configure_timing(ctx, mode); + if (ret) + return; + + ret =3D lt9211_configure_plls(ctx, mode); + if (ret) + return; + + ret =3D lt9211_configure_tx(ctx, ctx->jeida, + ctx->bpp24, + ctx->de); + if (ret) + return; + } =20 dev_dbg(ctx->dev, "LT9211 enabled.\n"); } @@ -672,11 +756,6 @@ static int lt9211_parse_dt(struct lt9211 *ctx) =20 static int lt9211_host_attach(struct lt9211 *ctx) { - const struct mipi_dsi_device_info info =3D { - .type =3D "lt9211", - .channel =3D 0, - .node =3D NULL, - }; struct device *dev =3D ctx->dev; struct device_node *host_node; struct device_node *endpoint; @@ -698,7 +777,11 @@ static int lt9211_host_attach(struct lt9211 *ctx) if (dsi_lanes < 0) return dsi_lanes; =20 - dsi =3D devm_mipi_dsi_device_register_full(dev, host, &info); + if (ctx->chip_type =3D=3D LT9211C) + dsi =3D devm_mipi_dsi_device_register_full(dev, host, <9211c_info); + else + dsi =3D devm_mipi_dsi_device_register_full(dev, host, <9211_info); + if (IS_ERR(dsi)) return dev_err_probe(dev, PTR_ERR(dsi), "failed to create dsi device\n"); @@ -707,11 +790,17 @@ static int lt9211_host_attach(struct lt9211 *ctx) =20 dsi->lanes =3D dsi_lanes; dsi->format =3D MIPI_DSI_FMT_RGB888; - dsi->mode_flags =3D MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | - MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO_NO_HSA | - MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP | - MIPI_DSI_MODE_NO_EOT_PACKET; =20 + if (ctx->chip_type =3D=3D LT9211C) { + dsi->mode_flags =3D MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM; + } else { + dsi->mode_flags =3D + MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | + MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO_NO_HSA | + MIPI_DSI_MODE_VIDEO_NO_HFP | + MIPI_DSI_MODE_VIDEO_NO_HBP | + MIPI_DSI_MODE_NO_EOT_PACKET; + } ret =3D devm_mipi_dsi_attach(dev, dsi); if (ret < 0) { dev_err(dev, "failed to attach dsi to host: %d\n", ret); @@ -732,6 +821,7 @@ static int lt9211_probe(struct i2c_client *client) return PTR_ERR(ctx); =20 ctx->dev =3D dev; + ctx->chip_type =3D LT9211; =20 /* * Put the chip in reset, pull nRST line low, @@ -748,10 +838,24 @@ static int lt9211_probe(struct i2c_client *client) if (ret) return ret; =20 - ctx->regmap =3D devm_regmap_init_i2c(client, <9211_regmap_config); + if (of_device_is_compatible(dev->of_node, "lontium,lt9211c")) { + ctx->chip_type =3D LT9211C; + ctx->regmap =3D + devm_regmap_init_i2c(client, <9211c_regmap_config); + } else { + ctx->chip_type =3D LT9211; + ctx->regmap =3D + devm_regmap_init_i2c(client, <9211_regmap_config); + } if (IS_ERR(ctx->regmap)) return PTR_ERR(ctx->regmap); =20 + /* Initialize LT9211C-specific fields */ + ctx->wq =3D create_workqueue("lt9211_work"); + if (!ctx->wq) + return -ENOMEM; + INIT_DELAYED_WORK(&ctx->lt9211_dw, lt9211_delayed_work_func); + dev_set_drvdata(dev, ctx); i2c_set_clientdata(client, ctx); =20 @@ -769,17 +873,620 @@ static void lt9211_remove(struct i2c_client *client) { struct lt9211 *ctx =3D i2c_get_clientdata(client); =20 + if (ctx->wq) + destroy_workqueue(ctx->wq); + drm_bridge_remove(&ctx->bridge); } =20 -static const struct i2c_device_id lt9211_id[] =3D { +static int lt9211c_configure_rx(struct lt9211 *ctx) +{ + unsigned int pval; + + const struct reg_sequence lt9211c_rx_phy_seq[] =3D { + { REG_DSI_LANE, REG_DSI_LANE_COUNT(ctx->dsi->lanes) }, + { 0x8201, 0x11 }, + { 0x8218, 0x48 }, + { 0x8201, 0x91 }, + { 0x8202, 0x00 }, + { 0x8203, 0xee }, + { 0x8209, 0x21 }, + { 0x8204, 0x44 }, + { 0x8205, 0xc4 }, + { 0x8206, 0x44 }, + { 0x8213, 0x0c }, + + { 0xd001, 0x00 }, + { 0xd002, 0x0e }, + { 0xd005, 0x00 }, + { 0xd00a, 0x59 }, + { 0xd00b, 0x20 }, + }; + + const struct reg_sequence lt9211c_rx_phy_reset_seq[] =3D { + { 0x8109, 0xde }, + { 0x8109, 0xdf }, + }; + + const struct reg_sequence lt9211c_rx_clk_sel_seq[] =3D { + { 0x85e9, 0x88 }, + { 0x8180, 0x51 }, + { 0x8181, 0x10 }, + { 0x8632, 0x03 }, + }; + + const struct reg_sequence lt9211c_rx_input_sel_seq[] =3D { + { 0xd004, 0x00 }, + { 0xd021, 0x46 }, + }; + + const struct reg_sequence lt9211c_rx_dig_seq[] =3D { + { 0x853f, 0x08 }, { 0x8540, 0x04 }, { 0x8541, 0x03 }, + { 0x8542, 0x02 }, { 0x8543, 0x01 }, { 0x8545, 0x04 }, + { 0x8546, 0x03 }, { 0x8547, 0x02 }, { 0x8548, 0x01 }, + { 0x8544, 0x00 }, { 0x8549, 0x00 }, + }; + + int ret; + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_rx_phy_seq, + ARRAY_SIZE(lt9211c_rx_phy_seq)); + if (ret) + return ret; + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_rx_phy_reset_seq, + ARRAY_SIZE(lt9211c_rx_phy_reset_seq)); + if (ret) + return ret; + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_rx_clk_sel_seq, + ARRAY_SIZE(lt9211c_rx_clk_sel_seq)); + if (ret) + return ret; + ret =3D regmap_read(ctx->regmap, 0x8180, &pval); + if (ret) + return ret; + + ret =3D regmap_write(ctx->regmap, 0x8180, ((pval & 0xfc) | 0x03)); + if (ret) + return ret; + + ret =3D regmap_read(ctx->regmap, 0x8680, &pval); + if (ret) + return ret; + + ret =3D regmap_write(ctx->regmap, 0x863f, (pval & 0xf8)); + if (ret) + return ret; + + ret =3D regmap_write(ctx->regmap, 0x863f, 0x05); + if (ret) + return ret; + + ret =3D regmap_read(ctx->regmap, 0x8530, &pval); + if (ret) + return ret; + + ret =3D regmap_write(ctx->regmap, 0x8530, ((pval & 0xf8) | 0x11)); + if (ret) + return ret; + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_rx_input_sel_seq, + ARRAY_SIZE(lt9211c_rx_input_sel_seq)); + if (ret) + return ret; + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_rx_dig_seq, + ARRAY_SIZE(lt9211c_rx_dig_seq)); + if (ret) + return ret; + + /* Give the chip time to lock onto RX stream. */ + msleep(100); + + return 0; +} + +static int lt9211c_autodetect_rx(struct lt9211 *ctx, + const struct drm_display_mode *mode) +{ + u16 width, height; + u8 buf[5]; + u8 format; + u8 sot[8]; + int ret; + + /* Read the SOT from the chip. */ + ret =3D regmap_bulk_read(ctx->regmap, 0xd088, sot, sizeof(sot)); + if (ret) + return ret; + + dev_dbg(ctx->dev, "Sot Num =3D 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", sot[0], + sot[2], sot[4], sot[6]); + + dev_dbg(ctx->dev, "Sot Data =3D 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", sot[1], + sot[3], sot[5], sot[7]); + /* HS Settle Set */ + if ((sot[0] > 0x10) && (sot[0] < 0x50)) + regmap_write(ctx->regmap, 0xd002, sot[0] - 5); + else + regmap_write(ctx->regmap, 0xd002, 0x08); + + /* Width/Height/Format Auto-detection */ + ret =3D regmap_bulk_read(ctx->regmap, 0xd082, buf, sizeof(buf)); + if (ret) + return ret; + width =3D (buf[0] << 8) | buf[1]; + height =3D (buf[3] << 8) | buf[4]; + format =3D buf[2] & 0xf; + + if (format =3D=3D 0x3) { /* YUV422 16bit */ + width /=3D 2; + } else if (format =3D=3D 0xa) { /* RGB888 24bit */ + width /=3D 3; + } else { + dev_err(ctx->dev, "Unsupported DSI format 0x%01x\n", format); + return -EINVAL; + } + + if (width !=3D mode->hdisplay) { + dev_err(ctx->dev, + "RX: Detected DSI width (%d) does not match mode hdisplay (%d)\n", + width, mode->hdisplay); + return -EINVAL; + } + + if (height !=3D mode->vdisplay) { + dev_err(ctx->dev, + "RX: Detected DSI height (%d) does not match mode vdisplay (%d)\n", + height, mode->vdisplay); + return -EINVAL; + } + + dev_dbg(ctx->dev, "RX: %dx%d format=3D0x%01x\n", width, height, format); + return 0; +} + +static int lt9211c_configure_timing(struct lt9211 *ctx, + const struct drm_display_mode *mode) +{ + const struct reg_sequence lt9211c_timing[] =3D { + { 0xd00d, (mode->vtotal >> 8) & 0xff }, + { 0xd00e, mode->vtotal & 0xff }, + { 0xd00f, (mode->vdisplay >> 8) & 0xff }, + { 0xd010, mode->vdisplay & 0xff }, + { 0xd011, (mode->htotal >> 8) & 0xff }, + { 0xd012, mode->htotal & 0xff }, + { 0xd013, (mode->hdisplay >> 8) & 0xff }, + { 0xd014, mode->hdisplay & 0xff }, + { 0xd015, (mode->vsync_end - mode->vsync_start) & 0xff }, + { 0xd04c, ((mode->hsync_end - mode->hsync_start) >> 8) & 0xff }, + { 0xd016, (mode->hsync_end - mode->hsync_start) & 0xff }, + { 0xd017, ((mode->vsync_start - mode->vdisplay) >> 8) & 0xff }, + { 0xd018, (mode->vsync_start - mode->vdisplay) & 0xff }, + { 0xd019, ((mode->hsync_start - mode->hdisplay) >> 8) & 0xff }, + { 0xd01a, (mode->hsync_start - mode->hdisplay) & 0xff }, + }; + + return regmap_multi_reg_write(ctx->regmap, lt9211c_timing, + ARRAY_SIZE(lt9211c_timing)); +} + +static int lt9211c_configure_plls(struct lt9211 *ctx, + const struct drm_display_mode *mode) +{ + const struct reg_sequence lt9211c_dessc_pll_reset[] =3D { + { 0x8103, 0xfe, 2000 }, + { 0x8103, 0xff, 0 }, + }; + + const struct reg_sequence lt9211c_pcr_cali_seq[] =3D { + { 0xd00a, 0x5f }, { 0xd01e, 0x51 }, { 0xd023, 0x80 }, + { 0xd024, 0x70 }, { 0xd025, 0x80 }, { 0xd02a, 0x10 }, + { 0xd021, 0x4f }, { 0xd022, 0xf0 }, { 0xd038, 0x04 }, + { 0xd039, 0x08 }, { 0xd03a, 0x10 }, { 0xd03b, 0x20 }, + { 0xd03f, 0x04 }, { 0xd040, 0x08 }, { 0xd041, 0x10 }, + { 0xd042, 0x20 }, { 0xd02b, 0xA0 }, + }; + + const struct reg_sequence lt9211c_pcr_reset_seq[] =3D { + { 0xd009, 0xdb }, + { 0xd009, 0xdf }, + { 0xd008, 0x80 }, + { 0xd008, 0x00 }, + }; + + unsigned int pval; + int ret; + u8 div; + u32 pcr_m; + u32 pcr_k; + u32 pcr_up; + u32 pcr_down; + + /* DeSSC PLL reference clock is 25 MHz XTal. */ + ret =3D regmap_write(ctx->regmap, 0x8226, 0x20); + if (ret) + return ret; + + /* Prediv =3D 0 */ + ret =3D regmap_write(ctx->regmap, 0x8227, 0x40); + if (ret) + return ret; + + if (mode->clock < 22000) { + ret =3D regmap_write(ctx->regmap, 0x822f, 0x07); + ret |=3D regmap_write(ctx->regmap, 0x822c, 0x01); + div =3D 16; + } else if (mode->clock < 44000) { + ret =3D regmap_write(ctx->regmap, 0x822f, 0x07); + div =3D 16; + } else if (mode->clock < 88000) { + ret =3D regmap_write(ctx->regmap, 0x822f, 0x06); + div =3D 8; + } else if (mode->clock < 176000) { + ret =3D regmap_write(ctx->regmap, 0x822f, 0x05); + div =3D 4; + } else { + ret =3D regmap_write(ctx->regmap, 0x822f, 0x04); + div =3D 2; + } + + if (ret) + return ret; + + pcr_m =3D (mode->clock * div) / 25; + pcr_k =3D pcr_m % 1000; + pcr_m /=3D 1000; + + pcr_up =3D pcr_m + 1; + pcr_down =3D pcr_m - 1; + + pcr_k <<=3D 14; + + ret =3D regmap_write(ctx->regmap, 0xd008, 0x00); + if (ret < 0) + return ret; + + /* 0xd026: pcr_m */ + ret =3D regmap_write(ctx->regmap, 0xd026, (0x80 | (u8)pcr_m) & 0x7f); + if (ret < 0) + return ret; + + /* 0xd027 0xd028 0xd029: pcr_k */ + ret =3D regmap_write(ctx->regmap, 0xd027, (pcr_k >> 16) & 0xff); + if (ret < 0) + return ret; + + ret =3D regmap_write(ctx->regmap, 0xd028, (pcr_k >> 8) & 0xff); + if (ret < 0) + return ret; + + ret =3D regmap_write(ctx->regmap, 0xd029, pcr_k & 0xff); + if (ret < 0) + return ret; + + /* 0xd02d: pcr_m overflow limit setting */ + ret =3D regmap_write(ctx->regmap, 0xd02d, pcr_up); + if (ret < 0) + return ret; + + /* 0xd031: pcr_m underflow limit setting */ + ret =3D regmap_write(ctx->regmap, 0xd031, pcr_down); + if (ret < 0) + return ret; + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_dessc_pll_reset, + ARRAY_SIZE(lt9211c_dessc_pll_reset)); + if (ret) + return ret; + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_pcr_cali_seq, + ARRAY_SIZE(lt9211c_pcr_cali_seq)); + if (ret) + return ret; + + if (mode->clock < 44000) { + ret =3D regmap_write(ctx->regmap, 0xd00c, 0x60); + ret |=3D regmap_write(ctx->regmap, 0xd01b, 0x00); + ret |=3D regmap_write(ctx->regmap, 0xd01c, 0x60); + } else { + ret =3D regmap_write(ctx->regmap, 0xd00c, 0x40); + ret |=3D regmap_write(ctx->regmap, 0xd01b, 0x00); + ret |=3D regmap_write(ctx->regmap, 0xd01c, 0x40); + } + if (ret) + return ret; + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_pcr_reset_seq, + ARRAY_SIZE(lt9211c_pcr_reset_seq)); + if (ret) + return ret; + + /* PCR stability test takes seconds. */ + ret =3D regmap_read_poll_timeout(ctx->regmap, 0xd087, pval, + ((pval & 0x18) =3D=3D 0x18), 20000, 3000000); + if (ret) + dev_err(ctx->dev, "PCR unstable, ret=3D%i\n", ret); + + ret =3D regmap_write(ctx->regmap, 0x8180, 0x51); + if (ret) + return ret; + + ret =3D regmap_write(ctx->regmap, 0x863f, 0x00); + if (ret) + return ret; + + ret =3D regmap_write(ctx->regmap, 0x863f, 0x01); + if (ret) + return ret; + + ret =3D regmap_read_poll_timeout(ctx->regmap, 0x8640, pval, + ((pval & 0x01) =3D=3D 0x01), 50000, 250000); + if (ret) + dev_err(ctx->dev, "Video check not stable, ret=3D%i\n", ret); + + return ret; +} + +static int lt9211c_configure_tx(struct lt9211 *ctx, + const struct drm_display_mode *mode) +{ + const struct reg_sequence lt9211c_tx_phy_off_seq[] =3D { + { 0x8236, 0x00 }, + { 0x8237, 0x00 }, + { 0x8108, 0x6f }, + { 0x8103, 0xbf }, + }; + + const struct reg_sequence lt9211c_tx_phy_seq[] =3D { + { 0x8236, 0x03 }, { 0x8237, 0x44 }, { 0x8238, 0x14 }, + { 0x8239, 0x31 }, { 0x823a, 0xc8 }, { 0x823b, 0x00 }, + { 0x823c, 0x0f }, { 0x8246, 0x40 }, { 0x8247, 0x40 }, + { 0x8248, 0x40 }, { 0x8249, 0x40 }, { 0x824a, 0x40 }, + { 0x824b, 0x40 }, { 0x824c, 0x40 }, { 0x824d, 0x40 }, + { 0x824e, 0x40 }, { 0x824f, 0x40 }, { 0x8250, 0x40 }, + { 0x8251, 0x40 }, + }; + + const struct reg_sequence lt9211c_tx_mltx_reset[] =3D { + { 0x8103, 0xbf }, + { 0x8103, 0xff }, + }; + + const struct reg_sequence lt9211c_tx_dig_seq[] =3D { + { 0x854a, 0x01 }, + { 0x854b, 0x00 }, + { 0x854c, 0x10 }, + { 0x854d, 0x20 }, + { 0x854e, 0x50 }, + { 0x854f, 0x30 }, + { 0x8550, 0x46 }, + { 0x8551, 0x10 }, + { 0x8552, 0x20 }, + { 0x8553, 0x50 }, + { 0x8554, 0x30 }, + { 0x8555, 0x00 }, + { 0x8556, 0x20 }, + + { 0x8568, 0x00 }, + { 0x856e, 0x10 | (ctx->de ? BIT(6) : 0) }, + { 0x856f, 0x81 | (ctx->jeida ? BIT(6) : 0) | + (ctx->lvds_dual_link ? BIT(4) : 0) | + (ctx->bpp24 ? BIT(2) : 0) }, + }; + + const struct reg_sequence lt9211c_tx_ssc_seq[] =3D { + { 0x8234, 0x00 }, { 0x856e, 0x10 }, { 0x8181, 0x15 }, + { 0x871e, 0x00 }, { 0x8717, 0x02 }, { 0x8718, 0x04 }, + { 0x8719, 0xd4 }, { 0x871A, 0x00 }, { 0x871B, 0x12 }, + { 0x871C, 0x00 }, { 0x871D, 0x24 }, { 0x871F, 0x1c }, + { 0x8720, 0x00 }, { 0x8721, 0x00 }, { 0x871e, 0x02 }, + }; + + const struct reg_sequence lt9211c_tx_pll_reset_seq[] =3D { + { 0x810c, 0xfe, 2000 }, + { 0x810c, 0xff, 0 }, + }; + + const struct reg_sequence lt9211c_tx_sw_reset_seq[] =3D { + { 0x8108, 0x6f, 2000 }, + { 0x8108, 0x7f, 0 }, + }; + + unsigned int pval; + int ret; + u32 phy_clk; + u8 pixclk_div; + u8 pre_div; + u8 div_set; + u8 sericlk_div; + u8 val; + + dev_info(ctx->dev, + "dual_link=3D%d,even_odd_swap=3D%d,bpp24=3D%d,jeida=3D%d,de=3D%d\n", + ctx->lvds_dual_link, ctx->lvds_dual_link_even_odd_swap, + ctx->bpp24, ctx->jeida, ctx->de); + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_tx_phy_off_seq, + ARRAY_SIZE(lt9211c_tx_phy_off_seq)); + if (ret) + return ret; + + ret =3D regmap_read(ctx->regmap, 0x8530, &pval); + if (ret) + return ret; + + ret =3D regmap_write(ctx->regmap, 0x8530, ((pval & 0x3f) | 0x40)); + if (ret) + return ret; + + /* [7]0:txpll normal work; txpll ref clk sel pix clk */ + ret =3D regmap_write(ctx->regmap, 0x8230, 0x00); + if (ret) + return ret; + + if (ctx->lvds_dual_link) + phy_clk =3D (u32)(mode->clock * 7 / 2); + else + phy_clk =3D (u32)(mode->clock * 7); + + /* 0x8231: prediv sel */ + if (mode->clock < 20000) { + val =3D 0x28; + pre_div =3D 1; + } else if (mode->clock < 40000) { + val =3D 0x28; + pre_div =3D 1; + } else if (mode->clock < 80000) { + val =3D 0x29; + pre_div =3D 2; + } else if (mode->clock < 160000) { + val =3D 0x2a; + pre_div =3D 4; + } else if (mode->clock < 320000) { + val =3D 0x2b; + pre_div =3D 8; + } else { + val =3D 0x2f; + pre_div =3D 16; + } + ret =3D regmap_write(ctx->regmap, 0x8231, val); + if (ret < 0) + return ret; + + /* 0x8232: serickdiv sel */ + if (phy_clk < 80000) { + val =3D 0x32; + sericlk_div =3D 16; + } else if (phy_clk < 160000) { + val =3D 0x22; + sericlk_div =3D 8; + } else if (phy_clk < 320000) { + val =3D 0x12; + sericlk_div =3D 4; + } else if (phy_clk < 640000) { + val =3D 0x02; + sericlk_div =3D 2; + } else { + val =3D 0x42; + sericlk_div =3D 1; + } + ret =3D regmap_write(ctx->regmap, 0x8232, val); + if (ret < 0) + return ret; + + /* 0x8233: pix_mux sel & pix_div sel + * To avoid floating point operations, The pixclk_div is enlarged by 10 t= imes + */ + if (mode->clock > 150000) { + val =3D 0x04; + pixclk_div =3D 35; + } else { + pixclk_div =3D + (u8)((phy_clk * sericlk_div * 10) / (mode->clock * 7)); + if (pixclk_div <=3D 10) + val =3D 0x00; + else if (pixclk_div <=3D 20) + val =3D 0x01; + else if (pixclk_div <=3D 40) + val =3D 0x02; + else + val =3D 0x03; + } + ret =3D regmap_write(ctx->regmap, 0x8233, val); + if (ret < 0) + return ret; + + ret =3D regmap_write(ctx->regmap, 0x8234, 0x01); + if (ret < 0) + return ret; + + /* 0x8235: div set */ + div_set =3D (u8)(phy_clk * sericlk_div / mode->clock / pre_div); + ret =3D regmap_write(ctx->regmap, 0x8235, div_set); + if (ret < 0) + return ret; + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_tx_ssc_seq, + ARRAY_SIZE(lt9211c_tx_ssc_seq)); + if (ret) + return ret; + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_tx_pll_reset_seq, + ARRAY_SIZE(lt9211c_tx_pll_reset_seq)); + if (ret) + return ret; + + ret =3D regmap_read_poll_timeout(ctx->regmap, 0x8739, pval, pval & 0x04, + 10000, 1000000); + if (ret) { + dev_err(ctx->dev, "TX PLL unstable, ret=3D%i\n", ret); + return ret; + } + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_tx_phy_seq, + ARRAY_SIZE(lt9211c_tx_phy_seq)); + if (ret) + return ret; + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_tx_mltx_reset, + ARRAY_SIZE(lt9211c_tx_mltx_reset)); + if (ret) + return ret; + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_tx_dig_seq, + ARRAY_SIZE(lt9211c_tx_dig_seq)); + if (ret) + return ret; + + ret =3D regmap_multi_reg_write(ctx->regmap, lt9211c_tx_sw_reset_seq, + ARRAY_SIZE(lt9211c_tx_sw_reset_seq)); + if (ret) + return ret; + + return 0; +} + +static void lt9211_delayed_work_func(struct work_struct *work) +{ + struct delayed_work *dw =3D to_delayed_work(work); + struct lt9211 *ctx =3D container_of(dw, struct lt9211, lt9211_dw); + int ret; + const struct drm_display_mode *mode =3D &ctx->mode; + + /* For LT9211C */ + if (ctx->chip_type =3D=3D LT9211C) { + ret =3D lt9211c_configure_rx(ctx); + if (ret) + return; + ret =3D lt9211c_autodetect_rx(ctx, mode); + if (ret) + return; + ret =3D lt9211c_configure_timing(ctx, mode); + if (ret) + return; + ret =3D lt9211c_configure_plls(ctx, mode); + if (ret) + return; + ret =3D lt9211c_configure_tx(ctx, mode); + if (ret) + return; + } else { + dev_err(ctx->dev, "LT9211: Delayed work called for non-LT9211C chip\n"); + } +} + +static struct i2c_device_id lt9211_id[] =3D { { "lontium,lt9211" }, + { "lontium,lt9211c" }, {}, }; MODULE_DEVICE_TABLE(i2c, lt9211_id); =20 static const struct of_device_id lt9211_match_table[] =3D { { .compatible =3D "lontium,lt9211" }, + { .compatible =3D "lontium,lt9211c" }, {}, }; MODULE_DEVICE_TABLE(of, lt9211_match_table); --=20 2.34.1