i2c-for-6.13-part2

Andi was super busy the last weeks, so this pull requests contains one
 series (nomadik) and a number of smaller additions which were ready to
 go but nearly overlooked. Despite the late collection, they have been
 properly reviewed and have been in -next for 6 days now in Andi's tree.
 
 New feature support:
  - Added support for frequencies up to 3.4 MHz on Nomadik I2C.
  - DesignWare now accounts for bus capacitance and clock
    optimisation (declared as new parameters in the binding) to
    improve the calculation of signal rise and fall times
    (t_high and t_low).
 
 New Hardware support:
  - DWAPB I2C controller on FUJITSU-MONAKA (new ACPI HID).
  - Allwinner A523 (new compatible ID).
  - Mobileye EyeQ6H (new compatible ID).
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEOZGx6rniZ1Gk92RdFA3kzBSgKbYFAmdDRfUACgkQFA3kzBSg
 KbZpFA//ZYScU383VPaSc6U750yAM3lFLfjlmi8gfgJ5r42a5xTG+zltu8MJeu3C
 wRJGu3MDxuE5jjHMGAUMauuD0w0tTkY7ZcfPqpj2hDEs7Un/oVD2quz5EkRyaKIS
 mU86GoEFr4RB7lUguSsQbV9Fk+mlu6CEiOxT270AnwSF2O0YKkrBPV+htvh/VKdL
 TdFLQph2XGk0atGnklraBHQqZq7bVFGgpfdj/oKg2uM+2gnfJuAU86CHCg0kGp7/
 /95sIlu8jORA9/0jJ6d5yyb4ScuGnYfjxdomnbODXsOAcLPfgjtnStKrApAH3I0K
 DyBfherU8o+kvEe1APjecxGFifms/01YxSpVUvsKW3I0UXM6ahOcbjJs9rQ++5JB
 BDfR7nE0eOh1yf7hwqRjOMYot4+tkAzSMoUefSfdfRay+dzgR2NSC8Y2uovkvbiu
 Ce5YVXCnbBcJB6IlSKuy4YiN65/tucypugpjvgtduCxHegkr7N0tAf+/mokPlGHV
 AO7BUnTovZQ3/YwIlpayD1kKKpvNtB4dmEPNnji1SMACHteB3PKPoybNlig+244K
 +G0f4oMUr1LBEwyeFLg0RNxFw8H1JviaVfOiUWaaPqUrJ3BxQk1XmqveI5IHxzB8
 yWDywTzyJuai9VI8NU8z7szTGepcNla9RlrixdDHmopS4sgBuxo=
 =TpAe
 -----END PGP SIGNATURE-----

Merge tag 'i2c-for-6.13-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull more i2c updates from Wolfram Sang:
 "Andi was super busy the last weeks, so this pull requests contains one
  series (nomadik) and a number of smaller additions which were ready to
  go but nearly overlooked.

  New feature support:

   - Added support for frequencies up to 3.4 MHz on Nomadik I2C

   - DesignWare now accounts for bus capacitance and clock optimisation
     (declared as new parameters in the binding) to improve the
     calculation of signal rise and fall times (t_high and t_low)

  New Hardware support:

   - DWAPB I2C controller on FUJITSU-MONAKA (new ACPI HID)

   - Allwinner A523 (new compatible ID)

   - Mobileye EyeQ6H (new compatible ID)"

* tag 'i2c-for-6.13-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  MAINTAINERS: transfer i2c-aspeed maintainership from Brendan to Ryan
  i2c: designware: determine HS tHIGH and tLOW based on HW parameters
  dt-bindings: i2c: snps,designware-i2c: declare bus capacitance and clk freq optimized
  i2c: nomadik: support >=1MHz speed modes
  i2c: nomadik: fix BRCR computation
  i2c: nomadik: support Mobileye EyeQ6H I2C controller
  i2c: nomadik: switch from of_device_is_compatible() to of_match_device()
  dt-bindings: i2c: nomadik: support 400kHz < clock-frequency <= 3.4MHz
  dt-bindings: i2c: nomadik: add mobileye,eyeq6h-i2c bindings
  dt-bindings: i2c: mv64xxx: Add Allwinner A523 compatible string
  i2c: designware: Add ACPI HID for DWAPB I2C controller on FUJITSU-MONAKA
  i2c: qup: use generic device property accessors
This commit is contained in:
Linus Torvalds 2024-11-25 17:15:12 -08:00
commit 70dbb12e95
10 changed files with 116 additions and 46 deletions

View File

@ -33,6 +33,7 @@ properties:
- allwinner,sun50i-a100-i2c
- allwinner,sun50i-h616-i2c
- allwinner,sun50i-r329-i2c
- allwinner,sun55i-a523-i2c
- const: allwinner,sun8i-v536-i2c
- const: allwinner,sun6i-a31-i2c
- const: marvell,mv64xxx-i2c

View File

@ -97,6 +97,22 @@ properties:
- const: tx
- const: rx
snps,bus-capacitance-pf:
$ref: /schemas/types.yaml#/definitions/uint32
description:
This property indicates the bus capacitance in picofarads (pF).
This value is used to compute the tHIGH and tLOW periods for high speed
mode.
enum: [100, 400]
default: 100
snps,clk-freq-optimized:
description:
This property indicates whether the hardware reduce its clock frequency
by reducing the internal latency required to generate the high period and
low period of SCL line.
type: boolean
unevaluatedProperties: false
required:
@ -121,6 +137,8 @@ examples:
i2c-sda-hold-time-ns = <300>;
i2c-sda-falling-time-ns = <300>;
i2c-scl-falling-time-ns = <300>;
snps,bus-capacitance-pf = <400>;
snps,clk-freq-optimized;
};
- |
i2c@2000 {

View File

@ -22,6 +22,7 @@ select:
enum:
- st,nomadik-i2c
- mobileye,eyeq5-i2c
- mobileye,eyeq6h-i2c
required:
- compatible
@ -29,15 +30,15 @@ properties:
compatible:
oneOf:
- items:
- const: st,nomadik-i2c
- enum:
- st,nomadik-i2c
- mobileye,eyeq5-i2c
- mobileye,eyeq6h-i2c
- const: arm,primecell
- items:
- const: stericsson,db8500-i2c
- const: st,nomadik-i2c
- const: arm,primecell
- items:
- const: mobileye,eyeq5-i2c
- const: arm,primecell
reg:
maxItems: 1
@ -54,7 +55,7 @@ properties:
- items:
- const: mclk
- const: apb_pclk
# Clock name in DB8500 or EyeQ5
# Clock name in DB8500 or EyeQ
- items:
- const: i2cclk
- const: apb_pclk
@ -67,7 +68,7 @@ properties:
clock-frequency:
minimum: 1
maximum: 400000
maximum: 3400000
mobileye,olb:
$ref: /schemas/types.yaml#/definitions/phandle-array

View File

@ -2213,7 +2213,7 @@ F: drivers/mmc/host/usdhi6rol0.c
F: drivers/pinctrl/pinctrl-artpec*
ARM/ASPEED I2C DRIVER
M: Brendan Higgins <brendanhiggins@google.com>
M: Ryan Chen <ryan_chen@aspeedtech.com>
R: Benjamin Herrenschmidt <benh@kernel.crashing.org>
R: Joel Stanley <joel@jms.id.au>
L: linux-i2c@vger.kernel.org

View File

@ -382,6 +382,11 @@ int i2c_dw_fw_parse_and_configure(struct dw_i2c_dev *dev)
i2c_parse_fw_timings(device, t, false);
if (device_property_read_u32(device, "snps,bus-capacitance-pf", &dev->bus_capacitance_pF))
dev->bus_capacitance_pF = 100;
dev->clk_freq_optimized = device_property_read_bool(device, "snps,clk-freq-optimized");
i2c_dw_adjust_bus_speed(dev);
if (is_of_node(fwnode))

View File

@ -242,6 +242,10 @@ struct reset_control;
* @set_sda_hold_time: callback to retrieve IP specific SDA hold timing
* @mode: operation mode - DW_IC_MASTER or DW_IC_SLAVE
* @rinfo: I²C GPIO recovery information
* @bus_capacitance_pF: bus capacitance in picofarads
* @clk_freq_optimized: if this value is true, it means the hardware reduces
* its internal clock frequency by reducing the internal latency required
* to generate the high period and low period of SCL line.
*
* HCNT and LCNT parameters can be used if the platform knows more accurate
* values than the one computed based only on the input clock frequency.
@ -299,6 +303,8 @@ struct dw_i2c_dev {
int (*set_sda_hold_time)(struct dw_i2c_dev *dev);
int mode;
struct i2c_bus_recovery_info rinfo;
u32 bus_capacitance_pF;
bool clk_freq_optimized;
};
#define ACCESS_INTR_MASK BIT(0)

View File

@ -151,19 +151,38 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
dev->hs_hcnt = 0;
dev->hs_lcnt = 0;
} else if (!dev->hs_hcnt || !dev->hs_lcnt) {
u32 t_high, t_low;
/*
* The legal values stated in the databook for bus
* capacitance are only 100pF and 400pF.
* If dev->bus_capacitance_pF is greater than or equals
* to 400, t_high and t_low are assumed to be
* appropriate values for 400pF, otherwise 100pF.
*/
if (dev->bus_capacitance_pF >= 400) {
/* assume bus capacitance is 400pF */
t_high = dev->clk_freq_optimized ? 160 : 120;
t_low = 320;
} else {
/* assume bus capacitance is 100pF */
t_high = 60;
t_low = dev->clk_freq_optimized ? 120 : 160;
}
ic_clk = i2c_dw_clk_rate(dev);
dev->hs_hcnt =
i2c_dw_scl_hcnt(dev,
DW_IC_HS_SCL_HCNT,
ic_clk,
160, /* tHIGH = 160 ns */
t_high,
sda_falling_time,
0); /* No offset */
dev->hs_lcnt =
i2c_dw_scl_lcnt(dev,
DW_IC_HS_SCL_LCNT,
ic_clk,
320, /* tLOW = 320 ns */
t_low,
scl_falling_time,
0); /* No offset */
}

View File

@ -349,6 +349,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
{ "AMDI0019", ACCESS_INTR_MASK | ARBITRATION_SEMAPHORE },
{ "AMDI0510", 0 },
{ "APMC0D0F", 0 },
{ "FUJI200B", 0 },
{ "HISI02A1", 0 },
{ "HISI02A2", 0 },
{ "HISI02A3", 0 },

View File

@ -6,10 +6,10 @@
* I2C master mode controller driver, used in Nomadik 8815
* and Ux500 platforms.
*
* The Mobileye EyeQ5 platform is also supported; it uses
* The Mobileye EyeQ5 and EyeQ6H platforms are also supported; they use
* the same Ux500/DB8500 IP block with two quirks:
* - The memory bus only supports 32-bit accesses.
* - A register must be configured for the I2C speed mode;
* - (only EyeQ5) A register must be configured for the I2C speed mode;
* it is located in a shared register region called OLB.
*
* Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
@ -26,6 +26,7 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
@ -396,7 +397,7 @@ static u32 load_i2c_mcr_reg(struct nmk_i2c_dev *priv, u16 flags)
*/
static void setup_i2c_controller(struct nmk_i2c_dev *priv)
{
u32 brcr1, brcr2;
u32 brcr;
u32 i2c_clk, div;
u32 ns;
u16 slsu;
@ -443,7 +444,7 @@ static void setup_i2c_controller(struct nmk_i2c_dev *priv)
/*
* The spec says, in case of std. mode the divider is
* 2 whereas it is 3 for fast and fastplus mode of
* operation. TODO - high speed support.
* operation.
*/
div = (priv->clk_freq > I2C_MAX_STANDARD_MODE_FREQ) ? 3 : 2;
@ -451,30 +452,23 @@ static void setup_i2c_controller(struct nmk_i2c_dev *priv)
* generate the mask for baud rate counters. The controller
* has two baud rate counters. One is used for High speed
* operation, and the other is for std, fast mode, fast mode
* plus operation. Currently we do not supprt high speed mode
* so set brcr1 to 0.
* plus operation.
*
* BRCR is a clock divider amount. Pick highest value that
* leads to rate strictly below target. Eg when asking for
* 400kHz you want a bus rate <=400kHz (and not >=400kHz).
*/
brcr1 = FIELD_PREP(I2C_BRCR_BRCNT1, 0);
brcr2 = FIELD_PREP(I2C_BRCR_BRCNT2, i2c_clk / (priv->clk_freq * div));
brcr = DIV_ROUND_UP(i2c_clk, priv->clk_freq * div);
if (priv->sm == I2C_FREQ_MODE_HIGH_SPEED)
brcr = FIELD_PREP(I2C_BRCR_BRCNT1, brcr);
else
brcr = FIELD_PREP(I2C_BRCR_BRCNT2, brcr);
/* set the baud rate counter register */
writel((brcr1 | brcr2), priv->virtbase + I2C_BRCR);
writel(brcr, priv->virtbase + I2C_BRCR);
/*
* set the speed mode. Currently we support
* only standard and fast mode of operation
* TODO - support for fast mode plus (up to 1Mb/s)
* and high speed (up to 3.4 Mb/s)
*/
if (priv->sm > I2C_FREQ_MODE_FAST) {
dev_err(&priv->adev->dev,
"do not support this mode defaulting to std. mode\n");
brcr2 = FIELD_PREP(I2C_BRCR_BRCNT2,
i2c_clk / (I2C_MAX_STANDARD_MODE_FREQ * 2));
writel((brcr1 | brcr2), priv->virtbase + I2C_BRCR);
writel(FIELD_PREP(I2C_CR_SM, I2C_FREQ_MODE_STANDARD),
priv->virtbase + I2C_CR);
}
/* set the speed mode */
writel(FIELD_PREP(I2C_CR_SM, priv->sm), priv->virtbase + I2C_CR);
/* set the Tx and Rx FIFO threshold */
@ -1015,11 +1009,14 @@ static void nmk_i2c_of_probe(struct device_node *np,
if (of_property_read_u32(np, "clock-frequency", &priv->clk_freq))
priv->clk_freq = I2C_MAX_STANDARD_MODE_FREQ;
/* This driver only supports 'standard' and 'fast' modes of operation. */
if (priv->clk_freq <= I2C_MAX_STANDARD_MODE_FREQ)
priv->sm = I2C_FREQ_MODE_STANDARD;
else
else if (priv->clk_freq <= I2C_MAX_FAST_MODE_FREQ)
priv->sm = I2C_FREQ_MODE_FAST;
else if (priv->clk_freq <= I2C_MAX_FAST_MODE_PLUS_FREQ)
priv->sm = I2C_FREQ_MODE_FAST_PLUS;
else
priv->sm = I2C_FREQ_MODE_HIGH_SPEED;
priv->tft = 1; /* Tx FIFO threshold */
priv->rft = 8; /* Rx FIFO threshold */
@ -1046,8 +1043,6 @@ static int nmk_i2c_eyeq5_probe(struct nmk_i2c_dev *priv)
struct regmap *olb;
unsigned int id;
priv->has_32b_bus = true;
olb = syscon_regmap_lookup_by_phandle_args(np, "mobileye,olb", 1, &id);
if (IS_ERR(olb))
return PTR_ERR(olb);
@ -1068,15 +1063,39 @@ static int nmk_i2c_eyeq5_probe(struct nmk_i2c_dev *priv)
return 0;
}
#define NMK_I2C_EYEQ_FLAG_32B_BUS BIT(0)
#define NMK_I2C_EYEQ_FLAG_IS_EYEQ5 BIT(1)
static const struct of_device_id nmk_i2c_eyeq_match_table[] = {
{
.compatible = "mobileye,eyeq5-i2c",
.data = (void *)(NMK_I2C_EYEQ_FLAG_32B_BUS | NMK_I2C_EYEQ_FLAG_IS_EYEQ5),
},
{
.compatible = "mobileye,eyeq6h-i2c",
.data = (void *)NMK_I2C_EYEQ_FLAG_32B_BUS,
},
};
static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
{
int ret = 0;
struct nmk_i2c_dev *priv;
struct device_node *np = adev->dev.of_node;
struct device *dev = &adev->dev;
struct i2c_adapter *adap;
struct i2c_vendor_data *vendor = id->data;
u32 max_fifo_threshold = (vendor->fifodepth / 2) - 1;
struct device_node *np = adev->dev.of_node;
const struct of_device_id *match;
struct device *dev = &adev->dev;
unsigned long match_flags = 0;
struct nmk_i2c_dev *priv;
struct i2c_adapter *adap;
int ret = 0;
/*
* We do not want to attach a .of_match_table to our amba driver.
* Do not convert to device_get_match_data().
*/
match = of_match_device(nmk_i2c_eyeq_match_table, dev);
if (match)
match_flags = (unsigned long)match->data;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@ -1084,10 +1103,10 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
priv->vendor = vendor;
priv->adev = adev;
priv->has_32b_bus = false;
priv->has_32b_bus = match_flags & NMK_I2C_EYEQ_FLAG_32B_BUS;
nmk_i2c_of_probe(np, priv);
if (of_device_is_compatible(np, "mobileye,eyeq5-i2c")) {
if (match_flags & NMK_I2C_EYEQ_FLAG_IS_EYEQ5) {
ret = nmk_i2c_eyeq5_probe(priv);
if (ret)
return dev_err_probe(dev, ret, "failed OLB lookup\n");

View File

@ -17,9 +17,9 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/scatterlist.h>
/* QUP Registers */
@ -1683,7 +1683,7 @@ static int qup_i2c_probe(struct platform_device *pdev)
}
}
if (of_device_is_compatible(pdev->dev.of_node, "qcom,i2c-qup-v1.1.1")) {
if (device_is_compatible(&pdev->dev, "qcom,i2c-qup-v1.1.1")) {
qup->adap.algo = &qup_i2c_algo;
qup->adap.quirks = &qup_i2c_quirks;
is_qup_v1 = true;