From nobody Wed Oct 1 20:31:50 2025 Received: from PH7PR06CU001.outbound.protection.outlook.com (mail-westus3azon11010027.outbound.protection.outlook.com [52.101.201.27]) (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 50609279787; Wed, 1 Oct 2025 15:37:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.201.27 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759333053; cv=fail; b=XLY2n3iSn/j8YvTqQtFU42k38N4aMkL/D9roVbANDq1bRpON2URRiFwBDtD57+LNzTNet0+8Fv6trlbbJH1oDKFVxBpYahbo5TDyB1fptQBIMcmxVLSliZTD1Ib4EwC70sl3c0DIk03CYLmE75PDQxVgAuojpghluW0q5jjrInE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759333053; c=relaxed/simple; bh=ApfBCN3SDOZzGFmmQkdOQ1hrhnceu2/b3oLTiN8R6aw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=RjYnynrJhWkn/GoKorFUwvA6t5wf27yO7sJTCl+9ZzfYm3sCemW1fL+0SSWH/0HjAYEZsRT3aeWIyh0v9xSG2goyjD9lHP/5qOSX6siEiwJLJVJN51WZIBqPiupYcH8ADAHYg9Akn169hgwAEnfCM1GHHzsN6GCdv5MilBANbuQ= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=qDdL3eDt; arc=fail smtp.client-ip=52.101.201.27 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="qDdL3eDt" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=C8Iw6JZS+SrQuc6jkoDEyStLpL9LjTHf3+8110iam2KEAsqeVrYpL38HVOSegf9AGeEdpdB6mRS3rz6EtgTZ1GyqkDjYdP04ZYWIDek7vEK4MSyUVHNnI5BHGu/SgGzkCnv2wsTsXoGaMoRCOQ9L2m4OItJjMhXxL9eystZYfdXt3N0l/Y8RwB0OfBLSafL8SztGUNCQuPBrpztJta+2uHk/5kV8Siah+qmkfY4uHu6fvA7F4GcBPMv/PyGcGHhNrLwlYVUCQY5U1zkh3G63/sF7GHkioZlXjfJGHl4p1F3LSIB3Rg/UBmWqHACcrBFWypxnwVK5/UMRQvustKIRZg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ieO13i4WjwWlEXnlylVJQI4PpcQdcb3k99Rlz55Jkac=; b=cPpuYwm6jzraPYh4/i1r5eZhYJRSyf4eLqDmEsJKIOk0/e2iN6mppsGaWo+Y2oPdDpjFlJbHRR7UbBiuA+NmuM50xCPq+DjZtq9XWBKgrwllF78jnLTrHHB1Cc56BSvuVp2E+h/cA5Yfa6m58SxH2m8ryFXFojKaLssN0HMrk+/Sy2SlUSKl9hZe32xK5Nfk59yiSyRlZxMxguYQFayDXTh04GDiPPG+PeISPKKDcozEfa+hC64EiL5rIPcfiVhRGnQyQKVgjpLPm37r7iecyRAsiS7nLocz0+2VnjNtS+kKWcf1Knl90Yr+RoKLZlk1aSZmMOE+GmRZOoDJgf2EGQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.161) smtp.rcpttodomain=kernel.org smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ieO13i4WjwWlEXnlylVJQI4PpcQdcb3k99Rlz55Jkac=; b=qDdL3eDtodLeq9IH3F6axsag7WX1YDgnETPLcSTLB1usP2nUeBpJYT9SQC2diPT9K++rsT7cp7De7p1f884EkqRm3/4LpWbvrHX4BgkS/vFWQ1q+OdRtxmahuElnSs6/AWuf8b7RpqxD+tTQvNQKrDTKrjF9B6La3LskOqKHN5Yn5DSFWa2a688YtK20IxRR8heCHW8zCfaQgpKyfU1ueQmD6AJ45sx17KNpUUVefmAKaivAhgdZy0az3ptKnmo3cSyH4dopdzWq0FHY0MeUedB2OYQZf/x2vffG9rUUycuROBquw9MqUMgm10Hb7ooGkHXJ6QLqIWfPtzWaJ3Gh1g== Received: from CH0PR03CA0414.namprd03.prod.outlook.com (2603:10b6:610:11b::32) by CY5PR12MB6384.namprd12.prod.outlook.com (2603:10b6:930:3c::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9160.18; Wed, 1 Oct 2025 15:37:16 +0000 Received: from CH3PEPF00000018.namprd21.prod.outlook.com (2603:10b6:610:11b:cafe::30) by CH0PR03CA0414.outlook.office365.com (2603:10b6:610:11b::32) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9160.17 via Frontend Transport; Wed, 1 Oct 2025 15:37:14 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.161) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.117.161 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.161; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.117.161) by CH3PEPF00000018.mail.protection.outlook.com (10.167.244.123) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9203.1 via Frontend Transport; Wed, 1 Oct 2025 15:37:14 +0000 Received: from rnnvmail202.nvidia.com (10.129.68.7) by mail.nvidia.com (10.129.200.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.14; Wed, 1 Oct 2025 08:37:00 -0700 Received: from rnnvmail203.nvidia.com (10.129.68.9) by rnnvmail202.nvidia.com (10.129.68.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20; Wed, 1 Oct 2025 08:36:59 -0700 Received: from kkartik-desktop.nvidia.com (10.127.8.13) by mail.nvidia.com (10.129.68.9) with Microsoft SMTP Server id 15.2.2562.20 via Frontend Transport; Wed, 1 Oct 2025 08:36:55 -0700 From: Kartik Rajput To: , , , , , , , , , , , , , CC: Subject: [PATCH 1/2] i2c: tegra: Add logic to support different register offsets Date: Wed, 1 Oct 2025 21:06:47 +0530 Message-ID: <20251001153648.667036-2-kkartik@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251001153648.667036-1-kkartik@nvidia.com> References: <20251001153648.667036-1-kkartik@nvidia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH3PEPF00000018:EE_|CY5PR12MB6384:EE_ X-MS-Office365-Filtering-Correlation-Id: fb6e6a41-8ec9-48a6-fad5-08de0100653f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|7416014|82310400026|1800799024|36860700013|921020; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?QaygtwqV4B3MprOI06ziaSmEWpBg5A5Qa4qf2TspF40X1/euRDPz1XjDdN1g?= =?us-ascii?Q?hF29SEaIX9W8VtbHRrjn+Qd3QRIGsuaEUvTgP4dN9MIpaSJ4vYxqijNWydeU?= =?us-ascii?Q?h1cVnid4FyPhxj/PvVREJBHOThfYEsJMljmu5JHzys77eClk1ORViTpuPaP+?= =?us-ascii?Q?yBml6RU6QFzLH/bcDC5SDW0jWW/TEo9ZmyeG9mhFznLc5sn+QGoV9eskoIDo?= =?us-ascii?Q?wKIt96xk2sJWPf6KFymrMn4242TyrD7ReEvWqFzO5YRE82qs44QhH6CSMSEi?= =?us-ascii?Q?9RwccnMryVmjjRLFXOnQMoDvWp/13L0J93TuUq5OrtH3QXSp1wYYEUJXdOO9?= =?us-ascii?Q?ZFqoTIcl8QcB07Ly1hXUEY38qolb2tNgBkskA6PVFnGVQsWBv28EBAjL7yNu?= =?us-ascii?Q?/2HdPPao7tC0w5H5dM8n0jhgsDsPf2Tqf+Xbs0RUpxvIBnbG3ZhSsyeHde7W?= =?us-ascii?Q?nuutiCJce6BNL3ozLTZLq5Tq4l/88lCCJryuP+yS9j5NDvAcA0It3iDclw2z?= =?us-ascii?Q?KvrJTwn/m5vIY3SoV1H2SVRfl9ok2IF1Fj1fw8BPaAEXZpYJdAvvbT1WDCGU?= =?us-ascii?Q?3cmqVMSLsHQeNtPBh59YLQg7g2D5HWcma2DvJxcme82H/GLgxmzU1AFhV0zT?= =?us-ascii?Q?vZ6Nj4xX4g9CsSyxK7T9okPH1Dpmp4nX0XCQxYsJ7IJmMJf0yellSzI4sWnG?= =?us-ascii?Q?DPl5jnr27zAzn616MF2qBFlYmjP4zskOgLSWQi1j/16A627lhXaSIkqETaiK?= =?us-ascii?Q?PpRRx6PuByi80v8l77Zt1JTuZSCfo0pxVN0IgSatTcwYlmmLxhwL7+xxgtGU?= =?us-ascii?Q?h0LZgqUtkzfDD3bH3yzkv3azT9DMjKufWoPgvjNEMos5htPXGsY4bOqQ+Lad?= =?us-ascii?Q?jR8wp9GHjbtmU96lZkYmqLp2AV5Q9lpWmGE+fLuJbb8p5gQZMk1evxHOHn6f?= =?us-ascii?Q?QeofUGf1z5zRdKaxsU5E4H25d+cNxtv5j2ZK5dAvVsOuxJH7hn51s1c58Guj?= =?us-ascii?Q?t38vYTJ01kXgttqO4coRDPlIHOjJwDKgMzk3+jnVpiEVf2efss5hnnnuScOA?= =?us-ascii?Q?qgYuv3JLuDNaAGbxZVja12cmjbFLlLYXxTDUAghOy7Qe5htQAL+ZMah6KPkb?= =?us-ascii?Q?x23275fS4iGyCNKdVF4syDQHVAjqtg20MnIoJcuL6TWas4p+0/hkI0ohMYW/?= =?us-ascii?Q?Nnzl6KFllW+HiiTY9OlI7IfiHjWFkUjYzvslkiKTm8PwkcI1VOGfE3PC4xii?= =?us-ascii?Q?yQDpGFV25U+/wnXStgbOJUNtlTlB5moq+v5mDZswNvfUvaXndWSx8B4bvKbG?= =?us-ascii?Q?Ioe5RCV/0Ls2TeyoyGYbvxObOHZMIEIggJ3yT20HRRRjFNGj+NvLVlT49y80?= =?us-ascii?Q?BKTHWmpJdUvPnOZtTYmYY0g7WhOnCeQlwscrz/HUO9TlSyHH4dfIW/pahXJS?= =?us-ascii?Q?cvALqKA7A2Vz9/+D2IdrFv3ft3/T1WxoOY1ABBShpoZnS2EgXeLbZV4IHam4?= =?us-ascii?Q?PhqiBi5sYsBlPWWLawxIbj28+xRk32Qo2d9aSBO11utacAe4DtryF/Ia2ZRY?= =?us-ascii?Q?jAbs7YZ6GzgG+bVCnsYHCfJDvAfttuQksnrKQuaC?= X-Forefront-Antispam-Report: CIP:216.228.117.161;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc6edge2.nvidia.com;CAT:NONE;SFS:(13230040)(376014)(7416014)(82310400026)(1800799024)(36860700013)(921020);DIR:OUT;SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Oct 2025 15:37:14.2005 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: fb6e6a41-8ec9-48a6-fad5-08de0100653f X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.117.161];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: CH3PEPF00000018.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY5PR12MB6384 Content-Type: text/plain; charset="utf-8" Tegra410 use different offsets for existing I2C registers, update the logic to use appropriate offsets per SoC. Signed-off-by: Kartik Rajput --- drivers/i2c/busses/i2c-tegra.c | 499 ++++++++++++++++++++++----------- 1 file changed, 334 insertions(+), 165 deletions(-) diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 038809264526..1e26d67cbd30 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -30,47 +30,35 @@ =20 #define BYTES_PER_FIFO_WORD 4 =20 -#define I2C_CNFG 0x000 #define I2C_CNFG_DEBOUNCE_CNT GENMASK(14, 12) #define I2C_CNFG_PACKET_MODE_EN BIT(10) #define I2C_CNFG_NEW_MASTER_FSM BIT(11) #define I2C_CNFG_MULTI_MASTER_MODE BIT(17) -#define I2C_STATUS 0x01c -#define I2C_SL_CNFG 0x020 + #define I2C_SL_CNFG_NACK BIT(1) #define I2C_SL_CNFG_NEWSL BIT(2) -#define I2C_SL_ADDR1 0x02c -#define I2C_SL_ADDR2 0x030 -#define I2C_TLOW_SEXT 0x034 -#define I2C_TX_FIFO 0x050 -#define I2C_RX_FIFO 0x054 -#define I2C_PACKET_TRANSFER_STATUS 0x058 -#define I2C_FIFO_CONTROL 0x05c + #define I2C_FIFO_CONTROL_TX_FLUSH BIT(1) #define I2C_FIFO_CONTROL_RX_FLUSH BIT(0) #define I2C_FIFO_CONTROL_TX_TRIG(x) (((x) - 1) << 5) #define I2C_FIFO_CONTROL_RX_TRIG(x) (((x) - 1) << 2) -#define I2C_FIFO_STATUS 0x060 #define I2C_FIFO_STATUS_TX GENMASK(7, 4) #define I2C_FIFO_STATUS_RX GENMASK(3, 0) -#define I2C_INT_MASK 0x064 -#define I2C_INT_STATUS 0x068 + #define I2C_INT_BUS_CLR_DONE BIT(11) #define I2C_INT_PACKET_XFER_COMPLETE BIT(7) #define I2C_INT_NO_ACK BIT(3) #define I2C_INT_ARBITRATION_LOST BIT(2) #define I2C_INT_TX_FIFO_DATA_REQ BIT(1) #define I2C_INT_RX_FIFO_DATA_REQ BIT(0) -#define I2C_CLK_DIVISOR 0x06c + #define I2C_CLK_DIVISOR_STD_FAST_MODE GENMASK(31, 16) #define I2C_CLK_DIVISOR_HSMODE GENMASK(15, 0) =20 -#define DVC_CTRL_REG1 0x000 #define DVC_CTRL_REG1_INTR_EN BIT(10) -#define DVC_CTRL_REG3 0x008 #define DVC_CTRL_REG3_SW_PROG BIT(26) #define DVC_CTRL_REG3_I2C_DONE_INTR_EN BIT(30) -#define DVC_STATUS 0x00c + #define DVC_STATUS_I2C_DONE_INTR BIT(30) =20 #define I2C_ERR_NONE 0x00 @@ -94,50 +82,37 @@ #define I2C_HEADER_HS_MODE BIT(22) #define I2C_HEADER_SLAVE_ADDR_SHIFT 1 =20 -#define I2C_BUS_CLEAR_CNFG 0x084 #define I2C_BC_SCLK_THRESHOLD GENMASK(23, 16) #define I2C_BC_STOP_COND BIT(2) #define I2C_BC_TERMINATE BIT(1) #define I2C_BC_ENABLE BIT(0) -#define I2C_BUS_CLEAR_STATUS 0x088 #define I2C_BC_STATUS BIT(0) =20 -#define I2C_CONFIG_LOAD 0x08c #define I2C_MSTR_CONFIG_LOAD BIT(0) =20 -#define I2C_CLKEN_OVERRIDE 0x090 #define I2C_MST_CORE_CLKEN_OVR BIT(0) =20 -#define I2C_INTERFACE_TIMING_0 0x094 -#define I2C_INTERFACE_TIMING_THIGH GENMASK(13, 8) -#define I2C_INTERFACE_TIMING_TLOW GENMASK(5, 0) -#define I2C_INTERFACE_TIMING_1 0x098 -#define I2C_INTERFACE_TIMING_TBUF GENMASK(29, 24) -#define I2C_INTERFACE_TIMING_TSU_STO GENMASK(21, 16) -#define I2C_INTERFACE_TIMING_THD_STA GENMASK(13, 8) -#define I2C_INTERFACE_TIMING_TSU_STA GENMASK(5, 0) - -#define I2C_HS_INTERFACE_TIMING_0 0x09c -#define I2C_HS_INTERFACE_TIMING_THIGH GENMASK(13, 8) -#define I2C_HS_INTERFACE_TIMING_TLOW GENMASK(5, 0) -#define I2C_HS_INTERFACE_TIMING_1 0x0a0 -#define I2C_HS_INTERFACE_TIMING_TSU_STO GENMASK(21, 16) -#define I2C_HS_INTERFACE_TIMING_THD_STA GENMASK(13, 8) -#define I2C_HS_INTERFACE_TIMING_TSU_STA GENMASK(5, 0) - -#define I2C_MST_FIFO_CONTROL 0x0b4 +#define I2C_INTERFACE_TIMING_THIGH GENMASK(13, 8) +#define I2C_INTERFACE_TIMING_TLOW GENMASK(5, 0) +#define I2C_INTERFACE_TIMING_TBUF GENMASK(29, 24) +#define I2C_INTERFACE_TIMING_TSU_STO GENMASK(21, 16) +#define I2C_INTERFACE_TIMING_THD_STA GENMASK(13, 8) +#define I2C_INTERFACE_TIMING_TSU_STA GENMASK(5, 0) + +#define I2C_HS_INTERFACE_TIMING_THIGH GENMASK(13, 8) +#define I2C_HS_INTERFACE_TIMING_TLOW GENMASK(5, 0) +#define I2C_HS_INTERFACE_TIMING_TSU_STO GENMASK(21, 16) +#define I2C_HS_INTERFACE_TIMING_THD_STA GENMASK(13, 8) +#define I2C_HS_INTERFACE_TIMING_TSU_STA GENMASK(5, 0) + #define I2C_MST_FIFO_CONTROL_RX_FLUSH BIT(0) #define I2C_MST_FIFO_CONTROL_TX_FLUSH BIT(1) #define I2C_MST_FIFO_CONTROL_RX_TRIG(x) (((x) - 1) << 4) #define I2C_MST_FIFO_CONTROL_TX_TRIG(x) (((x) - 1) << 16) =20 -#define I2C_MST_FIFO_STATUS 0x0b8 #define I2C_MST_FIFO_STATUS_TX GENMASK(23, 16) #define I2C_MST_FIFO_STATUS_RX GENMASK(7, 0) =20 -#define I2C_MASTER_RESET_CNTRL 0x0a8 - -#define I2C_SW_MUTEX 0x0ec #define I2C_SW_MUTEX_REQUEST GENMASK(3, 0) #define I2C_SW_MUTEX_GRANT GENMASK(7, 4) #define I2C_SW_MUTEX_ID_CCPLEX 9 @@ -159,6 +134,134 @@ */ #define I2C_PIO_MODE_PREFERRED_LEN 32 =20 +struct tegra_i2c_regs { + unsigned int cnfg; + unsigned int status; + unsigned int sl_cnfg; + unsigned int sl_addr1; + unsigned int sl_addr2; + unsigned int tlow_sext; + unsigned int tx_fifo; + unsigned int rx_fifo; + unsigned int packet_transfer_status; + unsigned int fifo_control; + unsigned int fifo_status; + unsigned int int_mask; + unsigned int int_status; + unsigned int clk_divisor; + unsigned int bus_clear_cnfg; + unsigned int bus_clear_status; + unsigned int config_load; + unsigned int clken_override; + unsigned int interface_timing_0; + unsigned int interface_timing_1; + unsigned int hs_interface_timing_0; + unsigned int hs_interface_timing_1; + unsigned int master_reset_cntrl; + unsigned int mst_fifo_control; + unsigned int mst_fifo_status; + unsigned int sw_mutex; + unsigned int dvc_ctrl_reg1; + unsigned int dvc_ctrl_reg3; + unsigned int dvc_status; +}; + +static const struct tegra_i2c_regs tegra20_i2c_regs =3D { + .cnfg =3D 0x000, + .status =3D 0x01c, + .sl_cnfg =3D 0x020, + .sl_addr1 =3D 0x02c, + .sl_addr2 =3D 0x030, + .tlow_sext =3D 0x034, + .tx_fifo =3D 0x050, + .rx_fifo =3D 0x054, + .packet_transfer_status =3D 0x058, + .fifo_control =3D 0x05c, + .fifo_status =3D 0x060, + .int_mask =3D 0x064, + .int_status =3D 0x068, + .clk_divisor =3D 0x06c, + .bus_clear_cnfg =3D 0x084, + .bus_clear_status =3D 0x088, + .config_load =3D 0x08c, + .clken_override =3D 0x090, + .interface_timing_0 =3D 0x094, + .interface_timing_1 =3D 0x098, + .hs_interface_timing_0 =3D 0x09c, + .hs_interface_timing_1 =3D 0x0a0, + .master_reset_cntrl =3D 0x0a8, + .mst_fifo_control =3D 0x0b4, + .mst_fifo_status =3D 0x0b8, + .sw_mutex =3D 0x0ec, + .dvc_ctrl_reg1 =3D 0x000, + .dvc_ctrl_reg3 =3D 0x008, + .dvc_status =3D 0x00c, +}; + +static const struct tegra_i2c_regs tegra20_i2c_regs_dvc =3D { + .cnfg =3D 0x000 + 0x40, + .status =3D 0x01c + 0x40, + .sl_cnfg =3D 0x020 + 0x40, + .sl_addr1 =3D 0x02c + 0x40, + .sl_addr2 =3D 0x030 + 0x40, + .tlow_sext =3D 0x034 + 0x40, + .tx_fifo =3D 0x050 + 0x10, + .rx_fifo =3D 0x054 + 0x10, + .packet_transfer_status =3D 0x058 + 0x10, + .fifo_control =3D 0x05c + 0x10, + .fifo_status =3D 0x060 + 0x10, + .int_mask =3D 0x064 + 0x10, + .int_status =3D 0x068 + 0x10, + .clk_divisor =3D 0x06c + 0x10, + .bus_clear_cnfg =3D 0x084 + 0x40, + .bus_clear_status =3D 0x088 + 0x40, + .config_load =3D 0x08c + 0x40, + .clken_override =3D 0x090 + 0x40, + .interface_timing_0 =3D 0x094 + 0x40, + .interface_timing_1 =3D 0x098 + 0x40, + .hs_interface_timing_0 =3D 0x09c + 0x40, + .hs_interface_timing_1 =3D 0x0a0 + 0x40, + .master_reset_cntrl =3D 0x0a8 + 0x40, + .mst_fifo_control =3D 0x0b4 + 0x10, + .mst_fifo_status =3D 0x0b8 + 0x10, + .sw_mutex =3D 0x0ec + 0x40, + .dvc_ctrl_reg1 =3D 0x000, + .dvc_ctrl_reg3 =3D 0x008, + .dvc_status =3D 0x00c, +}; + +static const struct tegra_i2c_regs tegra20_i2c_regs_vi =3D { + .cnfg =3D 0x0c00 + (0x000 << 2), + .status =3D 0x0c00 + (0x01c << 2), + .sl_cnfg =3D 0x0c00 + (0x020 << 2), + .sl_addr1 =3D 0x0c00 + (0x02c << 2), + .sl_addr2 =3D 0x0c00 + (0x030 << 2), + .tlow_sext =3D 0x0c00 + (0x034 << 2), + .tx_fifo =3D 0x0c00 + (0x050 << 2), + .rx_fifo =3D 0x0c00 + (0x054 << 2), + .packet_transfer_status =3D 0x0c00 + (0x058 << 2), + .fifo_control =3D 0x0c00 + (0x05c << 2), + .fifo_status =3D 0x0c00 + (0x060 << 2), + .int_mask =3D 0x0c00 + (0x064 << 2), + .int_status =3D 0x0c00 + (0x068 << 2), + .clk_divisor =3D 0x0c00 + (0x06c << 2), + .bus_clear_cnfg =3D 0x0c00 + (0x084 << 2), + .bus_clear_status =3D 0x0c00 + (0x088 << 2), + .config_load =3D 0x0c00 + (0x08c << 2), + .clken_override =3D 0x0c00 + (0x090 << 2), + .interface_timing_0 =3D 0x0c00 + (0x094 << 2), + .interface_timing_1 =3D 0x0c00 + (0x098 << 2), + .hs_interface_timing_0 =3D 0x0c00 + (0x09c << 2), + .hs_interface_timing_1 =3D 0x0c00 + (0x0a0 << 2), + .master_reset_cntrl =3D 0x0c00 + (0x0a8 << 2), + .mst_fifo_control =3D 0x0c00 + (0x0b4 << 2), + .mst_fifo_status =3D 0x0c00 + (0x0b8 << 2), + .sw_mutex =3D 0x0c00 + (0x0ec << 2), + .dvc_ctrl_reg1 =3D 0x000, + .dvc_ctrl_reg3 =3D 0x008, + .dvc_status =3D 0x00c, +}; + /* * msg_end_type: The bus control which needs to be sent at end of transfer. * @MSG_END_STOP: Send stop pulse. @@ -219,6 +322,9 @@ enum msg_end_type { * timing settings. * @has_hs_mode_support: Has support for high speed (HS) mode transfers. * @has_mutex: Has mutex register for mutual exclusion with other firmware= s or VMs. + * @is_dvc: This instance represents the DVC I2C controller variant. + * @is_vi: This instance represents the VI I2C controller variant. + * @regs: Register offsets for the specific SoC variant. */ struct tegra_i2c_hw_feature { bool has_continue_xfer_support; @@ -247,6 +353,9 @@ struct tegra_i2c_hw_feature { bool has_interface_timing_reg; bool has_hs_mode_support; bool has_mutex; + bool is_dvc; + bool is_vi; + const struct tegra_i2c_regs *regs; }; =20 /** @@ -262,8 +371,6 @@ struct tegra_i2c_hw_feature { * @base_phys: physical base address of the I2C controller * @cont_id: I2C controller ID, used for packet header * @irq: IRQ number of transfer complete interrupt - * @is_dvc: identifies the DVC I2C controller, has a different register la= yout - * @is_vi: identifies the VI I2C controller, has a different register layo= ut * @msg_complete: transfer completion notifier * @msg_buf_remaining: size of unsent data in the message buffer * @msg_len: length of message in current transfer @@ -316,12 +423,10 @@ struct tegra_i2c_dev { bool atomic_mode; bool dma_mode; bool msg_read; - bool is_dvc; - bool is_vi; }; =20 -#define IS_DVC(dev) (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && (dev)->is_dvc) -#define IS_VI(dev) (IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) && (dev)->is_vi) +#define IS_DVC(dev) (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && (dev)->hw->is= _dvc) +#define IS_VI(dev) (IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) && (dev)->hw->i= s_vi) =20 static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned int reg) @@ -334,40 +439,26 @@ static u32 dvc_readl(struct tegra_i2c_dev *i2c_dev, u= nsigned int reg) return readl_relaxed(i2c_dev->base + reg); } =20 -/* - * If necessary, i2c_writel() and i2c_readl() will offset the register - * in order to talk to the I2C block inside the DVC block. - */ -static u32 tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev, unsigned int = reg) -{ - if (IS_DVC(i2c_dev)) - reg +=3D (reg >=3D I2C_TX_FIFO) ? 0x10 : 0x40; - else if (IS_VI(i2c_dev)) - reg =3D 0xc00 + (reg << 2); - - return reg; -} - static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned in= t reg) { - writel_relaxed(val, i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg)); + writel_relaxed(val, i2c_dev->base + reg); =20 /* read back register to make sure that register writes completed */ - if (reg !=3D I2C_TX_FIFO) - readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg)); + if (reg !=3D i2c_dev->hw->regs->tx_fifo) + readl_relaxed(i2c_dev->base + reg); else if (IS_VI(i2c_dev)) - readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, I2C_INT_STATUS= )); + readl_relaxed(i2c_dev->base + i2c_dev->hw->regs->int_status); } =20 static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned int reg) { - return readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg)); + return readl_relaxed(i2c_dev->base + reg); } =20 static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data, unsigned int reg, unsigned int len) { - writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len); + writesl(i2c_dev->base + reg, data, len); } =20 static void i2c_writesl_vi(struct tegra_i2c_dev *i2c_dev, void *data, @@ -388,12 +479,12 @@ static void i2c_writesl_vi(struct tegra_i2c_dev *i2c_= dev, void *data, static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data, unsigned int reg, unsigned int len) { - readsl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len); + readsl(i2c_dev->base + reg, data, len); } =20 static bool tegra_i2c_mutex_acquired(struct tegra_i2c_dev *i2c_dev) { - unsigned int reg =3D tegra_i2c_reg_addr(i2c_dev, I2C_SW_MUTEX); + unsigned int reg =3D i2c_dev->hw->regs->sw_mutex; u32 val, id; =20 val =3D readl(i2c_dev->base + reg); @@ -404,7 +495,7 @@ static bool tegra_i2c_mutex_acquired(struct tegra_i2c_d= ev *i2c_dev) =20 static bool tegra_i2c_mutex_trylock(struct tegra_i2c_dev *i2c_dev) { - unsigned int reg =3D tegra_i2c_reg_addr(i2c_dev, I2C_SW_MUTEX); + unsigned int reg =3D i2c_dev->hw->regs->sw_mutex; u32 val, id; =20 val =3D readl(i2c_dev->base + reg); @@ -428,8 +519,8 @@ static int tegra_i2c_mutex_lock(struct tegra_i2c_dev *i= 2c_dev) =20 if (i2c_dev->atomic_mode) ret =3D read_poll_timeout_atomic(tegra_i2c_mutex_trylock, locked, locked, - USEC_PER_MSEC, I2C_SW_MUTEX_TIMEOUT_US, - false, i2c_dev); + USEC_PER_MSEC, I2C_SW_MUTEX_TIMEOUT_US, + false, i2c_dev); else ret =3D read_poll_timeout(tegra_i2c_mutex_trylock, locked, locked, USEC_= PER_MSEC, I2C_SW_MUTEX_TIMEOUT_US, false, i2c_dev); @@ -442,7 +533,7 @@ static int tegra_i2c_mutex_lock(struct tegra_i2c_dev *i= 2c_dev) =20 static int tegra_i2c_mutex_unlock(struct tegra_i2c_dev *i2c_dev) { - unsigned int reg =3D tegra_i2c_reg_addr(i2c_dev, I2C_SW_MUTEX); + unsigned int reg =3D i2c_dev->hw->regs->sw_mutex; u32 val, id; =20 if (!i2c_dev->hw->has_mutex) @@ -465,16 +556,16 @@ static void tegra_i2c_mask_irq(struct tegra_i2c_dev *= i2c_dev, u32 mask) { u32 int_mask; =20 - int_mask =3D i2c_readl(i2c_dev, I2C_INT_MASK) & ~mask; - i2c_writel(i2c_dev, int_mask, I2C_INT_MASK); + int_mask =3D i2c_readl(i2c_dev, i2c_dev->hw->regs->int_mask) & ~mask; + i2c_writel(i2c_dev, int_mask, i2c_dev->hw->regs->int_mask); } =20 static void tegra_i2c_unmask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask) { u32 int_mask; =20 - int_mask =3D i2c_readl(i2c_dev, I2C_INT_MASK) | mask; - i2c_writel(i2c_dev, int_mask, I2C_INT_MASK); + int_mask =3D i2c_readl(i2c_dev, i2c_dev->hw->regs->int_mask) | mask; + i2c_writel(i2c_dev, int_mask, i2c_dev->hw->regs->int_mask); } =20 static void tegra_i2c_dma_complete(void *args) @@ -602,14 +693,14 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_= dev) { u32 val; =20 - val =3D dvc_readl(i2c_dev, DVC_CTRL_REG3); + val =3D dvc_readl(i2c_dev, i2c_dev->hw->regs->dvc_ctrl_reg3); val |=3D DVC_CTRL_REG3_SW_PROG; val |=3D DVC_CTRL_REG3_I2C_DONE_INTR_EN; - dvc_writel(i2c_dev, val, DVC_CTRL_REG3); + dvc_writel(i2c_dev, val, i2c_dev->hw->regs->dvc_ctrl_reg3); =20 - val =3D dvc_readl(i2c_dev, DVC_CTRL_REG1); + val =3D dvc_readl(i2c_dev, i2c_dev->hw->regs->dvc_ctrl_reg1); val |=3D DVC_CTRL_REG1_INTR_EN; - dvc_writel(i2c_dev, val, DVC_CTRL_REG1); + dvc_writel(i2c_dev, val, i2c_dev->hw->regs->dvc_ctrl_reg1); } =20 static void tegra_i2c_vi_init(struct tegra_i2c_dev *i2c_dev) @@ -618,34 +709,34 @@ static void tegra_i2c_vi_init(struct tegra_i2c_dev *i= 2c_dev) =20 value =3D FIELD_PREP(I2C_INTERFACE_TIMING_THIGH, 2) | FIELD_PREP(I2C_INTERFACE_TIMING_TLOW, 4); - i2c_writel(i2c_dev, value, I2C_INTERFACE_TIMING_0); + i2c_writel(i2c_dev, value, i2c_dev->hw->regs->interface_timing_0); =20 value =3D FIELD_PREP(I2C_INTERFACE_TIMING_TBUF, 4) | FIELD_PREP(I2C_INTERFACE_TIMING_TSU_STO, 7) | FIELD_PREP(I2C_INTERFACE_TIMING_THD_STA, 4) | FIELD_PREP(I2C_INTERFACE_TIMING_TSU_STA, 4); - i2c_writel(i2c_dev, value, I2C_INTERFACE_TIMING_1); + i2c_writel(i2c_dev, value, i2c_dev->hw->regs->interface_timing_1); =20 value =3D FIELD_PREP(I2C_HS_INTERFACE_TIMING_THIGH, 3) | FIELD_PREP(I2C_HS_INTERFACE_TIMING_TLOW, 8); - i2c_writel(i2c_dev, value, I2C_HS_INTERFACE_TIMING_0); + i2c_writel(i2c_dev, value, i2c_dev->hw->regs->hs_interface_timing_0); =20 value =3D FIELD_PREP(I2C_HS_INTERFACE_TIMING_TSU_STO, 11) | FIELD_PREP(I2C_HS_INTERFACE_TIMING_THD_STA, 11) | FIELD_PREP(I2C_HS_INTERFACE_TIMING_TSU_STA, 11); - i2c_writel(i2c_dev, value, I2C_HS_INTERFACE_TIMING_1); + i2c_writel(i2c_dev, value, i2c_dev->hw->regs->hs_interface_timing_1); =20 value =3D FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND; - i2c_writel(i2c_dev, value, I2C_BUS_CLEAR_CNFG); + i2c_writel(i2c_dev, value, i2c_dev->hw->regs->bus_clear_cnfg); =20 - i2c_writel(i2c_dev, 0x0, I2C_TLOW_SEXT); + i2c_writel(i2c_dev, 0x0, i2c_dev->hw->regs->tlow_sext); } =20 static int tegra_i2c_poll_register(struct tegra_i2c_dev *i2c_dev, u32 reg, u32 mask, u32 delay_us, u32 timeout_us) { - void __iomem *addr =3D i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg); + void __iomem *addr =3D i2c_dev->base + reg; u32 val; =20 if (!i2c_dev->atomic_mode) @@ -664,11 +755,11 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev= *i2c_dev) if (i2c_dev->hw->has_mst_fifo) { mask =3D I2C_MST_FIFO_CONTROL_TX_FLUSH | I2C_MST_FIFO_CONTROL_RX_FLUSH; - offset =3D I2C_MST_FIFO_CONTROL; + offset =3D i2c_dev->hw->regs->mst_fifo_control; } else { mask =3D I2C_FIFO_CONTROL_TX_FLUSH | I2C_FIFO_CONTROL_RX_FLUSH; - offset =3D I2C_FIFO_CONTROL; + offset =3D i2c_dev->hw->regs->fifo_control; } =20 val =3D i2c_readl(i2c_dev, offset); @@ -691,9 +782,9 @@ static int tegra_i2c_wait_for_config_load(struct tegra_= i2c_dev *i2c_dev) if (!i2c_dev->hw->has_config_load_reg) return 0; =20 - i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD); + i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, i2c_dev->hw->regs->config_load); =20 - err =3D tegra_i2c_poll_register(i2c_dev, I2C_CONFIG_LOAD, 0xffffffff, + err =3D tegra_i2c_poll_register(i2c_dev, i2c_dev->hw->regs->config_load, = 0xffffffff, 1000, I2C_CONFIG_LOAD_TIMEOUT); if (err) { dev_err(i2c_dev->dev, "failed to load config\n"); @@ -714,10 +805,10 @@ static int tegra_i2c_master_reset(struct tegra_i2c_de= v *i2c_dev) * SW needs to wait for 2us after assertion and de-assertion of this soft * reset. */ - i2c_writel(i2c_dev, 0x1, I2C_MASTER_RESET_CNTRL); + i2c_writel(i2c_dev, 0x1, i2c_dev->hw->regs->master_reset_cntrl); fsleep(2); =20 - i2c_writel(i2c_dev, 0x0, I2C_MASTER_RESET_CNTRL); + i2c_writel(i2c_dev, 0x0, i2c_dev->hw->regs->master_reset_cntrl); fsleep(2); =20 return 0; @@ -758,8 +849,8 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) if (i2c_dev->hw->has_multi_master_mode) val |=3D I2C_CNFG_MULTI_MASTER_MODE; =20 - i2c_writel(i2c_dev, val, I2C_CNFG); - i2c_writel(i2c_dev, 0, I2C_INT_MASK); + i2c_writel(i2c_dev, val, i2c_dev->hw->regs->cnfg); + i2c_writel(i2c_dev, 0, i2c_dev->hw->regs->int_mask); =20 if (IS_VI(i2c_dev)) tegra_i2c_vi_init(i2c_dev); @@ -801,12 +892,12 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_d= ev) clk_divisor =3D FIELD_PREP(I2C_CLK_DIVISOR_HSMODE, i2c_dev->hw->clk_divisor_hs_mode) | FIELD_PREP(I2C_CLK_DIVISOR_STD_FAST_MODE, non_hs_mode); - i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR); + i2c_writel(i2c_dev, clk_divisor, i2c_dev->hw->regs->clk_divisor); =20 if (i2c_dev->hw->has_interface_timing_reg) { val =3D FIELD_PREP(I2C_INTERFACE_TIMING_THIGH, thigh) | FIELD_PREP(I2C_INTERFACE_TIMING_TLOW, tlow); - i2c_writel(i2c_dev, val, I2C_INTERFACE_TIMING_0); + i2c_writel(i2c_dev, val, i2c_dev->hw->regs->interface_timing_0); } =20 /* @@ -814,9 +905,8 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) * Otherwise, preserve the chip default values. */ if (i2c_dev->hw->has_interface_timing_reg && tsu_thd) - i2c_writel(i2c_dev, tsu_thd, I2C_INTERFACE_TIMING_1); + i2c_writel(i2c_dev, tsu_thd, i2c_dev->hw->regs->interface_timing_1); =20 - /* Write HS mode registers. These will get used only for HS mode*/ if (i2c_dev->hw->has_hs_mode_support) { tlow =3D i2c_dev->hw->tlow_hs_mode; thigh =3D i2c_dev->hw->thigh_hs_mode; @@ -824,8 +914,8 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) =20 val =3D FIELD_PREP(I2C_HS_INTERFACE_TIMING_THIGH, thigh) | FIELD_PREP(I2C_HS_INTERFACE_TIMING_TLOW, tlow); - i2c_writel(i2c_dev, val, I2C_HS_INTERFACE_TIMING_0); - i2c_writel(i2c_dev, tsu_thd, I2C_HS_INTERFACE_TIMING_1); + i2c_writel(i2c_dev, val, i2c_dev->hw->regs->hs_interface_timing_0); + i2c_writel(i2c_dev, tsu_thd, i2c_dev->hw->regs->hs_interface_timing_1); } =20 clk_multiplier =3D (tlow + thigh + 2) * (non_hs_mode + 1); @@ -838,12 +928,12 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_d= ev) } =20 if (!IS_DVC(i2c_dev) && !IS_VI(i2c_dev)) { - u32 sl_cfg =3D i2c_readl(i2c_dev, I2C_SL_CNFG); + u32 sl_cfg =3D i2c_readl(i2c_dev, i2c_dev->hw->regs->sl_cnfg); =20 sl_cfg |=3D I2C_SL_CNFG_NACK | I2C_SL_CNFG_NEWSL; - i2c_writel(i2c_dev, sl_cfg, I2C_SL_CNFG); - i2c_writel(i2c_dev, 0xfc, I2C_SL_ADDR1); - i2c_writel(i2c_dev, 0x00, I2C_SL_ADDR2); + i2c_writel(i2c_dev, sl_cfg, i2c_dev->hw->regs->sl_cnfg); + i2c_writel(i2c_dev, 0xfc, i2c_dev->hw->regs->sl_addr1); + i2c_writel(i2c_dev, 0x00, i2c_dev->hw->regs->sl_addr2); } =20 err =3D tegra_i2c_flush_fifos(i2c_dev); @@ -851,7 +941,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) return err; =20 if (i2c_dev->multimaster_mode && i2c_dev->hw->has_slcg_override_reg) - i2c_writel(i2c_dev, I2C_MST_CORE_CLKEN_OVR, I2C_CLKEN_OVERRIDE); + i2c_writel(i2c_dev, I2C_MST_CORE_CLKEN_OVR, i2c_dev->hw->regs->clken_ove= rride); =20 err =3D tegra_i2c_wait_for_config_load(i2c_dev); if (err) @@ -872,9 +962,9 @@ static int tegra_i2c_disable_packet_mode(struct tegra_i= 2c_dev *i2c_dev) */ udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->timings.bus_freq_hz)); =20 - cnfg =3D i2c_readl(i2c_dev, I2C_CNFG); + cnfg =3D i2c_readl(i2c_dev, i2c_dev->hw->regs->cnfg); if (cnfg & I2C_CNFG_PACKET_MODE_EN) - i2c_writel(i2c_dev, cnfg & ~I2C_CNFG_PACKET_MODE_EN, I2C_CNFG); + i2c_writel(i2c_dev, cnfg & ~I2C_CNFG_PACKET_MODE_EN, i2c_dev->hw->regs->= cnfg); =20 return tegra_i2c_wait_for_config_load(i2c_dev); } @@ -894,19 +984,18 @@ static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_d= ev *i2c_dev) return -EINVAL; =20 if (i2c_dev->hw->has_mst_fifo) { - val =3D i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS); + val =3D i2c_readl(i2c_dev, i2c_dev->hw->regs->mst_fifo_status); rx_fifo_avail =3D FIELD_GET(I2C_MST_FIFO_STATUS_RX, val); } else { - val =3D i2c_readl(i2c_dev, I2C_FIFO_STATUS); + val =3D i2c_readl(i2c_dev, i2c_dev->hw->regs->fifo_status); rx_fifo_avail =3D FIELD_GET(I2C_FIFO_STATUS_RX, val); } =20 - /* round down to exclude partial word at the end of buffer */ words_to_transfer =3D buf_remaining / BYTES_PER_FIFO_WORD; if (words_to_transfer > rx_fifo_avail) words_to_transfer =3D rx_fifo_avail; =20 - i2c_readsl(i2c_dev, buf, I2C_RX_FIFO, words_to_transfer); + i2c_readsl(i2c_dev, buf, i2c_dev->hw->regs->rx_fifo, words_to_transfer); =20 buf +=3D words_to_transfer * BYTES_PER_FIFO_WORD; buf_remaining -=3D words_to_transfer * BYTES_PER_FIFO_WORD; @@ -922,7 +1011,7 @@ static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_de= v *i2c_dev) * when (words_to_transfer was > rx_fifo_avail) earlier * in this function. */ - val =3D i2c_readl(i2c_dev, I2C_RX_FIFO); + val =3D i2c_readl(i2c_dev, i2c_dev->hw->regs->rx_fifo); val =3D cpu_to_le32(val); memcpy(buf, &val, buf_remaining); buf_remaining =3D 0; @@ -947,10 +1036,10 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_d= ev *i2c_dev) u32 val; =20 if (i2c_dev->hw->has_mst_fifo) { - val =3D i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS); + val =3D i2c_readl(i2c_dev, i2c_dev->hw->regs->mst_fifo_status); tx_fifo_avail =3D FIELD_GET(I2C_MST_FIFO_STATUS_TX, val); } else { - val =3D i2c_readl(i2c_dev, I2C_FIFO_STATUS); + val =3D i2c_readl(i2c_dev, i2c_dev->hw->regs->fifo_status); tx_fifo_avail =3D FIELD_GET(I2C_FIFO_STATUS_TX, val); } =20 @@ -981,9 +1070,9 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev= *i2c_dev) i2c_dev->msg_buf =3D buf + words_to_transfer * BYTES_PER_FIFO_WORD; =20 if (IS_VI(i2c_dev)) - i2c_writesl_vi(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer); + i2c_writesl_vi(i2c_dev, buf, i2c_dev->hw->regs->tx_fifo, words_to_trans= fer); else - i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer); + i2c_writesl(i2c_dev, buf, i2c_dev->hw->regs->tx_fifo, words_to_transfer= ); =20 buf +=3D words_to_transfer * BYTES_PER_FIFO_WORD; } @@ -1005,7 +1094,7 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_de= v *i2c_dev) i2c_dev->msg_buf_remaining =3D 0; i2c_dev->msg_buf =3D NULL; =20 - i2c_writel(i2c_dev, val, I2C_TX_FIFO); + i2c_writel(i2c_dev, val, i2c_dev->hw->regs->tx_fifo); } =20 return 0; @@ -1017,13 +1106,13 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev= _id) struct tegra_i2c_dev *i2c_dev =3D dev_id; u32 status; =20 - status =3D i2c_readl(i2c_dev, I2C_INT_STATUS); + status =3D i2c_readl(i2c_dev, i2c_dev->hw->regs->int_status); =20 if (status =3D=3D 0) { dev_warn(i2c_dev->dev, "IRQ status 0 %08x %08x %08x\n", - i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS), - i2c_readl(i2c_dev, I2C_STATUS), - i2c_readl(i2c_dev, I2C_CNFG)); + i2c_readl(i2c_dev, i2c_dev->hw->regs->packet_transfer_status), + i2c_readl(i2c_dev, i2c_dev->hw->regs->status), + i2c_readl(i2c_dev, i2c_dev->hw->regs->cnfg)); i2c_dev->msg_err |=3D I2C_ERR_UNKNOWN_INTERRUPT; goto err; } @@ -1062,13 +1151,13 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev= _id) tegra_i2c_fill_tx_fifo(i2c_dev); else tegra_i2c_mask_irq(i2c_dev, - I2C_INT_TX_FIFO_DATA_REQ); + I2C_INT_TX_FIFO_DATA_REQ); } } =20 - i2c_writel(i2c_dev, status, I2C_INT_STATUS); + i2c_writel(i2c_dev, status, i2c_dev->hw->regs->int_status); if (IS_DVC(i2c_dev)) - dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS); + dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, i2c_dev->hw->regs->dvc_sta= tus); =20 /* * During message read XFER_COMPLETE interrupt is triggered prior to @@ -1104,10 +1193,10 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev= _id) if (i2c_dev->hw->supports_bus_clear) tegra_i2c_mask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE); =20 - i2c_writel(i2c_dev, status, I2C_INT_STATUS); + i2c_writel(i2c_dev, status, i2c_dev->hw->regs->int_status); =20 if (IS_DVC(i2c_dev)) - dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS); + dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, i2c_dev->hw->regs->dvc_sta= tus); =20 if (i2c_dev->dma_mode) { dmaengine_terminate_async(i2c_dev->dma_chan); @@ -1120,16 +1209,16 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev= _id) } =20 static void tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, - size_t len) + size_t len) { struct dma_slave_config slv_config =3D {0}; u32 val, reg, dma_burst, reg_offset; int err; =20 if (i2c_dev->hw->has_mst_fifo) - reg =3D I2C_MST_FIFO_CONTROL; + reg =3D i2c_dev->hw->regs->mst_fifo_control; else - reg =3D I2C_FIFO_CONTROL; + reg =3D i2c_dev->hw->regs->fifo_control; =20 if (i2c_dev->dma_mode) { if (len & 0xF) @@ -1140,7 +1229,7 @@ static void tegra_i2c_config_fifo_trig(struct tegra_i= 2c_dev *i2c_dev, dma_burst =3D 8; =20 if (i2c_dev->msg_read) { - reg_offset =3D tegra_i2c_reg_addr(i2c_dev, I2C_RX_FIFO); + reg_offset =3D i2c_dev->hw->regs->rx_fifo; =20 slv_config.src_addr =3D i2c_dev->base_phys + reg_offset; slv_config.src_addr_width =3D DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -1151,7 +1240,7 @@ static void tegra_i2c_config_fifo_trig(struct tegra_i= 2c_dev *i2c_dev, else val =3D I2C_FIFO_CONTROL_RX_TRIG(dma_burst); } else { - reg_offset =3D tegra_i2c_reg_addr(i2c_dev, I2C_TX_FIFO); + reg_offset =3D i2c_dev->hw->regs->tx_fifo; =20 slv_config.dst_addr =3D i2c_dev->base_phys + reg_offset; slv_config.dst_addr_width =3D DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -1187,14 +1276,14 @@ static void tegra_i2c_config_fifo_trig(struct tegra= _i2c_dev *i2c_dev, } =20 static unsigned long tegra_i2c_poll_completion(struct tegra_i2c_dev *i2c_d= ev, - struct completion *complete, - unsigned int timeout_ms) + struct completion *complete, + unsigned int timeout_ms) { ktime_t ktime =3D ktime_get(); ktime_t ktimeout =3D ktime_add_ms(ktime, timeout_ms); =20 do { - u32 status =3D i2c_readl(i2c_dev, I2C_INT_STATUS); + u32 status =3D i2c_readl(i2c_dev, i2c_dev->hw->regs->int_status); =20 if (status) tegra_i2c_isr(i2c_dev->irq, i2c_dev); @@ -1253,14 +1342,14 @@ static int tegra_i2c_issue_bus_clear(struct i2c_ada= pter *adap) =20 val =3D FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND | I2C_BC_TERMINATE; - i2c_writel(i2c_dev, val, I2C_BUS_CLEAR_CNFG); + i2c_writel(i2c_dev, val, i2c_dev->hw->regs->bus_clear_cnfg); =20 err =3D tegra_i2c_wait_for_config_load(i2c_dev); if (err) return err; =20 val |=3D I2C_BC_ENABLE; - i2c_writel(i2c_dev, val, I2C_BUS_CLEAR_CNFG); + i2c_writel(i2c_dev, val, i2c_dev->hw->regs->bus_clear_cnfg); tegra_i2c_unmask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE); =20 time_left =3D tegra_i2c_wait_completion(i2c_dev, &i2c_dev->msg_complete, = 50); @@ -1271,7 +1360,7 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapt= er *adap) return -ETIMEDOUT; } =20 - val =3D i2c_readl(i2c_dev, I2C_BUS_CLEAR_STATUS); + val =3D i2c_readl(i2c_dev, i2c_dev->hw->regs->bus_clear_status); if (!(val & I2C_BC_STATUS)) { dev_err(i2c_dev->dev, "un-recovered arbitration lost\n"); return -EIO; @@ -1281,29 +1370,29 @@ static int tegra_i2c_issue_bus_clear(struct i2c_ada= pter *adap) } =20 static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev, - struct i2c_msg *msg, - enum msg_end_type end_state) + struct i2c_msg *msg, + enum msg_end_type end_state) { u32 *dma_buf =3D i2c_dev->dma_buf; u32 packet_header; =20 packet_header =3D FIELD_PREP(PACKET_HEADER0_HEADER_SIZE, 0) | FIELD_PREP(PACKET_HEADER0_PROTOCOL, - PACKET_HEADER0_PROTOCOL_I2C) | + PACKET_HEADER0_PROTOCOL_I2C) | FIELD_PREP(PACKET_HEADER0_CONT_ID, i2c_dev->cont_id) | FIELD_PREP(PACKET_HEADER0_PACKET_ID, 1); =20 if (i2c_dev->dma_mode && !i2c_dev->msg_read) *dma_buf++ =3D packet_header; else - i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO); + i2c_writel(i2c_dev, packet_header, i2c_dev->hw->regs->tx_fifo); =20 packet_header =3D i2c_dev->msg_len - 1; =20 if (i2c_dev->dma_mode && !i2c_dev->msg_read) *dma_buf++ =3D packet_header; else - i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO); + i2c_writel(i2c_dev, packet_header, i2c_dev->hw->regs->tx_fifo); =20 packet_header =3D I2C_HEADER_IE_ENABLE; =20 @@ -1331,7 +1420,7 @@ static void tegra_i2c_push_packet_header(struct tegra= _i2c_dev *i2c_dev, if (i2c_dev->dma_mode && !i2c_dev->msg_read) *dma_buf++ =3D packet_header; else - i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO); + i2c_writel(i2c_dev, packet_header, i2c_dev->hw->regs->tx_fifo); } =20 static int tegra_i2c_error_recover(struct tegra_i2c_dev *i2c_dev, @@ -1361,8 +1450,8 @@ static int tegra_i2c_error_recover(struct tegra_i2c_d= ev *i2c_dev, } =20 static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, - struct i2c_msg *msg, - enum msg_end_type end_state) + struct i2c_msg *msg, + enum msg_end_type end_state) { unsigned long time_left, xfer_time =3D 100; size_t xfer_size; @@ -1413,7 +1502,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i= 2c_dev, * Total bits =3D 9 bits per byte (including ACK bit) + Start & stop bits */ xfer_time +=3D DIV_ROUND_CLOSEST(((xfer_size * 9) + 2) * MSEC_PER_SEC, - i2c_dev->timings.bus_freq_hz); + i2c_dev->timings.bus_freq_hz); =20 int_mask =3D I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST; tegra_i2c_unmask_irq(i2c_dev, int_mask); @@ -1452,12 +1541,12 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev = *i2c_dev, =20 tegra_i2c_unmask_irq(i2c_dev, int_mask); dev_dbg(i2c_dev->dev, "unmasked IRQ: %02x\n", - i2c_readl(i2c_dev, I2C_INT_MASK)); + i2c_readl(i2c_dev, i2c_dev->hw->regs->int_mask)); =20 if (i2c_dev->dma_mode) { time_left =3D tegra_i2c_wait_completion(i2c_dev, - &i2c_dev->dma_complete, - xfer_time); + &i2c_dev->dma_complete, + xfer_time); =20 /* * Synchronize DMA first, since dmaengine_terminate_sync() @@ -1477,7 +1566,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i= 2c_dev, } =20 time_left =3D tegra_i2c_wait_completion(i2c_dev, &i2c_dev->msg_complete, - xfer_time); + xfer_time); =20 tegra_i2c_mask_irq(i2c_dev, int_mask); =20 @@ -1623,7 +1712,75 @@ static const struct tegra_i2c_hw_feature tegra20_i2c= _hw =3D { .has_interface_timing_reg =3D false, .has_hs_mode_support =3D false, .has_mutex =3D false, + .is_dvc =3D false, + .is_vi =3D false, + .regs =3D &tegra20_i2c_regs, +}; + +#if IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) +static const struct tegra_i2c_hw_feature tegra20_dvc_i2c_hw =3D { + .has_continue_xfer_support =3D false, + .has_per_pkt_xfer_complete_irq =3D false, + .clk_divisor_hs_mode =3D 3, + .clk_divisor_std_mode =3D 0, + .clk_divisor_fast_mode =3D 0, + .clk_divisor_fast_plus_mode =3D 0, + .has_config_load_reg =3D false, + .has_multi_master_mode =3D false, + .has_slcg_override_reg =3D false, + .has_mst_fifo =3D false, + .has_mst_reset =3D false, + .quirks =3D &tegra_i2c_quirks, + .supports_bus_clear =3D false, + .has_apb_dma =3D true, + .tlow_std_mode =3D 0x4, + .thigh_std_mode =3D 0x2, + .tlow_fast_fastplus_mode =3D 0x4, + .thigh_fast_fastplus_mode =3D 0x2, + .setup_hold_time_std_mode =3D 0x0, + .setup_hold_time_fast_fast_plus_mode =3D 0x0, + .setup_hold_time_hs_mode =3D 0x0, + .has_interface_timing_reg =3D false, + .has_hs_mode_support =3D false, + .has_mutex =3D false, + .is_dvc =3D true, + .is_vi =3D false, + .regs =3D &tegra20_i2c_regs_dvc, +}; +#endif + +#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) +static const struct tegra_i2c_hw_feature tegra210_vi_i2c_hw =3D { + .has_continue_xfer_support =3D true, + .has_per_pkt_xfer_complete_irq =3D true, + .clk_divisor_hs_mode =3D 1, + .clk_divisor_std_mode =3D 0x19, + .clk_divisor_fast_mode =3D 0x19, + .clk_divisor_fast_plus_mode =3D 0x10, + .has_config_load_reg =3D true, + .has_multi_master_mode =3D false, + .has_slcg_override_reg =3D true, + .has_mst_fifo =3D false, + .has_mst_reset =3D false, + .quirks =3D &tegra_i2c_quirks, + .supports_bus_clear =3D true, + .has_apb_dma =3D true, + .tlow_std_mode =3D 0x4, + .thigh_std_mode =3D 0x2, + .tlow_fast_fastplus_mode =3D 0x4, + .thigh_fast_fastplus_mode =3D 0x2, + .setup_hold_time_std_mode =3D 0, + .setup_hold_time_fast_fast_plus_mode =3D 0, + .setup_hold_time_hs_mode =3D 0, + .has_interface_timing_reg =3D true, + .has_hs_mode_support =3D false, + .has_mutex =3D false, + .is_dvc =3D false, + .is_vi =3D true, + .regs =3D &tegra20_i2c_regs_vi, }; +#endif + =20 static const struct tegra_i2c_hw_feature tegra30_i2c_hw =3D { .has_continue_xfer_support =3D true, @@ -1650,6 +1807,9 @@ static const struct tegra_i2c_hw_feature tegra30_i2c_= hw =3D { .has_interface_timing_reg =3D false, .has_hs_mode_support =3D false, .has_mutex =3D false, + .is_dvc =3D false, + .is_vi =3D false, + .regs =3D &tegra20_i2c_regs, }; =20 static const struct tegra_i2c_hw_feature tegra114_i2c_hw =3D { @@ -1677,6 +1837,9 @@ static const struct tegra_i2c_hw_feature tegra114_i2c= _hw =3D { .has_interface_timing_reg =3D false, .has_hs_mode_support =3D false, .has_mutex =3D false, + .is_dvc =3D false, + .is_vi =3D false, + .regs =3D &tegra20_i2c_regs, }; =20 static const struct tegra_i2c_hw_feature tegra124_i2c_hw =3D { @@ -1704,6 +1867,9 @@ static const struct tegra_i2c_hw_feature tegra124_i2c= _hw =3D { .has_interface_timing_reg =3D true, .has_hs_mode_support =3D false, .has_mutex =3D false, + .is_dvc =3D false, + .is_vi =3D false, + .regs =3D &tegra20_i2c_regs, }; =20 static const struct tegra_i2c_hw_feature tegra210_i2c_hw =3D { @@ -1731,6 +1897,9 @@ static const struct tegra_i2c_hw_feature tegra210_i2c= _hw =3D { .has_interface_timing_reg =3D true, .has_hs_mode_support =3D false, .has_mutex =3D false, + .is_dvc =3D false, + .is_vi =3D false, + .regs =3D &tegra20_i2c_regs, }; =20 static const struct tegra_i2c_hw_feature tegra186_i2c_hw =3D { @@ -1758,6 +1927,9 @@ static const struct tegra_i2c_hw_feature tegra186_i2c= _hw =3D { .has_interface_timing_reg =3D true, .has_hs_mode_support =3D false, .has_mutex =3D false, + .is_dvc =3D false, + .is_vi =3D false, + .regs =3D &tegra20_i2c_regs, }; =20 static const struct tegra_i2c_hw_feature tegra194_i2c_hw =3D { @@ -1787,6 +1959,9 @@ static const struct tegra_i2c_hw_feature tegra194_i2c= _hw =3D { .has_interface_timing_reg =3D true, .has_hs_mode_support =3D true, .has_mutex =3D false, + .is_dvc =3D false, + .is_vi =3D false, + .regs =3D &tegra20_i2c_regs, }; =20 static const struct tegra_i2c_hw_feature tegra256_i2c_hw =3D { @@ -1840,6 +2015,9 @@ static const struct tegra_i2c_hw_feature tegra264_i2c= _hw =3D { .has_interface_timing_reg =3D true, .has_hs_mode_support =3D true, .has_mutex =3D true, + .is_dvc =3D false, + .is_vi =3D false, + .regs =3D &tegra20_i2c_regs, }; =20 static const struct of_device_id tegra_i2c_of_match[] =3D { @@ -1848,7 +2026,7 @@ static const struct of_device_id tegra_i2c_of_match[]= =3D { { .compatible =3D "nvidia,tegra194-i2c", .data =3D &tegra194_i2c_hw, }, { .compatible =3D "nvidia,tegra186-i2c", .data =3D &tegra186_i2c_hw, }, #if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) - { .compatible =3D "nvidia,tegra210-i2c-vi", .data =3D &tegra210_i2c_hw, }, + { .compatible =3D "nvidia,tegra210-i2c-vi", .data =3D &tegra210_vi_i2c_hw= , }, #endif { .compatible =3D "nvidia,tegra210-i2c", .data =3D &tegra210_i2c_hw, }, { .compatible =3D "nvidia,tegra124-i2c", .data =3D &tegra124_i2c_hw, }, @@ -1856,7 +2034,7 @@ static const struct of_device_id tegra_i2c_of_match[]= =3D { { .compatible =3D "nvidia,tegra30-i2c", .data =3D &tegra30_i2c_hw, }, { .compatible =3D "nvidia,tegra20-i2c", .data =3D &tegra20_i2c_hw, }, #if IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) - { .compatible =3D "nvidia,tegra20-i2c-dvc", .data =3D &tegra20_i2c_hw, }, + { .compatible =3D "nvidia,tegra20-i2c-dvc", .data =3D &tegra20_dvc_i2c_hw= , }, #endif {}, }; @@ -1864,21 +2042,12 @@ MODULE_DEVICE_TABLE(of, tegra_i2c_of_match); =20 static void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev) { - struct device_node *np =3D i2c_dev->dev->of_node; bool multi_mode; =20 i2c_parse_fw_timings(i2c_dev->dev, &i2c_dev->timings, true); =20 multi_mode =3D device_property_read_bool(i2c_dev->dev, "multi-master"); i2c_dev->multimaster_mode =3D multi_mode; - - if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && - of_device_is_compatible(np, "nvidia,tegra20-i2c-dvc")) - i2c_dev->is_dvc =3D true; - - if (IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) && - of_device_is_compatible(np, "nvidia,tegra210-i2c-vi")) - i2c_dev->is_vi =3D true; } =20 static int tegra_i2c_init_clocks(struct tegra_i2c_dev *i2c_dev) --=20 2.43.0 From nobody Wed Oct 1 20:31:50 2025 Received: from PH7PR06CU001.outbound.protection.outlook.com (mail-westus3azon11010023.outbound.protection.outlook.com [52.101.201.23]) (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 8DB9127EFEE; Wed, 1 Oct 2025 15:37:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.201.23 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759333045; cv=fail; b=rRKBHhBd+nzlJ6FuTDEjAyhotzS3JDj8tRvraKusTl+iKinj4eTMKWWX9HJ/SUjWsi3sgIe++I2Upr686w7JabEYYcfpFWt3RYRKJio6MsLmoRxwY+B5WG/at95bA8/7TJyqp4G3UuOGYPnSVJqXG8V7fNQYcbyev7Bp2O52VLI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759333045; c=relaxed/simple; bh=KV76llOBeZTZayqIJ2LV5XyEolMphbU0+lXyzBUrm4w=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZCNv2fD1tKeDYxgELUBojeUt7fiHb3iAb6ultjilPFLkH0C0BPWUoAv2Rs0ZGpr4RFbLE/PAlHJk7s/+Kp/IZMDepLdL4pboR3QljDmJSt0ScpAYbyvCsaQCj4aKXncYpNQx1wjDCQ1DvP8Fyt6h1ULsX3/Huuf1UbKtndwkX2M= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=nsEK9Cph; arc=fail smtp.client-ip=52.101.201.23 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="nsEK9Cph" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=zVRjxlIW7RbAzAPYxH/QGCsd5nXbeLJeTlWY5WVa1Da33Asxk3yaN1wf+uX01ns5lXG13umgY3LxKmOKOxVcQRqxRed48dt6eSIAQZhvtQi5WZPAXc8+DcIgGqp4mGU+GRv2rMJNcqQKJSnQHPUbBYten9LFixf6ntMWVaP5FiZQpLbifDJ6gcJfTDIdGYriQ48YsTr7U8DC2qbiS0K8V1+2QIm2tUGQssY2vJqQnhAwvTS7Pw32QoXeq/rM2pOXd4B5IvUUwt74fEsRfPtLwROTZtXuicNmWWrCbt6QEZN/e9S5d2BHEeRwm/LP6g9AY3FXb2Xf2bEmqH/JOHcapA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=EOK/v+u2lYSyakDAjyWak+Ll3VrbHnC6yUIPDIOFz7E=; b=N2bzRzOWKPi6jETx6HKuxMP/TF4Nyxd5ViECJIB6tzX5hPDSdL4hoRCMlAf8HPQ3UKj68C/nemoeCzTjtuw172AR2v9CkRqEOzYY4dzlYFaa4P/TUL7fuT0ylBeJAtM4ljCTra9c1lxIWZhGesWeSa2Co+lRpPqktULa15Gd4MF+fXWYr1wZMu70Da/vbMQvVNh8UT3OvCI2krw1fzdOIBLAq40zH+/q8gbZ3RJxjiVq69N/Z5lm32SAf4JX8UO+HITNeld+QVcaYk5JMryJs6Dze7WTkqoBhNHJE0BU/B8G+uLNWVVXsYHYm9wU2jAa7m2bmWDz+NlZUiuyH8mojA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.160) smtp.rcpttodomain=kernel.org smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=EOK/v+u2lYSyakDAjyWak+Ll3VrbHnC6yUIPDIOFz7E=; b=nsEK9CphfJw/UQym38OH/lthoKTPMzp0AVlxF/Iw475p9Nlbfx47W1oU7gpSmRpxJRoGlCUTuz5eU10f7BYiepjd7Yv+JnUORd/EuPh4AWKsE6bP9mMfQXKhOWsj66o7hJfpv+EisINLbIxf2ELMlXymxqjo8saUr7ybrgmbuwbngCMQ6EReGCrekv9VFB1N6d+2DBope1nEPupwivGGfX8h2K1j4ErSS6HWtjbqr0z/3OQIGk6l8dV+lVErRfteVuG6nVFAcb9M8gqTVz8BtWbsrp60wJLpELL7/W7dgjsHYIStgw/rmVXO23Yphz/9Sf+vUNYKGr5fdj73OZdTrw== Received: from SJ0PR03CA0219.namprd03.prod.outlook.com (2603:10b6:a03:39f::14) by CH1PPFF5B95D789.namprd12.prod.outlook.com (2603:10b6:61f:fc00::62a) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9160.9; Wed, 1 Oct 2025 15:37:20 +0000 Received: from SJ5PEPF000001EB.namprd05.prod.outlook.com (2603:10b6:a03:39f:cafe::d7) by SJ0PR03CA0219.outlook.office365.com (2603:10b6:a03:39f::14) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9182.14 via Frontend Transport; Wed, 1 Oct 2025 15:37:20 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.160) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.117.160 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.160; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.117.160) by SJ5PEPF000001EB.mail.protection.outlook.com (10.167.242.199) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9182.15 via Frontend Transport; Wed, 1 Oct 2025 15:37:20 +0000 Received: from rnnvmail202.nvidia.com (10.129.68.7) by mail.nvidia.com (10.129.200.66) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.34; Wed, 1 Oct 2025 08:37:05 -0700 Received: from rnnvmail203.nvidia.com (10.129.68.9) by rnnvmail202.nvidia.com (10.129.68.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20; Wed, 1 Oct 2025 08:37:05 -0700 Received: from kkartik-desktop.nvidia.com (10.127.8.13) by mail.nvidia.com (10.129.68.9) with Microsoft SMTP Server id 15.2.2562.20 via Frontend Transport; Wed, 1 Oct 2025 08:37:00 -0700 From: Kartik Rajput To: , , , , , , , , , , , , , CC: Subject: [PATCH 2/2] i2c: tegra: Add support for Tegra410 Date: Wed, 1 Oct 2025 21:06:48 +0530 Message-ID: <20251001153648.667036-3-kkartik@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251001153648.667036-1-kkartik@nvidia.com> References: <20251001153648.667036-1-kkartik@nvidia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001EB:EE_|CH1PPFF5B95D789:EE_ X-MS-Office365-Filtering-Correlation-Id: 335ae237-04ff-4d72-98e2-08de010068de X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|7416014|376014|36860700013|82310400026|921020; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?r+311aucbexvpLw5zyvMMSWXR56teMYstbre/K9B56O8q0qna6/Otxj/MPUY?= =?us-ascii?Q?Aj8UmwNg/oiPfOU66joda1Ds6yvM79o6k+j2AA6ZP04gVaiHSDzvkXWOQYSf?= =?us-ascii?Q?Im2UwBEJylQHrmYQ/93zKNSFanttKuJDdV7kldxrub3jjCuiCkq9uOg+MqWS?= =?us-ascii?Q?+XEcaT2Y/PWSKBxbvLJIzQx3sOjDprFYQuFQg5dGP9evT+YilUI5gw/FsrtS?= =?us-ascii?Q?l9NGczMG8OY4KfNWMWBmQ9dosy+rFK7kzriMENF5D696LuqDMJYp0vUmQM4S?= =?us-ascii?Q?qc1XtS3LVmoY7Hj9ABJq5+oRDtHAtsw5WyCk5HzLMEFXn37wZ9yh5nlS9Uf5?= =?us-ascii?Q?Z7L+qhVLo8HC20bEUPhs8Wqn3SzOsT832BfxM/to9zI8T9VvatkUeOtEOy0c?= =?us-ascii?Q?JA7kbOZ5V0HlTCZZVGU14nIYzxQBxfLCi3e/IvdIkvAH2jfpWiGUXc8StBSJ?= =?us-ascii?Q?QNXNCUGFpHLqH4k9r/3KVWROzF/Q3tVkDr/PGuFa9KTvSzKkeHVerC6o4hCW?= =?us-ascii?Q?/mi2Qu3cxoZ+7dEIV5e3t8rKAPByZEGySKKPBLvCXcdErvYuyS+wz1K9PhJr?= =?us-ascii?Q?BPlnCaqNmfxNP0Bcwu8a34zW5MY1B4r1vhzJPUJW8ee4msjMV2xU1XD8wPEL?= =?us-ascii?Q?lWBTMO7kKk3fUAUCrFexY7lKjBXuGKSm5dlqAi6uAM2QQiLjJgq+i2LOOnJ5?= =?us-ascii?Q?ncwFu42daN3vgdidZF3TrPSTpoUlebGpreB5b2toykzkJx3MP/iursNl+yOp?= =?us-ascii?Q?kMEcup+MMMa6TQ/swlO1z1ylEch4LEjgYVWZe5tLgf7EnIszoFh57YytCkKz?= =?us-ascii?Q?A3FSz0mqD7kaQ/h+T43nEYdyw9xZ7MZvvCrXwV7/oGplCyuGoDm3IWqst7Oi?= =?us-ascii?Q?XcLzK73j6WIPDC0uyiglYoRFmPSifk+ixRLxHzm27x9uLasnbFRjDt9rniu/?= =?us-ascii?Q?rcqNSeCs+OEcNLpQrm4oD8CmtLl3e76aSPIlIPEA4A+IwALxyA2j9caujcG+?= =?us-ascii?Q?K/XQQCiSCOrl+Tjhj3tytxdrxOwLII4WG2/LZ1KfDaXPZy+5TTt/xAzl8fR0?= =?us-ascii?Q?CtbkaTpurkdfMxp7eMModdosj4m0BAHTpna3+ZuCbI/jJFvm5OcBxjsomx83?= =?us-ascii?Q?on0b9uPyBLNdz3AwDE1OY/QoG7/wCqk/UMK9qJX/+SxJEw+KGliCh5SOy77+?= =?us-ascii?Q?fhu7xMnFE8Ykl0RfBk0/Q0rK7E3qoJBiNpxnd2oKNFIOl2GbYglWeOjDULGq?= =?us-ascii?Q?Xo/T8JZuChgqPDv5lal8WPlDq2xbPpTPae0dyk0+h4NIte3/fz/pJ++A2U2K?= =?us-ascii?Q?9i1Sn+IllHFvppGBm7QNqk8nGtNmFKS/2EV3kXVbnFQhJzzl16mCtIyMoq9k?= =?us-ascii?Q?Y8w4sdNbiO7dYEHhOb4Ag6o9KJ/Ro+rmUlgLoPkchZ5MGj8oVvxPWl7Fymyu?= =?us-ascii?Q?GC1d0Lrmm15LNrS6Dow+A5BUFeKpcyUzd5eH8B+qp6uUkoWf1X9NbFC2bLA2?= =?us-ascii?Q?Be7uqlGV9eBQ/LJD3ATFKBFVnfbrNnjIQkDguNMEDt6i4pITBfDvkKGgf5Hz?= =?us-ascii?Q?0nLfsOnl2u5wVU9CmRH6RhGScuPJlo4zfqPScw1w?= X-Forefront-Antispam-Report: CIP:216.228.117.160;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc6edge1.nvidia.com;CAT:NONE;SFS:(13230040)(1800799024)(7416014)(376014)(36860700013)(82310400026)(921020);DIR:OUT;SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Oct 2025 15:37:20.3364 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 335ae237-04ff-4d72-98e2-08de010068de X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.117.160];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001EB.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH1PPFF5B95D789 Content-Type: text/plain; charset="utf-8" Add support for the Tegra410 SoC, which has 4 I2C controllers. The controllers are feature-equivalent to Tegra264; only the register offsets differ. Signed-off-by: Kartik Rajput --- drivers/i2c/busses/i2c-tegra.c | 64 ++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 1e26d67cbd30..bc9f60b69020 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -262,6 +262,38 @@ static const struct tegra_i2c_regs tegra20_i2c_regs_vi= =3D { .dvc_status =3D 0x00c, }; =20 +static const struct tegra_i2c_regs tegra410_i2c_regs =3D { + .cnfg =3D 0x000, + .status =3D 0x01c, + .sl_cnfg =3D 0x020, + .sl_addr1 =3D 0x02c, + .sl_addr2 =3D 0x030, + .tlow_sext =3D 0x034, + .tx_fifo =3D 0x054, + .rx_fifo =3D 0x058, + .packet_transfer_status =3D 0x05c, + .fifo_control =3D 0x060, + .fifo_status =3D 0x064, + .int_mask =3D 0x068, + .int_status =3D 0x06c, + .clk_divisor =3D 0x070, + .bus_clear_cnfg =3D 0x088, + .bus_clear_status =3D 0x08c, + .config_load =3D 0x090, + .clken_override =3D 0x094, + .interface_timing_0 =3D 0x098, + .interface_timing_1 =3D 0x09c, + .hs_interface_timing_0 =3D 0x0a0, + .hs_interface_timing_1 =3D 0x0a4, + .master_reset_cntrl =3D 0x0ac, + .mst_fifo_control =3D 0x0b8, + .mst_fifo_status =3D 0x0bc, + .sw_mutex =3D 0x0f0, + .dvc_ctrl_reg1 =3D 0x000, + .dvc_ctrl_reg3 =3D 0x008, + .dvc_status =3D 0x00c, +}; + /* * msg_end_type: The bus control which needs to be sent at end of transfer. * @MSG_END_STOP: Send stop pulse. @@ -2020,6 +2052,37 @@ static const struct tegra_i2c_hw_feature tegra264_i2= c_hw =3D { .regs =3D &tegra20_i2c_regs, }; =20 +static const struct tegra_i2c_hw_feature tegra410_i2c_hw =3D { + .has_continue_xfer_support =3D true, + .has_per_pkt_xfer_complete_irq =3D true, + .clk_divisor_hs_mode =3D 1, + .clk_divisor_std_mode =3D 0x1d, + .clk_divisor_fast_mode =3D 0x15, + .clk_divisor_fast_plus_mode =3D 0x8, + .has_config_load_reg =3D true, + .has_multi_master_mode =3D true, + .has_slcg_override_reg =3D true, + .has_mst_fifo =3D true, + .quirks =3D &tegra194_i2c_quirks, + .supports_bus_clear =3D true, + .has_apb_dma =3D false, + .tlow_std_mode =3D 0x8, + .thigh_std_mode =3D 0x7, + .tlow_fast_fastplus_mode =3D 0x2, + .thigh_fast_fastplus_mode =3D 0x2, + .tlow_hs_mode =3D 0x4, + .thigh_hs_mode =3D 0x2, + .setup_hold_time_std_mode =3D 0x08080808, + .setup_hold_time_fast_fast_plus_mode =3D 0x02020202, + .setup_hold_time_hs_mode =3D 0x090909, + .has_interface_timing_reg =3D true, + .has_hs_mode_support =3D true, + .has_mutex =3D true, + .is_dvc =3D false, + .is_vi =3D false, + .regs =3D &tegra410_i2c_regs, +}; + static const struct of_device_id tegra_i2c_of_match[] =3D { { .compatible =3D "nvidia,tegra264-i2c", .data =3D &tegra264_i2c_hw, }, { .compatible =3D "nvidia,tegra256-i2c", .data =3D &tegra256_i2c_hw, }, @@ -2330,6 +2393,7 @@ static const struct acpi_device_id tegra_i2c_acpi_mat= ch[] =3D { {.id =3D "NVDA0101", .driver_data =3D (kernel_ulong_t)&tegra210_i2c_hw}, {.id =3D "NVDA0201", .driver_data =3D (kernel_ulong_t)&tegra186_i2c_hw}, {.id =3D "NVDA0301", .driver_data =3D (kernel_ulong_t)&tegra194_i2c_hw}, + {.id =3D "NVDA2017", .driver_data =3D (kernel_ulong_t)&tegra410_i2c_hw}, { } }; MODULE_DEVICE_TABLE(acpi, tegra_i2c_acpi_match); --=20 2.43.0