From nobody Fri Nov 29 12:37:32 2024 Received: from mail-pl1-f170.google.com (mail-pl1-f170.google.com [209.85.214.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 93814150997; Fri, 20 Sep 2024 10:18:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726827537; cv=none; b=WvMjn6ftgNPbKQFWuXFb3mSc4LhGMllF/aztx4BjcEa2XNd10cLjSFh+3Io9liQlKZxQiw0f8t6RuHAjRHU15gc4Dm6dvDp9piMg61qAJ1qgObRM1HXijSlNIm2X3YA/OF6n2MtVdB0ARsFJhBHYTbua07KtM4QG9Jn0mcjY7kI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726827537; c=relaxed/simple; bh=nSldDNLELpj/wr+PBPXOADOHBG1s6JmVReWahXVOb04=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=gF1hDgKUCVstI+do8qyQQxAxhW+HeOyvqE46yj1yO6TQJl79BZyRPY7D59AlRUF7Pd652ZHEGTRIy1kDTR0HPVj/1ia5iT8FQYLS+cNnzkJlwRJgFBMJ/ThXK8DW2zMEm/VznzF1n8ewprUPIpsSlmgHMq+Ivotci7HOoEgnynw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jkoIwYM9; arc=none smtp.client-ip=209.85.214.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jkoIwYM9" Received: by mail-pl1-f170.google.com with SMTP id d9443c01a7336-207115e3056so15416285ad.2; Fri, 20 Sep 2024 03:18:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1726827535; x=1727432335; darn=vger.kernel.org; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=UH9kA9JWD+tVJWzEqr9eClxvqxO6z1+m9W6qbS/HMVQ=; b=jkoIwYM9ZeRXatQt4g+M8tZ1d4gJlOUTGQnc731vasU6Axsw62oYx5+/0gNBlSnPVj oZ/j1+rm+A94vCn/pvQFE20DJk3fGlsFNVe9S9fagX8PEZ4irzfdqyUXnmrbzV+RW/xj 38OOMB4LrSKb/xOPFm1pgO50wLQpws4DbBUIAYm4eVI093kEz7wELpW0yuzB1QXILV+R oQ/Tb3jitrYSb1gMvMBdqjE4tL8m011LRrv8yYfXdq7F2DUrpchhCgMjScqnYHz6uMQp jgX/mTmkN98yBpRf3BCRPRMnTkaReDXFRD4Kqr0PkCrjjv7TSFSqzW363UKJNB0v4hLS oiWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726827535; x=1727432335; h=references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=UH9kA9JWD+tVJWzEqr9eClxvqxO6z1+m9W6qbS/HMVQ=; b=qHcqv3vgZMJQ0zxEjJ4zadmUGF3H0ybmoMFILxapJWFs7yreNHbbd20Wze1DO49Ft6 3baF5wqGbTDPAAMOg8mXtgZ/E4BBfUkfbE4tBDnauCH7w9bIU/rF/2W1/ulEFaWQrGjo O7P+VY+cXkrDysa3vcIUbQoWFAPl+jNe0LoLTLgsCyeccSWCU2G9O9rGUslNzWSlcJk6 9Q24lrU1Y+WN0UFaCyuwIITtkXpXCcPStZH4k/UcLARgytpwQFtbb96IakjsNty5hT5r mrH8tcJgSIG6uVwZeMzeViAL6IhMR0RN1OZbmKUTs5uZ+/0QlrN2V7xwOsixjv2a5epV AiZQ== X-Forwarded-Encrypted: i=1; AJvYcCUHdnVzM8Yl3Mo0zEvyflnaowesVTlm84uIeET+bzi+jQPxJVJjU9T/Bln2Dzfm2B4oD3jo5Dy+hZ1BMopw@vger.kernel.org, AJvYcCWf45PyRLny8qXJQeBSkaKZdpEFCQneZkMMYjJeadWtNezfFK9okqogbfpFeG21hcApxRwrXSAyM7U=@vger.kernel.org X-Gm-Message-State: AOJu0Yz0tSCypI6cBA+8NqCMjHAezvqKelsp3iVbIQXmDxNA2bgj0SwQ 14gNCILS/JgljIiWzd15aTVyVtXDPbNLRsG3x1+Vbu6u/QuO/Pg= X-Google-Smtp-Source: AGHT+IHdceeTTlHzcpQIv7czEig7kJcoLhGOtCj3reepT8EtT67xY5W8H0utvE94U3qi0J/S6BfxQg== X-Received: by 2002:a17:902:ce8c:b0:206:fd9b:f4f1 with SMTP id d9443c01a7336-208d98d0779mr25157575ad.56.1726827534625; Fri, 20 Sep 2024 03:18:54 -0700 (PDT) Received: from localhost (2001-b400-e35c-9cc2-447a-d760-d4f6-01f4.emome-ip6.hinet.net. [2001:b400:e35c:9cc2:447a:d760:d4f6:1f4]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2079460255asm92326695ad.107.2024.09.20.03.18.53 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Fri, 20 Sep 2024 03:18:54 -0700 (PDT) From: warp5tw@gmail.com X-Google-Original-From: kfting@nuvoton.com To: avifishman70@gmail.com, tmaimon77@gmail.com, tali.perry1@gmail.com, venture@google.com, yuenn@google.com, benjaminfair@google.com, andi.shyti@kernel.org, andriy.shevchenko@linux.intel.com, wsa@kernel.org, rand.sec96@gmail.com, wsa+renesas@sang-engineering.com, warp5tw@gmail.com, tali.perry@nuvoton.com, Avi.Fishman@nuvoton.com, tomer.maimon@nuvoton.com, KWLIU@nuvoton.com, JJLIU0@nuvoton.com, kfting@nuvoton.com Cc: openbmc@lists.ozlabs.org, linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 5/6] i2c: npcm: use i2c frequency table Date: Fri, 20 Sep 2024 18:18:19 +0800 Message-Id: <20240920101820.44850-6-kfting@nuvoton.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240920101820.44850-1-kfting@nuvoton.com> References: <20240920101820.44850-1-kfting@nuvoton.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Tyrone Ting From: Tyrone Ting Modify i2c frequency from table parameters for NPCM i2c modules. Supported frequencies are: 1. 100KHz 2. 400KHz 3. 1MHz The original equations were tested on a variety of chips and base clocks. Since we added devices that use higher frequencies of the module we saw that there is a mismatch between the equation and the actual results on the bus itself, measured on scope. Meanwhile, the equations were not accurate to begin with. They are an approximation of the ideal value. The ideal value is calculated per frequency of the core module. So instead of using the equations we did an optimization per module frequency, verified on a device. Most of the work was focused on the rise time of the SCL and SDA, which depends on external load of the bus and PU. Different PCB designs, or specifically to this case: the number and type of targets on the bus, impact the required values for the timing registers. Users can recalculate the numbers for each bus and get an even better optimization, but our users chose not to. We manually picked values per frequency that match the entire valid range of targets (from 1 to max number). Then we check against the AMR described in SMB spec and make sure that none of the values is exceeding. This process was led by the chip architect and included a lot of testing. Signed-off-by: Tyrone Ting Reviewed-by: Tali Perry --- drivers/i2c/busses/i2c-npcm7xx.c | 374 ++++++++++++++++++++++++------- 1 file changed, 288 insertions(+), 86 deletions(-) diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm= 7xx.c index 248835220c86..9d533873e477 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -263,6 +263,265 @@ static const int npcm_i2caddr[I2C_NUM_OWN_ADDR] =3D { #define I2C_FREQ_MIN_HZ 10000 #define I2C_FREQ_MAX_HZ I2C_MAX_FAST_MODE_PLUS_FREQ =20 +struct smb_timing_t { + u32 core_clk; + u8 hldt; + u8 dbcnt; + u16 sclfrq; + u8 scllt; + u8 sclht; + bool fast_mode; +}; + +static struct smb_timing_t smb_timing_100khz[] =3D { + { + .core_clk =3D 100000000, .hldt =3D 0x2A, .dbcnt =3D 0x4, + .sclfrq =3D 0xFB, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 62500000, .hldt =3D 0x2A, .dbcnt =3D 0x1, + .sclfrq =3D 0x9D, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 50000000, .hldt =3D 0x2A, .dbcnt =3D 0x1, + .sclfrq =3D 0x7E, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 48000000, .hldt =3D 0x2A, .dbcnt =3D 0x1, + .sclfrq =3D 0x79, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 40000000, .hldt =3D 0x2A, .dbcnt =3D 0x1, + .sclfrq =3D 0x65, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 30000000, .hldt =3D 0x2A, .dbcnt =3D 0x1, + .sclfrq =3D 0x4C, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 29000000, .hldt =3D 0x2A, .dbcnt =3D 0x1, + .sclfrq =3D 0x49, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 26000000, .hldt =3D 0x2A, .dbcnt =3D 0x1, + .sclfrq =3D 0x42, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 25000000, .hldt =3D 0x2A, .dbcnt =3D 0x1, + .sclfrq =3D 0x3F, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 24000000, .hldt =3D 0x2A, .dbcnt =3D 0x1, + .sclfrq =3D 0x3D, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 20000000, .hldt =3D 0x2A, .dbcnt =3D 0x1, + .sclfrq =3D 0x33, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 16180000, .hldt =3D 0x2A, .dbcnt =3D 0x1, + .sclfrq =3D 0x29, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 15000000, .hldt =3D 0x23, .dbcnt =3D 0x1, + .sclfrq =3D 0x26, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 13000000, .hldt =3D 0x1D, .dbcnt =3D 0x1, + .sclfrq =3D 0x21, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 12000000, .hldt =3D 0x1B, .dbcnt =3D 0x1, + .sclfrq =3D 0x1F, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 10000000, .hldt =3D 0x18, .dbcnt =3D 0x1, + .sclfrq =3D 0x1A, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 9000000, .hldt =3D 0x16, .dbcnt =3D 0x1, + .sclfrq =3D 0x17, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 8090000, .hldt =3D 0x14, .dbcnt =3D 0x1, + .sclfrq =3D 0x15, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 7500000, .hldt =3D 0x7, .dbcnt =3D 0x1, + .sclfrq =3D 0x13, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 6500000, .hldt =3D 0xE, .dbcnt =3D 0x1, + .sclfrq =3D 0x11, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, + { + .core_clk =3D 4000000, .hldt =3D 0x9, .dbcnt =3D 0x1, + .sclfrq =3D 0xB, .scllt =3D 0x0, .sclht =3D 0x0, + .fast_mode =3D false, + }, +}; + +static struct smb_timing_t smb_timing_400khz[] =3D { + { + .core_clk =3D 100000000, .hldt =3D 0x2A, .dbcnt =3D 0x3, + .sclfrq =3D 0x0, .scllt =3D 0x47, .sclht =3D 0x35, + .fast_mode =3D true, + }, + { + .core_clk =3D 62500000, .hldt =3D 0x2A, .dbcnt =3D 0x2, + .sclfrq =3D 0x0, .scllt =3D 0x2C, .sclht =3D 0x22, + .fast_mode =3D true, + }, + { + .core_clk =3D 50000000, .hldt =3D 0x21, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0x24, .sclht =3D 0x1B, + .fast_mode =3D true, + }, + { + .core_clk =3D 48000000, .hldt =3D 0x1E, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0x24, .sclht =3D 0x19, + .fast_mode =3D true, + }, + { + .core_clk =3D 40000000, .hldt =3D 0x1B, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0x1E, .sclht =3D 0x14, + .fast_mode =3D true, + }, + { + .core_clk =3D 33000000, .hldt =3D 0x15, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0x19, .sclht =3D 0x11, + .fast_mode =3D true, + }, + { + .core_clk =3D 30000000, .hldt =3D 0x15, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0x19, .sclht =3D 0xD, + .fast_mode =3D true, + }, + { + .core_clk =3D 29000000, .hldt =3D 0x11, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0x15, .sclht =3D 0x10, + .fast_mode =3D true, + }, + { + .core_clk =3D 26000000, .hldt =3D 0x10, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0x13, .sclht =3D 0xE, + .fast_mode =3D true, + }, + { + .core_clk =3D 25000000, .hldt =3D 0xF, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0x13, .sclht =3D 0xD, + .fast_mode =3D true, + }, + { + .core_clk =3D 24000000, .hldt =3D 0xD, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0x12, .sclht =3D 0xD, + .fast_mode =3D true, + }, + { + .core_clk =3D 20000000, .hldt =3D 0xB, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0xF, .sclht =3D 0xA, + .fast_mode =3D true, + }, + { + .core_clk =3D 16180000, .hldt =3D 0xA, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0xC, .sclht =3D 0x9, + .fast_mode =3D true, + }, + { + .core_clk =3D 15000000, .hldt =3D 0x9, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0xB, .sclht =3D 0x8, + .fast_mode =3D true, + }, + { + .core_clk =3D 13000000, .hldt =3D 0x7, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0xA, .sclht =3D 0x7, + .fast_mode =3D true, + }, + { + .core_clk =3D 12000000, .hldt =3D 0x7, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0xA, .sclht =3D 0x6, + .fast_mode =3D true, + }, + { + .core_clk =3D 10000000, .hldt =3D 0x6, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0x8, .sclht =3D 0x5, + .fast_mode =3D true, + }, +}; + +static struct smb_timing_t smb_timing_1000khz[] =3D { + { + .core_clk =3D 100000000, .hldt =3D 0x15, .dbcnt =3D 0x4, + .sclfrq =3D 0x0, .scllt =3D 0x1C, .sclht =3D 0x15, + .fast_mode =3D true, + }, + { + .core_clk =3D 62500000, .hldt =3D 0xF, .dbcnt =3D 0x3, + .sclfrq =3D 0x0, .scllt =3D 0x11, .sclht =3D 0xE, + .fast_mode =3D true, + }, + { + .core_clk =3D 50000000, .hldt =3D 0xA, .dbcnt =3D 0x2, + .sclfrq =3D 0x0, .scllt =3D 0xE, .sclht =3D 0xB, + .fast_mode =3D true, + }, + { + .core_clk =3D 48000000, .hldt =3D 0x9, .dbcnt =3D 0x2, + .sclfrq =3D 0x0, .scllt =3D 0xD, .sclht =3D 0xB, + .fast_mode =3D true, + }, + { + .core_clk =3D 41000000, .hldt =3D 0x9, .dbcnt =3D 0x2, + .sclfrq =3D 0x0, .scllt =3D 0xC, .sclht =3D 0x9, + .fast_mode =3D true, + }, + { + .core_clk =3D 40000000, .hldt =3D 0x8, .dbcnt =3D 0x2, + .sclfrq =3D 0x0, .scllt =3D 0xB, .sclht =3D 0x9, + .fast_mode =3D true, + }, + { + .core_clk =3D 33000000, .hldt =3D 0x7, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0xA, .sclht =3D 0x7, + .fast_mode =3D true, + }, + { + .core_clk =3D 25000000, .hldt =3D 0x4, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0x7, .sclht =3D 0x6, + .fast_mode =3D true, + }, + { + .core_clk =3D 24000000, .hldt =3D 0x7, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0x8, .sclht =3D 0x5, + .fast_mode =3D true, + }, + { + .core_clk =3D 20000000, .hldt =3D 0x4, .dbcnt =3D 0x1, + .sclfrq =3D 0x0, .scllt =3D 0x6, .sclht =3D 0x4, + .fast_mode =3D true, + }, +}; + struct npcm_i2c_data { u8 fifo_size; u32 segctl_init_val; @@ -1805,102 +2064,45 @@ static void npcm_i2c_recovery_init(struct i2c_adap= ter *_adap) */ static int npcm_i2c_init_clk(struct npcm_i2c *bus, u32 bus_freq_hz) { - u32 k1 =3D 0; - u32 k2 =3D 0; - u8 dbnct =3D 0; - u32 sclfrq =3D 0; - u8 hldt =3D 7; + struct smb_timing_t *smb_timing; + u8 scl_table_cnt =3D 0, table_size =3D 0; u8 fast_mode =3D 0; - u32 src_clk_khz; - u32 bus_freq_khz; =20 - src_clk_khz =3D bus->apb_clk / 1000; - bus_freq_khz =3D bus_freq_hz / 1000; bus->bus_freq =3D bus_freq_hz; =20 - /* 100KHz and below: */ - if (bus_freq_hz <=3D I2C_MAX_STANDARD_MODE_FREQ) { - sclfrq =3D src_clk_khz / (bus_freq_khz * 4); - - if (sclfrq < SCLFRQ_MIN || sclfrq > SCLFRQ_MAX) - return -EDOM; - - if (src_clk_khz >=3D 40000) - hldt =3D 17; - else if (src_clk_khz >=3D 12500) - hldt =3D 15; - else - hldt =3D 7; - } - - /* 400KHz: */ - else if (bus_freq_hz <=3D I2C_MAX_FAST_MODE_FREQ) { - sclfrq =3D 0; + switch (bus_freq_hz) { + case I2C_MAX_STANDARD_MODE_FREQ: + smb_timing =3D smb_timing_100khz; + table_size =3D ARRAY_SIZE(smb_timing_100khz); + break; + case I2C_MAX_FAST_MODE_FREQ: + smb_timing =3D smb_timing_400khz; + table_size =3D ARRAY_SIZE(smb_timing_400khz); fast_mode =3D I2CCTL3_400K_MODE; - - if (src_clk_khz < 7500) - /* 400KHZ cannot be supported for core clock < 7.5MHz */ - return -EDOM; - - else if (src_clk_khz >=3D 50000) { - k1 =3D 80; - k2 =3D 48; - hldt =3D 12; - dbnct =3D 7; - } - - /* Master or Slave with frequency > 25MHz */ - else if (src_clk_khz > 25000) { - hldt =3D clk_coef(src_clk_khz, 300) + 7; - k1 =3D clk_coef(src_clk_khz, 1600); - k2 =3D clk_coef(src_clk_khz, 900); - } - } - - /* 1MHz: */ - else if (bus_freq_hz <=3D I2C_MAX_FAST_MODE_PLUS_FREQ) { - sclfrq =3D 0; + break; + case I2C_MAX_FAST_MODE_PLUS_FREQ: + smb_timing =3D smb_timing_1000khz; + table_size =3D ARRAY_SIZE(smb_timing_1000khz); fast_mode =3D I2CCTL3_400K_MODE; - - /* 1MHZ cannot be supported for core clock < 24 MHz */ - if (src_clk_khz < 24000) - return -EDOM; - - k1 =3D clk_coef(src_clk_khz, 620); - k2 =3D clk_coef(src_clk_khz, 380); - - /* Core clk > 40 MHz */ - if (src_clk_khz > 40000) { - /* - * Set HLDT: - * SDA hold time: (HLDT-7) * T(CLK) >=3D 120 - * HLDT =3D 120/T(CLK) + 7 =3D 120 * FREQ(CLK) + 7 - */ - hldt =3D clk_coef(src_clk_khz, 120) + 7; - } else { - hldt =3D 7; - dbnct =3D 2; - } + break; + default: + return -EINVAL; } =20 - /* Frequency larger than 1 MHz is not supported */ - else - return -EINVAL; + for (scl_table_cnt =3D 0; scl_table_cnt < table_size; scl_table_cnt++) + if (bus->apb_clk >=3D smb_timing[scl_table_cnt].core_clk) + break; =20 - if (bus_freq_hz >=3D I2C_MAX_FAST_MODE_FREQ) { - k1 =3D round_up(k1, 2); - k2 =3D round_up(k2 + 1, 2); - if (k1 < SCLFRQ_MIN || k1 > SCLFRQ_MAX || - k2 < SCLFRQ_MIN || k2 > SCLFRQ_MAX) - return -EDOM; - } + if (scl_table_cnt =3D=3D table_size) + return -EINVAL; =20 /* write sclfrq value. bits [6:0] are in I2CCTL2 reg */ - iowrite8(FIELD_PREP(I2CCTL2_SCLFRQ6_0, sclfrq & 0x7F), + iowrite8(FIELD_PREP(I2CCTL2_SCLFRQ6_0, smb_timing[scl_table_cnt].sclfrq &= 0x7F), bus->reg + NPCM_I2CCTL2); =20 /* bits [8:7] are in I2CCTL3 reg */ - iowrite8(fast_mode | FIELD_PREP(I2CCTL3_SCLFRQ8_7, (sclfrq >> 7) & 0x3), + iowrite8(FIELD_PREP(I2CCTL3_SCLFRQ8_7, (smb_timing[scl_table_cnt].sclfrq = >> 7) & 0x3) | + fast_mode, bus->reg + NPCM_I2CCTL3); =20 /* Select Bank 0 to access NPCM_I2CCTL4/NPCM_I2CCTL5 */ @@ -1912,13 +2114,13 @@ static int npcm_i2c_init_clk(struct npcm_i2c *bus, = u32 bus_freq_hz) * k1 =3D 2 * SCLLT7-0 -> Low Time =3D k1 / 2 * k2 =3D 2 * SCLLT7-0 -> High Time =3D k2 / 2 */ - iowrite8(k1 / 2, bus->reg + NPCM_I2CSCLLT); - iowrite8(k2 / 2, bus->reg + NPCM_I2CSCLHT); + iowrite8(smb_timing[scl_table_cnt].scllt, bus->reg + NPCM_I2CSCLLT); + iowrite8(smb_timing[scl_table_cnt].sclht, bus->reg + NPCM_I2CSCLHT); =20 - iowrite8(dbnct, bus->reg + NPCM_I2CCTL5); + iowrite8(smb_timing[scl_table_cnt].dbcnt, bus->reg + NPCM_I2CCTL5); } =20 - iowrite8(hldt, bus->reg + NPCM_I2CCTL4); + iowrite8(smb_timing[scl_table_cnt].hldt, bus->reg + NPCM_I2CCTL4); =20 /* Return to Bank 1, and stay there by default: */ npcm_i2c_select_bank(bus, I2C_BANK_1); --=20 2.34.1